OSDN Git Service

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