OSDN Git Service

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