OSDN Git Service

fd2cb47f601007a410626b6f13cf3cafb0eba42f
[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, 2001, 2002
3 ;; Free Software Foundation, Inc.
4 ;; Mostly by William Schelter.
5 ;; x86_64 support added by Jan Hubicka
6 ;;
7 ;; This file is part of GNU CC.
8 ;;
9 ;; GNU CC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
12 ;; any later version.
13 ;;
14 ;; GNU CC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 ;; GNU General Public License for more details.
18 ;;
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GNU CC; see the file COPYING.  If not, write to
21 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
22 ;; Boston, MA 02111-1307, USA.  */
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 ;; Macro #define NOTICE_UPDATE_CC in file i386.h handles condition code
30 ;; updates for most instructions.
31 ;;
32 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
33 ;; constraint letters.
34 ;;
35 ;; The special asm out single letter directives following a '%' are:
36 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
37 ;;     operands[1].
38 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
39 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
40 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
41 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
42 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
43 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
44 ;; 'J' Print the appropriate jump operand.
45 ;;
46 ;; 'b' Print the QImode name of the register for the indicated operand.
47 ;;     %b0 would print %al if operands[0] is reg 0.
48 ;; 'w' Likewise, print the HImode name of the register.
49 ;; 'k' Likewise, print the SImode name of the register.
50 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
51 ;; 'y' Print "st(0)" instead of "st" as a register.
52
53 ;; UNSPEC usage:
54
55 (define_constants
56   [; Relocation specifiers
57    (UNSPEC_GOT                  0)
58    (UNSPEC_GOTOFF               1)
59    (UNSPEC_GOTPCREL             2)
60    (UNSPEC_GOTTPOFF             3)
61    (UNSPEC_TPOFF                4)
62    (UNSPEC_NTPOFF               5)
63    (UNSPEC_DTPOFF               6)
64
65    ; Prologue support
66    (UNSPEC_STACK_PROBE          10)
67    (UNSPEC_STACK_ALLOC          11)
68    (UNSPEC_SET_GOT              12)
69    (UNSPEC_SSE_PROLOGUE_SAVE    13)
70
71    ; TLS support
72    (UNSPEC_TP                   15)
73    (UNSPEC_TLS_GD               16)
74    (UNSPEC_TLS_LD_BASE          17)
75
76    ; Other random patterns
77    (UNSPEC_SCAS                 20)
78    (UNSPEC_SIN                  21)
79    (UNSPEC_COS                  22)
80    (UNSPEC_BSF                  23)
81    (UNSPEC_FNSTSW               24)
82    (UNSPEC_SAHF                 25)
83    (UNSPEC_FSTCW                26)
84    (UNSPEC_ADD_CARRY            27)
85    (UNSPEC_FLDCW                28)
86
87    ; For SSE/MMX support:
88    (UNSPEC_FIX                  30)
89    (UNSPEC_MASKMOV              32)
90    (UNSPEC_MOVMSK               33)
91    (UNSPEC_MOVNT                34)
92    (UNSPEC_MOVA                 38)
93    (UNSPEC_MOVU                 39)
94    (UNSPEC_SHUFFLE              41)
95    (UNSPEC_RCP                  42)
96    (UNSPEC_RSQRT                43)
97    (UNSPEC_SFENCE               44)
98    (UNSPEC_NOP                  45)     ; prevents combiner cleverness
99    (UNSPEC_PAVGUSB              49)
100    (UNSPEC_PFRCP                50)
101    (UNSPEC_PFRCPIT1             51)
102    (UNSPEC_PFRCPIT2             52)
103    (UNSPEC_PFRSQRT              53)
104    (UNSPEC_PFRSQIT1             54)
105    (UNSPEC_PSHUFLW              55)
106    (UNSPEC_PSHUFHW              56)
107    (UNSPEC_MFENCE               59)
108    (UNSPEC_LFENCE               60)
109    (UNSPEC_PSADBW               61)
110   ])
111
112 (define_constants
113   [(UNSPECV_BLOCKAGE            0)
114    (UNSPECV_EH_RETURN           13)
115    (UNSPECV_EMMS                31)
116    (UNSPECV_LDMXCSR             37)
117    (UNSPECV_STMXCSR             40)
118    (UNSPECV_FEMMS               46)
119    (UNSPECV_CLFLUSH             57)
120   ])
121
122 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
123 ;; from i386.c.
124
125 ;; In C guard expressions, put expressions which may be compile-time
126 ;; constants first.  This allows for better optimization.  For
127 ;; example, write "TARGET_64BIT && reload_completed", not
128 ;; "reload_completed && TARGET_64BIT".
129
130 \f
131 ;; Processor type.  This attribute must exactly match the processor_type
132 ;; enumeration in i386.h.
133 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4"
134   (const (symbol_ref "ix86_cpu")))
135
136 ;; A basic instruction type.  Refinements due to arguments to be
137 ;; provided in other attributes.
138 (define_attr "type"
139   "other,multi,
140    alu,alu1,negnot,imov,imovx,lea,
141    incdec,ishift,rotate,imul,idiv,
142    icmp,test,ibr,setcc,icmov,
143    push,pop,call,callv,
144    str,cld,
145    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,
146    sselog,sseiadd,sseishft,sseimul,
147    sse,ssemov,sseadd,ssemul,ssecmp,ssecvt,ssediv,
148    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
149   (const_string "other"))
150
151 ;; Main data type used by the insn
152 (define_attr "mode"
153   "unknown,none,QI,HI,SI,DI,unknownfp,SF,DF,XF,TI,V4SF,V2DF,V2SF"
154   (const_string "unknown"))
155
156 ;; The CPU unit operations uses.
157 (define_attr "unit" "integer,i387,sse,mmx,unknown"
158   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp")
159            (const_string "i387")
160          (eq_attr "type" "sselog,sseiadd,sseishft,sseimul,
161                           sse,ssemov,sseadd,ssemul,ssecmp,ssecvt,ssediv")
162            (const_string "sse")
163          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
164            (const_string "mmx")]
165          (const_string "integer")))
166
167 ;; The (bounding maximum) length of an instruction immediate.
168 (define_attr "length_immediate" ""
169   (cond [(eq_attr "type" "incdec,setcc,icmov,ibr,str,cld,lea,other,multi,idiv")
170            (const_int 0)
171          (eq_attr "unit" "i387,sse,mmx")
172            (const_int 0)
173          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,imul,
174                           icmp,push,pop")
175            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
176          (eq_attr "type" "imov,test")
177            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
178          (eq_attr "type" "call")
179            (if_then_else (match_operand 0 "constant_call_address_operand" "")
180              (const_int 4)
181              (const_int 0))
182          (eq_attr "type" "callv")
183            (if_then_else (match_operand 1 "constant_call_address_operand" "")
184              (const_int 4)
185              (const_int 0))
186          (eq_attr "type" "ibr")
187            (if_then_else (and (ge (minus (match_dup 0) (pc))
188                                   (const_int -128))
189                               (lt (minus (match_dup 0) (pc))
190                                   (const_int 124)))
191              (const_int 1)
192              (const_int 4))
193          ]
194          (symbol_ref "/* Update immediate_length and other attributes! */
195                       abort(),1")))
196
197 ;; The (bounding maximum) length of an instruction address.
198 (define_attr "length_address" ""
199   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
200            (const_int 0)
201          (and (eq_attr "type" "call")
202               (match_operand 1 "constant_call_address_operand" ""))
203              (const_int 0)
204          (and (eq_attr "type" "callv")
205               (match_operand 1 "constant_call_address_operand" ""))
206              (const_int 0)
207          ]
208          (symbol_ref "ix86_attr_length_address_default (insn)")))
209
210 ;; Set when length prefix is used.
211 (define_attr "prefix_data16" ""
212   (if_then_else (ior (eq_attr "mode" "HI")
213                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
214     (const_int 1)
215     (const_int 0)))
216
217 ;; Set when string REP prefix is used.
218 (define_attr "prefix_rep" "" 
219   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
220     (const_int 1)
221     (const_int 0)))
222
223 ;; Set when 0f opcode prefix is used.
224 (define_attr "prefix_0f" ""
225   (if_then_else 
226     (eq_attr "type" 
227              "imovx,setcc,icmov,
228               sselog,sseiadd,sseishft,sseimul,
229               sse,ssemov,sseadd,ssemul,ssecmp,ssecvt,ssediv,
230               mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
231     (const_int 1)
232     (const_int 0)))
233
234 ;; Set when modrm byte is used.
235 (define_attr "modrm" ""
236   (cond [(eq_attr "type" "str,cld")
237            (const_int 0)
238          (eq_attr "unit" "i387")
239            (const_int 0)
240          (and (eq_attr "type" "incdec")
241               (ior (match_operand:SI 1 "register_operand" "")
242                    (match_operand:HI 1 "register_operand" "")))
243            (const_int 0)
244          (and (eq_attr "type" "push")
245               (not (match_operand 1 "memory_operand" "")))
246            (const_int 0)
247          (and (eq_attr "type" "pop")
248               (not (match_operand 0 "memory_operand" "")))
249            (const_int 0)
250          (and (eq_attr "type" "imov")
251               (and (match_operand 0 "register_operand" "")
252                    (match_operand 1 "immediate_operand" "")))
253            (const_int 0)
254          ]
255          (const_int 1)))
256
257 ;; The (bounding maximum) length of an instruction in bytes.
258 ;; ??? fistp is in fact fldcw/fistp/fldcw sequence.  Later we may want
259 ;; to split it and compute proper length as for other insns.
260 (define_attr "length" ""
261   (cond [(eq_attr "type" "other,multi,fistp")
262            (const_int 16)
263          (eq_attr "unit" "i387")
264            (plus (const_int 2)
265                  (plus (attr "prefix_data16")
266                        (attr "length_address")))]
267          (plus (plus (attr "modrm")
268                      (plus (attr "prefix_0f")
269                            (const_int 1)))
270                (plus (attr "prefix_rep")
271                      (plus (attr "prefix_data16")
272                            (plus (attr "length_immediate")
273                                  (attr "length_address")))))))
274
275 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
276 ;; `store' if there is a simple memory reference therein, or `unknown'
277 ;; if the instruction is complex.
278
279 (define_attr "memory" "none,load,store,both,unknown"
280   (cond [(eq_attr "type" "other,multi,str")
281            (const_string "unknown")
282          (eq_attr "type" "lea,fcmov,fpspc,cld")
283            (const_string "none")
284          (eq_attr "type" "fistp")
285            (const_string "both")
286          (eq_attr "type" "push")
287            (if_then_else (match_operand 1 "memory_operand" "")
288              (const_string "both")
289              (const_string "store"))
290          (eq_attr "type" "pop,setcc")
291            (if_then_else (match_operand 0 "memory_operand" "")
292              (const_string "both")
293              (const_string "load"))
294          (eq_attr "type" "icmp,test,ssecmp,mmxcmp,fcmp")
295            (if_then_else (ior (match_operand 0 "memory_operand" "")
296                               (match_operand 1 "memory_operand" ""))
297              (const_string "load")
298              (const_string "none"))
299          (eq_attr "type" "ibr")
300            (if_then_else (match_operand 0 "memory_operand" "")
301              (const_string "load")
302              (const_string "none"))
303          (eq_attr "type" "call")
304            (if_then_else (match_operand 0 "constant_call_address_operand" "")
305              (const_string "none")
306              (const_string "load"))
307          (eq_attr "type" "callv")
308            (if_then_else (match_operand 1 "constant_call_address_operand" "")
309              (const_string "none")
310              (const_string "load"))
311          (and (eq_attr "type" "alu1,negnot")
312               (match_operand 1 "memory_operand" ""))
313            (const_string "both")
314          (and (match_operand 0 "memory_operand" "")
315               (match_operand 1 "memory_operand" ""))
316            (const_string "both")
317          (match_operand 0 "memory_operand" "")
318            (const_string "store")
319          (match_operand 1 "memory_operand" "")
320            (const_string "load")
321          (and (eq_attr "type"
322                  "!alu1,negnot,
323                    imov,imovx,icmp,test,
324                    fmov,fcmp,fsgn,
325                    sse,ssemov,ssecmp,ssecvt,
326                    mmx,mmxmov,mmxcmp,mmxcvt")
327               (match_operand 2 "memory_operand" ""))
328            (const_string "load")
329          (and (eq_attr "type" "icmov")
330               (match_operand 3 "memory_operand" ""))
331            (const_string "load")
332         ]
333         (const_string "none")))
334
335 ;; Indicates if an instruction has both an immediate and a displacement.
336
337 (define_attr "imm_disp" "false,true,unknown"
338   (cond [(eq_attr "type" "other,multi")
339            (const_string "unknown")
340          (and (eq_attr "type" "icmp,test,imov")
341               (and (match_operand 0 "memory_displacement_operand" "")
342                    (match_operand 1 "immediate_operand" "")))
343            (const_string "true")
344          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
345               (and (match_operand 0 "memory_displacement_operand" "")
346                    (match_operand 2 "immediate_operand" "")))
347            (const_string "true")
348         ]
349         (const_string "false")))
350
351 ;; Indicates if an FP operation has an integer source.
352
353 (define_attr "fp_int_src" "false,true"
354   (const_string "false"))
355
356 ;; Describe a user's asm statement.
357 (define_asm_attributes
358   [(set_attr "length" "128")
359    (set_attr "type" "multi")])
360 \f
361 (include "pentium.md")
362 (include "ppro.md")
363 (include "k6.md")
364 (include "athlon.md")
365 \f
366 ;; Compare instructions.
367
368 ;; All compare insns have expanders that save the operands away without
369 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
370 ;; after the cmp) will actually emit the cmpM.
371
372 (define_expand "cmpdi"
373   [(set (reg:CC 17)
374         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
375                     (match_operand:DI 1 "x86_64_general_operand" "")))]
376   ""
377 {
378   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
379     operands[0] = force_reg (DImode, operands[0]);
380   ix86_compare_op0 = operands[0];
381   ix86_compare_op1 = operands[1];
382   DONE;
383 })
384
385 (define_expand "cmpsi"
386   [(set (reg:CC 17)
387         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
388                     (match_operand:SI 1 "general_operand" "")))]
389   ""
390 {
391   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
392     operands[0] = force_reg (SImode, operands[0]);
393   ix86_compare_op0 = operands[0];
394   ix86_compare_op1 = operands[1];
395   DONE;
396 })
397
398 (define_expand "cmphi"
399   [(set (reg:CC 17)
400         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
401                     (match_operand:HI 1 "general_operand" "")))]
402   ""
403 {
404   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
405     operands[0] = force_reg (HImode, operands[0]);
406   ix86_compare_op0 = operands[0];
407   ix86_compare_op1 = operands[1];
408   DONE;
409 })
410
411 (define_expand "cmpqi"
412   [(set (reg:CC 17)
413         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
414                     (match_operand:QI 1 "general_operand" "")))]
415   "TARGET_QIMODE_MATH"
416 {
417   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
418     operands[0] = force_reg (QImode, operands[0]);
419   ix86_compare_op0 = operands[0];
420   ix86_compare_op1 = operands[1];
421   DONE;
422 })
423
424 (define_insn "cmpdi_ccno_1_rex64"
425   [(set (reg 17)
426         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
427                  (match_operand:DI 1 "const0_operand" "n,n")))]
428   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
429   "@
430    test{q}\t{%0, %0|%0, %0}
431    cmp{q}\t{%1, %0|%0, %1}"
432   [(set_attr "type" "test,icmp")
433    (set_attr "length_immediate" "0,1")
434    (set_attr "mode" "DI")])
435
436 (define_insn "*cmpdi_minus_1_rex64"
437   [(set (reg 17)
438         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
439                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
440                  (const_int 0)))]
441   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
442   "cmp{q}\t{%1, %0|%0, %1}"
443   [(set_attr "type" "icmp")
444    (set_attr "mode" "DI")])
445
446 (define_expand "cmpdi_1_rex64"
447   [(set (reg:CC 17)
448         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
449                     (match_operand:DI 1 "general_operand" "")))]
450   "TARGET_64BIT"
451   "")
452
453 (define_insn "cmpdi_1_insn_rex64"
454   [(set (reg 17)
455         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
456                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
457   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
458   "cmp{q}\t{%1, %0|%0, %1}"
459   [(set_attr "type" "icmp")
460    (set_attr "mode" "DI")])
461
462
463 (define_insn "*cmpsi_ccno_1"
464   [(set (reg 17)
465         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
466                  (match_operand:SI 1 "const0_operand" "n,n")))]
467   "ix86_match_ccmode (insn, CCNOmode)"
468   "@
469    test{l}\t{%0, %0|%0, %0}
470    cmp{l}\t{%1, %0|%0, %1}"
471   [(set_attr "type" "test,icmp")
472    (set_attr "length_immediate" "0,1")
473    (set_attr "mode" "SI")])
474
475 (define_insn "*cmpsi_minus_1"
476   [(set (reg 17)
477         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
478                            (match_operand:SI 1 "general_operand" "ri,mr"))
479                  (const_int 0)))]
480   "ix86_match_ccmode (insn, CCGOCmode)"
481   "cmp{l}\t{%1, %0|%0, %1}"
482   [(set_attr "type" "icmp")
483    (set_attr "mode" "SI")])
484
485 (define_expand "cmpsi_1"
486   [(set (reg:CC 17)
487         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
488                     (match_operand:SI 1 "general_operand" "ri,mr")))]
489   ""
490   "")
491
492 (define_insn "*cmpsi_1_insn"
493   [(set (reg 17)
494         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
495                  (match_operand:SI 1 "general_operand" "ri,mr")))]
496   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
497     && ix86_match_ccmode (insn, CCmode)"
498   "cmp{l}\t{%1, %0|%0, %1}"
499   [(set_attr "type" "icmp")
500    (set_attr "mode" "SI")])
501
502 (define_insn "*cmphi_ccno_1"
503   [(set (reg 17)
504         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
505                  (match_operand:HI 1 "const0_operand" "n,n")))]
506   "ix86_match_ccmode (insn, CCNOmode)"
507   "@
508    test{w}\t{%0, %0|%0, %0}
509    cmp{w}\t{%1, %0|%0, %1}"
510   [(set_attr "type" "test,icmp")
511    (set_attr "length_immediate" "0,1")
512    (set_attr "mode" "HI")])
513
514 (define_insn "*cmphi_minus_1"
515   [(set (reg 17)
516         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
517                            (match_operand:HI 1 "general_operand" "ri,mr"))
518                  (const_int 0)))]
519   "ix86_match_ccmode (insn, CCGOCmode)"
520   "cmp{w}\t{%1, %0|%0, %1}"
521   [(set_attr "type" "icmp")
522    (set_attr "mode" "HI")])
523
524 (define_insn "*cmphi_1"
525   [(set (reg 17)
526         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
527                  (match_operand:HI 1 "general_operand" "ri,mr")))]
528   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
529    && ix86_match_ccmode (insn, CCmode)"
530   "cmp{w}\t{%1, %0|%0, %1}"
531   [(set_attr "type" "icmp")
532    (set_attr "mode" "HI")])
533
534 (define_insn "*cmpqi_ccno_1"
535   [(set (reg 17)
536         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
537                  (match_operand:QI 1 "const0_operand" "n,n")))]
538   "ix86_match_ccmode (insn, CCNOmode)"
539   "@
540    test{b}\t{%0, %0|%0, %0}
541    cmp{b}\t{$0, %0|%0, 0}"
542   [(set_attr "type" "test,icmp")
543    (set_attr "length_immediate" "0,1")
544    (set_attr "mode" "QI")])
545
546 (define_insn "*cmpqi_1"
547   [(set (reg 17)
548         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
549                  (match_operand:QI 1 "general_operand" "qi,mq")))]
550   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
551     && ix86_match_ccmode (insn, CCmode)"
552   "cmp{b}\t{%1, %0|%0, %1}"
553   [(set_attr "type" "icmp")
554    (set_attr "mode" "QI")])
555
556 (define_insn "*cmpqi_minus_1"
557   [(set (reg 17)
558         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
559                            (match_operand:QI 1 "general_operand" "qi,mq"))
560                  (const_int 0)))]
561   "ix86_match_ccmode (insn, CCGOCmode)"
562   "cmp{b}\t{%1, %0|%0, %1}"
563   [(set_attr "type" "icmp")
564    (set_attr "mode" "QI")])
565
566 (define_insn "*cmpqi_ext_1"
567   [(set (reg 17)
568         (compare
569           (match_operand:QI 0 "general_operand" "Qm")
570           (subreg:QI
571             (zero_extract:SI
572               (match_operand 1 "ext_register_operand" "Q")
573               (const_int 8)
574               (const_int 8)) 0)))]
575   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
576   "cmp{b}\t{%h1, %0|%0, %h1}"
577   [(set_attr "type" "icmp")
578    (set_attr "mode" "QI")])
579
580 (define_insn "*cmpqi_ext_1_rex64"
581   [(set (reg 17)
582         (compare
583           (match_operand:QI 0 "register_operand" "Q")
584           (subreg:QI
585             (zero_extract:SI
586               (match_operand 1 "ext_register_operand" "Q")
587               (const_int 8)
588               (const_int 8)) 0)))]
589   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
590   "cmp{b}\t{%h1, %0|%0, %h1}"
591   [(set_attr "type" "icmp")
592    (set_attr "mode" "QI")])
593
594 (define_insn "*cmpqi_ext_2"
595   [(set (reg 17)
596         (compare
597           (subreg:QI
598             (zero_extract:SI
599               (match_operand 0 "ext_register_operand" "Q")
600               (const_int 8)
601               (const_int 8)) 0)
602           (match_operand:QI 1 "const0_operand" "n")))]
603   "ix86_match_ccmode (insn, CCNOmode)"
604   "test{b}\t%h0, %h0"
605   [(set_attr "type" "test")
606    (set_attr "length_immediate" "0")
607    (set_attr "mode" "QI")])
608
609 (define_expand "cmpqi_ext_3"
610   [(set (reg:CC 17)
611         (compare:CC
612           (subreg:QI
613             (zero_extract:SI
614               (match_operand 0 "ext_register_operand" "")
615               (const_int 8)
616               (const_int 8)) 0)
617           (match_operand:QI 1 "general_operand" "")))]
618   ""
619   "")
620
621 (define_insn "cmpqi_ext_3_insn"
622   [(set (reg 17)
623         (compare
624           (subreg:QI
625             (zero_extract:SI
626               (match_operand 0 "ext_register_operand" "Q")
627               (const_int 8)
628               (const_int 8)) 0)
629           (match_operand:QI 1 "general_operand" "Qmn")))]
630   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
631   "cmp{b}\t{%1, %h0|%h0, %1}"
632   [(set_attr "type" "icmp")
633    (set_attr "mode" "QI")])
634
635 (define_insn "cmpqi_ext_3_insn_rex64"
636   [(set (reg 17)
637         (compare
638           (subreg:QI
639             (zero_extract:SI
640               (match_operand 0 "ext_register_operand" "Q")
641               (const_int 8)
642               (const_int 8)) 0)
643           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
644   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
645   "cmp{b}\t{%1, %h0|%h0, %1}"
646   [(set_attr "type" "icmp")
647    (set_attr "mode" "QI")])
648
649 (define_insn "*cmpqi_ext_4"
650   [(set (reg 17)
651         (compare
652           (subreg:QI
653             (zero_extract:SI
654               (match_operand 0 "ext_register_operand" "Q")
655               (const_int 8)
656               (const_int 8)) 0)
657           (subreg:QI
658             (zero_extract:SI
659               (match_operand 1 "ext_register_operand" "Q")
660               (const_int 8)
661               (const_int 8)) 0)))]
662   "ix86_match_ccmode (insn, CCmode)"
663   "cmp{b}\t{%h1, %h0|%h0, %h1}"
664   [(set_attr "type" "icmp")
665    (set_attr "mode" "QI")])
666
667 ;; These implement float point compares.
668 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
669 ;; which would allow mix and match FP modes on the compares.  Which is what
670 ;; the old patterns did, but with many more of them.
671
672 (define_expand "cmpxf"
673   [(set (reg:CC 17)
674         (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
675                     (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
676   "!TARGET_64BIT && TARGET_80387"
677 {
678   ix86_compare_op0 = operands[0];
679   ix86_compare_op1 = operands[1];
680   DONE;
681 })
682
683 (define_expand "cmptf"
684   [(set (reg:CC 17)
685         (compare:CC (match_operand:TF 0 "cmp_fp_expander_operand" "")
686                     (match_operand:TF 1 "cmp_fp_expander_operand" "")))]
687   "TARGET_80387"
688 {
689   ix86_compare_op0 = operands[0];
690   ix86_compare_op1 = operands[1];
691   DONE;
692 })
693
694 (define_expand "cmpdf"
695   [(set (reg:CC 17)
696         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
697                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
698   "TARGET_80387 || TARGET_SSE2"
699 {
700   ix86_compare_op0 = operands[0];
701   ix86_compare_op1 = operands[1];
702   DONE;
703 })
704
705 (define_expand "cmpsf"
706   [(set (reg:CC 17)
707         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
708                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
709   "TARGET_80387 || TARGET_SSE"
710 {
711   ix86_compare_op0 = operands[0];
712   ix86_compare_op1 = operands[1];
713   DONE;
714 })
715
716 ;; FP compares, step 1:
717 ;; Set the FP condition codes.
718 ;;
719 ;; CCFPmode     compare with exceptions
720 ;; CCFPUmode    compare with no exceptions
721
722 ;; %%% It is an unfortunate fact that ftst has no non-popping variant,
723 ;; and that fp moves clobber the condition codes, and that there is
724 ;; currently no way to describe this fact to reg-stack.  So there are
725 ;; no splitters yet for this.
726
727 ;; %%% YIKES!  This scheme does not retain a strong connection between 
728 ;; the real compare and the ultimate cc0 user, so CC_REVERSE does not
729 ;; work!  Only allow tos/mem with tos in op 0.
730 ;;
731 ;; Hmm, of course, this is what the actual _hardware_ does.  Perhaps
732 ;; things aren't as bad as they sound...
733
734 (define_insn "*cmpfp_0"
735   [(set (match_operand:HI 0 "register_operand" "=a")
736         (unspec:HI
737           [(compare:CCFP (match_operand 1 "register_operand" "f")
738                          (match_operand 2 "const0_operand" "X"))]
739           UNSPEC_FNSTSW))]
740   "TARGET_80387
741    && FLOAT_MODE_P (GET_MODE (operands[1]))
742    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
743 {
744   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
745     return "ftst\;fnstsw\t%0\;fstp\t%y0";
746   else
747     return "ftst\;fnstsw\t%0";
748 }
749   [(set_attr "type" "multi")
750    (set_attr "mode" "unknownfp")])
751
752 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
753 ;; used to manage the reg stack popping would not be preserved.
754
755 (define_insn "*cmpfp_2_sf"
756   [(set (reg:CCFP 18)
757         (compare:CCFP
758           (match_operand:SF 0 "register_operand" "f")
759           (match_operand:SF 1 "nonimmediate_operand" "fm")))]
760   "TARGET_80387"
761   "* return output_fp_compare (insn, operands, 0, 0);"
762   [(set_attr "type" "fcmp")
763    (set_attr "mode" "SF")])
764
765 (define_insn "*cmpfp_2_sf_1"
766   [(set (match_operand:HI 0 "register_operand" "=a")
767         (unspec:HI
768           [(compare:CCFP
769              (match_operand:SF 1 "register_operand" "f")
770              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
771           UNSPEC_FNSTSW))]
772   "TARGET_80387"
773   "* return output_fp_compare (insn, operands, 2, 0);"
774   [(set_attr "type" "fcmp")
775    (set_attr "mode" "SF")])
776
777 (define_insn "*cmpfp_2_df"
778   [(set (reg:CCFP 18)
779         (compare:CCFP
780           (match_operand:DF 0 "register_operand" "f")
781           (match_operand:DF 1 "nonimmediate_operand" "fm")))]
782   "TARGET_80387"
783   "* return output_fp_compare (insn, operands, 0, 0);"
784   [(set_attr "type" "fcmp")
785    (set_attr "mode" "DF")])
786
787 (define_insn "*cmpfp_2_df_1"
788   [(set (match_operand:HI 0 "register_operand" "=a")
789         (unspec:HI
790           [(compare:CCFP
791              (match_operand:DF 1 "register_operand" "f")
792              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
793           UNSPEC_FNSTSW))]
794   "TARGET_80387"
795   "* return output_fp_compare (insn, operands, 2, 0);"
796   [(set_attr "type" "multi")
797    (set_attr "mode" "DF")])
798
799 (define_insn "*cmpfp_2_xf"
800   [(set (reg:CCFP 18)
801         (compare:CCFP
802           (match_operand:XF 0 "register_operand" "f")
803           (match_operand:XF 1 "register_operand" "f")))]
804   "!TARGET_64BIT && TARGET_80387"
805   "* return output_fp_compare (insn, operands, 0, 0);"
806   [(set_attr "type" "fcmp")
807    (set_attr "mode" "XF")])
808
809 (define_insn "*cmpfp_2_tf"
810   [(set (reg:CCFP 18)
811         (compare:CCFP
812           (match_operand:TF 0 "register_operand" "f")
813           (match_operand:TF 1 "register_operand" "f")))]
814   "TARGET_80387"
815   "* return output_fp_compare (insn, operands, 0, 0);"
816   [(set_attr "type" "fcmp")
817    (set_attr "mode" "XF")])
818
819 (define_insn "*cmpfp_2_xf_1"
820   [(set (match_operand:HI 0 "register_operand" "=a")
821         (unspec:HI
822           [(compare:CCFP
823              (match_operand:XF 1 "register_operand" "f")
824              (match_operand:XF 2 "register_operand" "f"))]
825           UNSPEC_FNSTSW))]
826   "!TARGET_64BIT && TARGET_80387"
827   "* return output_fp_compare (insn, operands, 2, 0);"
828   [(set_attr "type" "multi")
829    (set_attr "mode" "XF")])
830
831 (define_insn "*cmpfp_2_tf_1"
832   [(set (match_operand:HI 0 "register_operand" "=a")
833         (unspec:HI
834           [(compare:CCFP
835              (match_operand:TF 1 "register_operand" "f")
836              (match_operand:TF 2 "register_operand" "f"))]
837           UNSPEC_FNSTSW))]
838   "TARGET_80387"
839   "* return output_fp_compare (insn, operands, 2, 0);"
840   [(set_attr "type" "multi")
841    (set_attr "mode" "XF")])
842
843 (define_insn "*cmpfp_2u"
844   [(set (reg:CCFPU 18)
845         (compare:CCFPU
846           (match_operand 0 "register_operand" "f")
847           (match_operand 1 "register_operand" "f")))]
848   "TARGET_80387
849    && FLOAT_MODE_P (GET_MODE (operands[0]))
850    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
851   "* return output_fp_compare (insn, operands, 0, 1);"
852   [(set_attr "type" "fcmp")
853    (set_attr "mode" "unknownfp")])
854
855 (define_insn "*cmpfp_2u_1"
856   [(set (match_operand:HI 0 "register_operand" "=a")
857         (unspec:HI
858           [(compare:CCFPU
859              (match_operand 1 "register_operand" "f")
860              (match_operand 2 "register_operand" "f"))]
861           UNSPEC_FNSTSW))]
862   "TARGET_80387
863    && FLOAT_MODE_P (GET_MODE (operands[1]))
864    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
865   "* return output_fp_compare (insn, operands, 2, 1);"
866   [(set_attr "type" "multi")
867    (set_attr "mode" "unknownfp")])
868
869 ;; Patterns to match the SImode-in-memory ficom instructions.
870 ;;
871 ;; %%% Play games with accepting gp registers, as otherwise we have to
872 ;; force them to memory during rtl generation, which is no good.  We
873 ;; can get rid of this once we teach reload to do memory input reloads 
874 ;; via pushes.
875
876 (define_insn "*ficom_1"
877   [(set (reg:CCFP 18)
878         (compare:CCFP
879           (match_operand 0 "register_operand" "f,f")
880           (float (match_operand:SI 1 "nonimmediate_operand" "m,?r"))))]
881   "0 && TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[0]))
882    && GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == GET_MODE (operands[0])"
883   "#")
884
885 ;; Split the not-really-implemented gp register case into a
886 ;; push-op-pop sequence.
887 ;;
888 ;; %%% This is most efficient, but am I gonna get in trouble
889 ;; for separating cc0_setter and cc0_user?
890
891 (define_split
892   [(set (reg:CCFP 18)
893         (compare:CCFP
894           (match_operand:SF 0 "register_operand" "")
895           (float (match_operand:SI 1 "register_operand" ""))))]
896   "0 && TARGET_80387 && reload_completed"
897   [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
898    (set (reg:CCFP 18) (compare:CCFP (match_dup 0) (match_dup 2)))
899    (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
900               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
901   "operands[2] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
902    operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);")
903
904 ;; FP compares, step 2
905 ;; Move the fpsw to ax.
906
907 (define_insn "x86_fnstsw_1"
908   [(set (match_operand:HI 0 "register_operand" "=a")
909         (unspec:HI [(reg 18)] UNSPEC_FNSTSW))]
910   "TARGET_80387"
911   "fnstsw\t%0"
912   [(set_attr "length" "2")
913    (set_attr "mode" "SI")
914    (set_attr "unit" "i387")
915    (set_attr "ppro_uops" "few")])
916
917 ;; FP compares, step 3
918 ;; Get ax into flags, general case.
919
920 (define_insn "x86_sahf_1"
921   [(set (reg:CC 17)
922         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
923   "!TARGET_64BIT"
924   "sahf"
925   [(set_attr "length" "1")
926    (set_attr "athlon_decode" "vector")
927    (set_attr "mode" "SI")
928    (set_attr "ppro_uops" "one")])
929
930 ;; Pentium Pro can do steps 1 through 3 in one go.
931
932 (define_insn "*cmpfp_i"
933   [(set (reg:CCFP 17)
934         (compare:CCFP (match_operand 0 "register_operand" "f")
935                       (match_operand 1 "register_operand" "f")))]
936   "TARGET_80387 && TARGET_CMOVE
937    && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
938    && FLOAT_MODE_P (GET_MODE (operands[0]))
939    && GET_MODE (operands[0]) == GET_MODE (operands[0])"
940   "* return output_fp_compare (insn, operands, 1, 0);"
941   [(set_attr "type" "fcmp")
942    (set_attr "mode" "unknownfp")
943    (set_attr "athlon_decode" "vector")])
944
945 (define_insn "*cmpfp_i_sse"
946   [(set (reg:CCFP 17)
947         (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
948                       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
949   "TARGET_80387
950    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
951    && GET_MODE (operands[0]) == GET_MODE (operands[0])"
952   "* return output_fp_compare (insn, operands, 1, 0);"
953   [(set_attr "type" "fcmp,ssecmp")
954    (set_attr "mode" "unknownfp")
955    (set_attr "athlon_decode" "vector")])
956
957 (define_insn "*cmpfp_i_sse_only"
958   [(set (reg:CCFP 17)
959         (compare:CCFP (match_operand 0 "register_operand" "x")
960                       (match_operand 1 "nonimmediate_operand" "xm")))]
961   "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
962    && GET_MODE (operands[0]) == GET_MODE (operands[0])"
963   "* return output_fp_compare (insn, operands, 1, 0);"
964   [(set_attr "type" "ssecmp")
965    (set_attr "mode" "unknownfp")
966    (set_attr "athlon_decode" "vector")])
967
968 (define_insn "*cmpfp_iu"
969   [(set (reg:CCFPU 17)
970         (compare:CCFPU (match_operand 0 "register_operand" "f")
971                        (match_operand 1 "register_operand" "f")))]
972   "TARGET_80387 && TARGET_CMOVE
973    && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
974    && FLOAT_MODE_P (GET_MODE (operands[0]))
975    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
976   "* return output_fp_compare (insn, operands, 1, 1);"
977   [(set_attr "type" "fcmp")
978    (set_attr "mode" "unknownfp")
979    (set_attr "athlon_decode" "vector")])
980
981 (define_insn "*cmpfp_iu_sse"
982   [(set (reg:CCFPU 17)
983         (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
984                        (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
985   "TARGET_80387
986    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
987    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
988   "* return output_fp_compare (insn, operands, 1, 1);"
989   [(set_attr "type" "fcmp,ssecmp")
990    (set_attr "mode" "unknownfp")
991    (set_attr "athlon_decode" "vector")])
992
993 (define_insn "*cmpfp_iu_sse_only"
994   [(set (reg:CCFPU 17)
995         (compare:CCFPU (match_operand 0 "register_operand" "x")
996                        (match_operand 1 "nonimmediate_operand" "xm")))]
997   "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
998    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
999   "* return output_fp_compare (insn, operands, 1, 1);"
1000   [(set_attr "type" "ssecmp")
1001    (set_attr "mode" "unknownfp")
1002    (set_attr "athlon_decode" "vector")])
1003 \f
1004 ;; Move instructions.
1005
1006 ;; General case of fullword move.
1007
1008 (define_expand "movsi"
1009   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1010         (match_operand:SI 1 "general_operand" ""))]
1011   ""
1012   "ix86_expand_move (SImode, operands); DONE;")
1013
1014 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1015 ;; general_operand.
1016 ;;
1017 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1018 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1019 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1020 ;; targets without our curiosities, and it is just as easy to represent
1021 ;; this differently.
1022
1023 (define_insn "*pushsi2"
1024   [(set (match_operand:SI 0 "push_operand" "=<")
1025         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1026   "!TARGET_64BIT"
1027   "push{l}\t%1"
1028   [(set_attr "type" "push")
1029    (set_attr "mode" "SI")])
1030
1031 ;; For 64BIT abi we always round up to 8 bytes.
1032 (define_insn "*pushsi2_rex64"
1033   [(set (match_operand:SI 0 "push_operand" "=X")
1034         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1035   "TARGET_64BIT"
1036   "push{q}\t%q1"
1037   [(set_attr "type" "push")
1038    (set_attr "mode" "SI")])
1039
1040 (define_insn "*pushsi2_prologue"
1041   [(set (match_operand:SI 0 "push_operand" "=<")
1042         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1043    (clobber (mem:BLK (scratch)))]
1044   "!TARGET_64BIT"
1045   "push{l}\t%1"
1046   [(set_attr "type" "push")
1047    (set_attr "mode" "SI")])
1048
1049 (define_insn "*popsi1_epilogue"
1050   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1051         (mem:SI (reg:SI 7)))
1052    (set (reg:SI 7)
1053         (plus:SI (reg:SI 7) (const_int 4)))
1054    (clobber (mem:BLK (scratch)))]
1055   "!TARGET_64BIT"
1056   "pop{l}\t%0"
1057   [(set_attr "type" "pop")
1058    (set_attr "mode" "SI")])
1059
1060 (define_insn "popsi1"
1061   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1062         (mem:SI (reg:SI 7)))
1063    (set (reg:SI 7)
1064         (plus:SI (reg:SI 7) (const_int 4)))]
1065   "!TARGET_64BIT"
1066   "pop{l}\t%0"
1067   [(set_attr "type" "pop")
1068    (set_attr "mode" "SI")])
1069
1070 (define_insn "*movsi_xor"
1071   [(set (match_operand:SI 0 "register_operand" "=r")
1072         (match_operand:SI 1 "const0_operand" "i"))
1073    (clobber (reg:CC 17))]
1074   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1075   "xor{l}\t{%0, %0|%0, %0}"
1076   [(set_attr "type" "alu1")
1077    (set_attr "mode" "SI")
1078    (set_attr "length_immediate" "0")])
1079
1080 (define_insn "*movsi_or"
1081   [(set (match_operand:SI 0 "register_operand" "=r")
1082         (match_operand:SI 1 "immediate_operand" "i"))
1083    (clobber (reg:CC 17))]
1084   "reload_completed && GET_CODE (operands[1]) == CONST_INT
1085    && INTVAL (operands[1]) == -1
1086    && (TARGET_PENTIUM || optimize_size)"
1087 {
1088   operands[1] = constm1_rtx;
1089   return "or{l}\t{%1, %0|%0, %1}";
1090 }
1091   [(set_attr "type" "alu1")
1092    (set_attr "mode" "SI")
1093    (set_attr "length_immediate" "1")])
1094
1095 ; The first alternative is used only to compute proper length of instruction.
1096 ; Reload's algorithm does not take into account the cost of spill instructions
1097 ; needed to free register in given class, so avoid it from choosing the first
1098 ; alternative when eax is not available.
1099
1100 (define_insn "*movsi_1"
1101   [(set (match_operand:SI 0 "nonimmediate_operand" "=*?a,r,*?a,m,!*y,!rm,!*y,!*Y,!rm,!*Y")
1102         (match_operand:SI 1 "general_operand" "im,rinm,rinm,rin,rm,*y,*y,rm,*Y,*Y"))]
1103   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1104 {
1105   switch (get_attr_type (insn))
1106     {
1107     case TYPE_SSEMOV:
1108       if (get_attr_mode (insn) == TImode)
1109         return "movdqa\t{%1, %0|%0, %1}";
1110       return "movd\t{%1, %0|%0, %1}";
1111
1112     case TYPE_MMXMOV:
1113       if (get_attr_mode (insn) == DImode)
1114         return "movq\t{%1, %0|%0, %1}";
1115       return "movd\t{%1, %0|%0, %1}";
1116
1117     case TYPE_LEA:
1118       return "lea{l}\t{%1, %0|%0, %1}";
1119
1120     default:
1121       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1122         abort();
1123       return "mov{l}\t{%1, %0|%0, %1}";
1124     }
1125 }
1126   [(set (attr "type")
1127      (cond [(eq_attr "alternative" "4,5,6")
1128               (const_string "mmxmov")
1129             (eq_attr "alternative" "7,8,9")
1130               (const_string "ssemov")
1131             (and (ne (symbol_ref "flag_pic") (const_int 0))
1132                  (match_operand:SI 1 "symbolic_operand" ""))
1133               (const_string "lea")
1134            ]
1135            (const_string "imov")))
1136    (set_attr "modrm" "0,*,0,*,*,*,*,*,*,*")
1137    (set_attr "mode" "SI,SI,SI,SI,SI,SI,DI,TI,SI,SI")])
1138
1139 ;; Stores and loads of ax to arbitary constant address.
1140 ;; We fake an second form of instruction to force reload to load address
1141 ;; into register when rax is not available
1142 (define_insn "*movabssi_1_rex64"
1143   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
1144         (match_operand:SI 1 "nonmemory_operand" "a,er,i"))]
1145   "TARGET_64BIT"
1146   "@
1147    movabs{l}\t{%1, %P0|%P0, %1}
1148    mov{l}\t{%1, %a0|%a0, %1}
1149    movabs{l}\t{%1, %a0|%a0, %1}"
1150   [(set_attr "type" "imov")
1151    (set_attr "modrm" "0,*,*")
1152    (set_attr "length_address" "8,0,0")
1153    (set_attr "length_immediate" "0,*,*")
1154    (set_attr "memory" "store")
1155    (set_attr "mode" "SI")])
1156
1157 (define_insn "*movabssi_2_rex64"
1158   [(set (match_operand:SI 0 "register_operand" "=a,r")
1159         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1160   "TARGET_64BIT"
1161   "@
1162    movabs{l}\t{%P1, %0|%0, %P1}
1163    mov{l}\t{%a1, %0|%0, %a1}"
1164   [(set_attr "type" "imov")
1165    (set_attr "modrm" "0,*")
1166    (set_attr "length_address" "8,0")
1167    (set_attr "length_immediate" "0")
1168    (set_attr "memory" "load")
1169    (set_attr "mode" "SI")])
1170
1171 (define_insn "*swapsi"
1172   [(set (match_operand:SI 0 "register_operand" "+r")
1173         (match_operand:SI 1 "register_operand" "+r"))
1174    (set (match_dup 1)
1175         (match_dup 0))]
1176   ""
1177   "xchg{l}\t%1, %0"
1178   [(set_attr "type" "imov")
1179    (set_attr "pent_pair" "np")
1180    (set_attr "athlon_decode" "vector")
1181    (set_attr "mode" "SI")
1182    (set_attr "modrm" "0")
1183    (set_attr "ppro_uops" "few")])
1184
1185 (define_expand "movhi"
1186   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1187         (match_operand:HI 1 "general_operand" ""))]
1188   ""
1189   "ix86_expand_move (HImode, operands); DONE;")
1190
1191 (define_insn "*pushhi2"
1192   [(set (match_operand:HI 0 "push_operand" "=<,<")
1193         (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1194   "!TARGET_64BIT"
1195   "@
1196    push{w}\t{|WORD PTR }%1
1197    push{w}\t%1"
1198   [(set_attr "type" "push")
1199    (set_attr "mode" "HI")])
1200
1201 ;; For 64BIT abi we always round up to 8 bytes.
1202 (define_insn "*pushhi2_rex64"
1203   [(set (match_operand:HI 0 "push_operand" "=X")
1204         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1205   "TARGET_64BIT"
1206   "push{q}\t%q1"
1207   [(set_attr "type" "push")
1208    (set_attr "mode" "QI")])
1209
1210 ; The first alternative is used only to compute proper length of instruction.
1211 ; Reload's algorithm does not take into account the cost of spill instructions
1212 ; needed to free register in given class, so avoid it from choosing the first
1213 ; alternative when eax is not available.
1214
1215 (define_insn "*movhi_1"
1216   [(set (match_operand:HI 0 "nonimmediate_operand" "=*?a,r,r,*?a,r,m")
1217         (match_operand:HI 1 "general_operand" "i,r,rn,rm,rm,rn"))]
1218   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1219 {
1220   switch (get_attr_type (insn))
1221     {
1222     case TYPE_IMOVX:
1223       /* movzwl is faster than movw on p2 due to partial word stalls,
1224          though not as fast as an aligned movl.  */
1225       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1226     default:
1227       if (get_attr_mode (insn) == MODE_SI)
1228         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1229       else
1230         return "mov{w}\t{%1, %0|%0, %1}";
1231     }
1232 }
1233   [(set (attr "type")
1234      (cond [(and (eq_attr "alternative" "0,1")
1235                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1236                           (const_int 0))
1237                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1238                           (const_int 0))))
1239               (const_string "imov")
1240             (and (eq_attr "alternative" "2,3,4")
1241                  (match_operand:HI 1 "aligned_operand" ""))
1242               (const_string "imov")
1243             (and (ne (symbol_ref "TARGET_MOVX")
1244                      (const_int 0))
1245                  (eq_attr "alternative" "0,1,3,4"))
1246               (const_string "imovx")
1247            ]
1248            (const_string "imov")))
1249     (set (attr "mode")
1250       (cond [(eq_attr "type" "imovx")
1251                (const_string "SI")
1252              (and (eq_attr "alternative" "2,3,4")
1253                   (match_operand:HI 1 "aligned_operand" ""))
1254                (const_string "SI")
1255              (and (eq_attr "alternative" "0,1")
1256                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1257                            (const_int 0))
1258                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1259                            (const_int 0))))
1260                (const_string "SI")
1261             ]
1262             (const_string "HI")))
1263    (set_attr "modrm" "0,*,*,0,*,*")])
1264
1265 ;; Stores and loads of ax to arbitary constant address.
1266 ;; We fake an second form of instruction to force reload to load address
1267 ;; into register when rax is not available
1268 (define_insn "*movabshi_1_rex64"
1269   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
1270         (match_operand:HI 1 "nonmemory_operand" "a,er,i"))]
1271   "TARGET_64BIT"
1272   "@
1273    movabs{w}\t{%1, %P0|%P0, %1}
1274    mov{w}\t{%1, %a0|%a0, %1}
1275    movabs{w}\t{%1, %a0|%a0, %1}"
1276   [(set_attr "type" "imov")
1277    (set_attr "modrm" "0,*,*")
1278    (set_attr "length_address" "8,0,0")
1279    (set_attr "length_immediate" "0,*,*")
1280    (set_attr "memory" "store")
1281    (set_attr "mode" "HI")])
1282
1283 (define_insn "*movabshi_2_rex64"
1284   [(set (match_operand:HI 0 "register_operand" "=a,r")
1285         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1286   "TARGET_64BIT"
1287   "@
1288    movabs{w}\t{%P1, %0|%0, %P1}
1289    mov{w}\t{%a1, %0|%0, %a1}"
1290   [(set_attr "type" "imov")
1291    (set_attr "modrm" "0,*")
1292    (set_attr "length_address" "8,0")
1293    (set_attr "length_immediate" "0")
1294    (set_attr "memory" "load")
1295    (set_attr "mode" "HI")])
1296
1297 (define_insn "*swaphi_1"
1298   [(set (match_operand:HI 0 "register_operand" "+r")
1299         (match_operand:HI 1 "register_operand" "+r"))
1300    (set (match_dup 1)
1301         (match_dup 0))]
1302   "TARGET_PARTIAL_REG_STALL"
1303   "xchg{w}\t%1, %0"
1304   [(set_attr "type" "imov")
1305    (set_attr "pent_pair" "np")
1306    (set_attr "mode" "HI")
1307    (set_attr "modrm" "0")
1308    (set_attr "ppro_uops" "few")])
1309
1310 (define_insn "*swaphi_2"
1311   [(set (match_operand:HI 0 "register_operand" "+r")
1312         (match_operand:HI 1 "register_operand" "+r"))
1313    (set (match_dup 1)
1314         (match_dup 0))]
1315   "! TARGET_PARTIAL_REG_STALL"
1316   "xchg{l}\t%k1, %k0"
1317   [(set_attr "type" "imov")
1318    (set_attr "pent_pair" "np")
1319    (set_attr "mode" "SI")
1320    (set_attr "modrm" "0")
1321    (set_attr "ppro_uops" "few")])
1322
1323 (define_expand "movstricthi"
1324   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1325         (match_operand:HI 1 "general_operand" ""))]
1326   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1327 {
1328   /* Don't generate memory->memory moves, go through a register */
1329   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1330     operands[1] = force_reg (HImode, operands[1]);
1331 })
1332
1333 (define_insn "*movstricthi_1"
1334   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1335         (match_operand:HI 1 "general_operand" "rn,m"))]
1336   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1337    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1338   "mov{w}\t{%1, %0|%0, %1}"
1339   [(set_attr "type" "imov")
1340    (set_attr "mode" "HI")])
1341
1342 (define_insn "*movstricthi_xor"
1343   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1344         (match_operand:HI 1 "const0_operand" "i"))
1345    (clobber (reg:CC 17))]
1346   "reload_completed
1347    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1348   "xor{w}\t{%0, %0|%0, %0}"
1349   [(set_attr "type" "alu1")
1350    (set_attr "mode" "HI")
1351    (set_attr "length_immediate" "0")])
1352
1353 (define_expand "movqi"
1354   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1355         (match_operand:QI 1 "general_operand" ""))]
1356   ""
1357   "ix86_expand_move (QImode, operands); DONE;")
1358
1359 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1360 ;; "push a byte".  But actually we use pushw, which has the effect
1361 ;; of rounding the amount pushed up to a halfword.
1362
1363 (define_insn "*pushqi2"
1364   [(set (match_operand:QI 0 "push_operand" "=X,X")
1365         (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1366   "!TARGET_64BIT"
1367   "@
1368    push{w}\t{|word ptr }%1
1369    push{w}\t%w1"
1370   [(set_attr "type" "push")
1371    (set_attr "mode" "HI")])
1372
1373 ;; For 64BIT abi we always round up to 8 bytes.
1374 (define_insn "*pushqi2_rex64"
1375   [(set (match_operand:QI 0 "push_operand" "=X")
1376         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1377   "TARGET_64BIT"
1378   "push{q}\t%q1"
1379   [(set_attr "type" "push")
1380    (set_attr "mode" "QI")])
1381
1382 ;; Situation is quite tricky about when to choose full sized (SImode) move
1383 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1384 ;; partial register dependency machines (such as AMD Athlon), where QImode
1385 ;; moves issue extra dependency and for partial register stalls machines
1386 ;; that don't use QImode patterns (and QImode move cause stall on the next
1387 ;; instruction).
1388 ;;
1389 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1390 ;; register stall machines with, where we use QImode instructions, since
1391 ;; partial register stall can be caused there.  Then we use movzx.
1392 (define_insn "*movqi_1"
1393   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1394         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1395   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1396 {
1397   switch (get_attr_type (insn))
1398     {
1399     case TYPE_IMOVX:
1400       if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1401         abort ();
1402       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1403     default:
1404       if (get_attr_mode (insn) == MODE_SI)
1405         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1406       else
1407         return "mov{b}\t{%1, %0|%0, %1}";
1408     }
1409 }
1410   [(set (attr "type")
1411      (cond [(and (eq_attr "alternative" "3")
1412                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1413                           (const_int 0))
1414                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1415                           (const_int 0))))
1416               (const_string "imov")
1417             (eq_attr "alternative" "3,5")
1418               (const_string "imovx")
1419             (and (ne (symbol_ref "TARGET_MOVX")
1420                      (const_int 0))
1421                  (eq_attr "alternative" "2"))
1422               (const_string "imovx")
1423            ]
1424            (const_string "imov")))
1425    (set (attr "mode")
1426       (cond [(eq_attr "alternative" "3,4,5")
1427                (const_string "SI")
1428              (eq_attr "alternative" "6")
1429                (const_string "QI")
1430              (eq_attr "type" "imovx")
1431                (const_string "SI")
1432              (and (eq_attr "type" "imov")
1433                   (and (eq_attr "alternative" "0,1,2")
1434                        (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1435                            (const_int 0))))
1436                (const_string "SI")
1437              ;; Avoid partial register stalls when not using QImode arithmetic
1438              (and (eq_attr "type" "imov")
1439                   (and (eq_attr "alternative" "0,1,2")
1440                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1441                                 (const_int 0))
1442                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1443                                 (const_int 0)))))
1444                (const_string "SI")
1445            ]
1446            (const_string "QI")))])
1447
1448 (define_expand "reload_outqi"
1449   [(parallel [(match_operand:QI 0 "" "=m")
1450               (match_operand:QI 1 "register_operand" "r")
1451               (match_operand:QI 2 "register_operand" "=&q")])]
1452   ""
1453 {
1454   rtx op0, op1, op2;
1455   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1456
1457   if (reg_overlap_mentioned_p (op2, op0))
1458     abort ();
1459   if (! q_regs_operand (op1, QImode))
1460     {
1461       emit_insn (gen_movqi (op2, op1));
1462       op1 = op2;
1463     }
1464   emit_insn (gen_movqi (op0, op1));
1465   DONE;
1466 })
1467
1468 (define_insn "*swapqi"
1469   [(set (match_operand:QI 0 "register_operand" "+r")
1470         (match_operand:QI 1 "register_operand" "+r"))
1471    (set (match_dup 1)
1472         (match_dup 0))]
1473   ""
1474   "xchg{b}\t%1, %0"
1475   [(set_attr "type" "imov")
1476    (set_attr "pent_pair" "np")
1477    (set_attr "mode" "QI")
1478    (set_attr "modrm" "0")
1479    (set_attr "ppro_uops" "few")])
1480
1481 (define_expand "movstrictqi"
1482   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1483         (match_operand:QI 1 "general_operand" ""))]
1484   "! TARGET_PARTIAL_REG_STALL"
1485 {
1486   /* Don't generate memory->memory moves, go through a register.  */
1487   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1488     operands[1] = force_reg (QImode, operands[1]);
1489 })
1490
1491 (define_insn "*movstrictqi_1"
1492   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1493         (match_operand:QI 1 "general_operand" "*qn,m"))]
1494   "! TARGET_PARTIAL_REG_STALL
1495    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1496   "mov{b}\t{%1, %0|%0, %1}"
1497   [(set_attr "type" "imov")
1498    (set_attr "mode" "QI")])
1499
1500 (define_insn "*movstrictqi_xor"
1501   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1502         (match_operand:QI 1 "const0_operand" "i"))
1503    (clobber (reg:CC 17))]
1504   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1505   "xor{b}\t{%0, %0|%0, %0}"
1506   [(set_attr "type" "alu1")
1507    (set_attr "mode" "QI")
1508    (set_attr "length_immediate" "0")])
1509
1510 (define_insn "*movsi_extv_1"
1511   [(set (match_operand:SI 0 "register_operand" "=R")
1512         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1513                          (const_int 8)
1514                          (const_int 8)))]
1515   ""
1516   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1517   [(set_attr "type" "imovx")
1518    (set_attr "mode" "SI")])
1519
1520 (define_insn "*movhi_extv_1"
1521   [(set (match_operand:HI 0 "register_operand" "=R")
1522         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1523                          (const_int 8)
1524                          (const_int 8)))]
1525   ""
1526   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1527   [(set_attr "type" "imovx")
1528    (set_attr "mode" "SI")])
1529
1530 (define_insn "*movqi_extv_1"
1531   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1532         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1533                          (const_int 8)
1534                          (const_int 8)))]
1535   "!TARGET_64BIT"
1536 {
1537   switch (get_attr_type (insn))
1538     {
1539     case TYPE_IMOVX:
1540       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1541     default:
1542       return "mov{b}\t{%h1, %0|%0, %h1}";
1543     }
1544 }
1545   [(set (attr "type")
1546      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1547                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1548                              (ne (symbol_ref "TARGET_MOVX")
1549                                  (const_int 0))))
1550         (const_string "imovx")
1551         (const_string "imov")))
1552    (set (attr "mode")
1553      (if_then_else (eq_attr "type" "imovx")
1554         (const_string "SI")
1555         (const_string "QI")))])
1556
1557 (define_insn "*movqi_extv_1_rex64"
1558   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1559         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1560                          (const_int 8)
1561                          (const_int 8)))]
1562   "TARGET_64BIT"
1563 {
1564   switch (get_attr_type (insn))
1565     {
1566     case TYPE_IMOVX:
1567       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1568     default:
1569       return "mov{b}\t{%h1, %0|%0, %h1}";
1570     }
1571 }
1572   [(set (attr "type")
1573      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1574                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1575                              (ne (symbol_ref "TARGET_MOVX")
1576                                  (const_int 0))))
1577         (const_string "imovx")
1578         (const_string "imov")))
1579    (set (attr "mode")
1580      (if_then_else (eq_attr "type" "imovx")
1581         (const_string "SI")
1582         (const_string "QI")))])
1583
1584 ;; Stores and loads of ax to arbitary constant address.
1585 ;; We fake an second form of instruction to force reload to load address
1586 ;; into register when rax is not available
1587 (define_insn "*movabsqi_1_rex64"
1588   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
1589         (match_operand:QI 1 "nonmemory_operand" "a,er,i"))]
1590   "TARGET_64BIT"
1591   "@
1592    movabs{b}\t{%1, %P0|%P0, %1}
1593    mov{b}\t{%1, %a0|%a0, %1}
1594    movabs{b}\t{%1, %a0|%a0, %1}"
1595   [(set_attr "type" "imov")
1596    (set_attr "modrm" "0,*,*")
1597    (set_attr "length_address" "8,0,0")
1598    (set_attr "length_immediate" "0,*,*")
1599    (set_attr "memory" "store")
1600    (set_attr "mode" "QI")])
1601
1602 (define_insn "*movabsqi_2_rex64"
1603   [(set (match_operand:QI 0 "register_operand" "=a,r")
1604         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1605   "TARGET_64BIT"
1606   "@
1607    movabs{b}\t{%P1, %0|%0, %P1}
1608    mov{b}\t{%a1, %0|%0, %a1}"
1609   [(set_attr "type" "imov")
1610    (set_attr "modrm" "0,*")
1611    (set_attr "length_address" "8,0")
1612    (set_attr "length_immediate" "0")
1613    (set_attr "memory" "load")
1614    (set_attr "mode" "QI")])
1615
1616 (define_insn "*movsi_extzv_1"
1617   [(set (match_operand:SI 0 "register_operand" "=R")
1618         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1619                          (const_int 8)
1620                          (const_int 8)))]
1621   ""
1622   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1623   [(set_attr "type" "imovx")
1624    (set_attr "mode" "SI")])
1625
1626 (define_insn "*movqi_extzv_2"
1627   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1628         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1629                                     (const_int 8)
1630                                     (const_int 8)) 0))]
1631   "!TARGET_64BIT"
1632 {
1633   switch (get_attr_type (insn))
1634     {
1635     case TYPE_IMOVX:
1636       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1637     default:
1638       return "mov{b}\t{%h1, %0|%0, %h1}";
1639     }
1640 }
1641   [(set (attr "type")
1642      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1643                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1644                              (ne (symbol_ref "TARGET_MOVX")
1645                                  (const_int 0))))
1646         (const_string "imovx")
1647         (const_string "imov")))
1648    (set (attr "mode")
1649      (if_then_else (eq_attr "type" "imovx")
1650         (const_string "SI")
1651         (const_string "QI")))])
1652
1653 (define_insn "*movqi_extzv_2_rex64"
1654   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1655         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1656                                     (const_int 8)
1657                                     (const_int 8)) 0))]
1658   "TARGET_64BIT"
1659 {
1660   switch (get_attr_type (insn))
1661     {
1662     case TYPE_IMOVX:
1663       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1664     default:
1665       return "mov{b}\t{%h1, %0|%0, %h1}";
1666     }
1667 }
1668   [(set (attr "type")
1669      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1670                         (ne (symbol_ref "TARGET_MOVX")
1671                             (const_int 0)))
1672         (const_string "imovx")
1673         (const_string "imov")))
1674    (set (attr "mode")
1675      (if_then_else (eq_attr "type" "imovx")
1676         (const_string "SI")
1677         (const_string "QI")))])
1678
1679 (define_insn "movsi_insv_1"
1680   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1681                          (const_int 8)
1682                          (const_int 8))
1683         (match_operand:SI 1 "general_operand" "Qmn"))]
1684   "!TARGET_64BIT"
1685   "mov{b}\t{%b1, %h0|%h0, %b1}"
1686   [(set_attr "type" "imov")
1687    (set_attr "mode" "QI")])
1688
1689 (define_insn "*movsi_insv_1_rex64"
1690   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1691                          (const_int 8)
1692                          (const_int 8))
1693         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1694   "TARGET_64BIT"
1695   "mov{b}\t{%b1, %h0|%h0, %b1}"
1696   [(set_attr "type" "imov")
1697    (set_attr "mode" "QI")])
1698
1699 (define_insn "*movqi_insv_2"
1700   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1701                          (const_int 8)
1702                          (const_int 8))
1703         (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1704                              (const_int 8))
1705                 (const_int 255)))]
1706   ""
1707   "mov{b}\t{%h1, %h0|%h0, %h1}"
1708   [(set_attr "type" "imov")
1709    (set_attr "mode" "QI")])
1710
1711 (define_expand "movdi"
1712   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1713         (match_operand:DI 1 "general_operand" ""))]
1714   ""
1715   "ix86_expand_move (DImode, operands); DONE;")
1716
1717 (define_insn "*pushdi"
1718   [(set (match_operand:DI 0 "push_operand" "=<")
1719         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1720   "!TARGET_64BIT"
1721   "#")
1722
1723 (define_insn "pushdi2_rex64"
1724   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1725         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1726   "TARGET_64BIT"
1727   "@
1728    push{q}\t%1
1729    #"
1730   [(set_attr "type" "push,multi")
1731    (set_attr "mode" "DI")])
1732
1733 ;; Convert impossible pushes of immediate to existing instructions.
1734 ;; First try to get scratch register and go through it.  In case this
1735 ;; fails, push sign extended lower part first and then overwrite
1736 ;; upper part by 32bit move.
1737 (define_peephole2
1738   [(match_scratch:DI 2 "r")
1739    (set (match_operand:DI 0 "push_operand" "")
1740         (match_operand:DI 1 "immediate_operand" ""))]
1741   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1742    && !x86_64_immediate_operand (operands[1], DImode)"
1743   [(set (match_dup 2) (match_dup 1))
1744    (set (match_dup 0) (match_dup 2))]
1745   "")
1746
1747 ;; We need to define this as both peepholer and splitter for case
1748 ;; peephole2 pass is not run.
1749 (define_peephole2
1750   [(set (match_operand:DI 0 "push_operand" "")
1751         (match_operand:DI 1 "immediate_operand" ""))]
1752   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1753    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1754   [(set (match_dup 0) (match_dup 1))
1755    (set (match_dup 2) (match_dup 3))]
1756   "split_di (operands + 1, 1, operands + 2, operands + 3);
1757    operands[1] = gen_lowpart (DImode, operands[2]);
1758    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1759                                                     GEN_INT (4)));
1760   ")
1761
1762 (define_split
1763   [(set (match_operand:DI 0 "push_operand" "")
1764         (match_operand:DI 1 "immediate_operand" ""))]
1765   "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
1766    && !symbolic_operand (operands[1], DImode)
1767    && !x86_64_immediate_operand (operands[1], DImode)"
1768   [(set (match_dup 0) (match_dup 1))
1769    (set (match_dup 2) (match_dup 3))]
1770   "split_di (operands + 1, 1, operands + 2, operands + 3);
1771    operands[1] = gen_lowpart (DImode, operands[2]);
1772    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1773                                                     GEN_INT (4)));
1774   ")
1775
1776 (define_insn "*pushdi2_prologue_rex64"
1777   [(set (match_operand:DI 0 "push_operand" "=<")
1778         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1779    (clobber (mem:BLK (scratch)))]
1780   "TARGET_64BIT"
1781   "push{q}\t%1"
1782   [(set_attr "type" "push")
1783    (set_attr "mode" "DI")])
1784
1785 (define_insn "*popdi1_epilogue_rex64"
1786   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1787         (mem:DI (reg:DI 7)))
1788    (set (reg:DI 7)
1789         (plus:DI (reg:DI 7) (const_int 8)))
1790    (clobber (mem:BLK (scratch)))]
1791   "TARGET_64BIT"
1792   "pop{q}\t%0"
1793   [(set_attr "type" "pop")
1794    (set_attr "mode" "DI")])
1795
1796 (define_insn "popdi1"
1797   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1798         (mem:DI (reg:DI 7)))
1799    (set (reg:DI 7)
1800         (plus:DI (reg:DI 7) (const_int 8)))]
1801   "TARGET_64BIT"
1802   "pop{q}\t%0"
1803   [(set_attr "type" "pop")
1804    (set_attr "mode" "DI")])
1805
1806 (define_insn "*movdi_xor_rex64"
1807   [(set (match_operand:DI 0 "register_operand" "=r")
1808         (match_operand:DI 1 "const0_operand" "i"))
1809    (clobber (reg:CC 17))]
1810   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1811    && reload_completed"
1812   "xor{l}\t{%k0, %k0|%k0, %k0}"
1813   [(set_attr "type" "alu1")
1814    (set_attr "mode" "SI")
1815    (set_attr "length_immediate" "0")])
1816
1817 (define_insn "*movdi_or_rex64"
1818   [(set (match_operand:DI 0 "register_operand" "=r")
1819         (match_operand:DI 1 "const_int_operand" "i"))
1820    (clobber (reg:CC 17))]
1821   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1822    && reload_completed
1823    && GET_CODE (operands[1]) == CONST_INT
1824    && INTVAL (operands[1]) == -1"
1825 {
1826   operands[1] = constm1_rtx;
1827   return "or{q}\t{%1, %0|%0, %1}";
1828 }
1829   [(set_attr "type" "alu1")
1830    (set_attr "mode" "DI")
1831    (set_attr "length_immediate" "1")])
1832
1833 (define_insn "*movdi_2"
1834   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*Y,!*Y")
1835         (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
1836   "!TARGET_64BIT
1837    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1838   "@
1839    #
1840    #
1841    movq\t{%1, %0|%0, %1}
1842    movq\t{%1, %0|%0, %1}
1843    movq\t{%1, %0|%0, %1}
1844    movdqa\t{%1, %0|%0, %1}
1845    movq\t{%1, %0|%0, %1}"
1846   [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov")
1847    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
1848
1849 (define_split
1850   [(set (match_operand:DI 0 "push_operand" "")
1851         (match_operand:DI 1 "general_operand" ""))]
1852   "!TARGET_64BIT && reload_completed
1853    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1854   [(const_int 0)]
1855   "ix86_split_long_move (operands); DONE;")
1856
1857 ;; %%% This multiword shite has got to go.
1858 (define_split
1859   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1860         (match_operand:DI 1 "general_operand" ""))]
1861   "!TARGET_64BIT && reload_completed
1862    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1863    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1864   [(const_int 0)]
1865   "ix86_split_long_move (operands); DONE;")
1866
1867 (define_insn "*movdi_1_rex64"
1868   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!m*y,!*y,!*Y,!m,!*Y")
1869         (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,m,*Y,*Y,*m"))]
1870   "TARGET_64BIT
1871    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1872 {
1873   switch (get_attr_type (insn))
1874     {
1875     case TYPE_SSEMOV:
1876       if (register_operand (operands[0], DImode)
1877           && register_operand (operands[1], DImode))
1878           return "movdqa\t{%1, %0|%0, %1}";
1879       /* FALLTHRU */
1880     case TYPE_MMXMOV:
1881       return "movq\t{%1, %0|%0, %1}";
1882     case TYPE_MULTI:
1883       return "#";
1884     case TYPE_LEA:
1885       return "lea{q}\t{%a1, %0|%0, %a1}";
1886     default:
1887       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1888         abort ();
1889       if (get_attr_mode (insn) == MODE_SI)
1890         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1891       else if (which_alternative == 2)
1892         return "movabs{q}\t{%1, %0|%0, %1}";
1893       else
1894         return "mov{q}\t{%1, %0|%0, %1}";
1895     }
1896 }
1897   [(set (attr "type")
1898      (cond [(eq_attr "alternative" "5,6")
1899               (const_string "mmxmov")
1900             (eq_attr "alternative" "7,8")
1901               (const_string "ssemov")
1902             (eq_attr "alternative" "4")
1903               (const_string "multi")
1904             (and (ne (symbol_ref "flag_pic") (const_int 0))
1905                  (match_operand:DI 1 "symbolic_operand" ""))
1906               (const_string "lea")
1907            ]
1908            (const_string "imov")))
1909    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*")
1910    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*")
1911    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI")])
1912
1913 ;; Stores and loads of ax to arbitary constant address.
1914 ;; We fake an second form of instruction to force reload to load address
1915 ;; into register when rax is not available
1916 (define_insn "*movabsdi_1_rex64"
1917   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
1918         (match_operand:DI 1 "nonmemory_operand" "a,er,i"))]
1919   "TARGET_64BIT"
1920   "@
1921    movabs{q}\t{%1, %P0|%P0, %1}
1922    mov{q}\t{%1, %a0|%a0, %1}
1923    movabs{q}\t{%1, %a0|%a0, %1}"
1924   [(set_attr "type" "imov")
1925    (set_attr "modrm" "0,*,*")
1926    (set_attr "length_address" "8,0,0")
1927    (set_attr "length_immediate" "0,*,*")
1928    (set_attr "memory" "store")
1929    (set_attr "mode" "DI")])
1930
1931 (define_insn "*movabsdi_2_rex64"
1932   [(set (match_operand:DI 0 "register_operand" "=a,r")
1933         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1934   "TARGET_64BIT"
1935   "@
1936    movabs{q}\t{%P1, %0|%0, %P1}
1937    mov{q}\t{%a1, %0|%0, %a1}"
1938   [(set_attr "type" "imov")
1939    (set_attr "modrm" "0,*")
1940    (set_attr "length_address" "8,0")
1941    (set_attr "length_immediate" "0")
1942    (set_attr "memory" "load")
1943    (set_attr "mode" "DI")])
1944
1945 ;; Convert impossible stores of immediate to existing instructions.
1946 ;; First try to get scratch register and go through it.  In case this
1947 ;; fails, move by 32bit parts.
1948 (define_peephole2
1949   [(match_scratch:DI 2 "r")
1950    (set (match_operand:DI 0 "memory_operand" "")
1951         (match_operand:DI 1 "immediate_operand" ""))]
1952   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1953    && !x86_64_immediate_operand (operands[1], DImode)"
1954   [(set (match_dup 2) (match_dup 1))
1955    (set (match_dup 0) (match_dup 2))]
1956   "")
1957
1958 ;; We need to define this as both peepholer and splitter for case
1959 ;; peephole2 pass is not run.
1960 (define_peephole2
1961   [(set (match_operand:DI 0 "memory_operand" "")
1962         (match_operand:DI 1 "immediate_operand" ""))]
1963   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1964    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1965   [(set (match_dup 2) (match_dup 3))
1966    (set (match_dup 4) (match_dup 5))]
1967   "split_di (operands, 2, operands + 2, operands + 4);")
1968
1969 (define_split
1970   [(set (match_operand:DI 0 "memory_operand" "")
1971         (match_operand:DI 1 "immediate_operand" ""))]
1972   "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
1973    && !symbolic_operand (operands[1], DImode)
1974    && !x86_64_immediate_operand (operands[1], DImode)"
1975   [(set (match_dup 2) (match_dup 3))
1976    (set (match_dup 4) (match_dup 5))]
1977   "split_di (operands, 2, operands + 2, operands + 4);")
1978
1979 (define_insn "*swapdi_rex64"
1980   [(set (match_operand:DI 0 "register_operand" "+r")
1981         (match_operand:DI 1 "register_operand" "+r"))
1982    (set (match_dup 1)
1983         (match_dup 0))]
1984   "TARGET_64BIT"
1985   "xchg{q}\t%1, %0"
1986   [(set_attr "type" "imov")
1987    (set_attr "pent_pair" "np")
1988    (set_attr "athlon_decode" "vector")
1989    (set_attr "mode" "DI")
1990    (set_attr "modrm" "0")
1991    (set_attr "ppro_uops" "few")])
1992
1993   
1994 (define_expand "movsf"
1995   [(set (match_operand:SF 0 "nonimmediate_operand" "")
1996         (match_operand:SF 1 "general_operand" ""))]
1997   ""
1998   "ix86_expand_move (SFmode, operands); DONE;")
1999
2000 (define_insn "*pushsf"
2001   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2002         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2003   "!TARGET_64BIT"
2004 {
2005   switch (which_alternative)
2006     {
2007     case 0:
2008       /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
2009       operands[0] = gen_rtx_MEM (SFmode, stack_pointer_rtx);
2010       operands[2] = stack_pointer_rtx;
2011       operands[3] = GEN_INT (4);
2012       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2013         return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
2014       else
2015         return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
2016
2017     case 1:
2018       return "push{l}\t%1";
2019     case 2:
2020       return "#";
2021
2022     default:
2023       abort ();
2024     }
2025 }
2026   [(set_attr "type" "multi,push,multi")
2027    (set_attr "mode" "SF,SI,SF")])
2028
2029 (define_insn "*pushsf_rex64"
2030   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2031         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2032   "TARGET_64BIT"
2033 {
2034   switch (which_alternative)
2035     {
2036     case 0:
2037       /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
2038       operands[0] = gen_rtx_MEM (SFmode, stack_pointer_rtx);
2039       operands[2] = stack_pointer_rtx;
2040       operands[3] = GEN_INT (8);
2041       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2042         return "sub{q}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
2043       else
2044         return "sub{q}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
2045
2046     case 1:
2047       return "push{q}\t%q1";
2048
2049     case 2:
2050       return "#";
2051
2052     default:
2053       abort ();
2054     }
2055 }
2056   [(set_attr "type" "multi,push,multi")
2057    (set_attr "mode" "SF,DI,SF")])
2058
2059 (define_split
2060   [(set (match_operand:SF 0 "push_operand" "")
2061         (match_operand:SF 1 "memory_operand" ""))]
2062   "reload_completed
2063    && GET_CODE (operands[1]) == MEM
2064    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2065    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2066   [(set (match_dup 0)
2067         (match_dup 1))]
2068   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2069
2070
2071 ;; %%% Kill this when call knows how to work this out.
2072 (define_split
2073   [(set (match_operand:SF 0 "push_operand" "")
2074         (match_operand:SF 1 "register_operand" ""))]
2075   "!TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
2076   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
2077    (set (mem:SF (reg:SI 7)) (match_dup 1))])
2078
2079 (define_split
2080   [(set (match_operand:SF 0 "push_operand" "")
2081         (match_operand:SF 1 "register_operand" ""))]
2082   "TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
2083   [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2084    (set (mem:SF (reg:DI 7)) (match_dup 1))])
2085
2086 (define_insn "*movsf_1"
2087   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m,!*y,!rm,!*y")
2088         (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,H,x,xm#rf,x#rf,rm,*y,*y"))]
2089   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2090    && (reload_in_progress || reload_completed
2091        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2092        || GET_CODE (operands[1]) != CONST_DOUBLE
2093        || memory_operand (operands[0], SFmode))" 
2094 {
2095   switch (which_alternative)
2096     {
2097     case 0:
2098       if (REG_P (operands[1])
2099           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2100         return "fstp\t%y0";
2101       else if (STACK_TOP_P (operands[0]))
2102         return "fld%z1\t%y1";
2103       else
2104         return "fst\t%y0";
2105
2106     case 1:
2107       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2108         return "fstp%z0\t%y0";
2109       else
2110         return "fst%z0\t%y0";
2111
2112     case 2:
2113       switch (standard_80387_constant_p (operands[1]))
2114         {
2115         case 1:
2116           return "fldz";
2117         case 2:
2118           return "fld1";
2119         }
2120       abort();
2121
2122     case 3:
2123     case 4:
2124       return "mov{l}\t{%1, %0|%0, %1}";
2125     case 5:
2126       if (TARGET_SSE2)
2127         return "pxor\t%0, %0";
2128       else
2129         return "xorps\t%0, %0";
2130     case 6:
2131       if (TARGET_PARTIAL_REG_DEPENDENCY)
2132         return "movaps\t{%1, %0|%0, %1}";
2133       else
2134         return "movss\t{%1, %0|%0, %1}";
2135     case 7:
2136     case 8:
2137       return "movss\t{%1, %0|%0, %1}";
2138
2139     case 9:
2140     case 10:
2141       return "movd\t{%1, %0|%0, %1}";
2142
2143     case 11:
2144       return "movq\t{%1, %0|%0, %1}";
2145
2146     default:
2147       abort();
2148     }
2149 }
2150   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2151    (set_attr "mode" "SF,SF,SF,SI,SI,TI,SF,SF,SF,SI,SI,DI")])
2152
2153 (define_insn "*swapsf"
2154   [(set (match_operand:SF 0 "register_operand" "+f")
2155         (match_operand:SF 1 "register_operand" "+f"))
2156    (set (match_dup 1)
2157         (match_dup 0))]
2158   "reload_completed || !TARGET_SSE"
2159 {
2160   if (STACK_TOP_P (operands[0]))
2161     return "fxch\t%1";
2162   else
2163     return "fxch\t%0";
2164 }
2165   [(set_attr "type" "fxch")
2166    (set_attr "mode" "SF")])
2167
2168 (define_expand "movdf"
2169   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2170         (match_operand:DF 1 "general_operand" ""))]
2171   ""
2172   "ix86_expand_move (DFmode, operands); DONE;")
2173
2174 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2175 ;; Size of pushdf using integer insturctions is 2+2*memory operand size
2176 ;; On the average, pushdf using integers can be still shorter.  Allow this
2177 ;; pattern for optimize_size too.
2178
2179 (define_insn "*pushdf_nointeger"
2180   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2181         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2182   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2183 {
2184   switch (which_alternative)
2185     {
2186     case 0:
2187       /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
2188       operands[0] = gen_rtx_MEM (DFmode, stack_pointer_rtx);
2189       operands[2] = stack_pointer_rtx;
2190       operands[3] = GEN_INT (8);
2191       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2192         return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
2193       else
2194         return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
2195
2196     case 1:
2197     case 2:
2198     case 3:
2199       return "#";
2200
2201     default:
2202       abort ();
2203     }
2204 }
2205   [(set_attr "type" "multi")
2206    (set_attr "mode" "DF,SI,SI,DF")])
2207
2208 (define_insn "*pushdf_integer"
2209   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2210         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2211   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2212 {
2213   switch (which_alternative)
2214     {
2215     case 0:
2216       /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
2217       operands[0] = gen_rtx_MEM (DFmode, stack_pointer_rtx);
2218       operands[2] = stack_pointer_rtx;
2219       operands[3] = GEN_INT (8);
2220       if (TARGET_64BIT)
2221         if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2222           return "sub{q}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
2223         else
2224           return "sub{q}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
2225       else
2226         if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2227           return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
2228         else
2229           return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
2230
2231
2232     case 1:
2233     case 2:
2234       return "#";
2235
2236     default:
2237       abort ();
2238     }
2239 }
2240   [(set_attr "type" "multi")
2241    (set_attr "mode" "DF,SI,DF")])
2242
2243 ;; %%% Kill this when call knows how to work this out.
2244 (define_split
2245   [(set (match_operand:DF 0 "push_operand" "")
2246         (match_operand:DF 1 "register_operand" ""))]
2247   "!TARGET_64BIT && reload_completed && ANY_FP_REGNO_P (REGNO (operands[1]))"
2248   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
2249    (set (mem:DF (reg:SI 7)) (match_dup 1))]
2250   "")
2251
2252 (define_split
2253   [(set (match_operand:DF 0 "push_operand" "")
2254         (match_operand:DF 1 "register_operand" ""))]
2255   "TARGET_64BIT && reload_completed && ANY_FP_REGNO_P (REGNO (operands[1]))"
2256   [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2257    (set (mem:DF (reg:DI 7)) (match_dup 1))]
2258   "")
2259
2260 (define_split
2261   [(set (match_operand:DF 0 "push_operand" "")
2262         (match_operand:DF 1 "general_operand" ""))]
2263   "reload_completed"
2264   [(const_int 0)]
2265   "ix86_split_long_move (operands); DONE;")
2266
2267 ;; Moving is usually shorter when only FP registers are used. This separate
2268 ;; movdf pattern avoids the use of integer registers for FP operations
2269 ;; when optimizing for size.
2270
2271 (define_insn "*movdf_nointeger"
2272   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2273         (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,H,Y#f,YHm#f,Y#f"))]
2274   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2275    && (optimize_size || !TARGET_INTEGER_DFMODE_MOVES)
2276    && (reload_in_progress || reload_completed
2277        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2278        || GET_CODE (operands[1]) != CONST_DOUBLE
2279        || memory_operand (operands[0], DFmode))" 
2280 {
2281   switch (which_alternative)
2282     {
2283     case 0:
2284       if (REG_P (operands[1])
2285           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2286         return "fstp\t%y0";
2287       else if (STACK_TOP_P (operands[0]))
2288         return "fld%z1\t%y1";
2289       else
2290         return "fst\t%y0";
2291
2292     case 1:
2293       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2294         return "fstp%z0\t%y0";
2295       else
2296         return "fst%z0\t%y0";
2297
2298     case 2:
2299       switch (standard_80387_constant_p (operands[1]))
2300         {
2301         case 1:
2302           return "fldz";
2303         case 2:
2304           return "fld1";
2305         }
2306       abort();
2307
2308     case 3:
2309     case 4:
2310       return "#";
2311     case 5:
2312       return "pxor\t%0, %0";
2313     case 6:
2314       if (TARGET_PARTIAL_REG_DEPENDENCY)
2315         return "movapd\t{%1, %0|%0, %1}";
2316       else
2317         return "movsd\t{%1, %0|%0, %1}";
2318     case 7:
2319     case 8:
2320         return "movsd\t{%1, %0|%0, %1}";
2321
2322     default:
2323       abort();
2324     }
2325 }
2326   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2327    (set_attr "mode" "DF,DF,DF,SI,SI,TI,DF,DF,DF")])
2328
2329 (define_insn "*movdf_integer"
2330   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2331         (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,H,Y#rf,Ym#rf,Y#rf"))]
2332   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2333    && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2334    && (reload_in_progress || reload_completed
2335        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2336        || GET_CODE (operands[1]) != CONST_DOUBLE
2337        || memory_operand (operands[0], DFmode))" 
2338 {
2339   switch (which_alternative)
2340     {
2341     case 0:
2342       if (REG_P (operands[1])
2343           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2344         return "fstp\t%y0";
2345       else if (STACK_TOP_P (operands[0]))
2346         return "fld%z1\t%y1";
2347       else
2348         return "fst\t%y0";
2349
2350     case 1:
2351       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2352         return "fstp%z0\t%y0";
2353       else
2354         return "fst%z0\t%y0";
2355
2356     case 2:
2357       switch (standard_80387_constant_p (operands[1]))
2358         {
2359         case 1:
2360           return "fldz";
2361         case 2:
2362           return "fld1";
2363         }
2364       abort();
2365
2366     case 3:
2367     case 4:
2368       return "#";
2369
2370     case 5:
2371       return "pxor\t%0, %0";
2372     case 6:
2373       if (TARGET_PARTIAL_REG_DEPENDENCY)
2374         return "movapd\t{%1, %0|%0, %1}";
2375       else
2376         return "movsd\t{%1, %0|%0, %1}";
2377     case 7:
2378     case 8:
2379       return "movsd\t{%1, %0|%0, %1}";
2380
2381     default:
2382       abort();
2383     }
2384 }
2385   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2386    (set_attr "mode" "DF,DF,DF,SI,SI,TI,DF,DF,DF")])
2387
2388 (define_split
2389   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2390         (match_operand:DF 1 "general_operand" ""))]
2391   "reload_completed
2392    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2393    && ! (ANY_FP_REG_P (operands[0]) || 
2394          (GET_CODE (operands[0]) == SUBREG
2395           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2396    && ! (ANY_FP_REG_P (operands[1]) || 
2397          (GET_CODE (operands[1]) == SUBREG
2398           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2399   [(const_int 0)]
2400   "ix86_split_long_move (operands); DONE;")
2401
2402 (define_insn "*swapdf"
2403   [(set (match_operand:DF 0 "register_operand" "+f")
2404         (match_operand:DF 1 "register_operand" "+f"))
2405    (set (match_dup 1)
2406         (match_dup 0))]
2407   "reload_completed || !TARGET_SSE2"
2408 {
2409   if (STACK_TOP_P (operands[0]))
2410     return "fxch\t%1";
2411   else
2412     return "fxch\t%0";
2413 }
2414   [(set_attr "type" "fxch")
2415    (set_attr "mode" "DF")])
2416
2417 (define_expand "movxf"
2418   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2419         (match_operand:XF 1 "general_operand" ""))]
2420   "!TARGET_64BIT"
2421   "ix86_expand_move (XFmode, operands); DONE;")
2422
2423 (define_expand "movtf"
2424   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2425         (match_operand:TF 1 "general_operand" ""))]
2426   ""
2427   "ix86_expand_move (TFmode, operands); DONE;")
2428
2429 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2430 ;; Size of pushdf using integer insturctions is 3+3*memory operand size
2431 ;; Pushing using integer instructions is longer except for constants
2432 ;; and direct memory references.
2433 ;; (assuming that any given constant is pushed only once, but this ought to be
2434 ;;  handled elsewhere).
2435
2436 (define_insn "*pushxf_nointeger"
2437   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2438         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2439   "!TARGET_64BIT && optimize_size"
2440 {
2441   switch (which_alternative)
2442     {
2443     case 0:
2444       /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
2445       operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
2446       operands[2] = stack_pointer_rtx;
2447       operands[3] = GEN_INT (12);
2448       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2449         return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
2450       else
2451         return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
2452
2453     case 1:
2454     case 2:
2455       return "#";
2456
2457     default:
2458       abort ();
2459     }
2460 }
2461   [(set_attr "type" "multi")
2462    (set_attr "mode" "XF,SI,SI")])
2463
2464 (define_insn "*pushtf_nointeger"
2465   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2466         (match_operand:TF 1 "general_no_elim_operand" "f,Fo,*r"))]
2467   "optimize_size"
2468 {
2469   switch (which_alternative)
2470     {
2471     case 0:
2472       /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
2473       operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
2474       operands[2] = stack_pointer_rtx;
2475       operands[3] = GEN_INT (16);
2476       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2477         return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
2478       else
2479         return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
2480
2481     case 1:
2482     case 2:
2483       return "#";
2484
2485     default:
2486       abort ();
2487     }
2488 }
2489   [(set_attr "type" "multi")
2490    (set_attr "mode" "XF,SI,SI")])
2491
2492 (define_insn "*pushxf_integer"
2493   [(set (match_operand:XF 0 "push_operand" "=<,<")
2494         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2495   "!TARGET_64BIT && !optimize_size"
2496 {
2497   switch (which_alternative)
2498     {
2499     case 0:
2500       /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
2501       operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
2502       operands[2] = stack_pointer_rtx;
2503       operands[3] = GEN_INT (12);
2504       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2505         return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
2506       else
2507         return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
2508
2509     case 1:
2510       return "#";
2511
2512     default:
2513       abort ();
2514     }
2515 }
2516   [(set_attr "type" "multi")
2517    (set_attr "mode" "XF,SI")])
2518
2519 (define_insn "*pushtf_integer"
2520   [(set (match_operand:TF 0 "push_operand" "=<,<")
2521         (match_operand:TF 1 "general_no_elim_operand" "f#r,rFo#f"))]
2522   "!optimize_size"
2523 {
2524   switch (which_alternative)
2525     {
2526     case 0:
2527       /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
2528       operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
2529       operands[2] = stack_pointer_rtx;
2530       operands[3] = GEN_INT (16);
2531       if (TARGET_64BIT)
2532         if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2533           return "sub{q}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
2534         else
2535           return "sub{q}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
2536       else
2537         if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2538           return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
2539         else
2540           return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
2541
2542     case 1:
2543       return "#";
2544
2545     default:
2546       abort ();
2547     }
2548 }
2549   [(set_attr "type" "multi")
2550    (set_attr "mode" "XF,SI")])
2551
2552 (define_split
2553   [(set (match_operand 0 "push_operand" "")
2554         (match_operand 1 "general_operand" ""))]
2555   "reload_completed
2556    && (GET_MODE (operands[0]) == XFmode
2557        || GET_MODE (operands[0]) == TFmode
2558        || GET_MODE (operands[0]) == DFmode)
2559    && (!REG_P (operands[1]) || !ANY_FP_REGNO_P (REGNO (operands[1])))"
2560   [(const_int 0)]
2561   "ix86_split_long_move (operands); DONE;")
2562
2563 (define_split
2564   [(set (match_operand:XF 0 "push_operand" "")
2565         (match_operand:XF 1 "register_operand" ""))]
2566   "!TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
2567   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
2568    (set (mem:XF (reg:SI 7)) (match_dup 1))])
2569
2570 (define_split
2571   [(set (match_operand:TF 0 "push_operand" "")
2572         (match_operand:TF 1 "register_operand" ""))]
2573   "!TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
2574   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
2575    (set (mem:TF (reg:SI 7)) (match_dup 1))])
2576
2577 (define_split
2578   [(set (match_operand:TF 0 "push_operand" "")
2579         (match_operand:TF 1 "register_operand" ""))]
2580   "TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
2581   [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
2582    (set (mem:TF (reg:DI 7)) (match_dup 1))])
2583
2584 ;; Do not use integer registers when optimizing for size
2585 (define_insn "*movxf_nointeger"
2586   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2587         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2588   "!TARGET_64BIT
2589    && optimize_size
2590    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2591    && (reload_in_progress || reload_completed
2592        || GET_CODE (operands[1]) != CONST_DOUBLE
2593        || memory_operand (operands[0], XFmode))" 
2594 {
2595   switch (which_alternative)
2596     {
2597     case 0:
2598       if (REG_P (operands[1])
2599           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2600         return "fstp\t%y0";
2601       else if (STACK_TOP_P (operands[0]))
2602         return "fld%z1\t%y1";
2603       else
2604         return "fst\t%y0";
2605
2606     case 1:
2607       /* There is no non-popping store to memory for XFmode.  So if
2608          we need one, follow the store with a load.  */
2609       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2610         return "fstp%z0\t%y0\;fld%z0\t%y0";
2611       else
2612         return "fstp%z0\t%y0";
2613
2614     case 2:
2615       switch (standard_80387_constant_p (operands[1]))
2616         {
2617         case 1:
2618           return "fldz";
2619         case 2:
2620           return "fld1";
2621         }
2622       break;
2623
2624     case 3: case 4:
2625       return "#";
2626     }
2627   abort();
2628 }
2629   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2630    (set_attr "mode" "XF,XF,XF,SI,SI")])
2631
2632 (define_insn "*movtf_nointeger"
2633   [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2634         (match_operand:TF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2635   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2636    && optimize_size
2637    && (reload_in_progress || reload_completed
2638        || GET_CODE (operands[1]) != CONST_DOUBLE
2639        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2640        || memory_operand (operands[0], TFmode))" 
2641 {
2642   switch (which_alternative)
2643     {
2644     case 0:
2645       if (REG_P (operands[1])
2646           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2647         return "fstp\t%y0";
2648       else if (STACK_TOP_P (operands[0]))
2649         return "fld%z1\t%y1";
2650       else
2651         return "fst\t%y0";
2652
2653     case 1:
2654       /* There is no non-popping store to memory for XFmode.  So if
2655          we need one, follow the store with a load.  */
2656       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2657         return "fstp%z0\t%y0\;fld%z0\t%y0";
2658       else
2659         return "fstp%z0\t%y0";
2660
2661     case 2:
2662       switch (standard_80387_constant_p (operands[1]))
2663         {
2664         case 1:
2665           return "fldz";
2666         case 2:
2667           return "fld1";
2668         }
2669       break;
2670
2671     case 3: case 4:
2672       return "#";
2673     }
2674   abort();
2675 }
2676   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2677    (set_attr "mode" "XF,XF,XF,SI,SI")])
2678
2679 (define_insn "*movxf_integer"
2680   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2681         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2682   "!TARGET_64BIT
2683    && !optimize_size
2684    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2685    && (reload_in_progress || reload_completed
2686        || GET_CODE (operands[1]) != CONST_DOUBLE
2687        || memory_operand (operands[0], XFmode))" 
2688 {
2689   switch (which_alternative)
2690     {
2691     case 0:
2692       if (REG_P (operands[1])
2693           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2694         return "fstp\t%y0";
2695       else if (STACK_TOP_P (operands[0]))
2696         return "fld%z1\t%y1";
2697       else
2698         return "fst\t%y0";
2699
2700     case 1:
2701       /* There is no non-popping store to memory for XFmode.  So if
2702          we need one, follow the store with a load.  */
2703       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2704         return "fstp%z0\t%y0\;fld%z0\t%y0";
2705       else
2706         return "fstp%z0\t%y0";
2707
2708     case 2:
2709       switch (standard_80387_constant_p (operands[1]))
2710         {
2711         case 1:
2712           return "fldz";
2713         case 2:
2714           return "fld1";
2715         }
2716       break;
2717
2718     case 3: case 4:
2719       return "#";
2720     }
2721   abort();
2722 }
2723   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2724    (set_attr "mode" "XF,XF,XF,SI,SI")])
2725
2726 (define_insn "*movtf_integer"
2727   [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2728         (match_operand:TF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2729   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2730    && !optimize_size
2731    && (reload_in_progress || reload_completed
2732        || GET_CODE (operands[1]) != CONST_DOUBLE
2733        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2734        || memory_operand (operands[0], TFmode))" 
2735 {
2736   switch (which_alternative)
2737     {
2738     case 0:
2739       if (REG_P (operands[1])
2740           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2741         return "fstp\t%y0";
2742       else if (STACK_TOP_P (operands[0]))
2743         return "fld%z1\t%y1";
2744       else
2745         return "fst\t%y0";
2746
2747     case 1:
2748       /* There is no non-popping store to memory for XFmode.  So if
2749          we need one, follow the store with a load.  */
2750       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2751         return "fstp%z0\t%y0\;fld%z0\t%y0";
2752       else
2753         return "fstp%z0\t%y0";
2754
2755     case 2:
2756       switch (standard_80387_constant_p (operands[1]))
2757         {
2758         case 1:
2759           return "fldz";
2760         case 2:
2761           return "fld1";
2762         }
2763       break;
2764
2765     case 3: case 4:
2766       return "#";
2767     }
2768   abort();
2769 }
2770   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2771    (set_attr "mode" "XF,XF,XF,SI,SI")])
2772
2773 (define_split
2774   [(set (match_operand 0 "nonimmediate_operand" "")
2775         (match_operand 1 "general_operand" ""))]
2776   "reload_completed
2777    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2778    && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode)
2779    && ! (ANY_FP_REG_P (operands[0]) || 
2780          (GET_CODE (operands[0]) == SUBREG
2781           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2782    && ! (ANY_FP_REG_P (operands[1]) || 
2783          (GET_CODE (operands[1]) == SUBREG
2784           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2785   [(const_int 0)]
2786   "ix86_split_long_move (operands); DONE;")
2787
2788 (define_split
2789   [(set (match_operand 0 "register_operand" "")
2790         (match_operand 1 "memory_operand" ""))]
2791   "reload_completed
2792    && GET_CODE (operands[1]) == MEM
2793    && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode
2794        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2795    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2796    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
2797    && (!(SSE_REG_P (operands[0]) || 
2798          (GET_CODE (operands[0]) == SUBREG
2799           && SSE_REG_P (SUBREG_REG (operands[0]))))
2800        || standard_sse_constant_p (get_pool_constant (XEXP (operands[1], 0))))
2801    && (!(FP_REG_P (operands[0]) || 
2802          (GET_CODE (operands[0]) == SUBREG
2803           && FP_REG_P (SUBREG_REG (operands[0]))))
2804        || standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0))))"
2805   [(set (match_dup 0)
2806         (match_dup 1))]
2807   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2808
2809 (define_insn "swapxf"
2810   [(set (match_operand:XF 0 "register_operand" "+f")
2811         (match_operand:XF 1 "register_operand" "+f"))
2812    (set (match_dup 1)
2813         (match_dup 0))]
2814   ""
2815 {
2816   if (STACK_TOP_P (operands[0]))
2817     return "fxch\t%1";
2818   else
2819     return "fxch\t%0";
2820 }
2821   [(set_attr "type" "fxch")
2822    (set_attr "mode" "XF")])
2823
2824 (define_insn "swaptf"
2825   [(set (match_operand:TF 0 "register_operand" "+f")
2826         (match_operand:TF 1 "register_operand" "+f"))
2827    (set (match_dup 1)
2828         (match_dup 0))]
2829   ""
2830 {
2831   if (STACK_TOP_P (operands[0]))
2832     return "fxch\t%1";
2833   else
2834     return "fxch\t%0";
2835 }
2836   [(set_attr "type" "fxch")
2837    (set_attr "mode" "XF")])
2838 \f
2839 ;; Zero extension instructions
2840
2841 (define_expand "zero_extendhisi2"
2842   [(set (match_operand:SI 0 "register_operand" "")
2843      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2844   ""
2845 {
2846   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2847     {
2848       operands[1] = force_reg (HImode, operands[1]);
2849       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2850       DONE;
2851     }
2852 })
2853
2854 (define_insn "zero_extendhisi2_and"
2855   [(set (match_operand:SI 0 "register_operand" "=r")
2856      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2857    (clobber (reg:CC 17))]
2858   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2859   "#"
2860   [(set_attr "type" "alu1")
2861    (set_attr "mode" "SI")])
2862
2863 (define_split
2864   [(set (match_operand:SI 0 "register_operand" "")
2865         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2866    (clobber (reg:CC 17))]
2867   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2868   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2869               (clobber (reg:CC 17))])]
2870   "")
2871
2872 (define_insn "*zero_extendhisi2_movzwl"
2873   [(set (match_operand:SI 0 "register_operand" "=r")
2874      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2875   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2876   "movz{wl|x}\t{%1, %0|%0, %1}"
2877   [(set_attr "type" "imovx")
2878    (set_attr "mode" "SI")])
2879
2880 (define_expand "zero_extendqihi2"
2881   [(parallel
2882     [(set (match_operand:HI 0 "register_operand" "")
2883        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2884      (clobber (reg:CC 17))])]
2885   ""
2886   "")
2887
2888 (define_insn "*zero_extendqihi2_and"
2889   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2890      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2891    (clobber (reg:CC 17))]
2892   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2893   "#"
2894   [(set_attr "type" "alu1")
2895    (set_attr "mode" "HI")])
2896
2897 (define_insn "*zero_extendqihi2_movzbw_and"
2898   [(set (match_operand:HI 0 "register_operand" "=r,r")
2899      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2900    (clobber (reg:CC 17))]
2901   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2902   "#"
2903   [(set_attr "type" "imovx,alu1")
2904    (set_attr "mode" "HI")])
2905
2906 (define_insn "*zero_extendqihi2_movzbw"
2907   [(set (match_operand:HI 0 "register_operand" "=r")
2908      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2909   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
2910   "movz{bw|x}\t{%1, %0|%0, %1}"
2911   [(set_attr "type" "imovx")
2912    (set_attr "mode" "HI")])
2913
2914 ;; For the movzbw case strip only the clobber
2915 (define_split
2916   [(set (match_operand:HI 0 "register_operand" "")
2917         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2918    (clobber (reg:CC 17))]
2919   "reload_completed 
2920    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
2921    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
2922   [(set (match_operand:HI 0 "register_operand" "")
2923         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
2924
2925 ;; When source and destination does not overlap, clear destination
2926 ;; first and then do the movb
2927 (define_split
2928   [(set (match_operand:HI 0 "register_operand" "")
2929         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2930    (clobber (reg:CC 17))]
2931   "reload_completed
2932    && ANY_QI_REG_P (operands[0])
2933    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2934    && !reg_overlap_mentioned_p (operands[0], operands[1])"
2935   [(set (match_dup 0) (const_int 0))
2936    (set (strict_low_part (match_dup 2)) (match_dup 1))]
2937   "operands[2] = gen_lowpart (QImode, operands[0]);")
2938
2939 ;; Rest is handled by single and.
2940 (define_split
2941   [(set (match_operand:HI 0 "register_operand" "")
2942         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
2943    (clobber (reg:CC 17))]
2944   "reload_completed
2945    && true_regnum (operands[0]) == true_regnum (operands[1])"
2946   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
2947               (clobber (reg:CC 17))])]
2948   "")
2949
2950 (define_expand "zero_extendqisi2"
2951   [(parallel
2952     [(set (match_operand:SI 0 "register_operand" "")
2953        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
2954      (clobber (reg:CC 17))])]
2955   ""
2956   "")
2957
2958 (define_insn "*zero_extendqisi2_and"
2959   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
2960      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2961    (clobber (reg:CC 17))]
2962   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2963   "#"
2964   [(set_attr "type" "alu1")
2965    (set_attr "mode" "SI")])
2966
2967 (define_insn "*zero_extendqisi2_movzbw_and"
2968   [(set (match_operand:SI 0 "register_operand" "=r,r")
2969      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2970    (clobber (reg:CC 17))]
2971   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2972   "#"
2973   [(set_attr "type" "imovx,alu1")
2974    (set_attr "mode" "SI")])
2975
2976 (define_insn "*zero_extendqisi2_movzbw"
2977   [(set (match_operand:SI 0 "register_operand" "=r")
2978      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2979   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
2980   "movz{bl|x}\t{%1, %0|%0, %1}"
2981   [(set_attr "type" "imovx")
2982    (set_attr "mode" "SI")])
2983
2984 ;; For the movzbl case strip only the clobber
2985 (define_split
2986   [(set (match_operand:SI 0 "register_operand" "")
2987         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
2988    (clobber (reg:CC 17))]
2989   "reload_completed 
2990    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
2991    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
2992   [(set (match_dup 0)
2993         (zero_extend:SI (match_dup 1)))])
2994
2995 ;; When source and destination does not overlap, clear destination
2996 ;; first and then do the movb
2997 (define_split
2998   [(set (match_operand:SI 0 "register_operand" "")
2999         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3000    (clobber (reg:CC 17))]
3001   "reload_completed
3002    && ANY_QI_REG_P (operands[0])
3003    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3004    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3005    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3006   [(set (match_dup 0) (const_int 0))
3007    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3008   "operands[2] = gen_lowpart (QImode, operands[0]);")
3009
3010 ;; Rest is handled by single and.
3011 (define_split
3012   [(set (match_operand:SI 0 "register_operand" "")
3013         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3014    (clobber (reg:CC 17))]
3015   "reload_completed
3016    && true_regnum (operands[0]) == true_regnum (operands[1])"
3017   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3018               (clobber (reg:CC 17))])]
3019   "")
3020
3021 ;; %%% Kill me once multi-word ops are sane.
3022 (define_expand "zero_extendsidi2"
3023   [(set (match_operand:DI 0 "register_operand" "=r")
3024      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3025   ""
3026   "if (!TARGET_64BIT)
3027      {
3028        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3029        DONE;
3030      }
3031   ")
3032
3033 (define_insn "zero_extendsidi2_32"
3034   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o")
3035         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r")))
3036    (clobber (reg:CC 17))]
3037   "!TARGET_64BIT"
3038   "#"
3039   [(set_attr "mode" "SI")])
3040
3041 (define_insn "zero_extendsidi2_rex64"
3042   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
3043      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0")))]
3044   "TARGET_64BIT"
3045   "@
3046    mov\t{%k1, %k0|%k0, %k1}
3047    #"
3048   [(set_attr "type" "imovx,imov")
3049    (set_attr "mode" "SI,DI")])
3050
3051 (define_split
3052   [(set (match_operand:DI 0 "memory_operand" "")
3053      (zero_extend:DI (match_dup 0)))]
3054   "TARGET_64BIT"
3055   [(set (match_dup 4) (const_int 0))]
3056   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3057
3058 (define_split 
3059   [(set (match_operand:DI 0 "register_operand" "")
3060         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3061    (clobber (reg:CC 17))]
3062   "!TARGET_64BIT && reload_completed
3063    && true_regnum (operands[0]) == true_regnum (operands[1])"
3064   [(set (match_dup 4) (const_int 0))]
3065   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3066
3067 (define_split 
3068   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3069         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3070    (clobber (reg:CC 17))]
3071   "!TARGET_64BIT && reload_completed"
3072   [(set (match_dup 3) (match_dup 1))
3073    (set (match_dup 4) (const_int 0))]
3074   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3075
3076 (define_insn "zero_extendhidi2"
3077   [(set (match_operand:DI 0 "register_operand" "=r,r")
3078      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3079   "TARGET_64BIT"
3080   "@
3081    movz{wl|x}\t{%1, %k0|%k0, %1} 
3082    movz{wq|x}\t{%1, %0|%0, %1}"
3083   [(set_attr "type" "imovx")
3084    (set_attr "mode" "SI,DI")])
3085
3086 (define_insn "zero_extendqidi2"
3087   [(set (match_operand:DI 0 "register_operand" "=r,r")
3088      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3089   "TARGET_64BIT"
3090   "@
3091    movz{bl|x}\t{%1, %k0|%k0, %1} 
3092    movz{bq|x}\t{%1, %0|%0, %1}"
3093   [(set_attr "type" "imovx")
3094    (set_attr "mode" "SI,DI")])
3095 \f
3096 ;; Sign extension instructions
3097
3098 (define_expand "extendsidi2"
3099   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3100                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3101               (clobber (reg:CC 17))
3102               (clobber (match_scratch:SI 2 ""))])]
3103   ""
3104 {
3105   if (TARGET_64BIT)
3106     {
3107       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3108       DONE;
3109     }
3110 })
3111
3112 (define_insn "*extendsidi2_1"
3113   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3114         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3115    (clobber (reg:CC 17))
3116    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3117   "!TARGET_64BIT"
3118   "#")
3119
3120 (define_insn "extendsidi2_rex64"
3121   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3122         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3123   "TARGET_64BIT"
3124   "@
3125    {cltq|cdqe}
3126    movs{lq|x}\t{%1,%0|%0, %1}"
3127   [(set_attr "type" "imovx")
3128    (set_attr "mode" "DI")
3129    (set_attr "prefix_0f" "0")
3130    (set_attr "modrm" "0,1")])
3131
3132 (define_insn "extendhidi2"
3133   [(set (match_operand:DI 0 "register_operand" "=r")
3134         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3135   "TARGET_64BIT"
3136   "movs{wq|x}\t{%1,%0|%0, %1}"
3137   [(set_attr "type" "imovx")
3138    (set_attr "mode" "DI")])
3139
3140 (define_insn "extendqidi2"
3141   [(set (match_operand:DI 0 "register_operand" "=r")
3142         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3143   "TARGET_64BIT"
3144   "movs{bq|x}\t{%1,%0|%0, %1}"
3145    [(set_attr "type" "imovx")
3146     (set_attr "mode" "DI")])
3147
3148 ;; Extend to memory case when source register does die.
3149 (define_split 
3150   [(set (match_operand:DI 0 "memory_operand" "")
3151         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3152    (clobber (reg:CC 17))
3153    (clobber (match_operand:SI 2 "register_operand" ""))]
3154   "(reload_completed
3155     && dead_or_set_p (insn, operands[1])
3156     && !reg_mentioned_p (operands[1], operands[0]))"
3157   [(set (match_dup 3) (match_dup 1))
3158    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3159               (clobber (reg:CC 17))])
3160    (set (match_dup 4) (match_dup 1))]
3161   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3162
3163 ;; Extend to memory case when source register does not die.
3164 (define_split 
3165   [(set (match_operand:DI 0 "memory_operand" "")
3166         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3167    (clobber (reg:CC 17))
3168    (clobber (match_operand:SI 2 "register_operand" ""))]
3169   "reload_completed"
3170   [(const_int 0)]
3171 {
3172   split_di (&operands[0], 1, &operands[3], &operands[4]);
3173
3174   emit_move_insn (operands[3], operands[1]);
3175
3176   /* Generate a cltd if possible and doing so it profitable.  */
3177   if (true_regnum (operands[1]) == 0
3178       && true_regnum (operands[2]) == 1
3179       && (optimize_size || TARGET_USE_CLTD))
3180     {
3181       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3182     }
3183   else
3184     {
3185       emit_move_insn (operands[2], operands[1]);
3186       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3187     }
3188   emit_move_insn (operands[4], operands[2]);
3189   DONE;
3190 })
3191
3192 ;; Extend to register case.  Optimize case where source and destination
3193 ;; registers match and cases where we can use cltd.
3194 (define_split 
3195   [(set (match_operand:DI 0 "register_operand" "")
3196         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3197    (clobber (reg:CC 17))
3198    (clobber (match_scratch:SI 2 ""))]
3199   "reload_completed"
3200   [(const_int 0)]
3201 {
3202   split_di (&operands[0], 1, &operands[3], &operands[4]);
3203
3204   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3205     emit_move_insn (operands[3], operands[1]);
3206
3207   /* Generate a cltd if possible and doing so it profitable.  */
3208   if (true_regnum (operands[3]) == 0
3209       && (optimize_size || TARGET_USE_CLTD))
3210     {
3211       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3212       DONE;
3213     }
3214
3215   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3216     emit_move_insn (operands[4], operands[1]);
3217
3218   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3219   DONE;
3220 })
3221
3222 (define_insn "extendhisi2"
3223   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3224         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3225   ""
3226 {
3227   switch (get_attr_prefix_0f (insn))
3228     {
3229     case 0:
3230       return "{cwtl|cwde}";
3231     default:
3232       return "movs{wl|x}\t{%1,%0|%0, %1}";
3233     }
3234 }
3235   [(set_attr "type" "imovx")
3236    (set_attr "mode" "SI")
3237    (set (attr "prefix_0f")
3238      ;; movsx is short decodable while cwtl is vector decoded.
3239      (if_then_else (and (eq_attr "cpu" "!k6")
3240                         (eq_attr "alternative" "0"))
3241         (const_string "0")
3242         (const_string "1")))
3243    (set (attr "modrm")
3244      (if_then_else (eq_attr "prefix_0f" "0")
3245         (const_string "0")
3246         (const_string "1")))])
3247
3248 (define_insn "*extendhisi2_zext"
3249   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3250         (zero_extend:DI
3251           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3252   "TARGET_64BIT"
3253 {
3254   switch (get_attr_prefix_0f (insn))
3255     {
3256     case 0:
3257       return "{cwtl|cwde}";
3258     default:
3259       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3260     }
3261 }
3262   [(set_attr "type" "imovx")
3263    (set_attr "mode" "SI")
3264    (set (attr "prefix_0f")
3265      ;; movsx is short decodable while cwtl is vector decoded.
3266      (if_then_else (and (eq_attr "cpu" "!k6")
3267                         (eq_attr "alternative" "0"))
3268         (const_string "0")
3269         (const_string "1")))
3270    (set (attr "modrm")
3271      (if_then_else (eq_attr "prefix_0f" "0")
3272         (const_string "0")
3273         (const_string "1")))])
3274
3275 (define_insn "extendqihi2"
3276   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3277         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3278   ""
3279 {
3280   switch (get_attr_prefix_0f (insn))
3281     {
3282     case 0:
3283       return "{cbtw|cbw}";
3284     default:
3285       return "movs{bw|x}\t{%1,%0|%0, %1}";
3286     }
3287 }
3288   [(set_attr "type" "imovx")
3289    (set_attr "mode" "HI")
3290    (set (attr "prefix_0f")
3291      ;; movsx is short decodable while cwtl is vector decoded.
3292      (if_then_else (and (eq_attr "cpu" "!k6")
3293                         (eq_attr "alternative" "0"))
3294         (const_string "0")
3295         (const_string "1")))
3296    (set (attr "modrm")
3297      (if_then_else (eq_attr "prefix_0f" "0")
3298         (const_string "0")
3299         (const_string "1")))])
3300
3301 (define_insn "extendqisi2"
3302   [(set (match_operand:SI 0 "register_operand" "=r")
3303         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3304   ""
3305   "movs{bl|x}\t{%1,%0|%0, %1}"
3306    [(set_attr "type" "imovx")
3307     (set_attr "mode" "SI")])
3308
3309 (define_insn "*extendqisi2_zext"
3310   [(set (match_operand:DI 0 "register_operand" "=r")
3311         (zero_extend:DI
3312           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3313   "TARGET_64BIT"
3314   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3315    [(set_attr "type" "imovx")
3316     (set_attr "mode" "SI")])
3317 \f
3318 ;; Conversions between float and double.
3319
3320 ;; These are all no-ops in the model used for the 80387.  So just
3321 ;; emit moves.
3322
3323 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3324 (define_insn "*dummy_extendsfdf2"
3325   [(set (match_operand:DF 0 "push_operand" "=<")
3326         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3327   "0"
3328   "#")
3329
3330 (define_split
3331   [(set (match_operand:DF 0 "push_operand" "")
3332         (float_extend:DF (match_operand:SF 1 "register_operand" "")))]
3333   "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
3334   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
3335    (set (mem:DF (reg:SI 7)) (float_extend:DF (match_dup 1)))])
3336
3337 (define_split
3338   [(set (match_operand:DF 0 "push_operand" "")
3339         (float_extend:DF (match_operand:SF 1 "register_operand" "")))]
3340   "TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
3341   [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
3342    (set (mem:DF (reg:DI 7)) (float_extend:DF (match_dup 1)))])
3343
3344 (define_insn "*dummy_extendsfxf2"
3345   [(set (match_operand:XF 0 "push_operand" "=<")
3346         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3347   "0"
3348   "#")
3349
3350 (define_split
3351   [(set (match_operand:XF 0 "push_operand" "")
3352         (float_extend:XF (match_operand:SF 1 "register_operand" "")))]
3353   "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
3354   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
3355    (set (mem:XF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
3356
3357 (define_insn "*dummy_extendsftf2"
3358   [(set (match_operand:TF 0 "push_operand" "=<")
3359         (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3360   "0"
3361   "#")
3362
3363 (define_split
3364   [(set (match_operand:TF 0 "push_operand" "")
3365         (float_extend:TF (match_operand:SF 1 "register_operand" "")))]
3366   "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
3367   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
3368    (set (mem:TF (reg:SI 7)) (float_extend:TF (match_dup 1)))])
3369
3370 (define_split
3371   [(set (match_operand:TF 0 "push_operand" "")
3372         (float_extend:TF (match_operand:SF 1 "register_operand" "")))]
3373   "TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
3374   [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
3375    (set (mem:DF (reg:DI 7)) (float_extend:TF (match_dup 1)))])
3376
3377 (define_insn "*dummy_extenddfxf2"
3378   [(set (match_operand:XF 0 "push_operand" "=<")
3379         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "f")))]
3380   "0"
3381   "#")
3382
3383 (define_split
3384   [(set (match_operand:XF 0 "push_operand" "")
3385         (float_extend:XF (match_operand:DF 1 "register_operand" "")))]
3386   "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
3387   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
3388    (set (mem:DF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
3389
3390 (define_insn "*dummy_extenddftf2"
3391   [(set (match_operand:TF 0 "push_operand" "=<")
3392         (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "f")))]
3393   "0"
3394   "#")
3395
3396 (define_split
3397   [(set (match_operand:TF 0 "push_operand" "")
3398         (float_extend:TF (match_operand:DF 1 "register_operand" "")))]
3399   "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
3400   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
3401    (set (mem:TF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
3402
3403 (define_split
3404   [(set (match_operand:TF 0 "push_operand" "")
3405         (float_extend:TF (match_operand:DF 1 "register_operand" "")))]
3406   "TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
3407   [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
3408    (set (mem:TF (reg:DI 7)) (float_extend:TF (match_dup 1)))])
3409
3410 (define_expand "extendsfdf2"
3411   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3412         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3413   "TARGET_80387 || TARGET_SSE2"
3414 {
3415   /* ??? Needed for compress_float_constant since all fp constants
3416      are LEGITIMATE_CONSTANT_P.  */
3417   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3418     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3419   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3420     operands[1] = force_reg (SFmode, operands[1]);
3421 })
3422
3423 (define_insn "*extendsfdf2_1"
3424   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
3425         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3426   "(TARGET_80387 || TARGET_SSE2)
3427    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3428 {
3429   switch (which_alternative)
3430     {
3431     case 0:
3432       if (REG_P (operands[1])
3433           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3434         return "fstp\t%y0";
3435       else if (STACK_TOP_P (operands[0]))
3436         return "fld%z1\t%y1";
3437       else
3438         return "fst\t%y0";
3439
3440     case 1:
3441       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3442         return "fstp%z0\t%y0";
3443
3444       else
3445         return "fst%z0\t%y0";
3446     case 2:
3447       return "cvtss2sd\t{%1, %0|%0, %1}";
3448
3449     default:
3450       abort ();
3451     }
3452 }
3453   [(set_attr "type" "fmov,fmov,ssecvt")
3454    (set_attr "mode" "SF,XF,DF")])
3455
3456 (define_insn "*extendsfdf2_1_sse_only"
3457   [(set (match_operand:DF 0 "register_operand" "=Y")
3458         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3459   "!TARGET_80387 && TARGET_SSE2
3460    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3461   "cvtss2sd\t{%1, %0|%0, %1}"
3462   [(set_attr "type" "ssecvt")
3463    (set_attr "mode" "DF")])
3464
3465 (define_expand "extendsfxf2"
3466   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3467         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3468   "!TARGET_64BIT && TARGET_80387"
3469 {
3470   /* ??? Needed for compress_float_constant since all fp constants
3471      are LEGITIMATE_CONSTANT_P.  */
3472   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3473     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3474   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3475     operands[1] = force_reg (SFmode, operands[1]);
3476 })
3477
3478 (define_insn "*extendsfxf2_1"
3479   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3480         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3481   "!TARGET_64BIT && TARGET_80387
3482    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3483 {
3484   switch (which_alternative)
3485     {
3486     case 0:
3487       if (REG_P (operands[1])
3488           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3489         return "fstp\t%y0";
3490       else if (STACK_TOP_P (operands[0]))
3491         return "fld%z1\t%y1";
3492       else
3493         return "fst\t%y0";
3494
3495     case 1:
3496       /* There is no non-popping store to memory for XFmode.  So if
3497          we need one, follow the store with a load.  */
3498       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3499         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3500       else
3501         return "fstp%z0\t%y0";
3502
3503     default:
3504       abort ();
3505     }
3506 }
3507   [(set_attr "type" "fmov")
3508    (set_attr "mode" "SF,XF")])
3509
3510 (define_expand "extendsftf2"
3511   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3512         (float_extend:TF (match_operand:SF 1 "general_operand" "")))]
3513   "TARGET_80387"
3514 {
3515   /* ??? Needed for compress_float_constant since all fp constants
3516      are LEGITIMATE_CONSTANT_P.  */
3517   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3518     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3519   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3520     operands[1] = force_reg (SFmode, operands[1]);
3521 })
3522
3523 (define_insn "*extendsftf2_1"
3524   [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
3525         (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3526   "TARGET_80387
3527    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3528 {
3529   switch (which_alternative)
3530     {
3531     case 0:
3532       if (REG_P (operands[1])
3533           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3534         return "fstp\t%y0";
3535       else if (STACK_TOP_P (operands[0]))
3536         return "fld%z1\t%y1";
3537       else
3538         return "fst\t%y0";
3539
3540     case 1:
3541       /* There is no non-popping store to memory for XFmode.  So if
3542          we need one, follow the store with a load.  */
3543       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3544         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3545       else
3546         return "fstp%z0\t%y0";
3547
3548     default:
3549       abort ();
3550     }
3551 }
3552   [(set_attr "type" "fmov")
3553    (set_attr "mode" "SF,XF")])
3554
3555 (define_expand "extenddfxf2"
3556   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3557         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3558   "!TARGET_64BIT && TARGET_80387"
3559 {
3560   /* ??? Needed for compress_float_constant since all fp constants
3561      are LEGITIMATE_CONSTANT_P.  */
3562   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3563     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3564   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3565     operands[1] = force_reg (DFmode, operands[1]);
3566 })
3567
3568 (define_insn "*extenddfxf2_1"
3569   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3570         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3571   "!TARGET_64BIT && TARGET_80387
3572    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3573 {
3574   switch (which_alternative)
3575     {
3576     case 0:
3577       if (REG_P (operands[1])
3578           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3579         return "fstp\t%y0";
3580       else if (STACK_TOP_P (operands[0]))
3581         return "fld%z1\t%y1";
3582       else
3583         return "fst\t%y0";
3584
3585     case 1:
3586       /* There is no non-popping store to memory for XFmode.  So if
3587          we need one, follow the store with a load.  */
3588       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3589         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3590       else
3591         return "fstp%z0\t%y0";
3592
3593     default:
3594       abort ();
3595     }
3596 }
3597   [(set_attr "type" "fmov")
3598    (set_attr "mode" "DF,XF")])
3599
3600 (define_expand "extenddftf2"
3601   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3602         (float_extend:TF (match_operand:DF 1 "general_operand" "")))]
3603   "TARGET_80387"
3604 {
3605   /* ??? Needed for compress_float_constant since all fp constants
3606      are LEGITIMATE_CONSTANT_P.  */
3607   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3608     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3609   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3610     operands[1] = force_reg (DFmode, operands[1]);
3611 })
3612
3613 (define_insn "*extenddftf2_1"
3614   [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
3615         (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3616   "TARGET_80387
3617    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3618 {
3619   switch (which_alternative)
3620     {
3621     case 0:
3622       if (REG_P (operands[1])
3623           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3624         return "fstp\t%y0";
3625       else if (STACK_TOP_P (operands[0]))
3626         return "fld%z1\t%y1";
3627       else
3628         return "fst\t%y0";
3629
3630     case 1:
3631       /* There is no non-popping store to memory for XFmode.  So if
3632          we need one, follow the store with a load.  */
3633       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3634         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3635       else
3636         return "fstp%z0\t%y0";
3637
3638     default:
3639       abort ();
3640     }
3641 }
3642   [(set_attr "type" "fmov")
3643    (set_attr "mode" "DF,XF")])
3644
3645 ;; %%% This seems bad bad news.
3646 ;; This cannot output into an f-reg because there is no way to be sure
3647 ;; of truncating in that case.  Otherwise this is just like a simple move
3648 ;; insn.  So we pretend we can output to a reg in order to get better
3649 ;; register preferencing, but we really use a stack slot.
3650
3651 (define_expand "truncdfsf2"
3652   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3653                    (float_truncate:SF
3654                     (match_operand:DF 1 "register_operand" "")))
3655               (clobber (match_dup 2))])]
3656   "TARGET_80387 || TARGET_SSE2"
3657   "
3658    if (TARGET_80387)
3659      operands[2] = assign_386_stack_local (SFmode, 0);
3660    else
3661      {
3662         emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3663         DONE;
3664      }
3665 ")
3666
3667 (define_insn "*truncdfsf2_1"
3668   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3669         (float_truncate:SF
3670          (match_operand:DF 1 "register_operand" "f,f,f,f")))
3671    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3672   "TARGET_80387 && !TARGET_SSE2"
3673 {
3674   switch (which_alternative)
3675     {
3676     case 0:
3677       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3678         return "fstp%z0\t%y0";
3679       else
3680         return "fst%z0\t%y0";
3681     default:
3682       abort ();
3683     }
3684 }
3685   [(set_attr "type" "fmov,multi,multi,multi")
3686    (set_attr "mode" "SF,SF,SF,SF")])
3687
3688 (define_insn "*truncdfsf2_1_sse"
3689   [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,Y")
3690         (float_truncate:SF
3691          (match_operand:DF 1 "nonimmediate_operand" "f,f,f,f,mY")))
3692    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3693   "TARGET_80387 && TARGET_SSE2"
3694 {
3695   switch (which_alternative)
3696     {
3697     case 0:
3698       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3699         return "fstp%z0\t%y0";
3700       else
3701         return "fst%z0\t%y0";
3702     case 4:
3703       return "cvtsd2ss\t{%1, %0|%0, %1}";
3704     default:
3705       abort ();
3706     }
3707 }
3708   [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3709    (set_attr "mode" "SF,SF,SF,SF,DF")])
3710
3711 (define_insn "*truncdfsf2_2"
3712   [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,!m")
3713         (float_truncate:SF
3714          (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
3715   "TARGET_80387 && TARGET_SSE2
3716    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3717 {
3718   switch (which_alternative)
3719     {
3720     case 0:
3721       return "cvtsd2ss\t{%1, %0|%0, %1}";
3722     case 1:
3723       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3724         return "fstp%z0\t%y0";
3725       else
3726         return "fst%z0\t%y0";
3727     default:
3728       abort ();
3729     }
3730 }
3731   [(set_attr "type" "ssecvt,fmov")
3732    (set_attr "mode" "DF,SF")])
3733
3734 (define_insn "truncdfsf2_3"
3735   [(set (match_operand:SF 0 "memory_operand" "=m")
3736         (float_truncate:SF
3737          (match_operand:DF 1 "register_operand" "f")))]
3738   "TARGET_80387"
3739 {
3740   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3741     return "fstp%z0\t%y0";
3742   else
3743     return "fst%z0\t%y0";
3744 }
3745   [(set_attr "type" "fmov")
3746    (set_attr "mode" "SF")])
3747
3748 (define_insn "truncdfsf2_sse_only"
3749   [(set (match_operand:SF 0 "register_operand" "=Y")
3750         (float_truncate:SF
3751          (match_operand:DF 1 "nonimmediate_operand" "mY")))]
3752   "!TARGET_80387 && TARGET_SSE2"
3753   "cvtsd2ss\t{%1, %0|%0, %1}"
3754   [(set_attr "type" "ssecvt")
3755    (set_attr "mode" "DF")])
3756
3757 (define_split
3758   [(set (match_operand:SF 0 "memory_operand" "")
3759         (float_truncate:SF
3760          (match_operand:DF 1 "register_operand" "")))
3761    (clobber (match_operand:SF 2 "memory_operand" ""))]
3762   "TARGET_80387"
3763   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3764   "")
3765
3766 (define_split
3767   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3768         (float_truncate:SF
3769          (match_operand:DF 1 "nonimmediate_operand" "")))
3770    (clobber (match_operand 2 "" ""))]
3771   "TARGET_80387 && reload_completed
3772    && !FP_REG_P (operands[0]) && !FP_REG_P (operands[1])"
3773   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3774   "")
3775
3776 (define_split
3777   [(set (match_operand:SF 0 "register_operand" "")
3778         (float_truncate:SF
3779          (match_operand:DF 1 "register_operand" "")))
3780    (clobber (match_operand:SF 2 "memory_operand" ""))]
3781   "TARGET_80387 && reload_completed
3782    && FP_REG_P (operands[1])"
3783   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3784    (set (match_dup 0) (match_dup 2))]
3785   "")
3786
3787 (define_expand "truncxfsf2"
3788   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3789                    (float_truncate:SF
3790                     (match_operand:XF 1 "register_operand" "")))
3791               (clobber (match_dup 2))])]
3792   "!TARGET_64BIT && TARGET_80387"
3793   "operands[2] = assign_386_stack_local (SFmode, 0);")
3794
3795 (define_insn "*truncxfsf2_1"
3796   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3797         (float_truncate:SF
3798          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3799    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3800   "!TARGET_64BIT && TARGET_80387"
3801 {
3802   switch (which_alternative)
3803     {
3804     case 0:
3805       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3806         return "fstp%z0\t%y0";
3807       else
3808         return "fst%z0\t%y0";
3809     default:
3810       abort();
3811     }
3812 }
3813   [(set_attr "type" "fmov,multi,multi,multi")
3814    (set_attr "mode" "SF")])
3815
3816 (define_insn "*truncxfsf2_2"
3817   [(set (match_operand:SF 0 "memory_operand" "=m")
3818         (float_truncate:SF
3819          (match_operand:XF 1 "register_operand" "f")))]
3820   "!TARGET_64BIT && TARGET_80387"
3821 {
3822   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3823     return "fstp%z0\t%y0";
3824   else
3825     return "fst%z0\t%y0";
3826 }
3827   [(set_attr "type" "fmov")
3828    (set_attr "mode" "SF")])
3829
3830 (define_split
3831   [(set (match_operand:SF 0 "memory_operand" "")
3832         (float_truncate:SF
3833          (match_operand:XF 1 "register_operand" "")))
3834    (clobber (match_operand:SF 2 "memory_operand" ""))]
3835   "TARGET_80387"
3836   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3837   "")
3838
3839 (define_split
3840   [(set (match_operand:SF 0 "register_operand" "")
3841         (float_truncate:SF
3842          (match_operand:XF 1 "register_operand" "")))
3843    (clobber (match_operand:SF 2 "memory_operand" ""))]
3844   "TARGET_80387 && reload_completed"
3845   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3846    (set (match_dup 0) (match_dup 2))]
3847   "")
3848
3849 (define_expand "trunctfsf2"
3850   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3851                    (float_truncate:SF
3852                     (match_operand:TF 1 "register_operand" "")))
3853               (clobber (match_dup 2))])]
3854   "TARGET_80387"
3855   "operands[2] = assign_386_stack_local (SFmode, 0);")
3856
3857 (define_insn "*trunctfsf2_1"
3858   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3859         (float_truncate:SF
3860          (match_operand:TF 1 "register_operand" "f,f,f,f")))
3861    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3862   "TARGET_80387"
3863 {
3864   switch (which_alternative)
3865     {
3866     case 0:
3867       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3868         return "fstp%z0\t%y0";
3869       else
3870         return "fst%z0\t%y0";
3871     default:
3872       abort();
3873     }
3874 }
3875   [(set_attr "type" "fmov,multi,multi,multi")
3876    (set_attr "mode" "SF")])
3877
3878 (define_insn "*trunctfsf2_2"
3879   [(set (match_operand:SF 0 "memory_operand" "=m")
3880         (float_truncate:SF
3881          (match_operand:TF 1 "register_operand" "f")))]
3882   "TARGET_80387"
3883 {
3884   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3885     return "fstp%z0\t%y0";
3886   else
3887     return "fst%z0\t%y0";
3888 }
3889   [(set_attr "type" "fmov")
3890    (set_attr "mode" "SF")])
3891
3892 (define_split
3893   [(set (match_operand:SF 0 "memory_operand" "")
3894         (float_truncate:SF
3895          (match_operand:TF 1 "register_operand" "")))
3896    (clobber (match_operand:SF 2 "memory_operand" ""))]
3897   "TARGET_80387"
3898   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3899   "")
3900
3901 (define_split
3902   [(set (match_operand:SF 0 "register_operand" "")
3903         (float_truncate:SF
3904          (match_operand:TF 1 "register_operand" "")))
3905    (clobber (match_operand:SF 2 "memory_operand" ""))]
3906   "TARGET_80387 && reload_completed"
3907   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3908    (set (match_dup 0) (match_dup 2))]
3909   "")
3910
3911
3912 (define_expand "truncxfdf2"
3913   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3914                    (float_truncate:DF
3915                     (match_operand:XF 1 "register_operand" "")))
3916               (clobber (match_dup 2))])]
3917   "!TARGET_64BIT && TARGET_80387"
3918   "operands[2] = assign_386_stack_local (DFmode, 0);")
3919
3920 (define_insn "*truncxfdf2_1"
3921   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3922         (float_truncate:DF
3923          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3924    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3925   "!TARGET_64BIT && TARGET_80387"
3926 {
3927   switch (which_alternative)
3928     {
3929     case 0:
3930       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3931         return "fstp%z0\t%y0";
3932       else
3933         return "fst%z0\t%y0";
3934     default:
3935       abort();
3936     }
3937   abort ();
3938 }
3939   [(set_attr "type" "fmov,multi,multi,multi")
3940    (set_attr "mode" "DF")])
3941
3942 (define_insn "*truncxfdf2_2"
3943   [(set (match_operand:DF 0 "memory_operand" "=m")
3944         (float_truncate:DF
3945           (match_operand:XF 1 "register_operand" "f")))]
3946   "!TARGET_64BIT && TARGET_80387"
3947 {
3948   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3949     return "fstp%z0\t%y0";
3950   else
3951     return "fst%z0\t%y0";
3952 }
3953   [(set_attr "type" "fmov")
3954    (set_attr "mode" "DF")])
3955
3956 (define_split
3957   [(set (match_operand:DF 0 "memory_operand" "")
3958         (float_truncate:DF
3959          (match_operand:XF 1 "register_operand" "")))
3960    (clobber (match_operand:DF 2 "memory_operand" ""))]
3961   "TARGET_80387"
3962   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
3963   "")
3964
3965 (define_split
3966   [(set (match_operand:DF 0 "register_operand" "")
3967         (float_truncate:DF
3968          (match_operand:XF 1 "register_operand" "")))
3969    (clobber (match_operand:DF 2 "memory_operand" ""))]
3970   "TARGET_80387 && reload_completed"
3971   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
3972    (set (match_dup 0) (match_dup 2))]
3973   "")
3974
3975 (define_expand "trunctfdf2"
3976   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3977                    (float_truncate:DF
3978                     (match_operand:TF 1 "register_operand" "")))
3979               (clobber (match_dup 2))])]
3980   "TARGET_80387"
3981   "operands[2] = assign_386_stack_local (DFmode, 0);")
3982
3983 (define_insn "*trunctfdf2_1"
3984   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3985         (float_truncate:DF
3986          (match_operand:TF 1 "register_operand" "f,f,f,f")))
3987    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3988   "TARGET_80387"
3989 {
3990   switch (which_alternative)
3991     {
3992     case 0:
3993       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3994         return "fstp%z0\t%y0";
3995       else
3996         return "fst%z0\t%y0";
3997     default:
3998       abort();
3999     }
4000   abort ();
4001 }
4002   [(set_attr "type" "fmov,multi,multi,multi")
4003    (set_attr "mode" "DF")])
4004
4005         (define_insn "*trunctfdf2_2"
4006   [(set (match_operand:DF 0 "memory_operand" "=m")
4007         (float_truncate:DF
4008           (match_operand:TF 1 "register_operand" "f")))]
4009   "TARGET_80387"
4010 {
4011   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4012     return "fstp%z0\t%y0";
4013   else
4014     return "fst%z0\t%y0";
4015 }
4016   [(set_attr "type" "fmov")
4017    (set_attr "mode" "DF")])
4018
4019 (define_split
4020   [(set (match_operand:DF 0 "memory_operand" "")
4021         (float_truncate:DF
4022          (match_operand:TF 1 "register_operand" "")))
4023    (clobber (match_operand:DF 2 "memory_operand" ""))]
4024   "TARGET_80387"
4025   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4026   "")
4027
4028 (define_split
4029   [(set (match_operand:DF 0 "register_operand" "")
4030         (float_truncate:DF
4031          (match_operand:TF 1 "register_operand" "")))
4032    (clobber (match_operand:DF 2 "memory_operand" ""))]
4033   "TARGET_80387 && reload_completed"
4034   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4035    (set (match_dup 0) (match_dup 2))]
4036   "")
4037
4038 \f
4039 ;; %%% Break up all these bad boys.
4040
4041 ;; Signed conversion to DImode.
4042
4043 (define_expand "fix_truncxfdi2"
4044   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4045         (fix:DI (match_operand:XF 1 "register_operand" "")))]
4046   "!TARGET_64BIT && TARGET_80387"
4047   "")
4048
4049 (define_expand "fix_trunctfdi2"
4050   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4051         (fix:DI (match_operand:TF 1 "register_operand" "")))]
4052   "TARGET_80387"
4053   "")
4054
4055 (define_expand "fix_truncdfdi2"
4056   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4057         (fix:DI (match_operand:DF 1 "register_operand" "")))]
4058   "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
4059 {
4060   if (TARGET_64BIT && TARGET_SSE2)
4061    {
4062      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4063      emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4064      if (out != operands[0])
4065         emit_move_insn (operands[0], out);
4066      DONE;
4067    }
4068 })
4069
4070 (define_expand "fix_truncsfdi2"
4071   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4072         (fix:DI (match_operand:SF 1 "register_operand" "")))]
4073   "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
4074 {
4075   if (TARGET_SSE && TARGET_64BIT)
4076    {
4077      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4078      emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4079      if (out != operands[0])
4080         emit_move_insn (operands[0], out);
4081      DONE;
4082    }
4083 })
4084
4085 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4086 ;; of the machinery.
4087 (define_insn_and_split "*fix_truncdi_1"
4088   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4089         (fix:DI (match_operand 1 "register_operand" "f,f")))]
4090   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4091    && !reload_completed && !reload_in_progress
4092    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4093   "#"
4094   "&& 1"
4095   [(const_int 0)]
4096 {
4097   operands[2] = assign_386_stack_local (HImode, 1);
4098   operands[3] = assign_386_stack_local (HImode, 2);
4099   if (memory_operand (operands[0], VOIDmode))
4100     emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4101                                        operands[2], operands[3]));
4102   else
4103     {
4104       operands[4] = assign_386_stack_local (DImode, 0);
4105       emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4106                                            operands[2], operands[3],
4107                                            operands[4]));
4108     }
4109   DONE;
4110 }
4111   [(set_attr "type" "fistp")])
4112
4113 (define_insn "fix_truncdi_nomemory"
4114   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4115         (fix:DI (match_operand 1 "register_operand" "f,f")))
4116    (use (match_operand:HI 2 "memory_operand" "m,m"))
4117    (use (match_operand:HI 3 "memory_operand" "m,m"))
4118    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4119    (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4120   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4121    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4122   "#"
4123   [(set_attr "type" "fistp")])
4124
4125 (define_insn "fix_truncdi_memory"
4126   [(set (match_operand:DI 0 "memory_operand" "=m")
4127         (fix:DI (match_operand 1 "register_operand" "f")))
4128    (use (match_operand:HI 2 "memory_operand" "m"))
4129    (use (match_operand:HI 3 "memory_operand" "m"))
4130    (clobber (match_scratch:DF 4 "=&1f"))]
4131   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4132    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4133   "* operands[5] = operands[4]; return output_fix_trunc (insn, operands);"
4134   [(set_attr "type" "fistp")])
4135
4136 (define_split 
4137   [(set (match_operand:DI 0 "register_operand" "")
4138         (fix:DI (match_operand 1 "register_operand" "")))
4139    (use (match_operand:HI 2 "memory_operand" ""))
4140    (use (match_operand:HI 3 "memory_operand" ""))
4141    (clobber (match_operand:DI 4 "memory_operand" ""))
4142    (clobber (match_scratch 5 ""))]
4143   "reload_completed"
4144   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4145               (use (match_dup 2))
4146               (use (match_dup 3))
4147               (clobber (match_dup 5))])
4148    (set (match_dup 0) (match_dup 4))]
4149   "")
4150
4151 (define_split 
4152   [(set (match_operand:DI 0 "memory_operand" "")
4153         (fix:DI (match_operand 1 "register_operand" "")))
4154    (use (match_operand:HI 2 "memory_operand" ""))
4155    (use (match_operand:HI 3 "memory_operand" ""))
4156    (clobber (match_operand:DI 4 "memory_operand" ""))
4157    (clobber (match_scratch 5 ""))]
4158   "reload_completed"
4159   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4160               (use (match_dup 2))
4161               (use (match_dup 3))
4162               (clobber (match_dup 5))])]
4163   "")
4164
4165 ;; When SSE available, it is always faster to use it!
4166 (define_insn "fix_truncsfdi_sse"
4167   [(set (match_operand:DI 0 "register_operand" "=r")
4168         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4169   "TARGET_64BIT && TARGET_SSE"
4170   "cvttss2si{q}\t{%1, %0|%0, %1}"
4171   [(set_attr "type" "ssecvt")])
4172
4173 (define_insn "fix_truncdfdi_sse"
4174   [(set (match_operand:DI 0 "register_operand" "=r")
4175         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
4176   "TARGET_64BIT && TARGET_SSE2"
4177   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4178   [(set_attr "type" "ssecvt")])
4179
4180 ;; Signed conversion to SImode.
4181
4182 (define_expand "fix_truncxfsi2"
4183   [(set (match_operand:SI 0 "nonimmediate_operand" "")
4184         (fix:SI (match_operand:XF 1 "register_operand" "")))]
4185   "!TARGET_64BIT && TARGET_80387"
4186   "")
4187
4188 (define_expand "fix_trunctfsi2"
4189   [(set (match_operand:SI 0 "nonimmediate_operand" "")
4190         (fix:SI (match_operand:TF 1 "register_operand" "")))]
4191   "TARGET_80387"
4192   "")
4193
4194 (define_expand "fix_truncdfsi2"
4195   [(set (match_operand:SI 0 "nonimmediate_operand" "")
4196         (fix:SI (match_operand:DF 1 "register_operand" "")))]
4197   "TARGET_80387 || TARGET_SSE2"
4198 {
4199   if (TARGET_SSE2)
4200    {
4201      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4202      emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4203      if (out != operands[0])
4204         emit_move_insn (operands[0], out);
4205      DONE;
4206    }
4207 })
4208
4209 (define_expand "fix_truncsfsi2"
4210   [(set (match_operand:SI 0 "nonimmediate_operand" "")
4211         (fix:SI (match_operand:SF 1 "register_operand" "")))]
4212   "TARGET_80387 || TARGET_SSE"
4213 {
4214   if (TARGET_SSE)
4215    {
4216      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4217      emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4218      if (out != operands[0])
4219         emit_move_insn (operands[0], out);
4220      DONE;
4221    }
4222 })
4223
4224 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4225 ;; of the machinery.
4226 (define_insn_and_split "*fix_truncsi_1"
4227   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4228         (fix:SI (match_operand 1 "register_operand" "f,f")))]
4229   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4230    && !reload_completed && !reload_in_progress
4231    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4232   "#"
4233   "&& 1"
4234   [(const_int 0)]
4235 {
4236   operands[2] = assign_386_stack_local (HImode, 1);
4237   operands[3] = assign_386_stack_local (HImode, 2);
4238   if (memory_operand (operands[0], VOIDmode))
4239     emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4240                                        operands[2], operands[3]));
4241   else
4242     {
4243       operands[4] = assign_386_stack_local (SImode, 0);
4244       emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4245                                            operands[2], operands[3],
4246                                            operands[4]));
4247     }
4248   DONE;
4249 }
4250   [(set_attr "type" "fistp")])
4251
4252 (define_insn "fix_truncsi_nomemory"
4253   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4254         (fix:SI (match_operand 1 "register_operand" "f,f")))
4255    (use (match_operand:HI 2 "memory_operand" "m,m"))
4256    (use (match_operand:HI 3 "memory_operand" "m,m"))
4257    (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4258   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4259    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4260   "#"
4261   [(set_attr "type" "fistp")])
4262
4263 (define_insn "fix_truncsi_memory"
4264   [(set (match_operand:SI 0 "memory_operand" "=m")
4265         (fix:SI (match_operand 1 "register_operand" "f")))
4266    (use (match_operand:HI 2 "memory_operand" "m"))
4267    (use (match_operand:HI 3 "memory_operand" "m"))]
4268   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4269    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4270   "* return output_fix_trunc (insn, operands);"
4271   [(set_attr "type" "fistp")])
4272
4273 ;; When SSE available, it is always faster to use it!
4274 (define_insn "fix_truncsfsi_sse"
4275   [(set (match_operand:SI 0 "register_operand" "=r")
4276         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4277   "TARGET_SSE"
4278   "cvttss2si\t{%1, %0|%0, %1}"
4279   [(set_attr "type" "ssecvt")])
4280
4281 (define_insn "fix_truncdfsi_sse"
4282   [(set (match_operand:SI 0 "register_operand" "=r")
4283         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
4284   "TARGET_SSE2"
4285   "cvttsd2si\t{%1, %0|%0, %1}"
4286   [(set_attr "type" "ssecvt")])
4287
4288 (define_split 
4289   [(set (match_operand:SI 0 "register_operand" "")
4290         (fix:SI (match_operand 1 "register_operand" "")))
4291    (use (match_operand:HI 2 "memory_operand" ""))
4292    (use (match_operand:HI 3 "memory_operand" ""))
4293    (clobber (match_operand:SI 4 "memory_operand" ""))]
4294   "reload_completed"
4295   [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4296               (use (match_dup 2))
4297               (use (match_dup 3))])
4298    (set (match_dup 0) (match_dup 4))]
4299   "")
4300
4301 (define_split 
4302   [(set (match_operand:SI 0 "memory_operand" "")
4303         (fix:SI (match_operand 1 "register_operand" "")))
4304    (use (match_operand:HI 2 "memory_operand" ""))
4305    (use (match_operand:HI 3 "memory_operand" ""))
4306    (clobber (match_operand:SI 4 "memory_operand" ""))]
4307   "reload_completed"
4308   [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4309               (use (match_dup 2))
4310               (use (match_dup 3))])]
4311   "")
4312
4313 ;; Signed conversion to HImode.
4314
4315 (define_expand "fix_truncxfhi2"
4316   [(set (match_operand:HI 0 "nonimmediate_operand" "")
4317         (fix:HI (match_operand:XF 1 "register_operand" "")))]
4318   "!TARGET_64BIT && TARGET_80387"
4319   "")
4320
4321 (define_expand "fix_trunctfhi2"
4322   [(set (match_operand:HI 0 "nonimmediate_operand" "")
4323         (fix:HI (match_operand:TF 1 "register_operand" "")))]
4324   "TARGET_80387"
4325   "")
4326
4327 (define_expand "fix_truncdfhi2"
4328   [(set (match_operand:HI 0 "nonimmediate_operand" "")
4329         (fix:HI (match_operand:DF 1 "register_operand" "")))]
4330   "TARGET_80387 && !TARGET_SSE2"
4331   "")
4332
4333 (define_expand "fix_truncsfhi2"
4334   [(set (match_operand:HI 0 "nonimmediate_operand" "")
4335         (fix:HI (match_operand:SF 1 "register_operand" "")))]
4336   "TARGET_80387 && !TARGET_SSE"
4337   "")
4338
4339 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4340 ;; of the machinery.
4341 (define_insn_and_split "*fix_trunchi_1"
4342   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4343         (fix:HI (match_operand 1 "register_operand" "f,f")))]
4344   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4345    && !reload_completed && !reload_in_progress
4346    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4347   "#"
4348   ""
4349   [(const_int 0)]
4350 {
4351   operands[2] = assign_386_stack_local (HImode, 1);
4352   operands[3] = assign_386_stack_local (HImode, 2);
4353   if (memory_operand (operands[0], VOIDmode))
4354     emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4355                                        operands[2], operands[3]));
4356   else
4357     {
4358       operands[4] = assign_386_stack_local (HImode, 0);
4359       emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4360                                            operands[2], operands[3],
4361                                            operands[4]));
4362     }
4363   DONE;
4364 }
4365   [(set_attr "type" "fistp")])
4366
4367 (define_insn "fix_trunchi_nomemory"
4368   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4369         (fix:HI (match_operand 1 "register_operand" "f,f")))
4370    (use (match_operand:HI 2 "memory_operand" "m,m"))
4371    (use (match_operand:HI 3 "memory_operand" "m,m"))
4372    (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4373   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4374    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4375   "#"
4376   [(set_attr "type" "fistp")])
4377
4378 (define_insn "fix_trunchi_memory"
4379   [(set (match_operand:HI 0 "memory_operand" "=m")
4380         (fix:HI (match_operand 1 "register_operand" "f")))
4381    (use (match_operand:HI 2 "memory_operand" "m"))
4382    (use (match_operand:HI 3 "memory_operand" "m"))]
4383   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4384    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4385   "* return output_fix_trunc (insn, operands);"
4386   [(set_attr "type" "fistp")])
4387
4388 (define_split 
4389   [(set (match_operand:HI 0 "memory_operand" "")
4390         (fix:HI (match_operand 1 "register_operand" "")))
4391    (use (match_operand:HI 2 "memory_operand" ""))
4392    (use (match_operand:HI 3 "memory_operand" ""))
4393    (clobber (match_operand:HI 4 "memory_operand" ""))]
4394   "reload_completed"
4395   [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4396               (use (match_dup 2))
4397               (use (match_dup 3))])]
4398   "")
4399
4400 (define_split 
4401   [(set (match_operand:HI 0 "register_operand" "")
4402         (fix:HI (match_operand 1 "register_operand" "")))
4403    (use (match_operand:HI 2 "memory_operand" ""))
4404    (use (match_operand:HI 3 "memory_operand" ""))
4405    (clobber (match_operand:HI 4 "memory_operand" ""))]
4406   "reload_completed"
4407   [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4408               (use (match_dup 2))
4409               (use (match_dup 3))
4410               (clobber (match_dup 4))])
4411    (set (match_dup 0) (match_dup 4))]
4412   "")
4413
4414 ;; %% Not used yet.
4415 (define_insn "x86_fnstcw_1"
4416   [(set (match_operand:HI 0 "memory_operand" "=m")
4417         (unspec:HI [(reg:HI 18)] UNSPEC_FSTCW))]
4418   "TARGET_80387"
4419   "fnstcw\t%0"
4420   [(set_attr "length" "2")
4421    (set_attr "mode" "HI")
4422    (set_attr "unit" "i387")
4423    (set_attr "ppro_uops" "few")])
4424
4425 (define_insn "x86_fldcw_1"
4426   [(set (reg:HI 18)
4427         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4428   "TARGET_80387"
4429   "fldcw\t%0"
4430   [(set_attr "length" "2")
4431    (set_attr "mode" "HI")
4432    (set_attr "unit" "i387")
4433    (set_attr "athlon_decode" "vector")
4434    (set_attr "ppro_uops" "few")])
4435 \f
4436 ;; Conversion between fixed point and floating point.
4437
4438 ;; Even though we only accept memory inputs, the backend _really_
4439 ;; wants to be able to do this between registers.
4440
4441 (define_insn "floathisf2"
4442   [(set (match_operand:SF 0 "register_operand" "=f,f")
4443         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4444   "TARGET_80387 && !TARGET_SSE"
4445   "@
4446    fild%z1\t%1
4447    #"
4448   [(set_attr "type" "fmov,multi")
4449    (set_attr "mode" "SF")
4450    (set_attr "fp_int_src" "true")])
4451
4452 (define_expand "floatsisf2"
4453   [(set (match_operand:SF 0 "register_operand" "")
4454         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4455   "TARGET_SSE || TARGET_80387"
4456   "")
4457
4458 (define_insn "*floatsisf2_i387"
4459   [(set (match_operand:SF 0 "register_operand" "=f,?f,x")
4460         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,mr")))]
4461   "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4462   "@
4463    fild%z1\t%1
4464    #
4465    cvtsi2ss\t{%1, %0|%0, %1}"
4466   [(set_attr "type" "fmov,multi,ssecvt")
4467    (set_attr "mode" "SF")
4468    (set_attr "fp_int_src" "true")])
4469
4470 (define_insn "*floatsisf2_sse"
4471   [(set (match_operand:SF 0 "register_operand" "=x")
4472         (float:SF (match_operand:SI 1 "nonimmediate_operand" "mr")))]
4473   "TARGET_SSE"
4474   "cvtsi2ss\t{%1, %0|%0, %1}"
4475   [(set_attr "type" "ssecvt")
4476    (set_attr "mode" "SF")
4477    (set_attr "fp_int_src" "true")])
4478
4479 (define_expand "floatdisf2"
4480   [(set (match_operand:SF 0 "register_operand" "")
4481         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4482   "(TARGET_64BIT && TARGET_SSE) || TARGET_80387"
4483   "")
4484
4485 (define_insn "*floatdisf2_i387_only"
4486   [(set (match_operand:SF 0 "register_operand" "=f,?f")
4487         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4488   "TARGET_80387 && (!TARGET_SSE || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
4489   "@
4490    fild%z1\t%1
4491    #"
4492   [(set_attr "type" "fmov,multi")
4493    (set_attr "mode" "SF")
4494    (set_attr "fp_int_src" "true")])
4495
4496 (define_insn "*floatdisf2_i387"
4497   [(set (match_operand:SF 0 "register_operand" "=f,?f,x")
4498         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,mr")))]
4499   "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4500   "@
4501    fild%z1\t%1
4502    #
4503    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4504   [(set_attr "type" "fmov,multi,ssecvt")
4505    (set_attr "mode" "SF")
4506    (set_attr "fp_int_src" "true")])
4507
4508 (define_insn "*floatdisf2_sse"
4509   [(set (match_operand:SF 0 "register_operand" "=x")
4510         (float:SF (match_operand:DI 1 "nonimmediate_operand" "mr")))]
4511   "TARGET_64BIT && TARGET_SSE"
4512   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4513   [(set_attr "type" "ssecvt")
4514    (set_attr "mode" "SF")
4515    (set_attr "fp_int_src" "true")])
4516
4517 (define_insn "floathidf2"
4518   [(set (match_operand:DF 0 "register_operand" "=f,f")
4519         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4520   "TARGET_80387 && !TARGET_SSE2"
4521   "@
4522    fild%z1\t%1
4523    #"
4524   [(set_attr "type" "fmov,multi")
4525    (set_attr "mode" "DF")
4526    (set_attr "fp_int_src" "true")])
4527
4528 (define_expand "floatsidf2"
4529   [(set (match_operand:DF 0 "register_operand" "")
4530         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4531   "TARGET_80387 || TARGET_SSE2"
4532   "")
4533
4534 (define_insn "*floatsidf2_i387"
4535   [(set (match_operand:DF 0 "register_operand" "=f,?f,Y")
4536         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,mr")))]
4537   "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4538   "@
4539    fild%z1\t%1
4540    #
4541    cvtsi2sd\t{%1, %0|%0, %1}"
4542   [(set_attr "type" "fmov,multi,ssecvt")
4543    (set_attr "mode" "DF")
4544    (set_attr "fp_int_src" "true")])
4545
4546 (define_insn "*floatsidf2_sse"
4547   [(set (match_operand:DF 0 "register_operand" "=Y")
4548         (float:DF (match_operand:SI 1 "nonimmediate_operand" "mr")))]
4549   "TARGET_SSE2"
4550   "cvtsi2sd\t{%1, %0|%0, %1}"
4551   [(set_attr "type" "ssecvt")
4552    (set_attr "mode" "DF")
4553    (set_attr "fp_int_src" "true")])
4554
4555 (define_expand "floatdidf2"
4556   [(set (match_operand:DF 0 "register_operand" "")
4557         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4558   "(TARGET_64BIT && TARGET_SSE2) || TARGET_80387"
4559   "")
4560
4561 (define_insn "*floatdidf2_i387_only"
4562   [(set (match_operand:DF 0 "register_operand" "=f,?f")
4563         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4564   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_64BIT)"
4565   "@
4566    fild%z1\t%1
4567    #"
4568   [(set_attr "type" "fmov,multi")
4569    (set_attr "mode" "DF")
4570    (set_attr "fp_int_src" "true")])
4571
4572 (define_insn "*floatdidf2_i387"
4573   [(set (match_operand:DF 0 "register_operand" "=f,?f,Y")
4574         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,mr")))]
4575   "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4576   "@
4577    fild%z1\t%1
4578    #
4579    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4580   [(set_attr "type" "fmov,multi,ssecvt")
4581    (set_attr "mode" "DF")
4582    (set_attr "fp_int_src" "true")])
4583
4584 (define_insn "*floatdidf2_sse"
4585   [(set (match_operand:DF 0 "register_operand" "=Y")
4586         (float:DF (match_operand:DI 1 "nonimmediate_operand" "mr")))]
4587   "TARGET_SSE2"
4588   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4589   [(set_attr "type" "ssecvt")
4590    (set_attr "mode" "DF")
4591    (set_attr "fp_int_src" "true")])
4592
4593 (define_insn "floathixf2"
4594   [(set (match_operand:XF 0 "register_operand" "=f,f")
4595         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4596   "!TARGET_64BIT && TARGET_80387"
4597   "@
4598    fild%z1\t%1
4599    #"
4600   [(set_attr "type" "fmov,multi")
4601    (set_attr "mode" "XF")
4602    (set_attr "fp_int_src" "true")])
4603
4604 (define_insn "floathitf2"
4605   [(set (match_operand:TF 0 "register_operand" "=f,f")
4606         (float:TF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4607   "TARGET_80387"
4608   "@
4609    fild%z1\t%1
4610    #"
4611   [(set_attr "type" "fmov,multi")
4612    (set_attr "mode" "XF")
4613    (set_attr "fp_int_src" "true")])
4614
4615 (define_insn "floatsixf2"
4616   [(set (match_operand:XF 0 "register_operand" "=f,f")
4617         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
4618   "!TARGET_64BIT && TARGET_80387"
4619   "@
4620    fild%z1\t%1
4621    #"
4622   [(set_attr "type" "fmov,multi")
4623    (set_attr "mode" "XF")
4624    (set_attr "fp_int_src" "true")])
4625
4626 (define_insn "floatsitf2"
4627   [(set (match_operand:TF 0 "register_operand" "=f,f")
4628         (float:TF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
4629   "TARGET_80387"
4630   "@
4631    fild%z1\t%1
4632    #"
4633   [(set_attr "type" "fmov,multi")
4634    (set_attr "mode" "XF")
4635    (set_attr "fp_int_src" "true")])
4636
4637 (define_insn "floatdixf2"
4638   [(set (match_operand:XF 0 "register_operand" "=f,f")
4639         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4640   "!TARGET_64BIT && TARGET_80387"
4641   "@
4642    fild%z1\t%1
4643    #"
4644   [(set_attr "type" "fmov,multi")
4645    (set_attr "mode" "XF")
4646    (set_attr "fp_int_src" "true")])
4647
4648 (define_insn "floatditf2"
4649   [(set (match_operand:TF 0 "register_operand" "=f,f")
4650         (float:TF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4651   "TARGET_80387"
4652   "@
4653    fild%z1\t%1
4654    #"
4655   [(set_attr "type" "fmov,multi")
4656    (set_attr "mode" "XF")
4657    (set_attr "fp_int_src" "true")])
4658
4659 ;; %%% Kill these when reload knows how to do it.
4660 (define_split
4661   [(set (match_operand 0 "register_operand" "")
4662         (float (match_operand 1 "register_operand" "")))]
4663   "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))
4664    && FP_REG_P (operands[0])"
4665   [(const_int 0)]
4666 {
4667   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4668   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4669   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4670   ix86_free_from_memory (GET_MODE (operands[1]));
4671   DONE;
4672 })
4673 \f
4674 ;; Add instructions
4675
4676 ;; %%% splits for addsidi3
4677 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4678 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4679 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4680
4681 (define_expand "adddi3"
4682   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4683         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4684                  (match_operand:DI 2 "x86_64_general_operand" "")))
4685    (clobber (reg:CC 17))]
4686   ""
4687   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4688
4689 (define_insn "*adddi3_1"
4690   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4691         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4692                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4693    (clobber (reg:CC 17))]
4694   "!TARGET_64BIT"
4695   "#")
4696
4697 (define_split
4698   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4699         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4700                  (match_operand:DI 2 "general_operand" "")))
4701    (clobber (reg:CC 17))]
4702   "!TARGET_64BIT && reload_completed"
4703   [(parallel [(set (reg:CC 17) (unspec:CC [(match_dup 1) (match_dup 2)]
4704                                           UNSPEC_ADD_CARRY))
4705               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4706    (parallel [(set (match_dup 3)
4707                    (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
4708                                      (match_dup 4))
4709                             (match_dup 5)))
4710               (clobber (reg:CC 17))])]
4711   "split_di (operands+0, 1, operands+0, operands+3);
4712    split_di (operands+1, 1, operands+1, operands+4);
4713    split_di (operands+2, 1, operands+2, operands+5);")
4714
4715 (define_insn "*adddi3_carry_rex64"
4716   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4717           (plus:DI (plus:DI (ltu:DI (reg:CC 17) (const_int 0))
4718                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4719                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4720    (clobber (reg:CC 17))]
4721   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4722   "adc{q}\t{%2, %0|%0, %2}"
4723   [(set_attr "type" "alu")
4724    (set_attr "pent_pair" "pu")
4725    (set_attr "mode" "DI")
4726    (set_attr "ppro_uops" "few")])
4727
4728 (define_insn "*adddi3_cc_rex64"
4729   [(set (reg:CC 17)
4730         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4731                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4732                    UNSPEC_ADD_CARRY))
4733    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4734         (plus:DI (match_dup 1) (match_dup 2)))]
4735   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4736   "add{q}\t{%2, %0|%0, %2}"
4737   [(set_attr "type" "alu")
4738    (set_attr "mode" "DI")])
4739
4740 (define_insn "*addsi3_carry"
4741   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4742           (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
4743                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4744                    (match_operand:SI 2 "general_operand" "ri,rm")))
4745    (clobber (reg:CC 17))]
4746   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4747   "adc{l}\t{%2, %0|%0, %2}"
4748   [(set_attr "type" "alu")
4749    (set_attr "pent_pair" "pu")
4750    (set_attr "mode" "SI")
4751    (set_attr "ppro_uops" "few")])
4752
4753 (define_insn "*addsi3_carry_zext"
4754   [(set (match_operand:DI 0 "register_operand" "=r")
4755           (zero_extend:DI 
4756             (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
4757                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4758                      (match_operand:SI 2 "general_operand" "rim"))))
4759    (clobber (reg:CC 17))]
4760   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4761   "adc{l}\t{%2, %k0|%k0, %2}"
4762   [(set_attr "type" "alu")
4763    (set_attr "pent_pair" "pu")
4764    (set_attr "mode" "SI")
4765    (set_attr "ppro_uops" "few")])
4766
4767 (define_insn "*addsi3_cc"
4768   [(set (reg:CC 17)
4769         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4770                     (match_operand:SI 2 "general_operand" "ri,rm")]
4771                    UNSPEC_ADD_CARRY))
4772    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4773         (plus:SI (match_dup 1) (match_dup 2)))]
4774   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4775   "add{l}\t{%2, %0|%0, %2}"
4776   [(set_attr "type" "alu")
4777    (set_attr "mode" "SI")])
4778
4779 (define_insn "addqi3_cc"
4780   [(set (reg:CC 17)
4781         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4782                     (match_operand:QI 2 "general_operand" "qi,qm")]
4783                    UNSPEC_ADD_CARRY))
4784    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4785         (plus:QI (match_dup 1) (match_dup 2)))]
4786   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4787   "add{b}\t{%2, %0|%0, %2}"
4788   [(set_attr "type" "alu")
4789    (set_attr "mode" "QI")])
4790
4791 (define_expand "addsi3"
4792   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4793                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4794                             (match_operand:SI 2 "general_operand" "")))
4795               (clobber (reg:CC 17))])]
4796   ""
4797   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4798
4799 (define_insn "*lea_1"
4800   [(set (match_operand:SI 0 "register_operand" "=r")
4801         (match_operand:SI 1 "address_operand" "p"))]
4802   "!TARGET_64BIT"
4803   "lea{l}\t{%a1, %0|%0, %a1}"
4804   [(set_attr "type" "lea")
4805    (set_attr "mode" "SI")])
4806
4807 (define_insn "*lea_1_rex64"
4808   [(set (match_operand:SI 0 "register_operand" "=r")
4809         (subreg:SI (match_operand:DI 1 "address_operand" "p") 0))]
4810   "TARGET_64BIT"
4811   "lea{l}\t{%a1, %0|%0, %a1}"
4812   [(set_attr "type" "lea")
4813    (set_attr "mode" "SI")])
4814
4815 (define_insn "*lea_1_zext"
4816   [(set (match_operand:DI 0 "register_operand" "=r")
4817         (zero_extend:DI (subreg:SI (match_operand:DI 1 "address_operand" "p") 0)))]
4818   "TARGET_64BIT"
4819   "lea{l}\t{%a1, %k0|%k0, %a1}"
4820   [(set_attr "type" "lea")
4821    (set_attr "mode" "SI")])
4822
4823 (define_insn "*lea_2_rex64"
4824   [(set (match_operand:DI 0 "register_operand" "=r")
4825         (match_operand:DI 1 "address_operand" "p"))]
4826   "TARGET_64BIT"
4827   "lea{q}\t{%a1, %0|%0, %a1}"
4828   [(set_attr "type" "lea")
4829    (set_attr "mode" "DI")])
4830
4831 ;; The lea patterns for non-Pmodes needs to be matched by several
4832 ;; insns converted to real lea by splitters.
4833
4834 (define_insn_and_split "*lea_general_1"
4835   [(set (match_operand 0 "register_operand" "=r")
4836         (plus (plus (match_operand 1 "register_operand" "r")
4837                     (match_operand 2 "register_operand" "r"))
4838               (match_operand 3 "immediate_operand" "i")))]
4839   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4840     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4841    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4842    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4843    && GET_MODE (operands[0]) == GET_MODE (operands[2])
4844    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4845        || GET_MODE (operands[3]) == VOIDmode)"
4846   "#"
4847   "&& reload_completed"
4848   [(const_int 0)]
4849 {
4850   rtx pat;
4851   operands[0] = gen_lowpart (SImode, operands[0]);
4852   operands[1] = gen_lowpart (Pmode, operands[1]);
4853   operands[2] = gen_lowpart (Pmode, operands[2]);
4854   operands[3] = gen_lowpart (Pmode, operands[3]);
4855   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4856                       operands[3]);
4857   if (Pmode != SImode)
4858     pat = gen_rtx_SUBREG (SImode, pat, 0);
4859   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4860   DONE;
4861 }
4862   [(set_attr "type" "lea")
4863    (set_attr "mode" "SI")])
4864
4865 (define_insn_and_split "*lea_general_1_zext"
4866   [(set (match_operand:DI 0 "register_operand" "=r")
4867         (zero_extend:DI
4868           (plus:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
4869                             (match_operand:SI 2 "register_operand" "r"))
4870                    (match_operand:SI 3 "immediate_operand" "i"))))]
4871   "TARGET_64BIT"
4872   "#"
4873   "&& reload_completed"
4874   [(set (match_dup 0)
4875         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4876                                                      (match_dup 2))
4877                                             (match_dup 3)) 0)))]
4878 {
4879   operands[1] = gen_lowpart (Pmode, operands[1]);
4880   operands[2] = gen_lowpart (Pmode, operands[2]);
4881   operands[3] = gen_lowpart (Pmode, operands[3]);
4882 }
4883   [(set_attr "type" "lea")
4884    (set_attr "mode" "SI")])
4885
4886 (define_insn_and_split "*lea_general_2"
4887   [(set (match_operand 0 "register_operand" "=r")
4888         (plus (mult (match_operand 1 "register_operand" "r")
4889                     (match_operand 2 "const248_operand" "i"))
4890               (match_operand 3 "nonmemory_operand" "ri")))]
4891   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4892     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4893    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4894    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4895    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4896        || GET_MODE (operands[3]) == VOIDmode)"
4897   "#"
4898   "&& reload_completed"
4899   [(const_int 0)]
4900 {
4901   rtx pat;
4902   operands[0] = gen_lowpart (SImode, operands[0]);
4903   operands[1] = gen_lowpart (Pmode, operands[1]);
4904   operands[3] = gen_lowpart (Pmode, operands[3]);
4905   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
4906                       operands[3]);
4907   if (Pmode != SImode)
4908     pat = gen_rtx_SUBREG (SImode, pat, 0);
4909   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4910   DONE;
4911 }
4912   [(set_attr "type" "lea")
4913    (set_attr "mode" "SI")])
4914
4915 (define_insn_and_split "*lea_general_2_zext"
4916   [(set (match_operand:DI 0 "register_operand" "=r")
4917         (zero_extend:DI
4918           (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
4919                             (match_operand:SI 2 "const248_operand" "n"))
4920                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
4921   "TARGET_64BIT"
4922   "#"
4923   "&& reload_completed"
4924   [(set (match_dup 0)
4925         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
4926                                                      (match_dup 2))
4927                                             (match_dup 3)) 0)))]
4928 {
4929   operands[1] = gen_lowpart (Pmode, operands[1]);
4930   operands[3] = gen_lowpart (Pmode, operands[3]);
4931 }
4932   [(set_attr "type" "lea")
4933    (set_attr "mode" "SI")])
4934
4935 (define_insn_and_split "*lea_general_3"
4936   [(set (match_operand 0 "register_operand" "=r")
4937         (plus (plus (mult (match_operand 1 "register_operand" "r")
4938                           (match_operand 2 "const248_operand" "i"))
4939                     (match_operand 3 "register_operand" "r"))
4940               (match_operand 4 "immediate_operand" "i")))]
4941   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4942     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4943    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4944    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4945    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
4946   "#"
4947   "&& reload_completed"
4948   [(const_int 0)]
4949 {
4950   rtx pat;
4951   operands[0] = gen_lowpart (SImode, operands[0]);
4952   operands[1] = gen_lowpart (Pmode, operands[1]);
4953   operands[3] = gen_lowpart (Pmode, operands[3]);
4954   operands[4] = gen_lowpart (Pmode, operands[4]);
4955   pat = gen_rtx_PLUS (Pmode,
4956                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
4957                                                          operands[2]),
4958                                     operands[3]),
4959                       operands[4]);
4960   if (Pmode != SImode)
4961     pat = gen_rtx_SUBREG (SImode, pat, 0);
4962   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4963   DONE;
4964 }
4965   [(set_attr "type" "lea")
4966    (set_attr "mode" "SI")])
4967
4968 (define_insn_and_split "*lea_general_3_zext"
4969   [(set (match_operand:DI 0 "register_operand" "=r")
4970         (zero_extend:DI
4971           (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
4972                                      (match_operand:SI 2 "const248_operand" "n"))
4973                             (match_operand:SI 3 "register_operand" "r"))
4974                    (match_operand:SI 4 "immediate_operand" "i"))))]
4975   "TARGET_64BIT"
4976   "#"
4977   "&& reload_completed"
4978   [(set (match_dup 0)
4979         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
4980                                                               (match_dup 2))
4981                                                      (match_dup 3))
4982                                             (match_dup 4)) 0)))]
4983 {
4984   operands[1] = gen_lowpart (Pmode, operands[1]);
4985   operands[3] = gen_lowpart (Pmode, operands[3]);
4986   operands[4] = gen_lowpart (Pmode, operands[4]);
4987 }
4988   [(set_attr "type" "lea")
4989    (set_attr "mode" "SI")])
4990
4991 (define_insn "*adddi_1_rex64"
4992   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
4993         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
4994                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,re")))
4995    (clobber (reg:CC 17))]
4996   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4997 {
4998   switch (get_attr_type (insn))
4999     {
5000     case TYPE_LEA:
5001       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5002       return "lea{q}\t{%a2, %0|%0, %a2}";
5003
5004     case TYPE_INCDEC:
5005       if (! rtx_equal_p (operands[0], operands[1]))
5006         abort ();
5007       if (operands[2] == const1_rtx)
5008         return "inc{q}\t%0";
5009       else if (operands[2] == constm1_rtx)
5010         return "dec{q}\t%0";
5011       else
5012         abort ();
5013
5014     default:
5015       if (! rtx_equal_p (operands[0], operands[1]))
5016         abort ();
5017
5018       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5019          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5020       if (GET_CODE (operands[2]) == CONST_INT
5021           /* Avoid overflows.  */
5022           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5023           && (INTVAL (operands[2]) == 128
5024               || (INTVAL (operands[2]) < 0
5025                   && INTVAL (operands[2]) != -128)))
5026         {
5027           operands[2] = GEN_INT (-INTVAL (operands[2]));
5028           return "sub{q}\t{%2, %0|%0, %2}";
5029         }
5030       return "add{q}\t{%2, %0|%0, %2}";
5031     }
5032 }
5033   [(set (attr "type")
5034      (cond [(eq_attr "alternative" "2")
5035               (const_string "lea")
5036             ; Current assemblers are broken and do not allow @GOTOFF in
5037             ; ought but a memory context.
5038             (match_operand:DI 2 "pic_symbolic_operand" "")
5039               (const_string "lea")
5040             (match_operand:DI 2 "incdec_operand" "")
5041               (const_string "incdec")
5042            ]
5043            (const_string "alu")))
5044    (set_attr "mode" "DI")])
5045
5046 ;; Convert lea to the lea pattern to avoid flags dependency.
5047 (define_split
5048   [(set (match_operand:DI 0 "register_operand" "")
5049         (plus:DI (match_operand:DI 1 "register_operand" "")
5050                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5051    (clobber (reg:CC 17))]
5052   "TARGET_64BIT && reload_completed
5053    && true_regnum (operands[0]) != true_regnum (operands[1])"
5054   [(set (match_dup 0)
5055         (plus:DI (match_dup 1)
5056                  (match_dup 2)))]
5057   "")
5058
5059 (define_insn "*adddi_2_rex64"
5060   [(set (reg 17)
5061         (compare
5062           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5063                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5064           (const_int 0)))                       
5065    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5066         (plus:DI (match_dup 1) (match_dup 2)))]
5067   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5068    && ix86_binary_operator_ok (PLUS, DImode, operands)
5069    /* Current assemblers are broken and do not allow @GOTOFF in
5070       ought but a memory context.  */
5071    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5072 {
5073   switch (get_attr_type (insn))
5074     {
5075     case TYPE_INCDEC:
5076       if (! rtx_equal_p (operands[0], operands[1]))
5077         abort ();
5078       if (operands[2] == const1_rtx)
5079         return "inc{q}\t%0";
5080       else if (operands[2] == constm1_rtx)
5081         return "dec{q}\t%0";
5082       else
5083         abort ();
5084
5085     default:
5086       if (! rtx_equal_p (operands[0], operands[1]))
5087         abort ();
5088       /* ???? We ought to handle there the 32bit case too
5089          - do we need new constrant?  */
5090       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5091          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5092       if (GET_CODE (operands[2]) == CONST_INT
5093           /* Avoid overflows.  */
5094           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5095           && (INTVAL (operands[2]) == 128
5096               || (INTVAL (operands[2]) < 0
5097                   && INTVAL (operands[2]) != -128)))
5098         {
5099           operands[2] = GEN_INT (-INTVAL (operands[2]));
5100           return "sub{q}\t{%2, %0|%0, %2}";
5101         }
5102       return "add{q}\t{%2, %0|%0, %2}";
5103     }
5104 }
5105   [(set (attr "type")
5106      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5107         (const_string "incdec")
5108         (const_string "alu")))
5109    (set_attr "mode" "DI")])
5110
5111 (define_insn "*adddi_3_rex64"
5112   [(set (reg 17)
5113         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5114                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5115    (clobber (match_scratch:DI 0 "=r"))]
5116   "TARGET_64BIT
5117    && ix86_match_ccmode (insn, CCZmode)
5118    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5119    /* Current assemblers are broken and do not allow @GOTOFF in
5120       ought but a memory context.  */
5121    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5122 {
5123   switch (get_attr_type (insn))
5124     {
5125     case TYPE_INCDEC:
5126       if (! rtx_equal_p (operands[0], operands[1]))
5127         abort ();
5128       if (operands[2] == const1_rtx)
5129         return "inc{q}\t%0";
5130       else if (operands[2] == constm1_rtx)
5131         return "dec{q}\t%0";
5132       else
5133         abort ();
5134
5135     default:
5136       if (! rtx_equal_p (operands[0], operands[1]))
5137         abort ();
5138       /* ???? We ought to handle there the 32bit case too
5139          - do we need new constrant?  */
5140       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5141          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5142       if (GET_CODE (operands[2]) == CONST_INT
5143           /* Avoid overflows.  */
5144           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5145           && (INTVAL (operands[2]) == 128
5146               || (INTVAL (operands[2]) < 0
5147                   && INTVAL (operands[2]) != -128)))
5148         {
5149           operands[2] = GEN_INT (-INTVAL (operands[2]));
5150           return "sub{q}\t{%2, %0|%0, %2}";
5151         }
5152       return "add{q}\t{%2, %0|%0, %2}";
5153     }
5154 }
5155   [(set (attr "type")
5156      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5157         (const_string "incdec")
5158         (const_string "alu")))
5159    (set_attr "mode" "DI")])
5160
5161 ; For comparisons against 1, -1 and 128, we may generate better code
5162 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5163 ; is matched then.  We can't accept general immediate, because for
5164 ; case of overflows,  the result is messed up.
5165 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5166 ; when negated.
5167 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5168 ; only for comparisons not depending on it.
5169 (define_insn "*adddi_4_rex64"
5170   [(set (reg 17)
5171         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5172                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5173    (clobber (match_scratch:DI 0 "=rm"))]
5174   "TARGET_64BIT
5175    &&  ix86_match_ccmode (insn, CCGCmode)"
5176 {
5177   switch (get_attr_type (insn))
5178     {
5179     case TYPE_INCDEC:
5180       if (operands[2] == constm1_rtx)
5181         return "inc{q}\t%0";
5182       else if (operands[2] == const1_rtx)
5183         return "dec{q}\t%0";
5184       else
5185         abort();
5186
5187     default:
5188       if (! rtx_equal_p (operands[0], operands[1]))
5189         abort ();
5190       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5191          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5192       if ((INTVAL (operands[2]) == -128
5193            || (INTVAL (operands[2]) > 0
5194                && INTVAL (operands[2]) != 128))
5195           /* Avoid overflows.  */
5196           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5197         return "sub{q}\t{%2, %0|%0, %2}";
5198       operands[2] = GEN_INT (-INTVAL (operands[2]));
5199       return "add{q}\t{%2, %0|%0, %2}";
5200     }
5201 }
5202   [(set (attr "type")
5203      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5204         (const_string "incdec")
5205         (const_string "alu")))
5206    (set_attr "mode" "DI")])
5207
5208 (define_insn "*adddi_5_rex64"
5209   [(set (reg 17)
5210         (compare
5211           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5212                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5213           (const_int 0)))                       
5214    (clobber (match_scratch:DI 0 "=r"))]
5215   "TARGET_64BIT
5216    && ix86_match_ccmode (insn, CCGOCmode)
5217    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5218    /* Current assemblers are broken and do not allow @GOTOFF in
5219       ought but a memory context.  */
5220    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5221 {
5222   switch (get_attr_type (insn))
5223     {
5224     case TYPE_INCDEC:
5225       if (! rtx_equal_p (operands[0], operands[1]))
5226         abort ();
5227       if (operands[2] == const1_rtx)
5228         return "inc{q}\t%0";
5229       else if (operands[2] == constm1_rtx)
5230         return "dec{q}\t%0";
5231       else
5232         abort();
5233
5234     default:
5235       if (! rtx_equal_p (operands[0], operands[1]))
5236         abort ();
5237       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5238          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5239       if (GET_CODE (operands[2]) == CONST_INT
5240           /* Avoid overflows.  */
5241           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5242           && (INTVAL (operands[2]) == 128
5243               || (INTVAL (operands[2]) < 0
5244                   && INTVAL (operands[2]) != -128)))
5245         {
5246           operands[2] = GEN_INT (-INTVAL (operands[2]));
5247           return "sub{q}\t{%2, %0|%0, %2}";
5248         }
5249       return "add{q}\t{%2, %0|%0, %2}";
5250     }
5251 }
5252   [(set (attr "type")
5253      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5254         (const_string "incdec")
5255         (const_string "alu")))
5256    (set_attr "mode" "DI")])
5257
5258
5259 (define_insn "*addsi_1"
5260   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5261         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5262                  (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
5263    (clobber (reg:CC 17))]
5264   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5265 {
5266   switch (get_attr_type (insn))
5267     {
5268     case TYPE_LEA:
5269       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5270       return "lea{l}\t{%a2, %0|%0, %a2}";
5271
5272     case TYPE_INCDEC:
5273       if (! rtx_equal_p (operands[0], operands[1]))
5274         abort ();
5275       if (operands[2] == const1_rtx)
5276         return "inc{l}\t%0";
5277       else if (operands[2] == constm1_rtx)
5278         return "dec{l}\t%0";
5279       else
5280         abort();
5281
5282     default:
5283       if (! rtx_equal_p (operands[0], operands[1]))
5284         abort ();
5285
5286       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5287          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5288       if (GET_CODE (operands[2]) == CONST_INT
5289           && (INTVAL (operands[2]) == 128
5290               || (INTVAL (operands[2]) < 0
5291                   && INTVAL (operands[2]) != -128)))
5292         {
5293           operands[2] = GEN_INT (-INTVAL (operands[2]));
5294           return "sub{l}\t{%2, %0|%0, %2}";
5295         }
5296       return "add{l}\t{%2, %0|%0, %2}";
5297     }
5298 }
5299   [(set (attr "type")
5300      (cond [(eq_attr "alternative" "2")
5301               (const_string "lea")
5302             ; Current assemblers are broken and do not allow @GOTOFF in
5303             ; ought but a memory context.
5304             (match_operand:SI 2 "pic_symbolic_operand" "")
5305               (const_string "lea")
5306             (match_operand:SI 2 "incdec_operand" "")
5307               (const_string "incdec")
5308            ]
5309            (const_string "alu")))
5310    (set_attr "mode" "SI")])
5311
5312 ;; Convert lea to the lea pattern to avoid flags dependency.
5313 (define_split
5314   [(set (match_operand 0 "register_operand" "")
5315         (plus (match_operand 1 "register_operand" "")
5316               (match_operand 2 "nonmemory_operand" "")))
5317    (clobber (reg:CC 17))]
5318   "reload_completed
5319    && true_regnum (operands[0]) != true_regnum (operands[1])"
5320   [(const_int 0)]
5321 {
5322   rtx pat;
5323   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5324      may confuse gen_lowpart.  */
5325   if (GET_MODE (operands[0]) != Pmode)
5326     {
5327       operands[1] = gen_lowpart (Pmode, operands[1]);
5328       operands[2] = gen_lowpart (Pmode, operands[2]);
5329     }
5330   operands[0] = gen_lowpart (SImode, operands[0]);
5331   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5332   if (Pmode != SImode)
5333     pat = gen_rtx_SUBREG (SImode, pat, 0);
5334   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5335   DONE;
5336 })
5337
5338 ;; It may seem that nonimmediate operand is proper one for operand 1.
5339 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5340 ;; we take care in ix86_binary_operator_ok to not allow two memory
5341 ;; operands so proper swapping will be done in reload.  This allow
5342 ;; patterns constructed from addsi_1 to match.
5343 (define_insn "addsi_1_zext"
5344   [(set (match_operand:DI 0 "register_operand" "=r,r")
5345         (zero_extend:DI
5346           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5347                    (match_operand:SI 2 "general_operand" "rmni,rni"))))
5348    (clobber (reg:CC 17))]
5349   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5350 {
5351   switch (get_attr_type (insn))
5352     {
5353     case TYPE_LEA:
5354       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5355       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5356
5357     case TYPE_INCDEC:
5358       if (operands[2] == const1_rtx)
5359         return "inc{l}\t%k0";
5360       else if (operands[2] == constm1_rtx)
5361         return "dec{l}\t%k0";
5362       else
5363         abort();
5364
5365     default:
5366       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5367          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5368       if (GET_CODE (operands[2]) == CONST_INT
5369           && (INTVAL (operands[2]) == 128
5370               || (INTVAL (operands[2]) < 0
5371                   && INTVAL (operands[2]) != -128)))
5372         {
5373           operands[2] = GEN_INT (-INTVAL (operands[2]));
5374           return "sub{l}\t{%2, %k0|%k0, %2}";
5375         }
5376       return "add{l}\t{%2, %k0|%k0, %2}";
5377     }
5378 }
5379   [(set (attr "type")
5380      (cond [(eq_attr "alternative" "1")
5381               (const_string "lea")
5382             ; Current assemblers are broken and do not allow @GOTOFF in
5383             ; ought but a memory context.
5384             (match_operand:SI 2 "pic_symbolic_operand" "")
5385               (const_string "lea")
5386             (match_operand:SI 2 "incdec_operand" "")
5387               (const_string "incdec")
5388            ]
5389            (const_string "alu")))
5390    (set_attr "mode" "SI")])
5391
5392 ;; Convert lea to the lea pattern to avoid flags dependency.
5393 (define_split
5394   [(set (match_operand:DI 0 "register_operand" "")
5395         (zero_extend:DI
5396           (plus:SI (match_operand:SI 1 "register_operand" "")
5397                    (match_operand:SI 2 "nonmemory_operand" ""))))
5398    (clobber (reg:CC 17))]
5399   "reload_completed
5400    && true_regnum (operands[0]) != true_regnum (operands[1])"
5401   [(set (match_dup 0)
5402         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5403 {
5404   operands[1] = gen_lowpart (Pmode, operands[1]);
5405   operands[2] = gen_lowpart (Pmode, operands[2]);
5406 })
5407
5408 (define_insn "*addsi_2"
5409   [(set (reg 17)
5410         (compare
5411           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5412                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5413           (const_int 0)))                       
5414    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5415         (plus:SI (match_dup 1) (match_dup 2)))]
5416   "ix86_match_ccmode (insn, CCGOCmode)
5417    && ix86_binary_operator_ok (PLUS, SImode, operands)
5418    /* Current assemblers are broken and do not allow @GOTOFF in
5419       ought but a memory context.  */
5420    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5421 {
5422   switch (get_attr_type (insn))
5423     {
5424     case TYPE_INCDEC:
5425       if (! rtx_equal_p (operands[0], operands[1]))
5426         abort ();
5427       if (operands[2] == const1_rtx)
5428         return "inc{l}\t%0";
5429       else if (operands[2] == constm1_rtx)
5430         return "dec{l}\t%0";
5431       else
5432         abort();
5433
5434     default:
5435       if (! rtx_equal_p (operands[0], operands[1]))
5436         abort ();
5437       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5438          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5439       if (GET_CODE (operands[2]) == CONST_INT
5440           && (INTVAL (operands[2]) == 128
5441               || (INTVAL (operands[2]) < 0
5442                   && INTVAL (operands[2]) != -128)))
5443         {
5444           operands[2] = GEN_INT (-INTVAL (operands[2]));
5445           return "sub{l}\t{%2, %0|%0, %2}";
5446         }
5447       return "add{l}\t{%2, %0|%0, %2}";
5448     }
5449 }
5450   [(set (attr "type")
5451      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5452         (const_string "incdec")
5453         (const_string "alu")))
5454    (set_attr "mode" "SI")])
5455
5456 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5457 (define_insn "*addsi_2_zext"
5458   [(set (reg 17)
5459         (compare
5460           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5461                    (match_operand:SI 2 "general_operand" "rmni"))
5462           (const_int 0)))                       
5463    (set (match_operand:DI 0 "register_operand" "=r")
5464         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5465   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5466    && ix86_binary_operator_ok (PLUS, SImode, operands)
5467    /* Current assemblers are broken and do not allow @GOTOFF in
5468       ought but a memory context.  */
5469    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5470 {
5471   switch (get_attr_type (insn))
5472     {
5473     case TYPE_INCDEC:
5474       if (operands[2] == const1_rtx)
5475         return "inc{l}\t%k0";
5476       else if (operands[2] == constm1_rtx)
5477         return "dec{l}\t%k0";
5478       else
5479         abort();
5480
5481     default:
5482       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5483          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5484       if (GET_CODE (operands[2]) == CONST_INT
5485           && (INTVAL (operands[2]) == 128
5486               || (INTVAL (operands[2]) < 0
5487                   && INTVAL (operands[2]) != -128)))
5488         {
5489           operands[2] = GEN_INT (-INTVAL (operands[2]));
5490           return "sub{l}\t{%2, %k0|%k0, %2}";
5491         }
5492       return "add{l}\t{%2, %k0|%k0, %2}";
5493     }
5494 }
5495   [(set (attr "type")
5496      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5497         (const_string "incdec")
5498         (const_string "alu")))
5499    (set_attr "mode" "SI")])
5500
5501 (define_insn "*addsi_3"
5502   [(set (reg 17)
5503         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5504                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5505    (clobber (match_scratch:SI 0 "=r"))]
5506   "ix86_match_ccmode (insn, CCZmode)
5507    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5508    /* Current assemblers are broken and do not allow @GOTOFF in
5509       ought but a memory context.  */
5510    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5511 {
5512   switch (get_attr_type (insn))
5513     {
5514     case TYPE_INCDEC:
5515       if (! rtx_equal_p (operands[0], operands[1]))
5516         abort ();
5517       if (operands[2] == const1_rtx)
5518         return "inc{l}\t%0";
5519       else if (operands[2] == constm1_rtx)
5520         return "dec{l}\t%0";
5521       else
5522         abort();
5523
5524     default:
5525       if (! rtx_equal_p (operands[0], operands[1]))
5526         abort ();
5527       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5528          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5529       if (GET_CODE (operands[2]) == CONST_INT
5530           && (INTVAL (operands[2]) == 128
5531               || (INTVAL (operands[2]) < 0
5532                   && INTVAL (operands[2]) != -128)))
5533         {
5534           operands[2] = GEN_INT (-INTVAL (operands[2]));
5535           return "sub{l}\t{%2, %0|%0, %2}";
5536         }
5537       return "add{l}\t{%2, %0|%0, %2}";
5538     }
5539 }
5540   [(set (attr "type")
5541      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5542         (const_string "incdec")
5543         (const_string "alu")))
5544    (set_attr "mode" "SI")])
5545
5546 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5547 (define_insn "*addsi_3_zext"
5548   [(set (reg 17)
5549         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5550                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5551    (set (match_operand:DI 0 "register_operand" "=r")
5552         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5553   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5554    && ix86_binary_operator_ok (PLUS, SImode, operands)
5555    /* Current assemblers are broken and do not allow @GOTOFF in
5556       ought but a memory context.  */
5557    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5558 {
5559   switch (get_attr_type (insn))
5560     {
5561     case TYPE_INCDEC:
5562       if (operands[2] == const1_rtx)
5563         return "inc{l}\t%k0";
5564       else if (operands[2] == constm1_rtx)
5565         return "dec{l}\t%k0";
5566       else
5567         abort();
5568
5569     default:
5570       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5571          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5572       if (GET_CODE (operands[2]) == CONST_INT
5573           && (INTVAL (operands[2]) == 128
5574               || (INTVAL (operands[2]) < 0
5575                   && INTVAL (operands[2]) != -128)))
5576         {
5577           operands[2] = GEN_INT (-INTVAL (operands[2]));
5578           return "sub{l}\t{%2, %k0|%k0, %2}";
5579         }
5580       return "add{l}\t{%2, %k0|%k0, %2}";
5581     }
5582 }
5583   [(set (attr "type")
5584      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5585         (const_string "incdec")
5586         (const_string "alu")))
5587    (set_attr "mode" "SI")])
5588
5589 ; For comparisons agains 1, -1 and 128, we may generate better code
5590 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5591 ; is matched then.  We can't accept general immediate, because for
5592 ; case of overflows,  the result is messed up.
5593 ; This pattern also don't hold of 0x80000000, since the value overflows
5594 ; when negated.
5595 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5596 ; only for comparisons not depending on it.
5597 (define_insn "*addsi_4"
5598   [(set (reg 17)
5599         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5600                  (match_operand:SI 2 "const_int_operand" "n")))
5601    (clobber (match_scratch:SI 0 "=rm"))]
5602   "ix86_match_ccmode (insn, CCGCmode)
5603    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5604 {
5605   switch (get_attr_type (insn))
5606     {
5607     case TYPE_INCDEC:
5608       if (operands[2] == constm1_rtx)
5609         return "inc{l}\t%0";
5610       else if (operands[2] == const1_rtx)
5611         return "dec{l}\t%0";
5612       else
5613         abort();
5614
5615     default:
5616       if (! rtx_equal_p (operands[0], operands[1]))
5617         abort ();
5618       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5619          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5620       if ((INTVAL (operands[2]) == -128
5621            || (INTVAL (operands[2]) > 0
5622                && INTVAL (operands[2]) != 128)))
5623         return "sub{l}\t{%2, %0|%0, %2}";
5624       operands[2] = GEN_INT (-INTVAL (operands[2]));
5625       return "add{l}\t{%2, %0|%0, %2}";
5626     }
5627 }
5628   [(set (attr "type")
5629      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5630         (const_string "incdec")
5631         (const_string "alu")))
5632    (set_attr "mode" "SI")])
5633
5634 (define_insn "*addsi_5"
5635   [(set (reg 17)
5636         (compare
5637           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5638                    (match_operand:SI 2 "general_operand" "rmni"))
5639           (const_int 0)))                       
5640    (clobber (match_scratch:SI 0 "=r"))]
5641   "ix86_match_ccmode (insn, CCGOCmode)
5642    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5643    /* Current assemblers are broken and do not allow @GOTOFF in
5644       ought but a memory context.  */
5645    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5646 {
5647   switch (get_attr_type (insn))
5648     {
5649     case TYPE_INCDEC:
5650       if (! rtx_equal_p (operands[0], operands[1]))
5651         abort ();
5652       if (operands[2] == const1_rtx)
5653         return "inc{l}\t%0";
5654       else if (operands[2] == constm1_rtx)
5655         return "dec{l}\t%0";
5656       else
5657         abort();
5658
5659     default:
5660       if (! rtx_equal_p (operands[0], operands[1]))
5661         abort ();
5662       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5663          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5664       if (GET_CODE (operands[2]) == CONST_INT
5665           && (INTVAL (operands[2]) == 128
5666               || (INTVAL (operands[2]) < 0
5667                   && INTVAL (operands[2]) != -128)))
5668         {
5669           operands[2] = GEN_INT (-INTVAL (operands[2]));
5670           return "sub{l}\t{%2, %0|%0, %2}";
5671         }
5672       return "add{l}\t{%2, %0|%0, %2}";
5673     }
5674 }
5675   [(set (attr "type")
5676      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5677         (const_string "incdec")
5678         (const_string "alu")))
5679    (set_attr "mode" "SI")])
5680
5681 (define_expand "addhi3"
5682   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5683                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5684                             (match_operand:HI 2 "general_operand" "")))
5685               (clobber (reg:CC 17))])]
5686   "TARGET_HIMODE_MATH"
5687   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5688
5689 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5690 ;; type optimizations enabled by define-splits.  This is not important
5691 ;; for PII, and in fact harmful because of partial register stalls.
5692
5693 (define_insn "*addhi_1_lea"
5694   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5695         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5696                  (match_operand:HI 2 "general_operand" "ri,rm,rni")))
5697    (clobber (reg:CC 17))]
5698   "!TARGET_PARTIAL_REG_STALL
5699    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5700 {
5701   switch (get_attr_type (insn))
5702     {
5703     case TYPE_LEA:
5704       return "#";
5705     case TYPE_INCDEC:
5706       if (operands[2] == const1_rtx)
5707         return "inc{w}\t%0";
5708       else if (operands[2] == constm1_rtx
5709                || (GET_CODE (operands[2]) == CONST_INT
5710                    && INTVAL (operands[2]) == 65535))
5711         return "dec{w}\t%0";
5712       abort();
5713
5714     default:
5715       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5716          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5717       if (GET_CODE (operands[2]) == CONST_INT
5718           && (INTVAL (operands[2]) == 128
5719               || (INTVAL (operands[2]) < 0
5720                   && INTVAL (operands[2]) != -128)))
5721         {
5722           operands[2] = GEN_INT (-INTVAL (operands[2]));
5723           return "sub{w}\t{%2, %0|%0, %2}";
5724         }
5725       return "add{w}\t{%2, %0|%0, %2}";
5726     }
5727 }
5728   [(set (attr "type")
5729      (if_then_else (eq_attr "alternative" "2")
5730         (const_string "lea")
5731         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5732            (const_string "incdec")
5733            (const_string "alu"))))
5734    (set_attr "mode" "HI,HI,SI")])
5735
5736 (define_insn "*addhi_1"
5737   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5738         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5739                  (match_operand:HI 2 "general_operand" "ri,rm")))
5740    (clobber (reg:CC 17))]
5741   "TARGET_PARTIAL_REG_STALL
5742    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5743 {
5744   switch (get_attr_type (insn))
5745     {
5746     case TYPE_INCDEC:
5747       if (operands[2] == const1_rtx)
5748         return "inc{w}\t%0";
5749       else if (operands[2] == constm1_rtx
5750                || (GET_CODE (operands[2]) == CONST_INT
5751                    && INTVAL (operands[2]) == 65535))
5752         return "dec{w}\t%0";
5753       abort();
5754
5755     default:
5756       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5757          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5758       if (GET_CODE (operands[2]) == CONST_INT
5759           && (INTVAL (operands[2]) == 128
5760               || (INTVAL (operands[2]) < 0
5761                   && INTVAL (operands[2]) != -128)))
5762         {
5763           operands[2] = GEN_INT (-INTVAL (operands[2]));
5764           return "sub{w}\t{%2, %0|%0, %2}";
5765         }
5766       return "add{w}\t{%2, %0|%0, %2}";
5767     }
5768 }
5769   [(set (attr "type")
5770      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5771         (const_string "incdec")
5772         (const_string "alu")))
5773    (set_attr "mode" "HI")])
5774
5775 (define_insn "*addhi_2"
5776   [(set (reg 17)
5777         (compare
5778           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5779                    (match_operand:HI 2 "general_operand" "rmni,rni"))
5780           (const_int 0)))                       
5781    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5782         (plus:HI (match_dup 1) (match_dup 2)))]
5783   "ix86_match_ccmode (insn, CCGOCmode)
5784    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5785 {
5786   switch (get_attr_type (insn))
5787     {
5788     case TYPE_INCDEC:
5789       if (operands[2] == const1_rtx)
5790         return "inc{w}\t%0";
5791       else if (operands[2] == constm1_rtx
5792                || (GET_CODE (operands[2]) == CONST_INT
5793                    && INTVAL (operands[2]) == 65535))
5794         return "dec{w}\t%0";
5795       abort();
5796
5797     default:
5798       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5799          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5800       if (GET_CODE (operands[2]) == CONST_INT
5801           && (INTVAL (operands[2]) == 128
5802               || (INTVAL (operands[2]) < 0
5803                   && INTVAL (operands[2]) != -128)))
5804         {
5805           operands[2] = GEN_INT (-INTVAL (operands[2]));
5806           return "sub{w}\t{%2, %0|%0, %2}";
5807         }
5808       return "add{w}\t{%2, %0|%0, %2}";
5809     }
5810 }
5811   [(set (attr "type")
5812      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5813         (const_string "incdec")
5814         (const_string "alu")))
5815    (set_attr "mode" "HI")])
5816
5817 (define_insn "*addhi_3"
5818   [(set (reg 17)
5819         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5820                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
5821    (clobber (match_scratch:HI 0 "=r"))]
5822   "ix86_match_ccmode (insn, CCZmode)
5823    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5824 {
5825   switch (get_attr_type (insn))
5826     {
5827     case TYPE_INCDEC:
5828       if (operands[2] == const1_rtx)
5829         return "inc{w}\t%0";
5830       else if (operands[2] == constm1_rtx
5831                || (GET_CODE (operands[2]) == CONST_INT
5832                    && INTVAL (operands[2]) == 65535))
5833         return "dec{w}\t%0";
5834       abort();
5835
5836     default:
5837       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5838          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5839       if (GET_CODE (operands[2]) == CONST_INT
5840           && (INTVAL (operands[2]) == 128
5841               || (INTVAL (operands[2]) < 0
5842                   && INTVAL (operands[2]) != -128)))
5843         {
5844           operands[2] = GEN_INT (-INTVAL (operands[2]));
5845           return "sub{w}\t{%2, %0|%0, %2}";
5846         }
5847       return "add{w}\t{%2, %0|%0, %2}";
5848     }
5849 }
5850   [(set (attr "type")
5851      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5852         (const_string "incdec")
5853         (const_string "alu")))
5854    (set_attr "mode" "HI")])
5855
5856 ; See comments above addsi_3_imm for details.
5857 (define_insn "*addhi_4"
5858   [(set (reg 17)
5859         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5860                  (match_operand:HI 2 "const_int_operand" "n")))
5861    (clobber (match_scratch:HI 0 "=rm"))]
5862   "ix86_match_ccmode (insn, CCGCmode)
5863    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5864 {
5865   switch (get_attr_type (insn))
5866     {
5867     case TYPE_INCDEC:
5868       if (operands[2] == constm1_rtx
5869           || (GET_CODE (operands[2]) == CONST_INT
5870               && INTVAL (operands[2]) == 65535))
5871         return "inc{w}\t%0";
5872       else if (operands[2] == const1_rtx)
5873         return "dec{w}\t%0";
5874       else
5875         abort();
5876
5877     default:
5878       if (! rtx_equal_p (operands[0], operands[1]))
5879         abort ();
5880       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5881          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5882       if ((INTVAL (operands[2]) == -128
5883            || (INTVAL (operands[2]) > 0
5884                && INTVAL (operands[2]) != 128)))
5885         return "sub{w}\t{%2, %0|%0, %2}";
5886       operands[2] = GEN_INT (-INTVAL (operands[2]));
5887       return "add{w}\t{%2, %0|%0, %2}";
5888     }
5889 }
5890   [(set (attr "type")
5891      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5892         (const_string "incdec")
5893         (const_string "alu")))
5894    (set_attr "mode" "SI")])
5895
5896
5897 (define_insn "*addhi_5"
5898   [(set (reg 17)
5899         (compare
5900           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
5901                    (match_operand:HI 2 "general_operand" "rmni"))
5902           (const_int 0)))                       
5903    (clobber (match_scratch:HI 0 "=r"))]
5904   "ix86_match_ccmode (insn, CCGOCmode)
5905    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5906 {
5907   switch (get_attr_type (insn))
5908     {
5909     case TYPE_INCDEC:
5910       if (operands[2] == const1_rtx)
5911         return "inc{w}\t%0";
5912       else if (operands[2] == constm1_rtx
5913                || (GET_CODE (operands[2]) == CONST_INT
5914                    && INTVAL (operands[2]) == 65535))
5915         return "dec{w}\t%0";
5916       abort();
5917
5918     default:
5919       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5920          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5921       if (GET_CODE (operands[2]) == CONST_INT
5922           && (INTVAL (operands[2]) == 128
5923               || (INTVAL (operands[2]) < 0
5924                   && INTVAL (operands[2]) != -128)))
5925         {
5926           operands[2] = GEN_INT (-INTVAL (operands[2]));
5927           return "sub{w}\t{%2, %0|%0, %2}";
5928         }
5929       return "add{w}\t{%2, %0|%0, %2}";
5930     }
5931 }
5932   [(set (attr "type")
5933      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5934         (const_string "incdec")
5935         (const_string "alu")))
5936    (set_attr "mode" "HI")])
5937
5938 (define_expand "addqi3"
5939   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
5940                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
5941                             (match_operand:QI 2 "general_operand" "")))
5942               (clobber (reg:CC 17))])]
5943   "TARGET_QIMODE_MATH"
5944   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
5945
5946 ;; %%% Potential partial reg stall on alternative 2.  What to do?
5947 (define_insn "*addqi_1_lea"
5948   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
5949         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
5950                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn")))
5951    (clobber (reg:CC 17))]
5952   "!TARGET_PARTIAL_REG_STALL
5953    && ix86_binary_operator_ok (PLUS, QImode, operands)"
5954 {
5955   int widen = (which_alternative == 2);
5956   switch (get_attr_type (insn))
5957     {
5958     case TYPE_LEA:
5959       return "#";
5960     case TYPE_INCDEC:
5961       if (operands[2] == const1_rtx)
5962         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5963       else if (operands[2] == constm1_rtx
5964                || (GET_CODE (operands[2]) == CONST_INT
5965                    && INTVAL (operands[2]) == 255))
5966         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5967       abort();
5968
5969     default:
5970       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5971          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5972       if (GET_CODE (operands[2]) == CONST_INT
5973           && (INTVAL (operands[2]) == 128
5974               || (INTVAL (operands[2]) < 0
5975                   && INTVAL (operands[2]) != -128)))
5976         {
5977           operands[2] = GEN_INT (-INTVAL (operands[2]));
5978           if (widen)
5979             return "sub{l}\t{%2, %k0|%k0, %2}";
5980           else
5981             return "sub{b}\t{%2, %0|%0, %2}";
5982         }
5983       if (widen)
5984         return "add{l}\t{%k2, %k0|%k0, %k2}";
5985       else
5986         return "add{b}\t{%2, %0|%0, %2}";
5987     }
5988 }
5989   [(set (attr "type")
5990      (if_then_else (eq_attr "alternative" "3")
5991         (const_string "lea")
5992         (if_then_else (match_operand:QI 2 "incdec_operand" "")
5993            (const_string "incdec")
5994            (const_string "alu"))))
5995    (set_attr "mode" "QI,QI,SI,SI")])
5996
5997 (define_insn "*addqi_1"
5998   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5999         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6000                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6001    (clobber (reg:CC 17))]
6002   "TARGET_PARTIAL_REG_STALL
6003    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6004 {
6005   int widen = (which_alternative == 2);
6006   switch (get_attr_type (insn))
6007     {
6008     case TYPE_INCDEC:
6009       if (operands[2] == const1_rtx)
6010         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6011       else if (operands[2] == constm1_rtx
6012                || (GET_CODE (operands[2]) == CONST_INT
6013                    && INTVAL (operands[2]) == 255))
6014         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6015       abort();
6016
6017     default:
6018       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6019          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6020       if (GET_CODE (operands[2]) == CONST_INT
6021           && (INTVAL (operands[2]) == 128
6022               || (INTVAL (operands[2]) < 0
6023                   && INTVAL (operands[2]) != -128)))
6024         {
6025           operands[2] = GEN_INT (-INTVAL (operands[2]));
6026           if (widen)
6027             return "sub{l}\t{%2, %k0|%k0, %2}";
6028           else
6029             return "sub{b}\t{%2, %0|%0, %2}";
6030         }
6031       if (widen)
6032         return "add{l}\t{%k2, %k0|%k0, %k2}";
6033       else
6034         return "add{b}\t{%2, %0|%0, %2}";
6035     }
6036 }
6037   [(set (attr "type")
6038      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6039         (const_string "incdec")
6040         (const_string "alu")))
6041    (set_attr "mode" "QI,QI,SI")])
6042
6043 (define_insn "*addqi_2"
6044   [(set (reg 17)
6045         (compare
6046           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6047                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6048           (const_int 0)))
6049    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6050         (plus:QI (match_dup 1) (match_dup 2)))]
6051   "ix86_match_ccmode (insn, CCGOCmode)
6052    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6053 {
6054   switch (get_attr_type (insn))
6055     {
6056     case TYPE_INCDEC:
6057       if (operands[2] == const1_rtx)
6058         return "inc{b}\t%0";
6059       else if (operands[2] == constm1_rtx
6060                || (GET_CODE (operands[2]) == CONST_INT
6061                    && INTVAL (operands[2]) == 255))
6062         return "dec{b}\t%0";
6063       abort();
6064
6065     default:
6066       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6067       if (GET_CODE (operands[2]) == CONST_INT
6068           && INTVAL (operands[2]) < 0)
6069         {
6070           operands[2] = GEN_INT (-INTVAL (operands[2]));
6071           return "sub{b}\t{%2, %0|%0, %2}";
6072         }
6073       return "add{b}\t{%2, %0|%0, %2}";
6074     }
6075 }
6076   [(set (attr "type")
6077      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6078         (const_string "incdec")
6079         (const_string "alu")))
6080    (set_attr "mode" "QI")])
6081
6082 (define_insn "*addqi_3"
6083   [(set (reg 17)
6084         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6085                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6086    (clobber (match_scratch:QI 0 "=q"))]
6087   "ix86_match_ccmode (insn, CCZmode)
6088    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6089 {
6090   switch (get_attr_type (insn))
6091     {
6092     case TYPE_INCDEC:
6093       if (operands[2] == const1_rtx)
6094         return "inc{b}\t%0";
6095       else if (operands[2] == constm1_rtx
6096                || (GET_CODE (operands[2]) == CONST_INT
6097                    && INTVAL (operands[2]) == 255))
6098         return "dec{b}\t%0";
6099       abort();
6100
6101     default:
6102       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6103       if (GET_CODE (operands[2]) == CONST_INT
6104           && INTVAL (operands[2]) < 0)
6105         {
6106           operands[2] = GEN_INT (-INTVAL (operands[2]));
6107           return "sub{b}\t{%2, %0|%0, %2}";
6108         }
6109       return "add{b}\t{%2, %0|%0, %2}";
6110     }
6111 }
6112   [(set (attr "type")
6113      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6114         (const_string "incdec")
6115         (const_string "alu")))
6116    (set_attr "mode" "QI")])
6117
6118 ; See comments above addsi_3_imm for details.
6119 (define_insn "*addqi_4"
6120   [(set (reg 17)
6121         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6122                  (match_operand:QI 2 "const_int_operand" "n")))
6123    (clobber (match_scratch:QI 0 "=qm"))]
6124   "ix86_match_ccmode (insn, CCGCmode)
6125    && (INTVAL (operands[2]) & 0xff) != 0x80"
6126 {
6127   switch (get_attr_type (insn))
6128     {
6129     case TYPE_INCDEC:
6130       if (operands[2] == constm1_rtx
6131           || (GET_CODE (operands[2]) == CONST_INT
6132               && INTVAL (operands[2]) == 255))
6133         return "inc{b}\t%0";
6134       else if (operands[2] == const1_rtx)
6135         return "dec{b}\t%0";
6136       else
6137         abort();
6138
6139     default:
6140       if (! rtx_equal_p (operands[0], operands[1]))
6141         abort ();
6142       if (INTVAL (operands[2]) < 0)
6143         {
6144           operands[2] = GEN_INT (-INTVAL (operands[2]));
6145           return "add{b}\t{%2, %0|%0, %2}";
6146         }
6147       return "sub{b}\t{%2, %0|%0, %2}";
6148     }
6149 }
6150   [(set (attr "type")
6151      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6152         (const_string "incdec")
6153         (const_string "alu")))
6154    (set_attr "mode" "QI")])
6155
6156
6157 (define_insn "*addqi_5"
6158   [(set (reg 17)
6159         (compare
6160           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6161                    (match_operand:QI 2 "general_operand" "qmni"))
6162           (const_int 0)))
6163    (clobber (match_scratch:QI 0 "=q"))]
6164   "ix86_match_ccmode (insn, CCGOCmode)
6165    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6166 {
6167   switch (get_attr_type (insn))
6168     {
6169     case TYPE_INCDEC:
6170       if (operands[2] == const1_rtx)
6171         return "inc{b}\t%0";
6172       else if (operands[2] == constm1_rtx
6173                || (GET_CODE (operands[2]) == CONST_INT
6174                    && INTVAL (operands[2]) == 255))
6175         return "dec{b}\t%0";
6176       abort();
6177
6178     default:
6179       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6180       if (GET_CODE (operands[2]) == CONST_INT
6181           && INTVAL (operands[2]) < 0)
6182         {
6183           operands[2] = GEN_INT (-INTVAL (operands[2]));
6184           return "sub{b}\t{%2, %0|%0, %2}";
6185         }
6186       return "add{b}\t{%2, %0|%0, %2}";
6187     }
6188 }
6189   [(set (attr "type")
6190      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6191         (const_string "incdec")
6192         (const_string "alu")))
6193    (set_attr "mode" "QI")])
6194
6195
6196 (define_insn "addqi_ext_1"
6197   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6198                          (const_int 8)
6199                          (const_int 8))
6200         (plus:SI
6201           (zero_extract:SI
6202             (match_operand 1 "ext_register_operand" "0")
6203             (const_int 8)
6204             (const_int 8))
6205           (match_operand:QI 2 "general_operand" "Qmn")))
6206    (clobber (reg:CC 17))]
6207   "!TARGET_64BIT"
6208 {
6209   switch (get_attr_type (insn))
6210     {
6211     case TYPE_INCDEC:
6212       if (operands[2] == const1_rtx)
6213         return "inc{b}\t%h0";
6214       else if (operands[2] == constm1_rtx
6215                || (GET_CODE (operands[2]) == CONST_INT
6216                    && INTVAL (operands[2]) == 255))
6217         return "dec{b}\t%h0";
6218       abort();
6219
6220     default:
6221       return "add{b}\t{%2, %h0|%h0, %2}";
6222     }
6223 }
6224   [(set (attr "type")
6225      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6226         (const_string "incdec")
6227         (const_string "alu")))
6228    (set_attr "mode" "QI")])
6229
6230 (define_insn "*addqi_ext_1_rex64"
6231   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6232                          (const_int 8)
6233                          (const_int 8))
6234         (plus:SI
6235           (zero_extract:SI
6236             (match_operand 1 "ext_register_operand" "0")
6237             (const_int 8)
6238             (const_int 8))
6239           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6240    (clobber (reg:CC 17))]
6241   "TARGET_64BIT"
6242 {
6243   switch (get_attr_type (insn))
6244     {
6245     case TYPE_INCDEC:
6246       if (operands[2] == const1_rtx)
6247         return "inc{b}\t%h0";
6248       else if (operands[2] == constm1_rtx
6249                || (GET_CODE (operands[2]) == CONST_INT
6250                    && INTVAL (operands[2]) == 255))
6251         return "dec{b}\t%h0";
6252       abort();
6253
6254     default:
6255       return "add{b}\t{%2, %h0|%h0, %2}";
6256     }
6257 }
6258   [(set (attr "type")
6259      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6260         (const_string "incdec")
6261         (const_string "alu")))
6262    (set_attr "mode" "QI")])
6263
6264 (define_insn "*addqi_ext_2"
6265   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6266                          (const_int 8)
6267                          (const_int 8))
6268         (plus:SI
6269           (zero_extract:SI
6270             (match_operand 1 "ext_register_operand" "%0")
6271             (const_int 8)
6272             (const_int 8))
6273           (zero_extract:SI
6274             (match_operand 2 "ext_register_operand" "Q")
6275             (const_int 8)
6276             (const_int 8))))
6277    (clobber (reg:CC 17))]
6278   ""
6279   "add{b}\t{%h2, %h0|%h0, %h2}"
6280   [(set_attr "type" "alu")
6281    (set_attr "mode" "QI")])
6282
6283 ;; The patterns that match these are at the end of this file.
6284
6285 (define_expand "addxf3"
6286   [(set (match_operand:XF 0 "register_operand" "")
6287         (plus:XF (match_operand:XF 1 "register_operand" "")
6288                  (match_operand:XF 2 "register_operand" "")))]
6289   "!TARGET_64BIT && TARGET_80387"
6290   "")
6291
6292 (define_expand "addtf3"
6293   [(set (match_operand:TF 0 "register_operand" "")
6294         (plus:TF (match_operand:TF 1 "register_operand" "")
6295                  (match_operand:TF 2 "register_operand" "")))]
6296   "TARGET_80387"
6297   "")
6298
6299 (define_expand "adddf3"
6300   [(set (match_operand:DF 0 "register_operand" "")
6301         (plus:DF (match_operand:DF 1 "register_operand" "")
6302                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6303   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6304   "")
6305
6306 (define_expand "addsf3"
6307   [(set (match_operand:SF 0 "register_operand" "")
6308         (plus:SF (match_operand:SF 1 "register_operand" "")
6309                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6310   "TARGET_80387 || TARGET_SSE_MATH"
6311   "")
6312 \f
6313 ;; Subtract instructions
6314
6315 ;; %%% splits for subsidi3
6316
6317 (define_expand "subdi3"
6318   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6319                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6320                              (match_operand:DI 2 "x86_64_general_operand" "")))
6321               (clobber (reg:CC 17))])]
6322   ""
6323   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6324
6325 (define_insn "*subdi3_1"
6326   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6327         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6328                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6329    (clobber (reg:CC 17))]
6330   "!TARGET_64BIT"
6331   "#")
6332
6333 (define_split
6334   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6335         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6336                   (match_operand:DI 2 "general_operand" "")))
6337    (clobber (reg:CC 17))]
6338   "!TARGET_64BIT && reload_completed"
6339   [(parallel [(set (reg:CC 17) (compare:CC (match_dup 1) (match_dup 2)))
6340               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6341    (parallel [(set (match_dup 3)
6342                    (minus:SI (match_dup 4)
6343                              (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
6344                                       (match_dup 5))))
6345               (clobber (reg:CC 17))])]
6346   "split_di (operands+0, 1, operands+0, operands+3);
6347    split_di (operands+1, 1, operands+1, operands+4);
6348    split_di (operands+2, 1, operands+2, operands+5);")
6349
6350 (define_insn "subdi3_carry_rex64"
6351   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6352           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6353             (plus:DI (ltu:DI (reg:CC 17) (const_int 0))
6354                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6355    (clobber (reg:CC 17))]
6356   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6357   "sbb{q}\t{%2, %0|%0, %2}"
6358   [(set_attr "type" "alu")
6359    (set_attr "pent_pair" "pu")
6360    (set_attr "ppro_uops" "few")
6361    (set_attr "mode" "DI")])
6362
6363 (define_insn "*subdi_1_rex64"
6364   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6365         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6366                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6367    (clobber (reg:CC 17))]
6368   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6369   "sub{q}\t{%2, %0|%0, %2}"
6370   [(set_attr "type" "alu")
6371    (set_attr "mode" "DI")])
6372
6373 (define_insn "*subdi_2_rex64"
6374   [(set (reg 17)
6375         (compare
6376           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6377                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6378           (const_int 0)))
6379    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6380         (minus:DI (match_dup 1) (match_dup 2)))]
6381   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6382    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6383   "sub{q}\t{%2, %0|%0, %2}"
6384   [(set_attr "type" "alu")
6385    (set_attr "mode" "DI")])
6386
6387 (define_insn "*subdi_3_rex63"
6388   [(set (reg 17)
6389         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6390                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6391    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6392         (minus:DI (match_dup 1) (match_dup 2)))]
6393   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6394    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6395   "sub{q}\t{%2, %0|%0, %2}"
6396   [(set_attr "type" "alu")
6397    (set_attr "mode" "DI")])
6398
6399
6400 (define_insn "subsi3_carry"
6401   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6402           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6403             (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
6404                (match_operand:SI 2 "general_operand" "ri,rm"))))
6405    (clobber (reg:CC 17))]
6406   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6407   "sbb{l}\t{%2, %0|%0, %2}"
6408   [(set_attr "type" "alu")
6409    (set_attr "pent_pair" "pu")
6410    (set_attr "ppro_uops" "few")
6411    (set_attr "mode" "SI")])
6412
6413 (define_insn "subsi3_carry_zext"
6414   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6415           (zero_extend:DI
6416             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6417               (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
6418                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6419    (clobber (reg:CC 17))]
6420   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6421   "sbb{l}\t{%2, %k0|%k0, %2}"
6422   [(set_attr "type" "alu")
6423    (set_attr "pent_pair" "pu")
6424    (set_attr "ppro_uops" "few")
6425    (set_attr "mode" "SI")])
6426
6427 (define_expand "subsi3"
6428   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6429                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6430                              (match_operand:SI 2 "general_operand" "")))
6431               (clobber (reg:CC 17))])]
6432   ""
6433   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6434
6435 (define_insn "*subsi_1"
6436   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6437         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6438                   (match_operand:SI 2 "general_operand" "ri,rm")))
6439    (clobber (reg:CC 17))]
6440   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6441   "sub{l}\t{%2, %0|%0, %2}"
6442   [(set_attr "type" "alu")
6443    (set_attr "mode" "SI")])
6444
6445 (define_insn "*subsi_1_zext"
6446   [(set (match_operand:DI 0 "register_operand" "=r")
6447         (zero_extend:DI
6448           (minus:SI (match_operand:SI 1 "register_operand" "0")
6449                     (match_operand:SI 2 "general_operand" "rim"))))
6450    (clobber (reg:CC 17))]
6451   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6452   "sub{l}\t{%2, %k0|%k0, %2}"
6453   [(set_attr "type" "alu")
6454    (set_attr "mode" "SI")])
6455
6456 (define_insn "*subsi_2"
6457   [(set (reg 17)
6458         (compare
6459           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6460                     (match_operand:SI 2 "general_operand" "ri,rm"))
6461           (const_int 0)))
6462    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6463         (minus:SI (match_dup 1) (match_dup 2)))]
6464   "ix86_match_ccmode (insn, CCGOCmode)
6465    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6466   "sub{l}\t{%2, %0|%0, %2}"
6467   [(set_attr "type" "alu")
6468    (set_attr "mode" "SI")])
6469
6470 (define_insn "*subsi_2_zext"
6471   [(set (reg 17)
6472         (compare
6473           (minus:SI (match_operand:SI 1 "register_operand" "0")
6474                     (match_operand:SI 2 "general_operand" "rim"))
6475           (const_int 0)))
6476    (set (match_operand:DI 0 "register_operand" "=r")
6477         (zero_extend:DI
6478           (minus:SI (match_dup 1)
6479                     (match_dup 2))))]
6480   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6481    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6482   "sub{l}\t{%2, %k0|%k0, %2}"
6483   [(set_attr "type" "alu")
6484    (set_attr "mode" "SI")])
6485
6486 (define_insn "*subsi_3"
6487   [(set (reg 17)
6488         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6489                  (match_operand:SI 2 "general_operand" "ri,rm")))
6490    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6491         (minus:SI (match_dup 1) (match_dup 2)))]
6492   "ix86_match_ccmode (insn, CCmode)
6493    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6494   "sub{l}\t{%2, %0|%0, %2}"
6495   [(set_attr "type" "alu")
6496    (set_attr "mode" "SI")])
6497
6498 (define_insn "*subsi_3_zext"
6499   [(set (reg 17)
6500         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6501                  (match_operand:SI 2 "general_operand" "rim")))
6502    (set (match_operand:DI 0 "register_operand" "=r")
6503         (zero_extend:DI
6504           (minus:SI (match_dup 1)
6505                     (match_dup 2))))]
6506   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6507    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6508   "sub{q}\t{%2, %0|%0, %2}"
6509   [(set_attr "type" "alu")
6510    (set_attr "mode" "DI")])
6511
6512 (define_expand "subhi3"
6513   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6514                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6515                              (match_operand:HI 2 "general_operand" "")))
6516               (clobber (reg:CC 17))])]
6517   "TARGET_HIMODE_MATH"
6518   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6519
6520 (define_insn "*subhi_1"
6521   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6522         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6523                   (match_operand:HI 2 "general_operand" "ri,rm")))
6524    (clobber (reg:CC 17))]
6525   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6526   "sub{w}\t{%2, %0|%0, %2}"
6527   [(set_attr "type" "alu")
6528    (set_attr "mode" "HI")])
6529
6530 (define_insn "*subhi_2"
6531   [(set (reg 17)
6532         (compare
6533           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6534                     (match_operand:HI 2 "general_operand" "ri,rm"))
6535           (const_int 0)))
6536    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6537         (minus:HI (match_dup 1) (match_dup 2)))]
6538   "ix86_match_ccmode (insn, CCGOCmode)
6539    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6540   "sub{w}\t{%2, %0|%0, %2}"
6541   [(set_attr "type" "alu")
6542    (set_attr "mode" "HI")])
6543
6544 (define_insn "*subhi_3"
6545   [(set (reg 17)
6546         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6547                  (match_operand:HI 2 "general_operand" "ri,rm")))
6548    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6549         (minus:HI (match_dup 1) (match_dup 2)))]
6550   "ix86_match_ccmode (insn, CCmode)
6551    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6552   "sub{w}\t{%2, %0|%0, %2}"
6553   [(set_attr "type" "alu")
6554    (set_attr "mode" "HI")])
6555
6556 (define_expand "subqi3"
6557   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6558                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6559                              (match_operand:QI 2 "general_operand" "")))
6560               (clobber (reg:CC 17))])]
6561   "TARGET_QIMODE_MATH"
6562   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6563
6564 (define_insn "*subqi_1"
6565   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6566         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6567                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6568    (clobber (reg:CC 17))]
6569   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6570   "sub{b}\t{%2, %0|%0, %2}"
6571   [(set_attr "type" "alu")
6572    (set_attr "mode" "QI")])
6573
6574 (define_insn "*subqi_2"
6575   [(set (reg 17)
6576         (compare
6577           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6578                     (match_operand:QI 2 "general_operand" "qi,qm"))
6579           (const_int 0)))
6580    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6581         (minus:HI (match_dup 1) (match_dup 2)))]
6582   "ix86_match_ccmode (insn, CCGOCmode)
6583    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6584   "sub{b}\t{%2, %0|%0, %2}"
6585   [(set_attr "type" "alu")
6586    (set_attr "mode" "QI")])
6587
6588 (define_insn "*subqi_3"
6589   [(set (reg 17)
6590         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6591                  (match_operand:QI 2 "general_operand" "qi,qm")))
6592    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6593         (minus:HI (match_dup 1) (match_dup 2)))]
6594   "ix86_match_ccmode (insn, CCmode)
6595    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6596   "sub{b}\t{%2, %0|%0, %2}"
6597   [(set_attr "type" "alu")
6598    (set_attr "mode" "QI")])
6599
6600 ;; The patterns that match these are at the end of this file.
6601
6602 (define_expand "subxf3"
6603   [(set (match_operand:XF 0 "register_operand" "")
6604         (minus:XF (match_operand:XF 1 "register_operand" "")
6605                   (match_operand:XF 2 "register_operand" "")))]
6606   "!TARGET_64BIT && TARGET_80387"
6607   "")
6608
6609 (define_expand "subtf3"
6610   [(set (match_operand:TF 0 "register_operand" "")
6611         (minus:TF (match_operand:TF 1 "register_operand" "")
6612                   (match_operand:TF 2 "register_operand" "")))]
6613   "TARGET_80387"
6614   "")
6615
6616 (define_expand "subdf3"
6617   [(set (match_operand:DF 0 "register_operand" "")
6618         (minus:DF (match_operand:DF 1 "register_operand" "")
6619                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6620   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6621   "")
6622
6623 (define_expand "subsf3"
6624   [(set (match_operand:SF 0 "register_operand" "")
6625         (minus:SF (match_operand:SF 1 "register_operand" "")
6626                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6627   "TARGET_80387 || TARGET_SSE_MATH"
6628   "")
6629 \f
6630 ;; Multiply instructions
6631
6632 (define_expand "muldi3"
6633   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6634                    (mult:DI (match_operand:DI 1 "register_operand" "")
6635                             (match_operand:DI 2 "x86_64_general_operand" "")))
6636               (clobber (reg:CC 17))])]
6637   "TARGET_64BIT"
6638   "")
6639
6640 (define_insn "*muldi3_1_rex64"
6641   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6642         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,0,0")
6643                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6644    (clobber (reg:CC 17))]
6645   "TARGET_64BIT
6646    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6647   "@
6648    imul{q}\t{%2, %1, %0|%0, %1, %2}
6649    imul{q}\t{%2, %1, %0|%0, %1, %2}
6650    imul{q}\t{%2, %0|%0, %2}"
6651   [(set_attr "type" "imul")
6652    (set_attr "prefix_0f" "0,0,1")
6653    (set_attr "mode" "DI")])
6654
6655 (define_expand "mulsi3"
6656   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6657                    (mult:SI (match_operand:SI 1 "register_operand" "")
6658                             (match_operand:SI 2 "general_operand" "")))
6659               (clobber (reg:CC 17))])]
6660   ""
6661   "")
6662
6663 (define_insn "*mulsi3_1"
6664   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6665         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,0,0")
6666                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6667    (clobber (reg:CC 17))]
6668   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6669   ; For the {r,0,i} alternative (i.e., register <- register * immediate),
6670   ; there are two ways of writing the exact same machine instruction
6671   ; in assembly language.  One, for example, is:
6672   ;
6673   ;   imul $12, %eax
6674   ;
6675   ; while the other is:
6676   ;
6677   ;   imul $12, %eax, %eax
6678   ;
6679   ; The first is simply short-hand for the latter.  But, some assemblers,
6680   ; like the SCO OSR5 COFF assembler, don't handle the first form.
6681   "@
6682    imul{l}\t{%2, %1, %0|%0, %1, %2}
6683    imul{l}\t{%2, %1, %0|%0, %1, %2}
6684    imul{l}\t{%2, %0|%0, %2}"
6685   [(set_attr "type" "imul")
6686    (set_attr "prefix_0f" "0,0,1")
6687    (set_attr "mode" "SI")])
6688
6689 (define_insn "*mulsi3_1_zext"
6690   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6691         (zero_extend:DI
6692           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,0,0")
6693                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6694    (clobber (reg:CC 17))]
6695   "TARGET_64BIT
6696    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6697   ; For the {r,0,i} alternative (i.e., register <- register * immediate),
6698   ; there are two ways of writing the exact same machine instruction
6699   ; in assembly language.  One, for example, is:
6700   ;
6701   ;   imul $12, %eax
6702   ;
6703   ; while the other is:
6704   ;
6705   ;   imul $12, %eax, %eax
6706   ;
6707   ; The first is simply short-hand for the latter.  But, some assemblers,
6708   ; like the SCO OSR5 COFF assembler, don't handle the first form.
6709   "@
6710    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6711    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6712    imul{l}\t{%2, %k0|%k0, %2}"
6713   [(set_attr "type" "imul")
6714    (set_attr "prefix_0f" "0,0,1")
6715    (set_attr "mode" "SI")])
6716
6717 (define_expand "mulhi3"
6718   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6719                    (mult:HI (match_operand:HI 1 "register_operand" "")
6720                             (match_operand:HI 2 "general_operand" "")))
6721               (clobber (reg:CC 17))])]
6722   "TARGET_HIMODE_MATH"
6723   "")
6724
6725 (define_insn "*mulhi3_1"
6726   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6727         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,0,0")
6728                  (match_operand:HI 2 "general_operand" "K,i,mr")))
6729    (clobber (reg:CC 17))]
6730   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6731   ; %%% There was a note about "Assembler has weird restrictions",
6732   ; concerning alternative 1 when op1 == op0.  True?
6733   "@
6734    imul{w}\t{%2, %1, %0|%0, %1, %2}
6735    imul{w}\t{%2, %1, %0|%0, %1, %2}
6736    imul{w}\t{%2, %0|%0, %2}"
6737   [(set_attr "type" "imul")
6738    (set_attr "prefix_0f" "0,0,1")
6739    (set_attr "mode" "HI")])
6740
6741 (define_expand "mulqi3"
6742   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6743                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6744                             (match_operand:QI 2 "register_operand" "")))
6745               (clobber (reg:CC 17))])]
6746   "TARGET_QIMODE_MATH"
6747   "")
6748
6749 (define_insn "*mulqi3_1"
6750   [(set (match_operand:QI 0 "register_operand" "=a")
6751         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6752                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6753    (clobber (reg:CC 17))]
6754   "TARGET_QIMODE_MATH
6755    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6756   "mul{b}\t%2"
6757   [(set_attr "type" "imul")
6758    (set_attr "length_immediate" "0")
6759    (set_attr "mode" "QI")])
6760
6761 (define_expand "umulqihi3"
6762   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6763                    (mult:HI (zero_extend:HI
6764                               (match_operand:QI 1 "nonimmediate_operand" ""))
6765                             (zero_extend:HI
6766                               (match_operand:QI 2 "register_operand" ""))))
6767               (clobber (reg:CC 17))])]
6768   "TARGET_QIMODE_MATH"
6769   "")
6770
6771 (define_insn "*umulqihi3_1"
6772   [(set (match_operand:HI 0 "register_operand" "=a")
6773         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6774                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6775    (clobber (reg:CC 17))]
6776   "TARGET_QIMODE_MATH
6777    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6778   "mul{b}\t%2"
6779   [(set_attr "type" "imul")
6780    (set_attr "length_immediate" "0")
6781    (set_attr "mode" "QI")])
6782
6783 (define_expand "mulqihi3"
6784   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6785                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
6786                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
6787               (clobber (reg:CC 17))])]
6788   "TARGET_QIMODE_MATH"
6789   "")
6790
6791 (define_insn "*mulqihi3_insn"
6792   [(set (match_operand:HI 0 "register_operand" "=a")
6793         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6794                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6795    (clobber (reg:CC 17))]
6796   "TARGET_QIMODE_MATH
6797    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6798   "imul{b}\t%2"
6799   [(set_attr "type" "imul")
6800    (set_attr "length_immediate" "0")
6801    (set_attr "mode" "QI")])
6802
6803 (define_expand "umulditi3"
6804   [(parallel [(set (match_operand:TI 0 "register_operand" "")
6805                    (mult:TI (zero_extend:TI
6806                               (match_operand:DI 1 "nonimmediate_operand" ""))
6807                             (zero_extend:TI
6808                               (match_operand:DI 2 "register_operand" ""))))
6809               (clobber (reg:CC 17))])]
6810   "TARGET_64BIT"
6811   "")
6812
6813 (define_insn "*umulditi3_insn"
6814   [(set (match_operand:TI 0 "register_operand" "=A")
6815         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
6816                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
6817    (clobber (reg:CC 17))]
6818   "TARGET_64BIT
6819    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6820   "mul{q}\t%2"
6821   [(set_attr "type" "imul")
6822    (set_attr "ppro_uops" "few")
6823    (set_attr "length_immediate" "0")
6824    (set_attr "mode" "DI")])
6825
6826 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
6827 (define_expand "umulsidi3"
6828   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6829                    (mult:DI (zero_extend:DI
6830                               (match_operand:SI 1 "nonimmediate_operand" ""))
6831                             (zero_extend:DI
6832                               (match_operand:SI 2 "register_operand" ""))))
6833               (clobber (reg:CC 17))])]
6834   "!TARGET_64BIT"
6835   "")
6836
6837 (define_insn "*umulsidi3_insn"
6838   [(set (match_operand:DI 0 "register_operand" "=A")
6839         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
6840                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
6841    (clobber (reg:CC 17))]
6842   "!TARGET_64BIT
6843    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6844   "mul{l}\t%2"
6845   [(set_attr "type" "imul")
6846    (set_attr "ppro_uops" "few")
6847    (set_attr "length_immediate" "0")
6848    (set_attr "mode" "SI")])
6849
6850 (define_expand "mulditi3"
6851   [(parallel [(set (match_operand:TI 0 "register_operand" "")
6852                    (mult:TI (sign_extend:TI
6853                               (match_operand:DI 1 "nonimmediate_operand" ""))
6854                             (sign_extend:TI
6855                               (match_operand:DI 2 "register_operand" ""))))
6856               (clobber (reg:CC 17))])]
6857   "TARGET_64BIT"
6858   "")
6859
6860 (define_insn "*mulditi3_insn"
6861   [(set (match_operand:TI 0 "register_operand" "=A")
6862         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
6863                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
6864    (clobber (reg:CC 17))]
6865   "TARGET_64BIT
6866    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6867   "imul{q}\t%2"
6868   [(set_attr "type" "imul")
6869    (set_attr "length_immediate" "0")
6870    (set_attr "mode" "DI")])
6871
6872 (define_expand "mulsidi3"
6873   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6874                    (mult:DI (sign_extend:DI
6875                               (match_operand:SI 1 "nonimmediate_operand" ""))
6876                             (sign_extend:DI
6877                               (match_operand:SI 2 "register_operand" ""))))
6878               (clobber (reg:CC 17))])]
6879   "!TARGET_64BIT"
6880   "")
6881
6882 (define_insn "*mulsidi3_insn"
6883   [(set (match_operand:DI 0 "register_operand" "=A")
6884         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
6885                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
6886    (clobber (reg:CC 17))]
6887   "!TARGET_64BIT
6888    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6889   "imul{l}\t%2"
6890   [(set_attr "type" "imul")
6891    (set_attr "length_immediate" "0")
6892    (set_attr "mode" "SI")])
6893
6894 (define_expand "umuldi3_highpart"
6895   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6896                    (truncate:DI
6897                      (lshiftrt:TI
6898                        (mult:TI (zero_extend:TI
6899                                   (match_operand:DI 1 "nonimmediate_operand" ""))
6900                                 (zero_extend:TI
6901                                   (match_operand:DI 2 "register_operand" "")))
6902                        (const_int 64))))
6903               (clobber (match_scratch:DI 3 ""))
6904               (clobber (reg:CC 17))])]
6905   "TARGET_64BIT"
6906   "")
6907
6908 (define_insn "*umuldi3_highpart_rex64"
6909   [(set (match_operand:DI 0 "register_operand" "=d")
6910         (truncate:DI
6911           (lshiftrt:TI
6912             (mult:TI (zero_extend:TI
6913                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
6914                      (zero_extend:TI
6915                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
6916             (const_int 64))))
6917    (clobber (match_scratch:DI 3 "=1"))
6918    (clobber (reg:CC 17))]
6919   "TARGET_64BIT
6920    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6921   "mul{q}\t%2"
6922   [(set_attr "type" "imul")
6923    (set_attr "ppro_uops" "few")
6924    (set_attr "length_immediate" "0")
6925    (set_attr "mode" "DI")])
6926
6927 (define_expand "umulsi3_highpart"
6928   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6929                    (truncate:SI
6930                      (lshiftrt:DI
6931                        (mult:DI (zero_extend:DI
6932                                   (match_operand:SI 1 "nonimmediate_operand" ""))
6933                                 (zero_extend:DI
6934                                   (match_operand:SI 2 "register_operand" "")))
6935                        (const_int 32))))
6936               (clobber (match_scratch:SI 3 ""))
6937               (clobber (reg:CC 17))])]
6938   ""
6939   "")
6940
6941 (define_insn "*umulsi3_highpart_insn"
6942   [(set (match_operand:SI 0 "register_operand" "=d")
6943         (truncate:SI
6944           (lshiftrt:DI
6945             (mult:DI (zero_extend:DI
6946                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
6947                      (zero_extend:DI
6948                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
6949             (const_int 32))))
6950    (clobber (match_scratch:SI 3 "=1"))
6951    (clobber (reg:CC 17))]
6952   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6953   "mul{l}\t%2"
6954   [(set_attr "type" "imul")
6955    (set_attr "ppro_uops" "few")
6956    (set_attr "length_immediate" "0")
6957    (set_attr "mode" "SI")])
6958
6959 (define_insn "*umulsi3_highpart_zext"
6960   [(set (match_operand:DI 0 "register_operand" "=d")
6961         (zero_extend:DI (truncate:SI
6962           (lshiftrt:DI
6963             (mult:DI (zero_extend:DI
6964                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
6965                      (zero_extend:DI
6966                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
6967             (const_int 32)))))
6968    (clobber (match_scratch:SI 3 "=1"))
6969    (clobber (reg:CC 17))]
6970   "TARGET_64BIT
6971    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6972   "mul{l}\t%2"
6973   [(set_attr "type" "imul")
6974    (set_attr "ppro_uops" "few")
6975    (set_attr "length_immediate" "0")
6976    (set_attr "mode" "SI")])
6977
6978 (define_expand "smuldi3_highpart"
6979   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
6980                    (truncate:DI
6981                      (lshiftrt:TI
6982                        (mult:TI (sign_extend:TI
6983                                   (match_operand:DI 1 "nonimmediate_operand" ""))
6984                                 (sign_extend:TI
6985                                   (match_operand:DI 2 "register_operand" "")))
6986                        (const_int 64))))
6987               (clobber (match_scratch:DI 3 ""))
6988               (clobber (reg:CC 17))])]
6989   "TARGET_64BIT"
6990   "")
6991
6992 (define_insn "*smuldi3_highpart_rex64"
6993   [(set (match_operand:DI 0 "register_operand" "=d")
6994         (truncate:DI
6995           (lshiftrt:TI
6996             (mult:TI (sign_extend:TI
6997                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
6998                      (sign_extend:TI
6999                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7000             (const_int 64))))
7001    (clobber (match_scratch:DI 3 "=1"))
7002    (clobber (reg:CC 17))]
7003   "TARGET_64BIT
7004    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7005   "imul{q}\t%2"
7006   [(set_attr "type" "imul")
7007    (set_attr "ppro_uops" "few")
7008    (set_attr "mode" "DI")])
7009
7010 (define_expand "smulsi3_highpart"
7011   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7012                    (truncate:SI
7013                      (lshiftrt:DI
7014                        (mult:DI (sign_extend:DI
7015                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7016                                 (sign_extend:DI
7017                                   (match_operand:SI 2 "register_operand" "")))
7018                        (const_int 32))))
7019               (clobber (match_scratch:SI 3 ""))
7020               (clobber (reg:CC 17))])]
7021   ""
7022   "")
7023
7024 (define_insn "*smulsi3_highpart_insn"
7025   [(set (match_operand:SI 0 "register_operand" "=d")
7026         (truncate:SI
7027           (lshiftrt:DI
7028             (mult:DI (sign_extend:DI
7029                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7030                      (sign_extend:DI
7031                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7032             (const_int 32))))
7033    (clobber (match_scratch:SI 3 "=1"))
7034    (clobber (reg:CC 17))]
7035   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7036   "imul{l}\t%2"
7037   [(set_attr "type" "imul")
7038    (set_attr "ppro_uops" "few")
7039    (set_attr "mode" "SI")])
7040
7041 (define_insn "*smulsi3_highpart_zext"
7042   [(set (match_operand:DI 0 "register_operand" "=d")
7043         (zero_extend:DI (truncate:SI
7044           (lshiftrt:DI
7045             (mult:DI (sign_extend:DI
7046                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7047                      (sign_extend:DI
7048                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7049             (const_int 32)))))
7050    (clobber (match_scratch:SI 3 "=1"))
7051    (clobber (reg:CC 17))]
7052   "TARGET_64BIT
7053    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7054   "imul{l}\t%2"
7055   [(set_attr "type" "imul")
7056    (set_attr "ppro_uops" "few")
7057    (set_attr "mode" "SI")])
7058
7059 ;; The patterns that match these are at the end of this file.
7060
7061 (define_expand "mulxf3"
7062   [(set (match_operand:XF 0 "register_operand" "")
7063         (mult:XF (match_operand:XF 1 "register_operand" "")
7064                  (match_operand:XF 2 "register_operand" "")))]
7065   "!TARGET_64BIT && TARGET_80387"
7066   "")
7067
7068 (define_expand "multf3"
7069   [(set (match_operand:TF 0 "register_operand" "")
7070         (mult:TF (match_operand:TF 1 "register_operand" "")
7071                  (match_operand:TF 2 "register_operand" "")))]
7072   "TARGET_80387"
7073   "")
7074
7075 (define_expand "muldf3"
7076   [(set (match_operand:DF 0 "register_operand" "")
7077         (mult:DF (match_operand:DF 1 "register_operand" "")
7078                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7079   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7080   "")
7081
7082 (define_expand "mulsf3"
7083   [(set (match_operand:SF 0 "register_operand" "")
7084         (mult:SF (match_operand:SF 1 "register_operand" "")
7085                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7086   "TARGET_80387 || TARGET_SSE_MATH"
7087   "")
7088 \f
7089 ;; Divide instructions
7090
7091 (define_insn "divqi3"
7092   [(set (match_operand:QI 0 "register_operand" "=a")
7093         (div:QI (match_operand:HI 1 "register_operand" "0")
7094                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7095    (clobber (reg:CC 17))]
7096   "TARGET_QIMODE_MATH"
7097   "idiv{b}\t%2"
7098   [(set_attr "type" "idiv")
7099    (set_attr "mode" "QI")
7100    (set_attr "ppro_uops" "few")])
7101
7102 (define_insn "udivqi3"
7103   [(set (match_operand:QI 0 "register_operand" "=a")
7104         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7105                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7106    (clobber (reg:CC 17))]
7107   "TARGET_QIMODE_MATH"
7108   "div{b}\t%2"
7109   [(set_attr "type" "idiv")
7110    (set_attr "mode" "QI")
7111    (set_attr "ppro_uops" "few")])
7112
7113 ;; The patterns that match these are at the end of this file.
7114
7115 (define_expand "divxf3"
7116   [(set (match_operand:XF 0 "register_operand" "")
7117         (div:XF (match_operand:XF 1 "register_operand" "")
7118                 (match_operand:XF 2 "register_operand" "")))]
7119   "!TARGET_64BIT && TARGET_80387"
7120   "")
7121
7122 (define_expand "divtf3"
7123   [(set (match_operand:TF 0 "register_operand" "")
7124         (div:TF (match_operand:TF 1 "register_operand" "")
7125                 (match_operand:TF 2 "register_operand" "")))]
7126   "TARGET_80387"
7127   "")
7128
7129 (define_expand "divdf3"
7130   [(set (match_operand:DF 0 "register_operand" "")
7131         (div:DF (match_operand:DF 1 "register_operand" "")
7132                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7133    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7134    "")
7135  
7136 (define_expand "divsf3"
7137   [(set (match_operand:SF 0 "register_operand" "")
7138         (div:SF (match_operand:SF 1 "register_operand" "")
7139                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7140   "TARGET_80387 || TARGET_SSE_MATH"
7141   "")
7142 \f
7143 ;; Remainder instructions.
7144
7145 (define_expand "divmoddi4"
7146   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7147                    (div:DI (match_operand:DI 1 "register_operand" "")
7148                            (match_operand:DI 2 "nonimmediate_operand" "")))
7149               (set (match_operand:DI 3 "register_operand" "")
7150                    (mod:DI (match_dup 1) (match_dup 2)))
7151               (clobber (reg:CC 17))])]
7152   "TARGET_64BIT"
7153   "")
7154
7155 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7156 ;; Penalize eax case sligthly because it results in worse scheduling
7157 ;; of code.
7158 (define_insn "*divmoddi4_nocltd_rex64"
7159   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7160         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7161                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7162    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7163         (mod:DI (match_dup 2) (match_dup 3)))
7164    (clobber (reg:CC 17))]
7165   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7166   "#"
7167   [(set_attr "type" "multi")])
7168
7169 (define_insn "*divmoddi4_cltd_rex64"
7170   [(set (match_operand:DI 0 "register_operand" "=a")
7171         (div:DI (match_operand:DI 2 "register_operand" "a")
7172                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7173    (set (match_operand:DI 1 "register_operand" "=&d")
7174         (mod:DI (match_dup 2) (match_dup 3)))
7175    (clobber (reg:CC 17))]
7176   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7177   "#"
7178   [(set_attr "type" "multi")])
7179
7180 (define_insn "*divmoddi_noext_rex64"
7181   [(set (match_operand:DI 0 "register_operand" "=a")
7182         (div:DI (match_operand:DI 1 "register_operand" "0")
7183                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7184    (set (match_operand:DI 3 "register_operand" "=d")
7185         (mod:DI (match_dup 1) (match_dup 2)))
7186    (use (match_operand:DI 4 "register_operand" "3"))
7187    (clobber (reg:CC 17))]
7188   "TARGET_64BIT"
7189   "idiv{q}\t%2"
7190   [(set_attr "type" "idiv")
7191    (set_attr "mode" "DI")
7192    (set_attr "ppro_uops" "few")])
7193
7194 (define_split
7195   [(set (match_operand:DI 0 "register_operand" "")
7196         (div:DI (match_operand:DI 1 "register_operand" "")
7197                 (match_operand:DI 2 "nonimmediate_operand" "")))
7198    (set (match_operand:DI 3 "register_operand" "")
7199         (mod:DI (match_dup 1) (match_dup 2)))
7200    (clobber (reg:CC 17))]
7201   "TARGET_64BIT && reload_completed"
7202   [(parallel [(set (match_dup 3)
7203                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7204               (clobber (reg:CC 17))])
7205    (parallel [(set (match_dup 0)
7206                    (div:DI (reg:DI 0) (match_dup 2)))
7207               (set (match_dup 3)
7208                    (mod:DI (reg:DI 0) (match_dup 2)))
7209               (use (match_dup 3))
7210               (clobber (reg:CC 17))])]
7211 {
7212   /* Avoid use of cltd in favour of a mov+shift.  */
7213   if (!TARGET_USE_CLTD && !optimize_size)
7214     {
7215       if (true_regnum (operands[1]))
7216         emit_move_insn (operands[0], operands[1]);
7217       else
7218         emit_move_insn (operands[3], operands[1]);
7219       operands[4] = operands[3];
7220     }
7221   else
7222     {
7223       if (true_regnum (operands[1]))
7224         abort();
7225       operands[4] = operands[1];
7226     }
7227 })
7228
7229
7230 (define_expand "divmodsi4"
7231   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7232                    (div:SI (match_operand:SI 1 "register_operand" "")
7233                            (match_operand:SI 2 "nonimmediate_operand" "")))
7234               (set (match_operand:SI 3 "register_operand" "")
7235                    (mod:SI (match_dup 1) (match_dup 2)))
7236               (clobber (reg:CC 17))])]
7237   ""
7238   "")
7239
7240 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7241 ;; Penalize eax case sligthly because it results in worse scheduling
7242 ;; of code.
7243 (define_insn "*divmodsi4_nocltd"
7244   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7245         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7246                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7247    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7248         (mod:SI (match_dup 2) (match_dup 3)))
7249    (clobber (reg:CC 17))]
7250   "!optimize_size && !TARGET_USE_CLTD"
7251   "#"
7252   [(set_attr "type" "multi")])
7253
7254 (define_insn "*divmodsi4_cltd"
7255   [(set (match_operand:SI 0 "register_operand" "=a")
7256         (div:SI (match_operand:SI 2 "register_operand" "a")
7257                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7258    (set (match_operand:SI 1 "register_operand" "=&d")
7259         (mod:SI (match_dup 2) (match_dup 3)))
7260    (clobber (reg:CC 17))]
7261   "optimize_size || TARGET_USE_CLTD"
7262   "#"
7263   [(set_attr "type" "multi")])
7264
7265 (define_insn "*divmodsi_noext"
7266   [(set (match_operand:SI 0 "register_operand" "=a")
7267         (div:SI (match_operand:SI 1 "register_operand" "0")
7268                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7269    (set (match_operand:SI 3 "register_operand" "=d")
7270         (mod:SI (match_dup 1) (match_dup 2)))
7271    (use (match_operand:SI 4 "register_operand" "3"))
7272    (clobber (reg:CC 17))]
7273   ""
7274   "idiv{l}\t%2"
7275   [(set_attr "type" "idiv")
7276    (set_attr "mode" "SI")
7277    (set_attr "ppro_uops" "few")])
7278
7279 (define_split
7280   [(set (match_operand:SI 0 "register_operand" "")
7281         (div:SI (match_operand:SI 1 "register_operand" "")
7282                 (match_operand:SI 2 "nonimmediate_operand" "")))
7283    (set (match_operand:SI 3 "register_operand" "")
7284         (mod:SI (match_dup 1) (match_dup 2)))
7285    (clobber (reg:CC 17))]
7286   "reload_completed"
7287   [(parallel [(set (match_dup 3)
7288                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7289               (clobber (reg:CC 17))])
7290    (parallel [(set (match_dup 0)
7291                    (div:SI (reg:SI 0) (match_dup 2)))
7292               (set (match_dup 3)
7293                    (mod:SI (reg:SI 0) (match_dup 2)))
7294               (use (match_dup 3))
7295               (clobber (reg:CC 17))])]
7296 {
7297   /* Avoid use of cltd in favour of a mov+shift.  */
7298   if (!TARGET_USE_CLTD && !optimize_size)
7299     {
7300       if (true_regnum (operands[1]))
7301         emit_move_insn (operands[0], operands[1]);
7302       else
7303         emit_move_insn (operands[3], operands[1]);
7304       operands[4] = operands[3];
7305     }
7306   else
7307     {
7308       if (true_regnum (operands[1]))
7309         abort();
7310       operands[4] = operands[1];
7311     }
7312 })
7313 ;; %%% Split me.
7314 (define_insn "divmodhi4"
7315   [(set (match_operand:HI 0 "register_operand" "=a")
7316         (div:HI (match_operand:HI 1 "register_operand" "0")
7317                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7318    (set (match_operand:HI 3 "register_operand" "=&d")
7319         (mod:HI (match_dup 1) (match_dup 2)))
7320    (clobber (reg:CC 17))]
7321   "TARGET_HIMODE_MATH"
7322   "cwtd\;idiv{w}\t%2"
7323   [(set_attr "type" "multi")
7324    (set_attr "length_immediate" "0")
7325    (set_attr "mode" "SI")])
7326
7327 (define_insn "udivmoddi4"
7328   [(set (match_operand:DI 0 "register_operand" "=a")
7329         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7330                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7331    (set (match_operand:DI 3 "register_operand" "=&d")
7332         (umod:DI (match_dup 1) (match_dup 2)))
7333    (clobber (reg:CC 17))]
7334   "TARGET_64BIT"
7335   "xor{q}\t%3, %3\;div{q}\t%2"
7336   [(set_attr "type" "multi")
7337    (set_attr "length_immediate" "0")
7338    (set_attr "mode" "DI")])
7339
7340 (define_insn "*udivmoddi4_noext"
7341   [(set (match_operand:DI 0 "register_operand" "=a")
7342         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7343                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7344    (set (match_operand:DI 3 "register_operand" "=d")
7345         (umod:DI (match_dup 1) (match_dup 2)))
7346    (use (match_dup 3))
7347    (clobber (reg:CC 17))]
7348   "TARGET_64BIT"
7349   "div{q}\t%2"
7350   [(set_attr "type" "idiv")
7351    (set_attr "ppro_uops" "few")
7352    (set_attr "mode" "DI")])
7353
7354 (define_split
7355   [(set (match_operand:DI 0 "register_operand" "")
7356         (udiv:DI (match_operand:DI 1 "register_operand" "")
7357                  (match_operand:DI 2 "nonimmediate_operand" "")))
7358    (set (match_operand:DI 3 "register_operand" "")
7359         (umod:DI (match_dup 1) (match_dup 2)))
7360    (clobber (reg:CC 17))]
7361   "TARGET_64BIT && reload_completed"
7362   [(set (match_dup 3) (const_int 0))
7363    (parallel [(set (match_dup 0)
7364                    (udiv:DI (match_dup 1) (match_dup 2)))
7365               (set (match_dup 3)
7366                    (umod:DI (match_dup 1) (match_dup 2)))
7367               (use (match_dup 3))
7368               (clobber (reg:CC 17))])]
7369   "")
7370
7371 (define_insn "udivmodsi4"
7372   [(set (match_operand:SI 0 "register_operand" "=a")
7373         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7374                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7375    (set (match_operand:SI 3 "register_operand" "=&d")
7376         (umod:SI (match_dup 1) (match_dup 2)))
7377    (clobber (reg:CC 17))]
7378   ""
7379   "xor{l}\t%3, %3\;div{l}\t%2"
7380   [(set_attr "type" "multi")
7381    (set_attr "length_immediate" "0")
7382    (set_attr "mode" "SI")])
7383
7384 (define_insn "*udivmodsi4_noext"
7385   [(set (match_operand:SI 0 "register_operand" "=a")
7386         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7387                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7388    (set (match_operand:SI 3 "register_operand" "=d")
7389         (umod:SI (match_dup 1) (match_dup 2)))
7390    (use (match_dup 3))
7391    (clobber (reg:CC 17))]
7392   ""
7393   "div{l}\t%2"
7394   [(set_attr "type" "idiv")
7395    (set_attr "ppro_uops" "few")
7396    (set_attr "mode" "SI")])
7397
7398 (define_split
7399   [(set (match_operand:SI 0 "register_operand" "")
7400         (udiv:SI (match_operand:SI 1 "register_operand" "")
7401                  (match_operand:SI 2 "nonimmediate_operand" "")))
7402    (set (match_operand:SI 3 "register_operand" "")
7403         (umod:SI (match_dup 1) (match_dup 2)))
7404    (clobber (reg:CC 17))]
7405   "reload_completed"
7406   [(set (match_dup 3) (const_int 0))
7407    (parallel [(set (match_dup 0)
7408                    (udiv:SI (match_dup 1) (match_dup 2)))
7409               (set (match_dup 3)
7410                    (umod:SI (match_dup 1) (match_dup 2)))
7411               (use (match_dup 3))
7412               (clobber (reg:CC 17))])]
7413   "")
7414
7415 (define_expand "udivmodhi4"
7416   [(set (match_dup 4) (const_int 0))
7417    (parallel [(set (match_operand:HI 0 "register_operand" "")
7418                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7419                             (match_operand:HI 2 "nonimmediate_operand" "")))
7420               (set (match_operand:HI 3 "register_operand" "")
7421                    (umod:HI (match_dup 1) (match_dup 2)))
7422               (use (match_dup 4))
7423               (clobber (reg:CC 17))])]
7424   "TARGET_HIMODE_MATH"
7425   "operands[4] = gen_reg_rtx (HImode);")
7426
7427 (define_insn "*udivmodhi_noext"
7428   [(set (match_operand:HI 0 "register_operand" "=a")
7429         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7430                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7431    (set (match_operand:HI 3 "register_operand" "=d")
7432         (umod:HI (match_dup 1) (match_dup 2)))
7433    (use (match_operand:HI 4 "register_operand" "3"))
7434    (clobber (reg:CC 17))]
7435   ""
7436   "div{w}\t%2"
7437   [(set_attr "type" "idiv")
7438    (set_attr "mode" "HI")
7439    (set_attr "ppro_uops" "few")])
7440
7441 ;; We can not use div/idiv for double division, because it causes
7442 ;; "division by zero" on the overflow and that's not what we expect
7443 ;; from truncate.  Because true (non truncating) double division is
7444 ;; never generated, we can't create this insn anyway.
7445 ;
7446 ;(define_insn ""
7447 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7448 ;       (truncate:SI
7449 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7450 ;                  (zero_extend:DI
7451 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7452 ;   (set (match_operand:SI 3 "register_operand" "=d")
7453 ;       (truncate:SI
7454 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7455 ;   (clobber (reg:CC 17))]
7456 ;  ""
7457 ;  "div{l}\t{%2, %0|%0, %2}"
7458 ;  [(set_attr "type" "idiv")
7459 ;   (set_attr "ppro_uops" "few")])
7460 \f
7461 ;;- Logical AND instructions
7462
7463 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7464 ;; Note that this excludes ah.
7465
7466 (define_insn "*testdi_1_rex64"
7467   [(set (reg 17)
7468         (compare
7469           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%*a,r,*a,r,rm")
7470                   (match_operand:DI 1 "x86_64_szext_nonmemory_operand" "Z,Z,e,e,re"))
7471           (const_int 0)))]
7472   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7473   "@
7474    test{l}\t{%k1, %k0|%k0, %k1} 
7475    test{l}\t{%k1, %k0|%k0, %k1} 
7476    test{q}\t{%1, %0|%0, %1} 
7477    test{q}\t{%1, %0|%0, %1} 
7478    test{q}\t{%1, %0|%0, %1}"
7479   [(set_attr "type" "test")
7480    (set_attr "modrm" "0,1,0,1,1")
7481    (set_attr "mode" "SI,SI,DI,DI,DI")
7482    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7483
7484 (define_insn "testsi_1"
7485   [(set (reg 17)
7486         (compare
7487           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%*a,r,rm")
7488                   (match_operand:SI 1 "nonmemory_operand" "in,in,rin"))
7489           (const_int 0)))]
7490   "ix86_match_ccmode (insn, CCNOmode)"
7491   "test{l}\t{%1, %0|%0, %1}"
7492   [(set_attr "type" "test")
7493    (set_attr "modrm" "0,1,1")
7494    (set_attr "mode" "SI")
7495    (set_attr "pent_pair" "uv,np,uv")])
7496
7497 (define_expand "testsi_ccno_1"
7498   [(set (reg:CCNO 17)
7499         (compare:CCNO
7500           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7501                   (match_operand:SI 1 "nonmemory_operand" ""))
7502           (const_int 0)))]
7503   ""
7504   "")
7505
7506 (define_insn "*testhi_1"
7507   [(set (reg 17)
7508         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%*a,r,rm")
7509                          (match_operand:HI 1 "nonmemory_operand" "n,n,rn"))
7510                  (const_int 0)))]
7511   "ix86_match_ccmode (insn, CCNOmode)"
7512   "test{w}\t{%1, %0|%0, %1}"
7513   [(set_attr "type" "test")
7514    (set_attr "modrm" "0,1,1")
7515    (set_attr "mode" "HI")
7516    (set_attr "pent_pair" "uv,np,uv")])
7517
7518 (define_expand "testqi_ccz_1"
7519   [(set (reg:CCZ 17)
7520         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7521                              (match_operand:QI 1 "nonmemory_operand" ""))
7522                  (const_int 0)))]
7523   ""
7524   "")
7525
7526 (define_insn "*testqi_1"
7527   [(set (reg 17)
7528         (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%*a,q,qm,r")
7529                          (match_operand:QI 1 "nonmemory_operand" "n,n,qn,n"))
7530                  (const_int 0)))]
7531   "ix86_match_ccmode (insn, CCNOmode)"
7532 {
7533   if (which_alternative == 3)
7534     {
7535       if (GET_CODE (operands[1]) == CONST_INT
7536           && (INTVAL (operands[1]) & 0xffffff00))
7537         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7538       return "test{l}\t{%1, %k0|%k0, %1}";
7539     }
7540   return "test{b}\t{%1, %0|%0, %1}";
7541 }
7542   [(set_attr "type" "test")
7543    (set_attr "modrm" "0,1,1,1")
7544    (set_attr "mode" "QI,QI,QI,SI")
7545    (set_attr "pent_pair" "uv,np,uv,np")])
7546
7547 (define_expand "testqi_ext_ccno_0"
7548   [(set (reg:CCNO 17)
7549         (compare:CCNO
7550           (and:SI
7551             (zero_extract:SI
7552               (match_operand 0 "ext_register_operand" "")
7553               (const_int 8)
7554               (const_int 8))
7555             (match_operand 1 "const_int_operand" ""))
7556           (const_int 0)))]
7557   ""
7558   "")
7559
7560 (define_insn "*testqi_ext_0"
7561   [(set (reg 17)
7562         (compare
7563           (and:SI
7564             (zero_extract:SI
7565               (match_operand 0 "ext_register_operand" "Q")
7566               (const_int 8)
7567               (const_int 8))
7568             (match_operand 1 "const_int_operand" "n"))
7569           (const_int 0)))]
7570   "(unsigned HOST_WIDE_INT) INTVAL (operands[1]) <= 0xff
7571    && ix86_match_ccmode (insn, CCNOmode)"
7572   "test{b}\t{%1, %h0|%h0, %1}"
7573   [(set_attr "type" "test")
7574    (set_attr "mode" "QI")
7575    (set_attr "length_immediate" "1")
7576    (set_attr "pent_pair" "np")])
7577
7578 (define_insn "*testqi_ext_1"
7579   [(set (reg 17)
7580         (compare
7581           (and:SI
7582             (zero_extract:SI
7583               (match_operand 0 "ext_register_operand" "Q")
7584               (const_int 8)
7585               (const_int 8))
7586             (zero_extend:SI
7587               (match_operand:QI 1 "nonimmediate_operand" "Qm")))
7588           (const_int 0)))]
7589   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7590   "test{b}\t{%1, %h0|%h0, %1}"
7591   [(set_attr "type" "test")
7592    (set_attr "mode" "QI")])
7593
7594 (define_insn "*testqi_ext_1_rex64"
7595   [(set (reg 17)
7596         (compare
7597           (and:SI
7598             (zero_extract:SI
7599               (match_operand 0 "ext_register_operand" "Q")
7600               (const_int 8)
7601               (const_int 8))
7602             (zero_extend:SI
7603               (match_operand:QI 1 "register_operand" "Q")))
7604           (const_int 0)))]
7605   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7606   "test{b}\t{%1, %h0|%h0, %1}"
7607   [(set_attr "type" "test")
7608    (set_attr "mode" "QI")])
7609
7610 (define_insn "*testqi_ext_2"
7611   [(set (reg 17)
7612         (compare
7613           (and:SI
7614             (zero_extract:SI
7615               (match_operand 0 "ext_register_operand" "Q")
7616               (const_int 8)
7617               (const_int 8))
7618             (zero_extract:SI
7619               (match_operand 1 "ext_register_operand" "Q")
7620               (const_int 8)
7621               (const_int 8)))
7622           (const_int 0)))]
7623   "ix86_match_ccmode (insn, CCNOmode)"
7624   "test{b}\t{%h1, %h0|%h0, %h1}"
7625   [(set_attr "type" "test")
7626    (set_attr "mode" "QI")])
7627
7628 ;; Combine likes to form bit extractions for some tests.  Humor it.
7629 (define_insn "*testqi_ext_3"
7630   [(set (reg 17)
7631         (compare (zero_extract:SI
7632                    (match_operand 0 "nonimmediate_operand" "rm")
7633                    (match_operand:SI 1 "const_int_operand" "")
7634                    (match_operand:SI 2 "const_int_operand" ""))
7635                  (const_int 0)))]
7636   "ix86_match_ccmode (insn, CCNOmode)
7637    && (GET_MODE (operands[0]) == SImode
7638        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7639        || GET_MODE (operands[0]) == HImode
7640        || GET_MODE (operands[0]) == QImode)"
7641   "#")
7642
7643 (define_insn "*testqi_ext_3_rex64"
7644   [(set (reg 17)
7645         (compare (zero_extract:DI
7646                    (match_operand 0 "nonimmediate_operand" "rm")
7647                    (match_operand:DI 1 "const_int_operand" "")
7648                    (match_operand:DI 2 "const_int_operand" ""))
7649                  (const_int 0)))]
7650   "TARGET_64BIT
7651    && ix86_match_ccmode (insn, CCNOmode)
7652    /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
7653    && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
7654    /* Ensure that resulting mask is zero or sign extended operand.  */
7655    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7656        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7657            && INTVAL (operands[1]) > 32))
7658    && (GET_MODE (operands[0]) == SImode
7659        || GET_MODE (operands[0]) == DImode
7660        || GET_MODE (operands[0]) == HImode
7661        || GET_MODE (operands[0]) == QImode)"
7662   "#")
7663
7664 (define_split
7665   [(set (reg 17)
7666         (compare (zero_extract
7667                    (match_operand 0 "nonimmediate_operand" "")
7668                    (match_operand 1 "const_int_operand" "")
7669                    (match_operand 2 "const_int_operand" ""))
7670                  (const_int 0)))]
7671   "ix86_match_ccmode (insn, CCNOmode)"
7672   [(set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
7673 {
7674   HOST_WIDE_INT len = INTVAL (operands[1]);
7675   HOST_WIDE_INT pos = INTVAL (operands[2]);
7676   HOST_WIDE_INT mask;
7677   enum machine_mode mode, submode;
7678
7679   mode = GET_MODE (operands[0]);
7680   if (GET_CODE (operands[0]) == MEM)
7681     {
7682       /* ??? Combine likes to put non-volatile mem extractions in QImode
7683          no matter the size of the test.  So find a mode that works.  */
7684       if (! MEM_VOLATILE_P (operands[0]))
7685         {
7686           mode = smallest_mode_for_size (pos + len, MODE_INT);
7687           operands[0] = adjust_address (operands[0], mode, 0);
7688         }
7689     }
7690   else if (GET_CODE (operands[0]) == SUBREG
7691            && (submode = GET_MODE (SUBREG_REG (operands[0])),
7692                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7693            && pos + len <= GET_MODE_BITSIZE (submode))
7694     {
7695       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7696       mode = submode;
7697       operands[0] = SUBREG_REG (operands[0]);
7698     }
7699   else if (mode == HImode && pos + len <= 8)
7700     {
7701       /* Small HImode tests can be converted to QImode.  */
7702       mode = QImode;
7703       operands[0] = gen_lowpart (QImode, operands[0]);
7704     }
7705
7706   mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
7707   mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
7708
7709   operands[3] = gen_rtx_AND (mode, operands[0], gen_int_mode (mask, mode));
7710 })
7711
7712 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7713 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7714 ;; this is relatively important trick.
7715 ;; Do the converison only post-reload to avoid limiting of the register class
7716 ;; to QI regs.
7717 (define_split
7718   [(set (reg 17)
7719         (compare
7720           (and (match_operand 0 "register_operand" "")
7721                (match_operand 1 "const_int_operand" ""))
7722           (const_int 0)))]
7723    "(!TARGET_PROMOTE_QImode || optimize_size)
7724     && reload_completed
7725     && QI_REG_P (operands[0])
7726     && ((ix86_match_ccmode (insn, CCZmode)
7727          && !(INTVAL (operands[1]) & ~(255 << 8)))
7728         || (ix86_match_ccmode (insn, CCNOmode)
7729             && !(INTVAL (operands[1]) & ~(127 << 8))))
7730     && GET_MODE (operands[0]) != QImode"
7731   [(set (reg:CCNO 17)
7732         (compare:CCNO
7733           (and:SI (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
7734                   (match_dup 1))
7735           (const_int 0)))]
7736   "operands[0] = gen_lowpart (SImode, operands[0]);
7737    operands[1] = gen_int_mode (INTVAL (operands[1]) >> 8, SImode);")
7738
7739 (define_split
7740   [(set (reg 17)
7741         (compare
7742           (and (match_operand 0 "nonimmediate_operand" "")
7743                (match_operand 1 "const_int_operand" ""))
7744           (const_int 0)))]
7745    "(!TARGET_PROMOTE_QImode || optimize_size)
7746     && reload_completed
7747     && (!REG_P (operands[0]) || ANY_QI_REG_P (operands[0]))
7748     && ((ix86_match_ccmode (insn, CCZmode)
7749          && !(INTVAL (operands[1]) & ~255))
7750         || (ix86_match_ccmode (insn, CCNOmode)
7751             && !(INTVAL (operands[1]) & ~127)))
7752     && GET_MODE (operands[0]) != QImode"
7753   [(set (reg:CCNO 17)
7754         (compare:CCNO
7755           (and:QI (match_dup 0)
7756                   (match_dup 1))
7757           (const_int 0)))]
7758   "operands[0] = gen_lowpart (QImode, operands[0]);
7759    operands[1] = gen_lowpart (QImode, operands[1]);")
7760
7761
7762 ;; %%% This used to optimize known byte-wide and operations to memory,
7763 ;; and sometimes to QImode registers.  If this is considered useful,
7764 ;; it should be done with splitters.
7765
7766 (define_expand "anddi3"
7767   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7768         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
7769                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
7770    (clobber (reg:CC 17))]
7771   "TARGET_64BIT"
7772   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
7773
7774 (define_insn "*anddi_1_rex64"
7775   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7776         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7777                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7778    (clobber (reg:CC 17))]
7779   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7780 {
7781   switch (get_attr_type (insn))
7782     {
7783     case TYPE_IMOVX:
7784       {
7785         enum machine_mode mode;
7786
7787         if (GET_CODE (operands[2]) != CONST_INT)
7788           abort ();
7789         if (INTVAL (operands[2]) == 0xff)
7790           mode = QImode;
7791         else if (INTVAL (operands[2]) == 0xffff)
7792           mode = HImode;
7793         else
7794           abort ();
7795         
7796         operands[1] = gen_lowpart (mode, operands[1]);
7797         if (mode == QImode)
7798           return "movz{bq|x}\t{%1,%0|%0, %1}";
7799         else
7800           return "movz{wq|x}\t{%1,%0|%0, %1}";
7801       }
7802
7803     default:
7804       if (! rtx_equal_p (operands[0], operands[1]))
7805         abort ();
7806       if (get_attr_mode (insn) == MODE_SI)
7807         return "and{l}\t{%k2, %k0|%k0, %k2}";
7808       else
7809         return "and{q}\t{%2, %0|%0, %2}";
7810     }
7811 }
7812   [(set_attr "type" "alu,alu,alu,imovx")
7813    (set_attr "length_immediate" "*,*,*,0")
7814    (set_attr "mode" "SI,DI,DI,DI")])
7815
7816 (define_insn "*anddi_2"
7817   [(set (reg 17)
7818         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7819                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7820                  (const_int 0)))
7821    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7822         (and:DI (match_dup 1) (match_dup 2)))]
7823   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7824    && ix86_binary_operator_ok (AND, DImode, operands)"
7825   "@
7826    and{l}\t{%k2, %k0|%k0, %k2} 
7827    and{q}\t{%2, %0|%0, %2} 
7828    and{q}\t{%2, %0|%0, %2}"
7829   [(set_attr "type" "alu")
7830    (set_attr "mode" "SI,DI,DI")])
7831
7832 (define_expand "andsi3"
7833   [(set (match_operand:SI 0 "nonimmediate_operand" "")
7834         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
7835                 (match_operand:SI 2 "general_operand" "")))
7836    (clobber (reg:CC 17))]
7837   ""
7838   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
7839
7840 (define_insn "*andsi_1"
7841   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7842         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7843                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7844    (clobber (reg:CC 17))]
7845   "ix86_binary_operator_ok (AND, SImode, operands)"
7846 {
7847   switch (get_attr_type (insn))
7848     {
7849     case TYPE_IMOVX:
7850       {
7851         enum machine_mode mode;
7852
7853         if (GET_CODE (operands[2]) != CONST_INT)
7854           abort ();
7855         if (INTVAL (operands[2]) == 0xff)
7856           mode = QImode;
7857         else if (INTVAL (operands[2]) == 0xffff)
7858           mode = HImode;
7859         else
7860           abort ();
7861         
7862         operands[1] = gen_lowpart (mode, operands[1]);
7863         if (mode == QImode)
7864           return "movz{bl|x}\t{%1,%0|%0, %1}";
7865         else
7866           return "movz{wl|x}\t{%1,%0|%0, %1}";
7867       }
7868
7869     default:
7870       if (! rtx_equal_p (operands[0], operands[1]))
7871         abort ();
7872       return "and{l}\t{%2, %0|%0, %2}";
7873     }
7874 }
7875   [(set_attr "type" "alu,alu,imovx")
7876    (set_attr "length_immediate" "*,*,0")
7877    (set_attr "mode" "SI")])
7878
7879 (define_split
7880   [(set (match_operand 0 "register_operand" "")
7881         (and (match_dup 0)
7882              (const_int -65536)))
7883    (clobber (reg:CC 17))]
7884   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
7885   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7886   "operands[1] = gen_lowpart (HImode, operands[0]);")
7887
7888 (define_split
7889   [(set (match_operand 0 "ext_register_operand" "")
7890         (and (match_dup 0)
7891              (const_int -256)))
7892    (clobber (reg:CC 17))]
7893   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
7894   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7895   "operands[1] = gen_lowpart (QImode, operands[0]);")
7896
7897 (define_split
7898   [(set (match_operand 0 "ext_register_operand" "")
7899         (and (match_dup 0)
7900              (const_int -65281)))
7901    (clobber (reg:CC 17))]
7902   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
7903   [(parallel [(set (zero_extract:SI (match_dup 0)
7904                                     (const_int 8)
7905                                     (const_int 8))
7906                    (xor:SI 
7907                      (zero_extract:SI (match_dup 0)
7908                                       (const_int 8)
7909                                       (const_int 8))
7910                      (zero_extract:SI (match_dup 0)
7911                                       (const_int 8)
7912                                       (const_int 8))))
7913               (clobber (reg:CC 17))])]
7914   "operands[0] = gen_lowpart (SImode, operands[0]);")
7915
7916 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7917 (define_insn "*andsi_1_zext"
7918   [(set (match_operand:DI 0 "register_operand" "=r")
7919         (zero_extend:DI
7920           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7921                   (match_operand:SI 2 "general_operand" "rim"))))
7922    (clobber (reg:CC 17))]
7923   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7924   "and{l}\t{%2, %k0|%k0, %2}"
7925   [(set_attr "type" "alu")
7926    (set_attr "mode" "SI")])
7927
7928 (define_insn "*andsi_2"
7929   [(set (reg 17)
7930         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
7931                          (match_operand:SI 2 "general_operand" "rim,ri"))
7932                  (const_int 0)))
7933    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
7934         (and:SI (match_dup 1) (match_dup 2)))]
7935   "ix86_match_ccmode (insn, CCNOmode)
7936    && ix86_binary_operator_ok (AND, SImode, operands)"
7937   "and{l}\t{%2, %0|%0, %2}"
7938   [(set_attr "type" "alu")
7939    (set_attr "mode" "SI")])
7940
7941 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7942 (define_insn "*andsi_2_zext"
7943   [(set (reg 17)
7944         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7945                          (match_operand:SI 2 "general_operand" "rim"))
7946                  (const_int 0)))
7947    (set (match_operand:DI 0 "register_operand" "=r")
7948         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7949   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7950    && ix86_binary_operator_ok (AND, SImode, operands)"
7951   "and{l}\t{%2, %k0|%k0, %2}"
7952   [(set_attr "type" "alu")
7953    (set_attr "mode" "SI")])
7954
7955 (define_expand "andhi3"
7956   [(set (match_operand:HI 0 "nonimmediate_operand" "")
7957         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
7958                 (match_operand:HI 2 "general_operand" "")))
7959    (clobber (reg:CC 17))]
7960   "TARGET_HIMODE_MATH"
7961   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
7962
7963 (define_insn "*andhi_1"
7964   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7965         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7966                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
7967    (clobber (reg:CC 17))]
7968   "ix86_binary_operator_ok (AND, HImode, operands)"
7969 {
7970   switch (get_attr_type (insn))
7971     {
7972     case TYPE_IMOVX:
7973       if (GET_CODE (operands[2]) != CONST_INT)
7974         abort ();
7975       if (INTVAL (operands[2]) == 0xff)
7976         return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7977       abort ();
7978
7979     default:
7980       if (! rtx_equal_p (operands[0], operands[1]))
7981         abort ();
7982
7983       return "and{w}\t{%2, %0|%0, %2}";
7984     }
7985 }
7986   [(set_attr "type" "alu,alu,imovx")
7987    (set_attr "length_immediate" "*,*,0")
7988    (set_attr "mode" "HI,HI,SI")])
7989
7990 (define_insn "*andhi_2"
7991   [(set (reg 17)
7992         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
7993                          (match_operand:HI 2 "general_operand" "rim,ri"))
7994                  (const_int 0)))
7995    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
7996         (and:HI (match_dup 1) (match_dup 2)))]
7997   "ix86_match_ccmode (insn, CCNOmode)
7998    && ix86_binary_operator_ok (AND, HImode, operands)"
7999   "and{w}\t{%2, %0|%0, %2}"
8000   [(set_attr "type" "alu")
8001    (set_attr "mode" "HI")])
8002
8003 (define_expand "andqi3"
8004   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8005         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8006                 (match_operand:QI 2 "general_operand" "")))
8007    (clobber (reg:CC 17))]
8008   "TARGET_QIMODE_MATH"
8009   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8010
8011 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8012 (define_insn "*andqi_1"
8013   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8014         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8015                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8016    (clobber (reg:CC 17))]
8017   "ix86_binary_operator_ok (AND, QImode, operands)"
8018   "@
8019    and{b}\t{%2, %0|%0, %2}
8020    and{b}\t{%2, %0|%0, %2}
8021    and{l}\t{%k2, %k0|%k0, %k2}"
8022   [(set_attr "type" "alu")
8023    (set_attr "mode" "QI,QI,SI")])
8024
8025 (define_insn "*andqi_1_slp"
8026   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8027         (and:QI (match_dup 0)
8028                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8029    (clobber (reg:CC 17))]
8030   ""
8031   "and{b}\t{%1, %0|%0, %1}"
8032   [(set_attr "type" "alu1")
8033    (set_attr "mode" "QI")])
8034
8035 (define_insn "*andqi_2"
8036   [(set (reg 17)
8037         (compare (and:QI
8038                    (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8039                    (match_operand:QI 2 "general_operand" "qim,qi,i"))
8040                  (const_int 0)))
8041    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8042         (and:QI (match_dup 1) (match_dup 2)))]
8043   "ix86_match_ccmode (insn, CCNOmode)
8044    && ix86_binary_operator_ok (AND, QImode, operands)"
8045 {
8046   if (which_alternative == 2)
8047     {
8048       if (GET_CODE (operands[2]) == CONST_INT
8049           && (INTVAL (operands[2]) & 0xffffff00))
8050         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8051       return "and{l}\t{%2, %k0|%k0, %2}";
8052     }
8053   return "and{b}\t{%2, %0|%0, %2}";
8054 }
8055   [(set_attr "type" "alu")
8056    (set_attr "mode" "QI,QI,SI")])
8057
8058 (define_insn "*andqi_2_slp"
8059   [(set (reg 17)
8060         (compare (and:QI
8061                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8062                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8063                  (const_int 0)))
8064    (set (strict_low_part (match_dup 0))
8065         (and:QI (match_dup 0) (match_dup 1)))]
8066   "ix86_match_ccmode (insn, CCNOmode)"
8067   "and{b}\t{%1, %0|%0, %1}"
8068   [(set_attr "type" "alu1")
8069    (set_attr "mode" "QI")])
8070
8071 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8072 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8073 ;; for a QImode operand, which of course failed.
8074
8075 (define_insn "andqi_ext_0"
8076   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8077                          (const_int 8)
8078                          (const_int 8))
8079         (and:SI 
8080           (zero_extract:SI
8081             (match_operand 1 "ext_register_operand" "0")
8082             (const_int 8)
8083             (const_int 8))
8084           (match_operand 2 "const_int_operand" "n")))
8085    (clobber (reg:CC 17))]
8086   "(unsigned HOST_WIDE_INT)INTVAL (operands[2]) <= 0xff"
8087   "and{b}\t{%2, %h0|%h0, %2}"
8088   [(set_attr "type" "alu")
8089    (set_attr "length_immediate" "1")
8090    (set_attr "mode" "QI")])
8091
8092 ;; Generated by peephole translating test to and.  This shows up
8093 ;; often in fp comparisons.
8094
8095 (define_insn "*andqi_ext_0_cc"
8096   [(set (reg 17)
8097         (compare
8098           (and:SI
8099             (zero_extract:SI
8100               (match_operand 1 "ext_register_operand" "0")
8101               (const_int 8)
8102               (const_int 8))
8103             (match_operand 2 "const_int_operand" "n"))
8104           (const_int 0)))
8105    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8106                          (const_int 8)
8107                          (const_int 8))
8108         (and:SI 
8109           (zero_extract:SI
8110             (match_dup 1)
8111             (const_int 8)
8112             (const_int 8))
8113           (match_dup 2)))]
8114   "ix86_match_ccmode (insn, CCNOmode)
8115    && (unsigned HOST_WIDE_INT)INTVAL (operands[2]) <= 0xff"
8116   "and{b}\t{%2, %h0|%h0, %2}"
8117   [(set_attr "type" "alu")
8118    (set_attr "length_immediate" "1")
8119    (set_attr "mode" "QI")])
8120
8121 (define_insn "*andqi_ext_1"
8122   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8123                          (const_int 8)
8124                          (const_int 8))
8125         (and:SI 
8126           (zero_extract:SI
8127             (match_operand 1 "ext_register_operand" "0")
8128             (const_int 8)
8129             (const_int 8))
8130           (zero_extend:SI
8131             (match_operand:QI 2 "general_operand" "Qm"))))
8132    (clobber (reg:CC 17))]
8133   "!TARGET_64BIT"
8134   "and{b}\t{%2, %h0|%h0, %2}"
8135   [(set_attr "type" "alu")
8136    (set_attr "length_immediate" "0")
8137    (set_attr "mode" "QI")])
8138
8139 (define_insn "*andqi_ext_1_rex64"
8140   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8141                          (const_int 8)
8142                          (const_int 8))
8143         (and:SI 
8144           (zero_extract:SI
8145             (match_operand 1 "ext_register_operand" "0")
8146             (const_int 8)
8147             (const_int 8))
8148           (zero_extend:SI
8149             (match_operand 2 "ext_register_operand" "Q"))))
8150    (clobber (reg:CC 17))]
8151   "TARGET_64BIT"
8152   "and{b}\t{%2, %h0|%h0, %2}"
8153   [(set_attr "type" "alu")
8154    (set_attr "length_immediate" "0")
8155    (set_attr "mode" "QI")])
8156
8157 (define_insn "*andqi_ext_2"
8158   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8159                          (const_int 8)
8160                          (const_int 8))
8161         (and:SI
8162           (zero_extract:SI
8163             (match_operand 1 "ext_register_operand" "%0")
8164             (const_int 8)
8165             (const_int 8))
8166           (zero_extract:SI
8167             (match_operand 2 "ext_register_operand" "Q")
8168             (const_int 8)
8169             (const_int 8))))
8170    (clobber (reg:CC 17))]
8171   ""
8172   "and{b}\t{%h2, %h0|%h0, %h2}"
8173   [(set_attr "type" "alu")
8174    (set_attr "length_immediate" "0")
8175    (set_attr "mode" "QI")])
8176 \f
8177 ;; Logical inclusive OR instructions
8178
8179 ;; %%% This used to optimize known byte-wide and operations to memory.
8180 ;; If this is considered useful, it should be done with splitters.
8181
8182 (define_expand "iordi3"
8183   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8184         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8185                 (match_operand:DI 2 "x86_64_general_operand" "")))
8186    (clobber (reg:CC 17))]
8187   "TARGET_64BIT"
8188   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8189
8190 (define_insn "*iordi_1_rex64"
8191   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8192         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8193                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8194    (clobber (reg:CC 17))]
8195   "TARGET_64BIT
8196    && ix86_binary_operator_ok (IOR, DImode, operands)"
8197   "or{q}\t{%2, %0|%0, %2}"
8198   [(set_attr "type" "alu")
8199    (set_attr "mode" "DI")])
8200
8201 (define_insn "*iordi_2_rex64"
8202   [(set (reg 17)
8203         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8204                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8205                  (const_int 0)))
8206    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8207         (ior:DI (match_dup 1) (match_dup 2)))]
8208   "TARGET_64BIT
8209    && ix86_match_ccmode (insn, CCNOmode)
8210    && ix86_binary_operator_ok (IOR, DImode, operands)"
8211   "or{q}\t{%2, %0|%0, %2}"
8212   [(set_attr "type" "alu")
8213    (set_attr "mode" "DI")])
8214
8215 (define_insn "*iordi_3_rex64"
8216   [(set (reg 17)
8217         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8218                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8219                  (const_int 0)))
8220    (clobber (match_scratch:DI 0 "=r"))]
8221   "TARGET_64BIT
8222    && ix86_match_ccmode (insn, CCNOmode)
8223    && ix86_binary_operator_ok (IOR, DImode, operands)"
8224   "or{q}\t{%2, %0|%0, %2}"
8225   [(set_attr "type" "alu")
8226    (set_attr "mode" "DI")])
8227
8228
8229 (define_expand "iorsi3"
8230   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8231         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8232                 (match_operand:SI 2 "general_operand" "")))
8233    (clobber (reg:CC 17))]
8234   ""
8235   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8236
8237 (define_insn "*iorsi_1"
8238   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8239         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8240                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8241    (clobber (reg:CC 17))]
8242   "ix86_binary_operator_ok (IOR, SImode, operands)"
8243   "or{l}\t{%2, %0|%0, %2}"
8244   [(set_attr "type" "alu")
8245    (set_attr "mode" "SI")])
8246
8247 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8248 (define_insn "*iorsi_1_zext"
8249   [(set (match_operand:DI 0 "register_operand" "=rm")
8250         (zero_extend:DI
8251           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8252                   (match_operand:SI 2 "general_operand" "rim"))))
8253    (clobber (reg:CC 17))]
8254   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8255   "or{l}\t{%2, %k0|%k0, %2}"
8256   [(set_attr "type" "alu")
8257    (set_attr "mode" "SI")])
8258
8259 (define_insn "*iorsi_1_zext_imm"
8260   [(set (match_operand:DI 0 "register_operand" "=rm")
8261         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8262                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8263    (clobber (reg:CC 17))]
8264   "TARGET_64BIT"
8265   "or{l}\t{%2, %k0|%k0, %2}"
8266   [(set_attr "type" "alu")
8267    (set_attr "mode" "SI")])
8268
8269 (define_insn "*iorsi_2"
8270   [(set (reg 17)
8271         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8272                          (match_operand:SI 2 "general_operand" "rim,ri"))
8273                  (const_int 0)))
8274    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8275         (ior:SI (match_dup 1) (match_dup 2)))]
8276   "ix86_match_ccmode (insn, CCNOmode)
8277    && ix86_binary_operator_ok (IOR, SImode, operands)"
8278   "or{l}\t{%2, %0|%0, %2}"
8279   [(set_attr "type" "alu")
8280    (set_attr "mode" "SI")])
8281
8282 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8283 ;; ??? Special case for immediate operand is missing - it is tricky.
8284 (define_insn "*iorsi_2_zext"
8285   [(set (reg 17)
8286         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8287                          (match_operand:SI 2 "general_operand" "rim"))
8288                  (const_int 0)))
8289    (set (match_operand:DI 0 "register_operand" "=r")
8290         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8291   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8292    && ix86_binary_operator_ok (IOR, SImode, operands)"
8293   "or{l}\t{%2, %k0|%k0, %2}"
8294   [(set_attr "type" "alu")
8295    (set_attr "mode" "SI")])
8296
8297 (define_insn "*iorsi_2_zext_imm"
8298   [(set (reg 17)
8299         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8300                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8301                  (const_int 0)))
8302    (set (match_operand:DI 0 "register_operand" "=r")
8303         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8304   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8305    && ix86_binary_operator_ok (IOR, SImode, operands)"
8306   "or{l}\t{%2, %k0|%k0, %2}"
8307   [(set_attr "type" "alu")
8308    (set_attr "mode" "SI")])
8309
8310 (define_insn "*iorsi_3"
8311   [(set (reg 17)
8312         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8313                          (match_operand:SI 2 "general_operand" "rim"))
8314                  (const_int 0)))
8315    (clobber (match_scratch:SI 0 "=r"))]
8316   "ix86_match_ccmode (insn, CCNOmode)
8317    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8318   "or{l}\t{%2, %0|%0, %2}"
8319   [(set_attr "type" "alu")
8320    (set_attr "mode" "SI")])
8321
8322 (define_expand "iorhi3"
8323   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8324         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8325                 (match_operand:HI 2 "general_operand" "")))
8326    (clobber (reg:CC 17))]
8327   "TARGET_HIMODE_MATH"
8328   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8329
8330 (define_insn "*iorhi_1"
8331   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8332         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8333                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8334    (clobber (reg:CC 17))]
8335   "ix86_binary_operator_ok (IOR, HImode, operands)"
8336   "or{w}\t{%2, %0|%0, %2}"
8337   [(set_attr "type" "alu")
8338    (set_attr "mode" "HI")])
8339
8340 (define_insn "*iorhi_2"
8341   [(set (reg 17)
8342         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8343                          (match_operand:HI 2 "general_operand" "rim,ri"))
8344                  (const_int 0)))
8345    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8346         (ior:HI (match_dup 1) (match_dup 2)))]
8347   "ix86_match_ccmode (insn, CCNOmode)
8348    && ix86_binary_operator_ok (IOR, HImode, operands)"
8349   "or{w}\t{%2, %0|%0, %2}"
8350   [(set_attr "type" "alu")
8351    (set_attr "mode" "HI")])
8352
8353 (define_insn "*iorhi_3"
8354   [(set (reg 17)
8355         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8356                          (match_operand:HI 2 "general_operand" "rim"))
8357                  (const_int 0)))
8358    (clobber (match_scratch:HI 0 "=r"))]
8359   "ix86_match_ccmode (insn, CCNOmode)
8360    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8361   "or{w}\t{%2, %0|%0, %2}"
8362   [(set_attr "type" "alu")
8363    (set_attr "mode" "HI")])
8364
8365 (define_expand "iorqi3"
8366   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8367         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8368                 (match_operand:QI 2 "general_operand" "")))
8369    (clobber (reg:CC 17))]
8370   "TARGET_QIMODE_MATH"
8371   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8372
8373 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8374 (define_insn "*iorqi_1"
8375   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8376         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8377                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8378    (clobber (reg:CC 17))]
8379   "ix86_binary_operator_ok (IOR, QImode, operands)"
8380   "@
8381    or{b}\t{%2, %0|%0, %2}
8382    or{b}\t{%2, %0|%0, %2}
8383    or{l}\t{%k2, %k0|%k0, %k2}"
8384   [(set_attr "type" "alu")
8385    (set_attr "mode" "QI,QI,SI")])
8386
8387 (define_insn "*iorqi_1_slp"
8388   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8389         (ior:QI (match_dup 0)
8390                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8391    (clobber (reg:CC 17))]
8392   ""
8393   "or{b}\t{%1, %0|%0, %1}"
8394   [(set_attr "type" "alu1")
8395    (set_attr "mode" "QI")])
8396
8397 (define_insn "*iorqi_2"
8398   [(set (reg 17)
8399         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8400                          (match_operand:QI 2 "general_operand" "qim,qi"))
8401                  (const_int 0)))
8402    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8403         (ior:QI (match_dup 1) (match_dup 2)))]
8404   "ix86_match_ccmode (insn, CCNOmode)
8405    && ix86_binary_operator_ok (IOR, QImode, operands)"
8406   "or{b}\t{%2, %0|%0, %2}"
8407   [(set_attr "type" "alu")
8408    (set_attr "mode" "QI")])
8409
8410 (define_insn "*iorqi_2_slp"
8411   [(set (reg 17)
8412         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8413                          (match_operand:QI 1 "general_operand" "qim,qi"))
8414                  (const_int 0)))
8415    (set (strict_low_part (match_dup 0))
8416         (ior:QI (match_dup 0) (match_dup 1)))]
8417   "ix86_match_ccmode (insn, CCNOmode)"
8418   "or{b}\t{%1, %0|%0, %1}"
8419   [(set_attr "type" "alu1")
8420    (set_attr "mode" "QI")])
8421
8422 (define_insn "*iorqi_3"
8423   [(set (reg 17)
8424         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8425                          (match_operand:QI 2 "general_operand" "qim"))
8426                  (const_int 0)))
8427    (clobber (match_scratch:QI 0 "=q"))]
8428   "ix86_match_ccmode (insn, CCNOmode)
8429    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8430   "or{b}\t{%2, %0|%0, %2}"
8431   [(set_attr "type" "alu")
8432    (set_attr "mode" "QI")])
8433
8434 \f
8435 ;; Logical XOR instructions
8436
8437 ;; %%% This used to optimize known byte-wide and operations to memory.
8438 ;; If this is considered useful, it should be done with splitters.
8439
8440 (define_expand "xordi3"
8441   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8442         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8443                 (match_operand:DI 2 "x86_64_general_operand" "")))
8444    (clobber (reg:CC 17))]
8445   "TARGET_64BIT"
8446   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8447
8448 (define_insn "*xordi_1_rex64"
8449   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8450         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8451                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8452    (clobber (reg:CC 17))]
8453   "TARGET_64BIT
8454    && ix86_binary_operator_ok (XOR, DImode, operands)"
8455   "@
8456    xor{q}\t{%2, %0|%0, %2} 
8457    xor{q}\t{%2, %0|%0, %2}"
8458   [(set_attr "type" "alu")
8459    (set_attr "mode" "DI,DI")])
8460
8461 (define_insn "*xordi_2_rex64"
8462   [(set (reg 17)
8463         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8464                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8465                  (const_int 0)))
8466    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8467         (xor:DI (match_dup 1) (match_dup 2)))]
8468   "TARGET_64BIT
8469    && ix86_match_ccmode (insn, CCNOmode)
8470    && ix86_binary_operator_ok (XOR, DImode, operands)"
8471   "@
8472    xor{q}\t{%2, %0|%0, %2} 
8473    xor{q}\t{%2, %0|%0, %2}"
8474   [(set_attr "type" "alu")
8475    (set_attr "mode" "DI,DI")])
8476
8477 (define_insn "*xordi_3_rex64"
8478   [(set (reg 17)
8479         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8480                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8481                  (const_int 0)))
8482    (clobber (match_scratch:DI 0 "=r"))]
8483   "TARGET_64BIT
8484    && ix86_match_ccmode (insn, CCNOmode)
8485    && ix86_binary_operator_ok (XOR, DImode, operands)"
8486   "xor{q}\t{%2, %0|%0, %2}"
8487   [(set_attr "type" "alu")
8488    (set_attr "mode" "DI")])
8489
8490 (define_expand "xorsi3"
8491   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8492         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8493                 (match_operand:SI 2 "general_operand" "")))
8494    (clobber (reg:CC 17))]
8495   ""
8496   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8497
8498 (define_insn "*xorsi_1"
8499   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8500         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8501                 (match_operand:SI 2 "general_operand" "ri,rm")))
8502    (clobber (reg:CC 17))]
8503   "ix86_binary_operator_ok (XOR, SImode, operands)"
8504   "xor{l}\t{%2, %0|%0, %2}"
8505   [(set_attr "type" "alu")
8506    (set_attr "mode" "SI")])
8507
8508 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8509 ;; Add speccase for immediates
8510 (define_insn "*xorsi_1_zext"
8511   [(set (match_operand:DI 0 "register_operand" "=r")
8512         (zero_extend:DI
8513           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8514                   (match_operand:SI 2 "general_operand" "rim"))))
8515    (clobber (reg:CC 17))]
8516   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8517   "xor{l}\t{%2, %k0|%k0, %2}"
8518   [(set_attr "type" "alu")
8519    (set_attr "mode" "SI")])
8520
8521 (define_insn "*xorsi_1_zext_imm"
8522   [(set (match_operand:DI 0 "register_operand" "=r")
8523         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8524                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8525    (clobber (reg:CC 17))]
8526   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8527   "xor{l}\t{%2, %k0|%k0, %2}"
8528   [(set_attr "type" "alu")
8529    (set_attr "mode" "SI")])
8530
8531 (define_insn "*xorsi_2"
8532   [(set (reg 17)
8533         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8534                          (match_operand:SI 2 "general_operand" "rim,ri"))
8535                  (const_int 0)))
8536    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8537         (xor:SI (match_dup 1) (match_dup 2)))]
8538   "ix86_match_ccmode (insn, CCNOmode)
8539    && ix86_binary_operator_ok (XOR, SImode, operands)"
8540   "xor{l}\t{%2, %0|%0, %2}"
8541   [(set_attr "type" "alu")
8542    (set_attr "mode" "SI")])
8543
8544 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8545 ;; ??? Special case for immediate operand is missing - it is tricky.
8546 (define_insn "*xorsi_2_zext"
8547   [(set (reg 17)
8548         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8549                          (match_operand:SI 2 "general_operand" "rim"))
8550                  (const_int 0)))
8551    (set (match_operand:DI 0 "register_operand" "=r")
8552         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8553   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8554    && ix86_binary_operator_ok (XOR, SImode, operands)"
8555   "xor{l}\t{%2, %k0|%k0, %2}"
8556   [(set_attr "type" "alu")
8557    (set_attr "mode" "SI")])
8558
8559 (define_insn "*xorsi_2_zext_imm"
8560   [(set (reg 17)
8561         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8562                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8563                  (const_int 0)))
8564    (set (match_operand:DI 0 "register_operand" "=r")
8565         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8566   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8567    && ix86_binary_operator_ok (XOR, SImode, operands)"
8568   "xor{l}\t{%2, %k0|%k0, %2}"
8569   [(set_attr "type" "alu")
8570    (set_attr "mode" "SI")])
8571
8572 (define_insn "*xorsi_3"
8573   [(set (reg 17)
8574         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8575                          (match_operand:SI 2 "general_operand" "rim"))
8576                  (const_int 0)))
8577    (clobber (match_scratch:SI 0 "=r"))]
8578   "ix86_match_ccmode (insn, CCNOmode)
8579    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8580   "xor{l}\t{%2, %0|%0, %2}"
8581   [(set_attr "type" "alu")
8582    (set_attr "mode" "SI")])
8583
8584 (define_expand "xorhi3"
8585   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8586         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
8587                 (match_operand:HI 2 "general_operand" "")))
8588    (clobber (reg:CC 17))]
8589   "TARGET_HIMODE_MATH"
8590   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
8591
8592 (define_insn "*xorhi_1"
8593   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8594         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8595                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8596    (clobber (reg:CC 17))]
8597   "ix86_binary_operator_ok (XOR, HImode, operands)"
8598   "xor{w}\t{%2, %0|%0, %2}"
8599   [(set_attr "type" "alu")
8600    (set_attr "mode" "HI")])
8601
8602 (define_insn "*xorhi_2"
8603   [(set (reg 17)
8604         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8605                          (match_operand:HI 2 "general_operand" "rim,ri"))
8606                  (const_int 0)))
8607    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8608         (xor:HI (match_dup 1) (match_dup 2)))]
8609   "ix86_match_ccmode (insn, CCNOmode)
8610    && ix86_binary_operator_ok (XOR, HImode, operands)"
8611   "xor{w}\t{%2, %0|%0, %2}"
8612   [(set_attr "type" "alu")
8613    (set_attr "mode" "HI")])
8614
8615 (define_insn "*xorhi_3"
8616   [(set (reg 17)
8617         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8618                          (match_operand:HI 2 "general_operand" "rim"))
8619                  (const_int 0)))
8620    (clobber (match_scratch:HI 0 "=r"))]
8621   "ix86_match_ccmode (insn, CCNOmode)
8622    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8623   "xor{w}\t{%2, %0|%0, %2}"
8624   [(set_attr "type" "alu")
8625    (set_attr "mode" "HI")])
8626
8627 (define_expand "xorqi3"
8628   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8629         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
8630                 (match_operand:QI 2 "general_operand" "")))
8631    (clobber (reg:CC 17))]
8632   "TARGET_QIMODE_MATH"
8633   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
8634
8635 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8636 (define_insn "*xorqi_1"
8637   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8638         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8639                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8640    (clobber (reg:CC 17))]
8641   "ix86_binary_operator_ok (XOR, QImode, operands)"
8642   "@
8643    xor{b}\t{%2, %0|%0, %2}
8644    xor{b}\t{%2, %0|%0, %2}
8645    xor{l}\t{%k2, %k0|%k0, %k2}"
8646   [(set_attr "type" "alu")
8647    (set_attr "mode" "QI,QI,SI")])
8648
8649 (define_insn "*xorqi_ext_1"
8650   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8651                          (const_int 8)
8652                          (const_int 8))
8653         (xor:SI 
8654           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8655                            (const_int 8)
8656                            (const_int 8))
8657           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8658                            (const_int 8)
8659                            (const_int 8))))
8660    (clobber (reg:CC 17))]
8661   ""
8662   "xor{b}\t{%h2, %h0|%h0, %h2}"
8663   [(set_attr "type" "alu")
8664    (set_attr "length_immediate" "0")
8665    (set_attr "mode" "QI")])
8666
8667 (define_insn "*xorqi_cc_1"
8668   [(set (reg 17)
8669         (compare
8670           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8671                   (match_operand:QI 2 "general_operand" "qim,qi"))
8672           (const_int 0)))
8673    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8674         (xor:QI (match_dup 1) (match_dup 2)))]
8675   "ix86_match_ccmode (insn, CCNOmode)
8676    && ix86_binary_operator_ok (XOR, QImode, operands)"
8677   "xor{b}\t{%2, %0|%0, %2}"
8678   [(set_attr "type" "alu")
8679    (set_attr "mode" "QI")])
8680
8681 (define_insn "*xorqi_cc_2"
8682   [(set (reg 17)
8683         (compare
8684           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8685                   (match_operand:QI 2 "general_operand" "qim"))
8686           (const_int 0)))
8687    (clobber (match_scratch:QI 0 "=q"))]
8688   "ix86_match_ccmode (insn, CCNOmode)
8689    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8690   "xor{b}\t{%2, %0|%0, %2}"
8691   [(set_attr "type" "alu")
8692    (set_attr "mode" "QI")])
8693
8694 (define_insn "*xorqi_cc_ext_1"
8695   [(set (reg 17)
8696         (compare
8697           (xor:SI
8698             (zero_extract:SI
8699               (match_operand 1 "ext_register_operand" "0")
8700               (const_int 8)
8701               (const_int 8))
8702             (match_operand:QI 2 "general_operand" "qmn"))
8703           (const_int 0)))
8704    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8705                          (const_int 8)
8706                          (const_int 8))
8707         (xor:SI 
8708           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
8709           (match_dup 2)))]
8710   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8711   "xor{b}\t{%2, %h0|%h0, %2}"
8712   [(set_attr "type" "alu")
8713    (set_attr "mode" "QI")])
8714
8715 (define_insn "*xorqi_cc_ext_1_rex64"
8716   [(set (reg 17)
8717         (compare
8718           (xor:SI
8719             (zero_extract:SI
8720               (match_operand 1 "ext_register_operand" "0")
8721               (const_int 8)
8722               (const_int 8))
8723             (match_operand:QI 2 "nonmemory_operand" "Qn"))
8724           (const_int 0)))
8725    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8726                          (const_int 8)
8727                          (const_int 8))
8728         (xor:SI 
8729           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
8730           (match_dup 2)))]
8731   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8732   "xor{b}\t{%2, %h0|%h0, %2}"
8733   [(set_attr "type" "alu")
8734    (set_attr "mode" "QI")])
8735
8736 (define_expand "xorqi_cc_ext_1"
8737   [(parallel [
8738      (set (reg:CCNO 17)
8739           (compare:CCNO
8740             (xor:SI
8741               (zero_extract:SI
8742                 (match_operand 1 "ext_register_operand" "")
8743                 (const_int 8)
8744                 (const_int 8))
8745               (match_operand:QI 2 "general_operand" ""))
8746             (const_int 0)))
8747      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8748                            (const_int 8)
8749                            (const_int 8))
8750           (xor:SI 
8751             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
8752             (match_dup 2)))])]
8753   ""
8754   "")
8755 \f
8756 ;; Negation instructions
8757
8758 (define_expand "negdi2"
8759   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
8760                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
8761               (clobber (reg:CC 17))])]
8762   ""
8763   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
8764
8765 (define_insn "*negdi2_1"
8766   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
8767         (neg:DI (match_operand:DI 1 "general_operand" "0")))
8768    (clobber (reg:CC 17))]
8769   "!TARGET_64BIT
8770    && ix86_unary_operator_ok (NEG, DImode, operands)"
8771   "#")
8772
8773 (define_split
8774   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8775         (neg:DI (match_operand:DI 1 "general_operand" "")))
8776    (clobber (reg:CC 17))]
8777   "!TARGET_64BIT && reload_completed"
8778   [(parallel
8779     [(set (reg:CCZ 17)
8780           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
8781      (set (match_dup 0) (neg:SI (match_dup 2)))])
8782    (parallel
8783     [(set (match_dup 1)
8784           (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
8785                             (match_dup 3))
8786                    (const_int 0)))
8787      (clobber (reg:CC 17))])
8788    (parallel
8789     [(set (match_dup 1)
8790           (neg:SI (match_dup 1)))
8791      (clobber (reg:CC 17))])]
8792   "split_di (operands+1, 1, operands+2, operands+3);
8793    split_di (operands+0, 1, operands+0, operands+1);")
8794
8795 (define_insn "*negdi2_1_rex64"
8796   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
8797         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
8798    (clobber (reg:CC 17))]
8799   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
8800   "neg{q}\t%0"
8801   [(set_attr "type" "negnot")
8802    (set_attr "mode" "DI")])
8803
8804 ;; The problem with neg is that it does not perform (compare x 0),
8805 ;; it really performs (compare 0 x), which leaves us with the zero
8806 ;; flag being the only useful item.
8807
8808 (define_insn "*negdi2_cmpz_rex64"
8809   [(set (reg:CCZ 17)
8810         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
8811                      (const_int 0)))
8812    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
8813         (neg:DI (match_dup 1)))]
8814   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
8815   "neg{q}\t%0"
8816   [(set_attr "type" "negnot")
8817    (set_attr "mode" "DI")])
8818
8819
8820 (define_expand "negsi2"
8821   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
8822                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
8823               (clobber (reg:CC 17))])]
8824   ""
8825   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
8826
8827 (define_insn "*negsi2_1"
8828   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
8829         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
8830    (clobber (reg:CC 17))]
8831   "ix86_unary_operator_ok (NEG, SImode, operands)"
8832   "neg{l}\t%0"
8833   [(set_attr "type" "negnot")
8834    (set_attr "mode" "SI")])
8835
8836 ;; Combine is quite creative about this pattern.
8837 (define_insn "*negsi2_1_zext"
8838   [(set (match_operand:DI 0 "register_operand" "=r")
8839         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8840                                         (const_int 32)))
8841                      (const_int 32)))
8842    (clobber (reg:CC 17))]
8843   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8844   "neg{l}\t%k0"
8845   [(set_attr "type" "negnot")
8846    (set_attr "mode" "SI")])
8847
8848 ;; The problem with neg is that it does not perform (compare x 0),
8849 ;; it really performs (compare 0 x), which leaves us with the zero
8850 ;; flag being the only useful item.
8851
8852 (define_insn "*negsi2_cmpz"
8853   [(set (reg:CCZ 17)
8854         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
8855                      (const_int 0)))
8856    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
8857         (neg:SI (match_dup 1)))]
8858   "ix86_unary_operator_ok (NEG, SImode, operands)"
8859   "neg{l}\t%0"
8860   [(set_attr "type" "negnot")
8861    (set_attr "mode" "SI")])
8862
8863 (define_insn "*negsi2_cmpz_zext"
8864   [(set (reg:CCZ 17)
8865         (compare:CCZ (lshiftrt:DI
8866                        (neg:DI (ashift:DI
8867                                  (match_operand:DI 1 "register_operand" "0")
8868                                  (const_int 32)))
8869                        (const_int 32))
8870                      (const_int 0)))
8871    (set (match_operand:DI 0 "register_operand" "=r")
8872         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8873                                         (const_int 32)))
8874                      (const_int 32)))]
8875   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8876   "neg{l}\t%k0"
8877   [(set_attr "type" "negnot")
8878    (set_attr "mode" "SI")])
8879
8880 (define_expand "neghi2"
8881   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
8882                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
8883               (clobber (reg:CC 17))])]
8884   "TARGET_HIMODE_MATH"
8885   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
8886
8887 (define_insn "*neghi2_1"
8888   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
8889         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
8890    (clobber (reg:CC 17))]
8891   "ix86_unary_operator_ok (NEG, HImode, operands)"
8892   "neg{w}\t%0"
8893   [(set_attr "type" "negnot")
8894    (set_attr "mode" "HI")])
8895
8896 (define_insn "*neghi2_cmpz"
8897   [(set (reg:CCZ 17)
8898         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
8899                      (const_int 0)))
8900    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
8901         (neg:HI (match_dup 1)))]
8902   "ix86_unary_operator_ok (NEG, HImode, operands)"
8903   "neg{w}\t%0"
8904   [(set_attr "type" "negnot")
8905    (set_attr "mode" "HI")])
8906
8907 (define_expand "negqi2"
8908   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
8909                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
8910               (clobber (reg:CC 17))])]
8911   "TARGET_QIMODE_MATH"
8912   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
8913
8914 (define_insn "*negqi2_1"
8915   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
8916         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
8917    (clobber (reg:CC 17))]
8918   "ix86_unary_operator_ok (NEG, QImode, operands)"
8919   "neg{b}\t%0"
8920   [(set_attr "type" "negnot")
8921    (set_attr "mode" "QI")])
8922
8923 (define_insn "*negqi2_cmpz"
8924   [(set (reg:CCZ 17)
8925         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
8926                      (const_int 0)))
8927    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
8928         (neg:QI (match_dup 1)))]
8929   "ix86_unary_operator_ok (NEG, QImode, operands)"
8930   "neg{b}\t%0"
8931   [(set_attr "type" "negnot")
8932    (set_attr "mode" "QI")])
8933
8934 ;; Changing of sign for FP values is doable using integer unit too.
8935
8936 (define_expand "negsf2"
8937   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
8938                    (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
8939               (clobber (reg:CC 17))])]
8940   "TARGET_80387"
8941   "if (TARGET_SSE)
8942      {
8943        /* In case operand is in memory,  we will not use SSE.  */
8944        if (memory_operand (operands[0], VOIDmode)
8945            && rtx_equal_p (operands[0], operands[1]))
8946          emit_insn (gen_negsf2_memory (operands[0], operands[1]));
8947        else
8948         {
8949           /* Using SSE is tricky, since we need bitwise negation of -0
8950              in register.  */
8951           rtx reg = gen_reg_rtx (SFmode);
8952           rtx dest = operands[0];
8953
8954           operands[1] = force_reg (SFmode, operands[1]);
8955           operands[0] = force_reg (SFmode, operands[0]);
8956           emit_move_insn (reg,
8957                           gen_lowpart (SFmode,
8958                                        gen_int_mode (0x80000000, SImode)));
8959           emit_insn (gen_negsf2_ifs (operands[0], operands[1], reg));
8960           if (dest != operands[0])
8961             emit_move_insn (dest, operands[0]);
8962         }
8963        DONE;
8964      }
8965    ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
8966
8967 (define_insn "negsf2_memory"
8968   [(set (match_operand:SF 0 "memory_operand" "=m")
8969         (neg:SF (match_operand:SF 1 "memory_operand" "0")))
8970    (clobber (reg:CC 17))]
8971   "ix86_unary_operator_ok (NEG, SFmode, operands)"
8972   "#")
8973
8974 (define_insn "negsf2_ifs"
8975   [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
8976         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
8977    (use (match_operand:SF 2 "nonmemory_operand" "x,0#x,*g#x,*g#x"))
8978    (clobber (reg:CC 17))]
8979   "TARGET_SSE
8980    && (reload_in_progress || reload_completed
8981        || (register_operand (operands[0], VOIDmode)
8982            && register_operand (operands[1], VOIDmode)))"
8983   "#")
8984
8985 (define_split
8986   [(set (match_operand:SF 0 "memory_operand" "")
8987         (neg:SF (match_operand:SF 1 "memory_operand" "")))
8988    (use (match_operand:SF 2 "" ""))
8989    (clobber (reg:CC 17))]
8990   ""
8991   [(parallel [(set (match_dup 0)
8992                    (neg:SF (match_dup 1)))
8993               (clobber (reg:CC 17))])])
8994
8995 (define_split
8996   [(set (match_operand:SF 0 "register_operand" "")
8997         (neg:SF (match_operand:SF 1 "register_operand" "")))
8998    (use (match_operand:SF 2 "" ""))
8999    (clobber (reg:CC 17))]
9000   "reload_completed && !SSE_REG_P (operands[0])"
9001   [(parallel [(set (match_dup 0)
9002                    (neg:SF (match_dup 1)))
9003               (clobber (reg:CC 17))])])
9004
9005 (define_split
9006   [(set (match_operand:SF 0 "register_operand" "")
9007         (neg:SF (match_operand:SF 1 "register_operand" "")))
9008    (use (match_operand:SF 2 "register_operand" ""))
9009    (clobber (reg:CC 17))]
9010   "reload_completed && SSE_REG_P (operands[0])"
9011   [(set (subreg:TI (match_dup 0) 0)
9012         (xor:TI (subreg:TI (match_dup 1) 0)
9013                 (subreg:TI (match_dup 2) 0)))]
9014 {
9015   if (operands_match_p (operands[0], operands[2]))
9016     {
9017       rtx tmp;
9018       tmp = operands[1];
9019       operands[1] = operands[2];
9020       operands[2] = tmp;
9021     }
9022 })
9023
9024
9025 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9026 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9027 ;; to itself.
9028 (define_insn "*negsf2_if"
9029   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9030         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
9031    (clobber (reg:CC 17))]
9032   "TARGET_80387 && !TARGET_SSE
9033    && ix86_unary_operator_ok (NEG, SFmode, operands)"
9034   "#")
9035
9036 (define_split
9037   [(set (match_operand:SF 0 "register_operand" "")
9038         (neg:SF (match_operand:SF 1 "register_operand" "")))
9039    (clobber (reg:CC 17))]
9040   "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
9041   [(set (match_dup 0)
9042         (neg:SF (match_dup 1)))]
9043   "")
9044
9045 (define_split
9046   [(set (match_operand:SF 0 "register_operand" "")
9047         (neg:SF (match_operand:SF 1 "register_operand" "")))
9048    (clobber (reg:CC 17))]
9049   "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
9050   [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9051               (clobber (reg:CC 17))])]
9052   "operands[1] = gen_int_mode (0x80000000, SImode);
9053    operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
9054
9055 (define_split
9056   [(set (match_operand 0 "memory_operand" "")
9057         (neg (match_operand 1 "memory_operand" "")))
9058    (clobber (reg:CC 17))]
9059   "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
9060   [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
9061               (clobber (reg:CC 17))])]
9062 {
9063   int size = GET_MODE_SIZE (GET_MODE (operands[1]));
9064
9065   /* XFmode's size is 12, TFmode 16, but only 10 bytes are used.  */
9066   if (size >= 12)
9067     size = 10;
9068   operands[0] = adjust_address (operands[0], QImode, size - 1);
9069   operands[1] = gen_int_mode (0x80, QImode);
9070 })
9071
9072 (define_expand "negdf2"
9073   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
9074                    (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
9075               (clobber (reg:CC 17))])]
9076   "TARGET_80387"
9077   "if (TARGET_SSE2)
9078      {
9079        /* In case operand is in memory,  we will not use SSE.  */
9080        if (memory_operand (operands[0], VOIDmode)
9081            && rtx_equal_p (operands[0], operands[1]))
9082          emit_insn (gen_negdf2_memory (operands[0], operands[1]));
9083        else
9084         {
9085           /* Using SSE is tricky, since we need bitwise negation of -0
9086              in register.  */
9087           rtx reg = gen_reg_rtx (DFmode);
9088 #if HOST_BITS_PER_WIDE_INT >= 64
9089           rtx imm = gen_int_mode (((HOST_WIDE_INT)1) << 63, DImode);
9090 #else
9091           rtx imm = immed_double_const (0, 0x80000000, DImode);
9092 #endif
9093           rtx dest = operands[0];
9094
9095           operands[1] = force_reg (DFmode, operands[1]);
9096           operands[0] = force_reg (DFmode, operands[0]);
9097           emit_move_insn (reg, gen_lowpart (DFmode, imm));
9098           emit_insn (gen_negdf2_ifs (operands[0], operands[1], reg));
9099           if (dest != operands[0])
9100             emit_move_insn (dest, operands[0]);
9101         }
9102        DONE;
9103      }
9104    ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
9105
9106 (define_insn "negdf2_memory"
9107   [(set (match_operand:DF 0 "memory_operand" "=m")
9108         (neg:DF (match_operand:DF 1 "memory_operand" "0")))
9109    (clobber (reg:CC 17))]
9110   "ix86_unary_operator_ok (NEG, DFmode, operands)"
9111   "#")
9112
9113 (define_insn "negdf2_ifs"
9114   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
9115         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
9116    (use (match_operand:DF 2 "nonmemory_operand" "Y,0,*g#Y,*g#Y"))
9117    (clobber (reg:CC 17))]
9118   "!TARGET_64BIT && TARGET_SSE2
9119    && (reload_in_progress || reload_completed
9120        || (register_operand (operands[0], VOIDmode)
9121            && register_operand (operands[1], VOIDmode)))"
9122   "#")
9123
9124 (define_insn "*negdf2_ifs_rex64"
9125   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,fm#Yr,r#Yf")
9126         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
9127    (use (match_operand:DF 2 "general_operand" "Y,0,*g#Yr,*rm"))
9128    (clobber (reg:CC 17))]
9129   "TARGET_64BIT && TARGET_SSE2
9130    && (reload_in_progress || reload_completed
9131        || (register_operand (operands[0], VOIDmode)
9132            && register_operand (operands[1], VOIDmode)))"
9133   "#")
9134
9135 (define_split
9136   [(set (match_operand:DF 0 "memory_operand" "")
9137         (neg:DF (match_operand:DF 1 "memory_operand" "")))
9138    (use (match_operand:DF 2 "" ""))
9139    (clobber (reg:CC 17))]
9140   ""
9141   [(parallel [(set (match_dup 0)
9142                    (neg:DF (match_dup 1)))
9143               (clobber (reg:CC 17))])])
9144
9145 (define_split
9146   [(set (match_operand:DF 0 "register_operand" "")
9147         (neg:DF (match_operand:DF 1 "register_operand" "")))
9148    (use (match_operand:DF 2 "" ""))
9149    (clobber (reg:CC 17))]
9150   "reload_completed && !SSE_REG_P (operands[0])
9151    && (!TARGET_64BIT || FP_REG_P (operands[0]))"
9152   [(parallel [(set (match_dup 0)
9153                    (neg:DF (match_dup 1)))
9154               (clobber (reg:CC 17))])])
9155
9156 (define_split
9157   [(set (match_operand:DF 0 "register_operand" "")
9158         (neg:DF (match_operand:DF 1 "register_operand" "")))
9159    (use (match_operand:DF 2 "" ""))
9160    (clobber (reg:CC 17))]
9161   "TARGET_64BIT && reload_completed && GENERAL_REG_P (operands[0])"
9162   [(parallel [(set (match_dup 0)
9163                    (xor:DI (match_dup 1) (match_dup 2)))
9164               (clobber (reg:CC 17))])]
9165    "operands[0] = gen_lowpart (DImode, operands[0]);
9166     operands[1] = gen_lowpart (DImode, operands[1]);
9167     operands[2] = gen_lowpart (DImode, operands[2]);")
9168
9169 (define_split
9170   [(set (match_operand:DF 0 "register_operand" "")
9171         (neg:DF (match_operand:DF 1 "register_operand" "")))
9172    (use (match_operand:DF 2 "register_operand" ""))
9173    (clobber (reg:CC 17))]
9174   "reload_completed && SSE_REG_P (operands[0])"
9175   [(set (subreg:TI (match_dup 0) 0)
9176         (xor:TI (subreg:TI (match_dup 1) 0)
9177                 (subreg:TI (match_dup 2) 0)))]
9178 {
9179   if (operands_match_p (operands[0], operands[2]))
9180     {
9181       rtx tmp;
9182       tmp = operands[1];
9183       operands[1] = operands[2];
9184       operands[2] = tmp;
9185     }
9186 })
9187
9188 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9189 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9190 ;; to itself.
9191 (define_insn "*negdf2_if"
9192   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9193         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9194    (clobber (reg:CC 17))]
9195   "!TARGET_64BIT && TARGET_80387
9196    && ix86_unary_operator_ok (NEG, DFmode, operands)"
9197   "#")
9198
9199 ;; FIXME: We should to allow integer registers here.  Problem is that
9200 ;; we need another scratch register to get constant from.
9201 ;; Forcing constant to mem if no register available in peep2 should be
9202 ;; safe even for PIC mode, because of RIP relative addressing.
9203 (define_insn "*negdf2_if_rex64"
9204   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
9205         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9206    (clobber (reg:CC 17))]
9207   "TARGET_64BIT && TARGET_80387
9208    && ix86_unary_operator_ok (NEG, DFmode, operands)"
9209   "#")
9210
9211 (define_split
9212   [(set (match_operand:DF 0 "register_operand" "")
9213         (neg:DF (match_operand:DF 1 "register_operand" "")))
9214    (clobber (reg:CC 17))]
9215   "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
9216   [(set (match_dup 0)
9217         (neg:DF (match_dup 1)))]
9218   "")
9219
9220 (define_split
9221   [(set (match_operand:DF 0 "register_operand" "")
9222         (neg:DF (match_operand:DF 1 "register_operand" "")))
9223    (clobber (reg:CC 17))]
9224   "!TARGET_64BIT && TARGET_80387 && reload_completed
9225    && !FP_REGNO_P (REGNO (operands[0]))"
9226   [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
9227               (clobber (reg:CC 17))])]
9228   "operands[4] = gen_int_mode (0x80000000, SImode);
9229    split_di (operands+0, 1, operands+2, operands+3);")
9230
9231 (define_expand "negxf2"
9232   [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
9233                    (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
9234               (clobber (reg:CC 17))])]
9235   "!TARGET_64BIT && TARGET_80387"
9236   "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
9237
9238 (define_expand "negtf2"
9239   [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
9240                    (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
9241               (clobber (reg:CC 17))])]
9242   "TARGET_80387"
9243   "ix86_expand_unary_operator (NEG, TFmode, operands); DONE;")
9244
9245 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9246 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9247 ;; to itself.
9248 (define_insn "*negxf2_if"
9249   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9250         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
9251    (clobber (reg:CC 17))]
9252   "!TARGET_64BIT && TARGET_80387
9253    && ix86_unary_operator_ok (NEG, XFmode, operands)"
9254   "#")
9255
9256 (define_split
9257   [(set (match_operand:XF 0 "register_operand" "")
9258         (neg:XF (match_operand:XF 1 "register_operand" "")))
9259    (clobber (reg:CC 17))]
9260   "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
9261   [(set (match_dup 0)
9262         (neg:XF (match_dup 1)))]
9263   "")
9264
9265 (define_split
9266   [(set (match_operand:XF 0 "register_operand" "")
9267         (neg:XF (match_operand:XF 1 "register_operand" "")))
9268    (clobber (reg:CC 17))]
9269   "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
9270   [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9271               (clobber (reg:CC 17))])]
9272   "operands[1] = GEN_INT (0x8000);
9273    operands[0] = gen_rtx_REG (SImode,
9274                               true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
9275
9276 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9277 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9278 ;; to itself.
9279 (define_insn "*negtf2_if"
9280   [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
9281         (neg:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
9282    (clobber (reg:CC 17))]
9283   "TARGET_80387 && ix86_unary_operator_ok (NEG, TFmode, operands)"
9284   "#")
9285
9286 (define_split
9287   [(set (match_operand:TF 0 "register_operand" "")
9288         (neg:TF (match_operand:TF 1 "register_operand" "")))
9289    (clobber (reg:CC 17))]
9290   "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
9291   [(set (match_dup 0)
9292         (neg:TF (match_dup 1)))]
9293   "")
9294
9295 (define_split
9296   [(set (match_operand:TF 0 "register_operand" "")
9297         (neg:TF (match_operand:TF 1 "register_operand" "")))
9298    (clobber (reg:CC 17))]
9299   "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
9300   [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9301               (clobber (reg:CC 17))])]
9302   "operands[1] = GEN_INT (0x8000);
9303    operands[0] = gen_rtx_REG (SImode,
9304                               true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
9305
9306 ;; Conditionize these after reload. If they matches before reload, we 
9307 ;; lose the clobber and ability to use integer instructions.
9308
9309 (define_insn "*negsf2_1"
9310   [(set (match_operand:SF 0 "register_operand" "=f")
9311         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9312   "TARGET_80387 && reload_completed"
9313   "fchs"
9314   [(set_attr "type" "fsgn")
9315    (set_attr "mode" "SF")
9316    (set_attr "ppro_uops" "few")])
9317
9318 (define_insn "*negdf2_1"
9319   [(set (match_operand:DF 0 "register_operand" "=f")
9320         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9321   "TARGET_80387 && reload_completed"
9322   "fchs"
9323   [(set_attr "type" "fsgn")
9324    (set_attr "mode" "DF")
9325    (set_attr "ppro_uops" "few")])
9326
9327 (define_insn "*negextendsfdf2"
9328   [(set (match_operand:DF 0 "register_operand" "=f")
9329         (neg:DF (float_extend:DF
9330                   (match_operand:SF 1 "register_operand" "0"))))]
9331   "TARGET_80387"
9332   "fchs"
9333   [(set_attr "type" "fsgn")
9334    (set_attr "mode" "DF")
9335    (set_attr "ppro_uops" "few")])
9336
9337 (define_insn "*negxf2_1"
9338   [(set (match_operand:XF 0 "register_operand" "=f")
9339         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9340   "!TARGET_64BIT && TARGET_80387 && reload_completed"
9341   "fchs"
9342   [(set_attr "type" "fsgn")
9343    (set_attr "mode" "XF")
9344    (set_attr "ppro_uops" "few")])
9345
9346 (define_insn "*negextenddfxf2"
9347   [(set (match_operand:XF 0 "register_operand" "=f")
9348         (neg:XF (float_extend:XF
9349                   (match_operand:DF 1 "register_operand" "0"))))]
9350   "!TARGET_64BIT && TARGET_80387"
9351   "fchs"
9352   [(set_attr "type" "fsgn")
9353    (set_attr "mode" "XF")
9354    (set_attr "ppro_uops" "few")])
9355
9356 (define_insn "*negextendsfxf2"
9357   [(set (match_operand:XF 0 "register_operand" "=f")
9358         (neg:XF (float_extend:XF
9359                   (match_operand:SF 1 "register_operand" "0"))))]
9360   "!TARGET_64BIT && TARGET_80387"
9361   "fchs"
9362   [(set_attr "type" "fsgn")
9363    (set_attr "mode" "XF")
9364    (set_attr "ppro_uops" "few")])
9365
9366 (define_insn "*negtf2_1"
9367   [(set (match_operand:TF 0 "register_operand" "=f")
9368         (neg:TF (match_operand:TF 1 "register_operand" "0")))]
9369   "TARGET_80387 && reload_completed"
9370   "fchs"
9371   [(set_attr "type" "fsgn")
9372    (set_attr "mode" "XF")
9373    (set_attr "ppro_uops" "few")])
9374
9375 (define_insn "*negextenddftf2"
9376   [(set (match_operand:TF 0 "register_operand" "=f")
9377         (neg:TF (float_extend:TF
9378                   (match_operand:DF 1 "register_operand" "0"))))]
9379   "TARGET_80387"
9380   "fchs"
9381   [(set_attr "type" "fsgn")
9382    (set_attr "mode" "XF")
9383    (set_attr "ppro_uops" "few")])
9384
9385 (define_insn "*negextendsftf2"
9386   [(set (match_operand:TF 0 "register_operand" "=f")
9387         (neg:TF (float_extend:TF
9388                   (match_operand:SF 1 "register_operand" "0"))))]
9389   "TARGET_80387"
9390   "fchs"
9391   [(set_attr "type" "fsgn")
9392    (set_attr "mode" "XF")
9393    (set_attr "ppro_uops" "few")])
9394 \f
9395 ;; Absolute value instructions
9396
9397 (define_expand "abssf2"
9398   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9399                    (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9400               (clobber (reg:CC 17))])]
9401   "TARGET_80387"
9402   "if (TARGET_SSE)
9403      {
9404        /* In case operand is in memory,  we will not use SSE.  */
9405        if (memory_operand (operands[0], VOIDmode)
9406            && rtx_equal_p (operands[0], operands[1]))
9407          emit_insn (gen_abssf2_memory (operands[0], operands[1]));
9408        else
9409         {
9410           /* Using SSE is tricky, since we need bitwise negation of -0
9411              in register.  */
9412           rtx reg = gen_reg_rtx (SFmode);
9413           rtx dest = operands[0];
9414
9415           operands[1] = force_reg (SFmode, operands[1]);
9416           operands[0] = force_reg (SFmode, operands[0]);
9417           emit_move_insn (reg,
9418                           gen_lowpart (SFmode,
9419                                        gen_int_mode (0x80000000, SImode)));
9420           emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
9421           if (dest != operands[0])
9422             emit_move_insn (dest, operands[0]);
9423         }
9424        DONE;
9425      }
9426    ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
9427
9428 (define_insn "abssf2_memory"
9429   [(set (match_operand:SF 0 "memory_operand" "=m")
9430         (abs:SF (match_operand:SF 1 "memory_operand" "0")))
9431    (clobber (reg:CC 17))]
9432   "ix86_unary_operator_ok (ABS, SFmode, operands)"
9433   "#")
9434
9435 (define_insn "abssf2_ifs"
9436   [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,f#xr,rm#xf")
9437         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "x,0,0")))
9438    (use (match_operand:SF 2 "nonmemory_operand" "*0#x,*g#x,*g#x"))
9439    (clobber (reg:CC 17))]
9440   "TARGET_SSE
9441    && (reload_in_progress || reload_completed
9442        || (register_operand (operands[0], VOIDmode)
9443            && register_operand (operands[1], VOIDmode)))"
9444   "#")
9445
9446 (define_split
9447   [(set (match_operand:SF 0 "memory_operand" "")
9448         (abs:SF (match_operand:SF 1 "memory_operand" "")))
9449    (use (match_operand:SF 2 "" ""))
9450    (clobber (reg:CC 17))]
9451   ""
9452   [(parallel [(set (match_dup 0)
9453                    (abs:SF (match_dup 1)))
9454               (clobber (reg:CC 17))])])
9455
9456 (define_split
9457   [(set (match_operand:SF 0 "register_operand" "")
9458         (abs:SF (match_operand:SF 1 "register_operand" "")))
9459    (use (match_operand:SF 2 "" ""))
9460    (clobber (reg:CC 17))]
9461   "reload_completed && !SSE_REG_P (operands[0])"
9462   [(parallel [(set (match_dup 0)
9463                    (abs:SF (match_dup 1)))
9464               (clobber (reg:CC 17))])])
9465
9466 (define_split
9467   [(set (match_operand:SF 0 "register_operand" "")
9468         (abs:SF (match_operand:SF 1 "register_operand" "")))
9469    (use (match_operand:SF 2 "register_operand" ""))
9470    (clobber (reg:CC 17))]
9471   "reload_completed && SSE_REG_P (operands[0])"
9472   [(set (subreg:TI (match_dup 0) 0)
9473         (and:TI (not:TI (subreg:TI (match_dup 2) 0))
9474                 (subreg:TI (match_dup 1) 0)))])
9475
9476 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9477 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9478 ;; to itself.
9479 (define_insn "*abssf2_if"
9480   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9481         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
9482    (clobber (reg:CC 17))]
9483   "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands) && !TARGET_SSE"
9484   "#")
9485
9486 (define_split
9487   [(set (match_operand:SF 0 "register_operand" "")
9488         (abs:SF (match_operand:SF 1 "register_operand" "")))
9489    (clobber (reg:CC 17))]
9490   "TARGET_80387 && FP_REGNO_P (REGNO (operands[0]))"
9491   [(set (match_dup 0)
9492         (abs:SF (match_dup 1)))]
9493   "")
9494
9495 (define_split
9496   [(set (match_operand:SF 0 "register_operand" "")
9497         (abs:SF (match_operand:SF 1 "register_operand" "")))
9498    (clobber (reg:CC 17))]
9499   "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
9500   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
9501               (clobber (reg:CC 17))])]
9502   "operands[1] = gen_int_mode (~0x80000000, SImode);
9503    operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
9504
9505 (define_split
9506   [(set (match_operand 0 "memory_operand" "")
9507         (abs (match_operand 1 "memory_operand" "")))
9508    (clobber (reg:CC 17))]
9509   "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
9510   [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
9511               (clobber (reg:CC 17))])]
9512 {
9513   int size = GET_MODE_SIZE (GET_MODE (operands[1]));
9514
9515   /* XFmode's size is 12, TFmode 16, but only 10 bytes are used.  */
9516   if (size >= 12)
9517     size = 10;
9518   operands[0] = adjust_address (operands[0], QImode, size - 1);
9519   operands[1] = gen_int_mode (~0x80, QImode);
9520 })
9521
9522 (define_expand "absdf2"
9523   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
9524                    (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
9525               (clobber (reg:CC 17))])]
9526   "TARGET_80387"
9527   "if (TARGET_SSE2)
9528      {
9529        /* In case operand is in memory,  we will not use SSE.  */
9530        if (memory_operand (operands[0], VOIDmode)
9531            && rtx_equal_p (operands[0], operands[1]))
9532          emit_insn (gen_absdf2_memory (operands[0], operands[1]));
9533        else
9534         {
9535           /* Using SSE is tricky, since we need bitwise negation of -0
9536              in register.  */
9537           rtx reg = gen_reg_rtx (DFmode);
9538 #if HOST_BITS_PER_WIDE_INT >= 64
9539           rtx imm = gen_int_mode (((HOST_WIDE_INT)1) << 63, DImode);
9540 #else
9541           rtx imm = immed_double_const (0, 0x80000000, DImode);
9542 #endif
9543           rtx dest = operands[0];
9544
9545           operands[1] = force_reg (DFmode, operands[1]);
9546           operands[0] = force_reg (DFmode, operands[0]);
9547           emit_move_insn (reg, gen_lowpart (DFmode, imm));
9548           emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
9549           if (dest != operands[0])
9550             emit_move_insn (dest, operands[0]);
9551         }
9552        DONE;
9553      }
9554    ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
9555
9556 (define_insn "absdf2_memory"
9557   [(set (match_operand:DF 0 "memory_operand" "=m")
9558         (abs:DF (match_operand:DF 1 "memory_operand" "0")))
9559    (clobber (reg:CC 17))]
9560   "ix86_unary_operator_ok (ABS, DFmode, operands)"
9561   "#")
9562
9563 (define_insn "absdf2_ifs"
9564   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,mf#Yr,mr#Yf")
9565         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "Y,0,0")))
9566    (use (match_operand:DF 2 "nonmemory_operand" "*0#Y,*g#Y,*g#Y"))
9567    (clobber (reg:CC 17))]
9568   "!TARGET_64BIT && TARGET_SSE2
9569    && (reload_in_progress || reload_completed
9570        || (register_operand (operands[0], VOIDmode)
9571            && register_operand (operands[1], VOIDmode)))"
9572   "#")
9573
9574 (define_insn "*absdf2_ifs_rex64"
9575   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,mf#Yr")
9576         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "Y,0")))
9577    (use (match_operand:DF 2 "nonmemory_operand" "*0#Y,*g#Y"))
9578    (clobber (reg:CC 17))]
9579   "TARGET_64BIT && TARGET_SSE2
9580    && (reload_in_progress || reload_completed
9581        || (register_operand (operands[0], VOIDmode)
9582            && register_operand (operands[1], VOIDmode)))"
9583   "#")
9584
9585 (define_split
9586   [(set (match_operand:DF 0 "memory_operand" "")
9587         (abs:DF (match_operand:DF 1 "memory_operand" "")))
9588    (use (match_operand:DF 2 "" ""))
9589    (clobber (reg:CC 17))]
9590   ""
9591   [(parallel [(set (match_dup 0)
9592                    (abs:DF (match_dup 1)))
9593               (clobber (reg:CC 17))])])
9594
9595 (define_split
9596   [(set (match_operand:DF 0 "register_operand" "")
9597         (abs:DF (match_operand:DF 1 "register_operand" "")))
9598    (use (match_operand:DF 2 "" ""))
9599    (clobber (reg:CC 17))]
9600   "reload_completed && !SSE_REG_P (operands[0])"
9601   [(parallel [(set (match_dup 0)
9602                    (abs:DF (match_dup 1)))
9603               (clobber (reg:CC 17))])])
9604
9605 (define_split
9606   [(set (match_operand:DF 0 "register_operand" "")
9607         (abs:DF (match_operand:DF 1 "register_operand" "")))
9608    (use (match_operand:DF 2 "register_operand" ""))
9609    (clobber (reg:CC 17))]
9610   "reload_completed && SSE_REG_P (operands[0])"
9611   [(set (subreg:TI (match_dup 0) 0)
9612         (and:TI (not:TI (subreg:TI (match_dup 2) 0))
9613                 (subreg:TI (match_dup 1) 0)))])
9614
9615
9616 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9617 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9618 ;; to itself.
9619 (define_insn "*absdf2_if"
9620   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9621         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9622    (clobber (reg:CC 17))]
9623   "!TARGET_64BIT && TARGET_80387
9624    && ix86_unary_operator_ok (ABS, DFmode, operands)"
9625   "#")
9626
9627 ;; FIXME: We should to allow integer registers here.  Problem is that
9628 ;; we need another scratch register to get constant from.
9629 ;; Forcing constant to mem if no register available in peep2 should be
9630 ;; safe even for PIC mode, because of RIP relative addressing.
9631 (define_insn "*absdf2_if_rex64"
9632   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
9633         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9634    (clobber (reg:CC 17))]
9635   "TARGET_64BIT && TARGET_80387
9636    && ix86_unary_operator_ok (ABS, DFmode, operands)"
9637   "#")
9638
9639 (define_split
9640   [(set (match_operand:DF 0 "register_operand" "")
9641         (abs:DF (match_operand:DF 1 "register_operand" "")))
9642    (clobber (reg:CC 17))]
9643   "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
9644   [(set (match_dup 0)
9645         (abs:DF (match_dup 1)))]
9646   "")
9647
9648 (define_split
9649   [(set (match_operand:DF 0 "register_operand" "")
9650         (abs:DF (match_operand:DF 1 "register_operand" "")))
9651    (clobber (reg:CC 17))]
9652   "!TARGET_64BIT && TARGET_80387 && reload_completed &&
9653    !FP_REGNO_P (REGNO (operands[0]))"
9654   [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
9655               (clobber (reg:CC 17))])]
9656   "operands[4] = gen_int_mode (~0x80000000, SImode);
9657    split_di (operands+0, 1, operands+2, operands+3);")
9658
9659 (define_expand "absxf2"
9660   [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
9661                    (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
9662               (clobber (reg:CC 17))])]
9663   "!TARGET_64BIT && TARGET_80387"
9664   "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
9665
9666 (define_expand "abstf2"
9667   [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
9668                    (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
9669               (clobber (reg:CC 17))])]
9670   "TARGET_80387"
9671   "ix86_expand_unary_operator (ABS, TFmode, operands); DONE;")
9672
9673 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9674 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9675 ;; to itself.
9676 (define_insn "*absxf2_if"
9677   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9678         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
9679    (clobber (reg:CC 17))]
9680   "!TARGET_64BIT && TARGET_80387
9681    && ix86_unary_operator_ok (ABS, XFmode, operands)"
9682   "#")
9683
9684 (define_split
9685   [(set (match_operand:XF 0 "register_operand" "")
9686         (abs:XF (match_operand:XF 1 "register_operand" "")))
9687    (clobber (reg:CC 17))]
9688   "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
9689   [(set (match_dup 0)
9690         (abs:XF (match_dup 1)))]
9691   "")
9692
9693 (define_split
9694   [(set (match_operand:XF 0 "register_operand" "")
9695         (abs:XF (match_operand:XF 1 "register_operand" "")))
9696    (clobber (reg:CC 17))]
9697   "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
9698   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
9699               (clobber (reg:CC 17))])]
9700   "operands[1] = GEN_INT (~0x8000);
9701    operands[0] = gen_rtx_REG (SImode,
9702                               true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
9703
9704 (define_insn "*abstf2_if"
9705   [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
9706         (abs:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
9707    (clobber (reg:CC 17))]
9708   "TARGET_80387 && ix86_unary_operator_ok (ABS, TFmode, operands)"
9709   "#")
9710
9711 (define_split
9712   [(set (match_operand:TF 0 "register_operand" "")
9713         (abs:TF (match_operand:TF 1 "register_operand" "")))
9714    (clobber (reg:CC 17))]
9715   "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
9716   [(set (match_dup 0)
9717         (abs:TF (match_dup 1)))]
9718   "")
9719
9720 (define_split
9721   [(set (match_operand:TF 0 "register_operand" "")
9722         (abs:TF (match_operand:TF 1 "register_operand" "")))
9723    (clobber (reg:CC 17))]
9724   "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
9725   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
9726               (clobber (reg:CC 17))])]
9727   "operands[1] = GEN_INT (~0x8000);
9728    operands[0] = gen_rtx_REG (SImode,
9729                               true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
9730
9731 (define_insn "*abssf2_1"
9732   [(set (match_operand:SF 0 "register_operand" "=f")
9733         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9734   "TARGET_80387 && reload_completed"
9735   "fabs"
9736   [(set_attr "type" "fsgn")
9737    (set_attr "mode" "SF")])
9738
9739 (define_insn "*absdf2_1"
9740   [(set (match_operand:DF 0 "register_operand" "=f")
9741         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9742   "TARGET_80387 && reload_completed"
9743   "fabs"
9744   [(set_attr "type" "fsgn")
9745    (set_attr "mode" "DF")])
9746
9747 (define_insn "*absextendsfdf2"
9748   [(set (match_operand:DF 0 "register_operand" "=f")
9749         (abs:DF (float_extend:DF
9750                   (match_operand:SF 1 "register_operand" "0"))))]
9751   "TARGET_80387"
9752   "fabs"
9753   [(set_attr "type" "fsgn")
9754    (set_attr "mode" "DF")])
9755
9756 (define_insn "*absxf2_1"
9757   [(set (match_operand:XF 0 "register_operand" "=f")
9758         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9759   "!TARGET_64BIT && TARGET_80387 && reload_completed"
9760   "fabs"
9761   [(set_attr "type" "fsgn")
9762    (set_attr "mode" "DF")])
9763
9764 (define_insn "*absextenddfxf2"
9765   [(set (match_operand:XF 0 "register_operand" "=f")
9766         (abs:XF (float_extend:XF
9767           (match_operand:DF 1 "register_operand" "0"))))]
9768   "!TARGET_64BIT && TARGET_80387"
9769   "fabs"
9770   [(set_attr "type" "fsgn")
9771    (set_attr "mode" "XF")])
9772
9773 (define_insn "*absextendsfxf2"
9774   [(set (match_operand:XF 0 "register_operand" "=f")
9775         (abs:XF (float_extend:XF
9776           (match_operand:SF 1 "register_operand" "0"))))]
9777   "!TARGET_64BIT && TARGET_80387"
9778   "fabs"
9779   [(set_attr "type" "fsgn")
9780    (set_attr "mode" "XF")])
9781
9782 (define_insn "*abstf2_1"
9783   [(set (match_operand:TF 0 "register_operand" "=f")
9784         (abs:TF (match_operand:TF 1 "register_operand" "0")))]
9785   "TARGET_80387 && reload_completed"
9786   "fabs"
9787   [(set_attr "type" "fsgn")
9788    (set_attr "mode" "DF")])
9789
9790 (define_insn "*absextenddftf2"
9791   [(set (match_operand:TF 0 "register_operand" "=f")
9792         (abs:TF (float_extend:TF
9793           (match_operand:DF 1 "register_operand" "0"))))]
9794   "TARGET_80387"
9795   "fabs"
9796   [(set_attr "type" "fsgn")
9797    (set_attr "mode" "XF")])
9798
9799 (define_insn "*absextendsftf2"
9800   [(set (match_operand:TF 0 "register_operand" "=f")
9801         (abs:TF (float_extend:TF
9802           (match_operand:SF 1 "register_operand" "0"))))]
9803   "TARGET_80387"
9804   "fabs"
9805   [(set_attr "type" "fsgn")
9806    (set_attr "mode" "XF")])
9807 \f
9808 ;; One complement instructions
9809
9810 (define_expand "one_cmpldi2"
9811   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9812         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9813   "TARGET_64BIT"
9814   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9815
9816 (define_insn "*one_cmpldi2_1_rex64"
9817   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9818         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9819   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9820   "not{q}\t%0"
9821   [(set_attr "type" "negnot")
9822    (set_attr "mode" "DI")])
9823
9824 (define_insn "*one_cmpldi2_2_rex64"
9825   [(set (reg 17)
9826         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9827                  (const_int 0)))
9828    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9829         (not:DI (match_dup 1)))]
9830   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9831    && ix86_unary_operator_ok (NOT, DImode, operands)"
9832   "#"
9833   [(set_attr "type" "alu1")
9834    (set_attr "mode" "DI")])
9835
9836 (define_split
9837   [(set (reg 17)
9838         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" ""))
9839                  (const_int 0)))
9840    (set (match_operand:DI 0 "nonimmediate_operand" "")
9841         (not:DI (match_dup 1)))]
9842   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9843   [(parallel [(set (reg:CCNO 17)
9844                    (compare:CCNO (xor:DI (match_dup 1) (const_int -1))
9845                                  (const_int 0)))
9846               (set (match_dup 0)
9847                    (xor:DI (match_dup 1) (const_int -1)))])]
9848   "")
9849
9850 (define_expand "one_cmplsi2"
9851   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9852         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
9853   ""
9854   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
9855
9856 (define_insn "*one_cmplsi2_1"
9857   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9858         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
9859   "ix86_unary_operator_ok (NOT, SImode, operands)"
9860   "not{l}\t%0"
9861   [(set_attr "type" "negnot")
9862    (set_attr "mode" "SI")])
9863
9864 ;; ??? Currently never generated - xor is used instead.
9865 (define_insn "*one_cmplsi2_1_zext"
9866   [(set (match_operand:DI 0 "register_operand" "=r")
9867         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9868   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9869   "not{l}\t%k0"
9870   [(set_attr "type" "negnot")
9871    (set_attr "mode" "SI")])
9872
9873 (define_insn "*one_cmplsi2_2"
9874   [(set (reg 17)
9875         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9876                  (const_int 0)))
9877    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9878         (not:SI (match_dup 1)))]
9879   "ix86_match_ccmode (insn, CCNOmode)
9880    && ix86_unary_operator_ok (NOT, SImode, operands)"
9881   "#"
9882   [(set_attr "type" "alu1")
9883    (set_attr "mode" "SI")])
9884
9885 (define_split
9886   [(set (reg 17)
9887         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
9888                  (const_int 0)))
9889    (set (match_operand:SI 0 "nonimmediate_operand" "")
9890         (not:SI (match_dup 1)))]
9891   "ix86_match_ccmode (insn, CCNOmode)"
9892   [(parallel [(set (reg:CCNO 17)
9893                    (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
9894                                  (const_int 0)))
9895               (set (match_dup 0)
9896                    (xor:SI (match_dup 1) (const_int -1)))])]
9897   "")
9898
9899 ;; ??? Currently never generated - xor is used instead.
9900 (define_insn "*one_cmplsi2_2_zext"
9901   [(set (reg 17)
9902         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9903                  (const_int 0)))
9904    (set (match_operand:DI 0 "register_operand" "=r")
9905         (zero_extend:DI (not:SI (match_dup 1))))]
9906   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9907    && ix86_unary_operator_ok (NOT, SImode, operands)"
9908   "#"
9909   [(set_attr "type" "alu1")
9910    (set_attr "mode" "SI")])
9911
9912 (define_split
9913   [(set (reg 17)
9914         (compare (not:SI (match_operand:SI 1 "register_operand" ""))
9915                  (const_int 0)))
9916    (set (match_operand:DI 0 "register_operand" "")
9917         (zero_extend:DI (not:SI (match_dup 1))))]
9918   "ix86_match_ccmode (insn, CCNOmode)"
9919   [(parallel [(set (reg:CCNO 17)
9920                    (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
9921                                  (const_int 0)))
9922               (set (match_dup 0)
9923                    (zero_extend:DI (xor:SI (match_dup 1) (const_int -1))))])]
9924   "")
9925
9926 (define_expand "one_cmplhi2"
9927   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9928         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
9929   "TARGET_HIMODE_MATH"
9930   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
9931
9932 (define_insn "*one_cmplhi2_1"
9933   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9934         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
9935   "ix86_unary_operator_ok (NOT, HImode, operands)"
9936   "not{w}\t%0"
9937   [(set_attr "type" "negnot")
9938    (set_attr "mode" "HI")])
9939
9940 (define_insn "*one_cmplhi2_2"
9941   [(set (reg 17)
9942         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9943                  (const_int 0)))
9944    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9945         (not:HI (match_dup 1)))]
9946   "ix86_match_ccmode (insn, CCNOmode)
9947    && ix86_unary_operator_ok (NEG, HImode, operands)"
9948   "#"
9949   [(set_attr "type" "alu1")
9950    (set_attr "mode" "HI")])
9951
9952 (define_split
9953   [(set (reg 17)
9954         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
9955                  (const_int 0)))
9956    (set (match_operand:HI 0 "nonimmediate_operand" "")
9957         (not:HI (match_dup 1)))]
9958   "ix86_match_ccmode (insn, CCNOmode)"
9959   [(parallel [(set (reg:CCNO 17)
9960                    (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
9961                                  (const_int 0)))
9962               (set (match_dup 0)
9963                    (xor:HI (match_dup 1) (const_int -1)))])]
9964   "")
9965
9966 ;; %%% Potential partial reg stall on alternative 1.  What to do?
9967 (define_expand "one_cmplqi2"
9968   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9969         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
9970   "TARGET_QIMODE_MATH"
9971   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
9972
9973 (define_insn "*one_cmplqi2_1"
9974   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9975         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9976   "ix86_unary_operator_ok (NOT, QImode, operands)"
9977   "@
9978    not{b}\t%0
9979    not{l}\t%k0"
9980   [(set_attr "type" "negnot")
9981    (set_attr "mode" "QI,SI")])
9982
9983 (define_insn "*one_cmplqi2_2"
9984   [(set (reg 17)
9985         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9986                  (const_int 0)))
9987    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9988         (not:QI (match_dup 1)))]
9989   "ix86_match_ccmode (insn, CCNOmode)
9990    && ix86_unary_operator_ok (NOT, QImode, operands)"
9991   "#"
9992   [(set_attr "type" "alu1")
9993    (set_attr "mode" "QI")])
9994
9995 (define_split
9996   [(set (reg 17)
9997         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
9998                  (const_int 0)))
9999    (set (match_operand:QI 0 "nonimmediate_operand" "")
10000         (not:QI (match_dup 1)))]
10001   "ix86_match_ccmode (insn, CCNOmode)"
10002   [(parallel [(set (reg:CCNO 17)
10003                    (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
10004                                  (const_int 0)))
10005               (set (match_dup 0)
10006                    (xor:QI (match_dup 1) (const_int -1)))])]
10007   "")
10008 \f
10009 ;; Arithmetic shift instructions
10010
10011 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10012 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10013 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10014 ;; from the assembler input.
10015 ;;
10016 ;; This instruction shifts the target reg/mem as usual, but instead of
10017 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10018 ;; is a left shift double, bits are taken from the high order bits of
10019 ;; reg, else if the insn is a shift right double, bits are taken from the
10020 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10021 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10022 ;;
10023 ;; Since sh[lr]d does not change the `reg' operand, that is done
10024 ;; separately, making all shifts emit pairs of shift double and normal
10025 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10026 ;; support a 63 bit shift, each shift where the count is in a reg expands
10027 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10028 ;;
10029 ;; If the shift count is a constant, we need never emit more than one
10030 ;; shift pair, instead using moves and sign extension for counts greater
10031 ;; than 31.
10032
10033 (define_expand "ashldi3"
10034   [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
10035                    (ashift:DI (match_operand:DI 1 "shiftdi_operand" "")
10036                               (match_operand:QI 2 "nonmemory_operand" "")))
10037               (clobber (reg:CC 17))])]
10038   ""
10039 {
10040   if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
10041     {
10042       emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
10043       DONE;
10044     }
10045   ix86_expand_binary_operator (ASHIFT, DImode, operands);
10046   DONE;
10047 })
10048
10049 (define_insn "*ashldi3_1_rex64"
10050   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10051         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,r")
10052                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10053    (clobber (reg:CC 17))]
10054   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10055 {
10056   switch (get_attr_type (insn))
10057     {
10058     case TYPE_ALU:
10059       if (operands[2] != const1_rtx)
10060         abort ();
10061       if (!rtx_equal_p (operands[0], operands[1]))
10062         abort ();
10063       return "add{q}\t{%0, %0|%0, %0}";
10064
10065     case TYPE_LEA:
10066       if (GET_CODE (operands[2]) != CONST_INT
10067           || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10068         abort ();
10069       operands[1] = gen_rtx_MULT (DImode, operands[1],
10070                                   GEN_INT (1 << INTVAL (operands[2])));
10071       return "lea{q}\t{%a1, %0|%0, %a1}";
10072
10073     default:
10074       if (REG_P (operands[2]))
10075         return "sal{q}\t{%b2, %0|%0, %b2}";
10076       else if (GET_CODE (operands[2]) == CONST_INT
10077                && INTVAL (operands[2]) == 1
10078                && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10079         return "sal{q}\t%0";
10080       else
10081         return "sal{q}\t{%2, %0|%0, %2}";
10082     }
10083 }
10084   [(set (attr "type")
10085      (cond [(eq_attr "alternative" "1")
10086               (const_string "lea")
10087             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10088                           (const_int 0))
10089                       (match_operand 0 "register_operand" ""))
10090                  (match_operand 2 "const1_operand" ""))
10091               (const_string "alu")
10092            ]
10093            (const_string "ishift")))
10094    (set_attr "mode" "DI")])
10095
10096 ;; Convert lea to the lea pattern to avoid flags dependency.
10097 (define_split
10098   [(set (match_operand:DI 0 "register_operand" "")
10099         (ashift:DI (match_operand:DI 1 "register_operand" "")
10100                    (match_operand:QI 2 "immediate_operand" "")))
10101    (clobber (reg:CC 17))]
10102   "TARGET_64BIT && reload_completed
10103    && true_regnum (operands[0]) != true_regnum (operands[1])"
10104   [(set (match_dup 0)
10105         (mult:DI (match_dup 1)
10106                  (match_dup 2)))]
10107   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10108
10109 ;; This pattern can't accept a variable shift count, since shifts by
10110 ;; zero don't affect the flags.  We assume that shifts by constant
10111 ;; zero are optimized away.
10112 (define_insn "*ashldi3_cmp_rex64"
10113   [(set (reg 17)
10114         (compare
10115           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10116                      (match_operand:QI 2 "immediate_operand" "e"))
10117           (const_int 0)))
10118    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10119         (ashift:DI (match_dup 1) (match_dup 2)))]
10120   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10121    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10122 {
10123   switch (get_attr_type (insn))
10124     {
10125     case TYPE_ALU:
10126       if (operands[2] != const1_rtx)
10127         abort ();
10128       return "add{q}\t{%0, %0|%0, %0}";
10129
10130     default:
10131       if (REG_P (operands[2]))
10132         return "sal{q}\t{%b2, %0|%0, %b2}";
10133       else if (GET_CODE (operands[2]) == CONST_INT
10134                && INTVAL (operands[2]) == 1
10135                && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10136         return "sal{q}\t%0";
10137       else
10138         return "sal{q}\t{%2, %0|%0, %2}";
10139     }
10140 }
10141   [(set (attr "type")
10142      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10143                           (const_int 0))
10144                       (match_operand 0 "register_operand" ""))
10145                  (match_operand 2 "const1_operand" ""))
10146               (const_string "alu")
10147            ]
10148            (const_string "ishift")))
10149    (set_attr "mode" "DI")])
10150
10151 (define_insn "ashldi3_1"
10152   [(set (match_operand:DI 0 "register_operand" "=r")
10153         (ashift:DI (match_operand:DI 1 "register_operand" "0")
10154                    (match_operand:QI 2 "nonmemory_operand" "Jc")))
10155    (clobber (match_scratch:SI 3 "=&r"))
10156    (clobber (reg:CC 17))]
10157   "!TARGET_64BIT && TARGET_CMOVE"
10158   "#"
10159   [(set_attr "type" "multi")])
10160
10161 (define_insn "*ashldi3_2"
10162   [(set (match_operand:DI 0 "register_operand" "=r")
10163         (ashift:DI (match_operand:DI 1 "register_operand" "0")
10164                    (match_operand:QI 2 "nonmemory_operand" "Jc")))
10165    (clobber (reg:CC 17))]
10166   "!TARGET_64BIT"
10167   "#"
10168   [(set_attr "type" "multi")])
10169
10170 (define_split
10171   [(set (match_operand:DI 0 "register_operand" "")
10172         (ashift:DI (match_operand:DI 1 "register_operand" "")
10173                    (match_operand:QI 2 "nonmemory_operand" "")))
10174    (clobber (match_scratch:SI 3 ""))
10175    (clobber (reg:CC 17))]
10176   "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
10177   [(const_int 0)]
10178   "ix86_split_ashldi (operands, operands[3]); DONE;")
10179
10180 (define_split
10181   [(set (match_operand:DI 0 "register_operand" "")
10182         (ashift:DI (match_operand:DI 1 "register_operand" "")
10183                    (match_operand:QI 2 "nonmemory_operand" "")))
10184    (clobber (reg:CC 17))]
10185   "!TARGET_64BIT && reload_completed"
10186   [(const_int 0)]
10187   "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10188
10189 (define_insn "x86_shld_1"
10190   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10191         (ior:SI (ashift:SI (match_dup 0)
10192                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10193                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10194                   (minus:QI (const_int 32) (match_dup 2)))))
10195    (clobber (reg:CC 17))]
10196   ""
10197   "@
10198    shld{l}\t{%2, %1, %0|%0, %1, %2}
10199    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10200   [(set_attr "type" "ishift")
10201    (set_attr "prefix_0f" "1")
10202    (set_attr "mode" "SI")
10203    (set_attr "pent_pair" "np")
10204    (set_attr "athlon_decode" "vector")
10205    (set_attr "ppro_uops" "few")])
10206
10207 (define_expand "x86_shift_adj_1"
10208   [(set (reg:CCZ 17)
10209         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10210                              (const_int 32))
10211                      (const_int 0)))
10212    (set (match_operand:SI 0 "register_operand" "")
10213         (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
10214                          (match_operand:SI 1 "register_operand" "")
10215                          (match_dup 0)))
10216    (set (match_dup 1)
10217         (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
10218                          (match_operand:SI 3 "register_operand" "r")
10219                          (match_dup 1)))]
10220   "TARGET_CMOVE"
10221   "")
10222
10223 (define_expand "x86_shift_adj_2"
10224   [(use (match_operand:SI 0 "register_operand" ""))
10225    (use (match_operand:SI 1 "register_operand" ""))
10226    (use (match_operand:QI 2 "register_operand" ""))]
10227   ""
10228 {
10229   rtx label = gen_label_rtx ();
10230   rtx tmp;
10231
10232   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10233
10234   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10235   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10236   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10237                               gen_rtx_LABEL_REF (VOIDmode, label),
10238                               pc_rtx);
10239   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10240   JUMP_LABEL (tmp) = label;
10241
10242   emit_move_insn (operands[0], operands[1]);
10243   emit_move_insn (operands[1], const0_rtx);
10244
10245   emit_label (label);
10246   LABEL_NUSES (label) = 1;
10247
10248   DONE;
10249 })
10250
10251 (define_expand "ashlsi3"
10252   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10253         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10254                    (match_operand:QI 2 "nonmemory_operand" "")))
10255    (clobber (reg:CC 17))]
10256   ""
10257   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10258
10259 (define_insn "*ashlsi3_1"
10260   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10261         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
10262                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10263    (clobber (reg:CC 17))]
10264   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10265 {
10266   switch (get_attr_type (insn))
10267     {
10268     case TYPE_ALU:
10269       if (operands[2] != const1_rtx)
10270         abort ();
10271       if (!rtx_equal_p (operands[0], operands[1]))
10272         abort ();
10273       return "add{l}\t{%0, %0|%0, %0}";
10274
10275     case TYPE_LEA:
10276       return "#";
10277
10278     default:
10279       if (REG_P (operands[2]))
10280         return "sal{l}\t{%b2, %0|%0, %b2}";
10281       else if (GET_CODE (operands[2]) == CONST_INT
10282                && INTVAL (operands[2]) == 1
10283                && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10284         return "sal{l}\t%0";
10285       else
10286         return "sal{l}\t{%2, %0|%0, %2}";
10287     }
10288 }
10289   [(set (attr "type")
10290      (cond [(eq_attr "alternative" "1")
10291               (const_string "lea")
10292             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10293                           (const_int 0))
10294                       (match_operand 0 "register_operand" ""))
10295                  (match_operand 2 "const1_operand" ""))
10296               (const_string "alu")
10297            ]
10298            (const_string "ishift")))
10299    (set_attr "mode" "SI")])
10300
10301 ;; Convert lea to the lea pattern to avoid flags dependency.
10302 (define_split
10303   [(set (match_operand 0 "register_operand" "")
10304         (ashift (match_operand 1 "register_operand" "")
10305                 (match_operand:QI 2 "const_int_operand" "")))
10306    (clobber (reg:CC 17))]
10307   "reload_completed
10308    && true_regnum (operands[0]) != true_regnum (operands[1])"
10309   [(const_int 0)]
10310 {
10311   rtx pat;
10312   operands[0] = gen_lowpart (SImode, operands[0]);
10313   operands[1] = gen_lowpart (Pmode, operands[1]);
10314   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10315   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10316   if (Pmode != SImode)
10317     pat = gen_rtx_SUBREG (SImode, pat, 0);
10318   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10319   DONE;
10320 })
10321
10322 (define_insn "*ashlsi3_1_zext"
10323   [(set (match_operand:DI 0 "register_operand" "=r,r")
10324         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r")
10325                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10326    (clobber (reg:CC 17))]
10327   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10328 {
10329   switch (get_attr_type (insn))
10330     {
10331     case TYPE_ALU:
10332       if (operands[2] != const1_rtx)
10333         abort ();
10334       return "add{l}\t{%k0, %k0|%k0, %k0}";
10335
10336     case TYPE_LEA:
10337       return "#";
10338
10339     default:
10340       if (REG_P (operands[2]))
10341         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10342       else if (GET_CODE (operands[2]) == CONST_INT
10343                && INTVAL (operands[2]) == 1
10344                && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10345         return "sal{l}\t%k0";
10346       else
10347         return "sal{l}\t{%2, %k0|%k0, %2}";
10348     }
10349 }
10350   [(set (attr "type")
10351      (cond [(eq_attr "alternative" "1")
10352               (const_string "lea")
10353             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10354                      (const_int 0))
10355                  (match_operand 2 "const1_operand" ""))
10356               (const_string "alu")
10357            ]
10358            (const_string "ishift")))
10359    (set_attr "mode" "SI")])
10360
10361 ;; Convert lea to the lea pattern to avoid flags dependency.
10362 (define_split
10363   [(set (match_operand:DI 0 "register_operand" "")
10364         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10365                                 (match_operand:QI 2 "const_int_operand" ""))))
10366    (clobber (reg:CC 17))]
10367   "reload_completed
10368    && true_regnum (operands[0]) != true_regnum (operands[1])"
10369   [(set (match_dup 0) (zero_extend:DI (subreg:SI (mult:SI (match_dup 1) (match_dup 2)) 0)))]
10370 {
10371   operands[1] = gen_lowpart (Pmode, operands[1]);
10372   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10373 })
10374
10375 ;; This pattern can't accept a variable shift count, since shifts by
10376 ;; zero don't affect the flags.  We assume that shifts by constant
10377 ;; zero are optimized away.
10378 (define_insn "*ashlsi3_cmp"
10379   [(set (reg 17)
10380         (compare
10381           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10382                      (match_operand:QI 2 "immediate_operand" "I"))
10383           (const_int 0)))
10384    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10385         (ashift:SI (match_dup 1) (match_dup 2)))]
10386   "ix86_match_ccmode (insn, CCGOCmode)
10387    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10388 {
10389   switch (get_attr_type (insn))
10390     {
10391     case TYPE_ALU:
10392       if (operands[2] != const1_rtx)
10393         abort ();
10394       return "add{l}\t{%0, %0|%0, %0}";
10395
10396     default:
10397       if (REG_P (operands[2]))
10398         return "sal{l}\t{%b2, %0|%0, %b2}";
10399       else if (GET_CODE (operands[2]) == CONST_INT
10400                && INTVAL (operands[2]) == 1
10401                && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10402         return "sal{l}\t%0";
10403       else
10404         return "sal{l}\t{%2, %0|%0, %2}";
10405     }
10406 }
10407   [(set (attr "type")
10408      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10409                           (const_int 0))
10410                       (match_operand 0 "register_operand" ""))
10411                  (match_operand 2 "const1_operand" ""))
10412               (const_string "alu")
10413            ]
10414            (const_string "ishift")))
10415    (set_attr "mode" "SI")])
10416
10417 (define_insn "*ashlsi3_cmp_zext"
10418   [(set (reg 17)
10419         (compare
10420           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10421                      (match_operand:QI 2 "immediate_operand" "I"))
10422           (const_int 0)))
10423    (set (match_operand:DI 0 "register_operand" "=r")
10424         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10425   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10426    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10427 {
10428   switch (get_attr_type (insn))
10429     {
10430     case TYPE_ALU:
10431       if (operands[2] != const1_rtx)
10432         abort ();
10433       return "add{l}\t{%k0, %k0|%k0, %k0}";
10434
10435     default:
10436       if (REG_P (operands[2]))
10437         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10438       else if (GET_CODE (operands[2]) == CONST_INT
10439                && INTVAL (operands[2]) == 1
10440                && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10441         return "sal{l}\t%k0";
10442       else
10443         return "sal{l}\t{%2, %k0|%k0, %2}";
10444     }
10445 }
10446   [(set (attr "type")
10447      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10448                      (const_int 0))
10449                  (match_operand 2 "const1_operand" ""))
10450               (const_string "alu")
10451            ]
10452            (const_string "ishift")))
10453    (set_attr "mode" "SI")])
10454
10455 (define_expand "ashlhi3"
10456   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10457         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10458                    (match_operand:QI 2 "nonmemory_operand" "")))
10459    (clobber (reg:CC 17))]
10460   "TARGET_HIMODE_MATH"
10461   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10462
10463 (define_insn "*ashlhi3_1_lea"
10464   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10465         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
10466                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10467    (clobber (reg:CC 17))]
10468   "!TARGET_PARTIAL_REG_STALL
10469    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10470 {
10471   switch (get_attr_type (insn))
10472     {
10473     case TYPE_LEA:
10474       return "#";
10475     case TYPE_ALU:
10476       if (operands[2] != const1_rtx)
10477         abort ();
10478       return "add{w}\t{%0, %0|%0, %0}";
10479
10480     default:
10481       if (REG_P (operands[2]))
10482         return "sal{w}\t{%b2, %0|%0, %b2}";
10483       else if (GET_CODE (operands[2]) == CONST_INT
10484                && INTVAL (operands[2]) == 1
10485                && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10486         return "sal{w}\t%0";
10487       else
10488         return "sal{w}\t{%2, %0|%0, %2}";
10489     }
10490 }
10491   [(set (attr "type")
10492      (cond [(eq_attr "alternative" "1")
10493               (const_string "lea")
10494             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10495                           (const_int 0))
10496                       (match_operand 0 "register_operand" ""))
10497                  (match_operand 2 "const1_operand" ""))
10498               (const_string "alu")
10499            ]
10500            (const_string "ishift")))
10501    (set_attr "mode" "HI,SI")])
10502
10503 (define_insn "*ashlhi3_1"
10504   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10505         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10506                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10507    (clobber (reg:CC 17))]
10508   "TARGET_PARTIAL_REG_STALL
10509    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10510 {
10511   switch (get_attr_type (insn))
10512     {
10513     case TYPE_ALU:
10514       if (operands[2] != const1_rtx)
10515         abort ();
10516       return "add{w}\t{%0, %0|%0, %0}";
10517
10518     default:
10519       if (REG_P (operands[2]))
10520         return "sal{w}\t{%b2, %0|%0, %b2}";
10521       else if (GET_CODE (operands[2]) == CONST_INT
10522                && INTVAL (operands[2]) == 1
10523                && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10524         return "sal{w}\t%0";
10525       else
10526         return "sal{w}\t{%2, %0|%0, %2}";
10527     }
10528 }
10529   [(set (attr "type")
10530      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10531                           (const_int 0))
10532                       (match_operand 0 "register_operand" ""))
10533                  (match_operand 2 "const1_operand" ""))
10534               (const_string "alu")
10535            ]
10536            (const_string "ishift")))
10537    (set_attr "mode" "HI")])
10538
10539 ;; This pattern can't accept a variable shift count, since shifts by
10540 ;; zero don't affect the flags.  We assume that shifts by constant
10541 ;; zero are optimized away.
10542 (define_insn "*ashlhi3_cmp"
10543   [(set (reg 17)
10544         (compare
10545           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10546                      (match_operand:QI 2 "immediate_operand" "I"))
10547           (const_int 0)))
10548    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10549         (ashift:HI (match_dup 1) (match_dup 2)))]
10550   "ix86_match_ccmode (insn, CCGOCmode)
10551    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10552 {
10553   switch (get_attr_type (insn))
10554     {
10555     case TYPE_ALU:
10556       if (operands[2] != const1_rtx)
10557         abort ();
10558       return "add{w}\t{%0, %0|%0, %0}";
10559
10560     default:
10561       if (REG_P (operands[2]))
10562         return "sal{w}\t{%b2, %0|%0, %b2}";
10563       else if (GET_CODE (operands[2]) == CONST_INT
10564                && INTVAL (operands[2]) == 1
10565                && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10566         return "sal{w}\t%0";
10567       else
10568         return "sal{w}\t{%2, %0|%0, %2}";
10569     }
10570 }
10571   [(set (attr "type")
10572      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10573                           (const_int 0))
10574                       (match_operand 0 "register_operand" ""))
10575                  (match_operand 2 "const1_operand" ""))
10576               (const_string "alu")
10577            ]
10578            (const_string "ishift")))
10579    (set_attr "mode" "HI")])
10580
10581 (define_expand "ashlqi3"
10582   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10583         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10584                    (match_operand:QI 2 "nonmemory_operand" "")))
10585    (clobber (reg:CC 17))]
10586   "TARGET_QIMODE_MATH"
10587   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10588
10589 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10590
10591 (define_insn "*ashlqi3_1_lea"
10592   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10593         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
10594                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10595    (clobber (reg:CC 17))]
10596   "!TARGET_PARTIAL_REG_STALL
10597    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10598 {
10599   switch (get_attr_type (insn))
10600     {
10601     case TYPE_LEA:
10602       return "#";
10603     case TYPE_ALU:
10604       if (operands[2] != const1_rtx)
10605         abort ();
10606       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10607         return "add{l}\t{%k0, %k0|%k0, %k0}";
10608       else
10609         return "add{b}\t{%0, %0|%0, %0}";
10610
10611     default:
10612       if (REG_P (operands[2]))
10613         {
10614           if (get_attr_mode (insn) == MODE_SI)
10615             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10616           else
10617             return "sal{b}\t{%b2, %0|%0, %b2}";
10618         }
10619       else if (GET_CODE (operands[2]) == CONST_INT
10620                && INTVAL (operands[2]) == 1
10621                && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10622         {
10623           if (get_attr_mode (insn) == MODE_SI)
10624             return "sal{l}\t%0";
10625           else
10626             return "sal{b}\t%0";
10627         }
10628       else
10629         {
10630           if (get_attr_mode (insn) == MODE_SI)
10631             return "sal{l}\t{%2, %k0|%k0, %2}";
10632           else
10633             return "sal{b}\t{%2, %0|%0, %2}";
10634         }
10635     }
10636 }
10637   [(set (attr "type")
10638      (cond [(eq_attr "alternative" "2")
10639               (const_string "lea")
10640             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10641                           (const_int 0))
10642                       (match_operand 0 "register_operand" ""))
10643                  (match_operand 2 "const1_operand" ""))
10644               (const_string "alu")
10645            ]
10646            (const_string "ishift")))
10647    (set_attr "mode" "QI,SI,SI")])
10648
10649 (define_insn "*ashlqi3_1"
10650   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10651         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10652                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10653    (clobber (reg:CC 17))]
10654   "TARGET_PARTIAL_REG_STALL
10655    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10656 {
10657   switch (get_attr_type (insn))
10658     {
10659     case TYPE_ALU:
10660       if (operands[2] != const1_rtx)
10661         abort ();
10662       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10663         return "add{l}\t{%k0, %k0|%k0, %k0}";
10664       else
10665         return "add{b}\t{%0, %0|%0, %0}";
10666
10667     default:
10668       if (REG_P (operands[2]))
10669         {
10670           if (get_attr_mode (insn) == MODE_SI)
10671             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10672           else
10673             return "sal{b}\t{%b2, %0|%0, %b2}";
10674         }
10675       else if (GET_CODE (operands[2]) == CONST_INT
10676                && INTVAL (operands[2]) == 1
10677                && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10678         {
10679           if (get_attr_mode (insn) == MODE_SI)
10680             return "sal{l}\t%0";
10681           else
10682             return "sal{b}\t%0";
10683         }
10684       else
10685         {
10686           if (get_attr_mode (insn) == MODE_SI)
10687             return "sal{l}\t{%2, %k0|%k0, %2}";
10688           else
10689             return "sal{b}\t{%2, %0|%0, %2}";
10690         }
10691     }
10692 }
10693   [(set (attr "type")
10694      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10695                           (const_int 0))
10696                       (match_operand 0 "register_operand" ""))
10697                  (match_operand 2 "const1_operand" ""))
10698               (const_string "alu")
10699            ]
10700            (const_string "ishift")))
10701    (set_attr "mode" "QI,SI")])
10702
10703 ;; This pattern can't accept a variable shift count, since shifts by
10704 ;; zero don't affect the flags.  We assume that shifts by constant
10705 ;; zero are optimized away.
10706 (define_insn "*ashlqi3_cmp"
10707   [(set (reg 17)
10708         (compare
10709           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10710                      (match_operand:QI 2 "immediate_operand" "I"))
10711           (const_int 0)))
10712    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10713         (ashift:QI (match_dup 1) (match_dup 2)))]
10714   "ix86_match_ccmode (insn, CCGOCmode)
10715    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10716 {
10717   switch (get_attr_type (insn))
10718     {
10719     case TYPE_ALU:
10720       if (operands[2] != const1_rtx)
10721         abort ();
10722       return "add{b}\t{%0, %0|%0, %0}";
10723
10724     default:
10725       if (REG_P (operands[2]))
10726         return "sal{b}\t{%b2, %0|%0, %b2}";
10727       else if (GET_CODE (operands[2]) == CONST_INT
10728                && INTVAL (operands[2]) == 1
10729                && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10730         return "sal{b}\t%0";
10731       else
10732         return "sal{b}\t{%2, %0|%0, %2}";
10733     }
10734 }
10735   [(set (attr "type")
10736      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10737                           (const_int 0))
10738                       (match_operand 0 "register_operand" ""))
10739                  (match_operand 2 "const1_operand" ""))
10740               (const_string "alu")
10741            ]
10742            (const_string "ishift")))
10743    (set_attr "mode" "QI")])
10744
10745 ;; See comment above `ashldi3' about how this works.
10746
10747 (define_expand "ashrdi3"
10748   [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
10749                    (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
10750                                 (match_operand:QI 2 "nonmemory_operand" "")))
10751               (clobber (reg:CC 17))])]
10752   ""
10753 {
10754   if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
10755     {
10756       emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
10757       DONE;
10758     }
10759   ix86_expand_binary_operator (ASHIFTRT, DImode, operands);
10760   DONE;
10761 })
10762
10763 (define_insn "ashrdi3_63_rex64"
10764   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10765         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10766                      (match_operand:DI 2 "const_int_operand" "i,i")))
10767    (clobber (reg:CC 17))]
10768   "TARGET_64BIT && INTVAL (operands[2]) == 63 && (TARGET_USE_CLTD || optimize_size)
10769    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10770   "@
10771    {cqto|cqo}
10772    sar{q}\t{%2, %0|%0, %2}"
10773   [(set_attr "type" "imovx,ishift")
10774    (set_attr "prefix_0f" "0,*")
10775    (set_attr "length_immediate" "0,*")
10776    (set_attr "modrm" "0,1")
10777    (set_attr "mode" "DI")])
10778
10779 (define_insn "*ashrdi3_1_one_bit_rex64"
10780   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10781         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10782                      (match_operand:QI 2 "const_int_1_operand" "")))
10783    (clobber (reg:CC 17))]
10784   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
10785    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
10786   "sar{q}\t%0"
10787   [(set_attr "type" "ishift")
10788    (set (attr "length") 
10789      (if_then_else (match_operand:DI 0 "register_operand" "") 
10790         (const_string "2")
10791         (const_string "*")))])
10792
10793 (define_insn "*ashrdi3_1_rex64"
10794   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
10795         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
10796                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
10797    (clobber (reg:CC 17))]
10798   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10799   "@
10800    sar{q}\t{%2, %0|%0, %2}
10801    sar{q}\t{%b2, %0|%0, %b2}"
10802   [(set_attr "type" "ishift")
10803    (set_attr "mode" "DI")])
10804
10805 ;; This pattern can't accept a variable shift count, since shifts by
10806 ;; zero don't affect the flags.  We assume that shifts by constant
10807 ;; zero are optimized away.
10808 (define_insn "*ashrdi3_one_bit_cmp_rex64"
10809   [(set (reg 17)
10810         (compare
10811           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10812                        (match_operand:QI 2 "const_int_1_operand" ""))
10813           (const_int 0)))
10814    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10815         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10816   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10817    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
10818    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10819   "sar{q}\t%0"
10820   [(set_attr "type" "ishift")
10821    (set (attr "length") 
10822      (if_then_else (match_operand:DI 0 "register_operand" "") 
10823         (const_string "2")
10824         (const_string "*")))])
10825
10826 ;; This pattern can't accept a variable shift count, since shifts by
10827 ;; zero don't affect the flags.  We assume that shifts by constant
10828 ;; zero are optimized away.
10829 (define_insn "*ashrdi3_cmp_rex64"
10830   [(set (reg 17)
10831         (compare
10832           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10833                        (match_operand:QI 2 "const_int_operand" "n"))
10834           (const_int 0)))
10835    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10836         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10837   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10838    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10839   "sar{q}\t{%2, %0|%0, %2}"
10840   [(set_attr "type" "ishift")
10841    (set_attr "mode" "DI")])
10842
10843
10844 (define_insn "ashrdi3_1"
10845   [(set (match_operand:DI 0 "register_operand" "=r")
10846         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
10847                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
10848    (clobber (match_scratch:SI 3 "=&r"))
10849    (clobber (reg:CC 17))]
10850   "!TARGET_64BIT && TARGET_CMOVE"
10851   "#"
10852   [(set_attr "type" "multi")])
10853
10854 (define_insn "*ashrdi3_2"
10855   [(set (match_operand:DI 0 "register_operand" "=r")
10856         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
10857                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
10858    (clobber (reg:CC 17))]
10859   "!TARGET_64BIT"
10860   "#"
10861   [(set_attr "type" "multi")])
10862
10863 (define_split
10864   [(set (match_operand:DI 0 "register_operand" "")
10865         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10866                      (match_operand:QI 2 "nonmemory_operand" "")))
10867    (clobber (match_scratch:SI 3 ""))
10868    (clobber (reg:CC 17))]
10869   "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
10870   [(const_int 0)]
10871   "ix86_split_ashrdi (operands, operands[3]); DONE;")
10872
10873 (define_split
10874   [(set (match_operand:DI 0 "register_operand" "")
10875         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10876                      (match_operand:QI 2 "nonmemory_operand" "")))
10877    (clobber (reg:CC 17))]
10878   "!TARGET_64BIT && reload_completed"
10879   [(const_int 0)]
10880   "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
10881
10882 (define_insn "x86_shrd_1"
10883   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10884         (ior:SI (ashiftrt:SI (match_dup 0)
10885                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10886                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
10887                   (minus:QI (const_int 32) (match_dup 2)))))
10888    (clobber (reg:CC 17))]
10889   ""
10890   "@
10891    shrd{l}\t{%2, %1, %0|%0, %1, %2}
10892    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10893   [(set_attr "type" "ishift")
10894    (set_attr "prefix_0f" "1")
10895    (set_attr "pent_pair" "np")
10896    (set_attr "ppro_uops" "few")
10897    (set_attr "mode" "SI")])
10898
10899 (define_expand "x86_shift_adj_3"
10900   [(use (match_operand:SI 0 "register_operand" ""))
10901    (use (match_operand:SI 1 "register_operand" ""))
10902    (use (match_operand:QI 2 "register_operand" ""))]
10903   ""
10904 {
10905   rtx label = gen_label_rtx ();
10906   rtx tmp;
10907
10908   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10909
10910   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10911   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10912   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10913                               gen_rtx_LABEL_REF (VOIDmode, label),
10914                               pc_rtx);
10915   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10916   JUMP_LABEL (tmp) = label;
10917
10918   emit_move_insn (operands[0], operands[1]);
10919   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
10920
10921   emit_label (label);
10922   LABEL_NUSES (label) = 1;
10923
10924   DONE;
10925 })
10926
10927 (define_insn "ashrsi3_31"
10928   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10929         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10930                      (match_operand:SI 2 "const_int_operand" "i,i")))
10931    (clobber (reg:CC 17))]
10932   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
10933    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10934   "@
10935    {cltd|cdq}
10936    sar{l}\t{%2, %0|%0, %2}"
10937   [(set_attr "type" "imovx,ishift")
10938    (set_attr "prefix_0f" "0,*")
10939    (set_attr "length_immediate" "0,*")
10940    (set_attr "modrm" "0,1")
10941    (set_attr "mode" "SI")])
10942
10943 (define_insn "*ashrsi3_31_zext"
10944   [(set (match_operand:DI 0 "register_operand" "=*d,r")
10945         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10946                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
10947    (clobber (reg:CC 17))]
10948   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
10949    && INTVAL (operands[2]) == 31
10950    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10951   "@
10952    {cltd|cdq}
10953    sar{l}\t{%2, %k0|%k0, %2}"
10954   [(set_attr "type" "imovx,ishift")
10955    (set_attr "prefix_0f" "0,*")
10956    (set_attr "length_immediate" "0,*")
10957    (set_attr "modrm" "0,1")
10958    (set_attr "mode" "SI")])
10959
10960 (define_expand "ashrsi3"
10961   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10962         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
10963                      (match_operand:QI 2 "nonmemory_operand" "")))
10964    (clobber (reg:CC 17))]
10965   ""
10966   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
10967
10968 (define_insn "*ashrsi3_1_one_bit"
10969   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10970         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10971                      (match_operand:QI 2 "const_int_1_operand" "")))
10972    (clobber (reg:CC 17))]
10973   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
10974    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
10975   "sar{l}\t%0"
10976   [(set_attr "type" "ishift")
10977    (set (attr "length") 
10978      (if_then_else (match_operand:SI 0 "register_operand" "") 
10979         (const_string "2")
10980         (const_string "*")))])
10981
10982 (define_insn "*ashrsi3_1_one_bit_zext"
10983   [(set (match_operand:DI 0 "register_operand" "=r")
10984         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
10985                                      (match_operand:QI 2 "const_int_1_operand" ""))))
10986    (clobber (reg:CC 17))]
10987   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
10988    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
10989   "sar{l}\t%k0"
10990   [(set_attr "type" "ishift")
10991    (set_attr "length" "2")])
10992
10993 (define_insn "*ashrsi3_1"
10994   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
10995         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
10996                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
10997    (clobber (reg:CC 17))]
10998   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10999   "@
11000    sar{l}\t{%2, %0|%0, %2}
11001    sar{l}\t{%b2, %0|%0, %b2}"
11002   [(set_attr "type" "ishift")
11003    (set_attr "mode" "SI")])
11004
11005 (define_insn "*ashrsi3_1_zext"
11006   [(set (match_operand:DI 0 "register_operand" "=r,r")
11007         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11008                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11009    (clobber (reg:CC 17))]
11010   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11011   "@
11012    sar{l}\t{%2, %k0|%k0, %2}
11013    sar{l}\t{%b2, %k0|%k0, %b2}"
11014   [(set_attr "type" "ishift")
11015    (set_attr "mode" "SI")])
11016
11017 ;; This pattern can't accept a variable shift count, since shifts by
11018 ;; zero don't affect the flags.  We assume that shifts by constant
11019 ;; zero are optimized away.
11020 (define_insn "*ashrsi3_one_bit_cmp"
11021   [(set (reg 17)
11022         (compare
11023           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11024                        (match_operand:QI 2 "const_int_1_operand" ""))
11025           (const_int 0)))
11026    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11027         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11028   "ix86_match_ccmode (insn, CCGOCmode)
11029    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11030    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11031   "sar{l}\t%0"
11032   [(set_attr "type" "ishift")
11033    (set (attr "length") 
11034      (if_then_else (match_operand:SI 0 "register_operand" "") 
11035         (const_string "2")
11036         (const_string "*")))])
11037
11038 (define_insn "*ashrsi3_one_bit_cmp_zext"
11039   [(set (reg 17)
11040         (compare
11041           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11042                        (match_operand:QI 2 "const_int_1_operand" ""))
11043           (const_int 0)))
11044    (set (match_operand:DI 0 "register_operand" "=r")
11045         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11046   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11047    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11048    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11049   "sar{l}\t%k0"
11050   [(set_attr "type" "ishift")
11051    (set_attr "length" "2")])
11052
11053 ;; This pattern can't accept a variable shift count, since shifts by
11054 ;; zero don't affect the flags.  We assume that shifts by constant
11055 ;; zero are optimized away.
11056 (define_insn "*ashrsi3_cmp"
11057   [(set (reg 17)
11058         (compare
11059           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11060                        (match_operand:QI 2 "immediate_operand" "I"))
11061           (const_int 0)))
11062    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11063         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11064   "ix86_match_ccmode (insn, CCGOCmode)
11065    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11066   "sar{l}\t{%2, %0|%0, %2}"
11067   [(set_attr "type" "ishift")
11068    (set_attr "mode" "SI")])
11069
11070 (define_insn "*ashrsi3_cmp_zext"
11071   [(set (reg 17)
11072         (compare
11073           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11074                        (match_operand:QI 2 "immediate_operand" "I"))
11075           (const_int 0)))
11076    (set (match_operand:DI 0 "register_operand" "=r")
11077         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11078   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11079    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11080   "sar{l}\t{%2, %k0|%k0, %2}"
11081   [(set_attr "type" "ishift")
11082    (set_attr "mode" "SI")])
11083
11084 (define_expand "ashrhi3"
11085   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11086         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11087                      (match_operand:QI 2 "nonmemory_operand" "")))
11088    (clobber (reg:CC 17))]
11089   "TARGET_HIMODE_MATH"
11090   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11091
11092 (define_insn "*ashrhi3_1_one_bit"
11093   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11094         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11095                      (match_operand:QI 2 "const_int_1_operand" "")))
11096    (clobber (reg:CC 17))]
11097   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11098    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11099   "sar{w}\t%0"
11100   [(set_attr "type" "ishift")
11101    (set (attr "length") 
11102      (if_then_else (match_operand 0 "register_operand" "") 
11103         (const_string "2")
11104         (const_string "*")))])
11105
11106 (define_insn "*ashrhi3_1"
11107   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11108         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11109                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11110    (clobber (reg:CC 17))]
11111   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11112   "@
11113    sar{w}\t{%2, %0|%0, %2}
11114    sar{w}\t{%b2, %0|%0, %b2}"
11115   [(set_attr "type" "ishift")
11116    (set_attr "mode" "HI")])
11117
11118 ;; This pattern can't accept a variable shift count, since shifts by
11119 ;; zero don't affect the flags.  We assume that shifts by constant
11120 ;; zero are optimized away.
11121 (define_insn "*ashrhi3_one_bit_cmp"
11122   [(set (reg 17)
11123         (compare
11124           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11125                        (match_operand:QI 2 "const_int_1_operand" ""))
11126           (const_int 0)))
11127    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11128         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11129   "ix86_match_ccmode (insn, CCGOCmode)
11130    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11131    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11132   "sar{w}\t%0"
11133   [(set_attr "type" "ishift")
11134    (set (attr "length") 
11135      (if_then_else (match_operand 0 "register_operand" "") 
11136         (const_string "2")
11137         (const_string "*")))])
11138
11139 ;; This pattern can't accept a variable shift count, since shifts by
11140 ;; zero don't affect the flags.  We assume that shifts by constant
11141 ;; zero are optimized away.
11142 (define_insn "*ashrhi3_cmp"
11143   [(set (reg 17)
11144         (compare
11145           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11146                        (match_operand:QI 2 "immediate_operand" "I"))
11147           (const_int 0)))
11148    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11149         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11150   "ix86_match_ccmode (insn, CCGOCmode)
11151    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11152   "sar{w}\t{%2, %0|%0, %2}"
11153   [(set_attr "type" "ishift")
11154    (set_attr "mode" "HI")])
11155
11156 (define_expand "ashrqi3"
11157   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11158         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11159                      (match_operand:QI 2 "nonmemory_operand" "")))
11160    (clobber (reg:CC 17))]
11161   "TARGET_QIMODE_MATH"
11162   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11163
11164 (define_insn "*ashrqi3_1_one_bit"
11165   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11166         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11167                      (match_operand:QI 2 "const_int_1_operand" "")))
11168    (clobber (reg:CC 17))]
11169   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11170    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11171   "sar{b}\t%0"
11172   [(set_attr "type" "ishift")
11173    (set (attr "length") 
11174      (if_then_else (match_operand 0 "register_operand" "") 
11175         (const_string "2")
11176         (const_string "*")))])
11177
11178 (define_insn "*ashrqi3_1"
11179   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11180         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11181                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11182    (clobber (reg:CC 17))]
11183   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11184   "@
11185    sar{b}\t{%2, %0|%0, %2}
11186    sar{b}\t{%b2, %0|%0, %b2}"
11187   [(set_attr "type" "ishift")
11188    (set_attr "mode" "QI")])
11189
11190 ;; This pattern can't accept a variable shift count, since shifts by
11191 ;; zero don't affect the flags.  We assume that shifts by constant
11192 ;; zero are optimized away.
11193 (define_insn "*ashrqi3_one_bit_cmp"
11194   [(set (reg 17)
11195         (compare
11196           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11197                        (match_operand:QI 2 "const_int_1_operand" "I"))
11198           (const_int 0)))
11199    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11200         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11201   "ix86_match_ccmode (insn, CCGOCmode)
11202    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11203    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11204   "sar{b}\t%0"
11205   [(set_attr "type" "ishift")
11206    (set (attr "length") 
11207      (if_then_else (match_operand 0 "register_operand" "") 
11208         (const_string "2")
11209         (const_string "*")))])
11210
11211 ;; This pattern can't accept a variable shift count, since shifts by
11212 ;; zero don't affect the flags.  We assume that shifts by constant
11213 ;; zero are optimized away.
11214 (define_insn "*ashrqi3_cmp"
11215   [(set (reg 17)
11216         (compare
11217           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11218                        (match_operand:QI 2 "immediate_operand" "I"))
11219           (const_int 0)))
11220    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11221         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11222   "ix86_match_ccmode (insn, CCGOCmode)
11223    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11224   "sar{b}\t{%2, %0|%0, %2}"
11225   [(set_attr "type" "ishift")
11226    (set_attr "mode" "QI")])
11227 \f
11228 ;; Logical shift instructions
11229
11230 ;; See comment above `ashldi3' about how this works.
11231
11232 (define_expand "lshrdi3"
11233   [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11234                    (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11235                                 (match_operand:QI 2 "nonmemory_operand" "")))
11236               (clobber (reg:CC 17))])]
11237   ""
11238 {
11239   if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11240     {
11241       emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
11242       DONE;
11243     }
11244   ix86_expand_binary_operator (LSHIFTRT, DImode, operands);
11245   DONE;
11246 })
11247
11248 (define_insn "*lshrdi3_1_one_bit_rex64"
11249   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11250         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11251                      (match_operand:QI 2 "const_int_1_operand" "")))
11252    (clobber (reg:CC 17))]
11253   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11254    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11255   "shr{q}\t%0"
11256   [(set_attr "type" "ishift")
11257    (set (attr "length") 
11258      (if_then_else (match_operand:DI 0 "register_operand" "") 
11259         (const_string "2")
11260         (const_string "*")))])
11261
11262 (define_insn "*lshrdi3_1_rex64"
11263   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11264         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11265                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11266    (clobber (reg:CC 17))]
11267   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11268   "@
11269    shr{q}\t{%2, %0|%0, %2}
11270    shr{q}\t{%b2, %0|%0, %b2}"
11271   [(set_attr "type" "ishift")
11272    (set_attr "mode" "DI")])
11273
11274 ;; This pattern can't accept a variable shift count, since shifts by
11275 ;; zero don't affect the flags.  We assume that shifts by constant
11276 ;; zero are optimized away.
11277 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11278   [(set (reg 17)
11279         (compare
11280           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11281                        (match_operand:QI 2 "const_int_1_operand" ""))
11282           (const_int 0)))
11283    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11284         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11285   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11286    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11287    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11288   "shr{q}\t%0"
11289   [(set_attr "type" "ishift")
11290    (set (attr "length") 
11291      (if_then_else (match_operand:DI 0 "register_operand" "") 
11292         (const_string "2")
11293         (const_string "*")))])
11294
11295 ;; This pattern can't accept a variable shift count, since shifts by
11296 ;; zero don't affect the flags.  We assume that shifts by constant
11297 ;; zero are optimized away.
11298 (define_insn "*lshrdi3_cmp_rex64"
11299   [(set (reg 17)
11300         (compare
11301           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11302                        (match_operand:QI 2 "const_int_operand" "e"))
11303           (const_int 0)))
11304    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11305         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11306   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11307    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11308   "shr{q}\t{%2, %0|%0, %2}"
11309   [(set_attr "type" "ishift")
11310    (set_attr "mode" "DI")])
11311
11312 (define_insn "lshrdi3_1"
11313   [(set (match_operand:DI 0 "register_operand" "=r")
11314         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11315                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11316    (clobber (match_scratch:SI 3 "=&r"))
11317    (clobber (reg:CC 17))]
11318   "!TARGET_64BIT && TARGET_CMOVE"
11319   "#"
11320   [(set_attr "type" "multi")])
11321
11322 (define_insn "*lshrdi3_2"
11323   [(set (match_operand:DI 0 "register_operand" "=r")
11324         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11325                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11326    (clobber (reg:CC 17))]
11327   "!TARGET_64BIT"
11328   "#"
11329   [(set_attr "type" "multi")])
11330
11331 (define_split 
11332   [(set (match_operand:DI 0 "register_operand" "")
11333         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11334                      (match_operand:QI 2 "nonmemory_operand" "")))
11335    (clobber (match_scratch:SI 3 ""))
11336    (clobber (reg:CC 17))]
11337   "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11338   [(const_int 0)]
11339   "ix86_split_lshrdi (operands, operands[3]); DONE;")
11340
11341 (define_split 
11342   [(set (match_operand:DI 0 "register_operand" "")
11343         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11344                      (match_operand:QI 2 "nonmemory_operand" "")))
11345    (clobber (reg:CC 17))]
11346   "!TARGET_64BIT && reload_completed"
11347   [(const_int 0)]
11348   "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11349
11350 (define_expand "lshrsi3"
11351   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11352         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11353                      (match_operand:QI 2 "nonmemory_operand" "")))
11354    (clobber (reg:CC 17))]
11355   ""
11356   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11357
11358 (define_insn "*lshrsi3_1_one_bit"
11359   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11360         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11361                      (match_operand:QI 2 "const_int_1_operand" "")))
11362    (clobber (reg:CC 17))]
11363   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11364    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11365   "shr{l}\t%0"
11366   [(set_attr "type" "ishift")
11367    (set (attr "length") 
11368      (if_then_else (match_operand:SI 0 "register_operand" "") 
11369         (const_string "2")
11370         (const_string "*")))])
11371
11372 (define_insn "*lshrsi3_1_one_bit_zext"
11373   [(set (match_operand:DI 0 "register_operand" "=r")
11374         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11375                      (match_operand:QI 2 "const_int_1_operand" "")))
11376    (clobber (reg:CC 17))]
11377   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11378    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11379   "shr{l}\t%k0"
11380   [(set_attr "type" "ishift")
11381    (set_attr "length" "2")])
11382
11383 (define_insn "*lshrsi3_1"
11384   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11385         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11386                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11387    (clobber (reg:CC 17))]
11388   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11389   "@
11390    shr{l}\t{%2, %0|%0, %2}
11391    shr{l}\t{%b2, %0|%0, %b2}"
11392   [(set_attr "type" "ishift")
11393    (set_attr "mode" "SI")])
11394
11395 (define_insn "*lshrsi3_1_zext"
11396   [(set (match_operand:DI 0 "register_operand" "=r,r")
11397         (zero_extend:DI
11398           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11399                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11400    (clobber (reg:CC 17))]
11401   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11402   "@
11403    shr{l}\t{%2, %k0|%k0, %2}
11404    shr{l}\t{%b2, %k0|%k0, %b2}"
11405   [(set_attr "type" "ishift")
11406    (set_attr "mode" "SI")])
11407
11408 ;; This pattern can't accept a variable shift count, since shifts by
11409 ;; zero don't affect the flags.  We assume that shifts by constant
11410 ;; zero are optimized away.
11411 (define_insn "*lshrsi3_one_bit_cmp"
11412   [(set (reg 17)
11413         (compare
11414           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11415                        (match_operand:QI 2 "const_int_1_operand" ""))
11416           (const_int 0)))
11417    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11418         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11419   "ix86_match_ccmode (insn, CCGOCmode)
11420    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11421    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11422   "shr{l}\t%0"
11423   [(set_attr "type" "ishift")
11424    (set (attr "length") 
11425      (if_then_else (match_operand:SI 0 "register_operand" "") 
11426         (const_string "2")
11427         (const_string "*")))])
11428
11429 (define_insn "*lshrsi3_cmp_one_bit_zext"
11430   [(set (reg 17)
11431         (compare
11432           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11433                        (match_operand:QI 2 "const_int_1_operand" ""))
11434           (const_int 0)))
11435    (set (match_operand:DI 0 "register_operand" "=r")
11436         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11437   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11438    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11439    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11440   "shr{l}\t%k0"
11441   [(set_attr "type" "ishift")
11442    (set_attr "length" "2")])
11443
11444 ;; This pattern can't accept a variable shift count, since shifts by
11445 ;; zero don't affect the flags.  We assume that shifts by constant
11446 ;; zero are optimized away.
11447 (define_insn "*lshrsi3_cmp"
11448   [(set (reg 17)
11449         (compare
11450           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11451                        (match_operand:QI 2 "immediate_operand" "I"))
11452           (const_int 0)))
11453    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11454         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11455   "ix86_match_ccmode (insn, CCGOCmode)
11456    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11457   "shr{l}\t{%2, %0|%0, %2}"
11458   [(set_attr "type" "ishift")
11459    (set_attr "mode" "SI")])
11460
11461 (define_insn "*lshrsi3_cmp_zext"
11462   [(set (reg 17)
11463         (compare
11464           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11465                        (match_operand:QI 2 "immediate_operand" "I"))
11466           (const_int 0)))
11467    (set (match_operand:DI 0 "register_operand" "=r")
11468         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11469   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11470    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11471   "shr{l}\t{%2, %k0|%k0, %2}"
11472   [(set_attr "type" "ishift")
11473    (set_attr "mode" "SI")])
11474
11475 (define_expand "lshrhi3"
11476   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11477         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11478                      (match_operand:QI 2 "nonmemory_operand" "")))
11479    (clobber (reg:CC 17))]
11480   "TARGET_HIMODE_MATH"
11481   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11482
11483 (define_insn "*lshrhi3_1_one_bit"
11484   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11485         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11486                      (match_operand:QI 2 "const_int_1_operand" "")))
11487    (clobber (reg:CC 17))]
11488   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11489    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11490   "shr{w}\t%0"
11491   [(set_attr "type" "ishift")
11492    (set (attr "length") 
11493      (if_then_else (match_operand 0 "register_operand" "") 
11494         (const_string "2")
11495         (const_string "*")))])
11496
11497 (define_insn "*lshrhi3_1"
11498   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11499         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11500                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11501    (clobber (reg:CC 17))]
11502   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11503   "@
11504    shr{w}\t{%2, %0|%0, %2}
11505    shr{w}\t{%b2, %0|%0, %b2}"
11506   [(set_attr "type" "ishift")
11507    (set_attr "mode" "HI")])
11508
11509 ;; This pattern can't accept a variable shift count, since shifts by
11510 ;; zero don't affect the flags.  We assume that shifts by constant
11511 ;; zero are optimized away.
11512 (define_insn "*lshrhi3_one_bit_cmp"
11513   [(set (reg 17)
11514         (compare
11515           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11516                        (match_operand:QI 2 "const_int_1_operand" ""))
11517           (const_int 0)))
11518    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11519         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11520   "ix86_match_ccmode (insn, CCGOCmode)
11521    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11522    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11523   "shr{w}\t%0"
11524   [(set_attr "type" "ishift")
11525    (set (attr "length") 
11526      (if_then_else (match_operand:SI 0 "register_operand" "") 
11527         (const_string "2")
11528         (const_string "*")))])
11529
11530 ;; This pattern can't accept a variable shift count, since shifts by
11531 ;; zero don't affect the flags.  We assume that shifts by constant
11532 ;; zero are optimized away.
11533 (define_insn "*lshrhi3_cmp"
11534   [(set (reg 17)
11535         (compare
11536           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11537                        (match_operand:QI 2 "immediate_operand" "I"))
11538           (const_int 0)))
11539    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11540         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11541   "ix86_match_ccmode (insn, CCGOCmode)
11542    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11543   "shr{w}\t{%2, %0|%0, %2}"
11544   [(set_attr "type" "ishift")
11545    (set_attr "mode" "HI")])
11546
11547 (define_expand "lshrqi3"
11548   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11549         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11550                      (match_operand:QI 2 "nonmemory_operand" "")))
11551    (clobber (reg:CC 17))]
11552   "TARGET_QIMODE_MATH"
11553   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11554
11555 (define_insn "*lshrqi3_1_one_bit"
11556   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11557         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11558                      (match_operand:QI 2 "const_int_1_operand" "")))
11559    (clobber (reg:CC 17))]
11560   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11561    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11562   "shr{b}\t%0"
11563   [(set_attr "type" "ishift")
11564    (set (attr "length") 
11565      (if_then_else (match_operand 0 "register_operand" "") 
11566         (const_string "2")
11567         (const_string "*")))])
11568
11569 (define_insn "*lshrqi3_1"
11570   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11571         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11572                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11573    (clobber (reg:CC 17))]
11574   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11575   "@
11576    shr{b}\t{%2, %0|%0, %2}
11577    shr{b}\t{%b2, %0|%0, %b2}"
11578   [(set_attr "type" "ishift")
11579    (set_attr "mode" "QI")])
11580
11581 ;; This pattern can't accept a variable shift count, since shifts by
11582 ;; zero don't affect the flags.  We assume that shifts by constant
11583 ;; zero are optimized away.
11584 (define_insn "*lshrqi2_one_bit_cmp"
11585   [(set (reg 17)
11586         (compare
11587           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11588                        (match_operand:QI 2 "const_int_1_operand" ""))
11589           (const_int 0)))
11590    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11591         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11592   "ix86_match_ccmode (insn, CCGOCmode)
11593    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11594    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11595   "shr{b}\t%0"
11596   [(set_attr "type" "ishift")
11597    (set (attr "length") 
11598      (if_then_else (match_operand:SI 0 "register_operand" "") 
11599         (const_string "2")
11600         (const_string "*")))])
11601
11602 ;; This pattern can't accept a variable shift count, since shifts by
11603 ;; zero don't affect the flags.  We assume that shifts by constant
11604 ;; zero are optimized away.
11605 (define_insn "*lshrqi2_cmp"
11606   [(set (reg 17)
11607         (compare
11608           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11609                        (match_operand:QI 2 "immediate_operand" "I"))
11610           (const_int 0)))
11611    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11612         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11613   "ix86_match_ccmode (insn, CCGOCmode)
11614    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11615   "shr{b}\t{%2, %0|%0, %2}"
11616   [(set_attr "type" "ishift")
11617    (set_attr "mode" "QI")])
11618 \f
11619 ;; Rotate instructions
11620
11621 (define_expand "rotldi3"
11622   [(set (match_operand:DI 0 "nonimmediate_operand" "")
11623         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
11624                    (match_operand:QI 2 "nonmemory_operand" "")))
11625    (clobber (reg:CC 17))]
11626   "TARGET_64BIT"
11627   "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
11628
11629 (define_insn "*rotlsi3_1_one_bit_rex64"
11630   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11631         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11632                    (match_operand:QI 2 "const_int_1_operand" "")))
11633    (clobber (reg:CC 17))]
11634   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
11635    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11636   "rol{q}\t%0"
11637   [(set_attr "type" "rotate")
11638    (set (attr "length") 
11639      (if_then_else (match_operand:DI 0 "register_operand" "") 
11640         (const_string "2")
11641         (const_string "*")))])
11642
11643 (define_insn "*rotldi3_1_rex64"
11644   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11645         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11646                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
11647    (clobber (reg:CC 17))]
11648   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
11649   "@
11650    rol{q}\t{%2, %0|%0, %2}
11651    rol{q}\t{%b2, %0|%0, %b2}"
11652   [(set_attr "type" "rotate")
11653    (set_attr "mode" "DI")])
11654
11655 (define_expand "rotlsi3"
11656   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11657         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
11658                    (match_operand:QI 2 "nonmemory_operand" "")))
11659    (clobber (reg:CC 17))]
11660   ""
11661   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
11662
11663 (define_insn "*rotlsi3_1_one_bit"
11664   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11665         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11666                    (match_operand:QI 2 "const_int_1_operand" "")))
11667    (clobber (reg:CC 17))]
11668   "ix86_binary_operator_ok (ROTATE, SImode, operands)
11669    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11670   "rol{l}\t%0"
11671   [(set_attr "type" "rotate")
11672    (set (attr "length") 
11673      (if_then_else (match_operand:SI 0 "register_operand" "") 
11674         (const_string "2")
11675         (const_string "*")))])
11676
11677 (define_insn "*rotlsi3_1_one_bit_zext"
11678   [(set (match_operand:DI 0 "register_operand" "=r")
11679         (zero_extend:DI
11680           (rotate:SI (match_operand:SI 1 "register_operand" "0")
11681                      (match_operand:QI 2 "const_int_1_operand" ""))))
11682    (clobber (reg:CC 17))]
11683   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
11684    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11685   "rol{l}\t%k0"
11686   [(set_attr "type" "rotate")
11687    (set_attr "length" "2")])
11688
11689 (define_insn "*rotlsi3_1"
11690   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11691         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11692                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11693    (clobber (reg:CC 17))]
11694   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
11695   "@
11696    rol{l}\t{%2, %0|%0, %2}
11697    rol{l}\t{%b2, %0|%0, %b2}"
11698   [(set_attr "type" "rotate")
11699    (set_attr "mode" "SI")])
11700
11701 (define_insn "*rotlsi3_1_zext"
11702   [(set (match_operand:DI 0 "register_operand" "=r,r")
11703         (zero_extend:DI
11704           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
11705                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11706    (clobber (reg:CC 17))]
11707   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
11708   "@
11709    rol{l}\t{%2, %k0|%k0, %2}
11710    rol{l}\t{%b2, %k0|%k0, %b2}"
11711   [(set_attr "type" "rotate")
11712    (set_attr "mode" "SI")])
11713
11714 (define_expand "rotlhi3"
11715   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11716         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
11717                    (match_operand:QI 2 "nonmemory_operand" "")))
11718    (clobber (reg:CC 17))]
11719   "TARGET_HIMODE_MATH"
11720   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
11721
11722 (define_insn "*rotlhi3_1_one_bit"
11723   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11724         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11725                    (match_operand:QI 2 "const_int_1_operand" "")))
11726    (clobber (reg:CC 17))]
11727   "ix86_binary_operator_ok (ROTATE, HImode, operands)
11728    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11729   "rol{w}\t%0"
11730   [(set_attr "type" "rotate")
11731    (set (attr "length") 
11732      (if_then_else (match_operand 0 "register_operand" "") 
11733         (const_string "2")
11734         (const_string "*")))])
11735
11736 (define_insn "*rotlhi3_1"
11737   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11738         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11739                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11740    (clobber (reg:CC 17))]
11741   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
11742   "@
11743    rol{w}\t{%2, %0|%0, %2}
11744    rol{w}\t{%b2, %0|%0, %b2}"
11745   [(set_attr "type" "rotate")
11746    (set_attr "mode" "HI")])
11747
11748 (define_expand "rotlqi3"
11749   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11750         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
11751                    (match_operand:QI 2 "nonmemory_operand" "")))
11752    (clobber (reg:CC 17))]
11753   "TARGET_QIMODE_MATH"
11754   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
11755
11756 (define_insn "*rotlqi3_1_one_bit"
11757   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11758         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11759                    (match_operand:QI 2 "const_int_1_operand" "")))
11760    (clobber (reg:CC 17))]
11761   "ix86_binary_operator_ok (ROTATE, QImode, operands)
11762    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11763   "rol{b}\t%0"
11764   [(set_attr "type" "rotate")
11765    (set (attr "length") 
11766      (if_then_else (match_operand 0 "register_operand" "") 
11767         (const_string "2")
11768         (const_string "*")))])
11769
11770 (define_insn "*rotlqi3_1"
11771   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11772         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11773                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11774    (clobber (reg:CC 17))]
11775   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
11776   "@
11777    rol{b}\t{%2, %0|%0, %2}
11778    rol{b}\t{%b2, %0|%0, %b2}"
11779   [(set_attr "type" "rotate")
11780    (set_attr "mode" "QI")])
11781
11782 (define_expand "rotrdi3"
11783   [(set (match_operand:DI 0 "nonimmediate_operand" "")
11784         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
11785                      (match_operand:QI 2 "nonmemory_operand" "")))
11786    (clobber (reg:CC 17))]
11787   "TARGET_64BIT"
11788   "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
11789
11790 (define_insn "*rotrdi3_1_one_bit_rex64"
11791   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11792         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11793                      (match_operand:QI 2 "const_int_1_operand" "")))
11794    (clobber (reg:CC 17))]
11795   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
11796    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11797   "ror{q}\t%0"
11798   [(set_attr "type" "rotate")
11799    (set (attr "length") 
11800      (if_then_else (match_operand:DI 0 "register_operand" "") 
11801         (const_string "2")
11802         (const_string "*")))])
11803
11804 (define_insn "*rotrdi3_1_rex64"
11805   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11806         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11807                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11808    (clobber (reg:CC 17))]
11809   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
11810   "@
11811    ror{q}\t{%2, %0|%0, %2}
11812    ror{q}\t{%b2, %0|%0, %b2}"
11813   [(set_attr "type" "rotate")
11814    (set_attr "mode" "DI")])
11815
11816 (define_expand "rotrsi3"
11817   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11818         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
11819                      (match_operand:QI 2 "nonmemory_operand" "")))
11820    (clobber (reg:CC 17))]
11821   ""
11822   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
11823
11824 (define_insn "*rotrsi3_1_one_bit"
11825   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11826         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11827                      (match_operand:QI 2 "const_int_1_operand" "")))
11828    (clobber (reg:CC 17))]
11829   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
11830    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11831   "ror{l}\t%0"
11832   [(set_attr "type" "rotate")
11833    (set (attr "length") 
11834      (if_then_else (match_operand:SI 0 "register_operand" "") 
11835         (const_string "2")
11836         (const_string "*")))])
11837
11838 (define_insn "*rotrsi3_1_one_bit_zext"
11839   [(set (match_operand:DI 0 "register_operand" "=r")
11840         (zero_extend:DI
11841           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
11842                        (match_operand:QI 2 "const_int_1_operand" ""))))
11843    (clobber (reg:CC 17))]
11844   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
11845    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11846   "ror{l}\t%k0"
11847   [(set_attr "type" "rotate")
11848    (set (attr "length") 
11849      (if_then_else (match_operand:SI 0 "register_operand" "") 
11850         (const_string "2")
11851         (const_string "*")))])
11852
11853 (define_insn "*rotrsi3_1"
11854   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11855         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11856                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11857    (clobber (reg:CC 17))]
11858   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
11859   "@
11860    ror{l}\t{%2, %0|%0, %2}
11861    ror{l}\t{%b2, %0|%0, %b2}"
11862   [(set_attr "type" "rotate")
11863    (set_attr "mode" "SI")])
11864
11865 (define_insn "*rotrsi3_1_zext"
11866   [(set (match_operand:DI 0 "register_operand" "=r,r")
11867         (zero_extend:DI
11868           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
11869                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11870    (clobber (reg:CC 17))]
11871   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
11872   "@
11873    ror{l}\t{%2, %k0|%k0, %2}
11874    ror{l}\t{%b2, %k0|%k0, %b2}"
11875   [(set_attr "type" "rotate")
11876    (set_attr "mode" "SI")])
11877
11878 (define_expand "rotrhi3"
11879   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11880         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
11881                      (match_operand:QI 2 "nonmemory_operand" "")))
11882    (clobber (reg:CC 17))]
11883   "TARGET_HIMODE_MATH"
11884   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
11885
11886 (define_insn "*rotrhi3_one_bit"
11887   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11888         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11889                      (match_operand:QI 2 "const_int_1_operand" "")))
11890    (clobber (reg:CC 17))]
11891   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
11892    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11893   "ror{w}\t%0"
11894   [(set_attr "type" "rotate")
11895    (set (attr "length") 
11896      (if_then_else (match_operand 0 "register_operand" "") 
11897         (const_string "2")
11898         (const_string "*")))])
11899
11900 (define_insn "*rotrhi3"
11901   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11902         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11903                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11904    (clobber (reg:CC 17))]
11905   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
11906   "@
11907    ror{w}\t{%2, %0|%0, %2}
11908    ror{w}\t{%b2, %0|%0, %b2}"
11909   [(set_attr "type" "rotate")
11910    (set_attr "mode" "HI")])
11911
11912 (define_expand "rotrqi3"
11913   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11914         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
11915                      (match_operand:QI 2 "nonmemory_operand" "")))
11916    (clobber (reg:CC 17))]
11917   "TARGET_QIMODE_MATH"
11918   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
11919
11920 (define_insn "*rotrqi3_1_one_bit"
11921   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11922         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11923                      (match_operand:QI 2 "const_int_1_operand" "")))
11924    (clobber (reg:CC 17))]
11925   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
11926    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11927   "ror{b}\t%0"
11928   [(set_attr "type" "rotate")
11929    (set (attr "length") 
11930      (if_then_else (match_operand 0 "register_operand" "") 
11931         (const_string "2")
11932         (const_string "*")))])
11933
11934 (define_insn "*rotrqi3_1"
11935   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11936         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11937                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11938    (clobber (reg:CC 17))]
11939   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
11940   "@
11941    ror{b}\t{%2, %0|%0, %2}
11942    ror{b}\t{%b2, %0|%0, %b2}"
11943   [(set_attr "type" "rotate")
11944    (set_attr "mode" "QI")])
11945 \f
11946 ;; Bit set / bit test instructions
11947
11948 (define_expand "extv"
11949   [(set (match_operand:SI 0 "register_operand" "")
11950         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
11951                          (match_operand:SI 2 "immediate_operand" "")
11952                          (match_operand:SI 3 "immediate_operand" "")))]
11953   ""
11954 {
11955   /* Handle extractions from %ah et al.  */
11956   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
11957     FAIL;
11958
11959   /* From mips.md: extract_bit_field doesn't verify that our source
11960      matches the predicate, so check it again here.  */
11961   if (! register_operand (operands[1], VOIDmode))
11962     FAIL;
11963 })
11964
11965 (define_expand "extzv"
11966   [(set (match_operand:SI 0 "register_operand" "")
11967         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
11968                          (match_operand:SI 2 "immediate_operand" "")
11969                          (match_operand:SI 3 "immediate_operand" "")))]
11970   ""
11971 {
11972   /* Handle extractions from %ah et al.  */
11973   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
11974     FAIL;
11975
11976   /* From mips.md: extract_bit_field doesn't verify that our source
11977      matches the predicate, so check it again here.  */
11978   if (! register_operand (operands[1], VOIDmode))
11979     FAIL;
11980 })
11981
11982 (define_expand "insv"
11983   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
11984                          (match_operand:SI 1 "immediate_operand" "")
11985                          (match_operand:SI 2 "immediate_operand" ""))
11986         (match_operand:SI 3 "register_operand" ""))]
11987   ""
11988 {
11989   /* Handle extractions from %ah et al.  */
11990   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
11991     FAIL;
11992
11993   /* From mips.md: insert_bit_field doesn't verify that our source
11994      matches the predicate, so check it again here.  */
11995   if (! register_operand (operands[0], VOIDmode))
11996     FAIL;
11997 })
11998
11999 ;; %%% bts, btr, btc, bt.
12000 \f
12001 ;; Store-flag instructions.
12002
12003 ;; For all sCOND expanders, also expand the compare or test insn that
12004 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12005
12006 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12007 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12008 ;; way, which can later delete the movzx if only QImode is needed.
12009
12010 (define_expand "seq"
12011   [(set (match_operand:QI 0 "register_operand" "")
12012         (eq:QI (reg:CC 17) (const_int 0)))]
12013   ""
12014   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12015
12016 (define_expand "sne"
12017   [(set (match_operand:QI 0 "register_operand" "")
12018         (ne:QI (reg:CC 17) (const_int 0)))]
12019   ""
12020   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12021
12022 (define_expand "sgt"
12023   [(set (match_operand:QI 0 "register_operand" "")
12024         (gt:QI (reg:CC 17) (const_int 0)))]
12025   ""
12026   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12027
12028 (define_expand "sgtu"
12029   [(set (match_operand:QI 0 "register_operand" "")
12030         (gtu:QI (reg:CC 17) (const_int 0)))]
12031   ""
12032   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12033
12034 (define_expand "slt"
12035   [(set (match_operand:QI 0 "register_operand" "")
12036         (lt:QI (reg:CC 17) (const_int 0)))]
12037   ""
12038   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12039
12040 (define_expand "sltu"
12041   [(set (match_operand:QI 0 "register_operand" "")
12042         (ltu:QI (reg:CC 17) (const_int 0)))]
12043   ""
12044   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12045
12046 (define_expand "sge"
12047   [(set (match_operand:QI 0 "register_operand" "")
12048         (ge:QI (reg:CC 17) (const_int 0)))]
12049   ""
12050   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12051
12052 (define_expand "sgeu"
12053   [(set (match_operand:QI 0 "register_operand" "")
12054         (geu:QI (reg:CC 17) (const_int 0)))]
12055   ""
12056   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12057
12058 (define_expand "sle"
12059   [(set (match_operand:QI 0 "register_operand" "")
12060         (le:QI (reg:CC 17) (const_int 0)))]
12061   ""
12062   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12063
12064 (define_expand "sleu"
12065   [(set (match_operand:QI 0 "register_operand" "")
12066         (leu:QI (reg:CC 17) (const_int 0)))]
12067   ""
12068   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12069
12070 (define_expand "sunordered"
12071   [(set (match_operand:QI 0 "register_operand" "")
12072         (unordered:QI (reg:CC 17) (const_int 0)))]
12073   "TARGET_80387 || TARGET_SSE"
12074   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12075
12076 (define_expand "sordered"
12077   [(set (match_operand:QI 0 "register_operand" "")
12078         (ordered:QI (reg:CC 17) (const_int 0)))]
12079   "TARGET_80387"
12080   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12081
12082 (define_expand "suneq"
12083   [(set (match_operand:QI 0 "register_operand" "")
12084         (uneq:QI (reg:CC 17) (const_int 0)))]
12085   "TARGET_80387 || TARGET_SSE"
12086   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12087
12088 (define_expand "sunge"
12089   [(set (match_operand:QI 0 "register_operand" "")
12090         (unge:QI (reg:CC 17) (const_int 0)))]
12091   "TARGET_80387 || TARGET_SSE"
12092   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12093
12094 (define_expand "sungt"
12095   [(set (match_operand:QI 0 "register_operand" "")
12096         (ungt:QI (reg:CC 17) (const_int 0)))]
12097   "TARGET_80387 || TARGET_SSE"
12098   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12099
12100 (define_expand "sunle"
12101   [(set (match_operand:QI 0 "register_operand" "")
12102         (unle:QI (reg:CC 17) (const_int 0)))]
12103   "TARGET_80387 || TARGET_SSE"
12104   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12105
12106 (define_expand "sunlt"
12107   [(set (match_operand:QI 0 "register_operand" "")
12108         (unlt:QI (reg:CC 17) (const_int 0)))]
12109   "TARGET_80387 || TARGET_SSE"
12110   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12111
12112 (define_expand "sltgt"
12113   [(set (match_operand:QI 0 "register_operand" "")
12114         (ltgt:QI (reg:CC 17) (const_int 0)))]
12115   "TARGET_80387 || TARGET_SSE"
12116   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12117
12118 (define_insn "*setcc_1"
12119   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12120         (match_operator:QI 1 "ix86_comparison_operator"
12121           [(reg 17) (const_int 0)]))]
12122   ""
12123   "set%C1\t%0"
12124   [(set_attr "type" "setcc")
12125    (set_attr "mode" "QI")])
12126
12127 (define_insn "setcc_2"
12128   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12129         (match_operator:QI 1 "ix86_comparison_operator"
12130           [(reg 17) (const_int 0)]))]
12131   ""
12132   "set%C1\t%0"
12133   [(set_attr "type" "setcc")
12134    (set_attr "mode" "QI")])
12135
12136 ;; In general it is not safe to assume too much about CCmode registers,
12137 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12138 ;; conditions this is safe on x86, so help combine not create
12139 ;;
12140 ;;      seta    %al
12141 ;;      testb   %al, %al
12142 ;;      sete    %al
12143
12144 (define_split 
12145   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12146         (ne:QI (match_operator 1 "ix86_comparison_operator"
12147                  [(reg 17) (const_int 0)])
12148             (const_int 0)))]
12149   ""
12150   [(set (match_dup 0) (match_dup 1))]
12151 {
12152   PUT_MODE (operands[1], QImode);
12153 })
12154
12155 (define_split 
12156   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12157         (ne:QI (match_operator 1 "ix86_comparison_operator"
12158                  [(reg 17) (const_int 0)])
12159             (const_int 0)))]
12160   ""
12161   [(set (match_dup 0) (match_dup 1))]
12162 {
12163   PUT_MODE (operands[1], QImode);
12164 })
12165
12166 (define_split 
12167   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12168         (eq:QI (match_operator 1 "ix86_comparison_operator"
12169                  [(reg 17) (const_int 0)])
12170             (const_int 0)))]
12171   ""
12172   [(set (match_dup 0) (match_dup 1))]
12173 {
12174   rtx new_op1 = copy_rtx (operands[1]);
12175   operands[1] = new_op1;
12176   PUT_MODE (new_op1, QImode);
12177   PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
12178                                         GET_MODE (XEXP (new_op1, 0))));
12179
12180   /* Make sure that (a) the CCmode we have for the flags is strong
12181      enough for the reversed compare or (b) we have a valid FP compare.  */
12182   if (! ix86_comparison_operator (new_op1, VOIDmode))
12183     FAIL;
12184 })
12185
12186 (define_split 
12187   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12188         (eq:QI (match_operator 1 "ix86_comparison_operator"
12189                  [(reg 17) (const_int 0)])
12190             (const_int 0)))]
12191   ""
12192   [(set (match_dup 0) (match_dup 1))]
12193 {
12194   rtx new_op1 = copy_rtx (operands[1]);
12195   operands[1] = new_op1;
12196   PUT_MODE (new_op1, QImode);
12197   PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
12198                                         GET_MODE (XEXP (new_op1, 0))));
12199
12200   /* Make sure that (a) the CCmode we have for the flags is strong
12201      enough for the reversed compare or (b) we have a valid FP compare.  */
12202   if (! ix86_comparison_operator (new_op1, VOIDmode))
12203     FAIL;
12204 })
12205
12206 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12207 ;; subsequent logical operations are used to imitate conditional moves.
12208 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12209 ;; it directly.  Futher holding this value in pseudo register might bring
12210 ;; problem in implicit normalization in spill code.
12211 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12212 ;; instructions after reload by splitting the conditional move patterns.
12213
12214 (define_insn "*sse_setccsf"
12215   [(set (match_operand:SF 0 "register_operand" "=x")
12216         (match_operator:SF 1 "sse_comparison_operator"
12217           [(match_operand:SF 2 "register_operand" "0")
12218            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12219   "TARGET_SSE && reload_completed"
12220   "cmp%D1ss\t{%3, %0|%0, %3}"
12221   [(set_attr "type" "ssecmp")
12222    (set_attr "mode" "SF")])
12223
12224 (define_insn "*sse_setccdf"
12225   [(set (match_operand:DF 0 "register_operand" "=Y")
12226         (match_operator:DF 1 "sse_comparison_operator"
12227           [(match_operand:DF 2 "register_operand" "0")
12228            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12229   "TARGET_SSE2 && reload_completed"
12230   "cmp%D1sd\t{%3, %0|%0, %3}"
12231   [(set_attr "type" "ssecmp")
12232    (set_attr "mode" "DF")])
12233 \f
12234 ;; Basic conditional jump instructions.
12235 ;; We ignore the overflow flag for signed branch instructions.
12236
12237 ;; For all bCOND expanders, also expand the compare or test insn that
12238 ;; generates reg 17.  Generate an equality comparison if `beq' or `bne'.
12239
12240 (define_expand "beq"
12241   [(set (pc)
12242         (if_then_else (match_dup 1)
12243                       (label_ref (match_operand 0 "" ""))
12244                       (pc)))]
12245   ""
12246   "ix86_expand_branch (EQ, operands[0]); DONE;")
12247
12248 (define_expand "bne"
12249   [(set (pc)
12250         (if_then_else (match_dup 1)
12251                       (label_ref (match_operand 0 "" ""))
12252                       (pc)))]
12253   ""
12254   "ix86_expand_branch (NE, operands[0]); DONE;")
12255
12256 (define_expand "bgt"
12257   [(set (pc)
12258         (if_then_else (match_dup 1)
12259                       (label_ref (match_operand 0 "" ""))
12260                       (pc)))]
12261   ""
12262   "ix86_expand_branch (GT, operands[0]); DONE;")
12263
12264 (define_expand "bgtu"
12265   [(set (pc)
12266         (if_then_else (match_dup 1)
12267                       (label_ref (match_operand 0 "" ""))
12268                       (pc)))]
12269   ""
12270   "ix86_expand_branch (GTU, operands[0]); DONE;")
12271
12272 (define_expand "blt"
12273   [(set (pc)
12274         (if_then_else (match_dup 1)
12275                       (label_ref (match_operand 0 "" ""))
12276                       (pc)))]
12277   ""
12278   "ix86_expand_branch (LT, operands[0]); DONE;")
12279
12280 (define_expand "bltu"
12281   [(set (pc)
12282         (if_then_else (match_dup 1)
12283                       (label_ref (match_operand 0 "" ""))
12284                       (pc)))]
12285   ""
12286   "ix86_expand_branch (LTU, operands[0]); DONE;")
12287
12288 (define_expand "bge"
12289   [(set (pc)
12290         (if_then_else (match_dup 1)
12291                       (label_ref (match_operand 0 "" ""))
12292                       (pc)))]
12293   ""
12294   "ix86_expand_branch (GE, operands[0]); DONE;")
12295
12296 (define_expand "bgeu"
12297   [(set (pc)
12298         (if_then_else (match_dup 1)
12299                       (label_ref (match_operand 0 "" ""))
12300                       (pc)))]
12301   ""
12302   "ix86_expand_branch (GEU, operands[0]); DONE;")
12303
12304 (define_expand "ble"
12305   [(set (pc)
12306         (if_then_else (match_dup 1)
12307                       (label_ref (match_operand 0 "" ""))
12308                       (pc)))]
12309   ""
12310   "ix86_expand_branch (LE, operands[0]); DONE;")
12311
12312 (define_expand "bleu"
12313   [(set (pc)
12314         (if_then_else (match_dup 1)
12315                       (label_ref (match_operand 0 "" ""))
12316                       (pc)))]
12317   ""
12318   "ix86_expand_branch (LEU, operands[0]); DONE;")
12319
12320 (define_expand "bunordered"
12321   [(set (pc)
12322         (if_then_else (match_dup 1)
12323                       (label_ref (match_operand 0 "" ""))
12324                       (pc)))]
12325   "TARGET_80387 || TARGET_SSE"
12326   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12327
12328 (define_expand "bordered"
12329   [(set (pc)
12330         (if_then_else (match_dup 1)
12331                       (label_ref (match_operand 0 "" ""))
12332                       (pc)))]
12333   "TARGET_80387 || TARGET_SSE"
12334   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12335
12336 (define_expand "buneq"
12337   [(set (pc)
12338         (if_then_else (match_dup 1)
12339                       (label_ref (match_operand 0 "" ""))
12340                       (pc)))]
12341   "TARGET_80387 || TARGET_SSE"
12342   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12343
12344 (define_expand "bunge"
12345   [(set (pc)
12346         (if_then_else (match_dup 1)
12347                       (label_ref (match_operand 0 "" ""))
12348                       (pc)))]
12349   "TARGET_80387 || TARGET_SSE"
12350   "ix86_expand_branch (UNGE, operands[0]); DONE;")
12351
12352 (define_expand "bungt"
12353   [(set (pc)
12354         (if_then_else (match_dup 1)
12355                       (label_ref (match_operand 0 "" ""))
12356                       (pc)))]
12357   "TARGET_80387 || TARGET_SSE"
12358   "ix86_expand_branch (UNGT, operands[0]); DONE;")
12359
12360 (define_expand "bunle"
12361   [(set (pc)
12362         (if_then_else (match_dup 1)
12363                       (label_ref (match_operand 0 "" ""))
12364                       (pc)))]
12365   "TARGET_80387 || TARGET_SSE"
12366   "ix86_expand_branch (UNLE, operands[0]); DONE;")
12367
12368 (define_expand "bunlt"
12369   [(set (pc)
12370         (if_then_else (match_dup 1)
12371                       (label_ref (match_operand 0 "" ""))
12372                       (pc)))]
12373   "TARGET_80387 || TARGET_SSE"
12374   "ix86_expand_branch (UNLT, operands[0]); DONE;")
12375
12376 (define_expand "bltgt"
12377   [(set (pc)
12378         (if_then_else (match_dup 1)
12379                       (label_ref (match_operand 0 "" ""))
12380                       (pc)))]
12381   "TARGET_80387 || TARGET_SSE"
12382   "ix86_expand_branch (LTGT, operands[0]); DONE;")
12383
12384 (define_insn "*jcc_1"
12385   [(set (pc)
12386         (if_then_else (match_operator 1 "ix86_comparison_operator"
12387                                       [(reg 17) (const_int 0)])
12388                       (label_ref (match_operand 0 "" ""))
12389                       (pc)))]
12390   ""
12391   "%+j%C1\t%l0"
12392   [(set_attr "type" "ibr")
12393    (set (attr "prefix_0f")
12394            (if_then_else (and (ge (minus (match_dup 0) (pc))
12395                                   (const_int -128))
12396                               (lt (minus (match_dup 0) (pc))
12397                                   (const_int 124)))
12398              (const_int 0)
12399              (const_int 1)))])
12400
12401 (define_insn "*jcc_2"
12402   [(set (pc)
12403         (if_then_else (match_operator 1 "ix86_comparison_operator"
12404                                       [(reg 17) (const_int 0)])
12405                       (pc)
12406                       (label_ref (match_operand 0 "" ""))))]
12407   ""
12408   "%+j%c1\t%l0"
12409   [(set_attr "type" "ibr")
12410    (set (attr "prefix_0f")
12411            (if_then_else (and (ge (minus (match_dup 0) (pc))
12412                                   (const_int -128))
12413                               (lt (minus (match_dup 0) (pc))
12414                                   (const_int 124)))
12415              (const_int 0)
12416              (const_int 1)))])
12417
12418 ;; In general it is not safe to assume too much about CCmode registers,
12419 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12420 ;; conditions this is safe on x86, so help combine not create
12421 ;;
12422 ;;      seta    %al
12423 ;;      testb   %al, %al
12424 ;;      je      Lfoo
12425
12426 (define_split 
12427   [(set (pc)
12428         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12429                                       [(reg 17) (const_int 0)])
12430                           (const_int 0))
12431                       (label_ref (match_operand 1 "" ""))
12432                       (pc)))]
12433   ""
12434   [(set (pc)
12435         (if_then_else (match_dup 0)
12436                       (label_ref (match_dup 1))
12437                       (pc)))]
12438 {
12439   PUT_MODE (operands[0], VOIDmode);
12440 })
12441   
12442 (define_split 
12443   [(set (pc)
12444         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12445                                       [(reg 17) (const_int 0)])
12446                           (const_int 0))
12447                       (label_ref (match_operand 1 "" ""))
12448                       (pc)))]
12449   ""
12450   [(set (pc)
12451         (if_then_else (match_dup 0)
12452                       (label_ref (match_dup 1))
12453                       (pc)))]
12454 {
12455   rtx new_op0 = copy_rtx (operands[0]);
12456   operands[0] = new_op0;
12457   PUT_MODE (new_op0, VOIDmode);
12458   PUT_CODE (new_op0, REVERSE_CONDITION (GET_CODE (new_op0),
12459                                         GET_MODE (XEXP (new_op0, 0))));
12460
12461   /* Make sure that (a) the CCmode we have for the flags is strong
12462      enough for the reversed compare or (b) we have a valid FP compare.  */
12463   if (! ix86_comparison_operator (new_op0, VOIDmode))
12464     FAIL;
12465 })
12466
12467 ;; Define combination compare-and-branch fp compare instructions to use
12468 ;; during early optimization.  Splitting the operation apart early makes
12469 ;; for bad code when we want to reverse the operation.
12470
12471 (define_insn "*fp_jcc_1"
12472   [(set (pc)
12473         (if_then_else (match_operator 0 "comparison_operator"
12474                         [(match_operand 1 "register_operand" "f")
12475                          (match_operand 2 "register_operand" "f")])
12476           (label_ref (match_operand 3 "" ""))
12477           (pc)))
12478    (clobber (reg:CCFP 18))
12479    (clobber (reg:CCFP 17))]
12480   "TARGET_CMOVE && TARGET_80387
12481    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12482    && FLOAT_MODE_P (GET_MODE (operands[1]))
12483    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12484    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12485   "#")
12486
12487 (define_insn "*fp_jcc_1_sse"
12488   [(set (pc)
12489         (if_then_else (match_operator 0 "comparison_operator"
12490                         [(match_operand 1 "register_operand" "f#x,x#f")
12491                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12492           (label_ref (match_operand 3 "" ""))
12493           (pc)))
12494    (clobber (reg:CCFP 18))
12495    (clobber (reg:CCFP 17))]
12496   "TARGET_80387
12497    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12498    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12499    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12500   "#")
12501
12502 (define_insn "*fp_jcc_1_sse_only"
12503   [(set (pc)
12504         (if_then_else (match_operator 0 "comparison_operator"
12505                         [(match_operand 1 "register_operand" "x")
12506                          (match_operand 2 "nonimmediate_operand" "xm")])
12507           (label_ref (match_operand 3 "" ""))
12508           (pc)))
12509    (clobber (reg:CCFP 18))
12510    (clobber (reg:CCFP 17))]
12511   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12512    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12513    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12514   "#")
12515
12516 (define_insn "*fp_jcc_2"
12517   [(set (pc)
12518         (if_then_else (match_operator 0 "comparison_operator"
12519                         [(match_operand 1 "register_operand" "f")
12520                          (match_operand 2 "register_operand" "f")])
12521           (pc)
12522           (label_ref (match_operand 3 "" ""))))
12523    (clobber (reg:CCFP 18))
12524    (clobber (reg:CCFP 17))]
12525   "TARGET_CMOVE && TARGET_80387
12526    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12527    && FLOAT_MODE_P (GET_MODE (operands[1]))
12528    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12529    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12530   "#")
12531
12532 (define_insn "*fp_jcc_2_sse"
12533   [(set (pc)
12534         (if_then_else (match_operator 0 "comparison_operator"
12535                         [(match_operand 1 "register_operand" "f#x,x#f")
12536                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12537           (pc)
12538           (label_ref (match_operand 3 "" ""))))
12539    (clobber (reg:CCFP 18))
12540    (clobber (reg:CCFP 17))]
12541   "TARGET_80387
12542    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12543    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12544    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12545   "#")
12546
12547 (define_insn "*fp_jcc_2_sse_only"
12548   [(set (pc)
12549         (if_then_else (match_operator 0 "comparison_operator"
12550                         [(match_operand 1 "register_operand" "x")
12551                          (match_operand 2 "nonimmediate_operand" "xm")])
12552           (pc)
12553           (label_ref (match_operand 3 "" ""))))
12554    (clobber (reg:CCFP 18))
12555    (clobber (reg:CCFP 17))]
12556   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12557    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12558    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12559   "#")
12560
12561 (define_insn "*fp_jcc_3"
12562   [(set (pc)
12563         (if_then_else (match_operator 0 "comparison_operator"
12564                         [(match_operand 1 "register_operand" "f")
12565                          (match_operand 2 "nonimmediate_operand" "fm")])
12566           (label_ref (match_operand 3 "" ""))
12567           (pc)))
12568    (clobber (reg:CCFP 18))
12569    (clobber (reg:CCFP 17))
12570    (clobber (match_scratch:HI 4 "=a"))]
12571   "TARGET_80387
12572    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12573    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12574    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12575    && SELECT_CC_MODE (GET_CODE (operands[0]),
12576                       operands[1], operands[2]) == CCFPmode
12577    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12578   "#")
12579
12580 (define_insn "*fp_jcc_4"
12581   [(set (pc)
12582         (if_then_else (match_operator 0 "comparison_operator"
12583                         [(match_operand 1 "register_operand" "f")
12584                          (match_operand 2 "nonimmediate_operand" "fm")])
12585           (pc)
12586           (label_ref (match_operand 3 "" ""))))
12587    (clobber (reg:CCFP 18))
12588    (clobber (reg:CCFP 17))
12589    (clobber (match_scratch:HI 4 "=a"))]
12590   "TARGET_80387
12591    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12592    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12593    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12594    && SELECT_CC_MODE (GET_CODE (operands[0]),
12595                       operands[1], operands[2]) == CCFPmode
12596    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12597   "#")
12598
12599 (define_insn "*fp_jcc_5"
12600   [(set (pc)
12601         (if_then_else (match_operator 0 "comparison_operator"
12602                         [(match_operand 1 "register_operand" "f")
12603                          (match_operand 2 "register_operand" "f")])
12604           (label_ref (match_operand 3 "" ""))
12605           (pc)))
12606    (clobber (reg:CCFP 18))
12607    (clobber (reg:CCFP 17))
12608    (clobber (match_scratch:HI 4 "=a"))]
12609   "TARGET_80387
12610    && FLOAT_MODE_P (GET_MODE (operands[1]))
12611    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12612    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12613   "#")
12614
12615 (define_insn "*fp_jcc_6"
12616   [(set (pc)
12617         (if_then_else (match_operator 0 "comparison_operator"
12618                         [(match_operand 1 "register_operand" "f")
12619                          (match_operand 2 "register_operand" "f")])
12620           (pc)
12621           (label_ref (match_operand 3 "" ""))))
12622    (clobber (reg:CCFP 18))
12623    (clobber (reg:CCFP 17))
12624    (clobber (match_scratch:HI 4 "=a"))]
12625   "TARGET_80387
12626    && FLOAT_MODE_P (GET_MODE (operands[1]))
12627    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12628    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12629   "#")
12630
12631 (define_split
12632   [(set (pc)
12633         (if_then_else (match_operator 0 "comparison_operator"
12634                         [(match_operand 1 "register_operand" "")
12635                          (match_operand 2 "nonimmediate_operand" "")])
12636           (match_operand 3 "" "")
12637           (match_operand 4 "" "")))
12638    (clobber (reg:CCFP 18))
12639    (clobber (reg:CCFP 17))]
12640   "reload_completed"
12641   [(const_int 0)]
12642 {
12643   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
12644                         operands[3], operands[4], NULL_RTX);
12645   DONE;
12646 })
12647
12648 (define_split
12649   [(set (pc)
12650         (if_then_else (match_operator 0 "comparison_operator"
12651                         [(match_operand 1 "register_operand" "")
12652                          (match_operand 2 "nonimmediate_operand" "")])
12653           (match_operand 3 "" "")
12654           (match_operand 4 "" "")))
12655    (clobber (reg:CCFP 18))
12656    (clobber (reg:CCFP 17))
12657    (clobber (match_scratch:HI 5 "=a"))]
12658   "reload_completed"
12659   [(set (pc)
12660         (if_then_else (match_dup 6)
12661           (match_dup 3)
12662           (match_dup 4)))]
12663 {
12664   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
12665                         operands[3], operands[4], operands[5]);
12666   DONE;
12667 })
12668 \f
12669 ;; Unconditional and other jump instructions
12670
12671 (define_insn "jump"
12672   [(set (pc)
12673         (label_ref (match_operand 0 "" "")))]
12674   ""
12675   "jmp\t%l0"
12676   [(set_attr "type" "ibr")])
12677
12678 (define_expand "indirect_jump"
12679   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
12680   ""
12681   "")
12682
12683 (define_insn "*indirect_jump"
12684   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
12685   "!TARGET_64BIT"
12686   "jmp\t%A0"
12687   [(set_attr "type" "ibr")
12688    (set_attr "length_immediate" "0")])
12689
12690 (define_insn "*indirect_jump_rtx64"
12691   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
12692   "TARGET_64BIT"
12693   "jmp\t%A0"
12694   [(set_attr "type" "ibr")
12695    (set_attr "length_immediate" "0")])
12696
12697 (define_expand "tablejump"
12698   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
12699               (use (label_ref (match_operand 1 "" "")))])]
12700   ""
12701 {
12702   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
12703      relative.  Convert the relative address to an absolute address.  */
12704   if (flag_pic)
12705     {
12706       rtx op0, op1;
12707       enum rtx_code code;
12708
12709       if (TARGET_64BIT)
12710         {
12711           code = PLUS;
12712           op0 = operands[0];
12713           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
12714         }
12715       else if (HAVE_AS_GOTOFF_IN_DATA)
12716         {
12717           code = PLUS;
12718           op0 = operands[0];
12719           op1 = pic_offset_table_rtx;
12720         }
12721       else
12722         {
12723           code = MINUS;
12724           op0 = pic_offset_table_rtx;
12725           op1 = operands[0];
12726         }
12727
12728       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 1,
12729                                          OPTAB_DIRECT);
12730     }
12731 })
12732
12733 (define_insn "*tablejump_1"
12734   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
12735    (use (label_ref (match_operand 1 "" "")))]
12736   "!TARGET_64BIT"
12737   "jmp\t%A0"
12738   [(set_attr "type" "ibr")
12739    (set_attr "length_immediate" "0")])
12740
12741 (define_insn "*tablejump_1_rtx64"
12742   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
12743    (use (label_ref (match_operand 1 "" "")))]
12744   "TARGET_64BIT"
12745   "jmp\t%A0"
12746   [(set_attr "type" "ibr")
12747    (set_attr "length_immediate" "0")])
12748 \f
12749 ;; Loop instruction
12750 ;;
12751 ;; This is all complicated by the fact that since this is a jump insn
12752 ;; we must handle our own reloads.
12753
12754 (define_expand "doloop_end"
12755   [(use (match_operand 0 "" ""))        ; loop pseudo
12756    (use (match_operand 1 "" ""))        ; iterations; zero if unknown
12757    (use (match_operand 2 "" ""))        ; max iterations
12758    (use (match_operand 3 "" ""))        ; loop level 
12759    (use (match_operand 4 "" ""))]       ; label
12760   "!TARGET_64BIT && TARGET_USE_LOOP"
12761   "                                 
12762 {
12763   /* Only use cloop on innermost loops.  */
12764   if (INTVAL (operands[3]) > 1)
12765     FAIL;
12766   if (GET_MODE (operands[0]) != SImode)
12767     FAIL;
12768   emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
12769                                            operands[0]));
12770   DONE;
12771 }")
12772
12773 (define_insn "doloop_end_internal"
12774   [(set (pc)
12775         (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
12776                           (const_int 1))
12777                       (label_ref (match_operand 0 "" ""))
12778                       (pc)))
12779    (set (match_operand:SI 2 "register_operand" "=1,1,*m*r")
12780         (plus:SI (match_dup 1)
12781                  (const_int -1)))
12782    (clobber (match_scratch:SI 3 "=X,X,r"))
12783    (clobber (reg:CC 17))]
12784   "!TARGET_64BIT && TARGET_USE_LOOP"
12785 {
12786   if (which_alternative != 0)
12787     return "#";
12788   if (get_attr_length (insn) == 2)
12789     return "%+loop\t%l0";
12790   else
12791     return "dec{l}\t%1\;%+jne\t%l0";
12792 }
12793   [(set_attr "ppro_uops" "many")
12794    (set (attr "type")
12795         (if_then_else (and (eq_attr "alternative" "0")
12796                            (and (ge (minus (match_dup 0) (pc))
12797                                     (const_int -128))
12798                                 (lt (minus (match_dup 0) (pc))
12799                                     (const_int 124))))
12800                       (const_string "ibr")
12801                       (const_string "multi")))])
12802
12803 (define_split
12804   [(set (pc)
12805         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
12806                           (const_int 1))
12807                       (match_operand 0 "" "")
12808                       (pc)))
12809    (set (match_dup 1)
12810         (plus:SI (match_dup 1)
12811                  (const_int -1)))
12812    (clobber (match_scratch:SI 2 ""))
12813    (clobber (reg:CC 17))]
12814   "!TARGET_64BIT && TARGET_USE_LOOP
12815    && reload_completed
12816    && REGNO (operands[1]) != 2"
12817   [(parallel [(set (reg:CCZ 17)
12818                    (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
12819                                  (const_int 0)))
12820               (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
12821    (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
12822                            (match_dup 0)
12823                            (pc)))]
12824   "")
12825   
12826 (define_split
12827   [(set (pc)
12828         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
12829                           (const_int 1))
12830                       (match_operand 0 "" "")
12831                       (pc)))
12832    (set (match_operand:SI 2 "nonimmediate_operand" "")
12833         (plus:SI (match_dup 1)
12834                  (const_int -1)))
12835    (clobber (match_scratch:SI 3 ""))
12836    (clobber (reg:CC 17))]
12837   "!TARGET_64BIT && TARGET_USE_LOOP
12838    && reload_completed
12839    && (! REG_P (operands[2])
12840        || ! rtx_equal_p (operands[1], operands[2]))"
12841   [(set (match_dup 3) (match_dup 1))
12842    (parallel [(set (reg:CCZ 17)
12843                    (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
12844                                 (const_int 0)))
12845               (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
12846    (set (match_dup 2) (match_dup 3))
12847    (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
12848                            (match_dup 0)
12849                            (pc)))]
12850   "")
12851
12852 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
12853
12854 (define_peephole2
12855   [(set (reg 17) (match_operand 0 "" ""))
12856    (set (match_operand:QI 1 "register_operand" "")
12857         (match_operator:QI 2 "ix86_comparison_operator"
12858           [(reg 17) (const_int 0)]))
12859    (set (match_operand 3 "q_regs_operand" "")
12860         (zero_extend (match_dup 1)))]
12861   "(peep2_reg_dead_p (3, operands[1])
12862     || operands_match_p (operands[1], operands[3]))
12863    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
12864   [(set (match_dup 4) (match_dup 0))
12865    (set (strict_low_part (match_dup 5))
12866         (match_dup 2))]
12867 {
12868   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
12869   operands[5] = gen_rtx_REG (QImode, REGNO (operands[3]));
12870   ix86_expand_clear (operands[3]);
12871 })
12872
12873 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
12874
12875 (define_peephole2
12876   [(set (reg 17) (match_operand 0 "" ""))
12877    (set (match_operand:QI 1 "register_operand" "")
12878         (match_operator:QI 2 "ix86_comparison_operator"
12879           [(reg 17) (const_int 0)]))
12880    (parallel [(set (match_operand 3 "q_regs_operand" "")
12881                    (zero_extend (match_dup 1)))
12882               (clobber (reg:CC 17))])]
12883   "(peep2_reg_dead_p (3, operands[1])
12884     || operands_match_p (operands[1], operands[3]))
12885    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
12886   [(set (match_dup 4) (match_dup 0))
12887    (set (strict_low_part (match_dup 5))
12888         (match_dup 2))]
12889 {
12890   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
12891   operands[5] = gen_rtx_REG (QImode, REGNO (operands[3]));
12892   ix86_expand_clear (operands[3]);
12893 })
12894 \f
12895 ;; Call instructions.
12896
12897 ;; The predicates normally associated with named expanders are not properly
12898 ;; checked for calls.  This is a bug in the generic code, but it isn't that
12899 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
12900
12901 ;; Call subroutine returning no value.
12902
12903 (define_expand "call_pop"
12904   [(parallel [(call (match_operand:QI 0 "" "")
12905                     (match_operand:SI 1 "" ""))
12906               (set (reg:SI 7)
12907                    (plus:SI (reg:SI 7)
12908                             (match_operand:SI 3 "" "")))])]
12909   "!TARGET_64BIT"
12910 {
12911   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3]);
12912   DONE;
12913 })
12914
12915 (define_insn "*call_pop_0"
12916   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
12917          (match_operand:SI 1 "" ""))
12918    (set (reg:SI 7) (plus:SI (reg:SI 7)
12919                             (match_operand:SI 2 "immediate_operand" "")))]
12920   "!TARGET_64BIT"
12921 {
12922   if (SIBLING_CALL_P (insn))
12923     return "jmp\t%P0";
12924   else
12925     return "call\t%P0";
12926 }
12927   [(set_attr "type" "call")])
12928   
12929 (define_insn "*call_pop_1"
12930   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
12931          (match_operand:SI 1 "" ""))
12932    (set (reg:SI 7) (plus:SI (reg:SI 7)
12933                             (match_operand:SI 2 "immediate_operand" "i")))]
12934   "!TARGET_64BIT"
12935 {
12936   if (constant_call_address_operand (operands[0], Pmode))
12937     {
12938       if (SIBLING_CALL_P (insn))
12939         return "jmp\t%P0";
12940       else
12941         return "call\t%P0";
12942     }
12943   if (SIBLING_CALL_P (insn))
12944     return "jmp\t%A0";
12945   else
12946     return "call\t%A0";
12947 }
12948   [(set_attr "type" "call")])
12949
12950 (define_expand "call"
12951   [(call (match_operand:QI 0 "" "")
12952          (match_operand 1 "" ""))
12953    (use (match_operand 2 "" ""))]
12954   ""
12955 {
12956   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL);
12957   DONE;
12958 })
12959
12960 (define_insn "*call_0"
12961   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
12962          (match_operand 1 "" ""))]
12963   ""
12964 {
12965   if (SIBLING_CALL_P (insn))
12966     return "jmp\t%P0";
12967   else
12968     return "call\t%P0";
12969 }
12970   [(set_attr "type" "call")])
12971
12972 (define_insn "*call_1"
12973   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
12974          (match_operand 1 "" ""))]
12975   "!TARGET_64BIT"
12976 {
12977   if (constant_call_address_operand (operands[0], QImode))
12978     {
12979       if (SIBLING_CALL_P (insn))
12980         return "jmp\t%P0";
12981       else
12982         return "call\t%P0";
12983     }
12984   if (SIBLING_CALL_P (insn))
12985     return "jmp\t%A0";
12986   else
12987     return "call\t%A0";
12988 }
12989   [(set_attr "type" "call")])
12990
12991 (define_insn "*call_1_rex64"
12992   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
12993          (match_operand 1 "" ""))]
12994   "TARGET_64BIT"
12995 {
12996   if (constant_call_address_operand (operands[0], QImode))
12997     {
12998       if (SIBLING_CALL_P (insn))
12999         return "jmp\t%P0";
13000       else
13001         return "call\t%P0";
13002     }
13003   if (SIBLING_CALL_P (insn))
13004     return "jmp\t%A0";
13005   else
13006     return "call\t%A0";
13007 }
13008   [(set_attr "type" "call")])
13009
13010 ;; Call subroutine, returning value in operand 0
13011
13012 (define_expand "call_value_pop"
13013   [(parallel [(set (match_operand 0 "" "")
13014                    (call (match_operand:QI 1 "" "")
13015                          (match_operand:SI 2 "" "")))
13016               (set (reg:SI 7)
13017                    (plus:SI (reg:SI 7)
13018                             (match_operand:SI 4 "" "")))])]
13019   "!TARGET_64BIT"
13020 {
13021   ix86_expand_call (operands[0], operands[1], operands[2],
13022                     operands[3], operands[4]);
13023   DONE;
13024 })
13025
13026 (define_expand "call_value"
13027   [(set (match_operand 0 "" "")
13028         (call (match_operand:QI 1 "" "")
13029               (match_operand:SI 2 "" "")))
13030    (use (match_operand:SI 3 "" ""))]
13031   ;; Operand 2 not used on the i386.
13032   ""
13033 {
13034   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL);
13035   DONE;
13036 })
13037
13038 ;; Call subroutine returning any type.
13039
13040 (define_expand "untyped_call"
13041   [(parallel [(call (match_operand 0 "" "")
13042                     (const_int 0))
13043               (match_operand 1 "" "")
13044               (match_operand 2 "" "")])]
13045   ""
13046 {
13047   int i;
13048
13049   /* In order to give reg-stack an easier job in validating two
13050      coprocessor registers as containing a possible return value,
13051      simply pretend the untyped call returns a complex long double
13052      value.  */
13053
13054   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13055                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13056                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13057                     NULL);
13058
13059   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13060     {
13061       rtx set = XVECEXP (operands[2], 0, i);
13062       emit_move_insn (SET_DEST (set), SET_SRC (set));
13063     }
13064
13065   /* The optimizer does not know that the call sets the function value
13066      registers we stored in the result block.  We avoid problems by
13067      claiming that all hard registers are used and clobbered at this
13068      point.  */
13069   emit_insn (gen_blockage (const0_rtx));
13070
13071   DONE;
13072 })
13073 \f
13074 ;; Prologue and epilogue instructions
13075
13076 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13077 ;; all of memory.  This blocks insns from being moved across this point.
13078
13079 (define_insn "blockage"
13080   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13081   ""
13082   ""
13083   [(set_attr "length" "0")])
13084
13085 ;; Insn emitted into the body of a function to return from a function.
13086 ;; This is only done if the function's epilogue is known to be simple.
13087 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13088
13089 (define_expand "return"
13090   [(return)]
13091   "ix86_can_use_return_insn_p ()"
13092 {
13093   if (current_function_pops_args)
13094     {
13095       rtx popc = GEN_INT (current_function_pops_args);
13096       emit_jump_insn (gen_return_pop_internal (popc));
13097       DONE;
13098     }
13099 })
13100
13101 (define_insn "return_internal"
13102   [(return)]
13103   "reload_completed"
13104   "ret"
13105   [(set_attr "length" "1")
13106    (set_attr "length_immediate" "0")
13107    (set_attr "modrm" "0")])
13108
13109 (define_insn "return_pop_internal"
13110   [(return)
13111    (use (match_operand:SI 0 "const_int_operand" ""))]
13112   "reload_completed"
13113   "ret\t%0"
13114   [(set_attr "length" "3")
13115    (set_attr "length_immediate" "2")
13116    (set_attr "modrm" "0")])
13117
13118 (define_insn "return_indirect_internal"
13119   [(return)
13120    (use (match_operand:SI 0 "register_operand" "r"))]
13121   "reload_completed"
13122   "jmp\t%A0"
13123   [(set_attr "type" "ibr")
13124    (set_attr "length_immediate" "0")])
13125
13126 (define_insn "nop"
13127   [(const_int 0)]
13128   ""
13129   "nop"
13130   [(set_attr "length" "1")
13131    (set_attr "length_immediate" "0")
13132    (set_attr "modrm" "0")
13133    (set_attr "ppro_uops" "one")])
13134
13135 (define_expand "prologue"
13136   [(const_int 1)]
13137   ""
13138   "ix86_expand_prologue (); DONE;")
13139
13140 (define_insn "set_got"
13141   [(set (match_operand:SI 0 "register_operand" "=r")
13142         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13143    (clobber (reg:CC 17))]
13144   "!TARGET_64BIT"
13145   { return output_set_got (operands[0]); }
13146   [(set_attr "type" "multi")
13147    (set_attr "length" "12")])
13148
13149 (define_expand "epilogue"
13150   [(const_int 1)]
13151   ""
13152   "ix86_expand_epilogue (1); DONE;")
13153
13154 (define_expand "sibcall_epilogue"
13155   [(const_int 1)]
13156   ""
13157   "ix86_expand_epilogue (0); DONE;")
13158
13159 (define_expand "eh_return"
13160   [(use (match_operand 0 "register_operand" ""))
13161    (use (match_operand 1 "register_operand" ""))]
13162   ""
13163 {
13164   rtx tmp, sa = operands[0], ra = operands[1];
13165
13166   /* Tricky bit: we write the address of the handler to which we will
13167      be returning into someone else's stack frame, one word below the
13168      stack address we wish to restore.  */
13169   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13170   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13171   tmp = gen_rtx_MEM (Pmode, tmp);
13172   emit_move_insn (tmp, ra);
13173
13174   if (Pmode == SImode)
13175     emit_insn (gen_eh_return_si (sa));
13176   else
13177     emit_insn (gen_eh_return_di (sa));
13178   emit_barrier ();
13179   DONE;
13180 })
13181
13182 (define_insn_and_split "eh_return_si"
13183   [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")]
13184                     UNSPECV_EH_RETURN)]
13185   "!TARGET_64BIT"
13186   "#"
13187   "reload_completed"
13188   [(const_int 1)]
13189   "ix86_expand_epilogue (2); DONE;")
13190
13191 (define_insn_and_split "eh_return_di"
13192   [(unspec_volatile [(match_operand:DI 0 "register_operand" "c")]
13193                     UNSPECV_EH_RETURN)]
13194   "TARGET_64BIT"
13195   "#"
13196   "reload_completed"
13197   [(const_int 1)]
13198   "ix86_expand_epilogue (2); DONE;")
13199
13200 (define_insn "leave"
13201   [(set (reg:SI 7) (plus:SI (reg:SI 6) (const_int 4)))
13202    (set (reg:SI 6) (mem:SI (reg:SI 6)))
13203    (clobber (mem:BLK (scratch)))]
13204   "!TARGET_64BIT"
13205   "leave"
13206   [(set_attr "length_immediate" "0")
13207    (set_attr "length" "1")
13208    (set_attr "modrm" "0")
13209    (set_attr "modrm" "0")
13210    (set_attr "athlon_decode" "vector")
13211    (set_attr "ppro_uops" "few")])
13212
13213 (define_insn "leave_rex64"
13214   [(set (reg:DI 7) (plus:DI (reg:DI 6) (const_int 8)))
13215    (set (reg:DI 6) (mem:DI (reg:DI 6)))
13216    (clobber (mem:BLK (scratch)))]
13217   "TARGET_64BIT"
13218   "leave"
13219   [(set_attr "length_immediate" "0")
13220    (set_attr "length" "1")
13221    (set_attr "modrm" "0")
13222    (set_attr "modrm" "0")
13223    (set_attr "athlon_decode" "vector")
13224    (set_attr "ppro_uops" "few")])
13225 \f
13226 (define_expand "ffssi2"
13227   [(set (match_operand:SI 0 "nonimmediate_operand" "") 
13228         (ffs:SI (match_operand:SI 1 "general_operand" "")))]
13229   ""
13230 {
13231   rtx out = gen_reg_rtx (SImode), tmp = gen_reg_rtx (SImode);
13232   rtx in = operands[1];
13233
13234   if (TARGET_CMOVE)
13235     {
13236       emit_move_insn (tmp, constm1_rtx);
13237       emit_insn (gen_ffssi_1 (out, in));
13238       emit_insn (gen_rtx_SET (VOIDmode, out,
13239                   gen_rtx_IF_THEN_ELSE (SImode, 
13240                     gen_rtx_EQ (VOIDmode, gen_rtx_REG (CCZmode, FLAGS_REG),
13241                                 const0_rtx),
13242                     tmp,
13243                     out)));
13244       emit_insn (gen_addsi3 (out, out, const1_rtx));
13245       emit_move_insn (operands[0], out);
13246     }
13247
13248   /* Pentium bsf instruction is extremly slow.  The following code is
13249      recommended by the Intel Optimizing Manual as a reasonable replacement:
13250            TEST    EAX,EAX
13251            JZ      SHORT BS2
13252            XOR     ECX,ECX
13253            MOV     DWORD PTR [TEMP+4],ECX
13254            SUB     ECX,EAX
13255            AND     EAX,ECX
13256            MOV     DWORD PTR [TEMP],EAX
13257            FILD    QWORD PTR [TEMP]
13258            FSTP    QWORD PTR [TEMP]
13259            WAIT    ; WAIT only needed for compatibility with
13260                    ; earlier processors
13261            MOV     ECX, DWORD PTR [TEMP+4]
13262            SHR     ECX,20
13263            SUB     ECX,3FFH
13264            TEST    EAX,EAX       ; clear zero flag
13265        BS2:
13266      Following piece of code expand ffs to similar beast.
13267        */
13268
13269   else if (TARGET_PENTIUM && !optimize_size && TARGET_80387)
13270     {
13271       rtx label = gen_label_rtx ();
13272       rtx lo, hi;
13273       rtx mem = assign_386_stack_local (DImode, 0);
13274       rtx fptmp = gen_reg_rtx (DFmode);
13275       split_di (&mem, 1, &lo, &hi);
13276
13277       emit_move_insn (out, const0_rtx);
13278
13279       emit_cmp_and_jump_insns (in, const0_rtx, EQ, 0, SImode, 1, label);
13280
13281       emit_move_insn (hi, out);
13282       emit_insn (gen_subsi3 (out, out, in));
13283       emit_insn (gen_andsi3 (out, out, in));
13284       emit_move_insn (lo, out);
13285       emit_insn (gen_floatdidf2 (fptmp,mem));
13286       emit_move_insn (gen_rtx_MEM (DFmode, XEXP (mem, 0)), fptmp);
13287       emit_move_insn (out, hi);
13288       emit_insn (gen_lshrsi3 (out, out, GEN_INT (20)));
13289       emit_insn (gen_subsi3 (out, out, GEN_INT (0x3ff - 1)));
13290
13291       emit_label (label);
13292       LABEL_NUSES (label) = 1;
13293
13294       emit_move_insn (operands[0], out);
13295     }
13296   else
13297     {
13298       emit_move_insn (tmp, const0_rtx);
13299       emit_insn (gen_ffssi_1 (out, in));
13300       emit_insn (gen_rtx_SET (VOIDmode, 
13301                   gen_rtx_STRICT_LOW_PART (VOIDmode, gen_lowpart (QImode, tmp)),
13302                   gen_rtx_EQ (QImode, gen_rtx_REG (CCZmode, FLAGS_REG),
13303                               const0_rtx)));
13304       emit_insn (gen_negsi2 (tmp, tmp));
13305       emit_insn (gen_iorsi3 (out, out, tmp));
13306       emit_insn (gen_addsi3 (out, out, const1_rtx));
13307       emit_move_insn (operands[0], out);
13308     }
13309   DONE;  
13310 })
13311
13312 (define_insn "ffssi_1"
13313   [(set (reg:CCZ 17)
13314         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13315                      (const_int 0)))
13316    (set (match_operand:SI 0 "register_operand" "=r")
13317         (unspec:SI [(match_dup 1)] UNSPEC_BSF))]
13318   ""
13319   "bsf{l}\t{%1, %0|%0, %1}"
13320   [(set_attr "prefix_0f" "1")
13321    (set_attr "ppro_uops" "few")])
13322
13323 ;; ffshi2 is not useful -- 4 word prefix ops are needed, which is larger
13324 ;; and slower than the two-byte movzx insn needed to do the work in SImode.
13325 \f
13326 ;; Thread-local storage patterns for ELF.
13327 ;;
13328 ;; Note that these code sequences must appear exactly as shown
13329 ;; in order to allow linker relaxation.
13330
13331 (define_insn "*tls_global_dynamic_gnu"
13332   [(set (match_operand:SI 0 "register_operand" "=a")
13333         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13334                     (match_operand:SI 2 "tls_symbolic_operand" "")
13335                     (match_operand:SI 3 "call_insn_operand" "")]
13336                     UNSPEC_TLS_GD))
13337    (clobber (match_scratch:SI 4 "=d"))
13338    (clobber (match_scratch:SI 5 "=c"))
13339    (clobber (reg:CC 17))]
13340   "TARGET_GNU_TLS"
13341   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
13342   [(set_attr "type" "multi")
13343    (set_attr "length" "12")])
13344
13345 (define_insn "*tls_global_dynamic_sun"
13346   [(set (match_operand:SI 0 "register_operand" "=a")
13347         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13348                     (match_operand:SI 2 "tls_symbolic_operand" "")
13349                     (match_operand:SI 3 "call_insn_operand" "")]
13350                     UNSPEC_TLS_GD))
13351    (clobber (match_scratch:SI 4 "=d"))
13352    (clobber (match_scratch:SI 5 "=c"))
13353    (clobber (reg:CC 17))]
13354   "TARGET_SUN_TLS"
13355   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
13356         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
13357   [(set_attr "type" "multi")
13358    (set_attr "length" "14")])
13359
13360 (define_expand "tls_global_dynamic"
13361   [(parallel [(set (match_operand:SI 0 "register_operand" "")
13362                    (unspec:SI
13363                     [(match_dup 2)
13364                      (match_operand:SI 1 "tls_symbolic_operand" "")
13365                      (match_dup 3)]
13366                     UNSPEC_TLS_GD))
13367               (clobber (match_scratch:SI 4 ""))
13368               (clobber (match_scratch:SI 5 ""))
13369               (clobber (reg:CC 17))])]
13370   ""
13371 {
13372   if (!flag_pic)
13373     abort ();
13374   operands[2] = pic_offset_table_rtx;
13375   operands[3] = ix86_tls_get_addr ();
13376 })
13377
13378 (define_insn "*tls_local_dynamic_base_gnu"
13379   [(set (match_operand:SI 0 "register_operand" "=a")
13380         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13381                     (match_operand:SI 2 "call_insn_operand" "")]
13382                    UNSPEC_TLS_LD_BASE))
13383    (clobber (match_scratch:SI 3 "=d"))
13384    (clobber (match_scratch:SI 4 "=c"))
13385    (clobber (reg:CC 17))]
13386   "TARGET_GNU_TLS"
13387   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
13388   [(set_attr "type" "multi")
13389    (set_attr "length" "11")])
13390
13391 (define_insn "*tls_local_dynamic_base_sun"
13392   [(set (match_operand:SI 0 "register_operand" "=a")
13393         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13394                     (match_operand:SI 2 "call_insn_operand" "")]
13395                    UNSPEC_TLS_LD_BASE))
13396    (clobber (match_scratch:SI 3 "=d"))
13397    (clobber (match_scratch:SI 4 "=c"))
13398    (clobber (reg:CC 17))]
13399   "TARGET_SUN_TLS"
13400   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
13401         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
13402   [(set_attr "type" "multi")
13403    (set_attr "length" "13")])
13404
13405 (define_expand "tls_local_dynamic_base"
13406   [(parallel [(set (match_operand:SI 0 "register_operand" "")
13407                    (unspec:SI [(match_dup 1) (match_dup 2)]
13408                               UNSPEC_TLS_LD_BASE))
13409               (clobber (match_scratch:SI 3 ""))
13410               (clobber (match_scratch:SI 4 ""))
13411               (clobber (reg:CC 17))])]
13412   ""
13413 {
13414   if (!flag_pic)
13415     abort ();
13416   operands[1] = pic_offset_table_rtx;
13417   operands[2] = ix86_tls_get_addr ();
13418 })
13419
13420 ;; Local dynamic of a single variable is a lose.  Show combine how
13421 ;; to convert that back to global dynamic.
13422
13423 (define_insn_and_split "*tls_local_dynamic_once"
13424   [(set (match_operand:SI 0 "register_operand" "=a")
13425         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13426                              (match_operand:SI 2 "call_insn_operand" "")]
13427                             UNSPEC_TLS_LD_BASE)
13428                  (const:SI (unspec:SI
13429                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
13430                             UNSPEC_DTPOFF))))
13431    (clobber (match_scratch:SI 4 "=d"))
13432    (clobber (match_scratch:SI 5 "=c"))
13433    (clobber (reg:CC 17))]
13434   ""
13435   "#"
13436   ""
13437   [(parallel [(set (match_dup 0)
13438                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
13439                               UNSPEC_TLS_GD))
13440               (clobber (match_dup 4))
13441               (clobber (match_dup 5))
13442               (clobber (reg:CC 17))])]
13443   "")
13444 \f
13445 ;; These patterns match the binary 387 instructions for addM3, subM3,
13446 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
13447 ;; SFmode.  The first is the normal insn, the second the same insn but
13448 ;; with one operand a conversion, and the third the same insn but with
13449 ;; the other operand a conversion.  The conversion may be SFmode or
13450 ;; SImode if the target mode DFmode, but only SImode if the target mode
13451 ;; is SFmode.
13452
13453 ;; Gcc is slightly more smart about handling normal two address instructions
13454 ;; so use special patterns for add and mull.
13455 (define_insn "*fop_sf_comm_nosse"
13456   [(set (match_operand:SF 0 "register_operand" "=f")
13457         (match_operator:SF 3 "binary_fp_operator"
13458                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
13459                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
13460   "TARGET_80387 && !TARGET_SSE_MATH
13461    && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
13462    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13463   "* return output_387_binary_op (insn, operands);"
13464   [(set (attr "type") 
13465         (if_then_else (match_operand:SF 3 "mult_operator" "") 
13466            (const_string "fmul")
13467            (const_string "fop")))
13468    (set_attr "mode" "SF")])
13469
13470 (define_insn "*fop_sf_comm"
13471   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
13472         (match_operator:SF 3 "binary_fp_operator"
13473                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
13474                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
13475   "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
13476    && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
13477    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13478   "* return output_387_binary_op (insn, operands);"
13479   [(set (attr "type") 
13480         (if_then_else (eq_attr "alternative" "1")
13481            (if_then_else (match_operand:SF 3 "mult_operator" "") 
13482               (const_string "ssemul")
13483               (const_string "sseadd"))
13484            (if_then_else (match_operand:SF 3 "mult_operator" "") 
13485               (const_string "fmul")
13486               (const_string "fop"))))
13487    (set_attr "mode" "SF")])
13488
13489 (define_insn "*fop_sf_comm_sse"
13490   [(set (match_operand:SF 0 "register_operand" "=x")
13491         (match_operator:SF 3 "binary_fp_operator"
13492                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
13493                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
13494   "TARGET_SSE_MATH && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
13495    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13496   "* return output_387_binary_op (insn, operands);"
13497   [(set (attr "type") 
13498         (if_then_else (match_operand:SF 3 "mult_operator" "") 
13499            (const_string "ssemul")
13500            (const_string "sseadd")))
13501    (set_attr "mode" "SF")])
13502
13503 (define_insn "*fop_df_comm_nosse"
13504   [(set (match_operand:DF 0 "register_operand" "=f")
13505         (match_operator:DF 3 "binary_fp_operator"
13506                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
13507                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
13508   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
13509    && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
13510    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13511   "* return output_387_binary_op (insn, operands);"
13512   [(set (attr "type") 
13513         (if_then_else (match_operand:SF 3 "mult_operator" "") 
13514            (const_string "fmul")
13515            (const_string "fop")))
13516    (set_attr "mode" "DF")])
13517
13518 (define_insn "*fop_df_comm"
13519   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
13520         (match_operator:DF 3 "binary_fp_operator"
13521                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
13522                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
13523   "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
13524    && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
13525    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13526   "* return output_387_binary_op (insn, operands);"
13527   [(set (attr "type") 
13528         (if_then_else (eq_attr "alternative" "1")
13529            (if_then_else (match_operand:SF 3 "mult_operator" "") 
13530               (const_string "ssemul")
13531               (const_string "sseadd"))
13532            (if_then_else (match_operand:SF 3 "mult_operator" "") 
13533               (const_string "fmul")
13534               (const_string "fop"))))
13535    (set_attr "mode" "DF")])
13536
13537 (define_insn "*fop_df_comm_sse"
13538   [(set (match_operand:DF 0 "register_operand" "=Y")
13539         (match_operator:DF 3 "binary_fp_operator"
13540                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
13541                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
13542   "TARGET_SSE2 && TARGET_SSE_MATH
13543    && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
13544    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13545   "* return output_387_binary_op (insn, operands);"
13546   [(set (attr "type") 
13547         (if_then_else (match_operand:SF 3 "mult_operator" "") 
13548            (const_string "ssemul")
13549            (const_string "sseadd")))
13550    (set_attr "mode" "DF")])
13551
13552 (define_insn "*fop_xf_comm"
13553   [(set (match_operand:XF 0 "register_operand" "=f")
13554         (match_operator:XF 3 "binary_fp_operator"
13555                         [(match_operand:XF 1 "register_operand" "%0")
13556                          (match_operand:XF 2 "register_operand" "f")]))]
13557   "!TARGET_64BIT && TARGET_80387
13558    && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
13559   "* return output_387_binary_op (insn, operands);"
13560   [(set (attr "type") 
13561         (if_then_else (match_operand:XF 3 "mult_operator" "") 
13562            (const_string "fmul")
13563            (const_string "fop")))
13564    (set_attr "mode" "XF")])
13565
13566 (define_insn "*fop_tf_comm"
13567   [(set (match_operand:TF 0 "register_operand" "=f")
13568         (match_operator:TF 3 "binary_fp_operator"
13569                         [(match_operand:TF 1 "register_operand" "%0")
13570                          (match_operand:TF 2 "register_operand" "f")]))]
13571   "TARGET_80387 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
13572   "* return output_387_binary_op (insn, operands);"
13573   [(set (attr "type") 
13574         (if_then_else (match_operand:TF 3 "mult_operator" "") 
13575            (const_string "fmul")
13576            (const_string "fop")))
13577    (set_attr "mode" "XF")])
13578
13579 (define_insn "*fop_sf_1_nosse"
13580   [(set (match_operand:SF 0 "register_operand" "=f,f")
13581         (match_operator:SF 3 "binary_fp_operator"
13582                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
13583                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
13584   "TARGET_80387 && !TARGET_SSE_MATH
13585    && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
13586    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13587   "* return output_387_binary_op (insn, operands);"
13588   [(set (attr "type") 
13589         (cond [(match_operand:SF 3 "mult_operator" "") 
13590                  (const_string "fmul")
13591                (match_operand:SF 3 "div_operator" "") 
13592                  (const_string "fdiv")
13593               ]
13594               (const_string "fop")))
13595    (set_attr "mode" "SF")])
13596
13597 (define_insn "*fop_sf_1"
13598   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
13599         (match_operator:SF 3 "binary_fp_operator"
13600                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
13601                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
13602   "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
13603    && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
13604    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13605   "* return output_387_binary_op (insn, operands);"
13606   [(set (attr "type") 
13607         (cond [(and (eq_attr "alternative" "2")
13608                     (match_operand:SF 3 "mult_operator" ""))
13609                  (const_string "ssemul")
13610                (and (eq_attr "alternative" "2")
13611                     (match_operand:SF 3 "div_operator" ""))
13612                  (const_string "ssediv")
13613                (eq_attr "alternative" "2")
13614                  (const_string "sseadd")
13615                (match_operand:SF 3 "mult_operator" "") 
13616                  (const_string "fmul")
13617                (match_operand:SF 3 "div_operator" "") 
13618                  (const_string "fdiv")
13619               ]
13620               (const_string "fop")))
13621    (set_attr "mode" "SF")])
13622
13623 (define_insn "*fop_sf_1_sse"
13624   [(set (match_operand:SF 0 "register_operand" "=x")
13625         (match_operator:SF 3 "binary_fp_operator"
13626                         [(match_operand:SF 1 "register_operand" "0")
13627                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
13628   "TARGET_SSE_MATH
13629    && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
13630   "* return output_387_binary_op (insn, operands);"
13631   [(set (attr "type") 
13632         (cond [(match_operand:SF 3 "mult_operator" "")
13633                  (const_string "ssemul")
13634                (match_operand:SF 3 "div_operator" "")
13635                  (const_string "ssediv")
13636               ]
13637               (const_string "sseadd")))
13638    (set_attr "mode" "SF")])
13639
13640 ;; ??? Add SSE splitters for these!
13641 (define_insn "*fop_sf_2"
13642   [(set (match_operand:SF 0 "register_operand" "=f,f")
13643         (match_operator:SF 3 "binary_fp_operator"
13644           [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
13645            (match_operand:SF 2 "register_operand" "0,0")]))]
13646   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
13647   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13648   [(set (attr "type") 
13649         (cond [(match_operand:SF 3 "mult_operator" "") 
13650                  (const_string "fmul")
13651                (match_operand:SF 3 "div_operator" "") 
13652                  (const_string "fdiv")
13653               ]
13654               (const_string "fop")))
13655    (set_attr "fp_int_src" "true")
13656    (set_attr "ppro_uops" "many")
13657    (set_attr "mode" "SI")])
13658
13659 (define_insn "*fop_sf_3"
13660   [(set (match_operand:SF 0 "register_operand" "=f,f")
13661         (match_operator:SF 3 "binary_fp_operator"
13662           [(match_operand:SF 1 "register_operand" "0,0")
13663            (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
13664   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
13665   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13666   [(set (attr "type") 
13667         (cond [(match_operand:SF 3 "mult_operator" "") 
13668                  (const_string "fmul")
13669                (match_operand:SF 3 "div_operator" "") 
13670                  (const_string "fdiv")
13671               ]
13672               (const_string "fop")))
13673    (set_attr "fp_int_src" "true")
13674    (set_attr "ppro_uops" "many")
13675    (set_attr "mode" "SI")])
13676
13677 (define_insn "*fop_df_1_nosse"
13678   [(set (match_operand:DF 0 "register_operand" "=f,f")
13679         (match_operator:DF 3 "binary_fp_operator"
13680                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
13681                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
13682   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
13683    && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
13684    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13685   "* return output_387_binary_op (insn, operands);"
13686   [(set (attr "type") 
13687         (cond [(match_operand:DF 3 "mult_operator" "") 
13688                  (const_string "fmul")
13689                (match_operand:DF 3 "div_operator" "")
13690                  (const_string "fdiv")
13691               ]
13692               (const_string "fop")))
13693    (set_attr "mode" "DF")])
13694
13695
13696 (define_insn "*fop_df_1"
13697   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
13698         (match_operator:DF 3 "binary_fp_operator"
13699                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
13700                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
13701   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
13702    && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
13703    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13704   "* return output_387_binary_op (insn, operands);"
13705   [(set (attr "type") 
13706         (cond [(and (eq_attr "alternative" "2")
13707                     (match_operand:SF 3 "mult_operator" ""))
13708                  (const_string "ssemul")
13709                (and (eq_attr "alternative" "2")
13710                     (match_operand:SF 3 "div_operator" ""))
13711                  (const_string "ssediv")
13712                (eq_attr "alternative" "2")
13713                  (const_string "sseadd")
13714                (match_operand:DF 3 "mult_operator" "") 
13715                  (const_string "fmul")
13716                (match_operand:DF 3 "div_operator" "") 
13717                  (const_string "fdiv")
13718               ]
13719               (const_string "fop")))
13720    (set_attr "mode" "DF")])
13721
13722 (define_insn "*fop_df_1_sse"
13723   [(set (match_operand:DF 0 "register_operand" "=Y")
13724         (match_operator:DF 3 "binary_fp_operator"
13725                         [(match_operand:DF 1 "register_operand" "0")
13726                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
13727   "TARGET_SSE2 && TARGET_SSE_MATH
13728    && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
13729   "* return output_387_binary_op (insn, operands);"
13730   [(set_attr "mode" "DF")
13731    (set (attr "type") 
13732         (cond [(match_operand:SF 3 "mult_operator" "")
13733                  (const_string "ssemul")
13734                (match_operand:SF 3 "div_operator" "")
13735                  (const_string "ssediv")
13736               ]
13737               (const_string "sseadd")))])
13738
13739 ;; ??? Add SSE splitters for these!
13740 (define_insn "*fop_df_2"
13741   [(set (match_operand:DF 0 "register_operand" "=f,f")
13742         (match_operator:DF 3 "binary_fp_operator"
13743            [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
13744             (match_operand:DF 2 "register_operand" "0,0")]))]
13745   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13746   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13747   [(set (attr "type") 
13748         (cond [(match_operand:DF 3 "mult_operator" "") 
13749                  (const_string "fmul")
13750                (match_operand:DF 3 "div_operator" "") 
13751                  (const_string "fdiv")
13752               ]
13753               (const_string "fop")))
13754    (set_attr "fp_int_src" "true")
13755    (set_attr "ppro_uops" "many")
13756    (set_attr "mode" "SI")])
13757
13758 (define_insn "*fop_df_3"
13759   [(set (match_operand:DF 0 "register_operand" "=f,f")
13760         (match_operator:DF 3 "binary_fp_operator"
13761            [(match_operand:DF 1 "register_operand" "0,0")
13762             (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
13763   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13764   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13765   [(set (attr "type") 
13766         (cond [(match_operand:DF 3 "mult_operator" "") 
13767                  (const_string "fmul")
13768                (match_operand:DF 3 "div_operator" "") 
13769                  (const_string "fdiv")
13770               ]
13771               (const_string "fop")))
13772    (set_attr "fp_int_src" "true")
13773    (set_attr "ppro_uops" "many")
13774    (set_attr "mode" "SI")])
13775
13776 (define_insn "*fop_df_4"
13777   [(set (match_operand:DF 0 "register_operand" "=f,f")
13778         (match_operator:DF 3 "binary_fp_operator"
13779            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13780             (match_operand:DF 2 "register_operand" "0,f")]))]
13781   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
13782    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13783   "* return output_387_binary_op (insn, operands);"
13784   [(set (attr "type") 
13785         (cond [(match_operand:DF 3 "mult_operator" "") 
13786                  (const_string "fmul")
13787                (match_operand:DF 3 "div_operator" "") 
13788                  (const_string "fdiv")
13789               ]
13790               (const_string "fop")))
13791    (set_attr "mode" "SF")])
13792
13793 (define_insn "*fop_df_5"
13794   [(set (match_operand:DF 0 "register_operand" "=f,f")
13795         (match_operator:DF 3 "binary_fp_operator"
13796           [(match_operand:DF 1 "register_operand" "0,f")
13797            (float_extend:DF
13798             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13799   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13800   "* return output_387_binary_op (insn, operands);"
13801   [(set (attr "type") 
13802         (cond [(match_operand:DF 3 "mult_operator" "") 
13803                  (const_string "fmul")
13804                (match_operand:DF 3 "div_operator" "") 
13805                  (const_string "fdiv")
13806               ]
13807               (const_string "fop")))
13808    (set_attr "mode" "SF")])
13809
13810 (define_insn "*fop_xf_1"
13811   [(set (match_operand:XF 0 "register_operand" "=f,f")
13812         (match_operator:XF 3 "binary_fp_operator"
13813                         [(match_operand:XF 1 "register_operand" "0,f")
13814                          (match_operand:XF 2 "register_operand" "f,0")]))]
13815   "!TARGET_64BIT && TARGET_80387
13816    && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
13817   "* return output_387_binary_op (insn, operands);"
13818   [(set (attr "type") 
13819         (cond [(match_operand:XF 3 "mult_operator" "") 
13820                  (const_string "fmul")
13821                (match_operand:XF 3 "div_operator" "") 
13822                  (const_string "fdiv")
13823               ]
13824               (const_string "fop")))
13825    (set_attr "mode" "XF")])
13826
13827 (define_insn "*fop_tf_1"
13828   [(set (match_operand:TF 0 "register_operand" "=f,f")
13829         (match_operator:TF 3 "binary_fp_operator"
13830                         [(match_operand:TF 1 "register_operand" "0,f")
13831                          (match_operand:TF 2 "register_operand" "f,0")]))]
13832   "TARGET_80387
13833    && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
13834   "* return output_387_binary_op (insn, operands);"
13835   [(set (attr "type") 
13836         (cond [(match_operand:TF 3 "mult_operator" "") 
13837                  (const_string "fmul")
13838                (match_operand:TF 3 "div_operator" "") 
13839                  (const_string "fdiv")
13840               ]
13841               (const_string "fop")))
13842    (set_attr "mode" "XF")])
13843
13844 (define_insn "*fop_xf_2"
13845   [(set (match_operand:XF 0 "register_operand" "=f,f")
13846         (match_operator:XF 3 "binary_fp_operator"
13847            [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
13848             (match_operand:XF 2 "register_operand" "0,0")]))]
13849   "!TARGET_64BIT && TARGET_80387 && TARGET_USE_FIOP"
13850   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13851   [(set (attr "type") 
13852         (cond [(match_operand:XF 3 "mult_operator" "") 
13853                  (const_string "fmul")
13854                (match_operand:XF 3 "div_operator" "") 
13855                  (const_string "fdiv")
13856               ]
13857               (const_string "fop")))
13858    (set_attr "fp_int_src" "true")
13859    (set_attr "mode" "SI")
13860    (set_attr "ppro_uops" "many")])
13861
13862 (define_insn "*fop_tf_2"
13863   [(set (match_operand:TF 0 "register_operand" "=f,f")
13864         (match_operator:TF 3 "binary_fp_operator"
13865            [(float:TF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
13866             (match_operand:TF 2 "register_operand" "0,0")]))]
13867   "TARGET_80387 && TARGET_USE_FIOP"
13868   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13869   [(set (attr "type") 
13870         (cond [(match_operand:TF 3 "mult_operator" "") 
13871                  (const_string "fmul")
13872                (match_operand:TF 3 "div_operator" "") 
13873                  (const_string "fdiv")
13874               ]
13875               (const_string "fop")))
13876    (set_attr "fp_int_src" "true")
13877    (set_attr "mode" "SI")
13878    (set_attr "ppro_uops" "many")])
13879
13880 (define_insn "*fop_xf_3"
13881   [(set (match_operand:XF 0 "register_operand" "=f,f")
13882         (match_operator:XF 3 "binary_fp_operator"
13883           [(match_operand:XF 1 "register_operand" "0,0")
13884            (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
13885   "!TARGET_64BIT && TARGET_80387 && TARGET_USE_FIOP"
13886   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13887   [(set (attr "type") 
13888         (cond [(match_operand:XF 3 "mult_operator" "") 
13889                  (const_string "fmul")
13890                (match_operand:XF 3 "div_operator" "") 
13891                  (const_string "fdiv")
13892               ]
13893               (const_string "fop")))
13894    (set_attr "fp_int_src" "true")
13895    (set_attr "mode" "SI")
13896    (set_attr "ppro_uops" "many")])
13897
13898 (define_insn "*fop_tf_3"
13899   [(set (match_operand:TF 0 "register_operand" "=f,f")
13900         (match_operator:TF 3 "binary_fp_operator"
13901           [(match_operand:TF 1 "register_operand" "0,0")
13902            (float:TF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
13903   "TARGET_80387 && TARGET_USE_FIOP"
13904   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13905   [(set (attr "type") 
13906         (cond [(match_operand:TF 3 "mult_operator" "") 
13907                  (const_string "fmul")
13908                (match_operand:TF 3 "div_operator" "") 
13909                  (const_string "fdiv")
13910               ]
13911               (const_string "fop")))
13912    (set_attr "fp_int_src" "true")
13913    (set_attr "mode" "SI")
13914    (set_attr "ppro_uops" "many")])
13915
13916 (define_insn "*fop_xf_4"
13917   [(set (match_operand:XF 0 "register_operand" "=f,f")
13918         (match_operator:XF 3 "binary_fp_operator"
13919            [(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13920             (match_operand:XF 2 "register_operand" "0,f")]))]
13921   "!TARGET_64BIT && TARGET_80387"
13922   "* return output_387_binary_op (insn, operands);"
13923   [(set (attr "type") 
13924         (cond [(match_operand:XF 3 "mult_operator" "") 
13925                  (const_string "fmul")
13926                (match_operand:XF 3 "div_operator" "") 
13927                  (const_string "fdiv")
13928               ]
13929               (const_string "fop")))
13930    (set_attr "mode" "SF")])
13931
13932 (define_insn "*fop_tf_4"
13933   [(set (match_operand:TF 0 "register_operand" "=f,f")
13934         (match_operator:TF 3 "binary_fp_operator"
13935            [(float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13936             (match_operand:TF 2 "register_operand" "0,f")]))]
13937   "TARGET_80387"
13938   "* return output_387_binary_op (insn, operands);"
13939   [(set (attr "type") 
13940         (cond [(match_operand:TF 3 "mult_operator" "") 
13941                  (const_string "fmul")
13942                (match_operand:TF 3 "div_operator" "") 
13943                  (const_string "fdiv")
13944               ]
13945               (const_string "fop")))
13946    (set_attr "mode" "SF")])
13947
13948 (define_insn "*fop_xf_5"
13949   [(set (match_operand:XF 0 "register_operand" "=f,f")
13950         (match_operator:XF 3 "binary_fp_operator"
13951           [(match_operand:XF 1 "register_operand" "0,f")
13952            (float_extend:XF
13953             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13954   "!TARGET_64BIT && TARGET_80387"
13955   "* return output_387_binary_op (insn, operands);"
13956   [(set (attr "type") 
13957         (cond [(match_operand:XF 3 "mult_operator" "") 
13958                  (const_string "fmul")
13959                (match_operand:XF 3 "div_operator" "") 
13960                  (const_string "fdiv")
13961               ]
13962               (const_string "fop")))
13963    (set_attr "mode" "SF")])
13964
13965 (define_insn "*fop_tf_5"
13966   [(set (match_operand:TF 0 "register_operand" "=f,f")
13967         (match_operator:TF 3 "binary_fp_operator"
13968           [(match_operand:TF 1 "register_operand" "0,f")
13969            (float_extend:TF
13970             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13971   "TARGET_80387"
13972   "* return output_387_binary_op (insn, operands);"
13973   [(set (attr "type") 
13974         (cond [(match_operand:TF 3 "mult_operator" "") 
13975                  (const_string "fmul")
13976                (match_operand:TF 3 "div_operator" "") 
13977                  (const_string "fdiv")
13978               ]
13979               (const_string "fop")))
13980    (set_attr "mode" "SF")])
13981
13982 (define_insn "*fop_xf_6"
13983   [(set (match_operand:XF 0 "register_operand" "=f,f")
13984         (match_operator:XF 3 "binary_fp_operator"
13985            [(float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,0"))
13986             (match_operand:XF 2 "register_operand" "0,f")]))]
13987   "!TARGET_64BIT && TARGET_80387"
13988   "* return output_387_binary_op (insn, operands);"
13989   [(set (attr "type") 
13990         (cond [(match_operand:XF 3 "mult_operator" "") 
13991                  (const_string "fmul")
13992                (match_operand:XF 3 "div_operator" "") 
13993                  (const_string "fdiv")
13994               ]
13995               (const_string "fop")))
13996    (set_attr "mode" "DF")])
13997
13998 (define_insn "*fop_tf_6"
13999   [(set (match_operand:TF 0 "register_operand" "=f,f")
14000         (match_operator:TF 3 "binary_fp_operator"
14001            [(float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "fm,0"))
14002             (match_operand:TF 2 "register_operand" "0,f")]))]
14003   "TARGET_80387"
14004   "* return output_387_binary_op (insn, operands);"
14005   [(set (attr "type") 
14006         (cond [(match_operand:TF 3 "mult_operator" "") 
14007                  (const_string "fmul")
14008                (match_operand:TF 3 "div_operator" "") 
14009                  (const_string "fdiv")
14010               ]
14011               (const_string "fop")))
14012    (set_attr "mode" "DF")])
14013
14014 (define_insn "*fop_xf_7"
14015   [(set (match_operand:XF 0 "register_operand" "=f,f")
14016         (match_operator:XF 3 "binary_fp_operator"
14017           [(match_operand:XF 1 "register_operand" "0,f")
14018            (float_extend:XF
14019             (match_operand:DF 2 "nonimmediate_operand" "fm,0"))]))]
14020   "!TARGET_64BIT && TARGET_80387"
14021   "* return output_387_binary_op (insn, operands);"
14022   [(set (attr "type") 
14023         (cond [(match_operand:XF 3 "mult_operator" "") 
14024                  (const_string "fmul")
14025                (match_operand:XF 3 "div_operator" "") 
14026                  (const_string "fdiv")
14027               ]
14028               (const_string "fop")))
14029    (set_attr "mode" "DF")])
14030
14031 (define_insn "*fop_tf_7"
14032   [(set (match_operand:TF 0 "register_operand" "=f,f")
14033         (match_operator:TF 3 "binary_fp_operator"
14034           [(match_operand:TF 1 "register_operand" "0,f")
14035            (float_extend:TF
14036             (match_operand:DF 2 "nonimmediate_operand" "fm,0"))]))]
14037   "TARGET_80387"
14038   "* return output_387_binary_op (insn, operands);"
14039   [(set (attr "type") 
14040         (cond [(match_operand:TF 3 "mult_operator" "") 
14041                  (const_string "fmul")
14042                (match_operand:TF 3 "div_operator" "") 
14043                  (const_string "fdiv")
14044               ]
14045               (const_string "fop")))
14046    (set_attr "mode" "DF")])
14047
14048 (define_split
14049   [(set (match_operand 0 "register_operand" "")
14050         (match_operator 3 "binary_fp_operator"
14051            [(float (match_operand:SI 1 "register_operand" ""))
14052             (match_operand 2 "register_operand" "")]))]
14053   "TARGET_80387 && reload_completed
14054    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14055   [(const_int 0)]
14056
14057   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14058   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14059   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14060                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14061                                           GET_MODE (operands[3]),
14062                                           operands[4],
14063                                           operands[2])));
14064   ix86_free_from_memory (GET_MODE (operands[1]));
14065   DONE;
14066 })
14067
14068 (define_split
14069   [(set (match_operand 0 "register_operand" "")
14070         (match_operator 3 "binary_fp_operator"
14071            [(match_operand 1 "register_operand" "")
14072             (float (match_operand:SI 2 "register_operand" ""))]))]
14073   "TARGET_80387 && reload_completed
14074    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14075   [(const_int 0)]
14076 {
14077   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14078   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14079   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14080                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14081                                           GET_MODE (operands[3]),
14082                                           operands[1],
14083                                           operands[4])));
14084   ix86_free_from_memory (GET_MODE (operands[2]));
14085   DONE;
14086 })
14087 \f
14088 ;; FPU special functions.
14089
14090 (define_expand "sqrtsf2"
14091   [(set (match_operand:SF 0 "register_operand" "")
14092         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14093   "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE_MATH"
14094 {
14095   if (!TARGET_SSE_MATH)
14096     operands[1] = force_reg (SFmode, operands[1]);
14097 })
14098
14099 (define_insn "sqrtsf2_1"
14100   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14101         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14102   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14103    && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14104   "@
14105    fsqrt
14106    sqrtss\t{%1, %0|%0, %1}"
14107   [(set_attr "type" "fpspc,sse")
14108    (set_attr "mode" "SF,SF")
14109    (set_attr "athlon_decode" "direct,*")])
14110
14111 (define_insn "sqrtsf2_1_sse_only"
14112   [(set (match_operand:SF 0 "register_operand" "=x")
14113         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14114   "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14115   "sqrtss\t{%1, %0|%0, %1}"
14116   [(set_attr "type" "sse")
14117    (set_attr "mode" "SF")
14118    (set_attr "athlon_decode" "*")])
14119
14120 (define_insn "sqrtsf2_i387"
14121   [(set (match_operand:SF 0 "register_operand" "=f")
14122         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14123   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14124    && !TARGET_SSE_MATH"
14125   "fsqrt"
14126   [(set_attr "type" "fpspc")
14127    (set_attr "mode" "SF")
14128    (set_attr "athlon_decode" "direct")])
14129
14130 (define_expand "sqrtdf2"
14131   [(set (match_operand:DF 0 "register_operand" "")
14132         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14133   "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387)
14134    || (TARGET_SSE2 && TARGET_SSE_MATH)"
14135 {
14136   if (!TARGET_SSE2 || !TARGET_SSE_MATH)
14137     operands[1] = force_reg (DFmode, operands[1]);
14138 })
14139
14140 (define_insn "sqrtdf2_1"
14141   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14142         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14143   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14144    && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14145   "@
14146    fsqrt
14147    sqrtsd\t{%1, %0|%0, %1}"
14148   [(set_attr "type" "fpspc,sse")
14149    (set_attr "mode" "DF,DF")
14150    (set_attr "athlon_decode" "direct,*")])
14151
14152 (define_insn "sqrtdf2_1_sse_only"
14153   [(set (match_operand:DF 0 "register_operand" "=Y")
14154         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14155   "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14156   "sqrtsd\t{%1, %0|%0, %1}"
14157   [(set_attr "type" "sse")
14158    (set_attr "mode" "DF")
14159    (set_attr "athlon_decode" "*")])
14160
14161 (define_insn "sqrtdf2_i387"
14162   [(set (match_operand:DF 0 "register_operand" "=f")
14163         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14164   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14165    && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
14166   "fsqrt"
14167   [(set_attr "type" "fpspc")
14168    (set_attr "mode" "DF")
14169    (set_attr "athlon_decode" "direct")])
14170
14171 (define_insn "*sqrtextendsfdf2"
14172   [(set (match_operand:DF 0 "register_operand" "=f")
14173         (sqrt:DF (float_extend:DF
14174                   (match_operand:SF 1 "register_operand" "0"))))]
14175   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14176    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14177   "fsqrt"
14178   [(set_attr "type" "fpspc")
14179    (set_attr "mode" "DF")
14180    (set_attr "athlon_decode" "direct")])
14181
14182 (define_insn "sqrtxf2"
14183   [(set (match_operand:XF 0 "register_operand" "=f")
14184         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14185   "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387 
14186    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14187   "fsqrt"
14188   [(set_attr "type" "fpspc")
14189    (set_attr "mode" "XF")
14190    (set_attr "athlon_decode" "direct")])
14191
14192 (define_insn "sqrttf2"
14193   [(set (match_operand:TF 0 "register_operand" "=f")
14194         (sqrt:TF (match_operand:TF 1 "register_operand" "0")))]
14195   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
14196    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14197   "fsqrt"
14198   [(set_attr "type" "fpspc")
14199    (set_attr "mode" "XF")
14200    (set_attr "athlon_decode" "direct")])
14201
14202 (define_insn "*sqrtextenddfxf2"
14203   [(set (match_operand:XF 0 "register_operand" "=f")
14204         (sqrt:XF (float_extend:XF
14205                   (match_operand:DF 1 "register_operand" "0"))))]
14206   "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14207   "fsqrt"
14208   [(set_attr "type" "fpspc")
14209    (set_attr "mode" "XF")
14210    (set_attr "athlon_decode" "direct")])
14211
14212 (define_insn "*sqrtextenddftf2"
14213   [(set (match_operand:TF 0 "register_operand" "=f")
14214         (sqrt:TF (float_extend:TF
14215                   (match_operand:DF 1 "register_operand" "0"))))]
14216   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
14217   "fsqrt"
14218   [(set_attr "type" "fpspc")
14219    (set_attr "mode" "XF")
14220    (set_attr "athlon_decode" "direct")])
14221
14222 (define_insn "*sqrtextendsfxf2"
14223   [(set (match_operand:XF 0 "register_operand" "=f")
14224         (sqrt:XF (float_extend:XF
14225                   (match_operand:SF 1 "register_operand" "0"))))]
14226   "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14227   "fsqrt"
14228   [(set_attr "type" "fpspc")
14229    (set_attr "mode" "XF")
14230    (set_attr "athlon_decode" "direct")])
14231
14232 (define_insn "*sqrtextendsftf2"
14233   [(set (match_operand:TF 0 "register_operand" "=f")
14234         (sqrt:TF (float_extend:TF
14235                   (match_operand:SF 1 "register_operand" "0"))))]
14236   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
14237   "fsqrt"
14238   [(set_attr "type" "fpspc")
14239    (set_attr "mode" "XF")
14240    (set_attr "athlon_decode" "direct")])
14241
14242 (define_insn "sindf2"
14243   [(set (match_operand:DF 0 "register_operand" "=f")
14244         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
14245   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
14246    && flag_unsafe_math_optimizations"
14247   "fsin"
14248   [(set_attr "type" "fpspc")
14249    (set_attr "mode" "DF")])
14250
14251 (define_insn "sinsf2"
14252   [(set (match_operand:SF 0 "register_operand" "=f")
14253         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
14254   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
14255    && flag_unsafe_math_optimizations"
14256   "fsin"
14257   [(set_attr "type" "fpspc")
14258    (set_attr "mode" "SF")])
14259
14260 (define_insn "*sinextendsfdf2"
14261   [(set (match_operand:DF 0 "register_operand" "=f")
14262         (unspec:DF [(float_extend:DF
14263                      (match_operand:SF 1 "register_operand" "0"))]
14264                    UNSPEC_SIN))]
14265   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
14266    && flag_unsafe_math_optimizations"
14267   "fsin"
14268   [(set_attr "type" "fpspc")
14269    (set_attr "mode" "DF")])
14270
14271 (define_insn "sinxf2"
14272   [(set (match_operand:XF 0 "register_operand" "=f")
14273         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
14274   "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387
14275    && flag_unsafe_math_optimizations"
14276   "fsin"
14277   [(set_attr "type" "fpspc")
14278    (set_attr "mode" "XF")])
14279
14280 (define_insn "sintf2"
14281   [(set (match_operand:TF 0 "register_operand" "=f")
14282         (unspec:TF [(match_operand:TF 1 "register_operand" "0")] UNSPEC_SIN))]
14283   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
14284    && flag_unsafe_math_optimizations"
14285   "fsin"
14286   [(set_attr "type" "fpspc")
14287    (set_attr "mode" "XF")])
14288
14289 (define_insn "cosdf2"
14290   [(set (match_operand:DF 0 "register_operand" "=f")
14291         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
14292   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
14293    && flag_unsafe_math_optimizations"
14294   "fcos"
14295   [(set_attr "type" "fpspc")
14296    (set_attr "mode" "DF")])
14297
14298 (define_insn "cossf2"
14299   [(set (match_operand:SF 0 "register_operand" "=f")
14300         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
14301   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
14302    && flag_unsafe_math_optimizations"
14303   "fcos"
14304   [(set_attr "type" "fpspc")
14305    (set_attr "mode" "SF")])
14306
14307 (define_insn "*cosextendsfdf2"
14308   [(set (match_operand:DF 0 "register_operand" "=f")
14309         (unspec:DF [(float_extend:DF
14310                      (match_operand:SF 1 "register_operand" "0"))]
14311                    UNSPEC_COS))]
14312   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
14313    && flag_unsafe_math_optimizations"
14314   "fcos"
14315   [(set_attr "type" "fpspc")
14316    (set_attr "mode" "DF")])
14317
14318 (define_insn "cosxf2"
14319   [(set (match_operand:XF 0 "register_operand" "=f")
14320         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
14321   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14322    && flag_unsafe_math_optimizations"
14323   "fcos"
14324   [(set_attr "type" "fpspc")
14325    (set_attr "mode" "XF")])
14326
14327 (define_insn "costf2"
14328   [(set (match_operand:TF 0 "register_operand" "=f")
14329         (unspec:TF [(match_operand:TF 1 "register_operand" "0")] UNSPEC_COS))]
14330   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
14331    && flag_unsafe_math_optimizations"
14332   "fcos"
14333   [(set_attr "type" "fpspc")
14334    (set_attr "mode" "XF")])
14335 \f
14336 ;; Block operation instructions
14337
14338 (define_insn "cld"
14339  [(set (reg:SI 19) (const_int 0))]
14340  ""
14341  "cld"
14342   [(set_attr "type" "cld")])
14343
14344 (define_expand "movstrsi"
14345   [(use (match_operand:BLK 0 "memory_operand" ""))
14346    (use (match_operand:BLK 1 "memory_operand" ""))
14347    (use (match_operand:SI 2 "nonmemory_operand" ""))
14348    (use (match_operand:SI 3 "const_int_operand" ""))]
14349   ""
14350 {
14351  if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
14352    DONE;
14353  else
14354    FAIL;
14355 })
14356
14357 (define_expand "movstrdi"
14358   [(use (match_operand:BLK 0 "memory_operand" ""))
14359    (use (match_operand:BLK 1 "memory_operand" ""))
14360    (use (match_operand:DI 2 "nonmemory_operand" ""))
14361    (use (match_operand:DI 3 "const_int_operand" ""))]
14362   "TARGET_64BIT"
14363 {
14364  if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
14365    DONE;
14366  else
14367    FAIL;
14368 })
14369
14370 ;; Most CPUs don't like single string operations
14371 ;; Handle this case here to simplify previous expander.
14372
14373 (define_expand "strmovdi_rex64"
14374   [(set (match_dup 2)
14375         (mem:DI (match_operand:DI 1 "register_operand" "")))
14376    (set (mem:DI (match_operand:DI 0 "register_operand" ""))
14377         (match_dup 2))
14378    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
14379               (clobber (reg:CC 17))])
14380    (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 8)))
14381               (clobber (reg:CC 17))])]
14382   "TARGET_64BIT"
14383 {
14384   if (TARGET_SINGLE_STRINGOP || optimize_size)
14385     {
14386       emit_insn (gen_strmovdi_rex_1 (operands[0], operands[1], operands[0],
14387                                      operands[1]));
14388       DONE;
14389     }
14390   else 
14391     operands[2] = gen_reg_rtx (DImode);
14392 })
14393
14394
14395 (define_expand "strmovsi"
14396   [(set (match_dup 2)
14397         (mem:SI (match_operand:SI 1 "register_operand" "")))
14398    (set (mem:SI (match_operand:SI 0 "register_operand" ""))
14399         (match_dup 2))
14400    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
14401               (clobber (reg:CC 17))])
14402    (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))
14403               (clobber (reg:CC 17))])]
14404   ""
14405 {
14406   if (TARGET_64BIT)
14407     {
14408       emit_insn (gen_strmovsi_rex64 (operands[0], operands[1]));
14409       DONE;
14410     }
14411   if (TARGET_SINGLE_STRINGOP || optimize_size)
14412     {
14413       emit_insn (gen_strmovsi_1 (operands[0], operands[1], operands[0],
14414                                 operands[1]));
14415       DONE;
14416     }
14417   else 
14418     operands[2] = gen_reg_rtx (SImode);
14419 })
14420
14421 (define_expand "strmovsi_rex64"
14422   [(set (match_dup 2)
14423         (mem:SI (match_operand:DI 1 "register_operand" "")))
14424    (set (mem:SI (match_operand:DI 0 "register_operand" ""))
14425         (match_dup 2))
14426    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
14427               (clobber (reg:CC 17))])
14428    (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 4)))
14429               (clobber (reg:CC 17))])]
14430   "TARGET_64BIT"
14431 {
14432   if (TARGET_SINGLE_STRINGOP || optimize_size)
14433     {
14434       emit_insn (gen_strmovsi_rex_1 (operands[0], operands[1], operands[0],
14435                                      operands[1]));
14436       DONE;
14437     }
14438   else 
14439     operands[2] = gen_reg_rtx (SImode);
14440 })
14441
14442 (define_expand "strmovhi"
14443   [(set (match_dup 2)
14444         (mem:HI (match_operand:SI 1 "register_operand" "")))
14445    (set (mem:HI (match_operand:SI 0 "register_operand" ""))
14446         (match_dup 2))
14447    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
14448               (clobber (reg:CC 17))])
14449    (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 2)))
14450               (clobber (reg:CC 17))])]
14451   ""
14452 {
14453   if (TARGET_64BIT)
14454     {
14455       emit_insn (gen_strmovhi_rex64 (operands[0], operands[1]));
14456       DONE;
14457     }
14458   if (TARGET_SINGLE_STRINGOP || optimize_size)
14459     {
14460       emit_insn (gen_strmovhi_1 (operands[0], operands[1], operands[0],
14461                                 operands[1]));
14462       DONE;
14463     }
14464   else 
14465     operands[2] = gen_reg_rtx (HImode);
14466 })
14467
14468 (define_expand "strmovhi_rex64"
14469   [(set (match_dup 2)
14470         (mem:HI (match_operand:DI 1 "register_operand" "")))
14471    (set (mem:HI (match_operand:DI 0 "register_operand" ""))
14472         (match_dup 2))
14473    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
14474               (clobber (reg:CC 17))])
14475    (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 2)))
14476               (clobber (reg:CC 17))])]
14477   "TARGET_64BIT"
14478 {
14479   if (TARGET_SINGLE_STRINGOP || optimize_size)
14480     {
14481       emit_insn (gen_strmovhi_rex_1 (operands[0], operands[1], operands[0],
14482                                      operands[1]));
14483       DONE;
14484     }
14485   else 
14486     operands[2] = gen_reg_rtx (HImode);
14487 })
14488
14489 (define_expand "strmovqi"
14490   [(set (match_dup 2)
14491         (mem:QI (match_operand:SI 1 "register_operand" "")))
14492    (set (mem:QI (match_operand:SI 0 "register_operand" ""))
14493         (match_dup 2))
14494    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14495               (clobber (reg:CC 17))])
14496    (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 1)))
14497               (clobber (reg:CC 17))])]
14498   ""
14499 {
14500   if (TARGET_64BIT)
14501     {
14502       emit_insn (gen_strmovqi_rex64 (operands[0], operands[1]));
14503       DONE;
14504     }
14505   if (TARGET_SINGLE_STRINGOP || optimize_size)
14506     {
14507       emit_insn (gen_strmovqi_1 (operands[0], operands[1], operands[0],
14508                                 operands[1]));
14509       DONE;
14510     }
14511   else 
14512     operands[2] = gen_reg_rtx (QImode);
14513 })
14514
14515 (define_expand "strmovqi_rex64"
14516   [(set (match_dup 2)
14517         (mem:QI (match_operand:DI 1 "register_operand" "")))
14518    (set (mem:QI (match_operand:DI 0 "register_operand" ""))
14519         (match_dup 2))
14520    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14521               (clobber (reg:CC 17))])
14522    (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 1)))
14523               (clobber (reg:CC 17))])]
14524   "TARGET_64BIT"
14525 {
14526   if (TARGET_SINGLE_STRINGOP || optimize_size)
14527     {
14528       emit_insn (gen_strmovqi_rex_1 (operands[0], operands[1], operands[0],
14529                                      operands[1]));
14530       DONE;
14531     }
14532   else 
14533     operands[2] = gen_reg_rtx (QImode);
14534 })
14535
14536 (define_insn "strmovdi_rex_1"
14537   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
14538         (mem:DI (match_operand:DI 3 "register_operand" "1")))
14539    (set (match_operand:DI 0 "register_operand" "=D")
14540         (plus:DI (match_dup 2)
14541                  (const_int 8)))
14542    (set (match_operand:DI 1 "register_operand" "=S")
14543         (plus:DI (match_dup 3)
14544                  (const_int 8)))
14545    (use (reg:SI 19))]
14546   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14547   "movsq"
14548   [(set_attr "type" "str")
14549    (set_attr "mode" "DI")
14550    (set_attr "memory" "both")])
14551
14552 (define_insn "strmovsi_1"
14553   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
14554         (mem:SI (match_operand:SI 3 "register_operand" "1")))
14555    (set (match_operand:SI 0 "register_operand" "=D")
14556         (plus:SI (match_dup 2)
14557                  (const_int 4)))
14558    (set (match_operand:SI 1 "register_operand" "=S")
14559         (plus:SI (match_dup 3)
14560                  (const_int 4)))
14561    (use (reg:SI 19))]
14562   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14563   "{movsl|movsd}"
14564   [(set_attr "type" "str")
14565    (set_attr "mode" "SI")
14566    (set_attr "memory" "both")])
14567
14568 (define_insn "strmovsi_rex_1"
14569   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
14570         (mem:SI (match_operand:DI 3 "register_operand" "1")))
14571    (set (match_operand:DI 0 "register_operand" "=D")
14572         (plus:DI (match_dup 2)
14573                  (const_int 4)))
14574    (set (match_operand:DI 1 "register_operand" "=S")
14575         (plus:DI (match_dup 3)
14576                  (const_int 4)))
14577    (use (reg:SI 19))]
14578   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14579   "{movsl|movsd}"
14580   [(set_attr "type" "str")
14581    (set_attr "mode" "SI")
14582    (set_attr "memory" "both")])
14583
14584 (define_insn "strmovhi_1"
14585   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
14586         (mem:HI (match_operand:SI 3 "register_operand" "1")))
14587    (set (match_operand:SI 0 "register_operand" "=D")
14588         (plus:SI (match_dup 2)
14589                  (const_int 2)))
14590    (set (match_operand:SI 1 "register_operand" "=S")
14591         (plus:SI (match_dup 3)
14592                  (const_int 2)))
14593    (use (reg:SI 19))]
14594   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14595   "movsw"
14596   [(set_attr "type" "str")
14597    (set_attr "memory" "both")
14598    (set_attr "mode" "HI")])
14599
14600 (define_insn "strmovhi_rex_1"
14601   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
14602         (mem:HI (match_operand:DI 3 "register_operand" "1")))
14603    (set (match_operand:DI 0 "register_operand" "=D")
14604         (plus:DI (match_dup 2)
14605                  (const_int 2)))
14606    (set (match_operand:DI 1 "register_operand" "=S")
14607         (plus:DI (match_dup 3)
14608                  (const_int 2)))
14609    (use (reg:SI 19))]
14610   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14611   "movsw"
14612   [(set_attr "type" "str")
14613    (set_attr "memory" "both")
14614    (set_attr "mode" "HI")])
14615
14616 (define_insn "strmovqi_1"
14617   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
14618         (mem:QI (match_operand:SI 3 "register_operand" "1")))
14619    (set (match_operand:SI 0 "register_operand" "=D")
14620         (plus:SI (match_dup 2)
14621                  (const_int 1)))
14622    (set (match_operand:SI 1 "register_operand" "=S")
14623         (plus:SI (match_dup 3)
14624                  (const_int 1)))
14625    (use (reg:SI 19))]
14626   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14627   "movsb"
14628   [(set_attr "type" "str")
14629    (set_attr "memory" "both")
14630    (set_attr "mode" "QI")])
14631
14632 (define_insn "strmovqi_rex_1"
14633   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
14634         (mem:QI (match_operand:DI 3 "register_operand" "1")))
14635    (set (match_operand:DI 0 "register_operand" "=D")
14636         (plus:DI (match_dup 2)
14637                  (const_int 1)))
14638    (set (match_operand:DI 1 "register_operand" "=S")
14639         (plus:DI (match_dup 3)
14640                  (const_int 1)))
14641    (use (reg:SI 19))]
14642   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14643   "movsb"
14644   [(set_attr "type" "str")
14645    (set_attr "memory" "both")
14646    (set_attr "mode" "QI")])
14647
14648 (define_insn "rep_movdi_rex64"
14649   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
14650    (set (match_operand:DI 0 "register_operand" "=D") 
14651         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
14652                             (const_int 3))
14653                  (match_operand:DI 3 "register_operand" "0")))
14654    (set (match_operand:DI 1 "register_operand" "=S") 
14655         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
14656                  (match_operand:DI 4 "register_operand" "1")))
14657    (set (mem:BLK (match_dup 3))
14658         (mem:BLK (match_dup 4)))
14659    (use (match_dup 5))
14660    (use (reg:SI 19))]
14661   "TARGET_64BIT"
14662   "{rep\;movsq|rep movsq}"
14663   [(set_attr "type" "str")
14664    (set_attr "prefix_rep" "1")
14665    (set_attr "memory" "both")
14666    (set_attr "mode" "DI")])
14667
14668 (define_insn "rep_movsi"
14669   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
14670    (set (match_operand:SI 0 "register_operand" "=D") 
14671         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
14672                             (const_int 2))
14673                  (match_operand:SI 3 "register_operand" "0")))
14674    (set (match_operand:SI 1 "register_operand" "=S") 
14675         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
14676                  (match_operand:SI 4 "register_operand" "1")))
14677    (set (mem:BLK (match_dup 3))
14678         (mem:BLK (match_dup 4)))
14679    (use (match_dup 5))
14680    (use (reg:SI 19))]
14681   "!TARGET_64BIT"
14682   "{rep\;movsl|rep movsd}"
14683   [(set_attr "type" "str")
14684    (set_attr "prefix_rep" "1")
14685    (set_attr "memory" "both")
14686    (set_attr "mode" "SI")])
14687
14688 (define_insn "rep_movsi_rex64"
14689   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
14690    (set (match_operand:DI 0 "register_operand" "=D") 
14691         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
14692                             (const_int 2))
14693                  (match_operand:DI 3 "register_operand" "0")))
14694    (set (match_operand:DI 1 "register_operand" "=S") 
14695         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
14696                  (match_operand:DI 4 "register_operand" "1")))
14697    (set (mem:BLK (match_dup 3))
14698         (mem:BLK (match_dup 4)))
14699    (use (match_dup 5))
14700    (use (reg:SI 19))]
14701   "TARGET_64BIT"
14702   "{rep\;movsl|rep movsd}"
14703   [(set_attr "type" "str")
14704    (set_attr "prefix_rep" "1")
14705    (set_attr "memory" "both")
14706    (set_attr "mode" "SI")])
14707
14708 (define_insn "rep_movqi"
14709   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
14710    (set (match_operand:SI 0 "register_operand" "=D") 
14711         (plus:SI (match_operand:SI 3 "register_operand" "0")
14712                  (match_operand:SI 5 "register_operand" "2")))
14713    (set (match_operand:SI 1 "register_operand" "=S") 
14714         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
14715    (set (mem:BLK (match_dup 3))
14716         (mem:BLK (match_dup 4)))
14717    (use (match_dup 5))
14718    (use (reg:SI 19))]
14719   "!TARGET_64BIT"
14720   "{rep\;movsb|rep movsb}"
14721   [(set_attr "type" "str")
14722    (set_attr "prefix_rep" "1")
14723    (set_attr "memory" "both")
14724    (set_attr "mode" "SI")])
14725
14726 (define_insn "rep_movqi_rex64"
14727   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
14728    (set (match_operand:DI 0 "register_operand" "=D") 
14729         (plus:DI (match_operand:DI 3 "register_operand" "0")
14730                  (match_operand:DI 5 "register_operand" "2")))
14731    (set (match_operand:DI 1 "register_operand" "=S") 
14732         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
14733    (set (mem:BLK (match_dup 3))
14734         (mem:BLK (match_dup 4)))
14735    (use (match_dup 5))
14736    (use (reg:SI 19))]
14737   "TARGET_64BIT"
14738   "{rep\;movsb|rep movsb}"
14739   [(set_attr "type" "str")
14740    (set_attr "prefix_rep" "1")
14741    (set_attr "memory" "both")
14742    (set_attr "mode" "SI")])
14743
14744 (define_expand "clrstrsi"
14745    [(use (match_operand:BLK 0 "memory_operand" ""))
14746     (use (match_operand:SI 1 "nonmemory_operand" ""))
14747     (use (match_operand 2 "const_int_operand" ""))]
14748   ""
14749 {
14750  if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
14751    DONE;
14752  else
14753    FAIL;
14754 })
14755
14756 (define_expand "clrstrdi"
14757    [(use (match_operand:BLK 0 "memory_operand" ""))
14758     (use (match_operand:DI 1 "nonmemory_operand" ""))
14759     (use (match_operand 2 "const_int_operand" ""))]
14760   "TARGET_64BIT"
14761 {
14762  if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
14763    DONE;
14764  else
14765    FAIL;
14766 })
14767
14768 ;; Most CPUs don't like single string operations
14769 ;; Handle this case here to simplify previous expander.
14770
14771 (define_expand "strsetdi_rex64"
14772   [(set (mem:DI (match_operand:DI 0 "register_operand" ""))
14773         (match_operand:DI 1 "register_operand" ""))
14774    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
14775               (clobber (reg:CC 17))])]
14776   "TARGET_64BIT"
14777 {
14778   if (TARGET_SINGLE_STRINGOP || optimize_size)
14779     {
14780       emit_insn (gen_strsetdi_rex_1 (operands[0], operands[0], operands[1]));
14781       DONE;
14782     }
14783 })
14784
14785 (define_expand "strsetsi"
14786   [(set (mem:SI (match_operand:SI 0 "register_operand" ""))
14787         (match_operand:SI 1 "register_operand" ""))
14788    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
14789               (clobber (reg:CC 17))])]
14790   ""
14791 {
14792   if (TARGET_64BIT)
14793     {
14794       emit_insn (gen_strsetsi_rex64 (operands[0], operands[1]));
14795       DONE;
14796     }
14797   else if (TARGET_SINGLE_STRINGOP || optimize_size)
14798     {
14799       emit_insn (gen_strsetsi_1 (operands[0], operands[0], operands[1]));
14800       DONE;
14801     }
14802 })
14803
14804 (define_expand "strsetsi_rex64"
14805   [(set (mem:SI (match_operand:DI 0 "register_operand" ""))
14806         (match_operand:SI 1 "register_operand" ""))
14807    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
14808               (clobber (reg:CC 17))])]
14809   "TARGET_64BIT"
14810 {
14811   if (TARGET_SINGLE_STRINGOP || optimize_size)
14812     {
14813       emit_insn (gen_strsetsi_rex_1 (operands[0], operands[0], operands[1]));
14814       DONE;
14815     }
14816 })
14817
14818 (define_expand "strsethi"
14819   [(set (mem:HI (match_operand:SI 0 "register_operand" ""))
14820         (match_operand:HI 1 "register_operand" ""))
14821    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
14822               (clobber (reg:CC 17))])]
14823   ""
14824 {
14825   if (TARGET_64BIT)
14826     {
14827       emit_insn (gen_strsethi_rex64 (operands[0], operands[1]));
14828       DONE;
14829     }
14830   else if (TARGET_SINGLE_STRINGOP || optimize_size)
14831     {
14832       emit_insn (gen_strsethi_1 (operands[0], operands[0], operands[1]));
14833       DONE;
14834     }
14835 })
14836
14837 (define_expand "strsethi_rex64"
14838   [(set (mem:HI (match_operand:DI 0 "register_operand" ""))
14839         (match_operand:HI 1 "register_operand" ""))
14840    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
14841               (clobber (reg:CC 17))])]
14842   "TARGET_64BIT"
14843 {
14844   if (TARGET_SINGLE_STRINGOP || optimize_size)
14845     {
14846       emit_insn (gen_strsethi_rex_1 (operands[0], operands[0], operands[1]));
14847       DONE;
14848     }
14849 })
14850
14851 (define_expand "strsetqi"
14852   [(set (mem:QI (match_operand:SI 0 "register_operand" ""))
14853         (match_operand:QI 1 "register_operand" ""))
14854    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14855               (clobber (reg:CC 17))])]
14856   ""
14857 {
14858   if (TARGET_64BIT)
14859     {
14860       emit_insn (gen_strsetqi_rex64 (operands[0], operands[1]));
14861       DONE;
14862     }
14863   else if (TARGET_SINGLE_STRINGOP || optimize_size)
14864     {
14865       emit_insn (gen_strsetqi_1 (operands[0], operands[0], operands[1]));
14866       DONE;
14867     }
14868 })
14869
14870 (define_expand "strsetqi_rex64"
14871   [(set (mem:QI (match_operand:DI 0 "register_operand" ""))
14872         (match_operand:QI 1 "register_operand" ""))
14873    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14874               (clobber (reg:CC 17))])]
14875   "TARGET_64BIT"
14876 {
14877   if (TARGET_SINGLE_STRINGOP || optimize_size)
14878     {
14879       emit_insn (gen_strsetqi_rex_1 (operands[0], operands[0], operands[1]));
14880       DONE;
14881     }
14882 })
14883
14884 (define_insn "strsetdi_rex_1"
14885   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
14886         (match_operand:SI 2 "register_operand" "a"))
14887    (set (match_operand:DI 0 "register_operand" "=D")
14888         (plus:DI (match_dup 1)
14889                  (const_int 8)))
14890    (use (reg:SI 19))]
14891   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14892   "stosq"
14893   [(set_attr "type" "str")
14894    (set_attr "memory" "store")
14895    (set_attr "mode" "DI")])
14896
14897 (define_insn "strsetsi_1"
14898   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
14899         (match_operand:SI 2 "register_operand" "a"))
14900    (set (match_operand:SI 0 "register_operand" "=D")
14901         (plus:SI (match_dup 1)
14902                  (const_int 4)))
14903    (use (reg:SI 19))]
14904   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14905   "{stosl|stosd}"
14906   [(set_attr "type" "str")
14907    (set_attr "memory" "store")
14908    (set_attr "mode" "SI")])
14909
14910 (define_insn "strsetsi_rex_1"
14911   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
14912         (match_operand:SI 2 "register_operand" "a"))
14913    (set (match_operand:DI 0 "register_operand" "=D")
14914         (plus:DI (match_dup 1)
14915                  (const_int 4)))
14916    (use (reg:SI 19))]
14917   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14918   "{stosl|stosd}"
14919   [(set_attr "type" "str")
14920    (set_attr "memory" "store")
14921    (set_attr "mode" "SI")])
14922
14923 (define_insn "strsethi_1"
14924   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
14925         (match_operand:HI 2 "register_operand" "a"))
14926    (set (match_operand:SI 0 "register_operand" "=D")
14927         (plus:SI (match_dup 1)
14928                  (const_int 2)))
14929    (use (reg:SI 19))]
14930   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14931   "stosw"
14932   [(set_attr "type" "str")
14933    (set_attr "memory" "store")
14934    (set_attr "mode" "HI")])
14935
14936 (define_insn "strsethi_rex_1"
14937   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
14938         (match_operand:HI 2 "register_operand" "a"))
14939    (set (match_operand:DI 0 "register_operand" "=D")
14940         (plus:DI (match_dup 1)
14941                  (const_int 2)))
14942    (use (reg:SI 19))]
14943   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14944   "stosw"
14945   [(set_attr "type" "str")
14946    (set_attr "memory" "store")
14947    (set_attr "mode" "HI")])
14948
14949 (define_insn "strsetqi_1"
14950   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
14951         (match_operand:QI 2 "register_operand" "a"))
14952    (set (match_operand:SI 0 "register_operand" "=D")
14953         (plus:SI (match_dup 1)
14954                  (const_int 1)))
14955    (use (reg:SI 19))]
14956   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14957   "stosb"
14958   [(set_attr "type" "str")
14959    (set_attr "memory" "store")
14960    (set_attr "mode" "QI")])
14961
14962 (define_insn "strsetqi_rex_1"
14963   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
14964         (match_operand:QI 2 "register_operand" "a"))
14965    (set (match_operand:DI 0 "register_operand" "=D")
14966         (plus:DI (match_dup 1)
14967                  (const_int 1)))
14968    (use (reg:SI 19))]
14969   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14970   "stosb"
14971   [(set_attr "type" "str")
14972    (set_attr "memory" "store")
14973    (set_attr "mode" "QI")])
14974
14975 (define_insn "rep_stosdi_rex64"
14976   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
14977    (set (match_operand:DI 0 "register_operand" "=D") 
14978         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
14979                             (const_int 3))
14980                  (match_operand:DI 3 "register_operand" "0")))
14981    (set (mem:BLK (match_dup 3))
14982         (const_int 0))
14983    (use (match_operand:DI 2 "register_operand" "a"))
14984    (use (match_dup 4))
14985    (use (reg:SI 19))]
14986   "TARGET_64BIT"
14987   "{rep\;stosq|rep stosq}"
14988   [(set_attr "type" "str")
14989    (set_attr "prefix_rep" "1")
14990    (set_attr "memory" "store")
14991    (set_attr "mode" "DI")])
14992
14993 (define_insn "rep_stossi"
14994   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
14995    (set (match_operand:SI 0 "register_operand" "=D") 
14996         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
14997                             (const_int 2))
14998                  (match_operand:SI 3 "register_operand" "0")))
14999    (set (mem:BLK (match_dup 3))
15000         (const_int 0))
15001    (use (match_operand:SI 2 "register_operand" "a"))
15002    (use (match_dup 4))
15003    (use (reg:SI 19))]
15004   "!TARGET_64BIT"
15005   "{rep\;stosl|rep stosd}"
15006   [(set_attr "type" "str")
15007    (set_attr "prefix_rep" "1")
15008    (set_attr "memory" "store")
15009    (set_attr "mode" "SI")])
15010
15011 (define_insn "rep_stossi_rex64"
15012   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15013    (set (match_operand:DI 0 "register_operand" "=D") 
15014         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15015                             (const_int 2))
15016                  (match_operand:DI 3 "register_operand" "0")))
15017    (set (mem:BLK (match_dup 3))
15018         (const_int 0))
15019    (use (match_operand:SI 2 "register_operand" "a"))
15020    (use (match_dup 4))
15021    (use (reg:SI 19))]
15022   "TARGET_64BIT"
15023   "{rep\;stosl|rep stosd}"
15024   [(set_attr "type" "str")
15025    (set_attr "prefix_rep" "1")
15026    (set_attr "memory" "store")
15027    (set_attr "mode" "SI")])
15028
15029 (define_insn "rep_stosqi"
15030   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15031    (set (match_operand:SI 0 "register_operand" "=D") 
15032         (plus:SI (match_operand:SI 3 "register_operand" "0")
15033                  (match_operand:SI 4 "register_operand" "1")))
15034    (set (mem:BLK (match_dup 3))
15035         (const_int 0))
15036    (use (match_operand:QI 2 "register_operand" "a"))
15037    (use (match_dup 4))
15038    (use (reg:SI 19))]
15039   "!TARGET_64BIT"
15040   "{rep\;stosb|rep stosb}"
15041   [(set_attr "type" "str")
15042    (set_attr "prefix_rep" "1")
15043    (set_attr "memory" "store")
15044    (set_attr "mode" "QI")])
15045
15046 (define_insn "rep_stosqi_rex64"
15047   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15048    (set (match_operand:DI 0 "register_operand" "=D") 
15049         (plus:DI (match_operand:DI 3 "register_operand" "0")
15050                  (match_operand:DI 4 "register_operand" "1")))
15051    (set (mem:BLK (match_dup 3))
15052         (const_int 0))
15053    (use (match_operand:QI 2 "register_operand" "a"))
15054    (use (match_dup 4))
15055    (use (reg:DI 19))]
15056   "TARGET_64BIT"
15057   "{rep\;stosb|rep stosb}"
15058   [(set_attr "type" "str")
15059    (set_attr "prefix_rep" "1")
15060    (set_attr "memory" "store")
15061    (set_attr "mode" "QI")])
15062
15063 (define_expand "cmpstrsi"
15064   [(set (match_operand:SI 0 "register_operand" "")
15065         (compare:SI (match_operand:BLK 1 "general_operand" "")
15066                     (match_operand:BLK 2 "general_operand" "")))
15067    (use (match_operand 3 "general_operand" ""))
15068    (use (match_operand 4 "immediate_operand" ""))]
15069   ""
15070 {
15071   rtx addr1, addr2, out, outlow, count, countreg, align;
15072
15073   out = operands[0];
15074   if (GET_CODE (out) != REG)
15075     out = gen_reg_rtx (SImode);
15076
15077   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15078   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15079   
15080   count = operands[3];
15081   countreg = ix86_zero_extend_to_Pmode (count);
15082
15083   /* %%% Iff we are testing strict equality, we can use known alignment
15084      to good advantage.  This may be possible with combine, particularly
15085      once cc0 is dead.  */
15086   align = operands[4];
15087
15088   emit_insn (gen_cld ());
15089   if (GET_CODE (count) == CONST_INT)
15090     {
15091       if (INTVAL (count) == 0)
15092         {
15093           emit_move_insn (operands[0], const0_rtx);
15094           DONE;
15095         }
15096       if (TARGET_64BIT)
15097         emit_insn (gen_cmpstrqi_nz_rex_1 (addr1, addr2, countreg, align,
15098                                           addr1, addr2, countreg));
15099       else
15100         emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
15101                                       addr1, addr2, countreg));
15102     }
15103   else
15104     {
15105       if (TARGET_64BIT)
15106         {
15107           emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
15108           emit_insn (gen_cmpstrqi_rex_1 (addr1, addr2, countreg, align,
15109                                          addr1, addr2, countreg));
15110         }
15111       else
15112         {
15113           emit_insn (gen_cmpsi_1 (countreg, countreg));
15114           emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
15115                                      addr1, addr2, countreg));
15116         }
15117     }
15118
15119   outlow = gen_lowpart (QImode, out);
15120   emit_insn (gen_cmpintqi (outlow));
15121   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15122
15123   if (operands[0] != out)
15124     emit_move_insn (operands[0], out);
15125
15126   DONE;
15127 })
15128
15129 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15130
15131 (define_expand "cmpintqi"
15132   [(set (match_dup 1)
15133         (gtu:QI (reg:CC 17) (const_int 0)))
15134    (set (match_dup 2)
15135         (ltu:QI (reg:CC 17) (const_int 0)))
15136    (parallel [(set (match_operand:QI 0 "register_operand" "")
15137                    (minus:QI (match_dup 1)
15138                              (match_dup 2)))
15139               (clobber (reg:CC 17))])]
15140   ""
15141   "operands[1] = gen_reg_rtx (QImode);
15142    operands[2] = gen_reg_rtx (QImode);")
15143
15144 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
15145 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
15146
15147 (define_insn "cmpstrqi_nz_1"
15148   [(set (reg:CC 17)
15149         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15150                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
15151    (use (match_operand:SI 6 "register_operand" "2"))
15152    (use (match_operand:SI 3 "immediate_operand" "i"))
15153    (use (reg:SI 19))
15154    (clobber (match_operand:SI 0 "register_operand" "=S"))
15155    (clobber (match_operand:SI 1 "register_operand" "=D"))
15156    (clobber (match_operand:SI 2 "register_operand" "=c"))]
15157   "!TARGET_64BIT"
15158   "repz{\;| }cmpsb"
15159   [(set_attr "type" "str")
15160    (set_attr "mode" "QI")
15161    (set_attr "prefix_rep" "1")])
15162
15163 (define_insn "cmpstrqi_nz_rex_1"
15164   [(set (reg:CC 17)
15165         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15166                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
15167    (use (match_operand:DI 6 "register_operand" "2"))
15168    (use (match_operand:SI 3 "immediate_operand" "i"))
15169    (use (reg:SI 19))
15170    (clobber (match_operand:DI 0 "register_operand" "=S"))
15171    (clobber (match_operand:DI 1 "register_operand" "=D"))
15172    (clobber (match_operand:DI 2 "register_operand" "=c"))]
15173   "TARGET_64BIT"
15174   "repz{\;| }cmpsb"
15175   [(set_attr "type" "str")
15176    (set_attr "mode" "QI")
15177    (set_attr "prefix_rep" "1")])
15178
15179 ;; The same, but the count is not known to not be zero.
15180
15181 (define_insn "cmpstrqi_1"
15182   [(set (reg:CC 17)
15183         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
15184                              (const_int 0))
15185           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15186                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
15187           (const_int 0)))
15188    (use (match_operand:SI 3 "immediate_operand" "i"))
15189    (use (reg:CC 17))
15190    (use (reg:SI 19))
15191    (clobber (match_operand:SI 0 "register_operand" "=S"))
15192    (clobber (match_operand:SI 1 "register_operand" "=D"))
15193    (clobber (match_operand:SI 2 "register_operand" "=c"))]
15194   "!TARGET_64BIT"
15195   "repz{\;| }cmpsb"
15196   [(set_attr "type" "str")
15197    (set_attr "mode" "QI")
15198    (set_attr "prefix_rep" "1")])
15199
15200 (define_insn "cmpstrqi_rex_1"
15201   [(set (reg:CC 17)
15202         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
15203                              (const_int 0))
15204           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15205                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
15206           (const_int 0)))
15207    (use (match_operand:SI 3 "immediate_operand" "i"))
15208    (use (reg:CC 17))
15209    (use (reg:SI 19))
15210    (clobber (match_operand:DI 0 "register_operand" "=S"))
15211    (clobber (match_operand:DI 1 "register_operand" "=D"))
15212    (clobber (match_operand:DI 2 "register_operand" "=c"))]
15213   "TARGET_64BIT"
15214   "repz{\;| }cmpsb"
15215   [(set_attr "type" "str")
15216    (set_attr "mode" "QI")
15217    (set_attr "prefix_rep" "1")])
15218
15219 (define_expand "strlensi"
15220   [(set (match_operand:SI 0 "register_operand" "")
15221         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
15222                     (match_operand:QI 2 "immediate_operand" "")
15223                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
15224   ""
15225 {
15226  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15227    DONE;
15228  else
15229    FAIL;
15230 })
15231
15232 (define_expand "strlendi"
15233   [(set (match_operand:DI 0 "register_operand" "")
15234         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
15235                     (match_operand:QI 2 "immediate_operand" "")
15236                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
15237   ""
15238 {
15239  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15240    DONE;
15241  else
15242    FAIL;
15243 })
15244
15245 (define_insn "strlenqi_1"
15246   [(set (match_operand:SI 0 "register_operand" "=&c")
15247         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
15248                     (match_operand:QI 2 "register_operand" "a")
15249                     (match_operand:SI 3 "immediate_operand" "i")
15250                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
15251    (use (reg:SI 19))
15252    (clobber (match_operand:SI 1 "register_operand" "=D"))
15253    (clobber (reg:CC 17))]
15254   "!TARGET_64BIT"
15255   "repnz{\;| }scasb"
15256   [(set_attr "type" "str")
15257    (set_attr "mode" "QI")
15258    (set_attr "prefix_rep" "1")])
15259
15260 (define_insn "strlenqi_rex_1"
15261   [(set (match_operand:DI 0 "register_operand" "=&c")
15262         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
15263                     (match_operand:QI 2 "register_operand" "a")
15264                     (match_operand:DI 3 "immediate_operand" "i")
15265                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
15266    (use (reg:SI 19))
15267    (clobber (match_operand:DI 1 "register_operand" "=D"))
15268    (clobber (reg:CC 17))]
15269   "TARGET_64BIT"
15270   "repnz{\;| }scasb"
15271   [(set_attr "type" "str")
15272    (set_attr "mode" "QI")
15273    (set_attr "prefix_rep" "1")])
15274
15275 ;; Peephole optimizations to clean up after cmpstr*.  This should be
15276 ;; handled in combine, but it is not currently up to the task.
15277 ;; When used for their truth value, the cmpstr* expanders generate
15278 ;; code like this:
15279 ;;
15280 ;;   repz cmpsb
15281 ;;   seta       %al
15282 ;;   setb       %dl
15283 ;;   cmpb       %al, %dl
15284 ;;   jcc        label
15285 ;;
15286 ;; The intermediate three instructions are unnecessary.
15287
15288 ;; This one handles cmpstr*_nz_1...
15289 (define_peephole2
15290   [(parallel[
15291      (set (reg:CC 17)
15292           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15293                       (mem:BLK (match_operand 5 "register_operand" ""))))
15294      (use (match_operand 6 "register_operand" ""))
15295      (use (match_operand:SI 3 "immediate_operand" ""))
15296      (use (reg:SI 19))
15297      (clobber (match_operand 0 "register_operand" ""))
15298      (clobber (match_operand 1 "register_operand" ""))
15299      (clobber (match_operand 2 "register_operand" ""))])
15300    (set (match_operand:QI 7 "register_operand" "")
15301         (gtu:QI (reg:CC 17) (const_int 0)))
15302    (set (match_operand:QI 8 "register_operand" "")
15303         (ltu:QI (reg:CC 17) (const_int 0)))
15304    (set (reg 17)
15305         (compare (match_dup 7) (match_dup 8)))
15306   ]
15307   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15308   [(parallel[
15309      (set (reg:CC 17)
15310           (compare:CC (mem:BLK (match_dup 4))
15311                       (mem:BLK (match_dup 5))))
15312      (use (match_dup 6))
15313      (use (match_dup 3))
15314      (use (reg:SI 19))
15315      (clobber (match_dup 0))
15316      (clobber (match_dup 1))
15317      (clobber (match_dup 2))])]
15318   "")
15319
15320 ;; ...and this one handles cmpstr*_1.
15321 (define_peephole2
15322   [(parallel[
15323      (set (reg:CC 17)
15324           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
15325                                (const_int 0))
15326             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15327                         (mem:BLK (match_operand 5 "register_operand" "")))
15328             (const_int 0)))
15329      (use (match_operand:SI 3 "immediate_operand" ""))
15330      (use (reg:CC 17))
15331      (use (reg:SI 19))
15332      (clobber (match_operand 0 "register_operand" ""))
15333      (clobber (match_operand 1 "register_operand" ""))
15334      (clobber (match_operand 2 "register_operand" ""))])
15335    (set (match_operand:QI 7 "register_operand" "")
15336         (gtu:QI (reg:CC 17) (const_int 0)))
15337    (set (match_operand:QI 8 "register_operand" "")
15338         (ltu:QI (reg:CC 17) (const_int 0)))
15339    (set (reg 17)
15340         (compare (match_dup 7) (match_dup 8)))
15341   ]
15342   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15343   [(parallel[
15344      (set (reg:CC 17)
15345           (if_then_else:CC (ne (match_dup 6)
15346                                (const_int 0))
15347             (compare:CC (mem:BLK (match_dup 4))
15348                         (mem:BLK (match_dup 5)))
15349             (const_int 0)))
15350      (use (match_dup 3))
15351      (use (reg:CC 17))
15352      (use (reg:SI 19))
15353      (clobber (match_dup 0))
15354      (clobber (match_dup 1))
15355      (clobber (match_dup 2))])]
15356   "")
15357
15358
15359 \f
15360 ;; Conditional move instructions.
15361
15362 (define_expand "movdicc"
15363   [(set (match_operand:DI 0 "register_operand" "")
15364         (if_then_else:DI (match_operand 1 "comparison_operator" "")
15365                          (match_operand:DI 2 "general_operand" "")
15366                          (match_operand:DI 3 "general_operand" "")))]
15367   "TARGET_64BIT"
15368   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
15369
15370 (define_insn "x86_movdicc_0_m1_rex64"
15371   [(set (match_operand:DI 0 "register_operand" "=r")
15372         (if_then_else:DI (ltu (reg:CC 17) (const_int 0))
15373           (const_int -1)
15374           (const_int 0)))
15375    (clobber (reg:CC 17))]
15376   "TARGET_64BIT"
15377   "sbb{q}\t%0, %0"
15378   ; Since we don't have the proper number of operands for an alu insn,
15379   ; fill in all the blanks.
15380   [(set_attr "type" "alu")
15381    (set_attr "pent_pair" "pu")
15382    (set_attr "memory" "none")
15383    (set_attr "imm_disp" "false")
15384    (set_attr "mode" "DI")
15385    (set_attr "length_immediate" "0")])
15386
15387 (define_insn "*movdicc_c_rex64"
15388   [(set (match_operand:DI 0 "register_operand" "=r,r")
15389         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
15390                                 [(reg 17) (const_int 0)])
15391                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
15392                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
15393   "TARGET_64BIT && TARGET_CMOVE
15394    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
15395   "@
15396    cmov%O2%C1\t{%2, %0|%0, %2}
15397    cmov%O2%c1\t{%3, %0|%0, %3}"
15398   [(set_attr "type" "icmov")
15399    (set_attr "mode" "DI")])
15400
15401 (define_expand "movsicc"
15402   [(set (match_operand:SI 0 "register_operand" "")
15403         (if_then_else:SI (match_operand 1 "comparison_operator" "")
15404                          (match_operand:SI 2 "general_operand" "")
15405                          (match_operand:SI 3 "general_operand" "")))]
15406   ""
15407   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
15408
15409 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
15410 ;; the register first winds up with `sbbl $0,reg', which is also weird.
15411 ;; So just document what we're doing explicitly.
15412
15413 (define_insn "x86_movsicc_0_m1"
15414   [(set (match_operand:SI 0 "register_operand" "=r")
15415         (if_then_else:SI (ltu (reg:CC 17) (const_int 0))
15416           (const_int -1)
15417           (const_int 0)))
15418    (clobber (reg:CC 17))]
15419   ""
15420   "sbb{l}\t%0, %0"
15421   ; Since we don't have the proper number of operands for an alu insn,
15422   ; fill in all the blanks.
15423   [(set_attr "type" "alu")
15424    (set_attr "pent_pair" "pu")
15425    (set_attr "memory" "none")
15426    (set_attr "imm_disp" "false")
15427    (set_attr "mode" "SI")
15428    (set_attr "length_immediate" "0")])
15429
15430 (define_insn "*movsicc_noc"
15431   [(set (match_operand:SI 0 "register_operand" "=r,r")
15432         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
15433                                 [(reg 17) (const_int 0)])
15434                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
15435                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
15436   "TARGET_CMOVE
15437    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
15438   "@
15439    cmov%O2%C1\t{%2, %0|%0, %2}
15440    cmov%O2%c1\t{%3, %0|%0, %3}"
15441   [(set_attr "type" "icmov")
15442    (set_attr "mode" "SI")])
15443
15444 (define_expand "movhicc"
15445   [(set (match_operand:HI 0 "register_operand" "")
15446         (if_then_else:HI (match_operand 1 "comparison_operator" "")
15447                          (match_operand:HI 2 "nonimmediate_operand" "")
15448                          (match_operand:HI 3 "nonimmediate_operand" "")))]
15449   "TARGET_CMOVE && TARGET_HIMODE_MATH"
15450   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
15451
15452 (define_insn "*movhicc_noc"
15453   [(set (match_operand:HI 0 "register_operand" "=r,r")
15454         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
15455                                 [(reg 17) (const_int 0)])
15456                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
15457                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
15458   "TARGET_CMOVE
15459    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
15460   "@
15461    cmov%O2%C1\t{%2, %0|%0, %2}
15462    cmov%O2%c1\t{%3, %0|%0, %3}"
15463   [(set_attr "type" "icmov")
15464    (set_attr "mode" "HI")])
15465
15466 (define_expand "movsfcc"
15467   [(set (match_operand:SF 0 "register_operand" "")
15468         (if_then_else:SF (match_operand 1 "comparison_operator" "")
15469                          (match_operand:SF 2 "register_operand" "")
15470                          (match_operand:SF 3 "register_operand" "")))]
15471   "TARGET_CMOVE"
15472   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
15473
15474 (define_insn "*movsfcc_1"
15475   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
15476         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
15477                                 [(reg 17) (const_int 0)])
15478                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
15479                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
15480   "TARGET_CMOVE
15481    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
15482   "@
15483    fcmov%F1\t{%2, %0|%0, %2}
15484    fcmov%f1\t{%3, %0|%0, %3}
15485    cmov%O2%C1\t{%2, %0|%0, %2}
15486    cmov%O2%c1\t{%3, %0|%0, %3}"
15487   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
15488    (set_attr "mode" "SF,SF,SI,SI")])
15489
15490 (define_expand "movdfcc"
15491   [(set (match_operand:DF 0 "register_operand" "")
15492         (if_then_else:DF (match_operand 1 "comparison_operator" "")
15493                          (match_operand:DF 2 "register_operand" "")
15494                          (match_operand:DF 3 "register_operand" "")))]
15495   "TARGET_CMOVE"
15496   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
15497
15498 (define_insn "*movdfcc_1"
15499   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
15500         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
15501                                 [(reg 17) (const_int 0)])
15502                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
15503                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
15504   "!TARGET_64BIT && TARGET_CMOVE
15505    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
15506   "@
15507    fcmov%F1\t{%2, %0|%0, %2}
15508    fcmov%f1\t{%3, %0|%0, %3}
15509    #
15510    #"
15511   [(set_attr "type" "fcmov,fcmov,multi,multi")
15512    (set_attr "mode" "DF")])
15513
15514 (define_insn "*movdfcc_1_rex64"
15515   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
15516         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
15517                                 [(reg 17) (const_int 0)])
15518                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
15519                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
15520   "TARGET_64BIT && TARGET_CMOVE
15521    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
15522   "@
15523    fcmov%F1\t{%2, %0|%0, %2}
15524    fcmov%f1\t{%3, %0|%0, %3}
15525    cmov%O2%C1\t{%2, %0|%0, %2}
15526    cmov%O2%c1\t{%3, %0|%0, %3}"
15527   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
15528    (set_attr "mode" "DF")])
15529
15530 (define_split
15531   [(set (match_operand:DF 0 "register_operand" "")
15532         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
15533                                 [(match_operand 4 "" "") (const_int 0)])
15534                       (match_operand:DF 2 "nonimmediate_operand" "")
15535                       (match_operand:DF 3 "nonimmediate_operand" "")))]
15536   "!TARGET_64BIT && !ANY_FP_REG_P (operands[0]) && reload_completed"
15537   [(set (match_dup 2)
15538         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
15539                       (match_dup 5)
15540                       (match_dup 7)))
15541    (set (match_dup 3)
15542         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
15543                       (match_dup 6)
15544                       (match_dup 8)))]
15545   "split_di (operands+2, 1, operands+5, operands+6);
15546    split_di (operands+3, 1, operands+7, operands+8);
15547    split_di (operands, 1, operands+2, operands+3);")
15548
15549 (define_expand "movxfcc"
15550   [(set (match_operand:XF 0 "register_operand" "")
15551         (if_then_else:XF (match_operand 1 "comparison_operator" "")
15552                          (match_operand:XF 2 "register_operand" "")
15553                          (match_operand:XF 3 "register_operand" "")))]
15554   "!TARGET_64BIT && TARGET_CMOVE"
15555   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
15556
15557 (define_expand "movtfcc"
15558   [(set (match_operand:TF 0 "register_operand" "")
15559         (if_then_else:TF (match_operand 1 "comparison_operator" "")
15560                          (match_operand:TF 2 "register_operand" "")
15561                          (match_operand:TF 3 "register_operand" "")))]
15562   "TARGET_CMOVE"
15563   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
15564
15565 (define_insn "*movxfcc_1"
15566   [(set (match_operand:XF 0 "register_operand" "=f,f")
15567         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
15568                                 [(reg 17) (const_int 0)])
15569                       (match_operand:XF 2 "register_operand" "f,0")
15570                       (match_operand:XF 3 "register_operand" "0,f")))]
15571   "!TARGET_64BIT && TARGET_CMOVE"
15572   "@
15573    fcmov%F1\t{%2, %0|%0, %2}
15574    fcmov%f1\t{%3, %0|%0, %3}"
15575   [(set_attr "type" "fcmov")
15576    (set_attr "mode" "XF")])
15577
15578 (define_insn "*movtfcc_1"
15579   [(set (match_operand:TF 0 "register_operand" "=f,f")
15580         (if_then_else:TF (match_operator 1 "fcmov_comparison_operator" 
15581                                 [(reg 17) (const_int 0)])
15582                       (match_operand:TF 2 "register_operand" "f,0")
15583                       (match_operand:TF 3 "register_operand" "0,f")))]
15584   "TARGET_CMOVE"
15585   "@
15586    fcmov%F1\t{%2, %0|%0, %2}
15587    fcmov%f1\t{%3, %0|%0, %3}"
15588   [(set_attr "type" "fcmov")
15589    (set_attr "mode" "XF")])
15590
15591 (define_expand "minsf3"
15592   [(parallel [
15593      (set (match_operand:SF 0 "register_operand" "")
15594           (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
15595                                (match_operand:SF 2 "nonimmediate_operand" ""))
15596                            (match_dup 1)
15597                            (match_dup 2)))
15598      (clobber (reg:CC 17))])]
15599   "TARGET_SSE"
15600   "")
15601
15602 (define_insn "*minsf"
15603   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
15604         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
15605                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
15606                          (match_dup 1)
15607                          (match_dup 2)))
15608    (clobber (reg:CC 17))]
15609   "TARGET_SSE && TARGET_IEEE_FP"
15610   "#")
15611
15612 (define_insn "*minsf_nonieee"
15613   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
15614         (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
15615                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
15616                          (match_dup 1)
15617                          (match_dup 2)))
15618    (clobber (reg:CC 17))]
15619   "TARGET_SSE && !TARGET_IEEE_FP
15620    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15621   "#")
15622
15623 (define_split
15624   [(set (match_operand:SF 0 "register_operand" "")
15625         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
15626                              (match_operand:SF 2 "nonimmediate_operand" ""))
15627                          (match_operand:SF 3 "register_operand" "")
15628                          (match_operand:SF 4 "nonimmediate_operand" "")))
15629    (clobber (reg:CC 17))]
15630   "SSE_REG_P (operands[0]) && reload_completed
15631    && ((operands_match_p (operands[1], operands[3])
15632         && operands_match_p (operands[2], operands[4]))
15633        || (operands_match_p (operands[1], operands[4])
15634            && operands_match_p (operands[2], operands[3])))"
15635   [(set (match_dup 0)
15636         (if_then_else:SF (lt (match_dup 1)
15637                              (match_dup 2))
15638                          (match_dup 1)
15639                          (match_dup 2)))])
15640
15641 ;; We can't represent the LT test directly.  Do this by swapping the operands.
15642
15643 (define_split
15644   [(set (match_operand:SF 0 "register_operand" "")
15645         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
15646                              (match_operand:SF 2 "register_operand" ""))
15647                          (match_operand:SF 3 "register_operand" "")
15648                          (match_operand:SF 4 "register_operand" "")))
15649    (clobber (reg:CC 17))]
15650   "FP_REG_P (operands[0]) && reload_completed
15651    && ((operands_match_p (operands[1], operands[3])
15652         && operands_match_p (operands[2], operands[4]))
15653        || (operands_match_p (operands[1], operands[4])
15654            && operands_match_p (operands[2], operands[3])))"
15655   [(set (reg:CCFP 17)
15656         (compare:CCFP (match_dup 2)
15657                       (match_dup 1)))
15658    (set (match_dup 0)
15659         (if_then_else:SF (ge (reg:CCFP 17) (const_int 0))
15660                          (match_dup 1)
15661                          (match_dup 2)))])
15662
15663 (define_insn "*minsf_sse"
15664   [(set (match_operand:SF 0 "register_operand" "=x")
15665         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
15666                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
15667                          (match_dup 1)
15668                          (match_dup 2)))]
15669   "TARGET_SSE && reload_completed"
15670   "minss\t{%2, %0|%0, %2}"
15671   [(set_attr "type" "sse")
15672    (set_attr "mode" "SF")])
15673
15674 (define_expand "mindf3"
15675   [(parallel [
15676      (set (match_operand:DF 0 "register_operand" "")
15677           (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
15678                                (match_operand:DF 2 "nonimmediate_operand" ""))
15679                            (match_dup 1)
15680                            (match_dup 2)))
15681      (clobber (reg:CC 17))])]
15682   "TARGET_SSE2 && TARGET_SSE_MATH"
15683   "#")
15684
15685 (define_insn "*mindf"
15686   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
15687         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
15688                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
15689                          (match_dup 1)
15690                          (match_dup 2)))
15691    (clobber (reg:CC 17))]
15692   "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
15693   "#")
15694
15695 (define_insn "*mindf_nonieee"
15696   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
15697         (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
15698                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
15699                          (match_dup 1)
15700                          (match_dup 2)))
15701    (clobber (reg:CC 17))]
15702   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
15703    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15704   "#")
15705
15706 (define_split
15707   [(set (match_operand:DF 0 "register_operand" "")
15708         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
15709                              (match_operand:DF 2 "nonimmediate_operand" ""))
15710                          (match_operand:DF 3 "register_operand" "")
15711                          (match_operand:DF 4 "nonimmediate_operand" "")))
15712    (clobber (reg:CC 17))]
15713   "SSE_REG_P (operands[0]) && reload_completed
15714    && ((operands_match_p (operands[1], operands[3])
15715         && operands_match_p (operands[2], operands[4]))
15716        || (operands_match_p (operands[1], operands[4])
15717            && operands_match_p (operands[2], operands[3])))"
15718   [(set (match_dup 0)
15719         (if_then_else:DF (lt (match_dup 1)
15720                              (match_dup 2))
15721                          (match_dup 1)
15722                          (match_dup 2)))])
15723
15724 ;; We can't represent the LT test directly.  Do this by swapping the operands.
15725 (define_split
15726   [(set (match_operand:DF 0 "register_operand" "")
15727         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
15728                              (match_operand:DF 2 "register_operand" ""))
15729                          (match_operand:DF 3 "register_operand" "")
15730                          (match_operand:DF 4 "register_operand" "")))
15731    (clobber (reg:CC 17))]
15732   "FP_REG_P (operands[0]) && reload_completed
15733    && ((operands_match_p (operands[1], operands[3])
15734         && operands_match_p (operands[2], operands[4]))
15735        || (operands_match_p (operands[1], operands[4])
15736            && operands_match_p (operands[2], operands[3])))"
15737   [(set (reg:CCFP 17)
15738         (compare:CCFP (match_dup 2)
15739                       (match_dup 2)))
15740    (set (match_dup 0)
15741         (if_then_else:DF (ge (reg:CCFP 17) (const_int 0))
15742                          (match_dup 1)
15743                          (match_dup 2)))])
15744
15745 (define_insn "*mindf_sse"
15746   [(set (match_operand:DF 0 "register_operand" "=Y")
15747         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
15748                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
15749                          (match_dup 1)
15750                          (match_dup 2)))]
15751   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
15752   "minsd\t{%2, %0|%0, %2}"
15753   [(set_attr "type" "sse")
15754    (set_attr "mode" "DF")])
15755
15756 (define_expand "maxsf3"
15757   [(parallel [
15758      (set (match_operand:SF 0 "register_operand" "")
15759           (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
15760                                (match_operand:SF 2 "nonimmediate_operand" ""))
15761                            (match_dup 1)
15762                            (match_dup 2)))
15763      (clobber (reg:CC 17))])]
15764   "TARGET_SSE"
15765   "#")
15766
15767 (define_insn "*maxsf"
15768   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
15769         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
15770                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
15771                          (match_dup 1)
15772                          (match_dup 2)))
15773    (clobber (reg:CC 17))]
15774   "TARGET_SSE && TARGET_IEEE_FP"
15775   "#")
15776
15777 (define_insn "*maxsf_nonieee"
15778   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
15779         (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
15780                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
15781                          (match_dup 1)
15782                          (match_dup 2)))
15783    (clobber (reg:CC 17))]
15784   "TARGET_SSE && !TARGET_IEEE_FP
15785    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15786   "#")
15787
15788 (define_split
15789   [(set (match_operand:SF 0 "register_operand" "")
15790         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
15791                              (match_operand:SF 2 "nonimmediate_operand" ""))
15792                          (match_operand:SF 3 "register_operand" "")
15793                          (match_operand:SF 4 "nonimmediate_operand" "")))
15794    (clobber (reg:CC 17))]
15795   "SSE_REG_P (operands[0]) && reload_completed
15796    && ((operands_match_p (operands[1], operands[3])
15797         && operands_match_p (operands[2], operands[4]))
15798        || (operands_match_p (operands[1], operands[4])
15799            && operands_match_p (operands[2], operands[3])))"
15800   [(set (match_dup 0)
15801         (if_then_else:SF (gt (match_dup 1)
15802                              (match_dup 2))
15803                          (match_dup 1)
15804                          (match_dup 2)))])
15805
15806 (define_split
15807   [(set (match_operand:SF 0 "register_operand" "")
15808         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
15809                              (match_operand:SF 2 "register_operand" ""))
15810                          (match_operand:SF 3 "register_operand" "")
15811                          (match_operand:SF 4 "register_operand" "")))
15812    (clobber (reg:CC 17))]
15813   "FP_REG_P (operands[0]) && reload_completed
15814    && ((operands_match_p (operands[1], operands[3])
15815         && operands_match_p (operands[2], operands[4]))
15816        || (operands_match_p (operands[1], operands[4])
15817            && operands_match_p (operands[2], operands[3])))"
15818   [(set (reg:CCFP 17)
15819         (compare:CCFP (match_dup 1)
15820                       (match_dup 2)))
15821    (set (match_dup 0)
15822         (if_then_else:SF (gt (reg:CCFP 17) (const_int 0))
15823                          (match_dup 1)
15824                          (match_dup 2)))])
15825
15826 (define_insn "*maxsf_sse"
15827   [(set (match_operand:SF 0 "register_operand" "=x")
15828         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
15829                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
15830                          (match_dup 1)
15831                          (match_dup 2)))]
15832   "TARGET_SSE && reload_completed"
15833   "maxss\t{%2, %0|%0, %2}"
15834   [(set_attr "type" "sse")
15835    (set_attr "mode" "SF")])
15836
15837 (define_expand "maxdf3"
15838   [(parallel [
15839      (set (match_operand:DF 0 "register_operand" "")
15840           (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
15841                                (match_operand:DF 2 "nonimmediate_operand" ""))
15842                            (match_dup 1)
15843                            (match_dup 2)))
15844      (clobber (reg:CC 17))])]
15845   "TARGET_SSE2 && TARGET_SSE_MATH"
15846   "#")
15847
15848 (define_insn "*maxdf"
15849   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
15850         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
15851                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
15852                          (match_dup 1)
15853                          (match_dup 2)))
15854    (clobber (reg:CC 17))]
15855   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
15856   "#")
15857
15858 (define_insn "*maxdf_nonieee"
15859   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
15860         (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
15861                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
15862                          (match_dup 1)
15863                          (match_dup 2)))
15864    (clobber (reg:CC 17))]
15865   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
15866    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15867   "#")
15868
15869 (define_split
15870   [(set (match_operand:DF 0 "register_operand" "")
15871         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
15872                              (match_operand:DF 2 "nonimmediate_operand" ""))
15873                          (match_operand:DF 3 "register_operand" "")
15874                          (match_operand:DF 4 "nonimmediate_operand" "")))
15875    (clobber (reg:CC 17))]
15876   "SSE_REG_P (operands[0]) && reload_completed
15877    && ((operands_match_p (operands[1], operands[3])
15878         && operands_match_p (operands[2], operands[4]))
15879        || (operands_match_p (operands[1], operands[4])
15880            && operands_match_p (operands[2], operands[3])))"
15881   [(set (match_dup 0)
15882         (if_then_else:DF (gt (match_dup 1)
15883                              (match_dup 2))
15884                          (match_dup 1)
15885                          (match_dup 2)))])
15886
15887 (define_split
15888   [(set (match_operand:DF 0 "register_operand" "")
15889         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
15890                              (match_operand:DF 2 "register_operand" ""))
15891                          (match_operand:DF 3 "register_operand" "")
15892                          (match_operand:DF 4 "register_operand" "")))
15893    (clobber (reg:CC 17))]
15894   "FP_REG_P (operands[0]) && reload_completed
15895    && ((operands_match_p (operands[1], operands[3])
15896         && operands_match_p (operands[2], operands[4]))
15897        || (operands_match_p (operands[1], operands[4])
15898            && operands_match_p (operands[2], operands[3])))"
15899   [(set (reg:CCFP 17)
15900         (compare:CCFP (match_dup 1)
15901                       (match_dup 2)))
15902    (set (match_dup 0)
15903         (if_then_else:DF (gt (reg:CCFP 17) (const_int 0))
15904                          (match_dup 1)
15905                          (match_dup 2)))])
15906
15907 (define_insn "*maxdf_sse"
15908   [(set (match_operand:DF 0 "register_operand" "=Y")
15909         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
15910                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
15911                          (match_dup 1)
15912                          (match_dup 2)))]
15913   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
15914   "maxsd\t{%2, %0|%0, %2}"
15915   [(set_attr "type" "sse")
15916    (set_attr "mode" "DF")])
15917 \f
15918 ;; Misc patterns (?)
15919
15920 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
15921 ;; Otherwise there will be nothing to keep
15922 ;; 
15923 ;; [(set (reg ebp) (reg esp))]
15924 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
15925 ;;  (clobber (eflags)]
15926 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
15927 ;;
15928 ;; in proper program order.
15929 (define_expand "pro_epilogue_adjust_stack"
15930   [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
15931                    (plus:SI (match_operand:SI 1 "register_operand" "0,r")
15932                             (match_operand:SI 2 "immediate_operand" "i,i")))
15933               (clobber (reg:CC 17))
15934               (clobber (mem:BLK (scratch)))])]
15935  ""
15936 {
15937   if (TARGET_64BIT)
15938     {
15939       emit_insn (gen_pro_epilogue_adjust_stack_rex64
15940                  (operands[0], operands[1], operands[2]));
15941       DONE;
15942     }
15943 })
15944
15945 (define_insn "*pro_epilogue_adjust_stack_1"
15946   [(set (match_operand:SI 0 "register_operand" "=r,r")
15947         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
15948                  (match_operand:SI 2 "immediate_operand" "i,i")))
15949    (clobber (reg:CC 17))
15950    (clobber (mem:BLK (scratch)))]
15951   "!TARGET_64BIT"
15952 {
15953   switch (get_attr_type (insn))
15954     {
15955     case TYPE_IMOV:
15956       return "mov{l}\t{%1, %0|%0, %1}";
15957
15958     case TYPE_ALU:
15959       if (GET_CODE (operands[2]) == CONST_INT
15960           && (INTVAL (operands[2]) == 128
15961               || (INTVAL (operands[2]) < 0
15962                   && INTVAL (operands[2]) != -128)))
15963         {
15964           operands[2] = GEN_INT (-INTVAL (operands[2]));
15965           return "sub{l}\t{%2, %0|%0, %2}";
15966         }
15967       return "add{l}\t{%2, %0|%0, %2}";
15968
15969     case TYPE_LEA:
15970       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
15971       return "lea{l}\t{%a2, %0|%0, %a2}";
15972
15973     default:
15974       abort ();
15975     }
15976 }
15977   [(set (attr "type")
15978         (cond [(eq_attr "alternative" "0")
15979                  (const_string "alu")
15980                (match_operand:SI 2 "const0_operand" "")
15981                  (const_string "imov")
15982               ]
15983               (const_string "lea")))
15984    (set_attr "mode" "SI")])
15985
15986 (define_insn "pro_epilogue_adjust_stack_rex64"
15987   [(set (match_operand:DI 0 "register_operand" "=r,r")
15988         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
15989                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
15990    (clobber (reg:CC 17))
15991    (clobber (mem:BLK (scratch)))]
15992   "TARGET_64BIT"
15993 {
15994   switch (get_attr_type (insn))
15995     {
15996     case TYPE_IMOV:
15997       return "mov{q}\t{%1, %0|%0, %1}";
15998
15999     case TYPE_ALU:
16000       if (GET_CODE (operands[2]) == CONST_INT
16001           && (INTVAL (operands[2]) == 128
16002               || (INTVAL (operands[2]) < 0
16003                   && INTVAL (operands[2]) != -128)))
16004         {
16005           operands[2] = GEN_INT (-INTVAL (operands[2]));
16006           return "sub{q}\t{%2, %0|%0, %2}";
16007         }
16008       return "add{q}\t{%2, %0|%0, %2}";
16009
16010     case TYPE_LEA:
16011       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16012       return "lea{q}\t{%a2, %0|%0, %a2}";
16013
16014     default:
16015       abort ();
16016     }
16017 }
16018   [(set (attr "type")
16019         (cond [(eq_attr "alternative" "0")
16020                  (const_string "alu")
16021                (match_operand:DI 2 "const0_operand" "")
16022                  (const_string "imov")
16023               ]
16024               (const_string "lea")))
16025    (set_attr "mode" "DI")])
16026
16027
16028 ;; Placeholder for the conditional moves.  This one is split either to SSE
16029 ;; based moves emulation or to usual cmove sequence.  Little bit unfortunate
16030 ;; fact is that compares supported by the cmp??ss instructions are exactly
16031 ;; swapped of those supported by cmove sequence.
16032 ;; The EQ/NE comparisons also needs bit care, since they are not directly
16033 ;; supported by i387 comparisons and we do need to emit two conditional moves
16034 ;; in tandem.
16035
16036 (define_insn "sse_movsfcc"
16037   [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?f#xr,?f#xr,?r#xf,?r#xf,?r#xf,?r#xf")
16038         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
16039                         [(match_operand:SF 4 "nonimmediate_operand" "0#fx,x#fx,f#x,f#x,xm#f,xm#f,f#x,f#x,xm#f,xm#f")
16040                          (match_operand:SF 5 "nonimmediate_operand" "xm#f,xm#f,f#x,f#x,x#f,x#f,f#x,f#x,x#f,x#f")])
16041                       (match_operand:SF 2 "nonimmediate_operand" "x#fr,0#fr,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx,0#rx")
16042                       (match_operand:SF 3 "nonimmediate_operand" "x#fr,x#fr,0#fx,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx")))
16043    (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
16044    (clobber (reg:CC 17))]
16045   "TARGET_SSE
16046    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
16047    && (!TARGET_IEEE_FP
16048        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
16049   "#")
16050
16051 (define_insn "sse_movsfcc_eq"
16052   [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
16053         (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
16054                              (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
16055                       (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
16056                       (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
16057    (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
16058    (clobber (reg:CC 17))]
16059   "TARGET_SSE
16060    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16061   "#")
16062
16063 (define_insn "sse_movdfcc"
16064   [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?f#Yr,?f#Yr,?r#Yf,?r#Yf,?r#Yf,?r#Yf")
16065         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
16066                         [(match_operand:DF 4 "nonimmediate_operand" "0#fY,Y#fY,f#Y,f#Y,Ym#f,Ym#f,f#Y,f#Y,Ym#f,Ym#f")
16067                          (match_operand:DF 5 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,f#Y,Y#f,Y#f,f#Y,f#Y,Y#f,Y#f")])
16068                       (match_operand:DF 2 "nonimmediate_operand" "Y#fr,0#fr,f#fY,0#fY,f#fY,0#fY,rm#rY,0#rY,rm#rY,0#rY")
16069                       (match_operand:DF 3 "nonimmediate_operand" "Y#fr,Y#fr,0#fY,f#fY,0#fY,f#fY,0#fY,rm#rY,0#rY,rm#rY")))
16070    (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
16071    (clobber (reg:CC 17))]
16072   "TARGET_SSE2
16073    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
16074    && (!TARGET_IEEE_FP
16075        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
16076   "#")
16077
16078 (define_insn "sse_movdfcc_eq"
16079   [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
16080         (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
16081                              (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
16082                       (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
16083                       (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
16084    (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
16085    (clobber (reg:CC 17))]
16086   "TARGET_SSE
16087    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16088   "#")
16089
16090 ;; For non-sse moves just expand the usual cmove sequence.
16091 (define_split
16092   [(set (match_operand 0 "register_operand" "")
16093         (if_then_else (match_operator 1 "comparison_operator"
16094                         [(match_operand 4 "nonimmediate_operand" "")
16095                          (match_operand 5 "register_operand" "")])
16096                       (match_operand 2 "nonimmediate_operand" "")
16097                       (match_operand 3 "nonimmediate_operand" "")))
16098    (clobber (match_operand 6 "" ""))
16099    (clobber (reg:CC 17))]
16100   "!SSE_REG_P (operands[0]) && reload_completed
16101    && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
16102   [(const_int 0)]
16103 {
16104    ix86_compare_op0 = operands[5];
16105    ix86_compare_op1 = operands[4];
16106    operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
16107                                  VOIDmode, operands[5], operands[4]);
16108    ix86_expand_fp_movcc (operands);
16109    DONE;
16110 })
16111
16112 ;; Split SSE based conditional move into seqence:
16113 ;; cmpCC op0, op4   -  set op0 to 0 or ffffffff depending on the comparison
16114 ;; and   op2, op0   -  zero op2 if comparison was false
16115 ;; nand  op0, op3   -  load op3 to op0 if comparison was false
16116 ;; or    op2, op0   -  get the non-zero one into the result.
16117 (define_split
16118   [(set (match_operand 0 "register_operand" "")
16119         (if_then_else (match_operator 1 "sse_comparison_operator"
16120                         [(match_operand 4 "register_operand" "")
16121                          (match_operand 5 "nonimmediate_operand" "")])
16122                       (match_operand 2 "register_operand" "")
16123                       (match_operand 3 "register_operand" "")))
16124    (clobber (match_operand 6 "" ""))
16125    (clobber (reg:CC 17))]
16126   "SSE_REG_P (operands[0]) && reload_completed"
16127   [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
16128    (set (subreg:TI (match_dup 2) 0) (and:TI (subreg:TI (match_dup 2) 0)
16129                                             (subreg:TI (match_dup 4) 0)))
16130    (set (subreg:TI (match_dup 4) 0) (and:TI (not:TI (subreg:TI (match_dup 4) 0))
16131                                             (subreg:TI (match_dup 3) 0)))
16132    (set (subreg:TI (match_dup 0) 0) (ior:TI (subreg:TI (match_dup 6) 0)
16133                                             (subreg:TI (match_dup 7) 0)))]
16134 {
16135   /* If op2 == op3, op3 will be clobbered before it is used.
16136      This should be optimized out though.  */
16137   if (operands_match_p (operands[2], operands[3]))
16138     abort ();
16139   PUT_MODE (operands[1], GET_MODE (operands[0]));
16140   if (operands_match_p (operands[0], operands[4]))
16141     operands[6] = operands[4], operands[7] = operands[2];
16142   else
16143     operands[6] = operands[2], operands[7] = operands[4];
16144 })
16145
16146 ;; Special case of conditional move we can handle effectivly.
16147 ;; Do not brother with the integer/floating point case, since these are
16148 ;; bot considerably slower, unlike in the generic case.
16149 (define_insn "*sse_movsfcc_const0_1"
16150   [(set (match_operand:SF 0 "register_operand" "=&x")
16151         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
16152                         [(match_operand:SF 4 "register_operand" "0")
16153                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
16154                       (match_operand:SF 2 "register_operand" "x")
16155                       (match_operand:SF 3 "const0_operand" "X")))]
16156   "TARGET_SSE"
16157   "#")
16158
16159 (define_insn "*sse_movsfcc_const0_2"
16160   [(set (match_operand:SF 0 "register_operand" "=&x")
16161         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
16162                         [(match_operand:SF 4 "register_operand" "0")
16163                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
16164                       (match_operand:SF 2 "const0_operand" "X")
16165                       (match_operand:SF 3 "register_operand" "x")))]
16166   "TARGET_SSE"
16167   "#")
16168
16169 (define_insn "*sse_movsfcc_const0_3"
16170   [(set (match_operand:SF 0 "register_operand" "=&x")
16171         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16172                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
16173                          (match_operand:SF 5 "register_operand" "0")])
16174                       (match_operand:SF 2 "register_operand" "x")
16175                       (match_operand:SF 3 "const0_operand" "X")))]
16176   "TARGET_SSE"
16177   "#")
16178
16179 (define_insn "*sse_movsfcc_const0_4"
16180   [(set (match_operand:SF 0 "register_operand" "=&x")
16181         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16182                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
16183                          (match_operand:SF 5 "register_operand" "0")])
16184                       (match_operand:SF 2 "const0_operand" "X")
16185                       (match_operand:SF 3 "register_operand" "x")))]
16186   "TARGET_SSE"
16187   "#")
16188
16189 (define_insn "*sse_movdfcc_const0_1"
16190   [(set (match_operand:DF 0 "register_operand" "=&Y")
16191         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
16192                         [(match_operand:DF 4 "register_operand" "0")
16193                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
16194                       (match_operand:DF 2 "register_operand" "Y")
16195                       (match_operand:DF 3 "const0_operand" "X")))]
16196   "TARGET_SSE2"
16197   "#")
16198
16199 (define_insn "*sse_movdfcc_const0_2"
16200   [(set (match_operand:DF 0 "register_operand" "=&Y")
16201         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
16202                         [(match_operand:DF 4 "register_operand" "0")
16203                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
16204                       (match_operand:DF 2 "const0_operand" "X")
16205                       (match_operand:DF 3 "register_operand" "Y")))]
16206   "TARGET_SSE2"
16207   "#")
16208
16209 (define_insn "*sse_movdfcc_const0_3"
16210   [(set (match_operand:DF 0 "register_operand" "=&Y")
16211         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16212                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
16213                          (match_operand:DF 5 "register_operand" "0")])
16214                       (match_operand:DF 2 "register_operand" "Y")
16215                       (match_operand:DF 3 "const0_operand" "X")))]
16216   "TARGET_SSE2"
16217   "#")
16218
16219 (define_insn "*sse_movdfcc_const0_4"
16220   [(set (match_operand:DF 0 "register_operand" "=&Y")
16221         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16222                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
16223                          (match_operand:DF 5 "register_operand" "0")])
16224                       (match_operand:DF 2 "const0_operand" "X")
16225                       (match_operand:DF 3 "register_operand" "Y")))]
16226   "TARGET_SSE2"
16227   "#")
16228
16229 (define_split
16230   [(set (match_operand 0 "register_operand" "")
16231         (if_then_else (match_operator 1 "comparison_operator"
16232                         [(match_operand 4 "register_operand" "")
16233                          (match_operand 5 "nonimmediate_operand" "")])
16234                       (match_operand 2 "nonmemory_operand" "")
16235                       (match_operand 3 "nonmemory_operand" "")))]
16236   "SSE_REG_P (operands[0]) && reload_completed
16237    && (const0_operand (operands[2], GET_MODE (operands[0]))
16238        || const0_operand (operands[3], GET_MODE (operands[0])))"
16239   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
16240    (set (subreg:TI (match_dup 0) 0) (and:TI (match_dup 6)
16241                                             (subreg:TI (match_dup 7) 0)))]
16242 {
16243   PUT_MODE (operands[1], GET_MODE (operands[0]));
16244   if (!sse_comparison_operator (operands[1], VOIDmode))
16245     {
16246       rtx tmp = operands[5];
16247       operands[5] = operands[4];
16248       operands[4] = tmp;
16249       PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
16250     }
16251   if (const0_operand (operands[2], GET_MODE (operands[0])))
16252     {
16253       operands[7] = operands[3];
16254       operands[6] = gen_rtx_NOT (TImode, gen_rtx_SUBREG (TImode, operands[0],
16255                                                          0));
16256     }
16257   else
16258     {
16259       operands[7] = operands[2];
16260       operands[6] = gen_rtx_SUBREG (TImode, operands[0], 0);
16261     }
16262 })
16263
16264 (define_expand "allocate_stack_worker"
16265   [(match_operand:SI 0 "register_operand" "")]
16266   "TARGET_STACK_PROBE"
16267 {
16268   if (TARGET_64BIT)
16269     emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
16270   else
16271     emit_insn (gen_allocate_stack_worker_1 (operands[0]));
16272   DONE;
16273 })
16274
16275 (define_insn "allocate_stack_worker_1"
16276   [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
16277    (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
16278    (clobber (match_dup 0))
16279    (clobber (reg:CC 17))]
16280   "!TARGET_64BIT && TARGET_STACK_PROBE"
16281   "call\t__alloca"
16282   [(set_attr "type" "multi")
16283    (set_attr "length" "5")])
16284
16285 (define_insn "allocate_stack_worker_rex64"
16286   [(unspec:DI [(match_operand:DI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
16287    (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
16288    (clobber (match_dup 0))
16289    (clobber (reg:CC 17))]
16290   "TARGET_64BIT && TARGET_STACK_PROBE"
16291   "call\t__alloca"
16292   [(set_attr "type" "multi")
16293    (set_attr "length" "5")])
16294
16295 (define_expand "allocate_stack"
16296   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
16297                    (minus:SI (reg:SI 7)
16298                              (match_operand:SI 1 "general_operand" "")))
16299               (clobber (reg:CC 17))])
16300    (parallel [(set (reg:SI 7)
16301                    (minus:SI (reg:SI 7) (match_dup 1)))
16302               (clobber (reg:CC 17))])]
16303   "TARGET_STACK_PROBE"
16304 {
16305 #ifdef CHECK_STACK_LIMIT
16306   if (GET_CODE (operands[1]) == CONST_INT
16307       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16308     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
16309                            operands[1]));
16310   else 
16311 #endif
16312     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
16313                                                             operands[1])));
16314
16315   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16316   DONE;
16317 })
16318
16319 (define_expand "builtin_setjmp_receiver"
16320   [(label_ref (match_operand 0 "" ""))]
16321   "!TARGET_64BIT && flag_pic"
16322 {
16323   emit_insn (gen_set_got (pic_offset_table_rtx));
16324   DONE;
16325 })
16326 \f
16327 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16328
16329 (define_split
16330   [(set (match_operand 0 "register_operand" "")
16331         (match_operator 3 "promotable_binary_operator"
16332            [(match_operand 1 "register_operand" "")
16333             (match_operand 2 "aligned_operand" "")]))
16334    (clobber (reg:CC 17))]
16335   "! TARGET_PARTIAL_REG_STALL && reload_completed
16336    && ((GET_MODE (operands[0]) == HImode 
16337         && ((!optimize_size && !TARGET_FAST_PREFIX)
16338             || GET_CODE (operands[2]) != CONST_INT
16339             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
16340        || (GET_MODE (operands[0]) == QImode 
16341            && (TARGET_PROMOTE_QImode || optimize_size)))"
16342   [(parallel [(set (match_dup 0)
16343                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16344               (clobber (reg:CC 17))])]
16345   "operands[0] = gen_lowpart (SImode, operands[0]);
16346    operands[1] = gen_lowpart (SImode, operands[1]);
16347    if (GET_CODE (operands[3]) != ASHIFT)
16348      operands[2] = gen_lowpart (SImode, operands[2]);
16349    PUT_MODE (operands[3], SImode);")
16350
16351 (define_split
16352   [(set (reg 17)
16353         (compare (and (match_operand 1 "aligned_operand" "")
16354                       (match_operand 2 "const_int_operand" ""))
16355                  (const_int 0)))
16356    (set (match_operand 0 "register_operand" "")
16357         (and (match_dup 1) (match_dup 2)))]
16358   "! TARGET_PARTIAL_REG_STALL && reload_completed
16359    && ix86_match_ccmode (insn, CCNOmode)
16360    && (GET_MODE (operands[0]) == HImode
16361        || (GET_MODE (operands[0]) == QImode 
16362            /* Ensure that the operand will remain sign extended immedaite.  */
16363            && INTVAL (operands[2]) >= 0
16364            && (TARGET_PROMOTE_QImode || optimize_size)))"
16365   [(parallel [(set (reg:CCNO 17)
16366                    (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
16367                                  (const_int 0)))
16368               (set (match_dup 0)
16369                    (and:SI (match_dup 1) (match_dup 2)))])]
16370   "operands[2]
16371      = gen_int_mode (INTVAL (operands[2])
16372                      & GET_MODE_MASK (GET_MODE (operands[0])),
16373                      SImode);
16374    operands[0] = gen_lowpart (SImode, operands[0]);
16375    operands[1] = gen_lowpart (SImode, operands[1]);")
16376
16377 ; Don't promote the QImode tests, as i386 don't have encoding of
16378 ; the test instruction with 32bit sign extended immediate and thus
16379 ; the code grows.
16380 (define_split
16381   [(set (reg 17)
16382         (compare (and (match_operand:HI 0 "aligned_operand" "")
16383                       (match_operand:HI 1 "const_int_operand" ""))
16384                  (const_int 0)))]
16385   "! TARGET_PARTIAL_REG_STALL && reload_completed
16386    && ix86_match_ccmode (insn, CCNOmode)
16387    && GET_MODE (operands[0]) == HImode"
16388   [(set (reg:CCNO 17)
16389         (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
16390                       (const_int 0)))]
16391   "operands[1]
16392      = gen_int_mode (INTVAL (operands[1])
16393                      & GET_MODE_MASK (GET_MODE (operands[0])),
16394                      SImode);
16395    operands[0] = gen_lowpart (SImode, operands[0]);")
16396
16397 (define_split
16398   [(set (match_operand 0 "register_operand" "")
16399         (neg (match_operand 1 "register_operand" "")))
16400    (clobber (reg:CC 17))]
16401   "! TARGET_PARTIAL_REG_STALL && reload_completed
16402    && (GET_MODE (operands[0]) == HImode
16403        || (GET_MODE (operands[0]) == QImode 
16404            && (TARGET_PROMOTE_QImode || optimize_size)))"
16405   [(parallel [(set (match_dup 0)
16406                    (neg:SI (match_dup 1)))
16407               (clobber (reg:CC 17))])]
16408   "operands[0] = gen_lowpart (SImode, operands[0]);
16409    operands[1] = gen_lowpart (SImode, operands[1]);")
16410
16411 (define_split
16412   [(set (match_operand 0 "register_operand" "")
16413         (not (match_operand 1 "register_operand" "")))]
16414   "! TARGET_PARTIAL_REG_STALL && reload_completed
16415    && (GET_MODE (operands[0]) == HImode
16416        || (GET_MODE (operands[0]) == QImode 
16417            && (TARGET_PROMOTE_QImode || optimize_size)))"
16418   [(set (match_dup 0)
16419         (not:SI (match_dup 1)))]
16420   "operands[0] = gen_lowpart (SImode, operands[0]);
16421    operands[1] = gen_lowpart (SImode, operands[1]);")
16422
16423 (define_split 
16424   [(set (match_operand 0 "register_operand" "")
16425         (if_then_else (match_operator 1 "comparison_operator" 
16426                                 [(reg 17) (const_int 0)])
16427                       (match_operand 2 "register_operand" "")
16428                       (match_operand 3 "register_operand" "")))]
16429   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16430    && (GET_MODE (operands[0]) == HImode
16431        || (GET_MODE (operands[0]) == QImode 
16432            && (TARGET_PROMOTE_QImode || optimize_size)))"
16433   [(set (match_dup 0)
16434         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16435   "operands[0] = gen_lowpart (SImode, operands[0]);
16436    operands[2] = gen_lowpart (SImode, operands[2]);
16437    operands[3] = gen_lowpart (SImode, operands[3]);")
16438                         
16439 \f
16440 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
16441 ;; transform a complex memory operation into two memory to register operations.
16442
16443 ;; Don't push memory operands
16444 (define_peephole2
16445   [(set (match_operand:SI 0 "push_operand" "")
16446         (match_operand:SI 1 "memory_operand" ""))
16447    (match_scratch:SI 2 "r")]
16448   "! optimize_size && ! TARGET_PUSH_MEMORY"
16449   [(set (match_dup 2) (match_dup 1))
16450    (set (match_dup 0) (match_dup 2))]
16451   "")
16452
16453 (define_peephole2
16454   [(set (match_operand:DI 0 "push_operand" "")
16455         (match_operand:DI 1 "memory_operand" ""))
16456    (match_scratch:DI 2 "r")]
16457   "! optimize_size && ! TARGET_PUSH_MEMORY"
16458   [(set (match_dup 2) (match_dup 1))
16459    (set (match_dup 0) (match_dup 2))]
16460   "")
16461
16462 ;; We need to handle SFmode only, because DFmode and XFmode is split to
16463 ;; SImode pushes.
16464 (define_peephole2
16465   [(set (match_operand:SF 0 "push_operand" "")
16466         (match_operand:SF 1 "memory_operand" ""))
16467    (match_scratch:SF 2 "r")]
16468   "! optimize_size && ! TARGET_PUSH_MEMORY"
16469   [(set (match_dup 2) (match_dup 1))
16470    (set (match_dup 0) (match_dup 2))]
16471   "")
16472
16473 (define_peephole2
16474   [(set (match_operand:HI 0 "push_operand" "")
16475         (match_operand:HI 1 "memory_operand" ""))
16476    (match_scratch:HI 2 "r")]
16477   "! optimize_size && ! TARGET_PUSH_MEMORY"
16478   [(set (match_dup 2) (match_dup 1))
16479    (set (match_dup 0) (match_dup 2))]
16480   "")
16481
16482 (define_peephole2
16483   [(set (match_operand:QI 0 "push_operand" "")
16484         (match_operand:QI 1 "memory_operand" ""))
16485    (match_scratch:QI 2 "q")]
16486   "! optimize_size && ! TARGET_PUSH_MEMORY"
16487   [(set (match_dup 2) (match_dup 1))
16488    (set (match_dup 0) (match_dup 2))]
16489   "")
16490
16491 ;; Don't move an immediate directly to memory when the instruction
16492 ;; gets too big.
16493 (define_peephole2
16494   [(match_scratch:SI 1 "r")
16495    (set (match_operand:SI 0 "memory_operand" "")
16496         (const_int 0))]
16497   "! optimize_size
16498    && ! TARGET_USE_MOV0
16499    && TARGET_SPLIT_LONG_MOVES
16500    && get_attr_length (insn) >= ix86_cost->large_insn
16501    && peep2_regno_dead_p (0, FLAGS_REG)"
16502   [(parallel [(set (match_dup 1) (const_int 0))
16503               (clobber (reg:CC 17))])
16504    (set (match_dup 0) (match_dup 1))]
16505   "")
16506
16507 (define_peephole2
16508   [(match_scratch:HI 1 "r")
16509    (set (match_operand:HI 0 "memory_operand" "")
16510         (const_int 0))]
16511   "! optimize_size
16512    && ! TARGET_USE_MOV0
16513    && TARGET_SPLIT_LONG_MOVES
16514    && get_attr_length (insn) >= ix86_cost->large_insn
16515    && peep2_regno_dead_p (0, FLAGS_REG)"
16516   [(parallel [(set (match_dup 2) (const_int 0))
16517               (clobber (reg:CC 17))])
16518    (set (match_dup 0) (match_dup 1))]
16519   "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
16520
16521 (define_peephole2
16522   [(match_scratch:QI 1 "q")
16523    (set (match_operand:QI 0 "memory_operand" "")
16524         (const_int 0))]
16525   "! optimize_size
16526    && ! TARGET_USE_MOV0
16527    && TARGET_SPLIT_LONG_MOVES
16528    && get_attr_length (insn) >= ix86_cost->large_insn
16529    && peep2_regno_dead_p (0, FLAGS_REG)"
16530   [(parallel [(set (match_dup 2) (const_int 0))
16531               (clobber (reg:CC 17))])
16532    (set (match_dup 0) (match_dup 1))]
16533   "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
16534
16535 (define_peephole2
16536   [(match_scratch:SI 2 "r")
16537    (set (match_operand:SI 0 "memory_operand" "")
16538         (match_operand:SI 1 "immediate_operand" ""))]
16539   "! optimize_size
16540    && get_attr_length (insn) >= ix86_cost->large_insn
16541    && TARGET_SPLIT_LONG_MOVES"
16542   [(set (match_dup 2) (match_dup 1))
16543    (set (match_dup 0) (match_dup 2))]
16544   "")
16545
16546 (define_peephole2
16547   [(match_scratch:HI 2 "r")
16548    (set (match_operand:HI 0 "memory_operand" "")
16549         (match_operand:HI 1 "immediate_operand" ""))]
16550   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
16551   && TARGET_SPLIT_LONG_MOVES"
16552   [(set (match_dup 2) (match_dup 1))
16553    (set (match_dup 0) (match_dup 2))]
16554   "")
16555
16556 (define_peephole2
16557   [(match_scratch:QI 2 "q")
16558    (set (match_operand:QI 0 "memory_operand" "")
16559         (match_operand:QI 1 "immediate_operand" ""))]
16560   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
16561   && TARGET_SPLIT_LONG_MOVES"
16562   [(set (match_dup 2) (match_dup 1))
16563    (set (match_dup 0) (match_dup 2))]
16564   "")
16565
16566 ;; Don't compare memory with zero, load and use a test instead.
16567 (define_peephole2
16568   [(set (reg 17)
16569         (compare (match_operand:SI 0 "memory_operand" "")
16570                  (const_int 0)))
16571    (match_scratch:SI 3 "r")]
16572   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
16573   [(set (match_dup 3) (match_dup 0))
16574    (set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
16575   "")
16576
16577 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
16578 ;; Don't split NOTs with a displacement operand, because resulting XOR
16579 ;; will not be pariable anyway.
16580 ;;
16581 ;; On AMD K6, NOT is vector decoded with memory operand that can not be
16582 ;; represented using a modRM byte.  The XOR replacement is long decoded,
16583 ;; so this split helps here as well.
16584 ;;
16585 ;; Note: Can't do this as a regular split because we can't get proper
16586 ;; lifetime information then.
16587
16588 (define_peephole2
16589   [(set (match_operand:SI 0 "nonimmediate_operand" "")
16590         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
16591   "!optimize_size
16592    && peep2_regno_dead_p (0, FLAGS_REG)
16593    && ((TARGET_PENTIUM 
16594         && (GET_CODE (operands[0]) != MEM
16595             || !memory_displacement_operand (operands[0], SImode)))
16596        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
16597   [(parallel [(set (match_dup 0)
16598                    (xor:SI (match_dup 1) (const_int -1)))
16599               (clobber (reg:CC 17))])]
16600   "")
16601
16602 (define_peephole2
16603   [(set (match_operand:HI 0 "nonimmediate_operand" "")
16604         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
16605   "!optimize_size
16606    && peep2_regno_dead_p (0, FLAGS_REG)
16607    && ((TARGET_PENTIUM 
16608         && (GET_CODE (operands[0]) != MEM
16609             || !memory_displacement_operand (operands[0], HImode)))
16610        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
16611   [(parallel [(set (match_dup 0)
16612                    (xor:HI (match_dup 1) (const_int -1)))
16613               (clobber (reg:CC 17))])]
16614   "")
16615
16616 (define_peephole2
16617   [(set (match_operand:QI 0 "nonimmediate_operand" "")
16618         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
16619   "!optimize_size
16620    && peep2_regno_dead_p (0, FLAGS_REG)
16621    && ((TARGET_PENTIUM 
16622         && (GET_CODE (operands[0]) != MEM
16623             || !memory_displacement_operand (operands[0], QImode)))
16624        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
16625   [(parallel [(set (match_dup 0)
16626                    (xor:QI (match_dup 1) (const_int -1)))
16627               (clobber (reg:CC 17))])]
16628   "")
16629
16630 ;; Non pairable "test imm, reg" instructions can be translated to
16631 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
16632 ;; byte opcode instead of two, have a short form for byte operands),
16633 ;; so do it for other CPUs as well.  Given that the value was dead,
16634 ;; this should not create any new dependencies.  Pass on the sub-word
16635 ;; versions if we're concerned about partial register stalls.
16636
16637 (define_peephole2
16638   [(set (reg 17)
16639         (compare (and:SI (match_operand:SI 0 "register_operand" "")
16640                          (match_operand:SI 1 "immediate_operand" ""))
16641                  (const_int 0)))]
16642   "ix86_match_ccmode (insn, CCNOmode)
16643    && (true_regnum (operands[0]) != 0
16644        || (GET_CODE (operands[1]) == CONST_INT
16645            && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')))
16646    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
16647   [(parallel
16648      [(set (reg:CCNO 17)
16649            (compare:CCNO (and:SI (match_dup 0)
16650                                  (match_dup 1))
16651                          (const_int 0)))
16652       (set (match_dup 0)
16653            (and:SI (match_dup 0) (match_dup 1)))])]
16654   "")
16655
16656 ;; We don't need to handle HImode case, because it will be promoted to SImode
16657 ;; on ! TARGET_PARTIAL_REG_STALL
16658
16659 (define_peephole2
16660   [(set (reg 17)
16661         (compare (and:QI (match_operand:QI 0 "register_operand" "")
16662                          (match_operand:QI 1 "immediate_operand" ""))
16663                  (const_int 0)))]
16664   "! TARGET_PARTIAL_REG_STALL
16665    && ix86_match_ccmode (insn, CCNOmode)
16666    && true_regnum (operands[0]) != 0
16667    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
16668   [(parallel
16669      [(set (reg:CCNO 17)
16670            (compare:CCNO (and:QI (match_dup 0)
16671                                  (match_dup 1))
16672                          (const_int 0)))
16673       (set (match_dup 0)
16674            (and:QI (match_dup 0) (match_dup 1)))])]
16675   "")
16676
16677 (define_peephole2
16678   [(set (reg 17)
16679         (compare
16680           (and:SI
16681             (zero_extract:SI
16682               (match_operand 0 "ext_register_operand" "")
16683               (const_int 8)
16684               (const_int 8))
16685             (match_operand 1 "const_int_operand" ""))
16686           (const_int 0)))]
16687   "! TARGET_PARTIAL_REG_STALL
16688    && ix86_match_ccmode (insn, CCNOmode)
16689    && true_regnum (operands[0]) != 0
16690    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
16691   [(parallel [(set (reg:CCNO 17)
16692                    (compare:CCNO
16693                        (and:SI
16694                          (zero_extract:SI
16695                          (match_dup 0)
16696                          (const_int 8)
16697                          (const_int 8))
16698                         (match_dup 1))
16699                    (const_int 0)))
16700               (set (zero_extract:SI (match_dup 0)
16701                                     (const_int 8)
16702                                     (const_int 8))
16703                    (and:SI 
16704                      (zero_extract:SI
16705                        (match_dup 0)
16706                        (const_int 8)
16707                        (const_int 8))
16708                      (match_dup 1)))])]
16709   "")
16710
16711 ;; Don't do logical operations with memory inputs.
16712 (define_peephole2
16713   [(match_scratch:SI 2 "r")
16714    (parallel [(set (match_operand:SI 0 "register_operand" "")
16715                    (match_operator:SI 3 "arith_or_logical_operator"
16716                      [(match_dup 0)
16717                       (match_operand:SI 1 "memory_operand" "")]))
16718               (clobber (reg:CC 17))])]
16719   "! optimize_size && ! TARGET_READ_MODIFY"
16720   [(set (match_dup 2) (match_dup 1))
16721    (parallel [(set (match_dup 0)
16722                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16723               (clobber (reg:CC 17))])]
16724   "")
16725
16726 (define_peephole2
16727   [(match_scratch:SI 2 "r")
16728    (parallel [(set (match_operand:SI 0 "register_operand" "")
16729                    (match_operator:SI 3 "arith_or_logical_operator"
16730                      [(match_operand:SI 1 "memory_operand" "")
16731                       (match_dup 0)]))
16732               (clobber (reg:CC 17))])]
16733   "! optimize_size && ! TARGET_READ_MODIFY"
16734   [(set (match_dup 2) (match_dup 1))
16735    (parallel [(set (match_dup 0)
16736                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16737               (clobber (reg:CC 17))])]
16738   "")
16739
16740 ; Don't do logical operations with memory outputs
16741 ;
16742 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16743 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
16744 ; the same decoder scheduling characteristics as the original.
16745
16746 (define_peephole2
16747   [(match_scratch:SI 2 "r")
16748    (parallel [(set (match_operand:SI 0 "memory_operand" "")
16749                    (match_operator:SI 3 "arith_or_logical_operator"
16750                      [(match_dup 0)
16751                       (match_operand:SI 1 "nonmemory_operand" "")]))
16752               (clobber (reg:CC 17))])]
16753   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
16754   [(set (match_dup 2) (match_dup 0))
16755    (parallel [(set (match_dup 2)
16756                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16757               (clobber (reg:CC 17))])
16758    (set (match_dup 0) (match_dup 2))]
16759   "")
16760
16761 (define_peephole2
16762   [(match_scratch:SI 2 "r")
16763    (parallel [(set (match_operand:SI 0 "memory_operand" "")
16764                    (match_operator:SI 3 "arith_or_logical_operator"
16765                      [(match_operand:SI 1 "nonmemory_operand" "")
16766                       (match_dup 0)]))
16767               (clobber (reg:CC 17))])]
16768   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
16769   [(set (match_dup 2) (match_dup 0))
16770    (parallel [(set (match_dup 2)
16771                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16772               (clobber (reg:CC 17))])
16773    (set (match_dup 0) (match_dup 2))]
16774   "")
16775
16776 ;; Attempt to always use XOR for zeroing registers.
16777 (define_peephole2
16778   [(set (match_operand 0 "register_operand" "")
16779         (const_int 0))]
16780   "(GET_MODE (operands[0]) == QImode
16781     || GET_MODE (operands[0]) == HImode
16782     || GET_MODE (operands[0]) == SImode
16783     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
16784    && (! TARGET_USE_MOV0 || optimize_size)
16785    && peep2_regno_dead_p (0, FLAGS_REG)"
16786   [(parallel [(set (match_dup 0) (const_int 0))
16787               (clobber (reg:CC 17))])]
16788   "operands[0] = gen_rtx_REG (GET_MODE (operands[0]) == DImode ? DImode : SImode,
16789                               true_regnum (operands[0]));")
16790
16791 (define_peephole2
16792   [(set (strict_low_part (match_operand 0 "register_operand" ""))
16793         (const_int 0))]
16794   "(GET_MODE (operands[0]) == QImode
16795     || GET_MODE (operands[0]) == HImode)
16796    && (! TARGET_USE_MOV0 || optimize_size)
16797    && peep2_regno_dead_p (0, FLAGS_REG)"
16798   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
16799               (clobber (reg:CC 17))])])
16800
16801 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
16802 (define_peephole2
16803   [(set (match_operand 0 "register_operand" "")
16804         (const_int -1))]
16805   "(GET_MODE (operands[0]) == HImode
16806     || GET_MODE (operands[0]) == SImode 
16807     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
16808    && (optimize_size || TARGET_PENTIUM)
16809    && peep2_regno_dead_p (0, FLAGS_REG)"
16810   [(parallel [(set (match_dup 0) (const_int -1))
16811               (clobber (reg:CC 17))])]
16812   "operands[0] = gen_rtx_REG (GET_MODE (operands[0]) == DImode ? DImode : SImode,
16813                               true_regnum (operands[0]));")
16814
16815 ;; Attempt to convert simple leas to adds. These can be created by
16816 ;; move expanders.
16817 (define_peephole2
16818   [(set (match_operand:SI 0 "register_operand" "")
16819         (plus:SI (match_dup 0)
16820                  (match_operand:SI 1 "nonmemory_operand" "")))]
16821   "peep2_regno_dead_p (0, FLAGS_REG)"
16822   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
16823               (clobber (reg:CC 17))])]
16824   "")
16825
16826 (define_peephole2
16827   [(set (match_operand:SI 0 "register_operand" "")
16828         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
16829                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
16830   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
16831   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
16832               (clobber (reg:CC 17))])]
16833   "operands[2] = gen_lowpart (SImode, operands[2]);")
16834
16835 (define_peephole2
16836   [(set (match_operand:DI 0 "register_operand" "")
16837         (plus:DI (match_dup 0)
16838                  (match_operand:DI 1 "x86_64_general_operand" "")))]
16839   "peep2_regno_dead_p (0, FLAGS_REG)"
16840   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
16841               (clobber (reg:CC 17))])]
16842   "")
16843
16844 (define_peephole2
16845   [(set (match_operand:SI 0 "register_operand" "")
16846         (mult:SI (match_dup 0)
16847                  (match_operand:SI 1 "const_int_operand" "")))]
16848   "exact_log2 (INTVAL (operands[1])) >= 0
16849    && peep2_regno_dead_p (0, FLAGS_REG)"
16850   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
16851               (clobber (reg:CC 17))])]
16852   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
16853
16854 (define_peephole2
16855   [(set (match_operand:DI 0 "register_operand" "")
16856         (mult:DI (match_dup 0)
16857                  (match_operand:DI 1 "const_int_operand" "")))]
16858   "exact_log2 (INTVAL (operands[1])) >= 0
16859    && peep2_regno_dead_p (0, FLAGS_REG)"
16860   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
16861               (clobber (reg:CC 17))])]
16862   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
16863
16864 (define_peephole2
16865   [(set (match_operand:SI 0 "register_operand" "")
16866         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
16867                    (match_operand:DI 2 "const_int_operand" "")) 0))]
16868   "exact_log2 (INTVAL (operands[1])) >= 0
16869    && REGNO (operands[0]) == REGNO (operands[1])
16870    && peep2_regno_dead_p (0, FLAGS_REG)"
16871   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
16872               (clobber (reg:CC 17))])]
16873   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
16874
16875 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
16876 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
16877 ;; many CPUs it is also faster, since special hardware to avoid esp
16878 ;; dependencies is present.
16879
16880 ;; While some of these conversions may be done using splitters, we use peepholes
16881 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
16882
16883 ;; Convert prologue esp subtractions to push.
16884 ;; We need register to push.  In order to keep verify_flow_info happy we have
16885 ;; two choices
16886 ;; - use scratch and clobber it in order to avoid dependencies
16887 ;; - use already live register
16888 ;; We can't use the second way right now, since there is no reliable way how to
16889 ;; verify that given register is live.  First choice will also most likely in
16890 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
16891 ;; call clobbered registers are dead.  We may want to use base pointer as an
16892 ;; alternative when no register is available later.
16893
16894 (define_peephole2
16895   [(match_scratch:SI 0 "r")
16896    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
16897               (clobber (reg:CC 17))
16898               (clobber (mem:BLK (scratch)))])]
16899   "optimize_size || !TARGET_SUB_ESP_4"
16900   [(clobber (match_dup 0))
16901    (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
16902               (clobber (mem:BLK (scratch)))])])
16903
16904 (define_peephole2
16905   [(match_scratch:SI 0 "r")
16906    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
16907               (clobber (reg:CC 17))
16908               (clobber (mem:BLK (scratch)))])]
16909   "optimize_size || !TARGET_SUB_ESP_8"
16910   [(clobber (match_dup 0))
16911    (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
16912    (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
16913               (clobber (mem:BLK (scratch)))])])
16914
16915 ;; Convert esp subtractions to push.
16916 (define_peephole2
16917   [(match_scratch:SI 0 "r")
16918    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
16919               (clobber (reg:CC 17))])]
16920   "optimize_size || !TARGET_SUB_ESP_4"
16921   [(clobber (match_dup 0))
16922    (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
16923
16924 (define_peephole2
16925   [(match_scratch:SI 0 "r")
16926    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
16927               (clobber (reg:CC 17))])]
16928   "optimize_size || !TARGET_SUB_ESP_8"
16929   [(clobber (match_dup 0))
16930    (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
16931    (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
16932
16933 ;; Convert epilogue deallocator to pop.
16934 (define_peephole2
16935   [(match_scratch:SI 0 "r")
16936    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
16937               (clobber (reg:CC 17))
16938               (clobber (mem:BLK (scratch)))])]
16939   "optimize_size || !TARGET_ADD_ESP_4"
16940   [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
16941               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
16942               (clobber (mem:BLK (scratch)))])]
16943   "")
16944
16945 ;; Two pops case is tricky, since pop causes dependency on destination register.
16946 ;; We use two registers if available.
16947 (define_peephole2
16948   [(match_scratch:SI 0 "r")
16949    (match_scratch:SI 1 "r")
16950    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
16951               (clobber (reg:CC 17))
16952               (clobber (mem:BLK (scratch)))])]
16953   "optimize_size || !TARGET_ADD_ESP_8"
16954   [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
16955               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
16956               (clobber (mem:BLK (scratch)))])
16957    (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
16958               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
16959   "")
16960
16961 (define_peephole2
16962   [(match_scratch:SI 0 "r")
16963    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
16964               (clobber (reg:CC 17))
16965               (clobber (mem:BLK (scratch)))])]
16966   "optimize_size"
16967   [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
16968               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
16969               (clobber (mem:BLK (scratch)))])
16970    (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
16971               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
16972   "")
16973
16974 ;; Convert esp additions to pop.
16975 (define_peephole2
16976   [(match_scratch:SI 0 "r")
16977    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
16978               (clobber (reg:CC 17))])]
16979   ""
16980   [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
16981               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
16982   "")
16983
16984 ;; Two pops case is tricky, since pop causes dependency on destination register.
16985 ;; We use two registers if available.
16986 (define_peephole2
16987   [(match_scratch:SI 0 "r")
16988    (match_scratch:SI 1 "r")
16989    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
16990               (clobber (reg:CC 17))])]
16991   ""
16992   [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
16993               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
16994    (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
16995               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
16996   "")
16997
16998 (define_peephole2
16999   [(match_scratch:SI 0 "r")
17000    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
17001               (clobber (reg:CC 17))])]
17002   "optimize_size"
17003   [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17004               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
17005    (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17006               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17007   "")
17008 \f
17009 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17010 ;; required and register dies.
17011 (define_peephole2
17012   [(set (reg 17)
17013         (compare (match_operand:SI 0 "register_operand" "")
17014                  (match_operand:SI 1 "incdec_operand" "")))]
17015   "ix86_match_ccmode (insn, CCGCmode)
17016    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17017   [(parallel [(set (reg:CCGC 17)
17018                    (compare:CCGC (match_dup 0)
17019                                  (match_dup 1)))
17020               (clobber (match_dup 0))])]
17021   "")
17022
17023 (define_peephole2
17024   [(set (reg 17)
17025         (compare (match_operand:HI 0 "register_operand" "")
17026                  (match_operand:HI 1 "incdec_operand" "")))]
17027   "ix86_match_ccmode (insn, CCGCmode)
17028    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17029   [(parallel [(set (reg:CCGC 17)
17030                    (compare:CCGC (match_dup 0)
17031                                  (match_dup 1)))
17032               (clobber (match_dup 0))])]
17033   "")
17034
17035 (define_peephole2
17036   [(set (reg 17)
17037         (compare (match_operand:QI 0 "register_operand" "")
17038                  (match_operand:QI 1 "incdec_operand" "")))]
17039   "ix86_match_ccmode (insn, CCGCmode)
17040    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17041   [(parallel [(set (reg:CCGC 17)
17042                    (compare:CCGC (match_dup 0)
17043                                  (match_dup 1)))
17044               (clobber (match_dup 0))])]
17045   "")
17046
17047 ;; Convert compares with 128 to shorter add -128
17048 (define_peephole2
17049   [(set (reg 17)
17050         (compare (match_operand:SI 0 "register_operand" "")
17051                  (const_int 128)))]
17052   "ix86_match_ccmode (insn, CCGCmode)
17053    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17054   [(parallel [(set (reg:CCGC 17)
17055                    (compare:CCGC (match_dup 0)
17056                                  (const_int 128)))
17057               (clobber (match_dup 0))])]
17058   "")
17059
17060 (define_peephole2
17061   [(set (reg 17)
17062         (compare (match_operand:HI 0 "register_operand" "")
17063                  (const_int 128)))]
17064   "ix86_match_ccmode (insn, CCGCmode)
17065    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17066   [(parallel [(set (reg:CCGC 17)
17067                    (compare:CCGC (match_dup 0)
17068                                  (const_int 128)))
17069               (clobber (match_dup 0))])]
17070   "")
17071 \f
17072 (define_peephole2
17073   [(match_scratch:DI 0 "r")
17074    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
17075               (clobber (reg:CC 17))
17076               (clobber (mem:BLK (scratch)))])]
17077   "optimize_size || !TARGET_SUB_ESP_4"
17078   [(clobber (match_dup 0))
17079    (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
17080               (clobber (mem:BLK (scratch)))])])
17081
17082 (define_peephole2
17083   [(match_scratch:DI 0 "r")
17084    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
17085               (clobber (reg:CC 17))
17086               (clobber (mem:BLK (scratch)))])]
17087   "optimize_size || !TARGET_SUB_ESP_8"
17088   [(clobber (match_dup 0))
17089    (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
17090    (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
17091               (clobber (mem:BLK (scratch)))])])
17092
17093 ;; Convert esp subtractions to push.
17094 (define_peephole2
17095   [(match_scratch:DI 0 "r")
17096    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
17097               (clobber (reg:CC 17))])]
17098   "optimize_size || !TARGET_SUB_ESP_4"
17099   [(clobber (match_dup 0))
17100    (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
17101
17102 (define_peephole2
17103   [(match_scratch:DI 0 "r")
17104    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
17105               (clobber (reg:CC 17))])]
17106   "optimize_size || !TARGET_SUB_ESP_8"
17107   [(clobber (match_dup 0))
17108    (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
17109    (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
17110
17111 ;; Convert epilogue deallocator to pop.
17112 (define_peephole2
17113   [(match_scratch:DI 0 "r")
17114    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
17115               (clobber (reg:CC 17))
17116               (clobber (mem:BLK (scratch)))])]
17117   "optimize_size || !TARGET_ADD_ESP_4"
17118   [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17119               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
17120               (clobber (mem:BLK (scratch)))])]
17121   "")
17122
17123 ;; Two pops case is tricky, since pop causes dependency on destination register.
17124 ;; We use two registers if available.
17125 (define_peephole2
17126   [(match_scratch:DI 0 "r")
17127    (match_scratch:DI 1 "r")
17128    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
17129               (clobber (reg:CC 17))
17130               (clobber (mem:BLK (scratch)))])]
17131   "optimize_size || !TARGET_ADD_ESP_8"
17132   [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17133               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
17134               (clobber (mem:BLK (scratch)))])
17135    (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
17136               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
17137   "")
17138
17139 (define_peephole2
17140   [(match_scratch:DI 0 "r")
17141    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
17142               (clobber (reg:CC 17))
17143               (clobber (mem:BLK (scratch)))])]
17144   "optimize_size"
17145   [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17146               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
17147               (clobber (mem:BLK (scratch)))])
17148    (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17149               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
17150   "")
17151
17152 ;; Convert esp additions to pop.
17153 (define_peephole2
17154   [(match_scratch:DI 0 "r")
17155    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
17156               (clobber (reg:CC 17))])]
17157   ""
17158   [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17159               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
17160   "")
17161
17162 ;; Two pops case is tricky, since pop causes dependency on destination register.
17163 ;; We use two registers if available.
17164 (define_peephole2
17165   [(match_scratch:DI 0 "r")
17166    (match_scratch:DI 1 "r")
17167    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
17168               (clobber (reg:CC 17))])]
17169   ""
17170   [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17171               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
17172    (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
17173               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
17174   "")
17175
17176 (define_peephole2
17177   [(match_scratch:DI 0 "r")
17178    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
17179               (clobber (reg:CC 17))])]
17180   "optimize_size"
17181   [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17182               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
17183    (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17184               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
17185   "")
17186 \f
17187 ;; Call-value patterns last so that the wildcard operand does not
17188 ;; disrupt insn-recog's switch tables.
17189
17190 (define_insn "*call_value_pop_0"
17191   [(set (match_operand 0 "" "")
17192         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17193               (match_operand:SI 2 "" "")))
17194    (set (reg:SI 7) (plus:SI (reg:SI 7)
17195                             (match_operand:SI 3 "immediate_operand" "")))]
17196   "!TARGET_64BIT"
17197 {
17198   if (SIBLING_CALL_P (insn))
17199     return "jmp\t%P1";
17200   else
17201     return "call\t%P1";
17202 }
17203   [(set_attr "type" "callv")])
17204
17205 (define_insn "*call_value_pop_1"
17206   [(set (match_operand 0 "" "")
17207         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
17208               (match_operand:SI 2 "" "")))
17209    (set (reg:SI 7) (plus:SI (reg:SI 7)
17210                             (match_operand:SI 3 "immediate_operand" "i")))]
17211   "!TARGET_64BIT"
17212 {
17213   if (constant_call_address_operand (operands[1], QImode))
17214     {
17215       if (SIBLING_CALL_P (insn))
17216         return "jmp\t%P1";
17217       else
17218         return "call\t%P1";
17219     }
17220   if (SIBLING_CALL_P (insn))
17221     return "jmp\t%A1";
17222   else
17223     return "call\t%A1";
17224 }
17225   [(set_attr "type" "callv")])
17226
17227 (define_insn "*call_value_0"
17228   [(set (match_operand 0 "" "")
17229         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17230               (match_operand:SI 2 "" "")))]
17231   "!TARGET_64BIT"
17232 {
17233   if (SIBLING_CALL_P (insn))
17234     return "jmp\t%P1";
17235   else
17236     return "call\t%P1";
17237 }
17238   [(set_attr "type" "callv")])
17239
17240 (define_insn "*call_value_0_rex64"
17241   [(set (match_operand 0 "" "")
17242         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17243               (match_operand:DI 2 "const_int_operand" "")))]
17244   "TARGET_64BIT"
17245 {
17246   if (SIBLING_CALL_P (insn))
17247     return "jmp\t%P1";
17248   else
17249     return "call\t%P1";
17250 }
17251   [(set_attr "type" "callv")])
17252
17253 (define_insn "*call_value_1"
17254   [(set (match_operand 0 "" "")
17255         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
17256               (match_operand:SI 2 "" "")))]
17257   "!TARGET_64BIT"
17258 {
17259   if (constant_call_address_operand (operands[1], QImode))
17260     {
17261       if (SIBLING_CALL_P (insn))
17262         return "jmp\t%P1";
17263       else
17264         return "call\t%P1";
17265     }
17266   if (SIBLING_CALL_P (insn))
17267     return "jmp\t%*%1";
17268   else
17269     return "call\t%*%1";
17270 }
17271   [(set_attr "type" "callv")])
17272
17273 (define_insn "*call_value_1_rex64"
17274   [(set (match_operand 0 "" "")
17275         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17276               (match_operand:DI 2 "" "")))]
17277   "TARGET_64BIT"
17278 {
17279   if (constant_call_address_operand (operands[1], QImode))
17280     {
17281       if (SIBLING_CALL_P (insn))
17282         return "jmp\t%P1";
17283       else
17284         return "call\t%P1";
17285     }
17286   if (SIBLING_CALL_P (insn))
17287     return "jmp\t%A1";
17288   else
17289     return "call\t%A1";
17290 }
17291   [(set_attr "type" "callv")])
17292 \f
17293 (define_insn "trap"
17294   [(trap_if (const_int 1) (const_int 5))]
17295   ""
17296   "int\t$5")
17297
17298 ;;; ix86 doesn't have conditional trap instructions, but we fake them
17299 ;;; for the sake of bounds checking.  By emitting bounds checks as
17300 ;;; conditional traps rather than as conditional jumps around
17301 ;;; unconditional traps we avoid introducing spurious basic-block
17302 ;;; boundaries and facilitate elimination of redundant checks.  In
17303 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
17304 ;;; interrupt 5.
17305 ;;; 
17306 ;;; FIXME: Static branch prediction rules for ix86 are such that
17307 ;;; forward conditional branches predict as untaken.  As implemented
17308 ;;; below, pseudo conditional traps violate that rule.  We should use
17309 ;;; .pushsection/.popsection to place all of the `int 5's in a special
17310 ;;; section loaded at the end of the text segment and branch forward
17311 ;;; there on bounds-failure, and then jump back immediately (in case
17312 ;;; the system chooses to ignore bounds violations, or to report
17313 ;;; violations and continue execution).
17314
17315 (define_expand "conditional_trap"
17316   [(trap_if (match_operator 0 "comparison_operator"
17317              [(match_dup 2) (const_int 0)])
17318             (match_operand 1 "const_int_operand" ""))]
17319   ""
17320 {
17321   emit_insn (gen_rtx_TRAP_IF (VOIDmode,
17322                               ix86_expand_compare (GET_CODE (operands[0]),
17323                                                    NULL, NULL),
17324                               operands[1]));
17325   DONE;
17326 })
17327
17328 (define_insn "*conditional_trap_1"
17329   [(trap_if (match_operator 0 "comparison_operator"
17330              [(reg 17) (const_int 0)])
17331             (match_operand 1 "const_int_operand" ""))]
17332   ""
17333 {
17334   operands[2] = gen_label_rtx ();
17335   output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
17336   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
17337                              CODE_LABEL_NUMBER (operands[2]));
17338   RET;
17339 })
17340
17341         ;; Pentium III SIMD instructions.
17342
17343 ;; Moves for SSE/MMX regs.
17344
17345 (define_insn "movv4sf_internal"
17346   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
17347         (match_operand:V4SF 1 "nonimmediate_operand" "xm,x"))]
17348   "TARGET_SSE"
17349   ;; @@@ let's try to use movaps here.
17350   "movaps\t{%1, %0|%0, %1}"
17351   [(set_attr "type" "ssemov")
17352    (set_attr "mode" "V4SF")])
17353
17354 (define_insn "movv4si_internal"
17355   [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,m")
17356         (match_operand:V4SI 1 "nonimmediate_operand" "xm,x"))]
17357   "TARGET_SSE"
17358   ;; @@@ let's try to use movaps here.
17359   "movaps\t{%1, %0|%0, %1}"
17360   [(set_attr "type" "ssemov")
17361    (set_attr "mode" "V4SF")])
17362
17363 (define_insn "movv8qi_internal"
17364   [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,m")
17365         (match_operand:V8QI 1 "nonimmediate_operand" "ym,y"))]
17366   "TARGET_MMX"
17367   "movq\t{%1, %0|%0, %1}"
17368   [(set_attr "type" "mmxmov")
17369    (set_attr "mode" "DI")])
17370
17371 (define_insn "movv4hi_internal"
17372   [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,m")
17373         (match_operand:V4HI 1 "nonimmediate_operand" "ym,y"))]
17374   "TARGET_MMX"
17375   "movq\t{%1, %0|%0, %1}"
17376   [(set_attr "type" "mmxmov")
17377    (set_attr "mode" "DI")])
17378
17379 (define_insn "movv2si_internal"
17380   [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,m")
17381         (match_operand:V2SI 1 "nonimmediate_operand" "ym,y"))]
17382   "TARGET_MMX"
17383   "movq\t{%1, %0|%0, %1}"
17384   [(set_attr "type" "mmxcvt")
17385    (set_attr "mode" "DI")])
17386
17387 (define_insn "movv2sf_internal"
17388   [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,m")
17389         (match_operand:V2SF 1 "nonimmediate_operand" "ym,y"))]
17390   "TARGET_3DNOW"
17391   "movq\\t{%1, %0|%0, %1}"
17392   [(set_attr "type" "mmxcvt")
17393    (set_attr "mode" "DI")])
17394
17395 (define_expand "movti"
17396   [(set (match_operand:TI 0 "general_operand" "")
17397         (match_operand:TI 1 "general_operand" ""))]
17398   "TARGET_SSE || TARGET_64BIT"
17399 {
17400   if (TARGET_64BIT)
17401     ix86_expand_move (TImode, operands);
17402   else
17403     ix86_expand_vector_move (TImode, operands);
17404   DONE;
17405 })
17406
17407 (define_insn "movv2df_internal"
17408   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
17409         (match_operand:V2DF 1 "general_operand" "xm,x"))]
17410   "TARGET_SSE2"
17411   ;; @@@ let's try to use movaps here.
17412   "movapd\t{%1, %0|%0, %1}"
17413   [(set_attr "type" "ssemov")
17414    (set_attr "mode" "V2DF")])
17415
17416 (define_insn "movv8hi_internal"
17417   [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,m")
17418         (match_operand:V8HI 1 "general_operand" "xm,x"))]
17419   "TARGET_SSE2"
17420   ;; @@@ let's try to use movaps here.
17421   "movaps\t{%1, %0|%0, %1}"
17422   [(set_attr "type" "ssemov")
17423    (set_attr "mode" "V4SF")])
17424
17425 (define_insn "movv16qi_internal"
17426   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
17427         (match_operand:V16QI 1 "general_operand" "xm,x"))]
17428   "TARGET_SSE2"
17429   ;; @@@ let's try to use movaps here.
17430   "movaps\t{%1, %0|%0, %1}"
17431   [(set_attr "type" "ssemov")
17432    (set_attr "mode" "V4SF")])
17433
17434 (define_expand "movv2df"
17435   [(set (match_operand:V2DF 0 "general_operand" "")
17436         (match_operand:V2DF 1 "general_operand" ""))]
17437   "TARGET_SSE2"
17438 {
17439   ix86_expand_vector_move (V2DFmode, operands);
17440   DONE;
17441 })
17442
17443 (define_expand "movv8hi"
17444   [(set (match_operand:V8HI 0 "general_operand" "")
17445         (match_operand:V8HI 1 "general_operand" ""))]
17446   "TARGET_SSE2"
17447 {
17448   ix86_expand_vector_move (V8HImode, operands);
17449   DONE;
17450 })
17451
17452 (define_expand "movv16qi"
17453   [(set (match_operand:V16QI 0 "general_operand" "")
17454         (match_operand:V16QI 1 "general_operand" ""))]
17455   "TARGET_SSE2"
17456 {
17457   ix86_expand_vector_move (V16QImode, operands);
17458   DONE;
17459 })
17460
17461 (define_expand "movv4sf"
17462   [(set (match_operand:V4SF 0 "general_operand" "")
17463         (match_operand:V4SF 1 "general_operand" ""))]
17464   "TARGET_SSE"
17465 {
17466   ix86_expand_vector_move (V4SFmode, operands);
17467   DONE;
17468 })
17469
17470 (define_expand "movv4si"
17471   [(set (match_operand:V4SI 0 "general_operand" "")
17472         (match_operand:V4SI 1 "general_operand" ""))]
17473   "TARGET_MMX"
17474 {
17475   ix86_expand_vector_move (V4SImode, operands);
17476   DONE;
17477 })
17478
17479 (define_expand "movv2si"
17480   [(set (match_operand:V2SI 0 "general_operand" "")
17481         (match_operand:V2SI 1 "general_operand" ""))]
17482   "TARGET_MMX"
17483 {
17484   ix86_expand_vector_move (V2SImode, operands);
17485   DONE;
17486 })
17487
17488 (define_expand "movv4hi"
17489   [(set (match_operand:V4HI 0 "general_operand" "")
17490         (match_operand:V4HI 1 "general_operand" ""))]
17491   "TARGET_MMX"
17492 {
17493   ix86_expand_vector_move (V4HImode, operands);
17494   DONE;
17495 })
17496
17497 (define_expand "movv8qi"
17498   [(set (match_operand:V8QI 0 "general_operand" "")
17499         (match_operand:V8QI 1 "general_operand" ""))]
17500   "TARGET_MMX"
17501 {
17502   ix86_expand_vector_move (V8QImode, operands);
17503   DONE;
17504 })
17505
17506 (define_expand "movv2sf"
17507   [(set (match_operand:V2SF 0 "general_operand" "")
17508         (match_operand:V2SF 1 "general_operand" ""))]
17509    "TARGET_3DNOW"
17510 {
17511   ix86_expand_vector_move (V2SFmode, operands);
17512   DONE;
17513 })
17514
17515 (define_insn_and_split "*pushti"
17516   [(set (match_operand:TI 0 "push_operand" "=<")
17517         (match_operand:TI 1 "nonmemory_operand" "x"))]
17518   "TARGET_SSE"
17519   "#"
17520   ""
17521   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
17522    (set (mem:TI (reg:SI 7)) (match_dup 1))]
17523   ""
17524   [(set_attr "type" "multi")])
17525
17526 (define_insn_and_split "*pushv2df"
17527   [(set (match_operand:V2DF 0 "push_operand" "=<")
17528         (match_operand:V2DF 1 "nonmemory_operand" "x"))]
17529   "TARGET_SSE2"
17530   "#"
17531   ""
17532   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
17533    (set (mem:V2DF (reg:SI 7)) (match_dup 1))]
17534   ""
17535   [(set_attr "type" "multi")])
17536
17537 (define_insn_and_split "*pushv8hi"
17538   [(set (match_operand:V8HI 0 "push_operand" "=<")
17539         (match_operand:V8HI 1 "nonmemory_operand" "x"))]
17540   "TARGET_SSE2"
17541   "#"
17542   ""
17543   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
17544    (set (mem:V8HI (reg:SI 7)) (match_dup 1))]
17545   ""
17546   [(set_attr "type" "multi")])
17547
17548 (define_insn_and_split "*pushv16qi"
17549   [(set (match_operand:V16QI 0 "push_operand" "=<")
17550         (match_operand:V16QI 1 "nonmemory_operand" "x"))]
17551   "TARGET_SSE2"
17552   "#"
17553   ""
17554   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
17555    (set (mem:V16QI (reg:SI 7)) (match_dup 1))]
17556   ""
17557   [(set_attr "type" "multi")])
17558
17559 (define_insn_and_split "*pushv4sf"
17560   [(set (match_operand:V4SF 0 "push_operand" "=<")
17561         (match_operand:V4SF 1 "nonmemory_operand" "x"))]
17562   "TARGET_SSE"
17563   "#"
17564   ""
17565   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
17566    (set (mem:V4SF (reg:SI 7)) (match_dup 1))]
17567   ""
17568   [(set_attr "type" "multi")])
17569
17570 (define_insn_and_split "*pushv4si"
17571   [(set (match_operand:V4SI 0 "push_operand" "=<")
17572         (match_operand:V4SI 1 "nonmemory_operand" "x"))]
17573   "TARGET_SSE"
17574   "#"
17575   ""
17576   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
17577    (set (mem:V4SI (reg:SI 7)) (match_dup 1))]
17578   ""
17579   [(set_attr "type" "multi")])
17580
17581 (define_insn_and_split "*pushv2si"
17582   [(set (match_operand:V2SI 0 "push_operand" "=<")
17583         (match_operand:V2SI 1 "nonmemory_operand" "y"))]
17584   "TARGET_MMX"
17585   "#"
17586   ""
17587   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
17588    (set (mem:V2SI (reg:SI 7)) (match_dup 1))]
17589   ""
17590   [(set_attr "type" "mmx")])
17591
17592 (define_insn_and_split "*pushv4hi"
17593   [(set (match_operand:V4HI 0 "push_operand" "=<")
17594         (match_operand:V4HI 1 "nonmemory_operand" "y"))]
17595   "TARGET_MMX"
17596   "#"
17597   ""
17598   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
17599    (set (mem:V4HI (reg:SI 7)) (match_dup 1))]
17600   ""
17601   [(set_attr "type" "mmx")])
17602
17603 (define_insn_and_split "*pushv8qi"
17604   [(set (match_operand:V8QI 0 "push_operand" "=<")
17605         (match_operand:V8QI 1 "nonmemory_operand" "y"))]
17606   "TARGET_MMX"
17607   "#"
17608   ""
17609   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
17610    (set (mem:V8QI (reg:SI 7)) (match_dup 1))]
17611   ""
17612   [(set_attr "type" "mmx")])
17613
17614 (define_insn_and_split "*pushv2sf"
17615   [(set (match_operand:V2SF 0 "push_operand" "=<")
17616         (match_operand:V2SF 1 "nonmemory_operand" "y"))]
17617   "TARGET_3DNOW"
17618   "#"
17619   ""
17620   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
17621    (set (mem:V2SF (reg:SI 7)) (match_dup 1))]
17622   ""
17623   [(set_attr "type" "mmx")])
17624
17625 (define_insn "movti_internal"
17626   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
17627         (match_operand:TI 1 "general_operand" "O,xm,x"))]
17628   "TARGET_SSE && !TARGET_64BIT"
17629   "@
17630    xorps\t%0, %0
17631    movaps\t{%1, %0|%0, %1}
17632    movaps\t{%1, %0|%0, %1}"
17633   [(set_attr "type" "ssemov,ssemov,ssemov")
17634    (set_attr "mode" "V4SF")])
17635
17636 (define_insn "*movti_rex64"
17637   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,mx,x")
17638         (match_operand:TI 1 "general_operand" "riFo,riF,O,x,m"))]
17639   "TARGET_64BIT
17640    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
17641   "@
17642    #
17643    #
17644    xorps\t%0, %0
17645    movaps\\t{%1, %0|%0, %1}
17646    movaps\\t{%1, %0|%0, %1}"
17647   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
17648    (set_attr "mode" "V4SF")])
17649
17650 (define_split
17651   [(set (match_operand:TI 0 "nonimmediate_operand" "")
17652         (match_operand:TI 1 "general_operand" ""))]
17653   "reload_completed && !SSE_REG_P (operands[0])
17654    && !SSE_REG_P (operands[1])"
17655   [(const_int 0)]
17656   "ix86_split_long_move (operands); DONE;")
17657
17658 ;; These two patterns are useful for specifying exactly whether to use
17659 ;; movaps or movups
17660 (define_insn "sse_movaps"
17661   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
17662         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
17663                      UNSPEC_MOVA))]
17664   "TARGET_SSE"
17665   "@
17666    movaps\t{%1, %0|%0, %1}
17667    movaps\t{%1, %0|%0, %1}"
17668   [(set_attr "type" "ssemov,ssemov")
17669    (set_attr "mode" "V4SF")])
17670
17671 (define_insn "sse_movups"
17672   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
17673         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
17674                      UNSPEC_MOVU))]
17675   "TARGET_SSE"
17676   "@
17677    movups\t{%1, %0|%0, %1}
17678    movups\t{%1, %0|%0, %1}"
17679   [(set_attr "type" "ssecvt,ssecvt")
17680    (set_attr "mode" "V4SF")])
17681
17682
17683 ;; SSE Strange Moves.
17684
17685 (define_insn "sse_movmskps"
17686   [(set (match_operand:SI 0 "register_operand" "=r")
17687         (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
17688                    UNSPEC_MOVMSK))]
17689   "TARGET_SSE"
17690   "movmskps\t{%1, %0|%0, %1}"
17691   [(set_attr "type" "ssecvt")
17692    (set_attr "mode" "V4SF")])
17693
17694 (define_insn "mmx_pmovmskb"
17695   [(set (match_operand:SI 0 "register_operand" "=r")
17696         (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
17697                    UNSPEC_MOVMSK))]
17698   "TARGET_SSE || TARGET_3DNOW_A"
17699   "pmovmskb\t{%1, %0|%0, %1}"
17700   [(set_attr "type" "ssecvt")
17701    (set_attr "mode" "V4SF")])
17702
17703
17704 (define_insn "mmx_maskmovq"
17705   [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
17706         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
17707                       (match_operand:V8QI 2 "register_operand" "y")]
17708                      UNSPEC_MASKMOV))]
17709   "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
17710   ;; @@@ check ordering of operands in intel/nonintel syntax
17711   "maskmovq\t{%2, %1|%1, %2}"
17712   [(set_attr "type" "mmxcvt")
17713    (set_attr "mode" "DI")])
17714
17715 (define_insn "mmx_maskmovq_rex"
17716   [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
17717         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
17718                       (match_operand:V8QI 2 "register_operand" "y")]
17719                      UNSPEC_MASKMOV))]
17720   "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
17721   ;; @@@ check ordering of operands in intel/nonintel syntax
17722   "maskmovq\t{%2, %1|%1, %2}"
17723   [(set_attr "type" "mmxcvt")
17724    (set_attr "mode" "DI")])
17725
17726 (define_insn "sse_movntv4sf"
17727   [(set (match_operand:V4SF 0 "memory_operand" "=m")
17728         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
17729                      UNSPEC_MOVNT))]
17730   "TARGET_SSE"
17731   "movntps\t{%1, %0|%0, %1}"
17732   [(set_attr "type" "ssemov")
17733    (set_attr "mode" "V4SF")])
17734
17735 (define_insn "sse_movntdi"
17736   [(set (match_operand:DI 0 "memory_operand" "=m")
17737         (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
17738                    UNSPEC_MOVNT))]
17739   "TARGET_SSE || TARGET_3DNOW_A"
17740   "movntq\t{%1, %0|%0, %1}"
17741   [(set_attr "type" "mmxmov")
17742    (set_attr "mode" "DI")])
17743
17744 (define_insn "sse_movhlps"
17745   [(set (match_operand:V4SF 0 "register_operand" "=x")
17746         (vec_merge:V4SF
17747          (match_operand:V4SF 1 "register_operand" "0")
17748          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
17749                           (parallel [(const_int 2)
17750                                      (const_int 3)
17751                                      (const_int 0)
17752                                      (const_int 1)]))
17753          (const_int 3)))]
17754   "TARGET_SSE"
17755   "movhlps\t{%2, %0|%0, %2}"
17756   [(set_attr "type" "ssecvt")
17757    (set_attr "mode" "V4SF")])
17758
17759 (define_insn "sse_movlhps"
17760   [(set (match_operand:V4SF 0 "register_operand" "=x")
17761         (vec_merge:V4SF
17762          (match_operand:V4SF 1 "register_operand" "0")
17763          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
17764                           (parallel [(const_int 2)
17765                                      (const_int 3)
17766                                      (const_int 0)
17767                                      (const_int 1)]))
17768          (const_int 12)))]
17769   "TARGET_SSE"
17770   "movlhps\t{%2, %0|%0, %2}"
17771   [(set_attr "type" "ssecvt")
17772    (set_attr "mode" "V4SF")])
17773
17774 (define_insn "sse_movhps"
17775   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
17776         (vec_merge:V4SF
17777          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
17778          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
17779          (const_int 12)))]
17780   "TARGET_SSE
17781    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
17782   "movhps\t{%2, %0|%0, %2}"
17783   [(set_attr "type" "ssecvt")
17784    (set_attr "mode" "V4SF")])
17785
17786 (define_insn "sse_movlps"
17787   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
17788         (vec_merge:V4SF
17789          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
17790          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
17791          (const_int 3)))]
17792   "TARGET_SSE
17793    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
17794   "movlps\t{%2, %0|%0, %2}"
17795   [(set_attr "type" "ssecvt")
17796    (set_attr "mode" "V4SF")])
17797
17798 (define_insn "sse_loadss"
17799   [(set (match_operand:V4SF 0 "register_operand" "=x")
17800         (vec_merge:V4SF
17801          (match_operand:V4SF 1 "memory_operand" "m")
17802          (vec_duplicate:V4SF (float:SF (const_int 0)))
17803          (const_int 1)))]
17804   "TARGET_SSE"
17805   "movss\t{%1, %0|%0, %1}"
17806   [(set_attr "type" "ssemov")
17807    (set_attr "mode" "SF")])
17808
17809 (define_insn "sse_movss"
17810   [(set (match_operand:V4SF 0 "register_operand" "=x")
17811         (vec_merge:V4SF
17812          (match_operand:V4SF 1 "register_operand" "0")
17813          (match_operand:V4SF 2 "register_operand" "x")
17814          (const_int 1)))]
17815   "TARGET_SSE"
17816   "movss\t{%2, %0|%0, %2}"
17817   [(set_attr "type" "ssemov")
17818    (set_attr "mode" "SF")])
17819
17820 (define_insn "sse_storess"
17821   [(set (match_operand:SF 0 "memory_operand" "=m")
17822         (vec_select:SF
17823          (match_operand:V4SF 1 "register_operand" "x")
17824          (parallel [(const_int 0)])))]
17825   "TARGET_SSE"
17826   "movss\t{%1, %0|%0, %1}"
17827   [(set_attr "type" "ssemov")
17828    (set_attr "mode" "SF")])
17829
17830 (define_insn "sse_shufps"
17831   [(set (match_operand:V4SF 0 "register_operand" "=x")
17832         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
17833                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")
17834                       (match_operand:SI 3 "immediate_operand" "i")]
17835                      UNSPEC_SHUFFLE))]
17836   "TARGET_SSE"
17837   ;; @@@ check operand order for intel/nonintel syntax
17838   "shufps\t{%3, %2, %0|%0, %2, %3}"
17839   [(set_attr "type" "ssecvt")
17840    (set_attr "mode" "V4SF")])
17841
17842
17843 ;; SSE arithmetic
17844
17845 (define_insn "addv4sf3"
17846   [(set (match_operand:V4SF 0 "register_operand" "=x")
17847         (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
17848                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
17849   "TARGET_SSE"
17850   "addps\t{%2, %0|%0, %2}"
17851   [(set_attr "type" "sseadd")
17852    (set_attr "mode" "V4SF")])
17853
17854 (define_insn "vmaddv4sf3"
17855   [(set (match_operand:V4SF 0 "register_operand" "=x")
17856         (vec_merge:V4SF
17857          (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
17858                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
17859          (match_dup 1)
17860          (const_int 1)))]
17861   "TARGET_SSE"
17862   "addss\t{%2, %0|%0, %2}"
17863   [(set_attr "type" "sseadd")
17864    (set_attr "mode" "SF")])
17865
17866 (define_insn "subv4sf3"
17867   [(set (match_operand:V4SF 0 "register_operand" "=x")
17868         (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
17869                     (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
17870   "TARGET_SSE"
17871   "subps\t{%2, %0|%0, %2}"
17872   [(set_attr "type" "sseadd")
17873    (set_attr "mode" "V4SF")])
17874
17875 (define_insn "vmsubv4sf3"
17876   [(set (match_operand:V4SF 0 "register_operand" "=x")
17877         (vec_merge:V4SF
17878          (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
17879                      (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
17880          (match_dup 1)
17881          (const_int 1)))]
17882   "TARGET_SSE"
17883   "subss\t{%2, %0|%0, %2}"
17884   [(set_attr "type" "sseadd")
17885    (set_attr "mode" "SF")])
17886
17887 (define_insn "mulv4sf3"
17888   [(set (match_operand:V4SF 0 "register_operand" "=x")
17889         (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
17890                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
17891   "TARGET_SSE"
17892   "mulps\t{%2, %0|%0, %2}"
17893   [(set_attr "type" "ssemul")
17894    (set_attr "mode" "V4SF")])
17895
17896 (define_insn "vmmulv4sf3"
17897   [(set (match_operand:V4SF 0 "register_operand" "=x")
17898         (vec_merge:V4SF
17899          (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
17900                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
17901          (match_dup 1)
17902          (const_int 1)))]
17903   "TARGET_SSE"
17904   "mulss\t{%2, %0|%0, %2}"
17905   [(set_attr "type" "ssemul")
17906    (set_attr "mode" "SF")])
17907
17908 (define_insn "divv4sf3"
17909   [(set (match_operand:V4SF 0 "register_operand" "=x")
17910         (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
17911                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
17912   "TARGET_SSE"
17913   "divps\t{%2, %0|%0, %2}"
17914   [(set_attr "type" "ssediv")
17915    (set_attr "mode" "V4SF")])
17916
17917 (define_insn "vmdivv4sf3"
17918   [(set (match_operand:V4SF 0 "register_operand" "=x")
17919         (vec_merge:V4SF
17920          (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
17921                    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
17922          (match_dup 1)
17923          (const_int 1)))]
17924   "TARGET_SSE"
17925   "divss\t{%2, %0|%0, %2}"
17926   [(set_attr "type" "ssediv")
17927    (set_attr "mode" "SF")])
17928
17929
17930 ;; SSE square root/reciprocal
17931
17932 (define_insn "rcpv4sf2"
17933   [(set (match_operand:V4SF 0 "register_operand" "=x")
17934         (unspec:V4SF
17935          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
17936   "TARGET_SSE"
17937   "rcpps\t{%1, %0|%0, %1}"
17938   [(set_attr "type" "sse")
17939    (set_attr "mode" "V4SF")])
17940
17941 (define_insn "vmrcpv4sf2"
17942   [(set (match_operand:V4SF 0 "register_operand" "=x")
17943         (vec_merge:V4SF
17944          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
17945                       UNSPEC_RCP)
17946          (match_operand:V4SF 2 "register_operand" "0")
17947          (const_int 1)))]
17948   "TARGET_SSE"
17949   "rcpss\t{%1, %0|%0, %1}"
17950   [(set_attr "type" "sse")
17951    (set_attr "mode" "SF")])
17952
17953 (define_insn "rsqrtv4sf2"
17954   [(set (match_operand:V4SF 0 "register_operand" "=x")
17955         (unspec:V4SF
17956          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
17957   "TARGET_SSE"
17958   "rsqrtps\t{%1, %0|%0, %1}"
17959   [(set_attr "type" "sse")
17960    (set_attr "mode" "V4SF")])
17961
17962 (define_insn "vmrsqrtv4sf2"
17963   [(set (match_operand:V4SF 0 "register_operand" "=x")
17964         (vec_merge:V4SF
17965          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
17966                       UNSPEC_RSQRT)
17967          (match_operand:V4SF 2 "register_operand" "0")
17968          (const_int 1)))]
17969   "TARGET_SSE"
17970   "rsqrtss\t{%1, %0|%0, %1}"
17971   [(set_attr "type" "sse")
17972    (set_attr "mode" "SF")])
17973
17974 (define_insn "sqrtv4sf2"
17975   [(set (match_operand:V4SF 0 "register_operand" "=x")
17976         (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
17977   "TARGET_SSE"
17978   "sqrtps\t{%1, %0|%0, %1}"
17979   [(set_attr "type" "sse")
17980    (set_attr "mode" "V4SF")])
17981
17982 (define_insn "vmsqrtv4sf2"
17983   [(set (match_operand:V4SF 0 "register_operand" "=x")
17984         (vec_merge:V4SF
17985          (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
17986          (match_operand:V4SF 2 "register_operand" "0")
17987          (const_int 1)))]
17988   "TARGET_SSE"
17989   "sqrtss\t{%1, %0|%0, %1}"
17990   [(set_attr "type" "sse")
17991    (set_attr "mode" "SF")])
17992
17993 ;; SSE logical operations.
17994
17995 ;; These are not called andti3 etc. because we really really don't want
17996 ;; the compiler to widen DImode ands to TImode ands and then try to move
17997 ;; into DImode subregs of SSE registers, and them together, and move out
17998 ;; of DImode subregs again!
17999
18000 (define_insn "*sse_andti3_df_1"
18001   [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18002         (and:TI (subreg:TI (match_operand:DF 1 "register_operand" "%0") 0)
18003                 (subreg:TI (match_operand:DF 2 "register_operand" "Y") 0)))]
18004   "TARGET_SSE2"
18005   "andpd\t{%2, %0|%0, %2}"
18006   [(set_attr "type" "sselog")
18007    (set_attr "mode" "V2DF")])
18008
18009 (define_insn "*sse_andti3_df_2"
18010   [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18011         (and:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0)
18012                 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
18013   "TARGET_SSE2"
18014   "andpd\t{%2, %0|%0, %2}"
18015   [(set_attr "type" "sselog")
18016    (set_attr "mode" "V2DF")])
18017
18018 (define_insn "*sse_andti3_sf_1"
18019   [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18020         (and:TI (subreg:TI (match_operand:SF 1 "register_operand" "%0") 0)
18021                 (subreg:TI (match_operand:SF 2 "register_operand" "x") 0)))]
18022   "TARGET_SSE"
18023   "andps\t{%2, %0|%0, %2}"
18024   [(set_attr "type" "sselog")
18025    (set_attr "mode" "V4SF")])
18026
18027 (define_insn "*sse_andti3_sf_2"
18028   [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18029         (and:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0)
18030                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18031   "TARGET_SSE"
18032   "andps\t{%2, %0|%0, %2}"
18033   [(set_attr "type" "sselog")
18034    (set_attr "mode" "V4SF")])
18035
18036 (define_insn "sse_andti3"
18037   [(set (match_operand:TI 0 "register_operand" "=x")
18038         (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
18039                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18040   "TARGET_SSE && !TARGET_SSE2
18041    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18042   "andps\t{%2, %0|%0, %2}"
18043   [(set_attr "type" "sselog")
18044    (set_attr "mode" "V4SF")])
18045
18046 (define_insn "sse2_andti3"
18047   [(set (match_operand:TI 0 "register_operand" "=x")
18048         (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
18049                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18050   "TARGET_SSE2
18051    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18052   "pand\t{%2, %0|%0, %2}"
18053   [(set_attr "type" "sselog")
18054    (set_attr "mode" "TI")])
18055
18056 (define_insn "sse2_andv2di3"
18057   [(set (match_operand:V2DI 0 "register_operand" "=x")
18058         (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
18059                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
18060   "TARGET_SSE2
18061    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18062   "pand\t{%2, %0|%0, %2}"
18063   [(set_attr "type" "sselog")
18064    (set_attr "mode" "TI")])
18065
18066 (define_insn "*sse_nandti3_df"
18067   [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18068         (and:TI (not:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0))
18069                 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
18070   "TARGET_SSE2"
18071   "andnpd\t{%2, %0|%0, %2}"
18072   [(set_attr "type" "sselog")
18073    (set_attr "mode" "V2DF")])
18074
18075 (define_insn "*sse_nandti3_sf"
18076   [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18077         (and:TI (not:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0))
18078                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18079   "TARGET_SSE"
18080   "andnps\t{%2, %0|%0, %2}"
18081   [(set_attr "type" "sselog")
18082    (set_attr "mode" "V4SF")])
18083
18084 (define_insn "sse_nandti3"
18085   [(set (match_operand:TI 0 "register_operand" "=x")
18086         (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
18087                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18088   "TARGET_SSE && !TARGET_SSE2"
18089   "andnps\t{%2, %0|%0, %2}"
18090   [(set_attr "type" "sselog")
18091    (set_attr "mode" "V4SF")])
18092
18093 (define_insn "sse2_nandti3"
18094   [(set (match_operand:TI 0 "register_operand" "=x")
18095         (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
18096                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18097   "TARGET_SSE2"
18098   "pandn\t{%2, %0|%0, %2}"
18099   [(set_attr "type" "sselog")
18100    (set_attr "mode" "TI")])
18101
18102 (define_insn "sse2_nandv2di3"
18103   [(set (match_operand:V2DI 0 "register_operand" "=x")
18104         (and:V2DI (not:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0"))
18105                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
18106   "TARGET_SSE2
18107    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18108   "pandn\t{%2, %0|%0, %2}"
18109   [(set_attr "type" "sselog")
18110    (set_attr "mode" "TI")])
18111
18112 (define_insn "*sse_iorti3_df_1"
18113   [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18114         (ior:TI (subreg:TI (match_operand:DF 1 "register_operand" "%0") 0)
18115                 (subreg:TI (match_operand:DF 2 "register_operand" "Y") 0)))]
18116   "TARGET_SSE2"
18117   "orpd\t{%2, %0|%0, %2}"
18118   [(set_attr "type" "sselog")
18119    (set_attr "mode" "V2DF")])
18120
18121 (define_insn "*sse_iorti3_df_2"
18122   [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18123         (ior:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0)
18124                 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
18125   "TARGET_SSE2"
18126   "orpd\t{%2, %0|%0, %2}"
18127   [(set_attr "type" "sselog")
18128    (set_attr "mode" "V2DF")])
18129
18130 (define_insn "*sse_iorti3_sf_1"
18131   [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18132         (ior:TI (subreg:TI (match_operand:SF 1 "register_operand" "%0") 0)
18133                 (subreg:TI (match_operand:SF 2 "register_operand" "x") 0)))]
18134   "TARGET_SSE"
18135   "orps\t{%2, %0|%0, %2}"
18136   [(set_attr "type" "sselog")
18137    (set_attr "mode" "V4SF")])
18138
18139 (define_insn "*sse_iorti3_sf_2"
18140   [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18141         (ior:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0)
18142                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18143   "TARGET_SSE"
18144   "orps\t{%2, %0|%0, %2}"
18145   [(set_attr "type" "sselog")
18146    (set_attr "mode" "V4SF")])
18147
18148 (define_insn "sse_iorti3"
18149   [(set (match_operand:TI 0 "register_operand" "=x")
18150         (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
18151                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18152   "TARGET_SSE && !TARGET_SSE2
18153    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18154   "orps\t{%2, %0|%0, %2}"
18155   [(set_attr "type" "sselog")
18156    (set_attr "mode" "V4SF")])
18157
18158 (define_insn "sse2_iorti3"
18159   [(set (match_operand:TI 0 "register_operand" "=x")
18160         (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
18161                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18162   "TARGET_SSE2
18163    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18164   "por\t{%2, %0|%0, %2}"
18165   [(set_attr "type" "sselog")
18166    (set_attr "mode" "TI")])
18167
18168 (define_insn "sse2_iorv2di3"
18169   [(set (match_operand:V2DI 0 "register_operand" "=x")
18170         (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
18171                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
18172   "TARGET_SSE2
18173    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18174   "por\t{%2, %0|%0, %2}"
18175   [(set_attr "type" "sselog")
18176    (set_attr "mode" "TI")])
18177
18178 (define_insn "*sse_xorti3_df_1"
18179   [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18180         (xor:TI (subreg:TI (match_operand:DF 1 "register_operand" "%0") 0)
18181                 (subreg:TI (match_operand:DF 2 "register_operand" "Y") 0)))]
18182   "TARGET_SSE2"
18183   "xorpd\t{%2, %0|%0, %2}"
18184   [(set_attr "type" "sselog")
18185    (set_attr "mode" "V2DF")])
18186
18187 (define_insn "*sse_xorti3_df_2"
18188   [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18189         (xor:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0)
18190                 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
18191   "TARGET_SSE2"
18192   "xorpd\t{%2, %0|%0, %2}"
18193   [(set_attr "type" "sselog")
18194    (set_attr "mode" "V2DF")])
18195
18196 (define_insn "*sse_xorti3_sf_1"
18197   [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18198         (xor:TI (subreg:TI (match_operand:SF 1 "register_operand" "%0") 0)
18199                 (subreg:TI (match_operand:SF 2 "register_operand" "x") 0)))]
18200   "TARGET_SSE"
18201   "xorps\t{%2, %0|%0, %2}"
18202   [(set_attr "type" "sselog")
18203    (set_attr "mode" "V4SF")])
18204
18205 (define_insn "*sse_xorti3_sf_2"
18206   [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18207         (xor:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0)
18208                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18209   "TARGET_SSE"
18210   "xorps\t{%2, %0|%0, %2}"
18211   [(set_attr "type" "sselog")
18212    (set_attr "mode" "V4SF")])
18213
18214 (define_insn "sse_xorti3"
18215   [(set (match_operand:TI 0 "register_operand" "=x")
18216         (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
18217                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18218   "TARGET_SSE && !TARGET_SSE2
18219    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18220   "xorps\t{%2, %0|%0, %2}"
18221   [(set_attr "type" "sselog")
18222    (set_attr "mode" "V4SF")])
18223
18224 (define_insn "sse2_xorti3"
18225   [(set (match_operand:TI 0 "register_operand" "=x")
18226         (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
18227                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18228   "TARGET_SSE2
18229    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18230   "pxor\t{%2, %0|%0, %2}"
18231   [(set_attr "type" "sselog")
18232    (set_attr "mode" "TI")])
18233
18234 (define_insn "sse2_xorv2di3"
18235   [(set (match_operand:V2DI 0 "register_operand" "=x")
18236         (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
18237                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
18238   "TARGET_SSE2
18239    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18240   "pxor\t{%2, %0|%0, %2}"
18241   [(set_attr "type" "sselog")
18242    (set_attr "mode" "TI")])
18243
18244 ;; Use xor, but don't show input operands so they aren't live before
18245 ;; this insn.
18246 (define_insn "sse_clrv4sf"
18247   [(set (match_operand:V4SF 0 "register_operand" "=x")
18248         (unspec:V4SF [(const_int 0)] UNSPEC_NOP))]
18249   "TARGET_SSE"
18250   "xorps\t{%0, %0|%0, %0}"
18251   [(set_attr "type" "sselog")
18252    (set_attr "memory" "none")
18253    (set_attr "mode" "V4SF")])
18254
18255 ;; SSE mask-generating compares
18256
18257 (define_insn "maskcmpv4sf3"
18258   [(set (match_operand:V4SI 0 "register_operand" "=x")
18259         (match_operator:V4SI 3 "sse_comparison_operator"
18260                 [(match_operand:V4SF 1 "register_operand" "0")
18261                  (match_operand:V4SF 2 "register_operand" "x")]))]
18262   "TARGET_SSE"
18263   "cmp%D3ps\t{%2, %0|%0, %2}"
18264   [(set_attr "type" "ssecmp")
18265    (set_attr "mode" "V4SF")])
18266
18267 (define_insn "maskncmpv4sf3"
18268   [(set (match_operand:V4SI 0 "register_operand" "=x")
18269         (not:V4SI
18270          (match_operator:V4SI 3 "sse_comparison_operator"
18271                 [(match_operand:V4SF 1 "register_operand" "0")
18272                  (match_operand:V4SF 2 "register_operand" "x")])))]
18273   "TARGET_SSE"
18274 {
18275   if (GET_CODE (operands[3]) == UNORDERED)
18276     return "cmpordps\t{%2, %0|%0, %2}";
18277   else
18278     return "cmpn%D3ps\t{%2, %0|%0, %2}";
18279 }
18280   [(set_attr "type" "ssecmp")
18281    (set_attr "mode" "V4SF")])
18282
18283 (define_insn "vmmaskcmpv4sf3"
18284   [(set (match_operand:V4SI 0 "register_operand" "=x")
18285         (vec_merge:V4SI
18286          (match_operator:V4SI 3 "sse_comparison_operator"
18287                 [(match_operand:V4SF 1 "register_operand" "0")
18288                  (match_operand:V4SF 2 "register_operand" "x")])
18289          (match_dup 1)
18290          (const_int 1)))]
18291   "TARGET_SSE"
18292   "cmp%D3ss\t{%2, %0|%0, %2}"
18293   [(set_attr "type" "ssecmp")
18294    (set_attr "mode" "SF")])
18295
18296 (define_insn "vmmaskncmpv4sf3"
18297   [(set (match_operand:V4SI 0 "register_operand" "=x")
18298         (vec_merge:V4SI
18299          (not:V4SI
18300           (match_operator:V4SI 3 "sse_comparison_operator"
18301                 [(match_operand:V4SF 1 "register_operand" "0")
18302                  (match_operand:V4SF 2 "register_operand" "x")]))
18303          (subreg:V4SI (match_dup 1) 0)
18304          (const_int 1)))]
18305   "TARGET_SSE"
18306 {
18307   if (GET_CODE (operands[3]) == UNORDERED)
18308     return "cmpordss\t{%2, %0|%0, %2}";
18309   else
18310     return "cmpn%D3ss\t{%2, %0|%0, %2}";
18311 }
18312   [(set_attr "type" "ssecmp")
18313    (set_attr "mode" "SF")])
18314
18315 (define_insn "sse_comi"
18316   [(set (reg:CCFP 17)
18317         (match_operator:CCFP 2 "sse_comparison_operator"
18318                         [(vec_select:SF
18319                           (match_operand:V4SF 0 "register_operand" "x")
18320                           (parallel [(const_int 0)]))
18321                          (vec_select:SF
18322                           (match_operand:V4SF 1 "register_operand" "x")
18323                           (parallel [(const_int 0)]))]))]
18324   "TARGET_SSE"
18325   "comiss\t{%1, %0|%0, %1}"
18326   [(set_attr "type" "ssecmp")
18327    (set_attr "mode" "SF")])
18328
18329 (define_insn "sse_ucomi"
18330   [(set (reg:CCFPU 17)
18331         (match_operator:CCFPU 2 "sse_comparison_operator"
18332                         [(vec_select:SF
18333                           (match_operand:V4SF 0 "register_operand" "x")
18334                           (parallel [(const_int 0)]))
18335                          (vec_select:SF
18336                           (match_operand:V4SF 1 "register_operand" "x")
18337                           (parallel [(const_int 0)]))]))]
18338   "TARGET_SSE"
18339   "ucomiss\t{%1, %0|%0, %1}"
18340   [(set_attr "type" "ssecmp")
18341    (set_attr "mode" "SF")])
18342
18343
18344 ;; SSE unpack
18345
18346 (define_insn "sse_unpckhps"
18347   [(set (match_operand:V4SF 0 "register_operand" "=x")
18348         (vec_merge:V4SF
18349          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
18350                           (parallel [(const_int 2)
18351                                      (const_int 0)
18352                                      (const_int 3)
18353                                      (const_int 1)]))
18354          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
18355                           (parallel [(const_int 0)
18356                                      (const_int 2)
18357                                      (const_int 1)
18358                                      (const_int 3)]))
18359          (const_int 5)))]
18360   "TARGET_SSE"
18361   "unpckhps\t{%2, %0|%0, %2}"
18362   [(set_attr "type" "ssecvt")
18363    (set_attr "mode" "V4SF")])
18364
18365 (define_insn "sse_unpcklps"
18366   [(set (match_operand:V4SF 0 "register_operand" "=x")
18367         (vec_merge:V4SF
18368          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
18369                           (parallel [(const_int 0)
18370                                      (const_int 2)
18371                                      (const_int 1)
18372                                      (const_int 3)]))
18373          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
18374                           (parallel [(const_int 2)
18375                                      (const_int 0)
18376                                      (const_int 3)
18377                                      (const_int 1)]))
18378          (const_int 5)))]
18379   "TARGET_SSE"
18380   "unpcklps\t{%2, %0|%0, %2}"
18381   [(set_attr "type" "ssecvt")
18382    (set_attr "mode" "V4SF")])
18383
18384
18385 ;; SSE min/max
18386
18387 (define_insn "smaxv4sf3"
18388   [(set (match_operand:V4SF 0 "register_operand" "=x")
18389         (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
18390                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
18391   "TARGET_SSE"
18392   "maxps\t{%2, %0|%0, %2}"
18393   [(set_attr "type" "sse")
18394    (set_attr "mode" "V4SF")])
18395
18396 (define_insn "vmsmaxv4sf3"
18397   [(set (match_operand:V4SF 0 "register_operand" "=x")
18398         (vec_merge:V4SF
18399          (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
18400                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
18401          (match_dup 1)
18402          (const_int 1)))]
18403   "TARGET_SSE"
18404   "maxss\t{%2, %0|%0, %2}"
18405   [(set_attr "type" "sse")
18406    (set_attr "mode" "SF")])
18407
18408 (define_insn "sminv4sf3"
18409   [(set (match_operand:V4SF 0 "register_operand" "=x")
18410         (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
18411                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
18412   "TARGET_SSE"
18413   "minps\t{%2, %0|%0, %2}"
18414   [(set_attr "type" "sse")
18415    (set_attr "mode" "V4SF")])
18416
18417 (define_insn "vmsminv4sf3"
18418   [(set (match_operand:V4SF 0 "register_operand" "=x")
18419         (vec_merge:V4SF
18420          (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
18421                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
18422          (match_dup 1)
18423          (const_int 1)))]
18424   "TARGET_SSE"
18425   "minss\t{%2, %0|%0, %2}"
18426   [(set_attr "type" "sse")
18427    (set_attr "mode" "SF")])
18428
18429
18430 ;; SSE <-> integer/MMX conversions
18431
18432 (define_insn "cvtpi2ps"
18433   [(set (match_operand:V4SF 0 "register_operand" "=x")
18434         (vec_merge:V4SF
18435          (match_operand:V4SF 1 "register_operand" "0")
18436          (vec_duplicate:V4SF
18437           (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
18438          (const_int 12)))]
18439   "TARGET_SSE"
18440   "cvtpi2ps\t{%2, %0|%0, %2}"
18441   [(set_attr "type" "ssecvt")
18442    (set_attr "mode" "V4SF")])
18443
18444 (define_insn "cvtps2pi"
18445   [(set (match_operand:V2SI 0 "register_operand" "=y")
18446         (vec_select:V2SI
18447          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
18448          (parallel [(const_int 0) (const_int 1)])))]
18449   "TARGET_SSE"
18450   "cvtps2pi\t{%1, %0|%0, %1}"
18451   [(set_attr "type" "ssecvt")
18452    (set_attr "mode" "V4SF")])
18453
18454 (define_insn "cvttps2pi"
18455   [(set (match_operand:V2SI 0 "register_operand" "=y")
18456         (vec_select:V2SI
18457          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
18458                       UNSPEC_FIX)
18459          (parallel [(const_int 0) (const_int 1)])))]
18460   "TARGET_SSE"
18461   "cvttps2pi\t{%1, %0|%0, %1}"
18462   [(set_attr "type" "ssecvt")
18463    (set_attr "mode" "SF")])
18464
18465 (define_insn "cvtsi2ss"
18466   [(set (match_operand:V4SF 0 "register_operand" "=x")
18467         (vec_merge:V4SF
18468          (match_operand:V4SF 1 "register_operand" "0")
18469          (vec_duplicate:V4SF
18470           (float:SF (match_operand:SI 2 "nonimmediate_operand" "rm")))
18471          (const_int 14)))]
18472   "TARGET_SSE"
18473   "cvtsi2ss\t{%2, %0|%0, %2}"
18474   [(set_attr "type" "ssecvt")
18475    (set_attr "mode" "SF")])
18476
18477 (define_insn "cvtss2si"
18478   [(set (match_operand:SI 0 "register_operand" "=r")
18479         (vec_select:SI
18480          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
18481          (parallel [(const_int 0)])))]
18482   "TARGET_SSE"
18483   "cvtss2si\t{%1, %0|%0, %1}"
18484   [(set_attr "type" "ssecvt")
18485    (set_attr "mode" "SF")])
18486
18487 (define_insn "cvttss2si"
18488   [(set (match_operand:SI 0 "register_operand" "=r")
18489         (vec_select:SI
18490          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
18491                       UNSPEC_FIX)
18492          (parallel [(const_int 0)])))]
18493   "TARGET_SSE"
18494   "cvttss2si\t{%1, %0|%0, %1}"
18495   [(set_attr "type" "ssecvt")
18496    (set_attr "mode" "SF")])
18497
18498
18499 ;; MMX insns
18500
18501 ;; MMX arithmetic
18502
18503 (define_insn "addv8qi3"
18504   [(set (match_operand:V8QI 0 "register_operand" "=y")
18505         (plus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18506                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18507   "TARGET_MMX"
18508   "paddb\t{%2, %0|%0, %2}"
18509   [(set_attr "type" "mmxadd")
18510    (set_attr "mode" "DI")])
18511
18512 (define_insn "addv4hi3"
18513   [(set (match_operand:V4HI 0 "register_operand" "=y")
18514         (plus:V4HI (match_operand:V4HI 1 "register_operand" "0")
18515                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18516   "TARGET_MMX"
18517   "paddw\t{%2, %0|%0, %2}"
18518   [(set_attr "type" "mmxadd")
18519    (set_attr "mode" "DI")])
18520
18521 (define_insn "addv2si3"
18522   [(set (match_operand:V2SI 0 "register_operand" "=y")
18523         (plus:V2SI (match_operand:V2SI 1 "register_operand" "0")
18524                    (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
18525   "TARGET_MMX"
18526   "paddd\t{%2, %0|%0, %2}"
18527   [(set_attr "type" "mmxadd")
18528    (set_attr "mode" "DI")])
18529
18530 (define_insn "ssaddv8qi3"
18531   [(set (match_operand:V8QI 0 "register_operand" "=y")
18532         (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18533                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18534   "TARGET_MMX"
18535   "paddsb\t{%2, %0|%0, %2}"
18536   [(set_attr "type" "mmxadd")
18537    (set_attr "mode" "DI")])
18538
18539 (define_insn "ssaddv4hi3"
18540   [(set (match_operand:V4HI 0 "register_operand" "=y")
18541         (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "0")
18542                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18543   "TARGET_MMX"
18544   "paddsw\t{%2, %0|%0, %2}"
18545   [(set_attr "type" "mmxadd")
18546    (set_attr "mode" "DI")])
18547
18548 (define_insn "usaddv8qi3"
18549   [(set (match_operand:V8QI 0 "register_operand" "=y")
18550         (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18551                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18552   "TARGET_MMX"
18553   "paddusb\t{%2, %0|%0, %2}"
18554   [(set_attr "type" "mmxadd")
18555    (set_attr "mode" "DI")])
18556
18557 (define_insn "usaddv4hi3"
18558   [(set (match_operand:V4HI 0 "register_operand" "=y")
18559         (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "0")
18560                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18561   "TARGET_MMX"
18562   "paddusw\t{%2, %0|%0, %2}"
18563   [(set_attr "type" "mmxadd")
18564    (set_attr "mode" "DI")])
18565
18566 (define_insn "subv8qi3"
18567   [(set (match_operand:V8QI 0 "register_operand" "=y")
18568         (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18569                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18570   "TARGET_MMX"
18571   "psubb\t{%2, %0|%0, %2}"
18572   [(set_attr "type" "mmxadd")
18573    (set_attr "mode" "DI")])
18574
18575 (define_insn "subv4hi3"
18576   [(set (match_operand:V4HI 0 "register_operand" "=y")
18577         (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
18578                     (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18579   "TARGET_MMX"
18580   "psubw\t{%2, %0|%0, %2}"
18581   [(set_attr "type" "mmxadd")
18582    (set_attr "mode" "DI")])
18583
18584 (define_insn "subv2si3"
18585   [(set (match_operand:V2SI 0 "register_operand" "=y")
18586         (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
18587                     (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
18588   "TARGET_MMX"
18589   "psubd\t{%2, %0|%0, %2}"
18590   [(set_attr "type" "mmxadd")
18591    (set_attr "mode" "DI")])
18592
18593 (define_insn "sssubv8qi3"
18594   [(set (match_operand:V8QI 0 "register_operand" "=y")
18595         (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18596                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18597   "TARGET_MMX"
18598   "psubsb\t{%2, %0|%0, %2}"
18599   [(set_attr "type" "mmxadd")
18600    (set_attr "mode" "DI")])
18601
18602 (define_insn "sssubv4hi3"
18603   [(set (match_operand:V4HI 0 "register_operand" "=y")
18604         (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
18605                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18606   "TARGET_MMX"
18607   "psubsw\t{%2, %0|%0, %2}"
18608   [(set_attr "type" "mmxadd")
18609    (set_attr "mode" "DI")])
18610
18611 (define_insn "ussubv8qi3"
18612   [(set (match_operand:V8QI 0 "register_operand" "=y")
18613         (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18614                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18615   "TARGET_MMX"
18616   "psubusb\t{%2, %0|%0, %2}"
18617   [(set_attr "type" "mmxadd")
18618    (set_attr "mode" "DI")])
18619
18620 (define_insn "ussubv4hi3"
18621   [(set (match_operand:V4HI 0 "register_operand" "=y")
18622         (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
18623                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18624   "TARGET_MMX"
18625   "psubusw\t{%2, %0|%0, %2}"
18626   [(set_attr "type" "mmxadd")
18627    (set_attr "mode" "DI")])
18628
18629 (define_insn "mulv4hi3"
18630   [(set (match_operand:V4HI 0 "register_operand" "=y")
18631         (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
18632                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18633   "TARGET_MMX"
18634   "pmullw\t{%2, %0|%0, %2}"
18635   [(set_attr "type" "mmxmul")
18636    (set_attr "mode" "DI")])
18637
18638 (define_insn "smulv4hi3_highpart"
18639   [(set (match_operand:V4HI 0 "register_operand" "=y")
18640         (truncate:V4HI
18641          (lshiftrt:V4SI
18642           (mult:V4SI (sign_extend:V4SI
18643                       (match_operand:V4HI 1 "register_operand" "0"))
18644                      (sign_extend:V4SI
18645                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
18646           (const_int 16))))]
18647   "TARGET_MMX"
18648   "pmulhw\t{%2, %0|%0, %2}"
18649   [(set_attr "type" "mmxmul")
18650    (set_attr "mode" "DI")])
18651
18652 (define_insn "umulv4hi3_highpart"
18653   [(set (match_operand:V4HI 0 "register_operand" "=y")
18654         (truncate:V4HI
18655          (lshiftrt:V4SI
18656           (mult:V4SI (zero_extend:V4SI
18657                       (match_operand:V4HI 1 "register_operand" "0"))
18658                      (zero_extend:V4SI
18659                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
18660           (const_int 16))))]
18661   "TARGET_SSE || TARGET_3DNOW_A"
18662   "pmulhuw\t{%2, %0|%0, %2}"
18663   [(set_attr "type" "mmxmul")
18664    (set_attr "mode" "DI")])
18665
18666 (define_insn "mmx_pmaddwd"
18667   [(set (match_operand:V2SI 0 "register_operand" "=y")
18668         (plus:V2SI
18669          (mult:V2SI
18670           (sign_extend:V2SI
18671            (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
18672                             (parallel [(const_int 0) (const_int 2)])))
18673           (sign_extend:V2SI
18674            (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
18675                             (parallel [(const_int 0) (const_int 2)]))))
18676          (mult:V2SI
18677           (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
18678                                              (parallel [(const_int 1)
18679                                                         (const_int 3)])))
18680           (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
18681                                              (parallel [(const_int 1)
18682                                                         (const_int 3)]))))))]
18683   "TARGET_MMX"
18684   "pmaddwd\t{%2, %0|%0, %2}"
18685   [(set_attr "type" "mmxmul")
18686    (set_attr "mode" "DI")])
18687
18688
18689 ;; MMX logical operations
18690 ;; Note we don't want to declare these as regular iordi3 insns to prevent
18691 ;; normal code that also wants to use the FPU from getting broken.
18692 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
18693 (define_insn "mmx_iordi3"
18694   [(set (match_operand:DI 0 "register_operand" "=y")
18695         (unspec:DI
18696          [(ior:DI (match_operand:DI 1 "register_operand" "0")
18697                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
18698          UNSPEC_NOP))]
18699   "TARGET_MMX"
18700   "por\t{%2, %0|%0, %2}"
18701   [(set_attr "type" "mmxadd")
18702    (set_attr "mode" "DI")])
18703
18704 (define_insn "mmx_xordi3"
18705   [(set (match_operand:DI 0 "register_operand" "=y")
18706         (unspec:DI
18707          [(xor:DI (match_operand:DI 1 "register_operand" "0")
18708                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
18709          UNSPEC_NOP))]
18710   "TARGET_MMX"
18711   "pxor\t{%2, %0|%0, %2}"
18712   [(set_attr "type" "mmxadd")
18713    (set_attr "mode" "DI")
18714    (set_attr "memory" "none")])
18715
18716 ;; Same as pxor, but don't show input operands so that we don't think
18717 ;; they are live.
18718 (define_insn "mmx_clrdi"
18719   [(set (match_operand:DI 0 "register_operand" "=y")
18720         (unspec:DI [(const_int 0)] UNSPEC_NOP))]
18721   "TARGET_MMX"
18722   "pxor\t{%0, %0|%0, %0}"
18723   [(set_attr "type" "mmxadd")
18724    (set_attr "mode" "DI")
18725    (set_attr "memory" "none")])
18726
18727 (define_insn "mmx_anddi3"
18728   [(set (match_operand:DI 0 "register_operand" "=y")
18729         (unspec:DI
18730          [(and:DI (match_operand:DI 1 "register_operand" "0")
18731                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
18732          UNSPEC_NOP))]
18733   "TARGET_MMX"
18734   "pand\t{%2, %0|%0, %2}"
18735   [(set_attr "type" "mmxadd")
18736    (set_attr "mode" "DI")])
18737
18738 (define_insn "mmx_nanddi3"
18739   [(set (match_operand:DI 0 "register_operand" "=y")
18740         (unspec:DI
18741          [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
18742                           (match_operand:DI 2 "nonimmediate_operand" "ym"))]
18743          UNSPEC_NOP))]
18744   "TARGET_MMX"
18745   "pandn\t{%2, %0|%0, %2}"
18746   [(set_attr "type" "mmxadd")
18747    (set_attr "mode" "DI")])
18748
18749
18750 ;; MMX unsigned averages/sum of absolute differences
18751
18752 (define_insn "mmx_uavgv8qi3"
18753   [(set (match_operand:V8QI 0 "register_operand" "=y")
18754         (ashiftrt:V8QI
18755          (plus:V8QI (plus:V8QI
18756                      (match_operand:V8QI 1 "register_operand" "0")
18757                      (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
18758                     (const_vector:V8QI [(const_int 1)
18759                                         (const_int 1)
18760                                         (const_int 1)
18761                                         (const_int 1)
18762                                         (const_int 1)
18763                                         (const_int 1)
18764                                         (const_int 1)
18765                                         (const_int 1)]))
18766          (const_int 1)))]
18767   "TARGET_SSE || TARGET_3DNOW_A"
18768   "pavgb\t{%2, %0|%0, %2}"
18769   [(set_attr "type" "mmxshft")
18770    (set_attr "mode" "DI")])
18771
18772 (define_insn "mmx_uavgv4hi3"
18773   [(set (match_operand:V4HI 0 "register_operand" "=y")
18774         (ashiftrt:V4HI
18775          (plus:V4HI (plus:V4HI
18776                      (match_operand:V4HI 1 "register_operand" "0")
18777                      (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
18778                     (const_vector:V4HI [(const_int 1)
18779                                         (const_int 1)
18780                                         (const_int 1)
18781                                         (const_int 1)]))
18782          (const_int 1)))]
18783   "TARGET_SSE || TARGET_3DNOW_A"
18784   "pavgw\t{%2, %0|%0, %2}"
18785   [(set_attr "type" "mmxshft")
18786    (set_attr "mode" "DI")])
18787
18788 (define_insn "mmx_psadbw"
18789   [(set (match_operand:DI 0 "register_operand" "=y")
18790         (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
18791                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
18792                    UNSPEC_PSADBW))]
18793   "TARGET_SSE || TARGET_3DNOW_A"
18794   "psadbw\t{%2, %0|%0, %2}"
18795   [(set_attr "type" "mmxshft")
18796    (set_attr "mode" "DI")])
18797
18798
18799 ;; MMX insert/extract/shuffle
18800
18801 (define_insn "mmx_pinsrw"
18802   [(set (match_operand:V4HI 0 "register_operand" "=y")
18803         (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
18804                         (vec_duplicate:V4HI
18805                          (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
18806                         (match_operand:SI 3 "immediate_operand" "i")))]
18807   "TARGET_SSE || TARGET_3DNOW_A"
18808   "pinsrw\t{%3, %2, %0|%0, %2, %3}"
18809   [(set_attr "type" "mmxcvt")
18810    (set_attr "mode" "DI")])
18811
18812 (define_insn "mmx_pextrw"
18813   [(set (match_operand:SI 0 "register_operand" "=r")
18814         (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
18815                                        (parallel
18816                                         [(match_operand:SI 2 "immediate_operand" "i")]))))]
18817   "TARGET_SSE || TARGET_3DNOW_A"
18818   "pextrw\t{%2, %1, %0|%0, %1, %2}"
18819   [(set_attr "type" "mmxcvt")
18820    (set_attr "mode" "DI")])
18821
18822 (define_insn "mmx_pshufw"
18823   [(set (match_operand:V4HI 0 "register_operand" "=y")
18824         (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "0")
18825                       (match_operand:SI 2 "immediate_operand" "i")]
18826                      UNSPEC_SHUFFLE))]
18827   "TARGET_SSE || TARGET_3DNOW_A"
18828   "pshufw\t{%2, %1, %0|%0, %1, %2}"
18829   [(set_attr "type" "mmxcvt")
18830    (set_attr "mode" "DI")])
18831
18832
18833 ;; MMX mask-generating comparisons
18834
18835 (define_insn "eqv8qi3"
18836   [(set (match_operand:V8QI 0 "register_operand" "=y")
18837         (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
18838                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18839   "TARGET_MMX"
18840   "pcmpeqb\t{%2, %0|%0, %2}"
18841   [(set_attr "type" "mmxcmp")
18842    (set_attr "mode" "DI")])
18843
18844 (define_insn "eqv4hi3"
18845   [(set (match_operand:V4HI 0 "register_operand" "=y")
18846         (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
18847                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18848   "TARGET_MMX"
18849   "pcmpeqw\t{%2, %0|%0, %2}"
18850   [(set_attr "type" "mmxcmp")
18851    (set_attr "mode" "DI")])
18852
18853 (define_insn "eqv2si3"
18854   [(set (match_operand:V2SI 0 "register_operand" "=y")
18855         (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
18856                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
18857   "TARGET_MMX"
18858   "pcmpeqd\t{%2, %0|%0, %2}"
18859   [(set_attr "type" "mmxcmp")
18860    (set_attr "mode" "DI")])
18861
18862 (define_insn "gtv8qi3"
18863   [(set (match_operand:V8QI 0 "register_operand" "=y")
18864         (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
18865                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18866   "TARGET_MMX"
18867   "pcmpgtb\t{%2, %0|%0, %2}"
18868   [(set_attr "type" "mmxcmp")
18869    (set_attr "mode" "DI")])
18870
18871 (define_insn "gtv4hi3"
18872   [(set (match_operand:V4HI 0 "register_operand" "=y")
18873         (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
18874                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18875   "TARGET_MMX"
18876   "pcmpgtw\t{%2, %0|%0, %2}"
18877   [(set_attr "type" "mmxcmp")
18878    (set_attr "mode" "DI")])
18879
18880 (define_insn "gtv2si3"
18881   [(set (match_operand:V2SI 0 "register_operand" "=y")
18882         (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
18883                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
18884   "TARGET_MMX"
18885   "pcmpgtd\t{%2, %0|%0, %2}"
18886   [(set_attr "type" "mmxcmp")
18887    (set_attr "mode" "DI")])
18888
18889
18890 ;; MMX max/min insns
18891
18892 (define_insn "umaxv8qi3"
18893   [(set (match_operand:V8QI 0 "register_operand" "=y")
18894         (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
18895                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18896   "TARGET_SSE || TARGET_3DNOW_A"
18897   "pmaxub\t{%2, %0|%0, %2}"
18898   [(set_attr "type" "mmxadd")
18899    (set_attr "mode" "DI")])
18900
18901 (define_insn "smaxv4hi3"
18902   [(set (match_operand:V4HI 0 "register_operand" "=y")
18903         (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
18904                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18905   "TARGET_SSE || TARGET_3DNOW_A"
18906   "pmaxsw\t{%2, %0|%0, %2}"
18907   [(set_attr "type" "mmxadd")
18908    (set_attr "mode" "DI")])
18909
18910 (define_insn "uminv8qi3"
18911   [(set (match_operand:V8QI 0 "register_operand" "=y")
18912         (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
18913                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18914   "TARGET_SSE || TARGET_3DNOW_A"
18915   "pminub\t{%2, %0|%0, %2}"
18916   [(set_attr "type" "mmxadd")
18917    (set_attr "mode" "DI")])
18918
18919 (define_insn "sminv4hi3"
18920   [(set (match_operand:V4HI 0 "register_operand" "=y")
18921         (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
18922                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18923   "TARGET_SSE || TARGET_3DNOW_A"
18924   "pminsw\t{%2, %0|%0, %2}"
18925   [(set_attr "type" "mmxadd")
18926    (set_attr "mode" "DI")])
18927
18928
18929 ;; MMX shifts
18930
18931 (define_insn "ashrv4hi3"
18932   [(set (match_operand:V4HI 0 "register_operand" "=y")
18933         (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
18934                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
18935   "TARGET_MMX"
18936   "psraw\t{%2, %0|%0, %2}"
18937   [(set_attr "type" "mmxshft")
18938    (set_attr "mode" "DI")])
18939
18940 (define_insn "ashrv2si3"
18941   [(set (match_operand:V2SI 0 "register_operand" "=y")
18942         (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
18943                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
18944   "TARGET_MMX"
18945   "psrad\t{%2, %0|%0, %2}"
18946   [(set_attr "type" "mmxshft")
18947    (set_attr "mode" "DI")])
18948
18949 (define_insn "lshrv4hi3"
18950   [(set (match_operand:V4HI 0 "register_operand" "=y")
18951         (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
18952                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
18953   "TARGET_MMX"
18954   "psrlw\t{%2, %0|%0, %2}"
18955   [(set_attr "type" "mmxshft")
18956    (set_attr "mode" "DI")])
18957
18958 (define_insn "lshrv2si3"
18959   [(set (match_operand:V2SI 0 "register_operand" "=y")
18960         (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
18961                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
18962   "TARGET_MMX"
18963   "psrld\t{%2, %0|%0, %2}"
18964   [(set_attr "type" "mmxshft")
18965    (set_attr "mode" "DI")])
18966
18967 ;; See logical MMX insns.
18968 (define_insn "mmx_lshrdi3"
18969   [(set (match_operand:DI 0 "register_operand" "=y")
18970         (unspec:DI
18971           [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
18972                        (match_operand:DI 2 "nonmemory_operand" "yi"))]
18973           UNSPEC_NOP))]
18974   "TARGET_MMX"
18975   "psrlq\t{%2, %0|%0, %2}"
18976   [(set_attr "type" "mmxshft")
18977    (set_attr "mode" "DI")])
18978
18979 (define_insn "ashlv4hi3"
18980   [(set (match_operand:V4HI 0 "register_operand" "=y")
18981         (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
18982                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
18983   "TARGET_MMX"
18984   "psllw\t{%2, %0|%0, %2}"
18985   [(set_attr "type" "mmxshft")
18986    (set_attr "mode" "DI")])
18987
18988 (define_insn "ashlv2si3"
18989   [(set (match_operand:V2SI 0 "register_operand" "=y")
18990         (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
18991                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
18992   "TARGET_MMX"
18993   "pslld\t{%2, %0|%0, %2}"
18994   [(set_attr "type" "mmxshft")
18995    (set_attr "mode" "DI")])
18996
18997 ;; See logical MMX insns.
18998 (define_insn "mmx_ashldi3"
18999   [(set (match_operand:DI 0 "register_operand" "=y")
19000         (unspec:DI
19001          [(ashift:DI (match_operand:DI 1 "register_operand" "0")
19002                      (match_operand:DI 2 "nonmemory_operand" "yi"))]
19003          UNSPEC_NOP))]
19004   "TARGET_MMX"
19005   "psllq\t{%2, %0|%0, %2}"
19006   [(set_attr "type" "mmxshft")
19007    (set_attr "mode" "DI")])
19008
19009
19010 ;; MMX pack/unpack insns.
19011
19012 (define_insn "mmx_packsswb"
19013   [(set (match_operand:V8QI 0 "register_operand" "=y")
19014         (vec_concat:V8QI
19015          (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
19016          (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
19017   "TARGET_MMX"
19018   "packsswb\t{%2, %0|%0, %2}"
19019   [(set_attr "type" "mmxshft")
19020    (set_attr "mode" "DI")])
19021
19022 (define_insn "mmx_packssdw"
19023   [(set (match_operand:V4HI 0 "register_operand" "=y")
19024         (vec_concat:V4HI
19025          (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
19026          (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
19027   "TARGET_MMX"
19028   "packssdw\t{%2, %0|%0, %2}"
19029   [(set_attr "type" "mmxshft")
19030    (set_attr "mode" "DI")])
19031
19032 (define_insn "mmx_packuswb"
19033   [(set (match_operand:V8QI 0 "register_operand" "=y")
19034         (vec_concat:V8QI
19035          (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
19036          (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
19037   "TARGET_MMX"
19038   "packuswb\t{%2, %0|%0, %2}"
19039   [(set_attr "type" "mmxshft")
19040    (set_attr "mode" "DI")])
19041
19042 (define_insn "mmx_punpckhbw"
19043   [(set (match_operand:V8QI 0 "register_operand" "=y")
19044         (vec_merge:V8QI
19045          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
19046                           (parallel [(const_int 4)
19047                                      (const_int 0)
19048                                      (const_int 5)
19049                                      (const_int 1)
19050                                      (const_int 6)
19051                                      (const_int 2)
19052                                      (const_int 7)
19053                                      (const_int 3)]))
19054          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
19055                           (parallel [(const_int 0)
19056                                      (const_int 4)
19057                                      (const_int 1)
19058                                      (const_int 5)
19059                                      (const_int 2)
19060                                      (const_int 6)
19061                                      (const_int 3)
19062                                      (const_int 7)]))
19063          (const_int 85)))]
19064   "TARGET_MMX"
19065   "punpckhbw\t{%2, %0|%0, %2}"
19066   [(set_attr "type" "mmxcvt")
19067    (set_attr "mode" "DI")])
19068
19069 (define_insn "mmx_punpckhwd"
19070   [(set (match_operand:V4HI 0 "register_operand" "=y")
19071         (vec_merge:V4HI
19072          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
19073                           (parallel [(const_int 0)
19074                                      (const_int 2)
19075                                      (const_int 1)
19076                                      (const_int 3)]))
19077          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
19078                           (parallel [(const_int 2)
19079                                      (const_int 0)
19080                                      (const_int 3)
19081                                      (const_int 1)]))
19082          (const_int 5)))]
19083   "TARGET_MMX"
19084   "punpckhwd\t{%2, %0|%0, %2}"
19085   [(set_attr "type" "mmxcvt")
19086    (set_attr "mode" "DI")])
19087
19088 (define_insn "mmx_punpckhdq"
19089   [(set (match_operand:V2SI 0 "register_operand" "=y")
19090         (vec_merge:V2SI
19091          (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
19092                           (parallel [(const_int 0)
19093                                      (const_int 1)]))
19094          (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
19095                           (parallel [(const_int 1)
19096                                      (const_int 0)]))
19097          (const_int 1)))]
19098   "TARGET_MMX"
19099   "punpckhdq\t{%2, %0|%0, %2}"
19100   [(set_attr "type" "mmxcvt")
19101    (set_attr "mode" "DI")])
19102
19103 (define_insn "mmx_punpcklbw"
19104   [(set (match_operand:V8QI 0 "register_operand" "=y")
19105         (vec_merge:V8QI
19106          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
19107                           (parallel [(const_int 0)
19108                                      (const_int 4)
19109                                      (const_int 1)
19110                                      (const_int 5)
19111                                      (const_int 2)
19112                                      (const_int 6)
19113                                      (const_int 3)
19114                                      (const_int 7)]))
19115          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
19116                           (parallel [(const_int 4)
19117                                      (const_int 0)
19118                                      (const_int 5)
19119                                      (const_int 1)
19120                                      (const_int 6)
19121                                      (const_int 2)
19122                                      (const_int 7)
19123                                      (const_int 3)]))
19124          (const_int 85)))]
19125   "TARGET_MMX"
19126   "punpcklbw\t{%2, %0|%0, %2}"
19127   [(set_attr "type" "mmxcvt")
19128    (set_attr "mode" "DI")])
19129
19130 (define_insn "mmx_punpcklwd"
19131   [(set (match_operand:V4HI 0 "register_operand" "=y")
19132         (vec_merge:V4HI
19133          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
19134                           (parallel [(const_int 2)
19135                                      (const_int 0)
19136                                      (const_int 3)
19137                                      (const_int 1)]))
19138          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
19139                           (parallel [(const_int 0)
19140                                      (const_int 2)
19141                                      (const_int 1)
19142                                      (const_int 3)]))
19143          (const_int 5)))]
19144   "TARGET_MMX"
19145   "punpcklwd\t{%2, %0|%0, %2}"
19146   [(set_attr "type" "mmxcvt")
19147    (set_attr "mode" "DI")])
19148
19149 (define_insn "mmx_punpckldq"
19150   [(set (match_operand:V2SI 0 "register_operand" "=y")
19151         (vec_merge:V2SI
19152          (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
19153                            (parallel [(const_int 1)
19154                                       (const_int 0)]))
19155          (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
19156                           (parallel [(const_int 0)
19157                                      (const_int 1)]))
19158          (const_int 1)))]
19159   "TARGET_MMX"
19160   "punpckldq\t{%2, %0|%0, %2}"
19161   [(set_attr "type" "mmxcvt")
19162    (set_attr "mode" "DI")])
19163
19164
19165 ;; Miscellaneous stuff
19166
19167 (define_insn "emms"
19168   [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
19169    (clobber (reg:XF 8))
19170    (clobber (reg:XF 9))
19171    (clobber (reg:XF 10))
19172    (clobber (reg:XF 11))
19173    (clobber (reg:XF 12))
19174    (clobber (reg:XF 13))
19175    (clobber (reg:XF 14))
19176    (clobber (reg:XF 15))
19177    (clobber (reg:DI 29))
19178    (clobber (reg:DI 30))
19179    (clobber (reg:DI 31))
19180    (clobber (reg:DI 32))
19181    (clobber (reg:DI 33))
19182    (clobber (reg:DI 34))
19183    (clobber (reg:DI 35))
19184    (clobber (reg:DI 36))]
19185   "TARGET_MMX"
19186   "emms"
19187   [(set_attr "type" "mmx")
19188    (set_attr "memory" "unknown")])
19189
19190 (define_insn "ldmxcsr"
19191   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
19192                     UNSPECV_LDMXCSR)]
19193   "TARGET_MMX"
19194   "ldmxcsr\t%0"
19195   [(set_attr "type" "mmx")
19196    (set_attr "memory" "load")])
19197
19198 (define_insn "stmxcsr"
19199   [(set (match_operand:SI 0 "memory_operand" "=m")
19200         (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
19201   "TARGET_MMX"
19202   "stmxcsr\t%0"
19203   [(set_attr "type" "mmx")
19204    (set_attr "memory" "store")])
19205
19206 (define_expand "sfence"
19207   [(set (match_dup 0)
19208         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
19209   "TARGET_SSE || TARGET_3DNOW_A"
19210 {
19211   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
19212   MEM_VOLATILE_P (operands[0]) = 1;
19213 })
19214
19215 (define_insn "*sfence_insn"
19216   [(set (match_operand:BLK 0 "" "")
19217         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
19218   "TARGET_SSE || TARGET_3DNOW_A"
19219   "sfence"
19220   [(set_attr "type" "sse")
19221    (set_attr "memory" "unknown")])
19222
19223 (define_expand "sse_prologue_save"
19224   [(parallel [(set (match_operand:BLK 0 "" "")
19225                    (unspec:BLK [(reg:DI 21)
19226                                 (reg:DI 22)
19227                                 (reg:DI 23)
19228                                 (reg:DI 24)
19229                                 (reg:DI 25)
19230                                 (reg:DI 26)
19231                                 (reg:DI 27)
19232                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19233               (use (match_operand:DI 1 "register_operand" ""))
19234               (use (match_operand:DI 2 "immediate_operand" ""))
19235               (use (label_ref:DI (match_operand 3 "" "")))])]
19236   "TARGET_64BIT"
19237   "")
19238
19239 (define_insn "*sse_prologue_save_insn"
19240   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
19241                           (match_operand:DI 4 "const_int_operand" "n")))
19242         (unspec:BLK [(reg:DI 21)
19243                      (reg:DI 22)
19244                      (reg:DI 23)
19245                      (reg:DI 24)
19246                      (reg:DI 25)
19247                      (reg:DI 26)
19248                      (reg:DI 27)
19249                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19250    (use (match_operand:DI 1 "register_operand" "r"))
19251    (use (match_operand:DI 2 "const_int_operand" "i"))
19252    (use (label_ref:DI (match_operand 3 "" "X")))]
19253   "TARGET_64BIT
19254    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
19255    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
19256   "*
19257 {
19258   int i;
19259   operands[0] = gen_rtx_MEM (Pmode,
19260                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
19261   output_asm_insn (\"jmp\\t%A1\", operands);
19262   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
19263     {
19264       operands[4] = adjust_address (operands[0], DImode, i*16);
19265       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
19266       PUT_MODE (operands[4], TImode);
19267       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
19268         output_asm_insn (\"rex\", operands);
19269       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
19270     }
19271   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
19272                              CODE_LABEL_NUMBER (operands[3]));
19273   RET;
19274 }
19275   "
19276   [(set_attr "type" "other")
19277    (set_attr "length_immediate" "0")
19278    (set_attr "length_address" "0")
19279    (set_attr "length" "135")
19280    (set_attr "memory" "store")
19281    (set_attr "modrm" "0")
19282    (set_attr "mode" "DI")])
19283
19284 ;; 3Dnow! instructions
19285
19286 (define_insn "addv2sf3"
19287   [(set (match_operand:V2SF 0 "register_operand" "=y")
19288         (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
19289                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19290   "TARGET_3DNOW"
19291   "pfadd\\t{%2, %0|%0, %2}"
19292   [(set_attr "type" "mmxadd")
19293    (set_attr "mode" "V2SF")])
19294
19295 (define_insn "subv2sf3"
19296   [(set (match_operand:V2SF 0 "register_operand" "=y")
19297         (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
19298                     (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19299   "TARGET_3DNOW"
19300   "pfsub\\t{%2, %0|%0, %2}"
19301   [(set_attr "type" "mmxadd")
19302    (set_attr "mode" "V2SF")])
19303
19304 (define_insn "subrv2sf3"
19305   [(set (match_operand:V2SF 0 "register_operand" "=y")
19306         (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
19307                     (match_operand:V2SF 1 "register_operand" "0")))]
19308   "TARGET_3DNOW"
19309   "pfsubr\\t{%2, %0|%0, %2}"
19310   [(set_attr "type" "mmxadd")
19311    (set_attr "mode" "V2SF")])
19312
19313 (define_insn "gtv2sf3"
19314   [(set (match_operand:V2SI 0 "register_operand" "=y")
19315         (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
19316                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19317  "TARGET_3DNOW"
19318   "pfcmpgt\\t{%2, %0|%0, %2}"
19319   [(set_attr "type" "mmxcmp")
19320    (set_attr "mode" "V2SF")])
19321
19322 (define_insn "gev2sf3"
19323   [(set (match_operand:V2SI 0 "register_operand" "=y")
19324         (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
19325                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19326   "TARGET_3DNOW"
19327   "pfcmpge\\t{%2, %0|%0, %2}"
19328   [(set_attr "type" "mmxcmp")
19329    (set_attr "mode" "V2SF")])
19330
19331 (define_insn "eqv2sf3"
19332   [(set (match_operand:V2SI 0 "register_operand" "=y")
19333         (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
19334                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19335   "TARGET_3DNOW"
19336   "pfcmpeq\\t{%2, %0|%0, %2}"
19337   [(set_attr "type" "mmxcmp")
19338    (set_attr "mode" "V2SF")])
19339
19340 (define_insn "pfmaxv2sf3"
19341   [(set (match_operand:V2SF 0 "register_operand" "=y")
19342         (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
19343                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19344   "TARGET_3DNOW"
19345   "pfmax\\t{%2, %0|%0, %2}"
19346   [(set_attr "type" "mmxadd")
19347    (set_attr "mode" "V2SF")])
19348
19349 (define_insn "pfminv2sf3"
19350   [(set (match_operand:V2SF 0 "register_operand" "=y")
19351         (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
19352                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19353   "TARGET_3DNOW"
19354   "pfmin\\t{%2, %0|%0, %2}"
19355   [(set_attr "type" "mmxadd")
19356    (set_attr "mode" "V2SF")])
19357
19358 (define_insn "mulv2sf3"
19359   [(set (match_operand:V2SF 0 "register_operand" "=y")
19360         (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
19361                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19362   "TARGET_3DNOW"
19363   "pfmul\\t{%2, %0|%0, %2}"
19364   [(set_attr "type" "mmxmul")
19365    (set_attr "mode" "V2SF")])
19366
19367 (define_insn "femms"
19368   [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
19369    (clobber (reg:XF 8))
19370    (clobber (reg:XF 9))
19371    (clobber (reg:XF 10))
19372    (clobber (reg:XF 11))
19373    (clobber (reg:XF 12))
19374    (clobber (reg:XF 13))
19375    (clobber (reg:XF 14))
19376    (clobber (reg:XF 15))
19377    (clobber (reg:DI 29))
19378    (clobber (reg:DI 30))
19379    (clobber (reg:DI 31))
19380    (clobber (reg:DI 32))
19381    (clobber (reg:DI 33))
19382    (clobber (reg:DI 34))
19383    (clobber (reg:DI 35))
19384    (clobber (reg:DI 36))]
19385   "TARGET_3DNOW"
19386   "femms"
19387   [(set_attr "type" "mmx")])
19388
19389 (define_insn "pf2id"
19390   [(set (match_operand:V2SI 0 "register_operand" "=y")
19391         (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
19392   "TARGET_3DNOW"
19393   "pf2id\\t{%1, %0|%0, %1}"
19394   [(set_attr "type" "mmxcvt")
19395    (set_attr "mode" "V2SF")])
19396
19397 (define_insn "pf2iw"
19398   [(set (match_operand:V2SI 0 "register_operand" "=y")
19399         (sign_extend:V2SI
19400            (ss_truncate:V2HI
19401               (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
19402   "TARGET_3DNOW_A"
19403   "pf2iw\\t{%1, %0|%0, %1}"
19404   [(set_attr "type" "mmxcvt")
19405    (set_attr "mode" "V2SF")])
19406
19407 (define_insn "pfacc"
19408   [(set (match_operand:V2SF 0 "register_operand" "=y")
19409         (vec_concat:V2SF
19410            (plus:SF
19411               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
19412                              (parallel [(const_int  0)]))
19413               (vec_select:SF (match_dup 1)
19414                              (parallel [(const_int 1)])))
19415            (plus:SF
19416               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
19417                              (parallel [(const_int  0)]))
19418               (vec_select:SF (match_dup 2)
19419                              (parallel [(const_int 1)])))))]
19420   "TARGET_3DNOW"
19421   "pfacc\\t{%2, %0|%0, %2}"
19422   [(set_attr "type" "mmxadd")
19423    (set_attr "mode" "V2SF")])
19424
19425 (define_insn "pfnacc"
19426   [(set (match_operand:V2SF 0 "register_operand" "=y")
19427         (vec_concat:V2SF
19428            (minus:SF
19429               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
19430                              (parallel [(const_int 0)]))
19431               (vec_select:SF (match_dup 1)
19432                              (parallel [(const_int 1)])))
19433            (minus:SF
19434               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
19435                              (parallel [(const_int  0)]))
19436               (vec_select:SF (match_dup 2)
19437                              (parallel [(const_int 1)])))))]
19438   "TARGET_3DNOW_A"
19439   "pfnacc\\t{%2, %0|%0, %2}"
19440   [(set_attr "type" "mmxadd")
19441    (set_attr "mode" "V2SF")])
19442
19443 (define_insn "pfpnacc"
19444   [(set (match_operand:V2SF 0 "register_operand" "=y")
19445         (vec_concat:V2SF
19446            (minus:SF
19447               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
19448                              (parallel [(const_int 0)]))
19449               (vec_select:SF (match_dup 1)
19450                              (parallel [(const_int 1)])))
19451            (plus:SF
19452               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
19453                              (parallel [(const_int 0)]))
19454               (vec_select:SF (match_dup 2)
19455                              (parallel [(const_int 1)])))))]
19456   "TARGET_3DNOW_A"
19457   "pfpnacc\\t{%2, %0|%0, %2}"
19458   [(set_attr "type" "mmxadd")
19459    (set_attr "mode" "V2SF")])
19460
19461 (define_insn "pi2fw"
19462   [(set (match_operand:V2SF 0 "register_operand" "=y")
19463         (float:V2SF
19464            (vec_concat:V2SI
19465               (sign_extend:SI
19466                  (truncate:HI
19467                     (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
19468                                    (parallel [(const_int 0)]))))
19469               (sign_extend:SI
19470                  (truncate:HI
19471                     (vec_select:SI (match_dup 1)
19472                                    (parallel [(const_int  1)])))))))]
19473   "TARGET_3DNOW_A"
19474   "pi2fw\\t{%1, %0|%0, %1}"
19475   [(set_attr "type" "mmxcvt")
19476    (set_attr "mode" "V2SF")])
19477
19478 (define_insn "floatv2si2"
19479   [(set (match_operand:V2SF 0 "register_operand" "=y")
19480         (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
19481   "TARGET_3DNOW"
19482   "pi2fd\\t{%1, %0|%0, %1}"
19483   [(set_attr "type" "mmxcvt")
19484    (set_attr "mode" "V2SF")])
19485
19486 ;; This insn is identical to pavgb in operation, but the opcode is
19487 ;; different.  To avoid accidentally matching pavgb, use an unspec.
19488
19489 (define_insn "pavgusb"
19490  [(set (match_operand:V8QI 0 "register_operand" "=y")
19491        (unspec:V8QI
19492           [(match_operand:V8QI 1 "register_operand" "0")
19493            (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
19494           UNSPEC_PAVGUSB))]
19495   "TARGET_3DNOW"
19496   "pavgusb\\t{%2, %0|%0, %2}"
19497   [(set_attr "type" "mmxshft")
19498    (set_attr "mode" "TI")])
19499
19500 ;; 3DNow reciprical and sqrt
19501  
19502 (define_insn "pfrcpv2sf2"
19503   [(set (match_operand:V2SF 0 "register_operand" "=y")
19504         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
19505         UNSPEC_PFRCP))]
19506   "TARGET_3DNOW"
19507   "pfrcp\\t{%1, %0|%0, %1}"
19508   [(set_attr "type" "mmx")
19509    (set_attr "mode" "TI")])
19510
19511 (define_insn "pfrcpit1v2sf3"
19512   [(set (match_operand:V2SF 0 "register_operand" "=y")
19513         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
19514                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
19515                      UNSPEC_PFRCPIT1))]
19516   "TARGET_3DNOW"
19517   "pfrcpit1\\t{%2, %0|%0, %2}"
19518   [(set_attr "type" "mmx")
19519    (set_attr "mode" "TI")])
19520
19521 (define_insn "pfrcpit2v2sf3"
19522   [(set (match_operand:V2SF 0 "register_operand" "=y")
19523         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
19524                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
19525                      UNSPEC_PFRCPIT2))]
19526   "TARGET_3DNOW"
19527   "pfrcpit2\\t{%2, %0|%0, %2}"
19528   [(set_attr "type" "mmx")
19529    (set_attr "mode" "TI")])
19530
19531 (define_insn "pfrsqrtv2sf2"
19532   [(set (match_operand:V2SF 0 "register_operand" "=y")
19533         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
19534                      UNSPEC_PFRSQRT))]
19535   "TARGET_3DNOW"
19536   "pfrsqrt\\t{%1, %0|%0, %1}"
19537   [(set_attr "type" "mmx")
19538    (set_attr "mode" "TI")])
19539                 
19540 (define_insn "pfrsqit1v2sf3"
19541   [(set (match_operand:V2SF 0 "register_operand" "=y")
19542         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
19543                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
19544                      UNSPEC_PFRSQIT1))]
19545   "TARGET_3DNOW"
19546   "pfrsqit1\\t{%2, %0|%0, %2}"
19547   [(set_attr "type" "mmx")
19548    (set_attr "mode" "TI")])
19549
19550 (define_insn "pmulhrwv4hi3"
19551   [(set (match_operand:V4HI 0 "register_operand" "=y")
19552         (truncate:V4HI
19553            (lshiftrt:V4SI
19554               (plus:V4SI
19555                  (mult:V4SI
19556                     (sign_extend:V4SI
19557                        (match_operand:V4HI 1 "register_operand" "0"))
19558                     (sign_extend:V4SI
19559                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
19560                  (const_vector:V4SI [(const_int 32768)
19561                                      (const_int 32768)
19562                                      (const_int 32768)
19563                                      (const_int 32768)]))
19564               (const_int 16))))]
19565   "TARGET_3DNOW"
19566   "pmulhrw\\t{%2, %0|%0, %2}"
19567   [(set_attr "type" "mmxmul")
19568    (set_attr "mode" "TI")])
19569
19570 (define_insn "pswapdv2si2"
19571   [(set (match_operand:V2SI 0 "register_operand" "=y")
19572         (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
19573                          (parallel [(const_int 1) (const_int 0)])))]
19574   "TARGET_3DNOW_A"
19575   "pswapd\\t{%1, %0|%0, %1}"
19576   [(set_attr "type" "mmxcvt")
19577    (set_attr "mode" "TI")])
19578
19579 (define_insn "pswapdv2sf2"
19580   [(set (match_operand:V2SF 0 "register_operand" "=y")
19581         (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
19582                          (parallel [(const_int 1) (const_int 0)])))]
19583   "TARGET_3DNOW_A"
19584   "pswapd\\t{%1, %0|%0, %1}"
19585   [(set_attr "type" "mmxcvt")
19586    (set_attr "mode" "TI")])
19587
19588 (define_expand "prefetch"
19589   [(prefetch (match_operand:SI 0 "address_operand" "")
19590              (match_operand:SI 1 "const_int_operand" "")
19591              (match_operand:SI 2 "const_int_operand" ""))]
19592   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
19593 {
19594   int rw = INTVAL (operands[1]);
19595   int locality = INTVAL (operands[2]);
19596
19597   if (rw != 0 && rw != 1)
19598     abort ();
19599   if (locality < 0 || locality > 3)
19600     abort ();
19601
19602   /* Use 3dNOW prefetch in case we are asking for write prefetch not
19603      suported by SSE counterpart or the SSE prefetch is not available
19604      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
19605      of locality.  */
19606   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
19607     operands[2] = GEN_INT (3);
19608   else
19609     operands[1] = const0_rtx;
19610 })
19611
19612 (define_insn "*prefetch_sse"
19613   [(prefetch (match_operand:SI 0 "address_operand" "p")
19614              (const_int 0)
19615              (match_operand:SI 1 "const_int_operand" ""))]
19616   "TARGET_PREFETCH_SSE"
19617 {
19618   static const char * const patterns[4] = {
19619    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19620   };
19621
19622   int locality = INTVAL (operands[1]);
19623   if (locality < 0 || locality > 3)
19624     abort ();
19625
19626   return patterns[locality];  
19627 }
19628   [(set_attr "type" "sse")
19629    (set_attr "memory" "none")])
19630
19631 (define_insn "*prefetch_3dnow"
19632   [(prefetch (match_operand:SI 0 "address_operand" "p")
19633              (match_operand:SI 1 "const_int_operand" "n")
19634              (const_int 3))]
19635   "TARGET_3DNOW"
19636 {
19637   if (INTVAL (operands[1]) == 0)
19638     return "prefetch\t%a0";
19639   else
19640     return "prefetchw\t%a0";
19641 }
19642   [(set_attr "type" "mmx")
19643    (set_attr "memory" "none")])
19644
19645 ;; SSE2 support
19646
19647 (define_insn "addv2df3"
19648   [(set (match_operand:V2DF 0 "register_operand" "=x")
19649         (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
19650                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
19651   "TARGET_SSE2"
19652   "addpd\t{%2, %0|%0, %2}"
19653   [(set_attr "type" "sseadd")
19654    (set_attr "mode" "V2DF")])
19655
19656 (define_insn "vmaddv2df3"
19657   [(set (match_operand:V2DF 0 "register_operand" "=x")
19658         (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
19659                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
19660                         (match_dup 1)
19661                         (const_int 1)))]
19662   "TARGET_SSE2"
19663   "addsd\t{%2, %0|%0, %2}"
19664   [(set_attr "type" "sseadd")
19665    (set_attr "mode" "DF")])
19666
19667 (define_insn "subv2df3"
19668   [(set (match_operand:V2DF 0 "register_operand" "=x")
19669         (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
19670                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
19671   "TARGET_SSE2"
19672   "subpd\t{%2, %0|%0, %2}"
19673   [(set_attr "type" "sseadd")
19674    (set_attr "mode" "V2DF")])
19675
19676 (define_insn "vmsubv2df3"
19677   [(set (match_operand:V2DF 0 "register_operand" "=x")
19678         (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
19679                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
19680                         (match_dup 1)
19681                         (const_int 1)))]
19682   "TARGET_SSE2"
19683   "subsd\t{%2, %0|%0, %2}"
19684   [(set_attr "type" "sseadd")
19685    (set_attr "mode" "DF")])
19686
19687 (define_insn "mulv2df3"
19688   [(set (match_operand:V2DF 0 "register_operand" "=x")
19689         (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
19690                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
19691   "TARGET_SSE2"
19692   "mulpd\t{%2, %0|%0, %2}"
19693   [(set_attr "type" "ssemul")
19694    (set_attr "mode" "V2DF")])
19695
19696 (define_insn "vmmulv2df3"
19697   [(set (match_operand:V2DF 0 "register_operand" "=x")
19698         (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
19699                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
19700                         (match_dup 1)
19701                         (const_int 1)))]
19702   "TARGET_SSE2"
19703   "mulsd\t{%2, %0|%0, %2}"
19704   [(set_attr "type" "ssemul")
19705    (set_attr "mode" "DF")])
19706
19707 (define_insn "divv2df3"
19708   [(set (match_operand:V2DF 0 "register_operand" "=x")
19709         (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
19710                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
19711   "TARGET_SSE2"
19712   "divpd\t{%2, %0|%0, %2}"
19713   [(set_attr "type" "ssediv")
19714    (set_attr "mode" "V2DF")])
19715
19716 (define_insn "vmdivv2df3"
19717   [(set (match_operand:V2DF 0 "register_operand" "=x")
19718         (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
19719                                   (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
19720                         (match_dup 1)
19721                         (const_int 1)))]
19722   "TARGET_SSE2"
19723   "divsd\t{%2, %0|%0, %2}"
19724   [(set_attr "type" "ssediv")
19725    (set_attr "mode" "DF")])
19726
19727 ;; SSE min/max
19728
19729 (define_insn "smaxv2df3"
19730   [(set (match_operand:V2DF 0 "register_operand" "=x")
19731         (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
19732                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
19733   "TARGET_SSE2"
19734   "maxpd\t{%2, %0|%0, %2}"
19735   [(set_attr "type" "sseadd")
19736    (set_attr "mode" "V2DF")])
19737
19738 (define_insn "vmsmaxv2df3"
19739   [(set (match_operand:V2DF 0 "register_operand" "=x")
19740         (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
19741                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
19742                         (match_dup 1)
19743                         (const_int 1)))]
19744   "TARGET_SSE2"
19745   "maxsd\t{%2, %0|%0, %2}"
19746   [(set_attr "type" "sseadd")
19747    (set_attr "mode" "DF")])
19748
19749 (define_insn "sminv2df3"
19750   [(set (match_operand:V2DF 0 "register_operand" "=x")
19751         (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
19752                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
19753   "TARGET_SSE2"
19754   "minpd\t{%2, %0|%0, %2}"
19755   [(set_attr "type" "sseadd")
19756    (set_attr "mode" "V2DF")])
19757
19758 (define_insn "vmsminv2df3"
19759   [(set (match_operand:V2DF 0 "register_operand" "=x")
19760         (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
19761                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
19762                         (match_dup 1)
19763                         (const_int 1)))]
19764   "TARGET_SSE2"
19765   "minsd\t{%2, %0|%0, %2}"
19766   [(set_attr "type" "sseadd")
19767    (set_attr "mode" "DF")])
19768
19769 (define_insn "sse2_anddf3"
19770   [(set (match_operand:V2DF 0 "register_operand" "=x")
19771         (subreg:V2DF (and:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "%0") 0)
19772                              (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "xm") 0)) 0))]
19773   "TARGET_SSE2"
19774   "andpd\t{%2, %0|%0, %2}"
19775   [(set_attr "type" "sselog")
19776    (set_attr "mode" "V2DF")])
19777
19778 (define_insn "sse2_nanddf3"
19779   [(set (match_operand:V2DF 0 "register_operand" "=x")
19780         (subreg:V2DF (and:TI (not:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "0") 0))
19781                              (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "xm") 0)) 0))]
19782   "TARGET_SSE2"
19783   "andnpd\t{%2, %0|%0, %2}"
19784   [(set_attr "type" "sselog")
19785    (set_attr "mode" "V2DF")])
19786
19787 (define_insn "sse2_iordf3"
19788   [(set (match_operand:V2DF 0 "register_operand" "=x")
19789         (subreg:V2DF (ior:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "%0") 0)
19790                              (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "xm") 0)) 0))]
19791   "TARGET_SSE2"
19792   "orpd\t{%2, %0|%0, %2}"
19793   [(set_attr "type" "sselog")
19794    (set_attr "mode" "V2DF")])
19795
19796 (define_insn "sse2_xordf3"
19797   [(set (match_operand:V2DF 0 "register_operand" "=x")
19798         (subreg:V2DF (xor:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "%0") 0)
19799                              (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "xm") 0)) 0))]
19800   "TARGET_SSE2"
19801   "xorpd\t{%2, %0|%0, %2}"
19802   [(set_attr "type" "sselog")
19803    (set_attr "mode" "V2DF")])
19804 ;; SSE2 square root.  There doesn't appear to be an extension for the
19805 ;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
19806
19807 (define_insn "sqrtv2df2"
19808   [(set (match_operand:V2DF 0 "register_operand" "=x")
19809         (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
19810   "TARGET_SSE2"
19811   "sqrtpd\t{%1, %0|%0, %1}"
19812   [(set_attr "type" "sse")
19813    (set_attr "mode" "V2DF")])
19814
19815 (define_insn "vmsqrtv2df2"
19816   [(set (match_operand:V2DF 0 "register_operand" "=x")
19817         (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
19818                         (match_operand:V2DF 2 "register_operand" "0")
19819                         (const_int 1)))]
19820   "TARGET_SSE2"
19821   "sqrtsd\t{%1, %0|%0, %1}"
19822   [(set_attr "type" "sse")
19823    (set_attr "mode" "SF")])
19824
19825 ;; SSE mask-generating compares
19826
19827 (define_insn "maskcmpv2df3"
19828   [(set (match_operand:V2DI 0 "register_operand" "=x")
19829         (match_operator:V2DI 3 "sse_comparison_operator"
19830                              [(match_operand:V2DF 1 "register_operand" "0")
19831                               (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
19832   "TARGET_SSE2"
19833   "cmp%D3pd\t{%2, %0|%0, %2}"
19834   [(set_attr "type" "ssecmp")
19835    (set_attr "mode" "V2DF")])
19836
19837 (define_insn "maskncmpv2df3"
19838   [(set (match_operand:V2DI 0 "register_operand" "=x")
19839         (not:V2DI
19840          (match_operator:V2DI 3 "sse_comparison_operator"
19841                               [(match_operand:V2DF 1 "register_operand" "0")
19842                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
19843   "TARGET_SSE2"
19844   "cmpn%D3pd\t{%2, %0|%0, %2}"
19845   [(set_attr "type" "ssecmp")
19846    (set_attr "mode" "V2DF")])
19847
19848 (define_insn "vmmaskcmpv2df3"
19849   [(set (match_operand:V2DI 0 "register_operand" "=x")
19850         (vec_merge:V2DI
19851          (match_operator:V2DI 3 "sse_comparison_operator"
19852                               [(match_operand:V2DF 1 "register_operand" "0")
19853                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])
19854          (match_dup 1)
19855          (const_int 1)))]
19856   "TARGET_SSE2"
19857   "cmp%D3sd\t{%2, %0|%0, %2}"
19858   [(set_attr "type" "ssecmp")
19859    (set_attr "mode" "DF")])
19860
19861 (define_insn "vmmaskncmpv2df3"
19862   [(set (match_operand:V2DI 0 "register_operand" "=x")
19863         (vec_merge:V2DI
19864          (not:V2DI
19865           (match_operator:V2DI 3 "sse_comparison_operator"
19866                                [(match_operand:V2DF 1 "register_operand" "0")
19867                                 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
19868          (subreg:V2DI (match_dup 1) 0)
19869          (const_int 1)))]
19870   "TARGET_SSE2"
19871   "cmp%D3sd\t{%2, %0|%0, %2}"
19872   [(set_attr "type" "ssecmp")
19873    (set_attr "mode" "DF")])
19874
19875 (define_insn "sse2_comi"
19876   [(set (reg:CCFP 17)
19877         (match_operator:CCFP 2 "sse_comparison_operator"
19878                         [(vec_select:DF
19879                           (match_operand:V2DF 0 "register_operand" "x")
19880                           (parallel [(const_int 0)]))
19881                          (vec_select:DF
19882                           (match_operand:V2DF 1 "register_operand" "x")
19883                           (parallel [(const_int 0)]))]))]
19884   "TARGET_SSE2"
19885   "comisd\t{%1, %0|%0, %1}"
19886   [(set_attr "type" "ssecmp")
19887    (set_attr "mode" "DF")])
19888
19889 (define_insn "sse2_ucomi"
19890   [(set (reg:CCFPU 17)
19891         (match_operator:CCFPU 2 "sse_comparison_operator"
19892                         [(vec_select:DF
19893                           (match_operand:V2DF 0 "register_operand" "x")
19894                           (parallel [(const_int 0)]))
19895                          (vec_select:DF
19896                           (match_operand:V2DF 1 "register_operand" "x")
19897                           (parallel [(const_int 0)]))]))]
19898   "TARGET_SSE2"
19899   "ucomisd\t{%1, %0|%0, %1}"
19900   [(set_attr "type" "ssecmp")
19901    (set_attr "mode" "DF")])
19902
19903 ;; SSE Strange Moves.
19904
19905 (define_insn "sse2_movmskpd"
19906   [(set (match_operand:SI 0 "register_operand" "=r")
19907         (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
19908                    UNSPEC_MOVMSK))]
19909   "TARGET_SSE2"
19910   "movmskpd\t{%1, %0|%0, %1}"
19911   [(set_attr "type" "ssecvt")
19912    (set_attr "mode" "V2DF")])
19913
19914 (define_insn "sse2_pmovmskb"
19915   [(set (match_operand:SI 0 "register_operand" "=r")
19916         (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
19917                    UNSPEC_MOVMSK))]
19918   "TARGET_SSE2"
19919   "pmovmskb\t{%1, %0|%0, %1}"
19920   [(set_attr "type" "ssecvt")
19921    (set_attr "mode" "V2DF")])
19922
19923 (define_insn "sse2_maskmovdqu"
19924   [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
19925         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
19926                        (match_operand:V16QI 2 "register_operand" "x")]
19927                       UNSPEC_MASKMOV))]
19928   "TARGET_SSE2"
19929   ;; @@@ check ordering of operands in intel/nonintel syntax
19930   "maskmovdqu\t{%2, %1|%1, %2}"
19931   [(set_attr "type" "ssecvt")
19932    (set_attr "mode" "TI")])
19933
19934 (define_insn "sse2_movntv2df"
19935   [(set (match_operand:V2DF 0 "memory_operand" "=m")
19936         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
19937                      UNSPEC_MOVNT))]
19938   "TARGET_SSE2"
19939   "movntpd\t{%1, %0|%0, %1}"
19940   [(set_attr "type" "ssecvt")
19941    (set_attr "mode" "V2DF")])
19942
19943 (define_insn "sse2_movntv2di"
19944   [(set (match_operand:V2DI 0 "memory_operand" "=m")
19945         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
19946                      UNSPEC_MOVNT))]
19947   "TARGET_SSE2"
19948   "movntdq\t{%1, %0|%0, %1}"
19949   [(set_attr "type" "ssecvt")
19950    (set_attr "mode" "TI")])
19951
19952 (define_insn "sse2_movntsi"
19953   [(set (match_operand:SI 0 "memory_operand" "=m")
19954         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
19955                    UNSPEC_MOVNT))]
19956   "TARGET_SSE2"
19957   "movnti\t{%1, %0|%0, %1}"
19958   [(set_attr "type" "ssecvt")
19959    (set_attr "mode" "V2DF")])
19960
19961 ;; SSE <-> integer/MMX conversions
19962
19963 ;; Conversions between SI and SF
19964
19965 (define_insn "cvtdq2ps"
19966   [(set (match_operand:V4SF 0 "register_operand" "=x")
19967         (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
19968   "TARGET_SSE2"
19969   "cvtdq2ps\t{%1, %0|%0, %1}"
19970   [(set_attr "type" "ssecvt")
19971    (set_attr "mode" "V2DF")])
19972
19973 (define_insn "cvtps2dq"
19974   [(set (match_operand:V4SI 0 "register_operand" "=x")
19975         (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
19976   "TARGET_SSE2"
19977   "cvtps2dq\t{%1, %0|%0, %1}"
19978   [(set_attr "type" "ssecvt")
19979    (set_attr "mode" "TI")])
19980
19981 (define_insn "cvttps2dq"
19982   [(set (match_operand:V4SI 0 "register_operand" "=x")
19983         (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
19984                      UNSPEC_FIX))]
19985   "TARGET_SSE2"
19986   "cvttps2dq\t{%1, %0|%0, %1}"
19987   [(set_attr "type" "ssecvt")
19988    (set_attr "mode" "TI")])
19989
19990 ;; Conversions between SI and DF
19991
19992 (define_insn "cvtdq2pd"
19993   [(set (match_operand:V2DF 0 "register_operand" "=x")
19994         (float:V2DF (vec_select:V2SI
19995                      (match_operand:V4SI 1 "nonimmediate_operand" "xm")
19996                      (parallel
19997                       [(const_int 0)
19998                        (const_int 1)]))))]
19999   "TARGET_SSE2"
20000   "cvtdq2pd\t{%1, %0|%0, %1}"
20001   [(set_attr "type" "ssecvt")
20002    (set_attr "mode" "V2DF")])
20003
20004 (define_insn "cvtpd2dq"
20005   [(set (match_operand:V4SI 0 "register_operand" "=x")
20006         (vec_concat:V4SI
20007          (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
20008          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
20009   "TARGET_SSE2"
20010   "cvtpd2dq\t{%1, %0|%0, %1}"
20011   [(set_attr "type" "ssecvt")
20012    (set_attr "mode" "TI")])
20013
20014 (define_insn "cvttpd2dq"
20015   [(set (match_operand:V4SI 0 "register_operand" "=x")
20016         (vec_concat:V4SI
20017          (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
20018                       UNSPEC_FIX)
20019          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
20020   "TARGET_SSE2"
20021   "cvttpd2dq\t{%1, %0|%0, %1}"
20022   [(set_attr "type" "ssecvt")
20023    (set_attr "mode" "TI")])
20024
20025 (define_insn "cvtpd2pi"
20026   [(set (match_operand:V2SI 0 "register_operand" "=y")
20027         (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
20028   "TARGET_SSE2"
20029   "cvtpd2pi\t{%1, %0|%0, %1}"
20030   [(set_attr "type" "ssecvt")
20031    (set_attr "mode" "TI")])
20032
20033 (define_insn "cvttpd2pi"
20034   [(set (match_operand:V2SI 0 "register_operand" "=y")
20035         (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
20036                      UNSPEC_FIX))]
20037   "TARGET_SSE2"
20038   "cvttpd2pi\t{%1, %0|%0, %1}"
20039   [(set_attr "type" "ssecvt")
20040    (set_attr "mode" "TI")])
20041
20042 (define_insn "cvtpi2pd"
20043   [(set (match_operand:V2DF 0 "register_operand" "=x")
20044         (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
20045   "TARGET_SSE2"
20046   "cvtpi2pd\t{%1, %0|%0, %1}"
20047   [(set_attr "type" "ssecvt")
20048    (set_attr "mode" "TI")])
20049
20050 ;; Conversions between SI and DF
20051
20052 (define_insn "cvtsd2si"
20053   [(set (match_operand:SI 0 "register_operand" "=r")
20054         (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "xm")
20055                                (parallel [(const_int 0)]))))]
20056   "TARGET_SSE2"
20057   "cvtsd2si\t{%1, %0|%0, %1}"
20058   [(set_attr "type" "ssecvt")
20059    (set_attr "mode" "SI")])
20060
20061 (define_insn "cvttsd2si"
20062   [(set (match_operand:SI 0 "register_operand" "=r")
20063         (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "xm")
20064                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
20065   "TARGET_SSE2"
20066   "cvttsd2si\t{%1, %0|%0, %1}"
20067   [(set_attr "type" "ssecvt")
20068    (set_attr "mode" "SI")])
20069
20070 (define_insn "cvtsi2sd"
20071   [(set (match_operand:V2DF 0 "register_operand" "=x")
20072         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
20073                         (vec_duplicate:V2DF
20074                           (float:DF
20075                             (match_operand:SI 2 "nonimmediate_operand" "rm")))
20076                         (const_int 2)))]
20077   "TARGET_SSE2"
20078   "cvtsd2si\t{%2, %0|%0, %2}"
20079   [(set_attr "type" "ssecvt")
20080    (set_attr "mode" "DF")])
20081
20082 ;; Conversions between SF and DF
20083
20084 (define_insn "cvtsd2ss"
20085   [(set (match_operand:V4SF 0 "register_operand" "=x")
20086         (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0")
20087                         (vec_duplicate:V4SF
20088                           (float_truncate:V2SF
20089                             (match_operand:V2DF 2 "register_operand" "xm")))
20090                         (const_int 14)))]
20091   "TARGET_SSE2"
20092   "cvtsd2ss\t{%2, %0|%0, %2}"
20093   [(set_attr "type" "ssecvt")
20094    (set_attr "mode" "SF")])
20095
20096 (define_insn "cvtss2sd"
20097   [(set (match_operand:V2DF 0 "register_operand" "=x")
20098         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
20099                         (float_extend:V2DF
20100                           (vec_select:V2SF
20101                             (match_operand:V4SF 2 "register_operand" "xm")
20102                             (parallel [(const_int 0)
20103                                        (const_int 1)])))
20104                         (const_int 2)))]
20105   "TARGET_SSE2"
20106   "cvtss2sd\t{%2, %0|%0, %2}"
20107   [(set_attr "type" "ssecvt")
20108    (set_attr "mode" "DF")])
20109
20110 (define_insn "cvtpd2ps"
20111   [(set (match_operand:V4SF 0 "register_operand" "=x")
20112         (subreg:V4SF
20113           (vec_concat:V4SI
20114             (subreg:V2SI (float_truncate:V2SF
20115                            (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
20116             (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
20117   "TARGET_SSE2"
20118   "cvtpd2ps\t{%1, %0|%0, %1}"
20119   [(set_attr "type" "ssecvt")
20120    (set_attr "mode" "V4SF")])
20121
20122 (define_insn "cvtps2pd"
20123   [(set (match_operand:V2DF 0 "register_operand" "=x")
20124         (float_extend:V2DF
20125           (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
20126                            (parallel [(const_int 0)
20127                                       (const_int 1)]))))]
20128   "TARGET_SSE2"
20129   "cvtps2pd\t{%1, %0|%0, %1}"
20130   [(set_attr "type" "ssecvt")
20131    (set_attr "mode" "V2DF")])
20132
20133 ;; SSE2 variants of MMX insns
20134
20135 ;; MMX arithmetic
20136
20137 (define_insn "addv16qi3"
20138   [(set (match_operand:V16QI 0 "register_operand" "=x")
20139         (plus:V16QI (match_operand:V16QI 1 "register_operand" "0")
20140                     (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
20141   "TARGET_SSE2"
20142   "paddb\t{%2, %0|%0, %2}"
20143   [(set_attr "type" "sseiadd")
20144    (set_attr "mode" "TI")])
20145
20146 (define_insn "addv8hi3"
20147   [(set (match_operand:V8HI 0 "register_operand" "=x")
20148         (plus:V8HI (match_operand:V8HI 1 "register_operand" "0")
20149                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
20150   "TARGET_SSE2"
20151   "paddw\t{%2, %0|%0, %2}"
20152   [(set_attr "type" "sseiadd")
20153    (set_attr "mode" "TI")])
20154
20155 (define_insn "addv4si3"
20156   [(set (match_operand:V4SI 0 "register_operand" "=x")
20157         (plus:V4SI (match_operand:V4SI 1 "register_operand" "0")
20158                    (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
20159   "TARGET_SSE2"
20160   "paddd\t{%2, %0|%0, %2}"
20161   [(set_attr "type" "sseiadd")
20162    (set_attr "mode" "TI")])
20163
20164 (define_insn "addv2di3"
20165   [(set (match_operand:V2DI 0 "register_operand" "=x")
20166         (plus:V2DI (match_operand:V2DI 1 "register_operand" "0")
20167                    (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20168   "TARGET_SSE2"
20169   "paddq\t{%2, %0|%0, %2}"
20170   [(set_attr "type" "sseiadd")
20171    (set_attr "mode" "TI")])
20172
20173 (define_insn "ssaddv16qi3"
20174   [(set (match_operand:V16QI 0 "register_operand" "=x")
20175         (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "0")
20176                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
20177   "TARGET_SSE2"
20178   "paddsb\t{%2, %0|%0, %2}"
20179   [(set_attr "type" "sseiadd")
20180    (set_attr "mode" "TI")])
20181
20182 (define_insn "ssaddv8hi3"
20183   [(set (match_operand:V8HI 0 "register_operand" "=x")
20184         (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "0")
20185                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
20186   "TARGET_SSE2"
20187   "paddsw\t{%2, %0|%0, %2}"
20188   [(set_attr "type" "sseiadd")
20189    (set_attr "mode" "TI")])
20190
20191 (define_insn "usaddv16qi3"
20192   [(set (match_operand:V16QI 0 "register_operand" "=x")
20193         (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "0")
20194                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
20195   "TARGET_SSE2"
20196   "paddusb\t{%2, %0|%0, %2}"
20197   [(set_attr "type" "sseiadd")
20198    (set_attr "mode" "TI")])
20199
20200 (define_insn "usaddv8hi3"
20201   [(set (match_operand:V8HI 0 "register_operand" "=x")
20202         (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "0")
20203                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
20204   "TARGET_SSE2"
20205   "paddusw\t{%2, %0|%0, %2}"
20206   [(set_attr "type" "sseiadd")
20207    (set_attr "mode" "TI")])
20208
20209 (define_insn "subv16qi3"
20210   [(set (match_operand:V16QI 0 "register_operand" "=x")
20211         (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
20212                      (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
20213   "TARGET_SSE2"
20214   "psubb\t{%2, %0|%0, %2}"
20215   [(set_attr "type" "sseiadd")
20216    (set_attr "mode" "TI")])
20217
20218 (define_insn "subv8hi3"
20219   [(set (match_operand:V8HI 0 "register_operand" "=x")
20220         (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
20221                     (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
20222   "TARGET_SSE2"
20223   "psubw\t{%2, %0|%0, %2}"
20224   [(set_attr "type" "sseiadd")
20225    (set_attr "mode" "TI")])
20226
20227 (define_insn "subv4si3"
20228   [(set (match_operand:V4SI 0 "register_operand" "=x")
20229         (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
20230                     (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
20231   "TARGET_SSE2"
20232   "psubd\t{%2, %0|%0, %2}"
20233   [(set_attr "type" "sseiadd")
20234    (set_attr "mode" "TI")])
20235
20236 (define_insn "subv2di3"
20237   [(set (match_operand:V2DI 0 "register_operand" "=x")
20238         (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
20239                     (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20240   "TARGET_SSE2"
20241   "psubq\t{%2, %0|%0, %2}"
20242   [(set_attr "type" "sseiadd")
20243    (set_attr "mode" "TI")])
20244
20245 (define_insn "sssubv16qi3"
20246   [(set (match_operand:V16QI 0 "register_operand" "=x")
20247         (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
20248                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
20249   "TARGET_SSE2"
20250   "psubsb\t{%2, %0|%0, %2}"
20251   [(set_attr "type" "sseiadd")
20252    (set_attr "mode" "TI")])
20253
20254 (define_insn "sssubv8hi3"
20255   [(set (match_operand:V8HI 0 "register_operand" "=x")
20256         (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
20257                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
20258   "TARGET_SSE2"
20259   "psubsw\t{%2, %0|%0, %2}"
20260   [(set_attr "type" "sseiadd")
20261    (set_attr "mode" "TI")])
20262
20263 (define_insn "ussubv16qi3"
20264   [(set (match_operand:V16QI 0 "register_operand" "=x")
20265         (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
20266                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
20267   "TARGET_SSE2"
20268   "psubusb\t{%2, %0|%0, %2}"
20269   [(set_attr "type" "sseiadd")
20270    (set_attr "mode" "TI")])
20271
20272 (define_insn "ussubv8hi3"
20273   [(set (match_operand:V8HI 0 "register_operand" "=x")
20274         (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
20275                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
20276   "TARGET_SSE2"
20277   "psubusw\t{%2, %0|%0, %2}"
20278   [(set_attr "type" "sseiadd")
20279    (set_attr "mode" "TI")])
20280
20281 (define_insn "mulv8hi3"
20282   [(set (match_operand:V8HI 0 "register_operand" "=x")
20283         (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
20284                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
20285   "TARGET_SSE2"
20286   "pmullw\t{%2, %0|%0, %2}"
20287   [(set_attr "type" "sseimul")
20288    (set_attr "mode" "TI")])
20289
20290 (define_insn "smulv8hi3_highpart"
20291   [(set (match_operand:V8HI 0 "register_operand" "=x")
20292         (truncate:V8HI
20293          (lshiftrt:V8SI
20294           (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
20295                      (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
20296           (const_int 16))))]
20297   "TARGET_SSE2"
20298   "pmulhw\t{%2, %0|%0, %2}"
20299   [(set_attr "type" "sseimul")
20300    (set_attr "mode" "TI")])
20301
20302 (define_insn "umulv8hi3_highpart"
20303   [(set (match_operand:V8HI 0 "register_operand" "=x")
20304         (truncate:V8HI
20305          (lshiftrt:V8SI
20306           (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
20307                      (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
20308           (const_int 16))))]
20309   "TARGET_SSE2"
20310   "pmulhuw\t{%2, %0|%0, %2}"
20311   [(set_attr "type" "sseimul")
20312    (set_attr "mode" "TI")])
20313
20314 (define_insn "sse2_umulsidi3"
20315   [(set (match_operand:DI 0 "register_operand" "=y")
20316         (mult:DI (zero_extend:DI (vec_select:SI
20317                                   (match_operand:V2SI 1 "register_operand" "0")
20318                                   (parallel [(const_int 0)])))
20319                  (zero_extend:DI (vec_select:SI
20320                                   (match_operand:V2SI 2 "nonimmediate_operand" "ym")
20321                                   (parallel [(const_int 0)])))))]
20322   "TARGET_SSE2"
20323   "pmuludq\t{%2, %0|%0, %2}"
20324   [(set_attr "type" "sseimul")
20325    (set_attr "mode" "TI")])
20326
20327 (define_insn "sse2_umulv2siv2di3"
20328   [(set (match_operand:V2DI 0 "register_operand" "=y")
20329         (mult:V2DI (zero_extend:V2DI
20330                      (vec_select:V2SI
20331                        (match_operand:V4SI 1 "register_operand" "0")
20332                        (parallel [(const_int 0) (const_int 2)])))
20333                    (zero_extend:V2DI
20334                      (vec_select:V2SI
20335                        (match_operand:V4SI 2 "nonimmediate_operand" "ym")
20336                        (parallel [(const_int 0) (const_int 2)])))))]
20337   "TARGET_SSE2"
20338   "pmuludq\t{%2, %0|%0, %2}"
20339   [(set_attr "type" "sseimul")
20340    (set_attr "mode" "TI")])
20341
20342 (define_insn "sse2_pmaddwd"
20343   [(set (match_operand:V4SI 0 "register_operand" "=x")
20344         (plus:V4SI
20345          (mult:V4SI
20346           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
20347                                              (parallel [(const_int 0)
20348                                                         (const_int 2)
20349                                                         (const_int 4)
20350                                                         (const_int 6)])))
20351           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
20352                                              (parallel [(const_int 0)
20353                                                         (const_int 2)
20354                                                         (const_int 4)
20355                                                         (const_int 6)]))))
20356          (mult:V4SI
20357           (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
20358                                              (parallel [(const_int 1)
20359                                                         (const_int 3)
20360                                                         (const_int 5)
20361                                                         (const_int 7)])))
20362           (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
20363                                              (parallel [(const_int 1)
20364                                                         (const_int 3)
20365                                                         (const_int 5)
20366                                                         (const_int 7)]))))))]
20367   "TARGET_SSE2"
20368   "pmaddwd\t{%2, %0|%0, %2}"
20369   [(set_attr "type" "sseiadd")
20370    (set_attr "mode" "TI")])
20371
20372 ;; Same as pxor, but don't show input operands so that we don't think
20373 ;; they are live.
20374 (define_insn "sse2_clrti"
20375   [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
20376   "TARGET_SSE2"
20377   "pxor\t{%0, %0|%0, %0}"
20378   [(set_attr "type" "sseiadd")
20379    (set_attr "memory" "none")
20380    (set_attr "mode" "TI")])
20381
20382 ;; MMX unsigned averages/sum of absolute differences
20383
20384 (define_insn "sse2_uavgv16qi3"
20385   [(set (match_operand:V16QI 0 "register_operand" "=x")
20386         (ashiftrt:V16QI
20387          (plus:V16QI (plus:V16QI
20388                      (match_operand:V16QI 1 "register_operand" "0")
20389                      (match_operand:V16QI 2 "nonimmediate_operand" "ym"))
20390                      (const_vector:V16QI [(const_int 1) (const_int 1)
20391                                           (const_int 1) (const_int 1)
20392                                           (const_int 1) (const_int 1)
20393                                           (const_int 1) (const_int 1)
20394                                           (const_int 1) (const_int 1)
20395                                           (const_int 1) (const_int 1)
20396                                           (const_int 1) (const_int 1)
20397                                           (const_int 1) (const_int 1)]))
20398          (const_int 1)))]
20399   "TARGET_SSE2"
20400   "pavgb\t{%2, %0|%0, %2}"
20401   [(set_attr "type" "sseiadd")
20402    (set_attr "mode" "TI")])
20403
20404 (define_insn "sse2_uavgv8hi3"
20405   [(set (match_operand:V8HI 0 "register_operand" "=x")
20406         (ashiftrt:V8HI
20407          (plus:V8HI (plus:V8HI
20408                      (match_operand:V8HI 1 "register_operand" "0")
20409                      (match_operand:V8HI 2 "nonimmediate_operand" "ym"))
20410                     (const_vector:V8HI [(const_int 1) (const_int 1)
20411                                         (const_int 1) (const_int 1)
20412                                         (const_int 1) (const_int 1)
20413                                         (const_int 1) (const_int 1)]))
20414          (const_int 1)))]
20415   "TARGET_SSE2"
20416   "pavgw\t{%2, %0|%0, %2}"
20417   [(set_attr "type" "sseiadd")
20418    (set_attr "mode" "TI")])
20419
20420 ;; @@@ this isn't the right representation.
20421 (define_insn "sse2_psadbw"
20422   [(set (match_operand:V2DI 0 "register_operand" "=x")
20423         (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
20424                       (match_operand:V16QI 2 "nonimmediate_operand" "ym")]
20425                      UNSPEC_PSADBW))]
20426   "TARGET_SSE2"
20427   "psadbw\t{%2, %0|%0, %2}"
20428   [(set_attr "type" "sseiadd")
20429    (set_attr "mode" "TI")])
20430
20431
20432 ;; MMX insert/extract/shuffle
20433
20434 (define_insn "sse2_pinsrw"
20435   [(set (match_operand:V8HI 0 "register_operand" "=x")
20436         (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
20437                         (vec_duplicate:V8HI
20438                          (match_operand:SI 2 "nonimmediate_operand" "rm"))
20439                         (match_operand:SI 3 "immediate_operand" "i")))]
20440   "TARGET_SSE2"
20441   "pinsrw\t{%3, %2, %0|%0, %2, %3}"
20442   [(set_attr "type" "ssecvt")
20443    (set_attr "mode" "TI")])
20444
20445 (define_insn "sse2_pextrw"
20446   [(set (match_operand:SI 0 "register_operand" "=r")
20447         (zero_extend:SI
20448           (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
20449                          (parallel
20450                           [(match_operand:SI 2 "immediate_operand" "i")]))))]
20451   "TARGET_SSE2"
20452   "pextrw\t{%2, %1, %0|%0, %1, %2}"
20453   [(set_attr "type" "ssecvt")
20454    (set_attr "mode" "TI")])
20455
20456 (define_insn "sse2_pshufd"
20457   [(set (match_operand:V4SI 0 "register_operand" "=x")
20458         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
20459                       (match_operand:SI 2 "immediate_operand" "i")]
20460                      UNSPEC_SHUFFLE))]
20461   "TARGET_SSE2"
20462   "pshufd\t{%2, %1, %0|%0, %1, %2}"
20463   [(set_attr "type" "ssecvt")
20464    (set_attr "mode" "TI")])
20465
20466 (define_insn "sse2_pshuflw"
20467   [(set (match_operand:V8HI 0 "register_operand" "=x")
20468         (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
20469                       (match_operand:SI 2 "immediate_operand" "i")]
20470                      UNSPEC_PSHUFLW))]
20471   "TARGET_SSE2"
20472   "pshuflw\t{%2, %1, %0|%0, %1, %2}"
20473   [(set_attr "type" "ssecvt")
20474    (set_attr "mode" "TI")])
20475
20476 (define_insn "sse2_pshufhw"
20477   [(set (match_operand:V8HI 0 "register_operand" "=x")
20478         (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
20479                       (match_operand:SI 2 "immediate_operand" "i")]
20480                      UNSPEC_PSHUFHW))]
20481   "TARGET_SSE2"
20482   "pshufhw\t{%2, %1, %0|%0, %1, %2}"
20483   [(set_attr "type" "ssecvt")
20484    (set_attr "mode" "TI")])
20485
20486 ;; MMX mask-generating comparisons
20487
20488 (define_insn "eqv16qi3"
20489   [(set (match_operand:V16QI 0 "register_operand" "=x")
20490         (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
20491                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
20492   "TARGET_SSE2"
20493   "pcmpeqb\t{%2, %0|%0, %2}"
20494   [(set_attr "type" "ssecmp")
20495    (set_attr "mode" "TI")])
20496
20497 (define_insn "eqv8hi3"
20498   [(set (match_operand:V8HI 0 "register_operand" "=x")
20499         (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
20500                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
20501   "TARGET_SSE2"
20502   "pcmpeqw\t{%2, %0|%0, %2}"
20503   [(set_attr "type" "ssecmp")
20504    (set_attr "mode" "TI")])
20505
20506 (define_insn "eqv4si3"
20507   [(set (match_operand:V4SI 0 "register_operand" "=x")
20508         (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
20509                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
20510   "TARGET_SSE2"
20511   "pcmpeqd\t{%2, %0|%0, %2}"
20512   [(set_attr "type" "ssecmp")
20513    (set_attr "mode" "TI")])
20514
20515 (define_insn "gtv16qi3"
20516   [(set (match_operand:V16QI 0 "register_operand" "=x")
20517         (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
20518                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
20519   "TARGET_SSE2"
20520   "pcmpgtb\t{%2, %0|%0, %2}"
20521   [(set_attr "type" "ssecmp")
20522    (set_attr "mode" "TI")])
20523
20524 (define_insn "gtv8hi3"
20525   [(set (match_operand:V8HI 0 "register_operand" "=x")
20526         (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
20527                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
20528   "TARGET_SSE2"
20529   "pcmpgtw\t{%2, %0|%0, %2}"
20530   [(set_attr "type" "ssecmp")
20531    (set_attr "mode" "TI")])
20532
20533 (define_insn "gtv4si3"
20534   [(set (match_operand:V4SI 0 "register_operand" "=x")
20535         (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
20536                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
20537   "TARGET_SSE2"
20538   "pcmpgtd\t{%2, %0|%0, %2}"
20539   [(set_attr "type" "ssecmp")
20540    (set_attr "mode" "TI")])
20541
20542
20543 ;; MMX max/min insns
20544
20545 (define_insn "umaxv16qi3"
20546   [(set (match_operand:V16QI 0 "register_operand" "=x")
20547         (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
20548                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
20549   "TARGET_SSE2"
20550   "pmaxub\t{%2, %0|%0, %2}"
20551   [(set_attr "type" "sseiadd")
20552    (set_attr "mode" "TI")])
20553
20554 (define_insn "smaxv8hi3"
20555   [(set (match_operand:V8HI 0 "register_operand" "=x")
20556         (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
20557                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
20558   "TARGET_SSE2"
20559   "pmaxsw\t{%2, %0|%0, %2}"
20560   [(set_attr "type" "sseiadd")
20561    (set_attr "mode" "TI")])
20562
20563 (define_insn "uminv16qi3"
20564   [(set (match_operand:V16QI 0 "register_operand" "=x")
20565         (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
20566                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
20567   "TARGET_SSE2"
20568   "pminub\t{%2, %0|%0, %2}"
20569   [(set_attr "type" "sseiadd")
20570    (set_attr "mode" "TI")])
20571
20572 (define_insn "sminv8hi3"
20573   [(set (match_operand:V8HI 0 "register_operand" "=x")
20574         (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
20575                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
20576   "TARGET_SSE2"
20577   "pminsw\t{%2, %0|%0, %2}"
20578   [(set_attr "type" "sseiadd")
20579    (set_attr "mode" "TI")])
20580
20581
20582 ;; MMX shifts
20583
20584 (define_insn "ashrv8hi3"
20585   [(set (match_operand:V8HI 0 "register_operand" "=x")
20586         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
20587                        (match_operand:SI 2 "nonmemory_operand" "ri")))]
20588   "TARGET_SSE2"
20589   "psraw\t{%2, %0|%0, %2}"
20590   [(set_attr "type" "sseishft")
20591    (set_attr "mode" "TI")])
20592
20593 (define_insn "ashrv4si3"
20594   [(set (match_operand:V4SI 0 "register_operand" "=x")
20595         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
20596                        (match_operand:SI 2 "nonmemory_operand" "ri")))]
20597   "TARGET_SSE2"
20598   "psrad\t{%2, %0|%0, %2}"
20599   [(set_attr "type" "sseishft")
20600    (set_attr "mode" "TI")])
20601
20602 (define_insn "lshrv8hi3"
20603   [(set (match_operand:V8HI 0 "register_operand" "=x")
20604         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
20605                        (match_operand:SI 2 "nonmemory_operand" "ri")))]
20606   "TARGET_SSE2"
20607   "psrlw\t{%2, %0|%0, %2}"
20608   [(set_attr "type" "sseishft")
20609    (set_attr "mode" "TI")])
20610
20611 (define_insn "lshrv4si3"
20612   [(set (match_operand:V4SI 0 "register_operand" "=x")
20613         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
20614                        (match_operand:SI 2 "nonmemory_operand" "ri")))]
20615   "TARGET_SSE2"
20616   "psrld\t{%2, %0|%0, %2}"
20617   [(set_attr "type" "sseishft")
20618    (set_attr "mode" "TI")])
20619
20620 (define_insn "lshrv2di3"
20621   [(set (match_operand:V2DI 0 "register_operand" "=x")
20622         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
20623                        (match_operand:SI 2 "nonmemory_operand" "ri")))]
20624   "TARGET_SSE2"
20625   "psrlq\t{%2, %0|%0, %2}"
20626   [(set_attr "type" "sseishft")
20627    (set_attr "mode" "TI")])
20628
20629 (define_insn "ashlv8hi3"
20630   [(set (match_operand:V8HI 0 "register_operand" "=x")
20631         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
20632                      (match_operand:SI 2 "nonmemory_operand" "ri")))]
20633   "TARGET_SSE2"
20634   "psllw\t{%2, %0|%0, %2}"
20635   [(set_attr "type" "sseishft")
20636    (set_attr "mode" "TI")])
20637
20638 (define_insn "ashlv4si3"
20639   [(set (match_operand:V4SI 0 "register_operand" "=x")
20640         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
20641                      (match_operand:SI 2 "nonmemory_operand" "ri")))]
20642   "TARGET_SSE2"
20643   "pslld\t{%2, %0|%0, %2}"
20644   [(set_attr "type" "sseishft")
20645    (set_attr "mode" "TI")])
20646
20647 (define_insn "ashlv2di3"
20648   [(set (match_operand:V2DI 0 "register_operand" "=x")
20649         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
20650                      (match_operand:SI 2 "nonmemory_operand" "ri")))]
20651   "TARGET_SSE2"
20652   "psllq\t{%2, %0|%0, %2}"
20653   [(set_attr "type" "sseishft")
20654    (set_attr "mode" "TI")])
20655
20656 (define_insn "ashrv8hi3_ti"
20657   [(set (match_operand:V8HI 0 "register_operand" "=x")
20658         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
20659                        (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
20660   "TARGET_SSE2"
20661   "psraw\t{%2, %0|%0, %2}"
20662   [(set_attr "type" "sseishft")
20663    (set_attr "mode" "TI")])
20664
20665 (define_insn "ashrv4si3_ti"
20666   [(set (match_operand:V4SI 0 "register_operand" "=x")
20667         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
20668                        (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
20669   "TARGET_SSE2"
20670   "psrad\t{%2, %0|%0, %2}"
20671   [(set_attr "type" "sseishft")
20672    (set_attr "mode" "TI")])
20673
20674 (define_insn "lshrv8hi3_ti"
20675   [(set (match_operand:V8HI 0 "register_operand" "=x")
20676         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
20677                        (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
20678   "TARGET_SSE2"
20679   "psrlw\t{%2, %0|%0, %2}"
20680   [(set_attr "type" "sseishft")
20681    (set_attr "mode" "TI")])
20682
20683 (define_insn "lshrv4si3_ti"
20684   [(set (match_operand:V4SI 0 "register_operand" "=x")
20685         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
20686                        (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
20687   "TARGET_SSE2"
20688   "psrld\t{%2, %0|%0, %2}"
20689   [(set_attr "type" "sseishft")
20690    (set_attr "mode" "TI")])
20691
20692 (define_insn "lshrv2di3_ti"
20693   [(set (match_operand:V2DI 0 "register_operand" "=x")
20694         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
20695                        (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
20696   "TARGET_SSE2"
20697   "psrlq\t{%2, %0|%0, %2}"
20698   [(set_attr "type" "sseishft")
20699    (set_attr "mode" "TI")])
20700
20701 (define_insn "ashlv8hi3_ti"
20702   [(set (match_operand:V8HI 0 "register_operand" "=x")
20703         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
20704                      (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
20705   "TARGET_SSE2"
20706   "psllw\t{%2, %0|%0, %2}"
20707   [(set_attr "type" "sseishft")
20708    (set_attr "mode" "TI")])
20709
20710 (define_insn "ashlv4si3_ti"
20711   [(set (match_operand:V4SI 0 "register_operand" "=x")
20712         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
20713                      (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
20714   "TARGET_SSE2"
20715   "pslld\t{%2, %0|%0, %2}"
20716   [(set_attr "type" "sseishft")
20717    (set_attr "mode" "TI")])
20718
20719 (define_insn "ashlv2di3_ti"
20720   [(set (match_operand:V2DI 0 "register_operand" "=x")
20721         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
20722                      (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
20723   "TARGET_SSE2"
20724   "psllq\t{%2, %0|%0, %2}"
20725   [(set_attr "type" "sseishft")
20726    (set_attr "mode" "TI")])
20727
20728 ;; See logical MMX insns for the reason for the unspec.  Strictly speaking
20729 ;; we wouldn't need here it since we never generate TImode arithmetic.
20730
20731 ;; There has to be some kind of prize for the weirdest new instruction...
20732 (define_insn "sse2_ashlti3"
20733   [(set (match_operand:TI 0 "register_operand" "=x")
20734         (unspec:TI
20735          [(ashift:TI (match_operand:TI 1 "register_operand" "0")
20736                      (mult:SI (match_operand:SI 2 "immediate_operand" "i")
20737                                (const_int 8)))] UNSPEC_NOP))]
20738   "TARGET_SSE2"
20739   "pslldq\t{%2, %0|%0, %2}"
20740   [(set_attr "type" "sseishft")
20741    (set_attr "mode" "TI")])
20742
20743 (define_insn "sse2_lshrti3"
20744   [(set (match_operand:TI 0 "register_operand" "=x")
20745         (unspec:TI
20746          [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
20747                        (mult:SI (match_operand:SI 2 "immediate_operand" "i")
20748                                 (const_int 8)))] UNSPEC_NOP))]
20749   "TARGET_SSE2"
20750   "pslrdq\t{%2, %0|%0, %2}"
20751   [(set_attr "type" "sseishft")
20752    (set_attr "mode" "TI")])
20753
20754 ;; SSE unpack
20755
20756 (define_insn "sse2_unpckhpd"
20757   [(set (match_operand:V2DF 0 "register_operand" "=x")
20758         (vec_concat:V2DF
20759          (vec_select:V2DF (match_operand:V2DF 1 "register_operand" "0")
20760                           (parallel [(const_int 1)]))
20761          (vec_select:V2DF (match_operand:V2DF 2 "register_operand" "x")
20762                           (parallel [(const_int 0)]))))]
20763   "TARGET_SSE2"
20764   "unpckhpd\t{%2, %0|%0, %2}"
20765   [(set_attr "type" "ssecvt")
20766    (set_attr "mode" "TI")])
20767
20768 (define_insn "sse2_unpcklpd"
20769   [(set (match_operand:V2DF 0 "register_operand" "=x")
20770         (vec_concat:V2DF
20771          (vec_select:V2DF (match_operand:V2DF 1 "register_operand" "0")
20772                           (parallel [(const_int 0)]))
20773          (vec_select:V2DF (match_operand:V2DF 2 "register_operand" "x")
20774                           (parallel [(const_int 1)]))))]
20775   "TARGET_SSE2"
20776   "unpcklpd\t{%2, %0|%0, %2}"
20777   [(set_attr "type" "ssecvt")
20778    (set_attr "mode" "TI")])
20779
20780 ;; MMX pack/unpack insns.
20781
20782 (define_insn "sse2_packsswb"
20783   [(set (match_operand:V16QI 0 "register_operand" "=x")
20784         (vec_concat:V16QI
20785          (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
20786          (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
20787   "TARGET_SSE2"
20788   "packsswb\t{%2, %0|%0, %2}"
20789   [(set_attr "type" "ssecvt")
20790    (set_attr "mode" "TI")])
20791
20792 (define_insn "sse2_packssdw"
20793   [(set (match_operand:V8HI 0 "register_operand" "=x")
20794         (vec_concat:V8HI
20795          (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
20796          (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
20797   "TARGET_SSE2"
20798   "packssdw\t{%2, %0|%0, %2}"
20799   [(set_attr "type" "ssecvt")
20800    (set_attr "mode" "TI")])
20801
20802 (define_insn "sse2_packuswb"
20803   [(set (match_operand:V16QI 0 "register_operand" "=x")
20804         (vec_concat:V16QI
20805          (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
20806          (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
20807   "TARGET_SSE2"
20808   "packuswb\t{%2, %0|%0, %2}"
20809   [(set_attr "type" "ssecvt")
20810    (set_attr "mode" "TI")])
20811
20812 (define_insn "sse2_punpckhbw"
20813   [(set (match_operand:V16QI 0 "register_operand" "=x")
20814         (vec_merge:V16QI
20815          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
20816                            (parallel [(const_int 8) (const_int 0)
20817                                       (const_int 9) (const_int 1)
20818                                       (const_int 10) (const_int 2)
20819                                       (const_int 11) (const_int 3)
20820                                       (const_int 12) (const_int 4)
20821                                       (const_int 13) (const_int 5)
20822                                       (const_int 14) (const_int 6)
20823                                       (const_int 15) (const_int 7)]))
20824          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
20825                            (parallel [(const_int 0) (const_int 8)
20826                                       (const_int 1) (const_int 9)
20827                                       (const_int 2) (const_int 10)
20828                                       (const_int 3) (const_int 11)
20829                                       (const_int 4) (const_int 12)
20830                                       (const_int 5) (const_int 13)
20831                                       (const_int 6) (const_int 14)
20832                                       (const_int 7) (const_int 15)]))
20833          (const_int 21845)))]
20834   "TARGET_SSE2"
20835   "punpckhbw\t{%2, %0|%0, %2}"
20836   [(set_attr "type" "ssecvt")
20837    (set_attr "mode" "TI")])
20838
20839 (define_insn "sse2_punpckhwd"
20840   [(set (match_operand:V8HI 0 "register_operand" "=x")
20841         (vec_merge:V8HI
20842          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
20843                           (parallel [(const_int 4) (const_int 0)
20844                                      (const_int 5) (const_int 1)
20845                                      (const_int 6) (const_int 2)
20846                                      (const_int 7) (const_int 3)]))
20847          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
20848                           (parallel [(const_int 0) (const_int 4)
20849                                      (const_int 1) (const_int 5)
20850                                      (const_int 2) (const_int 6)
20851                                      (const_int 3) (const_int 7)]))
20852          (const_int 85)))]
20853   "TARGET_SSE2"
20854   "punpckhwd\t{%2, %0|%0, %2}"
20855   [(set_attr "type" "ssecvt")
20856    (set_attr "mode" "TI")])
20857
20858 (define_insn "sse2_punpckhdq"
20859   [(set (match_operand:V4SI 0 "register_operand" "=x")
20860         (vec_merge:V4SI
20861          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
20862                           (parallel [(const_int 2) (const_int 0)
20863                                      (const_int 3) (const_int 1)]))
20864          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
20865                           (parallel [(const_int 0) (const_int 2)
20866                                      (const_int 1) (const_int 3)]))
20867          (const_int 5)))]
20868   "TARGET_SSE2"
20869   "punpckhdq\t{%2, %0|%0, %2}"
20870   [(set_attr "type" "ssecvt")
20871    (set_attr "mode" "TI")])
20872
20873 (define_insn "sse2_punpcklbw"
20874   [(set (match_operand:V16QI 0 "register_operand" "=x")
20875         (vec_merge:V16QI
20876          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
20877                            (parallel [(const_int 0) (const_int 8)
20878                                       (const_int 1) (const_int 9)
20879                                       (const_int 2) (const_int 10)
20880                                       (const_int 3) (const_int 11)
20881                                       (const_int 4) (const_int 12)
20882                                       (const_int 5) (const_int 13)
20883                                       (const_int 6) (const_int 14)
20884                                       (const_int 7) (const_int 15)]))
20885          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
20886                            (parallel [(const_int 8) (const_int 0)
20887                                       (const_int 9) (const_int 1)
20888                                       (const_int 10) (const_int 2)
20889                                       (const_int 11) (const_int 3)
20890                                       (const_int 12) (const_int 4)
20891                                       (const_int 13) (const_int 5)
20892                                       (const_int 14) (const_int 6)
20893                                       (const_int 15) (const_int 7)]))
20894          (const_int 21845)))]
20895   "TARGET_SSE2"
20896   "punpcklbw\t{%2, %0|%0, %2}"
20897   [(set_attr "type" "ssecvt")
20898    (set_attr "mode" "TI")])
20899
20900 (define_insn "sse2_punpcklwd"
20901   [(set (match_operand:V8HI 0 "register_operand" "=x")
20902         (vec_merge:V8HI
20903          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
20904                           (parallel [(const_int 0) (const_int 4)
20905                                      (const_int 1) (const_int 5)
20906                                      (const_int 2) (const_int 6)
20907                                      (const_int 3) (const_int 7)]))
20908          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
20909                           (parallel [(const_int 4) (const_int 0)
20910                                      (const_int 5) (const_int 1)
20911                                      (const_int 6) (const_int 2)
20912                                      (const_int 7) (const_int 3)]))
20913          (const_int 85)))]
20914   "TARGET_SSE2"
20915   "punpcklwd\t{%2, %0|%0, %2}"
20916   [(set_attr "type" "ssecvt")
20917    (set_attr "mode" "TI")])
20918
20919 (define_insn "sse2_punpckldq"
20920   [(set (match_operand:V4SI 0 "register_operand" "=x")
20921         (vec_merge:V4SI
20922          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
20923                           (parallel [(const_int 0) (const_int 2)
20924                                      (const_int 1) (const_int 3)]))
20925          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
20926                           (parallel [(const_int 2) (const_int 0)
20927                                      (const_int 3) (const_int 1)]))
20928          (const_int 5)))]
20929   "TARGET_SSE2"
20930   "punpckldq\t{%2, %0|%0, %2}"
20931   [(set_attr "type" "ssecvt")
20932    (set_attr "mode" "TI")])
20933
20934 ;; SSE2 moves
20935
20936 (define_insn "sse2_movapd"
20937   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
20938         (unspec:V2DF [(match_operand:V2DF 1 "general_operand" "xm,x")]
20939                      UNSPEC_MOVA))]
20940   "TARGET_SSE2"
20941   "@
20942    movapd\t{%1, %0|%0, %1}
20943    movapd\t{%1, %0|%0, %1}"
20944   [(set_attr "type" "ssemov")
20945    (set_attr "mode" "V2DF")])
20946
20947 (define_insn "sse2_movupd"
20948   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
20949         (unspec:V2DF [(match_operand:V2DF 1 "general_operand" "xm,x")]
20950                      UNSPEC_MOVU))]
20951   "TARGET_SSE2"
20952   "@
20953    movupd\t{%1, %0|%0, %1}
20954    movupd\t{%1, %0|%0, %1}"
20955   [(set_attr "type" "ssecvt")
20956    (set_attr "mode" "V2DF")])
20957
20958 (define_insn "sse2_movdqa"
20959   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,m")
20960         (unspec:TI [(match_operand:TI 1 "general_operand" "xm,x")]
20961                    UNSPEC_MOVA))]
20962   "TARGET_SSE2"
20963   "@
20964    movdqa\t{%1, %0|%0, %1}
20965    movdqa\t{%1, %0|%0, %1}"
20966   [(set_attr "type" "ssemov")
20967    (set_attr "mode" "TI")])
20968
20969 (define_insn "sse2_movdqu"
20970   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,m")
20971         (unspec:TI [(match_operand:TI 1 "general_operand" "xm,x")]
20972                    UNSPEC_MOVU))]
20973   "TARGET_SSE2"
20974   "@
20975    movdqu\t{%1, %0|%0, %1}
20976    movdqu\t{%1, %0|%0, %1}"
20977   [(set_attr "type" "ssecvt")
20978    (set_attr "mode" "TI")])
20979
20980 (define_insn "sse2_movdq2q"
20981   [(set (match_operand:DI 0 "nonimmediate_operand" "=y")
20982         (vec_select:DI (match_operand:V2DI 1 "general_operand" "x")
20983                        (parallel [(const_int 0)])))]
20984   "TARGET_SSE2"
20985   "movdq2q\t{%1, %0|%0, %1}"
20986   [(set_attr "type" "ssecvt")
20987    (set_attr "mode" "TI")])
20988
20989 (define_insn "sse2_movq2dq"
20990   [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x")
20991         (vec_concat:V2DI (match_operand:DI 1 "general_operand" "y")
20992                          (const_vector:DI [(const_int 0)])))]
20993   "TARGET_SSE2"
20994   "movq2dq\t{%1, %0|%0, %1}"
20995   [(set_attr "type" "ssecvt")
20996    (set_attr "mode" "TI")])
20997
20998 (define_insn "sse2_movhpd"
20999   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
21000         (vec_merge:V2DF
21001          (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
21002          (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
21003          (const_int 2)))]
21004   "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
21005   "movhpd\t{%2, %0|%0, %2}"
21006   [(set_attr "type" "ssecvt")
21007    (set_attr "mode" "V2DF")])
21008
21009 (define_insn "sse2_movlpd"
21010   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
21011         (vec_merge:V2DF
21012          (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
21013          (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
21014          (const_int 1)))]
21015   "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
21016   "movlpd\t{%2, %0|%0, %2}"
21017   [(set_attr "type" "ssecvt")
21018    (set_attr "mode" "V2DF")])
21019
21020 (define_insn "sse2_loadsd"
21021   [(set (match_operand:V2DF 0 "register_operand" "=x")
21022         (vec_merge:V2DF
21023          (match_operand:DF 1 "memory_operand" "m")
21024          (vec_duplicate:DF (float:DF (const_int 0)))
21025          (const_int 1)))]
21026   "TARGET_SSE2"
21027   "movsd\t{%1, %0|%0, %1}"
21028   [(set_attr "type" "ssecvt")
21029    (set_attr "mode" "DF")])
21030
21031 (define_insn "sse2_movsd"
21032   [(set (match_operand:V2DF 0 "register_operand" "=x")
21033         (vec_merge:V2DF
21034          (match_operand:V2DF 1 "register_operand" "0")
21035          (match_operand:V2DF 2 "register_operand" "x")
21036          (const_int 1)))]
21037   "TARGET_SSE2"
21038   "movsd\t{%2, %0|%0, %2}"
21039   [(set_attr "type" "ssecvt")
21040    (set_attr "mode" "DF")])
21041
21042 (define_insn "sse2_storesd"
21043   [(set (match_operand:DF 0 "memory_operand" "=m")
21044         (vec_select:DF
21045          (match_operand:V2DF 1 "register_operand" "x")
21046          (parallel [(const_int 0)])))]
21047   "TARGET_SSE2"
21048   "movsd\t{%1, %0|%0, %1}"
21049   [(set_attr "type" "ssecvt")
21050    (set_attr "mode" "DF")])
21051
21052 (define_insn "sse2_shufpd"
21053   [(set (match_operand:V2DF 0 "register_operand" "=x")
21054         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
21055                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")
21056                       (match_operand:SI 3 "immediate_operand" "i")]
21057                      UNSPEC_SHUFFLE))]
21058   "TARGET_SSE2"
21059   ;; @@@ check operand order for intel/nonintel syntax
21060   "shufpd\t{%3, %2, %0|%0, %2, %3}"
21061   [(set_attr "type" "ssecvt")
21062    (set_attr "mode" "V2DF")])
21063
21064 (define_insn "sse2_clflush"
21065   [(unspec_volatile [(match_operand:SI 0 "address_operand" "p")]
21066                     UNSPECV_CLFLUSH)]
21067   "TARGET_SSE2"
21068   "clflush %0"
21069   [(set_attr "type" "sse")
21070    (set_attr "memory" "unknown")])
21071
21072 (define_expand "sse2_mfence"
21073   [(set (match_dup 0)
21074         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
21075   "TARGET_SSE2"
21076 {
21077   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
21078   MEM_VOLATILE_P (operands[0]) = 1;
21079 })
21080
21081 (define_insn "*mfence_insn"
21082   [(set (match_operand:BLK 0 "" "")
21083         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
21084   "TARGET_SSE2"
21085   "mfence"
21086   [(set_attr "type" "sse")
21087    (set_attr "memory" "unknown")])
21088
21089 (define_expand "sse2_lfence"
21090   [(set (match_dup 0)
21091         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
21092   "TARGET_SSE2"
21093 {
21094   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
21095   MEM_VOLATILE_P (operands[0]) = 1;
21096 })
21097
21098 (define_insn "*lfence_insn"
21099   [(set (match_operand:BLK 0 "" "")
21100         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
21101   "TARGET_SSE2"
21102   "lfence"
21103   [(set_attr "type" "sse")
21104    (set_attr "memory" "unknown")])