OSDN Git Service

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