OSDN Git Service

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