OSDN Git Service

40ab29746ee1d3c163fa084e49193f119f729725
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / sse.md
1 ;; GCC machine description for SSE instructions
2 ;; Copyright (C) 2005, 2006, 2007, 2008
3 ;; Free Software Foundation, Inc.
4 ;;
5 ;; This file is part of GCC.
6 ;;
7 ;; GCC is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 3, or (at your option)
10 ;; any later version.
11 ;;
12 ;; GCC is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 ;; GNU General Public License for more details.
16 ;;
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3.  If not see
19 ;; <http://www.gnu.org/licenses/>.
20
21
22 ;; 16 byte integral modes handled by SSE, minus TImode, which gets
23 ;; special-cased for TARGET_64BIT.
24 (define_mode_iterator SSEMODEI [V16QI V8HI V4SI V2DI])
25
26 ;; All 16-byte vector modes handled by SSE
27 (define_mode_iterator SSEMODE [V16QI V8HI V4SI V2DI V4SF V2DF])
28
29 ;; Mix-n-match
30 (define_mode_iterator SSEMODE12 [V16QI V8HI])
31 (define_mode_iterator SSEMODE24 [V8HI V4SI])
32 (define_mode_iterator SSEMODE14 [V16QI V4SI])
33 (define_mode_iterator SSEMODE124 [V16QI V8HI V4SI])
34 (define_mode_iterator SSEMODE248 [V8HI V4SI V2DI])
35 (define_mode_iterator SSEMODE1248 [V16QI V8HI V4SI V2DI])
36 (define_mode_iterator SSEMODEF4 [SF DF V4SF V2DF])
37 (define_mode_iterator SSEMODEF2P [V4SF V2DF])
38
39 ;; Mapping from float mode to required SSE level
40 (define_mode_attr sse [(SF "sse") (DF "sse2") (V4SF "sse") (V2DF "sse2")])
41
42 ;; Mapping from integer vector mode to mnemonic suffix
43 (define_mode_attr ssevecsize [(V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")])
44
45 ;; Mapping of the sse5 suffix
46 (define_mode_attr ssemodesuffixf4 [(SF "ss") (DF "sd")
47                                    (V4SF "ps") (V2DF "pd")])
48 (define_mode_attr ssemodesuffixf2s [(SF "ss") (DF "sd")
49                                     (V4SF "ss") (V2DF "sd")])
50 (define_mode_attr ssemodesuffixf2c [(V4SF "s") (V2DF "d")])
51
52 ;; Mapping of the max integer size for sse5 rotate immediate constraint
53 (define_mode_attr sserotatemax [(V16QI "7") (V8HI "15") (V4SI "31") (V2DI "63")])
54
55 ;; Mapping of vector modes back to the scalar modes
56 (define_mode_attr ssescalarmode [(V4SF "SF") (V2DF "DF")])
57
58 ;; Mapping of immediate bits for blend instructions
59 (define_mode_attr blendbits [(V4SF "15") (V2DF "3")])
60
61 ;; Patterns whose name begins with "sse{,2,3}_" are invoked by intrinsics.
62
63 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
64 ;;
65 ;; Move patterns
66 ;;
67 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
68
69 ;; All of these patterns are enabled for SSE1 as well as SSE2.
70 ;; This is essential for maintaining stable calling conventions.
71
72 (define_expand "mov<mode>"
73   [(set (match_operand:SSEMODEI 0 "nonimmediate_operand" "")
74         (match_operand:SSEMODEI 1 "nonimmediate_operand" ""))]
75   "TARGET_SSE"
76 {
77   ix86_expand_vector_move (<MODE>mode, operands);
78   DONE;
79 })
80
81 (define_insn "*mov<mode>_internal"
82   [(set (match_operand:SSEMODEI 0 "nonimmediate_operand" "=x,x ,m")
83         (match_operand:SSEMODEI 1 "nonimmediate_or_sse_const_operand"  "C ,xm,x"))]
84   "TARGET_SSE
85    && (register_operand (operands[0], <MODE>mode)
86        || register_operand (operands[1], <MODE>mode))"
87 {
88   switch (which_alternative)
89     {
90     case 0:
91       return standard_sse_constant_opcode (insn, operands[1]);
92     case 1:
93     case 2:
94       if (get_attr_mode (insn) == MODE_V4SF)
95         return "movaps\t{%1, %0|%0, %1}";
96       else
97         return "movdqa\t{%1, %0|%0, %1}";
98     default:
99       gcc_unreachable ();
100     }
101 }
102   [(set_attr "type" "sselog1,ssemov,ssemov")
103    (set (attr "mode")
104         (if_then_else
105           (ior (ior (ne (symbol_ref "optimize_size") (const_int 0))
106                     (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
107                (and (eq_attr "alternative" "2")
108                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
109                         (const_int 0))))
110           (const_string "V4SF")
111           (const_string "TI")))])
112
113 ;; Move a DI from a 32-bit register pair (e.g. %edx:%eax) to an xmm.
114 ;; We'd rather avoid this entirely; if the 32-bit reg pair was loaded
115 ;; from memory, we'd prefer to load the memory directly into the %xmm
116 ;; register.  To facilitate this happy circumstance, this pattern won't
117 ;; split until after register allocation.  If the 64-bit value didn't
118 ;; come from memory, this is the best we can do.  This is much better
119 ;; than storing %edx:%eax into a stack temporary and loading an %xmm
120 ;; from there.
121
122 (define_insn_and_split "movdi_to_sse"
123   [(parallel
124     [(set (match_operand:V4SI 0 "register_operand" "=?x,x")
125           (subreg:V4SI (match_operand:DI 1 "nonimmediate_operand" "r,m") 0))
126      (clobber (match_scratch:V4SI 2 "=&x,X"))])]
127   "!TARGET_64BIT && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES"
128   "#"
129   "&& reload_completed"
130   [(const_int 0)]
131 {
132  if (register_operand (operands[1], DImode))
133    {
134       /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
135          Assemble the 64-bit DImode value in an xmm register.  */
136       emit_insn (gen_sse2_loadld (operands[0], CONST0_RTX (V4SImode),
137                                   gen_rtx_SUBREG (SImode, operands[1], 0)));
138       emit_insn (gen_sse2_loadld (operands[2], CONST0_RTX (V4SImode),
139                                   gen_rtx_SUBREG (SImode, operands[1], 4)));
140       emit_insn (gen_sse2_punpckldq (operands[0], operands[0], operands[2]));
141     }
142  else if (memory_operand (operands[1], DImode))
143       emit_insn (gen_vec_concatv2di (gen_lowpart (V2DImode, operands[0]), operands[1], const0_rtx));
144  else
145       gcc_unreachable ();
146 })
147
148 (define_expand "mov<mode>"
149   [(set (match_operand:SSEMODEF2P 0 "nonimmediate_operand" "")
150         (match_operand:SSEMODEF2P 1 "nonimmediate_operand" ""))]
151   "TARGET_SSE"
152 {
153   ix86_expand_vector_move (<MODE>mode, operands);
154   DONE;
155 })
156
157 (define_insn "*movv4sf_internal"
158   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
159         (match_operand:V4SF 1 "nonimmediate_or_sse_const_operand" "C,xm,x"))]
160   "TARGET_SSE
161    && (register_operand (operands[0], V4SFmode)
162        || register_operand (operands[1], V4SFmode))"
163 {
164   switch (which_alternative)
165     {
166     case 0:
167       return standard_sse_constant_opcode (insn, operands[1]);
168     case 1:
169     case 2:
170       return "movaps\t{%1, %0|%0, %1}";
171     default:
172       gcc_unreachable ();
173     }
174 }
175   [(set_attr "type" "sselog1,ssemov,ssemov")
176    (set_attr "mode" "V4SF")])
177
178 (define_split
179   [(set (match_operand:V4SF 0 "register_operand" "")
180         (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
181   "TARGET_SSE && reload_completed"
182   [(set (match_dup 0)
183         (vec_merge:V4SF
184           (vec_duplicate:V4SF (match_dup 1))
185           (match_dup 2)
186           (const_int 1)))]
187 {
188   operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
189   operands[2] = CONST0_RTX (V4SFmode);
190 })
191
192 (define_insn "*movv2df_internal"
193   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
194         (match_operand:V2DF 1 "nonimmediate_or_sse_const_operand" "C,xm,x"))]
195   "TARGET_SSE
196    && (register_operand (operands[0], V2DFmode)
197        || register_operand (operands[1], V2DFmode))"
198 {
199   switch (which_alternative)
200     {
201     case 0:
202       return standard_sse_constant_opcode (insn, operands[1]);
203     case 1:
204     case 2:
205       if (get_attr_mode (insn) == MODE_V4SF)
206         return "movaps\t{%1, %0|%0, %1}";
207       else
208         return "movapd\t{%1, %0|%0, %1}";
209     default:
210       gcc_unreachable ();
211     }
212 }
213   [(set_attr "type" "sselog1,ssemov,ssemov")
214    (set (attr "mode")
215         (if_then_else
216           (ior (ior (ne (symbol_ref "optimize_size") (const_int 0))
217                     (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
218                (and (eq_attr "alternative" "2")
219                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
220                         (const_int 0))))
221           (const_string "V4SF")
222           (const_string "V2DF")))])
223
224 (define_split
225   [(set (match_operand:V2DF 0 "register_operand" "")
226         (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
227   "TARGET_SSE2 && reload_completed"
228   [(set (match_dup 0) (vec_concat:V2DF (match_dup 1) (match_dup 2)))]
229 {
230   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
231   operands[2] = CONST0_RTX (DFmode);
232 })
233
234 (define_expand "push<mode>1"
235   [(match_operand:SSEMODE 0 "register_operand" "")]
236   "TARGET_SSE"
237 {
238   ix86_expand_push (<MODE>mode, operands[0]);
239   DONE;
240 })
241
242 (define_expand "movmisalign<mode>"
243   [(set (match_operand:SSEMODE 0 "nonimmediate_operand" "")
244         (match_operand:SSEMODE 1 "nonimmediate_operand" ""))]
245   "TARGET_SSE"
246 {
247   ix86_expand_vector_move_misalign (<MODE>mode, operands);
248   DONE;
249 })
250
251 (define_insn "<sse>_movup<ssemodesuffixf2c>"
252   [(set (match_operand:SSEMODEF2P 0 "nonimmediate_operand" "=x,m")
253         (unspec:SSEMODEF2P
254           [(match_operand:SSEMODEF2P 1 "nonimmediate_operand" "xm,x")]
255           UNSPEC_MOVU))]
256   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)
257    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
258   "movup<ssemodesuffixf2c>\t{%1, %0|%0, %1}"
259   [(set_attr "type" "ssemov")
260    (set_attr "mode" "<MODE>")])
261
262 (define_insn "sse2_movdqu"
263   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
264         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
265                       UNSPEC_MOVU))]
266   "TARGET_SSE2 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
267   "movdqu\t{%1, %0|%0, %1}"
268   [(set_attr "type" "ssemov")
269    (set_attr "prefix_data16" "1")
270    (set_attr "mode" "TI")])
271
272 (define_insn "<sse>_movnt<mode>"
273   [(set (match_operand:SSEMODEF2P 0 "memory_operand" "=m")
274         (unspec:SSEMODEF2P
275           [(match_operand:SSEMODEF2P 1 "register_operand" "x")]
276           UNSPEC_MOVNT))]
277   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
278   "movntp<ssemodesuffixf2c>\t{%1, %0|%0, %1}"
279   [(set_attr "type" "ssemov")
280    (set_attr "mode" "<MODE>")])
281
282 (define_insn "sse2_movntv2di"
283   [(set (match_operand:V2DI 0 "memory_operand" "=m")
284         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
285                      UNSPEC_MOVNT))]
286   "TARGET_SSE2"
287   "movntdq\t{%1, %0|%0, %1}"
288   [(set_attr "type" "ssecvt")
289    (set_attr "prefix_data16" "1")
290    (set_attr "mode" "TI")])
291
292 (define_insn "sse2_movntsi"
293   [(set (match_operand:SI 0 "memory_operand" "=m")
294         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
295                    UNSPEC_MOVNT))]
296   "TARGET_SSE2"
297   "movnti\t{%1, %0|%0, %1}"
298   [(set_attr "type" "ssecvt")
299    (set_attr "mode" "V2DF")])
300
301 (define_insn "sse3_lddqu"
302   [(set (match_operand:V16QI 0 "register_operand" "=x")
303         (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
304                       UNSPEC_LDDQU))]
305   "TARGET_SSE3"
306   "lddqu\t{%1, %0|%0, %1}"
307   [(set_attr "type" "ssecvt")
308    (set_attr "prefix_rep" "1")
309    (set_attr "mode" "TI")])
310
311 ; Expand patterns for non-temporal stores.  At the moment, only those
312 ; that directly map to insns are defined; it would be possible to
313 ; define patterns for other modes that would expand to several insns.
314
315 (define_expand "storent<mode>"
316   [(set (match_operand:SSEMODEF2P 0 "memory_operand" "")
317         (unspec:SSEMODEF2P
318           [(match_operand:SSEMODEF2P 1 "register_operand" "")]
319           UNSPEC_MOVNT))]
320   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
321   "")
322
323 (define_expand "storent<mode>"
324   [(set (match_operand:MODEF 0 "memory_operand" "")
325         (unspec:MODEF
326           [(match_operand:MODEF 1 "register_operand" "")]
327           UNSPEC_MOVNT))]
328   "TARGET_SSE4A"
329   "")
330
331 (define_expand "storentv2di"
332   [(set (match_operand:V2DI 0 "memory_operand" "")
333         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "")]
334                      UNSPEC_MOVNT))]
335   "TARGET_SSE2"
336   "")
337
338 (define_expand "storentsi"
339   [(set (match_operand:SI 0 "memory_operand" "")
340         (unspec:SI [(match_operand:SI 1 "register_operand" "")]
341                    UNSPEC_MOVNT))]
342   "TARGET_SSE2"
343   "")
344
345 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
346 ;;
347 ;; Parallel floating point arithmetic
348 ;;
349 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
350
351 (define_expand "<code><mode>2"
352   [(set (match_operand:SSEMODEF2P 0 "register_operand" "")
353         (absneg:SSEMODEF2P
354           (match_operand:SSEMODEF2P 1 "register_operand" "")))]
355   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
356   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
357
358 (define_expand "<addsub><mode>3"
359   [(set (match_operand:SSEMODEF2P 0 "register_operand" "")
360         (plusminus:SSEMODEF2P
361           (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "")
362           (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "")))]
363   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
364   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
365
366 (define_insn "*<addsub><mode>3"
367   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
368         (plusminus:SSEMODEF2P
369           (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "<comm>0")
370           (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")))]
371   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)
372    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
373   "<addsub>p<ssemodesuffixf2c>\t{%2, %0|%0, %2}"
374   [(set_attr "type" "sseadd")
375    (set_attr "mode" "<MODE>")])
376
377 (define_insn "<sse>_vm<addsub><mode>3"
378   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
379         (vec_merge:SSEMODEF2P
380           (plusminus:SSEMODEF2P
381             (match_operand:SSEMODEF2P 1 "register_operand" "0")
382             (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm"))
383           (match_dup 1)
384           (const_int 1)))]
385   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)
386    && ix86_binary_operator_ok (<CODE>, V4SFmode, operands)"
387   "<addsub>s<ssemodesuffixf2c>\t{%2, %0|%0, %2}"
388   [(set_attr "type" "sseadd")
389    (set_attr "mode" "<ssescalarmode>")])
390
391 (define_expand "mul<mode>3"
392   [(set (match_operand:SSEMODEF2P 0 "register_operand" "")
393         (mult:SSEMODEF2P
394           (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "")
395           (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "")))]
396   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
397   "ix86_fixup_binary_operands_no_copy (MULT, <MODE>mode, operands);")
398
399 (define_insn "*mul<mode>3"
400   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
401         (mult:SSEMODEF2P
402           (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "%0")
403           (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")))]
404   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)
405    && ix86_binary_operator_ok (MULT, <MODE>mode, operands)"
406   "mulp<ssemodesuffixf2c>\t{%2, %0|%0, %2}"
407   [(set_attr "type" "ssemul")
408    (set_attr "mode" "<MODE>")])
409
410 (define_insn "<sse>_vmmul<mode>3"
411   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
412         (vec_merge:SSEMODEF2P
413           (mult:SSEMODEF2P
414             (match_operand:SSEMODEF2P 1 "register_operand" "0")
415             (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm"))
416           (match_dup 1)
417           (const_int 1)))]
418   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)
419    && ix86_binary_operator_ok (MULT, <MODE>mode, operands)"
420   "muls<ssemodesuffixf2c>\t{%2, %0|%0, %2}"
421   [(set_attr "type" "ssemul")
422    (set_attr "mode" "<ssescalarmode>")])
423
424 (define_expand "divv4sf3"
425   [(set (match_operand:V4SF 0 "register_operand" "")
426         (div:V4SF (match_operand:V4SF 1 "register_operand" "")
427                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
428   "TARGET_SSE"
429 {
430   ix86_fixup_binary_operands_no_copy (DIV, V4SFmode, operands);
431
432   if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
433       && flag_finite_math_only && !flag_trapping_math
434       && flag_unsafe_math_optimizations)
435     {
436       ix86_emit_swdivsf (operands[0], operands[1],
437                          operands[2], V4SFmode);
438       DONE;
439     }
440 })
441
442 (define_expand "divv2df3"
443   [(set (match_operand:V2DF 0 "register_operand" "")
444         (div:V2DF (match_operand:V2DF 1 "register_operand" "")
445                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
446   "TARGET_SSE2"
447   "ix86_fixup_binary_operands_no_copy (DIV, V2DFmode, operands);")
448
449 (define_insn "<sse>_div<mode>3"
450   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
451         (div:SSEMODEF2P
452           (match_operand:SSEMODEF2P 1 "register_operand" "0")
453           (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")))]
454   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
455   "divp<ssemodesuffixf2c>\t{%2, %0|%0, %2}"
456   [(set_attr "type" "ssediv")
457    (set_attr "mode" "<MODE>")])
458
459 (define_insn "<sse>_vmdiv<mode>3"
460   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
461         (vec_merge:SSEMODEF2P
462           (div:SSEMODEF2P
463             (match_operand:SSEMODEF2P 1 "register_operand" "0")
464             (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm"))
465           (match_dup 1)
466           (const_int 1)))]
467   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
468   "divs<ssemodesuffixf2c>\t{%2, %0|%0, %2}"
469   [(set_attr "type" "ssediv")
470    (set_attr "mode" "<ssescalarmode>")])
471
472 (define_insn "sse_rcpv4sf2"
473   [(set (match_operand:V4SF 0 "register_operand" "=x")
474         (unspec:V4SF
475           [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
476   "TARGET_SSE"
477   "rcpps\t{%1, %0|%0, %1}"
478   [(set_attr "type" "sse")
479    (set_attr "mode" "V4SF")])
480
481 (define_insn "sse_vmrcpv4sf2"
482   [(set (match_operand:V4SF 0 "register_operand" "=x")
483         (vec_merge:V4SF
484           (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
485                        UNSPEC_RCP)
486           (match_operand:V4SF 2 "register_operand" "0")
487           (const_int 1)))]
488   "TARGET_SSE"
489   "rcpss\t{%1, %0|%0, %1}"
490   [(set_attr "type" "sse")
491    (set_attr "mode" "SF")])
492
493 (define_expand "sqrtv4sf2"
494   [(set (match_operand:V4SF 0 "register_operand" "")
495         (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "")))]
496   "TARGET_SSE"
497 {
498   if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
499       && flag_finite_math_only && !flag_trapping_math
500       && flag_unsafe_math_optimizations)
501     {
502       ix86_emit_swsqrtsf (operands[0], operands[1], V4SFmode, 0);
503       DONE;
504     }
505 })
506
507 (define_insn "sse_sqrtv4sf2"
508   [(set (match_operand:V4SF 0 "register_operand" "=x")
509         (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
510   "TARGET_SSE"
511   "sqrtps\t{%1, %0|%0, %1}"
512   [(set_attr "type" "sse")
513    (set_attr "mode" "V4SF")])
514
515 (define_insn "sqrtv2df2"
516   [(set (match_operand:V2DF 0 "register_operand" "=x")
517         (sqrt:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
518   "TARGET_SSE2"
519   "sqrtpd\t{%1, %0|%0, %1}"
520   [(set_attr "type" "sse")
521    (set_attr "mode" "V2DF")])
522
523 (define_insn "<sse>_vmsqrt<mode>2"
524   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
525         (vec_merge:SSEMODEF2P
526           (sqrt:SSEMODEF2P
527             (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "xm"))
528           (match_operand:SSEMODEF2P 2 "register_operand" "0")
529           (const_int 1)))]
530   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
531   "sqrts<ssemodesuffixf2c>\t{%1, %0|%0, %1}"
532   [(set_attr "type" "sse")
533    (set_attr "mode" "<ssescalarmode>")])
534
535 (define_expand "rsqrtv4sf2"
536   [(set (match_operand:V4SF 0 "register_operand" "")
537         (unspec:V4SF
538           [(match_operand:V4SF 1 "nonimmediate_operand" "")] UNSPEC_RSQRT))]
539   "TARGET_SSE_MATH"
540 {
541   ix86_emit_swsqrtsf (operands[0], operands[1], V4SFmode, 1);
542   DONE;
543 })
544
545 (define_insn "sse_rsqrtv4sf2"
546   [(set (match_operand:V4SF 0 "register_operand" "=x")
547         (unspec:V4SF
548           [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
549   "TARGET_SSE"
550   "rsqrtps\t{%1, %0|%0, %1}"
551   [(set_attr "type" "sse")
552    (set_attr "mode" "V4SF")])
553
554 (define_insn "sse_vmrsqrtv4sf2"
555   [(set (match_operand:V4SF 0 "register_operand" "=x")
556         (vec_merge:V4SF
557           (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
558                        UNSPEC_RSQRT)
559           (match_operand:V4SF 2 "register_operand" "0")
560           (const_int 1)))]
561   "TARGET_SSE"
562   "rsqrtss\t{%1, %0|%0, %1}"
563   [(set_attr "type" "sse")
564    (set_attr "mode" "SF")])
565
566 ;; ??? For !flag_finite_math_only, the representation with SMIN/SMAX
567 ;; isn't really correct, as those rtl operators aren't defined when
568 ;; applied to NaNs.  Hopefully the optimizers won't get too smart on us.
569
570 (define_expand "<code><mode>3"
571   [(set (match_operand:SSEMODEF2P 0 "register_operand" "")
572         (smaxmin:SSEMODEF2P
573           (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "")
574           (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "")))]
575   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
576 {
577   if (!flag_finite_math_only)
578     operands[1] = force_reg (<MODE>mode, operands[1]);
579   ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);
580 })
581
582 (define_insn "*<code><mode>3_finite"
583   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
584         (smaxmin:SSEMODEF2P
585           (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "%0")
586           (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")))]
587   "SSE_VEC_FLOAT_MODE_P (<MODE>mode) && flag_finite_math_only
588    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
589   "<maxminfprefix>p<ssemodesuffixf2c>\t{%2, %0|%0, %2}"
590   [(set_attr "type" "sseadd")
591    (set_attr "mode" "<MODE>")])
592
593 (define_insn "*<code><mode>3"
594   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
595         (smaxmin:SSEMODEF2P
596           (match_operand:SSEMODEF2P 1 "register_operand" "0")
597           (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")))]
598   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
599   "<maxminfprefix>p<ssemodesuffixf2c>\t{%2, %0|%0, %2}"
600   [(set_attr "type" "sseadd")
601    (set_attr "mode" "<MODE>")])
602
603 (define_insn "<sse>_vm<code><mode>3"
604   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
605         (vec_merge:SSEMODEF2P
606           (smaxmin:SSEMODEF2P
607             (match_operand:SSEMODEF2P 1 "register_operand" "0")
608             (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm"))
609          (match_dup 1)
610          (const_int 1)))]
611   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
612   "<maxminfprefix>s<ssemodesuffixf2c>\t{%2, %0|%0, %2}"
613   [(set_attr "type" "sse")
614    (set_attr "mode" "<ssescalarmode>")])
615
616 ;; These versions of the min/max patterns implement exactly the operations
617 ;;   min = (op1 < op2 ? op1 : op2)
618 ;;   max = (!(op1 < op2) ? op1 : op2)
619 ;; Their operands are not commutative, and thus they may be used in the
620 ;; presence of -0.0 and NaN.
621
622 (define_insn "*ieee_smin<mode>3"
623   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
624         (unspec:SSEMODEF2P
625           [(match_operand:SSEMODEF2P 1 "register_operand" "0")
626            (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")]
627          UNSPEC_IEEE_MIN))]
628   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
629   "minp<ssemodesuffixf2c>\t{%2, %0|%0, %2}"
630   [(set_attr "type" "sseadd")
631    (set_attr "mode" "<MODE>")])
632
633 (define_insn "*ieee_smax<mode>3"
634   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
635         (unspec:SSEMODEF2P
636           [(match_operand:SSEMODEF2P 1 "register_operand" "0")
637            (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")]
638          UNSPEC_IEEE_MAX))]
639   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
640   "maxp<ssemodesuffixf2c>\t{%2, %0|%0, %2}"
641   [(set_attr "type" "sseadd")
642    (set_attr "mode" "<MODE>")])
643
644 (define_insn "sse3_addsubv4sf3"
645   [(set (match_operand:V4SF 0 "register_operand" "=x")
646         (vec_merge:V4SF
647           (plus:V4SF
648             (match_operand:V4SF 1 "register_operand" "0")
649             (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
650           (minus:V4SF (match_dup 1) (match_dup 2))
651           (const_int 5)))]
652   "TARGET_SSE3"
653   "addsubps\t{%2, %0|%0, %2}"
654   [(set_attr "type" "sseadd")
655    (set_attr "prefix_rep" "1")
656    (set_attr "mode" "V4SF")])
657
658 (define_insn "sse3_addsubv2df3"
659   [(set (match_operand:V2DF 0 "register_operand" "=x")
660         (vec_merge:V2DF
661           (plus:V2DF
662             (match_operand:V2DF 1 "register_operand" "0")
663             (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
664           (minus:V2DF (match_dup 1) (match_dup 2))
665           (const_int 1)))]
666   "TARGET_SSE3"
667   "addsubpd\t{%2, %0|%0, %2}"
668   [(set_attr "type" "sseadd")
669    (set_attr "mode" "V2DF")])
670
671 (define_insn "sse3_h<addsub>v4sf3"
672   [(set (match_operand:V4SF 0 "register_operand" "=x")
673         (vec_concat:V4SF
674           (vec_concat:V2SF
675             (plusminus:SF
676               (vec_select:SF
677                 (match_operand:V4SF 1 "register_operand" "0")
678                 (parallel [(const_int 0)]))
679               (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
680             (plusminus:SF
681               (vec_select:SF (match_dup 1) (parallel [(const_int 2)]))
682               (vec_select:SF (match_dup 1) (parallel [(const_int 3)]))))
683           (vec_concat:V2SF
684             (plusminus:SF
685               (vec_select:SF
686                 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
687                 (parallel [(const_int 0)]))
688               (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))
689             (plusminus:SF
690               (vec_select:SF (match_dup 2) (parallel [(const_int 2)]))
691               (vec_select:SF (match_dup 2) (parallel [(const_int 3)]))))))]
692   "TARGET_SSE3"
693   "h<addsub>ps\t{%2, %0|%0, %2}"
694   [(set_attr "type" "sseadd")
695    (set_attr "prefix_rep" "1")
696    (set_attr "mode" "V4SF")])
697
698 (define_insn "sse3_h<addsub>v2df3"
699   [(set (match_operand:V2DF 0 "register_operand" "=x")
700         (vec_concat:V2DF
701           (plusminus:DF
702             (vec_select:DF
703               (match_operand:V2DF 1 "register_operand" "0")
704               (parallel [(const_int 0)]))
705             (vec_select:DF (match_dup 1) (parallel [(const_int 1)])))
706           (plusminus:DF
707             (vec_select:DF
708               (match_operand:V2DF 2 "nonimmediate_operand" "xm")
709               (parallel [(const_int 0)]))
710             (vec_select:DF (match_dup 2) (parallel [(const_int 1)])))))]
711   "TARGET_SSE3"
712   "h<addsub>pd\t{%2, %0|%0, %2}"
713   [(set_attr "type" "sseadd")
714    (set_attr "mode" "V2DF")])
715
716 (define_expand "reduc_splus_v4sf"
717   [(match_operand:V4SF 0 "register_operand" "")
718    (match_operand:V4SF 1 "register_operand" "")]
719   "TARGET_SSE"
720 {
721   if (TARGET_SSE3)
722     {
723       rtx tmp = gen_reg_rtx (V4SFmode);
724       emit_insn (gen_sse3_haddv4sf3 (tmp, operands[1], operands[1]));
725       emit_insn (gen_sse3_haddv4sf3 (operands[0], tmp, tmp));
726     }
727   else
728     ix86_expand_reduc_v4sf (gen_addv4sf3, operands[0], operands[1]);
729   DONE;
730 })
731
732 (define_expand "reduc_splus_v2df"
733   [(match_operand:V2DF 0 "register_operand" "")
734    (match_operand:V2DF 1 "register_operand" "")]
735   "TARGET_SSE3"
736 {
737   emit_insn (gen_sse3_haddv2df3 (operands[0], operands[1], operands[1]));
738   DONE;
739 })
740
741 (define_expand "reduc_smax_v4sf"
742   [(match_operand:V4SF 0 "register_operand" "")
743    (match_operand:V4SF 1 "register_operand" "")]
744   "TARGET_SSE"
745 {
746   ix86_expand_reduc_v4sf (gen_smaxv4sf3, operands[0], operands[1]);
747   DONE;
748 })
749
750 (define_expand "reduc_smin_v4sf"
751   [(match_operand:V4SF 0 "register_operand" "")
752    (match_operand:V4SF 1 "register_operand" "")]
753   "TARGET_SSE"
754 {
755   ix86_expand_reduc_v4sf (gen_sminv4sf3, operands[0], operands[1]);
756   DONE;
757 })
758
759 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
760 ;;
761 ;; Parallel floating point comparisons
762 ;;
763 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
764
765 (define_insn "<sse>_maskcmp<mode>3"
766   [(set (match_operand:SSEMODEF4 0 "register_operand" "=x")
767         (match_operator:SSEMODEF4 3 "sse_comparison_operator"
768                 [(match_operand:SSEMODEF4 1 "register_operand" "0")
769                  (match_operand:SSEMODEF4 2 "nonimmediate_operand" "xm")]))]
770   "(SSE_FLOAT_MODE_P (<MODE>mode) || SSE_VEC_FLOAT_MODE_P (<MODE>mode))
771    && !TARGET_SSE5"
772   "cmp%D3<ssemodesuffixf4>\t{%2, %0|%0, %2}"
773   [(set_attr "type" "ssecmp")
774    (set_attr "mode" "<MODE>")])
775
776 (define_insn "<sse>_vmmaskcmp<mode>3"
777   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
778         (vec_merge:SSEMODEF2P
779          (match_operator:SSEMODEF2P 3 "sse_comparison_operator"
780                 [(match_operand:SSEMODEF2P 1 "register_operand" "0")
781                  (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")])
782          (match_dup 1)
783          (const_int 1)))]
784   "SSE_VEC_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
785   "cmp%D3s<ssemodesuffixf2c>\t{%2, %0|%0, %2}"
786   [(set_attr "type" "ssecmp")
787    (set_attr "mode" "<ssescalarmode>")])
788
789 (define_insn "<sse>_comi"
790   [(set (reg:CCFP FLAGS_REG)
791         (compare:CCFP
792           (vec_select:MODEF
793             (match_operand:<ssevecmode> 0 "register_operand" "x")
794             (parallel [(const_int 0)]))
795           (vec_select:MODEF
796             (match_operand:<ssevecmode> 1 "nonimmediate_operand" "xm")
797             (parallel [(const_int 0)]))))]
798   "SSE_FLOAT_MODE_P (<MODE>mode)"
799   "comis<ssemodefsuffix>\t{%1, %0|%0, %1}"
800   [(set_attr "type" "ssecomi")
801    (set_attr "mode" "<MODE>")])
802
803 (define_insn "<sse>_ucomi"
804   [(set (reg:CCFPU FLAGS_REG)
805         (compare:CCFPU
806           (vec_select:MODEF
807             (match_operand:<ssevecmode> 0 "register_operand" "x")
808             (parallel [(const_int 0)]))
809           (vec_select:MODEF
810             (match_operand:<ssevecmode> 1 "nonimmediate_operand" "xm")
811             (parallel [(const_int 0)]))))]
812   "SSE_FLOAT_MODE_P (<MODE>mode)"
813   "ucomis<ssemodefsuffix>\t{%1, %0|%0, %1}"
814   [(set_attr "type" "ssecomi")
815    (set_attr "mode" "<MODE>")])
816
817 (define_expand "vcond<mode>"
818   [(set (match_operand:SSEMODEF2P 0 "register_operand" "")
819         (if_then_else:SSEMODEF2P
820           (match_operator 3 ""
821             [(match_operand:SSEMODEF2P 4 "nonimmediate_operand" "")
822              (match_operand:SSEMODEF2P 5 "nonimmediate_operand" "")])
823           (match_operand:SSEMODEF2P 1 "general_operand" "")
824           (match_operand:SSEMODEF2P 2 "general_operand" "")))]
825   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
826 {
827   if (ix86_expand_fp_vcond (operands))
828     DONE;
829   else
830     FAIL;
831 })
832
833 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
834 ;;
835 ;; Parallel floating point logical operations
836 ;;
837 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
838
839 (define_insn "<sse>_nand<mode>3"
840   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
841         (and:SSEMODEF2P
842           (not:SSEMODEF2P
843             (match_operand:SSEMODEF2P 1 "register_operand" "0"))
844           (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")))]
845   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
846   "andnp<ssemodesuffixf2c>\t{%2, %0|%0, %2}"
847   [(set_attr "type" "sselog")
848    (set_attr "mode" "<MODE>")])
849
850 (define_expand "<code><mode>3"
851   [(set (match_operand:SSEMODEF2P 0 "register_operand" "")
852         (plogic:SSEMODEF2P
853           (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "")
854           (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "")))]
855   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
856   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
857
858 (define_insn "*<code><mode>3"
859   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
860         (plogic:SSEMODEF2P
861           (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "%0")
862           (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")))]
863   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)
864    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
865   "<plogicprefix>p<ssemodesuffixf2c>\t{%2, %0|%0, %2}"
866   [(set_attr "type" "sselog")
867    (set_attr "mode" "<MODE>")])
868
869 ;; Also define scalar versions.  These are used for abs, neg, and
870 ;; conditional move.  Using subregs into vector modes causes register
871 ;; allocation lossage.  These patterns do not allow memory operands
872 ;; because the native instructions read the full 128-bits.
873
874 (define_insn "*nand<mode>3"
875   [(set (match_operand:MODEF 0 "register_operand" "=x")
876         (and:MODEF
877           (not:MODEF
878             (match_operand:MODEF 1 "register_operand" "0"))
879             (match_operand:MODEF 2 "register_operand" "x")))]
880   "SSE_FLOAT_MODE_P (<MODE>mode)"
881   "andnp<ssemodefsuffix>\t{%2, %0|%0, %2}"
882   [(set_attr "type" "sselog")
883    (set_attr "mode" "<ssevecmode>")])
884
885 (define_insn "*<code><mode>3"
886   [(set (match_operand:MODEF 0 "register_operand" "=x")
887         (plogic:MODEF
888           (match_operand:MODEF 1 "register_operand" "0")
889           (match_operand:MODEF 2 "register_operand" "x")))]
890   "SSE_FLOAT_MODE_P (<MODE>mode)"
891   "<plogicprefix>p<ssemodefsuffix>\t{%2, %0|%0, %2}"
892   [(set_attr "type" "sselog")
893    (set_attr "mode" "<ssevecmode>")])
894
895 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
896 ;;
897 ;; SSE5 floating point multiply/accumulate instructions This includes the
898 ;; scalar version of the instructions as well as the vector
899 ;;
900 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
901
902 ;; In order to match (*a * *b) + *c, particularly when vectorizing, allow
903 ;; combine to generate a multiply/add with two memory references.  We then
904 ;; split this insn, into loading up the destination register with one of the
905 ;; memory operations.  If we don't manage to split the insn, reload will
906 ;; generate the appropriate moves.  The reason this is needed, is that combine
907 ;; has already folded one of the memory references into both the multiply and
908 ;; add insns, and it can't generate a new pseudo.  I.e.:
909 ;;      (set (reg1) (mem (addr1)))
910 ;;      (set (reg2) (mult (reg1) (mem (addr2))))
911 ;;      (set (reg3) (plus (reg2) (mem (addr3))))
912
913 (define_insn "sse5_fmadd<mode>4"
914   [(set (match_operand:SSEMODEF4 0 "register_operand" "=x,x,x,x")
915         (plus:SSEMODEF4
916          (mult:SSEMODEF4
917           (match_operand:SSEMODEF4 1 "nonimmediate_operand" "%0,0,x,xm")
918           (match_operand:SSEMODEF4 2 "nonimmediate_operand" "x,xm,xm,x"))
919          (match_operand:SSEMODEF4 3 "nonimmediate_operand" "xm,x,0,0")))]
920   "TARGET_SSE5 && TARGET_FUSED_MADD
921    && ix86_sse5_valid_op_p (operands, insn, 4, true, 2)"
922   "fmadd<ssemodesuffixf4>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
923   [(set_attr "type" "ssemuladd")
924    (set_attr "mode" "<MODE>")])
925
926 ;; Split fmadd with two memory operands into a load and the fmadd.
927 (define_split
928   [(set (match_operand:SSEMODEF4 0 "register_operand" "")
929         (plus:SSEMODEF4
930          (mult:SSEMODEF4
931           (match_operand:SSEMODEF4 1 "nonimmediate_operand" "")
932           (match_operand:SSEMODEF4 2 "nonimmediate_operand" ""))
933          (match_operand:SSEMODEF4 3 "nonimmediate_operand" "")))]
934   "TARGET_SSE5
935    && !ix86_sse5_valid_op_p (operands, insn, 4, true, 1)
936    && ix86_sse5_valid_op_p (operands, insn, 4, true, 2)
937    && !reg_mentioned_p (operands[0], operands[1])
938    && !reg_mentioned_p (operands[0], operands[2])
939    && !reg_mentioned_p (operands[0], operands[3])"
940   [(const_int 0)]
941 {
942   ix86_expand_sse5_multiple_memory (operands, 4, <MODE>mode);
943   emit_insn (gen_sse5_fmadd<mode>4 (operands[0], operands[1],
944                                     operands[2], operands[3]));
945   DONE;
946 })
947
948 ;; For the scalar operations, use operand1 for the upper words that aren't
949 ;; modified, so restrict the forms that are generated.
950 ;; Scalar version of fmadd
951 (define_insn "sse5_vmfmadd<mode>4"
952   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x")
953         (vec_merge:SSEMODEF2P
954          (plus:SSEMODEF2P
955           (mult:SSEMODEF2P
956            (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "0,0")
957            (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm"))
958           (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x"))
959          (match_dup 1)
960          (const_int 1)))]
961   "TARGET_SSE5 && TARGET_FUSED_MADD
962    && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
963   "fmadd<ssemodesuffixf2s>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
964   [(set_attr "type" "ssemuladd")
965    (set_attr "mode" "<MODE>")])
966
967 ;; Floating multiply and subtract
968 ;; Allow two memory operands the same as fmadd
969 (define_insn "sse5_fmsub<mode>4"
970   [(set (match_operand:SSEMODEF4 0 "register_operand" "=x,x,x,x")
971         (minus:SSEMODEF4
972          (mult:SSEMODEF4
973           (match_operand:SSEMODEF4 1 "nonimmediate_operand" "%0,0,x,xm")
974           (match_operand:SSEMODEF4 2 "nonimmediate_operand" "x,xm,xm,x"))
975          (match_operand:SSEMODEF4 3 "nonimmediate_operand" "xm,x,0,0")))]
976   "TARGET_SSE5 && TARGET_FUSED_MADD
977    && ix86_sse5_valid_op_p (operands, insn, 4, true, 2)"
978   "fmsub<ssemodesuffixf4>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
979   [(set_attr "type" "ssemuladd")
980    (set_attr "mode" "<MODE>")])
981
982 ;; Split fmsub with two memory operands into a load and the fmsub.
983 (define_split
984   [(set (match_operand:SSEMODEF4 0 "register_operand" "")
985         (minus:SSEMODEF4
986          (mult:SSEMODEF4
987           (match_operand:SSEMODEF4 1 "nonimmediate_operand" "")
988           (match_operand:SSEMODEF4 2 "nonimmediate_operand" ""))
989          (match_operand:SSEMODEF4 3 "nonimmediate_operand" "")))]
990   "TARGET_SSE5
991    && !ix86_sse5_valid_op_p (operands, insn, 4, true, 1)
992    && ix86_sse5_valid_op_p (operands, insn, 4, true, 2)
993    && !reg_mentioned_p (operands[0], operands[1])
994    && !reg_mentioned_p (operands[0], operands[2])
995    && !reg_mentioned_p (operands[0], operands[3])"
996   [(const_int 0)]
997 {
998   ix86_expand_sse5_multiple_memory (operands, 4, <MODE>mode);
999   emit_insn (gen_sse5_fmsub<mode>4 (operands[0], operands[1],
1000                                     operands[2], operands[3]));
1001   DONE;
1002 })
1003
1004 ;; For the scalar operations, use operand1 for the upper words that aren't
1005 ;; modified, so restrict the forms that are generated.
1006 ;; Scalar version of fmsub
1007 (define_insn "sse5_vmfmsub<mode>4"
1008   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x")
1009         (vec_merge:SSEMODEF2P
1010          (minus:SSEMODEF2P
1011           (mult:SSEMODEF2P
1012            (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "0,0")
1013            (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm"))
1014           (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x"))
1015          (match_dup 1)
1016          (const_int 1)))]
1017   "TARGET_SSE5 && TARGET_FUSED_MADD
1018    && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
1019   "fmsub<ssemodesuffixf2s>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1020   [(set_attr "type" "ssemuladd")
1021    (set_attr "mode" "<MODE>")])
1022
1023 ;; Floating point negative multiply and add
1024 ;; Rewrite (- (a * b) + c) into the canonical form: c - (a * b)
1025 ;; Note operands are out of order to simplify call to ix86_sse5_valid_p
1026 ;; Allow two memory operands to help in optimizing.
1027 (define_insn "sse5_fnmadd<mode>4"
1028   [(set (match_operand:SSEMODEF4 0 "register_operand" "=x,x,x,x")
1029         (minus:SSEMODEF4
1030          (match_operand:SSEMODEF4 3 "nonimmediate_operand" "xm,x,0,0")
1031          (mult:SSEMODEF4
1032           (match_operand:SSEMODEF4 1 "nonimmediate_operand" "%0,0,x,xm")
1033           (match_operand:SSEMODEF4 2 "nonimmediate_operand" "x,xm,xm,x"))))]
1034   "TARGET_SSE5 && TARGET_FUSED_MADD
1035    && ix86_sse5_valid_op_p (operands, insn, 4, true, 2)"
1036   "fnmadd<ssemodesuffixf4>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1037   [(set_attr "type" "ssemuladd")
1038    (set_attr "mode" "<MODE>")])
1039
1040 ;; Split fnmadd with two memory operands into a load and the fnmadd.
1041 (define_split
1042   [(set (match_operand:SSEMODEF4 0 "register_operand" "")
1043         (minus:SSEMODEF4
1044          (match_operand:SSEMODEF4 3 "nonimmediate_operand" "")
1045          (mult:SSEMODEF4
1046           (match_operand:SSEMODEF4 1 "nonimmediate_operand" "")
1047           (match_operand:SSEMODEF4 2 "nonimmediate_operand" ""))))]
1048   "TARGET_SSE5
1049    && !ix86_sse5_valid_op_p (operands, insn, 4, true, 1)
1050    && ix86_sse5_valid_op_p (operands, insn, 4, true, 2)
1051    && !reg_mentioned_p (operands[0], operands[1])
1052    && !reg_mentioned_p (operands[0], operands[2])
1053    && !reg_mentioned_p (operands[0], operands[3])"
1054   [(const_int 0)]
1055 {
1056   ix86_expand_sse5_multiple_memory (operands, 4, <MODE>mode);
1057   emit_insn (gen_sse5_fnmadd<mode>4 (operands[0], operands[1],
1058                                      operands[2], operands[3]));
1059   DONE;
1060 })
1061
1062 ;; For the scalar operations, use operand1 for the upper words that aren't
1063 ;; modified, so restrict the forms that are generated.
1064 ;; Scalar version of fnmadd
1065 (define_insn "sse5_vmfnmadd<mode>4"
1066   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x")
1067         (vec_merge:SSEMODEF2P
1068          (minus:SSEMODEF2P
1069           (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x")
1070           (mult:SSEMODEF2P
1071            (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "0,0")
1072            (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm")))
1073          (match_dup 1)
1074          (const_int 1)))]
1075   "TARGET_SSE5 && TARGET_FUSED_MADD
1076    && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
1077   "fnmadd<ssemodesuffixf2s>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1078   [(set_attr "type" "ssemuladd")
1079    (set_attr "mode" "<MODE>")])
1080
1081 ;; Floating point negative multiply and subtract
1082 ;; Rewrite (- (a * b) - c) into the canonical form: ((-a) * b) - c
1083 ;; Allow 2 memory operands to help with optimization
1084 (define_insn "sse5_fnmsub<mode>4"
1085   [(set (match_operand:SSEMODEF4 0 "register_operand" "=x,x")
1086         (minus:SSEMODEF4
1087          (mult:SSEMODEF4
1088           (neg:SSEMODEF4
1089            (match_operand:SSEMODEF4 1 "nonimmediate_operand" "0,0"))
1090           (match_operand:SSEMODEF4 2 "nonimmediate_operand" "x,xm"))
1091          (match_operand:SSEMODEF4 3 "nonimmediate_operand" "xm,x")))]
1092   "TARGET_SSE5 && TARGET_FUSED_MADD
1093    && ix86_sse5_valid_op_p (operands, insn, 4, true, 2)"
1094   "fnmsub<ssemodesuffixf4>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1095   [(set_attr "type" "ssemuladd")
1096    (set_attr "mode" "<MODE>")])
1097
1098 ;; Split fnmsub with two memory operands into a load and the fmsub.
1099 (define_split
1100   [(set (match_operand:SSEMODEF4 0 "register_operand" "")
1101         (minus:SSEMODEF4
1102          (mult:SSEMODEF4
1103           (neg:SSEMODEF4
1104            (match_operand:SSEMODEF4 1 "nonimmediate_operand" ""))
1105           (match_operand:SSEMODEF4 2 "nonimmediate_operand" ""))
1106          (match_operand:SSEMODEF4 3 "nonimmediate_operand" "")))]
1107   "TARGET_SSE5
1108    && !ix86_sse5_valid_op_p (operands, insn, 4, true, 1)
1109    && ix86_sse5_valid_op_p (operands, insn, 4, true, 2)
1110    && !reg_mentioned_p (operands[0], operands[1])
1111    && !reg_mentioned_p (operands[0], operands[2])
1112    && !reg_mentioned_p (operands[0], operands[3])"
1113   [(const_int 0)]
1114 {
1115   ix86_expand_sse5_multiple_memory (operands, 4, <MODE>mode);
1116   emit_insn (gen_sse5_fnmsub<mode>4 (operands[0], operands[1],
1117                                      operands[2], operands[3]));
1118   DONE;
1119 })
1120
1121 ;; For the scalar operations, use operand1 for the upper words that aren't
1122 ;; modified, so restrict the forms that are generated.
1123 ;; Scalar version of fnmsub
1124 (define_insn "sse5_vmfnmsub<mode>4"
1125   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x")
1126         (vec_merge:SSEMODEF2P
1127          (minus:SSEMODEF2P
1128           (mult:SSEMODEF2P
1129            (neg:SSEMODEF2P
1130             (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "0,0"))
1131            (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm"))
1132           (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x"))
1133          (match_dup 1)
1134          (const_int 1)))]
1135   "TARGET_SSE5 && TARGET_FUSED_MADD
1136    && ix86_sse5_valid_op_p (operands, insn, 4, true, 2)"
1137   "fnmsub<ssemodesuffixf2s>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1138   [(set_attr "type" "ssemuladd")
1139    (set_attr "mode" "<MODE>")])
1140
1141 ;; The same instructions using an UNSPEC to allow the intrinsic to be used
1142 ;; even if the user used -mno-fused-madd
1143 ;; Parallel instructions.  During instruction generation, just default
1144 ;; to registers, and let combine later build the appropriate instruction.
1145 (define_expand "sse5i_fmadd<mode>4"
1146   [(set (match_operand:SSEMODEF2P 0 "register_operand" "")
1147         (unspec:SSEMODEF2P
1148          [(plus:SSEMODEF2P
1149            (mult:SSEMODEF2P
1150             (match_operand:SSEMODEF2P 1 "register_operand" "")
1151             (match_operand:SSEMODEF2P 2 "register_operand" ""))
1152            (match_operand:SSEMODEF2P 3 "register_operand" ""))]
1153          UNSPEC_SSE5_INTRINSIC))]
1154   "TARGET_SSE5"
1155 {
1156   /* If we have -mfused-madd, emit the normal insn rather than the UNSPEC */
1157   if (TARGET_FUSED_MADD)
1158     {
1159       emit_insn (gen_sse5_fmadd<mode>4 (operands[0], operands[1],
1160                                         operands[2], operands[3]));
1161       DONE;
1162     }
1163 })
1164
1165 (define_insn "*sse5i_fmadd<mode>4"
1166   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x,x,x")
1167         (unspec:SSEMODEF2P
1168          [(plus:SSEMODEF2P
1169            (mult:SSEMODEF2P
1170             (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "%0,0,x,xm")
1171             (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm,xm,x"))
1172            (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x,0,0"))]
1173          UNSPEC_SSE5_INTRINSIC))]
1174   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
1175   "fmadd<ssemodesuffixf4>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1176   [(set_attr "type" "ssemuladd")
1177    (set_attr "mode" "<MODE>")])
1178
1179 (define_expand "sse5i_fmsub<mode>4"
1180   [(set (match_operand:SSEMODEF2P 0 "register_operand" "")
1181         (unspec:SSEMODEF2P
1182          [(minus:SSEMODEF2P
1183            (mult:SSEMODEF2P
1184             (match_operand:SSEMODEF2P 1 "register_operand" "")
1185             (match_operand:SSEMODEF2P 2 "register_operand" ""))
1186            (match_operand:SSEMODEF2P 3 "register_operand" ""))]
1187          UNSPEC_SSE5_INTRINSIC))]
1188   "TARGET_SSE5"
1189 {
1190   /* If we have -mfused-madd, emit the normal insn rather than the UNSPEC */
1191   if (TARGET_FUSED_MADD)
1192     {
1193       emit_insn (gen_sse5_fmsub<mode>4 (operands[0], operands[1],
1194                                         operands[2], operands[3]));
1195       DONE;
1196     }
1197 })
1198
1199 (define_insn "*sse5i_fmsub<mode>4"
1200   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x,x,x")
1201         (unspec:SSEMODEF2P
1202          [(minus:SSEMODEF2P
1203            (mult:SSEMODEF2P
1204             (match_operand:SSEMODEF2P 1 "register_operand" "%0,0,x,xm")
1205             (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm,xm,x"))
1206            (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x,0,0"))]
1207          UNSPEC_SSE5_INTRINSIC))]
1208   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
1209   "fmsub<ssemodesuffixf4>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1210   [(set_attr "type" "ssemuladd")
1211    (set_attr "mode" "<MODE>")])
1212
1213 ;; Rewrite (- (a * b) + c) into the canonical form: c - (a * b)
1214 ;; Note operands are out of order to simplify call to ix86_sse5_valid_p
1215 (define_expand "sse5i_fnmadd<mode>4"
1216   [(set (match_operand:SSEMODEF2P 0 "register_operand" "")
1217         (unspec:SSEMODEF2P
1218          [(minus:SSEMODEF2P
1219            (match_operand:SSEMODEF2P 3 "register_operand" "")
1220            (mult:SSEMODEF2P
1221             (match_operand:SSEMODEF2P 1 "register_operand" "")
1222             (match_operand:SSEMODEF2P 2 "register_operand" "")))]
1223          UNSPEC_SSE5_INTRINSIC))]
1224   "TARGET_SSE5"
1225 {
1226   /* If we have -mfused-madd, emit the normal insn rather than the UNSPEC */
1227   if (TARGET_FUSED_MADD)
1228     {
1229       emit_insn (gen_sse5_fnmadd<mode>4 (operands[0], operands[1],
1230                                          operands[2], operands[3]));
1231       DONE;
1232     }
1233 })
1234
1235 (define_insn "*sse5i_fnmadd<mode>4"
1236   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x,x,x")
1237         (unspec:SSEMODEF2P
1238          [(minus:SSEMODEF2P
1239            (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x,0,0")
1240            (mult:SSEMODEF2P
1241             (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "%0,0,x,xm")
1242             (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm,xm,x")))]
1243          UNSPEC_SSE5_INTRINSIC))]
1244   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
1245   "fnmadd<ssemodesuffixf4>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1246   [(set_attr "type" "ssemuladd")
1247    (set_attr "mode" "<MODE>")])
1248
1249 ;; Rewrite (- (a * b) - c) into the canonical form: ((-a) * b) - c
1250 (define_expand "sse5i_fnmsub<mode>4"
1251   [(set (match_operand:SSEMODEF2P 0 "register_operand" "")
1252         (unspec:SSEMODEF2P
1253          [(minus:SSEMODEF2P
1254            (mult:SSEMODEF2P
1255             (neg:SSEMODEF2P
1256              (match_operand:SSEMODEF2P 1 "register_operand" ""))
1257             (match_operand:SSEMODEF2P 2 "register_operand" ""))
1258            (match_operand:SSEMODEF2P 3 "register_operand" ""))]
1259          UNSPEC_SSE5_INTRINSIC))]
1260   "TARGET_SSE5"
1261 {
1262   /* If we have -mfused-madd, emit the normal insn rather than the UNSPEC */
1263   if (TARGET_FUSED_MADD)
1264     {
1265       emit_insn (gen_sse5_fnmsub<mode>4 (operands[0], operands[1],
1266                                          operands[2], operands[3]));
1267       DONE;
1268     }
1269 })
1270
1271 (define_insn "*sse5i_fnmsub<mode>4"
1272   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x,x,x")
1273         (unspec:SSEMODEF2P
1274          [(minus:SSEMODEF2P
1275            (mult:SSEMODEF2P
1276             (neg:SSEMODEF2P
1277              (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "%0,0,x,xm"))
1278             (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm,xm,x"))
1279            (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x,0,0"))]
1280          UNSPEC_SSE5_INTRINSIC))]
1281   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
1282   "fnmsub<ssemodesuffixf4>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1283   [(set_attr "type" "ssemuladd")
1284    (set_attr "mode" "<MODE>")])
1285
1286 ;; Scalar instructions
1287 (define_expand "sse5i_vmfmadd<mode>4"
1288   [(set (match_operand:SSEMODEF2P 0 "register_operand" "")
1289         (unspec:SSEMODEF2P
1290          [(vec_merge:SSEMODEF2P
1291            (plus:SSEMODEF2P
1292             (mult:SSEMODEF2P
1293              (match_operand:SSEMODEF2P 1 "register_operand" "")
1294              (match_operand:SSEMODEF2P 2 "register_operand" ""))
1295             (match_operand:SSEMODEF2P 3 "register_operand" ""))
1296            (match_dup 1)
1297            (const_int 0))]
1298          UNSPEC_SSE5_INTRINSIC))]
1299   "TARGET_SSE5"
1300 {
1301   /* If we have -mfused-madd, emit the normal insn rather than the UNSPEC */
1302   if (TARGET_FUSED_MADD)
1303     {
1304       emit_insn (gen_sse5_vmfmadd<mode>4 (operands[0], operands[1],
1305                                           operands[2], operands[3]));
1306       DONE;
1307     }
1308 })
1309
1310 ;; For the scalar operations, use operand1 for the upper words that aren't
1311 ;; modified, so restrict the forms that are accepted.
1312 (define_insn "*sse5i_vmfmadd<mode>4"
1313   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x")
1314         (unspec:SSEMODEF2P
1315          [(vec_merge:SSEMODEF2P
1316            (plus:SSEMODEF2P
1317             (mult:SSEMODEF2P
1318              (match_operand:SSEMODEF2P 1 "register_operand" "0,0")
1319              (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm"))
1320             (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x"))
1321            (match_dup 0)
1322            (const_int 0))]
1323          UNSPEC_SSE5_INTRINSIC))]
1324   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
1325   "fmadd<ssemodesuffixf2s>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1326   [(set_attr "type" "ssemuladd")
1327    (set_attr "mode" "<ssescalarmode>")])
1328
1329 (define_expand "sse5i_vmfmsub<mode>4"
1330   [(set (match_operand:SSEMODEF2P 0 "register_operand" "")
1331         (unspec:SSEMODEF2P
1332          [(vec_merge:SSEMODEF2P
1333            (minus:SSEMODEF2P
1334             (mult:SSEMODEF2P
1335              (match_operand:SSEMODEF2P 1 "register_operand" "")
1336              (match_operand:SSEMODEF2P 2 "register_operand" ""))
1337             (match_operand:SSEMODEF2P 3 "register_operand" ""))
1338            (match_dup 0)
1339            (const_int 1))]
1340          UNSPEC_SSE5_INTRINSIC))]
1341   "TARGET_SSE5"
1342 {
1343   /* If we have -mfused-madd, emit the normal insn rather than the UNSPEC */
1344   if (TARGET_FUSED_MADD)
1345     {
1346       emit_insn (gen_sse5_vmfmsub<mode>4 (operands[0], operands[1],
1347                                           operands[2], operands[3]));
1348       DONE;
1349     }
1350 })
1351
1352 (define_insn "*sse5i_vmfmsub<mode>4"
1353   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x")
1354         (unspec:SSEMODEF2P
1355          [(vec_merge:SSEMODEF2P
1356            (minus:SSEMODEF2P
1357             (mult:SSEMODEF2P
1358              (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "0,0")
1359              (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm"))
1360             (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x"))
1361            (match_dup 1)
1362            (const_int 1))]
1363          UNSPEC_SSE5_INTRINSIC))]
1364   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
1365   "fmsub<ssemodesuffixf2s>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1366   [(set_attr "type" "ssemuladd")
1367    (set_attr "mode" "<ssescalarmode>")])
1368
1369 ;; Note operands are out of order to simplify call to ix86_sse5_valid_p
1370 (define_expand "sse5i_vmfnmadd<mode>4"
1371   [(set (match_operand:SSEMODEF2P 0 "register_operand" "")
1372         (unspec:SSEMODEF2P
1373          [(vec_merge:SSEMODEF2P
1374            (minus:SSEMODEF2P
1375             (match_operand:SSEMODEF2P 3 "register_operand" "")
1376             (mult:SSEMODEF2P
1377              (match_operand:SSEMODEF2P 1 "register_operand" "")
1378              (match_operand:SSEMODEF2P 2 "register_operand" "")))
1379            (match_dup 1)
1380            (const_int 1))]
1381          UNSPEC_SSE5_INTRINSIC))]
1382   "TARGET_SSE5"
1383 {
1384   /* If we have -mfused-madd, emit the normal insn rather than the UNSPEC */
1385   if (TARGET_FUSED_MADD)
1386     {
1387       emit_insn (gen_sse5_vmfnmadd<mode>4 (operands[0], operands[1],
1388                                            operands[2], operands[3]));
1389       DONE;
1390     }
1391 })
1392
1393 (define_insn "*sse5i_vmfnmadd<mode>4"
1394   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x")
1395         (unspec:SSEMODEF2P
1396          [(vec_merge:SSEMODEF2P
1397            (minus:SSEMODEF2P
1398             (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x")
1399             (mult:SSEMODEF2P
1400              (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "0,0")
1401              (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm")))
1402            (match_dup 1)
1403            (const_int 1))]
1404          UNSPEC_SSE5_INTRINSIC))]
1405   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
1406   "fnmadd<ssemodesuffixf2s>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1407   [(set_attr "type" "ssemuladd")
1408    (set_attr "mode" "<ssescalarmode>")])
1409
1410 (define_expand "sse5i_vmfnmsub<mode>4"
1411   [(set (match_operand:SSEMODEF2P 0 "register_operand" "")
1412         (unspec:SSEMODEF2P
1413          [(vec_merge:SSEMODEF2P
1414            (minus:SSEMODEF2P
1415             (mult:SSEMODEF2P
1416              (neg:SSEMODEF2P
1417               (match_operand:SSEMODEF2P 1 "register_operand" ""))
1418              (match_operand:SSEMODEF2P 2 "register_operand" ""))
1419             (match_operand:SSEMODEF2P 3 "register_operand" ""))
1420            (match_dup 1)
1421            (const_int 1))]
1422          UNSPEC_SSE5_INTRINSIC))]
1423   "TARGET_SSE5"
1424 {
1425   /* If we have -mfused-madd, emit the normal insn rather than the UNSPEC */
1426   if (TARGET_FUSED_MADD)
1427     {
1428       emit_insn (gen_sse5_vmfnmsub<mode>4 (operands[0], operands[1],
1429                                            operands[2], operands[3]));
1430       DONE;
1431     }
1432 })
1433
1434 (define_insn "*sse5i_vmfnmsub<mode>4"
1435   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x")
1436         (unspec:SSEMODEF2P
1437          [(vec_merge:SSEMODEF2P
1438            (minus:SSEMODEF2P
1439             (mult:SSEMODEF2P
1440              (neg:SSEMODEF2P
1441               (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "0,0"))
1442              (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm"))
1443             (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x"))
1444            (match_dup 1)
1445            (const_int 1))]
1446          UNSPEC_SSE5_INTRINSIC))]
1447   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
1448   "fnmsub<ssemodesuffixf2s>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1449   [(set_attr "type" "ssemuladd")
1450    (set_attr "mode" "<ssescalarmode>")])
1451
1452 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1453 ;;
1454 ;; Parallel single-precision floating point conversion operations
1455 ;;
1456 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1457
1458 (define_insn "sse_cvtpi2ps"
1459   [(set (match_operand:V4SF 0 "register_operand" "=x")
1460         (vec_merge:V4SF
1461           (vec_duplicate:V4SF
1462             (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
1463           (match_operand:V4SF 1 "register_operand" "0")
1464           (const_int 3)))]
1465   "TARGET_SSE"
1466   "cvtpi2ps\t{%2, %0|%0, %2}"
1467   [(set_attr "type" "ssecvt")
1468    (set_attr "mode" "V4SF")])
1469
1470 (define_insn "sse_cvtps2pi"
1471   [(set (match_operand:V2SI 0 "register_operand" "=y")
1472         (vec_select:V2SI
1473           (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
1474                        UNSPEC_FIX_NOTRUNC)
1475           (parallel [(const_int 0) (const_int 1)])))]
1476   "TARGET_SSE"
1477   "cvtps2pi\t{%1, %0|%0, %1}"
1478   [(set_attr "type" "ssecvt")
1479    (set_attr "unit" "mmx")
1480    (set_attr "mode" "DI")])
1481
1482 (define_insn "sse_cvttps2pi"
1483   [(set (match_operand:V2SI 0 "register_operand" "=y")
1484         (vec_select:V2SI
1485           (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
1486           (parallel [(const_int 0) (const_int 1)])))]
1487   "TARGET_SSE"
1488   "cvttps2pi\t{%1, %0|%0, %1}"
1489   [(set_attr "type" "ssecvt")
1490    (set_attr "unit" "mmx")
1491    (set_attr "mode" "SF")])
1492
1493 (define_insn "sse_cvtsi2ss"
1494   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
1495         (vec_merge:V4SF
1496           (vec_duplicate:V4SF
1497             (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,m")))
1498           (match_operand:V4SF 1 "register_operand" "0,0")
1499           (const_int 1)))]
1500   "TARGET_SSE"
1501   "cvtsi2ss\t{%2, %0|%0, %2}"
1502   [(set_attr "type" "sseicvt")
1503    (set_attr "athlon_decode" "vector,double")
1504    (set_attr "amdfam10_decode" "vector,double")
1505    (set_attr "mode" "SF")])
1506
1507 (define_insn "sse_cvtsi2ssq"
1508   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
1509         (vec_merge:V4SF
1510           (vec_duplicate:V4SF
1511             (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
1512           (match_operand:V4SF 1 "register_operand" "0,0")
1513           (const_int 1)))]
1514   "TARGET_SSE && TARGET_64BIT"
1515   "cvtsi2ssq\t{%2, %0|%0, %2}"
1516   [(set_attr "type" "sseicvt")
1517    (set_attr "athlon_decode" "vector,double")
1518    (set_attr "amdfam10_decode" "vector,double")
1519    (set_attr "mode" "SF")])
1520
1521 (define_insn "sse_cvtss2si"
1522   [(set (match_operand:SI 0 "register_operand" "=r,r")
1523         (unspec:SI
1524           [(vec_select:SF
1525              (match_operand:V4SF 1 "nonimmediate_operand" "x,m")
1526              (parallel [(const_int 0)]))]
1527           UNSPEC_FIX_NOTRUNC))]
1528   "TARGET_SSE"
1529   "cvtss2si\t{%1, %0|%0, %1}"
1530   [(set_attr "type" "sseicvt")
1531    (set_attr "athlon_decode" "double,vector")
1532    (set_attr "prefix_rep" "1")
1533    (set_attr "mode" "SI")])
1534
1535 (define_insn "sse_cvtss2si_2"
1536   [(set (match_operand:SI 0 "register_operand" "=r,r")
1537         (unspec:SI [(match_operand:SF 1 "nonimmediate_operand" "x,m")]
1538                    UNSPEC_FIX_NOTRUNC))]
1539   "TARGET_SSE"
1540   "cvtss2si\t{%1, %0|%0, %1}"
1541   [(set_attr "type" "sseicvt")
1542    (set_attr "athlon_decode" "double,vector")
1543    (set_attr "amdfam10_decode" "double,double")
1544    (set_attr "prefix_rep" "1")
1545    (set_attr "mode" "SI")])
1546
1547 (define_insn "sse_cvtss2siq"
1548   [(set (match_operand:DI 0 "register_operand" "=r,r")
1549         (unspec:DI
1550           [(vec_select:SF
1551              (match_operand:V4SF 1 "nonimmediate_operand" "x,m")
1552              (parallel [(const_int 0)]))]
1553           UNSPEC_FIX_NOTRUNC))]
1554   "TARGET_SSE && TARGET_64BIT"
1555   "cvtss2siq\t{%1, %0|%0, %1}"
1556   [(set_attr "type" "sseicvt")
1557    (set_attr "athlon_decode" "double,vector")
1558    (set_attr "prefix_rep" "1")
1559    (set_attr "mode" "DI")])
1560
1561 (define_insn "sse_cvtss2siq_2"
1562   [(set (match_operand:DI 0 "register_operand" "=r,r")
1563         (unspec:DI [(match_operand:SF 1 "nonimmediate_operand" "x,m")]
1564                    UNSPEC_FIX_NOTRUNC))]
1565   "TARGET_SSE && TARGET_64BIT"
1566   "cvtss2siq\t{%1, %0|%0, %1}"
1567   [(set_attr "type" "sseicvt")
1568    (set_attr "athlon_decode" "double,vector")
1569    (set_attr "amdfam10_decode" "double,double")
1570    (set_attr "prefix_rep" "1")
1571    (set_attr "mode" "DI")])
1572
1573 (define_insn "sse_cvttss2si"
1574   [(set (match_operand:SI 0 "register_operand" "=r,r")
1575         (fix:SI
1576           (vec_select:SF
1577             (match_operand:V4SF 1 "nonimmediate_operand" "x,m")
1578             (parallel [(const_int 0)]))))]
1579   "TARGET_SSE"
1580   "cvttss2si\t{%1, %0|%0, %1}"
1581   [(set_attr "type" "sseicvt")
1582    (set_attr "athlon_decode" "double,vector")
1583    (set_attr "amdfam10_decode" "double,double")
1584    (set_attr "prefix_rep" "1")
1585    (set_attr "mode" "SI")])
1586
1587 (define_insn "sse_cvttss2siq"
1588   [(set (match_operand:DI 0 "register_operand" "=r,r")
1589         (fix:DI
1590           (vec_select:SF
1591             (match_operand:V4SF 1 "nonimmediate_operand" "x,m")
1592             (parallel [(const_int 0)]))))]
1593   "TARGET_SSE && TARGET_64BIT"
1594   "cvttss2siq\t{%1, %0|%0, %1}"
1595   [(set_attr "type" "sseicvt")
1596    (set_attr "athlon_decode" "double,vector")
1597    (set_attr "amdfam10_decode" "double,double")
1598    (set_attr "prefix_rep" "1")
1599    (set_attr "mode" "DI")])
1600
1601 (define_insn "sse2_cvtdq2ps"
1602   [(set (match_operand:V4SF 0 "register_operand" "=x")
1603         (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
1604   "TARGET_SSE2"
1605   "cvtdq2ps\t{%1, %0|%0, %1}"
1606   [(set_attr "type" "ssecvt")
1607    (set_attr "mode" "V4SF")])
1608
1609 (define_insn "sse2_cvtps2dq"
1610   [(set (match_operand:V4SI 0 "register_operand" "=x")
1611         (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
1612                      UNSPEC_FIX_NOTRUNC))]
1613   "TARGET_SSE2"
1614   "cvtps2dq\t{%1, %0|%0, %1}"
1615   [(set_attr "type" "ssecvt")
1616    (set_attr "prefix_data16" "1")
1617    (set_attr "mode" "TI")])
1618
1619 (define_insn "sse2_cvttps2dq"
1620   [(set (match_operand:V4SI 0 "register_operand" "=x")
1621         (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
1622   "TARGET_SSE2"
1623   "cvttps2dq\t{%1, %0|%0, %1}"
1624   [(set_attr "type" "ssecvt")
1625    (set_attr "prefix_rep" "1")
1626    (set_attr "mode" "TI")])
1627
1628 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1629 ;;
1630 ;; Parallel double-precision floating point conversion operations
1631 ;;
1632 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1633
1634 (define_insn "sse2_cvtpi2pd"
1635   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
1636         (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "y,m")))]
1637   "TARGET_SSE2"
1638   "cvtpi2pd\t{%1, %0|%0, %1}"
1639   [(set_attr "type" "ssecvt")
1640    (set_attr "unit" "mmx,*")
1641    (set_attr "mode" "V2DF")])
1642
1643 (define_insn "sse2_cvtpd2pi"
1644   [(set (match_operand:V2SI 0 "register_operand" "=y")
1645         (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
1646                      UNSPEC_FIX_NOTRUNC))]
1647   "TARGET_SSE2"
1648   "cvtpd2pi\t{%1, %0|%0, %1}"
1649   [(set_attr "type" "ssecvt")
1650    (set_attr "unit" "mmx")
1651    (set_attr "prefix_data16" "1")
1652    (set_attr "mode" "DI")])
1653
1654 (define_insn "sse2_cvttpd2pi"
1655   [(set (match_operand:V2SI 0 "register_operand" "=y")
1656         (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
1657   "TARGET_SSE2"
1658   "cvttpd2pi\t{%1, %0|%0, %1}"
1659   [(set_attr "type" "ssecvt")
1660    (set_attr "unit" "mmx")
1661    (set_attr "prefix_data16" "1")
1662    (set_attr "mode" "TI")])
1663
1664 (define_insn "sse2_cvtsi2sd"
1665   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
1666         (vec_merge:V2DF
1667           (vec_duplicate:V2DF
1668             (float:DF (match_operand:SI 2 "nonimmediate_operand" "r,m")))
1669           (match_operand:V2DF 1 "register_operand" "0,0")
1670           (const_int 1)))]
1671   "TARGET_SSE2"
1672   "cvtsi2sd\t{%2, %0|%0, %2}"
1673   [(set_attr "type" "sseicvt")
1674    (set_attr "mode" "DF")
1675    (set_attr "athlon_decode" "double,direct")
1676    (set_attr "amdfam10_decode" "vector,double")])
1677
1678 (define_insn "sse2_cvtsi2sdq"
1679   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
1680         (vec_merge:V2DF
1681           (vec_duplicate:V2DF
1682             (float:DF (match_operand:DI 2 "nonimmediate_operand" "r,m")))
1683           (match_operand:V2DF 1 "register_operand" "0,0")
1684           (const_int 1)))]
1685   "TARGET_SSE2 && TARGET_64BIT"
1686   "cvtsi2sdq\t{%2, %0|%0, %2}"
1687   [(set_attr "type" "sseicvt")
1688    (set_attr "mode" "DF")
1689    (set_attr "athlon_decode" "double,direct")
1690    (set_attr "amdfam10_decode" "vector,double")])
1691
1692 (define_insn "sse2_cvtsd2si"
1693   [(set (match_operand:SI 0 "register_operand" "=r,r")
1694         (unspec:SI
1695           [(vec_select:DF
1696              (match_operand:V2DF 1 "nonimmediate_operand" "x,m")
1697              (parallel [(const_int 0)]))]
1698           UNSPEC_FIX_NOTRUNC))]
1699   "TARGET_SSE2"
1700   "cvtsd2si\t{%1, %0|%0, %1}"
1701   [(set_attr "type" "sseicvt")
1702    (set_attr "athlon_decode" "double,vector")
1703    (set_attr "prefix_rep" "1")
1704    (set_attr "mode" "SI")])
1705
1706 (define_insn "sse2_cvtsd2si_2"
1707   [(set (match_operand:SI 0 "register_operand" "=r,r")
1708         (unspec:SI [(match_operand:DF 1 "nonimmediate_operand" "x,m")]
1709                    UNSPEC_FIX_NOTRUNC))]
1710   "TARGET_SSE2"
1711   "cvtsd2si\t{%1, %0|%0, %1}"
1712   [(set_attr "type" "sseicvt")
1713    (set_attr "athlon_decode" "double,vector")
1714    (set_attr "amdfam10_decode" "double,double")
1715    (set_attr "prefix_rep" "1")
1716    (set_attr "mode" "SI")])
1717
1718 (define_insn "sse2_cvtsd2siq"
1719   [(set (match_operand:DI 0 "register_operand" "=r,r")
1720         (unspec:DI
1721           [(vec_select:DF
1722              (match_operand:V2DF 1 "nonimmediate_operand" "x,m")
1723              (parallel [(const_int 0)]))]
1724           UNSPEC_FIX_NOTRUNC))]
1725   "TARGET_SSE2 && TARGET_64BIT"
1726   "cvtsd2siq\t{%1, %0|%0, %1}"
1727   [(set_attr "type" "sseicvt")
1728    (set_attr "athlon_decode" "double,vector")
1729    (set_attr "prefix_rep" "1")
1730    (set_attr "mode" "DI")])
1731
1732 (define_insn "sse2_cvtsd2siq_2"
1733   [(set (match_operand:DI 0 "register_operand" "=r,r")
1734         (unspec:DI [(match_operand:DF 1 "nonimmediate_operand" "x,m")]
1735                    UNSPEC_FIX_NOTRUNC))]
1736   "TARGET_SSE2 && TARGET_64BIT"
1737   "cvtsd2siq\t{%1, %0|%0, %1}"
1738   [(set_attr "type" "sseicvt")
1739    (set_attr "athlon_decode" "double,vector")
1740    (set_attr "amdfam10_decode" "double,double")
1741    (set_attr "prefix_rep" "1")
1742    (set_attr "mode" "DI")])
1743
1744 (define_insn "sse2_cvttsd2si"
1745   [(set (match_operand:SI 0 "register_operand" "=r,r")
1746         (fix:SI
1747           (vec_select:DF
1748             (match_operand:V2DF 1 "nonimmediate_operand" "x,m")
1749             (parallel [(const_int 0)]))))]
1750   "TARGET_SSE2"
1751   "cvttsd2si\t{%1, %0|%0, %1}"
1752   [(set_attr "type" "sseicvt")
1753    (set_attr "prefix_rep" "1")
1754    (set_attr "mode" "SI")
1755    (set_attr "athlon_decode" "double,vector")
1756    (set_attr "amdfam10_decode" "double,double")])
1757
1758 (define_insn "sse2_cvttsd2siq"
1759   [(set (match_operand:DI 0 "register_operand" "=r,r")
1760         (fix:DI
1761           (vec_select:DF
1762             (match_operand:V2DF 1 "nonimmediate_operand" "x,m")
1763             (parallel [(const_int 0)]))))]
1764   "TARGET_SSE2 && TARGET_64BIT"
1765   "cvttsd2siq\t{%1, %0|%0, %1}"
1766   [(set_attr "type" "sseicvt")
1767    (set_attr "prefix_rep" "1")
1768    (set_attr "mode" "DI")
1769    (set_attr "athlon_decode" "double,vector")
1770    (set_attr "amdfam10_decode" "double,double")])
1771
1772 (define_insn "sse2_cvtdq2pd"
1773   [(set (match_operand:V2DF 0 "register_operand" "=x")
1774         (float:V2DF
1775           (vec_select:V2SI
1776             (match_operand:V4SI 1 "nonimmediate_operand" "xm")
1777             (parallel [(const_int 0) (const_int 1)]))))]
1778   "TARGET_SSE2"
1779   "cvtdq2pd\t{%1, %0|%0, %1}"
1780   [(set_attr "type" "ssecvt")
1781    (set_attr "mode" "V2DF")])
1782
1783 (define_expand "sse2_cvtpd2dq"
1784   [(set (match_operand:V4SI 0 "register_operand" "")
1785         (vec_concat:V4SI
1786           (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "")]
1787                        UNSPEC_FIX_NOTRUNC)
1788           (match_dup 2)))]
1789   "TARGET_SSE2"
1790   "operands[2] = CONST0_RTX (V2SImode);")
1791
1792 (define_insn "*sse2_cvtpd2dq"
1793   [(set (match_operand:V4SI 0 "register_operand" "=x")
1794         (vec_concat:V4SI
1795           (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
1796                        UNSPEC_FIX_NOTRUNC)
1797           (match_operand:V2SI 2 "const0_operand" "")))]
1798   "TARGET_SSE2"
1799   "cvtpd2dq\t{%1, %0|%0, %1}"
1800   [(set_attr "type" "ssecvt")
1801    (set_attr "prefix_rep" "1")
1802    (set_attr "mode" "TI")
1803    (set_attr "amdfam10_decode" "double")])
1804
1805 (define_expand "sse2_cvttpd2dq"
1806   [(set (match_operand:V4SI 0 "register_operand" "")
1807         (vec_concat:V4SI
1808           (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" ""))
1809           (match_dup 2)))]
1810   "TARGET_SSE2"
1811   "operands[2] = CONST0_RTX (V2SImode);")
1812
1813 (define_insn "*sse2_cvttpd2dq"
1814   [(set (match_operand:V4SI 0 "register_operand" "=x")
1815         (vec_concat:V4SI
1816           (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
1817           (match_operand:V2SI 2 "const0_operand" "")))]
1818   "TARGET_SSE2"
1819   "cvttpd2dq\t{%1, %0|%0, %1}"
1820   [(set_attr "type" "ssecvt")
1821    (set_attr "prefix_rep" "1")
1822    (set_attr "mode" "TI")
1823    (set_attr "amdfam10_decode" "double")])
1824
1825 (define_insn "sse2_cvtsd2ss"
1826   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
1827         (vec_merge:V4SF
1828           (vec_duplicate:V4SF
1829             (float_truncate:V2SF
1830               (match_operand:V2DF 2 "nonimmediate_operand" "x,m")))
1831           (match_operand:V4SF 1 "register_operand" "0,0")
1832           (const_int 1)))]
1833   "TARGET_SSE2"
1834   "cvtsd2ss\t{%2, %0|%0, %2}"
1835   [(set_attr "type" "ssecvt")
1836    (set_attr "athlon_decode" "vector,double")
1837    (set_attr "amdfam10_decode" "vector,double")
1838    (set_attr "mode" "SF")])
1839
1840 (define_insn "sse2_cvtss2sd"
1841   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
1842         (vec_merge:V2DF
1843           (float_extend:V2DF
1844             (vec_select:V2SF
1845               (match_operand:V4SF 2 "nonimmediate_operand" "x,m")
1846               (parallel [(const_int 0) (const_int 1)])))
1847           (match_operand:V2DF 1 "register_operand" "0,0")
1848           (const_int 1)))]
1849   "TARGET_SSE2"
1850   "cvtss2sd\t{%2, %0|%0, %2}"
1851   [(set_attr "type" "ssecvt")
1852    (set_attr "amdfam10_decode" "vector,double")
1853    (set_attr "mode" "DF")])
1854
1855 (define_expand "sse2_cvtpd2ps"
1856   [(set (match_operand:V4SF 0 "register_operand" "")
1857         (vec_concat:V4SF
1858           (float_truncate:V2SF
1859             (match_operand:V2DF 1 "nonimmediate_operand" ""))
1860           (match_dup 2)))]
1861   "TARGET_SSE2"
1862   "operands[2] = CONST0_RTX (V2SFmode);")
1863
1864 (define_insn "*sse2_cvtpd2ps"
1865   [(set (match_operand:V4SF 0 "register_operand" "=x")
1866         (vec_concat:V4SF
1867           (float_truncate:V2SF
1868             (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
1869           (match_operand:V2SF 2 "const0_operand" "")))]
1870   "TARGET_SSE2"
1871   "cvtpd2ps\t{%1, %0|%0, %1}"
1872   [(set_attr "type" "ssecvt")
1873    (set_attr "prefix_data16" "1")
1874    (set_attr "mode" "V4SF")
1875    (set_attr "amdfam10_decode" "double")])
1876
1877 (define_insn "sse2_cvtps2pd"
1878   [(set (match_operand:V2DF 0 "register_operand" "=x")
1879         (float_extend:V2DF
1880           (vec_select:V2SF
1881             (match_operand:V4SF 1 "nonimmediate_operand" "xm")
1882             (parallel [(const_int 0) (const_int 1)]))))]
1883   "TARGET_SSE2"
1884   "cvtps2pd\t{%1, %0|%0, %1}"
1885   [(set_attr "type" "ssecvt")
1886    (set_attr "mode" "V2DF")
1887    (set_attr "amdfam10_decode" "direct")])
1888
1889 (define_expand "vec_unpacks_hi_v4sf"
1890   [(set (match_dup 2)
1891    (vec_select:V4SF
1892      (vec_concat:V8SF
1893        (match_dup 2)
1894        (match_operand:V4SF 1 "nonimmediate_operand" ""))
1895      (parallel [(const_int 6)
1896                 (const_int 7)
1897                 (const_int 2)
1898                 (const_int 3)])))
1899   (set (match_operand:V2DF 0 "register_operand" "")
1900    (float_extend:V2DF
1901      (vec_select:V2SF
1902        (match_dup 2)
1903        (parallel [(const_int 0) (const_int 1)]))))]
1904  "TARGET_SSE2"
1905 {
1906  operands[2] = gen_reg_rtx (V4SFmode);
1907 })
1908
1909 (define_expand "vec_unpacks_lo_v4sf"
1910   [(set (match_operand:V2DF 0 "register_operand" "")
1911         (float_extend:V2DF
1912           (vec_select:V2SF
1913             (match_operand:V4SF 1 "nonimmediate_operand" "")
1914             (parallel [(const_int 0) (const_int 1)]))))]
1915   "TARGET_SSE2")
1916
1917 (define_expand "vec_unpacks_float_hi_v8hi"
1918   [(match_operand:V4SF 0 "register_operand" "")
1919    (match_operand:V8HI 1 "register_operand" "")]
1920   "TARGET_SSE2"
1921 {
1922   rtx tmp = gen_reg_rtx (V4SImode);
1923
1924   emit_insn (gen_vec_unpacks_hi_v8hi (tmp, operands[1]));
1925   emit_insn (gen_sse2_cvtdq2ps (operands[0], tmp));
1926   DONE;
1927 })
1928
1929 (define_expand "vec_unpacks_float_lo_v8hi"
1930   [(match_operand:V4SF 0 "register_operand" "")
1931    (match_operand:V8HI 1 "register_operand" "")]
1932   "TARGET_SSE2"
1933 {
1934   rtx tmp = gen_reg_rtx (V4SImode);
1935
1936   emit_insn (gen_vec_unpacks_lo_v8hi (tmp, operands[1]));
1937   emit_insn (gen_sse2_cvtdq2ps (operands[0], tmp));
1938   DONE;
1939 })
1940
1941 (define_expand "vec_unpacku_float_hi_v8hi"
1942   [(match_operand:V4SF 0 "register_operand" "")
1943    (match_operand:V8HI 1 "register_operand" "")]
1944   "TARGET_SSE2"
1945 {
1946   rtx tmp = gen_reg_rtx (V4SImode);
1947
1948   emit_insn (gen_vec_unpacku_hi_v8hi (tmp, operands[1]));
1949   emit_insn (gen_sse2_cvtdq2ps (operands[0], tmp));
1950   DONE;
1951 })
1952
1953 (define_expand "vec_unpacku_float_lo_v8hi"
1954   [(match_operand:V4SF 0 "register_operand" "")
1955    (match_operand:V8HI 1 "register_operand" "")]
1956   "TARGET_SSE2"
1957 {
1958   rtx tmp = gen_reg_rtx (V4SImode);
1959
1960   emit_insn (gen_vec_unpacku_lo_v8hi (tmp, operands[1]));
1961   emit_insn (gen_sse2_cvtdq2ps (operands[0], tmp));
1962   DONE;
1963 })
1964
1965 (define_expand "vec_unpacks_float_hi_v4si"
1966   [(set (match_dup 2)
1967         (vec_select:V4SI
1968           (match_operand:V4SI 1 "nonimmediate_operand" "")
1969           (parallel [(const_int 2)
1970                      (const_int 3)
1971                      (const_int 2)
1972                      (const_int 3)])))
1973    (set (match_operand:V2DF 0 "register_operand" "")
1974         (float:V2DF
1975           (vec_select:V2SI
1976           (match_dup 2)
1977             (parallel [(const_int 0) (const_int 1)]))))]
1978  "TARGET_SSE2"
1979 {
1980  operands[2] = gen_reg_rtx (V4SImode);
1981 })
1982
1983 (define_expand "vec_unpacks_float_lo_v4si"
1984   [(set (match_operand:V2DF 0 "register_operand" "")
1985         (float:V2DF
1986           (vec_select:V2SI
1987             (match_operand:V4SI 1 "nonimmediate_operand" "")
1988             (parallel [(const_int 0) (const_int 1)]))))]
1989   "TARGET_SSE2")
1990
1991 (define_expand "vec_pack_trunc_v2df"
1992   [(match_operand:V4SF 0 "register_operand" "")
1993    (match_operand:V2DF 1 "nonimmediate_operand" "")
1994    (match_operand:V2DF 2 "nonimmediate_operand" "")]
1995   "TARGET_SSE2"
1996 {
1997   rtx r1, r2;
1998
1999   r1 = gen_reg_rtx (V4SFmode);
2000   r2 = gen_reg_rtx (V4SFmode);
2001
2002   emit_insn (gen_sse2_cvtpd2ps (r1, operands[1]));
2003   emit_insn (gen_sse2_cvtpd2ps (r2, operands[2]));
2004   emit_insn (gen_sse_movlhps (operands[0], r1, r2));
2005   DONE;
2006 })
2007
2008 (define_expand "vec_pack_sfix_trunc_v2df"
2009   [(match_operand:V4SI 0 "register_operand" "")
2010    (match_operand:V2DF 1 "nonimmediate_operand" "")
2011    (match_operand:V2DF 2 "nonimmediate_operand" "")]
2012   "TARGET_SSE2"
2013 {
2014   rtx r1, r2;
2015
2016   r1 = gen_reg_rtx (V4SImode);
2017   r2 = gen_reg_rtx (V4SImode);
2018
2019   emit_insn (gen_sse2_cvttpd2dq (r1, operands[1]));
2020   emit_insn (gen_sse2_cvttpd2dq (r2, operands[2]));
2021   emit_insn (gen_sse2_punpcklqdq (gen_lowpart (V2DImode, operands[0]),
2022                                   gen_lowpart (V2DImode, r1),
2023                                   gen_lowpart (V2DImode, r2)));
2024   DONE;
2025 })
2026
2027 (define_expand "vec_pack_sfix_v2df"
2028   [(match_operand:V4SI 0 "register_operand" "")
2029    (match_operand:V2DF 1 "nonimmediate_operand" "")
2030    (match_operand:V2DF 2 "nonimmediate_operand" "")]
2031   "TARGET_SSE2"
2032 {
2033   rtx r1, r2;
2034
2035   r1 = gen_reg_rtx (V4SImode);
2036   r2 = gen_reg_rtx (V4SImode);
2037
2038   emit_insn (gen_sse2_cvtpd2dq (r1, operands[1]));
2039   emit_insn (gen_sse2_cvtpd2dq (r2, operands[2]));
2040   emit_insn (gen_sse2_punpcklqdq (gen_lowpart (V2DImode, operands[0]),
2041                                   gen_lowpart (V2DImode, r1),
2042                                   gen_lowpart (V2DImode, r2)));
2043   DONE;
2044 })
2045
2046 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2047 ;;
2048 ;; Parallel single-precision floating point element swizzling
2049 ;;
2050 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2051
2052 (define_insn "sse_movhlps"
2053   [(set (match_operand:V4SF 0 "nonimmediate_operand"     "=x,x,m")
2054         (vec_select:V4SF
2055           (vec_concat:V8SF
2056             (match_operand:V4SF 1 "nonimmediate_operand" " 0,0,0")
2057             (match_operand:V4SF 2 "nonimmediate_operand" " x,o,x"))
2058           (parallel [(const_int 6)
2059                      (const_int 7)
2060                      (const_int 2)
2061                      (const_int 3)])))]
2062   "TARGET_SSE && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
2063   "@
2064    movhlps\t{%2, %0|%0, %2}
2065    movlps\t{%H2, %0|%0, %H2}
2066    movhps\t{%2, %0|%0, %2}"
2067   [(set_attr "type" "ssemov")
2068    (set_attr "mode" "V4SF,V2SF,V2SF")])
2069
2070 (define_insn "sse_movlhps"
2071   [(set (match_operand:V4SF 0 "nonimmediate_operand"     "=x,x,o")
2072         (vec_select:V4SF
2073           (vec_concat:V8SF
2074             (match_operand:V4SF 1 "nonimmediate_operand" " 0,0,0")
2075             (match_operand:V4SF 2 "nonimmediate_operand" " x,m,x"))
2076           (parallel [(const_int 0)
2077                      (const_int 1)
2078                      (const_int 4)
2079                      (const_int 5)])))]
2080   "TARGET_SSE && ix86_binary_operator_ok (UNKNOWN, V4SFmode, operands)"
2081   "@
2082    movlhps\t{%2, %0|%0, %2}
2083    movhps\t{%2, %0|%0, %2}
2084    movlps\t{%2, %H0|%H0, %2}"
2085   [(set_attr "type" "ssemov")
2086    (set_attr "mode" "V4SF,V2SF,V2SF")])
2087
2088 (define_insn "sse_unpckhps"
2089   [(set (match_operand:V4SF 0 "register_operand" "=x")
2090         (vec_select:V4SF
2091           (vec_concat:V8SF
2092             (match_operand:V4SF 1 "register_operand" "0")
2093             (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
2094           (parallel [(const_int 2) (const_int 6)
2095                      (const_int 3) (const_int 7)])))]
2096   "TARGET_SSE"
2097   "unpckhps\t{%2, %0|%0, %2}"
2098   [(set_attr "type" "sselog")
2099    (set_attr "mode" "V4SF")])
2100
2101 (define_insn "sse_unpcklps"
2102   [(set (match_operand:V4SF 0 "register_operand" "=x")
2103         (vec_select:V4SF
2104           (vec_concat:V8SF
2105             (match_operand:V4SF 1 "register_operand" "0")
2106             (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
2107           (parallel [(const_int 0) (const_int 4)
2108                      (const_int 1) (const_int 5)])))]
2109   "TARGET_SSE"
2110   "unpcklps\t{%2, %0|%0, %2}"
2111   [(set_attr "type" "sselog")
2112    (set_attr "mode" "V4SF")])
2113
2114 ;; These are modeled with the same vec_concat as the others so that we
2115 ;; capture users of shufps that can use the new instructions
2116 (define_insn "sse3_movshdup"
2117   [(set (match_operand:V4SF 0 "register_operand" "=x")
2118         (vec_select:V4SF
2119           (vec_concat:V8SF
2120             (match_operand:V4SF 1 "nonimmediate_operand" "xm")
2121             (match_dup 1))
2122           (parallel [(const_int 1)
2123                      (const_int 1)
2124                      (const_int 7)
2125                      (const_int 7)])))]
2126   "TARGET_SSE3"
2127   "movshdup\t{%1, %0|%0, %1}"
2128   [(set_attr "type" "sse")
2129    (set_attr "prefix_rep" "1")
2130    (set_attr "mode" "V4SF")])
2131
2132 (define_insn "sse3_movsldup"
2133   [(set (match_operand:V4SF 0 "register_operand" "=x")
2134         (vec_select:V4SF
2135           (vec_concat:V8SF
2136             (match_operand:V4SF 1 "nonimmediate_operand" "xm")
2137             (match_dup 1))
2138           (parallel [(const_int 0)
2139                      (const_int 0)
2140                      (const_int 6)
2141                      (const_int 6)])))]
2142   "TARGET_SSE3"
2143   "movsldup\t{%1, %0|%0, %1}"
2144   [(set_attr "type" "sse")
2145    (set_attr "prefix_rep" "1")
2146    (set_attr "mode" "V4SF")])
2147
2148 (define_expand "sse_shufps"
2149   [(match_operand:V4SF 0 "register_operand" "")
2150    (match_operand:V4SF 1 "register_operand" "")
2151    (match_operand:V4SF 2 "nonimmediate_operand" "")
2152    (match_operand:SI 3 "const_int_operand" "")]
2153   "TARGET_SSE"
2154 {
2155   int mask = INTVAL (operands[3]);
2156   emit_insn (gen_sse_shufps_1 (operands[0], operands[1], operands[2],
2157                                GEN_INT ((mask >> 0) & 3),
2158                                GEN_INT ((mask >> 2) & 3),
2159                                GEN_INT (((mask >> 4) & 3) + 4),
2160                                GEN_INT (((mask >> 6) & 3) + 4)));
2161   DONE;
2162 })
2163
2164 (define_insn "sse_shufps_1"
2165   [(set (match_operand:V4SF 0 "register_operand" "=x")
2166         (vec_select:V4SF
2167           (vec_concat:V8SF
2168             (match_operand:V4SF 1 "register_operand" "0")
2169             (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
2170           (parallel [(match_operand 3 "const_0_to_3_operand" "")
2171                      (match_operand 4 "const_0_to_3_operand" "")
2172                      (match_operand 5 "const_4_to_7_operand" "")
2173                      (match_operand 6 "const_4_to_7_operand" "")])))]
2174   "TARGET_SSE"
2175 {
2176   int mask = 0;
2177   mask |= INTVAL (operands[3]) << 0;
2178   mask |= INTVAL (operands[4]) << 2;
2179   mask |= (INTVAL (operands[5]) - 4) << 4;
2180   mask |= (INTVAL (operands[6]) - 4) << 6;
2181   operands[3] = GEN_INT (mask);
2182
2183   return "shufps\t{%3, %2, %0|%0, %2, %3}";
2184 }
2185   [(set_attr "type" "sselog")
2186    (set_attr "mode" "V4SF")])
2187
2188 (define_insn "sse_storehps"
2189   [(set (match_operand:V2SF 0 "nonimmediate_operand" "=m,x,x")
2190         (vec_select:V2SF
2191           (match_operand:V4SF 1 "nonimmediate_operand" "x,x,o")
2192           (parallel [(const_int 2) (const_int 3)])))]
2193   "TARGET_SSE"
2194   "@
2195    movhps\t{%1, %0|%0, %1}
2196    movhlps\t{%1, %0|%0, %1}
2197    movlps\t{%H1, %0|%0, %H1}"
2198   [(set_attr "type" "ssemov")
2199    (set_attr "mode" "V2SF,V4SF,V2SF")])
2200
2201 (define_insn "sse_loadhps"
2202   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,o")
2203         (vec_concat:V4SF
2204           (vec_select:V2SF
2205             (match_operand:V4SF 1 "nonimmediate_operand" "0,0,0")
2206             (parallel [(const_int 0) (const_int 1)]))
2207           (match_operand:V2SF 2 "nonimmediate_operand" "m,x,x")))]
2208   "TARGET_SSE"
2209   "@
2210    movhps\t{%2, %0|%0, %2}
2211    movlhps\t{%2, %0|%0, %2}
2212    movlps\t{%2, %H0|%H0, %2}"
2213   [(set_attr "type" "ssemov")
2214    (set_attr "mode" "V2SF,V4SF,V2SF")])
2215
2216 (define_insn "sse_storelps"
2217   [(set (match_operand:V2SF 0 "nonimmediate_operand" "=m,x,x")
2218         (vec_select:V2SF
2219           (match_operand:V4SF 1 "nonimmediate_operand" "x,x,m")
2220           (parallel [(const_int 0) (const_int 1)])))]
2221   "TARGET_SSE"
2222   "@
2223    movlps\t{%1, %0|%0, %1}
2224    movaps\t{%1, %0|%0, %1}
2225    movlps\t{%1, %0|%0, %1}"
2226   [(set_attr "type" "ssemov")
2227    (set_attr "mode" "V2SF,V4SF,V2SF")])
2228
2229 (define_insn "sse_loadlps"
2230   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
2231         (vec_concat:V4SF
2232           (match_operand:V2SF 2 "nonimmediate_operand" "0,m,x")
2233           (vec_select:V2SF
2234             (match_operand:V4SF 1 "nonimmediate_operand" "x,0,0")
2235             (parallel [(const_int 2) (const_int 3)]))))]
2236   "TARGET_SSE"
2237   "@
2238    shufps\t{$0xe4, %1, %0|%0, %1, 0xe4}
2239    movlps\t{%2, %0|%0, %2}
2240    movlps\t{%2, %0|%0, %2}"
2241   [(set_attr "type" "sselog,ssemov,ssemov")
2242    (set_attr "mode" "V4SF,V2SF,V2SF")])
2243
2244 (define_insn "sse_movss"
2245   [(set (match_operand:V4SF 0 "register_operand" "=x")
2246         (vec_merge:V4SF
2247           (match_operand:V4SF 2 "register_operand" "x")
2248           (match_operand:V4SF 1 "register_operand" "0")
2249           (const_int 1)))]
2250   "TARGET_SSE"
2251   "movss\t{%2, %0|%0, %2}"
2252   [(set_attr "type" "ssemov")
2253    (set_attr "mode" "SF")])
2254
2255 (define_insn "*vec_dupv4sf"
2256   [(set (match_operand:V4SF 0 "register_operand" "=x")
2257         (vec_duplicate:V4SF
2258           (match_operand:SF 1 "register_operand" "0")))]
2259   "TARGET_SSE"
2260   "shufps\t{$0, %0, %0|%0, %0, 0}"
2261   [(set_attr "type" "sselog1")
2262    (set_attr "mode" "V4SF")])
2263
2264 ;; ??? In theory we can match memory for the MMX alternative, but allowing
2265 ;; nonimmediate_operand for operand 2 and *not* allowing memory for the SSE
2266 ;; alternatives pretty much forces the MMX alternative to be chosen.
2267 (define_insn "*sse_concatv2sf"
2268   [(set (match_operand:V2SF 0 "register_operand"     "=x,x,*y,*y")
2269         (vec_concat:V2SF
2270           (match_operand:SF 1 "nonimmediate_operand" " 0,m, 0, m")
2271           (match_operand:SF 2 "reg_or_0_operand"     " x,C,*y, C")))]
2272   "TARGET_SSE"
2273   "@
2274    unpcklps\t{%2, %0|%0, %2}
2275    movss\t{%1, %0|%0, %1}
2276    punpckldq\t{%2, %0|%0, %2}
2277    movd\t{%1, %0|%0, %1}"
2278   [(set_attr "type" "sselog,ssemov,mmxcvt,mmxmov")
2279    (set_attr "mode" "V4SF,SF,DI,DI")])
2280
2281 (define_insn "*sse_concatv4sf"
2282   [(set (match_operand:V4SF 0 "register_operand"   "=x,x")
2283         (vec_concat:V4SF
2284           (match_operand:V2SF 1 "register_operand" " 0,0")
2285           (match_operand:V2SF 2 "nonimmediate_operand" " x,m")))]
2286   "TARGET_SSE"
2287   "@
2288    movlhps\t{%2, %0|%0, %2}
2289    movhps\t{%2, %0|%0, %2}"
2290   [(set_attr "type" "ssemov")
2291    (set_attr "mode" "V4SF,V2SF")])
2292
2293 (define_expand "vec_initv4sf"
2294   [(match_operand:V4SF 0 "register_operand" "")
2295    (match_operand 1 "" "")]
2296   "TARGET_SSE"
2297 {
2298   ix86_expand_vector_init (false, operands[0], operands[1]);
2299   DONE;
2300 })
2301
2302 (define_insn "vec_setv4sf_0"
2303   [(set (match_operand:V4SF 0 "nonimmediate_operand"  "=x,x,Y2,m")
2304         (vec_merge:V4SF
2305           (vec_duplicate:V4SF
2306             (match_operand:SF 2 "general_operand"     " x,m,*r,x*rfF"))
2307           (match_operand:V4SF 1 "vector_move_operand" " 0,C,C ,0")
2308           (const_int 1)))]
2309   "TARGET_SSE"
2310   "@
2311    movss\t{%2, %0|%0, %2}
2312    movss\t{%2, %0|%0, %2}
2313    movd\t{%2, %0|%0, %2}
2314    #"
2315   [(set_attr "type" "ssemov")
2316    (set_attr "mode" "SF")])
2317
2318 ;; A subset is vec_setv4sf.
2319 (define_insn "*vec_setv4sf_sse4_1"
2320   [(set (match_operand:V4SF 0 "register_operand" "=x")
2321         (vec_merge:V4SF
2322           (vec_duplicate:V4SF
2323             (match_operand:SF 2 "nonimmediate_operand" "xm"))
2324           (match_operand:V4SF 1 "register_operand" "0")
2325           (match_operand:SI 3 "const_pow2_1_to_8_operand" "n")))]
2326   "TARGET_SSE4_1"
2327 {
2328   operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])) << 4);
2329   return "insertps\t{%3, %2, %0|%0, %2, %3}";
2330 }
2331   [(set_attr "type" "sselog")
2332    (set_attr "prefix_extra" "1")
2333    (set_attr "mode" "V4SF")])
2334
2335 (define_insn "sse4_1_insertps"
2336   [(set (match_operand:V4SF 0 "register_operand" "=x")
2337         (unspec:V4SF [(match_operand:V4SF 2 "register_operand" "x")
2338                       (match_operand:V4SF 1 "register_operand" "0")
2339                       (match_operand:SI 3 "const_0_to_255_operand" "n")]
2340                      UNSPEC_INSERTPS))]
2341   "TARGET_SSE4_1"
2342   "insertps\t{%3, %2, %0|%0, %2, %3}";
2343   [(set_attr "type" "sselog")
2344    (set_attr "prefix_extra" "1")
2345    (set_attr "mode" "V4SF")])
2346
2347 (define_split
2348   [(set (match_operand:V4SF 0 "memory_operand" "")
2349         (vec_merge:V4SF
2350           (vec_duplicate:V4SF
2351             (match_operand:SF 1 "nonmemory_operand" ""))
2352           (match_dup 0)
2353           (const_int 1)))]
2354   "TARGET_SSE && reload_completed"
2355   [(const_int 0)]
2356 {
2357   emit_move_insn (adjust_address (operands[0], SFmode, 0), operands[1]);
2358   DONE;
2359 })
2360
2361 (define_expand "vec_setv4sf"
2362   [(match_operand:V4SF 0 "register_operand" "")
2363    (match_operand:SF 1 "register_operand" "")
2364    (match_operand 2 "const_int_operand" "")]
2365   "TARGET_SSE"
2366 {
2367   ix86_expand_vector_set (false, operands[0], operands[1],
2368                           INTVAL (operands[2]));
2369   DONE;
2370 })
2371
2372 (define_insn_and_split "*vec_extractv4sf_0"
2373   [(set (match_operand:SF 0 "nonimmediate_operand" "=x,m,fr")
2374         (vec_select:SF
2375           (match_operand:V4SF 1 "nonimmediate_operand" "xm,x,m")
2376           (parallel [(const_int 0)])))]
2377   "TARGET_SSE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2378   "#"
2379   "&& reload_completed"
2380   [(const_int 0)]
2381 {
2382   rtx op1 = operands[1];
2383   if (REG_P (op1))
2384     op1 = gen_rtx_REG (SFmode, REGNO (op1));
2385   else
2386     op1 = gen_lowpart (SFmode, op1);
2387   emit_move_insn (operands[0], op1);
2388   DONE;
2389 })
2390
2391 (define_insn "*sse4_1_extractps"
2392   [(set (match_operand:SF 0 "nonimmediate_operand" "=rm")
2393         (vec_select:SF
2394           (match_operand:V4SF 1 "register_operand" "x")
2395           (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n")])))]
2396   "TARGET_SSE4_1"
2397   "extractps\t{%2, %1, %0|%0, %1, %2}"
2398   [(set_attr "type" "sselog")
2399    (set_attr "prefix_extra" "1")
2400    (set_attr "mode" "V4SF")])
2401
2402 (define_insn_and_split "*vec_extract_v4sf_mem"
2403   [(set (match_operand:SF 0 "register_operand" "=x*rf")
2404        (vec_select:SF
2405          (match_operand:V4SF 1 "memory_operand" "o")
2406          (parallel [(match_operand 2 "const_0_to_3_operand" "n")])))]
2407   ""
2408   "#"
2409   "reload_completed"
2410   [(const_int 0)]
2411 {
2412   int i = INTVAL (operands[2]);
2413
2414   emit_move_insn (operands[0], adjust_address (operands[1], SFmode, i*4));
2415   DONE;
2416 })
2417
2418 (define_expand "vec_extractv4sf"
2419   [(match_operand:SF 0 "register_operand" "")
2420    (match_operand:V4SF 1 "register_operand" "")
2421    (match_operand 2 "const_int_operand" "")]
2422   "TARGET_SSE"
2423 {
2424   ix86_expand_vector_extract (false, operands[0], operands[1],
2425                               INTVAL (operands[2]));
2426   DONE;
2427 })
2428
2429 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2430 ;;
2431 ;; Parallel double-precision floating point element swizzling
2432 ;;
2433 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2434
2435 (define_insn "sse2_unpckhpd"
2436   [(set (match_operand:V2DF 0 "nonimmediate_operand"     "=x,x,m")
2437         (vec_select:V2DF
2438           (vec_concat:V4DF
2439             (match_operand:V2DF 1 "nonimmediate_operand" " 0,o,x")
2440             (match_operand:V2DF 2 "nonimmediate_operand" " x,0,0"))
2441           (parallel [(const_int 1)
2442                      (const_int 3)])))]
2443   "TARGET_SSE2 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
2444   "@
2445    unpckhpd\t{%2, %0|%0, %2}
2446    movlpd\t{%H1, %0|%0, %H1}
2447    movhpd\t{%1, %0|%0, %1}"
2448   [(set_attr "type" "sselog,ssemov,ssemov")
2449    (set_attr "mode" "V2DF,V1DF,V1DF")])
2450
2451 (define_insn "*sse3_movddup"
2452   [(set (match_operand:V2DF 0 "nonimmediate_operand"     "=x,o")
2453         (vec_select:V2DF
2454           (vec_concat:V4DF
2455             (match_operand:V2DF 1 "nonimmediate_operand" "xm,x")
2456             (match_dup 1))
2457           (parallel [(const_int 0)
2458                      (const_int 2)])))]
2459   "TARGET_SSE3 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2460   "@
2461    movddup\t{%1, %0|%0, %1}
2462    #"
2463   [(set_attr "type" "sselog1,ssemov")
2464    (set_attr "mode" "V2DF")])
2465
2466 (define_split
2467   [(set (match_operand:V2DF 0 "memory_operand" "")
2468         (vec_select:V2DF
2469           (vec_concat:V4DF
2470             (match_operand:V2DF 1 "register_operand" "")
2471             (match_dup 1))
2472           (parallel [(const_int 0)
2473                      (const_int 2)])))]
2474   "TARGET_SSE3 && reload_completed"
2475   [(const_int 0)]
2476 {
2477   rtx low = gen_rtx_REG (DFmode, REGNO (operands[1]));
2478   emit_move_insn (adjust_address (operands[0], DFmode, 0), low);
2479   emit_move_insn (adjust_address (operands[0], DFmode, 8), low);
2480   DONE;
2481 })
2482
2483 (define_insn "sse2_unpcklpd"
2484   [(set (match_operand:V2DF 0 "nonimmediate_operand"     "=x,x,o")
2485         (vec_select:V2DF
2486           (vec_concat:V4DF
2487             (match_operand:V2DF 1 "nonimmediate_operand" " 0,0,0")
2488             (match_operand:V2DF 2 "nonimmediate_operand" " x,m,x"))
2489           (parallel [(const_int 0)
2490                      (const_int 2)])))]
2491   "TARGET_SSE2 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
2492   "@
2493    unpcklpd\t{%2, %0|%0, %2}
2494    movhpd\t{%2, %0|%0, %2}
2495    movlpd\t{%2, %H0|%H0, %2}"
2496   [(set_attr "type" "sselog,ssemov,ssemov")
2497    (set_attr "mode" "V2DF,V1DF,V1DF")])
2498
2499 (define_expand "sse2_shufpd"
2500   [(match_operand:V2DF 0 "register_operand" "")
2501    (match_operand:V2DF 1 "register_operand" "")
2502    (match_operand:V2DF 2 "nonimmediate_operand" "")
2503    (match_operand:SI 3 "const_int_operand" "")]
2504   "TARGET_SSE2"
2505 {
2506   int mask = INTVAL (operands[3]);
2507   emit_insn (gen_sse2_shufpd_1 (operands[0], operands[1], operands[2],
2508                                 GEN_INT (mask & 1),
2509                                 GEN_INT (mask & 2 ? 3 : 2)));
2510   DONE;
2511 })
2512
2513 (define_insn "sse2_shufpd_1"
2514   [(set (match_operand:V2DF 0 "register_operand" "=x")
2515         (vec_select:V2DF
2516           (vec_concat:V4DF
2517             (match_operand:V2DF 1 "register_operand" "0")
2518             (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
2519           (parallel [(match_operand 3 "const_0_to_1_operand" "")
2520                      (match_operand 4 "const_2_to_3_operand" "")])))]
2521   "TARGET_SSE2"
2522 {
2523   int mask;
2524   mask = INTVAL (operands[3]);
2525   mask |= (INTVAL (operands[4]) - 2) << 1;
2526   operands[3] = GEN_INT (mask);
2527
2528   return "shufpd\t{%3, %2, %0|%0, %2, %3}";
2529 }
2530   [(set_attr "type" "sselog")
2531    (set_attr "mode" "V2DF")])
2532
2533 (define_insn "sse2_storehpd"
2534   [(set (match_operand:DF 0 "nonimmediate_operand"     "=m,x,x*fr")
2535         (vec_select:DF
2536           (match_operand:V2DF 1 "nonimmediate_operand" " x,0,o")
2537           (parallel [(const_int 1)])))]
2538   "TARGET_SSE2 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2539   "@
2540    movhpd\t{%1, %0|%0, %1}
2541    unpckhpd\t%0, %0
2542    #"
2543   [(set_attr "type" "ssemov,sselog1,ssemov")
2544    (set_attr "mode" "V1DF,V2DF,DF")])
2545
2546 (define_split
2547   [(set (match_operand:DF 0 "register_operand" "")
2548         (vec_select:DF
2549           (match_operand:V2DF 1 "memory_operand" "")
2550           (parallel [(const_int 1)])))]
2551   "TARGET_SSE2 && reload_completed"
2552   [(set (match_dup 0) (match_dup 1))]
2553 {
2554   operands[1] = adjust_address (operands[1], DFmode, 8);
2555 })
2556
2557 (define_insn "sse2_storelpd"
2558   [(set (match_operand:DF 0 "nonimmediate_operand"     "=m,x,x*fr")
2559         (vec_select:DF
2560           (match_operand:V2DF 1 "nonimmediate_operand" " x,x,m")
2561           (parallel [(const_int 0)])))]
2562   "TARGET_SSE2 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2563   "@
2564    movlpd\t{%1, %0|%0, %1}
2565    #
2566    #"
2567   [(set_attr "type" "ssemov")
2568    (set_attr "mode" "V1DF,DF,DF")])
2569
2570 (define_split
2571   [(set (match_operand:DF 0 "register_operand" "")
2572         (vec_select:DF
2573           (match_operand:V2DF 1 "nonimmediate_operand" "")
2574           (parallel [(const_int 0)])))]
2575   "TARGET_SSE2 && reload_completed"
2576   [(const_int 0)]
2577 {
2578   rtx op1 = operands[1];
2579   if (REG_P (op1))
2580     op1 = gen_rtx_REG (DFmode, REGNO (op1));
2581   else
2582     op1 = gen_lowpart (DFmode, op1);
2583   emit_move_insn (operands[0], op1);
2584   DONE;
2585 })
2586
2587 (define_insn "sse2_loadhpd"
2588   [(set (match_operand:V2DF 0 "nonimmediate_operand"     "=x,x,x,o")
2589         (vec_concat:V2DF
2590           (vec_select:DF
2591             (match_operand:V2DF 1 "nonimmediate_operand" " 0,0,x,0")
2592             (parallel [(const_int 0)]))
2593           (match_operand:DF 2 "nonimmediate_operand"     " m,x,0,x*fr")))]
2594   "TARGET_SSE2 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
2595   "@
2596    movhpd\t{%2, %0|%0, %2}
2597    unpcklpd\t{%2, %0|%0, %2}
2598    shufpd\t{$1, %1, %0|%0, %1, 1}
2599    #"
2600   [(set_attr "type" "ssemov,sselog,sselog,other")
2601    (set_attr "mode" "V1DF,V2DF,V2DF,DF")])
2602
2603 (define_split
2604   [(set (match_operand:V2DF 0 "memory_operand" "")
2605         (vec_concat:V2DF
2606           (vec_select:DF (match_dup 0) (parallel [(const_int 0)]))
2607           (match_operand:DF 1 "register_operand" "")))]
2608   "TARGET_SSE2 && reload_completed"
2609   [(set (match_dup 0) (match_dup 1))]
2610 {
2611   operands[0] = adjust_address (operands[0], DFmode, 8);
2612 })
2613
2614 (define_insn "sse2_loadlpd"
2615   [(set (match_operand:V2DF 0 "nonimmediate_operand"    "=x,x,x,x,x,m")
2616         (vec_concat:V2DF
2617           (match_operand:DF 2 "nonimmediate_operand"    " m,m,x,0,0,x*fr")
2618           (vec_select:DF
2619             (match_operand:V2DF 1 "vector_move_operand" " C,0,0,x,o,0")
2620             (parallel [(const_int 1)]))))]
2621   "TARGET_SSE2 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
2622   "@
2623    movsd\t{%2, %0|%0, %2}
2624    movlpd\t{%2, %0|%0, %2}
2625    movsd\t{%2, %0|%0, %2}
2626    shufpd\t{$2, %2, %0|%0, %2, 2}
2627    movhpd\t{%H1, %0|%0, %H1}
2628    #"
2629   [(set_attr "type" "ssemov,ssemov,ssemov,sselog,ssemov,other")
2630    (set_attr "mode" "DF,V1DF,V1DF,V2DF,V1DF,DF")])
2631
2632 (define_split
2633   [(set (match_operand:V2DF 0 "memory_operand" "")
2634         (vec_concat:V2DF
2635           (match_operand:DF 1 "register_operand" "")
2636           (vec_select:DF (match_dup 0) (parallel [(const_int 1)]))))]
2637   "TARGET_SSE2 && reload_completed"
2638   [(set (match_dup 0) (match_dup 1))]
2639 {
2640   operands[0] = adjust_address (operands[0], DFmode, 8);
2641 })
2642
2643 ;; Not sure these two are ever used, but it doesn't hurt to have
2644 ;; them. -aoliva
2645 (define_insn "*vec_extractv2df_1_sse"
2646   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,x,x")
2647         (vec_select:DF
2648           (match_operand:V2DF 1 "nonimmediate_operand" "x,x,o")
2649           (parallel [(const_int 1)])))]
2650   "!TARGET_SSE2 && TARGET_SSE
2651    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2652   "@
2653    movhps\t{%1, %0|%0, %1}
2654    movhlps\t{%1, %0|%0, %1}
2655    movlps\t{%H1, %0|%0, %H1}"
2656   [(set_attr "type" "ssemov")
2657    (set_attr "mode" "V2SF,V4SF,V2SF")])
2658
2659 (define_insn "*vec_extractv2df_0_sse"
2660   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,x,x")
2661         (vec_select:DF
2662           (match_operand:V2DF 1 "nonimmediate_operand" "x,x,m")
2663           (parallel [(const_int 0)])))]
2664   "!TARGET_SSE2 && TARGET_SSE
2665    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2666   "@
2667    movlps\t{%1, %0|%0, %1}
2668    movaps\t{%1, %0|%0, %1}
2669    movlps\t{%1, %0|%0, %1}"
2670   [(set_attr "type" "ssemov")
2671    (set_attr "mode" "V2SF,V4SF,V2SF")])
2672
2673 (define_insn "sse2_movsd"
2674   [(set (match_operand:V2DF 0 "nonimmediate_operand"   "=x,x,m,x,x,o")
2675         (vec_merge:V2DF
2676           (match_operand:V2DF 2 "nonimmediate_operand" " x,m,x,0,0,0")
2677           (match_operand:V2DF 1 "nonimmediate_operand" " 0,0,0,x,o,x")
2678           (const_int 1)))]
2679   "TARGET_SSE2"
2680   "@
2681    movsd\t{%2, %0|%0, %2}
2682    movlpd\t{%2, %0|%0, %2}
2683    movlpd\t{%2, %0|%0, %2}
2684    shufpd\t{$2, %2, %0|%0, %2, 2}
2685    movhps\t{%H1, %0|%0, %H1}
2686    movhps\t{%1, %H0|%H0, %1}"
2687   [(set_attr "type" "ssemov,ssemov,ssemov,sselog,ssemov,ssemov")
2688    (set_attr "mode" "DF,V1DF,V1DF,V2DF,V1DF,V1DF")])
2689
2690 (define_insn "*vec_dupv2df_sse3"
2691   [(set (match_operand:V2DF 0 "register_operand" "=x")
2692         (vec_duplicate:V2DF
2693           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
2694   "TARGET_SSE3"
2695   "movddup\t{%1, %0|%0, %1}"
2696   [(set_attr "type" "sselog1")
2697    (set_attr "mode" "DF")])
2698
2699 (define_insn "vec_dupv2df"
2700   [(set (match_operand:V2DF 0 "register_operand" "=x")
2701         (vec_duplicate:V2DF
2702           (match_operand:DF 1 "register_operand" "0")))]
2703   "TARGET_SSE2"
2704   "unpcklpd\t%0, %0"
2705   [(set_attr "type" "sselog1")
2706    (set_attr "mode" "V2DF")])
2707
2708 (define_insn "*vec_concatv2df_sse3"
2709   [(set (match_operand:V2DF 0 "register_operand" "=x")
2710         (vec_concat:V2DF
2711           (match_operand:DF 1 "nonimmediate_operand" "xm")
2712           (match_dup 1)))]
2713   "TARGET_SSE3"
2714   "movddup\t{%1, %0|%0, %1}"
2715   [(set_attr "type" "sselog1")
2716    (set_attr "mode" "DF")])
2717
2718 (define_insn "*vec_concatv2df"
2719   [(set (match_operand:V2DF 0 "register_operand"     "=Y2,Y2,Y2,x,x")
2720         (vec_concat:V2DF
2721           (match_operand:DF 1 "nonimmediate_operand" " 0 ,0 ,m ,0,0")
2722           (match_operand:DF 2 "vector_move_operand"  " Y2,m ,C ,x,m")))]
2723   "TARGET_SSE"
2724   "@
2725    unpcklpd\t{%2, %0|%0, %2}
2726    movhpd\t{%2, %0|%0, %2}
2727    movsd\t{%1, %0|%0, %1}
2728    movlhps\t{%2, %0|%0, %2}
2729    movhps\t{%2, %0|%0, %2}"
2730   [(set_attr "type" "sselog,ssemov,ssemov,ssemov,ssemov")
2731    (set_attr "mode" "V2DF,V1DF,DF,V4SF,V2SF")])
2732
2733 (define_expand "vec_setv2df"
2734   [(match_operand:V2DF 0 "register_operand" "")
2735    (match_operand:DF 1 "register_operand" "")
2736    (match_operand 2 "const_int_operand" "")]
2737   "TARGET_SSE"
2738 {
2739   ix86_expand_vector_set (false, operands[0], operands[1],
2740                           INTVAL (operands[2]));
2741   DONE;
2742 })
2743
2744 (define_expand "vec_extractv2df"
2745   [(match_operand:DF 0 "register_operand" "")
2746    (match_operand:V2DF 1 "register_operand" "")
2747    (match_operand 2 "const_int_operand" "")]
2748   "TARGET_SSE"
2749 {
2750   ix86_expand_vector_extract (false, operands[0], operands[1],
2751                               INTVAL (operands[2]));
2752   DONE;
2753 })
2754
2755 (define_expand "vec_initv2df"
2756   [(match_operand:V2DF 0 "register_operand" "")
2757    (match_operand 1 "" "")]
2758   "TARGET_SSE"
2759 {
2760   ix86_expand_vector_init (false, operands[0], operands[1]);
2761   DONE;
2762 })
2763
2764 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2765 ;;
2766 ;; Parallel integral arithmetic
2767 ;;
2768 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2769
2770 (define_expand "neg<mode>2"
2771   [(set (match_operand:SSEMODEI 0 "register_operand" "")
2772         (minus:SSEMODEI
2773           (match_dup 2)
2774           (match_operand:SSEMODEI 1 "nonimmediate_operand" "")))]
2775   "TARGET_SSE2"
2776   "operands[2] = force_reg (<MODE>mode, CONST0_RTX (<MODE>mode));")
2777
2778 (define_expand "add<mode>3"
2779   [(set (match_operand:SSEMODEI 0 "register_operand" "")
2780         (plus:SSEMODEI (match_operand:SSEMODEI 1 "nonimmediate_operand" "")
2781                        (match_operand:SSEMODEI 2 "nonimmediate_operand" "")))]
2782   "TARGET_SSE2"
2783   "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
2784
2785 (define_insn "*add<mode>3"
2786   [(set (match_operand:SSEMODEI 0 "register_operand" "=x")
2787         (plus:SSEMODEI
2788           (match_operand:SSEMODEI 1 "nonimmediate_operand" "%0")
2789           (match_operand:SSEMODEI 2 "nonimmediate_operand" "xm")))]
2790   "TARGET_SSE2 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
2791   "padd<ssevecsize>\t{%2, %0|%0, %2}"
2792   [(set_attr "type" "sseiadd")
2793    (set_attr "prefix_data16" "1")
2794    (set_attr "mode" "TI")])
2795
2796 (define_insn "sse2_ssadd<mode>3"
2797   [(set (match_operand:SSEMODE12 0 "register_operand" "=x")
2798         (ss_plus:SSEMODE12
2799           (match_operand:SSEMODE12 1 "nonimmediate_operand" "%0")
2800           (match_operand:SSEMODE12 2 "nonimmediate_operand" "xm")))]
2801   "TARGET_SSE2 && ix86_binary_operator_ok (SS_PLUS, <MODE>mode, operands)"
2802   "padds<ssevecsize>\t{%2, %0|%0, %2}"
2803   [(set_attr "type" "sseiadd")
2804    (set_attr "prefix_data16" "1")
2805    (set_attr "mode" "TI")])
2806
2807 (define_insn "sse2_usadd<mode>3"
2808   [(set (match_operand:SSEMODE12 0 "register_operand" "=x")
2809         (us_plus:SSEMODE12
2810           (match_operand:SSEMODE12 1 "nonimmediate_operand" "%0")
2811           (match_operand:SSEMODE12 2 "nonimmediate_operand" "xm")))]
2812   "TARGET_SSE2 && ix86_binary_operator_ok (US_PLUS, <MODE>mode, operands)"
2813   "paddus<ssevecsize>\t{%2, %0|%0, %2}"
2814   [(set_attr "type" "sseiadd")
2815    (set_attr "prefix_data16" "1")
2816    (set_attr "mode" "TI")])
2817
2818 (define_expand "sub<mode>3"
2819   [(set (match_operand:SSEMODEI 0 "register_operand" "")
2820         (minus:SSEMODEI (match_operand:SSEMODEI 1 "register_operand" "")
2821                         (match_operand:SSEMODEI 2 "nonimmediate_operand" "")))]
2822   "TARGET_SSE2"
2823   "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
2824
2825 (define_insn "*sub<mode>3"
2826   [(set (match_operand:SSEMODEI 0 "register_operand" "=x")
2827         (minus:SSEMODEI
2828           (match_operand:SSEMODEI 1 "register_operand" "0")
2829           (match_operand:SSEMODEI 2 "nonimmediate_operand" "xm")))]
2830   "TARGET_SSE2"
2831   "psub<ssevecsize>\t{%2, %0|%0, %2}"
2832   [(set_attr "type" "sseiadd")
2833    (set_attr "prefix_data16" "1")
2834    (set_attr "mode" "TI")])
2835
2836 (define_insn "sse2_sssub<mode>3"
2837   [(set (match_operand:SSEMODE12 0 "register_operand" "=x")
2838         (ss_minus:SSEMODE12
2839           (match_operand:SSEMODE12 1 "register_operand" "0")
2840           (match_operand:SSEMODE12 2 "nonimmediate_operand" "xm")))]
2841   "TARGET_SSE2"
2842   "psubs<ssevecsize>\t{%2, %0|%0, %2}"
2843   [(set_attr "type" "sseiadd")
2844    (set_attr "prefix_data16" "1")
2845    (set_attr "mode" "TI")])
2846
2847 (define_insn "sse2_ussub<mode>3"
2848   [(set (match_operand:SSEMODE12 0 "register_operand" "=x")
2849         (us_minus:SSEMODE12
2850           (match_operand:SSEMODE12 1 "register_operand" "0")
2851           (match_operand:SSEMODE12 2 "nonimmediate_operand" "xm")))]
2852   "TARGET_SSE2"
2853   "psubus<ssevecsize>\t{%2, %0|%0, %2}"
2854   [(set_attr "type" "sseiadd")
2855    (set_attr "prefix_data16" "1")
2856    (set_attr "mode" "TI")])
2857
2858 (define_insn_and_split "mulv16qi3"
2859   [(set (match_operand:V16QI 0 "register_operand" "")
2860         (mult:V16QI (match_operand:V16QI 1 "register_operand" "")
2861                     (match_operand:V16QI 2 "register_operand" "")))]
2862   "TARGET_SSE2
2863    && !(reload_completed || reload_in_progress)"
2864   "#"
2865   "&& 1"
2866   [(const_int 0)]
2867 {
2868   rtx t[12], op0, op[3];
2869   int i;
2870
2871   if (TARGET_SSE5)
2872     {
2873       /* On SSE5, we can take advantage of the pperm instruction to pack and
2874          unpack the bytes.  Unpack data such that we've got a source byte in
2875          each low byte of each word.  We don't care what goes into the high
2876          byte, so put 0 there.  */
2877       for (i = 0; i < 6; ++i)
2878         t[i] = gen_reg_rtx (V8HImode);
2879
2880       for (i = 0; i < 2; i++)
2881         {
2882           op[0] = t[i];
2883           op[1] = operands[i+1];
2884           ix86_expand_sse5_unpack (op, true, true);             /* high bytes */
2885
2886           op[0] = t[i+2];
2887           ix86_expand_sse5_unpack (op, true, false);            /* low bytes */
2888         }
2889
2890       /* Multiply words.  */
2891       emit_insn (gen_mulv8hi3 (t[4], t[0], t[1]));              /* high bytes */
2892       emit_insn (gen_mulv8hi3 (t[5], t[2], t[3]));              /* low  bytes */
2893
2894       /* Pack the low byte of each word back into a single xmm */
2895       op[0] = operands[0];
2896       op[1] = t[5];
2897       op[2] = t[4];
2898       ix86_expand_sse5_pack (op);
2899       DONE;
2900     }
2901
2902   for (i = 0; i < 12; ++i)
2903     t[i] = gen_reg_rtx (V16QImode);
2904
2905   /* Unpack data such that we've got a source byte in each low byte of
2906      each word.  We don't care what goes into the high byte of each word.
2907      Rather than trying to get zero in there, most convenient is to let
2908      it be a copy of the low byte.  */
2909   emit_insn (gen_sse2_punpckhbw (t[0], operands[1], operands[1]));
2910   emit_insn (gen_sse2_punpckhbw (t[1], operands[2], operands[2]));
2911   emit_insn (gen_sse2_punpcklbw (t[2], operands[1], operands[1]));
2912   emit_insn (gen_sse2_punpcklbw (t[3], operands[2], operands[2]));
2913
2914   /* Multiply words.  The end-of-line annotations here give a picture of what
2915      the output of that instruction looks like.  Dot means don't care; the
2916      letters are the bytes of the result with A being the most significant.  */
2917   emit_insn (gen_mulv8hi3 (gen_lowpart (V8HImode, t[4]), /* .A.B.C.D.E.F.G.H */
2918                            gen_lowpart (V8HImode, t[0]),
2919                            gen_lowpart (V8HImode, t[1])));
2920   emit_insn (gen_mulv8hi3 (gen_lowpart (V8HImode, t[5]), /* .I.J.K.L.M.N.O.P */
2921                            gen_lowpart (V8HImode, t[2]),
2922                            gen_lowpart (V8HImode, t[3])));
2923
2924   /* Extract the relevant bytes and merge them back together.  */
2925   emit_insn (gen_sse2_punpckhbw (t[6], t[5], t[4]));    /* ..AI..BJ..CK..DL */
2926   emit_insn (gen_sse2_punpcklbw (t[7], t[5], t[4]));    /* ..EM..FN..GO..HP */
2927   emit_insn (gen_sse2_punpckhbw (t[8], t[7], t[6]));    /* ....AEIM....BFJN */
2928   emit_insn (gen_sse2_punpcklbw (t[9], t[7], t[6]));    /* ....CGKO....DHLP */
2929   emit_insn (gen_sse2_punpckhbw (t[10], t[9], t[8]));   /* ........ACEGIKMO */
2930   emit_insn (gen_sse2_punpcklbw (t[11], t[9], t[8]));   /* ........BDFHJLNP */
2931
2932   op0 = operands[0];
2933   emit_insn (gen_sse2_punpcklbw (op0, t[11], t[10]));   /* ABCDEFGHIJKLMNOP */
2934   DONE;
2935 })
2936
2937 (define_expand "mulv8hi3"
2938   [(set (match_operand:V8HI 0 "register_operand" "")
2939         (mult:V8HI (match_operand:V8HI 1 "nonimmediate_operand" "")
2940                    (match_operand:V8HI 2 "nonimmediate_operand" "")))]
2941   "TARGET_SSE2"
2942   "ix86_fixup_binary_operands_no_copy (MULT, V8HImode, operands);")
2943
2944 (define_insn "*mulv8hi3"
2945   [(set (match_operand:V8HI 0 "register_operand" "=x")
2946         (mult:V8HI (match_operand:V8HI 1 "nonimmediate_operand" "%0")
2947                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
2948   "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V8HImode, operands)"
2949   "pmullw\t{%2, %0|%0, %2}"
2950   [(set_attr "type" "sseimul")
2951    (set_attr "prefix_data16" "1")
2952    (set_attr "mode" "TI")])
2953
2954 (define_expand "smulv8hi3_highpart"
2955   [(set (match_operand:V8HI 0 "register_operand" "")
2956         (truncate:V8HI
2957           (lshiftrt:V8SI
2958             (mult:V8SI
2959               (sign_extend:V8SI
2960                 (match_operand:V8HI 1 "nonimmediate_operand" ""))
2961               (sign_extend:V8SI
2962                 (match_operand:V8HI 2 "nonimmediate_operand" "")))
2963             (const_int 16))))]
2964   "TARGET_SSE2"
2965   "ix86_fixup_binary_operands_no_copy (MULT, V8HImode, operands);")
2966
2967 (define_insn "*smulv8hi3_highpart"
2968   [(set (match_operand:V8HI 0 "register_operand" "=x")
2969         (truncate:V8HI
2970           (lshiftrt:V8SI
2971             (mult:V8SI
2972               (sign_extend:V8SI
2973                 (match_operand:V8HI 1 "nonimmediate_operand" "%0"))
2974               (sign_extend:V8SI
2975                 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
2976             (const_int 16))))]
2977   "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V8HImode, operands)"
2978   "pmulhw\t{%2, %0|%0, %2}"
2979   [(set_attr "type" "sseimul")
2980    (set_attr "prefix_data16" "1")
2981    (set_attr "mode" "TI")])
2982
2983 (define_expand "umulv8hi3_highpart"
2984   [(set (match_operand:V8HI 0 "register_operand" "")
2985         (truncate:V8HI
2986           (lshiftrt:V8SI
2987             (mult:V8SI
2988               (zero_extend:V8SI
2989                 (match_operand:V8HI 1 "nonimmediate_operand" ""))
2990               (zero_extend:V8SI
2991                 (match_operand:V8HI 2 "nonimmediate_operand" "")))
2992             (const_int 16))))]
2993   "TARGET_SSE2"
2994   "ix86_fixup_binary_operands_no_copy (MULT, V8HImode, operands);")
2995
2996 (define_insn "*umulv8hi3_highpart"
2997   [(set (match_operand:V8HI 0 "register_operand" "=x")
2998         (truncate:V8HI
2999           (lshiftrt:V8SI
3000             (mult:V8SI
3001               (zero_extend:V8SI
3002                 (match_operand:V8HI 1 "nonimmediate_operand" "%0"))
3003               (zero_extend:V8SI
3004                 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
3005             (const_int 16))))]
3006   "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V8HImode, operands)"
3007   "pmulhuw\t{%2, %0|%0, %2}"
3008   [(set_attr "type" "sseimul")
3009    (set_attr "prefix_data16" "1")
3010    (set_attr "mode" "TI")])
3011
3012 (define_insn "sse2_umulv2siv2di3"
3013   [(set (match_operand:V2DI 0 "register_operand" "=x")
3014         (mult:V2DI
3015           (zero_extend:V2DI
3016             (vec_select:V2SI
3017               (match_operand:V4SI 1 "nonimmediate_operand" "%0")
3018               (parallel [(const_int 0) (const_int 2)])))
3019           (zero_extend:V2DI
3020             (vec_select:V2SI
3021               (match_operand:V4SI 2 "nonimmediate_operand" "xm")
3022               (parallel [(const_int 0) (const_int 2)])))))]
3023   "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V4SImode, operands)"
3024   "pmuludq\t{%2, %0|%0, %2}"
3025   [(set_attr "type" "sseimul")
3026    (set_attr "prefix_data16" "1")
3027    (set_attr "mode" "TI")])
3028
3029 (define_insn "sse4_1_mulv2siv2di3"
3030   [(set (match_operand:V2DI 0 "register_operand" "=x")
3031         (mult:V2DI
3032           (sign_extend:V2DI
3033             (vec_select:V2SI
3034               (match_operand:V4SI 1 "nonimmediate_operand" "%0")
3035               (parallel [(const_int 0) (const_int 2)])))
3036           (sign_extend:V2DI
3037             (vec_select:V2SI
3038               (match_operand:V4SI 2 "nonimmediate_operand" "xm")
3039               (parallel [(const_int 0) (const_int 2)])))))]
3040   "TARGET_SSE4_1 && ix86_binary_operator_ok (MULT, V4SImode, operands)"
3041   "pmuldq\t{%2, %0|%0, %2}"
3042   [(set_attr "type" "sseimul")
3043    (set_attr "prefix_extra" "1")
3044    (set_attr "mode" "TI")])
3045
3046 (define_insn "sse2_pmaddwd"
3047   [(set (match_operand:V4SI 0 "register_operand" "=x")
3048         (plus:V4SI
3049           (mult:V4SI
3050             (sign_extend:V4SI
3051               (vec_select:V4HI
3052                 (match_operand:V8HI 1 "nonimmediate_operand" "%0")
3053                 (parallel [(const_int 0)
3054                            (const_int 2)
3055                            (const_int 4)
3056                            (const_int 6)])))
3057             (sign_extend:V4SI
3058               (vec_select:V4HI
3059                 (match_operand:V8HI 2 "nonimmediate_operand" "xm")
3060                 (parallel [(const_int 0)
3061                            (const_int 2)
3062                            (const_int 4)
3063                            (const_int 6)]))))
3064           (mult:V4SI
3065             (sign_extend:V4SI
3066               (vec_select:V4HI (match_dup 1)
3067                 (parallel [(const_int 1)
3068                            (const_int 3)
3069                            (const_int 5)
3070                            (const_int 7)])))
3071             (sign_extend:V4SI
3072               (vec_select:V4HI (match_dup 2)
3073                 (parallel [(const_int 1)
3074                            (const_int 3)
3075                            (const_int 5)
3076                            (const_int 7)]))))))]
3077   "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V8HImode, operands)"
3078   "pmaddwd\t{%2, %0|%0, %2}"
3079   [(set_attr "type" "sseiadd")
3080    (set_attr "prefix_data16" "1")
3081    (set_attr "mode" "TI")])
3082
3083 (define_expand "mulv4si3"
3084   [(set (match_operand:V4SI 0 "register_operand" "")
3085         (mult:V4SI (match_operand:V4SI 1 "register_operand" "")
3086                    (match_operand:V4SI 2 "register_operand" "")))]
3087   "TARGET_SSE2"
3088 {
3089   if (TARGET_SSE4_1 || TARGET_SSE5)
3090     ix86_fixup_binary_operands_no_copy (MULT, V4SImode, operands);
3091 })
3092
3093 (define_insn "*sse4_1_mulv4si3"
3094   [(set (match_operand:V4SI 0 "register_operand" "=x")
3095         (mult:V4SI (match_operand:V4SI 1 "nonimmediate_operand" "%0")
3096                    (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
3097   "TARGET_SSE4_1 && ix86_binary_operator_ok (MULT, V4SImode, operands)"
3098   "pmulld\t{%2, %0|%0, %2}"
3099   [(set_attr "type" "sseimul")
3100    (set_attr "prefix_extra" "1")
3101    (set_attr "mode" "TI")])
3102
3103 ;; We don't have a straight 32-bit parallel multiply on SSE5, so fake it with a
3104 ;; multiply/add.  In general, we expect the define_split to occur before
3105 ;; register allocation, so we have to handle the corner case where the target
3106 ;; is used as the base or index register in operands 1/2.
3107 (define_insn_and_split "*sse5_mulv4si3"
3108   [(set (match_operand:V4SI 0 "register_operand" "=&x")
3109         (mult:V4SI (match_operand:V4SI 1 "register_operand" "%x")
3110                    (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
3111   "TARGET_SSE5"
3112   "#"
3113   "&& (reload_completed
3114        || (!reg_mentioned_p (operands[0], operands[1])
3115            && !reg_mentioned_p (operands[0], operands[2])))"
3116   [(set (match_dup 0)
3117         (match_dup 3))
3118    (set (match_dup 0)
3119         (plus:V4SI (mult:V4SI (match_dup 1)
3120                               (match_dup 2))
3121                    (match_dup 0)))]
3122 {
3123   operands[3] = CONST0_RTX (V4SImode);
3124 }
3125   [(set_attr "type" "ssemuladd")
3126    (set_attr "mode" "TI")])
3127
3128 (define_insn_and_split "*sse2_mulv4si3"
3129   [(set (match_operand:V4SI 0 "register_operand" "")
3130         (mult:V4SI (match_operand:V4SI 1 "register_operand" "")
3131                    (match_operand:V4SI 2 "register_operand" "")))]
3132   "TARGET_SSE2 && !TARGET_SSE4_1 && !TARGET_SSE5
3133    && !(reload_completed || reload_in_progress)"
3134   "#"
3135   "&& 1"
3136   [(const_int 0)]
3137 {
3138   rtx t1, t2, t3, t4, t5, t6, thirtytwo;
3139   rtx op0, op1, op2;
3140
3141   op0 = operands[0];
3142   op1 = operands[1];
3143   op2 = operands[2];
3144   t1 = gen_reg_rtx (V4SImode);
3145   t2 = gen_reg_rtx (V4SImode);
3146   t3 = gen_reg_rtx (V4SImode);
3147   t4 = gen_reg_rtx (V4SImode);
3148   t5 = gen_reg_rtx (V4SImode);
3149   t6 = gen_reg_rtx (V4SImode);
3150   thirtytwo = GEN_INT (32);
3151
3152   /* Multiply elements 2 and 0.  */
3153   emit_insn (gen_sse2_umulv2siv2di3 (gen_lowpart (V2DImode, t1),
3154                                      op1, op2));
3155
3156   /* Shift both input vectors down one element, so that elements 3
3157      and 1 are now in the slots for elements 2 and 0.  For K8, at
3158      least, this is faster than using a shuffle.  */
3159   emit_insn (gen_sse2_lshrti3 (gen_lowpart (TImode, t2),
3160                                gen_lowpart (TImode, op1),
3161                                thirtytwo));
3162   emit_insn (gen_sse2_lshrti3 (gen_lowpart (TImode, t3),
3163                                gen_lowpart (TImode, op2),
3164                                thirtytwo));
3165   /* Multiply elements 3 and 1.  */
3166   emit_insn (gen_sse2_umulv2siv2di3 (gen_lowpart (V2DImode, t4),
3167                                      t2, t3));
3168
3169   /* Move the results in element 2 down to element 1; we don't care
3170      what goes in elements 2 and 3.  */
3171   emit_insn (gen_sse2_pshufd_1 (t5, t1, const0_rtx, const2_rtx,
3172                                 const0_rtx, const0_rtx));
3173   emit_insn (gen_sse2_pshufd_1 (t6, t4, const0_rtx, const2_rtx,
3174                                 const0_rtx, const0_rtx));
3175
3176   /* Merge the parts back together.  */
3177   emit_insn (gen_sse2_punpckldq (op0, t5, t6));
3178   DONE;
3179 })
3180
3181 (define_insn_and_split "mulv2di3"
3182   [(set (match_operand:V2DI 0 "register_operand" "")
3183         (mult:V2DI (match_operand:V2DI 1 "register_operand" "")
3184                    (match_operand:V2DI 2 "register_operand" "")))]
3185   "TARGET_SSE2
3186    && !(reload_completed || reload_in_progress)"
3187   "#"
3188   "&& 1"
3189   [(const_int 0)]
3190 {
3191   rtx t1, t2, t3, t4, t5, t6, thirtytwo;
3192   rtx op0, op1, op2;
3193
3194   op0 = operands[0];
3195   op1 = operands[1];
3196   op2 = operands[2];
3197   t1 = gen_reg_rtx (V2DImode);
3198   t2 = gen_reg_rtx (V2DImode);
3199   t3 = gen_reg_rtx (V2DImode);
3200   t4 = gen_reg_rtx (V2DImode);
3201   t5 = gen_reg_rtx (V2DImode);
3202   t6 = gen_reg_rtx (V2DImode);
3203   thirtytwo = GEN_INT (32);
3204
3205   /* Multiply low parts.  */
3206   emit_insn (gen_sse2_umulv2siv2di3 (t1, gen_lowpart (V4SImode, op1),
3207                                      gen_lowpart (V4SImode, op2)));
3208
3209   /* Shift input vectors left 32 bits so we can multiply high parts.  */
3210   emit_insn (gen_lshrv2di3 (t2, op1, thirtytwo));
3211   emit_insn (gen_lshrv2di3 (t3, op2, thirtytwo));
3212
3213   /* Multiply high parts by low parts.  */
3214   emit_insn (gen_sse2_umulv2siv2di3 (t4, gen_lowpart (V4SImode, op1),
3215                                      gen_lowpart (V4SImode, t3)));
3216   emit_insn (gen_sse2_umulv2siv2di3 (t5, gen_lowpart (V4SImode, op2),
3217                                      gen_lowpart (V4SImode, t2)));
3218
3219   /* Shift them back.  */
3220   emit_insn (gen_ashlv2di3 (t4, t4, thirtytwo));
3221   emit_insn (gen_ashlv2di3 (t5, t5, thirtytwo));
3222
3223   /* Add the three parts together.  */
3224   emit_insn (gen_addv2di3 (t6, t1, t4));
3225   emit_insn (gen_addv2di3 (op0, t6, t5));
3226   DONE;
3227 })
3228
3229 (define_expand "vec_widen_smult_hi_v8hi"
3230   [(match_operand:V4SI 0 "register_operand" "")
3231    (match_operand:V8HI 1 "register_operand" "")
3232    (match_operand:V8HI 2 "register_operand" "")]
3233   "TARGET_SSE2"
3234 {
3235   rtx op1, op2, t1, t2, dest;
3236
3237   op1 = operands[1];
3238   op2 = operands[2];
3239   t1 = gen_reg_rtx (V8HImode);
3240   t2 = gen_reg_rtx (V8HImode);
3241   dest = gen_lowpart (V8HImode, operands[0]);
3242
3243   emit_insn (gen_mulv8hi3 (t1, op1, op2));
3244   emit_insn (gen_smulv8hi3_highpart (t2, op1, op2));
3245   emit_insn (gen_vec_interleave_highv8hi (dest, t1, t2));
3246   DONE;
3247 })
3248
3249 (define_expand "vec_widen_smult_lo_v8hi"
3250   [(match_operand:V4SI 0 "register_operand" "")
3251    (match_operand:V8HI 1 "register_operand" "")
3252    (match_operand:V8HI 2 "register_operand" "")]
3253   "TARGET_SSE2"
3254 {
3255   rtx op1, op2, t1, t2, dest;
3256
3257   op1 = operands[1];
3258   op2 = operands[2];
3259   t1 = gen_reg_rtx (V8HImode);
3260   t2 = gen_reg_rtx (V8HImode);
3261   dest = gen_lowpart (V8HImode, operands[0]);
3262
3263   emit_insn (gen_mulv8hi3 (t1, op1, op2));
3264   emit_insn (gen_smulv8hi3_highpart (t2, op1, op2));
3265   emit_insn (gen_vec_interleave_lowv8hi (dest, t1, t2));
3266   DONE;
3267 })
3268
3269 (define_expand "vec_widen_umult_hi_v8hi"
3270   [(match_operand:V4SI 0 "register_operand" "")
3271    (match_operand:V8HI 1 "register_operand" "")
3272    (match_operand:V8HI 2 "register_operand" "")]
3273   "TARGET_SSE2"
3274 {
3275   rtx op1, op2, t1, t2, dest;
3276
3277   op1 = operands[1];
3278   op2 = operands[2];
3279   t1 = gen_reg_rtx (V8HImode);
3280   t2 = gen_reg_rtx (V8HImode);
3281   dest = gen_lowpart (V8HImode, operands[0]);
3282
3283   emit_insn (gen_mulv8hi3 (t1, op1, op2));
3284   emit_insn (gen_umulv8hi3_highpart (t2, op1, op2));
3285   emit_insn (gen_vec_interleave_highv8hi (dest, t1, t2));
3286   DONE;
3287 })
3288
3289 (define_expand "vec_widen_umult_lo_v8hi"
3290   [(match_operand:V4SI 0 "register_operand" "")
3291    (match_operand:V8HI 1 "register_operand" "")
3292    (match_operand:V8HI 2 "register_operand" "")]
3293   "TARGET_SSE2"
3294 {
3295   rtx op1, op2, t1, t2, dest;
3296
3297   op1 = operands[1];
3298   op2 = operands[2];
3299   t1 = gen_reg_rtx (V8HImode);
3300   t2 = gen_reg_rtx (V8HImode);
3301   dest = gen_lowpart (V8HImode, operands[0]);
3302
3303   emit_insn (gen_mulv8hi3 (t1, op1, op2));
3304   emit_insn (gen_umulv8hi3_highpart (t2, op1, op2));
3305   emit_insn (gen_vec_interleave_lowv8hi (dest, t1, t2));
3306   DONE;
3307 })
3308
3309 (define_expand "vec_widen_smult_hi_v4si"
3310   [(match_operand:V2DI 0 "register_operand" "")
3311    (match_operand:V4SI 1 "register_operand" "")
3312    (match_operand:V4SI 2 "register_operand" "")]
3313   "TARGET_SSE2"
3314 {
3315   rtx op1, op2, t1, t2;
3316
3317   op1 = operands[1];
3318   op2 = operands[2];
3319   t1 = gen_reg_rtx (V4SImode);
3320   t2 = gen_reg_rtx (V4SImode);
3321
3322   emit_insn (gen_vec_interleave_highv4si (t1, op1, op1));
3323   emit_insn (gen_vec_interleave_highv4si (t2, op2, op2));
3324   emit_insn (gen_sse2_umulv2siv2di3 (operands[0], t1, t2));
3325   DONE;
3326 })
3327
3328 (define_expand "vec_widen_smult_lo_v4si"
3329   [(match_operand:V2DI 0 "register_operand" "")
3330    (match_operand:V4SI 1 "register_operand" "")
3331    (match_operand:V4SI 2 "register_operand" "")]
3332   "TARGET_SSE2"
3333 {
3334   rtx op1, op2, t1, t2;
3335
3336   op1 = operands[1];
3337   op2 = operands[2];
3338   t1 = gen_reg_rtx (V4SImode);
3339   t2 = gen_reg_rtx (V4SImode);
3340
3341   emit_insn (gen_vec_interleave_lowv4si (t1, op1, op1));
3342   emit_insn (gen_vec_interleave_lowv4si (t2, op2, op2));
3343   emit_insn (gen_sse2_umulv2siv2di3 (operands[0], t1, t2));
3344   DONE;
3345 })
3346
3347 (define_expand "vec_widen_umult_hi_v4si"
3348   [(match_operand:V2DI 0 "register_operand" "")
3349    (match_operand:V4SI 1 "register_operand" "")
3350    (match_operand:V4SI 2 "register_operand" "")]
3351   "TARGET_SSE2"
3352 {
3353   rtx op1, op2, t1, t2;
3354
3355   op1 = operands[1];
3356   op2 = operands[2];
3357   t1 = gen_reg_rtx (V4SImode);
3358   t2 = gen_reg_rtx (V4SImode);
3359
3360   emit_insn (gen_vec_interleave_highv4si (t1, op1, op1));
3361   emit_insn (gen_vec_interleave_highv4si (t2, op2, op2));
3362   emit_insn (gen_sse2_umulv2siv2di3 (operands[0], t1, t2));
3363   DONE;
3364 })
3365
3366 (define_expand "vec_widen_umult_lo_v4si"
3367   [(match_operand:V2DI 0 "register_operand" "")
3368    (match_operand:V4SI 1 "register_operand" "")
3369    (match_operand:V4SI 2 "register_operand" "")]
3370   "TARGET_SSE2"
3371 {
3372   rtx op1, op2, t1, t2;
3373
3374   op1 = operands[1];
3375   op2 = operands[2];
3376   t1 = gen_reg_rtx (V4SImode);
3377   t2 = gen_reg_rtx (V4SImode);
3378
3379   emit_insn (gen_vec_interleave_lowv4si (t1, op1, op1));
3380   emit_insn (gen_vec_interleave_lowv4si (t2, op2, op2));
3381   emit_insn (gen_sse2_umulv2siv2di3 (operands[0], t1, t2));
3382   DONE;
3383 })
3384
3385 (define_expand "sdot_prodv8hi"
3386   [(match_operand:V4SI 0 "register_operand" "")
3387    (match_operand:V8HI 1 "register_operand" "")
3388    (match_operand:V8HI 2 "register_operand" "")
3389    (match_operand:V4SI 3 "register_operand" "")]
3390   "TARGET_SSE2"
3391 {
3392   rtx t = gen_reg_rtx (V4SImode);
3393   emit_insn (gen_sse2_pmaddwd (t, operands[1], operands[2]));
3394   emit_insn (gen_addv4si3 (operands[0], operands[3], t));
3395   DONE;
3396 })
3397
3398 (define_expand "udot_prodv4si"
3399   [(match_operand:V2DI 0 "register_operand" "")
3400    (match_operand:V4SI 1 "register_operand" "")
3401    (match_operand:V4SI 2 "register_operand" "")
3402    (match_operand:V2DI 3 "register_operand" "")]
3403   "TARGET_SSE2"
3404 {
3405   rtx t1, t2, t3, t4;
3406
3407   t1 = gen_reg_rtx (V2DImode);
3408   emit_insn (gen_sse2_umulv2siv2di3 (t1, operands[1], operands[2]));
3409   emit_insn (gen_addv2di3 (t1, t1, operands[3]));
3410
3411   t2 = gen_reg_rtx (V4SImode);
3412   t3 = gen_reg_rtx (V4SImode);
3413   emit_insn (gen_sse2_lshrti3 (gen_lowpart (TImode, t2),
3414                                gen_lowpart (TImode, operands[1]),
3415                                GEN_INT (32)));
3416   emit_insn (gen_sse2_lshrti3 (gen_lowpart (TImode, t3),
3417                                gen_lowpart (TImode, operands[2]),
3418                                GEN_INT (32)));
3419
3420   t4 = gen_reg_rtx (V2DImode);
3421   emit_insn (gen_sse2_umulv2siv2di3 (t4, t2, t3));
3422
3423   emit_insn (gen_addv2di3 (operands[0], t1, t4));
3424   DONE;
3425 })
3426
3427 (define_insn "ashr<mode>3"
3428   [(set (match_operand:SSEMODE24 0 "register_operand" "=x")
3429         (ashiftrt:SSEMODE24
3430           (match_operand:SSEMODE24 1 "register_operand" "0")
3431           (match_operand:SI 2 "nonmemory_operand" "xN")))]
3432   "TARGET_SSE2"
3433   "psra<ssevecsize>\t{%2, %0|%0, %2}"
3434   [(set_attr "type" "sseishft")
3435    (set_attr "prefix_data16" "1")
3436    (set_attr "mode" "TI")])
3437
3438 (define_insn "lshr<mode>3"
3439   [(set (match_operand:SSEMODE248 0 "register_operand" "=x")
3440         (lshiftrt:SSEMODE248
3441           (match_operand:SSEMODE248 1 "register_operand" "0")
3442           (match_operand:SI 2 "nonmemory_operand" "xN")))]
3443   "TARGET_SSE2"
3444   "psrl<ssevecsize>\t{%2, %0|%0, %2}"
3445   [(set_attr "type" "sseishft")
3446    (set_attr "prefix_data16" "1")
3447    (set_attr "mode" "TI")])
3448
3449 (define_insn "ashl<mode>3"
3450   [(set (match_operand:SSEMODE248 0 "register_operand" "=x")
3451         (ashift:SSEMODE248
3452           (match_operand:SSEMODE248 1 "register_operand" "0")
3453           (match_operand:SI 2 "nonmemory_operand" "xN")))]
3454   "TARGET_SSE2"
3455   "psll<ssevecsize>\t{%2, %0|%0, %2}"
3456   [(set_attr "type" "sseishft")
3457    (set_attr "prefix_data16" "1")
3458    (set_attr "mode" "TI")])
3459
3460 (define_expand "vec_shl_<mode>"
3461   [(set (match_operand:SSEMODEI 0 "register_operand" "")
3462         (ashift:TI (match_operand:SSEMODEI 1 "register_operand" "")
3463                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "")))]
3464   "TARGET_SSE2"
3465 {
3466   operands[0] = gen_lowpart (TImode, operands[0]);
3467   operands[1] = gen_lowpart (TImode, operands[1]);
3468 })
3469
3470 (define_expand "vec_shr_<mode>"
3471   [(set (match_operand:SSEMODEI 0 "register_operand" "")
3472         (lshiftrt:TI (match_operand:SSEMODEI 1 "register_operand" "")
3473                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "")))]
3474   "TARGET_SSE2"
3475 {
3476   operands[0] = gen_lowpart (TImode, operands[0]);
3477   operands[1] = gen_lowpart (TImode, operands[1]);
3478 })
3479
3480 (define_expand "<code>v16qi3"
3481   [(set (match_operand:V16QI 0 "register_operand" "")
3482         (umaxmin:V16QI
3483           (match_operand:V16QI 1 "nonimmediate_operand" "")
3484           (match_operand:V16QI 2 "nonimmediate_operand" "")))]
3485   "TARGET_SSE2"
3486   "ix86_fixup_binary_operands_no_copy (<CODE>, V16QImode, operands);")
3487
3488 (define_insn "*<code>v16qi3"
3489   [(set (match_operand:V16QI 0 "register_operand" "=x")
3490         (umaxmin:V16QI
3491           (match_operand:V16QI 1 "nonimmediate_operand" "%0")
3492           (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
3493   "TARGET_SSE2 && ix86_binary_operator_ok (<CODE>, V16QImode, operands)"
3494   "p<maxminiprefix>b\t{%2, %0|%0, %2}"
3495   [(set_attr "type" "sseiadd")
3496    (set_attr "prefix_data16" "1")
3497    (set_attr "mode" "TI")])
3498
3499 (define_expand "<code>v8hi3"
3500   [(set (match_operand:V8HI 0 "register_operand" "")
3501         (smaxmin:V8HI
3502           (match_operand:V8HI 1 "nonimmediate_operand" "")
3503           (match_operand:V8HI 2 "nonimmediate_operand" "")))]
3504   "TARGET_SSE2"
3505   "ix86_fixup_binary_operands_no_copy (<CODE>, V8HImode, operands);")
3506
3507 (define_insn "*<code>v8hi3"
3508   [(set (match_operand:V8HI 0 "register_operand" "=x")
3509         (smaxmin:V8HI
3510           (match_operand:V8HI 1 "nonimmediate_operand" "%0")
3511           (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
3512   "TARGET_SSE2 && ix86_binary_operator_ok (<CODE>, V8HImode, operands)"
3513   "p<maxminiprefix>w\t{%2, %0|%0, %2}"
3514   [(set_attr "type" "sseiadd")
3515    (set_attr "prefix_data16" "1")
3516    (set_attr "mode" "TI")])
3517
3518 (define_expand "umaxv8hi3"
3519   [(set (match_operand:V8HI 0 "register_operand" "")
3520         (umax:V8HI (match_operand:V8HI 1 "register_operand" "")
3521                    (match_operand:V8HI 2 "nonimmediate_operand" "")))]
3522   "TARGET_SSE2"
3523 {
3524   if (TARGET_SSE4_1)
3525     ix86_fixup_binary_operands_no_copy (UMAX, V8HImode, operands);
3526   else
3527     {
3528       rtx op0 = operands[0], op2 = operands[2], op3 = op0;
3529       if (rtx_equal_p (op3, op2))
3530         op3 = gen_reg_rtx (V8HImode);
3531       emit_insn (gen_sse2_ussubv8hi3 (op3, operands[1], op2));
3532       emit_insn (gen_addv8hi3 (op0, op3, op2));
3533       DONE;
3534     }
3535 })
3536
3537 (define_expand "smax<mode>3"
3538   [(set (match_operand:SSEMODE14 0 "register_operand" "")
3539         (smax:SSEMODE14 (match_operand:SSEMODE14 1 "register_operand" "")
3540                         (match_operand:SSEMODE14 2 "register_operand" "")))]
3541   "TARGET_SSE2"
3542 {
3543   if (TARGET_SSE4_1)
3544     ix86_fixup_binary_operands_no_copy (SMAX, <MODE>mode, operands);
3545   else
3546   {
3547     rtx xops[6];
3548     bool ok;
3549
3550     xops[0] = operands[0];
3551     xops[1] = operands[1];
3552     xops[2] = operands[2];
3553     xops[3] = gen_rtx_GT (VOIDmode, operands[1], operands[2]);
3554     xops[4] = operands[1];
3555     xops[5] = operands[2];
3556     ok = ix86_expand_int_vcond (xops);
3557     gcc_assert (ok);
3558     DONE;
3559   }
3560 })
3561
3562 (define_insn "*sse4_1_<code><mode>3"
3563   [(set (match_operand:SSEMODE14 0 "register_operand" "=x")
3564         (smaxmin:SSEMODE14
3565           (match_operand:SSEMODE14 1 "nonimmediate_operand" "%0")
3566           (match_operand:SSEMODE14 2 "nonimmediate_operand" "xm")))]
3567   "TARGET_SSE4_1 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
3568   "p<maxminiprefix><ssevecsize>\t{%2, %0|%0, %2}"
3569   [(set_attr "type" "sseiadd")
3570    (set_attr "prefix_extra" "1")
3571    (set_attr "mode" "TI")])
3572
3573 (define_expand "umaxv4si3"
3574   [(set (match_operand:V4SI 0 "register_operand" "")
3575         (umax:V4SI (match_operand:V4SI 1 "register_operand" "")
3576                    (match_operand:V4SI 2 "register_operand" "")))]
3577   "TARGET_SSE2"
3578 {
3579   if (TARGET_SSE4_1)
3580     ix86_fixup_binary_operands_no_copy (UMAX, V4SImode, operands);
3581   else
3582   {
3583     rtx xops[6];
3584     bool ok;
3585
3586     xops[0] = operands[0];
3587     xops[1] = operands[1];
3588     xops[2] = operands[2];
3589     xops[3] = gen_rtx_GTU (VOIDmode, operands[1], operands[2]);
3590     xops[4] = operands[1];
3591     xops[5] = operands[2];
3592     ok = ix86_expand_int_vcond (xops);
3593     gcc_assert (ok);
3594     DONE;
3595   }
3596 })
3597
3598 (define_insn "*sse4_1_<code><mode>3"
3599   [(set (match_operand:SSEMODE24 0 "register_operand" "=x")
3600         (umaxmin:SSEMODE24
3601           (match_operand:SSEMODE24 1 "nonimmediate_operand" "%0")
3602           (match_operand:SSEMODE24 2 "nonimmediate_operand" "xm")))]
3603   "TARGET_SSE4_1 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
3604   "p<maxminiprefix><ssevecsize>\t{%2, %0|%0, %2}"
3605   [(set_attr "type" "sseiadd")
3606    (set_attr "prefix_extra" "1")
3607    (set_attr "mode" "TI")])
3608
3609 (define_expand "smin<mode>3"
3610   [(set (match_operand:SSEMODE14 0 "register_operand" "")
3611         (smin:SSEMODE14 (match_operand:SSEMODE14 1 "register_operand" "")
3612                         (match_operand:SSEMODE14 2 "register_operand" "")))]
3613   "TARGET_SSE2"
3614 {
3615   if (TARGET_SSE4_1)
3616     ix86_fixup_binary_operands_no_copy (SMIN, <MODE>mode, operands);
3617   else
3618     {
3619       rtx xops[6];
3620       bool ok;
3621
3622       xops[0] = operands[0];
3623       xops[1] = operands[2];
3624       xops[2] = operands[1];
3625       xops[3] = gen_rtx_GT (VOIDmode, operands[1], operands[2]);
3626       xops[4] = operands[1];
3627       xops[5] = operands[2];
3628       ok = ix86_expand_int_vcond (xops);
3629       gcc_assert (ok);
3630       DONE;
3631     }
3632 })
3633
3634 (define_expand "umin<mode>3"
3635   [(set (match_operand:SSEMODE24 0 "register_operand" "")
3636         (umin:SSEMODE24 (match_operand:SSEMODE24 1 "register_operand" "")
3637                         (match_operand:SSEMODE24 2 "register_operand" "")))]
3638   "TARGET_SSE2"
3639 {
3640   if (TARGET_SSE4_1)
3641     ix86_fixup_binary_operands_no_copy (UMIN, <MODE>mode, operands);
3642   else
3643     {
3644       rtx xops[6];
3645       bool ok;
3646
3647       xops[0] = operands[0];
3648       xops[1] = operands[2];
3649       xops[2] = operands[1];
3650       xops[3] = gen_rtx_GTU (VOIDmode, operands[1], operands[2]);
3651       xops[4] = operands[1];
3652       xops[5] = operands[2];
3653       ok = ix86_expand_int_vcond (xops);
3654       gcc_assert (ok);
3655       DONE;
3656     }
3657 })
3658
3659 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3660 ;;
3661 ;; Parallel integral comparisons
3662 ;;
3663 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3664
3665 (define_insn "sse2_eq<mode>3"
3666   [(set (match_operand:SSEMODE124 0 "register_operand" "=x")
3667         (eq:SSEMODE124
3668           (match_operand:SSEMODE124 1 "nonimmediate_operand" "%0")
3669           (match_operand:SSEMODE124 2 "nonimmediate_operand" "xm")))]
3670   "TARGET_SSE2 && !TARGET_SSE5
3671    && ix86_binary_operator_ok (EQ, <MODE>mode, operands)"
3672   "pcmpeq<ssevecsize>\t{%2, %0|%0, %2}"
3673   [(set_attr "type" "ssecmp")
3674    (set_attr "prefix_data16" "1")
3675    (set_attr "mode" "TI")])
3676
3677 (define_insn "sse4_1_eqv2di3"
3678   [(set (match_operand:V2DI 0 "register_operand" "=x")
3679         (eq:V2DI
3680           (match_operand:V2DI 1 "nonimmediate_operand" "%0")
3681           (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
3682   "TARGET_SSE4_1 && ix86_binary_operator_ok (EQ, V2DImode, operands)"
3683   "pcmpeqq\t{%2, %0|%0, %2}"
3684   [(set_attr "type" "ssecmp")
3685    (set_attr "prefix_extra" "1")
3686    (set_attr "mode" "TI")])
3687
3688 (define_insn "sse2_gt<mode>3"
3689   [(set (match_operand:SSEMODE124 0 "register_operand" "=x")
3690         (gt:SSEMODE124
3691           (match_operand:SSEMODE124 1 "register_operand" "0")
3692           (match_operand:SSEMODE124 2 "nonimmediate_operand" "xm")))]
3693   "TARGET_SSE2 && !TARGET_SSE5"
3694   "pcmpgt<ssevecsize>\t{%2, %0|%0, %2}"
3695   [(set_attr "type" "ssecmp")
3696    (set_attr "prefix_data16" "1")
3697    (set_attr "mode" "TI")])
3698
3699 (define_insn "sse4_2_gtv2di3"
3700   [(set (match_operand:V2DI 0 "register_operand" "=x")
3701         (gt:V2DI
3702           (match_operand:V2DI 1 "nonimmediate_operand" "0")
3703           (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
3704   "TARGET_SSE4_2"
3705   "pcmpgtq\t{%2, %0|%0, %2}"
3706   [(set_attr "type" "ssecmp")
3707    (set_attr "mode" "TI")])
3708
3709 (define_expand "vcond<mode>"
3710   [(set (match_operand:SSEMODEI 0 "register_operand" "")
3711         (if_then_else:SSEMODEI
3712           (match_operator 3 ""
3713             [(match_operand:SSEMODEI 4 "nonimmediate_operand" "")
3714              (match_operand:SSEMODEI 5 "nonimmediate_operand" "")])
3715           (match_operand:SSEMODEI 1 "general_operand" "")
3716           (match_operand:SSEMODEI 2 "general_operand" "")))]
3717   "TARGET_SSE2"
3718 {
3719   if (ix86_expand_int_vcond (operands))
3720     DONE;
3721   else
3722     FAIL;
3723 })
3724
3725 (define_expand "vcondu<mode>"
3726   [(set (match_operand:SSEMODEI 0 "register_operand" "")
3727         (if_then_else:SSEMODEI
3728           (match_operator 3 ""
3729             [(match_operand:SSEMODEI 4 "nonimmediate_operand" "")
3730              (match_operand:SSEMODEI 5 "nonimmediate_operand" "")])
3731           (match_operand:SSEMODEI 1 "general_operand" "")
3732           (match_operand:SSEMODEI 2 "general_operand" "")))]
3733   "TARGET_SSE2"
3734 {
3735   if (ix86_expand_int_vcond (operands))
3736     DONE;
3737   else
3738     FAIL;
3739 })
3740
3741 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3742 ;;
3743 ;; Parallel bitwise logical operations
3744 ;;
3745 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3746
3747 (define_expand "one_cmpl<mode>2"
3748   [(set (match_operand:SSEMODEI 0 "register_operand" "")
3749         (xor:SSEMODEI (match_operand:SSEMODEI 1 "nonimmediate_operand" "")
3750                       (match_dup 2)))]
3751   "TARGET_SSE2"
3752 {
3753   int i, n = GET_MODE_NUNITS (<MODE>mode);
3754   rtvec v = rtvec_alloc (n);
3755
3756   for (i = 0; i < n; ++i)
3757     RTVEC_ELT (v, i) = constm1_rtx;
3758
3759   operands[2] = force_reg (<MODE>mode, gen_rtx_CONST_VECTOR (<MODE>mode, v));
3760 })
3761
3762 (define_insn "*sse_nand<mode>3"
3763   [(set (match_operand:SSEMODEI 0 "register_operand" "=x")
3764         (and:SSEMODEI
3765           (not:SSEMODEI (match_operand:SSEMODEI 1 "register_operand" "0"))
3766           (match_operand:SSEMODEI 2 "nonimmediate_operand" "xm")))]
3767   "(TARGET_SSE && !TARGET_SSE2)"
3768   "andnps\t{%2, %0|%0, %2}"
3769   [(set_attr "type" "sselog")
3770    (set_attr "mode" "V4SF")])
3771
3772 (define_insn "sse2_nand<mode>3"
3773   [(set (match_operand:SSEMODEI 0 "register_operand" "=x")
3774         (and:SSEMODEI
3775           (not:SSEMODEI (match_operand:SSEMODEI 1 "register_operand" "0"))
3776           (match_operand:SSEMODEI 2 "nonimmediate_operand" "xm")))]
3777   "TARGET_SSE2"
3778   "pandn\t{%2, %0|%0, %2}"
3779   [(set_attr "type" "sselog")
3780    (set_attr "prefix_data16" "1")
3781    (set_attr "mode" "TI")])
3782
3783 (define_insn "*nandtf3"
3784   [(set (match_operand:TF 0 "register_operand" "=x")
3785         (and:TF
3786           (not:TF (match_operand:TF 1 "register_operand" "0"))
3787           (match_operand:TF 2 "nonimmediate_operand" "xm")))]
3788   "TARGET_64BIT"
3789   "pandn\t{%2, %0|%0, %2}"
3790   [(set_attr "type" "sselog")
3791    (set_attr "prefix_data16" "1")
3792    (set_attr "mode" "TI")])
3793
3794 (define_expand "<code><mode>3"
3795   [(set (match_operand:SSEMODEI 0 "register_operand" "")
3796         (plogic:SSEMODEI
3797           (match_operand:SSEMODEI 1 "nonimmediate_operand" "")
3798           (match_operand:SSEMODEI 2 "nonimmediate_operand" "")))]
3799   "TARGET_SSE"
3800   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
3801
3802 (define_insn "*sse_<code><mode>3"
3803   [(set (match_operand:SSEMODEI 0 "register_operand" "=x")
3804         (plogic:SSEMODEI
3805           (match_operand:SSEMODEI 1 "nonimmediate_operand" "%0")
3806           (match_operand:SSEMODEI 2 "nonimmediate_operand" "xm")))]
3807   "(TARGET_SSE && !TARGET_SSE2)
3808    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
3809   "<plogicprefix>ps\t{%2, %0|%0, %2}"
3810   [(set_attr "type" "sselog")
3811    (set_attr "mode" "V4SF")])
3812
3813 (define_insn "*sse2_<code><mode>3"
3814   [(set (match_operand:SSEMODEI 0 "register_operand" "=x")
3815         (plogic:SSEMODEI
3816           (match_operand:SSEMODEI 1 "nonimmediate_operand" "%0")
3817           (match_operand:SSEMODEI 2 "nonimmediate_operand" "xm")))]
3818   "TARGET_SSE2 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
3819   "p<plogicprefix>\t{%2, %0|%0, %2}"
3820   [(set_attr "type" "sselog")
3821    (set_attr "prefix_data16" "1")
3822    (set_attr "mode" "TI")])
3823
3824 (define_expand "<code>tf3"
3825   [(set (match_operand:TF 0 "register_operand" "")
3826         (plogic:TF
3827           (match_operand:TF 1 "nonimmediate_operand" "")
3828           (match_operand:TF 2 "nonimmediate_operand" "")))]
3829   "TARGET_64BIT"
3830   "ix86_fixup_binary_operands_no_copy (<CODE>, TFmode, operands);")
3831
3832 (define_insn "*<code>tf3"
3833   [(set (match_operand:TF 0 "register_operand" "=x")
3834         (plogic:TF
3835           (match_operand:TF 1 "nonimmediate_operand" "%0")
3836           (match_operand:TF 2 "nonimmediate_operand" "xm")))]
3837   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, TFmode, operands)"
3838   "p<plogicprefix>\t{%2, %0|%0, %2}"
3839   [(set_attr "type" "sselog")
3840    (set_attr "prefix_data16" "1")
3841    (set_attr "mode" "TI")])
3842
3843 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3844 ;;
3845 ;; Parallel integral element swizzling
3846 ;;
3847 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3848
3849 ;; Reduce:
3850 ;;      op1 = abcdefghijklmnop
3851 ;;      op2 = qrstuvwxyz012345
3852 ;;       h1 = aqbrcsdteufvgwhx
3853 ;;       l1 = iyjzk0l1m2n3o4p5
3854 ;;       h2 = aiqybjrzcks0dlt1
3855 ;;       l2 = emu2fnv3gow4hpx5
3856 ;;       h3 = aeimquy2bfjnrvz3
3857 ;;       l3 = cgkosw04dhlptx15
3858 ;;   result = bdfhjlnprtvxz135
3859 (define_expand "vec_pack_trunc_v8hi"
3860   [(match_operand:V16QI 0 "register_operand" "")
3861    (match_operand:V8HI 1 "register_operand" "")
3862    (match_operand:V8HI 2 "register_operand" "")]
3863   "TARGET_SSE2"
3864 {
3865   rtx op1, op2, h1, l1, h2, l2, h3, l3;
3866
3867   op1 = gen_lowpart (V16QImode, operands[1]);
3868   op2 = gen_lowpart (V16QImode, operands[2]);
3869   h1 = gen_reg_rtx (V16QImode);
3870   l1 = gen_reg_rtx (V16QImode);
3871   h2 = gen_reg_rtx (V16QImode);
3872   l2 = gen_reg_rtx (V16QImode);
3873   h3 = gen_reg_rtx (V16QImode);
3874   l3 = gen_reg_rtx (V16QImode);
3875
3876   emit_insn (gen_vec_interleave_highv16qi (h1, op1, op2));
3877   emit_insn (gen_vec_interleave_lowv16qi (l1, op1, op2));
3878   emit_insn (gen_vec_interleave_highv16qi (h2, l1, h1));
3879   emit_insn (gen_vec_interleave_lowv16qi (l2, l1, h1));
3880   emit_insn (gen_vec_interleave_highv16qi (h3, l2, h2));
3881   emit_insn (gen_vec_interleave_lowv16qi (l3, l2, h2));
3882   emit_insn (gen_vec_interleave_lowv16qi (operands[0], l3, h3));
3883   DONE;
3884 })
3885
3886 ;; Reduce:
3887 ;;      op1 = abcdefgh
3888 ;;      op2 = ijklmnop
3889 ;;       h1 = aibjckdl
3890 ;;       l1 = emfngohp
3891 ;;       h2 = aeimbfjn
3892 ;;       l2 = cgkodhlp
3893 ;;   result = bdfhjlnp
3894 (define_expand "vec_pack_trunc_v4si"
3895   [(match_operand:V8HI 0 "register_operand" "")
3896    (match_operand:V4SI 1 "register_operand" "")
3897    (match_operand:V4SI 2 "register_operand" "")]
3898   "TARGET_SSE2"
3899 {
3900   rtx op1, op2, h1, l1, h2, l2;
3901
3902   op1 = gen_lowpart (V8HImode, operands[1]);
3903   op2 = gen_lowpart (V8HImode, operands[2]);
3904   h1 = gen_reg_rtx (V8HImode);
3905   l1 = gen_reg_rtx (V8HImode);
3906   h2 = gen_reg_rtx (V8HImode);
3907   l2 = gen_reg_rtx (V8HImode);
3908
3909   emit_insn (gen_vec_interleave_highv8hi (h1, op1, op2));
3910   emit_insn (gen_vec_interleave_lowv8hi (l1, op1, op2));
3911   emit_insn (gen_vec_interleave_highv8hi (h2, l1, h1));
3912   emit_insn (gen_vec_interleave_lowv8hi (l2, l1, h1));
3913   emit_insn (gen_vec_interleave_lowv8hi (operands[0], l2, h2));
3914   DONE;
3915 })
3916
3917 ;; Reduce:
3918 ;;     op1 = abcd
3919 ;;     op2 = efgh
3920 ;;      h1 = aebf
3921 ;;      l1 = cgdh
3922 ;;  result = bdfh
3923 (define_expand "vec_pack_trunc_v2di"
3924   [(match_operand:V4SI 0 "register_operand" "")
3925    (match_operand:V2DI 1 "register_operand" "")
3926    (match_operand:V2DI 2 "register_operand" "")]
3927   "TARGET_SSE2"
3928 {
3929   rtx op1, op2, h1, l1;
3930
3931   op1 = gen_lowpart (V4SImode, operands[1]);
3932   op2 = gen_lowpart (V4SImode, operands[2]);
3933   h1 = gen_reg_rtx (V4SImode);
3934   l1 = gen_reg_rtx (V4SImode);
3935
3936   emit_insn (gen_vec_interleave_highv4si (h1, op1, op2));
3937   emit_insn (gen_vec_interleave_lowv4si (l1, op1, op2));
3938   emit_insn (gen_vec_interleave_lowv4si (operands[0], l1, h1));
3939   DONE;
3940 })
3941
3942 (define_expand "vec_interleave_highv16qi"
3943   [(set (match_operand:V16QI 0 "register_operand" "")
3944         (vec_select:V16QI
3945           (vec_concat:V32QI
3946             (match_operand:V16QI 1 "register_operand" "")
3947             (match_operand:V16QI 2 "nonimmediate_operand" ""))
3948           (parallel [(const_int 8)  (const_int 24)
3949                      (const_int 9)  (const_int 25)
3950                      (const_int 10) (const_int 26)
3951                      (const_int 11) (const_int 27)
3952                      (const_int 12) (const_int 28)
3953                      (const_int 13) (const_int 29)
3954                      (const_int 14) (const_int 30)
3955                      (const_int 15) (const_int 31)])))]
3956   "TARGET_SSE2"
3957 {
3958   emit_insn (gen_sse2_punpckhbw (operands[0], operands[1], operands[2]));
3959   DONE;
3960 })
3961
3962 (define_expand "vec_interleave_lowv16qi"
3963   [(set (match_operand:V16QI 0 "register_operand" "")
3964         (vec_select:V16QI
3965           (vec_concat:V32QI
3966             (match_operand:V16QI 1 "register_operand" "")
3967             (match_operand:V16QI 2 "nonimmediate_operand" ""))
3968           (parallel [(const_int 0) (const_int 16)
3969                      (const_int 1) (const_int 17)
3970                      (const_int 2) (const_int 18)
3971                      (const_int 3) (const_int 19)
3972                      (const_int 4) (const_int 20)
3973                      (const_int 5) (const_int 21)
3974                      (const_int 6) (const_int 22)
3975                      (const_int 7) (const_int 23)])))]
3976   "TARGET_SSE2"
3977 {
3978   emit_insn (gen_sse2_punpcklbw (operands[0], operands[1], operands[2]));
3979   DONE;
3980 })
3981
3982 (define_expand "vec_interleave_highv8hi"
3983   [(set (match_operand:V8HI 0 "register_operand" "=")
3984         (vec_select:V8HI
3985           (vec_concat:V16HI
3986             (match_operand:V8HI 1 "register_operand" "")
3987             (match_operand:V8HI 2 "nonimmediate_operand" ""))
3988           (parallel [(const_int 4) (const_int 12)
3989                      (const_int 5) (const_int 13)
3990                      (const_int 6) (const_int 14)
3991                      (const_int 7) (const_int 15)])))]
3992   "TARGET_SSE2"
3993 {
3994   emit_insn (gen_sse2_punpckhwd (operands[0], operands[1], operands[2]));
3995   DONE;
3996 })
3997
3998 (define_expand "vec_interleave_lowv8hi"
3999   [(set (match_operand:V8HI 0 "register_operand" "")
4000         (vec_select:V8HI
4001           (vec_concat:V16HI
4002             (match_operand:V8HI 1 "register_operand" "")
4003             (match_operand:V8HI 2 "nonimmediate_operand" ""))
4004           (parallel [(const_int 0) (const_int 8)
4005                      (const_int 1) (const_int 9)
4006                      (const_int 2) (const_int 10)
4007                      (const_int 3) (const_int 11)])))]
4008   "TARGET_SSE2"
4009 {
4010   emit_insn (gen_sse2_punpcklwd (operands[0], operands[1], operands[2]));
4011   DONE;
4012 })
4013
4014 (define_expand "vec_interleave_highv4si"
4015   [(set (match_operand:V4SI 0 "register_operand" "")
4016         (vec_select:V4SI
4017           (vec_concat:V8SI
4018             (match_operand:V4SI 1 "register_operand" "")
4019             (match_operand:V4SI 2 "nonimmediate_operand" ""))
4020           (parallel [(const_int 2) (const_int 6)
4021                      (const_int 3) (const_int 7)])))]
4022   "TARGET_SSE2"
4023 {
4024   emit_insn (gen_sse2_punpckhdq (operands[0], operands[1], operands[2]));
4025   DONE;
4026 })
4027
4028 (define_expand "vec_interleave_lowv4si"
4029   [(set (match_operand:V4SI 0 "register_operand" "")
4030         (vec_select:V4SI
4031           (vec_concat:V8SI
4032             (match_operand:V4SI 1 "register_operand" "")
4033             (match_operand:V4SI 2 "nonimmediate_operand" ""))
4034           (parallel [(const_int 0) (const_int 4)
4035                      (const_int 1) (const_int 5)])))]
4036   "TARGET_SSE2"
4037 {
4038   emit_insn (gen_sse2_punpckldq (operands[0], operands[1], operands[2]));
4039   DONE;
4040 })
4041
4042 (define_expand "vec_interleave_highv2di"
4043   [(set (match_operand:V2DI 0 "register_operand" "")
4044         (vec_select:V2DI
4045           (vec_concat:V4DI
4046             (match_operand:V2DI 1 "register_operand" "")
4047             (match_operand:V2DI 2 "nonimmediate_operand" ""))
4048           (parallel [(const_int 1)
4049                      (const_int 3)])))]
4050   "TARGET_SSE2"
4051 {
4052   emit_insn (gen_sse2_punpckhqdq (operands[0], operands[1], operands[2]));
4053   DONE;
4054 })
4055
4056 (define_expand "vec_interleave_lowv2di"
4057   [(set (match_operand:V2DI 0 "register_operand" "")
4058         (vec_select:V2DI
4059           (vec_concat:V4DI
4060             (match_operand:V2DI 1 "register_operand" "")
4061             (match_operand:V2DI 2 "nonimmediate_operand" ""))
4062           (parallel [(const_int 0)
4063                      (const_int 2)])))]
4064   "TARGET_SSE2"
4065 {
4066   emit_insn (gen_sse2_punpcklqdq (operands[0], operands[1], operands[2]));
4067   DONE;
4068 })
4069
4070 (define_insn "sse2_packsswb"
4071   [(set (match_operand:V16QI 0 "register_operand" "=x")
4072         (vec_concat:V16QI
4073           (ss_truncate:V8QI
4074             (match_operand:V8HI 1 "register_operand" "0"))
4075           (ss_truncate:V8QI
4076             (match_operand:V8HI 2 "nonimmediate_operand" "xm"))))]
4077   "TARGET_SSE2"
4078   "packsswb\t{%2, %0|%0, %2}"
4079   [(set_attr "type" "sselog")
4080    (set_attr "prefix_data16" "1")
4081    (set_attr "mode" "TI")])
4082
4083 (define_insn "sse2_packssdw"
4084   [(set (match_operand:V8HI 0 "register_operand" "=x")
4085         (vec_concat:V8HI
4086           (ss_truncate:V4HI
4087             (match_operand:V4SI 1 "register_operand" "0"))
4088           (ss_truncate:V4HI
4089             (match_operand:V4SI 2 "nonimmediate_operand" "xm"))))]
4090   "TARGET_SSE2"
4091   "packssdw\t{%2, %0|%0, %2}"
4092   [(set_attr "type" "sselog")
4093    (set_attr "prefix_data16" "1")
4094    (set_attr "mode" "TI")])
4095
4096 (define_insn "sse2_packuswb"
4097   [(set (match_operand:V16QI 0 "register_operand" "=x")
4098         (vec_concat:V16QI
4099           (us_truncate:V8QI
4100             (match_operand:V8HI 1 "register_operand" "0"))
4101           (us_truncate:V8QI
4102             (match_operand:V8HI 2 "nonimmediate_operand" "xm"))))]
4103   "TARGET_SSE2"
4104   "packuswb\t{%2, %0|%0, %2}"
4105   [(set_attr "type" "sselog")
4106    (set_attr "prefix_data16" "1")
4107    (set_attr "mode" "TI")])
4108
4109 (define_insn "sse2_punpckhbw"
4110   [(set (match_operand:V16QI 0 "register_operand" "=x")
4111         (vec_select:V16QI
4112           (vec_concat:V32QI
4113             (match_operand:V16QI 1 "register_operand" "0")
4114             (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
4115           (parallel [(const_int 8)  (const_int 24)
4116                      (const_int 9)  (const_int 25)
4117                      (const_int 10) (const_int 26)
4118                      (const_int 11) (const_int 27)
4119                      (const_int 12) (const_int 28)
4120                      (const_int 13) (const_int 29)
4121                      (const_int 14) (const_int 30)
4122                      (const_int 15) (const_int 31)])))]
4123   "TARGET_SSE2"
4124   "punpckhbw\t{%2, %0|%0, %2}"
4125   [(set_attr "type" "sselog")
4126    (set_attr "prefix_data16" "1")
4127    (set_attr "mode" "TI")])
4128
4129 (define_insn "sse2_punpcklbw"
4130   [(set (match_operand:V16QI 0 "register_operand" "=x")
4131         (vec_select:V16QI
4132           (vec_concat:V32QI
4133             (match_operand:V16QI 1 "register_operand" "0")
4134             (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
4135           (parallel [(const_int 0) (const_int 16)
4136                      (const_int 1) (const_int 17)
4137                      (const_int 2) (const_int 18)
4138                      (const_int 3) (const_int 19)
4139                      (const_int 4) (const_int 20)
4140                      (const_int 5) (const_int 21)
4141                      (const_int 6) (const_int 22)
4142                      (const_int 7) (const_int 23)])))]
4143   "TARGET_SSE2"
4144   "punpcklbw\t{%2, %0|%0, %2}"
4145   [(set_attr "type" "sselog")
4146    (set_attr "prefix_data16" "1")
4147    (set_attr "mode" "TI")])
4148
4149 (define_insn "sse2_punpckhwd"
4150   [(set (match_operand:V8HI 0 "register_operand" "=x")
4151         (vec_select:V8HI
4152           (vec_concat:V16HI
4153             (match_operand:V8HI 1 "register_operand" "0")
4154             (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
4155           (parallel [(const_int 4) (const_int 12)
4156                      (const_int 5) (const_int 13)
4157                      (const_int 6) (const_int 14)
4158                      (const_int 7) (const_int 15)])))]
4159   "TARGET_SSE2"
4160   "punpckhwd\t{%2, %0|%0, %2}"
4161   [(set_attr "type" "sselog")
4162    (set_attr "prefix_data16" "1")
4163    (set_attr "mode" "TI")])
4164
4165 (define_insn "sse2_punpcklwd"
4166   [(set (match_operand:V8HI 0 "register_operand" "=x")
4167         (vec_select:V8HI
4168           (vec_concat:V16HI
4169             (match_operand:V8HI 1 "register_operand" "0")
4170             (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
4171           (parallel [(const_int 0) (const_int 8)
4172                      (const_int 1) (const_int 9)
4173                      (const_int 2) (const_int 10)
4174                      (const_int 3) (const_int 11)])))]
4175   "TARGET_SSE2"
4176   "punpcklwd\t{%2, %0|%0, %2}"
4177   [(set_attr "type" "sselog")
4178    (set_attr "prefix_data16" "1")
4179    (set_attr "mode" "TI")])
4180
4181 (define_insn "sse2_punpckhdq"
4182   [(set (match_operand:V4SI 0 "register_operand" "=x")
4183         (vec_select:V4SI
4184           (vec_concat:V8SI
4185             (match_operand:V4SI 1 "register_operand" "0")
4186             (match_operand:V4SI 2 "nonimmediate_operand" "xm"))
4187           (parallel [(const_int 2) (const_int 6)
4188                      (const_int 3) (const_int 7)])))]
4189   "TARGET_SSE2"
4190   "punpckhdq\t{%2, %0|%0, %2}"
4191   [(set_attr "type" "sselog")
4192    (set_attr "prefix_data16" "1")
4193    (set_attr "mode" "TI")])
4194
4195 (define_insn "sse2_punpckldq"
4196   [(set (match_operand:V4SI 0 "register_operand" "=x")
4197         (vec_select:V4SI
4198           (vec_concat:V8SI
4199             (match_operand:V4SI 1 "register_operand" "0")
4200             (match_operand:V4SI 2 "nonimmediate_operand" "xm"))
4201           (parallel [(const_int 0) (const_int 4)
4202                      (const_int 1) (const_int 5)])))]
4203   "TARGET_SSE2"
4204   "punpckldq\t{%2, %0|%0, %2}"
4205   [(set_attr "type" "sselog")
4206    (set_attr "prefix_data16" "1")
4207    (set_attr "mode" "TI")])
4208
4209 (define_insn "sse2_punpckhqdq"
4210   [(set (match_operand:V2DI 0 "register_operand" "=x")
4211         (vec_select:V2DI
4212           (vec_concat:V4DI
4213             (match_operand:V2DI 1 "register_operand" "0")
4214             (match_operand:V2DI 2 "nonimmediate_operand" "xm"))
4215           (parallel [(const_int 1)
4216                      (const_int 3)])))]
4217   "TARGET_SSE2"
4218   "punpckhqdq\t{%2, %0|%0, %2}"
4219   [(set_attr "type" "sselog")
4220    (set_attr "prefix_data16" "1")
4221    (set_attr "mode" "TI")])
4222
4223 (define_insn "sse2_punpcklqdq"
4224   [(set (match_operand:V2DI 0 "register_operand" "=x")
4225         (vec_select:V2DI
4226           (vec_concat:V4DI
4227             (match_operand:V2DI 1 "register_operand" "0")
4228             (match_operand:V2DI 2 "nonimmediate_operand" "xm"))
4229           (parallel [(const_int 0)
4230                      (const_int 2)])))]
4231   "TARGET_SSE2"
4232   "punpcklqdq\t{%2, %0|%0, %2}"
4233   [(set_attr "type" "sselog")
4234    (set_attr "prefix_data16" "1")
4235    (set_attr "mode" "TI")])
4236
4237 (define_insn "*sse4_1_pinsrb"
4238   [(set (match_operand:V16QI 0 "register_operand" "=x")
4239         (vec_merge:V16QI
4240           (vec_duplicate:V16QI
4241             (match_operand:QI 2 "nonimmediate_operand" "rm"))
4242           (match_operand:V16QI 1 "register_operand" "0")
4243           (match_operand:SI 3 "const_pow2_1_to_32768_operand" "n")))]
4244   "TARGET_SSE4_1"
4245 {
4246   operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
4247   return "pinsrb\t{%3, %k2, %0|%0, %k2, %3}";
4248 }
4249   [(set_attr "type" "sselog")
4250    (set_attr "prefix_extra" "1")
4251    (set_attr "mode" "TI")])
4252
4253 (define_insn "*sse2_pinsrw"
4254   [(set (match_operand:V8HI 0 "register_operand" "=x")
4255         (vec_merge:V8HI
4256           (vec_duplicate:V8HI
4257             (match_operand:HI 2 "nonimmediate_operand" "rm"))
4258           (match_operand:V8HI 1 "register_operand" "0")
4259           (match_operand:SI 3 "const_pow2_1_to_128_operand" "n")))]
4260   "TARGET_SSE2"
4261 {
4262   operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
4263   return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}";
4264 }
4265   [(set_attr "type" "sselog")
4266    (set_attr "prefix_data16" "1")
4267    (set_attr "mode" "TI")])
4268
4269 ;; It must come before sse2_loadld since it is preferred.
4270 (define_insn "*sse4_1_pinsrd"
4271   [(set (match_operand:V4SI 0 "register_operand" "=x")
4272         (vec_merge:V4SI
4273           (vec_duplicate:V4SI
4274             (match_operand:SI 2 "nonimmediate_operand" "rm"))
4275           (match_operand:V4SI 1 "register_operand" "0")
4276           (match_operand:SI 3 "const_pow2_1_to_8_operand" "n")))]
4277   "TARGET_SSE4_1"
4278 {
4279   operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
4280   return "pinsrd\t{%3, %2, %0|%0, %2, %3}";
4281 }
4282   [(set_attr "type" "sselog")
4283    (set_attr "prefix_extra" "1")
4284    (set_attr "mode" "TI")])
4285
4286 (define_insn "*sse4_1_pinsrq"
4287   [(set (match_operand:V2DI 0 "register_operand" "=x")
4288         (vec_merge:V2DI
4289           (vec_duplicate:V2DI
4290             (match_operand:DI 2 "nonimmediate_operand" "rm"))
4291           (match_operand:V2DI 1 "register_operand" "0")
4292           (match_operand:SI 3 "const_pow2_1_to_2_operand" "n")))]
4293   "TARGET_SSE4_1"
4294 {
4295   operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
4296   return "pinsrq\t{%3, %2, %0|%0, %2, %3}";
4297 }
4298   [(set_attr "type" "sselog")
4299    (set_attr "prefix_extra" "1")
4300    (set_attr "mode" "TI")])
4301
4302 (define_insn "*sse4_1_pextrb"
4303   [(set (match_operand:SI 0 "register_operand" "=r")
4304         (zero_extend:SI
4305           (vec_select:QI
4306             (match_operand:V16QI 1 "register_operand" "x")
4307             (parallel [(match_operand:SI 2 "const_0_to_15_operand" "n")]))))]
4308   "TARGET_SSE4_1"
4309   "pextrb\t{%2, %1, %0|%0, %1, %2}"
4310   [(set_attr "type" "sselog")
4311    (set_attr "prefix_extra" "1")
4312    (set_attr "mode" "TI")])
4313
4314 (define_insn "*sse4_1_pextrb_memory"
4315   [(set (match_operand:QI 0 "memory_operand" "=m")
4316         (vec_select:QI
4317           (match_operand:V16QI 1 "register_operand" "x")
4318           (parallel [(match_operand:SI 2 "const_0_to_15_operand" "n")])))]
4319   "TARGET_SSE4_1"
4320   "pextrb\t{%2, %1, %0|%0, %1, %2}"
4321   [(set_attr "type" "sselog")
4322    (set_attr "prefix_extra" "1")
4323    (set_attr "mode" "TI")])
4324
4325 (define_insn "*sse2_pextrw"
4326   [(set (match_operand:SI 0 "register_operand" "=r")
4327         (zero_extend:SI
4328           (vec_select:HI
4329             (match_operand:V8HI 1 "register_operand" "x")
4330             (parallel [(match_operand:SI 2 "const_0_to_7_operand" "n")]))))]
4331   "TARGET_SSE2"
4332   "pextrw\t{%2, %1, %0|%0, %1, %2}"
4333   [(set_attr "type" "sselog")
4334    (set_attr "prefix_data16" "1")
4335    (set_attr "mode" "TI")])
4336
4337 (define_insn "*sse4_1_pextrw_memory"
4338   [(set (match_operand:HI 0 "memory_operand" "=m")
4339         (vec_select:HI
4340           (match_operand:V8HI 1 "register_operand" "x")
4341           (parallel [(match_operand:SI 2 "const_0_to_7_operand" "n")])))]
4342   "TARGET_SSE4_1"
4343   "pextrw\t{%2, %1, %0|%0, %1, %2}"
4344   [(set_attr "type" "sselog")
4345    (set_attr "prefix_extra" "1")
4346    (set_attr "mode" "TI")])
4347
4348 (define_insn "*sse4_1_pextrd"
4349   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
4350         (vec_select:SI
4351           (match_operand:V4SI 1 "register_operand" "x")
4352           (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n")])))]
4353   "TARGET_SSE4_1"
4354   "pextrd\t{%2, %1, %0|%0, %1, %2}"
4355   [(set_attr "type" "sselog")
4356    (set_attr "prefix_extra" "1")
4357    (set_attr "mode" "TI")])
4358
4359 ;; It must come before *vec_extractv2di_1_sse since it is preferred.
4360 (define_insn "*sse4_1_pextrq"
4361   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
4362         (vec_select:DI
4363           (match_operand:V2DI 1 "register_operand" "x")
4364           (parallel [(match_operand:SI 2 "const_0_to_1_operand" "n")])))]
4365   "TARGET_SSE4_1 && TARGET_64BIT"
4366   "pextrq\t{%2, %1, %0|%0, %1, %2}"
4367   [(set_attr "type" "sselog")
4368    (set_attr "prefix_extra" "1")
4369    (set_attr "mode" "TI")])
4370
4371 (define_expand "sse2_pshufd"
4372   [(match_operand:V4SI 0 "register_operand" "")
4373    (match_operand:V4SI 1 "nonimmediate_operand" "")
4374    (match_operand:SI 2 "const_int_operand" "")]
4375   "TARGET_SSE2"
4376 {
4377   int mask = INTVAL (operands[2]);
4378   emit_insn (gen_sse2_pshufd_1 (operands[0], operands[1],
4379                                 GEN_INT ((mask >> 0) & 3),
4380                                 GEN_INT ((mask >> 2) & 3),
4381                                 GEN_INT ((mask >> 4) & 3),
4382                                 GEN_INT ((mask >> 6) & 3)));
4383   DONE;
4384 })
4385
4386 (define_insn "sse2_pshufd_1"
4387   [(set (match_operand:V4SI 0 "register_operand" "=x")
4388         (vec_select:V4SI
4389           (match_operand:V4SI 1 "nonimmediate_operand" "xm")
4390           (parallel [(match_operand 2 "const_0_to_3_operand" "")
4391                      (match_operand 3 "const_0_to_3_operand" "")
4392                      (match_operand 4 "const_0_to_3_operand" "")
4393                      (match_operand 5 "const_0_to_3_operand" "")])))]
4394   "TARGET_SSE2"
4395 {
4396   int mask = 0;
4397   mask |= INTVAL (operands[2]) << 0;
4398   mask |= INTVAL (operands[3]) << 2;
4399   mask |= INTVAL (operands[4]) << 4;
4400   mask |= INTVAL (operands[5]) << 6;
4401   operands[2] = GEN_INT (mask);
4402
4403   return "pshufd\t{%2, %1, %0|%0, %1, %2}";
4404 }
4405   [(set_attr "type" "sselog1")
4406    (set_attr "prefix_data16" "1")
4407    (set_attr "mode" "TI")])
4408
4409 (define_expand "sse2_pshuflw"
4410   [(match_operand:V8HI 0 "register_operand" "")
4411    (match_operand:V8HI 1 "nonimmediate_operand" "")
4412    (match_operand:SI 2 "const_int_operand" "")]
4413   "TARGET_SSE2"
4414 {
4415   int mask = INTVAL (operands[2]);
4416   emit_insn (gen_sse2_pshuflw_1 (operands[0], operands[1],
4417                                  GEN_INT ((mask >> 0) & 3),
4418                                  GEN_INT ((mask >> 2) & 3),
4419                                  GEN_INT ((mask >> 4) & 3),
4420                                  GEN_INT ((mask >> 6) & 3)));
4421   DONE;
4422 })
4423
4424 (define_insn "sse2_pshuflw_1"
4425   [(set (match_operand:V8HI 0 "register_operand" "=x")
4426         (vec_select:V8HI
4427           (match_operand:V8HI 1 "nonimmediate_operand" "xm")
4428           (parallel [(match_operand 2 "const_0_to_3_operand" "")
4429                      (match_operand 3 "const_0_to_3_operand" "")
4430                      (match_operand 4 "const_0_to_3_operand" "")
4431                      (match_operand 5 "const_0_to_3_operand" "")
4432                      (const_int 4)
4433                      (const_int 5)
4434                      (const_int 6)
4435                      (const_int 7)])))]
4436   "TARGET_SSE2"
4437 {
4438   int mask = 0;
4439   mask |= INTVAL (operands[2]) << 0;
4440   mask |= INTVAL (operands[3]) << 2;
4441   mask |= INTVAL (operands[4]) << 4;
4442   mask |= INTVAL (operands[5]) << 6;
4443   operands[2] = GEN_INT (mask);
4444
4445   return "pshuflw\t{%2, %1, %0|%0, %1, %2}";
4446 }
4447   [(set_attr "type" "sselog")
4448    (set_attr "prefix_rep" "1")
4449    (set_attr "mode" "TI")])
4450
4451 (define_expand "sse2_pshufhw"
4452   [(match_operand:V8HI 0 "register_operand" "")
4453    (match_operand:V8HI 1 "nonimmediate_operand" "")
4454    (match_operand:SI 2 "const_int_operand" "")]
4455   "TARGET_SSE2"
4456 {
4457   int mask = INTVAL (operands[2]);
4458   emit_insn (gen_sse2_pshufhw_1 (operands[0], operands[1],
4459                                  GEN_INT (((mask >> 0) & 3) + 4),
4460                                  GEN_INT (((mask >> 2) & 3) + 4),
4461                                  GEN_INT (((mask >> 4) & 3) + 4),
4462                                  GEN_INT (((mask >> 6) & 3) + 4)));
4463   DONE;
4464 })
4465
4466 (define_insn "sse2_pshufhw_1"
4467   [(set (match_operand:V8HI 0 "register_operand" "=x")
4468         (vec_select:V8HI
4469           (match_operand:V8HI 1 "nonimmediate_operand" "xm")
4470           (parallel [(const_int 0)
4471                      (const_int 1)
4472                      (const_int 2)
4473                      (const_int 3)
4474                      (match_operand 2 "const_4_to_7_operand" "")
4475                      (match_operand 3 "const_4_to_7_operand" "")
4476                      (match_operand 4 "const_4_to_7_operand" "")
4477                      (match_operand 5 "const_4_to_7_operand" "")])))]
4478   "TARGET_SSE2"
4479 {
4480   int mask = 0;
4481   mask |= (INTVAL (operands[2]) - 4) << 0;
4482   mask |= (INTVAL (operands[3]) - 4) << 2;
4483   mask |= (INTVAL (operands[4]) - 4) << 4;
4484   mask |= (INTVAL (operands[5]) - 4) << 6;
4485   operands[2] = GEN_INT (mask);
4486
4487   return "pshufhw\t{%2, %1, %0|%0, %1, %2}";
4488 }
4489   [(set_attr "type" "sselog")
4490    (set_attr "prefix_rep" "1")
4491    (set_attr "mode" "TI")])
4492
4493 (define_expand "sse2_loadd"
4494   [(set (match_operand:V4SI 0 "register_operand" "")
4495         (vec_merge:V4SI
4496           (vec_duplicate:V4SI
4497             (match_operand:SI 1 "nonimmediate_operand" ""))
4498           (match_dup 2)
4499           (const_int 1)))]
4500   "TARGET_SSE"
4501   "operands[2] = CONST0_RTX (V4SImode);")
4502
4503 (define_insn "sse2_loadld"
4504   [(set (match_operand:V4SI 0 "register_operand"       "=Y2,Yi,x,x")
4505         (vec_merge:V4SI
4506           (vec_duplicate:V4SI
4507             (match_operand:SI 2 "nonimmediate_operand" "m  ,r ,m,x"))
4508           (match_operand:V4SI 1 "reg_or_0_operand"     "C  ,C ,C,0")
4509           (const_int 1)))]
4510   "TARGET_SSE"
4511   "@
4512    movd\t{%2, %0|%0, %2}
4513    movd\t{%2, %0|%0, %2}
4514    movss\t{%2, %0|%0, %2}
4515    movss\t{%2, %0|%0, %2}"
4516   [(set_attr "type" "ssemov")
4517    (set_attr "mode" "TI,TI,V4SF,SF")])
4518
4519 (define_insn_and_split "sse2_stored"
4520   [(set (match_operand:SI 0 "nonimmediate_operand" "=mx,r")
4521         (vec_select:SI
4522           (match_operand:V4SI 1 "register_operand" "x,Yi")
4523           (parallel [(const_int 0)])))]
4524   "TARGET_SSE"
4525   "#"
4526   "&& reload_completed
4527    && (TARGET_INTER_UNIT_MOVES
4528        || MEM_P (operands [0])
4529        || !GENERAL_REGNO_P (true_regnum (operands [0])))"
4530   [(set (match_dup 0) (match_dup 1))]
4531 {
4532   operands[1] = gen_rtx_REG (SImode, REGNO (operands[1]));
4533 })
4534
4535 (define_insn_and_split "*vec_ext_v4si_mem"
4536   [(set (match_operand:SI 0 "register_operand" "=r")
4537         (vec_select:SI
4538           (match_operand:V4SI 1 "memory_operand" "o")
4539           (parallel [(match_operand 2 "const_0_to_3_operand" "")])))]
4540   ""
4541   "#"
4542   "reload_completed"
4543   [(const_int 0)]
4544 {
4545   int i = INTVAL (operands[2]);
4546
4547   emit_move_insn (operands[0], adjust_address (operands[1], SImode, i*4));
4548   DONE;
4549 })
4550
4551 (define_expand "sse_storeq"
4552   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4553         (vec_select:DI
4554           (match_operand:V2DI 1 "register_operand" "")
4555           (parallel [(const_int 0)])))]
4556   "TARGET_SSE"
4557   "")
4558
4559 (define_insn "*sse2_storeq_rex64"
4560   [(set (match_operand:DI 0 "nonimmediate_operand" "=mx,r,r")
4561         (vec_select:DI
4562           (match_operand:V2DI 1 "nonimmediate_operand" "x,Yi,o")
4563           (parallel [(const_int 0)])))]
4564   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
4565   "@
4566    #
4567    #
4568    mov{q}\t{%1, %0|%0, %1}"
4569   [(set_attr "type" "*,*,imov")
4570    (set_attr "mode" "*,*,DI")])
4571
4572 (define_insn "*sse2_storeq"
4573   [(set (match_operand:DI 0 "nonimmediate_operand" "=mx")
4574         (vec_select:DI
4575           (match_operand:V2DI 1 "register_operand" "x")
4576           (parallel [(const_int 0)])))]
4577   "TARGET_SSE"
4578   "#")
4579
4580 (define_split
4581   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4582         (vec_select:DI
4583           (match_operand:V2DI 1 "register_operand" "")
4584           (parallel [(const_int 0)])))]
4585   "TARGET_SSE
4586    && reload_completed
4587    && (TARGET_INTER_UNIT_MOVES
4588        || MEM_P (operands [0])
4589        || !GENERAL_REGNO_P (true_regnum (operands [0])))"
4590   [(set (match_dup 0) (match_dup 1))]
4591 {
4592   operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));
4593 })
4594
4595 (define_insn "*vec_extractv2di_1_rex64"
4596   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,x,x,r")
4597         (vec_select:DI
4598           (match_operand:V2DI 1 "nonimmediate_operand" "x,0,o,o")
4599           (parallel [(const_int 1)])))]
4600   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
4601   "@
4602    movhps\t{%1, %0|%0, %1}
4603    psrldq\t{$8, %0|%0, 8}
4604    movq\t{%H1, %0|%0, %H1}
4605    mov{q}\t{%H1, %0|%0, %H1}"
4606   [(set_attr "type" "ssemov,sseishft,ssemov,imov")
4607    (set_attr "memory" "*,none,*,*")
4608    (set_attr "mode" "V2SF,TI,TI,DI")])
4609
4610 (define_insn "*vec_extractv2di_1_sse2"
4611   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,x,x")
4612         (vec_select:DI
4613           (match_operand:V2DI 1 "nonimmediate_operand" "x,0,o")
4614           (parallel [(const_int 1)])))]
4615   "!TARGET_64BIT
4616    && TARGET_SSE2 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
4617   "@
4618    movhps\t{%1, %0|%0, %1}
4619    psrldq\t{$8, %0|%0, 8}
4620    movq\t{%H1, %0|%0, %H1}"
4621   [(set_attr "type" "ssemov,sseishft,ssemov")
4622    (set_attr "memory" "*,none,*")
4623    (set_attr "mode" "V2SF,TI,TI")])
4624
4625 ;; Not sure this is ever used, but it doesn't hurt to have it. -aoliva
4626 (define_insn "*vec_extractv2di_1_sse"
4627   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,x,x")
4628         (vec_select:DI
4629           (match_operand:V2DI 1 "nonimmediate_operand" "x,x,o")
4630           (parallel [(const_int 1)])))]
4631   "!TARGET_SSE2 && TARGET_SSE
4632    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
4633   "@
4634    movhps\t{%1, %0|%0, %1}
4635    movhlps\t{%1, %0|%0, %1}
4636    movlps\t{%H1, %0|%0, %H1}"
4637   [(set_attr "type" "ssemov")
4638    (set_attr "mode" "V2SF,V4SF,V2SF")])
4639
4640 (define_insn "*vec_dupv4si"
4641   [(set (match_operand:V4SI 0 "register_operand" "=Y2,x")
4642         (vec_duplicate:V4SI
4643           (match_operand:SI 1 "register_operand" " Y2,0")))]
4644   "TARGET_SSE"
4645   "@
4646    pshufd\t{$0, %1, %0|%0, %1, 0}
4647    shufps\t{$0, %0, %0|%0, %0, 0}"
4648   [(set_attr "type" "sselog1")
4649    (set_attr "mode" "TI,V4SF")])
4650
4651 (define_insn "*vec_dupv2di"
4652   [(set (match_operand:V2DI 0 "register_operand" "=Y2,x")
4653         (vec_duplicate:V2DI
4654           (match_operand:DI 1 "register_operand" " 0 ,0")))]
4655   "TARGET_SSE"
4656   "@
4657    punpcklqdq\t%0, %0
4658    movlhps\t%0, %0"
4659   [(set_attr "type" "sselog1,ssemov")
4660    (set_attr "mode" "TI,V4SF")])
4661
4662 ;; ??? In theory we can match memory for the MMX alternative, but allowing
4663 ;; nonimmediate_operand for operand 2 and *not* allowing memory for the SSE
4664 ;; alternatives pretty much forces the MMX alternative to be chosen.
4665 (define_insn "*sse2_concatv2si"
4666   [(set (match_operand:V2SI 0 "register_operand"     "=Y2, Y2,*y,*y")
4667         (vec_concat:V2SI
4668           (match_operand:SI 1 "nonimmediate_operand" " 0 ,rm , 0,rm")
4669           (match_operand:SI 2 "reg_or_0_operand"     " Y2,C  ,*y, C")))]
4670   "TARGET_SSE2"
4671   "@
4672    punpckldq\t{%2, %0|%0, %2}
4673    movd\t{%1, %0|%0, %1}
4674    punpckldq\t{%2, %0|%0, %2}
4675    movd\t{%1, %0|%0, %1}"
4676   [(set_attr "type" "sselog,ssemov,mmxcvt,mmxmov")
4677    (set_attr "mode" "TI,TI,DI,DI")])
4678
4679 (define_insn "*sse1_concatv2si"
4680   [(set (match_operand:V2SI 0 "register_operand"     "=x,x,*y,*y")
4681         (vec_concat:V2SI
4682           (match_operand:SI 1 "nonimmediate_operand" " 0,m, 0,*rm")
4683           (match_operand:SI 2 "reg_or_0_operand"     " x,C,*y,C")))]
4684   "TARGET_SSE"
4685   "@
4686    unpcklps\t{%2, %0|%0, %2}
4687    movss\t{%1, %0|%0, %1}
4688    punpckldq\t{%2, %0|%0, %2}
4689    movd\t{%1, %0|%0, %1}"
4690   [(set_attr "type" "sselog,ssemov,mmxcvt,mmxmov")
4691    (set_attr "mode" "V4SF,V4SF,DI,DI")])
4692
4693 (define_insn "*vec_concatv4si_1"
4694   [(set (match_operand:V4SI 0 "register_operand"       "=Y2,x,x")
4695         (vec_concat:V4SI
4696           (match_operand:V2SI 1 "register_operand"     " 0 ,0,0")
4697           (match_operand:V2SI 2 "nonimmediate_operand" " Y2,x,m")))]
4698   "TARGET_SSE"
4699   "@
4700    punpcklqdq\t{%2, %0|%0, %2}
4701    movlhps\t{%2, %0|%0, %2}
4702    movhps\t{%2, %0|%0, %2}"
4703   [(set_attr "type" "sselog,ssemov,ssemov")
4704    (set_attr "mode" "TI,V4SF,V2SF")])
4705
4706 (define_insn "vec_concatv2di"
4707   [(set (match_operand:V2DI 0 "register_operand"     "=Y2,?Y2,Y2,x,x,x")
4708         (vec_concat:V2DI
4709           (match_operand:DI 1 "nonimmediate_operand" "  m,*y ,0 ,0,0,m")
4710           (match_operand:DI 2 "vector_move_operand"  "  C,  C,Y2,x,m,0")))]
4711   "!TARGET_64BIT && TARGET_SSE"
4712   "@
4713    movq\t{%1, %0|%0, %1}
4714    movq2dq\t{%1, %0|%0, %1}
4715    punpcklqdq\t{%2, %0|%0, %2}
4716    movlhps\t{%2, %0|%0, %2}
4717    movhps\t{%2, %0|%0, %2}
4718    movlps\t{%1, %0|%0, %1}"
4719   [(set_attr "type" "ssemov,ssemov,sselog,ssemov,ssemov,ssemov")
4720    (set_attr "mode" "TI,TI,TI,V4SF,V2SF,V2SF")])
4721
4722 (define_insn "*vec_concatv2di_rex"
4723   [(set (match_operand:V2DI 0 "register_operand"     "=Y2,Yi,!Y2,Y2,x,x,x")
4724         (vec_concat:V2DI
4725           (match_operand:DI 1 "nonimmediate_operand" "  m,r ,*y ,0 ,0,0,m")
4726           (match_operand:DI 2 "vector_move_operand"  "  C,C ,C  ,Y2,x,m,0")))]
4727   "TARGET_64BIT"
4728   "@
4729    movq\t{%1, %0|%0, %1}
4730    movq\t{%1, %0|%0, %1}
4731    movq2dq\t{%1, %0|%0, %1}
4732    punpcklqdq\t{%2, %0|%0, %2}
4733    movlhps\t{%2, %0|%0, %2}
4734    movhps\t{%2, %0|%0, %2}
4735    movlps\t{%1, %0|%0, %1}"
4736   [(set_attr "type" "ssemov,ssemov,ssemov,sselog,ssemov,ssemov,ssemov")
4737    (set_attr "mode" "TI,TI,TI,TI,V4SF,V2SF,V2SF")])
4738
4739 (define_expand "vec_setv2di"
4740   [(match_operand:V2DI 0 "register_operand" "")
4741    (match_operand:DI 1 "register_operand" "")
4742    (match_operand 2 "const_int_operand" "")]
4743   "TARGET_SSE"
4744 {
4745   ix86_expand_vector_set (false, operands[0], operands[1],
4746                           INTVAL (operands[2]));
4747   DONE;
4748 })
4749
4750 (define_expand "vec_extractv2di"
4751   [(match_operand:DI 0 "register_operand" "")
4752    (match_operand:V2DI 1 "register_operand" "")
4753    (match_operand 2 "const_int_operand" "")]
4754   "TARGET_SSE"
4755 {
4756   ix86_expand_vector_extract (false, operands[0], operands[1],
4757                               INTVAL (operands[2]));
4758   DONE;
4759 })
4760
4761 (define_expand "vec_initv2di"
4762   [(match_operand:V2DI 0 "register_operand" "")
4763    (match_operand 1 "" "")]
4764   "TARGET_SSE"
4765 {
4766   ix86_expand_vector_init (false, operands[0], operands[1]);
4767   DONE;
4768 })
4769
4770 (define_expand "vec_setv4si"
4771   [(match_operand:V4SI 0 "register_operand" "")
4772    (match_operand:SI 1 "register_operand" "")
4773    (match_operand 2 "const_int_operand" "")]
4774   "TARGET_SSE"
4775 {
4776   ix86_expand_vector_set (false, operands[0], operands[1],
4777                           INTVAL (operands[2]));
4778   DONE;
4779 })
4780
4781 (define_expand "vec_extractv4si"
4782   [(match_operand:SI 0 "register_operand" "")
4783    (match_operand:V4SI 1 "register_operand" "")
4784    (match_operand 2 "const_int_operand" "")]
4785   "TARGET_SSE"
4786 {
4787   ix86_expand_vector_extract (false, operands[0], operands[1],
4788                               INTVAL (operands[2]));
4789   DONE;
4790 })
4791
4792 (define_expand "vec_initv4si"
4793   [(match_operand:V4SI 0 "register_operand" "")
4794    (match_operand 1 "" "")]
4795   "TARGET_SSE"
4796 {
4797   ix86_expand_vector_init (false, operands[0], operands[1]);
4798   DONE;
4799 })
4800
4801 (define_expand "vec_setv8hi"
4802   [(match_operand:V8HI 0 "register_operand" "")
4803    (match_operand:HI 1 "register_operand" "")
4804    (match_operand 2 "const_int_operand" "")]
4805   "TARGET_SSE"
4806 {
4807   ix86_expand_vector_set (false, operands[0], operands[1],
4808                           INTVAL (operands[2]));
4809   DONE;
4810 })
4811
4812 (define_expand "vec_extractv8hi"
4813   [(match_operand:HI 0 "register_operand" "")
4814    (match_operand:V8HI 1 "register_operand" "")
4815    (match_operand 2 "const_int_operand" "")]
4816   "TARGET_SSE"
4817 {
4818   ix86_expand_vector_extract (false, operands[0], operands[1],
4819                               INTVAL (operands[2]));
4820   DONE;
4821 })
4822
4823 (define_expand "vec_initv8hi"
4824   [(match_operand:V8HI 0 "register_operand" "")
4825    (match_operand 1 "" "")]
4826   "TARGET_SSE"
4827 {
4828   ix86_expand_vector_init (false, operands[0], operands[1]);
4829   DONE;
4830 })
4831
4832 (define_expand "vec_setv16qi"
4833   [(match_operand:V16QI 0 "register_operand" "")
4834    (match_operand:QI 1 "register_operand" "")
4835    (match_operand 2 "const_int_operand" "")]
4836   "TARGET_SSE"
4837 {
4838   ix86_expand_vector_set (false, operands[0], operands[1],
4839                           INTVAL (operands[2]));
4840   DONE;
4841 })
4842
4843 (define_expand "vec_extractv16qi"
4844   [(match_operand:QI 0 "register_operand" "")
4845    (match_operand:V16QI 1 "register_operand" "")
4846    (match_operand 2 "const_int_operand" "")]
4847   "TARGET_SSE"
4848 {
4849   ix86_expand_vector_extract (false, operands[0], operands[1],
4850                               INTVAL (operands[2]));
4851   DONE;
4852 })
4853
4854 (define_expand "vec_initv16qi"
4855   [(match_operand:V16QI 0 "register_operand" "")
4856    (match_operand 1 "" "")]
4857   "TARGET_SSE"
4858 {
4859   ix86_expand_vector_init (false, operands[0], operands[1]);
4860   DONE;
4861 })
4862
4863 (define_expand "vec_unpacku_hi_v16qi"
4864   [(match_operand:V8HI 0 "register_operand" "")
4865    (match_operand:V16QI 1 "register_operand" "")]
4866   "TARGET_SSE2"
4867 {
4868   if (TARGET_SSE4_1)
4869     ix86_expand_sse4_unpack (operands, true, true);
4870   else if (TARGET_SSE5)
4871     ix86_expand_sse5_unpack (operands, true, true);
4872   else
4873     ix86_expand_sse_unpack (operands, true, true);
4874   DONE;
4875 })
4876
4877 (define_expand "vec_unpacks_hi_v16qi"
4878   [(match_operand:V8HI 0 "register_operand" "")
4879    (match_operand:V16QI 1 "register_operand" "")]
4880   "TARGET_SSE2"
4881 {
4882   if (TARGET_SSE4_1)
4883     ix86_expand_sse4_unpack (operands, false, true);
4884   else if (TARGET_SSE5)
4885     ix86_expand_sse5_unpack (operands, false, true);
4886   else
4887     ix86_expand_sse_unpack (operands, false, true);
4888   DONE;
4889 })
4890
4891 (define_expand "vec_unpacku_lo_v16qi"
4892   [(match_operand:V8HI 0 "register_operand" "")
4893    (match_operand:V16QI 1 "register_operand" "")]
4894   "TARGET_SSE2"
4895 {
4896   if (TARGET_SSE4_1)
4897     ix86_expand_sse4_unpack (operands, true, false);
4898   else if (TARGET_SSE5)
4899     ix86_expand_sse5_unpack (operands, true, false);
4900   else
4901     ix86_expand_sse_unpack (operands, true, false);
4902   DONE;
4903 })
4904
4905 (define_expand "vec_unpacks_lo_v16qi"
4906   [(match_operand:V8HI 0 "register_operand" "")
4907    (match_operand:V16QI 1 "register_operand" "")]
4908   "TARGET_SSE2"
4909 {
4910   if (TARGET_SSE4_1)
4911     ix86_expand_sse4_unpack (operands, false, false);
4912   else if (TARGET_SSE5)
4913     ix86_expand_sse5_unpack (operands, false, false);
4914   else
4915     ix86_expand_sse_unpack (operands, false, false);
4916   DONE;
4917 })
4918
4919 (define_expand "vec_unpacku_hi_v8hi"
4920   [(match_operand:V4SI 0 "register_operand" "")
4921    (match_operand:V8HI 1 "register_operand" "")]
4922   "TARGET_SSE2"
4923 {
4924   if (TARGET_SSE4_1)
4925     ix86_expand_sse4_unpack (operands, true, true);
4926   else if (TARGET_SSE5)
4927     ix86_expand_sse5_unpack (operands, true, true);
4928   else
4929     ix86_expand_sse_unpack (operands, true, true);
4930   DONE;
4931 })
4932
4933 (define_expand "vec_unpacks_hi_v8hi"
4934   [(match_operand:V4SI 0 "register_operand" "")
4935    (match_operand:V8HI 1 "register_operand" "")]
4936   "TARGET_SSE2"
4937 {
4938   if (TARGET_SSE4_1)
4939     ix86_expand_sse4_unpack (operands, false, true);
4940   else if (TARGET_SSE5)
4941     ix86_expand_sse5_unpack (operands, false, true);
4942   else
4943     ix86_expand_sse_unpack (operands, false, true);
4944   DONE;
4945 })
4946
4947 (define_expand "vec_unpacku_lo_v8hi"
4948   [(match_operand:V4SI 0 "register_operand" "")
4949    (match_operand:V8HI 1 "register_operand" "")]
4950   "TARGET_SSE2"
4951 {
4952   if (TARGET_SSE4_1)
4953     ix86_expand_sse4_unpack (operands, true, false);
4954   else if (TARGET_SSE5)
4955     ix86_expand_sse5_unpack (operands, true, false);
4956   else
4957     ix86_expand_sse_unpack (operands, true, false);
4958   DONE;
4959 })
4960
4961 (define_expand "vec_unpacks_lo_v8hi"
4962   [(match_operand:V4SI 0 "register_operand" "")
4963    (match_operand:V8HI 1 "register_operand" "")]
4964   "TARGET_SSE2"
4965 {
4966   if (TARGET_SSE4_1)
4967     ix86_expand_sse4_unpack (operands, false, false);
4968   else if (TARGET_SSE5)
4969     ix86_expand_sse5_unpack (operands, false, false);
4970   else
4971     ix86_expand_sse_unpack (operands, false, false);
4972   DONE;
4973 })
4974
4975 (define_expand "vec_unpacku_hi_v4si"
4976   [(match_operand:V2DI 0 "register_operand" "")
4977    (match_operand:V4SI 1 "register_operand" "")]
4978   "TARGET_SSE2"
4979 {
4980   if (TARGET_SSE4_1)
4981     ix86_expand_sse4_unpack (operands, true, true);
4982   else if (TARGET_SSE5)
4983     ix86_expand_sse5_unpack (operands, true, true);
4984   else
4985     ix86_expand_sse_unpack (operands, true, true);
4986   DONE;
4987 })
4988
4989 (define_expand "vec_unpacks_hi_v4si"
4990   [(match_operand:V2DI 0 "register_operand" "")
4991    (match_operand:V4SI 1 "register_operand" "")]
4992   "TARGET_SSE2"
4993 {
4994   if (TARGET_SSE4_1)
4995     ix86_expand_sse4_unpack (operands, false, true);
4996   else if (TARGET_SSE5)
4997     ix86_expand_sse5_unpack (operands, false, true);
4998   else
4999     ix86_expand_sse_unpack (operands, false, true);
5000   DONE;
5001 })
5002
5003 (define_expand "vec_unpacku_lo_v4si"
5004   [(match_operand:V2DI 0 "register_operand" "")
5005    (match_operand:V4SI 1 "register_operand" "")]
5006   "TARGET_SSE2"
5007 {
5008   if (TARGET_SSE4_1)
5009     ix86_expand_sse4_unpack (operands, true, false);
5010   else if (TARGET_SSE5)
5011     ix86_expand_sse5_unpack (operands, true, false);
5012   else
5013     ix86_expand_sse_unpack (operands, true, false);
5014   DONE;
5015 })
5016
5017 (define_expand "vec_unpacks_lo_v4si"
5018   [(match_operand:V2DI 0 "register_operand" "")
5019    (match_operand:V4SI 1 "register_operand" "")]
5020   "TARGET_SSE2"
5021 {
5022   if (TARGET_SSE4_1)
5023     ix86_expand_sse4_unpack (operands, false, false);
5024   else if (TARGET_SSE5)
5025     ix86_expand_sse5_unpack (operands, false, false);
5026   else
5027     ix86_expand_sse_unpack (operands, false, false);
5028   DONE;
5029 })
5030
5031 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5032 ;;
5033 ;; Miscellaneous
5034 ;;
5035 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5036
5037 (define_insn "sse2_uavgv16qi3"
5038   [(set (match_operand:V16QI 0 "register_operand" "=x")
5039         (truncate:V16QI
5040           (lshiftrt:V16HI
5041             (plus:V16HI
5042               (plus:V16HI
5043                 (zero_extend:V16HI
5044                   (match_operand:V16QI 1 "nonimmediate_operand" "%0"))
5045                 (zero_extend:V16HI
5046                   (match_operand:V16QI 2 "nonimmediate_operand" "xm")))
5047               (const_vector:V16QI [(const_int 1) (const_int 1)
5048                                    (const_int 1) (const_int 1)
5049                                    (const_int 1) (const_int 1)
5050                                    (const_int 1) (const_int 1)
5051                                    (const_int 1) (const_int 1)
5052                                    (const_int 1) (const_int 1)
5053                                    (const_int 1) (const_int 1)
5054                                    (const_int 1) (const_int 1)]))
5055             (const_int 1))))]
5056   "TARGET_SSE2 && ix86_binary_operator_ok (PLUS, V16QImode, operands)"
5057   "pavgb\t{%2, %0|%0, %2}"
5058   [(set_attr "type" "sseiadd")
5059    (set_attr "prefix_data16" "1")
5060    (set_attr "mode" "TI")])
5061
5062 (define_insn "sse2_uavgv8hi3"
5063   [(set (match_operand:V8HI 0 "register_operand" "=x")
5064         (truncate:V8HI
5065           (lshiftrt:V8SI
5066             (plus:V8SI
5067               (plus:V8SI
5068                 (zero_extend:V8SI
5069                   (match_operand:V8HI 1 "nonimmediate_operand" "%0"))
5070                 (zero_extend:V8SI
5071                   (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
5072               (const_vector:V8HI [(const_int 1) (const_int 1)
5073                                   (const_int 1) (const_int 1)
5074                                   (const_int 1) (const_int 1)
5075                                   (const_int 1) (const_int 1)]))
5076             (const_int 1))))]
5077   "TARGET_SSE2 && ix86_binary_operator_ok (PLUS, V8HImode, operands)"
5078   "pavgw\t{%2, %0|%0, %2}"
5079   [(set_attr "type" "sseiadd")
5080    (set_attr "prefix_data16" "1")
5081    (set_attr "mode" "TI")])
5082
5083 ;; The correct representation for this is absolutely enormous, and
5084 ;; surely not generally useful.
5085 (define_insn "sse2_psadbw"
5086   [(set (match_operand:V2DI 0 "register_operand" "=x")
5087         (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
5088                       (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
5089                      UNSPEC_PSADBW))]
5090   "TARGET_SSE2"
5091   "psadbw\t{%2, %0|%0, %2}"
5092   [(set_attr "type" "sseiadd")
5093    (set_attr "prefix_data16" "1")
5094    (set_attr "mode" "TI")])
5095
5096 (define_insn "<sse>_movmskp<ssemodesuffixf2c>"
5097   [(set (match_operand:SI 0 "register_operand" "=r")
5098         (unspec:SI
5099           [(match_operand:SSEMODEF2P 1 "register_operand" "x")]
5100           UNSPEC_MOVMSK))]
5101   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
5102   "movmskp<ssemodesuffixf2c>\t{%1, %0|%0, %1}"
5103   [(set_attr "type" "ssecvt")
5104    (set_attr "mode" "<MODE>")])
5105
5106 (define_insn "sse2_pmovmskb"
5107   [(set (match_operand:SI 0 "register_operand" "=r")
5108         (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
5109                    UNSPEC_MOVMSK))]
5110   "TARGET_SSE2"
5111   "pmovmskb\t{%1, %0|%0, %1}"
5112   [(set_attr "type" "ssecvt")
5113    (set_attr "prefix_data16" "1")
5114    (set_attr "mode" "SI")])
5115
5116 (define_expand "sse2_maskmovdqu"
5117   [(set (match_operand:V16QI 0 "memory_operand" "")
5118         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "")
5119                        (match_operand:V16QI 2 "register_operand" "")
5120                        (match_dup 0)]
5121                       UNSPEC_MASKMOV))]
5122   "TARGET_SSE2"
5123   "")
5124
5125 (define_insn "*sse2_maskmovdqu"
5126   [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
5127         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
5128                        (match_operand:V16QI 2 "register_operand" "x")
5129                        (mem:V16QI (match_dup 0))]
5130                       UNSPEC_MASKMOV))]
5131   "TARGET_SSE2 && !TARGET_64BIT"
5132   ;; @@@ check ordering of operands in intel/nonintel syntax
5133   "maskmovdqu\t{%2, %1|%1, %2}"
5134   [(set_attr "type" "ssecvt")
5135    (set_attr "prefix_data16" "1")
5136    (set_attr "mode" "TI")])
5137
5138 (define_insn "*sse2_maskmovdqu_rex64"
5139   [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
5140         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
5141                        (match_operand:V16QI 2 "register_operand" "x")
5142                        (mem:V16QI (match_dup 0))]
5143                       UNSPEC_MASKMOV))]
5144   "TARGET_SSE2 && TARGET_64BIT"
5145   ;; @@@ check ordering of operands in intel/nonintel syntax
5146   "maskmovdqu\t{%2, %1|%1, %2}"
5147   [(set_attr "type" "ssecvt")
5148    (set_attr "prefix_data16" "1")
5149    (set_attr "mode" "TI")])
5150
5151 (define_insn "sse_ldmxcsr"
5152   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
5153                     UNSPECV_LDMXCSR)]
5154   "TARGET_SSE"
5155   "ldmxcsr\t%0"
5156   [(set_attr "type" "sse")
5157    (set_attr "memory" "load")])
5158
5159 (define_insn "sse_stmxcsr"
5160   [(set (match_operand:SI 0 "memory_operand" "=m")
5161         (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
5162   "TARGET_SSE"
5163   "stmxcsr\t%0"
5164   [(set_attr "type" "sse")
5165    (set_attr "memory" "store")])
5166
5167 (define_expand "sse_sfence"
5168   [(set (match_dup 0)
5169         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
5170   "TARGET_SSE || TARGET_3DNOW_A"
5171 {
5172   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
5173   MEM_VOLATILE_P (operands[0]) = 1;
5174 })
5175
5176 (define_insn "*sse_sfence"
5177   [(set (match_operand:BLK 0 "" "")
5178         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
5179   "TARGET_SSE || TARGET_3DNOW_A"
5180   "sfence"
5181   [(set_attr "type" "sse")
5182    (set_attr "memory" "unknown")])
5183
5184 (define_insn "sse2_clflush"
5185   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
5186                     UNSPECV_CLFLUSH)]
5187   "TARGET_SSE2"
5188   "clflush\t%a0"
5189   [(set_attr "type" "sse")
5190    (set_attr "memory" "unknown")])
5191
5192 (define_expand "sse2_mfence"
5193   [(set (match_dup 0)
5194         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
5195   "TARGET_SSE2"
5196 {
5197   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
5198   MEM_VOLATILE_P (operands[0]) = 1;
5199 })
5200
5201 (define_insn "*sse2_mfence"
5202   [(set (match_operand:BLK 0 "" "")
5203         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
5204   "TARGET_SSE2"
5205   "mfence"
5206   [(set_attr "type" "sse")
5207    (set_attr "memory" "unknown")])
5208
5209 (define_expand "sse2_lfence"
5210   [(set (match_dup 0)
5211         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
5212   "TARGET_SSE2"
5213 {
5214   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
5215   MEM_VOLATILE_P (operands[0]) = 1;
5216 })
5217
5218 (define_insn "*sse2_lfence"
5219   [(set (match_operand:BLK 0 "" "")
5220         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
5221   "TARGET_SSE2"
5222   "lfence"
5223   [(set_attr "type" "sse")
5224    (set_attr "memory" "unknown")])
5225
5226 (define_insn "sse3_mwait"
5227   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
5228                      (match_operand:SI 1 "register_operand" "c")]
5229                     UNSPECV_MWAIT)]
5230   "TARGET_SSE3"
5231 ;; 64bit version is "mwait %rax,%rcx". But only lower 32bits are used.
5232 ;; Since 32bit register operands are implicitly zero extended to 64bit,
5233 ;; we only need to set up 32bit registers.
5234   "mwait"
5235   [(set_attr "length" "3")])
5236
5237 (define_insn "sse3_monitor"
5238   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
5239                      (match_operand:SI 1 "register_operand" "c")
5240                      (match_operand:SI 2 "register_operand" "d")]
5241                     UNSPECV_MONITOR)]
5242   "TARGET_SSE3 && !TARGET_64BIT"
5243   "monitor\t%0, %1, %2"
5244   [(set_attr "length" "3")])
5245
5246 (define_insn "sse3_monitor64"
5247   [(unspec_volatile [(match_operand:DI 0 "register_operand" "a")
5248                      (match_operand:SI 1 "register_operand" "c")
5249                      (match_operand:SI 2 "register_operand" "d")]
5250                     UNSPECV_MONITOR)]
5251   "TARGET_SSE3 && TARGET_64BIT"
5252 ;; 64bit version is "monitor %rax,%rcx,%rdx". But only lower 32bits in
5253 ;; RCX and RDX are used.  Since 32bit register operands are implicitly
5254 ;; zero extended to 64bit, we only need to set up 32bit registers.
5255   "monitor"
5256   [(set_attr "length" "3")])
5257
5258 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5259 ;;
5260 ;; SSSE3 instructions
5261 ;;
5262 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5263
5264 (define_insn "ssse3_phaddwv8hi3"
5265   [(set (match_operand:V8HI 0 "register_operand" "=x")
5266         (vec_concat:V8HI
5267           (vec_concat:V4HI
5268             (vec_concat:V2HI
5269               (plus:HI
5270                 (vec_select:HI
5271                   (match_operand:V8HI 1 "register_operand" "0")
5272                   (parallel [(const_int 0)]))
5273                 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
5274               (plus:HI
5275                 (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
5276                 (vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
5277             (vec_concat:V2HI
5278               (plus:HI
5279                 (vec_select:HI (match_dup 1) (parallel [(const_int 4)]))
5280                 (vec_select:HI (match_dup 1) (parallel [(const_int 5)])))
5281               (plus:HI
5282                 (vec_select:HI (match_dup 1) (parallel [(const_int 6)]))
5283                 (vec_select:HI (match_dup 1) (parallel [(const_int 7)])))))
5284           (vec_concat:V4HI
5285             (vec_concat:V2HI
5286               (plus:HI
5287                 (vec_select:HI
5288                   (match_operand:V8HI 2 "nonimmediate_operand" "xm")
5289                   (parallel [(const_int 0)]))
5290                 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
5291               (plus:HI
5292                 (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
5293                 (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))
5294             (vec_concat:V2HI
5295               (plus:HI
5296                 (vec_select:HI (match_dup 2) (parallel [(const_int 4)]))
5297                 (vec_select:HI (match_dup 2) (parallel [(const_int 5)])))
5298               (plus:HI
5299                 (vec_select:HI (match_dup 2) (parallel [(const_int 6)]))
5300                 (vec_select:HI (match_dup 2) (parallel [(const_int 7)])))))))]
5301   "TARGET_SSSE3"
5302   "phaddw\t{%2, %0|%0, %2}"
5303   [(set_attr "type" "sseiadd")
5304    (set_attr "prefix_data16" "1")
5305    (set_attr "prefix_extra" "1")
5306    (set_attr "mode" "TI")])
5307
5308 (define_insn "ssse3_phaddwv4hi3"
5309   [(set (match_operand:V4HI 0 "register_operand" "=y")
5310         (vec_concat:V4HI
5311           (vec_concat:V2HI
5312             (plus:HI
5313               (vec_select:HI
5314                 (match_operand:V4HI 1 "register_operand" "0")
5315                 (parallel [(const_int 0)]))
5316               (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
5317             (plus:HI
5318               (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
5319               (vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
5320           (vec_concat:V2HI
5321             (plus:HI
5322               (vec_select:HI
5323                 (match_operand:V4HI 2 "nonimmediate_operand" "ym")
5324                 (parallel [(const_int 0)]))
5325               (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
5326             (plus:HI
5327               (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
5328               (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))))]
5329   "TARGET_SSSE3"
5330   "phaddw\t{%2, %0|%0, %2}"
5331   [(set_attr "type" "sseiadd")
5332    (set_attr "prefix_extra" "1")
5333    (set_attr "mode" "DI")])
5334
5335 (define_insn "ssse3_phadddv4si3"
5336   [(set (match_operand:V4SI 0 "register_operand" "=x")
5337         (vec_concat:V4SI
5338           (vec_concat:V2SI
5339             (plus:SI
5340               (vec_select:SI
5341                 (match_operand:V4SI 1 "register_operand" "0")
5342                 (parallel [(const_int 0)]))
5343               (vec_select:SI (match_dup 1) (parallel [(const_int 1)])))
5344             (plus:SI
5345               (vec_select:SI (match_dup 1) (parallel [(const_int 2)]))
5346               (vec_select:SI (match_dup 1) (parallel [(const_int 3)]))))
5347           (vec_concat:V2SI
5348             (plus:SI
5349               (vec_select:SI
5350                 (match_operand:V4SI 2 "nonimmediate_operand" "xm")
5351                 (parallel [(const_int 0)]))
5352               (vec_select:SI (match_dup 2) (parallel [(const_int 1)])))
5353             (plus:SI
5354               (vec_select:SI (match_dup 2) (parallel [(const_int 2)]))
5355               (vec_select:SI (match_dup 2) (parallel [(const_int 3)]))))))]
5356   "TARGET_SSSE3"
5357   "phaddd\t{%2, %0|%0, %2}"
5358   [(set_attr "type" "sseiadd")
5359    (set_attr "prefix_data16" "1")
5360    (set_attr "prefix_extra" "1")
5361    (set_attr "mode" "TI")])
5362
5363 (define_insn "ssse3_phadddv2si3"
5364   [(set (match_operand:V2SI 0 "register_operand" "=y")
5365         (vec_concat:V2SI
5366           (plus:SI
5367             (vec_select:SI
5368               (match_operand:V2SI 1 "register_operand" "0")
5369               (parallel [(const_int 0)]))
5370             (vec_select:SI (match_dup 1) (parallel [(const_int 1)])))
5371           (plus:SI
5372             (vec_select:SI
5373               (match_operand:V2SI 2 "nonimmediate_operand" "ym")
5374               (parallel [(const_int 0)]))
5375             (vec_select:SI (match_dup 2) (parallel [(const_int 1)])))))]
5376   "TARGET_SSSE3"
5377   "phaddd\t{%2, %0|%0, %2}"
5378   [(set_attr "type" "sseiadd")
5379    (set_attr "prefix_extra" "1")
5380    (set_attr "mode" "DI")])
5381
5382 (define_insn "ssse3_phaddswv8hi3"
5383   [(set (match_operand:V8HI 0 "register_operand" "=x")
5384         (vec_concat:V8HI
5385           (vec_concat:V4HI
5386             (vec_concat:V2HI
5387               (ss_plus:HI
5388                 (vec_select:HI
5389                   (match_operand:V8HI 1 "register_operand" "0")
5390                   (parallel [(const_int 0)]))
5391                 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
5392               (ss_plus:HI
5393                 (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
5394                 (vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
5395             (vec_concat:V2HI
5396               (ss_plus:HI
5397                 (vec_select:HI (match_dup 1) (parallel [(const_int 4)]))
5398                 (vec_select:HI (match_dup 1) (parallel [(const_int 5)])))
5399               (ss_plus:HI
5400                 (vec_select:HI (match_dup 1) (parallel [(const_int 6)]))
5401                 (vec_select:HI (match_dup 1) (parallel [(const_int 7)])))))
5402           (vec_concat:V4HI
5403             (vec_concat:V2HI
5404               (ss_plus:HI
5405                 (vec_select:HI
5406                   (match_operand:V8HI 2 "nonimmediate_operand" "xm")
5407                   (parallel [(const_int 0)]))
5408                 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
5409               (ss_plus:HI
5410                 (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
5411                 (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))
5412             (vec_concat:V2HI
5413               (ss_plus:HI
5414                 (vec_select:HI (match_dup 2) (parallel [(const_int 4)]))
5415                 (vec_select:HI (match_dup 2) (parallel [(const_int 5)])))
5416               (ss_plus:HI
5417                 (vec_select:HI (match_dup 2) (parallel [(const_int 6)]))
5418                 (vec_select:HI (match_dup 2) (parallel [(const_int 7)])))))))]
5419   "TARGET_SSSE3"
5420   "phaddsw\t{%2, %0|%0, %2}"
5421   [(set_attr "type" "sseiadd")
5422    (set_attr "prefix_data16" "1")
5423    (set_attr "prefix_extra" "1")
5424    (set_attr "mode" "TI")])
5425
5426 (define_insn "ssse3_phaddswv4hi3"
5427   [(set (match_operand:V4HI 0 "register_operand" "=y")
5428         (vec_concat:V4HI
5429           (vec_concat:V2HI
5430             (ss_plus:HI
5431               (vec_select:HI
5432                 (match_operand:V4HI 1 "register_operand" "0")
5433                 (parallel [(const_int 0)]))
5434               (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
5435             (ss_plus:HI
5436               (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
5437               (vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
5438           (vec_concat:V2HI
5439             (ss_plus:HI
5440               (vec_select:HI
5441                 (match_operand:V4HI 2 "nonimmediate_operand" "ym")
5442                 (parallel [(const_int 0)]))
5443               (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
5444             (ss_plus:HI
5445               (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
5446               (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))))]
5447   "TARGET_SSSE3"
5448   "phaddsw\t{%2, %0|%0, %2}"
5449   [(set_attr "type" "sseiadd")
5450    (set_attr "prefix_extra" "1")
5451    (set_attr "mode" "DI")])
5452
5453 (define_insn "ssse3_phsubwv8hi3"
5454   [(set (match_operand:V8HI 0 "register_operand" "=x")
5455         (vec_concat:V8HI
5456           (vec_concat:V4HI
5457             (vec_concat:V2HI
5458               (minus:HI
5459                 (vec_select:HI
5460                   (match_operand:V8HI 1 "register_operand" "0")
5461                   (parallel [(const_int 0)]))
5462                 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
5463               (minus:HI
5464                 (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
5465                 (vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
5466             (vec_concat:V2HI
5467               (minus:HI
5468                 (vec_select:HI (match_dup 1) (parallel [(const_int 4)]))
5469                 (vec_select:HI (match_dup 1) (parallel [(const_int 5)])))
5470               (minus:HI
5471                 (vec_select:HI (match_dup 1) (parallel [(const_int 6)]))
5472                 (vec_select:HI (match_dup 1) (parallel [(const_int 7)])))))
5473           (vec_concat:V4HI
5474             (vec_concat:V2HI
5475               (minus:HI
5476                 (vec_select:HI
5477                   (match_operand:V8HI 2 "nonimmediate_operand" "xm")
5478                   (parallel [(const_int 0)]))
5479                 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
5480               (minus:HI
5481                 (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
5482                 (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))
5483             (vec_concat:V2HI
5484               (minus:HI
5485                 (vec_select:HI (match_dup 2) (parallel [(const_int 4)]))
5486                 (vec_select:HI (match_dup 2) (parallel [(const_int 5)])))
5487               (minus:HI
5488                 (vec_select:HI (match_dup 2) (parallel [(const_int 6)]))
5489                 (vec_select:HI (match_dup 2) (parallel [(const_int 7)])))))))]
5490   "TARGET_SSSE3"
5491   "phsubw\t{%2, %0|%0, %2}"
5492   [(set_attr "type" "sseiadd")
5493    (set_attr "prefix_data16" "1")
5494    (set_attr "prefix_extra" "1")
5495    (set_attr "mode" "TI")])
5496
5497 (define_insn "ssse3_phsubwv4hi3"
5498   [(set (match_operand:V4HI 0 "register_operand" "=y")
5499         (vec_concat:V4HI
5500           (vec_concat:V2HI
5501             (minus:HI
5502               (vec_select:HI
5503                 (match_operand:V4HI 1 "register_operand" "0")
5504                 (parallel [(const_int 0)]))
5505               (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
5506             (minus:HI
5507               (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
5508               (vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
5509           (vec_concat:V2HI
5510             (minus:HI
5511               (vec_select:HI
5512                 (match_operand:V4HI 2 "nonimmediate_operand" "ym")
5513                 (parallel [(const_int 0)]))
5514               (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
5515             (minus:HI
5516               (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
5517               (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))))]
5518   "TARGET_SSSE3"
5519   "phsubw\t{%2, %0|%0, %2}"
5520   [(set_attr "type" "sseiadd")
5521    (set_attr "prefix_extra" "1")
5522    (set_attr "mode" "DI")])
5523
5524 (define_insn "ssse3_phsubdv4si3"
5525   [(set (match_operand:V4SI 0 "register_operand" "=x")
5526         (vec_concat:V4SI
5527           (vec_concat:V2SI
5528             (minus:SI
5529               (vec_select:SI
5530                 (match_operand:V4SI 1 "register_operand" "0")
5531                 (parallel [(const_int 0)]))
5532               (vec_select:SI (match_dup 1) (parallel [(const_int 1)])))
5533             (minus:SI
5534               (vec_select:SI (match_dup 1) (parallel [(const_int 2)]))
5535               (vec_select:SI (match_dup 1) (parallel [(const_int 3)]))))
5536           (vec_concat:V2SI
5537             (minus:SI
5538               (vec_select:SI
5539                 (match_operand:V4SI 2 "nonimmediate_operand" "xm")
5540                 (parallel [(const_int 0)]))
5541               (vec_select:SI (match_dup 2) (parallel [(const_int 1)])))
5542             (minus:SI
5543               (vec_select:SI (match_dup 2) (parallel [(const_int 2)]))
5544               (vec_select:SI (match_dup 2) (parallel [(const_int 3)]))))))]
5545   "TARGET_SSSE3"
5546   "phsubd\t{%2, %0|%0, %2}"
5547   [(set_attr "type" "sseiadd")
5548    (set_attr "prefix_data16" "1")
5549    (set_attr "prefix_extra" "1")
5550    (set_attr "mode" "TI")])
5551
5552 (define_insn "ssse3_phsubdv2si3"
5553   [(set (match_operand:V2SI 0 "register_operand" "=y")
5554         (vec_concat:V2SI
5555           (minus:SI
5556             (vec_select:SI
5557               (match_operand:V2SI 1 "register_operand" "0")
5558               (parallel [(const_int 0)]))
5559             (vec_select:SI (match_dup 1) (parallel [(const_int 1)])))
5560           (minus:SI
5561             (vec_select:SI
5562               (match_operand:V2SI 2 "nonimmediate_operand" "ym")
5563               (parallel [(const_int 0)]))
5564             (vec_select:SI (match_dup 2) (parallel [(const_int 1)])))))]
5565   "TARGET_SSSE3"
5566   "phsubd\t{%2, %0|%0, %2}"
5567   [(set_attr "type" "sseiadd")
5568    (set_attr "prefix_extra" "1")
5569    (set_attr "mode" "DI")])
5570
5571 (define_insn "ssse3_phsubswv8hi3"
5572   [(set (match_operand:V8HI 0 "register_operand" "=x")
5573         (vec_concat:V8HI
5574           (vec_concat:V4HI
5575             (vec_concat:V2HI
5576               (ss_minus:HI
5577                 (vec_select:HI
5578                   (match_operand:V8HI 1 "register_operand" "0")
5579                   (parallel [(const_int 0)]))
5580                 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
5581               (ss_minus:HI
5582                 (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
5583                 (vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
5584             (vec_concat:V2HI
5585               (ss_minus:HI
5586                 (vec_select:HI (match_dup 1) (parallel [(const_int 4)]))
5587                 (vec_select:HI (match_dup 1) (parallel [(const_int 5)])))
5588               (ss_minus:HI
5589                 (vec_select:HI (match_dup 1) (parallel [(const_int 6)]))
5590                 (vec_select:HI (match_dup 1) (parallel [(const_int 7)])))))
5591           (vec_concat:V4HI
5592             (vec_concat:V2HI
5593               (ss_minus:HI
5594                 (vec_select:HI
5595                   (match_operand:V8HI 2 "nonimmediate_operand" "xm")
5596                   (parallel [(const_int 0)]))
5597                 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
5598               (ss_minus:HI
5599                 (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
5600                 (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))
5601             (vec_concat:V2HI
5602               (ss_minus:HI
5603                 (vec_select:HI (match_dup 2) (parallel [(const_int 4)]))
5604                 (vec_select:HI (match_dup 2) (parallel [(const_int 5)])))
5605               (ss_minus:HI
5606                 (vec_select:HI (match_dup 2) (parallel [(const_int 6)]))
5607                 (vec_select:HI (match_dup 2) (parallel [(const_int 7)])))))))]
5608   "TARGET_SSSE3"
5609   "phsubsw\t{%2, %0|%0, %2}"
5610   [(set_attr "type" "sseiadd")
5611    (set_attr "prefix_data16" "1")
5612    (set_attr "prefix_extra" "1")
5613    (set_attr "mode" "TI")])
5614
5615 (define_insn "ssse3_phsubswv4hi3"
5616   [(set (match_operand:V4HI 0 "register_operand" "=y")
5617         (vec_concat:V4HI
5618           (vec_concat:V2HI
5619             (ss_minus:HI
5620               (vec_select:HI
5621                 (match_operand:V4HI 1 "register_operand" "0")
5622                 (parallel [(const_int 0)]))
5623               (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
5624             (ss_minus:HI
5625               (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
5626               (vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
5627           (vec_concat:V2HI
5628             (ss_minus:HI
5629               (vec_select:HI
5630                 (match_operand:V4HI 2 "nonimmediate_operand" "ym")
5631                 (parallel [(const_int 0)]))
5632               (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
5633             (ss_minus:HI
5634               (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
5635               (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))))]
5636   "TARGET_SSSE3"
5637   "phsubsw\t{%2, %0|%0, %2}"
5638   [(set_attr "type" "sseiadd")
5639    (set_attr "prefix_extra" "1")
5640    (set_attr "mode" "DI")])
5641
5642 (define_insn "ssse3_pmaddubswv8hi3"
5643   [(set (match_operand:V8HI 0 "register_operand" "=x")
5644         (ss_plus:V8HI
5645           (mult:V8HI
5646             (zero_extend:V8HI
5647               (vec_select:V4QI
5648                 (match_operand:V16QI 1 "nonimmediate_operand" "0")
5649                 (parallel [(const_int 0)
5650                            (const_int 2)
5651                            (const_int 4)
5652                            (const_int 6)
5653                            (const_int 8)
5654                            (const_int 10)
5655                            (const_int 12)
5656                            (const_int 14)])))
5657             (sign_extend:V8HI
5658               (vec_select:V8QI
5659                 (match_operand:V16QI 2 "nonimmediate_operand" "xm")
5660                 (parallel [(const_int 0)
5661                            (const_int 2)
5662                            (const_int 4)
5663                            (const_int 6)
5664                            (const_int 8)
5665                            (const_int 10)
5666                            (const_int 12)
5667                            (const_int 14)]))))
5668           (mult:V8HI
5669             (zero_extend:V8HI
5670               (vec_select:V16QI (match_dup 1)
5671                 (parallel [(const_int 1)
5672                            (const_int 3)
5673                            (const_int 5)
5674                            (const_int 7)
5675                            (const_int 9)
5676                            (const_int 11)
5677                            (const_int 13)
5678                            (const_int 15)])))
5679             (sign_extend:V8HI
5680               (vec_select:V16QI (match_dup 2)
5681                 (parallel [(const_int 1)
5682                            (const_int 3)
5683                            (const_int 5)
5684                            (const_int 7)
5685                            (const_int 9)
5686                            (const_int 11)
5687                            (const_int 13)
5688                            (const_int 15)]))))))]
5689   "TARGET_SSSE3"
5690   "pmaddubsw\t{%2, %0|%0, %2}"
5691   [(set_attr "type" "sseiadd")
5692    (set_attr "prefix_data16" "1")
5693    (set_attr "prefix_extra" "1")
5694    (set_attr "mode" "TI")])
5695
5696 (define_insn "ssse3_pmaddubswv4hi3"
5697   [(set (match_operand:V4HI 0 "register_operand" "=y")
5698         (ss_plus:V4HI
5699           (mult:V4HI
5700             (zero_extend:V4HI
5701               (vec_select:V4QI
5702                 (match_operand:V8QI 1 "nonimmediate_operand" "0")
5703                 (parallel [(const_int 0)
5704                            (const_int 2)
5705                            (const_int 4)
5706                            (const_int 6)])))
5707             (sign_extend:V4HI
5708               (vec_select:V4QI
5709                 (match_operand:V8QI 2 "nonimmediate_operand" "ym")
5710                 (parallel [(const_int 0)
5711                            (const_int 2)
5712                            (const_int 4)
5713                            (const_int 6)]))))
5714           (mult:V4HI
5715             (zero_extend:V4HI
5716               (vec_select:V8QI (match_dup 1)
5717                 (parallel [(const_int 1)
5718                            (const_int 3)
5719                            (const_int 5)
5720                            (const_int 7)])))
5721             (sign_extend:V4HI
5722               (vec_select:V8QI (match_dup 2)
5723                 (parallel [(const_int 1)
5724                            (const_int 3)
5725                            (const_int 5)
5726                            (const_int 7)]))))))]
5727   "TARGET_SSSE3"
5728   "pmaddubsw\t{%2, %0|%0, %2}"
5729   [(set_attr "type" "sseiadd")
5730    (set_attr "prefix_extra" "1")
5731    (set_attr "mode" "DI")])
5732
5733 (define_insn "ssse3_pmulhrswv8hi3"
5734   [(set (match_operand:V8HI 0 "register_operand" "=x")
5735         (truncate:V8HI
5736           (lshiftrt:V8SI
5737             (plus:V8SI
5738               (lshiftrt:V8SI
5739                 (mult:V8SI
5740                   (sign_extend:V8SI
5741                     (match_operand:V8HI 1 "nonimmediate_operand" "%0"))
5742                   (sign_extend:V8SI
5743                     (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
5744                 (const_int 14))
5745               (const_vector:V8HI [(const_int 1) (const_int 1)
5746                                   (const_int 1) (const_int 1)
5747                                   (const_int 1) (const_int 1)
5748                                   (const_int 1) (const_int 1)]))
5749             (const_int 1))))]
5750   "TARGET_SSSE3 && ix86_binary_operator_ok (MULT, V8HImode, operands)"
5751   "pmulhrsw\t{%2, %0|%0, %2}"
5752   [(set_attr "type" "sseimul")
5753    (set_attr "prefix_data16" "1")
5754    (set_attr "prefix_extra" "1")
5755    (set_attr "mode" "TI")])
5756
5757 (define_insn "ssse3_pmulhrswv4hi3"
5758   [(set (match_operand:V4HI 0 "register_operand" "=y")
5759         (truncate:V4HI
5760           (lshiftrt:V4SI
5761             (plus:V4SI
5762               (lshiftrt:V4SI
5763                 (mult:V4SI
5764                   (sign_extend:V4SI
5765                     (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
5766                   (sign_extend:V4SI
5767                     (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
5768                 (const_int 14))
5769               (const_vector:V4HI [(const_int 1) (const_int 1)
5770                                   (const_int 1) (const_int 1)]))
5771             (const_int 1))))]
5772   "TARGET_SSSE3 && ix86_binary_operator_ok (MULT, V4HImode, operands)"
5773   "pmulhrsw\t{%2, %0|%0, %2}"
5774   [(set_attr "type" "sseimul")
5775    (set_attr "prefix_extra" "1")
5776    (set_attr "mode" "DI")])
5777
5778 (define_insn "ssse3_pshufbv16qi3"
5779   [(set (match_operand:V16QI 0 "register_operand" "=x")
5780         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "0")
5781                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
5782                       UNSPEC_PSHUFB))]
5783   "TARGET_SSSE3"
5784   "pshufb\t{%2, %0|%0, %2}";
5785   [(set_attr "type" "sselog1")
5786    (set_attr "prefix_data16" "1")
5787    (set_attr "prefix_extra" "1")
5788    (set_attr "mode" "TI")])
5789
5790 (define_insn "ssse3_pshufbv8qi3"
5791   [(set (match_operand:V8QI 0 "register_operand" "=y")
5792         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "0")
5793                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
5794                      UNSPEC_PSHUFB))]
5795   "TARGET_SSSE3"
5796   "pshufb\t{%2, %0|%0, %2}";
5797   [(set_attr "type" "sselog1")
5798    (set_attr "prefix_extra" "1")
5799    (set_attr "mode" "DI")])
5800
5801 (define_insn "ssse3_psign<mode>3"
5802   [(set (match_operand:SSEMODE124 0 "register_operand" "=x")
5803         (unspec:SSEMODE124
5804           [(match_operand:SSEMODE124 1 "register_operand" "0")
5805            (match_operand:SSEMODE124 2 "nonimmediate_operand" "xm")]
5806           UNSPEC_PSIGN))]
5807   "TARGET_SSSE3"
5808   "psign<ssevecsize>\t{%2, %0|%0, %2}";
5809   [(set_attr "type" "sselog1")
5810    (set_attr "prefix_data16" "1")
5811    (set_attr "prefix_extra" "1")
5812    (set_attr "mode" "TI")])
5813
5814 (define_insn "ssse3_psign<mode>3"
5815   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
5816         (unspec:MMXMODEI
5817           [(match_operand:MMXMODEI 1 "register_operand" "0")
5818            (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")]
5819           UNSPEC_PSIGN))]
5820   "TARGET_SSSE3"
5821   "psign<mmxvecsize>\t{%2, %0|%0, %2}";
5822   [(set_attr "type" "sselog1")
5823    (set_attr "prefix_extra" "1")
5824    (set_attr "mode" "DI")])
5825
5826 (define_insn "ssse3_palignrti"
5827   [(set (match_operand:TI 0 "register_operand" "=x")
5828         (unspec:TI [(match_operand:TI 1 "register_operand" "0")
5829                     (match_operand:TI 2 "nonimmediate_operand" "xm")
5830                     (match_operand:SI 3 "const_0_to_255_mul_8_operand" "n")]
5831                    UNSPEC_PALIGNR))]
5832   "TARGET_SSSE3"
5833 {
5834   operands[3] = GEN_INT (INTVAL (operands[3]) / 8);
5835   return "palignr\t{%3, %2, %0|%0, %2, %3}";
5836 }
5837   [(set_attr "type" "sseishft")
5838    (set_attr "prefix_data16" "1")
5839    (set_attr "prefix_extra" "1")
5840    (set_attr "mode" "TI")])
5841
5842 (define_insn "ssse3_palignrdi"
5843   [(set (match_operand:DI 0 "register_operand" "=y")
5844         (unspec:DI [(match_operand:DI 1 "register_operand" "0")
5845                     (match_operand:DI 2 "nonimmediate_operand" "ym")
5846                     (match_operand:SI 3 "const_0_to_255_mul_8_operand" "n")]
5847                    UNSPEC_PALIGNR))]
5848   "TARGET_SSSE3"
5849 {
5850   operands[3] = GEN_INT (INTVAL (operands[3]) / 8);
5851   return "palignr\t{%3, %2, %0|%0, %2, %3}";
5852 }
5853   [(set_attr "type" "sseishft")
5854    (set_attr "prefix_extra" "1")
5855    (set_attr "mode" "DI")])
5856
5857 (define_insn "abs<mode>2"
5858   [(set (match_operand:SSEMODE124 0 "register_operand" "=x")
5859         (abs:SSEMODE124 (match_operand:SSEMODE124 1 "nonimmediate_operand" "xm")))]
5860   "TARGET_SSSE3"
5861   "pabs<ssevecsize>\t{%1, %0|%0, %1}";
5862   [(set_attr "type" "sselog1")
5863    (set_attr "prefix_data16" "1")
5864    (set_attr "prefix_extra" "1")
5865    (set_attr "mode" "TI")])
5866
5867 (define_insn "abs<mode>2"
5868   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
5869         (abs:MMXMODEI (match_operand:MMXMODEI 1 "nonimmediate_operand" "ym")))]
5870   "TARGET_SSSE3"
5871   "pabs<mmxvecsize>\t{%1, %0|%0, %1}";
5872   [(set_attr "type" "sselog1")
5873    (set_attr "prefix_extra" "1")
5874    (set_attr "mode" "DI")])
5875
5876 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5877 ;;
5878 ;; AMD SSE4A instructions
5879 ;;
5880 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5881
5882 (define_insn "sse4a_movnt<mode>"
5883   [(set (match_operand:MODEF 0 "memory_operand" "=m")
5884         (unspec:MODEF
5885           [(match_operand:MODEF 1 "register_operand" "x")]
5886           UNSPEC_MOVNT))]
5887   "TARGET_SSE4A"
5888   "movnts<ssemodefsuffix>\t{%1, %0|%0, %1}"
5889   [(set_attr "type" "ssemov")
5890    (set_attr "mode" "<MODE>")])
5891
5892 (define_insn "sse4a_vmmovnt<mode>"
5893   [(set (match_operand:<ssescalarmode> 0 "memory_operand" "=m")
5894         (unspec:<ssescalarmode>
5895           [(vec_select:<ssescalarmode>
5896              (match_operand:SSEMODEF2P 1 "register_operand" "x")
5897              (parallel [(const_int 0)]))]
5898           UNSPEC_MOVNT))]
5899   "TARGET_SSE4A"
5900   "movnts<ssemodesuffixf2c>\t{%1, %0|%0, %1}"
5901   [(set_attr "type" "ssemov")
5902    (set_attr "mode" "<ssescalarmode>")])
5903
5904 (define_insn "sse4a_extrqi"
5905   [(set (match_operand:V2DI 0 "register_operand" "=x")
5906         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0")
5907                       (match_operand 2 "const_int_operand" "")
5908                       (match_operand 3 "const_int_operand" "")]
5909                      UNSPEC_EXTRQI))]
5910   "TARGET_SSE4A"
5911   "extrq\t{%3, %2, %0|%0, %2, %3}"
5912   [(set_attr "type" "sse")
5913    (set_attr "prefix_data16" "1")
5914    (set_attr "mode" "TI")])
5915
5916 (define_insn "sse4a_extrq"
5917   [(set (match_operand:V2DI 0 "register_operand" "=x")
5918         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0")
5919                       (match_operand:V16QI 2 "register_operand" "x")]
5920                      UNSPEC_EXTRQ))]
5921   "TARGET_SSE4A"
5922   "extrq\t{%2, %0|%0, %2}"
5923   [(set_attr "type" "sse")
5924    (set_attr "prefix_data16" "1")
5925    (set_attr "mode" "TI")])
5926
5927 (define_insn "sse4a_insertqi"
5928   [(set (match_operand:V2DI 0 "register_operand" "=x")
5929         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0")
5930                       (match_operand:V2DI 2 "register_operand" "x")
5931                       (match_operand 3 "const_int_operand" "")
5932                       (match_operand 4 "const_int_operand" "")]
5933                      UNSPEC_INSERTQI))]
5934   "TARGET_SSE4A"
5935   "insertq\t{%4, %3, %2, %0|%0, %2, %3, %4}"
5936   [(set_attr "type" "sseins")
5937    (set_attr "prefix_rep" "1")
5938    (set_attr "mode" "TI")])
5939
5940 (define_insn "sse4a_insertq"
5941   [(set (match_operand:V2DI 0 "register_operand" "=x")
5942         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0")
5943                       (match_operand:V2DI 2 "register_operand" "x")]
5944                      UNSPEC_INSERTQ))]
5945   "TARGET_SSE4A"
5946   "insertq\t{%2, %0|%0, %2}"
5947   [(set_attr "type" "sseins")
5948    (set_attr "prefix_rep" "1")
5949    (set_attr "mode" "TI")])
5950
5951 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5952 ;;
5953 ;; Intel SSE4.1 instructions
5954 ;;
5955 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5956
5957 (define_insn "sse4_1_blendp<ssemodesuffixf2c>"
5958   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
5959         (vec_merge:SSEMODEF2P
5960           (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")
5961           (match_operand:SSEMODEF2P 1 "register_operand" "0")
5962           (match_operand:SI 3 "const_0_to_<blendbits>_operand" "n")))]
5963   "TARGET_SSE4_1"
5964   "blendp<ssemodesuffixf2c>\t{%3, %2, %0|%0, %2, %3}"
5965   [(set_attr "type" "ssemov")
5966    (set_attr "prefix_extra" "1")
5967    (set_attr "mode" "<MODE>")])
5968
5969 (define_insn "sse4_1_blendvp<ssemodesuffixf2c>"
5970   [(set (match_operand:SSEMODEF2P 0 "reg_not_xmm0_operand" "=x")
5971         (unspec:SSEMODEF2P
5972           [(match_operand:SSEMODEF2P 1 "reg_not_xmm0_operand" "0")
5973            (match_operand:SSEMODEF2P 2 "nonimm_not_xmm0_operand" "xm")
5974            (match_operand:SSEMODEF2P 3 "register_operand" "Yz")]
5975           UNSPEC_BLENDV))]
5976   "TARGET_SSE4_1"
5977   "blendvp<ssemodesuffixf2c>\t{%3, %2, %0|%0, %2, %3}"
5978   [(set_attr "type" "ssemov")
5979    (set_attr "prefix_extra" "1")
5980    (set_attr "mode" "<MODE>")])
5981
5982 (define_insn "sse4_1_dpp<ssemodesuffixf2c>"
5983   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
5984         (unspec:SSEMODEF2P
5985           [(match_operand:SSEMODEF2P 1 "nonimmediate_operand" "%0")
5986            (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")
5987            (match_operand:SI 3 "const_0_to_255_operand" "n")]
5988           UNSPEC_DP))]
5989   "TARGET_SSE4_1"
5990   "dpp<ssemodesuffixf2c>\t{%3, %2, %0|%0, %2, %3}"
5991   [(set_attr "type" "ssemul")
5992    (set_attr "prefix_extra" "1")
5993    (set_attr "mode" "<MODE>")])
5994
5995 (define_insn "sse4_1_movntdqa"
5996   [(set (match_operand:V2DI 0 "register_operand" "=x")
5997         (unspec:V2DI [(match_operand:V2DI 1 "memory_operand" "m")]
5998                      UNSPEC_MOVNTDQA))]
5999   "TARGET_SSE4_1"
6000   "movntdqa\t{%1, %0|%0, %1}"
6001   [(set_attr "type" "ssecvt")
6002    (set_attr "prefix_extra" "1")
6003    (set_attr "mode" "TI")])
6004
6005 (define_insn "sse4_1_mpsadbw"
6006   [(set (match_operand:V16QI 0 "register_operand" "=x")
6007         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "0")
6008                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")
6009                        (match_operand:SI 3 "const_0_to_255_operand" "n")]
6010                       UNSPEC_MPSADBW))]
6011   "TARGET_SSE4_1"
6012   "mpsadbw\t{%3, %2, %0|%0, %2, %3}"
6013   [(set_attr "type" "sselog1")
6014    (set_attr "prefix_extra" "1")
6015    (set_attr "mode" "TI")])
6016
6017 (define_insn "sse4_1_packusdw"
6018   [(set (match_operand:V8HI 0 "register_operand" "=x")
6019         (vec_concat:V8HI
6020           (us_truncate:V4HI
6021             (match_operand:V4SI 1 "register_operand" "0"))
6022           (us_truncate:V4HI
6023             (match_operand:V4SI 2 "nonimmediate_operand" "xm"))))]
6024   "TARGET_SSE4_1"
6025   "packusdw\t{%2, %0|%0, %2}"
6026   [(set_attr "type" "sselog")
6027    (set_attr "prefix_extra" "1")
6028    (set_attr "mode" "TI")])
6029
6030 (define_insn "sse4_1_pblendvb"
6031   [(set (match_operand:V16QI 0 "reg_not_xmm0_operand" "=x")
6032         (unspec:V16QI [(match_operand:V16QI 1 "reg_not_xmm0_operand"  "0")
6033                        (match_operand:V16QI 2 "nonimm_not_xmm0_operand" "xm")
6034                        (match_operand:V16QI 3 "register_operand" "Yz")]
6035                       UNSPEC_BLENDV))]
6036   "TARGET_SSE4_1"
6037   "pblendvb\t{%3, %2, %0|%0, %2, %3}"
6038   [(set_attr "type" "ssemov")
6039    (set_attr "prefix_extra" "1")
6040    (set_attr "mode" "TI")])
6041
6042 (define_insn "sse4_1_pblendw"
6043   [(set (match_operand:V8HI 0 "register_operand" "=x")
6044         (vec_merge:V8HI
6045           (match_operand:V8HI 2 "nonimmediate_operand" "xm")
6046           (match_operand:V8HI 1 "register_operand" "0")
6047           (match_operand:SI 3 "const_0_to_255_operand" "n")))]
6048   "TARGET_SSE4_1"
6049   "pblendw\t{%3, %2, %0|%0, %2, %3}"
6050   [(set_attr "type" "ssemov")
6051    (set_attr "prefix_extra" "1")
6052    (set_attr "mode" "TI")])
6053
6054 (define_insn "sse4_1_phminposuw"
6055   [(set (match_operand:V8HI 0 "register_operand" "=x")
6056         (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")]
6057                      UNSPEC_PHMINPOSUW))]
6058   "TARGET_SSE4_1"
6059   "phminposuw\t{%1, %0|%0, %1}"
6060   [(set_attr "type" "sselog1")
6061    (set_attr "prefix_extra" "1")
6062    (set_attr "mode" "TI")])
6063
6064 (define_insn "sse4_1_extendv8qiv8hi2"
6065   [(set (match_operand:V8HI 0 "register_operand" "=x")
6066         (sign_extend:V8HI
6067           (vec_select:V8QI
6068             (match_operand:V16QI 1 "register_operand" "x")
6069             (parallel [(const_int 0)
6070                        (const_int 1)
6071                        (const_int 2)
6072                        (const_int 3)
6073                        (const_int 4)
6074                        (const_int 5)
6075                        (const_int 6)
6076                        (const_int 7)]))))]
6077   "TARGET_SSE4_1"
6078   "pmovsxbw\t{%1, %0|%0, %1}"
6079   [(set_attr "type" "ssemov")
6080    (set_attr "prefix_extra" "1")
6081    (set_attr "mode" "TI")])
6082
6083 (define_insn "*sse4_1_extendv8qiv8hi2"
6084   [(set (match_operand:V8HI 0 "register_operand" "=x")
6085         (sign_extend:V8HI
6086           (vec_select:V8QI
6087             (vec_duplicate:V16QI
6088               (match_operand:V8QI 1 "nonimmediate_operand" "xm"))
6089             (parallel [(const_int 0)
6090                        (const_int 1)
6091                        (const_int 2)
6092                        (const_int 3)
6093                        (const_int 4)
6094                        (const_int 5)
6095                        (const_int 6)
6096                        (const_int 7)]))))]
6097   "TARGET_SSE4_1"
6098   "pmovsxbw\t{%1, %0|%0, %1}"
6099   [(set_attr "type" "ssemov")
6100    (set_attr "prefix_extra" "1")
6101    (set_attr "mode" "TI")])
6102
6103 (define_insn "sse4_1_extendv4qiv4si2"
6104   [(set (match_operand:V4SI 0 "register_operand" "=x")
6105         (sign_extend:V4SI
6106           (vec_select:V4QI
6107             (match_operand:V16QI 1 "register_operand" "x")
6108             (parallel [(const_int 0)
6109                        (const_int 1)
6110                        (const_int 2)
6111                        (const_int 3)]))))]
6112   "TARGET_SSE4_1"
6113   "pmovsxbd\t{%1, %0|%0, %1}"
6114   [(set_attr "type" "ssemov")
6115    (set_attr "prefix_extra" "1")
6116    (set_attr "mode" "TI")])
6117
6118 (define_insn "*sse4_1_extendv4qiv4si2"
6119   [(set (match_operand:V4SI 0 "register_operand" "=x")
6120         (sign_extend:V4SI
6121           (vec_select:V4QI
6122             (vec_duplicate:V16QI
6123               (match_operand:V4QI 1 "nonimmediate_operand" "xm"))
6124             (parallel [(const_int 0)
6125                        (const_int 1)
6126                        (const_int 2)
6127                        (const_int 3)]))))]
6128   "TARGET_SSE4_1"
6129   "pmovsxbd\t{%1, %0|%0, %1}"
6130   [(set_attr "type" "ssemov")
6131    (set_attr "prefix_extra" "1")
6132    (set_attr "mode" "TI")])
6133
6134 (define_insn "sse4_1_extendv2qiv2di2"
6135   [(set (match_operand:V2DI 0 "register_operand" "=x")
6136         (sign_extend:V2DI
6137           (vec_select:V2QI
6138             (match_operand:V16QI 1 "register_operand" "x")
6139             (parallel [(const_int 0)
6140                        (const_int 1)]))))]
6141   "TARGET_SSE4_1"
6142   "pmovsxbq\t{%1, %0|%0, %1}"
6143   [(set_attr "type" "ssemov")
6144    (set_attr "prefix_extra" "1")
6145    (set_attr "mode" "TI")])
6146
6147 (define_insn "*sse4_1_extendv2qiv2di2"
6148   [(set (match_operand:V2DI 0 "register_operand" "=x")
6149         (sign_extend:V2DI
6150           (vec_select:V2QI
6151             (vec_duplicate:V16QI
6152               (match_operand:V2QI 1 "nonimmediate_operand" "xm"))
6153             (parallel [(const_int 0)
6154                        (const_int 1)]))))]
6155   "TARGET_SSE4_1"
6156   "pmovsxbq\t{%1, %0|%0, %1}"
6157   [(set_attr "type" "ssemov")
6158    (set_attr "prefix_extra" "1")
6159    (set_attr "mode" "TI")])
6160
6161 (define_insn "sse4_1_extendv4hiv4si2"
6162   [(set (match_operand:V4SI 0 "register_operand" "=x")
6163         (sign_extend:V4SI
6164           (vec_select:V4HI
6165             (match_operand:V8HI 1 "register_operand" "x")
6166             (parallel [(const_int 0)
6167                        (const_int 1)
6168                        (const_int 2)
6169                        (const_int 3)]))))]
6170   "TARGET_SSE4_1"
6171   "pmovsxwd\t{%1, %0|%0, %1}"
6172   [(set_attr "type" "ssemov")
6173    (set_attr "prefix_extra" "1")
6174    (set_attr "mode" "TI")])
6175
6176 (define_insn "*sse4_1_extendv4hiv4si2"
6177   [(set (match_operand:V4SI 0 "register_operand" "=x")
6178         (sign_extend:V4SI
6179           (vec_select:V4HI
6180             (vec_duplicate:V8HI
6181               (match_operand:V2HI 1 "nonimmediate_operand" "xm"))
6182             (parallel [(const_int 0)
6183                        (const_int 1)
6184                        (const_int 2)
6185                        (const_int 3)]))))]
6186   "TARGET_SSE4_1"
6187   "pmovsxwd\t{%1, %0|%0, %1}"
6188   [(set_attr "type" "ssemov")
6189    (set_attr "prefix_extra" "1")
6190    (set_attr "mode" "TI")])
6191
6192 (define_insn "sse4_1_extendv2hiv2di2"
6193   [(set (match_operand:V2DI 0 "register_operand" "=x")
6194         (sign_extend:V2DI
6195           (vec_select:V2HI
6196             (match_operand:V8HI 1 "register_operand" "x")
6197             (parallel [(const_int 0)
6198                        (const_int 1)]))))]
6199   "TARGET_SSE4_1"
6200   "pmovsxwq\t{%1, %0|%0, %1}"
6201   [(set_attr "type" "ssemov")
6202    (set_attr "prefix_extra" "1")
6203    (set_attr "mode" "TI")])
6204
6205 (define_insn "*sse4_1_extendv2hiv2di2"
6206   [(set (match_operand:V2DI 0 "register_operand" "=x")
6207         (sign_extend:V2DI
6208           (vec_select:V2HI
6209             (vec_duplicate:V8HI
6210               (match_operand:V8HI 1 "nonimmediate_operand" "xm"))
6211             (parallel [(const_int 0)
6212                        (const_int 1)]))))]
6213   "TARGET_SSE4_1"
6214   "pmovsxwq\t{%1, %0|%0, %1}"
6215   [(set_attr "type" "ssemov")
6216    (set_attr "prefix_extra" "1")
6217    (set_attr "mode" "TI")])
6218
6219 (define_insn "sse4_1_extendv2siv2di2"
6220   [(set (match_operand:V2DI 0 "register_operand" "=x")
6221         (sign_extend:V2DI
6222           (vec_select:V2SI
6223             (match_operand:V4SI 1 "register_operand" "x")
6224             (parallel [(const_int 0)
6225                        (const_int 1)]))))]
6226   "TARGET_SSE4_1"
6227   "pmovsxdq\t{%1, %0|%0, %1}"
6228   [(set_attr "type" "ssemov")
6229    (set_attr "prefix_extra" "1")
6230    (set_attr "mode" "TI")])
6231
6232 (define_insn "*sse4_1_extendv2siv2di2"
6233   [(set (match_operand:V2DI 0 "register_operand" "=x")
6234         (sign_extend:V2DI
6235           (vec_select:V2SI
6236             (vec_duplicate:V4SI
6237               (match_operand:V2SI 1 "nonimmediate_operand" "xm"))
6238             (parallel [(const_int 0)
6239                        (const_int 1)]))))]
6240   "TARGET_SSE4_1"
6241   "pmovsxdq\t{%1, %0|%0, %1}"
6242   [(set_attr "type" "ssemov")
6243    (set_attr "prefix_extra" "1")
6244    (set_attr "mode" "TI")])
6245
6246 (define_insn "sse4_1_zero_extendv8qiv8hi2"
6247   [(set (match_operand:V8HI 0 "register_operand" "=x")
6248         (zero_extend:V8HI
6249           (vec_select:V8QI
6250             (match_operand:V16QI 1 "register_operand" "x")
6251             (parallel [(const_int 0)
6252                        (const_int 1)
6253                        (const_int 2)
6254                        (const_int 3)
6255                        (const_int 4)
6256                        (const_int 5)
6257                        (const_int 6)
6258                        (const_int 7)]))))]
6259   "TARGET_SSE4_1"
6260   "pmovzxbw\t{%1, %0|%0, %1}"
6261   [(set_attr "type" "ssemov")
6262    (set_attr "prefix_extra" "1")
6263    (set_attr "mode" "TI")])
6264
6265 (define_insn "*sse4_1_zero_extendv8qiv8hi2"
6266   [(set (match_operand:V8HI 0 "register_operand" "=x")
6267         (zero_extend:V8HI
6268           (vec_select:V8QI
6269             (vec_duplicate:V16QI
6270               (match_operand:V8QI 1 "nonimmediate_operand" "xm"))
6271             (parallel [(const_int 0)
6272                        (const_int 1)
6273                        (const_int 2)
6274                        (const_int 3)
6275                        (const_int 4)
6276                        (const_int 5)
6277                        (const_int 6)
6278                        (const_int 7)]))))]
6279   "TARGET_SSE4_1"
6280   "pmovzxbw\t{%1, %0|%0, %1}"
6281   [(set_attr "type" "ssemov")
6282    (set_attr "prefix_extra" "1")
6283    (set_attr "mode" "TI")])
6284
6285 (define_insn "sse4_1_zero_extendv4qiv4si2"
6286   [(set (match_operand:V4SI 0 "register_operand" "=x")
6287         (zero_extend:V4SI
6288           (vec_select:V4QI
6289             (match_operand:V16QI 1 "register_operand" "x")
6290             (parallel [(const_int 0)
6291                        (const_int 1)
6292                        (const_int 2)
6293                        (const_int 3)]))))]
6294   "TARGET_SSE4_1"
6295   "pmovzxbd\t{%1, %0|%0, %1}"
6296   [(set_attr "type" "ssemov")
6297    (set_attr "prefix_extra" "1")
6298    (set_attr "mode" "TI")])
6299
6300 (define_insn "*sse4_1_zero_extendv4qiv4si2"
6301   [(set (match_operand:V4SI 0 "register_operand" "=x")
6302         (zero_extend:V4SI
6303           (vec_select:V4QI
6304             (vec_duplicate:V16QI
6305               (match_operand:V4QI 1 "nonimmediate_operand" "xm"))
6306             (parallel [(const_int 0)
6307                        (const_int 1)
6308                        (const_int 2)
6309                        (const_int 3)]))))]
6310   "TARGET_SSE4_1"
6311   "pmovzxbd\t{%1, %0|%0, %1}"
6312   [(set_attr "type" "ssemov")
6313    (set_attr "prefix_extra" "1")
6314    (set_attr "mode" "TI")])
6315
6316 (define_insn "sse4_1_zero_extendv2qiv2di2"
6317   [(set (match_operand:V2DI 0 "register_operand" "=x")
6318         (zero_extend:V2DI
6319           (vec_select:V2QI
6320             (match_operand:V16QI 1 "register_operand" "x")
6321             (parallel [(const_int 0)
6322                        (const_int 1)]))))]
6323   "TARGET_SSE4_1"
6324   "pmovzxbq\t{%1, %0|%0, %1}"
6325   [(set_attr "type" "ssemov")
6326    (set_attr "prefix_extra" "1")
6327    (set_attr "mode" "TI")])
6328
6329 (define_insn "*sse4_1_zero_extendv2qiv2di2"
6330   [(set (match_operand:V2DI 0 "register_operand" "=x")
6331         (zero_extend:V2DI
6332           (vec_select:V2QI
6333             (vec_duplicate:V16QI
6334               (match_operand:V2QI 1 "nonimmediate_operand" "xm"))
6335             (parallel [(const_int 0)
6336                        (const_int 1)]))))]
6337   "TARGET_SSE4_1"
6338   "pmovzxbq\t{%1, %0|%0, %1}"
6339   [(set_attr "type" "ssemov")
6340    (set_attr "prefix_extra" "1")
6341    (set_attr "mode" "TI")])
6342
6343 (define_insn "sse4_1_zero_extendv4hiv4si2"
6344   [(set (match_operand:V4SI 0 "register_operand" "=x")
6345         (zero_extend:V4SI
6346           (vec_select:V4HI
6347             (match_operand:V8HI 1 "register_operand" "x")
6348             (parallel [(const_int 0)
6349                        (const_int 1)
6350                        (const_int 2)
6351                        (const_int 3)]))))]
6352   "TARGET_SSE4_1"
6353   "pmovzxwd\t{%1, %0|%0, %1}"
6354   [(set_attr "type" "ssemov")
6355    (set_attr "prefix_extra" "1")
6356    (set_attr "mode" "TI")])
6357
6358 (define_insn "*sse4_1_zero_extendv4hiv4si2"
6359   [(set (match_operand:V4SI 0 "register_operand" "=x")
6360         (zero_extend:V4SI
6361           (vec_select:V4HI
6362             (vec_duplicate:V8HI
6363               (match_operand:V4HI 1 "nonimmediate_operand" "xm"))
6364             (parallel [(const_int 0)
6365                        (const_int 1)
6366                        (const_int 2)
6367                        (const_int 3)]))))]
6368   "TARGET_SSE4_1"
6369   "pmovzxwd\t{%1, %0|%0, %1}"
6370   [(set_attr "type" "ssemov")
6371    (set_attr "prefix_extra" "1")
6372    (set_attr "mode" "TI")])
6373
6374 (define_insn "sse4_1_zero_extendv2hiv2di2"
6375   [(set (match_operand:V2DI 0 "register_operand" "=x")
6376         (zero_extend:V2DI
6377           (vec_select:V2HI
6378             (match_operand:V8HI 1 "register_operand" "x")
6379             (parallel [(const_int 0)
6380                        (const_int 1)]))))]
6381   "TARGET_SSE4_1"
6382   "pmovzxwq\t{%1, %0|%0, %1}"
6383   [(set_attr "type" "ssemov")
6384    (set_attr "prefix_extra" "1")
6385    (set_attr "mode" "TI")])
6386
6387 (define_insn "*sse4_1_zero_extendv2hiv2di2"
6388   [(set (match_operand:V2DI 0 "register_operand" "=x")
6389         (zero_extend:V2DI
6390           (vec_select:V2HI
6391             (vec_duplicate:V8HI
6392               (match_operand:V2HI 1 "nonimmediate_operand" "xm"))
6393             (parallel [(const_int 0)
6394                        (const_int 1)]))))]
6395   "TARGET_SSE4_1"
6396   "pmovzxwq\t{%1, %0|%0, %1}"
6397   [(set_attr "type" "ssemov")
6398    (set_attr "prefix_extra" "1")
6399    (set_attr "mode" "TI")])
6400
6401 (define_insn "sse4_1_zero_extendv2siv2di2"
6402   [(set (match_operand:V2DI 0 "register_operand" "=x")
6403         (zero_extend:V2DI
6404           (vec_select:V2SI
6405             (match_operand:V4SI 1 "register_operand" "x")
6406             (parallel [(const_int 0)
6407                        (const_int 1)]))))]
6408   "TARGET_SSE4_1"
6409   "pmovzxdq\t{%1, %0|%0, %1}"
6410   [(set_attr "type" "ssemov")
6411    (set_attr "prefix_extra" "1")
6412    (set_attr "mode" "TI")])
6413
6414 (define_insn "*sse4_1_zero_extendv2siv2di2"
6415   [(set (match_operand:V2DI 0 "register_operand" "=x")
6416         (zero_extend:V2DI
6417           (vec_select:V2SI
6418             (vec_duplicate:V4SI
6419               (match_operand:V2SI 1 "nonimmediate_operand" "xm"))
6420             (parallel [(const_int 0)
6421                        (const_int 1)]))))]
6422   "TARGET_SSE4_1"
6423   "pmovzxdq\t{%1, %0|%0, %1}"
6424   [(set_attr "type" "ssemov")
6425    (set_attr "prefix_extra" "1")
6426    (set_attr "mode" "TI")])
6427
6428 ;; ptest is very similar to comiss and ucomiss when setting FLAGS_REG.
6429 ;; But it is not a really compare instruction.
6430 (define_insn "sse4_1_ptest"
6431   [(set (reg:CC FLAGS_REG)
6432         (unspec:CC [(match_operand:V2DI 0 "register_operand" "x")
6433                     (match_operand:V2DI 1 "nonimmediate_operand" "xm")]
6434                    UNSPEC_PTEST))]
6435   "TARGET_SSE4_1"
6436   "ptest\t{%1, %0|%0, %1}"
6437   [(set_attr "type" "ssecomi")
6438    (set_attr "prefix_extra" "1")
6439    (set_attr "mode" "TI")])
6440
6441 (define_insn "sse4_1_roundp<ssemodesuffixf2c>"
6442   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
6443         (unspec:SSEMODEF2P
6444           [(match_operand:SSEMODEF2P 1 "nonimmediate_operand" "xm")
6445            (match_operand:SI 2 "const_0_to_15_operand" "n")]
6446           UNSPEC_ROUND))]
6447   "TARGET_ROUND"
6448   "roundp<ssemodesuffixf2c>\t{%2, %1, %0|%0, %1, %2}"
6449   [(set_attr "type" "ssecvt")
6450    (set_attr "prefix_extra" "1")
6451    (set_attr "mode" "<MODE>")])
6452
6453 (define_insn "sse4_1_rounds<ssemodesuffixf2c>"
6454   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
6455         (vec_merge:SSEMODEF2P
6456           (unspec:SSEMODEF2P
6457             [(match_operand:SSEMODEF2P 2 "register_operand" "x")
6458              (match_operand:SI 3 "const_0_to_15_operand" "n")]
6459             UNSPEC_ROUND)
6460           (match_operand:SSEMODEF2P 1 "register_operand" "0")
6461           (const_int 1)))]
6462   "TARGET_ROUND"
6463   "rounds<ssemodesuffixf2c>\t{%3, %2, %0|%0, %2, %3}"
6464   [(set_attr "type" "ssecvt")
6465    (set_attr "prefix_extra" "1")
6466    (set_attr "mode" "<MODE>")])
6467
6468 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6469 ;;
6470 ;; Intel SSE4.2 string/text processing instructions
6471 ;;
6472 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6473
6474 (define_insn_and_split "sse4_2_pcmpestr"
6475   [(set (match_operand:SI 0 "register_operand" "=c,c")
6476         (unspec:SI
6477           [(match_operand:V16QI 2 "reg_not_xmm0_operand" "x,x")
6478            (match_operand:SI 3 "register_operand" "a,a")
6479            (match_operand:V16QI 4 "nonimm_not_xmm0_operand" "x,m")
6480            (match_operand:SI 5 "register_operand" "d,d")
6481            (match_operand:SI 6 "const_0_to_255_operand" "n,n")]
6482           UNSPEC_PCMPESTR))
6483    (set (match_operand:V16QI 1 "register_operand" "=Yz,Yz")
6484         (unspec:V16QI
6485           [(match_dup 2)
6486            (match_dup 3)
6487            (match_dup 4)
6488            (match_dup 5)
6489            (match_dup 6)]
6490           UNSPEC_PCMPESTR))
6491    (set (reg:CC FLAGS_REG)
6492         (unspec:CC
6493           [(match_dup 2)
6494            (match_dup 3)
6495            (match_dup 4)
6496            (match_dup 5)
6497            (match_dup 6)]
6498           UNSPEC_PCMPESTR))]
6499   "TARGET_SSE4_2
6500    && !(reload_completed || reload_in_progress)"
6501   "#"
6502   "&& 1"
6503   [(const_int 0)]
6504 {
6505   int ecx = !find_regno_note (curr_insn, REG_UNUSED, REGNO (operands[0]));
6506   int xmm0 = !find_regno_note (curr_insn, REG_UNUSED, REGNO (operands[1]));
6507   int flags = !find_regno_note (curr_insn, REG_UNUSED, FLAGS_REG);
6508
6509   if (ecx)
6510     emit_insn (gen_sse4_2_pcmpestri (operands[0], operands[2],
6511                                      operands[3], operands[4],
6512                                      operands[5], operands[6]));
6513   if (xmm0)
6514     emit_insn (gen_sse4_2_pcmpestrm (operands[1], operands[2],
6515                                      operands[3], operands[4],
6516                                      operands[5], operands[6]));
6517   if (flags && !(ecx || xmm0))
6518     emit_insn (gen_sse4_2_pcmpestr_cconly (NULL, NULL,
6519                                            operands[2], operands[3],
6520                                            operands[4], operands[5],
6521                                            operands[6]));
6522   DONE;
6523 }
6524   [(set_attr "type" "sselog")
6525    (set_attr "prefix_data16" "1")
6526    (set_attr "prefix_extra" "1")
6527    (set_attr "memory" "none,load")
6528    (set_attr "mode" "TI")])
6529
6530 (define_insn "sse4_2_pcmpestri"
6531   [(set (match_operand:SI 0 "register_operand" "=c,c")
6532         (unspec:SI
6533           [(match_operand:V16QI 1 "register_operand" "x,x")
6534            (match_operand:SI 2 "register_operand" "a,a")
6535            (match_operand:V16QI 3 "nonimmediate_operand" "x,m")
6536            (match_operand:SI 4 "register_operand" "d,d")
6537            (match_operand:SI 5 "const_0_to_255_operand" "n,n")]
6538           UNSPEC_PCMPESTR))
6539    (set (reg:CC FLAGS_REG)
6540         (unspec:CC
6541           [(match_dup 1)
6542            (match_dup 2)
6543            (match_dup 3)
6544            (match_dup 4)
6545            (match_dup 5)]
6546           UNSPEC_PCMPESTR))]
6547   "TARGET_SSE4_2"
6548   "pcmpestri\t{%5, %3, %1|%1, %3, %5}"
6549   [(set_attr "type" "sselog")
6550    (set_attr "prefix_data16" "1")
6551    (set_attr "prefix_extra" "1")
6552    (set_attr "memory" "none,load")
6553    (set_attr "mode" "TI")])
6554
6555 (define_insn "sse4_2_pcmpestrm"
6556   [(set (match_operand:V16QI 0 "register_operand" "=Yz,Yz")
6557         (unspec:V16QI
6558           [(match_operand:V16QI 1 "register_operand" "x,x")
6559            (match_operand:SI 2 "register_operand" "a,a")
6560            (match_operand:V16QI 3 "nonimmediate_operand" "x,m")
6561            (match_operand:SI 4 "register_operand" "d,d")
6562            (match_operand:SI 5 "const_0_to_255_operand" "n,n")]
6563           UNSPEC_PCMPESTR))
6564    (set (reg:CC FLAGS_REG)
6565         (unspec:CC
6566           [(match_dup 1)
6567            (match_dup 2)
6568            (match_dup 3)
6569            (match_dup 4)
6570            (match_dup 5)]
6571           UNSPEC_PCMPESTR))]
6572   "TARGET_SSE4_2"
6573   "pcmpestrm\t{%5, %3, %1|%1, %3, %5}"
6574   [(set_attr "type" "sselog")
6575    (set_attr "prefix_data16" "1")
6576    (set_attr "prefix_extra" "1")
6577    (set_attr "memory" "none,load")
6578    (set_attr "mode" "TI")])
6579
6580 (define_insn "sse4_2_pcmpestr_cconly"
6581   [(set (reg:CC FLAGS_REG)
6582         (unspec:CC
6583           [(match_operand:V16QI 2 "register_operand" "x,x,x,x")
6584            (match_operand:SI 3 "register_operand" "a,a,a,a")
6585            (match_operand:V16QI 4 "nonimmediate_operand" "x,m,x,m")
6586            (match_operand:SI 5 "register_operand" "d,d,d,d")
6587            (match_operand:SI 6 "const_0_to_255_operand" "n,n,n,n")]
6588           UNSPEC_PCMPESTR))
6589    (clobber (match_scratch:V16QI 0 "=Yz,Yz,X,X"))
6590    (clobber (match_scratch:SI    1 "= X, X,c,c"))]
6591   "TARGET_SSE4_2"
6592   "@
6593    pcmpestrm\t{%6, %4, %2|%2, %4, %6}
6594    pcmpestrm\t{%6, %4, %2|%2, %4, %6}
6595    pcmpestri\t{%6, %4, %2|%2, %4, %6}
6596    pcmpestri\t{%6, %4, %2|%2, %4, %6}"
6597   [(set_attr "type" "sselog")
6598    (set_attr "prefix_data16" "1")
6599    (set_attr "prefix_extra" "1")
6600    (set_attr "memory" "none,load,none,load")
6601    (set_attr "mode" "TI")])
6602
6603 (define_insn_and_split "sse4_2_pcmpistr"
6604   [(set (match_operand:SI 0 "register_operand" "=c,c")
6605         (unspec:SI
6606           [(match_operand:V16QI 2 "reg_not_xmm0_operand" "x,x")
6607            (match_operand:V16QI 3 "nonimm_not_xmm0_operand" "x,m")
6608            (match_operand:SI 4 "const_0_to_255_operand" "n,n")]
6609           UNSPEC_PCMPISTR))
6610    (set (match_operand:V16QI 1 "register_operand" "=Yz,Yz")
6611         (unspec:V16QI
6612           [(match_dup 2)
6613            (match_dup 3)
6614            (match_dup 4)]
6615           UNSPEC_PCMPISTR))
6616    (set (reg:CC FLAGS_REG)
6617         (unspec:CC
6618           [(match_dup 2)
6619            (match_dup 3)
6620            (match_dup 4)]
6621           UNSPEC_PCMPISTR))]
6622   "TARGET_SSE4_2
6623    && !(reload_completed || reload_in_progress)"
6624   "#"
6625   "&& 1"
6626   [(const_int 0)]
6627 {
6628   int ecx = !find_regno_note (curr_insn, REG_UNUSED, REGNO (operands[0]));
6629   int xmm0 = !find_regno_note (curr_insn, REG_UNUSED, REGNO (operands[1]));
6630   int flags = !find_regno_note (curr_insn, REG_UNUSED, FLAGS_REG);
6631
6632   if (ecx)
6633     emit_insn (gen_sse4_2_pcmpistri (operands[0], operands[2],
6634                                      operands[3], operands[4]));
6635   if (xmm0)
6636     emit_insn (gen_sse4_2_pcmpistrm (operands[1], operands[2],
6637                                      operands[3], operands[4]));
6638   if (flags && !(ecx || xmm0))
6639     emit_insn (gen_sse4_2_pcmpistr_cconly (NULL, NULL,
6640                                            operands[2], operands[3],
6641                                            operands[4]));
6642   DONE;
6643 }
6644   [(set_attr "type" "sselog")
6645    (set_attr "prefix_data16" "1")
6646    (set_attr "prefix_extra" "1")
6647    (set_attr "memory" "none,load")
6648    (set_attr "mode" "TI")])
6649
6650 (define_insn "sse4_2_pcmpistri"
6651   [(set (match_operand:SI 0 "register_operand" "=c,c")
6652         (unspec:SI
6653           [(match_operand:V16QI 1 "register_operand" "x,x")
6654            (match_operand:V16QI 2 "nonimmediate_operand" "x,m")
6655            (match_operand:SI 3 "const_0_to_255_operand" "n,n")]
6656           UNSPEC_PCMPISTR))
6657    (set (reg:CC FLAGS_REG)
6658         (unspec:CC
6659           [(match_dup 1)
6660            (match_dup 2)
6661            (match_dup 3)]
6662           UNSPEC_PCMPISTR))]
6663   "TARGET_SSE4_2"
6664   "pcmpistri\t{%3, %2, %1|%1, %2, %3}"
6665   [(set_attr "type" "sselog")
6666    (set_attr "prefix_data16" "1")
6667    (set_attr "prefix_extra" "1")
6668    (set_attr "memory" "none,load")
6669    (set_attr "mode" "TI")])
6670
6671 (define_insn "sse4_2_pcmpistrm"
6672   [(set (match_operand:V16QI 0 "register_operand" "=Yz,Yz")
6673         (unspec:V16QI
6674           [(match_operand:V16QI 1 "register_operand" "x,x")
6675            (match_operand:V16QI 2 "nonimmediate_operand" "x,m")
6676            (match_operand:SI 3 "const_0_to_255_operand" "n,n")]
6677           UNSPEC_PCMPISTR))
6678    (set (reg:CC FLAGS_REG)
6679         (unspec:CC
6680           [(match_dup 1)
6681            (match_dup 2)
6682            (match_dup 3)]
6683           UNSPEC_PCMPISTR))]
6684   "TARGET_SSE4_2"
6685   "pcmpistrm\t{%3, %2, %1|%1, %2, %3}"
6686   [(set_attr "type" "sselog")
6687    (set_attr "prefix_data16" "1")
6688    (set_attr "prefix_extra" "1")
6689    (set_attr "memory" "none,load")
6690    (set_attr "mode" "TI")])
6691
6692 (define_insn "sse4_2_pcmpistr_cconly"
6693   [(set (reg:CC FLAGS_REG)
6694         (unspec:CC
6695           [(match_operand:V16QI 2 "register_operand" "x,x,x,x")
6696            (match_operand:V16QI 3 "nonimmediate_operand" "x,m,x,m")
6697            (match_operand:SI 4 "const_0_to_255_operand" "n,n,n,n")]
6698           UNSPEC_PCMPISTR))
6699    (clobber (match_scratch:V16QI 0 "=Yz,Yz,X,X"))
6700    (clobber (match_scratch:SI    1 "= X, X,c,c"))]
6701   "TARGET_SSE4_2"
6702   "@
6703    pcmpistrm\t{%4, %3, %2|%2, %3, %4}
6704    pcmpistrm\t{%4, %3, %2|%2, %3, %4}
6705    pcmpistri\t{%4, %3, %2|%2, %3, %4}
6706    pcmpistri\t{%4, %3, %2|%2, %3, %4}"
6707   [(set_attr "type" "sselog")
6708    (set_attr "prefix_data16" "1")
6709    (set_attr "prefix_extra" "1")
6710    (set_attr "memory" "none,load,none,load")
6711    (set_attr "mode" "TI")])
6712
6713 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6714 ;;
6715 ;; SSE5 instructions
6716 ;;
6717 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6718
6719 ;; SSE5 parallel integer multiply/add instructions.
6720 ;; Note the instruction does not allow the value being added to be a memory
6721 ;; operation.  However by pretending via the nonimmediate_operand predicate
6722 ;; that it does and splitting it later allows the following to be recognized:
6723 ;;      a[i] = b[i] * c[i] + d[i];
6724 (define_insn "sse5_pmacsww"
6725   [(set (match_operand:V8HI 0 "register_operand" "=x,x,x")
6726         (plus:V8HI
6727          (mult:V8HI
6728           (match_operand:V8HI 1 "nonimmediate_operand" "%x,x,m")
6729           (match_operand:V8HI 2 "nonimmediate_operand" "x,m,x"))
6730          (match_operand:V8HI 3 "nonimmediate_operand" "0,0,0")))]
6731   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 2)"
6732   "@
6733    pmacsww\t{%3, %2, %1, %0|%0, %1, %2, %3}
6734    pmacsww\t{%3, %2, %1, %0|%0, %1, %2, %3}
6735    pmacsww\t{%3, %1, %2, %0|%0, %2, %1, %3}"
6736   [(set_attr "type" "ssemuladd")
6737    (set_attr "mode" "TI")])
6738
6739 ;; Split pmacsww with two memory operands into a load and the pmacsww.
6740 (define_split
6741   [(set (match_operand:V8HI 0 "register_operand" "")
6742         (plus:V8HI
6743          (mult:V8HI (match_operand:V8HI 1 "nonimmediate_operand" "")
6744                     (match_operand:V8HI 2 "nonimmediate_operand" ""))
6745          (match_operand:V8HI 3 "nonimmediate_operand" "")))]
6746   "TARGET_SSE5
6747    && !ix86_sse5_valid_op_p (operands, insn, 4, false, 1)
6748    && ix86_sse5_valid_op_p (operands, insn, 4, false, 2)
6749    && !reg_mentioned_p (operands[0], operands[1])
6750    && !reg_mentioned_p (operands[0], operands[2])
6751    && !reg_mentioned_p (operands[0], operands[3])"
6752   [(const_int 0)]
6753 {
6754   ix86_expand_sse5_multiple_memory (operands, 4, V8HImode);
6755   emit_insn (gen_sse5_pmacsww (operands[0], operands[1], operands[2],
6756                                operands[3]));
6757   DONE;
6758 })
6759
6760 (define_insn "sse5_pmacssww"
6761   [(set (match_operand:V8HI 0 "register_operand" "=x,x,x")
6762         (ss_plus:V8HI
6763          (mult:V8HI (match_operand:V8HI 1 "nonimmediate_operand" "%x,x,m")
6764                     (match_operand:V8HI 2 "nonimmediate_operand" "x,m,x"))
6765          (match_operand:V8HI 3 "nonimmediate_operand" "0,0,0")))]
6766   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1)"
6767   "@
6768    pmacssww\t{%3, %2, %1, %0|%0, %1, %2, %3}
6769    pmacssww\t{%3, %2, %1, %0|%0, %1, %2, %3}
6770    pmacssww\t{%3, %1, %2, %0|%0, %2, %1, %3}"
6771   [(set_attr "type" "ssemuladd")
6772    (set_attr "mode" "TI")])
6773
6774 ;; Note the instruction does not allow the value being added to be a memory
6775 ;; operation.  However by pretending via the nonimmediate_operand predicate
6776 ;; that it does and splitting it later allows the following to be recognized:
6777 ;;      a[i] = b[i] * c[i] + d[i];
6778 (define_insn "sse5_pmacsdd"
6779   [(set (match_operand:V4SI 0 "register_operand" "=x,x,x")
6780         (plus:V4SI
6781          (mult:V4SI
6782           (match_operand:V4SI 1 "nonimmediate_operand" "%x,x,m")
6783           (match_operand:V4SI 2 "nonimmediate_operand" "x,m,x"))
6784          (match_operand:V4SI 3 "nonimmediate_operand" "0,0,0")))]
6785   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 2)"
6786   "@
6787    pmacsdd\t{%3, %2, %1, %0|%0, %1, %2, %3}
6788    pmacsdd\t{%3, %2, %1, %0|%0, %1, %2, %3}
6789    pmacsdd\t{%3, %1, %2, %0|%0, %2, %1, %3}"
6790   [(set_attr "type" "ssemuladd")
6791    (set_attr "mode" "TI")])
6792
6793 ;; Split pmacsdd with two memory operands into a load and the pmacsdd.
6794 (define_split
6795   [(set (match_operand:V4SI 0 "register_operand" "")
6796         (plus:V4SI
6797          (mult:V4SI (match_operand:V4SI 1 "nonimmediate_operand" "")
6798                     (match_operand:V4SI 2 "nonimmediate_operand" ""))
6799          (match_operand:V4SI 3 "nonimmediate_operand" "")))]
6800   "TARGET_SSE5
6801    && !ix86_sse5_valid_op_p (operands, insn, 4, false, 1)
6802    && ix86_sse5_valid_op_p (operands, insn, 4, false, 2)
6803    && !reg_mentioned_p (operands[0], operands[1])
6804    && !reg_mentioned_p (operands[0], operands[2])
6805    && !reg_mentioned_p (operands[0], operands[3])"
6806   [(const_int 0)]
6807 {
6808   ix86_expand_sse5_multiple_memory (operands, 4, V4SImode);
6809   emit_insn (gen_sse5_pmacsdd (operands[0], operands[1], operands[2],
6810                                operands[3]));
6811   DONE;
6812 })
6813
6814 (define_insn "sse5_pmacssdd"
6815   [(set (match_operand:V4SI 0 "register_operand" "=x,x,x")
6816         (ss_plus:V4SI
6817          (mult:V4SI (match_operand:V4SI 1 "nonimmediate_operand" "%x,x,m")
6818                     (match_operand:V4SI 2 "nonimmediate_operand" "x,m,x"))
6819          (match_operand:V4SI 3 "nonimmediate_operand" "0,0,0")))]
6820   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1)"
6821   "@
6822    pmacssdd\t{%3, %2, %1, %0|%0, %1, %2, %3}
6823    pmacssdd\t{%3, %2, %1, %0|%0, %1, %2, %3}
6824    pmacssdd\t{%3, %1, %2, %0|%0, %2, %1, %3}"
6825   [(set_attr "type" "ssemuladd")
6826    (set_attr "mode" "TI")])
6827
6828 (define_insn "sse5_pmacssdql"
6829   [(set (match_operand:V2DI 0 "register_operand" "=x,x,x")
6830         (ss_plus:V2DI
6831          (mult:V2DI
6832           (sign_extend:V2DI
6833            (vec_select:V2SI
6834             (match_operand:V4SI 1 "nonimmediate_operand" "x,x,m")
6835             (parallel [(const_int 1)
6836                        (const_int 3)])))
6837            (vec_select:V2SI
6838             (match_operand:V4SI 2 "nonimmediate_operand" "x,m,x")
6839             (parallel [(const_int 1)
6840                        (const_int 3)])))
6841          (match_operand:V2DI 3 "register_operand" "0,0,0")))]
6842   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1)"
6843   "@
6844    pmacssdql\t{%3, %2, %1, %0|%0, %1, %2, %3}
6845    pmacssdql\t{%3, %2, %1, %0|%0, %1, %2, %3}
6846    pmacssdql\t{%3, %1, %2, %0|%0, %2, %1, %3}"
6847   [(set_attr "type" "ssemuladd")
6848    (set_attr "mode" "TI")])
6849
6850 (define_insn "sse5_pmacssdqh"
6851   [(set (match_operand:V2DI 0 "register_operand" "=x,x,x")
6852         (ss_plus:V2DI
6853          (mult:V2DI
6854           (sign_extend:V2DI
6855            (vec_select:V2SI
6856             (match_operand:V4SI 1 "nonimmediate_operand" "x,x,m")
6857             (parallel [(const_int 0)
6858                        (const_int 2)])))
6859           (sign_extend:V2DI
6860            (vec_select:V2SI
6861             (match_operand:V4SI 2 "nonimmediate_operand" "x,m,x")
6862             (parallel [(const_int 0)
6863                        (const_int 2)]))))
6864          (match_operand:V2DI 3 "register_operand" "0,0,0")))]
6865   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1)"
6866   "@
6867    pmacssdqh\t{%3, %2, %1, %0|%0, %1, %2, %3}
6868    pmacssdqh\t{%3, %2, %1, %0|%0, %1, %2, %3}
6869    pmacssdqh\t{%3, %1, %2, %0|%0, %2, %1, %3}"
6870   [(set_attr "type" "ssemuladd")
6871    (set_attr "mode" "TI")])
6872
6873 (define_insn "sse5_pmacsdql"
6874   [(set (match_operand:V2DI 0 "register_operand" "=x,x,x")
6875         (plus:V2DI
6876          (mult:V2DI
6877           (sign_extend:V2DI
6878            (vec_select:V2SI
6879             (match_operand:V4SI 1 "nonimmediate_operand" "x,x,m")
6880             (parallel [(const_int 1)
6881                        (const_int 3)])))
6882           (sign_extend:V2DI
6883            (vec_select:V2SI
6884             (match_operand:V4SI 2 "nonimmediate_operand" "x,m,x")
6885             (parallel [(const_int 1)
6886                        (const_int 3)]))))
6887          (match_operand:V2DI 3 "register_operand" "0,0,0")))]
6888   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1)"
6889   "@
6890    pmacsdql\t{%3, %2, %1, %0|%0, %1, %2, %3}
6891    pmacsdql\t{%3, %2, %1, %0|%0, %1, %2, %3}
6892    pmacsdql\t{%3, %1, %2, %0|%0, %2, %1, %3}"
6893   [(set_attr "type" "ssemuladd")
6894    (set_attr "mode" "TI")])
6895
6896 (define_insn "sse5_pmacsdqh"
6897   [(set (match_operand:V2DI 0 "register_operand" "=x,x,x")
6898         (plus:V2DI
6899          (mult:V2DI
6900           (sign_extend:V2DI
6901            (vec_select:V2SI
6902             (match_operand:V4SI 1 "nonimmediate_operand" "x,x,m")
6903             (parallel [(const_int 0)
6904                        (const_int 2)])))
6905           (sign_extend:V2DI
6906            (vec_select:V2SI
6907             (match_operand:V4SI 2 "nonimmediate_operand" "x,m,x")
6908             (parallel [(const_int 0)
6909                        (const_int 2)]))))
6910          (match_operand:V2DI 3 "register_operand" "0,0,0")))]
6911   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1)"
6912   "@
6913    pmacsdqh\t{%3, %2, %1, %0|%0, %1, %2, %3}
6914    pmacsdqh\t{%3, %2, %1, %0|%0, %1, %2, %3}
6915    pmacsdqh\t{%3, %1, %2, %0|%0, %2, %1, %3}"
6916   [(set_attr "type" "ssemuladd")
6917    (set_attr "mode" "TI")])
6918
6919 ;; SSE5 parallel integer multiply/add instructions for the intrinisics
6920 (define_insn "sse5_pmacsswd"
6921   [(set (match_operand:V4SI 0 "register_operand" "=x,x,x")
6922         (ss_plus:V4SI
6923          (mult:V4SI
6924           (sign_extend:V4SI
6925            (vec_select:V4HI
6926             (match_operand:V8HI 1 "nonimmediate_operand" "x,x,m")
6927             (parallel [(const_int 1)
6928                        (const_int 3)
6929                        (const_int 5)
6930                        (const_int 7)])))
6931           (sign_extend:V4SI
6932            (vec_select:V4HI
6933             (match_operand:V8HI 2 "nonimmediate_operand" "x,m,x")
6934             (parallel [(const_int 1)
6935                        (const_int 3)
6936                        (const_int 5)
6937                        (const_int 7)]))))
6938          (match_operand:V4SI 3 "register_operand" "0,0,0")))]
6939   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1)"
6940   "@
6941    pmacsswd\t{%3, %2, %1, %0|%0, %1, %2, %3}
6942    pmacsswd\t{%3, %2, %1, %0|%0, %1, %2, %3}
6943    pmacsswd\t{%3, %1, %2, %0|%0, %2, %1, %3}"
6944   [(set_attr "type" "ssemuladd")
6945    (set_attr "mode" "TI")])
6946
6947 (define_insn "sse5_pmacswd"
6948   [(set (match_operand:V4SI 0 "register_operand" "=x,x,x")
6949         (plus:V4SI
6950          (mult:V4SI
6951           (sign_extend:V4SI
6952            (vec_select:V4HI
6953             (match_operand:V8HI 1 "nonimmediate_operand" "x,x,m")
6954             (parallel [(const_int 1)
6955                        (const_int 3)
6956                        (const_int 5)
6957                        (const_int 7)])))
6958           (sign_extend:V4SI
6959            (vec_select:V4HI
6960             (match_operand:V8HI 2 "nonimmediate_operand" "x,m,x")
6961             (parallel [(const_int 1)
6962                        (const_int 3)
6963                        (const_int 5)
6964                        (const_int 7)]))))
6965          (match_operand:V4SI 3 "register_operand" "0,0,0")))]
6966   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1)"
6967   "@
6968    pmacswd\t{%3, %2, %1, %0|%0, %1, %2, %3}
6969    pmacswd\t{%3, %2, %1, %0|%0, %1, %2, %3}
6970    pmacswd\t{%3, %1, %2, %0|%0, %2, %1, %3}"
6971   [(set_attr "type" "ssemuladd")
6972    (set_attr "mode" "TI")])
6973
6974 (define_insn "sse5_pmadcsswd"
6975   [(set (match_operand:V4SI 0 "register_operand" "=x,x,x")
6976         (ss_plus:V4SI
6977          (plus:V4SI
6978           (mult:V4SI
6979            (sign_extend:V4SI
6980             (vec_select:V4HI
6981              (match_operand:V8HI 1 "nonimmediate_operand" "x,x,m")
6982              (parallel [(const_int 0)
6983                         (const_int 2)
6984                         (const_int 4)
6985                         (const_int 6)])))
6986            (sign_extend:V4SI
6987             (vec_select:V4HI
6988              (match_operand:V8HI 2 "nonimmediate_operand" "x,m,x")
6989              (parallel [(const_int 0)
6990                         (const_int 2)
6991                         (const_int 4)
6992                         (const_int 6)]))))
6993           (mult:V4SI
6994            (sign_extend:V4SI
6995             (vec_select:V4HI
6996              (match_dup 1)
6997              (parallel [(const_int 1)
6998                         (const_int 3)
6999                         (const_int 5)
7000                         (const_int 7)])))
7001            (sign_extend:V4SI
7002             (vec_select:V4HI
7003              (match_dup 2)
7004              (parallel [(const_int 1)
7005                         (const_int 3)
7006                         (const_int 5)
7007                         (const_int 7)])))))
7008          (match_operand:V4SI 3 "register_operand" "0,0,0")))]
7009   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1)"
7010   "@
7011    pmadcsswd\t{%3, %2, %1, %0|%0, %1, %2, %3}
7012    pmadcsswd\t{%3, %2, %1, %0|%0, %1, %2, %3}
7013    pmadcsswd\t{%3, %1, %2, %0|%0, %2, %1, %3}"
7014   [(set_attr "type" "ssemuladd")
7015    (set_attr "mode" "TI")])
7016
7017 (define_insn "sse5_pmadcswd"
7018   [(set (match_operand:V4SI 0 "register_operand" "=x,x,x")
7019         (plus:V4SI
7020          (plus:V4SI
7021           (mult:V4SI
7022            (sign_extend:V4SI
7023             (vec_select:V4HI
7024              (match_operand:V8HI 1 "nonimmediate_operand" "x,x,m")
7025              (parallel [(const_int 0)
7026                         (const_int 2)
7027                         (const_int 4)
7028                         (const_int 6)])))
7029            (sign_extend:V4SI
7030             (vec_select:V4HI
7031              (match_operand:V8HI 2 "nonimmediate_operand" "x,m,x")
7032              (parallel [(const_int 0)
7033                         (const_int 2)
7034                         (const_int 4)
7035                         (const_int 6)]))))
7036           (mult:V4SI
7037            (sign_extend:V4SI
7038             (vec_select:V4HI
7039              (match_dup 1)
7040              (parallel [(const_int 1)
7041                         (const_int 3)
7042                         (const_int 5)
7043                         (const_int 7)])))
7044            (sign_extend:V4SI
7045             (vec_select:V4HI
7046              (match_dup 2)
7047              (parallel [(const_int 1)
7048                         (const_int 3)
7049                         (const_int 5)
7050                         (const_int 7)])))))
7051          (match_operand:V4SI 3 "register_operand" "0,0,0")))]
7052   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1)"
7053   "@
7054    pmadcswd\t{%3, %2, %1, %0|%0, %1, %2, %3}
7055    pmadcswd\t{%3, %2, %1, %0|%0, %1, %2, %3}
7056    pmadcswd\t{%3, %1, %2, %0|%0, %2, %1, %3}"
7057   [(set_attr "type" "ssemuladd")
7058    (set_attr "mode" "TI")])
7059
7060 ;; SSE5 parallel XMM conditional moves
7061 (define_insn "sse5_pcmov_<mode>"
7062   [(set (match_operand:SSEMODE 0 "register_operand" "=x,x,x,x,x,x")
7063         (if_then_else:SSEMODE
7064           (match_operand:SSEMODE 3 "nonimmediate_operand" "0,0,xm,x,0,0")
7065           (match_operand:SSEMODE 1 "vector_move_operand" "x,xm,0,0,C,x")
7066           (match_operand:SSEMODE 2 "vector_move_operand" "xm,x,x,xm,x,C")))]
7067   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
7068   "@
7069    pcmov\t{%3, %2, %1, %0|%0, %1, %2, %3}
7070    pcmov\t{%3, %2, %1, %0|%0, %1, %2, %3}
7071    pcmov\t{%3, %2, %1, %0|%0, %1, %2, %3}
7072    pcmov\t{%3, %2, %1, %0|%0, %1, %2, %3}
7073    andps\t{%2, %0|%0, %2}
7074    andnps\t{%1, %0|%0, %1}"
7075   [(set_attr "type" "sse4arg")])
7076
7077 ;; SSE5 horizontal add/subtract instructions
7078 (define_insn "sse5_phaddbw"
7079   [(set (match_operand:V8HI 0 "register_operand" "=x")
7080         (plus:V8HI
7081          (sign_extend:V8HI
7082           (vec_select:V8QI
7083            (match_operand:V16QI 1 "nonimmediate_operand" "xm")
7084            (parallel [(const_int 0)
7085                       (const_int 2)
7086                       (const_int 4)
7087                       (const_int 6)
7088                       (const_int 8)
7089                       (const_int 10)
7090                       (const_int 12)
7091                       (const_int 14)])))
7092          (sign_extend:V8HI
7093           (vec_select:V8QI
7094            (match_dup 1)
7095            (parallel [(const_int 1)
7096                       (const_int 3)
7097                       (const_int 5)
7098                       (const_int 7)
7099                       (const_int 9)
7100                       (const_int 11)
7101                       (const_int 13)
7102                       (const_int 15)])))))]
7103   "TARGET_SSE5"
7104   "phaddbw\t{%1, %0|%0, %1}"
7105   [(set_attr "type" "sseiadd1")])
7106
7107 (define_insn "sse5_phaddbd"
7108   [(set (match_operand:V4SI 0 "register_operand" "=x")
7109         (plus:V4SI
7110          (plus:V4SI
7111           (sign_extend:V4SI
7112            (vec_select:V4QI
7113             (match_operand:V16QI 1 "nonimmediate_operand" "xm")
7114             (parallel [(const_int 0)
7115                        (const_int 4)
7116                        (const_int 8)
7117                        (const_int 12)])))
7118           (sign_extend:V4SI
7119            (vec_select:V4QI
7120             (match_dup 1)
7121             (parallel [(const_int 1)
7122                        (const_int 5)
7123                        (const_int 9)
7124                        (const_int 13)]))))
7125          (plus:V4SI
7126           (sign_extend:V4SI
7127            (vec_select:V4QI
7128             (match_dup 1)
7129             (parallel [(const_int 2)
7130                        (const_int 6)
7131                        (const_int 10)
7132                        (const_int 14)])))
7133           (sign_extend:V4SI
7134            (vec_select:V4QI
7135             (match_dup 1)
7136             (parallel [(const_int 3)
7137                        (const_int 7)
7138                        (const_int 11)
7139                        (const_int 15)]))))))]
7140   "TARGET_SSE5"
7141   "phaddbd\t{%1, %0|%0, %1}"
7142   [(set_attr "type" "sseiadd1")])
7143
7144 (define_insn "sse5_phaddbq"
7145   [(set (match_operand:V2DI 0 "register_operand" "=x")
7146         (plus:V2DI
7147          (plus:V2DI
7148           (plus:V2DI
7149            (sign_extend:V2DI
7150             (vec_select:V2QI
7151              (match_operand:V16QI 1 "nonimmediate_operand" "xm")
7152              (parallel [(const_int 0)
7153                         (const_int 4)])))
7154            (sign_extend:V2DI
7155             (vec_select:V2QI
7156              (match_dup 1)
7157              (parallel [(const_int 1)
7158                         (const_int 5)]))))
7159           (plus:V2DI
7160            (sign_extend:V2DI
7161             (vec_select:V2QI
7162              (match_dup 1)
7163              (parallel [(const_int 2)
7164                         (const_int 6)])))
7165            (sign_extend:V2DI
7166             (vec_select:V2QI
7167              (match_dup 1)
7168              (parallel [(const_int 3)
7169                         (const_int 7)])))))
7170          (plus:V2DI
7171           (plus:V2DI
7172            (sign_extend:V2DI
7173             (vec_select:V2QI
7174              (match_dup 1)
7175              (parallel [(const_int 8)
7176                         (const_int 12)])))
7177            (sign_extend:V2DI
7178             (vec_select:V2QI
7179              (match_dup 1)
7180              (parallel [(const_int 9)
7181                         (const_int 13)]))))
7182           (plus:V2DI
7183            (sign_extend:V2DI
7184             (vec_select:V2QI
7185              (match_dup 1)
7186              (parallel [(const_int 10)
7187                         (const_int 14)])))
7188            (sign_extend:V2DI
7189             (vec_select:V2QI
7190              (match_dup 1)
7191              (parallel [(const_int 11)
7192                         (const_int 15)])))))))]
7193   "TARGET_SSE5"
7194   "phaddbq\t{%1, %0|%0, %1}"
7195   [(set_attr "type" "sseiadd1")])
7196
7197 (define_insn "sse5_phaddwd"
7198   [(set (match_operand:V4SI 0 "register_operand" "=x")
7199         (plus:V4SI
7200          (sign_extend:V4SI
7201           (vec_select:V4HI
7202            (match_operand:V8HI 1 "nonimmediate_operand" "xm")
7203            (parallel [(const_int 0)
7204                       (const_int 2)
7205                       (const_int 4)
7206                       (const_int 6)])))
7207          (sign_extend:V4SI
7208           (vec_select:V4HI
7209            (match_dup 1)
7210            (parallel [(const_int 1)
7211                       (const_int 3)
7212                       (const_int 5)
7213                       (const_int 7)])))))]
7214   "TARGET_SSE5"
7215   "phaddwd\t{%1, %0|%0, %1}"
7216   [(set_attr "type" "sseiadd1")])
7217
7218 (define_insn "sse5_phaddwq"
7219   [(set (match_operand:V2DI 0 "register_operand" "=x")
7220         (plus:V2DI
7221          (plus:V2DI
7222           (sign_extend:V2DI
7223            (vec_select:V2HI
7224             (match_operand:V8HI 1 "nonimmediate_operand" "xm")
7225             (parallel [(const_int 0)
7226                        (const_int 4)])))
7227           (sign_extend:V2DI
7228            (vec_select:V2HI
7229             (match_dup 1)
7230             (parallel [(const_int 1)
7231                        (const_int 5)]))))
7232          (plus:V2DI
7233           (sign_extend:V2DI
7234            (vec_select:V2HI
7235             (match_dup 1)
7236             (parallel [(const_int 2)
7237                        (const_int 6)])))
7238           (sign_extend:V2DI
7239            (vec_select:V2HI
7240             (match_dup 1)
7241             (parallel [(const_int 3)
7242                        (const_int 7)]))))))]
7243   "TARGET_SSE5"
7244   "phaddwq\t{%1, %0|%0, %1}"
7245   [(set_attr "type" "sseiadd1")])
7246
7247 (define_insn "sse5_phadddq"
7248   [(set (match_operand:V2DI 0 "register_operand" "=x")
7249         (plus:V2DI
7250          (sign_extend:V2DI
7251           (vec_select:V2SI
7252            (match_operand:V4SI 1 "nonimmediate_operand" "xm")
7253            (parallel [(const_int 0)
7254                       (const_int 2)])))
7255          (sign_extend:V2DI
7256           (vec_select:V2SI
7257            (match_dup 1)
7258            (parallel [(const_int 1)
7259                       (const_int 3)])))))]
7260   "TARGET_SSE5"
7261   "phadddq\t{%1, %0|%0, %1}"
7262   [(set_attr "type" "sseiadd1")])
7263
7264 (define_insn "sse5_phaddubw"
7265   [(set (match_operand:V8HI 0 "register_operand" "=x")
7266         (plus:V8HI
7267          (zero_extend:V8HI
7268           (vec_select:V8QI
7269            (match_operand:V16QI 1 "nonimmediate_operand" "xm")
7270            (parallel [(const_int 0)
7271                       (const_int 2)
7272                       (const_int 4)
7273                       (const_int 6)
7274                       (const_int 8)
7275                       (const_int 10)
7276                       (const_int 12)
7277                       (const_int 14)])))
7278          (zero_extend:V8HI
7279           (vec_select:V8QI
7280            (match_dup 1)
7281            (parallel [(const_int 1)
7282                       (const_int 3)
7283                       (const_int 5)
7284                       (const_int 7)
7285                       (const_int 9)
7286                       (const_int 11)
7287                       (const_int 13)
7288                       (const_int 15)])))))]
7289   "TARGET_SSE5"
7290   "phaddubw\t{%1, %0|%0, %1}"
7291   [(set_attr "type" "sseiadd1")])
7292
7293 (define_insn "sse5_phaddubd"
7294   [(set (match_operand:V4SI 0 "register_operand" "=x")
7295         (plus:V4SI
7296          (plus:V4SI
7297           (zero_extend:V4SI
7298            (vec_select:V4QI
7299             (match_operand:V16QI 1 "nonimmediate_operand" "xm")
7300             (parallel [(const_int 0)
7301                        (const_int 4)
7302                        (const_int 8)
7303                        (const_int 12)])))
7304           (zero_extend:V4SI
7305            (vec_select:V4QI
7306             (match_dup 1)
7307             (parallel [(const_int 1)
7308                        (const_int 5)
7309                        (const_int 9)
7310                        (const_int 13)]))))
7311          (plus:V4SI
7312           (zero_extend:V4SI
7313            (vec_select:V4QI
7314             (match_dup 1)
7315             (parallel [(const_int 2)
7316                        (const_int 6)
7317                        (const_int 10)
7318                        (const_int 14)])))
7319           (zero_extend:V4SI
7320            (vec_select:V4QI
7321             (match_dup 1)
7322             (parallel [(const_int 3)
7323                        (const_int 7)
7324                        (const_int 11)
7325                        (const_int 15)]))))))]
7326   "TARGET_SSE5"
7327   "phaddubd\t{%1, %0|%0, %1}"
7328   [(set_attr "type" "sseiadd1")])
7329
7330 (define_insn "sse5_phaddubq"
7331   [(set (match_operand:V2DI 0 "register_operand" "=x")
7332         (plus:V2DI
7333          (plus:V2DI
7334           (plus:V2DI
7335            (zero_extend:V2DI
7336             (vec_select:V2QI
7337              (match_operand:V16QI 1 "nonimmediate_operand" "xm")
7338              (parallel [(const_int 0)
7339                         (const_int 4)])))
7340            (sign_extend:V2DI
7341             (vec_select:V2QI
7342              (match_dup 1)
7343              (parallel [(const_int 1)
7344                         (const_int 5)]))))
7345           (plus:V2DI
7346            (zero_extend:V2DI
7347             (vec_select:V2QI
7348              (match_dup 1)
7349              (parallel [(const_int 2)
7350                         (const_int 6)])))
7351            (zero_extend:V2DI
7352             (vec_select:V2QI
7353              (match_dup 1)
7354              (parallel [(const_int 3)
7355                         (const_int 7)])))))
7356          (plus:V2DI
7357           (plus:V2DI
7358            (zero_extend:V2DI
7359             (vec_select:V2QI
7360              (match_dup 1)
7361              (parallel [(const_int 8)
7362                         (const_int 12)])))
7363            (sign_extend:V2DI
7364             (vec_select:V2QI
7365              (match_dup 1)
7366              (parallel [(const_int 9)
7367                         (const_int 13)]))))
7368           (plus:V2DI
7369            (zero_extend:V2DI
7370             (vec_select:V2QI
7371              (match_dup 1)
7372              (parallel [(const_int 10)
7373                         (const_int 14)])))
7374            (zero_extend:V2DI
7375             (vec_select:V2QI
7376              (match_dup 1)
7377              (parallel [(const_int 11)
7378                         (const_int 15)])))))))]
7379   "TARGET_SSE5"
7380   "phaddubq\t{%1, %0|%0, %1}"
7381   [(set_attr "type" "sseiadd1")])
7382
7383 (define_insn "sse5_phadduwd"
7384   [(set (match_operand:V4SI 0 "register_operand" "=x")
7385         (plus:V4SI
7386          (zero_extend:V4SI
7387           (vec_select:V4HI
7388            (match_operand:V8HI 1 "nonimmediate_operand" "xm")
7389            (parallel [(const_int 0)
7390                       (const_int 2)
7391                       (const_int 4)
7392                       (const_int 6)])))
7393          (zero_extend:V4SI
7394           (vec_select:V4HI
7395            (match_dup 1)
7396            (parallel [(const_int 1)
7397                       (const_int 3)
7398                       (const_int 5)
7399                       (const_int 7)])))))]
7400   "TARGET_SSE5"
7401   "phadduwd\t{%1, %0|%0, %1}"
7402   [(set_attr "type" "sseiadd1")])
7403
7404 (define_insn "sse5_phadduwq"
7405   [(set (match_operand:V2DI 0 "register_operand" "=x")
7406         (plus:V2DI
7407          (plus:V2DI
7408           (zero_extend:V2DI
7409            (vec_select:V2HI
7410             (match_operand:V8HI 1 "nonimmediate_operand" "xm")
7411             (parallel [(const_int 0)
7412                        (const_int 4)])))
7413           (zero_extend:V2DI
7414            (vec_select:V2HI
7415             (match_dup 1)
7416             (parallel [(const_int 1)
7417                        (const_int 5)]))))
7418          (plus:V2DI
7419           (zero_extend:V2DI
7420            (vec_select:V2HI
7421             (match_dup 1)
7422             (parallel [(const_int 2)
7423                        (const_int 6)])))
7424           (zero_extend:V2DI
7425            (vec_select:V2HI
7426             (match_dup 1)
7427             (parallel [(const_int 3)
7428                        (const_int 7)]))))))]
7429   "TARGET_SSE5"
7430   "phadduwq\t{%1, %0|%0, %1}"
7431   [(set_attr "type" "sseiadd1")])
7432
7433 (define_insn "sse5_phaddudq"
7434   [(set (match_operand:V2DI 0 "register_operand" "=x")
7435         (plus:V2DI
7436          (zero_extend:V2DI
7437           (vec_select:V2SI
7438            (match_operand:V4SI 1 "nonimmediate_operand" "xm")
7439            (parallel [(const_int 0)
7440                       (const_int 2)])))
7441          (zero_extend:V2DI
7442           (vec_select:V2SI
7443            (match_dup 1)
7444            (parallel [(const_int 1)
7445                       (const_int 3)])))))]
7446   "TARGET_SSE5"
7447   "phaddudq\t{%1, %0|%0, %1}"
7448   [(set_attr "type" "sseiadd1")])
7449
7450 (define_insn "sse5_phsubbw"
7451   [(set (match_operand:V8HI 0 "register_operand" "=x")
7452         (minus:V8HI
7453          (sign_extend:V8HI
7454           (vec_select:V8QI
7455            (match_operand:V16QI 1 "nonimmediate_operand" "xm")
7456            (parallel [(const_int 0)
7457                       (const_int 2)
7458                       (const_int 4)
7459                       (const_int 6)
7460                       (const_int 8)
7461                       (const_int 10)
7462                       (const_int 12)
7463                       (const_int 14)])))
7464          (sign_extend:V8HI
7465           (vec_select:V8QI
7466            (match_dup 1)
7467            (parallel [(const_int 1)
7468                       (const_int 3)
7469                       (const_int 5)
7470                       (const_int 7)
7471                       (const_int 9)
7472                       (const_int 11)
7473                       (const_int 13)
7474                       (const_int 15)])))))]
7475   "TARGET_SSE5"
7476   "phsubbw\t{%1, %0|%0, %1}"
7477   [(set_attr "type" "sseiadd1")])
7478
7479 (define_insn "sse5_phsubwd"
7480   [(set (match_operand:V4SI 0 "register_operand" "=x")
7481         (minus:V4SI
7482          (sign_extend:V4SI
7483           (vec_select:V4HI
7484            (match_operand:V8HI 1 "nonimmediate_operand" "xm")
7485            (parallel [(const_int 0)
7486                       (const_int 2)
7487                       (const_int 4)
7488                       (const_int 6)])))
7489          (sign_extend:V4SI
7490           (vec_select:V4HI
7491            (match_dup 1)
7492            (parallel [(const_int 1)
7493                       (const_int 3)
7494                       (const_int 5)
7495                       (const_int 7)])))))]
7496   "TARGET_SSE5"
7497   "phsubwd\t{%1, %0|%0, %1}"
7498   [(set_attr "type" "sseiadd1")])
7499
7500 (define_insn "sse5_phsubdq"
7501   [(set (match_operand:V2DI 0 "register_operand" "=x")
7502         (minus:V2DI
7503          (sign_extend:V2DI
7504           (vec_select:V2SI
7505            (match_operand:V4SI 1 "nonimmediate_operand" "xm")
7506            (parallel [(const_int 0)
7507                       (const_int 2)])))
7508          (sign_extend:V2DI
7509           (vec_select:V2SI
7510            (match_dup 1)
7511            (parallel [(const_int 1)
7512                       (const_int 3)])))))]
7513   "TARGET_SSE5"
7514   "phsubdq\t{%1, %0|%0, %1}"
7515   [(set_attr "type" "sseiadd1")])
7516
7517 ;; SSE5 permute instructions
7518 (define_insn "sse5_pperm"
7519   [(set (match_operand:V16QI 0 "register_operand" "=x,x,x,x")
7520         (unspec:V16QI
7521           [(match_operand:V16QI 1 "nonimmediate_operand" "0,0,x,xm")
7522            (match_operand:V16QI 2 "nonimmediate_operand" "x,xm,xm,x")
7523            (match_operand:V16QI 3 "nonimmediate_operand" "xm,x,0,0")]
7524           UNSPEC_SSE5_PERMUTE))]
7525   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
7526   "pperm\t{%3, %2, %1, %0|%0, %1, %2, %3}"
7527   [(set_attr "type" "sse4arg")
7528    (set_attr "mode" "TI")])
7529
7530 ;; The following are for the various unpack insns which doesn't need the first
7531 ;; source operand, so we can just use the output operand for the first operand.
7532 ;; This allows either of the other two operands to be a memory operand.  We
7533 ;; can't just use the first operand as an argument to the normal pperm because
7534 ;; then an output only argument, suddenly becomes an input operand.
7535 (define_insn "sse5_pperm_zero_v16qi_v8hi"
7536   [(set (match_operand:V8HI 0 "register_operand" "=x,x")
7537         (zero_extend:V8HI
7538          (vec_select:V8QI
7539           (match_operand:V16QI 1 "nonimmediate_operand" "xm,x")
7540           (match_operand 2 "" ""))))    ;; parallel with const_int's
7541    (use (match_operand:V16QI 3 "nonimmediate_operand" "x,xm"))]
7542   "TARGET_SSE5
7543    && (register_operand (operands[1], V16QImode)
7544        || register_operand (operands[2], V16QImode))"
7545   "pperm\t{%3, %1, %0, %0|%0, %0, %1, %3}"
7546   [(set_attr "type" "sseadd")
7547    (set_attr "mode" "TI")])
7548
7549 (define_insn "sse5_pperm_sign_v16qi_v8hi"
7550   [(set (match_operand:V8HI 0 "register_operand" "=x,x")
7551         (sign_extend:V8HI
7552          (vec_select:V8QI
7553           (match_operand:V16QI 1 "nonimmediate_operand" "xm,x")
7554           (match_operand 2 "" ""))))    ;; parallel with const_int's
7555    (use (match_operand:V16QI 3 "nonimmediate_operand" "x,xm"))]
7556   "TARGET_SSE5
7557    && (register_operand (operands[1], V16QImode)
7558        || register_operand (operands[2], V16QImode))"
7559   "pperm\t{%3, %1, %0, %0|%0, %0, %1, %3}"
7560   [(set_attr "type" "sseadd")
7561    (set_attr "mode" "TI")])
7562
7563 (define_insn "sse5_pperm_zero_v8hi_v4si"
7564   [(set (match_operand:V4SI 0 "register_operand" "=x,x")
7565         (zero_extend:V4SI
7566          (vec_select:V4HI
7567           (match_operand:V8HI 1 "nonimmediate_operand" "xm,x")
7568           (match_operand 2 "" ""))))    ;; parallel with const_int's
7569    (use (match_operand:V16QI 3 "nonimmediate_operand" "x,xm"))]
7570   "TARGET_SSE5
7571    && (register_operand (operands[1], V8HImode)
7572        || register_operand (operands[2], V16QImode))"
7573   "pperm\t{%3, %1, %0, %0|%0, %0, %1, %3}"
7574   [(set_attr "type" "sseadd")
7575    (set_attr "mode" "TI")])
7576
7577 (define_insn "sse5_pperm_sign_v8hi_v4si"
7578   [(set (match_operand:V4SI 0 "register_operand" "=x,x")
7579         (sign_extend:V4SI
7580          (vec_select:V4HI
7581           (match_operand:V8HI 1 "nonimmediate_operand" "xm,x")
7582           (match_operand 2 "" ""))))    ;; parallel with const_int's
7583    (use (match_operand:V16QI 3 "nonimmediate_operand" "x,xm"))]
7584   "TARGET_SSE5
7585    && (register_operand (operands[1], V8HImode)
7586        || register_operand (operands[2], V16QImode))"
7587   "pperm\t{%3, %1, %0, %0|%0, %0, %1, %3}"
7588   [(set_attr "type" "sseadd")
7589    (set_attr "mode" "TI")])
7590
7591 (define_insn "sse5_pperm_zero_v4si_v2di"
7592   [(set (match_operand:V2DI 0 "register_operand" "=x,x")
7593         (zero_extend:V2DI
7594          (vec_select:V2SI
7595           (match_operand:V4SI 1 "nonimmediate_operand" "xm,x")
7596           (match_operand 2 "" ""))))    ;; parallel with const_int's
7597    (use (match_operand:V16QI 3 "nonimmediate_operand" "x,xm"))]
7598   "TARGET_SSE5
7599    && (register_operand (operands[1], V4SImode)
7600        || register_operand (operands[2], V16QImode))"
7601   "pperm\t{%3, %1, %0, %0|%0, %0, %1, %3}"
7602   [(set_attr "type" "sseadd")
7603    (set_attr "mode" "TI")])
7604
7605 (define_insn "sse5_pperm_sign_v4si_v2di"
7606   [(set (match_operand:V2DI 0 "register_operand" "=x,x")
7607         (sign_extend:V2DI
7608          (vec_select:V2SI
7609           (match_operand:V4SI 1 "nonimmediate_operand" "xm,x")
7610           (match_operand 2 "" ""))))    ;; parallel with const_int's
7611    (use (match_operand:V16QI 3 "nonimmediate_operand" "x,xm"))]
7612   "TARGET_SSE5
7613    && (register_operand (operands[1], V4SImode)
7614        || register_operand (operands[2], V16QImode))"
7615   "pperm\t{%3, %1, %0, %0|%0, %0, %1, %3}"
7616   [(set_attr "type" "sseadd")
7617    (set_attr "mode" "TI")])
7618
7619 ;; SSE5 pack instructions that combine two vectors into a smaller vector
7620 (define_insn "sse5_pperm_pack_v2di_v4si"
7621   [(set (match_operand:V4SI 0 "register_operand" "=x,x,x,x")
7622         (vec_concat:V4SI
7623          (truncate:V2SI
7624           (match_operand:V2DI 1 "nonimmediate_operand" "0,0,x,xm"))
7625          (truncate:V2SI
7626           (match_operand:V2DI 2 "nonimmediate_operand" "x,xm,xm,x"))))
7627    (use (match_operand:V16QI 3 "nonimmediate_operand" "xm,x,0,0"))]
7628   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
7629   "pperm\t{%3, %2, %1, %0|%0, %1, %2, %3}"
7630   [(set_attr "type" "sse4arg")
7631    (set_attr "mode" "TI")])
7632
7633 (define_insn "sse5_pperm_pack_v4si_v8hi"
7634   [(set (match_operand:V8HI 0 "register_operand" "=x,x,x,x")
7635         (vec_concat:V8HI
7636          (truncate:V4HI
7637           (match_operand:V4SI 1 "nonimmediate_operand" "0,0,x,xm"))
7638          (truncate:V4HI
7639           (match_operand:V4SI 2 "nonimmediate_operand" "x,xm,xm,x"))))
7640    (use (match_operand:V16QI 3 "nonimmediate_operand" "xm,x,0,0"))]
7641   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
7642   "pperm\t{%3, %2, %1, %0|%0, %1, %2, %3}"
7643   [(set_attr "type" "sse4arg")
7644    (set_attr "mode" "TI")])
7645
7646 (define_insn "sse5_pperm_pack_v8hi_v16qi"
7647   [(set (match_operand:V16QI 0 "register_operand" "=x,x,x,x")
7648         (vec_concat:V16QI
7649          (truncate:V8QI
7650           (match_operand:V8HI 1 "nonimmediate_operand" "0,0,x,xm"))
7651          (truncate:V8QI
7652           (match_operand:V8HI 2 "nonimmediate_operand" "x,xm,xm,x"))))
7653    (use (match_operand:V16QI 3 "nonimmediate_operand" "xm,x,0,0"))]
7654   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
7655   "pperm\t{%3, %2, %1, %0|%0, %1, %2, %3}"
7656   [(set_attr "type" "sse4arg")
7657    (set_attr "mode" "TI")])
7658
7659 ;; Floating point permutation (permps, permpd)
7660 (define_insn "sse5_perm<mode>"
7661   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x,x,x")
7662         (unspec:SSEMODEF2P
7663          [(match_operand:SSEMODEF2P 1 "nonimmediate_operand" "0,0,x,xm")
7664           (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm,xm,x")
7665           (match_operand:V16QI 3 "nonimmediate_operand" "xm,x,0,0")]
7666          UNSPEC_SSE5_PERMUTE))]
7667   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
7668   "perm<ssemodesuffixf4>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
7669   [(set_attr "type" "sse4arg")
7670    (set_attr "mode" "<MODE>")])
7671
7672 ;; SSE5 packed rotate instructions
7673 (define_insn "rotl<mode>3"
7674   [(set (match_operand:SSEMODE1248 0 "register_operand" "=x")
7675         (rotate:SSEMODE1248
7676          (match_operand:SSEMODE1248 1 "nonimmediate_operand" "xm")
7677          (match_operand:SI 2 "const_0_to_<sserotatemax>_operand" "n")))]
7678   "TARGET_SSE5"
7679   "prot<ssevecsize>\t{%2, %1, %0|%0, %1, %2}"
7680   [(set_attr "type" "sseishft")
7681    (set_attr "mode" "TI")])
7682
7683 (define_insn "sse5_rotl<mode>3"
7684   [(set (match_operand:SSEMODE1248 0 "register_operand" "=x,x")
7685         (rotate:SSEMODE1248
7686          (match_operand:SSEMODE1248 1 "nonimmediate_operand" "x,xm")
7687          (match_operand:SSEMODE1248 2 "nonimmediate_operand" "xm,x")))]
7688   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 3, true, 1)"
7689   "prot<ssevecsize>\t{%2, %1, %0|%0, %1, %2}"
7690   [(set_attr "type" "sseishft")
7691    (set_attr "mode" "TI")])
7692
7693 ;; SSE5 packed shift instructions.  Note negative values for the shift amount
7694 ;; convert this into a right shift instead of left shift.  For now, model this
7695 ;; with an UNSPEC instead of using ashift/lshift since the rest of the x86 does
7696 ;; not have the concept of negating the shift amount.  Also, there is no LSHIFT
7697 (define_insn "sse5_ashl<mode>3"
7698   [(set (match_operand:SSEMODE1248 0 "register_operand" "=x,x")
7699         (unspec:SSEMODE1248
7700          [(match_operand:SSEMODE1248 1 "nonimmediate_operand" "x,xm")
7701           (match_operand:SSEMODE1248 2 "nonimmediate_operand" "xm,x")]
7702          UNSPEC_SSE5_ASHIFT))]
7703   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 3, true, 1)"
7704   "psha<ssevecsize>\t{%2, %1, %0|%0, %1, %2}"
7705   [(set_attr "type" "sseishft")
7706    (set_attr "mode" "TI")])
7707
7708 (define_insn "sse5_lshl<mode>3"
7709   [(set (match_operand:SSEMODE1248 0 "register_operand" "=x,x")
7710         (unspec:SSEMODE1248
7711          [(match_operand:SSEMODE1248 1 "nonimmediate_operand" "x,xm")
7712           (match_operand:SSEMODE1248 2 "nonimmediate_operand" "xm,x")]
7713          UNSPEC_SSE5_LSHIFT))]
7714   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 3, true, 1)"
7715   "pshl<ssevecsize>\t{%2, %1, %0|%0, %1, %2}"
7716   [(set_attr "type" "sseishft")
7717    (set_attr "mode" "TI")])
7718
7719 ;; SSE5 FRCZ support
7720 ;; parallel insns
7721 (define_insn "sse5_frcz<mode>2"
7722   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
7723         (unspec:SSEMODEF2P
7724          [(match_operand:SSEMODEF2P 1 "nonimmediate_operand" "xm")]
7725          UNSPEC_FRCZ))]
7726   "TARGET_SSE5"
7727   "frcz<ssemodesuffixf4>\t{%1, %0|%0, %1}"
7728   [(set_attr "type" "ssecvt1")
7729    (set_attr "prefix_extra" "1")
7730    (set_attr "mode" "<MODE>")])
7731
7732 ;; scalar insns
7733 (define_insn "sse5_vmfrcz<mode>2"
7734   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
7735         (vec_merge:SSEMODEF2P
7736           (unspec:SSEMODEF2P
7737            [(match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")]
7738            UNSPEC_FRCZ)
7739           (match_operand:SSEMODEF2P 1 "register_operand" "0")
7740           (const_int 1)))]
7741   "TARGET_SSE5"
7742   "frcz<ssemodesuffixf2s>\t{%2, %0|%0, %2}"
7743   [(set_attr "type" "ssecvt1")
7744    (set_attr "prefix_extra" "1")
7745    (set_attr "mode" "<MODE>")])
7746
7747 (define_insn "sse5_cvtph2ps"
7748   [(set (match_operand:V4SF 0 "register_operand" "=x")
7749         (unspec:V4SF [(match_operand:V4HI 1 "nonimmediate_operand" "xm")]
7750                      UNSPEC_CVTPH2PS))]
7751   "TARGET_SSE5"
7752   "cvtph2ps\t{%1, %0|%0, %1}"
7753   [(set_attr "type" "ssecvt")
7754    (set_attr "mode" "V4SF")])
7755
7756 (define_insn "sse5_cvtps2ph"
7757   [(set (match_operand:V4HI 0 "nonimmediate_operand" "=xm")
7758         (unspec:V4HI [(match_operand:V4SF 1 "register_operand" "x")]
7759                      UNSPEC_CVTPS2PH))]
7760   "TARGET_SSE5"
7761   "cvtps2ph\t{%1, %0|%0, %1}"
7762   [(set_attr "type" "ssecvt")
7763    (set_attr "mode" "V4SF")])
7764
7765 ;; Scalar versions of the com instructions that use vector types that are
7766 ;; called from the intrinsics.  Unlike the the other s{s,d} instructions, the
7767 ;; com instructions fill in 0's in the upper bits instead of leaving them
7768 ;; unmodified, so we use const_vector of 0 instead of match_dup.
7769 (define_expand "sse5_vmmaskcmp<mode>3"
7770   [(set (match_operand:SSEMODEF2P 0 "register_operand" "")
7771         (vec_merge:SSEMODEF2P
7772          (match_operator:SSEMODEF2P 1 "sse5_comparison_float_operator"
7773           [(match_operand:SSEMODEF2P 2 "register_operand" "")
7774            (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "")])
7775          (match_dup 4)
7776          (const_int 1)))]
7777   "TARGET_SSE5"
7778 {
7779   operands[4] = CONST0_RTX (<MODE>mode);
7780 })
7781
7782 (define_insn "*sse5_vmmaskcmp<mode>3"
7783   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
7784         (vec_merge:SSEMODEF2P
7785          (match_operator:SSEMODEF2P 1 "sse5_comparison_float_operator"
7786           [(match_operand:SSEMODEF2P 2 "register_operand" "x")
7787            (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm")])
7788           (match_operand:SSEMODEF2P 4 "")
7789           (const_int 1)))]
7790   "TARGET_SSE5"
7791   "com%Y1<ssemodesuffixf2s>\t{%3, %2, %0|%0, %2, %3}"
7792   [(set_attr "type" "sse4arg")
7793    (set_attr "mode" "<ssescalarmode>")])
7794
7795 ;; We don't have a comparison operator that always returns true/false, so
7796 ;; handle comfalse and comtrue specially.
7797 (define_insn "sse5_com_tf<mode>3"
7798   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
7799         (unspec:SSEMODEF2P
7800          [(match_operand:SSEMODEF2P 1 "register_operand" "x")
7801           (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")
7802           (match_operand:SI 3 "const_int_operand" "n")]
7803          UNSPEC_SSE5_TRUEFALSE))]
7804   "TARGET_SSE5"
7805 {
7806   const char *ret = NULL;
7807
7808   switch (INTVAL (operands[3]))
7809     {
7810     case COM_FALSE_S:
7811       ret = \"comfalses<ssemodesuffixf2c>\t{%2, %1, %0|%0, %1, %2}\";
7812       break;
7813
7814     case COM_FALSE_P:
7815       ret = \"comfalsep<ssemodesuffixf2c>\t{%2, %1, %0|%0, %1, %2}\";
7816       break;
7817
7818     case COM_TRUE_S:
7819       ret = \"comfalses<ssemodesuffixf2c>\t{%2, %1, %0|%0, %1, %2}\";
7820       break;
7821
7822     case COM_TRUE_P:
7823       ret = \"comfalsep<ssemodesuffixf2c>\t{%2, %1, %0|%0, %1, %2}\";
7824       break;
7825
7826     default:
7827       gcc_unreachable ();
7828     }
7829
7830   return ret;
7831 }
7832   [(set_attr "type" "ssecmp")
7833    (set_attr "mode" "<MODE>")])
7834
7835 (define_insn "sse5_maskcmp<mode>3"
7836   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
7837         (match_operator:SSEMODEF2P 1 "sse5_comparison_float_operator"
7838          [(match_operand:SSEMODEF2P 2 "register_operand" "x")
7839           (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm")]))]
7840   "TARGET_SSE5"
7841   "com%Y1<ssemodesuffixf4>\t{%3, %2, %0|%0, %2, %3}"
7842   [(set_attr "type" "ssecmp")
7843    (set_attr "mode" "<MODE>")])
7844
7845 (define_insn "sse5_maskcmp<mode>3"
7846   [(set (match_operand:SSEMODE1248 0 "register_operand" "=x")
7847         (match_operator:SSEMODE1248 1 "ix86_comparison_int_operator"
7848          [(match_operand:SSEMODE1248 2 "register_operand" "x")
7849           (match_operand:SSEMODE1248 3 "nonimmediate_operand" "xm")]))]
7850   "TARGET_SSE5"
7851   "pcom%Y1<ssevecsize>\t{%3, %2, %0|%0, %2, %3}"
7852   [(set_attr "type" "sse4arg")
7853    (set_attr "mode" "TI")])
7854
7855 (define_insn "sse5_maskcmp_uns<mode>3"
7856   [(set (match_operand:SSEMODE1248 0 "register_operand" "=x")
7857         (match_operator:SSEMODE1248 1 "ix86_comparison_uns_operator"
7858          [(match_operand:SSEMODE1248 2 "register_operand" "x")
7859           (match_operand:SSEMODE1248 3 "nonimmediate_operand" "xm")]))]
7860   "TARGET_SSE5"
7861   "pcom%Y1u<ssevecsize>\t{%3, %2, %0|%0, %2, %3}"
7862   [(set_attr "type" "ssecmp")
7863    (set_attr "mode" "TI")])
7864
7865 ;; Version of pcom*u* that is called from the intrinsics that allows pcomequ*
7866 ;; and pcomneu* not to be converted to the signed ones in case somebody needs
7867 ;; the exact instruction generated for the intrinsic.
7868 (define_insn "sse5_maskcmp_uns2<mode>3"
7869   [(set (match_operand:SSEMODE1248 0 "register_operand" "=x")
7870         (unspec:SSEMODE1248
7871          [(match_operator:SSEMODE1248 1 "ix86_comparison_uns_operator"
7872           [(match_operand:SSEMODE1248 2 "register_operand" "x")
7873            (match_operand:SSEMODE1248 3 "nonimmediate_operand" "xm")])]
7874          UNSPEC_SSE5_UNSIGNED_CMP))]
7875   "TARGET_SSE5"
7876   "pcom%Y1u<ssevecsize>\t{%3, %2, %0|%0, %2, %3}"
7877   [(set_attr "type" "ssecmp")
7878    (set_attr "mode" "TI")])
7879
7880 ;; Pcomtrue and pcomfalse support.  These are useless instructions, but are
7881 ;; being added here to be complete.
7882 (define_insn "sse5_pcom_tf<mode>3"
7883   [(set (match_operand:SSEMODE1248 0 "register_operand" "=x")
7884         (unspec:SSEMODE1248
7885           [(match_operand:SSEMODE1248 1 "register_operand" "x")
7886            (match_operand:SSEMODE1248 2 "nonimmediate_operand" "xm")
7887            (match_operand:SI 3 "const_int_operand" "n")]
7888           UNSPEC_SSE5_TRUEFALSE))]
7889   "TARGET_SSE5"
7890 {
7891   return ((INTVAL (operands[3]) != 0)
7892           ? "pcomtrue<ssevecsize>\t{%2, %1, %0|%0, %1, %2}"
7893           : "pcomfalse<ssevecsize>\t{%2, %1, %0|%0, %1, %2}");
7894 }
7895   [(set_attr "type" "ssecmp")
7896    (set_attr "mode" "TI")])
7897
7898 (define_insn "aesenc"
7899   [(set (match_operand:V2DI 0 "register_operand" "=x")
7900         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0")
7901                        (match_operand:V2DI 2 "nonimmediate_operand" "xm")]
7902                       UNSPEC_AESENC))]
7903   "TARGET_AES"
7904   "aesenc\t{%2, %0|%0, %2}"
7905   [(set_attr "type" "sselog1")
7906    (set_attr "prefix_extra" "1")
7907    (set_attr "mode" "TI")])
7908
7909 (define_insn "aesenclast"
7910   [(set (match_operand:V2DI 0 "register_operand" "=x")
7911         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0")
7912                        (match_operand:V2DI 2 "nonimmediate_operand" "xm")]
7913                       UNSPEC_AESENCLAST))]
7914   "TARGET_AES"
7915   "aesenclast\t{%2, %0|%0, %2}"
7916   [(set_attr "type" "sselog1")
7917    (set_attr "prefix_extra" "1")
7918    (set_attr "mode" "TI")])
7919
7920 (define_insn "aesdec"
7921   [(set (match_operand:V2DI 0 "register_operand" "=x")
7922         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0")
7923                        (match_operand:V2DI 2 "nonimmediate_operand" "xm")]
7924                       UNSPEC_AESDEC))]
7925   "TARGET_AES"
7926   "aesdec\t{%2, %0|%0, %2}"
7927   [(set_attr "type" "sselog1")
7928    (set_attr "prefix_extra" "1")
7929    (set_attr "mode" "TI")])
7930
7931 (define_insn "aesdeclast"
7932   [(set (match_operand:V2DI 0 "register_operand" "=x")
7933         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0")
7934                        (match_operand:V2DI 2 "nonimmediate_operand" "xm")]
7935                       UNSPEC_AESDECLAST))]
7936   "TARGET_AES"
7937   "aesdeclast\t{%2, %0|%0, %2}"
7938   [(set_attr "type" "sselog1")
7939    (set_attr "prefix_extra" "1")
7940    (set_attr "mode" "TI")])
7941
7942 (define_insn "aesimc"
7943   [(set (match_operand:V2DI 0 "register_operand" "=x")
7944         (unspec:V2DI [(match_operand:V2DI 1 "nonimmediate_operand" "xm")]
7945                       UNSPEC_AESIMC))]
7946   "TARGET_AES"
7947   "aesimc\t{%1, %0|%0, %1}"
7948   [(set_attr "type" "sselog1")
7949    (set_attr "prefix_extra" "1")
7950    (set_attr "mode" "TI")])
7951
7952 (define_insn "aeskeygenassist"
7953   [(set (match_operand:V2DI 0 "register_operand" "=x")
7954         (unspec:V2DI [(match_operand:V2DI 1 "nonimmediate_operand" "xm")
7955                       (match_operand:SI 2 "const_0_to_255_operand" "n")]
7956                      UNSPEC_AESKEYGENASSIST))]
7957   "TARGET_AES"
7958   "aeskeygenassist\t{%2, %1, %0|%0, %1, %2}"
7959   [(set_attr "type" "sselog1")
7960    (set_attr "prefix_extra" "1")
7961    (set_attr "mode" "TI")])
7962
7963 (define_insn "pclmulqdq"
7964   [(set (match_operand:V2DI 0 "register_operand" "=x")
7965         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0")
7966                       (match_operand:V2DI 2 "nonimmediate_operand" "xm")
7967                       (match_operand:SI 3 "const_0_to_255_operand" "n")]
7968                      UNSPEC_PCLMUL))]
7969   "TARGET_PCLMUL"
7970   "pclmulqdq\t{%3, %2, %0|%0, %2, %3}"
7971   [(set_attr "type" "sselog1")
7972    (set_attr "prefix_extra" "1")
7973    (set_attr "mode" "TI")])