OSDN Git Service

PR target/30041
[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_maskcmpsf3"
737   [(set (match_operand:SF 0 "register_operand" "=x")
738         (match_operator:SF 3 "sse_comparison_operator"
739                 [(match_operand:SF 1 "register_operand" "0")
740                  (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
741   "TARGET_SSE"
742   "cmp%D3ss\t{%2, %0|%0, %2}"
743   [(set_attr "type" "ssecmp")
744    (set_attr "mode" "SF")])
745
746 (define_insn "sse_vmmaskcmpv4sf3"
747   [(set (match_operand:V4SF 0 "register_operand" "=x")
748         (vec_merge:V4SF
749          (match_operator:V4SF 3 "sse_comparison_operator"
750                 [(match_operand:V4SF 1 "register_operand" "0")
751                  (match_operand:V4SF 2 "register_operand" "x")])
752          (match_dup 1)
753          (const_int 1)))]
754   "TARGET_SSE"
755   "cmp%D3ss\t{%2, %0|%0, %2}"
756   [(set_attr "type" "ssecmp")
757    (set_attr "mode" "SF")])
758
759 (define_insn "sse_comi"
760   [(set (reg:CCFP FLAGS_REG)
761         (compare:CCFP
762           (vec_select:SF
763             (match_operand:V4SF 0 "register_operand" "x")
764             (parallel [(const_int 0)]))
765           (vec_select:SF
766             (match_operand:V4SF 1 "nonimmediate_operand" "xm")
767             (parallel [(const_int 0)]))))]
768   "TARGET_SSE"
769   "comiss\t{%1, %0|%0, %1}"
770   [(set_attr "type" "ssecomi")
771    (set_attr "mode" "SF")])
772
773 (define_insn "sse_ucomi"
774   [(set (reg:CCFPU FLAGS_REG)
775         (compare:CCFPU
776           (vec_select:SF
777             (match_operand:V4SF 0 "register_operand" "x")
778             (parallel [(const_int 0)]))
779           (vec_select:SF
780             (match_operand:V4SF 1 "nonimmediate_operand" "xm")
781             (parallel [(const_int 0)]))))]
782   "TARGET_SSE"
783   "ucomiss\t{%1, %0|%0, %1}"
784   [(set_attr "type" "ssecomi")
785    (set_attr "mode" "SF")])
786
787 (define_expand "vcondv4sf"
788   [(set (match_operand:V4SF 0 "register_operand" "")
789         (if_then_else:V4SF
790           (match_operator 3 ""
791             [(match_operand:V4SF 4 "nonimmediate_operand" "")
792              (match_operand:V4SF 5 "nonimmediate_operand" "")])
793           (match_operand:V4SF 1 "general_operand" "")
794           (match_operand:V4SF 2 "general_operand" "")))]
795   "TARGET_SSE"
796 {
797   if (ix86_expand_fp_vcond (operands))
798     DONE;
799   else
800     FAIL;
801 })
802
803 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
804 ;;
805 ;; Parallel single-precision floating point logical operations
806 ;;
807 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
808
809 (define_expand "andv4sf3"
810   [(set (match_operand:V4SF 0 "register_operand" "")
811         (and:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "")
812                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
813   "TARGET_SSE"
814   "ix86_fixup_binary_operands_no_copy (AND, V4SFmode, operands);")
815
816 (define_insn "*andv4sf3"
817   [(set (match_operand:V4SF 0 "register_operand" "=x")
818         (and:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
819                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
820   "TARGET_SSE && ix86_binary_operator_ok (AND, V4SFmode, operands)"
821   "andps\t{%2, %0|%0, %2}"
822   [(set_attr "type" "sselog")
823    (set_attr "mode" "V4SF")])
824
825 (define_insn "sse_nandv4sf3"
826   [(set (match_operand:V4SF 0 "register_operand" "=x")
827         (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" "0"))
828                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
829   "TARGET_SSE"
830   "andnps\t{%2, %0|%0, %2}"
831   [(set_attr "type" "sselog")
832    (set_attr "mode" "V4SF")])
833
834 (define_expand "iorv4sf3"
835   [(set (match_operand:V4SF 0 "register_operand" "")
836         (ior:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "")
837                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
838   "TARGET_SSE"
839   "ix86_fixup_binary_operands_no_copy (IOR, V4SFmode, operands);")
840
841 (define_insn "*iorv4sf3"
842   [(set (match_operand:V4SF 0 "register_operand" "=x")
843         (ior:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
844                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
845   "TARGET_SSE && ix86_binary_operator_ok (IOR, V4SFmode, operands)"
846   "orps\t{%2, %0|%0, %2}"
847   [(set_attr "type" "sselog")
848    (set_attr "mode" "V4SF")])
849
850 (define_expand "xorv4sf3"
851   [(set (match_operand:V4SF 0 "register_operand" "")
852         (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "")
853                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
854   "TARGET_SSE"
855   "ix86_fixup_binary_operands_no_copy (XOR, V4SFmode, operands);")
856
857 (define_insn "*xorv4sf3"
858   [(set (match_operand:V4SF 0 "register_operand" "=x")
859         (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
860                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
861   "TARGET_SSE && ix86_binary_operator_ok (XOR, V4SFmode, operands)"
862   "xorps\t{%2, %0|%0, %2}"
863   [(set_attr "type" "sselog")
864    (set_attr "mode" "V4SF")])
865
866 ;; Also define scalar versions.  These are used for abs, neg, and
867 ;; conditional move.  Using subregs into vector modes causes register
868 ;; allocation lossage.  These patterns do not allow memory operands
869 ;; because the native instructions read the full 128-bits.
870
871 (define_insn "*andsf3"
872   [(set (match_operand:SF 0 "register_operand" "=x")
873         (and:SF (match_operand:SF 1 "register_operand" "0")
874                 (match_operand:SF 2 "register_operand" "x")))]
875   "TARGET_SSE"
876   "andps\t{%2, %0|%0, %2}"
877   [(set_attr "type" "sselog")
878    (set_attr "mode" "V4SF")])
879
880 (define_insn "*nandsf3"
881   [(set (match_operand:SF 0 "register_operand" "=x")
882         (and:SF (not:SF (match_operand:SF 1 "register_operand" "0"))
883                 (match_operand:SF 2 "register_operand" "x")))]
884   "TARGET_SSE"
885   "andnps\t{%2, %0|%0, %2}"
886   [(set_attr "type" "sselog")
887    (set_attr "mode" "V4SF")])
888
889 (define_insn "*iorsf3"
890   [(set (match_operand:SF 0 "register_operand" "=x")
891         (ior:SF (match_operand:SF 1 "register_operand" "0")
892                 (match_operand:SF 2 "register_operand" "x")))]
893   "TARGET_SSE"
894   "orps\t{%2, %0|%0, %2}"
895   [(set_attr "type" "sselog")
896    (set_attr "mode" "V4SF")])
897
898 (define_insn "*xorsf3"
899   [(set (match_operand:SF 0 "register_operand" "=x")
900         (xor:SF (match_operand:SF 1 "register_operand" "0")
901                 (match_operand:SF 2 "register_operand" "x")))]
902   "TARGET_SSE"
903   "xorps\t{%2, %0|%0, %2}"
904   [(set_attr "type" "sselog")
905    (set_attr "mode" "V4SF")])
906
907 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
908 ;;
909 ;; Parallel single-precision floating point conversion operations
910 ;;
911 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
912
913 (define_insn "sse_cvtpi2ps"
914   [(set (match_operand:V4SF 0 "register_operand" "=x")
915         (vec_merge:V4SF
916           (vec_duplicate:V4SF
917             (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
918           (match_operand:V4SF 1 "register_operand" "0")
919           (const_int 3)))]
920   "TARGET_SSE"
921   "cvtpi2ps\t{%2, %0|%0, %2}"
922   [(set_attr "type" "ssecvt")
923    (set_attr "mode" "V4SF")])
924
925 (define_insn "sse_cvtps2pi"
926   [(set (match_operand:V2SI 0 "register_operand" "=y")
927         (vec_select:V2SI
928           (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
929                        UNSPEC_FIX_NOTRUNC)
930           (parallel [(const_int 0) (const_int 1)])))]
931   "TARGET_SSE"
932   "cvtps2pi\t{%1, %0|%0, %1}"
933   [(set_attr "type" "ssecvt")
934    (set_attr "unit" "mmx")
935    (set_attr "mode" "DI")])
936
937 (define_insn "sse_cvttps2pi"
938   [(set (match_operand:V2SI 0 "register_operand" "=y")
939         (vec_select:V2SI
940           (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
941           (parallel [(const_int 0) (const_int 1)])))]
942   "TARGET_SSE"
943   "cvttps2pi\t{%1, %0|%0, %1}"
944   [(set_attr "type" "ssecvt")
945    (set_attr "unit" "mmx")
946    (set_attr "mode" "SF")])
947
948 (define_insn "sse_cvtsi2ss"
949   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
950         (vec_merge:V4SF
951           (vec_duplicate:V4SF
952             (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,m")))
953           (match_operand:V4SF 1 "register_operand" "0,0")
954           (const_int 1)))]
955   "TARGET_SSE"
956   "cvtsi2ss\t{%2, %0|%0, %2}"
957   [(set_attr "type" "sseicvt")
958    (set_attr "athlon_decode" "vector,double")
959    (set_attr "mode" "SF")])
960
961 (define_insn "sse_cvtsi2ssq"
962   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
963         (vec_merge:V4SF
964           (vec_duplicate:V4SF
965             (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
966           (match_operand:V4SF 1 "register_operand" "0,0")
967           (const_int 1)))]
968   "TARGET_SSE && TARGET_64BIT"
969   "cvtsi2ssq\t{%2, %0|%0, %2}"
970   [(set_attr "type" "sseicvt")
971    (set_attr "athlon_decode" "vector,double")
972    (set_attr "mode" "SF")])
973
974 (define_insn "sse_cvtss2si"
975   [(set (match_operand:SI 0 "register_operand" "=r,r")
976         (unspec:SI
977           [(vec_select:SF
978              (match_operand:V4SF 1 "nonimmediate_operand" "x,m")
979              (parallel [(const_int 0)]))]
980           UNSPEC_FIX_NOTRUNC))]
981   "TARGET_SSE"
982   "cvtss2si\t{%1, %0|%0, %1}"
983   [(set_attr "type" "sseicvt")
984    (set_attr "athlon_decode" "double,vector")
985    (set_attr "mode" "SI")])
986
987 (define_insn "sse_cvtss2si_2"
988   [(set (match_operand:SI 0 "register_operand" "=r,r")
989         (unspec:SI [(match_operand:SF 1 "nonimmediate_operand" "x,m")]
990          UNSPEC_FIX_NOTRUNC))]
991   "TARGET_SSE"
992   "cvtss2si\t{%1, %0|%0, %1}"
993   [(set_attr "type" "sseicvt")
994    (set_attr "athlon_decode" "double,vector")
995    (set_attr "mode" "SI")])
996
997 (define_insn "sse_cvtss2siq"
998   [(set (match_operand:DI 0 "register_operand" "=r,r")
999         (unspec:DI
1000           [(vec_select:SF
1001              (match_operand:V4SF 1 "nonimmediate_operand" "x,m")
1002              (parallel [(const_int 0)]))]
1003           UNSPEC_FIX_NOTRUNC))]
1004   "TARGET_SSE && TARGET_64BIT"
1005   "cvtss2siq\t{%1, %0|%0, %1}"
1006   [(set_attr "type" "sseicvt")
1007    (set_attr "athlon_decode" "double,vector")
1008    (set_attr "mode" "DI")])
1009
1010 (define_insn "sse_cvtss2siq_2"
1011   [(set (match_operand:DI 0 "register_operand" "=r,r")
1012         (unspec:DI [(match_operand:SF 1 "nonimmediate_operand" "x,m")]
1013          UNSPEC_FIX_NOTRUNC))]
1014   "TARGET_SSE && TARGET_64BIT"
1015   "cvtss2siq\t{%1, %0|%0, %1}"
1016   [(set_attr "type" "sseicvt")
1017    (set_attr "athlon_decode" "double,vector")
1018    (set_attr "mode" "DI")])
1019
1020 (define_insn "sse_cvttss2si"
1021   [(set (match_operand:SI 0 "register_operand" "=r,r")
1022         (fix:SI
1023           (vec_select:SF
1024             (match_operand:V4SF 1 "nonimmediate_operand" "x,m")
1025             (parallel [(const_int 0)]))))]
1026   "TARGET_SSE"
1027   "cvttss2si\t{%1, %0|%0, %1}"
1028   [(set_attr "type" "sseicvt")
1029    (set_attr "athlon_decode" "double,vector")
1030    (set_attr "mode" "SI")])
1031
1032 (define_insn "sse_cvttss2siq"
1033   [(set (match_operand:DI 0 "register_operand" "=r,r")
1034         (fix:DI
1035           (vec_select:SF
1036             (match_operand:V4SF 1 "nonimmediate_operand" "x,m")
1037             (parallel [(const_int 0)]))))]
1038   "TARGET_SSE && TARGET_64BIT"
1039   "cvttss2siq\t{%1, %0|%0, %1}"
1040   [(set_attr "type" "sseicvt")
1041    (set_attr "athlon_decode" "double,vector")
1042    (set_attr "mode" "DI")])
1043
1044 (define_insn "sse2_cvtdq2ps"
1045   [(set (match_operand:V4SF 0 "register_operand" "=x")
1046         (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
1047   "TARGET_SSE2"
1048   "cvtdq2ps\t{%1, %0|%0, %1}"
1049   [(set_attr "type" "ssecvt")
1050    (set_attr "mode" "V2DF")])
1051
1052 (define_insn "sse2_cvtps2dq"
1053   [(set (match_operand:V4SI 0 "register_operand" "=x")
1054         (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
1055                      UNSPEC_FIX_NOTRUNC))]
1056   "TARGET_SSE2"
1057   "cvtps2dq\t{%1, %0|%0, %1}"
1058   [(set_attr "type" "ssecvt")
1059    (set_attr "mode" "TI")])
1060
1061 (define_insn "sse2_cvttps2dq"
1062   [(set (match_operand:V4SI 0 "register_operand" "=x")
1063         (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
1064   "TARGET_SSE2"
1065   "cvttps2dq\t{%1, %0|%0, %1}"
1066   [(set_attr "type" "ssecvt")
1067    (set_attr "mode" "TI")])
1068
1069 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1070 ;;
1071 ;; Parallel single-precision floating point element swizzling
1072 ;;
1073 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1074
1075 (define_insn "sse_movhlps"
1076   [(set (match_operand:V4SF 0 "nonimmediate_operand"     "=x,x,m")
1077         (vec_select:V4SF
1078           (vec_concat:V8SF
1079             (match_operand:V4SF 1 "nonimmediate_operand" " 0,0,0")
1080             (match_operand:V4SF 2 "nonimmediate_operand" " x,o,x"))
1081           (parallel [(const_int 6)
1082                      (const_int 7)
1083                      (const_int 2)
1084                      (const_int 3)])))]
1085   "TARGET_SSE && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
1086   "@
1087    movhlps\t{%2, %0|%0, %2}
1088    movlps\t{%H2, %0|%0, %H2}
1089    movhps\t{%2, %0|%0, %2}"
1090   [(set_attr "type" "ssemov")
1091    (set_attr "mode" "V4SF,V2SF,V2SF")])
1092
1093 (define_insn "sse_movlhps"
1094   [(set (match_operand:V4SF 0 "nonimmediate_operand"     "=x,x,o")
1095         (vec_select:V4SF
1096           (vec_concat:V8SF
1097             (match_operand:V4SF 1 "nonimmediate_operand" " 0,0,0")
1098             (match_operand:V4SF 2 "nonimmediate_operand" " x,m,x"))
1099           (parallel [(const_int 0)
1100                      (const_int 1)
1101                      (const_int 4)
1102                      (const_int 5)])))]
1103   "TARGET_SSE && ix86_binary_operator_ok (UNKNOWN, V4SFmode, operands)"
1104   "@
1105    movlhps\t{%2, %0|%0, %2}
1106    movhps\t{%2, %0|%0, %2}
1107    movlps\t{%2, %H0|%H0, %2}"
1108   [(set_attr "type" "ssemov")
1109    (set_attr "mode" "V4SF,V2SF,V2SF")])
1110
1111 (define_insn "sse_unpckhps"
1112   [(set (match_operand:V4SF 0 "register_operand" "=x")
1113         (vec_select:V4SF
1114           (vec_concat:V8SF
1115             (match_operand:V4SF 1 "register_operand" "0")
1116             (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
1117           (parallel [(const_int 2) (const_int 6)
1118                      (const_int 3) (const_int 7)])))]
1119   "TARGET_SSE"
1120   "unpckhps\t{%2, %0|%0, %2}"
1121   [(set_attr "type" "sselog")
1122    (set_attr "mode" "V4SF")])
1123
1124 (define_insn "sse_unpcklps"
1125   [(set (match_operand:V4SF 0 "register_operand" "=x")
1126         (vec_select:V4SF
1127           (vec_concat:V8SF
1128             (match_operand:V4SF 1 "register_operand" "0")
1129             (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
1130           (parallel [(const_int 0) (const_int 4)
1131                      (const_int 1) (const_int 5)])))]
1132   "TARGET_SSE"
1133   "unpcklps\t{%2, %0|%0, %2}"
1134   [(set_attr "type" "sselog")
1135    (set_attr "mode" "V4SF")])
1136
1137 ;; These are modeled with the same vec_concat as the others so that we
1138 ;; capture users of shufps that can use the new instructions
1139 (define_insn "sse3_movshdup"
1140   [(set (match_operand:V4SF 0 "register_operand" "=x")
1141         (vec_select:V4SF
1142           (vec_concat:V8SF
1143             (match_operand:V4SF 1 "nonimmediate_operand" "xm")
1144             (match_dup 1))
1145           (parallel [(const_int 1)
1146                      (const_int 1)
1147                      (const_int 7)
1148                      (const_int 7)])))]
1149   "TARGET_SSE3"
1150   "movshdup\t{%1, %0|%0, %1}"
1151   [(set_attr "type" "sse")
1152    (set_attr "mode" "V4SF")])
1153
1154 (define_insn "sse3_movsldup"
1155   [(set (match_operand:V4SF 0 "register_operand" "=x")
1156         (vec_select:V4SF
1157           (vec_concat:V8SF
1158             (match_operand:V4SF 1 "nonimmediate_operand" "xm")
1159             (match_dup 1))
1160           (parallel [(const_int 0)
1161                      (const_int 0)
1162                      (const_int 6)
1163                      (const_int 6)])))]
1164   "TARGET_SSE3"
1165   "movsldup\t{%1, %0|%0, %1}"
1166   [(set_attr "type" "sse")
1167    (set_attr "mode" "V4SF")])
1168
1169 (define_expand "sse_shufps"
1170   [(match_operand:V4SF 0 "register_operand" "")
1171    (match_operand:V4SF 1 "register_operand" "")
1172    (match_operand:V4SF 2 "nonimmediate_operand" "")
1173    (match_operand:SI 3 "const_int_operand" "")]
1174   "TARGET_SSE"
1175 {
1176   int mask = INTVAL (operands[3]);
1177   emit_insn (gen_sse_shufps_1 (operands[0], operands[1], operands[2],
1178                                GEN_INT ((mask >> 0) & 3),
1179                                GEN_INT ((mask >> 2) & 3),
1180                                GEN_INT (((mask >> 4) & 3) + 4),
1181                                GEN_INT (((mask >> 6) & 3) + 4)));
1182   DONE;
1183 })
1184
1185 (define_insn "sse_shufps_1"
1186   [(set (match_operand:V4SF 0 "register_operand" "=x")
1187         (vec_select:V4SF
1188           (vec_concat:V8SF
1189             (match_operand:V4SF 1 "register_operand" "0")
1190             (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
1191           (parallel [(match_operand 3 "const_0_to_3_operand" "")
1192                      (match_operand 4 "const_0_to_3_operand" "")
1193                      (match_operand 5 "const_4_to_7_operand" "")
1194                      (match_operand 6 "const_4_to_7_operand" "")])))]
1195   "TARGET_SSE"
1196 {
1197   int mask = 0;
1198   mask |= INTVAL (operands[3]) << 0;
1199   mask |= INTVAL (operands[4]) << 2;
1200   mask |= (INTVAL (operands[5]) - 4) << 4;
1201   mask |= (INTVAL (operands[6]) - 4) << 6;
1202   operands[3] = GEN_INT (mask);
1203
1204   return "shufps\t{%3, %2, %0|%0, %2, %3}";
1205 }
1206   [(set_attr "type" "sselog")
1207    (set_attr "mode" "V4SF")])
1208
1209 (define_insn "sse_storehps"
1210   [(set (match_operand:V2SF 0 "nonimmediate_operand" "=m,x,x")
1211         (vec_select:V2SF
1212           (match_operand:V4SF 1 "nonimmediate_operand" "x,x,o")
1213           (parallel [(const_int 2) (const_int 3)])))]
1214   "TARGET_SSE"
1215   "@
1216    movhps\t{%1, %0|%0, %1}
1217    movhlps\t{%1, %0|%0, %1}
1218    movlps\t{%H1, %0|%0, %H1}"
1219   [(set_attr "type" "ssemov")
1220    (set_attr "mode" "V2SF,V4SF,V2SF")])
1221
1222 (define_insn "sse_loadhps"
1223   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,o")
1224         (vec_concat:V4SF
1225           (vec_select:V2SF
1226             (match_operand:V4SF 1 "nonimmediate_operand" "0,0,0")
1227             (parallel [(const_int 0) (const_int 1)]))
1228           (match_operand:V2SF 2 "nonimmediate_operand" "m,x,x")))]
1229   "TARGET_SSE"
1230   "@
1231    movhps\t{%2, %0|%0, %2}
1232    movlhps\t{%2, %0|%0, %2}
1233    movlps\t{%2, %H0|%H0, %2}"
1234   [(set_attr "type" "ssemov")
1235    (set_attr "mode" "V2SF,V4SF,V2SF")])
1236
1237 (define_insn "sse_storelps"
1238   [(set (match_operand:V2SF 0 "nonimmediate_operand" "=m,x,x")
1239         (vec_select:V2SF
1240           (match_operand:V4SF 1 "nonimmediate_operand" "x,x,m")
1241           (parallel [(const_int 0) (const_int 1)])))]
1242   "TARGET_SSE"
1243   "@
1244    movlps\t{%1, %0|%0, %1}
1245    movaps\t{%1, %0|%0, %1}
1246    movlps\t{%1, %0|%0, %1}"
1247   [(set_attr "type" "ssemov")
1248    (set_attr "mode" "V2SF,V4SF,V2SF")])
1249
1250 (define_insn "sse_loadlps"
1251   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
1252         (vec_concat:V4SF
1253           (match_operand:V2SF 2 "nonimmediate_operand" "0,m,x")
1254           (vec_select:V2SF
1255             (match_operand:V4SF 1 "nonimmediate_operand" "x,0,0")
1256             (parallel [(const_int 2) (const_int 3)]))))]
1257   "TARGET_SSE"
1258   "@
1259    shufps\t{$0xe4, %1, %0|%0, %1, 0xe4}
1260    movlps\t{%2, %0|%0, %2}
1261    movlps\t{%2, %0|%0, %2}"
1262   [(set_attr "type" "sselog,ssemov,ssemov")
1263    (set_attr "mode" "V4SF,V2SF,V2SF")])
1264
1265 (define_insn "sse_movss"
1266   [(set (match_operand:V4SF 0 "register_operand" "=x")
1267         (vec_merge:V4SF
1268           (match_operand:V4SF 2 "register_operand" "x")
1269           (match_operand:V4SF 1 "register_operand" "0")
1270           (const_int 1)))]
1271   "TARGET_SSE"
1272   "movss\t{%2, %0|%0, %2}"
1273   [(set_attr "type" "ssemov")
1274    (set_attr "mode" "SF")])
1275
1276 (define_insn "*vec_dupv4sf"
1277   [(set (match_operand:V4SF 0 "register_operand" "=x")
1278         (vec_duplicate:V4SF
1279           (match_operand:SF 1 "register_operand" "0")))]
1280   "TARGET_SSE"
1281   "shufps\t{$0, %0, %0|%0, %0, 0}"
1282   [(set_attr "type" "sselog1")
1283    (set_attr "mode" "V4SF")])
1284
1285 ;; ??? In theory we can match memory for the MMX alternative, but allowing
1286 ;; nonimmediate_operand for operand 2 and *not* allowing memory for the SSE
1287 ;; alternatives pretty much forces the MMX alternative to be chosen.
1288 (define_insn "*sse_concatv2sf"
1289   [(set (match_operand:V2SF 0 "register_operand"     "=x,x,*y,*y")
1290         (vec_concat:V2SF
1291           (match_operand:SF 1 "nonimmediate_operand" " 0,m, 0, m")
1292           (match_operand:SF 2 "reg_or_0_operand"     " x,C,*y, C")))]
1293   "TARGET_SSE"
1294   "@
1295    unpcklps\t{%2, %0|%0, %2}
1296    movss\t{%1, %0|%0, %1}
1297    punpckldq\t{%2, %0|%0, %2}
1298    movd\t{%1, %0|%0, %1}"
1299   [(set_attr "type" "sselog,ssemov,mmxcvt,mmxmov")
1300    (set_attr "mode" "V4SF,SF,DI,DI")])
1301
1302 (define_insn "*sse_concatv4sf"
1303   [(set (match_operand:V4SF 0 "register_operand"   "=x,x")
1304         (vec_concat:V4SF
1305           (match_operand:V2SF 1 "register_operand" " 0,0")
1306           (match_operand:V2SF 2 "nonimmediate_operand" " x,m")))]
1307   "TARGET_SSE"
1308   "@
1309    movlhps\t{%2, %0|%0, %2}
1310    movhps\t{%2, %0|%0, %2}"
1311   [(set_attr "type" "ssemov")
1312    (set_attr "mode" "V4SF,V2SF")])
1313
1314 (define_expand "vec_initv4sf"
1315   [(match_operand:V4SF 0 "register_operand" "")
1316    (match_operand 1 "" "")]
1317   "TARGET_SSE"
1318 {
1319   ix86_expand_vector_init (false, operands[0], operands[1]);
1320   DONE;
1321 })
1322
1323 (define_insn "*vec_setv4sf_0"
1324   [(set (match_operand:V4SF 0 "nonimmediate_operand"  "=x,x,Y ,m")
1325         (vec_merge:V4SF
1326           (vec_duplicate:V4SF
1327             (match_operand:SF 2 "general_operand"     " x,m,*r,x*rfF"))
1328           (match_operand:V4SF 1 "vector_move_operand" " 0,C,C ,0")
1329           (const_int 1)))]
1330   "TARGET_SSE"
1331   "@
1332    movss\t{%2, %0|%0, %2}
1333    movss\t{%2, %0|%0, %2}
1334    movd\t{%2, %0|%0, %2}
1335    #"
1336   [(set_attr "type" "ssemov")
1337    (set_attr "mode" "SF")])
1338
1339 (define_split
1340   [(set (match_operand:V4SF 0 "memory_operand" "")
1341         (vec_merge:V4SF
1342           (vec_duplicate:V4SF
1343             (match_operand:SF 1 "nonmemory_operand" ""))
1344           (match_dup 0)
1345           (const_int 1)))]
1346   "TARGET_SSE && reload_completed"
1347   [(const_int 0)]
1348 {
1349   emit_move_insn (adjust_address (operands[0], SFmode, 0), operands[1]);
1350   DONE;
1351 })
1352
1353 (define_expand "vec_setv4sf"
1354   [(match_operand:V4SF 0 "register_operand" "")
1355    (match_operand:SF 1 "register_operand" "")
1356    (match_operand 2 "const_int_operand" "")]
1357   "TARGET_SSE"
1358 {
1359   ix86_expand_vector_set (false, operands[0], operands[1],
1360                           INTVAL (operands[2]));
1361   DONE;
1362 })
1363
1364 (define_insn_and_split "*vec_extractv4sf_0"
1365   [(set (match_operand:SF 0 "nonimmediate_operand" "=x,m,fr")
1366         (vec_select:SF
1367           (match_operand:V4SF 1 "nonimmediate_operand" "xm,x,m")
1368           (parallel [(const_int 0)])))]
1369   "TARGET_SSE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1370   "#"
1371   "&& reload_completed"
1372   [(const_int 0)]
1373 {
1374   rtx op1 = operands[1];
1375   if (REG_P (op1))
1376     op1 = gen_rtx_REG (SFmode, REGNO (op1));
1377   else
1378     op1 = gen_lowpart (SFmode, op1);
1379   emit_move_insn (operands[0], op1);
1380   DONE;
1381 })
1382
1383 (define_expand "vec_extractv4sf"
1384   [(match_operand:SF 0 "register_operand" "")
1385    (match_operand:V4SF 1 "register_operand" "")
1386    (match_operand 2 "const_int_operand" "")]
1387   "TARGET_SSE"
1388 {
1389   ix86_expand_vector_extract (false, operands[0], operands[1],
1390                               INTVAL (operands[2]));
1391   DONE;
1392 })
1393
1394 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1395 ;;
1396 ;; Parallel double-precision floating point arithmetic
1397 ;;
1398 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1399
1400 (define_expand "negv2df2"
1401   [(set (match_operand:V2DF 0 "register_operand" "")
1402         (neg:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")))]
1403   "TARGET_SSE2"
1404   "ix86_expand_fp_absneg_operator (NEG, V2DFmode, operands); DONE;")
1405
1406 (define_expand "absv2df2"
1407   [(set (match_operand:V2DF 0 "register_operand" "")
1408         (abs:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")))]
1409   "TARGET_SSE2"
1410   "ix86_expand_fp_absneg_operator (ABS, V2DFmode, operands); DONE;")
1411
1412 (define_expand "addv2df3"
1413   [(set (match_operand:V2DF 0 "register_operand" "")
1414         (plus:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
1415                    (match_operand:V2DF 2 "nonimmediate_operand" "")))]
1416   "TARGET_SSE2"
1417   "ix86_fixup_binary_operands_no_copy (PLUS, V2DFmode, operands);")
1418
1419 (define_insn "*addv2df3"
1420   [(set (match_operand:V2DF 0 "register_operand" "=x")
1421         (plus:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
1422                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
1423   "TARGET_SSE2 && ix86_binary_operator_ok (PLUS, V2DFmode, operands)"
1424   "addpd\t{%2, %0|%0, %2}"
1425   [(set_attr "type" "sseadd")
1426    (set_attr "mode" "V2DF")])
1427
1428 (define_insn "sse2_vmaddv2df3"
1429   [(set (match_operand:V2DF 0 "register_operand" "=x")
1430         (vec_merge:V2DF
1431           (plus:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
1432                      (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
1433           (match_dup 1)
1434           (const_int 1)))]
1435   "TARGET_SSE2 && ix86_binary_operator_ok (PLUS, V4SFmode, operands)"
1436   "addsd\t{%2, %0|%0, %2}"
1437   [(set_attr "type" "sseadd")
1438    (set_attr "mode" "DF")])
1439
1440 (define_expand "subv2df3"
1441   [(set (match_operand:V2DF 0 "register_operand" "")
1442         (minus:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
1443                     (match_operand:V2DF 2 "nonimmediate_operand" "")))]
1444   "TARGET_SSE2"
1445   "ix86_fixup_binary_operands_no_copy (MINUS, V2DFmode, operands);")
1446
1447 (define_insn "*subv2df3"
1448   [(set (match_operand:V2DF 0 "register_operand" "=x")
1449         (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
1450                     (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
1451   "TARGET_SSE2"
1452   "subpd\t{%2, %0|%0, %2}"
1453   [(set_attr "type" "sseadd")
1454    (set_attr "mode" "V2DF")])
1455
1456 (define_insn "sse2_vmsubv2df3"
1457   [(set (match_operand:V2DF 0 "register_operand" "=x")
1458         (vec_merge:V2DF
1459           (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
1460                       (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
1461           (match_dup 1)
1462           (const_int 1)))]
1463   "TARGET_SSE2"
1464   "subsd\t{%2, %0|%0, %2}"
1465   [(set_attr "type" "sseadd")
1466    (set_attr "mode" "DF")])
1467
1468 (define_expand "mulv2df3"
1469   [(set (match_operand:V2DF 0 "register_operand" "")
1470         (mult:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
1471                    (match_operand:V2DF 2 "nonimmediate_operand" "")))]
1472   "TARGET_SSE2"
1473   "ix86_fixup_binary_operands_no_copy (MULT, V2DFmode, operands);")
1474
1475 (define_insn "*mulv2df3"
1476   [(set (match_operand:V2DF 0 "register_operand" "=x")
1477         (mult:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
1478                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
1479   "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V2DFmode, operands)"
1480   "mulpd\t{%2, %0|%0, %2}"
1481   [(set_attr "type" "ssemul")
1482    (set_attr "mode" "V2DF")])
1483
1484 (define_insn "sse2_vmmulv2df3"
1485   [(set (match_operand:V2DF 0 "register_operand" "=x")
1486         (vec_merge:V2DF
1487           (mult:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
1488                      (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
1489           (match_dup 1)
1490           (const_int 1)))]
1491   "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V2DFmode, operands)"
1492   "mulsd\t{%2, %0|%0, %2}"
1493   [(set_attr "type" "ssemul")
1494    (set_attr "mode" "DF")])
1495
1496 (define_expand "divv2df3"
1497   [(set (match_operand:V2DF 0 "register_operand" "")
1498         (div:V2DF (match_operand:V2DF 1 "register_operand" "")
1499                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
1500   "TARGET_SSE2"
1501   "ix86_fixup_binary_operands_no_copy (DIV, V2DFmode, operands);")
1502
1503 (define_insn "*divv2df3"
1504   [(set (match_operand:V2DF 0 "register_operand" "=x")
1505         (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
1506                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
1507   "TARGET_SSE2"
1508   "divpd\t{%2, %0|%0, %2}"
1509   [(set_attr "type" "ssediv")
1510    (set_attr "mode" "V2DF")])
1511
1512 (define_insn "sse2_vmdivv2df3"
1513   [(set (match_operand:V2DF 0 "register_operand" "=x")
1514         (vec_merge:V2DF
1515           (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
1516                     (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
1517           (match_dup 1)
1518           (const_int 1)))]
1519   "TARGET_SSE2"
1520   "divsd\t{%2, %0|%0, %2}"
1521   [(set_attr "type" "ssediv")
1522    (set_attr "mode" "DF")])
1523
1524 (define_insn "sqrtv2df2"
1525   [(set (match_operand:V2DF 0 "register_operand" "=x")
1526         (sqrt:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
1527   "TARGET_SSE2"
1528   "sqrtpd\t{%1, %0|%0, %1}"
1529   [(set_attr "type" "sse")
1530    (set_attr "mode" "V2DF")])
1531
1532 (define_insn "sse2_vmsqrtv2df2"
1533   [(set (match_operand:V2DF 0 "register_operand" "=x")
1534         (vec_merge:V2DF
1535           (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
1536           (match_operand:V2DF 2 "register_operand" "0")
1537           (const_int 1)))]
1538   "TARGET_SSE2"
1539   "sqrtsd\t{%1, %0|%0, %1}"
1540   [(set_attr "type" "sse")
1541    (set_attr "mode" "DF")])
1542
1543 ;; ??? For !flag_finite_math_only, the representation with SMIN/SMAX
1544 ;; isn't really correct, as those rtl operators aren't defined when 
1545 ;; applied to NaNs.  Hopefully the optimizers won't get too smart on us.
1546
1547 (define_expand "smaxv2df3"
1548   [(set (match_operand:V2DF 0 "register_operand" "")
1549         (smax:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
1550                    (match_operand:V2DF 2 "nonimmediate_operand" "")))]
1551   "TARGET_SSE2"
1552 {
1553   if (!flag_finite_math_only)
1554     operands[1] = force_reg (V2DFmode, operands[1]);
1555   ix86_fixup_binary_operands_no_copy (SMAX, V2DFmode, operands);
1556 })
1557
1558 (define_insn "*smaxv2df3_finite"
1559   [(set (match_operand:V2DF 0 "register_operand" "=x")
1560         (smax:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
1561                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
1562   "TARGET_SSE2 && flag_finite_math_only
1563    && ix86_binary_operator_ok (SMAX, V2DFmode, operands)"
1564   "maxpd\t{%2, %0|%0, %2}"
1565   [(set_attr "type" "sseadd")
1566    (set_attr "mode" "V2DF")])
1567
1568 (define_insn "*smaxv2df3"
1569   [(set (match_operand:V2DF 0 "register_operand" "=x")
1570         (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
1571                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
1572   "TARGET_SSE2"
1573   "maxpd\t{%2, %0|%0, %2}"
1574   [(set_attr "type" "sseadd")
1575    (set_attr "mode" "V2DF")])
1576
1577 (define_insn "*sse2_vmsmaxv2df3_finite"
1578   [(set (match_operand:V2DF 0 "register_operand" "=x")
1579         (vec_merge:V2DF
1580           (smax:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
1581                      (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
1582           (match_dup 1)
1583           (const_int 1)))]
1584   "TARGET_SSE2 && flag_finite_math_only
1585    && ix86_binary_operator_ok (SMAX, V2DFmode, operands)"
1586   "maxsd\t{%2, %0|%0, %2}"
1587   [(set_attr "type" "sseadd")
1588    (set_attr "mode" "DF")])
1589
1590 (define_insn "sse2_vmsmaxv2df3"
1591   [(set (match_operand:V2DF 0 "register_operand" "=x")
1592         (vec_merge:V2DF
1593           (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
1594                      (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
1595           (match_dup 1)
1596           (const_int 1)))]
1597   "TARGET_SSE2"
1598   "maxsd\t{%2, %0|%0, %2}"
1599   [(set_attr "type" "sseadd")
1600    (set_attr "mode" "DF")])
1601
1602 (define_expand "sminv2df3"
1603   [(set (match_operand:V2DF 0 "register_operand" "")
1604         (smin:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
1605                    (match_operand:V2DF 2 "nonimmediate_operand" "")))]
1606   "TARGET_SSE2"
1607 {
1608   if (!flag_finite_math_only)
1609     operands[1] = force_reg (V2DFmode, operands[1]);
1610   ix86_fixup_binary_operands_no_copy (SMIN, V2DFmode, operands);
1611 })
1612
1613 (define_insn "*sminv2df3_finite"
1614   [(set (match_operand:V2DF 0 "register_operand" "=x")
1615         (smin:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
1616                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
1617   "TARGET_SSE2 && flag_finite_math_only
1618    && ix86_binary_operator_ok (SMIN, V2DFmode, operands)"
1619   "minpd\t{%2, %0|%0, %2}"
1620   [(set_attr "type" "sseadd")
1621    (set_attr "mode" "V2DF")])
1622
1623 (define_insn "*sminv2df3"
1624   [(set (match_operand:V2DF 0 "register_operand" "=x")
1625         (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
1626                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
1627   "TARGET_SSE2"
1628   "minpd\t{%2, %0|%0, %2}"
1629   [(set_attr "type" "sseadd")
1630    (set_attr "mode" "V2DF")])
1631
1632 (define_insn "*sse2_vmsminv2df3_finite"
1633   [(set (match_operand:V2DF 0 "register_operand" "=x")
1634         (vec_merge:V2DF
1635           (smin:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
1636                      (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
1637           (match_dup 1)
1638           (const_int 1)))]
1639   "TARGET_SSE2 && flag_finite_math_only
1640    && ix86_binary_operator_ok (SMIN, V2DFmode, operands)"
1641   "minsd\t{%2, %0|%0, %2}"
1642   [(set_attr "type" "sseadd")
1643    (set_attr "mode" "DF")])
1644
1645 (define_insn "sse2_vmsminv2df3"
1646   [(set (match_operand:V2DF 0 "register_operand" "=x")
1647         (vec_merge:V2DF
1648           (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
1649                      (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
1650           (match_dup 1)
1651           (const_int 1)))]
1652   "TARGET_SSE2"
1653   "minsd\t{%2, %0|%0, %2}"
1654   [(set_attr "type" "sseadd")
1655    (set_attr "mode" "DF")])
1656
1657 (define_insn "sse3_addsubv2df3"
1658   [(set (match_operand:V2DF 0 "register_operand" "=x")
1659         (vec_merge:V2DF
1660           (plus:V2DF
1661             (match_operand:V2DF 1 "register_operand" "0")
1662             (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
1663           (minus:V2DF (match_dup 1) (match_dup 2))
1664           (const_int 1)))]
1665   "TARGET_SSE3"
1666   "addsubpd\t{%2, %0|%0, %2}"
1667   [(set_attr "type" "sseadd")
1668    (set_attr "mode" "V2DF")])
1669
1670 (define_insn "sse3_haddv2df3"
1671   [(set (match_operand:V2DF 0 "register_operand" "=x")
1672         (vec_concat:V2DF
1673           (plus:DF
1674             (vec_select:DF
1675               (match_operand:V2DF 1 "register_operand" "0")
1676               (parallel [(const_int 0)]))
1677             (vec_select:DF (match_dup 1) (parallel [(const_int 1)])))
1678           (plus:DF
1679             (vec_select:DF
1680               (match_operand:V2DF 2 "nonimmediate_operand" "xm")
1681               (parallel [(const_int 0)]))
1682             (vec_select:DF (match_dup 2) (parallel [(const_int 1)])))))]
1683   "TARGET_SSE3"
1684   "haddpd\t{%2, %0|%0, %2}"
1685   [(set_attr "type" "sseadd")
1686    (set_attr "mode" "V2DF")])
1687
1688 (define_insn "sse3_hsubv2df3"
1689   [(set (match_operand:V2DF 0 "register_operand" "=x")
1690         (vec_concat:V2DF
1691           (minus:DF
1692             (vec_select:DF
1693               (match_operand:V2DF 1 "register_operand" "0")
1694               (parallel [(const_int 0)]))
1695             (vec_select:DF (match_dup 1) (parallel [(const_int 1)])))
1696           (minus:DF
1697             (vec_select:DF
1698               (match_operand:V2DF 2 "nonimmediate_operand" "xm")
1699               (parallel [(const_int 0)]))
1700             (vec_select:DF (match_dup 2) (parallel [(const_int 1)])))))]
1701   "TARGET_SSE3"
1702   "hsubpd\t{%2, %0|%0, %2}"
1703   [(set_attr "type" "sseadd")
1704    (set_attr "mode" "V2DF")])
1705
1706 (define_expand "reduc_splus_v2df"
1707   [(match_operand:V2DF 0 "register_operand" "")
1708    (match_operand:V2DF 1 "register_operand" "")]
1709   "TARGET_SSE3"
1710 {
1711   emit_insn (gen_sse3_haddv2df3 (operands[0], operands[1], operands[1]));
1712   DONE;
1713 })
1714
1715 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1716 ;;
1717 ;; Parallel double-precision floating point comparisons
1718 ;;
1719 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1720
1721 (define_insn "sse2_maskcmpv2df3"
1722   [(set (match_operand:V2DF 0 "register_operand" "=x")
1723         (match_operator:V2DF 3 "sse_comparison_operator"
1724                 [(match_operand:V2DF 1 "register_operand" "0")
1725                  (match_operand:V2DF 2 "nonimmediate_operand" "xm")]))]
1726   "TARGET_SSE2"
1727   "cmp%D3pd\t{%2, %0|%0, %2}"
1728   [(set_attr "type" "ssecmp")
1729    (set_attr "mode" "V2DF")])
1730
1731 (define_insn "sse2_maskcmpdf3"
1732   [(set (match_operand:DF 0 "register_operand" "=x")
1733         (match_operator:DF 3 "sse_comparison_operator"
1734                 [(match_operand:DF 1 "register_operand" "0")
1735                  (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
1736   "TARGET_SSE2"
1737   "cmp%D3sd\t{%2, %0|%0, %2}"
1738   [(set_attr "type" "ssecmp")
1739    (set_attr "mode" "DF")])
1740
1741 (define_insn "sse2_vmmaskcmpv2df3"
1742   [(set (match_operand:V2DF 0 "register_operand" "=x")
1743         (vec_merge:V2DF
1744           (match_operator:V2DF 3 "sse_comparison_operator"
1745                 [(match_operand:V2DF 1 "register_operand" "0")
1746                  (match_operand:V2DF 2 "nonimmediate_operand" "xm")])
1747           (match_dup 1)
1748           (const_int 1)))]
1749   "TARGET_SSE2"
1750   "cmp%D3sd\t{%2, %0|%0, %2}"
1751   [(set_attr "type" "ssecmp")
1752    (set_attr "mode" "DF")])
1753
1754 (define_insn "sse2_comi"
1755   [(set (reg:CCFP FLAGS_REG)
1756         (compare:CCFP
1757           (vec_select:DF
1758             (match_operand:V2DF 0 "register_operand" "x")
1759             (parallel [(const_int 0)]))
1760           (vec_select:DF
1761             (match_operand:V2DF 1 "nonimmediate_operand" "xm")
1762             (parallel [(const_int 0)]))))]
1763   "TARGET_SSE2"
1764   "comisd\t{%1, %0|%0, %1}"
1765   [(set_attr "type" "ssecomi")
1766    (set_attr "mode" "DF")])
1767
1768 (define_insn "sse2_ucomi"
1769   [(set (reg:CCFPU FLAGS_REG)
1770         (compare:CCFPU
1771           (vec_select:DF
1772             (match_operand:V2DF 0 "register_operand" "x")
1773             (parallel [(const_int 0)]))
1774           (vec_select:DF
1775             (match_operand:V2DF 1 "nonimmediate_operand" "xm")
1776             (parallel [(const_int 0)]))))]
1777   "TARGET_SSE2"
1778   "ucomisd\t{%1, %0|%0, %1}"
1779   [(set_attr "type" "ssecomi")
1780    (set_attr "mode" "DF")])
1781
1782 (define_expand "vcondv2df"
1783   [(set (match_operand:V2DF 0 "register_operand" "")
1784         (if_then_else:V2DF
1785           (match_operator 3 ""
1786             [(match_operand:V2DF 4 "nonimmediate_operand" "")
1787              (match_operand:V2DF 5 "nonimmediate_operand" "")])
1788           (match_operand:V2DF 1 "general_operand" "")
1789           (match_operand:V2DF 2 "general_operand" "")))]
1790   "TARGET_SSE2"
1791 {
1792   if (ix86_expand_fp_vcond (operands))
1793     DONE;
1794   else
1795     FAIL;
1796 })
1797
1798 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1799 ;;
1800 ;; Parallel double-precision floating point logical operations
1801 ;;
1802 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1803
1804 (define_expand "andv2df3"
1805   [(set (match_operand:V2DF 0 "register_operand" "")
1806         (and:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
1807                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
1808   "TARGET_SSE2"
1809   "ix86_fixup_binary_operands_no_copy (AND, V2DFmode, operands);")
1810
1811 (define_insn "*andv2df3"
1812   [(set (match_operand:V2DF 0 "register_operand" "=x")
1813         (and:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
1814                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
1815   "TARGET_SSE2 && ix86_binary_operator_ok (AND, V2DFmode, operands)"
1816   "andpd\t{%2, %0|%0, %2}"
1817   [(set_attr "type" "sselog")
1818    (set_attr "mode" "V2DF")])
1819
1820 (define_insn "sse2_nandv2df3"
1821   [(set (match_operand:V2DF 0 "register_operand" "=x")
1822         (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" "0"))
1823                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
1824   "TARGET_SSE2"
1825   "andnpd\t{%2, %0|%0, %2}"
1826   [(set_attr "type" "sselog")
1827    (set_attr "mode" "V2DF")])
1828
1829 (define_expand "iorv2df3"
1830   [(set (match_operand:V2DF 0 "register_operand" "")
1831         (ior:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
1832                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
1833   "TARGET_SSE2"
1834   "ix86_fixup_binary_operands_no_copy (IOR, V2DFmode, operands);")
1835
1836 (define_insn "*iorv2df3"
1837   [(set (match_operand:V2DF 0 "register_operand" "=x")
1838         (ior:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
1839                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
1840   "TARGET_SSE2 && ix86_binary_operator_ok (IOR, V2DFmode, operands)"
1841   "orpd\t{%2, %0|%0, %2}"
1842   [(set_attr "type" "sselog")
1843    (set_attr "mode" "V2DF")])
1844
1845 (define_expand "xorv2df3"
1846   [(set (match_operand:V2DF 0 "register_operand" "")
1847         (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
1848                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
1849   "TARGET_SSE2"
1850   "ix86_fixup_binary_operands_no_copy (XOR, V2DFmode, operands);")
1851
1852 (define_insn "*xorv2df3"
1853   [(set (match_operand:V2DF 0 "register_operand" "=x")
1854         (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
1855                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
1856   "TARGET_SSE2 && ix86_binary_operator_ok (XOR, V2DFmode, operands)"
1857   "xorpd\t{%2, %0|%0, %2}"
1858   [(set_attr "type" "sselog")
1859    (set_attr "mode" "V2DF")])
1860
1861 ;; Also define scalar versions.  These are used for abs, neg, and
1862 ;; conditional move.  Using subregs into vector modes causes register
1863 ;; allocation lossage.  These patterns do not allow memory operands
1864 ;; because the native instructions read the full 128-bits.
1865
1866 (define_insn "*anddf3"
1867   [(set (match_operand:DF 0 "register_operand" "=x")
1868         (and:DF (match_operand:DF 1 "register_operand" "0")
1869                 (match_operand:DF 2 "register_operand" "x")))]
1870   "TARGET_SSE2"
1871   "andpd\t{%2, %0|%0, %2}"
1872   [(set_attr "type" "sselog")
1873    (set_attr "mode" "V2DF")])
1874
1875 (define_insn "*nanddf3"
1876   [(set (match_operand:DF 0 "register_operand" "=x")
1877         (and:DF (not:DF (match_operand:DF 1 "register_operand" "0"))
1878                 (match_operand:DF 2 "register_operand" "x")))]
1879   "TARGET_SSE2"
1880   "andnpd\t{%2, %0|%0, %2}"
1881   [(set_attr "type" "sselog")
1882    (set_attr "mode" "V2DF")])
1883
1884 (define_insn "*iordf3"
1885   [(set (match_operand:DF 0 "register_operand" "=x")
1886         (ior:DF (match_operand:DF 1 "register_operand" "0")
1887                 (match_operand:DF 2 "register_operand" "x")))]
1888   "TARGET_SSE2"
1889   "orpd\t{%2, %0|%0, %2}"
1890   [(set_attr "type" "sselog")
1891    (set_attr "mode" "V2DF")])
1892
1893 (define_insn "*xordf3"
1894   [(set (match_operand:DF 0 "register_operand" "=x")
1895         (xor:DF (match_operand:DF 1 "register_operand" "0")
1896                 (match_operand:DF 2 "register_operand" "x")))]
1897   "TARGET_SSE2"
1898   "xorpd\t{%2, %0|%0, %2}"
1899   [(set_attr "type" "sselog")
1900    (set_attr "mode" "V2DF")])
1901
1902 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1903 ;;
1904 ;; Parallel double-precision floating point conversion operations
1905 ;;
1906 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1907
1908 (define_insn "sse2_cvtpi2pd"
1909   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
1910         (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "y,m")))]
1911   "TARGET_SSE2"
1912   "cvtpi2pd\t{%1, %0|%0, %1}"
1913   [(set_attr "type" "ssecvt")
1914    (set_attr "unit" "mmx,*")
1915    (set_attr "mode" "V2DF")])
1916
1917 (define_insn "sse2_cvtpd2pi"
1918   [(set (match_operand:V2SI 0 "register_operand" "=y")
1919         (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
1920                      UNSPEC_FIX_NOTRUNC))]
1921   "TARGET_SSE2"
1922   "cvtpd2pi\t{%1, %0|%0, %1}"
1923   [(set_attr "type" "ssecvt")
1924    (set_attr "unit" "mmx")
1925    (set_attr "mode" "DI")])
1926
1927 (define_insn "sse2_cvttpd2pi"
1928   [(set (match_operand:V2SI 0 "register_operand" "=y")
1929         (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
1930   "TARGET_SSE2"
1931   "cvttpd2pi\t{%1, %0|%0, %1}"
1932   [(set_attr "type" "ssecvt")
1933    (set_attr "unit" "mmx")
1934    (set_attr "mode" "TI")])
1935
1936 (define_insn "sse2_cvtsi2sd"
1937   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
1938         (vec_merge:V2DF
1939           (vec_duplicate:V2DF
1940             (float:DF (match_operand:SI 2 "nonimmediate_operand" "r,m")))
1941           (match_operand:V2DF 1 "register_operand" "0,0")
1942           (const_int 1)))]
1943   "TARGET_SSE2"
1944   "cvtsi2sd\t{%2, %0|%0, %2}"
1945   [(set_attr "type" "sseicvt")
1946    (set_attr "mode" "DF")
1947    (set_attr "athlon_decode" "double,direct")])
1948
1949 (define_insn "sse2_cvtsi2sdq"
1950   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
1951         (vec_merge:V2DF
1952           (vec_duplicate:V2DF
1953             (float:DF (match_operand:DI 2 "nonimmediate_operand" "r,m")))
1954           (match_operand:V2DF 1 "register_operand" "0,0")
1955           (const_int 1)))]
1956   "TARGET_SSE2 && TARGET_64BIT"
1957   "cvtsi2sdq\t{%2, %0|%0, %2}"
1958   [(set_attr "type" "sseicvt")
1959    (set_attr "mode" "DF")
1960    (set_attr "athlon_decode" "double,direct")])
1961
1962 (define_insn "sse2_cvtsd2si"
1963   [(set (match_operand:SI 0 "register_operand" "=r,r")
1964         (unspec:SI
1965           [(vec_select:DF
1966              (match_operand:V2DF 1 "nonimmediate_operand" "x,m")
1967              (parallel [(const_int 0)]))]
1968           UNSPEC_FIX_NOTRUNC))]
1969   "TARGET_SSE2"
1970   "cvtsd2si\t{%1, %0|%0, %1}"
1971   [(set_attr "type" "sseicvt")
1972    (set_attr "athlon_decode" "double,vector")
1973    (set_attr "mode" "SI")])
1974
1975 (define_insn "sse2_cvtsd2si_2"
1976   [(set (match_operand:SI 0 "register_operand" "=r,r")
1977         (unspec:SI [(match_operand:DF 1 "nonimmediate_operand" "x,m")]
1978          UNSPEC_FIX_NOTRUNC))]
1979   "TARGET_SSE2"
1980   "cvtsd2si\t{%1, %0|%0, %1}"
1981   [(set_attr "type" "sseicvt")
1982    (set_attr "athlon_decode" "double,vector")
1983    (set_attr "mode" "SI")])
1984
1985 (define_insn "sse2_cvtsd2siq"
1986   [(set (match_operand:DI 0 "register_operand" "=r,r")
1987         (unspec:DI
1988           [(vec_select:DF
1989              (match_operand:V2DF 1 "nonimmediate_operand" "x,m")
1990              (parallel [(const_int 0)]))]
1991           UNSPEC_FIX_NOTRUNC))]
1992   "TARGET_SSE2 && TARGET_64BIT"
1993   "cvtsd2siq\t{%1, %0|%0, %1}"
1994   [(set_attr "type" "sseicvt")
1995    (set_attr "athlon_decode" "double,vector")
1996    (set_attr "mode" "DI")])
1997
1998 (define_insn "sse2_cvtsd2siq_2"
1999   [(set (match_operand:DI 0 "register_operand" "=r,r")
2000         (unspec:DI [(match_operand:DF 1 "nonimmediate_operand" "x,m")]
2001          UNSPEC_FIX_NOTRUNC))]
2002   "TARGET_SSE2 && TARGET_64BIT"
2003   "cvtsd2siq\t{%1, %0|%0, %1}"
2004   [(set_attr "type" "sseicvt")
2005    (set_attr "athlon_decode" "double,vector")
2006    (set_attr "mode" "DI")])
2007
2008 (define_insn "sse2_cvttsd2si"
2009   [(set (match_operand:SI 0 "register_operand" "=r,r")
2010         (fix:SI
2011           (vec_select:DF
2012             (match_operand:V2DF 1 "nonimmediate_operand" "x,m")
2013             (parallel [(const_int 0)]))))]
2014   "TARGET_SSE2"
2015   "cvttsd2si\t{%1, %0|%0, %1}"
2016   [(set_attr "type" "sseicvt")
2017    (set_attr "mode" "SI")
2018    (set_attr "athlon_decode" "double,vector")])
2019
2020 (define_insn "sse2_cvttsd2siq"
2021   [(set (match_operand:DI 0 "register_operand" "=r,r")
2022         (fix:DI
2023           (vec_select:DF
2024             (match_operand:V2DF 1 "nonimmediate_operand" "x,m")
2025             (parallel [(const_int 0)]))))]
2026   "TARGET_SSE2 && TARGET_64BIT"
2027   "cvttsd2siq\t{%1, %0|%0, %1}"
2028   [(set_attr "type" "sseicvt")
2029    (set_attr "mode" "DI")
2030    (set_attr "athlon_decode" "double,vector")])
2031
2032 (define_insn "sse2_cvtdq2pd"
2033   [(set (match_operand:V2DF 0 "register_operand" "=x")
2034         (float:V2DF
2035           (vec_select:V2SI
2036             (match_operand:V4SI 1 "nonimmediate_operand" "xm")
2037             (parallel [(const_int 0) (const_int 1)]))))]
2038   "TARGET_SSE2"
2039   "cvtdq2pd\t{%1, %0|%0, %1}"
2040   [(set_attr "type" "ssecvt")
2041    (set_attr "mode" "V2DF")])
2042
2043 (define_expand "sse2_cvtpd2dq"
2044   [(set (match_operand:V4SI 0 "register_operand" "")
2045         (vec_concat:V4SI
2046           (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "")]
2047                        UNSPEC_FIX_NOTRUNC)
2048           (match_dup 2)))]
2049   "TARGET_SSE2"
2050   "operands[2] = CONST0_RTX (V2SImode);")
2051
2052 (define_insn "*sse2_cvtpd2dq"
2053   [(set (match_operand:V4SI 0 "register_operand" "=x")
2054         (vec_concat:V4SI
2055           (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
2056                        UNSPEC_FIX_NOTRUNC)
2057           (match_operand:V2SI 2 "const0_operand" "")))]
2058   "TARGET_SSE2"
2059   "cvtpd2dq\t{%1, %0|%0, %1}"
2060   [(set_attr "type" "ssecvt")
2061    (set_attr "mode" "TI")])
2062
2063 (define_expand "sse2_cvttpd2dq"
2064   [(set (match_operand:V4SI 0 "register_operand" "")
2065         (vec_concat:V4SI
2066           (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" ""))
2067           (match_dup 2)))]
2068   "TARGET_SSE2"
2069   "operands[2] = CONST0_RTX (V2SImode);")
2070
2071 (define_insn "*sse2_cvttpd2dq"
2072   [(set (match_operand:V4SI 0 "register_operand" "=x")
2073         (vec_concat:V4SI
2074           (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
2075           (match_operand:V2SI 2 "const0_operand" "")))]
2076   "TARGET_SSE2"
2077   "cvttpd2dq\t{%1, %0|%0, %1}"
2078   [(set_attr "type" "ssecvt")
2079    (set_attr "mode" "TI")])
2080
2081 (define_insn "sse2_cvtsd2ss"
2082   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
2083         (vec_merge:V4SF
2084           (vec_duplicate:V4SF
2085             (float_truncate:V2SF
2086               (match_operand:V2DF 2 "nonimmediate_operand" "x,m")))
2087           (match_operand:V4SF 1 "register_operand" "0,0")
2088           (const_int 1)))]
2089   "TARGET_SSE2"
2090   "cvtsd2ss\t{%2, %0|%0, %2}"
2091   [(set_attr "type" "ssecvt")
2092    (set_attr "athlon_decode" "vector,double")
2093    (set_attr "mode" "SF")])
2094
2095 (define_insn "sse2_cvtss2sd"
2096   [(set (match_operand:V2DF 0 "register_operand" "=x")
2097         (vec_merge:V2DF
2098           (float_extend:V2DF
2099             (vec_select:V2SF
2100               (match_operand:V4SF 2 "nonimmediate_operand" "xm")
2101               (parallel [(const_int 0) (const_int 1)])))
2102           (match_operand:V2DF 1 "register_operand" "0")
2103           (const_int 1)))]
2104   "TARGET_SSE2"
2105   "cvtss2sd\t{%2, %0|%0, %2}"
2106   [(set_attr "type" "ssecvt")
2107    (set_attr "mode" "DF")])
2108
2109 (define_expand "sse2_cvtpd2ps"
2110   [(set (match_operand:V4SF 0 "register_operand" "")
2111         (vec_concat:V4SF
2112           (float_truncate:V2SF
2113             (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
2114           (match_dup 2)))]
2115   "TARGET_SSE2"
2116   "operands[2] = CONST0_RTX (V2SFmode);")
2117
2118 (define_insn "*sse2_cvtpd2ps"
2119   [(set (match_operand:V4SF 0 "register_operand" "=x")
2120         (vec_concat:V4SF
2121           (float_truncate:V2SF
2122             (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
2123           (match_operand:V2SF 2 "const0_operand" "")))]
2124   "TARGET_SSE2"
2125   "cvtpd2ps\t{%1, %0|%0, %1}"
2126   [(set_attr "type" "ssecvt")
2127    (set_attr "mode" "V4SF")])
2128
2129 (define_insn "sse2_cvtps2pd"
2130   [(set (match_operand:V2DF 0 "register_operand" "=x")
2131         (float_extend:V2DF
2132           (vec_select:V2SF
2133             (match_operand:V4SF 1 "nonimmediate_operand" "xm")
2134             (parallel [(const_int 0) (const_int 1)]))))]
2135   "TARGET_SSE2"
2136   "cvtps2pd\t{%1, %0|%0, %1}"
2137   [(set_attr "type" "ssecvt")
2138    (set_attr "mode" "V2DF")])
2139
2140 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2141 ;;
2142 ;; Parallel double-precision floating point element swizzling
2143 ;;
2144 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2145
2146 (define_insn "sse2_unpckhpd"
2147   [(set (match_operand:V2DF 0 "nonimmediate_operand"     "=x,x,m")
2148         (vec_select:V2DF
2149           (vec_concat:V4DF
2150             (match_operand:V2DF 1 "nonimmediate_operand" " 0,o,x")
2151             (match_operand:V2DF 2 "nonimmediate_operand" " x,0,0"))
2152           (parallel [(const_int 1)
2153                      (const_int 3)])))]
2154   "TARGET_SSE2 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
2155   "@
2156    unpckhpd\t{%2, %0|%0, %2}
2157    movlpd\t{%H1, %0|%0, %H1}
2158    movhpd\t{%1, %0|%0, %1}"
2159   [(set_attr "type" "sselog,ssemov,ssemov")
2160    (set_attr "mode" "V2DF,V1DF,V1DF")])
2161
2162 (define_insn "*sse3_movddup"
2163   [(set (match_operand:V2DF 0 "nonimmediate_operand"     "=x,o")
2164         (vec_select:V2DF
2165           (vec_concat:V4DF
2166             (match_operand:V2DF 1 "nonimmediate_operand" "xm,x")
2167             (match_dup 1))
2168           (parallel [(const_int 0)
2169                      (const_int 2)])))]
2170   "TARGET_SSE3 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2171   "@
2172    movddup\t{%1, %0|%0, %1}
2173    #"
2174   [(set_attr "type" "sselog1,ssemov")
2175    (set_attr "mode" "V2DF")])
2176
2177 (define_split
2178   [(set (match_operand:V2DF 0 "memory_operand" "")
2179         (vec_select:V2DF
2180           (vec_concat:V4DF
2181             (match_operand:V2DF 1 "register_operand" "")
2182             (match_dup 1))
2183           (parallel [(const_int 0)
2184                      (const_int 2)])))]
2185   "TARGET_SSE3 && reload_completed"
2186   [(const_int 0)]
2187 {
2188   rtx low = gen_rtx_REG (DFmode, REGNO (operands[1]));
2189   emit_move_insn (adjust_address (operands[0], DFmode, 0), low);
2190   emit_move_insn (adjust_address (operands[0], DFmode, 8), low);
2191   DONE;
2192 })
2193
2194 (define_insn "sse2_unpcklpd"
2195   [(set (match_operand:V2DF 0 "nonimmediate_operand"     "=x,x,o")
2196         (vec_select:V2DF
2197           (vec_concat:V4DF
2198             (match_operand:V2DF 1 "nonimmediate_operand" " 0,0,0")
2199             (match_operand:V2DF 2 "nonimmediate_operand" " x,m,x"))
2200           (parallel [(const_int 0)
2201                      (const_int 2)])))]
2202   "TARGET_SSE2 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
2203   "@
2204    unpcklpd\t{%2, %0|%0, %2}
2205    movhpd\t{%2, %0|%0, %2}
2206    movlpd\t{%2, %H0|%H0, %2}"
2207   [(set_attr "type" "sselog,ssemov,ssemov")
2208    (set_attr "mode" "V2DF,V1DF,V1DF")])
2209
2210 (define_expand "sse2_shufpd"
2211   [(match_operand:V2DF 0 "register_operand" "")
2212    (match_operand:V2DF 1 "register_operand" "")
2213    (match_operand:V2DF 2 "nonimmediate_operand" "")
2214    (match_operand:SI 3 "const_int_operand" "")]
2215   "TARGET_SSE2"
2216 {
2217   int mask = INTVAL (operands[3]);
2218   emit_insn (gen_sse2_shufpd_1 (operands[0], operands[1], operands[2],
2219                                 GEN_INT (mask & 1),
2220                                 GEN_INT (mask & 2 ? 3 : 2)));
2221   DONE;
2222 })
2223
2224 (define_insn "sse2_shufpd_1"
2225   [(set (match_operand:V2DF 0 "register_operand" "=x")
2226         (vec_select:V2DF
2227           (vec_concat:V4DF
2228             (match_operand:V2DF 1 "register_operand" "0")
2229             (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
2230           (parallel [(match_operand 3 "const_0_to_1_operand" "")
2231                      (match_operand 4 "const_2_to_3_operand" "")])))]
2232   "TARGET_SSE2"
2233 {
2234   int mask;
2235   mask = INTVAL (operands[3]);
2236   mask |= (INTVAL (operands[4]) - 2) << 1;
2237   operands[3] = GEN_INT (mask);
2238
2239   return "shufpd\t{%3, %2, %0|%0, %2, %3}";
2240 }
2241   [(set_attr "type" "sselog")
2242    (set_attr "mode" "V2DF")])
2243
2244 (define_insn "sse2_storehpd"
2245   [(set (match_operand:DF 0 "nonimmediate_operand"     "=m,x,x*fr")
2246         (vec_select:DF
2247           (match_operand:V2DF 1 "nonimmediate_operand" " x,0,o")
2248           (parallel [(const_int 1)])))]
2249   "TARGET_SSE2 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2250   "@
2251    movhpd\t{%1, %0|%0, %1}
2252    unpckhpd\t%0, %0
2253    #"
2254   [(set_attr "type" "ssemov,sselog1,ssemov")
2255    (set_attr "mode" "V1DF,V2DF,DF")])
2256
2257 (define_split
2258   [(set (match_operand:DF 0 "register_operand" "")
2259         (vec_select:DF
2260           (match_operand:V2DF 1 "memory_operand" "")
2261           (parallel [(const_int 1)])))]
2262   "TARGET_SSE2 && reload_completed"
2263   [(set (match_dup 0) (match_dup 1))]
2264 {
2265   operands[1] = adjust_address (operands[1], DFmode, 8);
2266 })
2267
2268 (define_insn "sse2_storelpd"
2269   [(set (match_operand:DF 0 "nonimmediate_operand"     "=m,x,x*fr")
2270         (vec_select:DF
2271           (match_operand:V2DF 1 "nonimmediate_operand" " x,x,m")
2272           (parallel [(const_int 0)])))]
2273   "TARGET_SSE2 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2274   "@
2275    movlpd\t{%1, %0|%0, %1}
2276    #
2277    #"
2278   [(set_attr "type" "ssemov")
2279    (set_attr "mode" "V1DF,DF,DF")])
2280
2281 (define_split
2282   [(set (match_operand:DF 0 "register_operand" "")
2283         (vec_select:DF
2284           (match_operand:V2DF 1 "nonimmediate_operand" "")
2285           (parallel [(const_int 0)])))]
2286   "TARGET_SSE2 && reload_completed"
2287   [(const_int 0)]
2288 {
2289   rtx op1 = operands[1];
2290   if (REG_P (op1))
2291     op1 = gen_rtx_REG (DFmode, REGNO (op1));
2292   else
2293     op1 = gen_lowpart (DFmode, op1);
2294   emit_move_insn (operands[0], op1);
2295   DONE;
2296 })
2297
2298 (define_insn "sse2_loadhpd"
2299   [(set (match_operand:V2DF 0 "nonimmediate_operand"     "=x,x,x,o")
2300         (vec_concat:V2DF
2301           (vec_select:DF
2302             (match_operand:V2DF 1 "nonimmediate_operand" " 0,0,x,0")
2303             (parallel [(const_int 0)]))
2304           (match_operand:DF 2 "nonimmediate_operand"     " m,x,0,x*fr")))]
2305   "TARGET_SSE2 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
2306   "@
2307    movhpd\t{%2, %0|%0, %2}
2308    unpcklpd\t{%2, %0|%0, %2}
2309    shufpd\t{$1, %1, %0|%0, %1, 1}
2310    #"
2311   [(set_attr "type" "ssemov,sselog,sselog,other")
2312    (set_attr "mode" "V1DF,V2DF,V2DF,DF")])
2313
2314 (define_split
2315   [(set (match_operand:V2DF 0 "memory_operand" "")
2316         (vec_concat:V2DF
2317           (vec_select:DF (match_dup 0) (parallel [(const_int 0)]))
2318           (match_operand:DF 1 "register_operand" "")))]
2319   "TARGET_SSE2 && reload_completed"
2320   [(set (match_dup 0) (match_dup 1))]
2321 {
2322   operands[0] = adjust_address (operands[0], DFmode, 8);
2323 })
2324
2325 (define_insn "sse2_loadlpd"
2326   [(set (match_operand:V2DF 0 "nonimmediate_operand"    "=x,x,x,x,x,m")
2327         (vec_concat:V2DF
2328           (match_operand:DF 2 "nonimmediate_operand"    " m,m,x,0,0,x*fr")
2329           (vec_select:DF
2330             (match_operand:V2DF 1 "vector_move_operand" " C,0,0,x,o,0")
2331             (parallel [(const_int 1)]))))]
2332   "TARGET_SSE2 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
2333   "@
2334    movsd\t{%2, %0|%0, %2}
2335    movlpd\t{%2, %0|%0, %2}
2336    movsd\t{%2, %0|%0, %2}
2337    shufpd\t{$2, %2, %0|%0, %2, 2}
2338    movhpd\t{%H1, %0|%0, %H1}
2339    #"
2340   [(set_attr "type" "ssemov,ssemov,ssemov,sselog,ssemov,other")
2341    (set_attr "mode" "DF,V1DF,V1DF,V2DF,V1DF,DF")])
2342
2343 (define_split
2344   [(set (match_operand:V2DF 0 "memory_operand" "")
2345         (vec_concat:V2DF
2346           (match_operand:DF 1 "register_operand" "")
2347           (vec_select:DF (match_dup 0) (parallel [(const_int 1)]))))]
2348   "TARGET_SSE2 && reload_completed"
2349   [(set (match_dup 0) (match_dup 1))]
2350 {
2351   operands[0] = adjust_address (operands[0], DFmode, 8);
2352 })
2353
2354 ;; Not sure these two are ever used, but it doesn't hurt to have
2355 ;; them. -aoliva
2356 (define_insn "*vec_extractv2df_1_sse"
2357   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,x,x")
2358         (vec_select:DF
2359           (match_operand:V2DF 1 "nonimmediate_operand" "x,x,o")
2360           (parallel [(const_int 1)])))]
2361   "!TARGET_SSE2 && TARGET_SSE
2362    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2363   "@
2364    movhps\t{%1, %0|%0, %1}
2365    movhlps\t{%1, %0|%0, %1}
2366    movlps\t{%H1, %0|%0, %H1}"
2367   [(set_attr "type" "ssemov")
2368    (set_attr "mode" "V2SF,V4SF,V2SF")])
2369
2370 (define_insn "*vec_extractv2df_0_sse"
2371   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,x,x")
2372         (vec_select:DF
2373           (match_operand:V2DF 1 "nonimmediate_operand" "x,x,m")
2374           (parallel [(const_int 0)])))]
2375   "!TARGET_SSE2 && TARGET_SSE
2376    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2377   "@
2378    movlps\t{%1, %0|%0, %1}
2379    movaps\t{%1, %0|%0, %1}
2380    movlps\t{%1, %0|%0, %1}"
2381   [(set_attr "type" "ssemov")
2382    (set_attr "mode" "V2SF,V4SF,V2SF")])
2383
2384 (define_insn "sse2_movsd"
2385   [(set (match_operand:V2DF 0 "nonimmediate_operand"   "=x,x,m,x,x,o")
2386         (vec_merge:V2DF
2387           (match_operand:V2DF 2 "nonimmediate_operand" " x,m,x,0,0,0")
2388           (match_operand:V2DF 1 "nonimmediate_operand" " 0,0,0,x,o,x")
2389           (const_int 1)))]
2390   "TARGET_SSE2"
2391   "@
2392    movsd\t{%2, %0|%0, %2}
2393    movlpd\t{%2, %0|%0, %2}
2394    movlpd\t{%2, %0|%0, %2}
2395    shufpd\t{$2, %2, %0|%0, %2, 2}
2396    movhps\t{%H1, %0|%0, %H1}
2397    movhps\t{%1, %H0|%H0, %1}"
2398   [(set_attr "type" "ssemov,ssemov,ssemov,sselog,ssemov,ssemov")
2399    (set_attr "mode" "DF,V1DF,V1DF,V2DF,V1DF,V1DF")])
2400
2401 (define_insn "*vec_dupv2df_sse3"
2402   [(set (match_operand:V2DF 0 "register_operand" "=x")
2403         (vec_duplicate:V2DF
2404           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
2405   "TARGET_SSE3"
2406   "movddup\t{%1, %0|%0, %1}"
2407   [(set_attr "type" "sselog1")
2408    (set_attr "mode" "DF")])
2409
2410 (define_insn "*vec_dupv2df"
2411   [(set (match_operand:V2DF 0 "register_operand" "=x")
2412         (vec_duplicate:V2DF
2413           (match_operand:DF 1 "register_operand" "0")))]
2414   "TARGET_SSE2"
2415   "unpcklpd\t%0, %0"
2416   [(set_attr "type" "sselog1")
2417    (set_attr "mode" "V4SF")])
2418
2419 (define_insn "*vec_concatv2df_sse3"
2420   [(set (match_operand:V2DF 0 "register_operand" "=x")
2421         (vec_concat:V2DF
2422           (match_operand:DF 1 "nonimmediate_operand" "xm")
2423           (match_dup 1)))]
2424   "TARGET_SSE3"
2425   "movddup\t{%1, %0|%0, %1}"
2426   [(set_attr "type" "sselog1")
2427    (set_attr "mode" "DF")])
2428
2429 (define_insn "*vec_concatv2df"
2430   [(set (match_operand:V2DF 0 "register_operand"     "=Y,Y,Y,x,x")
2431         (vec_concat:V2DF
2432           (match_operand:DF 1 "nonimmediate_operand" " 0,0,m,0,0")
2433           (match_operand:DF 2 "vector_move_operand"  " Y,m,C,x,m")))]
2434   "TARGET_SSE"
2435   "@
2436    unpcklpd\t{%2, %0|%0, %2}
2437    movhpd\t{%2, %0|%0, %2}
2438    movsd\t{%1, %0|%0, %1}
2439    movlhps\t{%2, %0|%0, %2}
2440    movhps\t{%2, %0|%0, %2}"
2441   [(set_attr "type" "sselog,ssemov,ssemov,ssemov,ssemov")
2442    (set_attr "mode" "V2DF,V1DF,DF,V4SF,V2SF")])
2443
2444 (define_expand "vec_setv2df"
2445   [(match_operand:V2DF 0 "register_operand" "")
2446    (match_operand:DF 1 "register_operand" "")
2447    (match_operand 2 "const_int_operand" "")]
2448   "TARGET_SSE"
2449 {
2450   ix86_expand_vector_set (false, operands[0], operands[1],
2451                           INTVAL (operands[2]));
2452   DONE;
2453 })
2454
2455 (define_expand "vec_extractv2df"
2456   [(match_operand:DF 0 "register_operand" "")
2457    (match_operand:V2DF 1 "register_operand" "")
2458    (match_operand 2 "const_int_operand" "")]
2459   "TARGET_SSE"
2460 {
2461   ix86_expand_vector_extract (false, operands[0], operands[1],
2462                               INTVAL (operands[2]));
2463   DONE;
2464 })
2465
2466 (define_expand "vec_initv2df"
2467   [(match_operand:V2DF 0 "register_operand" "")
2468    (match_operand 1 "" "")]
2469   "TARGET_SSE"
2470 {
2471   ix86_expand_vector_init (false, operands[0], operands[1]);
2472   DONE;
2473 })
2474
2475 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2476 ;;
2477 ;; Parallel integral arithmetic
2478 ;;
2479 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2480
2481 (define_expand "neg<mode>2"
2482   [(set (match_operand:SSEMODEI 0 "register_operand" "")
2483         (minus:SSEMODEI
2484           (match_dup 2)
2485           (match_operand:SSEMODEI 1 "nonimmediate_operand" "")))]
2486   "TARGET_SSE2"
2487   "operands[2] = force_reg (<MODE>mode, CONST0_RTX (<MODE>mode));")
2488
2489 (define_expand "add<mode>3"
2490   [(set (match_operand:SSEMODEI 0 "register_operand" "")
2491         (plus:SSEMODEI (match_operand:SSEMODEI 1 "nonimmediate_operand" "")
2492                        (match_operand:SSEMODEI 2 "nonimmediate_operand" "")))]
2493   "TARGET_SSE2"
2494   "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
2495
2496 (define_insn "*add<mode>3"
2497   [(set (match_operand:SSEMODEI 0 "register_operand" "=x")
2498         (plus:SSEMODEI
2499           (match_operand:SSEMODEI 1 "nonimmediate_operand" "%0")
2500           (match_operand:SSEMODEI 2 "nonimmediate_operand" "xm")))]
2501   "TARGET_SSE2 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
2502   "padd<ssevecsize>\t{%2, %0|%0, %2}"
2503   [(set_attr "type" "sseiadd")
2504    (set_attr "mode" "TI")])
2505
2506 (define_insn "sse2_ssadd<mode>3"
2507   [(set (match_operand:SSEMODE12 0 "register_operand" "=x")
2508         (ss_plus:SSEMODE12
2509           (match_operand:SSEMODE12 1 "nonimmediate_operand" "%0")
2510           (match_operand:SSEMODE12 2 "nonimmediate_operand" "xm")))]
2511   "TARGET_SSE2 && ix86_binary_operator_ok (SS_PLUS, <MODE>mode, operands)"
2512   "padds<ssevecsize>\t{%2, %0|%0, %2}"
2513   [(set_attr "type" "sseiadd")
2514    (set_attr "mode" "TI")])
2515
2516 (define_insn "sse2_usadd<mode>3"
2517   [(set (match_operand:SSEMODE12 0 "register_operand" "=x")
2518         (us_plus:SSEMODE12
2519           (match_operand:SSEMODE12 1 "nonimmediate_operand" "%0")
2520           (match_operand:SSEMODE12 2 "nonimmediate_operand" "xm")))]
2521   "TARGET_SSE2 && ix86_binary_operator_ok (US_PLUS, <MODE>mode, operands)"
2522   "paddus<ssevecsize>\t{%2, %0|%0, %2}"
2523   [(set_attr "type" "sseiadd")
2524    (set_attr "mode" "TI")])
2525
2526 (define_expand "sub<mode>3"
2527   [(set (match_operand:SSEMODEI 0 "register_operand" "")
2528         (minus:SSEMODEI (match_operand:SSEMODEI 1 "register_operand" "")
2529                         (match_operand:SSEMODEI 2 "nonimmediate_operand" "")))]
2530   "TARGET_SSE2"
2531   "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
2532
2533 (define_insn "*sub<mode>3"
2534   [(set (match_operand:SSEMODEI 0 "register_operand" "=x")
2535         (minus:SSEMODEI
2536           (match_operand:SSEMODEI 1 "register_operand" "0")
2537           (match_operand:SSEMODEI 2 "nonimmediate_operand" "xm")))]
2538   "TARGET_SSE2"
2539   "psub<ssevecsize>\t{%2, %0|%0, %2}"
2540   [(set_attr "type" "sseiadd")
2541    (set_attr "mode" "TI")])
2542
2543 (define_insn "sse2_sssub<mode>3"
2544   [(set (match_operand:SSEMODE12 0 "register_operand" "=x")
2545         (ss_minus:SSEMODE12
2546           (match_operand:SSEMODE12 1 "register_operand" "0")
2547           (match_operand:SSEMODE12 2 "nonimmediate_operand" "xm")))]
2548   "TARGET_SSE2"
2549   "psubs<ssevecsize>\t{%2, %0|%0, %2}"
2550   [(set_attr "type" "sseiadd")
2551    (set_attr "mode" "TI")])
2552
2553 (define_insn "sse2_ussub<mode>3"
2554   [(set (match_operand:SSEMODE12 0 "register_operand" "=x")
2555         (us_minus:SSEMODE12
2556           (match_operand:SSEMODE12 1 "register_operand" "0")
2557           (match_operand:SSEMODE12 2 "nonimmediate_operand" "xm")))]
2558   "TARGET_SSE2"
2559   "psubus<ssevecsize>\t{%2, %0|%0, %2}"
2560   [(set_attr "type" "sseiadd")
2561    (set_attr "mode" "TI")])
2562
2563 (define_expand "mulv16qi3"
2564   [(set (match_operand:V16QI 0 "register_operand" "")
2565         (mult:V16QI (match_operand:V16QI 1 "register_operand" "")
2566                     (match_operand:V16QI 2 "register_operand" "")))]
2567   "TARGET_SSE2"
2568 {
2569   rtx t[12], op0;
2570   int i;
2571
2572   for (i = 0; i < 12; ++i)
2573     t[i] = gen_reg_rtx (V16QImode);
2574
2575   /* Unpack data such that we've got a source byte in each low byte of
2576      each word.  We don't care what goes into the high byte of each word.
2577      Rather than trying to get zero in there, most convenient is to let
2578      it be a copy of the low byte.  */
2579   emit_insn (gen_sse2_punpckhbw (t[0], operands[1], operands[1]));
2580   emit_insn (gen_sse2_punpckhbw (t[1], operands[2], operands[2]));
2581   emit_insn (gen_sse2_punpcklbw (t[2], operands[1], operands[1]));
2582   emit_insn (gen_sse2_punpcklbw (t[3], operands[2], operands[2]));
2583
2584   /* Multiply words.  The end-of-line annotations here give a picture of what
2585      the output of that instruction looks like.  Dot means don't care; the 
2586      letters are the bytes of the result with A being the most significant.  */
2587   emit_insn (gen_mulv8hi3 (gen_lowpart (V8HImode, t[4]), /* .A.B.C.D.E.F.G.H */
2588                            gen_lowpart (V8HImode, t[0]),
2589                            gen_lowpart (V8HImode, t[1])));
2590   emit_insn (gen_mulv8hi3 (gen_lowpart (V8HImode, t[5]), /* .I.J.K.L.M.N.O.P */
2591                            gen_lowpart (V8HImode, t[2]),
2592                            gen_lowpart (V8HImode, t[3])));
2593
2594   /* Extract the relevant bytes and merge them back together.  */
2595   emit_insn (gen_sse2_punpckhbw (t[6], t[5], t[4]));    /* ..AI..BJ..CK..DL */
2596   emit_insn (gen_sse2_punpcklbw (t[7], t[5], t[4]));    /* ..EM..FN..GO..HP */
2597   emit_insn (gen_sse2_punpckhbw (t[8], t[7], t[6]));    /* ....AEIM....BFJN */
2598   emit_insn (gen_sse2_punpcklbw (t[9], t[7], t[6]));    /* ....CGKO....DHLP */
2599   emit_insn (gen_sse2_punpckhbw (t[10], t[9], t[8]));   /* ........ACEGIKMO */
2600   emit_insn (gen_sse2_punpcklbw (t[11], t[9], t[8]));   /* ........BDFHJLNP */
2601
2602   op0 = operands[0];
2603   emit_insn (gen_sse2_punpcklbw (op0, t[11], t[10]));   /* ABCDEFGHIJKLMNOP */
2604   DONE;
2605 })
2606
2607 (define_expand "mulv8hi3"
2608   [(set (match_operand:V8HI 0 "register_operand" "")
2609         (mult:V8HI (match_operand:V8HI 1 "nonimmediate_operand" "")
2610                    (match_operand:V8HI 2 "nonimmediate_operand" "")))]
2611   "TARGET_SSE2"
2612   "ix86_fixup_binary_operands_no_copy (MULT, V8HImode, operands);")
2613
2614 (define_insn "*mulv8hi3"
2615   [(set (match_operand:V8HI 0 "register_operand" "=x")
2616         (mult:V8HI (match_operand:V8HI 1 "nonimmediate_operand" "%0")
2617                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
2618   "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V8HImode, operands)"
2619   "pmullw\t{%2, %0|%0, %2}"
2620   [(set_attr "type" "sseimul")
2621    (set_attr "mode" "TI")])
2622
2623 (define_expand "smulv8hi3_highpart"
2624   [(set (match_operand:V8HI 0 "register_operand" "")
2625         (truncate:V8HI
2626           (lshiftrt:V8SI 
2627             (mult:V8SI 
2628               (sign_extend:V8SI
2629                 (match_operand:V8HI 1 "nonimmediate_operand" ""))
2630               (sign_extend:V8SI
2631                 (match_operand:V8HI 2 "nonimmediate_operand" "")))
2632             (const_int 16))))]
2633   "TARGET_SSE2"
2634   "ix86_fixup_binary_operands_no_copy (MULT, V8HImode, operands);")
2635   
2636 (define_insn "*smulv8hi3_highpart"
2637   [(set (match_operand:V8HI 0 "register_operand" "=x")
2638         (truncate:V8HI
2639           (lshiftrt:V8SI
2640             (mult:V8SI
2641               (sign_extend:V8SI
2642                 (match_operand:V8HI 1 "nonimmediate_operand" "%0"))
2643               (sign_extend:V8SI
2644                 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
2645             (const_int 16))))]
2646   "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V8HImode, operands)"
2647   "pmulhw\t{%2, %0|%0, %2}"
2648   [(set_attr "type" "sseimul")
2649    (set_attr "mode" "TI")])
2650
2651 (define_expand "umulv8hi3_highpart"
2652   [(set (match_operand:V8HI 0 "register_operand" "")
2653         (truncate:V8HI
2654           (lshiftrt:V8SI
2655             (mult:V8SI
2656               (zero_extend:V8SI
2657                 (match_operand:V8HI 1 "nonimmediate_operand" ""))
2658               (zero_extend:V8SI
2659                 (match_operand:V8HI 2 "nonimmediate_operand" "")))
2660             (const_int 16))))]
2661   "TARGET_SSE2"
2662   "ix86_fixup_binary_operands_no_copy (MULT, V8HImode, operands);")
2663
2664 (define_insn "*umulv8hi3_highpart"
2665   [(set (match_operand:V8HI 0 "register_operand" "=x")
2666         (truncate:V8HI
2667           (lshiftrt:V8SI
2668             (mult:V8SI
2669               (zero_extend:V8SI
2670                 (match_operand:V8HI 1 "nonimmediate_operand" "%0"))
2671               (zero_extend:V8SI
2672                 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
2673             (const_int 16))))]
2674   "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V8HImode, operands)"
2675   "pmulhuw\t{%2, %0|%0, %2}"
2676   [(set_attr "type" "sseimul")
2677    (set_attr "mode" "TI")])
2678
2679 (define_insn "sse2_umulv2siv2di3"
2680   [(set (match_operand:V2DI 0 "register_operand" "=x")
2681         (mult:V2DI
2682           (zero_extend:V2DI
2683             (vec_select:V2SI
2684               (match_operand:V4SI 1 "nonimmediate_operand" "%0")
2685               (parallel [(const_int 0) (const_int 2)])))
2686           (zero_extend:V2DI
2687             (vec_select:V2SI
2688               (match_operand:V4SI 2 "nonimmediate_operand" "xm")
2689               (parallel [(const_int 0) (const_int 2)])))))]
2690   "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V8HImode, operands)"
2691   "pmuludq\t{%2, %0|%0, %2}"
2692   [(set_attr "type" "sseimul")
2693    (set_attr "mode" "TI")])
2694
2695 (define_insn "sse2_pmaddwd"
2696   [(set (match_operand:V4SI 0 "register_operand" "=x")
2697         (plus:V4SI
2698           (mult:V4SI
2699             (sign_extend:V4SI
2700               (vec_select:V4HI
2701                 (match_operand:V8HI 1 "nonimmediate_operand" "%0")
2702                 (parallel [(const_int 0)
2703                            (const_int 2)
2704                            (const_int 4)
2705                            (const_int 6)])))
2706             (sign_extend:V4SI
2707               (vec_select:V4HI
2708                 (match_operand:V8HI 2 "nonimmediate_operand" "xm")
2709                 (parallel [(const_int 0)
2710                            (const_int 2)
2711                            (const_int 4)
2712                            (const_int 6)]))))
2713           (mult:V4SI
2714             (sign_extend:V4SI
2715               (vec_select:V4HI (match_dup 1)
2716                 (parallel [(const_int 1)
2717                            (const_int 3)
2718                            (const_int 5)
2719                            (const_int 7)])))
2720             (sign_extend:V4SI
2721               (vec_select:V4HI (match_dup 2)
2722                 (parallel [(const_int 1)
2723                            (const_int 3)
2724                            (const_int 5)
2725                            (const_int 7)]))))))]
2726   "TARGET_SSE2"
2727   "pmaddwd\t{%2, %0|%0, %2}"
2728   [(set_attr "type" "sseiadd")
2729    (set_attr "mode" "TI")])
2730
2731 (define_expand "mulv4si3"
2732   [(set (match_operand:V4SI 0 "register_operand" "")
2733         (mult:V4SI (match_operand:V4SI 1 "register_operand" "")
2734                    (match_operand:V4SI 2 "register_operand" "")))]
2735   "TARGET_SSE2"
2736 {
2737   rtx t1, t2, t3, t4, t5, t6, thirtytwo;
2738   rtx op0, op1, op2;
2739
2740   op0 = operands[0];
2741   op1 = operands[1];
2742   op2 = operands[2];
2743   t1 = gen_reg_rtx (V4SImode);
2744   t2 = gen_reg_rtx (V4SImode);
2745   t3 = gen_reg_rtx (V4SImode);
2746   t4 = gen_reg_rtx (V4SImode);
2747   t5 = gen_reg_rtx (V4SImode);
2748   t6 = gen_reg_rtx (V4SImode);
2749   thirtytwo = GEN_INT (32);
2750
2751   /* Multiply elements 2 and 0.  */
2752   emit_insn (gen_sse2_umulv2siv2di3 (gen_lowpart (V2DImode, t1), op1, op2));
2753
2754   /* Shift both input vectors down one element, so that elements 3 and 1
2755      are now in the slots for elements 2 and 0.  For K8, at least, this is
2756      faster than using a shuffle.  */
2757   emit_insn (gen_sse2_lshrti3 (gen_lowpart (TImode, t2),
2758                                gen_lowpart (TImode, op1), thirtytwo));
2759   emit_insn (gen_sse2_lshrti3 (gen_lowpart (TImode, t3),
2760                                gen_lowpart (TImode, op2), thirtytwo));
2761
2762   /* Multiply elements 3 and 1.  */
2763   emit_insn (gen_sse2_umulv2siv2di3 (gen_lowpart (V2DImode, t4), t2, t3));
2764
2765   /* Move the results in element 2 down to element 1; we don't care what
2766      goes in elements 2 and 3.  */
2767   emit_insn (gen_sse2_pshufd_1 (t5, t1, const0_rtx, const2_rtx,
2768                                 const0_rtx, const0_rtx));
2769   emit_insn (gen_sse2_pshufd_1 (t6, t4, const0_rtx, const2_rtx,
2770                                 const0_rtx, const0_rtx));
2771
2772   /* Merge the parts back together.  */
2773   emit_insn (gen_sse2_punpckldq (op0, t5, t6));
2774   DONE;
2775 })
2776
2777 (define_expand "mulv2di3"
2778   [(set (match_operand:V2DI 0 "register_operand" "")
2779         (mult:V2DI (match_operand:V2DI 1 "register_operand" "")
2780                    (match_operand:V2DI 2 "register_operand" "")))]
2781   "TARGET_SSE2"
2782 {
2783   rtx t1, t2, t3, t4, t5, t6, thirtytwo;
2784   rtx op0, op1, op2;
2785
2786   op0 = operands[0];
2787   op1 = operands[1];
2788   op2 = operands[2];
2789   t1 = gen_reg_rtx (V2DImode);
2790   t2 = gen_reg_rtx (V2DImode);
2791   t3 = gen_reg_rtx (V2DImode);
2792   t4 = gen_reg_rtx (V2DImode);
2793   t5 = gen_reg_rtx (V2DImode);
2794   t6 = gen_reg_rtx (V2DImode);
2795   thirtytwo = GEN_INT (32);
2796
2797   /* Multiply low parts.  */
2798   emit_insn (gen_sse2_umulv2siv2di3 (t1, gen_lowpart (V4SImode, op1),
2799                                      gen_lowpart (V4SImode, op2)));
2800
2801   /* Shift input vectors left 32 bits so we can multiply high parts.  */
2802   emit_insn (gen_lshrv2di3 (t2, op1, thirtytwo));
2803   emit_insn (gen_lshrv2di3 (t3, op2, thirtytwo));
2804
2805   /* Multiply high parts by low parts.  */
2806   emit_insn (gen_sse2_umulv2siv2di3 (t4, gen_lowpart (V4SImode, op1),
2807                                      gen_lowpart (V4SImode, t3)));
2808   emit_insn (gen_sse2_umulv2siv2di3 (t5, gen_lowpart (V4SImode, op2),
2809                                      gen_lowpart (V4SImode, t2)));
2810
2811   /* Shift them back.  */
2812   emit_insn (gen_ashlv2di3 (t4, t4, thirtytwo));
2813   emit_insn (gen_ashlv2di3 (t5, t5, thirtytwo));
2814
2815   /* Add the three parts together.  */
2816   emit_insn (gen_addv2di3 (t6, t1, t4));
2817   emit_insn (gen_addv2di3 (op0, t6, t5));
2818   DONE;
2819 })
2820
2821 (define_expand "vec_widen_smult_hi_v8hi"
2822   [(match_operand:V4SI 0 "register_operand" "")
2823    (match_operand:V8HI 1 "register_operand" "")
2824    (match_operand:V8HI 2 "register_operand" "")]
2825   "TARGET_SSE2"
2826 {
2827   rtx op1, op2, t1, t2, dest;
2828
2829   op1 = operands[1];
2830   op2 = operands[2];
2831   t1 = gen_reg_rtx (V8HImode);
2832   t2 = gen_reg_rtx (V8HImode);
2833   dest = gen_lowpart (V8HImode, operands[0]);
2834
2835   emit_insn (gen_mulv8hi3 (t1, op1, op2));
2836   emit_insn (gen_smulv8hi3_highpart (t2, op1, op2));
2837   emit_insn (gen_vec_interleave_highv8hi (dest, t1, t2));
2838   DONE;
2839 })
2840
2841 (define_expand "vec_widen_smult_lo_v8hi"
2842   [(match_operand:V4SI 0 "register_operand" "")
2843    (match_operand:V8HI 1 "register_operand" "")
2844    (match_operand:V8HI 2 "register_operand" "")]
2845   "TARGET_SSE2"
2846 {
2847   rtx op1, op2, t1, t2, dest;
2848
2849   op1 = operands[1];
2850   op2 = operands[2];
2851   t1 = gen_reg_rtx (V8HImode);
2852   t2 = gen_reg_rtx (V8HImode);
2853   dest = gen_lowpart (V8HImode, operands[0]);
2854
2855   emit_insn (gen_mulv8hi3 (t1, op1, op2));
2856   emit_insn (gen_smulv8hi3_highpart (t2, op1, op2));
2857   emit_insn (gen_vec_interleave_lowv8hi (dest, t1, t2));
2858   DONE;
2859 })
2860
2861 (define_expand "vec_widen_umult_hi_v8hi"
2862   [(match_operand:V4SI 0 "register_operand" "")
2863    (match_operand:V8HI 1 "register_operand" "")
2864    (match_operand:V8HI 2 "register_operand" "")]
2865   "TARGET_SSE2"
2866 {
2867   rtx op1, op2, t1, t2, dest;
2868
2869   op1 = operands[1];
2870   op2 = operands[2];
2871   t1 = gen_reg_rtx (V8HImode);
2872   t2 = gen_reg_rtx (V8HImode);
2873   dest = gen_lowpart (V8HImode, operands[0]);
2874
2875   emit_insn (gen_mulv8hi3 (t1, op1, op2));
2876   emit_insn (gen_umulv8hi3_highpart (t2, op1, op2));
2877   emit_insn (gen_vec_interleave_highv8hi (dest, t1, t2));
2878   DONE;
2879 })
2880
2881 (define_expand "vec_widen_umult_lo_v8hi"
2882   [(match_operand:V4SI 0 "register_operand" "")
2883    (match_operand:V8HI 1 "register_operand" "")
2884    (match_operand:V8HI 2 "register_operand" "")]
2885   "TARGET_SSE2"
2886 {
2887   rtx op1, op2, t1, t2, dest;
2888
2889   op1 = operands[1];
2890   op2 = operands[2];
2891   t1 = gen_reg_rtx (V8HImode);
2892   t2 = gen_reg_rtx (V8HImode);
2893   dest = gen_lowpart (V8HImode, operands[0]);
2894
2895   emit_insn (gen_mulv8hi3 (t1, op1, op2));
2896   emit_insn (gen_umulv8hi3_highpart (t2, op1, op2));
2897   emit_insn (gen_vec_interleave_lowv8hi (dest, t1, t2));
2898   DONE;
2899 })
2900
2901 (define_expand "vec_widen_smult_hi_v4si"
2902   [(match_operand:V2DI 0 "register_operand" "")
2903    (match_operand:V4SI 1 "register_operand" "")
2904    (match_operand:V4SI 2 "register_operand" "")]
2905   "TARGET_SSE2"
2906 {
2907   rtx op1, op2, t1, t2;
2908
2909   op1 = operands[1];
2910   op2 = operands[2];
2911   t1 = gen_reg_rtx (V4SImode);
2912   t2 = gen_reg_rtx (V4SImode);
2913
2914   emit_insn (gen_vec_interleave_highv4si (t1, op1, op1));
2915   emit_insn (gen_vec_interleave_highv4si (t2, op2, op2));
2916   emit_insn (gen_sse2_umulv2siv2di3 (operands[0], t1, t2));
2917   DONE;
2918 })
2919
2920 (define_expand "vec_widen_smult_lo_v4si"
2921   [(match_operand:V2DI 0 "register_operand" "")
2922    (match_operand:V4SI 1 "register_operand" "")
2923    (match_operand:V4SI 2 "register_operand" "")]
2924   "TARGET_SSE2"
2925 {
2926   rtx op1, op2, t1, t2;
2927
2928   op1 = operands[1];
2929   op2 = operands[2];
2930   t1 = gen_reg_rtx (V4SImode);
2931   t2 = gen_reg_rtx (V4SImode);
2932
2933   emit_insn (gen_vec_interleave_lowv4si (t1, op1, op1));
2934   emit_insn (gen_vec_interleave_lowv4si (t2, op2, op2));
2935   emit_insn (gen_sse2_umulv2siv2di3 (operands[0], t1, t2));
2936   DONE;
2937 })
2938
2939 (define_expand "vec_widen_umult_hi_v4si"
2940   [(match_operand:V2DI 0 "register_operand" "")
2941    (match_operand:V4SI 1 "register_operand" "")
2942    (match_operand:V4SI 2 "register_operand" "")]
2943   "TARGET_SSE2"
2944 {
2945   rtx op1, op2, t1, t2;
2946
2947   op1 = operands[1];
2948   op2 = operands[2];
2949   t1 = gen_reg_rtx (V4SImode);
2950   t2 = gen_reg_rtx (V4SImode);
2951
2952   emit_insn (gen_vec_interleave_highv4si (t1, op1, op1));
2953   emit_insn (gen_vec_interleave_highv4si (t2, op2, op2));
2954   emit_insn (gen_sse2_umulv2siv2di3 (operands[0], t1, t2));
2955   DONE;
2956 })
2957
2958 (define_expand "vec_widen_umult_lo_v4si"
2959   [(match_operand:V2DI 0 "register_operand" "")
2960    (match_operand:V4SI 1 "register_operand" "")
2961    (match_operand:V4SI 2 "register_operand" "")]
2962   "TARGET_SSE2"
2963 {
2964   rtx op1, op2, t1, t2;
2965
2966   op1 = operands[1];
2967   op2 = operands[2];
2968   t1 = gen_reg_rtx (V4SImode);
2969   t2 = gen_reg_rtx (V4SImode);
2970
2971   emit_insn (gen_vec_interleave_lowv4si (t1, op1, op1));
2972   emit_insn (gen_vec_interleave_lowv4si (t2, op2, op2));
2973   emit_insn (gen_sse2_umulv2siv2di3 (operands[0], t1, t2));
2974   DONE;
2975 })
2976
2977 (define_expand "sdot_prodv8hi"
2978   [(match_operand:V4SI 0 "register_operand" "")
2979    (match_operand:V8HI 1 "nonimmediate_operand" "")
2980    (match_operand:V8HI 2 "nonimmediate_operand" "")
2981    (match_operand:V4SI 3 "register_operand" "")]
2982   "TARGET_SSE2"
2983 {
2984   rtx t = gen_reg_rtx (V4SImode);
2985   emit_insn (gen_sse2_pmaddwd (t, operands[1], operands[2]));
2986   emit_insn (gen_addv4si3 (operands[0], operands[3], t));
2987   DONE;
2988 })
2989
2990 (define_expand "udot_prodv4si"
2991   [(match_operand:V2DI 0 "register_operand" "") 
2992    (match_operand:V4SI 1 "register_operand" "") 
2993    (match_operand:V4SI 2 "register_operand" "")
2994    (match_operand:V2DI 3 "register_operand" "")]
2995   "TARGET_SSE2"
2996 {
2997   rtx t1, t2, t3, t4;
2998
2999   t1 = gen_reg_rtx (V2DImode);
3000   emit_insn (gen_sse2_umulv2siv2di3 (t1, operands[1], operands[2]));
3001   emit_insn (gen_addv2di3 (t1, t1, operands[3]));
3002
3003   t2 = gen_reg_rtx (V4SImode);
3004   t3 = gen_reg_rtx (V4SImode);
3005   emit_insn (gen_sse2_lshrti3 (gen_lowpart (TImode, t2),
3006                                gen_lowpart (TImode, operands[1]),
3007                                GEN_INT (32)));
3008   emit_insn (gen_sse2_lshrti3 (gen_lowpart (TImode, t3),
3009                                gen_lowpart (TImode, operands[2]),
3010                                GEN_INT (32)));
3011
3012   t4 = gen_reg_rtx (V2DImode);
3013   emit_insn (gen_sse2_umulv2siv2di3 (t4, t2, t3));
3014
3015   emit_insn (gen_addv2di3 (operands[0], t1, t4));
3016   DONE;
3017 })
3018
3019 (define_insn "ashr<mode>3"
3020   [(set (match_operand:SSEMODE24 0 "register_operand" "=x")
3021         (ashiftrt:SSEMODE24
3022           (match_operand:SSEMODE24 1 "register_operand" "0")
3023           (match_operand:SI 2 "nonmemory_operand" "xi")))]
3024   "TARGET_SSE2"
3025   "psra<ssevecsize>\t{%2, %0|%0, %2}"
3026   [(set_attr "type" "sseishft")
3027    (set_attr "mode" "TI")])
3028
3029 (define_insn "lshr<mode>3"
3030   [(set (match_operand:SSEMODE248 0 "register_operand" "=x")
3031         (lshiftrt:SSEMODE248
3032           (match_operand:SSEMODE248 1 "register_operand" "0")
3033           (match_operand:SI 2 "nonmemory_operand" "xi")))]
3034   "TARGET_SSE2"
3035   "psrl<ssevecsize>\t{%2, %0|%0, %2}"
3036   [(set_attr "type" "sseishft")
3037    (set_attr "mode" "TI")])
3038
3039 (define_insn "ashl<mode>3"
3040   [(set (match_operand:SSEMODE248 0 "register_operand" "=x")
3041         (ashift:SSEMODE248
3042           (match_operand:SSEMODE248 1 "register_operand" "0")
3043           (match_operand:SI 2 "nonmemory_operand" "xi")))]
3044   "TARGET_SSE2"
3045   "psll<ssevecsize>\t{%2, %0|%0, %2}"
3046   [(set_attr "type" "sseishft")
3047    (set_attr "mode" "TI")])
3048
3049 (define_insn "sse2_ashlti3"
3050   [(set (match_operand:TI 0 "register_operand" "=x")
3051         (ashift:TI (match_operand:TI 1 "register_operand" "0")
3052                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
3053   "TARGET_SSE2"
3054 {
3055   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
3056   return "pslldq\t{%2, %0|%0, %2}";
3057 }
3058   [(set_attr "type" "sseishft")
3059    (set_attr "mode" "TI")])
3060
3061 (define_expand "vec_shl_<mode>"
3062   [(set (match_operand:SSEMODEI 0 "register_operand" "")
3063         (ashift:TI (match_operand:SSEMODEI 1 "register_operand" "")
3064                    (match_operand:SI 2 "general_operand" "")))]
3065   "TARGET_SSE2"
3066 {
3067   if (!const_0_to_255_mul_8_operand (operands[2], SImode))
3068     FAIL;
3069   operands[0] = gen_lowpart (TImode, operands[0]);
3070   operands[1] = gen_lowpart (TImode, operands[1]);
3071 })
3072
3073 (define_insn "sse2_lshrti3"
3074   [(set (match_operand:TI 0 "register_operand" "=x")
3075         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
3076                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
3077   "TARGET_SSE2"
3078 {
3079   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
3080   return "psrldq\t{%2, %0|%0, %2}";
3081 }
3082   [(set_attr "type" "sseishft")
3083    (set_attr "mode" "TI")])
3084
3085 (define_expand "vec_shr_<mode>"
3086   [(set (match_operand:SSEMODEI 0 "register_operand" "")
3087         (lshiftrt:TI (match_operand:SSEMODEI 1 "register_operand" "")
3088                      (match_operand:SI 2 "general_operand" "")))]
3089   "TARGET_SSE2"
3090 {
3091   if (!const_0_to_255_mul_8_operand (operands[2], SImode))
3092     FAIL;
3093   operands[0] = gen_lowpart (TImode, operands[0]);
3094   operands[1] = gen_lowpart (TImode, operands[1]);
3095 })
3096
3097 (define_expand "umaxv16qi3"
3098   [(set (match_operand:V16QI 0 "register_operand" "")
3099         (umax:V16QI (match_operand:V16QI 1 "nonimmediate_operand" "")
3100                     (match_operand:V16QI 2 "nonimmediate_operand" "")))]
3101   "TARGET_SSE2"
3102   "ix86_fixup_binary_operands_no_copy (UMAX, V16QImode, operands);")
3103
3104 (define_insn "*umaxv16qi3"
3105   [(set (match_operand:V16QI 0 "register_operand" "=x")
3106         (umax:V16QI (match_operand:V16QI 1 "nonimmediate_operand" "%0")
3107                     (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
3108   "TARGET_SSE2 && ix86_binary_operator_ok (UMAX, V16QImode, operands)"
3109   "pmaxub\t{%2, %0|%0, %2}"
3110   [(set_attr "type" "sseiadd")
3111    (set_attr "mode" "TI")])
3112
3113 (define_expand "smaxv8hi3"
3114   [(set (match_operand:V8HI 0 "register_operand" "")
3115         (smax:V8HI (match_operand:V8HI 1 "nonimmediate_operand" "")
3116                    (match_operand:V8HI 2 "nonimmediate_operand" "")))]
3117   "TARGET_SSE2"
3118   "ix86_fixup_binary_operands_no_copy (SMAX, V8HImode, operands);")
3119
3120 (define_insn "*smaxv8hi3"
3121   [(set (match_operand:V8HI 0 "register_operand" "=x")
3122         (smax:V8HI (match_operand:V8HI 1 "nonimmediate_operand" "%0")
3123                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
3124   "TARGET_SSE2 && ix86_binary_operator_ok (SMAX, V8HImode, operands)"
3125   "pmaxsw\t{%2, %0|%0, %2}"
3126   [(set_attr "type" "sseiadd")
3127    (set_attr "mode" "TI")])
3128
3129 (define_expand "umaxv8hi3"
3130   [(set (match_operand:V8HI 0 "register_operand" "=x")
3131         (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
3132                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
3133    (set (match_dup 3)
3134         (plus:V8HI (match_dup 0) (match_dup 2)))]
3135   "TARGET_SSE2"
3136 {
3137   operands[3] = operands[0];
3138   if (rtx_equal_p (operands[0], operands[2]))
3139     operands[0] = gen_reg_rtx (V8HImode);
3140 })
3141
3142 (define_expand "smax<mode>3"
3143   [(set (match_operand:SSEMODE14 0 "register_operand" "")
3144         (smax:SSEMODE14 (match_operand:SSEMODE14 1 "register_operand" "")
3145                         (match_operand:SSEMODE14 2 "register_operand" "")))]
3146   "TARGET_SSE2"
3147 {
3148   rtx xops[6];
3149   bool ok;
3150
3151   xops[0] = operands[0];
3152   xops[1] = operands[1];
3153   xops[2] = operands[2];
3154   xops[3] = gen_rtx_GT (VOIDmode, operands[1], operands[2]);
3155   xops[4] = operands[1];
3156   xops[5] = operands[2];
3157   ok = ix86_expand_int_vcond (xops);
3158   gcc_assert (ok);
3159   DONE;
3160 })
3161
3162 (define_expand "umaxv4si3"
3163   [(set (match_operand:V4SI 0 "register_operand" "")
3164         (umax:V4SI (match_operand:V4SI 1 "register_operand" "")
3165                    (match_operand:V4SI 2 "register_operand" "")))]
3166   "TARGET_SSE2"
3167 {
3168   rtx xops[6];
3169   bool ok;
3170
3171   xops[0] = operands[0];
3172   xops[1] = operands[1];
3173   xops[2] = operands[2];
3174   xops[3] = gen_rtx_GTU (VOIDmode, operands[1], operands[2]);
3175   xops[4] = operands[1];
3176   xops[5] = operands[2];
3177   ok = ix86_expand_int_vcond (xops);
3178   gcc_assert (ok);
3179   DONE;
3180 })
3181
3182 (define_expand "uminv16qi3"
3183   [(set (match_operand:V16QI 0 "register_operand" "")
3184         (umin:V16QI (match_operand:V16QI 1 "nonimmediate_operand" "")
3185                     (match_operand:V16QI 2 "nonimmediate_operand" "")))]
3186   "TARGET_SSE2"
3187   "ix86_fixup_binary_operands_no_copy (UMAX, V16QImode, operands);")
3188
3189 (define_insn "*uminv16qi3"
3190   [(set (match_operand:V16QI 0 "register_operand" "=x")
3191         (umin:V16QI (match_operand:V16QI 1 "nonimmediate_operand" "%0")
3192                     (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
3193   "TARGET_SSE2 && ix86_binary_operator_ok (UMIN, V16QImode, operands)"
3194   "pminub\t{%2, %0|%0, %2}"
3195   [(set_attr "type" "sseiadd")
3196    (set_attr "mode" "TI")])
3197
3198 (define_expand "sminv8hi3"
3199   [(set (match_operand:V8HI 0 "register_operand" "")
3200         (smin:V8HI (match_operand:V8HI 1 "nonimmediate_operand" "")
3201                    (match_operand:V8HI 2 "nonimmediate_operand" "")))]
3202   "TARGET_SSE2"
3203   "ix86_fixup_binary_operands_no_copy (SMIN, V8HImode, operands);")
3204
3205 (define_insn "*sminv8hi3"
3206   [(set (match_operand:V8HI 0 "register_operand" "=x")
3207         (smin:V8HI (match_operand:V8HI 1 "nonimmediate_operand" "%0")
3208                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
3209   "TARGET_SSE2 && ix86_binary_operator_ok (SMIN, V8HImode, operands)"
3210   "pminsw\t{%2, %0|%0, %2}"
3211   [(set_attr "type" "sseiadd")
3212    (set_attr "mode" "TI")])
3213
3214 (define_expand "smin<mode>3"
3215   [(set (match_operand:SSEMODE14 0 "register_operand" "")
3216         (smin:SSEMODE14 (match_operand:SSEMODE14 1 "register_operand" "")
3217                         (match_operand:SSEMODE14 2 "register_operand" "")))]
3218   "TARGET_SSE2"
3219 {
3220   rtx xops[6];
3221   bool ok;
3222
3223   xops[0] = operands[0];
3224   xops[1] = operands[2];
3225   xops[2] = operands[1];
3226   xops[3] = gen_rtx_GT (VOIDmode, operands[1], operands[2]);
3227   xops[4] = operands[1];
3228   xops[5] = operands[2];
3229   ok = ix86_expand_int_vcond (xops);
3230   gcc_assert (ok);
3231   DONE;
3232 })
3233
3234 (define_expand "umin<mode>3"
3235   [(set (match_operand:SSEMODE24 0 "register_operand" "")
3236         (umin:SSEMODE24 (match_operand:SSEMODE24 1 "register_operand" "")
3237                         (match_operand:SSEMODE24 2 "register_operand" "")))]
3238   "TARGET_SSE2"
3239 {
3240   rtx xops[6];
3241   bool ok;
3242
3243   xops[0] = operands[0];
3244   xops[1] = operands[2];
3245   xops[2] = operands[1];
3246   xops[3] = gen_rtx_GTU (VOIDmode, operands[1], operands[2]);
3247   xops[4] = operands[1];
3248   xops[5] = operands[2];
3249   ok = ix86_expand_int_vcond (xops);
3250   gcc_assert (ok);
3251   DONE;
3252 })
3253
3254 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3255 ;;
3256 ;; Parallel integral comparisons
3257 ;;
3258 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3259
3260 (define_insn "sse2_eq<mode>3"
3261   [(set (match_operand:SSEMODE124 0 "register_operand" "=x")
3262         (eq:SSEMODE124
3263           (match_operand:SSEMODE124 1 "nonimmediate_operand" "%0")
3264           (match_operand:SSEMODE124 2 "nonimmediate_operand" "xm")))]
3265   "TARGET_SSE2 && ix86_binary_operator_ok (EQ, <MODE>mode, operands)"
3266   "pcmpeq<ssevecsize>\t{%2, %0|%0, %2}"
3267   [(set_attr "type" "ssecmp")
3268    (set_attr "mode" "TI")])
3269
3270 (define_insn "sse2_gt<mode>3"
3271   [(set (match_operand:SSEMODE124 0 "register_operand" "=x")
3272         (gt:SSEMODE124
3273           (match_operand:SSEMODE124 1 "register_operand" "0")
3274           (match_operand:SSEMODE124 2 "nonimmediate_operand" "xm")))]
3275   "TARGET_SSE2"
3276   "pcmpgt<ssevecsize>\t{%2, %0|%0, %2}"
3277   [(set_attr "type" "ssecmp")
3278    (set_attr "mode" "TI")])
3279
3280 (define_expand "vcond<mode>"
3281   [(set (match_operand:SSEMODE124 0 "register_operand" "")
3282         (if_then_else:SSEMODE124
3283           (match_operator 3 ""
3284             [(match_operand:SSEMODE124 4 "nonimmediate_operand" "")
3285              (match_operand:SSEMODE124 5 "nonimmediate_operand" "")])
3286           (match_operand:SSEMODE124 1 "general_operand" "")
3287           (match_operand:SSEMODE124 2 "general_operand" "")))]
3288   "TARGET_SSE2"
3289 {
3290   if (ix86_expand_int_vcond (operands))
3291     DONE;
3292   else
3293     FAIL;
3294 })
3295
3296 (define_expand "vcondu<mode>"
3297   [(set (match_operand:SSEMODE124 0 "register_operand" "")
3298         (if_then_else:SSEMODE124
3299           (match_operator 3 ""
3300             [(match_operand:SSEMODE124 4 "nonimmediate_operand" "")
3301              (match_operand:SSEMODE124 5 "nonimmediate_operand" "")])
3302           (match_operand:SSEMODE124 1 "general_operand" "")
3303           (match_operand:SSEMODE124 2 "general_operand" "")))]
3304   "TARGET_SSE2"
3305 {
3306   if (ix86_expand_int_vcond (operands))
3307     DONE;
3308   else
3309     FAIL;
3310 })
3311
3312 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3313 ;;
3314 ;; Parallel integral logical operations
3315 ;;
3316 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3317
3318 (define_expand "one_cmpl<mode>2"
3319   [(set (match_operand:SSEMODEI 0 "register_operand" "")
3320         (xor:SSEMODEI (match_operand:SSEMODEI 1 "nonimmediate_operand" "")
3321                       (match_dup 2)))]
3322   "TARGET_SSE2"
3323 {
3324   int i, n = GET_MODE_NUNITS (<MODE>mode);
3325   rtvec v = rtvec_alloc (n);
3326
3327   for (i = 0; i < n; ++i)
3328     RTVEC_ELT (v, i) = constm1_rtx;
3329
3330   operands[2] = force_reg (<MODE>mode, gen_rtx_CONST_VECTOR (<MODE>mode, v));
3331 })
3332
3333 (define_expand "and<mode>3"
3334   [(set (match_operand:SSEMODEI 0 "register_operand" "")
3335         (and:SSEMODEI (match_operand:SSEMODEI 1 "nonimmediate_operand" "")
3336                       (match_operand:SSEMODEI 2 "nonimmediate_operand" "")))]
3337   "TARGET_SSE2"
3338   "ix86_fixup_binary_operands_no_copy (AND, <MODE>mode, operands);")
3339
3340 (define_insn "*and<mode>3"
3341   [(set (match_operand:SSEMODEI 0 "register_operand" "=x")
3342         (and:SSEMODEI
3343           (match_operand:SSEMODEI 1 "nonimmediate_operand" "%0")
3344           (match_operand:SSEMODEI 2 "nonimmediate_operand" "xm")))]
3345   "TARGET_SSE2 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
3346   "pand\t{%2, %0|%0, %2}"
3347   [(set_attr "type" "sselog")
3348    (set_attr "mode" "TI")])
3349
3350 (define_insn "sse2_nand<mode>3"
3351   [(set (match_operand:SSEMODEI 0 "register_operand" "=x")
3352         (and:SSEMODEI
3353           (not:SSEMODEI (match_operand:SSEMODEI 1 "register_operand" "0"))
3354           (match_operand:SSEMODEI 2 "nonimmediate_operand" "xm")))]
3355   "TARGET_SSE2"
3356   "pandn\t{%2, %0|%0, %2}"
3357   [(set_attr "type" "sselog")
3358    (set_attr "mode" "TI")])
3359
3360 (define_expand "ior<mode>3"
3361   [(set (match_operand:SSEMODEI 0 "register_operand" "")
3362         (ior:SSEMODEI (match_operand:SSEMODEI 1 "nonimmediate_operand" "")
3363                       (match_operand:SSEMODEI 2 "nonimmediate_operand" "")))]
3364   "TARGET_SSE2"
3365   "ix86_fixup_binary_operands_no_copy (IOR, <MODE>mode, operands);")
3366
3367 (define_insn "*ior<mode>3"
3368   [(set (match_operand:SSEMODEI 0 "register_operand" "=x")
3369         (ior:SSEMODEI
3370           (match_operand:SSEMODEI 1 "nonimmediate_operand" "%0")
3371           (match_operand:SSEMODEI 2 "nonimmediate_operand" "xm")))]
3372   "TARGET_SSE2 && ix86_binary_operator_ok (IOR, <MODE>mode, operands)"
3373   "por\t{%2, %0|%0, %2}"
3374   [(set_attr "type" "sselog")
3375    (set_attr "mode" "TI")])
3376
3377 (define_expand "xor<mode>3"
3378   [(set (match_operand:SSEMODEI 0 "register_operand" "")
3379         (xor:SSEMODEI (match_operand:SSEMODEI 1 "nonimmediate_operand" "")
3380                       (match_operand:SSEMODEI 2 "nonimmediate_operand" "")))]
3381   "TARGET_SSE2"
3382   "ix86_fixup_binary_operands_no_copy (XOR, <MODE>mode, operands);")
3383
3384 (define_insn "*xor<mode>3"
3385   [(set (match_operand:SSEMODEI 0 "register_operand" "=x")
3386         (xor:SSEMODEI
3387           (match_operand:SSEMODEI 1 "nonimmediate_operand" "%0")
3388           (match_operand:SSEMODEI 2 "nonimmediate_operand" "xm")))]
3389   "TARGET_SSE2 && ix86_binary_operator_ok (XOR, <MODE>mode, operands)"
3390   "pxor\t{%2, %0|%0, %2}"
3391   [(set_attr "type" "sselog")
3392    (set_attr "mode" "TI")])
3393
3394 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3395 ;;
3396 ;; Parallel integral element swizzling
3397 ;;
3398 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3399
3400 ;; Reduce:
3401 ;;      op1 = abcdefghijklmnop
3402 ;;      op2 = qrstuvwxyz012345
3403 ;;       h1 = aqbrcsdteufvgwhx
3404 ;;       l1 = iyjzk0l1m2n3o4p5
3405 ;;       h2 = aiqybjrzcks0dlt1
3406 ;;       l2 = emu2fnv3gow4hpx5
3407 ;;       h3 = aeimquy2bfjnrvz3
3408 ;;       l3 = cgkosw04dhlptx15
3409 ;;   result = bdfhjlnprtvxz135
3410 (define_expand "vec_pack_mod_v8hi"
3411   [(match_operand:V16QI 0 "register_operand" "")
3412    (match_operand:V8HI 1 "register_operand" "")
3413    (match_operand:V8HI 2 "register_operand" "")]
3414   "TARGET_SSE2"
3415 {
3416   rtx op1, op2, h1, l1, h2, l2, h3, l3;
3417                                                                                 
3418   op1 = gen_lowpart (V16QImode, operands[1]);
3419   op2 = gen_lowpart (V16QImode, operands[2]);
3420   h1 = gen_reg_rtx (V16QImode);
3421   l1 = gen_reg_rtx (V16QImode);
3422   h2 = gen_reg_rtx (V16QImode);
3423   l2 = gen_reg_rtx (V16QImode);
3424   h3 = gen_reg_rtx (V16QImode);
3425   l3 = gen_reg_rtx (V16QImode);
3426                                                                                 
3427   emit_insn (gen_vec_interleave_highv16qi (h1, op1, op2));
3428   emit_insn (gen_vec_interleave_lowv16qi (l1, op1, op2));
3429   emit_insn (gen_vec_interleave_highv16qi (h2, l1, h1));
3430   emit_insn (gen_vec_interleave_lowv16qi (l2, l1, h1));
3431   emit_insn (gen_vec_interleave_highv16qi (h3, l2, h2));
3432   emit_insn (gen_vec_interleave_lowv16qi (l3, l2, h2));
3433   emit_insn (gen_vec_interleave_lowv16qi (operands[0], l3, h3));
3434   DONE;
3435 })
3436                                                                                 
3437 ;; Reduce:
3438 ;;      op1 = abcdefgh
3439 ;;      op2 = ijklmnop
3440 ;;       h1 = aibjckdl
3441 ;;       l1 = emfngohp
3442 ;;       h2 = aeimbfjn
3443 ;;       l2 = cgkodhlp
3444 ;;   result = bdfhjlnp
3445 (define_expand "vec_pack_mod_v4si"
3446   [(match_operand:V8HI 0 "register_operand" "")
3447    (match_operand:V4SI 1 "register_operand" "")
3448    (match_operand:V4SI 2 "register_operand" "")]
3449   "TARGET_SSE2"
3450 {
3451   rtx op1, op2, h1, l1, h2, l2;
3452                                                                                 
3453   op1 = gen_lowpart (V8HImode, operands[1]);
3454   op2 = gen_lowpart (V8HImode, operands[2]);
3455   h1 = gen_reg_rtx (V8HImode);
3456   l1 = gen_reg_rtx (V8HImode);
3457   h2 = gen_reg_rtx (V8HImode);
3458   l2 = gen_reg_rtx (V8HImode);
3459                                                                                 
3460   emit_insn (gen_vec_interleave_highv8hi (h1, op1, op2));
3461   emit_insn (gen_vec_interleave_lowv8hi (l1, op1, op2));
3462   emit_insn (gen_vec_interleave_highv8hi (h2, l1, h1));
3463   emit_insn (gen_vec_interleave_lowv8hi (l2, l1, h1));
3464   emit_insn (gen_vec_interleave_lowv8hi (operands[0], l2, h2));
3465   DONE;
3466 })
3467                                                                                 
3468 ;; Reduce:
3469 ;;     op1 = abcd
3470 ;;     op2 = efgh
3471 ;;      h1 = aebf
3472 ;;      l1 = cgdh
3473 ;;  result = bdfh
3474 (define_expand "vec_pack_mod_v2di"
3475   [(match_operand:V4SI 0 "register_operand" "")
3476    (match_operand:V2DI 1 "register_operand" "")
3477    (match_operand:V2DI 2 "register_operand" "")]
3478   "TARGET_SSE2"
3479 {
3480   rtx op1, op2, h1, l1;
3481                                                                                 
3482   op1 = gen_lowpart (V4SImode, operands[1]);
3483   op2 = gen_lowpart (V4SImode, operands[2]);
3484   h1 = gen_reg_rtx (V4SImode);
3485   l1 = gen_reg_rtx (V4SImode);
3486                                                                                 
3487   emit_insn (gen_vec_interleave_highv4si (h1, op1, op2));
3488   emit_insn (gen_vec_interleave_lowv4si (l1, op1, op2));
3489   emit_insn (gen_vec_interleave_lowv4si (operands[0], l1, h1));
3490   DONE;
3491 })
3492
3493 (define_expand "vec_interleave_highv16qi"
3494   [(set (match_operand:V16QI 0 "register_operand" "=x")
3495         (vec_select:V16QI
3496           (vec_concat:V32QI
3497             (match_operand:V16QI 1 "register_operand" "0")
3498             (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
3499           (parallel [(const_int 8)  (const_int 24)
3500                      (const_int 9)  (const_int 25)
3501                      (const_int 10) (const_int 26)
3502                      (const_int 11) (const_int 27)
3503                      (const_int 12) (const_int 28)
3504                      (const_int 13) (const_int 29)
3505                      (const_int 14) (const_int 30)
3506                      (const_int 15) (const_int 31)])))]
3507   "TARGET_SSE2"
3508 {
3509   emit_insn (gen_sse2_punpckhbw (operands[0], operands[1], operands[2]));
3510   DONE;
3511 })
3512
3513 (define_expand "vec_interleave_lowv16qi"
3514   [(set (match_operand:V16QI 0 "register_operand" "=x")
3515         (vec_select:V16QI
3516           (vec_concat:V32QI
3517             (match_operand:V16QI 1 "register_operand" "0")
3518             (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
3519           (parallel [(const_int 0) (const_int 16)
3520                      (const_int 1) (const_int 17)
3521                      (const_int 2) (const_int 18)
3522                      (const_int 3) (const_int 19)
3523                      (const_int 4) (const_int 20)
3524                      (const_int 5) (const_int 21)
3525                      (const_int 6) (const_int 22)
3526                      (const_int 7) (const_int 23)])))]
3527   "TARGET_SSE2"
3528 {
3529   emit_insn (gen_sse2_punpcklbw (operands[0], operands[1], operands[2]));
3530   DONE;
3531 })
3532
3533 (define_expand "vec_interleave_highv8hi"
3534   [(set (match_operand:V8HI 0 "register_operand" "=x")
3535         (vec_select:V8HI
3536           (vec_concat:V16HI
3537             (match_operand:V8HI 1 "register_operand" "0")
3538             (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
3539           (parallel [(const_int 4) (const_int 12)
3540                      (const_int 5) (const_int 13)
3541                      (const_int 6) (const_int 14)
3542                      (const_int 7) (const_int 15)])))]
3543   "TARGET_SSE2"
3544 {
3545   emit_insn (gen_sse2_punpckhwd (operands[0], operands[1], operands[2]));
3546   DONE;
3547 })
3548
3549 (define_expand "vec_interleave_lowv8hi"
3550   [(set (match_operand:V8HI 0 "register_operand" "=x")
3551         (vec_select:V8HI
3552           (vec_concat:V16HI
3553             (match_operand:V8HI 1 "register_operand" "0")
3554             (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
3555           (parallel [(const_int 0) (const_int 8)
3556                      (const_int 1) (const_int 9)
3557                      (const_int 2) (const_int 10)
3558                      (const_int 3) (const_int 11)])))]
3559   "TARGET_SSE2"
3560 {
3561   emit_insn (gen_sse2_punpcklwd (operands[0], operands[1], operands[2]));
3562   DONE;
3563 })
3564
3565 (define_expand "vec_interleave_highv4si"
3566   [(set (match_operand:V4SI 0 "register_operand" "=x")
3567         (vec_select:V4SI
3568           (vec_concat:V8SI
3569             (match_operand:V4SI 1 "register_operand" "0")
3570             (match_operand:V4SI 2 "nonimmediate_operand" "xm"))
3571           (parallel [(const_int 2) (const_int 6)
3572                      (const_int 3) (const_int 7)])))]
3573   "TARGET_SSE2"
3574 {
3575   emit_insn (gen_sse2_punpckhdq (operands[0], operands[1], operands[2]));
3576   DONE;
3577 })
3578
3579 (define_expand "vec_interleave_lowv4si"
3580   [(set (match_operand:V4SI 0 "register_operand" "=x")
3581         (vec_select:V4SI
3582           (vec_concat:V8SI
3583             (match_operand:V4SI 1 "register_operand" "0")
3584             (match_operand:V4SI 2 "nonimmediate_operand" "xm"))
3585           (parallel [(const_int 0) (const_int 4)
3586                      (const_int 1) (const_int 5)])))]
3587   "TARGET_SSE2"
3588 {
3589   emit_insn (gen_sse2_punpckldq (operands[0], operands[1], operands[2]));
3590   DONE;
3591 })
3592
3593 (define_expand "vec_interleave_highv2di"
3594   [(set (match_operand:V2DI 0 "register_operand" "=x")
3595         (vec_select:V2DI
3596           (vec_concat:V4DI
3597             (match_operand:V2DI 1 "register_operand" "0")
3598             (match_operand:V2DI 2 "nonimmediate_operand" "xm"))
3599           (parallel [(const_int 1)
3600                      (const_int 3)])))]
3601   "TARGET_SSE2"
3602 {
3603   emit_insn (gen_sse2_punpckhqdq (operands[0], operands[1], operands[2]));
3604   DONE;
3605 })
3606
3607 (define_expand "vec_interleave_lowv2di"
3608   [(set (match_operand:V2DI 0 "register_operand" "=x")
3609         (vec_select:V2DI
3610           (vec_concat:V4DI
3611             (match_operand:V2DI 1 "register_operand" "0")
3612             (match_operand:V2DI 2 "nonimmediate_operand" "xm"))
3613           (parallel [(const_int 0)
3614                      (const_int 2)])))]
3615   "TARGET_SSE2"
3616 {
3617   emit_insn (gen_sse2_punpcklqdq (operands[0], operands[1], operands[2]));
3618   DONE;
3619 })
3620
3621 (define_insn "sse2_packsswb"
3622   [(set (match_operand:V16QI 0 "register_operand" "=x")
3623         (vec_concat:V16QI
3624           (ss_truncate:V8QI
3625             (match_operand:V8HI 1 "register_operand" "0"))
3626           (ss_truncate:V8QI
3627             (match_operand:V8HI 2 "nonimmediate_operand" "xm"))))]
3628   "TARGET_SSE2"
3629   "packsswb\t{%2, %0|%0, %2}"
3630   [(set_attr "type" "sselog")
3631    (set_attr "mode" "TI")])
3632
3633 (define_insn "sse2_packssdw"
3634   [(set (match_operand:V8HI 0 "register_operand" "=x")
3635         (vec_concat:V8HI
3636           (ss_truncate:V4HI
3637             (match_operand:V4SI 1 "register_operand" "0"))
3638           (ss_truncate:V4HI
3639             (match_operand:V4SI 2 "nonimmediate_operand" "xm"))))]
3640   "TARGET_SSE2"
3641   "packssdw\t{%2, %0|%0, %2}"
3642   [(set_attr "type" "sselog")
3643    (set_attr "mode" "TI")])
3644
3645 (define_insn "sse2_packuswb"
3646   [(set (match_operand:V16QI 0 "register_operand" "=x")
3647         (vec_concat:V16QI
3648           (us_truncate:V8QI
3649             (match_operand:V8HI 1 "register_operand" "0"))
3650           (us_truncate:V8QI
3651             (match_operand:V8HI 2 "nonimmediate_operand" "xm"))))]
3652   "TARGET_SSE2"
3653   "packuswb\t{%2, %0|%0, %2}"
3654   [(set_attr "type" "sselog")
3655    (set_attr "mode" "TI")])
3656
3657 (define_insn "sse2_punpckhbw"
3658   [(set (match_operand:V16QI 0 "register_operand" "=x")
3659         (vec_select:V16QI
3660           (vec_concat:V32QI
3661             (match_operand:V16QI 1 "register_operand" "0")
3662             (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
3663           (parallel [(const_int 8)  (const_int 24)
3664                      (const_int 9)  (const_int 25)
3665                      (const_int 10) (const_int 26)
3666                      (const_int 11) (const_int 27)
3667                      (const_int 12) (const_int 28) 
3668                      (const_int 13) (const_int 29)
3669                      (const_int 14) (const_int 30)
3670                      (const_int 15) (const_int 31)])))]
3671   "TARGET_SSE2"
3672   "punpckhbw\t{%2, %0|%0, %2}"
3673   [(set_attr "type" "sselog")
3674    (set_attr "mode" "TI")])
3675
3676 (define_insn "sse2_punpcklbw"
3677   [(set (match_operand:V16QI 0 "register_operand" "=x")
3678         (vec_select:V16QI
3679           (vec_concat:V32QI
3680             (match_operand:V16QI 1 "register_operand" "0")
3681             (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
3682           (parallel [(const_int 0) (const_int 16)
3683                      (const_int 1) (const_int 17)
3684                      (const_int 2) (const_int 18)
3685                      (const_int 3) (const_int 19)
3686                      (const_int 4) (const_int 20)
3687                      (const_int 5) (const_int 21)
3688                      (const_int 6) (const_int 22)
3689                      (const_int 7) (const_int 23)])))]
3690   "TARGET_SSE2"
3691   "punpcklbw\t{%2, %0|%0, %2}"
3692   [(set_attr "type" "sselog")
3693    (set_attr "mode" "TI")])
3694
3695 (define_insn "sse2_punpckhwd"
3696   [(set (match_operand:V8HI 0 "register_operand" "=x")
3697         (vec_select:V8HI
3698           (vec_concat:V16HI
3699             (match_operand:V8HI 1 "register_operand" "0")
3700             (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
3701           (parallel [(const_int 4) (const_int 12)
3702                      (const_int 5) (const_int 13)
3703                      (const_int 6) (const_int 14)
3704                      (const_int 7) (const_int 15)])))]
3705   "TARGET_SSE2"
3706   "punpckhwd\t{%2, %0|%0, %2}"
3707   [(set_attr "type" "sselog")
3708    (set_attr "mode" "TI")])
3709
3710 (define_insn "sse2_punpcklwd"
3711   [(set (match_operand:V8HI 0 "register_operand" "=x")
3712         (vec_select:V8HI
3713           (vec_concat:V16HI
3714             (match_operand:V8HI 1 "register_operand" "0")
3715             (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
3716           (parallel [(const_int 0) (const_int 8)
3717                      (const_int 1) (const_int 9)
3718                      (const_int 2) (const_int 10)
3719                      (const_int 3) (const_int 11)])))]
3720   "TARGET_SSE2"
3721   "punpcklwd\t{%2, %0|%0, %2}"
3722   [(set_attr "type" "sselog")
3723    (set_attr "mode" "TI")])
3724
3725 (define_insn "sse2_punpckhdq"
3726   [(set (match_operand:V4SI 0 "register_operand" "=x")
3727         (vec_select:V4SI
3728           (vec_concat:V8SI
3729             (match_operand:V4SI 1 "register_operand" "0")
3730             (match_operand:V4SI 2 "nonimmediate_operand" "xm"))
3731           (parallel [(const_int 2) (const_int 6)
3732                      (const_int 3) (const_int 7)])))]
3733   "TARGET_SSE2"
3734   "punpckhdq\t{%2, %0|%0, %2}"
3735   [(set_attr "type" "sselog")
3736    (set_attr "mode" "TI")])
3737
3738 (define_insn "sse2_punpckldq"
3739   [(set (match_operand:V4SI 0 "register_operand" "=x")
3740         (vec_select:V4SI
3741           (vec_concat:V8SI
3742             (match_operand:V4SI 1 "register_operand" "0")
3743             (match_operand:V4SI 2 "nonimmediate_operand" "xm"))
3744           (parallel [(const_int 0) (const_int 4)
3745                      (const_int 1) (const_int 5)])))]
3746   "TARGET_SSE2"
3747   "punpckldq\t{%2, %0|%0, %2}"
3748   [(set_attr "type" "sselog")
3749    (set_attr "mode" "TI")])
3750
3751 (define_insn "sse2_punpckhqdq"
3752   [(set (match_operand:V2DI 0 "register_operand" "=x")
3753         (vec_select:V2DI
3754           (vec_concat:V4DI
3755             (match_operand:V2DI 1 "register_operand" "0")
3756             (match_operand:V2DI 2 "nonimmediate_operand" "xm"))
3757           (parallel [(const_int 1)
3758                      (const_int 3)])))]
3759   "TARGET_SSE2"
3760   "punpckhqdq\t{%2, %0|%0, %2}"
3761   [(set_attr "type" "sselog")
3762    (set_attr "mode" "TI")])
3763
3764 (define_insn "sse2_punpcklqdq"
3765   [(set (match_operand:V2DI 0 "register_operand" "=x")
3766         (vec_select:V2DI
3767           (vec_concat:V4DI
3768             (match_operand:V2DI 1 "register_operand" "0")
3769             (match_operand:V2DI 2 "nonimmediate_operand" "xm"))
3770           (parallel [(const_int 0)
3771                      (const_int 2)])))]
3772   "TARGET_SSE2"
3773   "punpcklqdq\t{%2, %0|%0, %2}"
3774   [(set_attr "type" "sselog")
3775    (set_attr "mode" "TI")])
3776
3777 (define_expand "sse2_pinsrw"
3778   [(set (match_operand:V8HI 0 "register_operand" "")
3779         (vec_merge:V8HI
3780           (vec_duplicate:V8HI
3781             (match_operand:SI 2 "nonimmediate_operand" ""))
3782           (match_operand:V8HI 1 "register_operand" "")
3783           (match_operand:SI 3 "const_0_to_7_operand" "")))]
3784   "TARGET_SSE2"
3785 {
3786   operands[2] = gen_lowpart (HImode, operands[2]);
3787   operands[3] = GEN_INT ((1 << INTVAL (operands[3])));
3788 })
3789
3790 (define_insn "*sse2_pinsrw"
3791   [(set (match_operand:V8HI 0 "register_operand" "=x")
3792         (vec_merge:V8HI
3793           (vec_duplicate:V8HI
3794             (match_operand:HI 2 "nonimmediate_operand" "rm"))
3795           (match_operand:V8HI 1 "register_operand" "0")
3796           (match_operand:SI 3 "const_pow2_1_to_128_operand" "n")))]
3797   "TARGET_SSE2"
3798 {
3799   operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
3800   return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}";
3801 }
3802   [(set_attr "type" "sselog")
3803    (set_attr "mode" "TI")])
3804
3805 (define_insn "sse2_pextrw"
3806   [(set (match_operand:SI 0 "register_operand" "=r")
3807         (zero_extend:SI
3808           (vec_select:HI
3809             (match_operand:V8HI 1 "register_operand" "x")
3810             (parallel [(match_operand:SI 2 "const_0_to_7_operand" "n")]))))]
3811   "TARGET_SSE2"
3812   "pextrw\t{%2, %1, %0|%0, %1, %2}"
3813   [(set_attr "type" "sselog")
3814    (set_attr "mode" "TI")])
3815
3816 (define_expand "sse2_pshufd"
3817   [(match_operand:V4SI 0 "register_operand" "")
3818    (match_operand:V4SI 1 "nonimmediate_operand" "")
3819    (match_operand:SI 2 "const_int_operand" "")]
3820   "TARGET_SSE2"
3821 {
3822   int mask = INTVAL (operands[2]);
3823   emit_insn (gen_sse2_pshufd_1 (operands[0], operands[1],
3824                                 GEN_INT ((mask >> 0) & 3),
3825                                 GEN_INT ((mask >> 2) & 3),
3826                                 GEN_INT ((mask >> 4) & 3),
3827                                 GEN_INT ((mask >> 6) & 3)));
3828   DONE;
3829 })
3830
3831 (define_insn "sse2_pshufd_1"
3832   [(set (match_operand:V4SI 0 "register_operand" "=x")
3833         (vec_select:V4SI
3834           (match_operand:V4SI 1 "nonimmediate_operand" "xm")
3835           (parallel [(match_operand 2 "const_0_to_3_operand" "")
3836                      (match_operand 3 "const_0_to_3_operand" "")
3837                      (match_operand 4 "const_0_to_3_operand" "")
3838                      (match_operand 5 "const_0_to_3_operand" "")])))]
3839   "TARGET_SSE2"
3840 {
3841   int mask = 0;
3842   mask |= INTVAL (operands[2]) << 0;
3843   mask |= INTVAL (operands[3]) << 2;
3844   mask |= INTVAL (operands[4]) << 4;
3845   mask |= INTVAL (operands[5]) << 6;
3846   operands[2] = GEN_INT (mask);
3847
3848   return "pshufd\t{%2, %1, %0|%0, %1, %2}";
3849 }
3850   [(set_attr "type" "sselog1")
3851    (set_attr "mode" "TI")])
3852
3853 (define_expand "sse2_pshuflw"
3854   [(match_operand:V8HI 0 "register_operand" "")
3855    (match_operand:V8HI 1 "nonimmediate_operand" "")
3856    (match_operand:SI 2 "const_int_operand" "")]
3857   "TARGET_SSE2"
3858 {
3859   int mask = INTVAL (operands[2]);
3860   emit_insn (gen_sse2_pshuflw_1 (operands[0], operands[1],
3861                                  GEN_INT ((mask >> 0) & 3),
3862                                  GEN_INT ((mask >> 2) & 3),
3863                                  GEN_INT ((mask >> 4) & 3),
3864                                  GEN_INT ((mask >> 6) & 3)));
3865   DONE;
3866 })
3867
3868 (define_insn "sse2_pshuflw_1"
3869   [(set (match_operand:V8HI 0 "register_operand" "=x")
3870         (vec_select:V8HI
3871           (match_operand:V8HI 1 "nonimmediate_operand" "xm")
3872           (parallel [(match_operand 2 "const_0_to_3_operand" "")
3873                      (match_operand 3 "const_0_to_3_operand" "")
3874                      (match_operand 4 "const_0_to_3_operand" "")
3875                      (match_operand 5 "const_0_to_3_operand" "")
3876                      (const_int 4)
3877                      (const_int 5)
3878                      (const_int 6)
3879                      (const_int 7)])))]
3880   "TARGET_SSE2"
3881 {
3882   int mask = 0;
3883   mask |= INTVAL (operands[2]) << 0;
3884   mask |= INTVAL (operands[3]) << 2;
3885   mask |= INTVAL (operands[4]) << 4;
3886   mask |= INTVAL (operands[5]) << 6;
3887   operands[2] = GEN_INT (mask);
3888
3889   return "pshuflw\t{%2, %1, %0|%0, %1, %2}";
3890 }
3891   [(set_attr "type" "sselog")
3892    (set_attr "mode" "TI")])
3893
3894 (define_expand "sse2_pshufhw"
3895   [(match_operand:V8HI 0 "register_operand" "")
3896    (match_operand:V8HI 1 "nonimmediate_operand" "")
3897    (match_operand:SI 2 "const_int_operand" "")]
3898   "TARGET_SSE2"
3899 {
3900   int mask = INTVAL (operands[2]);
3901   emit_insn (gen_sse2_pshufhw_1 (operands[0], operands[1],
3902                                  GEN_INT (((mask >> 0) & 3) + 4),
3903                                  GEN_INT (((mask >> 2) & 3) + 4),
3904                                  GEN_INT (((mask >> 4) & 3) + 4),
3905                                  GEN_INT (((mask >> 6) & 3) + 4)));
3906   DONE;
3907 })
3908
3909 (define_insn "sse2_pshufhw_1"
3910   [(set (match_operand:V8HI 0 "register_operand" "=x")
3911         (vec_select:V8HI
3912           (match_operand:V8HI 1 "nonimmediate_operand" "xm")
3913           (parallel [(const_int 0)
3914                      (const_int 1)
3915                      (const_int 2)
3916                      (const_int 3)
3917                      (match_operand 2 "const_4_to_7_operand" "")
3918                      (match_operand 3 "const_4_to_7_operand" "")
3919                      (match_operand 4 "const_4_to_7_operand" "")
3920                      (match_operand 5 "const_4_to_7_operand" "")])))]
3921   "TARGET_SSE2"
3922 {
3923   int mask = 0;
3924   mask |= (INTVAL (operands[2]) - 4) << 0;
3925   mask |= (INTVAL (operands[3]) - 4) << 2;
3926   mask |= (INTVAL (operands[4]) - 4) << 4;
3927   mask |= (INTVAL (operands[5]) - 4) << 6;
3928   operands[2] = GEN_INT (mask);
3929
3930   return "pshufhw\t{%2, %1, %0|%0, %1, %2}";
3931 }
3932   [(set_attr "type" "sselog")
3933    (set_attr "mode" "TI")])
3934
3935 (define_expand "sse2_loadd"
3936   [(set (match_operand:V4SI 0 "register_operand" "")
3937         (vec_merge:V4SI
3938           (vec_duplicate:V4SI
3939             (match_operand:SI 1 "nonimmediate_operand" ""))
3940           (match_dup 2)
3941           (const_int 1)))]
3942   "TARGET_SSE"
3943   "operands[2] = CONST0_RTX (V4SImode);")
3944
3945 (define_insn "sse2_loadld"
3946   [(set (match_operand:V4SI 0 "register_operand"       "=Y,x,x")
3947         (vec_merge:V4SI
3948           (vec_duplicate:V4SI
3949             (match_operand:SI 2 "nonimmediate_operand" "mr,m,x"))
3950           (match_operand:V4SI 1 "reg_or_0_operand"     " C,C,0")
3951           (const_int 1)))]
3952   "TARGET_SSE"
3953   "@
3954    movd\t{%2, %0|%0, %2}
3955    movss\t{%2, %0|%0, %2}
3956    movss\t{%2, %0|%0, %2}"
3957   [(set_attr "type" "ssemov")
3958    (set_attr "mode" "TI,V4SF,SF")])
3959
3960 ;; ??? The hardware supports more, but TARGET_INTER_UNIT_MOVES must
3961 ;; be taken into account, and movdi isn't fully populated even without.
3962 (define_insn_and_split "sse2_stored"
3963   [(set (match_operand:SI 0 "nonimmediate_operand" "=mx")
3964         (vec_select:SI
3965           (match_operand:V4SI 1 "register_operand" "x")
3966           (parallel [(const_int 0)])))]
3967   "TARGET_SSE"
3968   "#"
3969   "&& reload_completed"
3970   [(set (match_dup 0) (match_dup 1))]
3971 {
3972   operands[1] = gen_rtx_REG (SImode, REGNO (operands[1]));
3973 })
3974
3975 (define_expand "sse_storeq"
3976   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3977         (vec_select:DI
3978           (match_operand:V2DI 1 "register_operand" "")
3979           (parallel [(const_int 0)])))]
3980   "TARGET_SSE"
3981   "")
3982
3983 ;; ??? The hardware supports more, but TARGET_INTER_UNIT_MOVES must
3984 ;; be taken into account, and movdi isn't fully populated even without.
3985 (define_insn "*sse2_storeq"
3986   [(set (match_operand:DI 0 "nonimmediate_operand" "=mx")
3987         (vec_select:DI
3988           (match_operand:V2DI 1 "register_operand" "x")
3989           (parallel [(const_int 0)])))]
3990   "TARGET_SSE"
3991   "#")
3992
3993 (define_split
3994   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3995         (vec_select:DI
3996           (match_operand:V2DI 1 "register_operand" "")
3997           (parallel [(const_int 0)])))]
3998   "TARGET_SSE && reload_completed"
3999   [(set (match_dup 0) (match_dup 1))]
4000 {
4001   operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));
4002 })
4003
4004 (define_insn "*vec_extractv2di_1_sse2"
4005   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,x,x")
4006         (vec_select:DI
4007           (match_operand:V2DI 1 "nonimmediate_operand" "x,0,o")
4008           (parallel [(const_int 1)])))]
4009   "TARGET_SSE2 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
4010   "@
4011    movhps\t{%1, %0|%0, %1}
4012    psrldq\t{$4, %0|%0, 4}
4013    movq\t{%H1, %0|%0, %H1}"
4014   [(set_attr "type" "ssemov,sseishft,ssemov")
4015    (set_attr "mode" "V2SF,TI,TI")])
4016
4017 ;; Not sure this is ever used, but it doesn't hurt to have it. -aoliva
4018 (define_insn "*vec_extractv2di_1_sse"
4019   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,x,x")
4020         (vec_select:DI
4021           (match_operand:V2DI 1 "nonimmediate_operand" "x,x,o")
4022           (parallel [(const_int 1)])))]
4023   "!TARGET_SSE2 && TARGET_SSE
4024    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
4025   "@
4026    movhps\t{%1, %0|%0, %1}
4027    movhlps\t{%1, %0|%0, %1}
4028    movlps\t{%H1, %0|%0, %H1}"
4029   [(set_attr "type" "ssemov")
4030    (set_attr "mode" "V2SF,V4SF,V2SF")])
4031
4032 (define_insn "*vec_dupv4si"
4033   [(set (match_operand:V4SI 0 "register_operand" "=Y,x")
4034         (vec_duplicate:V4SI
4035           (match_operand:SI 1 "register_operand" " Y,0")))]
4036   "TARGET_SSE"
4037   "@
4038    pshufd\t{$0, %1, %0|%0, %1, 0}
4039    shufps\t{$0, %0, %0|%0, %0, 0}"
4040   [(set_attr "type" "sselog1")
4041    (set_attr "mode" "TI,V4SF")])
4042
4043 (define_insn "*vec_dupv2di"
4044   [(set (match_operand:V2DI 0 "register_operand" "=Y,x")
4045         (vec_duplicate:V2DI
4046           (match_operand:DI 1 "register_operand" " 0,0")))]
4047   "TARGET_SSE"
4048   "@
4049    punpcklqdq\t%0, %0
4050    movlhps\t%0, %0"
4051   [(set_attr "type" "sselog1,ssemov")
4052    (set_attr "mode" "TI,V4SF")])
4053
4054 ;; ??? In theory we can match memory for the MMX alternative, but allowing
4055 ;; nonimmediate_operand for operand 2 and *not* allowing memory for the SSE
4056 ;; alternatives pretty much forces the MMX alternative to be chosen.
4057 (define_insn "*sse2_concatv2si"
4058   [(set (match_operand:V2SI 0 "register_operand"     "=Y, Y,*y,*y")
4059         (vec_concat:V2SI
4060           (match_operand:SI 1 "nonimmediate_operand" " 0,rm, 0,rm")
4061           (match_operand:SI 2 "reg_or_0_operand"     " Y, C,*y, C")))]
4062   "TARGET_SSE2"
4063   "@
4064    punpckldq\t{%2, %0|%0, %2}
4065    movd\t{%1, %0|%0, %1}
4066    punpckldq\t{%2, %0|%0, %2}
4067    movd\t{%1, %0|%0, %1}"
4068   [(set_attr "type" "sselog,ssemov,mmxcvt,mmxmov")
4069    (set_attr "mode" "TI,TI,DI,DI")])
4070
4071 (define_insn "*sse1_concatv2si"
4072   [(set (match_operand:V2SI 0 "register_operand"     "=x,x,*y,*y")
4073         (vec_concat:V2SI
4074           (match_operand:SI 1 "nonimmediate_operand" " 0,m, 0,*rm")
4075           (match_operand:SI 2 "reg_or_0_operand"     " x,C,*y,C")))]
4076   "TARGET_SSE"
4077   "@
4078    unpcklps\t{%2, %0|%0, %2}
4079    movss\t{%1, %0|%0, %1}
4080    punpckldq\t{%2, %0|%0, %2}
4081    movd\t{%1, %0|%0, %1}"
4082   [(set_attr "type" "sselog,ssemov,mmxcvt,mmxmov")
4083    (set_attr "mode" "V4SF,V4SF,DI,DI")])
4084
4085 (define_insn "*vec_concatv4si_1"
4086   [(set (match_operand:V4SI 0 "register_operand"       "=Y,x,x")
4087         (vec_concat:V4SI
4088           (match_operand:V2SI 1 "register_operand"     " 0,0,0")
4089           (match_operand:V2SI 2 "nonimmediate_operand" " Y,x,m")))]
4090   "TARGET_SSE"
4091   "@
4092    punpcklqdq\t{%2, %0|%0, %2}
4093    movlhps\t{%2, %0|%0, %2}
4094    movhps\t{%2, %0|%0, %2}"
4095   [(set_attr "type" "sselog,ssemov,ssemov")
4096    (set_attr "mode" "TI,V4SF,V2SF")])
4097
4098 (define_insn "*vec_concatv2di"
4099   [(set (match_operand:V2DI 0 "register_operand"     "=Y,?Y,Y,x,x,x")
4100         (vec_concat:V2DI
4101           (match_operand:DI 1 "nonimmediate_operand" " m,*y,0,0,0,m")
4102           (match_operand:DI 2 "vector_move_operand"  " C, C,Y,x,m,0")))]
4103   "TARGET_SSE"
4104   "@
4105    movq\t{%1, %0|%0, %1}
4106    movq2dq\t{%1, %0|%0, %1}
4107    punpcklqdq\t{%2, %0|%0, %2}
4108    movlhps\t{%2, %0|%0, %2}
4109    movhps\t{%2, %0|%0, %2}
4110    movlps\t{%1, %0|%0, %1}"
4111   [(set_attr "type" "ssemov,ssemov,sselog,ssemov,ssemov,ssemov")
4112    (set_attr "mode" "TI,TI,TI,V4SF,V2SF,V2SF")])
4113
4114 (define_expand "vec_setv2di"
4115   [(match_operand:V2DI 0 "register_operand" "")
4116    (match_operand:DI 1 "register_operand" "")
4117    (match_operand 2 "const_int_operand" "")]
4118   "TARGET_SSE"
4119 {
4120   ix86_expand_vector_set (false, operands[0], operands[1],
4121                           INTVAL (operands[2]));
4122   DONE;
4123 })
4124
4125 (define_expand "vec_extractv2di"
4126   [(match_operand:DI 0 "register_operand" "")
4127    (match_operand:V2DI 1 "register_operand" "")
4128    (match_operand 2 "const_int_operand" "")]
4129   "TARGET_SSE"
4130 {
4131   ix86_expand_vector_extract (false, operands[0], operands[1],
4132                               INTVAL (operands[2]));
4133   DONE;
4134 })
4135
4136 (define_expand "vec_initv2di"
4137   [(match_operand:V2DI 0 "register_operand" "")
4138    (match_operand 1 "" "")]
4139   "TARGET_SSE"
4140 {
4141   ix86_expand_vector_init (false, operands[0], operands[1]);
4142   DONE;
4143 })
4144
4145 (define_expand "vec_setv4si"
4146   [(match_operand:V4SI 0 "register_operand" "")
4147    (match_operand:SI 1 "register_operand" "")
4148    (match_operand 2 "const_int_operand" "")]
4149   "TARGET_SSE"
4150 {
4151   ix86_expand_vector_set (false, operands[0], operands[1],
4152                           INTVAL (operands[2]));
4153   DONE;
4154 })
4155
4156 (define_expand "vec_extractv4si"
4157   [(match_operand:SI 0 "register_operand" "")
4158    (match_operand:V4SI 1 "register_operand" "")
4159    (match_operand 2 "const_int_operand" "")]
4160   "TARGET_SSE"
4161 {
4162   ix86_expand_vector_extract (false, operands[0], operands[1],
4163                               INTVAL (operands[2]));
4164   DONE;
4165 })
4166
4167 (define_expand "vec_initv4si"
4168   [(match_operand:V4SI 0 "register_operand" "")
4169    (match_operand 1 "" "")]
4170   "TARGET_SSE"
4171 {
4172   ix86_expand_vector_init (false, operands[0], operands[1]);
4173   DONE;
4174 })
4175
4176 (define_expand "vec_setv8hi"
4177   [(match_operand:V8HI 0 "register_operand" "")
4178    (match_operand:HI 1 "register_operand" "")
4179    (match_operand 2 "const_int_operand" "")]
4180   "TARGET_SSE"
4181 {
4182   ix86_expand_vector_set (false, operands[0], operands[1],
4183                           INTVAL (operands[2]));
4184   DONE;
4185 })
4186
4187 (define_expand "vec_extractv8hi"
4188   [(match_operand:HI 0 "register_operand" "")
4189    (match_operand:V8HI 1 "register_operand" "")
4190    (match_operand 2 "const_int_operand" "")]
4191   "TARGET_SSE"
4192 {
4193   ix86_expand_vector_extract (false, operands[0], operands[1],
4194                               INTVAL (operands[2]));
4195   DONE;
4196 })
4197
4198 (define_expand "vec_initv8hi"
4199   [(match_operand:V8HI 0 "register_operand" "")
4200    (match_operand 1 "" "")]
4201   "TARGET_SSE"
4202 {
4203   ix86_expand_vector_init (false, operands[0], operands[1]);
4204   DONE;
4205 })
4206
4207 (define_expand "vec_setv16qi"
4208   [(match_operand:V16QI 0 "register_operand" "")
4209    (match_operand:QI 1 "register_operand" "")
4210    (match_operand 2 "const_int_operand" "")]
4211   "TARGET_SSE"
4212 {
4213   ix86_expand_vector_set (false, operands[0], operands[1],
4214                           INTVAL (operands[2]));
4215   DONE;
4216 })
4217
4218 (define_expand "vec_extractv16qi"
4219   [(match_operand:QI 0 "register_operand" "")
4220    (match_operand:V16QI 1 "register_operand" "")
4221    (match_operand 2 "const_int_operand" "")]
4222   "TARGET_SSE"
4223 {
4224   ix86_expand_vector_extract (false, operands[0], operands[1],
4225                               INTVAL (operands[2]));
4226   DONE;
4227 })
4228
4229 (define_expand "vec_initv16qi"
4230   [(match_operand:V16QI 0 "register_operand" "")
4231    (match_operand 1 "" "")]
4232   "TARGET_SSE"
4233 {
4234   ix86_expand_vector_init (false, operands[0], operands[1]);
4235   DONE;
4236 })
4237
4238 (define_expand "vec_unpacku_hi_v16qi"
4239   [(match_operand:V8HI 0 "register_operand" "")
4240    (match_operand:V16QI 1 "register_operand" "")]
4241   "TARGET_SSE2"
4242 {
4243   ix86_expand_sse_unpack (operands, true, true);
4244   DONE;
4245 })
4246
4247 (define_expand "vec_unpacks_hi_v16qi"
4248   [(match_operand:V8HI 0 "register_operand" "")
4249    (match_operand:V16QI 1 "register_operand" "")]
4250   "TARGET_SSE2"
4251 {
4252   ix86_expand_sse_unpack (operands, false, true);
4253   DONE;
4254 })
4255
4256 (define_expand "vec_unpacku_lo_v16qi"
4257   [(match_operand:V8HI 0 "register_operand" "")
4258    (match_operand:V16QI 1 "register_operand" "")]
4259   "TARGET_SSE2"
4260 {
4261   ix86_expand_sse_unpack (operands, true, false);
4262   DONE;
4263 })
4264
4265 (define_expand "vec_unpacks_lo_v16qi"
4266   [(match_operand:V8HI 0 "register_operand" "")
4267    (match_operand:V16QI 1 "register_operand" "")]
4268   "TARGET_SSE2"
4269 {
4270   ix86_expand_sse_unpack (operands, false, false);
4271   DONE;
4272 })
4273
4274 (define_expand "vec_unpacku_hi_v8hi"
4275   [(match_operand:V4SI 0 "register_operand" "")
4276    (match_operand:V8HI 1 "register_operand" "")]
4277   "TARGET_SSE2"
4278 {
4279   ix86_expand_sse_unpack (operands, true, true);
4280   DONE;
4281 })
4282
4283 (define_expand "vec_unpacks_hi_v8hi"
4284   [(match_operand:V4SI 0 "register_operand" "")
4285    (match_operand:V8HI 1 "register_operand" "")]
4286   "TARGET_SSE2"
4287 {
4288   ix86_expand_sse_unpack (operands, false, true);
4289   DONE;
4290 })
4291
4292 (define_expand "vec_unpacku_lo_v8hi"
4293   [(match_operand:V4SI 0 "register_operand" "")
4294    (match_operand:V8HI 1 "register_operand" "")]
4295   "TARGET_SSE2"
4296 {
4297   ix86_expand_sse_unpack (operands, true, false);
4298   DONE;
4299 })
4300
4301 (define_expand "vec_unpacks_lo_v8hi"
4302   [(match_operand:V4SI 0 "register_operand" "")
4303    (match_operand:V8HI 1 "register_operand" "")]
4304   "TARGET_SSE2"
4305 {
4306   ix86_expand_sse_unpack (operands, false, false);
4307   DONE;
4308 })
4309
4310 (define_expand "vec_unpacku_hi_v4si"
4311   [(match_operand:V2DI 0 "register_operand" "")
4312    (match_operand:V4SI 1 "register_operand" "")]
4313   "TARGET_SSE2"
4314 {
4315   ix86_expand_sse_unpack (operands, true, true);
4316   DONE;
4317 })
4318
4319 (define_expand "vec_unpacks_hi_v4si"
4320   [(match_operand:V2DI 0 "register_operand" "")
4321    (match_operand:V4SI 1 "register_operand" "")]
4322   "TARGET_SSE2"
4323 {
4324   ix86_expand_sse_unpack (operands, false, true);
4325   DONE;
4326 })
4327
4328 (define_expand "vec_unpacku_lo_v4si"
4329   [(match_operand:V2DI 0 "register_operand" "")
4330    (match_operand:V4SI 1 "register_operand" "")]
4331   "TARGET_SSE2"
4332 {
4333   ix86_expand_sse_unpack (operands, true, false);
4334   DONE;
4335 })
4336
4337 (define_expand "vec_unpacks_lo_v4si"
4338   [(match_operand:V2DI 0 "register_operand" "")
4339    (match_operand:V4SI 1 "register_operand" "")]
4340   "TARGET_SSE2"
4341 {
4342   ix86_expand_sse_unpack (operands, false, false);
4343   DONE;
4344 })
4345
4346 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4347 ;;
4348 ;; Miscellaneous
4349 ;;
4350 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4351
4352 (define_insn "sse2_uavgv16qi3"
4353   [(set (match_operand:V16QI 0 "register_operand" "=x")
4354         (truncate:V16QI
4355           (lshiftrt:V16HI
4356             (plus:V16HI
4357               (plus:V16HI
4358                 (zero_extend:V16HI
4359                   (match_operand:V16QI 1 "nonimmediate_operand" "%0"))
4360                 (zero_extend:V16HI
4361                   (match_operand:V16QI 2 "nonimmediate_operand" "xm")))
4362               (const_vector:V16QI [(const_int 1) (const_int 1)
4363                                    (const_int 1) (const_int 1)
4364                                    (const_int 1) (const_int 1)
4365                                    (const_int 1) (const_int 1)
4366                                    (const_int 1) (const_int 1)
4367                                    (const_int 1) (const_int 1)
4368                                    (const_int 1) (const_int 1)
4369                                    (const_int 1) (const_int 1)]))
4370             (const_int 1))))]
4371   "TARGET_SSE2 && ix86_binary_operator_ok (PLUS, V16QImode, operands)"
4372   "pavgb\t{%2, %0|%0, %2}"
4373   [(set_attr "type" "sseiadd")
4374    (set_attr "mode" "TI")])
4375
4376 (define_insn "sse2_uavgv8hi3"
4377   [(set (match_operand:V8HI 0 "register_operand" "=x")
4378         (truncate:V8HI
4379           (lshiftrt:V8SI
4380             (plus:V8SI
4381               (plus:V8SI
4382                 (zero_extend:V8SI
4383                   (match_operand:V8HI 1 "nonimmediate_operand" "%0"))
4384                 (zero_extend:V8SI
4385                   (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
4386               (const_vector:V8HI [(const_int 1) (const_int 1)
4387                                   (const_int 1) (const_int 1)
4388                                   (const_int 1) (const_int 1)
4389                                   (const_int 1) (const_int 1)]))
4390             (const_int 1))))]
4391   "TARGET_SSE2 && ix86_binary_operator_ok (PLUS, V8HImode, operands)"
4392   "pavgw\t{%2, %0|%0, %2}"
4393   [(set_attr "type" "sseiadd")
4394    (set_attr "mode" "TI")])
4395
4396 ;; The correct representation for this is absolutely enormous, and 
4397 ;; surely not generally useful.
4398 (define_insn "sse2_psadbw"
4399   [(set (match_operand:V2DI 0 "register_operand" "=x")
4400         (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
4401                       (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
4402                      UNSPEC_PSADBW))]
4403   "TARGET_SSE2"
4404   "psadbw\t{%2, %0|%0, %2}"
4405   [(set_attr "type" "sseiadd")
4406    (set_attr "mode" "TI")])
4407
4408 (define_insn "sse_movmskps"
4409   [(set (match_operand:SI 0 "register_operand" "=r")
4410         (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
4411                    UNSPEC_MOVMSK))]
4412   "TARGET_SSE"
4413   "movmskps\t{%1, %0|%0, %1}"
4414   [(set_attr "type" "ssecvt")
4415    (set_attr "mode" "V4SF")])
4416
4417 (define_insn "sse2_movmskpd"
4418   [(set (match_operand:SI 0 "register_operand" "=r")
4419         (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
4420                    UNSPEC_MOVMSK))]
4421   "TARGET_SSE2"
4422   "movmskpd\t{%1, %0|%0, %1}"
4423   [(set_attr "type" "ssecvt")
4424    (set_attr "mode" "V2DF")])
4425
4426 (define_insn "sse2_pmovmskb"
4427   [(set (match_operand:SI 0 "register_operand" "=r")
4428         (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
4429                    UNSPEC_MOVMSK))]
4430   "TARGET_SSE2"
4431   "pmovmskb\t{%1, %0|%0, %1}"
4432   [(set_attr "type" "ssecvt")
4433    (set_attr "mode" "V2DF")])
4434
4435 (define_expand "sse2_maskmovdqu"
4436   [(set (match_operand:V16QI 0 "memory_operand" "")
4437         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
4438                        (match_operand:V16QI 2 "register_operand" "x")
4439                        (match_dup 0)]
4440                       UNSPEC_MASKMOV))]
4441   "TARGET_SSE2"
4442   "")
4443
4444 (define_insn "*sse2_maskmovdqu"
4445   [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
4446         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
4447                        (match_operand:V16QI 2 "register_operand" "x")
4448                        (mem:V16QI (match_dup 0))]
4449                       UNSPEC_MASKMOV))]
4450   "TARGET_SSE2 && !TARGET_64BIT"
4451   ;; @@@ check ordering of operands in intel/nonintel syntax
4452   "maskmovdqu\t{%2, %1|%1, %2}"
4453   [(set_attr "type" "ssecvt")
4454    (set_attr "mode" "TI")])
4455
4456 (define_insn "*sse2_maskmovdqu_rex64"
4457   [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
4458         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
4459                        (match_operand:V16QI 2 "register_operand" "x")
4460                        (mem:V16QI (match_dup 0))]
4461                       UNSPEC_MASKMOV))]
4462   "TARGET_SSE2 && TARGET_64BIT"
4463   ;; @@@ check ordering of operands in intel/nonintel syntax
4464   "maskmovdqu\t{%2, %1|%1, %2}"
4465   [(set_attr "type" "ssecvt")
4466    (set_attr "mode" "TI")])
4467
4468 (define_insn "sse_ldmxcsr"
4469   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
4470                     UNSPECV_LDMXCSR)]
4471   "TARGET_SSE"
4472   "ldmxcsr\t%0"
4473   [(set_attr "type" "sse")
4474    (set_attr "memory" "load")])
4475
4476 (define_insn "sse_stmxcsr"
4477   [(set (match_operand:SI 0 "memory_operand" "=m")
4478         (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
4479   "TARGET_SSE"
4480   "stmxcsr\t%0"
4481   [(set_attr "type" "sse")
4482    (set_attr "memory" "store")])
4483
4484 (define_expand "sse_sfence"
4485   [(set (match_dup 0)
4486         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
4487   "TARGET_SSE || TARGET_3DNOW_A"
4488 {
4489   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
4490   MEM_VOLATILE_P (operands[0]) = 1;
4491 })
4492
4493 (define_insn "*sse_sfence"
4494   [(set (match_operand:BLK 0 "" "")
4495         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
4496   "TARGET_SSE || TARGET_3DNOW_A"
4497   "sfence"
4498   [(set_attr "type" "sse")
4499    (set_attr "memory" "unknown")])
4500
4501 (define_insn "sse2_clflush"
4502   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
4503                     UNSPECV_CLFLUSH)]
4504   "TARGET_SSE2"
4505   "clflush\t%a0"
4506   [(set_attr "type" "sse")
4507    (set_attr "memory" "unknown")])
4508
4509 (define_expand "sse2_mfence"
4510   [(set (match_dup 0)
4511         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
4512   "TARGET_SSE2"
4513 {
4514   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
4515   MEM_VOLATILE_P (operands[0]) = 1;
4516 })
4517
4518 (define_insn "*sse2_mfence"
4519   [(set (match_operand:BLK 0 "" "")
4520         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
4521   "TARGET_SSE2"
4522   "mfence"
4523   [(set_attr "type" "sse")
4524    (set_attr "memory" "unknown")])
4525
4526 (define_expand "sse2_lfence"
4527   [(set (match_dup 0)
4528         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
4529   "TARGET_SSE2"
4530 {
4531   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
4532   MEM_VOLATILE_P (operands[0]) = 1;
4533 })
4534
4535 (define_insn "*sse2_lfence"
4536   [(set (match_operand:BLK 0 "" "")
4537         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
4538   "TARGET_SSE2"
4539   "lfence"
4540   [(set_attr "type" "sse")
4541    (set_attr "memory" "unknown")])
4542
4543 (define_insn "sse3_mwait"
4544   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
4545                      (match_operand:SI 1 "register_operand" "c")]
4546                     UNSPECV_MWAIT)]
4547   "TARGET_SSE3"
4548 ;; 64bit version is "mwait %rax,%rcx". But only lower 32bits are used.
4549 ;; Since 32bit register operands are implicitly zero extended to 64bit,
4550 ;; we only need to set up 32bit registers.
4551   "mwait"
4552   [(set_attr "length" "3")])
4553
4554 (define_insn "sse3_monitor"
4555   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
4556                      (match_operand:SI 1 "register_operand" "c")
4557                      (match_operand:SI 2 "register_operand" "d")]
4558                     UNSPECV_MONITOR)]
4559   "TARGET_SSE3 && !TARGET_64BIT"
4560   "monitor\t%0, %1, %2"
4561   [(set_attr "length" "3")])
4562
4563 (define_insn "sse3_monitor64"
4564   [(unspec_volatile [(match_operand:DI 0 "register_operand" "a")
4565                      (match_operand:SI 1 "register_operand" "c")
4566                      (match_operand:SI 2 "register_operand" "d")]
4567                     UNSPECV_MONITOR)]
4568   "TARGET_SSE3 && TARGET_64BIT"
4569 ;; 64bit version is "monitor %rax,%rcx,%rdx". But only lower 32bits in
4570 ;; RCX and RDX are used.  Since 32bit register operands are implicitly
4571 ;; zero extended to 64bit, we only need to set up 32bit registers.
4572   "monitor"
4573   [(set_attr "length" "3")])
4574
4575 ;; SSSE3
4576 (define_insn "ssse3_phaddwv8hi3"
4577   [(set (match_operand:V8HI 0 "register_operand" "=x")
4578         (vec_concat:V8HI
4579           (vec_concat:V4HI
4580             (vec_concat:V2HI
4581               (plus:HI
4582                 (vec_select:HI
4583                   (match_operand:V8HI 1 "register_operand" "0")
4584                   (parallel [(const_int 0)]))
4585                 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
4586               (plus:HI
4587                 (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
4588                 (vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
4589             (vec_concat:V2HI
4590               (plus:HI
4591                 (vec_select:HI (match_dup 1) (parallel [(const_int 4)]))
4592                 (vec_select:HI (match_dup 1) (parallel [(const_int 5)])))
4593               (plus:HI
4594                 (vec_select:HI (match_dup 1) (parallel [(const_int 6)]))
4595                 (vec_select:HI (match_dup 1) (parallel [(const_int 7)])))))
4596           (vec_concat:V4HI
4597             (vec_concat:V2HI
4598               (plus:HI
4599                 (vec_select:HI
4600                   (match_operand:V8HI 2 "nonimmediate_operand" "xm")
4601                   (parallel [(const_int 0)]))
4602                 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
4603               (plus:HI
4604                 (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
4605                 (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))
4606             (vec_concat:V2HI
4607               (plus:HI
4608                 (vec_select:HI (match_dup 2) (parallel [(const_int 4)]))
4609                 (vec_select:HI (match_dup 2) (parallel [(const_int 5)])))
4610               (plus:HI
4611                 (vec_select:HI (match_dup 2) (parallel [(const_int 6)]))
4612                 (vec_select:HI (match_dup 2) (parallel [(const_int 7)])))))))]
4613   "TARGET_SSSE3"
4614   "phaddw\t{%2, %0|%0, %2}"
4615   [(set_attr "type" "sseiadd")
4616    (set_attr "mode" "TI")])
4617
4618 (define_insn "ssse3_phaddwv4hi3"
4619   [(set (match_operand:V4HI 0 "register_operand" "=y")
4620         (vec_concat:V4HI
4621           (vec_concat:V2HI
4622             (plus:HI
4623               (vec_select:HI
4624                 (match_operand:V4HI 1 "register_operand" "0")
4625                 (parallel [(const_int 0)]))
4626               (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
4627             (plus:HI
4628               (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
4629               (vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
4630           (vec_concat:V2HI
4631             (plus:HI
4632               (vec_select:HI
4633                 (match_operand:V4HI 2 "nonimmediate_operand" "ym")
4634                 (parallel [(const_int 0)]))
4635               (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
4636             (plus:HI
4637               (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
4638               (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))))]
4639   "TARGET_SSSE3"
4640   "phaddw\t{%2, %0|%0, %2}"
4641   [(set_attr "type" "sseiadd")
4642    (set_attr "mode" "DI")])
4643
4644 (define_insn "ssse3_phadddv4si3"
4645   [(set (match_operand:V4SI 0 "register_operand" "=x")
4646         (vec_concat:V4SI
4647           (vec_concat:V2SI
4648             (plus:SI
4649               (vec_select:SI
4650                 (match_operand:V4SI 1 "register_operand" "0")
4651                 (parallel [(const_int 0)]))
4652               (vec_select:SI (match_dup 1) (parallel [(const_int 1)])))
4653             (plus:SI
4654               (vec_select:SI (match_dup 1) (parallel [(const_int 2)]))
4655               (vec_select:SI (match_dup 1) (parallel [(const_int 3)]))))
4656           (vec_concat:V2SI
4657             (plus:SI
4658               (vec_select:SI
4659                 (match_operand:V4SI 2 "nonimmediate_operand" "xm")
4660                 (parallel [(const_int 0)]))
4661               (vec_select:SI (match_dup 2) (parallel [(const_int 1)])))
4662             (plus:SI
4663               (vec_select:SI (match_dup 2) (parallel [(const_int 2)]))
4664               (vec_select:SI (match_dup 2) (parallel [(const_int 3)]))))))]
4665   "TARGET_SSSE3"
4666   "phaddd\t{%2, %0|%0, %2}"
4667   [(set_attr "type" "sseiadd")
4668    (set_attr "mode" "TI")])
4669
4670 (define_insn "ssse3_phadddv2si3"
4671   [(set (match_operand:V2SI 0 "register_operand" "=y")
4672         (vec_concat:V2SI
4673           (plus:SI
4674             (vec_select:SI
4675               (match_operand:V2SI 1 "register_operand" "0")
4676               (parallel [(const_int 0)]))
4677             (vec_select:SI (match_dup 1) (parallel [(const_int 1)])))
4678           (plus:SI
4679             (vec_select:SI
4680               (match_operand:V2SI 2 "nonimmediate_operand" "ym")
4681               (parallel [(const_int 0)]))
4682             (vec_select:SI (match_dup 2) (parallel [(const_int 1)])))))]
4683   "TARGET_SSSE3"
4684   "phaddd\t{%2, %0|%0, %2}"
4685   [(set_attr "type" "sseiadd")
4686    (set_attr "mode" "DI")])
4687
4688 (define_insn "ssse3_phaddswv8hi3"
4689   [(set (match_operand:V8HI 0 "register_operand" "=x")
4690         (vec_concat:V8HI
4691           (vec_concat:V4HI
4692             (vec_concat:V2HI
4693               (ss_plus:HI
4694                 (vec_select:HI
4695                   (match_operand:V8HI 1 "register_operand" "0")
4696                   (parallel [(const_int 0)]))
4697                 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
4698               (ss_plus:HI
4699                 (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
4700                 (vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
4701             (vec_concat:V2HI
4702               (ss_plus:HI
4703                 (vec_select:HI (match_dup 1) (parallel [(const_int 4)]))
4704                 (vec_select:HI (match_dup 1) (parallel [(const_int 5)])))
4705               (ss_plus:HI
4706                 (vec_select:HI (match_dup 1) (parallel [(const_int 6)]))
4707                 (vec_select:HI (match_dup 1) (parallel [(const_int 7)])))))
4708           (vec_concat:V4HI
4709             (vec_concat:V2HI
4710               (ss_plus:HI
4711                 (vec_select:HI
4712                   (match_operand:V8HI 2 "nonimmediate_operand" "xm")
4713                   (parallel [(const_int 0)]))
4714                 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
4715               (ss_plus:HI
4716                 (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
4717                 (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))
4718             (vec_concat:V2HI
4719               (ss_plus:HI
4720                 (vec_select:HI (match_dup 2) (parallel [(const_int 4)]))
4721                 (vec_select:HI (match_dup 2) (parallel [(const_int 5)])))
4722               (ss_plus:HI
4723                 (vec_select:HI (match_dup 2) (parallel [(const_int 6)]))
4724                 (vec_select:HI (match_dup 2) (parallel [(const_int 7)])))))))]
4725   "TARGET_SSSE3"
4726   "phaddsw\t{%2, %0|%0, %2}"
4727   [(set_attr "type" "sseiadd")
4728    (set_attr "mode" "TI")])
4729
4730 (define_insn "ssse3_phaddswv4hi3"
4731   [(set (match_operand:V4HI 0 "register_operand" "=y")
4732         (vec_concat:V4HI
4733           (vec_concat:V2HI
4734             (ss_plus:HI
4735               (vec_select:HI
4736                 (match_operand:V4HI 1 "register_operand" "0")
4737                 (parallel [(const_int 0)]))
4738               (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
4739             (ss_plus:HI
4740               (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
4741               (vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
4742           (vec_concat:V2HI
4743             (ss_plus:HI
4744               (vec_select:HI
4745                 (match_operand:V4HI 2 "nonimmediate_operand" "ym")
4746                 (parallel [(const_int 0)]))
4747               (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
4748             (ss_plus:HI
4749               (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
4750               (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))))]
4751   "TARGET_SSSE3"
4752   "phaddsw\t{%2, %0|%0, %2}"
4753   [(set_attr "type" "sseiadd")
4754    (set_attr "mode" "DI")])
4755
4756 (define_insn "ssse3_phsubwv8hi3"
4757   [(set (match_operand:V8HI 0 "register_operand" "=x")
4758         (vec_concat:V8HI
4759           (vec_concat:V4HI
4760             (vec_concat:V2HI
4761               (minus:HI
4762                 (vec_select:HI
4763                   (match_operand:V8HI 1 "register_operand" "0")
4764                   (parallel [(const_int 0)]))
4765                 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
4766               (minus:HI
4767                 (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
4768                 (vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
4769             (vec_concat:V2HI
4770               (minus:HI
4771                 (vec_select:HI (match_dup 1) (parallel [(const_int 4)]))
4772                 (vec_select:HI (match_dup 1) (parallel [(const_int 5)])))
4773               (minus:HI
4774                 (vec_select:HI (match_dup 1) (parallel [(const_int 6)]))
4775                 (vec_select:HI (match_dup 1) (parallel [(const_int 7)])))))
4776           (vec_concat:V4HI
4777             (vec_concat:V2HI
4778               (minus:HI
4779                 (vec_select:HI
4780                   (match_operand:V8HI 2 "nonimmediate_operand" "xm")
4781                   (parallel [(const_int 0)]))
4782                 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
4783               (minus:HI
4784                 (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
4785                 (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))
4786             (vec_concat:V2HI
4787               (minus:HI
4788                 (vec_select:HI (match_dup 2) (parallel [(const_int 4)]))
4789                 (vec_select:HI (match_dup 2) (parallel [(const_int 5)])))
4790               (minus:HI
4791                 (vec_select:HI (match_dup 2) (parallel [(const_int 6)]))
4792                 (vec_select:HI (match_dup 2) (parallel [(const_int 7)])))))))]
4793   "TARGET_SSSE3"
4794   "phsubw\t{%2, %0|%0, %2}"
4795   [(set_attr "type" "sseiadd")
4796    (set_attr "mode" "TI")])
4797
4798 (define_insn "ssse3_phsubwv4hi3"
4799   [(set (match_operand:V4HI 0 "register_operand" "=y")
4800         (vec_concat:V4HI
4801           (vec_concat:V2HI
4802             (minus:HI
4803               (vec_select:HI
4804                 (match_operand:V4HI 1 "register_operand" "0")
4805                 (parallel [(const_int 0)]))
4806               (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
4807             (minus:HI
4808               (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
4809               (vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
4810           (vec_concat:V2HI
4811             (minus:HI
4812               (vec_select:HI
4813                 (match_operand:V4HI 2 "nonimmediate_operand" "ym")
4814                 (parallel [(const_int 0)]))
4815               (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
4816             (minus:HI
4817               (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
4818               (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))))]
4819   "TARGET_SSSE3"
4820   "phsubw\t{%2, %0|%0, %2}"
4821   [(set_attr "type" "sseiadd")
4822    (set_attr "mode" "DI")])
4823
4824 (define_insn "ssse3_phsubdv4si3"
4825   [(set (match_operand:V4SI 0 "register_operand" "=x")
4826         (vec_concat:V4SI
4827           (vec_concat:V2SI
4828             (minus:SI
4829               (vec_select:SI
4830                 (match_operand:V4SI 1 "register_operand" "0")
4831                 (parallel [(const_int 0)]))
4832               (vec_select:SI (match_dup 1) (parallel [(const_int 1)])))
4833             (minus:SI
4834               (vec_select:SI (match_dup 1) (parallel [(const_int 2)]))
4835               (vec_select:SI (match_dup 1) (parallel [(const_int 3)]))))
4836           (vec_concat:V2SI
4837             (minus:SI
4838               (vec_select:SI
4839                 (match_operand:V4SI 2 "nonimmediate_operand" "xm")
4840                 (parallel [(const_int 0)]))
4841               (vec_select:SI (match_dup 2) (parallel [(const_int 1)])))
4842             (minus:SI
4843               (vec_select:SI (match_dup 2) (parallel [(const_int 2)]))
4844               (vec_select:SI (match_dup 2) (parallel [(const_int 3)]))))))]
4845   "TARGET_SSSE3"
4846   "phsubd\t{%2, %0|%0, %2}"
4847   [(set_attr "type" "sseiadd")
4848    (set_attr "mode" "TI")])
4849
4850 (define_insn "ssse3_phsubdv2si3"
4851   [(set (match_operand:V2SI 0 "register_operand" "=y")
4852         (vec_concat:V2SI
4853           (minus:SI
4854             (vec_select:SI
4855               (match_operand:V2SI 1 "register_operand" "0")
4856               (parallel [(const_int 0)]))
4857             (vec_select:SI (match_dup 1) (parallel [(const_int 1)])))
4858           (minus:SI
4859             (vec_select:SI
4860               (match_operand:V2SI 2 "nonimmediate_operand" "ym")
4861               (parallel [(const_int 0)]))
4862             (vec_select:SI (match_dup 2) (parallel [(const_int 1)])))))]
4863   "TARGET_SSSE3"
4864   "phsubd\t{%2, %0|%0, %2}"
4865   [(set_attr "type" "sseiadd")
4866    (set_attr "mode" "DI")])
4867
4868 (define_insn "ssse3_phsubswv8hi3"
4869   [(set (match_operand:V8HI 0 "register_operand" "=x")
4870         (vec_concat:V8HI
4871           (vec_concat:V4HI
4872             (vec_concat:V2HI
4873               (ss_minus:HI
4874                 (vec_select:HI
4875                   (match_operand:V8HI 1 "register_operand" "0")
4876                   (parallel [(const_int 0)]))
4877                 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
4878               (ss_minus:HI
4879                 (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
4880                 (vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
4881             (vec_concat:V2HI
4882               (ss_minus:HI
4883                 (vec_select:HI (match_dup 1) (parallel [(const_int 4)]))
4884                 (vec_select:HI (match_dup 1) (parallel [(const_int 5)])))
4885               (ss_minus:HI
4886                 (vec_select:HI (match_dup 1) (parallel [(const_int 6)]))
4887                 (vec_select:HI (match_dup 1) (parallel [(const_int 7)])))))
4888           (vec_concat:V4HI
4889             (vec_concat:V2HI
4890               (ss_minus:HI
4891                 (vec_select:HI
4892                   (match_operand:V8HI 2 "nonimmediate_operand" "xm")
4893                   (parallel [(const_int 0)]))
4894                 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
4895               (ss_minus:HI
4896                 (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
4897                 (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))
4898             (vec_concat:V2HI
4899               (ss_minus:HI
4900                 (vec_select:HI (match_dup 2) (parallel [(const_int 4)]))
4901                 (vec_select:HI (match_dup 2) (parallel [(const_int 5)])))
4902               (ss_minus:HI
4903                 (vec_select:HI (match_dup 2) (parallel [(const_int 6)]))
4904                 (vec_select:HI (match_dup 2) (parallel [(const_int 7)])))))))]
4905   "TARGET_SSSE3"
4906   "phsubsw\t{%2, %0|%0, %2}"
4907   [(set_attr "type" "sseiadd")
4908    (set_attr "mode" "TI")])
4909
4910 (define_insn "ssse3_phsubswv4hi3"
4911   [(set (match_operand:V4HI 0 "register_operand" "=y")
4912         (vec_concat:V4HI
4913           (vec_concat:V2HI
4914             (ss_minus:HI
4915               (vec_select:HI
4916                 (match_operand:V4HI 1 "register_operand" "0")
4917                 (parallel [(const_int 0)]))
4918               (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
4919             (ss_minus:HI
4920               (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
4921               (vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
4922           (vec_concat:V2HI
4923             (ss_minus:HI
4924               (vec_select:HI
4925                 (match_operand:V4HI 2 "nonimmediate_operand" "ym")
4926                 (parallel [(const_int 0)]))
4927               (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
4928             (ss_minus:HI
4929               (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
4930               (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))))]
4931   "TARGET_SSSE3"
4932   "phsubsw\t{%2, %0|%0, %2}"
4933   [(set_attr "type" "sseiadd")
4934    (set_attr "mode" "DI")])
4935
4936 (define_insn "ssse3_pmaddubswv8hi3"
4937   [(set (match_operand:V8HI 0 "register_operand" "=x")
4938         (ss_plus:V8HI
4939           (mult:V8HI
4940             (zero_extend:V8HI
4941               (vec_select:V4QI
4942                 (match_operand:V16QI 1 "nonimmediate_operand" "%0")
4943                 (parallel [(const_int 0)
4944                            (const_int 2)
4945                            (const_int 4)
4946                            (const_int 6)
4947                            (const_int 8)
4948                            (const_int 10)
4949                            (const_int 12)
4950                            (const_int 14)])))
4951             (sign_extend:V8HI
4952               (vec_select:V8QI
4953                 (match_operand:V16QI 2 "nonimmediate_operand" "xm")
4954                 (parallel [(const_int 0)
4955                            (const_int 2)
4956                            (const_int 4)
4957                            (const_int 6)
4958                            (const_int 8)
4959                            (const_int 10)
4960                            (const_int 12)
4961                            (const_int 14)]))))
4962           (mult:V8HI
4963             (zero_extend:V8HI
4964               (vec_select:V16QI (match_dup 1)
4965                 (parallel [(const_int 1)
4966                            (const_int 3)
4967                            (const_int 5)
4968                            (const_int 7)
4969                            (const_int 9)
4970                            (const_int 11)
4971                            (const_int 13)
4972                            (const_int 15)])))
4973             (sign_extend:V8HI
4974               (vec_select:V16QI (match_dup 2)
4975                 (parallel [(const_int 1)
4976                            (const_int 3)
4977                            (const_int 5)
4978                            (const_int 7)
4979                            (const_int 9)
4980                            (const_int 11)
4981                            (const_int 13)
4982                            (const_int 15)]))))))]
4983   "TARGET_SSSE3"
4984   "pmaddubsw\t{%2, %0|%0, %2}"
4985   [(set_attr "type" "sseiadd")
4986    (set_attr "mode" "TI")])
4987
4988 (define_insn "ssse3_pmaddubswv4hi3"
4989   [(set (match_operand:V4HI 0 "register_operand" "=y")
4990         (ss_plus:V4HI
4991           (mult:V4HI
4992             (zero_extend:V4HI
4993               (vec_select:V4QI
4994                 (match_operand:V8QI 1 "nonimmediate_operand" "%0")
4995                 (parallel [(const_int 0)
4996                            (const_int 2)
4997                            (const_int 4)
4998                            (const_int 6)])))
4999             (sign_extend:V4HI
5000               (vec_select:V4QI
5001                 (match_operand:V8QI 2 "nonimmediate_operand" "ym")
5002                 (parallel [(const_int 0)
5003                            (const_int 2)
5004                            (const_int 4)
5005                            (const_int 6)]))))
5006           (mult:V4HI
5007             (zero_extend:V4HI
5008               (vec_select:V8QI (match_dup 1)
5009                 (parallel [(const_int 1)
5010                            (const_int 3)
5011                            (const_int 5)
5012                            (const_int 7)])))
5013             (sign_extend:V4HI
5014               (vec_select:V8QI (match_dup 2)
5015                 (parallel [(const_int 1)
5016                            (const_int 3)
5017                            (const_int 5)
5018                            (const_int 7)]))))))]
5019   "TARGET_SSSE3"
5020   "pmaddubsw\t{%2, %0|%0, %2}"
5021   [(set_attr "type" "sseiadd")
5022    (set_attr "mode" "DI")])
5023
5024 (define_insn "ssse3_pmulhrswv8hi3"
5025   [(set (match_operand:V8HI 0 "register_operand" "=x")
5026         (truncate:V8HI
5027           (lshiftrt:V8SI
5028             (plus:V8SI
5029               (lshiftrt:V8SI
5030                 (mult:V8SI
5031                   (sign_extend:V8SI
5032                     (match_operand:V8HI 1 "nonimmediate_operand" "%0"))
5033                   (sign_extend:V8SI
5034                     (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
5035                 (const_int 14))
5036               (const_vector:V8HI [(const_int 1) (const_int 1)
5037                                   (const_int 1) (const_int 1)
5038                                   (const_int 1) (const_int 1)
5039                                   (const_int 1) (const_int 1)]))
5040             (const_int 1))))]
5041   "TARGET_SSSE3 && ix86_binary_operator_ok (MULT, V8HImode, operands)"
5042   "pmulhrsw\t{%2, %0|%0, %2}"
5043   [(set_attr "type" "sseimul")
5044    (set_attr "mode" "TI")])
5045
5046 (define_insn "ssse3_pmulhrswv4hi3"
5047   [(set (match_operand:V4HI 0 "register_operand" "=y")
5048         (truncate:V4HI
5049           (lshiftrt:V4SI
5050             (plus:V4SI
5051               (lshiftrt:V4SI
5052                 (mult:V4SI
5053                   (sign_extend:V4SI
5054                     (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
5055                   (sign_extend:V4SI
5056                     (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
5057                 (const_int 14))
5058               (const_vector:V4HI [(const_int 1) (const_int 1)
5059                                   (const_int 1) (const_int 1)]))
5060             (const_int 1))))]
5061   "TARGET_SSSE3 && ix86_binary_operator_ok (MULT, V4HImode, operands)"
5062   "pmulhrsw\t{%2, %0|%0, %2}"
5063   [(set_attr "type" "sseimul")
5064    (set_attr "mode" "DI")])
5065
5066 (define_insn "ssse3_pshufbv16qi3"
5067   [(set (match_operand:V16QI 0 "register_operand" "=x")
5068         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "0")
5069                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
5070                        UNSPEC_PSHUFB))]
5071   "TARGET_SSSE3"
5072   "pshufb\t{%2, %0|%0, %2}";
5073   [(set_attr "type" "sselog1")
5074    (set_attr "mode" "TI")])
5075
5076 (define_insn "ssse3_pshufbv8qi3"
5077   [(set (match_operand:V8QI 0 "register_operand" "=y")
5078         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "0")
5079                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
5080                       UNSPEC_PSHUFB))]
5081   "TARGET_SSSE3"
5082   "pshufb\t{%2, %0|%0, %2}";
5083   [(set_attr "type" "sselog1")
5084    (set_attr "mode" "DI")])
5085
5086 (define_insn "ssse3_psign<mode>3"
5087   [(set (match_operand:SSEMODE124 0 "register_operand" "=x")
5088         (unspec:SSEMODE124 [(match_operand:SSEMODE124 1 "register_operand" "0")
5089                             (match_operand:SSEMODE124 2 "nonimmediate_operand" "xm")]
5090                             UNSPEC_PSIGN))]
5091   "TARGET_SSSE3"
5092   "psign<ssevecsize>\t{%2, %0|%0, %2}";
5093   [(set_attr "type" "sselog1")
5094    (set_attr "mode" "TI")])
5095
5096 (define_insn "ssse3_psign<mode>3"
5097   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
5098         (unspec:MMXMODEI [(match_operand:MMXMODEI 1 "register_operand" "0")
5099                           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")]
5100                           UNSPEC_PSIGN))]
5101   "TARGET_SSSE3"
5102   "psign<mmxvecsize>\t{%2, %0|%0, %2}";
5103   [(set_attr "type" "sselog1")
5104    (set_attr "mode" "DI")])
5105
5106 (define_insn "ssse3_palignrti"
5107   [(set (match_operand:TI 0 "register_operand" "=x")
5108         (unspec:TI [(match_operand:TI 1 "register_operand" "0")
5109                     (match_operand:TI 2 "nonimmediate_operand" "xm")
5110                     (match_operand:SI 3 "const_0_to_255_mul_8_operand" "n")]
5111                     UNSPEC_PALIGNR))]
5112   "TARGET_SSSE3"
5113 {
5114   operands[3] = GEN_INT (INTVAL (operands[3]) / 8);
5115   return "palignr\t{%3, %2, %0|%0, %2, %3}";
5116 }
5117   [(set_attr "type" "sseishft")
5118    (set_attr "mode" "TI")])
5119
5120 (define_insn "ssse3_palignrdi"
5121   [(set (match_operand:DI 0 "register_operand" "=y")
5122         (unspec:DI [(match_operand:DI 1 "register_operand" "0")
5123                     (match_operand:DI 2 "nonimmediate_operand" "ym")
5124                     (match_operand:SI 3 "const_0_to_255_mul_8_operand" "n")]
5125                     UNSPEC_PALIGNR))]
5126   "TARGET_SSSE3"
5127 {
5128   operands[3] = GEN_INT (INTVAL (operands[3]) / 8);
5129   return "palignr\t{%3, %2, %0|%0, %2, %3}";
5130 }
5131   [(set_attr "type" "sseishft")
5132    (set_attr "mode" "DI")])
5133
5134 (define_insn "abs<mode>2"
5135   [(set (match_operand:SSEMODE124 0 "register_operand" "=x")
5136         (abs:SSEMODE124 (match_operand:SSEMODE124 1 "nonimmediate_operand" "xm")))]
5137   "TARGET_SSSE3"
5138   "pabs<ssevecsize>\t{%1, %0|%0, %1}";
5139   [(set_attr "type" "sselog1")
5140    (set_attr "mode" "TI")])
5141
5142 (define_insn "abs<mode>2"
5143   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
5144         (abs:MMXMODEI (match_operand:MMXMODEI 1 "nonimmediate_operand" "ym")))]
5145   "TARGET_SSSE3"
5146   "pabs<mmxvecsize>\t{%1, %0|%0, %1}";
5147   [(set_attr "type" "sselog1")
5148    (set_attr "mode" "DI")])