OSDN Git Service

2006-10-21 H.J. Lu <hongjiu.lu@intel.com>
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / sse.md
1 ;; GCC machine description for SSE instructions
2 ;; Copyright (C) 2005, 2006
3 ;; Free Software Foundation, Inc.
4 ;;
5 ;; This file is part of GCC.
6 ;;
7 ;; GCC is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 2, or (at your option)
10 ;; any later version.
11 ;;
12 ;; GCC is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 ;; GNU General Public License for more details.
16 ;;
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING.  If not, write to
19 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
20 ;; Boston, MA 02110-1301, USA.
21
22
23 ;; 16 byte integral modes handled by SSE, minus TImode, which gets
24 ;; special-cased for TARGET_64BIT.
25 (define_mode_macro SSEMODEI [V16QI V8HI V4SI V2DI])
26
27 ;; All 16-byte vector modes handled by SSE
28 (define_mode_macro SSEMODE [V16QI V8HI V4SI V2DI V4SF V2DF])
29
30 ;; Mix-n-match
31 (define_mode_macro SSEMODE12 [V16QI V8HI])
32 (define_mode_macro SSEMODE24 [V8HI V4SI])
33 (define_mode_macro SSEMODE14 [V16QI V4SI])
34 (define_mode_macro SSEMODE124 [V16QI V8HI V4SI])
35 (define_mode_macro SSEMODE248 [V8HI V4SI V2DI])
36
37 ;; Mapping from integer vector mode to mnemonic suffix
38 (define_mode_attr ssevecsize [(V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")])
39
40 ;; Patterns whose name begins with "sse{,2,3}_" are invoked by intrinsics.
41
42 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
43 ;;
44 ;; Move patterns
45 ;;
46 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
47
48 ;; All of these patterns are enabled for SSE1 as well as SSE2.
49 ;; This is essential for maintaining stable calling conventions.
50
51 (define_expand "mov<mode>"
52   [(set (match_operand:SSEMODEI 0 "nonimmediate_operand" "")
53         (match_operand:SSEMODEI 1 "nonimmediate_operand" ""))]
54   "TARGET_SSE"
55 {
56   ix86_expand_vector_move (<MODE>mode, operands);
57   DONE;
58 })
59
60 (define_insn "*mov<mode>_internal"
61   [(set (match_operand:SSEMODEI 0 "nonimmediate_operand" "=x,x ,m")
62         (match_operand:SSEMODEI 1 "nonimmediate_or_sse_const_operand"  "C ,xm,x"))]
63   "TARGET_SSE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
64 {
65   switch (which_alternative)
66     {
67     case 0:
68       return standard_sse_constant_opcode (insn, operands[1]);
69     case 1:
70     case 2:
71       if (get_attr_mode (insn) == MODE_V4SF)
72         return "movaps\t{%1, %0|%0, %1}";
73       else
74         return "movdqa\t{%1, %0|%0, %1}";
75     default:
76       gcc_unreachable ();
77     }
78 }
79   [(set_attr "type" "sselog1,ssemov,ssemov")
80    (set (attr "mode")
81         (if_then_else
82           (ior (ior (ne (symbol_ref "optimize_size") (const_int 0))
83                     (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
84                (and (eq_attr "alternative" "2")
85                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
86                         (const_int 0))))
87           (const_string "V4SF")
88           (const_string "TI")))])
89
90 (define_expand "movv4sf"
91   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
92         (match_operand:V4SF 1 "nonimmediate_operand" ""))]
93   "TARGET_SSE"
94 {
95   ix86_expand_vector_move (V4SFmode, operands);
96   DONE;
97 })
98
99 (define_insn "*movv4sf_internal"
100   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
101         (match_operand:V4SF 1 "nonimmediate_or_sse_const_operand" "C,xm,x"))]
102   "TARGET_SSE"
103 {
104   switch (which_alternative)
105     {
106     case 0:
107       return standard_sse_constant_opcode (insn, operands[1]);
108     case 1:
109     case 2:
110       return "movaps\t{%1, %0|%0, %1}";
111     default:
112       abort();
113     }
114 }
115   [(set_attr "type" "sselog1,ssemov,ssemov")
116    (set_attr "mode" "V4SF")])
117
118 (define_split
119   [(set (match_operand:V4SF 0 "register_operand" "")
120         (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
121   "TARGET_SSE && reload_completed"
122   [(set (match_dup 0)
123         (vec_merge:V4SF
124           (vec_duplicate:V4SF (match_dup 1))
125           (match_dup 2)
126           (const_int 1)))]
127 {
128   operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
129   operands[2] = CONST0_RTX (V4SFmode);
130 })
131
132 (define_expand "movv2df"
133   [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
134         (match_operand:V2DF 1 "nonimmediate_operand" ""))]
135   "TARGET_SSE"
136 {
137   ix86_expand_vector_move (V2DFmode, operands);
138   DONE;
139 })
140
141 (define_insn "*movv2df_internal"
142   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
143         (match_operand:V2DF 1 "nonimmediate_or_sse_const_operand" "C,xm,x"))]
144   "TARGET_SSE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
145 {
146   switch (which_alternative)
147     {
148     case 0:
149       return standard_sse_constant_opcode (insn, operands[1]);
150     case 1:
151     case 2:
152       if (get_attr_mode (insn) == MODE_V4SF)
153         return "movaps\t{%1, %0|%0, %1}";
154       else
155         return "movapd\t{%1, %0|%0, %1}";
156     default:
157       gcc_unreachable ();
158     }
159 }
160   [(set_attr "type" "sselog1,ssemov,ssemov")
161    (set (attr "mode")
162         (if_then_else
163           (ior (ior (ne (symbol_ref "optimize_size") (const_int 0))
164                     (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
165                (and (eq_attr "alternative" "2")
166                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
167                         (const_int 0))))
168           (const_string "V4SF")
169           (const_string "V2DF")))])
170
171 (define_split
172   [(set (match_operand:V2DF 0 "register_operand" "")
173         (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
174   "TARGET_SSE2 && reload_completed"
175   [(set (match_dup 0) (vec_concat:V2DF (match_dup 1) (match_dup 2)))]
176 {
177   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
178   operands[2] = CONST0_RTX (DFmode);
179 })
180
181 (define_expand "push<mode>1"
182   [(match_operand:SSEMODE 0 "register_operand" "")]
183   "TARGET_SSE"
184 {
185   ix86_expand_push (<MODE>mode, operands[0]);
186   DONE;
187 })
188
189 (define_expand "movmisalign<mode>"
190   [(set (match_operand:SSEMODE 0 "nonimmediate_operand" "")
191         (match_operand:SSEMODE 1 "nonimmediate_operand" ""))]
192   "TARGET_SSE"
193 {
194   ix86_expand_vector_move_misalign (<MODE>mode, operands);
195   DONE;
196 })
197
198 (define_insn "sse_movups"
199   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
200         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
201                      UNSPEC_MOVU))]
202   "TARGET_SSE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
203   "movups\t{%1, %0|%0, %1}"
204   [(set_attr "type" "ssemov")
205    (set_attr "mode" "V2DF")])
206
207 (define_insn "sse2_movupd"
208   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
209         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
210                      UNSPEC_MOVU))]
211   "TARGET_SSE2 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
212   "movupd\t{%1, %0|%0, %1}"
213   [(set_attr "type" "ssemov")
214    (set_attr "mode" "V2DF")])
215
216 (define_insn "sse2_movdqu"
217   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
218         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
219                       UNSPEC_MOVU))]
220   "TARGET_SSE2 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
221   "movdqu\t{%1, %0|%0, %1}"
222   [(set_attr "type" "ssemov")
223    (set_attr "mode" "TI")])
224
225 (define_insn "sse_movntv4sf"
226   [(set (match_operand:V4SF 0 "memory_operand" "=m")
227         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
228                      UNSPEC_MOVNT))]
229   "TARGET_SSE"
230   "movntps\t{%1, %0|%0, %1}"
231   [(set_attr "type" "ssemov")
232    (set_attr "mode" "V4SF")])
233
234 (define_insn "sse2_movntv2df"
235   [(set (match_operand:V2DF 0 "memory_operand" "=m")
236         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
237                      UNSPEC_MOVNT))]
238   "TARGET_SSE2"
239   "movntpd\t{%1, %0|%0, %1}"
240   [(set_attr "type" "ssecvt")
241    (set_attr "mode" "V2DF")])
242
243 (define_insn "sse2_movntv2di"
244   [(set (match_operand:V2DI 0 "memory_operand" "=m")
245         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
246                      UNSPEC_MOVNT))]
247   "TARGET_SSE2"
248   "movntdq\t{%1, %0|%0, %1}"
249   [(set_attr "type" "ssecvt")
250    (set_attr "mode" "TI")])
251
252 (define_insn "sse2_movntsi"
253   [(set (match_operand:SI 0 "memory_operand" "=m")
254         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
255                    UNSPEC_MOVNT))]
256   "TARGET_SSE2"
257   "movnti\t{%1, %0|%0, %1}"
258   [(set_attr "type" "ssecvt")
259    (set_attr "mode" "V2DF")])
260
261 (define_insn "sse3_lddqu"
262   [(set (match_operand:V16QI 0 "register_operand" "=x")
263         (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
264                       UNSPEC_LDDQU))]
265   "TARGET_SSE3"
266   "lddqu\t{%1, %0|%0, %1}"
267   [(set_attr "type" "ssecvt")
268    (set_attr "mode" "TI")])
269
270 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
271 ;;
272 ;; Parallel single-precision floating point arithmetic
273 ;;
274 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
275
276 (define_expand "negv4sf2"
277   [(set (match_operand:V4SF 0 "register_operand" "")
278         (neg:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "")))]
279   "TARGET_SSE"
280   "ix86_expand_fp_absneg_operator (NEG, V4SFmode, operands); DONE;")
281
282 (define_expand "absv4sf2"
283   [(set (match_operand:V4SF 0 "register_operand" "")
284         (abs:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "")))]
285   "TARGET_SSE"
286   "ix86_expand_fp_absneg_operator (ABS, V4SFmode, operands); DONE;")
287
288 (define_expand "addv4sf3"
289   [(set (match_operand:V4SF 0 "register_operand" "")
290         (plus:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "")
291                    (match_operand:V4SF 2 "nonimmediate_operand" "")))]
292   "TARGET_SSE"
293   "ix86_fixup_binary_operands_no_copy (PLUS, V4SFmode, operands);")
294
295 (define_insn "*addv4sf3"
296   [(set (match_operand:V4SF 0 "register_operand" "=x")
297         (plus:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
298                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
299   "TARGET_SSE && ix86_binary_operator_ok (PLUS, V4SFmode, operands)"
300   "addps\t{%2, %0|%0, %2}"
301   [(set_attr "type" "sseadd")
302    (set_attr "mode" "V4SF")])
303
304 (define_insn "sse_vmaddv4sf3"
305   [(set (match_operand:V4SF 0 "register_operand" "=x")
306         (vec_merge:V4SF
307           (plus:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
308                      (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
309           (match_dup 1)
310           (const_int 1)))]
311   "TARGET_SSE && ix86_binary_operator_ok (PLUS, V4SFmode, operands)"
312   "addss\t{%2, %0|%0, %2}"
313   [(set_attr "type" "sseadd")
314    (set_attr "mode" "SF")])
315
316 (define_expand "subv4sf3"
317   [(set (match_operand:V4SF 0 "register_operand" "")
318         (minus:V4SF (match_operand:V4SF 1 "register_operand" "")
319                     (match_operand:V4SF 2 "nonimmediate_operand" "")))]
320   "TARGET_SSE"
321   "ix86_fixup_binary_operands_no_copy (MINUS, V4SFmode, operands);")
322
323 (define_insn "*subv4sf3"
324   [(set (match_operand:V4SF 0 "register_operand" "=x")
325         (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
326                     (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
327   "TARGET_SSE"
328   "subps\t{%2, %0|%0, %2}"
329   [(set_attr "type" "sseadd")
330    (set_attr "mode" "V4SF")])
331
332 (define_insn "sse_vmsubv4sf3"
333   [(set (match_operand:V4SF 0 "register_operand" "=x")
334         (vec_merge:V4SF
335           (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
336                       (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
337           (match_dup 1)
338           (const_int 1)))]
339   "TARGET_SSE"
340   "subss\t{%2, %0|%0, %2}"
341   [(set_attr "type" "sseadd")
342    (set_attr "mode" "SF")])
343
344 (define_expand "mulv4sf3"
345   [(set (match_operand:V4SF 0 "register_operand" "")
346         (mult:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "")
347                    (match_operand:V4SF 2 "nonimmediate_operand" "")))]
348   "TARGET_SSE"
349   "ix86_fixup_binary_operands_no_copy (MULT, V4SFmode, operands);")
350
351 (define_insn "*mulv4sf3"
352   [(set (match_operand:V4SF 0 "register_operand" "=x")
353         (mult:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
354                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
355   "TARGET_SSE && ix86_binary_operator_ok (MULT, V4SFmode, operands)"
356   "mulps\t{%2, %0|%0, %2}"
357   [(set_attr "type" "ssemul")
358    (set_attr "mode" "V4SF")])
359
360 (define_insn "sse_vmmulv4sf3"
361   [(set (match_operand:V4SF 0 "register_operand" "=x")
362         (vec_merge:V4SF
363           (mult:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
364                      (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
365           (match_dup 1)
366           (const_int 1)))]
367   "TARGET_SSE && ix86_binary_operator_ok (MULT, V4SFmode, operands)"
368   "mulss\t{%2, %0|%0, %2}"
369   [(set_attr "type" "ssemul")
370    (set_attr "mode" "SF")])
371
372 (define_expand "divv4sf3"
373   [(set (match_operand:V4SF 0 "register_operand" "")
374         (div:V4SF (match_operand:V4SF 1 "register_operand" "")
375                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
376   "TARGET_SSE"
377   "ix86_fixup_binary_operands_no_copy (DIV, V4SFmode, operands);")
378
379 (define_insn "*divv4sf3"
380   [(set (match_operand:V4SF 0 "register_operand" "=x")
381         (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
382                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
383   "TARGET_SSE"
384   "divps\t{%2, %0|%0, %2}"
385   [(set_attr "type" "ssediv")
386    (set_attr "mode" "V4SF")])
387
388 (define_insn "sse_vmdivv4sf3"
389   [(set (match_operand:V4SF 0 "register_operand" "=x")
390         (vec_merge:V4SF
391           (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
392                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
393           (match_dup 1)
394           (const_int 1)))]
395   "TARGET_SSE"
396   "divss\t{%2, %0|%0, %2}"
397   [(set_attr "type" "ssediv")
398    (set_attr "mode" "SF")])
399
400 (define_insn "sse_rcpv4sf2"
401   [(set (match_operand:V4SF 0 "register_operand" "=x")
402         (unspec:V4SF
403          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
404   "TARGET_SSE"
405   "rcpps\t{%1, %0|%0, %1}"
406   [(set_attr "type" "sse")
407    (set_attr "mode" "V4SF")])
408
409 (define_insn "sse_vmrcpv4sf2"
410   [(set (match_operand:V4SF 0 "register_operand" "=x")
411         (vec_merge:V4SF
412           (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
413                        UNSPEC_RCP)
414           (match_operand:V4SF 2 "register_operand" "0")
415           (const_int 1)))]
416   "TARGET_SSE"
417   "rcpss\t{%1, %0|%0, %1}"
418   [(set_attr "type" "sse")
419    (set_attr "mode" "SF")])
420
421 (define_insn "sse_rsqrtv4sf2"
422   [(set (match_operand:V4SF 0 "register_operand" "=x")
423         (unspec:V4SF
424           [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
425   "TARGET_SSE"
426   "rsqrtps\t{%1, %0|%0, %1}"
427   [(set_attr "type" "sse")
428    (set_attr "mode" "V4SF")])
429
430 (define_insn "sse_vmrsqrtv4sf2"
431   [(set (match_operand:V4SF 0 "register_operand" "=x")
432         (vec_merge:V4SF
433           (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
434                        UNSPEC_RSQRT)
435           (match_operand:V4SF 2 "register_operand" "0")
436           (const_int 1)))]
437   "TARGET_SSE"
438   "rsqrtss\t{%1, %0|%0, %1}"
439   [(set_attr "type" "sse")
440    (set_attr "mode" "SF")])
441
442 (define_insn "sqrtv4sf2"
443   [(set (match_operand:V4SF 0 "register_operand" "=x")
444         (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
445   "TARGET_SSE"
446   "sqrtps\t{%1, %0|%0, %1}"
447   [(set_attr "type" "sse")
448    (set_attr "mode" "V4SF")])
449
450 (define_insn "sse_vmsqrtv4sf2"
451   [(set (match_operand:V4SF 0 "register_operand" "=x")
452         (vec_merge:V4SF
453           (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
454           (match_operand:V4SF 2 "register_operand" "0")
455           (const_int 1)))]
456   "TARGET_SSE"
457   "sqrtss\t{%1, %0|%0, %1}"
458   [(set_attr "type" "sse")
459    (set_attr "mode" "SF")])
460
461 ;; ??? For !flag_finite_math_only, the representation with SMIN/SMAX
462 ;; isn't really correct, as those rtl operators aren't defined when 
463 ;; applied to NaNs.  Hopefully the optimizers won't get too smart on us.
464
465 (define_expand "smaxv4sf3"
466   [(set (match_operand:V4SF 0 "register_operand" "")
467         (smax:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "")
468                    (match_operand:V4SF 2 "nonimmediate_operand" "")))]
469   "TARGET_SSE"
470 {
471   if (!flag_finite_math_only)
472     operands[1] = force_reg (V4SFmode, operands[1]);
473   ix86_fixup_binary_operands_no_copy (SMAX, V4SFmode, operands);
474 })
475
476 (define_insn "*smaxv4sf3_finite"
477   [(set (match_operand:V4SF 0 "register_operand" "=x")
478         (smax:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
479                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
480   "TARGET_SSE && flag_finite_math_only
481    && ix86_binary_operator_ok (SMAX, V4SFmode, operands)"
482   "maxps\t{%2, %0|%0, %2}"
483   [(set_attr "type" "sse")
484    (set_attr "mode" "V4SF")])
485
486 (define_insn "*smaxv4sf3"
487   [(set (match_operand:V4SF 0 "register_operand" "=x")
488         (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
489                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
490   "TARGET_SSE"
491   "maxps\t{%2, %0|%0, %2}"
492   [(set_attr "type" "sse")
493    (set_attr "mode" "V4SF")])
494
495 (define_insn "*sse_vmsmaxv4sf3_finite"
496   [(set (match_operand:V4SF 0 "register_operand" "=x")
497         (vec_merge:V4SF
498          (smax:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
499                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
500          (match_dup 1)
501          (const_int 1)))]
502   "TARGET_SSE && flag_finite_math_only
503    && ix86_binary_operator_ok (SMAX, V4SFmode, operands)"
504   "maxss\t{%2, %0|%0, %2}"
505   [(set_attr "type" "sse")
506    (set_attr "mode" "SF")])
507
508 (define_insn "sse_vmsmaxv4sf3"
509   [(set (match_operand:V4SF 0 "register_operand" "=x")
510         (vec_merge:V4SF
511          (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
512                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
513          (match_dup 1)
514          (const_int 1)))]
515   "TARGET_SSE"
516   "maxss\t{%2, %0|%0, %2}"
517   [(set_attr "type" "sse")
518    (set_attr "mode" "SF")])
519
520 (define_expand "sminv4sf3"
521   [(set (match_operand:V4SF 0 "register_operand" "")
522         (smin:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "")
523                    (match_operand:V4SF 2 "nonimmediate_operand" "")))]
524   "TARGET_SSE"
525 {
526   if (!flag_finite_math_only)
527     operands[1] = force_reg (V4SFmode, operands[1]);
528   ix86_fixup_binary_operands_no_copy (SMIN, V4SFmode, operands);
529 })
530
531 (define_insn "*sminv4sf3_finite"
532   [(set (match_operand:V4SF 0 "register_operand" "=x")
533         (smin:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
534                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
535   "TARGET_SSE && flag_finite_math_only
536    && ix86_binary_operator_ok (SMIN, V4SFmode, operands)"
537   "minps\t{%2, %0|%0, %2}"
538   [(set_attr "type" "sse")
539    (set_attr "mode" "V4SF")])
540
541 (define_insn "*sminv4sf3"
542   [(set (match_operand:V4SF 0 "register_operand" "=x")
543         (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
544                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
545   "TARGET_SSE"
546   "minps\t{%2, %0|%0, %2}"
547   [(set_attr "type" "sse")
548    (set_attr "mode" "V4SF")])
549
550 (define_insn "*sse_vmsminv4sf3_finite"
551   [(set (match_operand:V4SF 0 "register_operand" "=x")
552         (vec_merge:V4SF
553          (smin:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
554                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
555          (match_dup 1)
556          (const_int 1)))]
557   "TARGET_SSE && flag_finite_math_only
558    && ix86_binary_operator_ok (SMIN, V4SFmode, operands)"
559   "minss\t{%2, %0|%0, %2}"
560   [(set_attr "type" "sse")
561    (set_attr "mode" "SF")])
562
563 (define_insn "sse_vmsminv4sf3"
564   [(set (match_operand:V4SF 0 "register_operand" "=x")
565         (vec_merge:V4SF
566          (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
567                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
568          (match_dup 1)
569          (const_int 1)))]
570   "TARGET_SSE"
571   "minss\t{%2, %0|%0, %2}"
572   [(set_attr "type" "sse")
573    (set_attr "mode" "SF")])
574
575 ;; These versions of the min/max patterns implement exactly the operations
576 ;;   min = (op1 < op2 ? op1 : op2)
577 ;;   max = (!(op1 < op2) ? op1 : op2)
578 ;; Their operands are not commutative, and thus they may be used in the
579 ;; presence of -0.0 and NaN.
580
581 (define_insn "*ieee_sminv4sf3"
582   [(set (match_operand:V4SF 0 "register_operand" "=x")
583         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
584                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
585                      UNSPEC_IEEE_MIN))]
586   "TARGET_SSE"
587   "minps\t{%2, %0|%0, %2}"
588   [(set_attr "type" "sseadd")
589    (set_attr "mode" "V4SF")])
590
591 (define_insn "*ieee_smaxv4sf3"
592   [(set (match_operand:V4SF 0 "register_operand" "=x")
593         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
594                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
595                      UNSPEC_IEEE_MAX))]
596   "TARGET_SSE"
597   "maxps\t{%2, %0|%0, %2}"
598   [(set_attr "type" "sseadd")
599    (set_attr "mode" "V4SF")])
600
601 (define_insn "*ieee_sminv2df3"
602   [(set (match_operand:V2DF 0 "register_operand" "=x")
603         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
604                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
605                      UNSPEC_IEEE_MIN))]
606   "TARGET_SSE2"
607   "minpd\t{%2, %0|%0, %2}"
608   [(set_attr "type" "sseadd")
609    (set_attr "mode" "V2DF")])
610
611 (define_insn "*ieee_smaxv2df3"
612   [(set (match_operand:V2DF 0 "register_operand" "=x")
613         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
614                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
615                      UNSPEC_IEEE_MAX))]
616   "TARGET_SSE2"
617   "maxpd\t{%2, %0|%0, %2}"
618   [(set_attr "type" "sseadd")
619    (set_attr "mode" "V2DF")])
620
621 (define_insn "sse3_addsubv4sf3"
622   [(set (match_operand:V4SF 0 "register_operand" "=x")
623         (vec_merge:V4SF
624           (plus:V4SF
625             (match_operand:V4SF 1 "register_operand" "0")
626             (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
627           (minus:V4SF (match_dup 1) (match_dup 2))
628           (const_int 5)))]
629   "TARGET_SSE3"
630   "addsubps\t{%2, %0|%0, %2}"
631   [(set_attr "type" "sseadd")
632    (set_attr "mode" "V4SF")])
633
634 (define_insn "sse3_haddv4sf3"
635   [(set (match_operand:V4SF 0 "register_operand" "=x")
636         (vec_concat:V4SF
637           (vec_concat:V2SF
638             (plus:SF
639               (vec_select:SF 
640                 (match_operand:V4SF 1 "register_operand" "0")
641                 (parallel [(const_int 0)]))
642               (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
643             (plus:SF
644               (vec_select:SF (match_dup 1) (parallel [(const_int 2)]))
645               (vec_select:SF (match_dup 1) (parallel [(const_int 3)]))))
646           (vec_concat:V2SF
647             (plus:SF
648               (vec_select:SF
649                 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
650                 (parallel [(const_int 0)]))
651               (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))
652             (plus:SF
653               (vec_select:SF (match_dup 2) (parallel [(const_int 2)]))
654               (vec_select:SF (match_dup 2) (parallel [(const_int 3)]))))))]
655   "TARGET_SSE3"
656   "haddps\t{%2, %0|%0, %2}"
657   [(set_attr "type" "sseadd")
658    (set_attr "mode" "V4SF")])
659
660 (define_insn "sse3_hsubv4sf3"
661   [(set (match_operand:V4SF 0 "register_operand" "=x")
662         (vec_concat:V4SF
663           (vec_concat:V2SF
664             (minus:SF
665               (vec_select:SF 
666                 (match_operand:V4SF 1 "register_operand" "0")
667                 (parallel [(const_int 0)]))
668               (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
669             (minus:SF
670               (vec_select:SF (match_dup 1) (parallel [(const_int 2)]))
671               (vec_select:SF (match_dup 1) (parallel [(const_int 3)]))))
672           (vec_concat:V2SF
673             (minus:SF
674               (vec_select:SF
675                 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
676                 (parallel [(const_int 0)]))
677               (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))
678             (minus:SF
679               (vec_select:SF (match_dup 2) (parallel [(const_int 2)]))
680               (vec_select:SF (match_dup 2) (parallel [(const_int 3)]))))))]
681   "TARGET_SSE3"
682   "hsubps\t{%2, %0|%0, %2}"
683   [(set_attr "type" "sseadd")
684    (set_attr "mode" "V4SF")])
685
686 (define_expand "reduc_splus_v4sf"
687   [(match_operand:V4SF 0 "register_operand" "")
688    (match_operand:V4SF 1 "register_operand" "")]
689   "TARGET_SSE"
690 {
691   if (TARGET_SSE3)
692     {
693       rtx tmp = gen_reg_rtx (V4SFmode);
694       emit_insn (gen_sse3_haddv4sf3 (tmp, operands[1], operands[1]));
695       emit_insn (gen_sse3_haddv4sf3 (operands[0], tmp, tmp));
696     }
697   else
698     ix86_expand_reduc_v4sf (gen_addv4sf3, operands[0], operands[1]);
699   DONE;
700 })
701
702 (define_expand "reduc_smax_v4sf"
703   [(match_operand:V4SF 0 "register_operand" "")
704    (match_operand:V4SF 1 "register_operand" "")]
705   "TARGET_SSE"
706 {
707   ix86_expand_reduc_v4sf (gen_smaxv4sf3, operands[0], operands[1]);
708   DONE;
709 })
710
711 (define_expand "reduc_smin_v4sf"
712   [(match_operand:V4SF 0 "register_operand" "")
713    (match_operand:V4SF 1 "register_operand" "")]
714   "TARGET_SSE"
715 {
716   ix86_expand_reduc_v4sf (gen_sminv4sf3, operands[0], operands[1]);
717   DONE;
718 })
719
720 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
721 ;;
722 ;; Parallel single-precision floating point comparisons
723 ;;
724 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
725
726 (define_insn "sse_maskcmpv4sf3"
727   [(set (match_operand:V4SF 0 "register_operand" "=x")
728         (match_operator:V4SF 3 "sse_comparison_operator"
729                 [(match_operand:V4SF 1 "register_operand" "0")
730                  (match_operand:V4SF 2 "nonimmediate_operand" "xm")]))]
731   "TARGET_SSE"
732   "cmp%D3ps\t{%2, %0|%0, %2}"
733   [(set_attr "type" "ssecmp")
734    (set_attr "mode" "V4SF")])
735
736 (define_insn "sse_vmmaskcmpv4sf3"
737   [(set (match_operand:V4SF 0 "register_operand" "=x")
738         (vec_merge:V4SF
739          (match_operator:V4SF 3 "sse_comparison_operator"
740                 [(match_operand:V4SF 1 "register_operand" "0")
741                  (match_operand:V4SF 2 "register_operand" "x")])
742          (match_dup 1)
743          (const_int 1)))]
744   "TARGET_SSE"
745   "cmp%D3ss\t{%2, %0|%0, %2}"
746   [(set_attr "type" "ssecmp")
747    (set_attr "mode" "SF")])
748
749 (define_insn "sse_comi"
750   [(set (reg:CCFP FLAGS_REG)
751         (compare:CCFP
752           (vec_select:SF
753             (match_operand:V4SF 0 "register_operand" "x")
754             (parallel [(const_int 0)]))
755           (vec_select:SF
756             (match_operand:V4SF 1 "nonimmediate_operand" "xm")
757             (parallel [(const_int 0)]))))]
758   "TARGET_SSE"
759   "comiss\t{%1, %0|%0, %1}"
760   [(set_attr "type" "ssecomi")
761    (set_attr "mode" "SF")])
762
763 (define_insn "sse_ucomi"
764   [(set (reg:CCFPU FLAGS_REG)
765         (compare:CCFPU
766           (vec_select:SF
767             (match_operand:V4SF 0 "register_operand" "x")
768             (parallel [(const_int 0)]))
769           (vec_select:SF
770             (match_operand:V4SF 1 "nonimmediate_operand" "xm")
771             (parallel [(const_int 0)]))))]
772   "TARGET_SSE"
773   "ucomiss\t{%1, %0|%0, %1}"
774   [(set_attr "type" "ssecomi")
775    (set_attr "mode" "SF")])
776
777 (define_expand "vcondv4sf"
778   [(set (match_operand:V4SF 0 "register_operand" "")
779         (if_then_else:V4SF
780           (match_operator 3 ""
781             [(match_operand:V4SF 4 "nonimmediate_operand" "")
782              (match_operand:V4SF 5 "nonimmediate_operand" "")])
783           (match_operand:V4SF 1 "general_operand" "")
784           (match_operand:V4SF 2 "general_operand" "")))]
785   "TARGET_SSE"
786 {
787   if (ix86_expand_fp_vcond (operands))
788     DONE;
789   else
790     FAIL;
791 })
792
793 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
794 ;;
795 ;; Parallel single-precision floating point logical operations
796 ;;
797 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
798
799 (define_expand "andv4sf3"
800   [(set (match_operand:V4SF 0 "register_operand" "")
801         (and:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "")
802                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
803   "TARGET_SSE"
804   "ix86_fixup_binary_operands_no_copy (AND, V4SFmode, operands);")
805
806 (define_insn "*andv4sf3"
807   [(set (match_operand:V4SF 0 "register_operand" "=x")
808         (and:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
809                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
810   "TARGET_SSE && ix86_binary_operator_ok (AND, V4SFmode, operands)"
811   "andps\t{%2, %0|%0, %2}"
812   [(set_attr "type" "sselog")
813    (set_attr "mode" "V4SF")])
814
815 (define_insn "sse_nandv4sf3"
816   [(set (match_operand:V4SF 0 "register_operand" "=x")
817         (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" "0"))
818                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
819   "TARGET_SSE"
820   "andnps\t{%2, %0|%0, %2}"
821   [(set_attr "type" "sselog")
822    (set_attr "mode" "V4SF")])
823
824 (define_expand "iorv4sf3"
825   [(set (match_operand:V4SF 0 "register_operand" "")
826         (ior:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "")
827                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
828   "TARGET_SSE"
829   "ix86_fixup_binary_operands_no_copy (IOR, V4SFmode, operands);")
830
831 (define_insn "*iorv4sf3"
832   [(set (match_operand:V4SF 0 "register_operand" "=x")
833         (ior:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
834                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
835   "TARGET_SSE && ix86_binary_operator_ok (IOR, V4SFmode, operands)"
836   "orps\t{%2, %0|%0, %2}"
837   [(set_attr "type" "sselog")
838    (set_attr "mode" "V4SF")])
839
840 (define_expand "xorv4sf3"
841   [(set (match_operand:V4SF 0 "register_operand" "")
842         (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "")
843                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
844   "TARGET_SSE"
845   "ix86_fixup_binary_operands_no_copy (XOR, V4SFmode, operands);")
846
847 (define_insn "*xorv4sf3"
848   [(set (match_operand:V4SF 0 "register_operand" "=x")
849         (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
850                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
851   "TARGET_SSE && ix86_binary_operator_ok (XOR, V4SFmode, operands)"
852   "xorps\t{%2, %0|%0, %2}"
853   [(set_attr "type" "sselog")
854    (set_attr "mode" "V4SF")])
855
856 ;; Also define scalar versions.  These are used for abs, neg, and
857 ;; conditional move.  Using subregs into vector modes causes register
858 ;; allocation lossage.  These patterns do not allow memory operands
859 ;; because the native instructions read the full 128-bits.
860
861 (define_insn "*andsf3"
862   [(set (match_operand:SF 0 "register_operand" "=x")
863         (and:SF (match_operand:SF 1 "register_operand" "0")
864                 (match_operand:SF 2 "register_operand" "x")))]
865   "TARGET_SSE"
866   "andps\t{%2, %0|%0, %2}"
867   [(set_attr "type" "sselog")
868    (set_attr "mode" "V4SF")])
869
870 (define_insn "*nandsf3"
871   [(set (match_operand:SF 0 "register_operand" "=x")
872         (and:SF (not:SF (match_operand:SF 1 "register_operand" "0"))
873                 (match_operand:SF 2 "register_operand" "x")))]
874   "TARGET_SSE"
875   "andnps\t{%2, %0|%0, %2}"
876   [(set_attr "type" "sselog")
877    (set_attr "mode" "V4SF")])
878
879 (define_insn "*iorsf3"
880   [(set (match_operand:SF 0 "register_operand" "=x")
881         (ior:SF (match_operand:SF 1 "register_operand" "0")
882                 (match_operand:SF 2 "register_operand" "x")))]
883   "TARGET_SSE"
884   "orps\t{%2, %0|%0, %2}"
885   [(set_attr "type" "sselog")
886    (set_attr "mode" "V4SF")])
887
888 (define_insn "*xorsf3"
889   [(set (match_operand:SF 0 "register_operand" "=x")
890         (xor:SF (match_operand:SF 1 "register_operand" "0")
891                 (match_operand:SF 2 "register_operand" "x")))]
892   "TARGET_SSE"
893   "xorps\t{%2, %0|%0, %2}"
894   [(set_attr "type" "sselog")
895    (set_attr "mode" "V4SF")])
896
897 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
898 ;;
899 ;; Parallel single-precision floating point conversion operations
900 ;;
901 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
902
903 (define_insn "sse_cvtpi2ps"
904   [(set (match_operand:V4SF 0 "register_operand" "=x")
905         (vec_merge:V4SF
906           (vec_duplicate:V4SF
907             (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
908           (match_operand:V4SF 1 "register_operand" "0")
909           (const_int 3)))]
910   "TARGET_SSE"
911   "cvtpi2ps\t{%2, %0|%0, %2}"
912   [(set_attr "type" "ssecvt")
913    (set_attr "mode" "V4SF")])
914
915 (define_insn "sse_cvtps2pi"
916   [(set (match_operand:V2SI 0 "register_operand" "=y")
917         (vec_select:V2SI
918           (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
919                        UNSPEC_FIX_NOTRUNC)
920           (parallel [(const_int 0) (const_int 1)])))]
921   "TARGET_SSE"
922   "cvtps2pi\t{%1, %0|%0, %1}"
923   [(set_attr "type" "ssecvt")
924    (set_attr "unit" "mmx")
925    (set_attr "mode" "DI")])
926
927 (define_insn "sse_cvttps2pi"
928   [(set (match_operand:V2SI 0 "register_operand" "=y")
929         (vec_select:V2SI
930           (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
931           (parallel [(const_int 0) (const_int 1)])))]
932   "TARGET_SSE"
933   "cvttps2pi\t{%1, %0|%0, %1}"
934   [(set_attr "type" "ssecvt")
935    (set_attr "unit" "mmx")
936    (set_attr "mode" "SF")])
937
938 (define_insn "sse_cvtsi2ss"
939   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
940         (vec_merge:V4SF
941           (vec_duplicate:V4SF
942             (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,m")))
943           (match_operand:V4SF 1 "register_operand" "0,0")
944           (const_int 1)))]
945   "TARGET_SSE"
946   "cvtsi2ss\t{%2, %0|%0, %2}"
947   [(set_attr "type" "sseicvt")
948    (set_attr "athlon_decode" "vector,double")
949    (set_attr "mode" "SF")])
950
951 (define_insn "sse_cvtsi2ssq"
952   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
953         (vec_merge:V4SF
954           (vec_duplicate:V4SF
955             (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
956           (match_operand:V4SF 1 "register_operand" "0,0")
957           (const_int 1)))]
958   "TARGET_SSE && TARGET_64BIT"
959   "cvtsi2ssq\t{%2, %0|%0, %2}"
960   [(set_attr "type" "sseicvt")
961    (set_attr "athlon_decode" "vector,double")
962    (set_attr "mode" "SF")])
963
964 (define_insn "sse_cvtss2si"
965   [(set (match_operand:SI 0 "register_operand" "=r,r")
966         (unspec:SI
967           [(vec_select:SF
968              (match_operand:V4SF 1 "nonimmediate_operand" "x,m")
969              (parallel [(const_int 0)]))]
970           UNSPEC_FIX_NOTRUNC))]
971   "TARGET_SSE"
972   "cvtss2si\t{%1, %0|%0, %1}"
973   [(set_attr "type" "sseicvt")
974    (set_attr "athlon_decode" "double,vector")
975    (set_attr "mode" "SI")])
976
977 (define_insn "sse_cvtss2siq"
978   [(set (match_operand:DI 0 "register_operand" "=r,r")
979         (unspec:DI
980           [(vec_select:SF
981              (match_operand:V4SF 1 "nonimmediate_operand" "x,m")
982              (parallel [(const_int 0)]))]
983           UNSPEC_FIX_NOTRUNC))]
984   "TARGET_SSE && TARGET_64BIT"
985   "cvtss2siq\t{%1, %0|%0, %1}"
986   [(set_attr "type" "sseicvt")
987    (set_attr "athlon_decode" "double,vector")
988    (set_attr "mode" "DI")])
989
990 (define_insn "sse_cvttss2si"
991   [(set (match_operand:SI 0 "register_operand" "=r,r")
992         (fix:SI
993           (vec_select:SF
994             (match_operand:V4SF 1 "nonimmediate_operand" "x,m")
995             (parallel [(const_int 0)]))))]
996   "TARGET_SSE"
997   "cvttss2si\t{%1, %0|%0, %1}"
998   [(set_attr "type" "sseicvt")
999    (set_attr "athlon_decode" "double,vector")
1000    (set_attr "mode" "SI")])
1001
1002 (define_insn "sse_cvttss2siq"
1003   [(set (match_operand:DI 0 "register_operand" "=r,r")
1004         (fix:DI
1005           (vec_select:SF
1006             (match_operand:V4SF 1 "nonimmediate_operand" "x,m")
1007             (parallel [(const_int 0)]))))]
1008   "TARGET_SSE && TARGET_64BIT"
1009   "cvttss2siq\t{%1, %0|%0, %1}"
1010   [(set_attr "type" "sseicvt")
1011    (set_attr "athlon_decode" "double,vector")
1012    (set_attr "mode" "DI")])
1013
1014 (define_insn "sse2_cvtdq2ps"
1015   [(set (match_operand:V4SF 0 "register_operand" "=x")
1016         (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
1017   "TARGET_SSE2"
1018   "cvtdq2ps\t{%1, %0|%0, %1}"
1019   [(set_attr "type" "ssecvt")
1020    (set_attr "mode" "V2DF")])
1021
1022 (define_insn "sse2_cvtps2dq"
1023   [(set (match_operand:V4SI 0 "register_operand" "=x")
1024         (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
1025                      UNSPEC_FIX_NOTRUNC))]
1026   "TARGET_SSE2"
1027   "cvtps2dq\t{%1, %0|%0, %1}"
1028   [(set_attr "type" "ssecvt")
1029    (set_attr "mode" "TI")])
1030
1031 (define_insn "sse2_cvttps2dq"
1032   [(set (match_operand:V4SI 0 "register_operand" "=x")
1033         (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
1034   "TARGET_SSE2"
1035   "cvttps2dq\t{%1, %0|%0, %1}"
1036   [(set_attr "type" "ssecvt")
1037    (set_attr "mode" "TI")])
1038
1039 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1040 ;;
1041 ;; Parallel single-precision floating point element swizzling
1042 ;;
1043 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1044
1045 (define_insn "sse_movhlps"
1046   [(set (match_operand:V4SF 0 "nonimmediate_operand"     "=x,x,m")
1047         (vec_select:V4SF
1048           (vec_concat:V8SF
1049             (match_operand:V4SF 1 "nonimmediate_operand" " 0,0,0")
1050             (match_operand:V4SF 2 "nonimmediate_operand" " x,o,x"))
1051           (parallel [(const_int 6)
1052                      (const_int 7)
1053                      (const_int 2)
1054                      (const_int 3)])))]
1055   "TARGET_SSE && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
1056   "@
1057    movhlps\t{%2, %0|%0, %2}
1058    movlps\t{%H2, %0|%0, %H2}
1059    movhps\t{%2, %0|%0, %2}"
1060   [(set_attr "type" "ssemov")
1061    (set_attr "mode" "V4SF,V2SF,V2SF")])
1062
1063 (define_insn "sse_movlhps"
1064   [(set (match_operand:V4SF 0 "nonimmediate_operand"     "=x,x,o")
1065         (vec_select:V4SF
1066           (vec_concat:V8SF
1067             (match_operand:V4SF 1 "nonimmediate_operand" " 0,0,0")
1068             (match_operand:V4SF 2 "nonimmediate_operand" " x,m,x"))
1069           (parallel [(const_int 0)
1070                      (const_int 1)
1071                      (const_int 4)
1072                      (const_int 5)])))]
1073   "TARGET_SSE && ix86_binary_operator_ok (UNKNOWN, V4SFmode, operands)"
1074   "@
1075    movlhps\t{%2, %0|%0, %2}
1076    movhps\t{%2, %0|%0, %2}
1077    movlps\t{%2, %H0|%H0, %2}"
1078   [(set_attr "type" "ssemov")
1079    (set_attr "mode" "V4SF,V2SF,V2SF")])
1080
1081 (define_insn "sse_unpckhps"
1082   [(set (match_operand:V4SF 0 "register_operand" "=x")
1083         (vec_select:V4SF
1084           (vec_concat:V8SF
1085             (match_operand:V4SF 1 "register_operand" "0")
1086             (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
1087           (parallel [(const_int 2) (const_int 6)
1088                      (const_int 3) (const_int 7)])))]
1089   "TARGET_SSE"
1090   "unpckhps\t{%2, %0|%0, %2}"
1091   [(set_attr "type" "sselog")
1092    (set_attr "mode" "V4SF")])
1093
1094 (define_insn "sse_unpcklps"
1095   [(set (match_operand:V4SF 0 "register_operand" "=x")
1096         (vec_select:V4SF
1097           (vec_concat:V8SF
1098             (match_operand:V4SF 1 "register_operand" "0")
1099             (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
1100           (parallel [(const_int 0) (const_int 4)
1101                      (const_int 1) (const_int 5)])))]
1102   "TARGET_SSE"
1103   "unpcklps\t{%2, %0|%0, %2}"
1104   [(set_attr "type" "sselog")
1105    (set_attr "mode" "V4SF")])
1106
1107 ;; These are modeled with the same vec_concat as the others so that we
1108 ;; capture users of shufps that can use the new instructions
1109 (define_insn "sse3_movshdup"
1110   [(set (match_operand:V4SF 0 "register_operand" "=x")
1111         (vec_select:V4SF
1112           (vec_concat:V8SF
1113             (match_operand:V4SF 1 "nonimmediate_operand" "xm")
1114             (match_dup 1))
1115           (parallel [(const_int 1)
1116                      (const_int 1)
1117                      (const_int 7)
1118                      (const_int 7)])))]
1119   "TARGET_SSE3"
1120   "movshdup\t{%1, %0|%0, %1}"
1121   [(set_attr "type" "sse")
1122    (set_attr "mode" "V4SF")])
1123
1124 (define_insn "sse3_movsldup"
1125   [(set (match_operand:V4SF 0 "register_operand" "=x")
1126         (vec_select:V4SF
1127           (vec_concat:V8SF
1128             (match_operand:V4SF 1 "nonimmediate_operand" "xm")
1129             (match_dup 1))
1130           (parallel [(const_int 0)
1131                      (const_int 0)
1132                      (const_int 6)
1133                      (const_int 6)])))]
1134   "TARGET_SSE3"
1135   "movsldup\t{%1, %0|%0, %1}"
1136   [(set_attr "type" "sse")
1137    (set_attr "mode" "V4SF")])
1138
1139 (define_expand "sse_shufps"
1140   [(match_operand:V4SF 0 "register_operand" "")
1141    (match_operand:V4SF 1 "register_operand" "")
1142    (match_operand:V4SF 2 "nonimmediate_operand" "")
1143    (match_operand:SI 3 "const_int_operand" "")]
1144   "TARGET_SSE"
1145 {
1146   int mask = INTVAL (operands[3]);
1147   emit_insn (gen_sse_shufps_1 (operands[0], operands[1], operands[2],
1148                                GEN_INT ((mask >> 0) & 3),
1149                                GEN_INT ((mask >> 2) & 3),
1150                                GEN_INT (((mask >> 4) & 3) + 4),
1151                                GEN_INT (((mask >> 6) & 3) + 4)));
1152   DONE;
1153 })
1154
1155 (define_insn "sse_shufps_1"
1156   [(set (match_operand:V4SF 0 "register_operand" "=x")
1157         (vec_select:V4SF
1158           (vec_concat:V8SF
1159             (match_operand:V4SF 1 "register_operand" "0")
1160             (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
1161           (parallel [(match_operand 3 "const_0_to_3_operand" "")
1162                      (match_operand 4 "const_0_to_3_operand" "")
1163                      (match_operand 5 "const_4_to_7_operand" "")
1164                      (match_operand 6 "const_4_to_7_operand" "")])))]
1165   "TARGET_SSE"
1166 {
1167   int mask = 0;
1168   mask |= INTVAL (operands[3]) << 0;
1169   mask |= INTVAL (operands[4]) << 2;
1170   mask |= (INTVAL (operands[5]) - 4) << 4;
1171   mask |= (INTVAL (operands[6]) - 4) << 6;
1172   operands[3] = GEN_INT (mask);
1173
1174   return "shufps\t{%3, %2, %0|%0, %2, %3}";
1175 }
1176   [(set_attr "type" "sselog")
1177    (set_attr "mode" "V4SF")])
1178
1179 (define_insn "sse_storehps"
1180   [(set (match_operand:V2SF 0 "nonimmediate_operand" "=m,x,x")
1181         (vec_select:V2SF
1182           (match_operand:V4SF 1 "nonimmediate_operand" "x,x,o")
1183           (parallel [(const_int 2) (const_int 3)])))]
1184   "TARGET_SSE"
1185   "@
1186    movhps\t{%1, %0|%0, %1}
1187    movhlps\t{%1, %0|%0, %1}
1188    movlps\t{%H1, %0|%0, %H1}"
1189   [(set_attr "type" "ssemov")
1190    (set_attr "mode" "V2SF,V4SF,V2SF")])
1191
1192 (define_insn "sse_loadhps"
1193   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,o")
1194         (vec_concat:V4SF
1195           (vec_select:V2SF
1196             (match_operand:V4SF 1 "nonimmediate_operand" "0,0,0")
1197             (parallel [(const_int 0) (const_int 1)]))
1198           (match_operand:V2SF 2 "nonimmediate_operand" "m,x,x")))]
1199   "TARGET_SSE"
1200   "@
1201    movhps\t{%2, %0|%0, %2}
1202    movlhps\t{%2, %0|%0, %2}
1203    movlps\t{%2, %H0|%H0, %2}"
1204   [(set_attr "type" "ssemov")
1205    (set_attr "mode" "V2SF,V4SF,V2SF")])
1206
1207 (define_insn "sse_storelps"
1208   [(set (match_operand:V2SF 0 "nonimmediate_operand" "=m,x,x")
1209         (vec_select:V2SF
1210           (match_operand:V4SF 1 "nonimmediate_operand" "x,x,m")
1211           (parallel [(const_int 0) (const_int 1)])))]
1212   "TARGET_SSE"
1213   "@
1214    movlps\t{%1, %0|%0, %1}
1215    movaps\t{%1, %0|%0, %1}
1216    movlps\t{%1, %0|%0, %1}"
1217   [(set_attr "type" "ssemov")
1218    (set_attr "mode" "V2SF,V4SF,V2SF")])
1219
1220 (define_insn "sse_loadlps"
1221   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
1222         (vec_concat:V4SF
1223           (match_operand:V2SF 2 "nonimmediate_operand" "0,m,x")
1224           (vec_select:V2SF
1225             (match_operand:V4SF 1 "nonimmediate_operand" "x,0,0")
1226             (parallel [(const_int 2) (const_int 3)]))))]
1227   "TARGET_SSE"
1228   "@
1229    shufps\t{$0xe4, %1, %0|%0, %1, 0xe4}
1230    movlps\t{%2, %0|%0, %2}
1231    movlps\t{%2, %0|%0, %2}"
1232   [(set_attr "type" "sselog,ssemov,ssemov")
1233    (set_attr "mode" "V4SF,V2SF,V2SF")])
1234
1235 (define_insn "sse_movss"
1236   [(set (match_operand:V4SF 0 "register_operand" "=x")
1237         (vec_merge:V4SF
1238           (match_operand:V4SF 2 "register_operand" "x")
1239           (match_operand:V4SF 1 "register_operand" "0")
1240           (const_int 1)))]
1241   "TARGET_SSE"
1242   "movss\t{%2, %0|%0, %2}"
1243   [(set_attr "type" "ssemov")
1244    (set_attr "mode" "SF")])
1245
1246 (define_insn "*vec_dupv4sf"
1247   [(set (match_operand:V4SF 0 "register_operand" "=x")
1248         (vec_duplicate:V4SF
1249           (match_operand:SF 1 "register_operand" "0")))]
1250   "TARGET_SSE"
1251   "shufps\t{$0, %0, %0|%0, %0, 0}"
1252   [(set_attr "type" "sselog1")
1253    (set_attr "mode" "V4SF")])
1254
1255 ;; ??? In theory we can match memory for the MMX alternative, but allowing
1256 ;; nonimmediate_operand for operand 2 and *not* allowing memory for the SSE
1257 ;; alternatives pretty much forces the MMX alternative to be chosen.
1258 (define_insn "*sse_concatv2sf"
1259   [(set (match_operand:V2SF 0 "register_operand"     "=x,x,*y,*y")
1260         (vec_concat:V2SF
1261           (match_operand:SF 1 "nonimmediate_operand" " 0,m, 0, m")
1262           (match_operand:SF 2 "reg_or_0_operand"     " x,C,*y, C")))]
1263   "TARGET_SSE"
1264   "@
1265    unpcklps\t{%2, %0|%0, %2}
1266    movss\t{%1, %0|%0, %1}
1267    punpckldq\t{%2, %0|%0, %2}
1268    movd\t{%1, %0|%0, %1}"
1269   [(set_attr "type" "sselog,ssemov,mmxcvt,mmxmov")
1270    (set_attr "mode" "V4SF,SF,DI,DI")])
1271
1272 (define_insn "*sse_concatv4sf"
1273   [(set (match_operand:V4SF 0 "register_operand"   "=x,x")
1274         (vec_concat:V4SF
1275           (match_operand:V2SF 1 "register_operand" " 0,0")
1276           (match_operand:V2SF 2 "nonimmediate_operand" " x,m")))]
1277   "TARGET_SSE"
1278   "@
1279    movlhps\t{%2, %0|%0, %2}
1280    movhps\t{%2, %0|%0, %2}"
1281   [(set_attr "type" "ssemov")
1282    (set_attr "mode" "V4SF,V2SF")])
1283
1284 (define_expand "vec_initv4sf"
1285   [(match_operand:V4SF 0 "register_operand" "")
1286    (match_operand 1 "" "")]
1287   "TARGET_SSE"
1288 {
1289   ix86_expand_vector_init (false, operands[0], operands[1]);
1290   DONE;
1291 })
1292
1293 (define_insn "*vec_setv4sf_0"
1294   [(set (match_operand:V4SF 0 "nonimmediate_operand"  "=x,x,Y ,m")
1295         (vec_merge:V4SF
1296           (vec_duplicate:V4SF
1297             (match_operand:SF 2 "general_operand"     " x,m,*r,x*rfF"))
1298           (match_operand:V4SF 1 "vector_move_operand" " 0,C,C ,0")
1299           (const_int 1)))]
1300   "TARGET_SSE"
1301   "@
1302    movss\t{%2, %0|%0, %2}
1303    movss\t{%2, %0|%0, %2}
1304    movd\t{%2, %0|%0, %2}
1305    #"
1306   [(set_attr "type" "ssemov")
1307    (set_attr "mode" "SF")])
1308
1309 (define_split
1310   [(set (match_operand:V4SF 0 "memory_operand" "")
1311         (vec_merge:V4SF
1312           (vec_duplicate:V4SF
1313             (match_operand:SF 1 "nonmemory_operand" ""))
1314           (match_dup 0)
1315           (const_int 1)))]
1316   "TARGET_SSE && reload_completed"
1317   [(const_int 0)]
1318 {
1319   emit_move_insn (adjust_address (operands[0], SFmode, 0), operands[1]);
1320   DONE;
1321 })
1322
1323 (define_expand "vec_setv4sf"
1324   [(match_operand:V4SF 0 "register_operand" "")
1325    (match_operand:SF 1 "register_operand" "")
1326    (match_operand 2 "const_int_operand" "")]
1327   "TARGET_SSE"
1328 {
1329   ix86_expand_vector_set (false, operands[0], operands[1],
1330                           INTVAL (operands[2]));
1331   DONE;
1332 })
1333
1334 (define_insn_and_split "*vec_extractv4sf_0"
1335   [(set (match_operand:SF 0 "nonimmediate_operand" "=x,m,fr")
1336         (vec_select:SF
1337           (match_operand:V4SF 1 "nonimmediate_operand" "xm,x,m")
1338           (parallel [(const_int 0)])))]
1339   "TARGET_SSE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1340   "#"
1341   "&& reload_completed"
1342   [(const_int 0)]
1343 {
1344   rtx op1 = operands[1];
1345   if (REG_P (op1))
1346     op1 = gen_rtx_REG (SFmode, REGNO (op1));
1347   else
1348     op1 = gen_lowpart (SFmode, op1);
1349   emit_move_insn (operands[0], op1);
1350   DONE;
1351 })
1352
1353 (define_expand "vec_extractv4sf"
1354   [(match_operand:SF 0 "register_operand" "")
1355    (match_operand:V4SF 1 "register_operand" "")
1356    (match_operand 2 "const_int_operand" "")]
1357   "TARGET_SSE"
1358 {
1359   ix86_expand_vector_extract (false, operands[0], operands[1],
1360                               INTVAL (operands[2]));
1361   DONE;
1362 })
1363
1364 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1365 ;;
1366 ;; Parallel double-precision floating point arithmetic
1367 ;;
1368 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1369
1370 (define_expand "negv2df2"
1371   [(set (match_operand:V2DF 0 "register_operand" "")
1372         (neg:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")))]
1373   "TARGET_SSE2"
1374   "ix86_expand_fp_absneg_operator (NEG, V2DFmode, operands); DONE;")
1375
1376 (define_expand "absv2df2"
1377   [(set (match_operand:V2DF 0 "register_operand" "")
1378         (abs:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")))]
1379   "TARGET_SSE2"
1380   "ix86_expand_fp_absneg_operator (ABS, V2DFmode, operands); DONE;")
1381
1382 (define_expand "addv2df3"
1383   [(set (match_operand:V2DF 0 "register_operand" "")
1384         (plus:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
1385                    (match_operand:V2DF 2 "nonimmediate_operand" "")))]
1386   "TARGET_SSE2"
1387   "ix86_fixup_binary_operands_no_copy (PLUS, V2DFmode, operands);")
1388
1389 (define_insn "*addv2df3"
1390   [(set (match_operand:V2DF 0 "register_operand" "=x")
1391         (plus:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
1392                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
1393   "TARGET_SSE2 && ix86_binary_operator_ok (PLUS, V2DFmode, operands)"
1394   "addpd\t{%2, %0|%0, %2}"
1395   [(set_attr "type" "sseadd")
1396    (set_attr "mode" "V2DF")])
1397
1398 (define_insn "sse2_vmaddv2df3"
1399   [(set (match_operand:V2DF 0 "register_operand" "=x")
1400         (vec_merge:V2DF
1401           (plus:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
1402                      (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
1403           (match_dup 1)
1404           (const_int 1)))]
1405   "TARGET_SSE2 && ix86_binary_operator_ok (PLUS, V4SFmode, operands)"
1406   "addsd\t{%2, %0|%0, %2}"
1407   [(set_attr "type" "sseadd")
1408    (set_attr "mode" "DF")])
1409
1410 (define_expand "subv2df3"
1411   [(set (match_operand:V2DF 0 "register_operand" "")
1412         (minus:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
1413                     (match_operand:V2DF 2 "nonimmediate_operand" "")))]
1414   "TARGET_SSE2"
1415   "ix86_fixup_binary_operands_no_copy (MINUS, V2DFmode, operands);")
1416
1417 (define_insn "*subv2df3"
1418   [(set (match_operand:V2DF 0 "register_operand" "=x")
1419         (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
1420                     (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
1421   "TARGET_SSE2"
1422   "subpd\t{%2, %0|%0, %2}"
1423   [(set_attr "type" "sseadd")
1424    (set_attr "mode" "V2DF")])
1425
1426 (define_insn "sse2_vmsubv2df3"
1427   [(set (match_operand:V2DF 0 "register_operand" "=x")
1428         (vec_merge:V2DF
1429           (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
1430                       (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
1431           (match_dup 1)
1432           (const_int 1)))]
1433   "TARGET_SSE2"
1434   "subsd\t{%2, %0|%0, %2}"
1435   [(set_attr "type" "sseadd")
1436    (set_attr "mode" "DF")])
1437
1438 (define_expand "mulv2df3"
1439   [(set (match_operand:V2DF 0 "register_operand" "")
1440         (mult:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
1441                    (match_operand:V2DF 2 "nonimmediate_operand" "")))]
1442   "TARGET_SSE2"
1443   "ix86_fixup_binary_operands_no_copy (MULT, V2DFmode, operands);")
1444
1445 (define_insn "*mulv2df3"
1446   [(set (match_operand:V2DF 0 "register_operand" "=x")
1447         (mult:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
1448                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
1449   "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V2DFmode, operands)"
1450   "mulpd\t{%2, %0|%0, %2}"
1451   [(set_attr "type" "ssemul")
1452    (set_attr "mode" "V2DF")])
1453
1454 (define_insn "sse2_vmmulv2df3"
1455   [(set (match_operand:V2DF 0 "register_operand" "=x")
1456         (vec_merge:V2DF
1457           (mult:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
1458                      (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
1459           (match_dup 1)
1460           (const_int 1)))]
1461   "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V2DFmode, operands)"
1462   "mulsd\t{%2, %0|%0, %2}"
1463   [(set_attr "type" "ssemul")
1464    (set_attr "mode" "DF")])
1465
1466 (define_expand "divv2df3"
1467   [(set (match_operand:V2DF 0 "register_operand" "")
1468         (div:V2DF (match_operand:V2DF 1 "register_operand" "")
1469                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
1470   "TARGET_SSE2"
1471   "ix86_fixup_binary_operands_no_copy (DIV, V2DFmode, operands);")
1472
1473 (define_insn "*divv2df3"
1474   [(set (match_operand:V2DF 0 "register_operand" "=x")
1475         (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
1476                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
1477   "TARGET_SSE2"
1478   "divpd\t{%2, %0|%0, %2}"
1479   [(set_attr "type" "ssediv")
1480    (set_attr "mode" "V2DF")])
1481
1482 (define_insn "sse2_vmdivv2df3"
1483   [(set (match_operand:V2DF 0 "register_operand" "=x")
1484         (vec_merge:V2DF
1485           (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
1486                     (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
1487           (match_dup 1)
1488           (const_int 1)))]
1489   "TARGET_SSE2"
1490   "divsd\t{%2, %0|%0, %2}"
1491   [(set_attr "type" "ssediv")
1492    (set_attr "mode" "DF")])
1493
1494 (define_insn "sqrtv2df2"
1495   [(set (match_operand:V2DF 0 "register_operand" "=x")
1496         (sqrt:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
1497   "TARGET_SSE2"
1498   "sqrtpd\t{%1, %0|%0, %1}"
1499   [(set_attr "type" "sse")
1500    (set_attr "mode" "V2DF")])
1501
1502 (define_insn "sse2_vmsqrtv2df2"
1503   [(set (match_operand:V2DF 0 "register_operand" "=x")
1504         (vec_merge:V2DF
1505           (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
1506           (match_operand:V2DF 2 "register_operand" "0")
1507           (const_int 1)))]
1508   "TARGET_SSE2"
1509   "sqrtsd\t{%1, %0|%0, %1}"
1510   [(set_attr "type" "sse")
1511    (set_attr "mode" "DF")])
1512
1513 ;; ??? For !flag_finite_math_only, the representation with SMIN/SMAX
1514 ;; isn't really correct, as those rtl operators aren't defined when 
1515 ;; applied to NaNs.  Hopefully the optimizers won't get too smart on us.
1516
1517 (define_expand "smaxv2df3"
1518   [(set (match_operand:V2DF 0 "register_operand" "")
1519         (smax:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
1520                    (match_operand:V2DF 2 "nonimmediate_operand" "")))]
1521   "TARGET_SSE2"
1522 {
1523   if (!flag_finite_math_only)
1524     operands[1] = force_reg (V2DFmode, operands[1]);
1525   ix86_fixup_binary_operands_no_copy (SMAX, V2DFmode, operands);
1526 })
1527
1528 (define_insn "*smaxv2df3_finite"
1529   [(set (match_operand:V2DF 0 "register_operand" "=x")
1530         (smax:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
1531                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
1532   "TARGET_SSE2 && flag_finite_math_only
1533    && ix86_binary_operator_ok (SMAX, V2DFmode, operands)"
1534   "maxpd\t{%2, %0|%0, %2}"
1535   [(set_attr "type" "sseadd")
1536    (set_attr "mode" "V2DF")])
1537
1538 (define_insn "*smaxv2df3"
1539   [(set (match_operand:V2DF 0 "register_operand" "=x")
1540         (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
1541                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
1542   "TARGET_SSE2"
1543   "maxpd\t{%2, %0|%0, %2}"
1544   [(set_attr "type" "sseadd")
1545    (set_attr "mode" "V2DF")])
1546
1547 (define_insn "*sse2_vmsmaxv2df3_finite"
1548   [(set (match_operand:V2DF 0 "register_operand" "=x")
1549         (vec_merge:V2DF
1550           (smax:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
1551                      (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
1552           (match_dup 1)
1553           (const_int 1)))]
1554   "TARGET_SSE2 && flag_finite_math_only
1555    && ix86_binary_operator_ok (SMAX, V2DFmode, operands)"
1556   "maxsd\t{%2, %0|%0, %2}"
1557   [(set_attr "type" "sseadd")
1558    (set_attr "mode" "DF")])
1559
1560 (define_insn "sse2_vmsmaxv2df3"
1561   [(set (match_operand:V2DF 0 "register_operand" "=x")
1562         (vec_merge:V2DF
1563           (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
1564                      (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
1565           (match_dup 1)
1566           (const_int 1)))]
1567   "TARGET_SSE2"
1568   "maxsd\t{%2, %0|%0, %2}"
1569   [(set_attr "type" "sseadd")
1570    (set_attr "mode" "DF")])
1571
1572 (define_expand "sminv2df3"
1573   [(set (match_operand:V2DF 0 "register_operand" "")
1574         (smin:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
1575                    (match_operand:V2DF 2 "nonimmediate_operand" "")))]
1576   "TARGET_SSE2"
1577 {
1578   if (!flag_finite_math_only)
1579     operands[1] = force_reg (V2DFmode, operands[1]);
1580   ix86_fixup_binary_operands_no_copy (SMIN, V2DFmode, operands);
1581 })
1582
1583 (define_insn "*sminv2df3_finite"
1584   [(set (match_operand:V2DF 0 "register_operand" "=x")
1585         (smin:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
1586                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
1587   "TARGET_SSE2 && flag_finite_math_only
1588    && ix86_binary_operator_ok (SMIN, V2DFmode, operands)"
1589   "minpd\t{%2, %0|%0, %2}"
1590   [(set_attr "type" "sseadd")
1591    (set_attr "mode" "V2DF")])
1592
1593 (define_insn "*sminv2df3"
1594   [(set (match_operand:V2DF 0 "register_operand" "=x")
1595         (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
1596                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
1597   "TARGET_SSE2"
1598   "minpd\t{%2, %0|%0, %2}"
1599   [(set_attr "type" "sseadd")
1600    (set_attr "mode" "V2DF")])
1601
1602 (define_insn "*sse2_vmsminv2df3_finite"
1603   [(set (match_operand:V2DF 0 "register_operand" "=x")
1604         (vec_merge:V2DF
1605           (smin:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
1606                      (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
1607           (match_dup 1)
1608           (const_int 1)))]
1609   "TARGET_SSE2 && flag_finite_math_only
1610    && ix86_binary_operator_ok (SMIN, V2DFmode, operands)"
1611   "minsd\t{%2, %0|%0, %2}"
1612   [(set_attr "type" "sseadd")
1613    (set_attr "mode" "DF")])
1614
1615 (define_insn "sse2_vmsminv2df3"
1616   [(set (match_operand:V2DF 0 "register_operand" "=x")
1617         (vec_merge:V2DF
1618           (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
1619                      (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
1620           (match_dup 1)
1621           (const_int 1)))]
1622   "TARGET_SSE2"
1623   "minsd\t{%2, %0|%0, %2}"
1624   [(set_attr "type" "sseadd")
1625    (set_attr "mode" "DF")])
1626
1627 (define_insn "sse3_addsubv2df3"
1628   [(set (match_operand:V2DF 0 "register_operand" "=x")
1629         (vec_merge:V2DF
1630           (plus:V2DF
1631             (match_operand:V2DF 1 "register_operand" "0")
1632             (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
1633           (minus:V2DF (match_dup 1) (match_dup 2))
1634           (const_int 1)))]
1635   "TARGET_SSE3"
1636   "addsubpd\t{%2, %0|%0, %2}"
1637   [(set_attr "type" "sseadd")
1638    (set_attr "mode" "V2DF")])
1639
1640 (define_insn "sse3_haddv2df3"
1641   [(set (match_operand:V2DF 0 "register_operand" "=x")
1642         (vec_concat:V2DF
1643           (plus:DF
1644             (vec_select:DF
1645               (match_operand:V2DF 1 "register_operand" "0")
1646               (parallel [(const_int 0)]))
1647             (vec_select:DF (match_dup 1) (parallel [(const_int 1)])))
1648           (plus:DF
1649             (vec_select:DF
1650               (match_operand:V2DF 2 "nonimmediate_operand" "xm")
1651               (parallel [(const_int 0)]))
1652             (vec_select:DF (match_dup 2) (parallel [(const_int 1)])))))]
1653   "TARGET_SSE3"
1654   "haddpd\t{%2, %0|%0, %2}"
1655   [(set_attr "type" "sseadd")
1656    (set_attr "mode" "V2DF")])
1657
1658 (define_insn "sse3_hsubv2df3"
1659   [(set (match_operand:V2DF 0 "register_operand" "=x")
1660         (vec_concat:V2DF
1661           (minus:DF
1662             (vec_select:DF
1663               (match_operand:V2DF 1 "register_operand" "0")
1664               (parallel [(const_int 0)]))
1665             (vec_select:DF (match_dup 1) (parallel [(const_int 1)])))
1666           (minus:DF
1667             (vec_select:DF
1668               (match_operand:V2DF 2 "nonimmediate_operand" "xm")
1669               (parallel [(const_int 0)]))
1670             (vec_select:DF (match_dup 2) (parallel [(const_int 1)])))))]
1671   "TARGET_SSE3"
1672   "hsubpd\t{%2, %0|%0, %2}"
1673   [(set_attr "type" "sseadd")
1674    (set_attr "mode" "V2DF")])
1675
1676 (define_expand "reduc_splus_v2df"
1677   [(match_operand:V2DF 0 "register_operand" "")
1678    (match_operand:V2DF 1 "register_operand" "")]
1679   "TARGET_SSE3"
1680 {
1681   emit_insn (gen_sse3_haddv2df3 (operands[0], operands[1], operands[1]));
1682   DONE;
1683 })
1684
1685 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1686 ;;
1687 ;; Parallel double-precision floating point comparisons
1688 ;;
1689 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1690
1691 (define_insn "sse2_maskcmpv2df3"
1692   [(set (match_operand:V2DF 0 "register_operand" "=x")
1693         (match_operator:V2DF 3 "sse_comparison_operator"
1694                 [(match_operand:V2DF 1 "register_operand" "0")
1695                  (match_operand:V2DF 2 "nonimmediate_operand" "xm")]))]
1696   "TARGET_SSE2"
1697   "cmp%D3pd\t{%2, %0|%0, %2}"
1698   [(set_attr "type" "ssecmp")
1699    (set_attr "mode" "V2DF")])
1700
1701 (define_insn "sse2_vmmaskcmpv2df3"
1702   [(set (match_operand:V2DF 0 "register_operand" "=x")
1703         (vec_merge:V2DF
1704           (match_operator:V2DF 3 "sse_comparison_operator"
1705                 [(match_operand:V2DF 1 "register_operand" "0")
1706                  (match_operand:V2DF 2 "nonimmediate_operand" "xm")])
1707           (match_dup 1)
1708           (const_int 1)))]
1709   "TARGET_SSE2"
1710   "cmp%D3sd\t{%2, %0|%0, %2}"
1711   [(set_attr "type" "ssecmp")
1712    (set_attr "mode" "DF")])
1713
1714 (define_insn "sse2_comi"
1715   [(set (reg:CCFP FLAGS_REG)
1716         (compare:CCFP
1717           (vec_select:DF
1718             (match_operand:V2DF 0 "register_operand" "x")
1719             (parallel [(const_int 0)]))
1720           (vec_select:DF
1721             (match_operand:V2DF 1 "nonimmediate_operand" "xm")
1722             (parallel [(const_int 0)]))))]
1723   "TARGET_SSE2"
1724   "comisd\t{%1, %0|%0, %1}"
1725   [(set_attr "type" "ssecomi")
1726    (set_attr "mode" "DF")])
1727
1728 (define_insn "sse2_ucomi"
1729   [(set (reg:CCFPU FLAGS_REG)
1730         (compare:CCFPU
1731           (vec_select:DF
1732             (match_operand:V2DF 0 "register_operand" "x")
1733             (parallel [(const_int 0)]))
1734           (vec_select:DF
1735             (match_operand:V2DF 1 "nonimmediate_operand" "xm")
1736             (parallel [(const_int 0)]))))]
1737   "TARGET_SSE2"
1738   "ucomisd\t{%1, %0|%0, %1}"
1739   [(set_attr "type" "ssecomi")
1740    (set_attr "mode" "DF")])
1741
1742 (define_expand "vcondv2df"
1743   [(set (match_operand:V2DF 0 "register_operand" "")
1744         (if_then_else:V2DF
1745           (match_operator 3 ""
1746             [(match_operand:V2DF 4 "nonimmediate_operand" "")
1747              (match_operand:V2DF 5 "nonimmediate_operand" "")])
1748           (match_operand:V2DF 1 "general_operand" "")
1749           (match_operand:V2DF 2 "general_operand" "")))]
1750   "TARGET_SSE2"
1751 {
1752   if (ix86_expand_fp_vcond (operands))
1753     DONE;
1754   else
1755     FAIL;
1756 })
1757
1758 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1759 ;;
1760 ;; Parallel double-precision floating point logical operations
1761 ;;
1762 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1763
1764 (define_expand "andv2df3"
1765   [(set (match_operand:V2DF 0 "register_operand" "")
1766         (and:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
1767                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
1768   "TARGET_SSE2"
1769   "ix86_fixup_binary_operands_no_copy (AND, V2DFmode, operands);")
1770
1771 (define_insn "*andv2df3"
1772   [(set (match_operand:V2DF 0 "register_operand" "=x")
1773         (and:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
1774                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
1775   "TARGET_SSE2 && ix86_binary_operator_ok (AND, V2DFmode, operands)"
1776   "andpd\t{%2, %0|%0, %2}"
1777   [(set_attr "type" "sselog")
1778    (set_attr "mode" "V2DF")])
1779
1780 (define_insn "sse2_nandv2df3"
1781   [(set (match_operand:V2DF 0 "register_operand" "=x")
1782         (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" "0"))
1783                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
1784   "TARGET_SSE2"
1785   "andnpd\t{%2, %0|%0, %2}"
1786   [(set_attr "type" "sselog")
1787    (set_attr "mode" "V2DF")])
1788
1789 (define_expand "iorv2df3"
1790   [(set (match_operand:V2DF 0 "register_operand" "")
1791         (ior:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
1792                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
1793   "TARGET_SSE2"
1794   "ix86_fixup_binary_operands_no_copy (IOR, V2DFmode, operands);")
1795
1796 (define_insn "*iorv2df3"
1797   [(set (match_operand:V2DF 0 "register_operand" "=x")
1798         (ior:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
1799                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
1800   "TARGET_SSE2 && ix86_binary_operator_ok (IOR, V2DFmode, operands)"
1801   "orpd\t{%2, %0|%0, %2}"
1802   [(set_attr "type" "sselog")
1803    (set_attr "mode" "V2DF")])
1804
1805 (define_expand "xorv2df3"
1806   [(set (match_operand:V2DF 0 "register_operand" "")
1807         (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
1808                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
1809   "TARGET_SSE2"
1810   "ix86_fixup_binary_operands_no_copy (XOR, V2DFmode, operands);")
1811
1812 (define_insn "*xorv2df3"
1813   [(set (match_operand:V2DF 0 "register_operand" "=x")
1814         (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
1815                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
1816   "TARGET_SSE2 && ix86_binary_operator_ok (XOR, V2DFmode, operands)"
1817   "xorpd\t{%2, %0|%0, %2}"
1818   [(set_attr "type" "sselog")
1819    (set_attr "mode" "V2DF")])
1820
1821 ;; Also define scalar versions.  These are used for abs, neg, and
1822 ;; conditional move.  Using subregs into vector modes causes register
1823 ;; allocation lossage.  These patterns do not allow memory operands
1824 ;; because the native instructions read the full 128-bits.
1825
1826 (define_insn "*anddf3"
1827   [(set (match_operand:DF 0 "register_operand" "=x")
1828         (and:DF (match_operand:DF 1 "register_operand" "0")
1829                 (match_operand:DF 2 "register_operand" "x")))]
1830   "TARGET_SSE2"
1831   "andpd\t{%2, %0|%0, %2}"
1832   [(set_attr "type" "sselog")
1833    (set_attr "mode" "V2DF")])
1834
1835 (define_insn "*nanddf3"
1836   [(set (match_operand:DF 0 "register_operand" "=x")
1837         (and:DF (not:DF (match_operand:DF 1 "register_operand" "0"))
1838                 (match_operand:DF 2 "register_operand" "x")))]
1839   "TARGET_SSE2"
1840   "andnpd\t{%2, %0|%0, %2}"
1841   [(set_attr "type" "sselog")
1842    (set_attr "mode" "V2DF")])
1843
1844 (define_insn "*iordf3"
1845   [(set (match_operand:DF 0 "register_operand" "=x")
1846         (ior:DF (match_operand:DF 1 "register_operand" "0")
1847                 (match_operand:DF 2 "register_operand" "x")))]
1848   "TARGET_SSE2"
1849   "orpd\t{%2, %0|%0, %2}"
1850   [(set_attr "type" "sselog")
1851    (set_attr "mode" "V2DF")])
1852
1853 (define_insn "*xordf3"
1854   [(set (match_operand:DF 0 "register_operand" "=x")
1855         (xor:DF (match_operand:DF 1 "register_operand" "0")
1856                 (match_operand:DF 2 "register_operand" "x")))]
1857   "TARGET_SSE2"
1858   "xorpd\t{%2, %0|%0, %2}"
1859   [(set_attr "type" "sselog")
1860    (set_attr "mode" "V2DF")])
1861
1862 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1863 ;;
1864 ;; Parallel double-precision floating point conversion operations
1865 ;;
1866 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1867
1868 (define_insn "sse2_cvtpi2pd"
1869   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
1870         (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "y,m")))]
1871   "TARGET_SSE2"
1872   "cvtpi2pd\t{%1, %0|%0, %1}"
1873   [(set_attr "type" "ssecvt")
1874    (set_attr "unit" "mmx,*")
1875    (set_attr "mode" "V2DF")])
1876
1877 (define_insn "sse2_cvtpd2pi"
1878   [(set (match_operand:V2SI 0 "register_operand" "=y")
1879         (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
1880                      UNSPEC_FIX_NOTRUNC))]
1881   "TARGET_SSE2"
1882   "cvtpd2pi\t{%1, %0|%0, %1}"
1883   [(set_attr "type" "ssecvt")
1884    (set_attr "unit" "mmx")
1885    (set_attr "mode" "DI")])
1886
1887 (define_insn "sse2_cvttpd2pi"
1888   [(set (match_operand:V2SI 0 "register_operand" "=y")
1889         (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
1890   "TARGET_SSE2"
1891   "cvttpd2pi\t{%1, %0|%0, %1}"
1892   [(set_attr "type" "ssecvt")
1893    (set_attr "unit" "mmx")
1894    (set_attr "mode" "TI")])
1895
1896 (define_insn "sse2_cvtsi2sd"
1897   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
1898         (vec_merge:V2DF
1899           (vec_duplicate:V2DF
1900             (float:DF (match_operand:SI 2 "nonimmediate_operand" "r,m")))
1901           (match_operand:V2DF 1 "register_operand" "0,0")
1902           (const_int 1)))]
1903   "TARGET_SSE2"
1904   "cvtsi2sd\t{%2, %0|%0, %2}"
1905   [(set_attr "type" "sseicvt")
1906    (set_attr "mode" "DF")
1907    (set_attr "athlon_decode" "double,direct")])
1908
1909 (define_insn "sse2_cvtsi2sdq"
1910   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
1911         (vec_merge:V2DF
1912           (vec_duplicate:V2DF
1913             (float:DF (match_operand:DI 2 "nonimmediate_operand" "r,m")))
1914           (match_operand:V2DF 1 "register_operand" "0,0")
1915           (const_int 1)))]
1916   "TARGET_SSE2 && TARGET_64BIT"
1917   "cvtsi2sdq\t{%2, %0|%0, %2}"
1918   [(set_attr "type" "sseicvt")
1919    (set_attr "mode" "DF")
1920    (set_attr "athlon_decode" "double,direct")])
1921
1922 (define_insn "sse2_cvtsd2si"
1923   [(set (match_operand:SI 0 "register_operand" "=r,r")
1924         (unspec:SI
1925           [(vec_select:DF
1926              (match_operand:V2DF 1 "nonimmediate_operand" "x,m")
1927              (parallel [(const_int 0)]))]
1928           UNSPEC_FIX_NOTRUNC))]
1929   "TARGET_SSE2"
1930   "cvtsd2si\t{%1, %0|%0, %1}"
1931   [(set_attr "type" "sseicvt")
1932    (set_attr "athlon_decode" "double,vector")
1933    (set_attr "mode" "SI")])
1934
1935 (define_insn "sse2_cvtsd2siq"
1936   [(set (match_operand:DI 0 "register_operand" "=r,r")
1937         (unspec:DI
1938           [(vec_select:DF
1939              (match_operand:V2DF 1 "nonimmediate_operand" "x,m")
1940              (parallel [(const_int 0)]))]
1941           UNSPEC_FIX_NOTRUNC))]
1942   "TARGET_SSE2 && TARGET_64BIT"
1943   "cvtsd2siq\t{%1, %0|%0, %1}"
1944   [(set_attr "type" "sseicvt")
1945    (set_attr "athlon_decode" "double,vector")
1946    (set_attr "mode" "DI")])
1947
1948 (define_insn "sse2_cvttsd2si"
1949   [(set (match_operand:SI 0 "register_operand" "=r,r")
1950         (fix:SI
1951           (vec_select:DF
1952             (match_operand:V2DF 1 "nonimmediate_operand" "x,m")
1953             (parallel [(const_int 0)]))))]
1954   "TARGET_SSE2"
1955   "cvttsd2si\t{%1, %0|%0, %1}"
1956   [(set_attr "type" "sseicvt")
1957    (set_attr "mode" "SI")
1958    (set_attr "athlon_decode" "double,vector")])
1959
1960 (define_insn "sse2_cvttsd2siq"
1961   [(set (match_operand:DI 0 "register_operand" "=r,r")
1962         (fix:DI
1963           (vec_select:DF
1964             (match_operand:V2DF 1 "nonimmediate_operand" "x,m")
1965             (parallel [(const_int 0)]))))]
1966   "TARGET_SSE2 && TARGET_64BIT"
1967   "cvttsd2siq\t{%1, %0|%0, %1}"
1968   [(set_attr "type" "sseicvt")
1969    (set_attr "mode" "DI")
1970    (set_attr "athlon_decode" "double,vector")])
1971
1972 (define_insn "sse2_cvtdq2pd"
1973   [(set (match_operand:V2DF 0 "register_operand" "=x")
1974         (float:V2DF
1975           (vec_select:V2SI
1976             (match_operand:V4SI 1 "nonimmediate_operand" "xm")
1977             (parallel [(const_int 0) (const_int 1)]))))]
1978   "TARGET_SSE2"
1979   "cvtdq2pd\t{%1, %0|%0, %1}"
1980   [(set_attr "type" "ssecvt")
1981    (set_attr "mode" "V2DF")])
1982
1983 (define_expand "sse2_cvtpd2dq"
1984   [(set (match_operand:V4SI 0 "register_operand" "")
1985         (vec_concat:V4SI
1986           (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "")]
1987                        UNSPEC_FIX_NOTRUNC)
1988           (match_dup 2)))]
1989   "TARGET_SSE2"
1990   "operands[2] = CONST0_RTX (V2SImode);")
1991
1992 (define_insn "*sse2_cvtpd2dq"
1993   [(set (match_operand:V4SI 0 "register_operand" "=x")
1994         (vec_concat:V4SI
1995           (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
1996                        UNSPEC_FIX_NOTRUNC)
1997           (match_operand:V2SI 2 "const0_operand" "")))]
1998   "TARGET_SSE2"
1999   "cvtpd2dq\t{%1, %0|%0, %1}"
2000   [(set_attr "type" "ssecvt")
2001    (set_attr "mode" "TI")])
2002
2003 (define_expand "sse2_cvttpd2dq"
2004   [(set (match_operand:V4SI 0 "register_operand" "")
2005         (vec_concat:V4SI
2006           (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" ""))
2007           (match_dup 2)))]
2008   "TARGET_SSE2"
2009   "operands[2] = CONST0_RTX (V2SImode);")
2010
2011 (define_insn "*sse2_cvttpd2dq"
2012   [(set (match_operand:V4SI 0 "register_operand" "=x")
2013         (vec_concat:V4SI
2014           (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
2015           (match_operand:V2SI 2 "const0_operand" "")))]
2016   "TARGET_SSE2"
2017   "cvttpd2dq\t{%1, %0|%0, %1}"
2018   [(set_attr "type" "ssecvt")
2019    (set_attr "mode" "TI")])
2020
2021 (define_insn "sse2_cvtsd2ss"
2022   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
2023         (vec_merge:V4SF
2024           (vec_duplicate:V4SF
2025             (float_truncate:V2SF
2026               (match_operand:V2DF 2 "nonimmediate_operand" "x,m")))
2027           (match_operand:V4SF 1 "register_operand" "0,0")
2028           (const_int 1)))]
2029   "TARGET_SSE2"
2030   "cvtsd2ss\t{%2, %0|%0, %2}"
2031   [(set_attr "type" "ssecvt")
2032    (set_attr "athlon_decode" "vector,double")
2033    (set_attr "mode" "SF")])
2034
2035 (define_insn "sse2_cvtss2sd"
2036   [(set (match_operand:V2DF 0 "register_operand" "=x")
2037         (vec_merge:V2DF
2038           (float_extend:V2DF
2039             (vec_select:V2SF
2040               (match_operand:V4SF 2 "nonimmediate_operand" "xm")
2041               (parallel [(const_int 0) (const_int 1)])))
2042           (match_operand:V2DF 1 "register_operand" "0")
2043           (const_int 1)))]
2044   "TARGET_SSE2"
2045   "cvtss2sd\t{%2, %0|%0, %2}"
2046   [(set_attr "type" "ssecvt")
2047    (set_attr "mode" "DF")])
2048
2049 (define_expand "sse2_cvtpd2ps"
2050   [(set (match_operand:V4SF 0 "register_operand" "")
2051         (vec_concat:V4SF
2052           (float_truncate:V2SF
2053             (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
2054           (match_dup 2)))]
2055   "TARGET_SSE2"
2056   "operands[2] = CONST0_RTX (V2SFmode);")
2057
2058 (define_insn "*sse2_cvtpd2ps"
2059   [(set (match_operand:V4SF 0 "register_operand" "=x")
2060         (vec_concat:V4SF
2061           (float_truncate:V2SF
2062             (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
2063           (match_operand:V2SF 2 "const0_operand" "")))]
2064   "TARGET_SSE2"
2065   "cvtpd2ps\t{%1, %0|%0, %1}"
2066   [(set_attr "type" "ssecvt")
2067    (set_attr "mode" "V4SF")])
2068
2069 (define_insn "sse2_cvtps2pd"
2070   [(set (match_operand:V2DF 0 "register_operand" "=x")
2071         (float_extend:V2DF
2072           (vec_select:V2SF
2073             (match_operand:V4SF 1 "nonimmediate_operand" "xm")
2074             (parallel [(const_int 0) (const_int 1)]))))]
2075   "TARGET_SSE2"
2076   "cvtps2pd\t{%1, %0|%0, %1}"
2077   [(set_attr "type" "ssecvt")
2078    (set_attr "mode" "V2DF")])
2079
2080 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2081 ;;
2082 ;; Parallel double-precision floating point element swizzling
2083 ;;
2084 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2085
2086 (define_insn "sse2_unpckhpd"
2087   [(set (match_operand:V2DF 0 "nonimmediate_operand"     "=x,x,m")
2088         (vec_select:V2DF
2089           (vec_concat:V4DF
2090             (match_operand:V2DF 1 "nonimmediate_operand" " 0,o,x")
2091             (match_operand:V2DF 2 "nonimmediate_operand" " x,0,0"))
2092           (parallel [(const_int 1)
2093                      (const_int 3)])))]
2094   "TARGET_SSE2 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
2095   "@
2096    unpckhpd\t{%2, %0|%0, %2}
2097    movlpd\t{%H1, %0|%0, %H1}
2098    movhpd\t{%1, %0|%0, %1}"
2099   [(set_attr "type" "sselog,ssemov,ssemov")
2100    (set_attr "mode" "V2DF,V1DF,V1DF")])
2101
2102 (define_insn "*sse3_movddup"
2103   [(set (match_operand:V2DF 0 "nonimmediate_operand"     "=x,o")
2104         (vec_select:V2DF
2105           (vec_concat:V4DF
2106             (match_operand:V2DF 1 "nonimmediate_operand" "xm,x")
2107             (match_dup 1))
2108           (parallel [(const_int 0)
2109                      (const_int 2)])))]
2110   "TARGET_SSE3 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
2111   "@
2112    movddup\t{%1, %0|%0, %1}
2113    #"
2114   [(set_attr "type" "sselog,ssemov")
2115    (set_attr "mode" "V2DF")])
2116
2117 (define_split
2118   [(set (match_operand:V2DF 0 "memory_operand" "")
2119         (vec_select:V2DF
2120           (vec_concat:V4DF
2121             (match_operand:V2DF 1 "register_operand" "")
2122             (match_dup 1))
2123           (parallel [(const_int 0)
2124                      (const_int 2)])))]
2125   "TARGET_SSE3 && reload_completed"
2126   [(const_int 0)]
2127 {
2128   rtx low = gen_rtx_REG (DFmode, REGNO (operands[1]));
2129   emit_move_insn (adjust_address (operands[0], DFmode, 0), low);
2130   emit_move_insn (adjust_address (operands[0], DFmode, 8), low);
2131   DONE;
2132 })
2133
2134 (define_insn "sse2_unpcklpd"
2135   [(set (match_operand:V2DF 0 "nonimmediate_operand"     "=x,x,o")
2136         (vec_select:V2DF
2137           (vec_concat:V4DF
2138             (match_operand:V2DF 1 "nonimmediate_operand" " 0,0,0")
2139             (match_operand:V2DF 2 "nonimmediate_operand" " x,m,x"))
2140           (parallel [(const_int 0)
2141                      (const_int 2)])))]
2142   "TARGET_SSE2 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
2143   "@
2144    unpcklpd\t{%2, %0|%0, %2}
2145    movhpd\t{%2, %0|%0, %2}
2146    movlpd\t{%2, %H0|%H0, %2}"
2147   [(set_attr "type" "sselog,ssemov,ssemov")
2148    (set_attr "mode" "V2DF,V1DF,V1DF")])
2149
2150 (define_expand "sse2_shufpd"
2151   [(match_operand:V2DF 0 "register_operand" "")
2152    (match_operand:V2DF 1 "register_operand" "")
2153    (match_operand:V2DF 2 "nonimmediate_operand" "")
2154    (match_operand:SI 3 "const_int_operand" "")]
2155   "TARGET_SSE2"
2156 {
2157   int mask = INTVAL (operands[3]);
2158   emit_insn (gen_sse2_shufpd_1 (operands[0], operands[1], operands[2],
2159                                 GEN_INT (mask & 1),
2160                                 GEN_INT (mask & 2 ? 3 : 2)));
2161   DONE;
2162 })
2163
2164 (define_insn "sse2_shufpd_1"
2165   [(set (match_operand:V2DF 0 "register_operand" "=x")
2166         (vec_select:V2DF
2167           (vec_concat:V4DF
2168             (match_operand:V2DF 1 "register_operand" "0")
2169             (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
2170           (parallel [(match_operand 3 "const_0_to_1_operand" "")
2171                      (match_operand 4 "const_2_to_3_operand" "")])))]
2172   "TARGET_SSE2"
2173 {
2174   int mask;
2175   mask = INTVAL (operands[3]);
2176   mask |= (INTVAL (operands[4]) - 2) << 1;
2177   operands[3] = GEN_INT (mask);
2178
2179   return "shufpd\t{%3, %2, %0|%0, %2, %3}";
2180 }
2181   [(set_attr "type" "sselog")
2182    (set_attr "mode" "V2DF")])
2183
2184 (define_insn "sse2_storehpd"
2185   [(set (match_operand:DF 0 "nonimmediate_operand"     "=m,x,x*fr")
2186         (vec_select:DF
2187           (match_operand:V2DF 1 "nonimmediate_operand" " x,0,o")
2188           (parallel [(const_int 1)])))]
2189   "TARGET_SSE2 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2190   "@
2191    movhpd\t{%1, %0|%0, %1}
2192    unpckhpd\t%0, %0
2193    #"
2194   [(set_attr "type" "ssemov,sselog1,ssemov")
2195    (set_attr "mode" "V1DF,V2DF,DF")])
2196
2197 (define_split
2198   [(set (match_operand:DF 0 "register_operand" "")
2199         (vec_select:DF
2200           (match_operand:V2DF 1 "memory_operand" "")
2201           (parallel [(const_int 1)])))]
2202   "TARGET_SSE2 && reload_completed"
2203   [(set (match_dup 0) (match_dup 1))]
2204 {
2205   operands[1] = adjust_address (operands[1], DFmode, 8);
2206 })
2207
2208 (define_insn "sse2_storelpd"
2209   [(set (match_operand:DF 0 "nonimmediate_operand"     "=m,x,x*fr")
2210         (vec_select:DF
2211           (match_operand:V2DF 1 "nonimmediate_operand" " x,x,m")
2212           (parallel [(const_int 0)])))]
2213   "TARGET_SSE2 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2214   "@
2215    movlpd\t{%1, %0|%0, %1}
2216    #
2217    #"
2218   [(set_attr "type" "ssemov")
2219    (set_attr "mode" "V1DF,DF,DF")])
2220
2221 (define_split
2222   [(set (match_operand:DF 0 "register_operand" "")
2223         (vec_select:DF
2224           (match_operand:V2DF 1 "nonimmediate_operand" "")
2225           (parallel [(const_int 0)])))]
2226   "TARGET_SSE2 && reload_completed"
2227   [(const_int 0)]
2228 {
2229   rtx op1 = operands[1];
2230   if (REG_P (op1))
2231     op1 = gen_rtx_REG (DFmode, REGNO (op1));
2232   else
2233     op1 = gen_lowpart (DFmode, op1);
2234   emit_move_insn (operands[0], op1);
2235   DONE;
2236 })
2237
2238 (define_insn "sse2_loadhpd"
2239   [(set (match_operand:V2DF 0 "nonimmediate_operand"     "=x,x,x,o")
2240         (vec_concat:V2DF
2241           (vec_select:DF
2242             (match_operand:V2DF 1 "nonimmediate_operand" " 0,0,x,0")
2243             (parallel [(const_int 0)]))
2244           (match_operand:DF 2 "nonimmediate_operand"     " m,x,0,x*fr")))]
2245   "TARGET_SSE2 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
2246   "@
2247    movhpd\t{%2, %0|%0, %2}
2248    unpcklpd\t{%2, %0|%0, %2}
2249    shufpd\t{$1, %1, %0|%0, %1, 1}
2250    #"
2251   [(set_attr "type" "ssemov,sselog,sselog,other")
2252    (set_attr "mode" "V1DF,V2DF,V2DF,DF")])
2253
2254 (define_split
2255   [(set (match_operand:V2DF 0 "memory_operand" "")
2256         (vec_concat:V2DF
2257           (vec_select:DF (match_dup 0) (parallel [(const_int 0)]))
2258           (match_operand:DF 1 "register_operand" "")))]
2259   "TARGET_SSE2 && reload_completed"
2260   [(set (match_dup 0) (match_dup 1))]
2261 {
2262   operands[0] = adjust_address (operands[0], DFmode, 8);
2263 })
2264
2265 (define_insn "sse2_loadlpd"
2266   [(set (match_operand:V2DF 0 "nonimmediate_operand"    "=x,x,x,x,x,m")
2267         (vec_concat:V2DF
2268           (match_operand:DF 2 "nonimmediate_operand"    " m,m,x,0,0,x*fr")
2269           (vec_select:DF
2270             (match_operand:V2DF 1 "vector_move_operand" " C,0,0,x,o,0")
2271             (parallel [(const_int 1)]))))]
2272   "TARGET_SSE2 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
2273   "@
2274    movsd\t{%2, %0|%0, %2}
2275    movlpd\t{%2, %0|%0, %2}
2276    movsd\t{%2, %0|%0, %2}
2277    shufpd\t{$2, %2, %0|%0, %2, 2}
2278    movhpd\t{%H1, %0|%0, %H1}
2279    #"
2280   [(set_attr "type" "ssemov,ssemov,ssemov,sselog,ssemov,other")
2281    (set_attr "mode" "DF,V1DF,V1DF,V2DF,V1DF,DF")])
2282
2283 (define_split
2284   [(set (match_operand:V2DF 0 "memory_operand" "")
2285         (vec_concat:V2DF
2286           (match_operand:DF 1 "register_operand" "")
2287           (vec_select:DF (match_dup 0) (parallel [(const_int 1)]))))]
2288   "TARGET_SSE2 && reload_completed"
2289   [(set (match_dup 0) (match_dup 1))]
2290 {
2291   operands[0] = adjust_address (operands[0], DFmode, 8);
2292 })
2293
2294 ;; Not sure these two are ever used, but it doesn't hurt to have
2295 ;; them. -aoliva
2296 (define_insn "*vec_extractv2df_1_sse"
2297   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,x,x")
2298         (vec_select:DF
2299           (match_operand:V2DF 1 "nonimmediate_operand" "x,x,o")
2300           (parallel [(const_int 1)])))]
2301   "!TARGET_SSE2 && TARGET_SSE
2302    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2303   "@
2304    movhps\t{%1, %0|%0, %1}
2305    movhlps\t{%1, %0|%0, %1}
2306    movlps\t{%H1, %0|%0, %H1}"
2307   [(set_attr "type" "ssemov")
2308    (set_attr "mode" "V2SF,V4SF,V2SF")])
2309
2310 (define_insn "*vec_extractv2df_0_sse"
2311   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,x,x")
2312         (vec_select:DF
2313           (match_operand:V2DF 1 "nonimmediate_operand" "x,x,m")
2314           (parallel [(const_int 0)])))]
2315   "!TARGET_SSE2 && TARGET_SSE
2316    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2317   "@
2318    movlps\t{%1, %0|%0, %1}
2319    movaps\t{%1, %0|%0, %1}
2320    movlps\t{%1, %0|%0, %1}"
2321   [(set_attr "type" "ssemov")
2322    (set_attr "mode" "V2SF,V4SF,V2SF")])
2323
2324 (define_insn "sse2_movsd"
2325   [(set (match_operand:V2DF 0 "nonimmediate_operand"   "=x,x,m,x,x,o")
2326         (vec_merge:V2DF
2327           (match_operand:V2DF 2 "nonimmediate_operand" " x,m,x,0,0,0")
2328           (match_operand:V2DF 1 "nonimmediate_operand" " 0,0,0,x,o,x")
2329           (const_int 1)))]
2330   "TARGET_SSE2"
2331   "@
2332    movsd\t{%2, %0|%0, %2}
2333    movlpd\t{%2, %0|%0, %2}
2334    movlpd\t{%2, %0|%0, %2}
2335    shufpd\t{$2, %2, %0|%0, %2, 2}
2336    movhps\t{%H1, %0|%0, %H1}
2337    movhps\t{%1, %H0|%H0, %1}"
2338   [(set_attr "type" "ssemov,ssemov,ssemov,sselog,ssemov,ssemov")
2339    (set_attr "mode" "DF,V1DF,V1DF,V2DF,V1DF,V1DF")])
2340
2341 (define_insn "*vec_dupv2df_sse3"
2342   [(set (match_operand:V2DF 0 "register_operand" "=x")
2343         (vec_duplicate:V2DF
2344           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
2345   "TARGET_SSE3"
2346   "movddup\t{%1, %0|%0, %1}"
2347   [(set_attr "type" "sselog1")
2348    (set_attr "mode" "DF")])
2349
2350 (define_insn "*vec_dupv2df"
2351   [(set (match_operand:V2DF 0 "register_operand" "=x")
2352         (vec_duplicate:V2DF
2353           (match_operand:DF 1 "register_operand" "0")))]
2354   "TARGET_SSE2"
2355   "unpcklpd\t%0, %0"
2356   [(set_attr "type" "sselog1")
2357    (set_attr "mode" "V4SF")])
2358
2359 (define_insn "*vec_concatv2df_sse3"
2360   [(set (match_operand:V2DF 0 "register_operand" "=x")
2361         (vec_concat:V2DF
2362           (match_operand:DF 1 "nonimmediate_operand" "xm")
2363           (match_dup 1)))]
2364   "TARGET_SSE3"
2365   "movddup\t{%1, %0|%0, %1}"
2366   [(set_attr "type" "sselog1")
2367    (set_attr "mode" "DF")])
2368
2369 (define_insn "*vec_concatv2df"
2370   [(set (match_operand:V2DF 0 "register_operand"     "=Y,Y,Y,x,x")
2371         (vec_concat:V2DF
2372           (match_operand:DF 1 "nonimmediate_operand" " 0,0,m,0,0")
2373           (match_operand:DF 2 "vector_move_operand"  " Y,m,C,x,m")))]
2374   "TARGET_SSE"
2375   "@
2376    unpcklpd\t{%2, %0|%0, %2}
2377    movhpd\t{%2, %0|%0, %2}
2378    movsd\t{%1, %0|%0, %1}
2379    movlhps\t{%2, %0|%0, %2}
2380    movhps\t{%2, %0|%0, %2}"
2381   [(set_attr "type" "sselog,ssemov,ssemov,ssemov,ssemov")
2382    (set_attr "mode" "V2DF,V1DF,DF,V4SF,V2SF")])
2383
2384 (define_expand "vec_setv2df"
2385   [(match_operand:V2DF 0 "register_operand" "")
2386    (match_operand:DF 1 "register_operand" "")
2387    (match_operand 2 "const_int_operand" "")]
2388   "TARGET_SSE"
2389 {
2390   ix86_expand_vector_set (false, operands[0], operands[1],
2391                           INTVAL (operands[2]));
2392   DONE;
2393 })
2394
2395 (define_expand "vec_extractv2df"
2396   [(match_operand:DF 0 "register_operand" "")
2397    (match_operand:V2DF 1 "register_operand" "")
2398    (match_operand 2 "const_int_operand" "")]
2399   "TARGET_SSE"
2400 {
2401   ix86_expand_vector_extract (false, operands[0], operands[1],
2402                               INTVAL (operands[2]));
2403   DONE;
2404 })
2405
2406 (define_expand "vec_initv2df"
2407   [(match_operand:V2DF 0 "register_operand" "")
2408    (match_operand 1 "" "")]
2409   "TARGET_SSE"
2410 {
2411   ix86_expand_vector_init (false, operands[0], operands[1]);
2412   DONE;
2413 })
2414
2415 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2416 ;;
2417 ;; Parallel integral arithmetic
2418 ;;
2419 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2420
2421 (define_expand "neg<mode>2"
2422   [(set (match_operand:SSEMODEI 0 "register_operand" "")
2423         (minus:SSEMODEI
2424           (match_dup 2)
2425           (match_operand:SSEMODEI 1 "nonimmediate_operand" "")))]
2426   "TARGET_SSE2"
2427   "operands[2] = force_reg (<MODE>mode, CONST0_RTX (<MODE>mode));")
2428
2429 (define_expand "add<mode>3"
2430   [(set (match_operand:SSEMODEI 0 "register_operand" "")
2431         (plus:SSEMODEI (match_operand:SSEMODEI 1 "nonimmediate_operand" "")
2432                        (match_operand:SSEMODEI 2 "nonimmediate_operand" "")))]
2433   "TARGET_SSE2"
2434   "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
2435
2436 (define_insn "*add<mode>3"
2437   [(set (match_operand:SSEMODEI 0 "register_operand" "=x")
2438         (plus:SSEMODEI
2439           (match_operand:SSEMODEI 1 "nonimmediate_operand" "%0")
2440           (match_operand:SSEMODEI 2 "nonimmediate_operand" "xm")))]
2441   "TARGET_SSE2 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
2442   "padd<ssevecsize>\t{%2, %0|%0, %2}"
2443   [(set_attr "type" "sseiadd")
2444    (set_attr "mode" "TI")])
2445
2446 (define_insn "sse2_ssadd<mode>3"
2447   [(set (match_operand:SSEMODE12 0 "register_operand" "=x")
2448         (ss_plus:SSEMODE12
2449           (match_operand:SSEMODE12 1 "nonimmediate_operand" "%0")
2450           (match_operand:SSEMODE12 2 "nonimmediate_operand" "xm")))]
2451   "TARGET_SSE2 && ix86_binary_operator_ok (SS_PLUS, <MODE>mode, operands)"
2452   "padds<ssevecsize>\t{%2, %0|%0, %2}"
2453   [(set_attr "type" "sseiadd")
2454    (set_attr "mode" "TI")])
2455
2456 (define_insn "sse2_usadd<mode>3"
2457   [(set (match_operand:SSEMODE12 0 "register_operand" "=x")
2458         (us_plus:SSEMODE12
2459           (match_operand:SSEMODE12 1 "nonimmediate_operand" "%0")
2460           (match_operand:SSEMODE12 2 "nonimmediate_operand" "xm")))]
2461   "TARGET_SSE2 && ix86_binary_operator_ok (US_PLUS, <MODE>mode, operands)"
2462   "paddus<ssevecsize>\t{%2, %0|%0, %2}"
2463   [(set_attr "type" "sseiadd")
2464    (set_attr "mode" "TI")])
2465
2466 (define_expand "sub<mode>3"
2467   [(set (match_operand:SSEMODEI 0 "register_operand" "")
2468         (minus:SSEMODEI (match_operand:SSEMODEI 1 "register_operand" "")
2469                         (match_operand:SSEMODEI 2 "nonimmediate_operand" "")))]
2470   "TARGET_SSE2"
2471   "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
2472
2473 (define_insn "*sub<mode>3"
2474   [(set (match_operand:SSEMODEI 0 "register_operand" "=x")
2475         (minus:SSEMODEI
2476           (match_operand:SSEMODEI 1 "register_operand" "0")
2477           (match_operand:SSEMODEI 2 "nonimmediate_operand" "xm")))]
2478   "TARGET_SSE2"
2479   "psub<ssevecsize>\t{%2, %0|%0, %2}"
2480   [(set_attr "type" "sseiadd")
2481    (set_attr "mode" "TI")])
2482
2483 (define_insn "sse2_sssub<mode>3"
2484   [(set (match_operand:SSEMODE12 0 "register_operand" "=x")
2485         (ss_minus:SSEMODE12
2486           (match_operand:SSEMODE12 1 "register_operand" "0")
2487           (match_operand:SSEMODE12 2 "nonimmediate_operand" "xm")))]
2488   "TARGET_SSE2"
2489   "psubs<ssevecsize>\t{%2, %0|%0, %2}"
2490   [(set_attr "type" "sseiadd")
2491    (set_attr "mode" "TI")])
2492
2493 (define_insn "sse2_ussub<mode>3"
2494   [(set (match_operand:SSEMODE12 0 "register_operand" "=x")
2495         (us_minus:SSEMODE12
2496           (match_operand:SSEMODE12 1 "register_operand" "0")
2497           (match_operand:SSEMODE12 2 "nonimmediate_operand" "xm")))]
2498   "TARGET_SSE2"
2499   "psubus<ssevecsize>\t{%2, %0|%0, %2}"
2500   [(set_attr "type" "sseiadd")
2501    (set_attr "mode" "TI")])
2502
2503 (define_expand "mulv16qi3"
2504   [(set (match_operand:V16QI 0 "register_operand" "")
2505         (mult:V16QI (match_operand:V16QI 1 "register_operand" "")
2506                     (match_operand:V16QI 2 "register_operand" "")))]
2507   "TARGET_SSE2"
2508 {
2509   rtx t[12], op0;
2510   int i;
2511
2512   for (i = 0; i < 12; ++i)
2513     t[i] = gen_reg_rtx (V16QImode);
2514
2515   /* Unpack data such that we've got a source byte in each low byte of
2516      each word.  We don't care what goes into the high byte of each word.
2517      Rather than trying to get zero in there, most convenient is to let
2518      it be a copy of the low byte.  */
2519   emit_insn (gen_sse2_punpckhbw (t[0], operands[1], operands[1]));
2520   emit_insn (gen_sse2_punpckhbw (t[1], operands[2], operands[2]));
2521   emit_insn (gen_sse2_punpcklbw (t[2], operands[1], operands[1]));
2522   emit_insn (gen_sse2_punpcklbw (t[3], operands[2], operands[2]));
2523
2524   /* Multiply words.  The end-of-line annotations here give a picture of what
2525      the output of that instruction looks like.  Dot means don't care; the 
2526      letters are the bytes of the result with A being the most significant.  */
2527   emit_insn (gen_mulv8hi3 (gen_lowpart (V8HImode, t[4]), /* .A.B.C.D.E.F.G.H */
2528                            gen_lowpart (V8HImode, t[0]),
2529                            gen_lowpart (V8HImode, t[1])));
2530   emit_insn (gen_mulv8hi3 (gen_lowpart (V8HImode, t[5]), /* .I.J.K.L.M.N.O.P */
2531                            gen_lowpart (V8HImode, t[2]),
2532                            gen_lowpart (V8HImode, t[3])));
2533
2534   /* Extract the relevant bytes and merge them back together.  */
2535   emit_insn (gen_sse2_punpckhbw (t[6], t[5], t[4]));    /* ..AI..BJ..CK..DL */
2536   emit_insn (gen_sse2_punpcklbw (t[7], t[5], t[4]));    /* ..EM..FN..GO..HP */
2537   emit_insn (gen_sse2_punpckhbw (t[8], t[7], t[6]));    /* ....AEIM....BFJN */
2538   emit_insn (gen_sse2_punpcklbw (t[9], t[7], t[6]));    /* ....CGKO....DHLP */
2539   emit_insn (gen_sse2_punpckhbw (t[10], t[9], t[8]));   /* ........ACEGIKMO */
2540   emit_insn (gen_sse2_punpcklbw (t[11], t[9], t[8]));   /* ........BDFHJLNP */
2541
2542   op0 = operands[0];
2543   emit_insn (gen_sse2_punpcklbw (op0, t[11], t[10]));   /* ABCDEFGHIJKLMNOP */
2544   DONE;
2545 })
2546
2547 (define_expand "mulv8hi3"
2548   [(set (match_operand:V8HI 0 "register_operand" "")
2549         (mult:V8HI (match_operand:V8HI 1 "nonimmediate_operand" "")
2550                    (match_operand:V8HI 2 "nonimmediate_operand" "")))]
2551   "TARGET_SSE2"
2552   "ix86_fixup_binary_operands_no_copy (MULT, V8HImode, operands);")
2553
2554 (define_insn "*mulv8hi3"
2555   [(set (match_operand:V8HI 0 "register_operand" "=x")
2556         (mult:V8HI (match_operand:V8HI 1 "nonimmediate_operand" "%0")
2557                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
2558   "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V8HImode, operands)"
2559   "pmullw\t{%2, %0|%0, %2}"
2560   [(set_attr "type" "sseimul")
2561    (set_attr "mode" "TI")])
2562
2563 (define_insn "sse2_smulv8hi3_highpart"
2564   [(set (match_operand:V8HI 0 "register_operand" "=x")
2565         (truncate:V8HI
2566           (lshiftrt:V8SI
2567             (mult:V8SI
2568               (sign_extend:V8SI
2569                 (match_operand:V8HI 1 "nonimmediate_operand" "%0"))
2570               (sign_extend:V8SI
2571                 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
2572             (const_int 16))))]
2573   "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V8HImode, operands)"
2574   "pmulhw\t{%2, %0|%0, %2}"
2575   [(set_attr "type" "sseimul")
2576    (set_attr "mode" "TI")])
2577
2578 (define_insn "sse2_umulv8hi3_highpart"
2579   [(set (match_operand:V8HI 0 "register_operand" "=x")
2580         (truncate:V8HI
2581           (lshiftrt:V8SI
2582             (mult:V8SI
2583               (zero_extend:V8SI
2584                 (match_operand:V8HI 1 "nonimmediate_operand" "%0"))
2585               (zero_extend:V8SI
2586                 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
2587             (const_int 16))))]
2588   "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V8HImode, operands)"
2589   "pmulhuw\t{%2, %0|%0, %2}"
2590   [(set_attr "type" "sseimul")
2591    (set_attr "mode" "TI")])
2592
2593 (define_insn "sse2_umulv2siv2di3"
2594   [(set (match_operand:V2DI 0 "register_operand" "=x")
2595         (mult:V2DI
2596           (zero_extend:V2DI
2597             (vec_select:V2SI
2598               (match_operand:V4SI 1 "nonimmediate_operand" "%0")
2599               (parallel [(const_int 0) (const_int 2)])))
2600           (zero_extend:V2DI
2601             (vec_select:V2SI
2602               (match_operand:V4SI 2 "nonimmediate_operand" "xm")
2603               (parallel [(const_int 0) (const_int 2)])))))]
2604   "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V8HImode, operands)"
2605   "pmuludq\t{%2, %0|%0, %2}"
2606   [(set_attr "type" "sseimul")
2607    (set_attr "mode" "TI")])
2608
2609 (define_insn "sse2_pmaddwd"
2610   [(set (match_operand:V4SI 0 "register_operand" "=x")
2611         (plus:V4SI
2612           (mult:V4SI
2613             (sign_extend:V4SI
2614               (vec_select:V4HI
2615                 (match_operand:V8HI 1 "nonimmediate_operand" "%0")
2616                 (parallel [(const_int 0)
2617                            (const_int 2)
2618                            (const_int 4)
2619                            (const_int 6)])))
2620             (sign_extend:V4SI
2621               (vec_select:V4HI
2622                 (match_operand:V8HI 2 "nonimmediate_operand" "xm")
2623                 (parallel [(const_int 0)
2624                            (const_int 2)
2625                            (const_int 4)
2626                            (const_int 6)]))))
2627           (mult:V4SI
2628             (sign_extend:V4SI
2629               (vec_select:V4HI (match_dup 1)
2630                 (parallel [(const_int 1)
2631                            (const_int 3)
2632                            (const_int 5)
2633                            (const_int 7)])))
2634             (sign_extend:V4SI
2635               (vec_select:V4HI (match_dup 2)
2636                 (parallel [(const_int 1)
2637                            (const_int 3)
2638                            (const_int 5)
2639                            (const_int 7)]))))))]
2640   "TARGET_SSE2"
2641   "pmaddwd\t{%2, %0|%0, %2}"
2642   [(set_attr "type" "sseiadd")
2643    (set_attr "mode" "TI")])
2644
2645 (define_expand "mulv4si3"
2646   [(set (match_operand:V4SI 0 "register_operand" "")
2647         (mult:V4SI (match_operand:V4SI 1 "register_operand" "")
2648                    (match_operand:V4SI 2 "register_operand" "")))]
2649   "TARGET_SSE2"
2650 {
2651   rtx t1, t2, t3, t4, t5, t6, thirtytwo;
2652   rtx op0, op1, op2;
2653
2654   op0 = operands[0];
2655   op1 = operands[1];
2656   op2 = operands[2];
2657   t1 = gen_reg_rtx (V4SImode);
2658   t2 = gen_reg_rtx (V4SImode);
2659   t3 = gen_reg_rtx (V4SImode);
2660   t4 = gen_reg_rtx (V4SImode);
2661   t5 = gen_reg_rtx (V4SImode);
2662   t6 = gen_reg_rtx (V4SImode);
2663   thirtytwo = GEN_INT (32);
2664
2665   /* Multiply elements 2 and 0.  */
2666   emit_insn (gen_sse2_umulv2siv2di3 (gen_lowpart (V2DImode, t1), op1, op2));
2667
2668   /* Shift both input vectors down one element, so that elements 3 and 1
2669      are now in the slots for elements 2 and 0.  For K8, at least, this is
2670      faster than using a shuffle.  */
2671   emit_insn (gen_sse2_lshrti3 (gen_lowpart (TImode, t2),
2672                                gen_lowpart (TImode, op1), thirtytwo));
2673   emit_insn (gen_sse2_lshrti3 (gen_lowpart (TImode, t3),
2674                                gen_lowpart (TImode, op2), thirtytwo));
2675
2676   /* Multiply elements 3 and 1.  */
2677   emit_insn (gen_sse2_umulv2siv2di3 (gen_lowpart (V2DImode, t4), t2, t3));
2678
2679   /* Move the results in element 2 down to element 1; we don't care what
2680      goes in elements 2 and 3.  */
2681   emit_insn (gen_sse2_pshufd_1 (t5, t1, const0_rtx, const2_rtx,
2682                                 const0_rtx, const0_rtx));
2683   emit_insn (gen_sse2_pshufd_1 (t6, t4, const0_rtx, const2_rtx,
2684                                 const0_rtx, const0_rtx));
2685
2686   /* Merge the parts back together.  */
2687   emit_insn (gen_sse2_punpckldq (op0, t5, t6));
2688   DONE;
2689 })
2690
2691 (define_expand "mulv2di3"
2692   [(set (match_operand:V2DI 0 "register_operand" "")
2693         (mult:V2DI (match_operand:V2DI 1 "register_operand" "")
2694                    (match_operand:V2DI 2 "register_operand" "")))]
2695   "TARGET_SSE2"
2696 {
2697   rtx t1, t2, t3, t4, t5, t6, thirtytwo;
2698   rtx op0, op1, op2;
2699
2700   op0 = operands[0];
2701   op1 = operands[1];
2702   op2 = operands[2];
2703   t1 = gen_reg_rtx (V2DImode);
2704   t2 = gen_reg_rtx (V2DImode);
2705   t3 = gen_reg_rtx (V2DImode);
2706   t4 = gen_reg_rtx (V2DImode);
2707   t5 = gen_reg_rtx (V2DImode);
2708   t6 = gen_reg_rtx (V2DImode);
2709   thirtytwo = GEN_INT (32);
2710
2711   /* Multiply low parts.  */
2712   emit_insn (gen_sse2_umulv2siv2di3 (t1, gen_lowpart (V4SImode, op1),
2713                                      gen_lowpart (V4SImode, op2)));
2714
2715   /* Shift input vectors left 32 bits so we can multiply high parts.  */
2716   emit_insn (gen_lshrv2di3 (t2, op1, thirtytwo));
2717   emit_insn (gen_lshrv2di3 (t3, op2, thirtytwo));
2718
2719   /* Multiply high parts by low parts.  */
2720   emit_insn (gen_sse2_umulv2siv2di3 (t4, gen_lowpart (V4SImode, op1),
2721                                      gen_lowpart (V4SImode, t3)));
2722   emit_insn (gen_sse2_umulv2siv2di3 (t5, gen_lowpart (V4SImode, op2),
2723                                      gen_lowpart (V4SImode, t2)));
2724
2725   /* Shift them back.  */
2726   emit_insn (gen_ashlv2di3 (t4, t4, thirtytwo));
2727   emit_insn (gen_ashlv2di3 (t5, t5, thirtytwo));
2728
2729   /* Add the three parts together.  */
2730   emit_insn (gen_addv2di3 (t6, t1, t4));
2731   emit_insn (gen_addv2di3 (op0, t6, t5));
2732   DONE;
2733 })
2734
2735 (define_expand "sdot_prodv8hi"
2736   [(match_operand:V4SI 0 "register_operand" "")
2737    (match_operand:V8HI 1 "nonimmediate_operand" "")
2738    (match_operand:V8HI 2 "nonimmediate_operand" "")
2739    (match_operand:V4SI 3 "register_operand" "")]
2740   "TARGET_SSE2"
2741 {
2742   rtx t = gen_reg_rtx (V4SImode);
2743   emit_insn (gen_sse2_pmaddwd (t, operands[1], operands[2]));
2744   emit_insn (gen_addv4si3 (operands[0], operands[3], t));
2745   DONE;
2746 })
2747
2748 (define_expand "udot_prodv4si"
2749   [(match_operand:V2DI 0 "register_operand" "") 
2750    (match_operand:V4SI 1 "register_operand" "") 
2751    (match_operand:V4SI 2 "register_operand" "")
2752    (match_operand:V2DI 3 "register_operand" "")]
2753   "TARGET_SSE2"
2754 {
2755   rtx t1, t2, t3, t4;
2756
2757   t1 = gen_reg_rtx (V2DImode);
2758   emit_insn (gen_sse2_umulv2siv2di3 (t1, operands[1], operands[2]));
2759   emit_insn (gen_addv2di3 (t1, t1, operands[3]));
2760
2761   t2 = gen_reg_rtx (V4SImode);
2762   t3 = gen_reg_rtx (V4SImode);
2763   emit_insn (gen_sse2_lshrti3 (gen_lowpart (TImode, t2),
2764                                gen_lowpart (TImode, operands[1]),
2765                                GEN_INT (32)));
2766   emit_insn (gen_sse2_lshrti3 (gen_lowpart (TImode, t3),
2767                                gen_lowpart (TImode, operands[2]),
2768                                GEN_INT (32)));
2769
2770   t4 = gen_reg_rtx (V2DImode);
2771   emit_insn (gen_sse2_umulv2siv2di3 (t4, t2, t3));
2772
2773   emit_insn (gen_addv2di3 (operands[0], t1, t4));
2774   DONE;
2775 })
2776
2777 (define_insn "ashr<mode>3"
2778   [(set (match_operand:SSEMODE24 0 "register_operand" "=x")
2779         (ashiftrt:SSEMODE24
2780           (match_operand:SSEMODE24 1 "register_operand" "0")
2781           (match_operand:SI 2 "nonmemory_operand" "xi")))]
2782   "TARGET_SSE2"
2783   "psra<ssevecsize>\t{%2, %0|%0, %2}"
2784   [(set_attr "type" "sseishft")
2785    (set_attr "mode" "TI")])
2786
2787 (define_insn "lshr<mode>3"
2788   [(set (match_operand:SSEMODE248 0 "register_operand" "=x")
2789         (lshiftrt:SSEMODE248
2790           (match_operand:SSEMODE248 1 "register_operand" "0")
2791           (match_operand:SI 2 "nonmemory_operand" "xi")))]
2792   "TARGET_SSE2"
2793   "psrl<ssevecsize>\t{%2, %0|%0, %2}"
2794   [(set_attr "type" "sseishft")
2795    (set_attr "mode" "TI")])
2796
2797 (define_insn "ashl<mode>3"
2798   [(set (match_operand:SSEMODE248 0 "register_operand" "=x")
2799         (ashift:SSEMODE248
2800           (match_operand:SSEMODE248 1 "register_operand" "0")
2801           (match_operand:SI 2 "nonmemory_operand" "xi")))]
2802   "TARGET_SSE2"
2803   "psll<ssevecsize>\t{%2, %0|%0, %2}"
2804   [(set_attr "type" "sseishft")
2805    (set_attr "mode" "TI")])
2806
2807 (define_insn "sse2_ashlti3"
2808   [(set (match_operand:TI 0 "register_operand" "=x")
2809         (ashift:TI (match_operand:TI 1 "register_operand" "0")
2810                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
2811   "TARGET_SSE2"
2812 {
2813   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
2814   return "pslldq\t{%2, %0|%0, %2}";
2815 }
2816   [(set_attr "type" "sseishft")
2817    (set_attr "mode" "TI")])
2818
2819 (define_expand "vec_shl_<mode>"
2820   [(set (match_operand:SSEMODEI 0 "register_operand" "")
2821         (ashift:TI (match_operand:SSEMODEI 1 "register_operand" "")
2822                    (match_operand:SI 2 "general_operand" "")))]
2823   "TARGET_SSE2"
2824 {
2825   if (!const_0_to_255_mul_8_operand (operands[2], SImode))
2826     FAIL;
2827   operands[0] = gen_lowpart (TImode, operands[0]);
2828   operands[1] = gen_lowpart (TImode, operands[1]);
2829 })
2830
2831 (define_insn "sse2_lshrti3"
2832   [(set (match_operand:TI 0 "register_operand" "=x")
2833         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
2834                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
2835   "TARGET_SSE2"
2836 {
2837   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
2838   return "psrldq\t{%2, %0|%0, %2}";
2839 }
2840   [(set_attr "type" "sseishft")
2841    (set_attr "mode" "TI")])
2842
2843 (define_expand "vec_shr_<mode>"
2844   [(set (match_operand:SSEMODEI 0 "register_operand" "")
2845         (lshiftrt:TI (match_operand:SSEMODEI 1 "register_operand" "")
2846                      (match_operand:SI 2 "general_operand" "")))]
2847   "TARGET_SSE2"
2848 {
2849   if (!const_0_to_255_mul_8_operand (operands[2], SImode))
2850     FAIL;
2851   operands[0] = gen_lowpart (TImode, operands[0]);
2852   operands[1] = gen_lowpart (TImode, operands[1]);
2853 })
2854
2855 (define_expand "umaxv16qi3"
2856   [(set (match_operand:V16QI 0 "register_operand" "")
2857         (umax:V16QI (match_operand:V16QI 1 "nonimmediate_operand" "")
2858                     (match_operand:V16QI 2 "nonimmediate_operand" "")))]
2859   "TARGET_SSE2"
2860   "ix86_fixup_binary_operands_no_copy (UMAX, V16QImode, operands);")
2861
2862 (define_insn "*umaxv16qi3"
2863   [(set (match_operand:V16QI 0 "register_operand" "=x")
2864         (umax:V16QI (match_operand:V16QI 1 "nonimmediate_operand" "%0")
2865                     (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
2866   "TARGET_SSE2 && ix86_binary_operator_ok (UMAX, V16QImode, operands)"
2867   "pmaxub\t{%2, %0|%0, %2}"
2868   [(set_attr "type" "sseiadd")
2869    (set_attr "mode" "TI")])
2870
2871 (define_expand "smaxv8hi3"
2872   [(set (match_operand:V8HI 0 "register_operand" "")
2873         (smax:V8HI (match_operand:V8HI 1 "nonimmediate_operand" "")
2874                    (match_operand:V8HI 2 "nonimmediate_operand" "")))]
2875   "TARGET_SSE2"
2876   "ix86_fixup_binary_operands_no_copy (SMAX, V8HImode, operands);")
2877
2878 (define_insn "*smaxv8hi3"
2879   [(set (match_operand:V8HI 0 "register_operand" "=x")
2880         (smax:V8HI (match_operand:V8HI 1 "nonimmediate_operand" "%0")
2881                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
2882   "TARGET_SSE2 && ix86_binary_operator_ok (SMAX, V8HImode, operands)"
2883   "pmaxsw\t{%2, %0|%0, %2}"
2884   [(set_attr "type" "sseiadd")
2885    (set_attr "mode" "TI")])
2886
2887 (define_expand "umaxv8hi3"
2888   [(set (match_operand:V8HI 0 "register_operand" "=x")
2889         (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
2890                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
2891    (set (match_dup 3)
2892         (plus:V8HI (match_dup 0) (match_dup 2)))]
2893   "TARGET_SSE2"
2894 {
2895   operands[3] = operands[0];
2896   if (rtx_equal_p (operands[0], operands[2]))
2897     operands[0] = gen_reg_rtx (V8HImode);
2898 })
2899
2900 (define_expand "smax<mode>3"
2901   [(set (match_operand:SSEMODE14 0 "register_operand" "")
2902         (smax:SSEMODE14 (match_operand:SSEMODE14 1 "register_operand" "")
2903                         (match_operand:SSEMODE14 2 "register_operand" "")))]
2904   "TARGET_SSE2"
2905 {
2906   rtx xops[6];
2907   bool ok;
2908
2909   xops[0] = operands[0];
2910   xops[1] = operands[1];
2911   xops[2] = operands[2];
2912   xops[3] = gen_rtx_GT (VOIDmode, operands[1], operands[2]);
2913   xops[4] = operands[1];
2914   xops[5] = operands[2];
2915   ok = ix86_expand_int_vcond (xops);
2916   gcc_assert (ok);
2917   DONE;
2918 })
2919
2920 (define_expand "umaxv4si3"
2921   [(set (match_operand:V4SI 0 "register_operand" "")
2922         (umax:V4SI (match_operand:V4SI 1 "register_operand" "")
2923                    (match_operand:V4SI 2 "register_operand" "")))]
2924   "TARGET_SSE2"
2925 {
2926   rtx xops[6];
2927   bool ok;
2928
2929   xops[0] = operands[0];
2930   xops[1] = operands[1];
2931   xops[2] = operands[2];
2932   xops[3] = gen_rtx_GTU (VOIDmode, operands[1], operands[2]);
2933   xops[4] = operands[1];
2934   xops[5] = operands[2];
2935   ok = ix86_expand_int_vcond (xops);
2936   gcc_assert (ok);
2937   DONE;
2938 })
2939
2940 (define_expand "uminv16qi3"
2941   [(set (match_operand:V16QI 0 "register_operand" "")
2942         (umin:V16QI (match_operand:V16QI 1 "nonimmediate_operand" "")
2943                     (match_operand:V16QI 2 "nonimmediate_operand" "")))]
2944   "TARGET_SSE2"
2945   "ix86_fixup_binary_operands_no_copy (UMAX, V16QImode, operands);")
2946
2947 (define_insn "*uminv16qi3"
2948   [(set (match_operand:V16QI 0 "register_operand" "=x")
2949         (umin:V16QI (match_operand:V16QI 1 "nonimmediate_operand" "%0")
2950                     (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
2951   "TARGET_SSE2 && ix86_binary_operator_ok (UMIN, V16QImode, operands)"
2952   "pminub\t{%2, %0|%0, %2}"
2953   [(set_attr "type" "sseiadd")
2954    (set_attr "mode" "TI")])
2955
2956 (define_expand "sminv8hi3"
2957   [(set (match_operand:V8HI 0 "register_operand" "")
2958         (smin:V8HI (match_operand:V8HI 1 "nonimmediate_operand" "")
2959                    (match_operand:V8HI 2 "nonimmediate_operand" "")))]
2960   "TARGET_SSE2"
2961   "ix86_fixup_binary_operands_no_copy (SMIN, V8HImode, operands);")
2962
2963 (define_insn "*sminv8hi3"
2964   [(set (match_operand:V8HI 0 "register_operand" "=x")
2965         (smin:V8HI (match_operand:V8HI 1 "nonimmediate_operand" "%0")
2966                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
2967   "TARGET_SSE2 && ix86_binary_operator_ok (SMIN, V8HImode, operands)"
2968   "pminsw\t{%2, %0|%0, %2}"
2969   [(set_attr "type" "sseiadd")
2970    (set_attr "mode" "TI")])
2971
2972 (define_expand "smin<mode>3"
2973   [(set (match_operand:SSEMODE14 0 "register_operand" "")
2974         (smin:SSEMODE14 (match_operand:SSEMODE14 1 "register_operand" "")
2975                         (match_operand:SSEMODE14 2 "register_operand" "")))]
2976   "TARGET_SSE2"
2977 {
2978   rtx xops[6];
2979   bool ok;
2980
2981   xops[0] = operands[0];
2982   xops[1] = operands[2];
2983   xops[2] = operands[1];
2984   xops[3] = gen_rtx_GT (VOIDmode, operands[1], operands[2]);
2985   xops[4] = operands[1];
2986   xops[5] = operands[2];
2987   ok = ix86_expand_int_vcond (xops);
2988   gcc_assert (ok);
2989   DONE;
2990 })
2991
2992 (define_expand "umin<mode>3"
2993   [(set (match_operand:SSEMODE24 0 "register_operand" "")
2994         (umin:SSEMODE24 (match_operand:SSEMODE24 1 "register_operand" "")
2995                         (match_operand:SSEMODE24 2 "register_operand" "")))]
2996   "TARGET_SSE2"
2997 {
2998   rtx xops[6];
2999   bool ok;
3000
3001   xops[0] = operands[0];
3002   xops[1] = operands[2];
3003   xops[2] = operands[1];
3004   xops[3] = gen_rtx_GTU (VOIDmode, operands[1], operands[2]);
3005   xops[4] = operands[1];
3006   xops[5] = operands[2];
3007   ok = ix86_expand_int_vcond (xops);
3008   gcc_assert (ok);
3009   DONE;
3010 })
3011
3012 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3013 ;;
3014 ;; Parallel integral comparisons
3015 ;;
3016 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3017
3018 (define_insn "sse2_eq<mode>3"
3019   [(set (match_operand:SSEMODE124 0 "register_operand" "=x")
3020         (eq:SSEMODE124
3021           (match_operand:SSEMODE124 1 "nonimmediate_operand" "%0")
3022           (match_operand:SSEMODE124 2 "nonimmediate_operand" "xm")))]
3023   "TARGET_SSE2 && ix86_binary_operator_ok (EQ, <MODE>mode, operands)"
3024   "pcmpeq<ssevecsize>\t{%2, %0|%0, %2}"
3025   [(set_attr "type" "ssecmp")
3026    (set_attr "mode" "TI")])
3027
3028 (define_insn "sse2_gt<mode>3"
3029   [(set (match_operand:SSEMODE124 0 "register_operand" "=x")
3030         (gt:SSEMODE124
3031           (match_operand:SSEMODE124 1 "register_operand" "0")
3032           (match_operand:SSEMODE124 2 "nonimmediate_operand" "xm")))]
3033   "TARGET_SSE2"
3034   "pcmpgt<ssevecsize>\t{%2, %0|%0, %2}"
3035   [(set_attr "type" "ssecmp")
3036    (set_attr "mode" "TI")])
3037
3038 (define_expand "vcond<mode>"
3039   [(set (match_operand:SSEMODE124 0 "register_operand" "")
3040         (if_then_else:SSEMODE124
3041           (match_operator 3 ""
3042             [(match_operand:SSEMODE124 4 "nonimmediate_operand" "")
3043              (match_operand:SSEMODE124 5 "nonimmediate_operand" "")])
3044           (match_operand:SSEMODE124 1 "general_operand" "")
3045           (match_operand:SSEMODE124 2 "general_operand" "")))]
3046   "TARGET_SSE2"
3047 {
3048   if (ix86_expand_int_vcond (operands))
3049     DONE;
3050   else
3051     FAIL;
3052 })
3053
3054 (define_expand "vcondu<mode>"
3055   [(set (match_operand:SSEMODE124 0 "register_operand" "")
3056         (if_then_else:SSEMODE124
3057           (match_operator 3 ""
3058             [(match_operand:SSEMODE124 4 "nonimmediate_operand" "")
3059              (match_operand:SSEMODE124 5 "nonimmediate_operand" "")])
3060           (match_operand:SSEMODE124 1 "general_operand" "")
3061           (match_operand:SSEMODE124 2 "general_operand" "")))]
3062   "TARGET_SSE2"
3063 {
3064   if (ix86_expand_int_vcond (operands))
3065     DONE;
3066   else
3067     FAIL;
3068 })
3069
3070 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3071 ;;
3072 ;; Parallel integral logical operations
3073 ;;
3074 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3075
3076 (define_expand "one_cmpl<mode>2"
3077   [(set (match_operand:SSEMODEI 0 "register_operand" "")
3078         (xor:SSEMODEI (match_operand:SSEMODEI 1 "nonimmediate_operand" "")
3079                       (match_dup 2)))]
3080   "TARGET_SSE2"
3081 {
3082   int i, n = GET_MODE_NUNITS (<MODE>mode);
3083   rtvec v = rtvec_alloc (n);
3084
3085   for (i = 0; i < n; ++i)
3086     RTVEC_ELT (v, i) = constm1_rtx;
3087
3088   operands[2] = force_reg (<MODE>mode, gen_rtx_CONST_VECTOR (<MODE>mode, v));
3089 })
3090
3091 (define_expand "and<mode>3"
3092   [(set (match_operand:SSEMODEI 0 "register_operand" "")
3093         (and:SSEMODEI (match_operand:SSEMODEI 1 "nonimmediate_operand" "")
3094                       (match_operand:SSEMODEI 2 "nonimmediate_operand" "")))]
3095   "TARGET_SSE2"
3096   "ix86_fixup_binary_operands_no_copy (AND, <MODE>mode, operands);")
3097
3098 (define_insn "*and<mode>3"
3099   [(set (match_operand:SSEMODEI 0 "register_operand" "=x")
3100         (and:SSEMODEI
3101           (match_operand:SSEMODEI 1 "nonimmediate_operand" "%0")
3102           (match_operand:SSEMODEI 2 "nonimmediate_operand" "xm")))]
3103   "TARGET_SSE2 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
3104   "pand\t{%2, %0|%0, %2}"
3105   [(set_attr "type" "sselog")
3106    (set_attr "mode" "TI")])
3107
3108 (define_insn "sse2_nand<mode>3"
3109   [(set (match_operand:SSEMODEI 0 "register_operand" "=x")
3110         (and:SSEMODEI
3111           (not:SSEMODEI (match_operand:SSEMODEI 1 "register_operand" "0"))
3112           (match_operand:SSEMODEI 2 "nonimmediate_operand" "xm")))]
3113   "TARGET_SSE2"
3114   "pandn\t{%2, %0|%0, %2}"
3115   [(set_attr "type" "sselog")
3116    (set_attr "mode" "TI")])
3117
3118 (define_expand "ior<mode>3"
3119   [(set (match_operand:SSEMODEI 0 "register_operand" "")
3120         (ior:SSEMODEI (match_operand:SSEMODEI 1 "nonimmediate_operand" "")
3121                       (match_operand:SSEMODEI 2 "nonimmediate_operand" "")))]
3122   "TARGET_SSE2"
3123   "ix86_fixup_binary_operands_no_copy (IOR, <MODE>mode, operands);")
3124
3125 (define_insn "*ior<mode>3"
3126   [(set (match_operand:SSEMODEI 0 "register_operand" "=x")
3127         (ior:SSEMODEI
3128           (match_operand:SSEMODEI 1 "nonimmediate_operand" "%0")
3129           (match_operand:SSEMODEI 2 "nonimmediate_operand" "xm")))]
3130   "TARGET_SSE2 && ix86_binary_operator_ok (IOR, <MODE>mode, operands)"
3131   "por\t{%2, %0|%0, %2}"
3132   [(set_attr "type" "sselog")
3133    (set_attr "mode" "TI")])
3134
3135 (define_expand "xor<mode>3"
3136   [(set (match_operand:SSEMODEI 0 "register_operand" "")
3137         (xor:SSEMODEI (match_operand:SSEMODEI 1 "nonimmediate_operand" "")
3138                       (match_operand:SSEMODEI 2 "nonimmediate_operand" "")))]
3139   "TARGET_SSE2"
3140   "ix86_fixup_binary_operands_no_copy (XOR, <MODE>mode, operands);")
3141
3142 (define_insn "*xor<mode>3"
3143   [(set (match_operand:SSEMODEI 0 "register_operand" "=x")
3144         (xor:SSEMODEI
3145           (match_operand:SSEMODEI 1 "nonimmediate_operand" "%0")
3146           (match_operand:SSEMODEI 2 "nonimmediate_operand" "xm")))]
3147   "TARGET_SSE2 && ix86_binary_operator_ok (XOR, <MODE>mode, operands)"
3148   "pxor\t{%2, %0|%0, %2}"
3149   [(set_attr "type" "sselog")
3150    (set_attr "mode" "TI")])
3151
3152 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3153 ;;
3154 ;; Parallel integral element swizzling
3155 ;;
3156 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3157
3158 (define_insn "sse2_packsswb"
3159   [(set (match_operand:V16QI 0 "register_operand" "=x")
3160         (vec_concat:V16QI
3161           (ss_truncate:V8QI
3162             (match_operand:V8HI 1 "register_operand" "0"))
3163           (ss_truncate:V8QI
3164             (match_operand:V8HI 2 "nonimmediate_operand" "xm"))))]
3165   "TARGET_SSE2"
3166   "packsswb\t{%2, %0|%0, %2}"
3167   [(set_attr "type" "sselog")
3168    (set_attr "mode" "TI")])
3169
3170 (define_insn "sse2_packssdw"
3171   [(set (match_operand:V8HI 0 "register_operand" "=x")
3172         (vec_concat:V8HI
3173           (ss_truncate:V4HI
3174             (match_operand:V4SI 1 "register_operand" "0"))
3175           (ss_truncate:V4HI
3176             (match_operand:V4SI 2 "nonimmediate_operand" "xm"))))]
3177   "TARGET_SSE2"
3178   "packssdw\t{%2, %0|%0, %2}"
3179   [(set_attr "type" "sselog")
3180    (set_attr "mode" "TI")])
3181
3182 (define_insn "sse2_packuswb"
3183   [(set (match_operand:V16QI 0 "register_operand" "=x")
3184         (vec_concat:V16QI
3185           (us_truncate:V8QI
3186             (match_operand:V8HI 1 "register_operand" "0"))
3187           (us_truncate:V8QI
3188             (match_operand:V8HI 2 "nonimmediate_operand" "xm"))))]
3189   "TARGET_SSE2"
3190   "packuswb\t{%2, %0|%0, %2}"
3191   [(set_attr "type" "sselog")
3192    (set_attr "mode" "TI")])
3193
3194 (define_insn "sse2_punpckhbw"
3195   [(set (match_operand:V16QI 0 "register_operand" "=x")
3196         (vec_select:V16QI
3197           (vec_concat:V32QI
3198             (match_operand:V16QI 1 "register_operand" "0")
3199             (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
3200           (parallel [(const_int 8)  (const_int 24)
3201                      (const_int 9)  (const_int 25)
3202                      (const_int 10) (const_int 26)
3203                      (const_int 11) (const_int 27)
3204                      (const_int 12) (const_int 28) 
3205                      (const_int 13) (const_int 29)
3206                      (const_int 14) (const_int 30)
3207                      (const_int 15) (const_int 31)])))]
3208   "TARGET_SSE2"
3209   "punpckhbw\t{%2, %0|%0, %2}"
3210   [(set_attr "type" "sselog")
3211    (set_attr "mode" "TI")])
3212
3213 (define_insn "sse2_punpcklbw"
3214   [(set (match_operand:V16QI 0 "register_operand" "=x")
3215         (vec_select:V16QI
3216           (vec_concat:V32QI
3217             (match_operand:V16QI 1 "register_operand" "0")
3218             (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
3219           (parallel [(const_int 0) (const_int 16)
3220                      (const_int 1) (const_int 17)
3221                      (const_int 2) (const_int 18)
3222                      (const_int 3) (const_int 19)
3223                      (const_int 4) (const_int 20)
3224                      (const_int 5) (const_int 21)
3225                      (const_int 6) (const_int 22)
3226                      (const_int 7) (const_int 23)])))]
3227   "TARGET_SSE2"
3228   "punpcklbw\t{%2, %0|%0, %2}"
3229   [(set_attr "type" "sselog")
3230    (set_attr "mode" "TI")])
3231
3232 (define_insn "sse2_punpckhwd"
3233   [(set (match_operand:V8HI 0 "register_operand" "=x")
3234         (vec_select:V8HI
3235           (vec_concat:V16HI
3236             (match_operand:V8HI 1 "register_operand" "0")
3237             (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
3238           (parallel [(const_int 4) (const_int 12)
3239                      (const_int 5) (const_int 13)
3240                      (const_int 6) (const_int 14)
3241                      (const_int 7) (const_int 15)])))]
3242   "TARGET_SSE2"
3243   "punpckhwd\t{%2, %0|%0, %2}"
3244   [(set_attr "type" "sselog")
3245    (set_attr "mode" "TI")])
3246
3247 (define_insn "sse2_punpcklwd"
3248   [(set (match_operand:V8HI 0 "register_operand" "=x")
3249         (vec_select:V8HI
3250           (vec_concat:V16HI
3251             (match_operand:V8HI 1 "register_operand" "0")
3252             (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
3253           (parallel [(const_int 0) (const_int 8)
3254                      (const_int 1) (const_int 9)
3255                      (const_int 2) (const_int 10)
3256                      (const_int 3) (const_int 11)])))]
3257   "TARGET_SSE2"
3258   "punpcklwd\t{%2, %0|%0, %2}"
3259   [(set_attr "type" "sselog")
3260    (set_attr "mode" "TI")])
3261
3262 (define_insn "sse2_punpckhdq"
3263   [(set (match_operand:V4SI 0 "register_operand" "=x")
3264         (vec_select:V4SI
3265           (vec_concat:V8SI
3266             (match_operand:V4SI 1 "register_operand" "0")
3267             (match_operand:V4SI 2 "nonimmediate_operand" "xm"))
3268           (parallel [(const_int 2) (const_int 6)
3269                      (const_int 3) (const_int 7)])))]
3270   "TARGET_SSE2"
3271   "punpckhdq\t{%2, %0|%0, %2}"
3272   [(set_attr "type" "sselog")
3273    (set_attr "mode" "TI")])
3274
3275 (define_insn "sse2_punpckldq"
3276   [(set (match_operand:V4SI 0 "register_operand" "=x")
3277         (vec_select:V4SI
3278           (vec_concat:V8SI
3279             (match_operand:V4SI 1 "register_operand" "0")
3280             (match_operand:V4SI 2 "nonimmediate_operand" "xm"))
3281           (parallel [(const_int 0) (const_int 4)
3282                      (const_int 1) (const_int 5)])))]
3283   "TARGET_SSE2"
3284   "punpckldq\t{%2, %0|%0, %2}"
3285   [(set_attr "type" "sselog")
3286    (set_attr "mode" "TI")])
3287
3288 (define_insn "sse2_punpckhqdq"
3289   [(set (match_operand:V2DI 0 "register_operand" "=x")
3290         (vec_select:V2DI
3291           (vec_concat:V4DI
3292             (match_operand:V2DI 1 "register_operand" "0")
3293             (match_operand:V2DI 2 "nonimmediate_operand" "xm"))
3294           (parallel [(const_int 1)
3295                      (const_int 3)])))]
3296   "TARGET_SSE2"
3297   "punpckhqdq\t{%2, %0|%0, %2}"
3298   [(set_attr "type" "sselog")
3299    (set_attr "mode" "TI")])
3300
3301 (define_insn "sse2_punpcklqdq"
3302   [(set (match_operand:V2DI 0 "register_operand" "=x")
3303         (vec_select:V2DI
3304           (vec_concat:V4DI
3305             (match_operand:V2DI 1 "register_operand" "0")
3306             (match_operand:V2DI 2 "nonimmediate_operand" "xm"))
3307           (parallel [(const_int 0)
3308                      (const_int 2)])))]
3309   "TARGET_SSE2"
3310   "punpcklqdq\t{%2, %0|%0, %2}"
3311   [(set_attr "type" "sselog")
3312    (set_attr "mode" "TI")])
3313
3314 (define_expand "sse2_pinsrw"
3315   [(set (match_operand:V8HI 0 "register_operand" "")
3316         (vec_merge:V8HI
3317           (vec_duplicate:V8HI
3318             (match_operand:SI 2 "nonimmediate_operand" ""))
3319           (match_operand:V8HI 1 "register_operand" "")
3320           (match_operand:SI 3 "const_0_to_7_operand" "")))]
3321   "TARGET_SSE2"
3322 {
3323   operands[2] = gen_lowpart (HImode, operands[2]);
3324   operands[3] = GEN_INT ((1 << INTVAL (operands[3])));
3325 })
3326
3327 (define_insn "*sse2_pinsrw"
3328   [(set (match_operand:V8HI 0 "register_operand" "=x")
3329         (vec_merge:V8HI
3330           (vec_duplicate:V8HI
3331             (match_operand:HI 2 "nonimmediate_operand" "rm"))
3332           (match_operand:V8HI 1 "register_operand" "0")
3333           (match_operand:SI 3 "const_pow2_1_to_128_operand" "n")))]
3334   "TARGET_SSE2"
3335 {
3336   operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
3337   return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}";
3338 }
3339   [(set_attr "type" "sselog")
3340    (set_attr "mode" "TI")])
3341
3342 (define_insn "sse2_pextrw"
3343   [(set (match_operand:SI 0 "register_operand" "=r")
3344         (zero_extend:SI
3345           (vec_select:HI
3346             (match_operand:V8HI 1 "register_operand" "x")
3347             (parallel [(match_operand:SI 2 "const_0_to_7_operand" "n")]))))]
3348   "TARGET_SSE2"
3349   "pextrw\t{%2, %1, %0|%0, %1, %2}"
3350   [(set_attr "type" "sselog")
3351    (set_attr "mode" "TI")])
3352
3353 (define_expand "sse2_pshufd"
3354   [(match_operand:V4SI 0 "register_operand" "")
3355    (match_operand:V4SI 1 "nonimmediate_operand" "")
3356    (match_operand:SI 2 "const_int_operand" "")]
3357   "TARGET_SSE2"
3358 {
3359   int mask = INTVAL (operands[2]);
3360   emit_insn (gen_sse2_pshufd_1 (operands[0], operands[1],
3361                                 GEN_INT ((mask >> 0) & 3),
3362                                 GEN_INT ((mask >> 2) & 3),
3363                                 GEN_INT ((mask >> 4) & 3),
3364                                 GEN_INT ((mask >> 6) & 3)));
3365   DONE;
3366 })
3367
3368 (define_insn "sse2_pshufd_1"
3369   [(set (match_operand:V4SI 0 "register_operand" "=x")
3370         (vec_select:V4SI
3371           (match_operand:V4SI 1 "nonimmediate_operand" "xm")
3372           (parallel [(match_operand 2 "const_0_to_3_operand" "")
3373                      (match_operand 3 "const_0_to_3_operand" "")
3374                      (match_operand 4 "const_0_to_3_operand" "")
3375                      (match_operand 5 "const_0_to_3_operand" "")])))]
3376   "TARGET_SSE2"
3377 {
3378   int mask = 0;
3379   mask |= INTVAL (operands[2]) << 0;
3380   mask |= INTVAL (operands[3]) << 2;
3381   mask |= INTVAL (operands[4]) << 4;
3382   mask |= INTVAL (operands[5]) << 6;
3383   operands[2] = GEN_INT (mask);
3384
3385   return "pshufd\t{%2, %1, %0|%0, %1, %2}";
3386 }
3387   [(set_attr "type" "sselog1")
3388    (set_attr "mode" "TI")])
3389
3390 (define_expand "sse2_pshuflw"
3391   [(match_operand:V8HI 0 "register_operand" "")
3392    (match_operand:V8HI 1 "nonimmediate_operand" "")
3393    (match_operand:SI 2 "const_int_operand" "")]
3394   "TARGET_SSE2"
3395 {
3396   int mask = INTVAL (operands[2]);
3397   emit_insn (gen_sse2_pshuflw_1 (operands[0], operands[1],
3398                                  GEN_INT ((mask >> 0) & 3),
3399                                  GEN_INT ((mask >> 2) & 3),
3400                                  GEN_INT ((mask >> 4) & 3),
3401                                  GEN_INT ((mask >> 6) & 3)));
3402   DONE;
3403 })
3404
3405 (define_insn "sse2_pshuflw_1"
3406   [(set (match_operand:V8HI 0 "register_operand" "=x")
3407         (vec_select:V8HI
3408           (match_operand:V8HI 1 "nonimmediate_operand" "xm")
3409           (parallel [(match_operand 2 "const_0_to_3_operand" "")
3410                      (match_operand 3 "const_0_to_3_operand" "")
3411                      (match_operand 4 "const_0_to_3_operand" "")
3412                      (match_operand 5 "const_0_to_3_operand" "")
3413                      (const_int 4)
3414                      (const_int 5)
3415                      (const_int 6)
3416                      (const_int 7)])))]
3417   "TARGET_SSE2"
3418 {
3419   int mask = 0;
3420   mask |= INTVAL (operands[2]) << 0;