OSDN Git Service

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