OSDN Git Service

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