OSDN Git Service

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