OSDN Git Service

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