OSDN Git Service

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