OSDN Git Service

ece1b437af76de9686b6156d78c0f828bde18391
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / sse.md
1 ;; GCC machine description for SSE instructions
2 ;; Copyright (C) 2005, 2006, 2007, 2008, 2009
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 ;; 32 byte integral vector modes handled by AVX
30 (define_mode_iterator AVX256MODEI [V32QI V16HI V8SI V4DI])
31
32 ;; All 32-byte vector modes handled by AVX
33 (define_mode_iterator AVX256MODE [V32QI V16HI V8SI V4DI V8SF V4DF])
34
35 ;; All QI vector modes handled by AVX
36 (define_mode_iterator AVXMODEQI [V32QI V16QI])
37
38 ;; All DI vector modes handled by AVX
39 (define_mode_iterator AVXMODEDI [V4DI V2DI])
40
41 ;; All vector modes handled by AVX
42 (define_mode_iterator AVXMODE [V16QI V8HI V4SI V2DI V4SF V2DF V32QI V16HI V8SI V4DI V8SF V4DF])
43
44 ;; Mix-n-match
45 (define_mode_iterator SSEMODE12 [V16QI V8HI])
46 (define_mode_iterator SSEMODE24 [V8HI V4SI])
47 (define_mode_iterator SSEMODE14 [V16QI V4SI])
48 (define_mode_iterator SSEMODE124 [V16QI V8HI V4SI])
49 (define_mode_iterator SSEMODE248 [V8HI V4SI V2DI])
50 (define_mode_iterator SSEMODE1248 [V16QI V8HI V4SI V2DI])
51 (define_mode_iterator SSEMODEF4 [SF DF V4SF V2DF])
52 (define_mode_iterator SSEMODEF2P [V4SF V2DF])
53
54 (define_mode_iterator AVX256MODEF2P [V8SF V4DF])
55 (define_mode_iterator AVX256MODE2P [V8SI V8SF V4DF])
56 (define_mode_iterator AVX256MODE4P [V4DI V4DF])
57 (define_mode_iterator AVX256MODE8P [V8SI V8SF])
58 (define_mode_iterator AVXMODEF2P [V4SF V2DF V8SF V4DF])
59 (define_mode_iterator AVXMODEF4P [V4SF V4DF])
60 (define_mode_iterator AVXMODEDCVTDQ2PS [V4SF V8SF])
61 (define_mode_iterator AVXMODEDCVTPS2DQ [V4SI V8SI])
62
63 ;; Int-float size matches
64 (define_mode_iterator SSEMODE4S [V4SF V4SI])
65 (define_mode_iterator SSEMODE2D [V2DF V2DI])
66
67 ;; Mapping from float mode to required SSE level
68 (define_mode_attr sse [(SF "sse") (DF "sse2") (V4SF "sse") (V2DF "sse2")])
69
70 ;; Mapping from integer vector mode to mnemonic suffix
71 (define_mode_attr ssevecsize [(V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")])
72
73 ;; Mapping of the sse5 suffix
74 (define_mode_attr ssemodesuffixf4 [(SF "ss") (DF "sd")
75                                    (V4SF "ps") (V2DF "pd")])
76 (define_mode_attr ssemodesuffixf2s [(SF "ss") (DF "sd")
77                                     (V4SF "ss") (V2DF "sd")])
78 (define_mode_attr ssemodesuffixf2c [(V4SF "s") (V2DF "d")])
79
80 ;; Mapping of the max integer size for sse5 rotate immediate constraint
81 (define_mode_attr sserotatemax [(V16QI "7") (V8HI "15") (V4SI "31") (V2DI "63")])
82
83 ;; Mapping of vector modes back to the scalar modes
84 (define_mode_attr ssescalarmode [(V4SF "SF") (V2DF "DF")
85                                  (V16QI "QI") (V8HI "HI")
86                                  (V4SI "SI") (V2DI "DI")])
87
88 ;; Mapping of vector modes to a vector mode of double size
89 (define_mode_attr ssedoublesizemode [(V2DF "V4DF") (V2DI "V4DI")
90                                      (V4SF "V8SF") (V4SI "V8SI")])
91
92 ;; Number of scalar elements in each vector type
93 (define_mode_attr ssescalarnum [(V4SF "4") (V2DF "2")
94                                 (V16QI "16") (V8HI "8")
95                                 (V4SI "4") (V2DI "2")])
96
97 ;; Mapping for AVX
98 (define_mode_attr avxvecmode
99   [(V16QI "TI") (V8HI "TI") (V4SI "TI") (V2DI "TI") (V4SF "V4SF")
100    (V2DF "V2DF") (V32QI "OI") (V16HI "OI") (V8SI "OI") (V4DI "OI")
101    (V8SF "V8SF") (V4DF "V4DF")])
102 (define_mode_attr avxvecpsmode
103   [(V16QI "V4SF") (V8HI "V4SF") (V4SI "V4SF") (V2DI "V4SF")
104    (V32QI "V8SF") (V16HI "V8SF") (V8SI "V8SF") (V4DI "V8SF")])
105 (define_mode_attr avxhalfvecmode
106   [(V4SF "V2SF") (V32QI "V16QI")  (V16HI "V8HI") (V8SI "V4SI")
107    (V4DI "V2DI") (V8SF "V4SF") (V4DF "V2DF")])
108 (define_mode_attr avxscalarmode
109   [(V16QI "QI") (V8HI "HI") (V4SI "SI") (V4SF "SF") (V2DF "DF")
110    (V8SF "SF") (V4DF "DF")])
111 (define_mode_attr avxcvtvecmode
112   [(V4SF "V4SI") (V8SF "V8SI") (V4SI "V4SF") (V8SI "V8SF")])
113 (define_mode_attr avxpermvecmode
114   [(V2DF "V2DI") (V4SF "V4SI") (V4DF "V4DI") (V8SF "V8SI")])
115 (define_mode_attr avxmodesuffixf2c
116   [(V4SF "s") (V2DF "d") (V8SF "s") (V4DF "d")])
117 (define_mode_attr avxmodesuffixp
118  [(V2DF "pd") (V4SI "si") (V4SF "ps") (V8SF "ps") (V8SI "si")
119   (V4DF "pd")])
120 (define_mode_attr avxmodesuffix
121   [(V16QI "") (V32QI "256") (V4SI "") (V4SF "") (V2DF "")
122    (V8SI "256") (V8SF "256") (V4DF "256")])
123
124 ;; Mapping of immediate bits for blend instructions
125 (define_mode_attr blendbits
126   [(V8SF "255") (V4SF "15") (V4DF "15") (V2DF "3")])
127
128 ;; Mapping of immediate bits for vpermil instructions
129 (define_mode_attr vpermilbits
130   [(V8SF "255") (V4SF "255") (V4DF "15") (V2DF "3")])
131
132 ;; Mapping of immediate bits for pinsr instructions
133 (define_mode_attr pinsrbits [(V16QI "32768") (V8HI "128") (V4SI "8")])
134
135 ;; Patterns whose name begins with "sse{,2,3}_" are invoked by intrinsics.
136
137 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
138 ;;
139 ;; Move patterns
140 ;;
141 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
142
143 (define_expand "mov<mode>"
144   [(set (match_operand:AVX256MODE 0 "nonimmediate_operand" "")
145         (match_operand:AVX256MODE 1 "nonimmediate_operand" ""))]
146   "TARGET_AVX"
147 {
148   ix86_expand_vector_move (<MODE>mode, operands);
149   DONE;
150 })
151
152 (define_insn "*avx_mov<mode>_internal"
153   [(set (match_operand:AVXMODE 0 "nonimmediate_operand" "=x,x ,m")
154         (match_operand:AVXMODE 1 "nonimmediate_or_sse_const_operand"  "C ,xm,x"))]
155   "TARGET_AVX
156    && (register_operand (operands[0], <MODE>mode)
157        || register_operand (operands[1], <MODE>mode))"
158 {
159   switch (which_alternative)
160     {
161     case 0:
162       return standard_sse_constant_opcode (insn, operands[1]);
163     case 1:
164     case 2:
165       switch (get_attr_mode (insn))
166         {
167         case MODE_V8SF:
168         case MODE_V4SF:
169           return "vmovaps\t{%1, %0|%0, %1}";
170         case MODE_V4DF:
171         case MODE_V2DF:
172           return "vmovapd\t{%1, %0|%0, %1}";
173         default:
174           return "vmovdqa\t{%1, %0|%0, %1}";
175         }
176     default:
177       gcc_unreachable ();
178     }
179 }
180   [(set_attr "type" "sselog1,ssemov,ssemov")
181    (set_attr "prefix" "vex")
182    (set_attr "mode" "<avxvecmode>")])
183
184 ;; All of these patterns are enabled for SSE1 as well as SSE2.
185 ;; This is essential for maintaining stable calling conventions.
186
187 (define_expand "mov<mode>"
188   [(set (match_operand:SSEMODE 0 "nonimmediate_operand" "")
189         (match_operand:SSEMODE 1 "nonimmediate_operand" ""))]
190   "TARGET_SSE"
191 {
192   ix86_expand_vector_move (<MODE>mode, operands);
193   DONE;
194 })
195
196 (define_insn "*mov<mode>_internal"
197   [(set (match_operand:SSEMODE 0 "nonimmediate_operand" "=x,x ,m")
198         (match_operand:SSEMODE 1 "nonimmediate_or_sse_const_operand"  "C ,xm,x"))]
199   "TARGET_SSE
200    && (register_operand (operands[0], <MODE>mode)
201        || register_operand (operands[1], <MODE>mode))"
202 {
203   switch (which_alternative)
204     {
205     case 0:
206       return standard_sse_constant_opcode (insn, operands[1]);
207     case 1:
208     case 2:
209       switch (get_attr_mode (insn))
210         {
211         case MODE_V4SF:
212           return "movaps\t{%1, %0|%0, %1}";
213         case MODE_V2DF:
214           return "movapd\t{%1, %0|%0, %1}";
215         default:
216           return "movdqa\t{%1, %0|%0, %1}";
217         }
218     default:
219       gcc_unreachable ();
220     }
221 }
222   [(set_attr "type" "sselog1,ssemov,ssemov")
223    (set (attr "mode")
224         (cond [(ior (ior (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
225                          (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
226                     (and (eq_attr "alternative" "2")
227                          (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
228                              (const_int 0))))
229                  (const_string "V4SF")
230                (eq (const_string "<MODE>mode") (const_string "V4SFmode"))
231                  (const_string "V4SF")
232                (eq (const_string "<MODE>mode") (const_string "V2DFmode"))
233                  (const_string "V2DF")
234               ]
235           (const_string "TI")))])
236
237 ;; Move a DI from a 32-bit register pair (e.g. %edx:%eax) to an xmm.
238 ;; We'd rather avoid this entirely; if the 32-bit reg pair was loaded
239 ;; from memory, we'd prefer to load the memory directly into the %xmm
240 ;; register.  To facilitate this happy circumstance, this pattern won't
241 ;; split until after register allocation.  If the 64-bit value didn't
242 ;; come from memory, this is the best we can do.  This is much better
243 ;; than storing %edx:%eax into a stack temporary and loading an %xmm
244 ;; from there.
245
246 (define_insn_and_split "movdi_to_sse"
247   [(parallel
248     [(set (match_operand:V4SI 0 "register_operand" "=?x,x")
249           (subreg:V4SI (match_operand:DI 1 "nonimmediate_operand" "r,m") 0))
250      (clobber (match_scratch:V4SI 2 "=&x,X"))])]
251   "!TARGET_64BIT && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES"
252   "#"
253   "&& reload_completed"
254   [(const_int 0)]
255 {
256  if (register_operand (operands[1], DImode))
257    {
258       /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
259          Assemble the 64-bit DImode value in an xmm register.  */
260       emit_insn (gen_sse2_loadld (operands[0], CONST0_RTX (V4SImode),
261                                   gen_rtx_SUBREG (SImode, operands[1], 0)));
262       emit_insn (gen_sse2_loadld (operands[2], CONST0_RTX (V4SImode),
263                                   gen_rtx_SUBREG (SImode, operands[1], 4)));
264       emit_insn (gen_sse2_punpckldq (operands[0], operands[0], operands[2]));
265     }
266  else if (memory_operand (operands[1], DImode))
267       emit_insn (gen_vec_concatv2di (gen_lowpart (V2DImode, operands[0]), operands[1], const0_rtx));
268  else
269       gcc_unreachable ();
270 })
271
272 (define_split
273   [(set (match_operand:V4SF 0 "register_operand" "")
274         (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
275   "TARGET_SSE && reload_completed"
276   [(set (match_dup 0)
277         (vec_merge:V4SF
278           (vec_duplicate:V4SF (match_dup 1))
279           (match_dup 2)
280           (const_int 1)))]
281 {
282   operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
283   operands[2] = CONST0_RTX (V4SFmode);
284 })
285
286 (define_split
287   [(set (match_operand:V2DF 0 "register_operand" "")
288         (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
289   "TARGET_SSE2 && reload_completed"
290   [(set (match_dup 0) (vec_concat:V2DF (match_dup 1) (match_dup 2)))]
291 {
292   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
293   operands[2] = CONST0_RTX (DFmode);
294 })
295
296 (define_expand "push<mode>1"
297   [(match_operand:AVX256MODE 0 "register_operand" "")]
298   "TARGET_AVX"
299 {
300   ix86_expand_push (<MODE>mode, operands[0]);
301   DONE;
302 })
303
304 (define_expand "push<mode>1"
305   [(match_operand:SSEMODE 0 "register_operand" "")]
306   "TARGET_SSE"
307 {
308   ix86_expand_push (<MODE>mode, operands[0]);
309   DONE;
310 })
311
312 (define_expand "movmisalign<mode>"
313   [(set (match_operand:AVX256MODE 0 "nonimmediate_operand" "")
314         (match_operand:AVX256MODE 1 "nonimmediate_operand" ""))]
315   "TARGET_AVX"
316 {
317   ix86_expand_vector_move_misalign (<MODE>mode, operands);
318   DONE;
319 })
320
321 (define_expand "movmisalign<mode>"
322   [(set (match_operand:SSEMODE 0 "nonimmediate_operand" "")
323         (match_operand:SSEMODE 1 "nonimmediate_operand" ""))]
324   "TARGET_SSE"
325 {
326   ix86_expand_vector_move_misalign (<MODE>mode, operands);
327   DONE;
328 })
329
330 (define_insn "avx_movup<avxmodesuffixf2c><avxmodesuffix>"
331   [(set (match_operand:AVXMODEF2P 0 "nonimmediate_operand" "=x,m")
332         (unspec:AVXMODEF2P
333           [(match_operand:AVXMODEF2P 1 "nonimmediate_operand" "xm,x")]
334           UNSPEC_MOVU))]
335   "AVX_VEC_FLOAT_MODE_P (<MODE>mode)
336    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
337   "vmovup<avxmodesuffixf2c>\t{%1, %0|%0, %1}"
338   [(set_attr "type" "ssemov")
339    (set_attr "movu" "1")
340    (set_attr "prefix" "vex")
341    (set_attr "mode" "<MODE>")])
342
343 (define_insn "sse2_movq128"
344   [(set (match_operand:V2DI 0 "register_operand" "=x")
345         (vec_concat:V2DI
346           (vec_select:DI
347             (match_operand:V2DI 1 "nonimmediate_operand" "xm")
348             (parallel [(const_int 0)]))
349           (const_int 0)))]
350   "TARGET_SSE2"
351   "%vmovq\t{%1, %0|%0, %1}"
352   [(set_attr "type" "ssemov")
353    (set_attr "prefix" "maybe_vex")
354    (set_attr "mode" "TI")])
355
356 (define_insn "<sse>_movup<ssemodesuffixf2c>"
357   [(set (match_operand:SSEMODEF2P 0 "nonimmediate_operand" "=x,m")
358         (unspec:SSEMODEF2P
359           [(match_operand:SSEMODEF2P 1 "nonimmediate_operand" "xm,x")]
360           UNSPEC_MOVU))]
361   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)
362    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
363   "movup<ssemodesuffixf2c>\t{%1, %0|%0, %1}"
364   [(set_attr "type" "ssemov")
365    (set_attr "movu" "1")
366    (set_attr "mode" "<MODE>")])
367
368 (define_insn "avx_movdqu<avxmodesuffix>"
369   [(set (match_operand:AVXMODEQI 0 "nonimmediate_operand" "=x,m")
370         (unspec:AVXMODEQI
371           [(match_operand:AVXMODEQI 1 "nonimmediate_operand" "xm,x")]
372           UNSPEC_MOVU))]
373   "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
374   "vmovdqu\t{%1, %0|%0, %1}"
375   [(set_attr "type" "ssemov")
376    (set_attr "movu" "1")
377    (set_attr "prefix" "vex")
378    (set_attr "mode" "<avxvecmode>")])
379
380 (define_insn "sse2_movdqu"
381   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
382         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
383                       UNSPEC_MOVU))]
384   "TARGET_SSE2 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
385   "movdqu\t{%1, %0|%0, %1}"
386   [(set_attr "type" "ssemov")
387    (set_attr "movu" "1")
388    (set_attr "prefix_data16" "1")
389    (set_attr "mode" "TI")])
390
391 (define_insn "avx_movnt<mode>"
392   [(set (match_operand:AVXMODEF2P 0 "memory_operand" "=m")
393         (unspec:AVXMODEF2P
394           [(match_operand:AVXMODEF2P 1 "register_operand" "x")]
395           UNSPEC_MOVNT))]
396   "AVX_VEC_FLOAT_MODE_P (<MODE>mode)"
397   "vmovntp<avxmodesuffixf2c>\t{%1, %0|%0, %1}"
398   [(set_attr "type" "ssemov")
399    (set_attr "prefix" "vex")
400    (set_attr "mode" "<MODE>")])
401
402 (define_insn "<sse>_movnt<mode>"
403   [(set (match_operand:SSEMODEF2P 0 "memory_operand" "=m")
404         (unspec:SSEMODEF2P
405           [(match_operand:SSEMODEF2P 1 "register_operand" "x")]
406           UNSPEC_MOVNT))]
407   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
408   "movntp<ssemodesuffixf2c>\t{%1, %0|%0, %1}"
409   [(set_attr "type" "ssemov")
410    (set_attr "mode" "<MODE>")])
411
412 (define_insn "avx_movnt<mode>"
413   [(set (match_operand:AVXMODEDI 0 "memory_operand" "=m")
414         (unspec:AVXMODEDI
415           [(match_operand:AVXMODEDI 1 "register_operand" "x")]
416           UNSPEC_MOVNT))]
417   "TARGET_AVX"
418   "vmovntdq\t{%1, %0|%0, %1}"
419   [(set_attr "type" "ssecvt")
420    (set_attr "prefix" "vex")
421    (set_attr "mode" "<avxvecmode>")])
422
423 (define_insn "sse2_movntv2di"
424   [(set (match_operand:V2DI 0 "memory_operand" "=m")
425         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
426                      UNSPEC_MOVNT))]
427   "TARGET_SSE2"
428   "movntdq\t{%1, %0|%0, %1}"
429   [(set_attr "type" "ssemov")
430    (set_attr "prefix_data16" "1")
431    (set_attr "mode" "TI")])
432
433 (define_insn "sse2_movntsi"
434   [(set (match_operand:SI 0 "memory_operand" "=m")
435         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
436                    UNSPEC_MOVNT))]
437   "TARGET_SSE2"
438   "movnti\t{%1, %0|%0, %1}"
439   [(set_attr "type" "ssemov")
440    (set_attr "mode" "V2DF")])
441
442 (define_insn "avx_lddqu<avxmodesuffix>"
443   [(set (match_operand:AVXMODEQI 0 "register_operand" "=x")
444         (unspec:AVXMODEQI
445           [(match_operand:AVXMODEQI 1 "memory_operand" "m")]
446           UNSPEC_LDDQU))]
447   "TARGET_AVX"
448   "vlddqu\t{%1, %0|%0, %1}"
449   [(set_attr "type" "ssecvt")
450    (set_attr "movu" "1")
451    (set_attr "prefix" "vex")
452    (set_attr "mode" "<avxvecmode>")])
453
454 (define_insn "sse3_lddqu"
455   [(set (match_operand:V16QI 0 "register_operand" "=x")
456         (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
457                       UNSPEC_LDDQU))]
458   "TARGET_SSE3"
459   "lddqu\t{%1, %0|%0, %1}"
460   [(set_attr "type" "ssemov")
461    (set_attr "movu" "1")
462    (set_attr "prefix_rep" "1")
463    (set_attr "mode" "TI")])
464
465 ; Expand patterns for non-temporal stores.  At the moment, only those
466 ; that directly map to insns are defined; it would be possible to
467 ; define patterns for other modes that would expand to several insns.
468
469 (define_expand "storent<mode>"
470   [(set (match_operand:SSEMODEF2P 0 "memory_operand" "")
471         (unspec:SSEMODEF2P
472           [(match_operand:SSEMODEF2P 1 "register_operand" "")]
473           UNSPEC_MOVNT))]
474   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
475   "")
476
477 (define_expand "storent<mode>"
478   [(set (match_operand:MODEF 0 "memory_operand" "")
479         (unspec:MODEF
480           [(match_operand:MODEF 1 "register_operand" "")]
481           UNSPEC_MOVNT))]
482   "TARGET_SSE4A"
483   "")
484
485 (define_expand "storentv2di"
486   [(set (match_operand:V2DI 0 "memory_operand" "")
487         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "")]
488                      UNSPEC_MOVNT))]
489   "TARGET_SSE2"
490   "")
491
492 (define_expand "storentsi"
493   [(set (match_operand:SI 0 "memory_operand" "")
494         (unspec:SI [(match_operand:SI 1 "register_operand" "")]
495                    UNSPEC_MOVNT))]
496   "TARGET_SSE2"
497   "")
498
499 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
500 ;;
501 ;; Parallel floating point arithmetic
502 ;;
503 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
504
505 (define_expand "<code><mode>2"
506   [(set (match_operand:SSEMODEF2P 0 "register_operand" "")
507         (absneg:SSEMODEF2P
508           (match_operand:SSEMODEF2P 1 "register_operand" "")))]
509   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
510   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
511
512 (define_expand "<plusminus_insn><mode>3"
513   [(set (match_operand:AVX256MODEF2P 0 "register_operand" "")
514         (plusminus:AVX256MODEF2P
515           (match_operand:AVX256MODEF2P 1 "nonimmediate_operand" "")
516           (match_operand:AVX256MODEF2P 2 "nonimmediate_operand" "")))]
517   "AVX256_VEC_FLOAT_MODE_P (<MODE>mode)"
518   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
519
520 (define_insn "*avx_<plusminus_insn><mode>3"
521   [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x")
522         (plusminus:AVXMODEF2P
523           (match_operand:AVXMODEF2P 1 "nonimmediate_operand" "<comm>x")
524           (match_operand:AVXMODEF2P 2 "nonimmediate_operand" "xm")))]
525   "AVX_VEC_FLOAT_MODE_P (<MODE>mode)
526    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
527   "v<plusminus_mnemonic>p<avxmodesuffixf2c>\t{%2, %1, %0|%0, %1, %2}"
528   [(set_attr "type" "sseadd")
529    (set_attr "prefix" "vex")
530    (set_attr "mode" "<avxvecmode>")])
531
532 (define_expand "<plusminus_insn><mode>3"
533   [(set (match_operand:SSEMODEF2P 0 "register_operand" "")
534         (plusminus:SSEMODEF2P
535           (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "")
536           (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "")))]
537   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
538   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
539
540 (define_insn "*<plusminus_insn><mode>3"
541   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
542         (plusminus:SSEMODEF2P
543           (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "<comm>0")
544           (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")))]
545   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)
546    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
547   "<plusminus_mnemonic>p<ssemodesuffixf2c>\t{%2, %0|%0, %2}"
548   [(set_attr "type" "sseadd")
549    (set_attr "mode" "<MODE>")])
550
551 (define_insn "*avx_vm<plusminus_insn><mode>3"
552   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
553         (vec_merge:SSEMODEF2P
554           (plusminus:SSEMODEF2P
555             (match_operand:SSEMODEF2P 1 "register_operand" "x")
556             (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm"))
557           (match_dup 1)
558           (const_int 1)))]
559   "AVX128_VEC_FLOAT_MODE_P (<MODE>mode)"
560   "v<plusminus_mnemonic>s<ssemodesuffixf2c>\t{%2, %1, %0|%0, %1, %2}"
561   [(set_attr "type" "sseadd")
562    (set_attr "prefix" "vex")
563    (set_attr "mode" "<ssescalarmode>")])
564
565 (define_insn "<sse>_vm<plusminus_insn><mode>3"
566   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
567         (vec_merge:SSEMODEF2P
568           (plusminus:SSEMODEF2P
569             (match_operand:SSEMODEF2P 1 "register_operand" "0")
570             (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm"))
571           (match_dup 1)
572           (const_int 1)))]
573   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
574   "<plusminus_mnemonic>s<ssemodesuffixf2c>\t{%2, %0|%0, %2}"
575   [(set_attr "type" "sseadd")
576    (set_attr "mode" "<ssescalarmode>")])
577
578 (define_expand "mul<mode>3"
579   [(set (match_operand:AVX256MODEF2P 0 "register_operand" "")
580         (mult:AVX256MODEF2P
581           (match_operand:AVX256MODEF2P 1 "nonimmediate_operand" "")
582           (match_operand:AVX256MODEF2P 2 "nonimmediate_operand" "")))]
583   "AVX256_VEC_FLOAT_MODE_P (<MODE>mode)"
584   "ix86_fixup_binary_operands_no_copy (MULT, <MODE>mode, operands);")
585
586 (define_insn "*avx_mul<mode>3"
587   [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x")
588         (mult:AVXMODEF2P
589           (match_operand:AVXMODEF2P 1 "nonimmediate_operand" "%x")
590           (match_operand:AVXMODEF2P 2 "nonimmediate_operand" "xm")))]
591   "AVX_VEC_FLOAT_MODE_P (<MODE>mode)
592    && ix86_binary_operator_ok (MULT, <MODE>mode, operands)"
593   "vmulp<avxmodesuffixf2c>\t{%2, %1, %0|%0, %1, %2}"
594   [(set_attr "type" "ssemul")
595    (set_attr "prefix" "vex")
596    (set_attr "mode" "<avxvecmode>")])
597
598 (define_expand "mul<mode>3"
599   [(set (match_operand:SSEMODEF2P 0 "register_operand" "")
600         (mult:SSEMODEF2P
601           (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "")
602           (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "")))]
603   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
604   "ix86_fixup_binary_operands_no_copy (MULT, <MODE>mode, operands);")
605
606 (define_insn "*mul<mode>3"
607   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
608         (mult:SSEMODEF2P
609           (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "%0")
610           (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")))]
611   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)
612    && ix86_binary_operator_ok (MULT, <MODE>mode, operands)"
613   "mulp<ssemodesuffixf2c>\t{%2, %0|%0, %2}"
614   [(set_attr "type" "ssemul")
615    (set_attr "mode" "<MODE>")])
616
617 (define_insn "*avx_vmmul<mode>3"
618   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
619         (vec_merge:SSEMODEF2P
620           (mult:SSEMODEF2P
621             (match_operand:SSEMODEF2P 1 "register_operand" "x")
622             (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm"))
623           (match_dup 1)
624           (const_int 1)))]
625   "AVX_VEC_FLOAT_MODE_P (<MODE>mode)"
626   "vmuls<ssemodesuffixf2c>\t{%2, %1, %0|%0, %1, %2}"
627   [(set_attr "type" "ssemul")
628    (set_attr "prefix" "vex")
629    (set_attr "mode" "<ssescalarmode>")])
630
631 (define_insn "<sse>_vmmul<mode>3"
632   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
633         (vec_merge:SSEMODEF2P
634           (mult:SSEMODEF2P
635             (match_operand:SSEMODEF2P 1 "register_operand" "0")
636             (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm"))
637           (match_dup 1)
638           (const_int 1)))]
639   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
640   "muls<ssemodesuffixf2c>\t{%2, %0|%0, %2}"
641   [(set_attr "type" "ssemul")
642    (set_attr "mode" "<ssescalarmode>")])
643
644 (define_expand "divv8sf3"
645   [(set (match_operand:V8SF 0 "register_operand" "")
646         (div:V8SF (match_operand:V8SF 1 "register_operand" "")
647                   (match_operand:V8SF 2 "nonimmediate_operand" "")))]
648   "TARGET_AVX"
649 {
650   ix86_fixup_binary_operands_no_copy (DIV, V8SFmode, operands);
651
652   if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
653       && flag_finite_math_only && !flag_trapping_math
654       && flag_unsafe_math_optimizations)
655     {
656       ix86_emit_swdivsf (operands[0], operands[1],
657                          operands[2], V8SFmode);
658       DONE;
659     }
660 })
661
662 (define_expand "divv4df3"
663   [(set (match_operand:V4DF 0 "register_operand" "")
664         (div:V4DF (match_operand:V4DF 1 "register_operand" "")
665                   (match_operand:V4DF 2 "nonimmediate_operand" "")))]
666   "TARGET_AVX"
667   "ix86_fixup_binary_operands_no_copy (DIV, V4DFmode, operands);")
668
669 (define_insn "avx_div<mode>3"
670   [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x")
671         (div:AVXMODEF2P
672           (match_operand:AVXMODEF2P 1 "register_operand" "x")
673           (match_operand:AVXMODEF2P 2 "nonimmediate_operand" "xm")))]
674   "AVX_VEC_FLOAT_MODE_P (<MODE>mode)"
675   "vdivp<avxmodesuffixf2c>\t{%2, %1, %0|%0, %1, %2}"
676   [(set_attr "type" "ssediv")
677    (set_attr "prefix" "vex")
678    (set_attr "mode" "<MODE>")])
679
680 (define_expand "divv4sf3"
681   [(set (match_operand:V4SF 0 "register_operand" "")
682         (div:V4SF (match_operand:V4SF 1 "register_operand" "")
683                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
684   "TARGET_SSE"
685 {
686   if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
687       && flag_finite_math_only && !flag_trapping_math
688       && flag_unsafe_math_optimizations)
689     {
690       ix86_emit_swdivsf (operands[0], operands[1],
691                          operands[2], V4SFmode);
692       DONE;
693     }
694 })
695
696 (define_expand "divv2df3"
697   [(set (match_operand:V2DF 0 "register_operand" "")
698         (div:V2DF (match_operand:V2DF 1 "register_operand" "")
699                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
700   "TARGET_SSE2"
701   "")
702
703 (define_insn "*avx_div<mode>3"
704   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
705         (div:SSEMODEF2P
706           (match_operand:SSEMODEF2P 1 "register_operand" "x")
707           (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")))]
708   "AVX128_VEC_FLOAT_MODE_P (<MODE>mode)"
709   "vdivp<ssemodesuffixf2c>\t{%2, %1, %0|%0, %1, %2}"
710   [(set_attr "type" "ssediv")
711    (set_attr "prefix" "vex")
712    (set_attr "mode" "<MODE>")])
713
714 (define_insn "<sse>_div<mode>3"
715   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
716         (div:SSEMODEF2P
717           (match_operand:SSEMODEF2P 1 "register_operand" "0")
718           (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")))]
719   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
720   "divp<ssemodesuffixf2c>\t{%2, %0|%0, %2}"
721   [(set_attr "type" "ssediv")
722    (set_attr "mode" "<MODE>")])
723
724 (define_insn "*avx_vmdiv<mode>3"
725   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
726         (vec_merge:SSEMODEF2P
727           (div:SSEMODEF2P
728             (match_operand:SSEMODEF2P 1 "register_operand" "x")
729             (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm"))
730           (match_dup 1)
731           (const_int 1)))]
732   "AVX128_VEC_FLOAT_MODE_P (<MODE>mode)"
733   "vdivs<ssemodesuffixf2c>\t{%2, %1, %0|%0, %1, %2}"
734   [(set_attr "type" "ssediv")
735    (set_attr "prefix" "vex")
736    (set_attr "mode" "<ssescalarmode>")])
737
738 (define_insn "<sse>_vmdiv<mode>3"
739   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
740         (vec_merge:SSEMODEF2P
741           (div:SSEMODEF2P
742             (match_operand:SSEMODEF2P 1 "register_operand" "0")
743             (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm"))
744           (match_dup 1)
745           (const_int 1)))]
746   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
747   "divs<ssemodesuffixf2c>\t{%2, %0|%0, %2}"
748   [(set_attr "type" "ssediv")
749    (set_attr "mode" "<ssescalarmode>")])
750
751 (define_insn "avx_rcpv8sf2"
752   [(set (match_operand:V8SF 0 "register_operand" "=x")
753         (unspec:V8SF
754           [(match_operand:V8SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
755   "TARGET_AVX"
756   "vrcpps\t{%1, %0|%0, %1}"
757   [(set_attr "type" "sse")
758    (set_attr "prefix" "vex")
759    (set_attr "mode" "V8SF")])
760
761 (define_insn "sse_rcpv4sf2"
762   [(set (match_operand:V4SF 0 "register_operand" "=x")
763         (unspec:V4SF
764           [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
765   "TARGET_SSE"
766   "%vrcpps\t{%1, %0|%0, %1}"
767   [(set_attr "type" "sse")
768    (set_attr "atom_sse_attr" "rcp")
769    (set_attr "prefix" "maybe_vex")
770    (set_attr "mode" "V4SF")])
771
772 (define_insn "*avx_vmrcpv4sf2"
773   [(set (match_operand:V4SF 0 "register_operand" "=x")
774         (vec_merge:V4SF
775           (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
776                        UNSPEC_RCP)
777           (match_operand:V4SF 2 "register_operand" "x")
778           (const_int 1)))]
779   "TARGET_AVX"
780   "vrcpss\t{%1, %2, %0|%0, %2, %1}"
781   [(set_attr "type" "sse")
782    (set_attr "prefix" "vex")
783    (set_attr "mode" "SF")])
784
785 (define_insn "sse_vmrcpv4sf2"
786   [(set (match_operand:V4SF 0 "register_operand" "=x")
787         (vec_merge:V4SF
788           (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
789                        UNSPEC_RCP)
790           (match_operand:V4SF 2 "register_operand" "0")
791           (const_int 1)))]
792   "TARGET_SSE"
793   "rcpss\t{%1, %0|%0, %1}"
794   [(set_attr "type" "sse")
795    (set_attr "atom_sse_attr" "rcp")
796    (set_attr "mode" "SF")])
797
798 (define_expand "sqrtv8sf2"
799   [(set (match_operand:V8SF 0 "register_operand" "")
800         (sqrt:V8SF (match_operand:V8SF 1 "nonimmediate_operand" "")))]
801   "TARGET_AVX"
802 {
803   if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
804       && flag_finite_math_only && !flag_trapping_math
805       && flag_unsafe_math_optimizations)
806     {
807       ix86_emit_swsqrtsf (operands[0], operands[1], V8SFmode, 0);
808       DONE;
809     }
810 })
811
812 (define_insn "avx_sqrtv8sf2"
813   [(set (match_operand:V8SF 0 "register_operand" "=x")
814         (sqrt:V8SF (match_operand:V8SF 1 "nonimmediate_operand" "xm")))]
815   "TARGET_AVX"
816   "vsqrtps\t{%1, %0|%0, %1}"
817   [(set_attr "type" "sse")
818    (set_attr "prefix" "vex")
819    (set_attr "mode" "V8SF")])
820
821 (define_expand "sqrtv4sf2"
822   [(set (match_operand:V4SF 0 "register_operand" "")
823         (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "")))]
824   "TARGET_SSE"
825 {
826   if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
827       && flag_finite_math_only && !flag_trapping_math
828       && flag_unsafe_math_optimizations)
829     {
830       ix86_emit_swsqrtsf (operands[0], operands[1], V4SFmode, 0);
831       DONE;
832     }
833 })
834
835 (define_insn "sse_sqrtv4sf2"
836   [(set (match_operand:V4SF 0 "register_operand" "=x")
837         (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
838   "TARGET_SSE"
839   "%vsqrtps\t{%1, %0|%0, %1}"
840   [(set_attr "type" "sse")
841    (set_attr "atom_sse_attr" "sqrt")
842    (set_attr "prefix" "maybe_vex")
843    (set_attr "mode" "V4SF")])
844
845 (define_insn "sqrtv4df2"
846   [(set (match_operand:V4DF 0 "register_operand" "=x")
847         (sqrt:V4DF (match_operand:V4DF 1 "nonimmediate_operand" "xm")))]
848   "TARGET_AVX"
849   "vsqrtpd\t{%1, %0|%0, %1}"
850   [(set_attr "type" "sse")
851    (set_attr "prefix" "vex")
852    (set_attr "mode" "V4DF")])
853
854 (define_insn "sqrtv2df2"
855   [(set (match_operand:V2DF 0 "register_operand" "=x")
856         (sqrt:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
857   "TARGET_SSE2"
858   "%vsqrtpd\t{%1, %0|%0, %1}"
859   [(set_attr "type" "sse")
860    (set_attr "prefix" "maybe_vex")
861    (set_attr "mode" "V2DF")])
862
863 (define_insn "*avx_vmsqrt<mode>2"
864   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
865         (vec_merge:SSEMODEF2P
866           (sqrt:SSEMODEF2P
867             (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "xm"))
868           (match_operand:SSEMODEF2P 2 "register_operand" "x")
869           (const_int 1)))]
870   "AVX_VEC_FLOAT_MODE_P (<MODE>mode)"
871   "vsqrts<ssemodesuffixf2c>\t{%1, %2, %0|%0, %2, %1}"
872   [(set_attr "type" "sse")
873    (set_attr "prefix" "vex")
874    (set_attr "mode" "<ssescalarmode>")])
875
876 (define_insn "<sse>_vmsqrt<mode>2"
877   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
878         (vec_merge:SSEMODEF2P
879           (sqrt:SSEMODEF2P
880             (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "xm"))
881           (match_operand:SSEMODEF2P 2 "register_operand" "0")
882           (const_int 1)))]
883   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
884   "sqrts<ssemodesuffixf2c>\t{%1, %0|%0, %1}"
885   [(set_attr "type" "sse")
886    (set_attr "atom_sse_attr" "sqrt")
887    (set_attr "mode" "<ssescalarmode>")])
888
889 (define_expand "rsqrtv8sf2"
890   [(set (match_operand:V8SF 0 "register_operand" "")
891         (unspec:V8SF
892           [(match_operand:V8SF 1 "nonimmediate_operand" "")] UNSPEC_RSQRT))]
893   "TARGET_AVX && TARGET_SSE_MATH"
894 {
895   ix86_emit_swsqrtsf (operands[0], operands[1], V8SFmode, 1);
896   DONE;
897 })
898
899 (define_insn "avx_rsqrtv8sf2"
900   [(set (match_operand:V8SF 0 "register_operand" "=x")
901         (unspec:V8SF
902           [(match_operand:V8SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
903   "TARGET_AVX"
904   "vrsqrtps\t{%1, %0|%0, %1}"
905   [(set_attr "type" "sse")
906    (set_attr "prefix" "vex")
907    (set_attr "mode" "V8SF")])
908
909 (define_expand "rsqrtv4sf2"
910   [(set (match_operand:V4SF 0 "register_operand" "")
911         (unspec:V4SF
912           [(match_operand:V4SF 1 "nonimmediate_operand" "")] UNSPEC_RSQRT))]
913   "TARGET_SSE_MATH"
914 {
915   ix86_emit_swsqrtsf (operands[0], operands[1], V4SFmode, 1);
916   DONE;
917 })
918
919 (define_insn "sse_rsqrtv4sf2"
920   [(set (match_operand:V4SF 0 "register_operand" "=x")
921         (unspec:V4SF
922           [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
923   "TARGET_SSE"
924   "%vrsqrtps\t{%1, %0|%0, %1}"
925   [(set_attr "type" "sse")
926    (set_attr "prefix" "maybe_vex")
927    (set_attr "mode" "V4SF")])
928
929 (define_insn "*avx_vmrsqrtv4sf2"
930   [(set (match_operand:V4SF 0 "register_operand" "=x")
931         (vec_merge:V4SF
932           (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
933                        UNSPEC_RSQRT)
934           (match_operand:V4SF 2 "register_operand" "x")
935           (const_int 1)))]
936   "TARGET_AVX"
937   "vrsqrtss\t{%1, %2, %0|%0, %2, %1}"
938   [(set_attr "type" "sse")
939    (set_attr "prefix" "vex")
940    (set_attr "mode" "SF")])
941
942 (define_insn "sse_vmrsqrtv4sf2"
943   [(set (match_operand:V4SF 0 "register_operand" "=x")
944         (vec_merge:V4SF
945           (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
946                        UNSPEC_RSQRT)
947           (match_operand:V4SF 2 "register_operand" "0")
948           (const_int 1)))]
949   "TARGET_SSE"
950   "rsqrtss\t{%1, %0|%0, %1}"
951   [(set_attr "type" "sse")
952    (set_attr "mode" "SF")])
953
954 ;; ??? For !flag_finite_math_only, the representation with SMIN/SMAX
955 ;; isn't really correct, as those rtl operators aren't defined when
956 ;; applied to NaNs.  Hopefully the optimizers won't get too smart on us.
957
958 (define_expand "<code><mode>3"
959   [(set (match_operand:AVX256MODEF2P 0 "register_operand" "")
960         (smaxmin:AVX256MODEF2P
961           (match_operand:AVX256MODEF2P 1 "nonimmediate_operand" "")
962           (match_operand:AVX256MODEF2P 2 "nonimmediate_operand" "")))]
963   "AVX256_VEC_FLOAT_MODE_P (<MODE>mode)"
964 {
965   if (!flag_finite_math_only)
966     operands[1] = force_reg (<MODE>mode, operands[1]);
967   ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);
968 })
969
970 (define_expand "<code><mode>3"
971   [(set (match_operand:SSEMODEF2P 0 "register_operand" "")
972         (smaxmin:SSEMODEF2P
973           (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "")
974           (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "")))]
975   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
976 {
977   if (!flag_finite_math_only)
978     operands[1] = force_reg (<MODE>mode, operands[1]);
979   ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);
980 })
981
982 (define_insn "*avx_<code><mode>3_finite"
983   [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x")
984         (smaxmin:AVXMODEF2P
985           (match_operand:AVXMODEF2P 1 "nonimmediate_operand" "%x")
986           (match_operand:AVXMODEF2P 2 "nonimmediate_operand" "xm")))]
987   "AVX_VEC_FLOAT_MODE_P (<MODE>mode) && flag_finite_math_only
988    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
989   "v<maxminfprefix>p<avxmodesuffixf2c>\t{%2, %1, %0|%0, %1, %2}"
990   [(set_attr "type" "sseadd")
991    (set_attr "prefix" "vex")
992    (set_attr "mode" "<MODE>")])
993
994 (define_insn "*<code><mode>3_finite"
995   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
996         (smaxmin:SSEMODEF2P
997           (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "%0")
998           (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")))]
999   "SSE_VEC_FLOAT_MODE_P (<MODE>mode) && flag_finite_math_only
1000    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
1001   "<maxminfprefix>p<ssemodesuffixf2c>\t{%2, %0|%0, %2}"
1002   [(set_attr "type" "sseadd")
1003    (set_attr "mode" "<MODE>")])
1004
1005 (define_insn "*avx_<code><mode>3"
1006   [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x")
1007         (smaxmin:AVXMODEF2P
1008           (match_operand:AVXMODEF2P 1 "nonimmediate_operand" "%x")
1009           (match_operand:AVXMODEF2P 2 "nonimmediate_operand" "xm")))]
1010   "AVX_VEC_FLOAT_MODE_P (<MODE>mode)"
1011   "v<maxminfprefix>p<avxmodesuffixf2c>\t{%2, %1, %0|%0, %1, %2}"
1012   [(set_attr "type" "sseadd")
1013    (set_attr "prefix" "vex")
1014    (set_attr "mode" "<avxvecmode>")])
1015
1016 (define_insn "*<code><mode>3"
1017   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
1018         (smaxmin:SSEMODEF2P
1019           (match_operand:SSEMODEF2P 1 "register_operand" "0")
1020           (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")))]
1021   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
1022   "<maxminfprefix>p<ssemodesuffixf2c>\t{%2, %0|%0, %2}"
1023   [(set_attr "type" "sseadd")
1024    (set_attr "mode" "<MODE>")])
1025
1026 (define_insn "*avx_vm<code><mode>3"
1027   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
1028         (vec_merge:SSEMODEF2P
1029           (smaxmin:SSEMODEF2P
1030             (match_operand:SSEMODEF2P 1 "register_operand" "x")
1031             (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm"))
1032          (match_dup 1)
1033          (const_int 1)))]
1034   "AVX128_VEC_FLOAT_MODE_P (<MODE>mode)"
1035   "v<maxminfprefix>s<ssemodesuffixf2c>\t{%2, %1, %0|%0, %1, %2}"
1036   [(set_attr "type" "sse")
1037    (set_attr "prefix" "vex")
1038    (set_attr "mode" "<ssescalarmode>")])
1039
1040 (define_insn "<sse>_vm<code><mode>3"
1041   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
1042         (vec_merge:SSEMODEF2P
1043           (smaxmin:SSEMODEF2P
1044             (match_operand:SSEMODEF2P 1 "register_operand" "0")
1045             (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm"))
1046          (match_dup 1)
1047          (const_int 1)))]
1048   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
1049   "<maxminfprefix>s<ssemodesuffixf2c>\t{%2, %0|%0, %2}"
1050   [(set_attr "type" "sseadd")
1051    (set_attr "mode" "<ssescalarmode>")])
1052
1053 ;; These versions of the min/max patterns implement exactly the operations
1054 ;;   min = (op1 < op2 ? op1 : op2)
1055 ;;   max = (!(op1 < op2) ? op1 : op2)
1056 ;; Their operands are not commutative, and thus they may be used in the
1057 ;; presence of -0.0 and NaN.
1058
1059 (define_insn "*avx_ieee_smin<mode>3"
1060   [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x")
1061         (unspec:AVXMODEF2P
1062           [(match_operand:AVXMODEF2P 1 "register_operand" "x")
1063            (match_operand:AVXMODEF2P 2 "nonimmediate_operand" "xm")]
1064          UNSPEC_IEEE_MIN))]
1065   "AVX_VEC_FLOAT_MODE_P (<MODE>mode)"
1066   "vminp<avxmodesuffixf2c>\t{%2, %1, %0|%0, %1, %2}"
1067   [(set_attr "type" "sseadd")
1068    (set_attr "prefix" "vex")
1069    (set_attr "mode" "<avxvecmode>")])
1070
1071 (define_insn "*avx_ieee_smax<mode>3"
1072   [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x")
1073         (unspec:AVXMODEF2P
1074           [(match_operand:AVXMODEF2P 1 "register_operand" "x")
1075            (match_operand:AVXMODEF2P 2 "nonimmediate_operand" "xm")]
1076          UNSPEC_IEEE_MAX))]
1077   "AVX_VEC_FLOAT_MODE_P (<MODE>mode)"
1078   "vmaxp<avxmodesuffixf2c>\t{%2, %1, %0|%0, %1, %2}"
1079   [(set_attr "type" "sseadd")
1080    (set_attr "prefix" "vex")
1081    (set_attr "mode" "<avxvecmode>")])
1082
1083 (define_insn "*ieee_smin<mode>3"
1084   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
1085         (unspec:SSEMODEF2P
1086           [(match_operand:SSEMODEF2P 1 "register_operand" "0")
1087            (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")]
1088          UNSPEC_IEEE_MIN))]
1089   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
1090   "minp<ssemodesuffixf2c>\t{%2, %0|%0, %2}"
1091   [(set_attr "type" "sseadd")
1092    (set_attr "mode" "<MODE>")])
1093
1094 (define_insn "*ieee_smax<mode>3"
1095   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
1096         (unspec:SSEMODEF2P
1097           [(match_operand:SSEMODEF2P 1 "register_operand" "0")
1098            (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")]
1099          UNSPEC_IEEE_MAX))]
1100   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
1101   "maxp<ssemodesuffixf2c>\t{%2, %0|%0, %2}"
1102   [(set_attr "type" "sseadd")
1103    (set_attr "mode" "<MODE>")])
1104
1105 (define_insn "avx_addsubv8sf3"
1106   [(set (match_operand:V8SF 0 "register_operand" "=x")
1107         (vec_merge:V8SF
1108           (plus:V8SF
1109             (match_operand:V8SF 1 "register_operand" "x")
1110             (match_operand:V8SF 2 "nonimmediate_operand" "xm"))
1111           (minus:V8SF (match_dup 1) (match_dup 2))
1112           (const_int 170)))]
1113   "TARGET_AVX"
1114   "vaddsubps\t{%2, %1, %0|%0, %1, %2}"
1115   [(set_attr "type" "sseadd")
1116    (set_attr "prefix" "vex")
1117    (set_attr "mode" "V8SF")])
1118
1119 (define_insn "avx_addsubv4df3"
1120   [(set (match_operand:V4DF 0 "register_operand" "=x")
1121         (vec_merge:V4DF
1122           (plus:V4DF
1123             (match_operand:V4DF 1 "register_operand" "x")
1124             (match_operand:V4DF 2 "nonimmediate_operand" "xm"))
1125           (minus:V4DF (match_dup 1) (match_dup 2))
1126           (const_int 10)))]
1127   "TARGET_AVX"
1128   "vaddsubpd\t{%2, %1, %0|%0, %1, %2}"
1129   [(set_attr "type" "sseadd")
1130    (set_attr "prefix" "vex")
1131    (set_attr "mode" "V4DF")])
1132
1133 (define_insn "*avx_addsubv4sf3"
1134   [(set (match_operand:V4SF 0 "register_operand" "=x")
1135         (vec_merge:V4SF
1136           (plus:V4SF
1137             (match_operand:V4SF 1 "register_operand" "x")
1138             (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
1139           (minus:V4SF (match_dup 1) (match_dup 2))
1140           (const_int 10)))]
1141   "TARGET_AVX"
1142   "vaddsubps\t{%2, %1, %0|%0, %1, %2}"
1143   [(set_attr "type" "sseadd")
1144    (set_attr "prefix" "vex")
1145    (set_attr "mode" "V4SF")])
1146
1147 (define_insn "sse3_addsubv4sf3"
1148   [(set (match_operand:V4SF 0 "register_operand" "=x")
1149         (vec_merge:V4SF
1150           (plus:V4SF
1151             (match_operand:V4SF 1 "register_operand" "0")
1152             (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
1153           (minus:V4SF (match_dup 1) (match_dup 2))
1154           (const_int 10)))]
1155   "TARGET_SSE3"
1156   "addsubps\t{%2, %0|%0, %2}"
1157   [(set_attr "type" "sseadd")
1158    (set_attr "prefix_rep" "1")
1159    (set_attr "mode" "V4SF")])
1160
1161 (define_insn "*avx_addsubv2df3"
1162   [(set (match_operand:V2DF 0 "register_operand" "=x")
1163         (vec_merge:V2DF
1164           (plus:V2DF
1165             (match_operand:V2DF 1 "register_operand" "x")
1166             (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
1167           (minus:V2DF (match_dup 1) (match_dup 2))
1168           (const_int 2)))]
1169   "TARGET_AVX"
1170   "vaddsubpd\t{%2, %1, %0|%0, %1, %2}"
1171   [(set_attr "type" "sseadd")
1172    (set_attr "prefix" "vex")
1173    (set_attr "mode" "V2DF")])
1174
1175 (define_insn "sse3_addsubv2df3"
1176   [(set (match_operand:V2DF 0 "register_operand" "=x")
1177         (vec_merge:V2DF
1178           (plus:V2DF
1179             (match_operand:V2DF 1 "register_operand" "0")
1180             (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
1181           (minus:V2DF (match_dup 1) (match_dup 2))
1182           (const_int 2)))]
1183   "TARGET_SSE3"
1184   "addsubpd\t{%2, %0|%0, %2}"
1185   [(set_attr "type" "sseadd")
1186    (set_attr "atom_unit" "complex")
1187    (set_attr "mode" "V2DF")])
1188
1189 (define_insn "avx_h<plusminus_insn>v4df3"
1190   [(set (match_operand:V4DF 0 "register_operand" "=x")
1191         (vec_concat:V4DF
1192           (vec_concat:V2DF
1193             (plusminus:DF
1194               (vec_select:DF
1195                 (match_operand:V4DF 1 "register_operand" "x")
1196                 (parallel [(const_int 0)]))
1197               (vec_select:DF (match_dup 1) (parallel [(const_int 1)])))
1198             (plusminus:DF
1199               (vec_select:DF (match_dup 1) (parallel [(const_int 2)]))
1200               (vec_select:DF (match_dup 1) (parallel [(const_int 3)]))))
1201           (vec_concat:V2DF
1202             (plusminus:DF
1203               (vec_select:DF
1204                 (match_operand:V4DF 2 "nonimmediate_operand" "xm")
1205                 (parallel [(const_int 0)]))
1206               (vec_select:DF (match_dup 2) (parallel [(const_int 1)])))
1207             (plusminus:DF
1208               (vec_select:DF (match_dup 2) (parallel [(const_int 2)]))
1209               (vec_select:DF (match_dup 2) (parallel [(const_int 3)]))))))]
1210   "TARGET_AVX"
1211   "vh<plusminus_mnemonic>pd\t{%2, %1, %0|%0, %1, %2}"
1212   [(set_attr "type" "sseadd")
1213    (set_attr "prefix" "vex")
1214    (set_attr "mode" "V4DF")])
1215
1216 (define_insn "avx_h<plusminus_insn>v8sf3"
1217   [(set (match_operand:V8SF 0 "register_operand" "=x")
1218         (vec_concat:V8SF
1219           (vec_concat:V4SF
1220             (vec_concat:V2SF
1221               (plusminus:SF
1222                 (vec_select:SF
1223                   (match_operand:V8SF 1 "register_operand" "x")
1224                   (parallel [(const_int 0)]))
1225                 (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
1226               (plusminus:SF
1227                 (vec_select:SF (match_dup 1) (parallel [(const_int 2)]))
1228                 (vec_select:SF (match_dup 1) (parallel [(const_int 3)]))))
1229             (vec_concat:V2SF
1230               (plusminus:SF
1231                 (vec_select:SF
1232                   (match_operand:V8SF 2 "nonimmediate_operand" "xm")
1233                   (parallel [(const_int 0)]))
1234                 (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))
1235               (plusminus:SF
1236                 (vec_select:SF (match_dup 2) (parallel [(const_int 2)]))
1237                 (vec_select:SF (match_dup 2) (parallel [(const_int 3)])))))
1238           (vec_concat:V4SF
1239             (vec_concat:V2SF
1240               (plusminus:SF
1241                 (vec_select:SF (match_dup 1) (parallel [(const_int 4)]))
1242                 (vec_select:SF (match_dup 1) (parallel [(const_int 5)])))
1243               (plusminus:SF
1244                 (vec_select:SF (match_dup 1) (parallel [(const_int 6)]))
1245                 (vec_select:SF (match_dup 1) (parallel [(const_int 7)]))))
1246             (vec_concat:V2SF
1247               (plusminus:SF
1248                 (vec_select:SF (match_dup 2) (parallel [(const_int 4)]))
1249                 (vec_select:SF (match_dup 2) (parallel [(const_int 5)])))
1250               (plusminus:SF
1251                 (vec_select:SF (match_dup 2) (parallel [(const_int 6)]))
1252                 (vec_select:SF (match_dup 2) (parallel [(const_int 7)])))))))]
1253   "TARGET_AVX"
1254   "vh<plusminus_mnemonic>ps\t{%2, %1, %0|%0, %1, %2}"
1255   [(set_attr "type" "sseadd")
1256    (set_attr "prefix" "vex")
1257    (set_attr "mode" "V8SF")])
1258
1259 (define_insn "*avx_h<plusminus_insn>v4sf3"
1260   [(set (match_operand:V4SF 0 "register_operand" "=x")
1261         (vec_concat:V4SF
1262           (vec_concat:V2SF
1263             (plusminus:SF
1264               (vec_select:SF
1265                 (match_operand:V4SF 1 "register_operand" "x")
1266                 (parallel [(const_int 0)]))
1267               (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
1268             (plusminus:SF
1269               (vec_select:SF (match_dup 1) (parallel [(const_int 2)]))
1270               (vec_select:SF (match_dup 1) (parallel [(const_int 3)]))))
1271           (vec_concat:V2SF
1272             (plusminus:SF
1273               (vec_select:SF
1274                 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
1275                 (parallel [(const_int 0)]))
1276               (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))
1277             (plusminus:SF
1278               (vec_select:SF (match_dup 2) (parallel [(const_int 2)]))
1279               (vec_select:SF (match_dup 2) (parallel [(const_int 3)]))))))]
1280   "TARGET_AVX"
1281   "vh<plusminus_mnemonic>ps\t{%2, %1, %0|%0, %1, %2}"
1282   [(set_attr "type" "sseadd")
1283    (set_attr "prefix" "vex")
1284    (set_attr "mode" "V4SF")])
1285
1286 (define_insn "sse3_h<plusminus_insn>v4sf3"
1287   [(set (match_operand:V4SF 0 "register_operand" "=x")
1288         (vec_concat:V4SF
1289           (vec_concat:V2SF
1290             (plusminus:SF
1291               (vec_select:SF
1292                 (match_operand:V4SF 1 "register_operand" "0")
1293                 (parallel [(const_int 0)]))
1294               (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
1295             (plusminus:SF
1296               (vec_select:SF (match_dup 1) (parallel [(const_int 2)]))
1297               (vec_select:SF (match_dup 1) (parallel [(const_int 3)]))))
1298           (vec_concat:V2SF
1299             (plusminus:SF
1300               (vec_select:SF
1301                 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
1302                 (parallel [(const_int 0)]))
1303               (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))
1304             (plusminus:SF
1305               (vec_select:SF (match_dup 2) (parallel [(const_int 2)]))
1306               (vec_select:SF (match_dup 2) (parallel [(const_int 3)]))))))]
1307   "TARGET_SSE3"
1308   "h<plusminus_mnemonic>ps\t{%2, %0|%0, %2}"
1309   [(set_attr "type" "sseadd")
1310    (set_attr "atom_unit" "complex")
1311    (set_attr "prefix_rep" "1")
1312    (set_attr "mode" "V4SF")])
1313
1314 (define_insn "*avx_h<plusminus_insn>v2df3"
1315   [(set (match_operand:V2DF 0 "register_operand" "=x")
1316         (vec_concat:V2DF
1317           (plusminus:DF
1318             (vec_select:DF
1319               (match_operand:V2DF 1 "register_operand" "x")
1320               (parallel [(const_int 0)]))
1321             (vec_select:DF (match_dup 1) (parallel [(const_int 1)])))
1322           (plusminus:DF
1323             (vec_select:DF
1324               (match_operand:V2DF 2 "nonimmediate_operand" "xm")
1325               (parallel [(const_int 0)]))
1326             (vec_select:DF (match_dup 2) (parallel [(const_int 1)])))))]
1327   "TARGET_AVX"
1328   "vh<plusminus_mnemonic>pd\t{%2, %1, %0|%0, %1, %2}"
1329   [(set_attr "type" "sseadd")
1330    (set_attr "prefix" "vex")
1331    (set_attr "mode" "V2DF")])
1332
1333 (define_insn "sse3_h<plusminus_insn>v2df3"
1334   [(set (match_operand:V2DF 0 "register_operand" "=x")
1335         (vec_concat:V2DF
1336           (plusminus:DF
1337             (vec_select:DF
1338               (match_operand:V2DF 1 "register_operand" "0")
1339               (parallel [(const_int 0)]))
1340             (vec_select:DF (match_dup 1) (parallel [(const_int 1)])))
1341           (plusminus:DF
1342             (vec_select:DF
1343               (match_operand:V2DF 2 "nonimmediate_operand" "xm")
1344               (parallel [(const_int 0)]))
1345             (vec_select:DF (match_dup 2) (parallel [(const_int 1)])))))]
1346   "TARGET_SSE3"
1347   "h<plusminus_mnemonic>pd\t{%2, %0|%0, %2}"
1348   [(set_attr "type" "sseadd")
1349    (set_attr "mode" "V2DF")])
1350
1351 (define_expand "reduc_splus_v4sf"
1352   [(match_operand:V4SF 0 "register_operand" "")
1353    (match_operand:V4SF 1 "register_operand" "")]
1354   "TARGET_SSE"
1355 {
1356   if (TARGET_SSE3)
1357     {
1358       rtx tmp = gen_reg_rtx (V4SFmode);
1359       emit_insn (gen_sse3_haddv4sf3 (tmp, operands[1], operands[1]));
1360       emit_insn (gen_sse3_haddv4sf3 (operands[0], tmp, tmp));
1361     }
1362   else
1363     ix86_expand_reduc_v4sf (gen_addv4sf3, operands[0], operands[1]);
1364   DONE;
1365 })
1366
1367 (define_expand "reduc_splus_v2df"
1368   [(match_operand:V2DF 0 "register_operand" "")
1369    (match_operand:V2DF 1 "register_operand" "")]
1370   "TARGET_SSE3"
1371 {
1372   emit_insn (gen_sse3_haddv2df3 (operands[0], operands[1], operands[1]));
1373   DONE;
1374 })
1375
1376 (define_expand "reduc_smax_v4sf"
1377   [(match_operand:V4SF 0 "register_operand" "")
1378    (match_operand:V4SF 1 "register_operand" "")]
1379   "TARGET_SSE"
1380 {
1381   ix86_expand_reduc_v4sf (gen_smaxv4sf3, operands[0], operands[1]);
1382   DONE;
1383 })
1384
1385 (define_expand "reduc_smin_v4sf"
1386   [(match_operand:V4SF 0 "register_operand" "")
1387    (match_operand:V4SF 1 "register_operand" "")]
1388   "TARGET_SSE"
1389 {
1390   ix86_expand_reduc_v4sf (gen_sminv4sf3, operands[0], operands[1]);
1391   DONE;
1392 })
1393
1394 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1395 ;;
1396 ;; Parallel floating point comparisons
1397 ;;
1398 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1399
1400 (define_insn "avx_cmpp<avxmodesuffixf2c><mode>3"
1401   [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x")
1402         (unspec:AVXMODEF2P
1403           [(match_operand:AVXMODEF2P 1 "register_operand" "x")
1404            (match_operand:AVXMODEF2P 2 "nonimmediate_operand" "xm")
1405            (match_operand:SI 3 "const_0_to_31_operand" "n")]
1406           UNSPEC_PCMP))]
1407   "TARGET_AVX"
1408   "vcmpp<avxmodesuffixf2c>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1409   [(set_attr "type" "ssecmp")
1410    (set_attr "prefix" "vex")
1411    (set_attr "mode" "<MODE>")])
1412
1413 (define_insn "avx_cmps<ssemodesuffixf2c><mode>3"
1414   [(set (match_operand:SSEMODEF2P 0 "register_operand" "")
1415         (vec_merge:SSEMODEF2P
1416           (unspec:SSEMODEF2P
1417             [(match_operand:SSEMODEF2P 1 "register_operand" "x")
1418              (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")
1419              (match_operand:SI 3 "const_0_to_31_operand" "n")]
1420             UNSPEC_PCMP)
1421          (match_dup 1)
1422          (const_int 1)))]
1423   "TARGET_AVX"
1424   "vcmps<ssemodesuffixf2c>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1425   [(set_attr "type" "ssecmp")
1426    (set_attr "prefix" "vex")
1427    (set_attr "mode" "<ssescalarmode>")])
1428
1429 ;; We don't promote 128bit vector compare intrinsics. But vectorizer
1430 ;; may generate 256bit vector compare instructions.
1431 (define_insn "*avx_maskcmp<mode>3"
1432   [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x")
1433         (match_operator:AVXMODEF2P 3 "avx_comparison_float_operator"
1434                 [(match_operand:AVXMODEF2P 1 "register_operand" "x")
1435                  (match_operand:AVXMODEF2P 2 "nonimmediate_operand" "xm")]))]
1436   "AVX_VEC_FLOAT_MODE_P (<MODE>mode)"
1437   "vcmp%D3p<avxmodesuffixf2c>\t{%2, %1, %0|%0, %1, %2}"
1438   [(set_attr "type" "ssecmp")
1439    (set_attr "prefix" "vex")
1440    (set_attr "mode" "<avxvecmode>")])
1441
1442 (define_insn "<sse>_maskcmp<mode>3"
1443   [(set (match_operand:SSEMODEF4 0 "register_operand" "=x")
1444         (match_operator:SSEMODEF4 3 "sse_comparison_operator"
1445                 [(match_operand:SSEMODEF4 1 "register_operand" "0")
1446                  (match_operand:SSEMODEF4 2 "nonimmediate_operand" "xm")]))]
1447   "(SSE_FLOAT_MODE_P (<MODE>mode) || SSE_VEC_FLOAT_MODE_P (<MODE>mode))
1448    && !TARGET_SSE5"
1449   "cmp%D3<ssemodesuffixf4>\t{%2, %0|%0, %2}"
1450   [(set_attr "type" "ssecmp")
1451    (set_attr "mode" "<MODE>")])
1452
1453 (define_insn "<sse>_vmmaskcmp<mode>3"
1454   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
1455         (vec_merge:SSEMODEF2P
1456          (match_operator:SSEMODEF2P 3 "sse_comparison_operator"
1457                 [(match_operand:SSEMODEF2P 1 "register_operand" "0")
1458                  (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")])
1459          (match_dup 1)
1460          (const_int 1)))]
1461   "SSE_VEC_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
1462   "cmp%D3s<ssemodesuffixf2c>\t{%2, %0|%0, %2}"
1463   [(set_attr "type" "ssecmp")
1464    (set_attr "mode" "<ssescalarmode>")])
1465
1466 (define_insn "<sse>_comi"
1467   [(set (reg:CCFP FLAGS_REG)
1468         (compare:CCFP
1469           (vec_select:MODEF
1470             (match_operand:<ssevecmode> 0 "register_operand" "x")
1471             (parallel [(const_int 0)]))
1472           (vec_select:MODEF
1473             (match_operand:<ssevecmode> 1 "nonimmediate_operand" "xm")
1474             (parallel [(const_int 0)]))))]
1475   "SSE_FLOAT_MODE_P (<MODE>mode)"
1476   "%vcomis<ssemodefsuffix>\t{%1, %0|%0, %1}"
1477   [(set_attr "type" "ssecomi")
1478    (set_attr "prefix" "maybe_vex")
1479    (set_attr "mode" "<MODE>")])
1480
1481 (define_insn "<sse>_ucomi"
1482   [(set (reg:CCFPU FLAGS_REG)
1483         (compare:CCFPU
1484           (vec_select:MODEF
1485             (match_operand:<ssevecmode> 0 "register_operand" "x")
1486             (parallel [(const_int 0)]))
1487           (vec_select:MODEF
1488             (match_operand:<ssevecmode> 1 "nonimmediate_operand" "xm")
1489             (parallel [(const_int 0)]))))]
1490   "SSE_FLOAT_MODE_P (<MODE>mode)"
1491   "%vucomis<ssemodefsuffix>\t{%1, %0|%0, %1}"
1492   [(set_attr "type" "ssecomi")
1493    (set_attr "prefix" "maybe_vex")
1494    (set_attr "mode" "<MODE>")])
1495
1496 (define_expand "vcond<mode>"
1497   [(set (match_operand:SSEMODEF2P 0 "register_operand" "")
1498         (if_then_else:SSEMODEF2P
1499           (match_operator 3 ""
1500             [(match_operand:SSEMODEF2P 4 "nonimmediate_operand" "")
1501              (match_operand:SSEMODEF2P 5 "nonimmediate_operand" "")])
1502           (match_operand:SSEMODEF2P 1 "general_operand" "")
1503           (match_operand:SSEMODEF2P 2 "general_operand" "")))]
1504   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
1505 {
1506   if (ix86_expand_fp_vcond (operands))
1507     DONE;
1508   else
1509     FAIL;
1510 })
1511
1512 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1513 ;;
1514 ;; Parallel floating point logical operations
1515 ;;
1516 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1517
1518 (define_insn "avx_andnot<mode>3"
1519   [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x")
1520         (and:AVXMODEF2P
1521           (not:AVXMODEF2P
1522             (match_operand:AVXMODEF2P 1 "register_operand" "x"))
1523           (match_operand:AVXMODEF2P 2 "nonimmediate_operand" "xm")))]
1524   "AVX_VEC_FLOAT_MODE_P (<MODE>mode)"
1525   "vandnp<avxmodesuffixf2c>\t{%2, %1, %0|%0, %1, %2}"
1526   [(set_attr "type" "sselog")
1527    (set_attr "prefix" "vex")
1528    (set_attr "mode" "<avxvecmode>")])
1529
1530 (define_insn "<sse>_andnot<mode>3"
1531   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
1532         (and:SSEMODEF2P
1533           (not:SSEMODEF2P
1534             (match_operand:SSEMODEF2P 1 "register_operand" "0"))
1535           (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")))]
1536   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
1537   "andnp<ssemodesuffixf2c>\t{%2, %0|%0, %2}"
1538   [(set_attr "type" "sselog")
1539    (set_attr "mode" "<MODE>")])
1540
1541 (define_expand "<code><mode>3"
1542   [(set (match_operand:AVX256MODEF2P 0 "register_operand" "")
1543         (plogic:AVX256MODEF2P
1544           (match_operand:AVX256MODEF2P 1 "nonimmediate_operand" "")
1545           (match_operand:AVX256MODEF2P 2 "nonimmediate_operand" "")))]
1546   "AVX256_VEC_FLOAT_MODE_P (<MODE>mode)"
1547   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
1548
1549 (define_insn "*avx_<code><mode>3"
1550   [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x")
1551         (plogic:AVXMODEF2P
1552           (match_operand:AVXMODEF2P 1 "nonimmediate_operand" "%x")
1553           (match_operand:AVXMODEF2P 2 "nonimmediate_operand" "xm")))]
1554   "AVX_VEC_FLOAT_MODE_P (<MODE>mode)
1555    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
1556   "v<plogicprefix>p<avxmodesuffixf2c>\t{%2, %1, %0|%0, %1, %2}"
1557   [(set_attr "type" "sselog")
1558    (set_attr "prefix" "vex")
1559    (set_attr "mode" "<avxvecmode>")])
1560
1561 (define_expand "<code><mode>3"
1562   [(set (match_operand:SSEMODEF2P 0 "register_operand" "")
1563         (plogic:SSEMODEF2P
1564           (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "")
1565           (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "")))]
1566   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
1567   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
1568
1569 (define_insn "*<code><mode>3"
1570   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
1571         (plogic:SSEMODEF2P
1572           (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "%0")
1573           (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")))]
1574   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)
1575    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
1576   "<plogicprefix>p<ssemodesuffixf2c>\t{%2, %0|%0, %2}"
1577   [(set_attr "type" "sselog")
1578    (set_attr "mode" "<MODE>")])
1579
1580 ;; Also define scalar versions.  These are used for abs, neg, and
1581 ;; conditional move.  Using subregs into vector modes causes register
1582 ;; allocation lossage.  These patterns do not allow memory operands
1583 ;; because the native instructions read the full 128-bits.
1584
1585 (define_insn "*avx_andnot<mode>3"
1586   [(set (match_operand:MODEF 0 "register_operand" "=x")
1587         (and:MODEF
1588           (not:MODEF
1589             (match_operand:MODEF 1 "register_operand" "x"))
1590             (match_operand:MODEF 2 "register_operand" "x")))]
1591   "AVX_FLOAT_MODE_P (<MODE>mode)"
1592   "vandnp<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
1593   [(set_attr "type" "sselog")
1594    (set_attr "prefix" "vex")
1595    (set_attr "mode" "<ssevecmode>")])
1596
1597 (define_insn "*andnot<mode>3"
1598   [(set (match_operand:MODEF 0 "register_operand" "=x")
1599         (and:MODEF
1600           (not:MODEF
1601             (match_operand:MODEF 1 "register_operand" "0"))
1602             (match_operand:MODEF 2 "register_operand" "x")))]
1603   "SSE_FLOAT_MODE_P (<MODE>mode)"
1604   "andnp<ssemodefsuffix>\t{%2, %0|%0, %2}"
1605   [(set_attr "type" "sselog")
1606    (set_attr "mode" "<ssevecmode>")])
1607
1608 (define_insn "*avx_<code><mode>3"
1609   [(set (match_operand:MODEF 0 "register_operand" "=x")
1610         (plogic:MODEF
1611           (match_operand:MODEF 1 "register_operand" "x")
1612           (match_operand:MODEF 2 "register_operand" "x")))]
1613   "AVX_FLOAT_MODE_P (<MODE>mode)"
1614   "v<plogicprefix>p<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
1615   [(set_attr "type" "sselog")
1616    (set_attr "prefix" "vex")
1617    (set_attr "mode" "<ssevecmode>")])
1618
1619 (define_insn "*<code><mode>3"
1620   [(set (match_operand:MODEF 0 "register_operand" "=x")
1621         (plogic:MODEF
1622           (match_operand:MODEF 1 "register_operand" "0")
1623           (match_operand:MODEF 2 "register_operand" "x")))]
1624   "SSE_FLOAT_MODE_P (<MODE>mode)"
1625   "<plogicprefix>p<ssemodefsuffix>\t{%2, %0|%0, %2}"
1626   [(set_attr "type" "sselog")
1627    (set_attr "mode" "<ssevecmode>")])
1628
1629 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1630 ;;
1631 ;; SSE5 floating point multiply/accumulate instructions This includes the
1632 ;; scalar version of the instructions as well as the vector
1633 ;;
1634 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1635
1636 ;; In order to match (*a * *b) + *c, particularly when vectorizing, allow
1637 ;; combine to generate a multiply/add with two memory references.  We then
1638 ;; split this insn, into loading up the destination register with one of the
1639 ;; memory operations.  If we don't manage to split the insn, reload will
1640 ;; generate the appropriate moves.  The reason this is needed, is that combine
1641 ;; has already folded one of the memory references into both the multiply and
1642 ;; add insns, and it can't generate a new pseudo.  I.e.:
1643 ;;      (set (reg1) (mem (addr1)))
1644 ;;      (set (reg2) (mult (reg1) (mem (addr2))))
1645 ;;      (set (reg3) (plus (reg2) (mem (addr3))))
1646
1647 (define_insn "sse5_fmadd<mode>4"
1648   [(set (match_operand:SSEMODEF4 0 "register_operand" "=x,x,x,x")
1649         (plus:SSEMODEF4
1650          (mult:SSEMODEF4
1651           (match_operand:SSEMODEF4 1 "nonimmediate_operand" "%0,0,x,xm")
1652           (match_operand:SSEMODEF4 2 "nonimmediate_operand" "x,xm,xm,x"))
1653          (match_operand:SSEMODEF4 3 "nonimmediate_operand" "xm,x,0,0")))]
1654   "TARGET_SSE5 && TARGET_FUSED_MADD
1655    && ix86_sse5_valid_op_p (operands, insn, 4, true, 2, true)"
1656   "fmadd<ssemodesuffixf4>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1657   [(set_attr "type" "ssemuladd")
1658    (set_attr "mode" "<MODE>")])
1659
1660 ;; Split fmadd with two memory operands into a load and the fmadd.
1661 (define_split
1662   [(set (match_operand:SSEMODEF4 0 "register_operand" "")
1663         (plus:SSEMODEF4
1664          (mult:SSEMODEF4
1665           (match_operand:SSEMODEF4 1 "nonimmediate_operand" "")
1666           (match_operand:SSEMODEF4 2 "nonimmediate_operand" ""))
1667          (match_operand:SSEMODEF4 3 "nonimmediate_operand" "")))]
1668   "TARGET_SSE5
1669    && !ix86_sse5_valid_op_p (operands, insn, 4, true, 1, true)
1670    && ix86_sse5_valid_op_p (operands, insn, 4, true, 2, true)
1671    && !reg_mentioned_p (operands[0], operands[1])
1672    && !reg_mentioned_p (operands[0], operands[2])
1673    && !reg_mentioned_p (operands[0], operands[3])"
1674   [(const_int 0)]
1675 {
1676   ix86_expand_sse5_multiple_memory (operands, 4, <MODE>mode);
1677   emit_insn (gen_sse5_fmadd<mode>4 (operands[0], operands[1],
1678                                     operands[2], operands[3]));
1679   DONE;
1680 })
1681
1682 ;; For the scalar operations, use operand1 for the upper words that aren't
1683 ;; modified, so restrict the forms that are generated.
1684 ;; Scalar version of fmadd
1685 (define_insn "sse5_vmfmadd<mode>4"
1686   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x")
1687         (vec_merge:SSEMODEF2P
1688          (plus:SSEMODEF2P
1689           (mult:SSEMODEF2P
1690            (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "0,0")
1691            (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm"))
1692           (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x"))
1693          (match_dup 1)
1694          (const_int 1)))]
1695   "TARGET_SSE5 && TARGET_FUSED_MADD
1696    && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, true)"
1697   "fmadd<ssemodesuffixf2s>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1698   [(set_attr "type" "ssemuladd")
1699    (set_attr "mode" "<MODE>")])
1700
1701 ;; Floating multiply and subtract
1702 ;; Allow two memory operands the same as fmadd
1703 (define_insn "sse5_fmsub<mode>4"
1704   [(set (match_operand:SSEMODEF4 0 "register_operand" "=x,x,x,x")
1705         (minus:SSEMODEF4
1706          (mult:SSEMODEF4
1707           (match_operand:SSEMODEF4 1 "nonimmediate_operand" "%0,0,x,xm")
1708           (match_operand:SSEMODEF4 2 "nonimmediate_operand" "x,xm,xm,x"))
1709          (match_operand:SSEMODEF4 3 "nonimmediate_operand" "xm,x,0,0")))]
1710   "TARGET_SSE5 && TARGET_FUSED_MADD
1711    && ix86_sse5_valid_op_p (operands, insn, 4, true, 2, true)"
1712   "fmsub<ssemodesuffixf4>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1713   [(set_attr "type" "ssemuladd")
1714    (set_attr "mode" "<MODE>")])
1715
1716 ;; Split fmsub with two memory operands into a load and the fmsub.
1717 (define_split
1718   [(set (match_operand:SSEMODEF4 0 "register_operand" "")
1719         (minus:SSEMODEF4
1720          (mult:SSEMODEF4
1721           (match_operand:SSEMODEF4 1 "nonimmediate_operand" "")
1722           (match_operand:SSEMODEF4 2 "nonimmediate_operand" ""))
1723          (match_operand:SSEMODEF4 3 "nonimmediate_operand" "")))]
1724   "TARGET_SSE5
1725    && !ix86_sse5_valid_op_p (operands, insn, 4, true, 1, true)
1726    && ix86_sse5_valid_op_p (operands, insn, 4, true, 2, true)
1727    && !reg_mentioned_p (operands[0], operands[1])
1728    && !reg_mentioned_p (operands[0], operands[2])
1729    && !reg_mentioned_p (operands[0], operands[3])"
1730   [(const_int 0)]
1731 {
1732   ix86_expand_sse5_multiple_memory (operands, 4, <MODE>mode);
1733   emit_insn (gen_sse5_fmsub<mode>4 (operands[0], operands[1],
1734                                     operands[2], operands[3]));
1735   DONE;
1736 })
1737
1738 ;; For the scalar operations, use operand1 for the upper words that aren't
1739 ;; modified, so restrict the forms that are generated.
1740 ;; Scalar version of fmsub
1741 (define_insn "sse5_vmfmsub<mode>4"
1742   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x")
1743         (vec_merge:SSEMODEF2P
1744          (minus:SSEMODEF2P
1745           (mult:SSEMODEF2P
1746            (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "0,0")
1747            (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm"))
1748           (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x"))
1749          (match_dup 1)
1750          (const_int 1)))]
1751   "TARGET_SSE5 && TARGET_FUSED_MADD
1752    && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
1753   "fmsub<ssemodesuffixf2s>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1754   [(set_attr "type" "ssemuladd")
1755    (set_attr "mode" "<MODE>")])
1756
1757 ;; Floating point negative multiply and add
1758 ;; Rewrite (- (a * b) + c) into the canonical form: c - (a * b)
1759 ;; Note operands are out of order to simplify call to ix86_sse5_valid_p
1760 ;; Allow two memory operands to help in optimizing.
1761 (define_insn "sse5_fnmadd<mode>4"
1762   [(set (match_operand:SSEMODEF4 0 "register_operand" "=x,x,x,x")
1763         (minus:SSEMODEF4
1764          (match_operand:SSEMODEF4 3 "nonimmediate_operand" "xm,x,0,0")
1765          (mult:SSEMODEF4
1766           (match_operand:SSEMODEF4 1 "nonimmediate_operand" "%0,0,x,xm")
1767           (match_operand:SSEMODEF4 2 "nonimmediate_operand" "x,xm,xm,x"))))]
1768   "TARGET_SSE5 && TARGET_FUSED_MADD
1769    && ix86_sse5_valid_op_p (operands, insn, 4, true, 2, true)"
1770   "fnmadd<ssemodesuffixf4>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1771   [(set_attr "type" "ssemuladd")
1772    (set_attr "mode" "<MODE>")])
1773
1774 ;; Split fnmadd with two memory operands into a load and the fnmadd.
1775 (define_split
1776   [(set (match_operand:SSEMODEF4 0 "register_operand" "")
1777         (minus:SSEMODEF4
1778          (match_operand:SSEMODEF4 3 "nonimmediate_operand" "")
1779          (mult:SSEMODEF4
1780           (match_operand:SSEMODEF4 1 "nonimmediate_operand" "")
1781           (match_operand:SSEMODEF4 2 "nonimmediate_operand" ""))))]
1782   "TARGET_SSE5
1783    && !ix86_sse5_valid_op_p (operands, insn, 4, true, 1, true)
1784    && ix86_sse5_valid_op_p (operands, insn, 4, true, 2, true)
1785    && !reg_mentioned_p (operands[0], operands[1])
1786    && !reg_mentioned_p (operands[0], operands[2])
1787    && !reg_mentioned_p (operands[0], operands[3])"
1788   [(const_int 0)]
1789 {
1790   ix86_expand_sse5_multiple_memory (operands, 4, <MODE>mode);
1791   emit_insn (gen_sse5_fnmadd<mode>4 (operands[0], operands[1],
1792                                      operands[2], operands[3]));
1793   DONE;
1794 })
1795
1796 ;; For the scalar operations, use operand1 for the upper words that aren't
1797 ;; modified, so restrict the forms that are generated.
1798 ;; Scalar version of fnmadd
1799 (define_insn "sse5_vmfnmadd<mode>4"
1800   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x")
1801         (vec_merge:SSEMODEF2P
1802          (minus:SSEMODEF2P
1803           (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x")
1804           (mult:SSEMODEF2P
1805            (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "0,0")
1806            (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm")))
1807          (match_dup 1)
1808          (const_int 1)))]
1809   "TARGET_SSE5 && TARGET_FUSED_MADD
1810    && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, true)"
1811   "fnmadd<ssemodesuffixf2s>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1812   [(set_attr "type" "ssemuladd")
1813    (set_attr "mode" "<MODE>")])
1814
1815 ;; Floating point negative multiply and subtract
1816 ;; Rewrite (- (a * b) - c) into the canonical form: ((-a) * b) - c
1817 ;; Allow 2 memory operands to help with optimization
1818 (define_insn "sse5_fnmsub<mode>4"
1819   [(set (match_operand:SSEMODEF4 0 "register_operand" "=x,x")
1820         (minus:SSEMODEF4
1821          (mult:SSEMODEF4
1822           (neg:SSEMODEF4
1823            (match_operand:SSEMODEF4 1 "nonimmediate_operand" "0,0"))
1824           (match_operand:SSEMODEF4 2 "nonimmediate_operand" "x,xm"))
1825          (match_operand:SSEMODEF4 3 "nonimmediate_operand" "xm,x")))]
1826   "TARGET_SSE5 && TARGET_FUSED_MADD
1827    && ix86_sse5_valid_op_p (operands, insn, 4, true, 2, false)"
1828   "fnmsub<ssemodesuffixf4>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1829   [(set_attr "type" "ssemuladd")
1830    (set_attr "mode" "<MODE>")])
1831
1832 ;; Split fnmsub with two memory operands into a load and the fmsub.
1833 (define_split
1834   [(set (match_operand:SSEMODEF4 0 "register_operand" "")
1835         (minus:SSEMODEF4
1836          (mult:SSEMODEF4
1837           (neg:SSEMODEF4
1838            (match_operand:SSEMODEF4 1 "nonimmediate_operand" ""))
1839           (match_operand:SSEMODEF4 2 "nonimmediate_operand" ""))
1840          (match_operand:SSEMODEF4 3 "nonimmediate_operand" "")))]
1841   "TARGET_SSE5
1842    && !ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)
1843    && ix86_sse5_valid_op_p (operands, insn, 4, true, 2, false)
1844    && !reg_mentioned_p (operands[0], operands[1])
1845    && !reg_mentioned_p (operands[0], operands[2])
1846    && !reg_mentioned_p (operands[0], operands[3])"
1847   [(const_int 0)]
1848 {
1849   ix86_expand_sse5_multiple_memory (operands, 4, <MODE>mode);
1850   emit_insn (gen_sse5_fnmsub<mode>4 (operands[0], operands[1],
1851                                      operands[2], operands[3]));
1852   DONE;
1853 })
1854
1855 ;; For the scalar operations, use operand1 for the upper words that aren't
1856 ;; modified, so restrict the forms that are generated.
1857 ;; Scalar version of fnmsub
1858 (define_insn "sse5_vmfnmsub<mode>4"
1859   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x")
1860         (vec_merge:SSEMODEF2P
1861          (minus:SSEMODEF2P
1862           (mult:SSEMODEF2P
1863            (neg:SSEMODEF2P
1864             (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "0,0"))
1865            (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm"))
1866           (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x"))
1867          (match_dup 1)
1868          (const_int 1)))]
1869   "TARGET_SSE5 && TARGET_FUSED_MADD
1870    && ix86_sse5_valid_op_p (operands, insn, 4, true, 2, false)"
1871   "fnmsub<ssemodesuffixf2s>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1872   [(set_attr "type" "ssemuladd")
1873    (set_attr "mode" "<MODE>")])
1874
1875 ;; The same instructions using an UNSPEC to allow the intrinsic to be used
1876 ;; even if the user used -mno-fused-madd
1877 ;; Parallel instructions.  During instruction generation, just default
1878 ;; to registers, and let combine later build the appropriate instruction.
1879 (define_expand "sse5i_fmadd<mode>4"
1880   [(set (match_operand:SSEMODEF2P 0 "register_operand" "")
1881         (unspec:SSEMODEF2P
1882          [(plus:SSEMODEF2P
1883            (mult:SSEMODEF2P
1884             (match_operand:SSEMODEF2P 1 "register_operand" "")
1885             (match_operand:SSEMODEF2P 2 "register_operand" ""))
1886            (match_operand:SSEMODEF2P 3 "register_operand" ""))]
1887          UNSPEC_SSE5_INTRINSIC))]
1888   "TARGET_SSE5"
1889 {
1890   /* If we have -mfused-madd, emit the normal insn rather than the UNSPEC */
1891   if (TARGET_FUSED_MADD)
1892     {
1893       emit_insn (gen_sse5_fmadd<mode>4 (operands[0], operands[1],
1894                                         operands[2], operands[3]));
1895       DONE;
1896     }
1897 })
1898
1899 (define_insn "*sse5i_fmadd<mode>4"
1900   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x,x,x")
1901         (unspec:SSEMODEF2P
1902          [(plus:SSEMODEF2P
1903            (mult:SSEMODEF2P
1904             (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "%0,0,x,xm")
1905             (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm,xm,x"))
1906            (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x,0,0"))]
1907          UNSPEC_SSE5_INTRINSIC))]
1908   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, true)"
1909   "fmadd<ssemodesuffixf4>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1910   [(set_attr "type" "ssemuladd")
1911    (set_attr "mode" "<MODE>")])
1912
1913 (define_expand "sse5i_fmsub<mode>4"
1914   [(set (match_operand:SSEMODEF2P 0 "register_operand" "")
1915         (unspec:SSEMODEF2P
1916          [(minus:SSEMODEF2P
1917            (mult:SSEMODEF2P
1918             (match_operand:SSEMODEF2P 1 "register_operand" "")
1919             (match_operand:SSEMODEF2P 2 "register_operand" ""))
1920            (match_operand:SSEMODEF2P 3 "register_operand" ""))]
1921          UNSPEC_SSE5_INTRINSIC))]
1922   "TARGET_SSE5"
1923 {
1924   /* If we have -mfused-madd, emit the normal insn rather than the UNSPEC */
1925   if (TARGET_FUSED_MADD)
1926     {
1927       emit_insn (gen_sse5_fmsub<mode>4 (operands[0], operands[1],
1928                                         operands[2], operands[3]));
1929       DONE;
1930     }
1931 })
1932
1933 (define_insn "*sse5i_fmsub<mode>4"
1934   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x,x,x")
1935         (unspec:SSEMODEF2P
1936          [(minus:SSEMODEF2P
1937            (mult:SSEMODEF2P
1938             (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "%0,0,x,xm")
1939             (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm,xm,x"))
1940            (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x,0,0"))]
1941          UNSPEC_SSE5_INTRINSIC))]
1942   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, true)"
1943   "fmsub<ssemodesuffixf4>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1944   [(set_attr "type" "ssemuladd")
1945    (set_attr "mode" "<MODE>")])
1946
1947 ;; Rewrite (- (a * b) + c) into the canonical form: c - (a * b)
1948 ;; Note operands are out of order to simplify call to ix86_sse5_valid_p
1949 (define_expand "sse5i_fnmadd<mode>4"
1950   [(set (match_operand:SSEMODEF2P 0 "register_operand" "")
1951         (unspec:SSEMODEF2P
1952          [(minus:SSEMODEF2P
1953            (match_operand:SSEMODEF2P 3 "register_operand" "")
1954            (mult:SSEMODEF2P
1955             (match_operand:SSEMODEF2P 1 "register_operand" "")
1956             (match_operand:SSEMODEF2P 2 "register_operand" "")))]
1957          UNSPEC_SSE5_INTRINSIC))]
1958   "TARGET_SSE5"
1959 {
1960   /* If we have -mfused-madd, emit the normal insn rather than the UNSPEC */
1961   if (TARGET_FUSED_MADD)
1962     {
1963       emit_insn (gen_sse5_fnmadd<mode>4 (operands[0], operands[1],
1964                                          operands[2], operands[3]));
1965       DONE;
1966     }
1967 })
1968
1969 (define_insn "*sse5i_fnmadd<mode>4"
1970   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x,x,x")
1971         (unspec:SSEMODEF2P
1972          [(minus:SSEMODEF2P
1973            (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x,0,0")
1974            (mult:SSEMODEF2P
1975             (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "%0,0,x,xm")
1976             (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm,xm,x")))]
1977          UNSPEC_SSE5_INTRINSIC))]
1978   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, true)"
1979   "fnmadd<ssemodesuffixf4>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1980   [(set_attr "type" "ssemuladd")
1981    (set_attr "mode" "<MODE>")])
1982
1983 ;; Rewrite (- (a * b) - c) into the canonical form: ((-a) * b) - c
1984 (define_expand "sse5i_fnmsub<mode>4"
1985   [(set (match_operand:SSEMODEF2P 0 "register_operand" "")
1986         (unspec:SSEMODEF2P
1987          [(minus:SSEMODEF2P
1988            (mult:SSEMODEF2P
1989             (neg:SSEMODEF2P
1990              (match_operand:SSEMODEF2P 1 "register_operand" ""))
1991             (match_operand:SSEMODEF2P 2 "register_operand" ""))
1992            (match_operand:SSEMODEF2P 3 "register_operand" ""))]
1993          UNSPEC_SSE5_INTRINSIC))]
1994   "TARGET_SSE5"
1995 {
1996   /* If we have -mfused-madd, emit the normal insn rather than the UNSPEC */
1997   if (TARGET_FUSED_MADD)
1998     {
1999       emit_insn (gen_sse5_fnmsub<mode>4 (operands[0], operands[1],
2000                                          operands[2], operands[3]));
2001       DONE;
2002     }
2003 })
2004
2005 (define_insn "*sse5i_fnmsub<mode>4"
2006   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x,x,x")
2007         (unspec:SSEMODEF2P
2008          [(minus:SSEMODEF2P
2009            (mult:SSEMODEF2P
2010             (neg:SSEMODEF2P
2011              (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "0,0,x,xm"))
2012             (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm,xm,x"))
2013            (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x,0,0"))]
2014          UNSPEC_SSE5_INTRINSIC))]
2015   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
2016   "fnmsub<ssemodesuffixf4>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
2017   [(set_attr "type" "ssemuladd")
2018    (set_attr "mode" "<MODE>")])
2019
2020 ;; Scalar instructions
2021 (define_expand "sse5i_vmfmadd<mode>4"
2022   [(set (match_operand:SSEMODEF2P 0 "register_operand" "")
2023         (unspec:SSEMODEF2P
2024          [(vec_merge:SSEMODEF2P
2025            (plus:SSEMODEF2P
2026             (mult:SSEMODEF2P
2027              (match_operand:SSEMODEF2P 1 "register_operand" "")
2028              (match_operand:SSEMODEF2P 2 "register_operand" ""))
2029             (match_operand:SSEMODEF2P 3 "register_operand" ""))
2030            (match_dup 1)
2031            (const_int 0))]
2032          UNSPEC_SSE5_INTRINSIC))]
2033   "TARGET_SSE5"
2034 {
2035   /* If we have -mfused-madd, emit the normal insn rather than the UNSPEC */
2036   if (TARGET_FUSED_MADD)
2037     {
2038       emit_insn (gen_sse5_vmfmadd<mode>4 (operands[0], operands[1],
2039                                           operands[2], operands[3]));
2040       DONE;
2041     }
2042 })
2043
2044 ;; For the scalar operations, use operand1 for the upper words that aren't
2045 ;; modified, so restrict the forms that are accepted.
2046 (define_insn "*sse5i_vmfmadd<mode>4"
2047   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x")
2048         (unspec:SSEMODEF2P
2049          [(vec_merge:SSEMODEF2P
2050            (plus:SSEMODEF2P
2051             (mult:SSEMODEF2P
2052              (match_operand:SSEMODEF2P 1 "register_operand" "0,0")
2053              (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm"))
2054             (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x"))
2055            (match_dup 0)
2056            (const_int 0))]
2057          UNSPEC_SSE5_INTRINSIC))]
2058   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
2059   "fmadd<ssemodesuffixf2s>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
2060   [(set_attr "type" "ssemuladd")
2061    (set_attr "mode" "<ssescalarmode>")])
2062
2063 (define_expand "sse5i_vmfmsub<mode>4"
2064   [(set (match_operand:SSEMODEF2P 0 "register_operand" "")
2065         (unspec:SSEMODEF2P
2066          [(vec_merge:SSEMODEF2P
2067            (minus:SSEMODEF2P
2068             (mult:SSEMODEF2P
2069              (match_operand:SSEMODEF2P 1 "register_operand" "")
2070              (match_operand:SSEMODEF2P 2 "register_operand" ""))
2071             (match_operand:SSEMODEF2P 3 "register_operand" ""))
2072            (match_dup 0)
2073            (const_int 1))]
2074          UNSPEC_SSE5_INTRINSIC))]
2075   "TARGET_SSE5"
2076 {
2077   /* If we have -mfused-madd, emit the normal insn rather than the UNSPEC */
2078   if (TARGET_FUSED_MADD)
2079     {
2080       emit_insn (gen_sse5_vmfmsub<mode>4 (operands[0], operands[1],
2081                                           operands[2], operands[3]));
2082       DONE;
2083     }
2084 })
2085
2086 (define_insn "*sse5i_vmfmsub<mode>4"
2087   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x")
2088         (unspec:SSEMODEF2P
2089          [(vec_merge:SSEMODEF2P
2090            (minus:SSEMODEF2P
2091             (mult:SSEMODEF2P
2092              (match_operand:SSEMODEF2P 1 "register_operand" "0,0")
2093              (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm"))
2094             (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x"))
2095            (match_dup 1)
2096            (const_int 1))]
2097          UNSPEC_SSE5_INTRINSIC))]
2098   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
2099   "fmsub<ssemodesuffixf2s>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
2100   [(set_attr "type" "ssemuladd")
2101    (set_attr "mode" "<ssescalarmode>")])
2102
2103 ;; Note operands are out of order to simplify call to ix86_sse5_valid_p
2104 (define_expand "sse5i_vmfnmadd<mode>4"
2105   [(set (match_operand:SSEMODEF2P 0 "register_operand" "")
2106         (unspec:SSEMODEF2P
2107          [(vec_merge:SSEMODEF2P
2108            (minus:SSEMODEF2P
2109             (match_operand:SSEMODEF2P 3 "register_operand" "")
2110             (mult:SSEMODEF2P
2111              (match_operand:SSEMODEF2P 1 "register_operand" "")
2112              (match_operand:SSEMODEF2P 2 "register_operand" "")))
2113            (match_dup 1)
2114            (const_int 1))]
2115          UNSPEC_SSE5_INTRINSIC))]
2116   "TARGET_SSE5"
2117 {
2118   /* If we have -mfused-madd, emit the normal insn rather than the UNSPEC */
2119   if (TARGET_FUSED_MADD)
2120     {
2121       emit_insn (gen_sse5_vmfnmadd<mode>4 (operands[0], operands[1],
2122                                            operands[2], operands[3]));
2123       DONE;
2124     }
2125 })
2126
2127 (define_insn "*sse5i_vmfnmadd<mode>4"
2128   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x")
2129         (unspec:SSEMODEF2P
2130          [(vec_merge:SSEMODEF2P
2131            (minus:SSEMODEF2P
2132             (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x")
2133             (mult:SSEMODEF2P
2134              (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "%0,0")
2135              (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm")))
2136            (match_dup 1)
2137            (const_int 1))]
2138          UNSPEC_SSE5_INTRINSIC))]
2139   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, true)"
2140   "fnmadd<ssemodesuffixf2s>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
2141   [(set_attr "type" "ssemuladd")
2142    (set_attr "mode" "<ssescalarmode>")])
2143
2144 (define_expand "sse5i_vmfnmsub<mode>4"
2145   [(set (match_operand:SSEMODEF2P 0 "register_operand" "")
2146         (unspec:SSEMODEF2P
2147          [(vec_merge:SSEMODEF2P
2148            (minus:SSEMODEF2P
2149             (mult:SSEMODEF2P
2150              (neg:SSEMODEF2P
2151               (match_operand:SSEMODEF2P 1 "register_operand" ""))
2152              (match_operand:SSEMODEF2P 2 "register_operand" ""))
2153             (match_operand:SSEMODEF2P 3 "register_operand" ""))
2154            (match_dup 1)
2155            (const_int 1))]
2156          UNSPEC_SSE5_INTRINSIC))]
2157   "TARGET_SSE5"
2158 {
2159   /* If we have -mfused-madd, emit the normal insn rather than the UNSPEC */
2160   if (TARGET_FUSED_MADD)
2161     {
2162       emit_insn (gen_sse5_vmfnmsub<mode>4 (operands[0], operands[1],
2163                                            operands[2], operands[3]));
2164       DONE;
2165     }
2166 })
2167
2168 (define_insn "*sse5i_vmfnmsub<mode>4"
2169   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x")
2170         (unspec:SSEMODEF2P
2171          [(vec_merge:SSEMODEF2P
2172            (minus:SSEMODEF2P
2173             (mult:SSEMODEF2P
2174              (neg:SSEMODEF2P
2175               (match_operand:SSEMODEF2P 1 "register_operand" "0,0"))
2176              (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm"))
2177             (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x"))
2178            (match_dup 1)
2179            (const_int 1))]
2180          UNSPEC_SSE5_INTRINSIC))]
2181   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
2182   "fnmsub<ssemodesuffixf2s>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
2183   [(set_attr "type" "ssemuladd")
2184    (set_attr "mode" "<ssescalarmode>")])
2185
2186 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2187 ;;
2188 ;; Parallel single-precision floating point conversion operations
2189 ;;
2190 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2191
2192 (define_insn "sse_cvtpi2ps"
2193   [(set (match_operand:V4SF 0 "register_operand" "=x")
2194         (vec_merge:V4SF
2195           (vec_duplicate:V4SF
2196             (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
2197           (match_operand:V4SF 1 "register_operand" "0")
2198           (const_int 3)))]
2199   "TARGET_SSE"
2200   "cvtpi2ps\t{%2, %0|%0, %2}"
2201   [(set_attr "type" "ssecvt")
2202    (set_attr "mode" "V4SF")])
2203
2204 (define_insn "sse_cvtps2pi"
2205   [(set (match_operand:V2SI 0 "register_operand" "=y")
2206         (vec_select:V2SI
2207           (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
2208                        UNSPEC_FIX_NOTRUNC)
2209           (parallel [(const_int 0) (const_int 1)])))]
2210   "TARGET_SSE"
2211   "cvtps2pi\t{%1, %0|%0, %1}"
2212   [(set_attr "type" "ssecvt")
2213    (set_attr "unit" "mmx")
2214    (set_attr "mode" "DI")])
2215
2216 (define_insn "sse_cvttps2pi"
2217   [(set (match_operand:V2SI 0 "register_operand" "=y")
2218         (vec_select:V2SI
2219           (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
2220           (parallel [(const_int 0) (const_int 1)])))]
2221   "TARGET_SSE"
2222   "cvttps2pi\t{%1, %0|%0, %1}"
2223   [(set_attr "type" "ssecvt")
2224    (set_attr "unit" "mmx")
2225    (set_attr "mode" "SF")])
2226
2227 (define_insn "*avx_cvtsi2ss"
2228   [(set (match_operand:V4SF 0 "register_operand" "=x")
2229         (vec_merge:V4SF
2230           (vec_duplicate:V4SF
2231             (float:SF (match_operand:SI 2 "nonimmediate_operand" "rm")))
2232           (match_operand:V4SF 1 "register_operand" "x")
2233           (const_int 1)))]
2234   "TARGET_AVX"
2235   "vcvtsi2ss\t{%2, %1, %0|%0, %1, %2}"
2236   [(set_attr "type" "sseicvt")
2237    (set_attr "prefix" "vex")
2238    (set_attr "mode" "SF")])
2239
2240 (define_insn "sse_cvtsi2ss"
2241   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
2242         (vec_merge:V4SF
2243           (vec_duplicate:V4SF
2244             (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,m")))
2245           (match_operand:V4SF 1 "register_operand" "0,0")
2246           (const_int 1)))]
2247   "TARGET_SSE"
2248   "cvtsi2ss\t{%2, %0|%0, %2}"
2249   [(set_attr "type" "sseicvt")
2250    (set_attr "athlon_decode" "vector,double")
2251    (set_attr "amdfam10_decode" "vector,double")
2252    (set_attr "mode" "SF")])
2253
2254 (define_insn "*avx_cvtsi2ssq"
2255   [(set (match_operand:V4SF 0 "register_operand" "=x")
2256         (vec_merge:V4SF
2257           (vec_duplicate:V4SF
2258             (float:SF (match_operand:DI 2 "nonimmediate_operand" "rm")))
2259           (match_operand:V4SF 1 "register_operand" "x")
2260           (const_int 1)))]
2261   "TARGET_AVX && TARGET_64BIT"
2262   "vcvtsi2ssq\t{%2, %1, %0|%0, %1, %2}"
2263   [(set_attr "type" "sseicvt")
2264    (set_attr "prefix" "vex")
2265    (set_attr "mode" "SF")])
2266
2267 (define_insn "sse_cvtsi2ssq"
2268   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
2269         (vec_merge:V4SF
2270           (vec_duplicate:V4SF
2271             (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
2272           (match_operand:V4SF 1 "register_operand" "0,0")
2273           (const_int 1)))]
2274   "TARGET_SSE && TARGET_64BIT"
2275   "cvtsi2ssq\t{%2, %0|%0, %2}"
2276   [(set_attr "type" "sseicvt")
2277    (set_attr "athlon_decode" "vector,double")
2278    (set_attr "amdfam10_decode" "vector,double")
2279    (set_attr "mode" "SF")])
2280
2281 (define_insn "sse_cvtss2si"
2282   [(set (match_operand:SI 0 "register_operand" "=r,r")
2283         (unspec:SI
2284           [(vec_select:SF
2285              (match_operand:V4SF 1 "nonimmediate_operand" "x,m")
2286              (parallel [(const_int 0)]))]
2287           UNSPEC_FIX_NOTRUNC))]
2288   "TARGET_SSE"
2289   "%vcvtss2si\t{%1, %0|%0, %1}"
2290   [(set_attr "type" "sseicvt")
2291    (set_attr "athlon_decode" "double,vector")
2292    (set_attr "prefix_rep" "1")
2293    (set_attr "prefix" "maybe_vex")
2294    (set_attr "mode" "SI")])
2295
2296 (define_insn "sse_cvtss2si_2"
2297   [(set (match_operand:SI 0 "register_operand" "=r,r")
2298         (unspec:SI [(match_operand:SF 1 "nonimmediate_operand" "x,m")]
2299                    UNSPEC_FIX_NOTRUNC))]
2300   "TARGET_SSE"
2301   "%vcvtss2si\t{%1, %0|%0, %1}"
2302   [(set_attr "type" "sseicvt")
2303    (set_attr "athlon_decode" "double,vector")
2304    (set_attr "amdfam10_decode" "double,double")
2305    (set_attr "prefix_rep" "1")
2306    (set_attr "prefix" "maybe_vex")
2307    (set_attr "mode" "SI")])
2308
2309 (define_insn "sse_cvtss2siq"
2310   [(set (match_operand:DI 0 "register_operand" "=r,r")
2311         (unspec:DI
2312           [(vec_select:SF
2313              (match_operand:V4SF 1 "nonimmediate_operand" "x,m")
2314              (parallel [(const_int 0)]))]
2315           UNSPEC_FIX_NOTRUNC))]
2316   "TARGET_SSE && TARGET_64BIT"
2317   "%vcvtss2siq\t{%1, %0|%0, %1}"
2318   [(set_attr "type" "sseicvt")
2319    (set_attr "athlon_decode" "double,vector")
2320    (set_attr "prefix_rep" "1")
2321    (set_attr "prefix" "maybe_vex")
2322    (set_attr "mode" "DI")])
2323
2324 (define_insn "sse_cvtss2siq_2"
2325   [(set (match_operand:DI 0 "register_operand" "=r,r")
2326         (unspec:DI [(match_operand:SF 1 "nonimmediate_operand" "x,m")]
2327                    UNSPEC_FIX_NOTRUNC))]
2328   "TARGET_SSE && TARGET_64BIT"
2329   "%vcvtss2siq\t{%1, %0|%0, %1}"
2330   [(set_attr "type" "sseicvt")
2331    (set_attr "athlon_decode" "double,vector")
2332    (set_attr "amdfam10_decode" "double,double")
2333    (set_attr "prefix_rep" "1")
2334    (set_attr "prefix" "maybe_vex")
2335    (set_attr "mode" "DI")])
2336
2337 (define_insn "sse_cvttss2si"
2338   [(set (match_operand:SI 0 "register_operand" "=r,r")
2339         (fix:SI
2340           (vec_select:SF
2341             (match_operand:V4SF 1 "nonimmediate_operand" "x,m")
2342             (parallel [(const_int 0)]))))]
2343   "TARGET_SSE"
2344   "%vcvttss2si\t{%1, %0|%0, %1}"
2345   [(set_attr "type" "sseicvt")
2346    (set_attr "athlon_decode" "double,vector")
2347    (set_attr "amdfam10_decode" "double,double")
2348    (set_attr "prefix_rep" "1")
2349    (set_attr "prefix" "maybe_vex")
2350    (set_attr "mode" "SI")])
2351
2352 (define_insn "sse_cvttss2siq"
2353   [(set (match_operand:DI 0 "register_operand" "=r,r")
2354         (fix:DI
2355           (vec_select:SF
2356             (match_operand:V4SF 1 "nonimmediate_operand" "x,m")
2357             (parallel [(const_int 0)]))))]
2358   "TARGET_SSE && TARGET_64BIT"
2359   "%vcvttss2siq\t{%1, %0|%0, %1}"
2360   [(set_attr "type" "sseicvt")
2361    (set_attr "athlon_decode" "double,vector")
2362    (set_attr "amdfam10_decode" "double,double")
2363    (set_attr "prefix_rep" "1")
2364    (set_attr "prefix" "maybe_vex")
2365    (set_attr "mode" "DI")])
2366
2367 (define_insn "avx_cvtdq2ps<avxmodesuffix>"
2368   [(set (match_operand:AVXMODEDCVTDQ2PS 0 "register_operand" "=x")
2369         (float:AVXMODEDCVTDQ2PS
2370           (match_operand:<avxcvtvecmode> 1 "nonimmediate_operand" "xm")))]
2371   "TARGET_AVX"
2372   "vcvtdq2ps\t{%1, %0|%0, %1}"
2373   [(set_attr "type" "ssecvt")
2374    (set_attr "prefix" "vex")
2375    (set_attr "mode" "<avxvecmode>")])
2376
2377 (define_insn "sse2_cvtdq2ps"
2378   [(set (match_operand:V4SF 0 "register_operand" "=x")
2379         (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
2380   "TARGET_SSE2"
2381   "cvtdq2ps\t{%1, %0|%0, %1}"
2382   [(set_attr "type" "ssecvt")
2383    (set_attr "mode" "V4SF")])
2384
2385 (define_insn "avx_cvtps2dq<avxmodesuffix>"
2386   [(set (match_operand:AVXMODEDCVTPS2DQ 0 "register_operand" "=x")
2387         (unspec:AVXMODEDCVTPS2DQ
2388           [(match_operand:<avxcvtvecmode> 1 "nonimmediate_operand" "xm")]
2389           UNSPEC_FIX_NOTRUNC))]
2390   "TARGET_AVX"
2391   "vcvtps2dq\t{%1, %0|%0, %1}"
2392   [(set_attr "type" "ssecvt")
2393    (set_attr "prefix" "vex")
2394    (set_attr "mode" "<avxvecmode>")])
2395
2396 (define_insn "sse2_cvtps2dq"
2397   [(set (match_operand:V4SI 0 "register_operand" "=x")
2398         (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
2399                      UNSPEC_FIX_NOTRUNC))]
2400   "TARGET_SSE2"
2401   "cvtps2dq\t{%1, %0|%0, %1}"
2402   [(set_attr "type" "ssecvt")
2403    (set_attr "prefix_data16" "1")
2404    (set_attr "mode" "TI")])
2405
2406 (define_insn "avx_cvttps2dq<avxmodesuffix>"
2407   [(set (match_operand:AVXMODEDCVTPS2DQ 0 "register_operand" "=x")
2408         (fix:AVXMODEDCVTPS2DQ
2409           (match_operand:<avxcvtvecmode> 1 "nonimmediate_operand" "xm")))]
2410   "TARGET_AVX"
2411   "vcvttps2dq\t{%1, %0|%0, %1}"
2412   [(set_attr "type" "ssecvt")
2413    (set_attr "prefix" "vex")
2414    (set_attr "mode" "<avxvecmode>")])
2415
2416 (define_insn "sse2_cvttps2dq"
2417   [(set (match_operand:V4SI 0 "register_operand" "=x")
2418         (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
2419   "TARGET_SSE2"
2420   "cvttps2dq\t{%1, %0|%0, %1}"
2421   [(set_attr "type" "ssecvt")
2422    (set_attr "prefix_rep" "1")
2423    (set_attr "mode" "TI")])
2424
2425 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2426 ;;
2427 ;; Parallel double-precision floating point conversion operations
2428 ;;
2429 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2430
2431 (define_insn "sse2_cvtpi2pd"
2432   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
2433         (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "y,m")))]
2434   "TARGET_SSE2"
2435   "cvtpi2pd\t{%1, %0|%0, %1}"
2436   [(set_attr "type" "ssecvt")
2437    (set_attr "unit" "mmx,*")
2438    (set_attr "mode" "V2DF")])
2439
2440 (define_insn "sse2_cvtpd2pi"
2441   [(set (match_operand:V2SI 0 "register_operand" "=y")
2442         (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
2443                      UNSPEC_FIX_NOTRUNC))]
2444   "TARGET_SSE2"
2445   "cvtpd2pi\t{%1, %0|%0, %1}"
2446   [(set_attr "type" "ssecvt")
2447    (set_attr "unit" "mmx")
2448    (set_attr "prefix_data16" "1")
2449    (set_attr "mode" "DI")])
2450
2451 (define_insn "sse2_cvttpd2pi"
2452   [(set (match_operand:V2SI 0 "register_operand" "=y")
2453         (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
2454   "TARGET_SSE2"
2455   "cvttpd2pi\t{%1, %0|%0, %1}"
2456   [(set_attr "type" "ssecvt")
2457    (set_attr "unit" "mmx")
2458    (set_attr "prefix_data16" "1")
2459    (set_attr "mode" "TI")])
2460
2461 (define_insn "*avx_cvtsi2sd"
2462   [(set (match_operand:V2DF 0 "register_operand" "=x")
2463         (vec_merge:V2DF
2464           (vec_duplicate:V2DF
2465             (float:DF (match_operand:SI 2 "nonimmediate_operand" "rm")))
2466           (match_operand:V2DF 1 "register_operand" "x")
2467           (const_int 1)))]
2468   "TARGET_AVX"
2469   "vcvtsi2sd\t{%2, %1, %0|%0, %1, %2}"
2470   [(set_attr "type" "sseicvt")
2471    (set_attr "prefix" "vex")
2472    (set_attr "mode" "DF")])
2473
2474 (define_insn "sse2_cvtsi2sd"
2475   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
2476         (vec_merge:V2DF
2477           (vec_duplicate:V2DF
2478             (float:DF (match_operand:SI 2 "nonimmediate_operand" "r,m")))
2479           (match_operand:V2DF 1 "register_operand" "0,0")
2480           (const_int 1)))]
2481   "TARGET_SSE2"
2482   "cvtsi2sd\t{%2, %0|%0, %2}"
2483   [(set_attr "type" "sseicvt")
2484    (set_attr "mode" "DF")
2485    (set_attr "athlon_decode" "double,direct")
2486    (set_attr "amdfam10_decode" "vector,double")])
2487
2488 (define_insn "*avx_cvtsi2sdq"
2489   [(set (match_operand:V2DF 0 "register_operand" "=x")
2490         (vec_merge:V2DF
2491           (vec_duplicate:V2DF
2492             (float:DF (match_operand:DI 2 "nonimmediate_operand" "rm")))
2493           (match_operand:V2DF 1 "register_operand" "x")
2494           (const_int 1)))]
2495   "TARGET_AVX && TARGET_64BIT"
2496   "vcvtsi2sdq\t{%2, %1, %0|%0, %1, %2}"
2497   [(set_attr "type" "sseicvt")
2498    (set_attr "prefix" "vex")
2499    (set_attr "mode" "DF")])
2500
2501 (define_insn "sse2_cvtsi2sdq"
2502   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
2503         (vec_merge:V2DF
2504           (vec_duplicate:V2DF
2505             (float:DF (match_operand:DI 2 "nonimmediate_operand" "r,m")))
2506           (match_operand:V2DF 1 "register_operand" "0,0")
2507           (const_int 1)))]
2508   "TARGET_SSE2 && TARGET_64BIT"
2509   "cvtsi2sdq\t{%2, %0|%0, %2}"
2510   [(set_attr "type" "sseicvt")
2511    (set_attr "mode" "DF")
2512    (set_attr "athlon_decode" "double,direct")
2513    (set_attr "amdfam10_decode" "vector,double")])
2514
2515 (define_insn "sse2_cvtsd2si"
2516   [(set (match_operand:SI 0 "register_operand" "=r,r")
2517         (unspec:SI
2518           [(vec_select:DF
2519              (match_operand:V2DF 1 "nonimmediate_operand" "x,m")
2520              (parallel [(const_int 0)]))]
2521           UNSPEC_FIX_NOTRUNC))]
2522   "TARGET_SSE2"
2523   "%vcvtsd2si\t{%1, %0|%0, %1}"
2524   [(set_attr "type" "sseicvt")
2525    (set_attr "athlon_decode" "double,vector")
2526    (set_attr "prefix_rep" "1")
2527    (set_attr "prefix" "maybe_vex")
2528    (set_attr "mode" "SI")])
2529
2530 (define_insn "sse2_cvtsd2si_2"
2531   [(set (match_operand:SI 0 "register_operand" "=r,r")
2532         (unspec:SI [(match_operand:DF 1 "nonimmediate_operand" "x,m")]
2533                    UNSPEC_FIX_NOTRUNC))]
2534   "TARGET_SSE2"
2535   "%vcvtsd2si\t{%1, %0|%0, %1}"
2536   [(set_attr "type" "sseicvt")
2537    (set_attr "athlon_decode" "double,vector")
2538    (set_attr "amdfam10_decode" "double,double")
2539    (set_attr "prefix_rep" "1")
2540    (set_attr "prefix" "maybe_vex")
2541    (set_attr "mode" "SI")])
2542
2543 (define_insn "sse2_cvtsd2siq"
2544   [(set (match_operand:DI 0 "register_operand" "=r,r")
2545         (unspec:DI
2546           [(vec_select:DF
2547              (match_operand:V2DF 1 "nonimmediate_operand" "x,m")
2548              (parallel [(const_int 0)]))]
2549           UNSPEC_FIX_NOTRUNC))]
2550   "TARGET_SSE2 && TARGET_64BIT"
2551   "%vcvtsd2siq\t{%1, %0|%0, %1}"
2552   [(set_attr "type" "sseicvt")
2553    (set_attr "athlon_decode" "double,vector")
2554    (set_attr "prefix_rep" "1")
2555    (set_attr "prefix" "maybe_vex")
2556    (set_attr "mode" "DI")])
2557
2558 (define_insn "sse2_cvtsd2siq_2"
2559   [(set (match_operand:DI 0 "register_operand" "=r,r")
2560         (unspec:DI [(match_operand:DF 1 "nonimmediate_operand" "x,m")]
2561                    UNSPEC_FIX_NOTRUNC))]
2562   "TARGET_SSE2 && TARGET_64BIT"
2563   "%vcvtsd2siq\t{%1, %0|%0, %1}"
2564   [(set_attr "type" "sseicvt")
2565    (set_attr "athlon_decode" "double,vector")
2566    (set_attr "amdfam10_decode" "double,double")
2567    (set_attr "prefix_rep" "1")
2568    (set_attr "prefix" "maybe_vex")
2569    (set_attr "mode" "DI")])
2570
2571 (define_insn "sse2_cvttsd2si"
2572   [(set (match_operand:SI 0 "register_operand" "=r,r")
2573         (fix:SI
2574           (vec_select:DF
2575             (match_operand:V2DF 1 "nonimmediate_operand" "x,m")
2576             (parallel [(const_int 0)]))))]
2577   "TARGET_SSE2"
2578   "%vcvttsd2si\t{%1, %0|%0, %1}"
2579   [(set_attr "type" "sseicvt")
2580    (set_attr "prefix_rep" "1")
2581    (set_attr "prefix" "maybe_vex")
2582    (set_attr "mode" "SI")
2583    (set_attr "athlon_decode" "double,vector")
2584    (set_attr "amdfam10_decode" "double,double")])
2585
2586 (define_insn "sse2_cvttsd2siq"
2587   [(set (match_operand:DI 0 "register_operand" "=r,r")
2588         (fix:DI
2589           (vec_select:DF
2590             (match_operand:V2DF 1 "nonimmediate_operand" "x,m")
2591             (parallel [(const_int 0)]))))]
2592   "TARGET_SSE2 && TARGET_64BIT"
2593   "%vcvttsd2siq\t{%1, %0|%0, %1}"
2594   [(set_attr "type" "sseicvt")
2595    (set_attr "prefix_rep" "1")
2596    (set_attr "prefix" "maybe_vex")
2597    (set_attr "mode" "DI")
2598    (set_attr "athlon_decode" "double,vector")
2599    (set_attr "amdfam10_decode" "double,double")])
2600
2601 (define_insn "avx_cvtdq2pd256"
2602   [(set (match_operand:V4DF 0 "register_operand" "=x")
2603         (float:V4DF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
2604   "TARGET_AVX"
2605   "vcvtdq2pd\t{%1, %0|%0, %1}"
2606   [(set_attr "type" "ssecvt")
2607    (set_attr "prefix" "vex")
2608    (set_attr "mode" "V4DF")])
2609
2610 (define_insn "sse2_cvtdq2pd"
2611   [(set (match_operand:V2DF 0 "register_operand" "=x")
2612         (float:V2DF
2613           (vec_select:V2SI
2614             (match_operand:V4SI 1 "nonimmediate_operand" "xm")
2615             (parallel [(const_int 0) (const_int 1)]))))]
2616   "TARGET_SSE2"
2617   "%vcvtdq2pd\t{%1, %0|%0, %1}"
2618   [(set_attr "type" "ssecvt")
2619    (set_attr "prefix" "maybe_vex")
2620    (set_attr "mode" "V2DF")])
2621
2622 (define_insn "avx_cvtpd2dq256"
2623   [(set (match_operand:V4SI 0 "register_operand" "=x")
2624         (unspec:V4SI [(match_operand:V4DF 1 "nonimmediate_operand" "xm")]
2625                      UNSPEC_FIX_NOTRUNC))]
2626   "TARGET_AVX"
2627   "vcvtpd2dq{y}\t{%1, %0|%0, %1}"
2628   [(set_attr "type" "ssecvt")
2629    (set_attr "prefix" "vex")
2630    (set_attr "mode" "OI")])
2631
2632 (define_expand "sse2_cvtpd2dq"
2633   [(set (match_operand:V4SI 0 "register_operand" "")
2634         (vec_concat:V4SI
2635           (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "")]
2636                        UNSPEC_FIX_NOTRUNC)
2637           (match_dup 2)))]
2638   "TARGET_SSE2"
2639   "operands[2] = CONST0_RTX (V2SImode);")
2640
2641 (define_insn "*sse2_cvtpd2dq"
2642   [(set (match_operand:V4SI 0 "register_operand" "=x")
2643         (vec_concat:V4SI
2644           (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
2645                        UNSPEC_FIX_NOTRUNC)
2646           (match_operand:V2SI 2 "const0_operand" "")))]
2647   "TARGET_SSE2"
2648   "* return TARGET_AVX ? \"vcvtpd2dq{x}\t{%1, %0|%0, %1}\"
2649                        : \"cvtpd2dq\t{%1, %0|%0, %1}\";"
2650   [(set_attr "type" "ssecvt")
2651    (set_attr "prefix_rep" "1")
2652    (set_attr "prefix" "maybe_vex")
2653    (set_attr "mode" "TI")
2654    (set_attr "amdfam10_decode" "double")])
2655
2656 (define_insn "avx_cvttpd2dq256"
2657   [(set (match_operand:V4SI 0 "register_operand" "=x")
2658         (fix:V4SI (match_operand:V4DF 1 "nonimmediate_operand" "xm")))]
2659   "TARGET_AVX"
2660   "vcvttpd2dq{y}\t{%1, %0|%0, %1}"
2661   [(set_attr "type" "ssecvt")
2662    (set_attr "prefix" "vex")
2663    (set_attr "mode" "OI")])
2664
2665 (define_expand "sse2_cvttpd2dq"
2666   [(set (match_operand:V4SI 0 "register_operand" "")
2667         (vec_concat:V4SI
2668           (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" ""))
2669           (match_dup 2)))]
2670   "TARGET_SSE2"
2671   "operands[2] = CONST0_RTX (V2SImode);")
2672
2673 (define_insn "*sse2_cvttpd2dq"
2674   [(set (match_operand:V4SI 0 "register_operand" "=x")
2675         (vec_concat:V4SI
2676           (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
2677           (match_operand:V2SI 2 "const0_operand" "")))]
2678   "TARGET_SSE2"
2679   "* return TARGET_AVX ? \"vcvttpd2dq{x}\t{%1, %0|%0, %1}\"
2680                        : \"cvttpd2dq\t{%1, %0|%0, %1}\";"
2681   [(set_attr "type" "ssecvt")
2682    (set_attr "prefix_rep" "1")
2683    (set_attr "prefix" "maybe_vex")
2684    (set_attr "mode" "TI")
2685    (set_attr "amdfam10_decode" "double")])
2686
2687 (define_insn "*avx_cvtsd2ss"
2688   [(set (match_operand:V4SF 0 "register_operand" "=x")
2689         (vec_merge:V4SF
2690           (vec_duplicate:V4SF
2691             (float_truncate:V2SF
2692               (match_operand:V2DF 2 "nonimmediate_operand" "xm")))
2693           (match_operand:V4SF 1 "register_operand" "x")
2694           (const_int 1)))]
2695   "TARGET_AVX"
2696   "vcvtsd2ss\t{%2, %1, %0|%0, %1, %2}"
2697   [(set_attr "type" "ssecvt")
2698    (set_attr "prefix" "vex")
2699    (set_attr "mode" "SF")])
2700
2701 (define_insn "sse2_cvtsd2ss"
2702   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
2703         (vec_merge:V4SF
2704           (vec_duplicate:V4SF
2705             (float_truncate:V2SF
2706               (match_operand:V2DF 2 "nonimmediate_operand" "x,m")))
2707           (match_operand:V4SF 1 "register_operand" "0,0")
2708           (const_int 1)))]
2709   "TARGET_SSE2"
2710   "cvtsd2ss\t{%2, %0|%0, %2}"
2711   [(set_attr "type" "ssecvt")
2712    (set_attr "athlon_decode" "vector,double")
2713    (set_attr "amdfam10_decode" "vector,double")
2714    (set_attr "mode" "SF")])
2715
2716 (define_insn "*avx_cvtss2sd"
2717   [(set (match_operand:V2DF 0 "register_operand" "=x")
2718         (vec_merge:V2DF
2719           (float_extend:V2DF
2720             (vec_select:V2SF
2721               (match_operand:V4SF 2 "nonimmediate_operand" "xm")
2722               (parallel [(const_int 0) (const_int 1)])))
2723           (match_operand:V2DF 1 "register_operand" "x")
2724           (const_int 1)))]
2725   "TARGET_AVX"
2726   "vcvtss2sd\t{%2, %1, %0|%0, %1, %2}"
2727   [(set_attr "type" "ssecvt")
2728    (set_attr "prefix" "vex")
2729    (set_attr "mode" "DF")])
2730
2731 (define_insn "sse2_cvtss2sd"
2732   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
2733         (vec_merge:V2DF
2734           (float_extend:V2DF
2735             (vec_select:V2SF
2736               (match_operand:V4SF 2 "nonimmediate_operand" "x,m")
2737               (parallel [(const_int 0) (const_int 1)])))
2738           (match_operand:V2DF 1 "register_operand" "0,0")
2739           (const_int 1)))]
2740   "TARGET_SSE2"
2741   "cvtss2sd\t{%2, %0|%0, %2}"
2742   [(set_attr "type" "ssecvt")
2743    (set_attr "amdfam10_decode" "vector,double")
2744    (set_attr "mode" "DF")])
2745
2746 (define_insn "avx_cvtpd2ps256"
2747   [(set (match_operand:V4SF 0 "register_operand" "=x")
2748         (float_truncate:V4SF
2749           (match_operand:V4DF 1 "nonimmediate_operand" "xm")))]
2750   "TARGET_AVX"
2751   "vcvtpd2ps{y}\t{%1, %0|%0, %1}"
2752   [(set_attr "type" "ssecvt")
2753    (set_attr "prefix" "vex")
2754    (set_attr "mode" "V4SF")])
2755
2756 (define_expand "sse2_cvtpd2ps"
2757   [(set (match_operand:V4SF 0 "register_operand" "")
2758         (vec_concat:V4SF
2759           (float_truncate:V2SF
2760             (match_operand:V2DF 1 "nonimmediate_operand" ""))
2761           (match_dup 2)))]
2762   "TARGET_SSE2"
2763   "operands[2] = CONST0_RTX (V2SFmode);")
2764
2765 (define_insn "*sse2_cvtpd2ps"
2766   [(set (match_operand:V4SF 0 "register_operand" "=x")
2767         (vec_concat:V4SF
2768           (float_truncate:V2SF
2769             (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
2770           (match_operand:V2SF 2 "const0_operand" "")))]
2771   "TARGET_SSE2"
2772   "* return TARGET_AVX ? \"vcvtpd2ps{x}\t{%1, %0|%0, %1}\"
2773                        : \"cvtpd2ps\t{%1, %0|%0, %1}\";"
2774   [(set_attr "type" "ssecvt")
2775    (set_attr "prefix_data16" "1")
2776    (set_attr "prefix" "maybe_vex")
2777    (set_attr "mode" "V4SF")
2778    (set_attr "amdfam10_decode" "double")])
2779
2780 (define_insn "avx_cvtps2pd256"
2781   [(set (match_operand:V4DF 0 "register_operand" "=x")
2782         (float_extend:V4DF
2783           (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
2784   "TARGET_AVX"
2785   "vcvtps2pd\t{%1, %0|%0, %1}"
2786   [(set_attr "type" "ssecvt")
2787    (set_attr "prefix" "vex")
2788    (set_attr "mode" "V4DF")])
2789
2790 (define_insn "sse2_cvtps2pd"
2791   [(set (match_operand:V2DF 0 "register_operand" "=x")
2792         (float_extend:V2DF
2793           (vec_select:V2SF
2794             (match_operand:V4SF 1 "nonimmediate_operand" "xm")
2795             (parallel [(const_int 0) (const_int 1)]))))]
2796   "TARGET_SSE2"
2797   "%vcvtps2pd\t{%1, %0|%0, %1}"
2798   [(set_attr "type" "ssecvt")
2799    (set_attr "prefix" "maybe_vex")
2800    (set_attr "mode" "V2DF")
2801    (set_attr "amdfam10_decode" "direct")])
2802
2803 (define_expand "vec_unpacks_hi_v4sf"
2804   [(set (match_dup 2)
2805    (vec_select:V4SF
2806      (vec_concat:V8SF
2807        (match_dup 2)
2808        (match_operand:V4SF 1 "nonimmediate_operand" ""))
2809      (parallel [(const_int 6)
2810                 (const_int 7)
2811                 (const_int 2)
2812                 (const_int 3)])))
2813   (set (match_operand:V2DF 0 "register_operand" "")
2814    (float_extend:V2DF
2815      (vec_select:V2SF
2816        (match_dup 2)
2817        (parallel [(const_int 0) (const_int 1)]))))]
2818  "TARGET_SSE2"
2819 {
2820  operands[2] = gen_reg_rtx (V4SFmode);
2821 })
2822
2823 (define_expand "vec_unpacks_lo_v4sf"
2824   [(set (match_operand:V2DF 0 "register_operand" "")
2825         (float_extend:V2DF
2826           (vec_select:V2SF
2827             (match_operand:V4SF 1 "nonimmediate_operand" "")
2828             (parallel [(const_int 0) (const_int 1)]))))]
2829   "TARGET_SSE2")
2830
2831 (define_expand "vec_unpacks_float_hi_v8hi"
2832   [(match_operand:V4SF 0 "register_operand" "")
2833    (match_operand:V8HI 1 "register_operand" "")]
2834   "TARGET_SSE2"
2835 {
2836   rtx tmp = gen_reg_rtx (V4SImode);
2837
2838   emit_insn (gen_vec_unpacks_hi_v8hi (tmp, operands[1]));
2839   emit_insn (gen_sse2_cvtdq2ps (operands[0], tmp));
2840   DONE;
2841 })
2842
2843 (define_expand "vec_unpacks_float_lo_v8hi"
2844   [(match_operand:V4SF 0 "register_operand" "")
2845    (match_operand:V8HI 1 "register_operand" "")]
2846   "TARGET_SSE2"
2847 {
2848   rtx tmp = gen_reg_rtx (V4SImode);
2849
2850   emit_insn (gen_vec_unpacks_lo_v8hi (tmp, operands[1]));
2851   emit_insn (gen_sse2_cvtdq2ps (operands[0], tmp));
2852   DONE;
2853 })
2854
2855 (define_expand "vec_unpacku_float_hi_v8hi"
2856   [(match_operand:V4SF 0 "register_operand" "")
2857    (match_operand:V8HI 1 "register_operand" "")]
2858   "TARGET_SSE2"
2859 {
2860   rtx tmp = gen_reg_rtx (V4SImode);
2861
2862   emit_insn (gen_vec_unpacku_hi_v8hi (tmp, operands[1]));
2863   emit_insn (gen_sse2_cvtdq2ps (operands[0], tmp));
2864   DONE;
2865 })
2866
2867 (define_expand "vec_unpacku_float_lo_v8hi"
2868   [(match_operand:V4SF 0 "register_operand" "")
2869    (match_operand:V8HI 1 "register_operand" "")]
2870   "TARGET_SSE2"
2871 {
2872   rtx tmp = gen_reg_rtx (V4SImode);
2873
2874   emit_insn (gen_vec_unpacku_lo_v8hi (tmp, operands[1]));
2875   emit_insn (gen_sse2_cvtdq2ps (operands[0], tmp));
2876   DONE;
2877 })
2878
2879 (define_expand "vec_unpacks_float_hi_v4si"
2880   [(set (match_dup 2)
2881         (vec_select:V4SI
2882           (match_operand:V4SI 1 "nonimmediate_operand" "")
2883           (parallel [(const_int 2)
2884                      (const_int 3)
2885                      (const_int 2)
2886                      (const_int 3)])))
2887    (set (match_operand:V2DF 0 "register_operand" "")
2888         (float:V2DF
2889           (vec_select:V2SI
2890           (match_dup 2)
2891             (parallel [(const_int 0) (const_int 1)]))))]
2892  "TARGET_SSE2"
2893 {
2894  operands[2] = gen_reg_rtx (V4SImode);
2895 })
2896
2897 (define_expand "vec_unpacks_float_lo_v4si"
2898   [(set (match_operand:V2DF 0 "register_operand" "")
2899         (float:V2DF
2900           (vec_select:V2SI
2901             (match_operand:V4SI 1 "nonimmediate_operand" "")
2902             (parallel [(const_int 0) (const_int 1)]))))]
2903   "TARGET_SSE2")
2904
2905 (define_expand "vec_pack_trunc_v2df"
2906   [(match_operand:V4SF 0 "register_operand" "")
2907    (match_operand:V2DF 1 "nonimmediate_operand" "")
2908    (match_operand:V2DF 2 "nonimmediate_operand" "")]
2909   "TARGET_SSE2"
2910 {
2911   rtx r1, r2;
2912
2913   r1 = gen_reg_rtx (V4SFmode);
2914   r2 = gen_reg_rtx (V4SFmode);
2915
2916   emit_insn (gen_sse2_cvtpd2ps (r1, operands[1]));
2917   emit_insn (gen_sse2_cvtpd2ps (r2, operands[2]));
2918   emit_insn (gen_sse_movlhps (operands[0], r1, r2));
2919   DONE;
2920 })
2921
2922 (define_expand "vec_pack_sfix_trunc_v2df"
2923   [(match_operand:V4SI 0 "register_operand" "")
2924    (match_operand:V2DF 1 "nonimmediate_operand" "")
2925    (match_operand:V2DF 2 "nonimmediate_operand" "")]
2926   "TARGET_SSE2"
2927 {
2928   rtx r1, r2;
2929
2930   r1 = gen_reg_rtx (V4SImode);
2931   r2 = gen_reg_rtx (V4SImode);
2932
2933   emit_insn (gen_sse2_cvttpd2dq (r1, operands[1]));
2934   emit_insn (gen_sse2_cvttpd2dq (r2, operands[2]));
2935   emit_insn (gen_sse2_punpcklqdq (gen_lowpart (V2DImode, operands[0]),
2936                                   gen_lowpart (V2DImode, r1),
2937                                   gen_lowpart (V2DImode, r2)));
2938   DONE;
2939 })
2940
2941 (define_expand "vec_pack_sfix_v2df"
2942   [(match_operand:V4SI 0 "register_operand" "")
2943    (match_operand:V2DF 1 "nonimmediate_operand" "")
2944    (match_operand:V2DF 2 "nonimmediate_operand" "")]
2945   "TARGET_SSE2"
2946 {
2947   rtx r1, r2;
2948
2949   r1 = gen_reg_rtx (V4SImode);
2950   r2 = gen_reg_rtx (V4SImode);
2951
2952   emit_insn (gen_sse2_cvtpd2dq (r1, operands[1]));
2953   emit_insn (gen_sse2_cvtpd2dq (r2, operands[2]));
2954   emit_insn (gen_sse2_punpcklqdq (gen_lowpart (V2DImode, operands[0]),
2955                                   gen_lowpart (V2DImode, r1),
2956                                   gen_lowpart (V2DImode, r2)));
2957   DONE;
2958 })
2959
2960 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2961 ;;
2962 ;; Parallel single-precision floating point element swizzling
2963 ;;
2964 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2965
2966 (define_expand "sse_movhlps_exp"
2967   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
2968         (vec_select:V4SF
2969           (vec_concat:V8SF
2970             (match_operand:V4SF 1 "nonimmediate_operand" "")
2971             (match_operand:V4SF 2 "nonimmediate_operand" ""))
2972           (parallel [(const_int 6)
2973                      (const_int 7)
2974                      (const_int 2)
2975                      (const_int 3)])))]
2976   "TARGET_SSE"
2977   "ix86_fixup_binary_operands (UNKNOWN, V4SFmode, operands);")
2978
2979 (define_insn "*avx_movhlps"
2980   [(set (match_operand:V4SF 0 "nonimmediate_operand"     "=x,x,m")
2981         (vec_select:V4SF
2982           (vec_concat:V8SF
2983             (match_operand:V4SF 1 "nonimmediate_operand" " x,x,0")
2984             (match_operand:V4SF 2 "nonimmediate_operand" " x,o,x"))
2985           (parallel [(const_int 6)
2986                      (const_int 7)
2987                      (const_int 2)
2988                      (const_int 3)])))]
2989   "TARGET_AVX && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
2990   "@
2991    vmovhlps\t{%2, %1, %0|%0, %1, %2}
2992    vmovlps\t{%H2, %1, %0|%0, %1, %H2}
2993    vmovhps\t{%2, %0|%0, %2}"
2994   [(set_attr "type" "ssemov")
2995    (set_attr "prefix" "vex")
2996    (set_attr "mode" "V4SF,V2SF,V2SF")])
2997
2998 (define_insn "sse_movhlps"
2999   [(set (match_operand:V4SF 0 "nonimmediate_operand"     "=x,x,m")
3000         (vec_select:V4SF
3001           (vec_concat:V8SF
3002             (match_operand:V4SF 1 "nonimmediate_operand" " 0,0,0")
3003             (match_operand:V4SF 2 "nonimmediate_operand" " x,o,x"))
3004           (parallel [(const_int 6)
3005                      (const_int 7)
3006                      (const_int 2)
3007                      (const_int 3)])))]
3008   "TARGET_SSE && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
3009   "@
3010    movhlps\t{%2, %0|%0, %2}
3011    movlps\t{%H2, %0|%0, %H2}
3012    movhps\t{%2, %0|%0, %2}"
3013   [(set_attr "type" "ssemov")
3014    (set_attr "mode" "V4SF,V2SF,V2SF")])
3015
3016 (define_expand "sse_movlhps_exp"
3017   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
3018         (vec_select:V4SF
3019           (vec_concat:V8SF
3020             (match_operand:V4SF 1 "nonimmediate_operand" "")
3021             (match_operand:V4SF 2 "nonimmediate_operand" ""))
3022           (parallel [(const_int 0)
3023                      (const_int 1)
3024                      (const_int 4)
3025                      (const_int 5)])))]
3026   "TARGET_SSE"
3027   "ix86_fixup_binary_operands (UNKNOWN, V4SFmode, operands);")
3028
3029 (define_insn "*avx_movlhps"
3030   [(set (match_operand:V4SF 0 "nonimmediate_operand"     "=x,x,o")
3031         (vec_select:V4SF
3032           (vec_concat:V8SF
3033             (match_operand:V4SF 1 "nonimmediate_operand" " x,x,0")
3034             (match_operand:V4SF 2 "nonimmediate_operand" " x,m,x"))
3035           (parallel [(const_int 0)
3036                      (const_int 1)
3037                      (const_int 4)
3038                      (const_int 5)])))]
3039   "TARGET_AVX && ix86_binary_operator_ok (UNKNOWN, V4SFmode, operands)"
3040   "@
3041    vmovlhps\t{%2, %1, %0|%0, %1, %2}
3042    vmovhps\t{%2, %1, %0|%0, %1, %2}
3043    vmovlps\t{%2, %H0|%H0, %2}"
3044   [(set_attr "type" "ssemov")
3045    (set_attr "prefix" "vex")
3046    (set_attr "mode" "V4SF,V2SF,V2SF")])
3047
3048 (define_insn "sse_movlhps"
3049   [(set (match_operand:V4SF 0 "nonimmediate_operand"     "=x,x,o")
3050         (vec_select:V4SF
3051           (vec_concat:V8SF
3052             (match_operand:V4SF 1 "nonimmediate_operand" " 0,0,0")
3053             (match_operand:V4SF 2 "nonimmediate_operand" " x,m,x"))
3054           (parallel [(const_int 0)
3055                      (const_int 1)
3056                      (const_int 4)
3057                      (const_int 5)])))]
3058   "TARGET_SSE && ix86_binary_operator_ok (UNKNOWN, V4SFmode, operands)"
3059   "@
3060    movlhps\t{%2, %0|%0, %2}
3061    movhps\t{%2, %0|%0, %2}
3062    movlps\t{%2, %H0|%H0, %2}"
3063   [(set_attr "type" "ssemov")
3064    (set_attr "mode" "V4SF,V2SF,V2SF")])
3065
3066 (define_insn "avx_unpckhps256"
3067   [(set (match_operand:V8SF 0 "register_operand" "=x")
3068         (vec_select:V8SF
3069           (vec_concat:V16SF
3070             (match_operand:V8SF 1 "register_operand" "x")
3071             (match_operand:V8SF 2 "nonimmediate_operand" "xm"))
3072           (parallel [(const_int 2) (const_int 10)
3073                      (const_int 3) (const_int 11)
3074                      (const_int 6) (const_int 14)
3075                      (const_int 7) (const_int 15)])))]
3076   "TARGET_AVX"
3077   "vunpckhps\t{%2, %1, %0|%0, %1, %2}"
3078   [(set_attr "type" "sselog")
3079    (set_attr "prefix" "vex")
3080    (set_attr "mode" "V8SF")])
3081
3082 (define_insn "*avx_unpckhps"
3083   [(set (match_operand:V4SF 0 "register_operand" "=x")
3084         (vec_select:V4SF
3085           (vec_concat:V8SF
3086             (match_operand:V4SF 1 "register_operand" "x")
3087             (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
3088           (parallel [(const_int 2) (const_int 6)
3089                      (const_int 3) (const_int 7)])))]
3090   "TARGET_AVX"
3091   "vunpckhps\t{%2, %1, %0|%0, %1, %2}"
3092   [(set_attr "type" "sselog")
3093    (set_attr "prefix" "vex")
3094    (set_attr "mode" "V4SF")])
3095
3096 (define_insn "sse_unpckhps"
3097   [(set (match_operand:V4SF 0 "register_operand" "=x")
3098         (vec_select:V4SF
3099           (vec_concat:V8SF
3100             (match_operand:V4SF 1 "register_operand" "0")
3101             (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
3102           (parallel [(const_int 2) (const_int 6)
3103                      (const_int 3) (const_int 7)])))]
3104   "TARGET_SSE"
3105   "unpckhps\t{%2, %0|%0, %2}"
3106   [(set_attr "type" "sselog")
3107    (set_attr "mode" "V4SF")])
3108
3109 (define_insn "avx_unpcklps256"
3110   [(set (match_operand:V8SF 0 "register_operand" "=x")
3111         (vec_select:V8SF
3112           (vec_concat:V16SF
3113             (match_operand:V8SF 1 "register_operand" "x")
3114             (match_operand:V8SF 2 "nonimmediate_operand" "xm"))
3115           (parallel [(const_int 0) (const_int 8)
3116                      (const_int 1) (const_int 9)
3117                      (const_int 4) (const_int 12)
3118                      (const_int 5) (const_int 13)])))]
3119   "TARGET_AVX"
3120   "vunpcklps\t{%2, %1, %0|%0, %1, %2}"
3121   [(set_attr "type" "sselog")
3122    (set_attr "prefix" "vex")
3123    (set_attr "mode" "V8SF")])
3124
3125 (define_insn "*avx_unpcklps"
3126   [(set (match_operand:V4SF 0 "register_operand" "=x")
3127         (vec_select:V4SF
3128           (vec_concat:V8SF
3129             (match_operand:V4SF 1 "register_operand" "x")
3130             (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
3131           (parallel [(const_int 0) (const_int 4)
3132                      (const_int 1) (const_int 5)])))]
3133   "TARGET_AVX"
3134   "vunpcklps\t{%2, %1, %0|%0, %1, %2}"
3135   [(set_attr "type" "sselog")
3136    (set_attr "prefix" "vex")
3137    (set_attr "mode" "V4SF")])
3138
3139 (define_insn "sse_unpcklps"
3140   [(set (match_operand:V4SF 0 "register_operand" "=x")
3141         (vec_select:V4SF
3142           (vec_concat:V8SF
3143             (match_operand:V4SF 1 "register_operand" "0")
3144             (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
3145           (parallel [(const_int 0) (const_int 4)
3146                      (const_int 1) (const_int 5)])))]
3147   "TARGET_SSE"
3148   "unpcklps\t{%2, %0|%0, %2}"
3149   [(set_attr "type" "sselog")
3150    (set_attr "mode" "V4SF")])
3151
3152 ;; These are modeled with the same vec_concat as the others so that we
3153 ;; capture users of shufps that can use the new instructions
3154 (define_insn "avx_movshdup256"
3155   [(set (match_operand:V8SF 0 "register_operand" "=x")
3156         (vec_select:V8SF
3157           (vec_concat:V16SF
3158             (match_operand:V8SF 1 "nonimmediate_operand" "xm")
3159             (match_dup 1))
3160           (parallel [(const_int 1) (const_int 1)
3161                      (const_int 3) (const_int 3)
3162                      (const_int 5) (const_int 5)
3163                      (const_int 7) (const_int 7)])))]
3164   "TARGET_AVX"
3165   "vmovshdup\t{%1, %0|%0, %1}"
3166   [(set_attr "type" "sse")
3167    (set_attr "prefix" "vex")
3168    (set_attr "mode" "V8SF")])
3169
3170 (define_insn "sse3_movshdup"
3171   [(set (match_operand:V4SF 0 "register_operand" "=x")
3172         (vec_select:V4SF
3173           (vec_concat:V8SF
3174             (match_operand:V4SF 1 "nonimmediate_operand" "xm")
3175             (match_dup 1))
3176           (parallel [(const_int 1)
3177                      (const_int 1)
3178                      (const_int 7)
3179                      (const_int 7)])))]
3180   "TARGET_SSE3"
3181   "%vmovshdup\t{%1, %0|%0, %1}"
3182   [(set_attr "type" "sse")
3183    (set_attr "prefix_rep" "1")
3184    (set_attr "prefix" "maybe_vex")
3185    (set_attr "mode" "V4SF")])
3186
3187 (define_insn "avx_movsldup256"
3188   [(set (match_operand:V8SF 0 "register_operand" "=x")
3189         (vec_select:V8SF
3190           (vec_concat:V16SF
3191             (match_operand:V8SF 1 "nonimmediate_operand" "xm")
3192             (match_dup 1))
3193           (parallel [(const_int 0) (const_int 0)
3194                      (const_int 2) (const_int 2)
3195                      (const_int 4) (const_int 4)
3196                      (const_int 6) (const_int 6)])))]
3197   "TARGET_AVX"
3198   "vmovsldup\t{%1, %0|%0, %1}"
3199   [(set_attr "type" "sse")
3200    (set_attr "prefix" "vex")
3201    (set_attr "mode" "V8SF")])
3202
3203 (define_insn "sse3_movsldup"
3204   [(set (match_operand:V4SF 0 "register_operand" "=x")
3205         (vec_select:V4SF
3206           (vec_concat:V8SF
3207             (match_operand:V4SF 1 "nonimmediate_operand" "xm")
3208             (match_dup 1))
3209           (parallel [(const_int 0)
3210                      (const_int 0)
3211                      (const_int 6)
3212                      (const_int 6)])))]
3213   "TARGET_SSE3"
3214   "%vmovsldup\t{%1, %0|%0, %1}"
3215   [(set_attr "type" "sse")
3216    (set_attr "prefix_rep" "1")
3217    (set_attr "prefix" "maybe_vex")
3218    (set_attr "mode" "V4SF")])
3219
3220 (define_expand "avx_shufps256"
3221   [(match_operand:V8SF 0 "register_operand" "")
3222    (match_operand:V8SF 1 "register_operand" "")
3223    (match_operand:V8SF 2 "nonimmediate_operand" "")
3224    (match_operand:SI 3 "const_int_operand" "")]
3225   "TARGET_AVX"
3226 {
3227   int mask = INTVAL (operands[3]);
3228   emit_insn (gen_avx_shufps256_1 (operands[0], operands[1], operands[2],
3229                                   GEN_INT ((mask >> 0) & 3),
3230                                   GEN_INT ((mask >> 2) & 3),
3231                                   GEN_INT (((mask >> 4) & 3) + 8),
3232                                   GEN_INT (((mask >> 6) & 3) + 8),
3233                                   GEN_INT (((mask >> 0) & 3) + 4),
3234                                   GEN_INT (((mask >> 2) & 3) + 4),
3235                                   GEN_INT (((mask >> 4) & 3) + 12),
3236                                   GEN_INT (((mask >> 6) & 3) + 12)));
3237   DONE;
3238 })
3239
3240 ;; One bit in mask selects 2 elements.
3241 (define_insn "avx_shufps256_1"
3242   [(set (match_operand:V8SF 0 "register_operand" "=x")
3243         (vec_select:V8SF
3244           (vec_concat:V16SF
3245             (match_operand:V8SF 1 "register_operand" "x")
3246             (match_operand:V8SF 2 "nonimmediate_operand" "xm"))
3247           (parallel [(match_operand 3  "const_0_to_3_operand"   "")
3248                      (match_operand 4  "const_0_to_3_operand"   "")
3249                      (match_operand 5  "const_8_to_11_operand"  "")
3250                      (match_operand 6  "const_8_to_11_operand"  "")
3251                      (match_operand 7  "const_4_to_7_operand"   "")
3252                      (match_operand 8  "const_4_to_7_operand"   "")
3253                      (match_operand 9  "const_12_to_15_operand" "")
3254                      (match_operand 10 "const_12_to_15_operand" "")])))]
3255   "TARGET_AVX
3256    && (INTVAL (operands[3]) == (INTVAL (operands[7]) - 4)
3257        && INTVAL (operands[4]) == (INTVAL (operands[8]) - 4)
3258        && INTVAL (operands[5]) == (INTVAL (operands[9]) - 4)
3259        && INTVAL (operands[6]) == (INTVAL (operands[10]) - 4))"
3260 {
3261   int mask;
3262   mask = INTVAL (operands[3]);
3263   mask |= INTVAL (operands[4]) << 2;
3264   mask |= (INTVAL (operands[5]) - 8) << 4;
3265   mask |= (INTVAL (operands[6]) - 8) << 6;
3266   operands[3] = GEN_INT (mask);
3267
3268   return "vshufps\t{%3, %2, %1, %0|%0, %1, %2, %3}";
3269 }
3270   [(set_attr "type" "sselog")
3271    (set_attr "prefix" "vex")
3272    (set_attr "mode" "V8SF")])
3273
3274 (define_expand "sse_shufps"
3275   [(match_operand:V4SF 0 "register_operand" "")
3276    (match_operand:V4SF 1 "register_operand" "")
3277    (match_operand:V4SF 2 "nonimmediate_operand" "")
3278    (match_operand:SI 3 "const_int_operand" "")]
3279   "TARGET_SSE"
3280 {
3281   int mask = INTVAL (operands[3]);
3282   emit_insn (gen_sse_shufps_v4sf (operands[0], operands[1], operands[2],
3283                                GEN_INT ((mask >> 0) & 3),
3284                                GEN_INT ((mask >> 2) & 3),
3285                                GEN_INT (((mask >> 4) & 3) + 4),
3286                                GEN_INT (((mask >> 6) & 3) + 4)));
3287   DONE;
3288 })
3289
3290 (define_insn "*avx_shufps_<mode>"
3291   [(set (match_operand:SSEMODE4S 0 "register_operand" "=x")
3292         (vec_select:SSEMODE4S
3293           (vec_concat:<ssedoublesizemode>
3294             (match_operand:SSEMODE4S 1 "register_operand" "x")
3295             (match_operand:SSEMODE4S 2 "nonimmediate_operand" "xm"))
3296           (parallel [(match_operand 3 "const_0_to_3_operand" "")
3297                      (match_operand 4 "const_0_to_3_operand" "")
3298                      (match_operand 5 "const_4_to_7_operand" "")
3299                      (match_operand 6 "const_4_to_7_operand" "")])))]
3300   "TARGET_AVX"
3301 {
3302   int mask = 0;
3303   mask |= INTVAL (operands[3]) << 0;
3304   mask |= INTVAL (operands[4]) << 2;
3305   mask |= (INTVAL (operands[5]) - 4) << 4;
3306   mask |= (INTVAL (operands[6]) - 4) << 6;
3307   operands[3] = GEN_INT (mask);
3308
3309   return "vshufps\t{%3, %2, %1, %0|%0, %1, %2, %3}";
3310 }
3311   [(set_attr "type" "sselog")
3312    (set_attr "prefix" "vex")
3313    (set_attr "mode" "V4SF")])
3314
3315 (define_insn "sse_shufps_<mode>"
3316   [(set (match_operand:SSEMODE4S 0 "register_operand" "=x")
3317         (vec_select:SSEMODE4S
3318           (vec_concat:<ssedoublesizemode>
3319             (match_operand:SSEMODE4S 1 "register_operand" "0")
3320             (match_operand:SSEMODE4S 2 "nonimmediate_operand" "xm"))
3321           (parallel [(match_operand 3 "const_0_to_3_operand" "")
3322                      (match_operand 4 "const_0_to_3_operand" "")
3323                      (match_operand 5 "const_4_to_7_operand" "")
3324                      (match_operand 6 "const_4_to_7_operand" "")])))]
3325   "TARGET_SSE"
3326 {
3327   int mask = 0;
3328   mask |= INTVAL (operands[3]) << 0;
3329   mask |= INTVAL (operands[4]) << 2;
3330   mask |= (INTVAL (operands[5]) - 4) << 4;
3331   mask |= (INTVAL (operands[6]) - 4) << 6;
3332   operands[3] = GEN_INT (mask);
3333
3334   return "shufps\t{%3, %2, %0|%0, %2, %3}";
3335 }
3336   [(set_attr "type" "sselog")
3337    (set_attr "mode" "V4SF")])
3338
3339 (define_insn "sse_storehps"
3340   [(set (match_operand:V2SF 0 "nonimmediate_operand" "=m,x,x")
3341         (vec_select:V2SF
3342           (match_operand:V4SF 1 "nonimmediate_operand" "x,x,o")
3343           (parallel [(const_int 2) (const_int 3)])))]
3344   "TARGET_SSE"
3345   "@
3346    %vmovhps\t{%1, %0|%0, %1}
3347    %vmovhlps\t{%1, %d0|%d0, %1}
3348    %vmovlps\t{%H1, %d0|%d0, %H1}"
3349   [(set_attr "type" "ssemov")
3350    (set_attr "prefix" "maybe_vex")
3351    (set_attr "mode" "V2SF,V4SF,V2SF")])
3352
3353 (define_expand "sse_loadhps_exp"
3354   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
3355         (vec_concat:V4SF
3356           (vec_select:V2SF
3357             (match_operand:V4SF 1 "nonimmediate_operand" "")
3358             (parallel [(const_int 0) (const_int 1)]))
3359           (match_operand:V2SF 2 "nonimmediate_operand" "")))]
3360   "TARGET_SSE"
3361   "ix86_fixup_binary_operands (UNKNOWN, V4SFmode, operands);")
3362
3363 (define_insn "*avx_loadhps"
3364   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,o")
3365         (vec_concat:V4SF
3366           (vec_select:V2SF
3367             (match_operand:V4SF 1 "nonimmediate_operand" "x,x,0")
3368             (parallel [(const_int 0) (const_int 1)]))
3369           (match_operand:V2SF 2 "nonimmediate_operand" "m,x,x")))]
3370   "TARGET_AVX"
3371   "@
3372    vmovhps\t{%2, %1, %0|%0, %1, %2}
3373    vmovlhps\t{%2, %1, %0|%0, %1, %2}
3374    vmovlps\t{%2, %H0|%H0, %2}"
3375   [(set_attr "type" "ssemov")
3376    (set_attr "prefix" "vex")
3377    (set_attr "mode" "V2SF,V4SF,V2SF")])
3378
3379 (define_insn "sse_loadhps"
3380   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,o")
3381         (vec_concat:V4SF
3382           (vec_select:V2SF
3383             (match_operand:V4SF 1 "nonimmediate_operand" "0,0,0")
3384             (parallel [(const_int 0) (const_int 1)]))
3385           (match_operand:V2SF 2 "nonimmediate_operand" "m,x,x")))]
3386   "TARGET_SSE"
3387   "@
3388    movhps\t{%2, %0|%0, %2}
3389    movlhps\t{%2, %0|%0, %2}
3390    movlps\t{%2, %H0|%H0, %2}"
3391   [(set_attr "type" "ssemov")
3392    (set_attr "mode" "V2SF,V4SF,V2SF")])
3393
3394 (define_insn "*avx_storelps"
3395   [(set (match_operand:V2SF 0 "nonimmediate_operand" "=m,x,x")
3396         (vec_select:V2SF
3397           (match_operand:V4SF 1 "nonimmediate_operand" "x,x,m")
3398           (parallel [(const_int 0) (const_int 1)])))]
3399   "TARGET_AVX"
3400   "@
3401    vmovlps\t{%1, %0|%0, %1}
3402    vmovaps\t{%1, %0|%0, %1}
3403    vmovlps\t{%1, %0, %0|%0, %0, %1}"
3404   [(set_attr "type" "ssemov")
3405    (set_attr "prefix" "vex")
3406    (set_attr "mode" "V2SF,V2DF,V2SF")])
3407
3408 (define_insn "sse_storelps"
3409   [(set (match_operand:V2SF 0 "nonimmediate_operand" "=m,x,x")
3410         (vec_select:V2SF
3411           (match_operand:V4SF 1 "nonimmediate_operand" "x,x,m")
3412           (parallel [(const_int 0) (const_int 1)])))]
3413   "TARGET_SSE"
3414   "@
3415    movlps\t{%1, %0|%0, %1}
3416    movaps\t{%1, %0|%0, %1}
3417    movlps\t{%1, %0|%0, %1}"
3418   [(set_attr "type" "ssemov")
3419    (set_attr "mode" "V2SF,V4SF,V2SF")])
3420
3421 (define_expand "sse_loadlps_exp"
3422   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
3423         (vec_concat:V4SF
3424           (match_operand:V2SF 2 "nonimmediate_operand" "")
3425           (vec_select:V2SF
3426             (match_operand:V4SF 1 "nonimmediate_operand" "")
3427             (parallel [(const_int 2) (const_int 3)]))))]
3428   "TARGET_SSE"
3429   "ix86_fixup_binary_operands (UNKNOWN, V4SFmode, operands);")
3430
3431 (define_insn "*avx_loadlps"
3432   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
3433         (vec_concat:V4SF
3434           (match_operand:V2SF 2 "nonimmediate_operand" "x,m,x")
3435           (vec_select:V2SF
3436             (match_operand:V4SF 1 "nonimmediate_operand" "x,x,0")
3437             (parallel [(const_int 2) (const_int 3)]))))]
3438   "TARGET_AVX"
3439   "@
3440    shufps\t{$0xe4, %1, %2, %0|%0, %2, %1, 0xe4}
3441    vmovlps\t{%2, %1, %0|%0, %1, %2}
3442    vmovlps\t{%2, %0|%0, %2}"
3443   [(set_attr "type" "sselog,ssemov,ssemov")
3444    (set_attr "prefix" "vex")
3445    (set_attr "mode" "V4SF,V2SF,V2SF")])
3446
3447 (define_insn "sse_loadlps"
3448   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
3449         (vec_concat:V4SF
3450           (match_operand:V2SF 2 "nonimmediate_operand" "0,m,x")
3451           (vec_select:V2SF
3452             (match_operand:V4SF 1 "nonimmediate_operand" "x,0,0")
3453             (parallel [(const_int 2) (const_int 3)]))))]
3454   "TARGET_SSE"
3455   "@
3456    shufps\t{$0xe4, %1, %0|%0, %1, 0xe4}
3457    movlps\t{%2, %0|%0, %2}
3458    movlps\t{%2, %0|%0, %2}"
3459   [(set_attr "type" "sselog,ssemov,ssemov")
3460    (set_attr "mode" "V4SF,V2SF,V2SF")])
3461
3462 (define_insn "*avx_movss"
3463   [(set (match_operand:V4SF 0 "register_operand" "=x")
3464         (vec_merge:V4SF
3465           (match_operand:V4SF 2 "register_operand" "x")
3466           (match_operand:V4SF 1 "register_operand" "x")
3467           (const_int 1)))]
3468   "TARGET_AVX"
3469   "vmovss\t{%2, %1, %0|%0, %1, %2}"
3470   [(set_attr "type" "ssemov")
3471    (set_attr "prefix" "vex")
3472    (set_attr "mode" "SF")])
3473
3474 (define_insn "sse_movss"
3475   [(set (match_operand:V4SF 0 "register_operand" "=x")
3476         (vec_merge:V4SF
3477           (match_operand:V4SF 2 "register_operand" "x")
3478           (match_operand:V4SF 1 "register_operand" "0")
3479           (const_int 1)))]
3480   "TARGET_SSE"
3481   "movss\t{%2, %0|%0, %2}"
3482   [(set_attr "type" "ssemov")
3483    (set_attr "mode" "SF")])
3484
3485 (define_insn "*vec_dupv4sf_avx"
3486   [(set (match_operand:V4SF 0 "register_operand" "=x")
3487         (vec_duplicate:V4SF
3488           (match_operand:SF 1 "register_operand" "x")))]
3489   "TARGET_AVX"
3490   "vshufps\t{$0, %1, %1, %0|%0, %1, %1, 0}"
3491   [(set_attr "type" "sselog1")
3492    (set_attr "prefix" "vex")
3493    (set_attr "mode" "V4SF")])
3494
3495 (define_insn "*vec_dupv4sf"
3496   [(set (match_operand:V4SF 0 "register_operand" "=x")
3497         (vec_duplicate:V4SF
3498           (match_operand:SF 1 "register_operand" "0")))]
3499   "TARGET_SSE"
3500   "shufps\t{$0, %0, %0|%0, %0, 0}"
3501   [(set_attr "type" "sselog1")
3502    (set_attr "mode" "V4SF")])
3503
3504 (define_insn "*vec_concatv2sf_avx"
3505   [(set (match_operand:V2SF 0 "register_operand"     "=x,x,x,*y ,*y")
3506         (vec_concat:V2SF
3507           (match_operand:SF 1 "nonimmediate_operand" " x,x,m, x , m")
3508           (match_operand:SF 2 "vector_move_operand"  " x,m,C,*ym, C")))]
3509   "TARGET_AVX"
3510   "@
3511    vunpcklps\t{%2, %1, %0|%0, %1, %2}
3512    vinsertps\t{$0x10, %2, %1, %0|%0, %1, %2, 0x10}
3513    vmovss\t{%1, %0|%0, %1}
3514    punpckldq\t{%2, %0|%0, %2}
3515    movd\t{%1, %0|%0, %1}"
3516   [(set_attr "type" "sselog,sselog,ssemov,mmxcvt,mmxmov")
3517    (set (attr "prefix")
3518      (if_then_else (eq_attr "alternative" "3,4")
3519        (const_string "orig")
3520        (const_string "vex")))
3521    (set_attr "mode" "V4SF,V4SF,SF,DI,DI")])
3522
3523 ;; Although insertps takes register source, we prefer
3524 ;; unpcklps with register source since it is shorter.
3525 (define_insn "*vec_concatv2sf_sse4_1"
3526   [(set (match_operand:V2SF 0 "register_operand"     "=x,x,x,*y ,*y")
3527         (vec_concat:V2SF
3528           (match_operand:SF 1 "nonimmediate_operand" " 0,0,m, 0 , m")
3529           (match_operand:SF 2 "vector_move_operand"  " x,m,C,*ym, C")))]
3530   "TARGET_SSE4_1"
3531   "@
3532    unpcklps\t{%2, %0|%0, %2}
3533    insertps\t{$0x10, %2, %0|%0, %2, 0x10}
3534    movss\t{%1, %0|%0, %1}
3535    punpckldq\t{%2, %0|%0, %2}
3536    movd\t{%1, %0|%0, %1}"
3537   [(set_attr "type" "sselog,sselog,ssemov,mmxcvt,mmxmov")
3538    (set_attr "prefix_extra" "*,1,*,*,*")
3539    (set_attr "mode" "V4SF,V4SF,SF,DI,DI")])
3540
3541 ;; ??? In theory we can match memory for the MMX alternative, but allowing
3542 ;; nonimmediate_operand for operand 2 and *not* allowing memory for the SSE
3543 ;; alternatives pretty much forces the MMX alternative to be chosen.
3544 (define_insn "*vec_concatv2sf_sse"
3545   [(set (match_operand:V2SF 0 "register_operand"     "=x,x,*y,*y")
3546         (vec_concat:V2SF
3547           (match_operand:SF 1 "nonimmediate_operand" " 0,m, 0, m")
3548           (match_operand:SF 2 "reg_or_0_operand"     " x,C,*y, C")))]
3549   "TARGET_SSE"
3550   "@
3551    unpcklps\t{%2, %0|%0, %2}
3552    movss\t{%1, %0|%0, %1}
3553    punpckldq\t{%2, %0|%0, %2}
3554    movd\t{%1, %0|%0, %1}"
3555   [(set_attr "type" "sselog,ssemov,mmxcvt,mmxmov")
3556    (set_attr "mode" "V4SF,SF,DI,DI")])
3557
3558 (define_insn "*vec_concatv4sf_avx"
3559   [(set (match_operand:V4SF 0 "register_operand"   "=x,x")
3560         (vec_concat:V4SF
3561           (match_operand:V2SF 1 "register_operand" " x,x")
3562           (match_operand:V2SF 2 "nonimmediate_operand" " x,m")))]
3563   "TARGET_AVX"
3564   "@
3565    vmovlhps\t{%2, %1, %0|%0, %1, %2}
3566    vmovhps\t{%2, %1, %0|%0, %1, %2}"
3567   [(set_attr "type" "ssemov")
3568    (set_attr "prefix" "vex")
3569    (set_attr "mode" "V4SF,V2SF")])
3570
3571 (define_insn "*vec_concatv4sf_sse"
3572   [(set (match_operand:V4SF 0 "register_operand"   "=x,x")
3573         (vec_concat:V4SF
3574           (match_operand:V2SF 1 "register_operand" " 0,0")
3575           (match_operand:V2SF 2 "nonimmediate_operand" " x,m")))]
3576   "TARGET_SSE"
3577   "@
3578    movlhps\t{%2, %0|%0, %2}
3579    movhps\t{%2, %0|%0, %2}"
3580   [(set_attr "type" "ssemov")
3581    (set_attr "mode" "V4SF,V2SF")])
3582
3583 (define_expand "vec_init<mode>"
3584   [(match_operand:SSEMODE 0 "register_operand" "")
3585    (match_operand 1 "" "")]
3586   "TARGET_SSE"
3587 {
3588   ix86_expand_vector_init (false, operands[0], operands[1]);
3589   DONE;
3590 })
3591
3592 (define_insn "*vec_setv4sf_0_avx"
3593   [(set (match_operand:V4SF 0 "nonimmediate_operand"  "=x,x,x,m")
3594         (vec_merge:V4SF
3595           (vec_duplicate:V4SF
3596             (match_operand:SF 2 "general_operand"     " x,m,*r,x*rfF"))
3597           (match_operand:V4SF 1 "vector_move_operand" " x,C,C ,0")
3598           (const_int 1)))]
3599   "TARGET_AVX"
3600   "@
3601    vmovss\t{%2, %1, %0|%0, %1, %2}
3602    vmovss\t{%2, %0|%0, %2}
3603    vmovd\t{%2, %0|%0, %2}
3604    #"
3605   [(set_attr "type" "ssemov")
3606    (set_attr "prefix" "vex")
3607    (set_attr "mode" "SF")])
3608
3609 (define_insn "vec_setv4sf_0"
3610   [(set (match_operand:V4SF 0 "nonimmediate_operand"  "=x,x,Y2,m")
3611         (vec_merge:V4SF
3612           (vec_duplicate:V4SF
3613             (match_operand:SF 2 "general_operand"     " x,m,*r,x*rfF"))
3614           (match_operand:V4SF 1 "vector_move_operand" " 0,C,C ,0")
3615           (const_int 1)))]
3616   "TARGET_SSE"
3617   "@
3618    movss\t{%2, %0|%0, %2}
3619    movss\t{%2, %0|%0, %2}
3620    movd\t{%2, %0|%0, %2}
3621    #"
3622   [(set_attr "type" "ssemov")
3623    (set_attr "mode" "SF")])
3624
3625 ;; A subset is vec_setv4sf.
3626 (define_insn "*vec_setv4sf_avx"
3627   [(set (match_operand:V4SF 0 "register_operand" "=x")
3628         (vec_merge:V4SF
3629           (vec_duplicate:V4SF
3630             (match_operand:SF 2 "nonimmediate_operand" "xm"))
3631           (match_operand:V4SF 1 "register_operand" "x")
3632           (match_operand:SI 3 "const_pow2_1_to_8_operand" "n")))]
3633   "TARGET_AVX"
3634 {
3635   operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])) << 4);
3636   return "vinsertps\t{%3, %2, %1, %0|%0, %1, %2, %3}";
3637 }
3638   [(set_attr "type" "sselog")
3639    (set_attr "prefix" "vex")
3640    (set_attr "mode" "V4SF")])
3641
3642 (define_insn "*vec_setv4sf_sse4_1"
3643   [(set (match_operand:V4SF 0 "register_operand" "=x")
3644         (vec_merge:V4SF
3645           (vec_duplicate:V4SF
3646             (match_operand:SF 2 "nonimmediate_operand" "xm"))
3647           (match_operand:V4SF 1 "register_operand" "0")
3648           (match_operand:SI 3 "const_pow2_1_to_8_operand" "n")))]
3649   "TARGET_SSE4_1"
3650 {
3651   operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])) << 4);
3652   return "insertps\t{%3, %2, %0|%0, %2, %3}";
3653 }
3654   [(set_attr "type" "sselog")
3655    (set_attr "prefix_extra" "1")
3656    (set_attr "mode" "V4SF")])
3657
3658 (define_insn "*avx_insertps"
3659   [(set (match_operand:V4SF 0 "register_operand" "=x")
3660         (unspec:V4SF [(match_operand:V4SF 2 "nonimmediate_operand" "xm")
3661                       (match_operand:V4SF 1 "register_operand" "x")
3662                       (match_operand:SI 3 "const_0_to_255_operand" "n")]
3663                      UNSPEC_INSERTPS))]
3664   "TARGET_AVX"
3665   "vinsertps\t{%3, %2, %1, %0|%0, %1, %2, %3}";
3666   [(set_attr "type" "sselog")
3667    (set_attr "prefix" "vex")
3668    (set_attr "mode" "V4SF")])
3669
3670 (define_insn "sse4_1_insertps"
3671   [(set (match_operand:V4SF 0 "register_operand" "=x")
3672         (unspec:V4SF [(match_operand:V4SF 2 "register_operand" "x")
3673                       (match_operand:V4SF 1 "register_operand" "0")
3674                       (match_operand:SI 3 "const_0_to_255_operand" "n")]
3675                      UNSPEC_INSERTPS))]
3676   "TARGET_SSE4_1"
3677   "insertps\t{%3, %2, %0|%0, %2, %3}";
3678   [(set_attr "type" "sselog")
3679    (set_attr "prefix_extra" "1")
3680    (set_attr "mode" "V4SF")])
3681
3682 (define_split
3683   [(set (match_operand:V4SF 0 "memory_operand" "")
3684         (vec_merge:V4SF
3685           (vec_duplicate:V4SF
3686             (match_operand:SF 1 "nonmemory_operand" ""))
3687           (match_dup 0)
3688           (const_int 1)))]
3689   "TARGET_SSE && reload_completed"
3690   [(const_int 0)]
3691 {
3692   emit_move_insn (adjust_address (operands[0], SFmode, 0), operands[1]);
3693   DONE;
3694 })
3695
3696 (define_expand "vec_set<mode>"
3697   [(match_operand:SSEMODE 0 "register_operand" "")
3698    (match_operand:<ssescalarmode> 1 "register_operand" "")
3699    (match_operand 2 "const_int_operand" "")]
3700   "TARGET_SSE"
3701 {
3702   ix86_expand_vector_set (false, operands[0], operands[1],
3703                           INTVAL (operands[2]));
3704   DONE;
3705 })
3706
3707 (define_insn_and_split "*vec_extractv4sf_0"
3708   [(set (match_operand:SF 0 "nonimmediate_operand" "=x,m,f,r")
3709         (vec_select:SF
3710           (match_operand:V4SF 1 "nonimmediate_operand" "xm,x,m,m")
3711           (parallel [(const_int 0)])))]
3712   "TARGET_SSE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3713   "#"
3714   "&& reload_completed"
3715   [(const_int 0)]
3716 {
3717   rtx op1 = operands[1];
3718   if (REG_P (op1))
3719     op1 = gen_rtx_REG (SFmode, REGNO (op1));
3720   else
3721     op1 = gen_lowpart (SFmode, op1);
3722   emit_move_insn (operands[0], op1);
3723   DONE;
3724 })
3725
3726 (define_expand "avx_vextractf128<mode>"
3727   [(match_operand:<avxhalfvecmode> 0 "nonimmediate_operand" "")
3728    (match_operand:AVX256MODE 1 "register_operand" "")
3729    (match_operand:SI 2 "const_0_to_1_operand" "")]
3730   "TARGET_AVX"
3731 {
3732   switch (INTVAL (operands[2]))
3733     {
3734     case 0:
3735       emit_insn (gen_vec_extract_lo_<mode> (operands[0], operands[1]));
3736       break;
3737     case 1:
3738       emit_insn (gen_vec_extract_hi_<mode> (operands[0], operands[1]));
3739       break;
3740     default:
3741       gcc_unreachable ();
3742     }
3743   DONE;
3744 })
3745
3746 (define_insn "vec_extract_lo_<mode>"
3747   [(set (match_operand:<avxhalfvecmode> 0 "nonimmediate_operand" "=x,m")
3748         (vec_select:<avxhalfvecmode>
3749           (match_operand:AVX256MODE4P 1 "register_operand" "x,x")
3750           (parallel [(const_int 0) (const_int 1)])))]
3751   "TARGET_AVX"
3752   "vextractf128\t{$0x0, %1, %0|%0, %1, 0x0}"
3753   [(set_attr "type" "sselog")
3754    (set_attr "memory" "none,store")
3755    (set_attr "prefix" "vex")
3756    (set_attr "mode" "V8SF")])
3757
3758 (define_insn "vec_extract_hi_<mode>"
3759   [(set (match_operand:<avxhalfvecmode> 0 "nonimmediate_operand" "=x,m")
3760         (vec_select:<avxhalfvecmode>
3761           (match_operand:AVX256MODE4P 1 "register_operand" "x,x")
3762           (parallel [(const_int 2) (const_int 3)])))]
3763   "TARGET_AVX"
3764   "vextractf128\t{$0x1, %1, %0|%0, %1, 0x1}"
3765   [(set_attr "type" "sselog")
3766    (set_attr "memory" "none,store")
3767    (set_attr "prefix" "vex")
3768    (set_attr "mode" "V8SF")])
3769
3770 (define_insn "vec_extract_lo_<mode>"
3771   [(set (match_operand:<avxhalfvecmode> 0 "nonimmediate_operand" "=x,m")
3772         (vec_select:<avxhalfvecmode>
3773           (match_operand:AVX256MODE8P 1 "register_operand" "x,x")
3774           (parallel [(const_int 0) (const_int 1)
3775                      (const_int 2) (const_int 3)])))]
3776   "TARGET_AVX"
3777   "vextractf128\t{$0x1, %1, %0|%0, %1, 0x1}"
3778   [(set_attr "type" "sselog")
3779    (set_attr "memory" "none,store")
3780    (set_attr "prefix" "vex")
3781    (set_attr "mode" "V8SF")])
3782
3783 (define_insn "vec_extract_hi_<mode>"
3784   [(set (match_operand:<avxhalfvecmode> 0 "nonimmediate_operand" "=x,m")
3785         (vec_select:<avxhalfvecmode>
3786           (match_operand:AVX256MODE8P 1 "register_operand" "x,x")
3787           (parallel [(const_int 4) (const_int 5)
3788                      (const_int 6) (const_int 7)])))]
3789   "TARGET_AVX"
3790   "vextractf128\t{$0x1, %1, %0|%0, %1, 0x1}"
3791   [(set_attr "type" "sselog")
3792    (set_attr "memory" "none,store")
3793    (set_attr "prefix" "vex")
3794    (set_attr "mode" "V8SF")])
3795
3796 (define_insn "vec_extract_lo_v16hi"
3797   [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,m")
3798         (vec_select:V8HI
3799           (match_operand:V16HI 1 "register_operand" "x,x")
3800           (parallel [(const_int 0) (const_int 1)
3801                      (const_int 2) (const_int 3)
3802                      (const_int 4) (const_int 5)
3803                      (const_int 6) (const_int 7)])))]
3804   "TARGET_AVX"
3805   "vextractf128\t{$0x1, %1, %0|%0, %1, 0x1}"
3806   [(set_attr "type" "sselog")
3807    (set_attr "memory" "none,store")
3808    (set_attr "prefix" "vex")
3809    (set_attr "mode" "V8SF")])
3810
3811 (define_insn "vec_extract_hi_v16hi"
3812   [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,m")
3813         (vec_select:V8HI
3814           (match_operand:V16HI 1 "register_operand" "x,x")
3815           (parallel [(const_int 8) (const_int 9)
3816                      (const_int 10) (const_int 11)
3817                      (const_int 12) (const_int 13)
3818                      (const_int 14) (const_int 15)])))]
3819   "TARGET_AVX"
3820   "vextractf128\t{$0x1, %1, %0|%0, %1, 0x1}"
3821   [(set_attr "type" "sselog")
3822    (set_attr "memory" "none,store")
3823    (set_attr "prefix" "vex")
3824    (set_attr "mode" "V8SF")])
3825
3826 (define_insn "vec_extract_lo_v32qi"
3827   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
3828         (vec_select:V16QI
3829           (match_operand:V32QI 1 "register_operand" "x,x")
3830           (parallel [(const_int 0) (const_int 1)
3831                      (const_int 2) (const_int 3)
3832                      (const_int 4) (const_int 5)
3833                      (const_int 6) (const_int 7)
3834                      (const_int 8) (const_int 9)
3835                      (const_int 10) (const_int 11)
3836                      (const_int 12) (const_int 13)
3837                      (const_int 14) (const_int 15)])))]
3838   "TARGET_AVX"
3839   "vextractf128\t{$0x1, %1, %0|%0, %1, 0x1}"
3840   [(set_attr "type" "sselog")
3841    (set_attr "memory" "none,store")
3842    (set_attr "prefix" "vex")
3843    (set_attr "mode" "V8SF")])
3844
3845 (define_insn "vec_extract_hi_v32qi"
3846   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
3847         (vec_select:V16QI
3848           (match_operand:V32QI 1 "register_operand" "x,x")
3849           (parallel [(const_int 16) (const_int 17)
3850                      (const_int 18) (const_int 19)
3851                      (const_int 20) (const_int 21)
3852                      (const_int 22) (const_int 23)
3853                      (const_int 24) (const_int 25)
3854                      (const_int 26) (const_int 27)
3855                      (const_int 28) (const_int 29)
3856                      (const_int 30) (const_int 31)])))]
3857   "TARGET_AVX"
3858   "vextractf128\t{$0x1, %1, %0|%0, %1, 0x1}"
3859   [(set_attr "type" "sselog")
3860    (set_attr "memory" "none,store")
3861    (set_attr "prefix" "vex")
3862    (set_attr "mode" "V8SF")])
3863
3864 (define_insn "*sse4_1_extractps"
3865   [(set (match_operand:SF 0 "nonimmediate_operand" "=rm")
3866         (vec_select:SF
3867           (match_operand:V4SF 1 "register_operand" "x")
3868           (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n")])))]
3869   "TARGET_SSE4_1"
3870   "%vextractps\t{%2, %1, %0|%0, %1, %2}"
3871   [(set_attr "type" "sselog")
3872    (set_attr "prefix_extra" "1")
3873    (set_attr "prefix" "maybe_vex")
3874    (set_attr "mode" "V4SF")])
3875
3876 (define_insn_and_split "*vec_extract_v4sf_mem"
3877   [(set (match_operand:SF 0 "register_operand" "=x*rf")
3878        (vec_select:SF
3879          (match_operand:V4SF 1 "memory_operand" "o")
3880          (parallel [(match_operand 2 "const_0_to_3_operand" "n")])))]
3881   ""
3882   "#"
3883   "reload_completed"
3884   [(const_int 0)]
3885 {
3886   int i = INTVAL (operands[2]);
3887
3888   emit_move_insn (operands[0], adjust_address (operands[1], SFmode, i*4));
3889   DONE;
3890 })
3891
3892 (define_expand "vec_extract<mode>"
3893   [(match_operand:<ssescalarmode> 0 "register_operand" "")
3894    (match_operand:SSEMODE 1 "register_operand" "")
3895    (match_operand 2 "const_int_operand" "")]
3896   "TARGET_SSE"
3897 {
3898   ix86_expand_vector_extract (false, operands[0], operands[1],
3899                               INTVAL (operands[2]));
3900   DONE;
3901 })
3902
3903 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3904 ;;
3905 ;; Parallel double-precision floating point element swizzling
3906 ;;
3907 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3908
3909 (define_insn "avx_unpckhpd256"
3910   [(set (match_operand:V4DF 0 "register_operand" "=x")
3911         (vec_select:V4DF
3912           (vec_concat:V8DF
3913             (match_operand:V4DF 1 "register_operand" "x")
3914             (match_operand:V4DF 2 "nonimmediate_operand" "xm"))
3915           (parallel [(const_int 1) (const_int 5)
3916                      (const_int 3) (const_int 7)])))]
3917   "TARGET_AVX"
3918   "vunpckhpd\t{%2, %1, %0|%0, %1, %2}"
3919   [(set_attr "type" "sselog")
3920    (set_attr "prefix" "vex")
3921    (set_attr "mode" "V4DF")])
3922
3923 (define_expand "sse2_unpckhpd_exp"
3924   [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
3925         (vec_select:V2DF
3926           (vec_concat:V4DF
3927             (match_operand:V2DF 1 "nonimmediate_operand" "")
3928             (match_operand:V2DF 2 "nonimmediate_operand" ""))
3929           (parallel [(const_int 1)
3930                      (const_int 3)])))]
3931   "TARGET_SSE2"
3932   "ix86_fixup_binary_operands (UNKNOWN, V2DFmode, operands);")
3933
3934 (define_insn "*avx_unpckhpd"
3935   [(set (match_operand:V2DF 0 "nonimmediate_operand"     "=x,x,m")
3936         (vec_select:V2DF
3937           (vec_concat:V4DF
3938             (match_operand:V2DF 1 "nonimmediate_operand" " x,o,x")
3939             (match_operand:V2DF 2 "nonimmediate_operand" " x,x,0"))
3940           (parallel [(const_int 1)
3941                      (const_int 3)])))]
3942   "TARGET_AVX && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
3943   "@
3944    vunpckhpd\t{%2, %1, %0|%0, %1, %2}
3945    vmovlpd\t{%H1, %2, %0|%0, %2, %H1}
3946    vmovhpd\t{%1, %0|%0, %1}"
3947   [(set_attr "type" "sselog,ssemov,ssemov")
3948    (set_attr "prefix" "vex")
3949    (set_attr "mode" "V2DF,V1DF,V1DF")])
3950
3951 (define_insn "sse2_unpckhpd"
3952   [(set (match_operand:V2DF 0 "nonimmediate_operand"     "=x,x,m")
3953         (vec_select:V2DF
3954           (vec_concat:V4DF
3955             (match_operand:V2DF 1 "nonimmediate_operand" " 0,o,x")
3956             (match_operand:V2DF 2 "nonimmediate_operand" " x,0,0"))
3957           (parallel [(const_int 1)
3958                      (const_int 3)])))]
3959   "TARGET_SSE2 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
3960   "@
3961    unpckhpd\t{%2, %0|%0, %2}
3962    movlpd\t{%H1, %0|%0, %H1}
3963    movhpd\t{%1, %0|%0, %1}"
3964   [(set_attr "type" "sselog,ssemov,ssemov")
3965    (set_attr "mode" "V2DF,V1DF,V1DF")])
3966
3967 (define_insn "avx_movddup256"
3968   [(set (match_operand:V4DF 0 "register_operand" "=x")
3969         (vec_select:V4DF
3970           (vec_concat:V8DF
3971             (match_operand:V4DF 1 "nonimmediate_operand" "xm")
3972             (match_dup 1))
3973           (parallel [(const_int 0) (const_int 2)
3974                      (const_int 4) (const_int 6)])))]
3975   "TARGET_AVX"
3976   "vmovddup\t{%1, %0|%0, %1}"
3977   [(set_attr "type" "sselog1")
3978    (set_attr "prefix" "vex")
3979    (set_attr "mode" "V4DF")])
3980
3981 (define_insn "*avx_movddup"
3982   [(set (match_operand:V2DF 0 "nonimmediate_operand"     "=x,o")
3983         (vec_select:V2DF
3984           (vec_concat:V4DF
3985             (match_operand:V2DF 1 "nonimmediate_operand" "xm,x")
3986             (match_dup 1))
3987           (parallel [(const_int 0)
3988                      (const_int 2)])))]
3989   "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3990   "@
3991    vmovddup\t{%1, %0|%0, %1}
3992    #"
3993   [(set_attr "type" "sselog1,ssemov")
3994    (set_attr "prefix" "vex")
3995    (set_attr "mode" "V2DF")])
3996
3997 (define_insn "*sse3_movddup"
3998   [(set (match_operand:V2DF 0 "nonimmediate_operand"     "=x,o")
3999         (vec_select:V2DF
4000           (vec_concat:V4DF
4001             (match_operand:V2DF 1 "nonimmediate_operand" "xm,x")
4002             (match_dup 1))
4003           (parallel [(const_int 0)
4004                      (const_int 2)])))]
4005   "TARGET_SSE3 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
4006   "@
4007    movddup\t{%1, %0|%0, %1}
4008    #"
4009   [(set_attr "type" "sselog1,ssemov")
4010    (set_attr "mode" "V2DF")])
4011
4012 (define_split
4013   [(set (match_operand:V2DF 0 "memory_operand" "")
4014         (vec_select:V2DF
4015           (vec_concat:V4DF
4016             (match_operand:V2DF 1 "register_operand" "")
4017             (match_dup 1))
4018           (parallel [(const_int 0)
4019                      (const_int 2)])))]
4020   "TARGET_SSE3 && reload_completed"
4021   [(const_int 0)]
4022 {
4023   rtx low = gen_rtx_REG (DFmode, REGNO (operands[1]));
4024   emit_move_insn (adjust_address (operands[0], DFmode, 0), low);
4025   emit_move_insn (adjust_address (operands[0], DFmode, 8), low);
4026   DONE;
4027 })
4028
4029 (define_insn "avx_unpcklpd256"
4030   [(set (match_operand:V4DF 0 "register_operand" "=x")
4031         (vec_select:V4DF
4032           (vec_concat:V8DF
4033             (match_operand:V4DF 1 "register_operand" "x")
4034             (match_operand:V4DF 2 "nonimmediate_operand" "xm"))
4035           (parallel [(const_int 0) (const_int 4)
4036                      (const_int 2) (const_int 6)])))]
4037   "TARGET_AVX"
4038   "vunpcklpd\t{%2, %1, %0|%0, %1, %2}"
4039   [(set_attr "type" "sselog")
4040    (set_attr "prefix" "vex")
4041    (set_attr "mode" "V4DF")])
4042
4043 (define_expand "sse2_unpcklpd_exp"
4044   [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
4045         (vec_select:V2DF
4046           (vec_concat:V4DF
4047             (match_operand:V2DF 1 "nonimmediate_operand" "")
4048             (match_operand:V2DF 2 "nonimmediate_operand" ""))
4049           (parallel [(const_int 0)
4050                      (const_int 2)])))]
4051   "TARGET_SSE2"
4052   "ix86_fixup_binary_operands (UNKNOWN, V2DFmode, operands);")
4053
4054 (define_insn "*avx_unpcklpd"
4055   [(set (match_operand:V2DF 0 "nonimmediate_operand"     "=x,x,o")
4056         (vec_select:V2DF
4057           (vec_concat:V4DF
4058             (match_operand:V2DF 1 "nonimmediate_operand" " x,x,0")
4059             (match_operand:V2DF 2 "nonimmediate_operand" " x,m,x"))
4060           (parallel [(const_int 0)
4061                      (const_int 2)])))]
4062   "TARGET_AVX && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
4063   "@
4064    vunpcklpd\t{%2, %1, %0|%0, %1, %2}
4065    vmovhpd\t{%2, %1, %0|%0, %1, %2}
4066    vmovlpd\t{%2, %H0|%H0, %2}"
4067   [(set_attr "type" "sselog,ssemov,ssemov")
4068    (set_attr "prefix" "vex")
4069    (set_attr "mode" "V2DF,V1DF,V1DF")])
4070
4071 (define_insn "sse2_unpcklpd"
4072   [(set (match_operand:V2DF 0 "nonimmediate_operand"     "=x,x,o")
4073         (vec_select:V2DF
4074           (vec_concat:V4DF
4075             (match_operand:V2DF 1 "nonimmediate_operand" " 0,0,0")
4076             (match_operand:V2DF 2 "nonimmediate_operand" " x,m,x"))
4077           (parallel [(const_int 0)
4078                      (const_int 2)])))]
4079   "TARGET_SSE2 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
4080   "@
4081    unpcklpd\t{%2, %0|%0, %2}
4082    movhpd\t{%2, %0|%0, %2}
4083    movlpd\t{%2, %H0|%H0, %2}"
4084   [(set_attr "type" "sselog,ssemov,ssemov")
4085    (set_attr "mode" "V2DF,V1DF,V1DF")])
4086
4087 (define_expand "avx_shufpd256"
4088   [(match_operand:V4DF 0 "register_operand" "")
4089    (match_operand:V4DF 1 "register_operand" "")
4090    (match_operand:V4DF 2 "nonimmediate_operand" "")
4091    (match_operand:SI 3 "const_int_operand" "")]
4092   "TARGET_AVX"
4093 {
4094   int mask = INTVAL (operands[3]);
4095   emit_insn (gen_avx_shufpd256_1 (operands[0], operands[1], operands[2],
4096                                    GEN_INT (mask & 1),
4097                                    GEN_INT (mask & 2 ? 5 : 4),
4098                                    GEN_INT (mask & 4 ? 3 : 2),
4099                                    GEN_INT (mask & 8 ? 7 : 6)));
4100   DONE;
4101 })
4102
4103 (define_insn "avx_shufpd256_1"
4104   [(set (match_operand:V4DF 0 "register_operand" "=x")
4105         (vec_select:V4DF
4106           (vec_concat:V8DF
4107             (match_operand:V4DF 1 "register_operand" "x")
4108             (match_operand:V4DF 2 "nonimmediate_operand" "xm"))
4109           (parallel [(match_operand 3 "const_0_to_1_operand" "")
4110                      (match_operand 4 "const_4_to_5_operand" "")
4111                      (match_operand 5 "const_2_to_3_operand" "")
4112                      (match_operand 6 "const_6_to_7_operand" "")])))]
4113   "TARGET_AVX"
4114 {
4115   int mask;
4116   mask = INTVAL (operands[3]);
4117   mask |= (INTVAL (operands[4]) - 4) << 1;
4118   mask |= (INTVAL (operands[5]) - 2) << 2;
4119   mask |= (INTVAL (operands[6]) - 6) << 3;
4120   operands[3] = GEN_INT (mask);
4121
4122   return "vshufpd\t{%3, %2, %1, %0|%0, %1, %2, %3}";
4123 }
4124   [(set_attr "type" "sselog")
4125    (set_attr "prefix" "vex")
4126    (set_attr "mode" "V4DF")])
4127
4128 (define_expand "sse2_shufpd"
4129   [(match_operand:V2DF 0 "register_operand" "")
4130    (match_operand:V2DF 1 "register_operand" "")
4131    (match_operand:V2DF 2 "nonimmediate_operand" "")
4132    (match_operand:SI 3 "const_int_operand" "")]
4133   "TARGET_SSE2"
4134 {
4135   int mask = INTVAL (operands[3]);
4136   emit_insn (gen_sse2_shufpd_v2df (operands[0], operands[1], operands[2],
4137                                 GEN_INT (mask & 1),
4138                                 GEN_INT (mask & 2 ? 3 : 2)));
4139   DONE;
4140 })
4141
4142 (define_expand "vec_extract_even<mode>"
4143   [(set (match_operand:SSEMODE4S 0 "register_operand" "")
4144         (vec_select:SSEMODE4S
4145           (vec_concat:<ssedoublesizemode>
4146             (match_operand:SSEMODE4S 1 "register_operand" "")
4147             (match_operand:SSEMODE4S 2 "nonimmediate_operand" ""))
4148           (parallel [(const_int 0)
4149                      (const_int 2)
4150                      (const_int 4)
4151                      (const_int 6)])))]
4152   "TARGET_SSE")
4153
4154 (define_expand "vec_extract_odd<mode>"
4155   [(set (match_operand:SSEMODE4S 0 "register_operand" "")
4156         (vec_select:SSEMODE4S
4157           (vec_concat:<ssedoublesizemode>
4158             (match_operand:SSEMODE4S 1 "register_operand" "")
4159             (match_operand:SSEMODE4S 2 "nonimmediate_operand" ""))
4160           (parallel [(const_int 1)
4161                      (const_int 3)
4162                      (const_int 5)
4163                      (const_int 7)])))]
4164   "TARGET_SSE")
4165
4166 (define_expand "vec_extract_even<mode>"
4167   [(set (match_operand:SSEMODE2D 0 "register_operand" "")
4168         (vec_select:SSEMODE2D
4169           (vec_concat:<ssedoublesizemode>
4170             (match_operand:SSEMODE2D 1 "register_operand" "")
4171             (match_operand:SSEMODE2D 2 "nonimmediate_operand" ""))
4172           (parallel [(const_int 0)
4173                      (const_int 2)])))]
4174   "TARGET_SSE2")
4175
4176 (define_expand "vec_extract_odd<mode>"
4177   [(set (match_operand:SSEMODE2D 0 "register_operand" "")
4178         (vec_select:SSEMODE2D
4179           (vec_concat:<ssedoublesizemode>
4180             (match_operand:SSEMODE2D 1 "register_operand" "")
4181             (match_operand:SSEMODE2D 2 "nonimmediate_operand" ""))
4182           (parallel [(const_int 1)
4183                      (const_int 3)])))]
4184   "TARGET_SSE2")
4185
4186 ;; punpcklqdq and punpckhqdq are shorter than shufpd.
4187 (define_insn "*avx_punpckhqdq"
4188   [(set (match_operand:V2DI 0 "register_operand" "=x")
4189         (vec_select:V2DI
4190           (vec_concat:V4DI
4191             (match_operand:V2DI 1 "register_operand" "x")
4192             (match_operand:V2DI 2 "nonimmediate_operand" "xm"))
4193           (parallel [(const_int 1)
4194                      (const_int 3)])))]
4195   "TARGET_AVX"
4196   "vpunpckhqdq\t{%2, %1, %0|%0, %1, %2}"
4197   [(set_attr "type" "sselog")
4198    (set_attr "prefix" "vex")
4199    (set_attr "mode" "TI")])
4200
4201 (define_insn "sse2_punpckhqdq"
4202   [(set (match_operand:V2DI 0 "register_operand" "=x")
4203         (vec_select:V2DI
4204           (vec_concat:V4DI
4205             (match_operand:V2DI 1 "register_operand" "0")
4206             (match_operand:V2DI 2 "nonimmediate_operand" "xm"))
4207           (parallel [(const_int 1)
4208                      (const_int 3)])))]
4209   "TARGET_SSE2"
4210   "punpckhqdq\t{%2, %0|%0, %2}"
4211   [(set_attr "type" "sselog")
4212    (set_attr "prefix_data16" "1")
4213    (set_attr "mode" "TI")])
4214
4215 (define_insn "*avx_punpcklqdq"
4216   [(set (match_operand:V2DI 0 "register_operand" "=x")
4217         (vec_select:V2DI
4218           (vec_concat:V4DI
4219             (match_operand:V2DI 1 "register_operand" "x")
4220             (match_operand:V2DI 2 "nonimmediate_operand" "xm"))
4221           (parallel [(const_int 0)
4222                      (const_int 2)])))]
4223   "TARGET_AVX"
4224   "vpunpcklqdq\t{%2, %1, %0|%0, %1, %2}"
4225   [(set_attr "type" "sselog")
4226    (set_attr "prefix" "vex")
4227    (set_attr "mode" "TI")])
4228
4229 (define_insn "sse2_punpcklqdq"
4230   [(set (match_operand:V2DI 0 "register_operand" "=x")
4231         (vec_select:V2DI
4232           (vec_concat:V4DI
4233             (match_operand:V2DI 1 "register_operand" "0")
4234             (match_operand:V2DI 2 "nonimmediate_operand" "xm"))
4235           (parallel [(const_int 0)
4236                      (const_int 2)])))]
4237   "TARGET_SSE2"
4238   "punpcklqdq\t{%2, %0|%0, %2}"
4239   [(set_attr "type" "sselog")
4240    (set_attr "prefix_data16" "1")
4241    (set_attr "mode" "TI")])
4242
4243 (define_insn "*avx_shufpd_<mode>"
4244   [(set (match_operand:SSEMODE2D 0 "register_operand" "=x")
4245         (vec_select:SSEMODE2D
4246           (vec_concat:<ssedoublesizemode>
4247             (match_operand:SSEMODE2D 1 "register_operand" "x")
4248             (match_operand:SSEMODE2D 2 "nonimmediate_operand" "xm"))
4249           (parallel [(match_operand 3 "const_0_to_1_operand" "")
4250                      (match_operand 4 "const_2_to_3_operand" "")])))]
4251   "TARGET_AVX"
4252 {
4253   int mask;
4254   mask = INTVAL (operands[3]);
4255   mask |= (INTVAL (operands[4]) - 2) << 1;
4256   operands[3] = GEN_INT (mask);
4257
4258   return "vshufpd\t{%3, %2, %1, %0|%0, %1, %2, %3}";
4259 }
4260   [(set_attr "type" "sselog")
4261    (set_attr "prefix" "vex")
4262    (set_attr "mode" "V2DF")])
4263
4264 (define_insn "sse2_shufpd_<mode>"
4265   [(set (match_operand:SSEMODE2D 0 "register_operand" "=x")
4266         (vec_select:SSEMODE2D
4267           (vec_concat:<ssedoublesizemode>
4268             (match_operand:SSEMODE2D 1 "register_operand" "0")
4269             (match_operand:SSEMODE2D 2 "nonimmediate_operand" "xm"))
4270           (parallel [(match_operand 3 "const_0_to_1_operand" "")
4271                      (match_operand 4 "const_2_to_3_operand" "")])))]
4272   "TARGET_SSE2"
4273 {
4274   int mask;
4275   mask = INTVAL (operands[3]);
4276   mask |= (INTVAL (operands[4]) - 2) << 1;
4277   operands[3] = GEN_INT (mask);
4278
4279   return "shufpd\t{%3, %2, %0|%0, %2, %3}";
4280 }
4281   [(set_attr "type" "sselog")
4282    (set_attr "mode" "V2DF")])
4283
4284 ;; Avoid combining registers from different units in a single alternative,
4285 ;; see comment above inline_secondary_memory_needed function in i386.c
4286 (define_insn "*avx_storehpd"
4287   [(set (match_operand:DF 0 "nonimmediate_operand"     "=m,x,x,*f,r")
4288         (vec_select:DF
4289           (match_operand:V2DF 1 "nonimmediate_operand" " x,x,o,o,o")
4290           (parallel [(const_int 1)])))]
4291   "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
4292   "@
4293    vmovhpd\t{%1, %0|%0, %1}
4294    vunpckhpd\t{%1, %1, %0|%0, %1, %1}
4295    #
4296    #
4297    #"
4298   [(set_attr "type" "ssemov,sselog1,ssemov,fmov,imov")
4299    (set_attr "prefix" "vex")
4300    (set_attr "mode" "V1DF,V2DF,DF,DF,DF")])
4301
4302 (define_insn "sse2_storehpd"
4303   [(set (match_operand:DF 0 "nonimmediate_operand"     "=m,x,x,*f,r")
4304         (vec_select:DF
4305           (match_operand:V2DF 1 "nonimmediate_operand" " x,0,o,o,o")
4306           (parallel [(const_int 1)])))]
4307   "TARGET_SSE2 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
4308   "@
4309    movhpd\t{%1, %0|%0, %1}
4310    unpckhpd\t%0, %0
4311    #
4312    #
4313    #"
4314   [(set_attr "type" "ssemov,sselog1,ssemov,fmov,imov")
4315    (set_attr "mode" "V1DF,V2DF,DF,DF,DF")])
4316
4317 (define_split
4318   [(set (match_operand:DF 0 "register_operand" "")
4319         (vec_select:DF
4320           (match_operand:V2DF 1 "memory_operand" "")
4321           (parallel [(const_int 1)])))]
4322   "TARGET_SSE2 && reload_completed"
4323   [(set (match_dup 0) (match_dup 1))]
4324 {
4325   operands[1] = adjust_address (operands[1], DFmode, 8);
4326 })
4327
4328 ;; Avoid combining registers from different units in a single alternative,
4329 ;; see comment above inline_secondary_memory_needed function in i386.c
4330 (define_insn "sse2_storelpd"
4331   [(set (match_operand:DF 0 "nonimmediate_operand"     "=m,x,x,*f,r")
4332         (vec_select:DF
4333           (match_operand:V2DF 1 "nonimmediate_operand" " x,x,m,m,m")
4334           (parallel [(const_int 0)])))]
4335   "TARGET_SSE2 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
4336   "@
4337    %vmovlpd\t{%1, %0|%0, %1}
4338    #
4339    #
4340    #
4341    #"
4342   [(set_attr "type" "ssemov,ssemov,ssemov,fmov,imov")
4343    (set_attr "prefix" "maybe_vex")
4344    (set_attr "mode" "V1DF,DF,DF,DF,DF")])
4345
4346 (define_split
4347   [(set (match_operand:DF 0 "register_operand" "")
4348         (vec_select:DF
4349           (match_operand:V2DF 1 "nonimmediate_operand" "")
4350           (parallel [(const_int 0)])))]
4351   "TARGET_SSE2 && reload_completed"
4352   [(const_int 0)]
4353 {
4354   rtx op1 = operands[1];
4355   if (REG_P (op1))
4356     op1 = gen_rtx_REG (DFmode, REGNO (op1));
4357   else
4358     op1 = gen_lowpart (DFmode, op1);
4359   emit_move_insn (operands[0], op1);
4360   DONE;
4361 })
4362
4363 (define_expand "sse2_loadhpd_exp"
4364   [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
4365         (vec_concat:V2DF
4366           (vec_select:DF
4367             (match_operand:V2DF 1 "nonimmediate_operand" "")
4368             (parallel [(const_int 0)]))
4369           (match_operand:DF 2 "nonimmediate_operand" "")))]
4370   "TARGET_SSE2"
4371   "ix86_fixup_binary_operands (UNKNOWN, V2DFmode, operands);")
4372
4373 ;; Avoid combining registers from different units in a single alternative,
4374 ;; see comment above inline_secondary_memory_needed function in i386.c
4375 (define_insn "*avx_loadhpd"
4376   [(set (match_operand:V2DF 0 "nonimmediate_operand"     "=x,x,o,o,o")
4377         (vec_concat:V2DF
4378           (vec_select:DF
4379             (match_operand:V2DF 1 "nonimmediate_operand" " x,x,0,0,0")
4380             (parallel [(const_int 0)]))
4381           (match_operand:DF 2 "nonimmediate_operand"     " m,x,x,*f,r")))]
4382   "TARGET_AVX && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
4383   "@
4384    vmovhpd\t{%2, %1, %0|%0, %1, %2}
4385    vunpcklpd\t{%2, %1, %0|%0, %1, %2}
4386    #
4387    #
4388    #"
4389   [(set_attr "type" "ssemov,sselog,ssemov,fmov,imov")
4390    (set_attr "prefix" "vex")
4391    (set_attr "mode" "V1DF,V2DF,DF,DF,DF")])
4392
4393 (define_insn "sse2_loadhpd"
4394   [(set (match_operand:V2DF 0 "nonimmediate_operand"     "=x,x,x,o,o,o")
4395         (vec_concat:V2DF
4396           (vec_select:DF
4397             (match_operand:V2DF 1 "nonimmediate_operand" " 0,0,x,0,0,0")
4398             (parallel [(const_int 0)]))
4399           (match_operand:DF 2 "nonimmediate_operand"     " m,x,0,x,*f,r")))]
4400   "TARGET_SSE2 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
4401   "@
4402    movhpd\t{%2, %0|%0, %2}
4403    unpcklpd\t{%2, %0|%0, %2}
4404    shufpd\t{$1, %1, %0|%0, %1, 1}
4405    #
4406    #
4407    #"
4408   [(set_attr "type" "ssemov,sselog,sselog,ssemov,fmov,imov")
4409    (set_attr "mode" "V1DF,V2DF,V2DF,DF,DF,DF")])
4410
4411 (define_split
4412   [(set (match_operand:V2DF 0 "memory_operand" "")
4413         (vec_concat:V2DF
4414           (vec_select:DF (match_dup 0) (parallel [(const_int 0)]))
4415           (match_operand:DF 1 "register_operand" "")))]
4416   "TARGET_SSE2 && reload_completed"
4417   [(set (match_dup 0) (match_dup 1))]
4418 {
4419   operands[0] = adjust_address (operands[0], DFmode, 8);
4420 })
4421
4422 (define_expand "sse2_loadlpd_exp"
4423   [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
4424         (vec_concat:V2DF
4425           (match_operand:DF 2 "nonimmediate_operand" "")
4426           (vec_select:DF
4427             (match_operand:V2DF 1 "nonimmediate_operand" "")
4428             (parallel [(const_int 1)]))))]
4429   "TARGET_SSE2"
4430   "ix86_fixup_binary_operands (UNKNOWN, V2DFmode, operands);")
4431
4432 ;; Avoid combining registers from different units in a single alternative,
4433 ;; see comment above inline_secondary_memory_needed function in i386.c
4434 (define_insn "*avx_loadlpd"
4435   [(set (match_operand:V2DF 0 "nonimmediate_operand"    "=x,x,x,x,m,m,m")
4436         (vec_concat:V2DF
4437           (match_operand:DF 2 "nonimmediate_operand"    " m,m,x,x,x,*f,r")
4438           (vec_select:DF
4439             (match_operand:V2DF 1 "vector_move_operand" " C,x,x,o,0,0,0")
4440             (parallel [(const_int 1)]))))]
4441   "TARGET_AVX && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
4442   "@
4443    vmovsd\t{%2, %0|%0, %2}
4444    vmovlpd\t{%2, %1, %0|%0, %1, %2}
4445    vmovsd\t{%2, %1, %0|%0, %1, %2}
4446    vmovhpd\t{%H1, %2, %0|%0, %2, %H1}
4447    #
4448    #
4449    #"
4450   [(set_attr "type" "ssemov,ssemov,ssemov,ssemov,ssemov,fmov,imov")
4451    (set_attr "prefix" "vex")
4452    (set_attr "mode" "DF,V1DF,V1DF,V1DF,DF,DF,DF")])
4453
4454 (define_insn "sse2_loadlpd"
4455   [(set (match_operand:V2DF 0 "nonimmediate_operand"    "=x,x,x,x,x,m,m,m")
4456         (vec_concat:V2DF
4457           (match_operand:DF 2 "nonimmediate_operand"    " m,m,x,0,0,x,*f,r")
4458           (vec_select:DF
4459             (match_operand:V2DF 1 "vector_move_operand" " C,0,0,x,o,0,0,0")
4460             (parallel [(const_int 1)]))))]
4461   "TARGET_SSE2 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
4462   "@
4463    movsd\t{%2, %0|%0, %2}
4464    movlpd\t{%2, %0|%0, %2}
4465    movsd\t{%2, %0|%0, %2}
4466    shufpd\t{$2, %2, %0|%0, %2, 2}
4467    movhpd\t{%H1, %0|%0, %H1}
4468    #
4469    #
4470    #"
4471   [(set_attr "type" "ssemov,ssemov,ssemov,sselog,ssemov,ssemov,fmov,imov")
4472    (set_attr "mode" "DF,V1DF,V1DF,V2DF,V1DF,DF,DF,DF")])
4473
4474 (define_split
4475   [(set (match_operand:V2DF 0 "memory_operand" "")
4476         (vec_concat:V2DF
4477           (match_operand:DF 1 "register_operand" "")
4478           (vec_select:DF (match_dup 0) (parallel [(const_int 1)]))))]
4479   "TARGET_SSE2 && reload_completed"
4480   [(set (match_dup 0) (match_dup 1))]
4481 {
4482   operands[0] = adjust_address (operands[0], DFmode, 8);
4483 })
4484
4485 ;; Not sure these two are ever used, but it doesn't hurt to have
4486 ;; them. -aoliva
4487 (define_insn "*vec_extractv2df_1_sse"
4488   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,x,x")
4489         (vec_select:DF
4490           (match_operand:V2DF 1 "nonimmediate_operand" "x,x,o")
4491           (parallel [(const_int 1)])))]
4492   "!TARGET_SSE2 && TARGET_SSE
4493    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
4494   "@
4495    movhps\t{%1, %0|%0, %1}
4496    movhlps\t{%1, %0|%0, %1}
4497    movlps\t{%H1, %0|%0, %H1}"
4498   [(set_attr "type" "ssemov")
4499    (set_attr "mode" "V2SF,V4SF,V2SF")])
4500
4501 (define_insn "*vec_extractv2df_0_sse"
4502   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,x,x")
4503         (vec_select:DF
4504           (match_operand:V2DF 1 "nonimmediate_operand" "x,x,m")
4505           (parallel [(const_int 0)])))]
4506   "!TARGET_SSE2 && TARGET_SSE
4507    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
4508   "@
4509    movlps\t{%1, %0|%0, %1}
4510    movaps\t{%1, %0|%0, %1}
4511    movlps\t{%1, %0|%0, %1}"
4512   [(set_attr "type" "ssemov")
4513    (set_attr "mode" "V2SF,V4SF,V2SF")])
4514
4515 (define_insn "*avx_movsd"
4516   [(set (match_operand:V2DF 0 "nonimmediate_operand"   "=x,x,m,x,o")
4517         (vec_merge:V2DF
4518           (match_operand:V2DF 2 "nonimmediate_operand" " x,m,x,x,0")
4519           (match_operand:V2DF 1 "nonimmediate_operand" " x,x,0,o,x")
4520           (const_int 1)))]
4521   "TARGET_AVX"
4522   "@
4523    vmovsd\t{%2, %1, %0|%0, %1, %2}
4524    vmovlpd\t{%2, %1, %0|%0, %1, %2}
4525    vmovlpd\t{%2, %0|%0, %2}
4526    vmovhps\t{%H1, %2, %0|%0, %2, %H1}
4527    vmovhps\t{%1, %H0|%H0, %1}"
4528   [(set_attr "type" "ssemov,ssemov,ssemov,ssemov,ssemov")
4529    (set_attr "prefix" "vex")
4530    (set_attr "mode" "DF,V1DF,V1DF,V1DF,V1DF")])
4531
4532 (define_insn "sse2_movsd"
4533   [(set (match_operand:V2DF 0 "nonimmediate_operand"   "=x,x,m,x,x,o")
4534         (vec_merge:V2DF
4535           (match_operand:V2DF 2 "nonimmediate_operand" " x,m,x,0,0,0")
4536           (match_operand:V2DF 1 "nonimmediate_operand" " 0,0,0,x,o,x")
4537           (const_int 1)))]
4538   "TARGET_SSE2"
4539   "@
4540    movsd\t{%2, %0|%0, %2}
4541    movlpd\t{%2, %0|%0, %2}
4542    movlpd\t{%2, %0|%0, %2}
4543    shufpd\t{$2, %2, %0|%0, %2, 2}
4544    movhps\t{%H1, %0|%0, %H1}
4545    movhps\t{%1, %H0|%H0, %1}"
4546   [(set_attr "type" "ssemov,ssemov,ssemov,sselog,ssemov,ssemov")
4547    (set_attr "mode" "DF,V1DF,V1DF,V2DF,V1DF,V1DF")])
4548
4549 (define_insn "*vec_dupv2df_sse3"
4550   [(set (match_operand:V2DF 0 "register_operand" "=x")
4551         (vec_duplicate:V2DF
4552           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4553   "TARGET_SSE3"
4554   "%vmovddup\t{%1, %0|%0, %1}"
4555   [(set_attr "type" "sselog1")
4556    (set_attr "prefix" "maybe_vex")
4557    (set_attr "mode" "DF")])
4558
4559 (define_insn "vec_dupv2df"
4560   [(set (match_operand:V2DF 0 "register_operand" "=x")
4561         (vec_duplicate:V2DF
4562           (match_operand:DF 1 "register_operand" "0")))]
4563   "TARGET_SSE2"
4564   "unpcklpd\t%0, %0"
4565   [(set_attr "type" "sselog1")
4566    (set_attr "mode" "V2DF")])
4567
4568 (define_insn "*vec_concatv2df_sse3"
4569   [(set (match_operand:V2DF 0 "register_operand" "=x")
4570         (vec_concat:V2DF
4571           (match_operand:DF 1 "nonimmediate_operand" "xm")
4572           (match_dup 1)))]
4573   "TARGET_SSE3"
4574   "%vmovddup\t{%1, %0|%0, %1}"
4575   [(set_attr "type" "sselog1")
4576    (set_attr "prefix" "maybe_vex")
4577    (set_attr "mode" "DF")])
4578
4579 (define_insn "*vec_concatv2df_avx"
4580   [(set (match_operand:V2DF 0 "register_operand"     "=x,x,x")
4581         (vec_concat:V2DF
4582           (match_operand:DF 1 "nonimmediate_operand" " x,x,m")
4583           (match_operand:DF 2 "vector_move_operand"  " x,m,C")))]
4584   "TARGET_AVX"
4585   "@
4586    vunpcklpd\t{%2, %1, %0|%0, %1, %2}
4587    vmovhpd\t{%2, %1, %0|%0, %1, %2}
4588    vmovsd\t{%1, %0|%0, %1}"
4589   [(set_attr "type" "ssemov")
4590    (set_attr "prefix" "vex")
4591    (set_attr "mode" "DF,V1DF,DF")])
4592
4593 (define_insn "*vec_concatv2df"
4594   [(set (match_operand:V2DF 0 "register_operand"     "=Y2,Y2,Y2,x,x")
4595         (vec_concat:V2DF
4596           (match_operand:DF 1 "nonimmediate_operand" " 0 ,0 ,m ,0,0")
4597           (match_operand:DF 2 "vector_move_operand"  " Y2,m ,C ,x,m")))]
4598   "TARGET_SSE"
4599   "@
4600    unpcklpd\t{%2, %0|%0, %2}
4601    movhpd\t{%2, %0|%0, %2}
4602    movsd\t{%1, %0|%0, %1}
4603    movlhps\t{%2, %0|%0, %2}
4604    movhps\t{%2, %0|%0, %2}"
4605   [(set_attr "type" "sselog,ssemov,ssemov,ssemov,ssemov")
4606    (set_attr "mode" "V2DF,V1DF,DF,V4SF,V2SF")])
4607
4608 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4609 ;;
4610 ;; Parallel integral arithmetic
4611 ;;
4612 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4613
4614 (define_expand "neg<mode>2"
4615   [(set (match_operand:SSEMODEI 0 "register_operand" "")
4616         (minus:SSEMODEI
4617           (match_dup 2)
4618           (match_operand:SSEMODEI 1 "nonimmediate_operand" "")))]
4619   "TARGET_SSE2"
4620   "operands[2] = force_reg (<MODE>mode, CONST0_RTX (<MODE>mode));")
4621
4622 (define_expand "<plusminus_insn><mode>3"
4623   [(set (match_operand:SSEMODEI 0 "register_operand" "")
4624         (plusminus:SSEMODEI
4625           (match_operand:SSEMODEI 1 "nonimmediate_operand" "")
4626           (match_operand:SSEMODEI 2 "nonimmediate_operand" "")))]
4627   "TARGET_SSE2"
4628   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
4629
4630 (define_insn "*avx_<plusminus_insn><mode>3"
4631   [(set (match_operand:SSEMODEI 0 "register_operand" "=x")
4632         (plusminus:SSEMODEI
4633           (match_operand:SSEMODEI 1 "nonimmediate_operand" "<comm>x")
4634           (match_operand:SSEMODEI 2 "nonimmediate_operand" "xm")))]
4635   "TARGET_AVX && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
4636   "vp<plusminus_mnemonic><ssevecsize>\t{%2, %1, %0|%0, %1, %2}"
4637   [(set_attr "type" "sseiadd")
4638    (set_attr "prefix" "vex")
4639    (set_attr "mode" "TI")])
4640
4641 (define_insn "*<plusminus_insn><mode>3"
4642   [(set (match_operand:SSEMODEI 0 "register_operand" "=x")
4643         (plusminus:SSEMODEI
4644           (match_operand:SSEMODEI 1 "nonimmediate_operand" "<comm>0")
4645           (match_operand:SSEMODEI 2 "nonimmediate_operand" "xm")))]
4646   "TARGET_SSE2 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
4647   "p<plusminus_mnemonic><ssevecsize>\t{%2, %0|%0, %2}"
4648   [(set_attr "type" "sseiadd")
4649    (set_attr "prefix_data16" "1")
4650    (set_attr "mode" "TI")])
4651
4652 (define_expand "sse2_<plusminus_insn><mode>3"
4653   [(set (match_operand:SSEMODE12 0 "register_operand" "")
4654         (sat_plusminus:SSEMODE12
4655           (match_operand:SSEMODE12 1 "nonimmediate_operand" "")
4656           (match_operand:SSEMODE12 2 "nonimmediate_operand" "")))]
4657   "TARGET_SSE2"
4658   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
4659
4660 (define_insn "*avx_<plusminus_insn><mode>3"
4661   [(set (match_operand:SSEMODE12 0 "register_operand" "=x")
4662         (sat_plusminus:SSEMODE12
4663           (match_operand:SSEMODE12 1 "nonimmediate_operand" "<comm>x")
4664           (match_operand:SSEMODE12 2 "nonimmediate_operand" "xm")))]
4665   "TARGET_AVX && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
4666   "vp<plusminus_mnemonic><ssevecsize>\t{%2, %1, %0|%0, %1, %2}"
4667   [(set_attr "type" "sseiadd")
4668    (set_attr "prefix" "vex")
4669    (set_attr "mode" "TI")])
4670
4671 (define_insn "*sse2_<plusminus_insn><mode>3"
4672   [(set (match_operand:SSEMODE12 0 "register_operand" "=x")
4673         (sat_plusminus:SSEMODE12
4674           (match_operand:SSEMODE12 1 "nonimmediate_operand" "<comm>0")
4675           (match_operand:SSEMODE12 2 "nonimmediate_operand" "xm")))]
4676   "TARGET_SSE2 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
4677   "p<plusminus_mnemonic><ssevecsize>\t{%2, %0|%0, %2}"
4678   [(set_attr "type" "sseiadd")
4679    (set_attr "prefix_data16" "1")
4680    (set_attr "mode" "TI")])
4681
4682 (define_insn_and_split "mulv16qi3"
4683   [(set (match_operand:V16QI 0 "register_operand" "")
4684         (mult:V16QI (match_operand:V16QI 1 "register_operand" "")
4685                     (match_operand:V16QI 2 "register_operand" "")))]
4686   "TARGET_SSE2
4687    && !(reload_completed || reload_in_progress)"
4688   "#"
4689   "&& 1"
4690   [(const_int 0)]
4691 {
4692   rtx t[12], op0, op[3];
4693   int i;
4694
4695   if (TARGET_SSE5)
4696     {
4697       /* On SSE5, we can take advantage of the pperm instruction to pack and
4698          unpack the bytes.  Unpack data such that we've got a source byte in
4699          each low byte of each word.  We don't care what goes into the high
4700          byte, so put 0 there.  */
4701       for (i = 0; i < 6; ++i)
4702         t[i] = gen_reg_rtx (V8HImode);
4703
4704       for (i = 0; i < 2; i++)
4705         {
4706           op[0] = t[i];
4707           op[1] = operands[i+1];
4708           ix86_expand_sse5_unpack (op, true, true);             /* high bytes */
4709
4710           op[0] = t[i+2];
4711           ix86_expand_sse5_unpack (op, true, false);            /* low bytes */
4712         }
4713
4714       /* Multiply words.  */
4715       emit_insn (gen_mulv8hi3 (t[4], t[0], t[1]));              /* high bytes */
4716       emit_insn (gen_mulv8hi3 (t[5], t[2], t[3]));              /* low  bytes */
4717
4718       /* Pack the low byte of each word back into a single xmm */
4719       op[0] = operands[0];
4720       op[1] = t[5];
4721       op[2] = t[4];
4722       ix86_expand_sse5_pack (op);
4723       DONE;
4724     }
4725
4726   for (i = 0; i < 12; ++i)
4727     t[i] = gen_reg_rtx (V16QImode);
4728
4729   /* Unpack data such that we've got a source byte in each low byte of
4730      each word.  We don't care what goes into the high byte of each word.
4731      Rather than trying to get zero in there, most convenient is to let
4732      it be a copy of the low byte.  */
4733   emit_insn (gen_sse2_punpckhbw (t[0], operands[1], operands[1]));
4734   emit_insn (gen_sse2_punpckhbw (t[1], operands[2], operands[2]));
4735   emit_insn (gen_sse2_punpcklbw (t[2], operands[1], operands[1]));
4736   emit_insn (gen_sse2_punpcklbw (t[3], operands[2], operands[2]));
4737
4738   /* Multiply words.  The end-of-line annotations here give a picture of what
4739      the output of that instruction looks like.  Dot means don't care; the
4740      letters are the bytes of the result with A being the most significant.  */
4741   emit_insn (gen_mulv8hi3 (gen_lowpart (V8HImode, t[4]), /* .A.B.C.D.E.F.G.H */
4742                            gen_lowpart (V8HImode, t[0]),
4743                            gen_lowpart (V8HImode, t[1])));
4744   emit_insn (gen_mulv8hi3 (gen_lowpart (V8HImode, t[5]), /* .I.J.K.L.M.N.O.P */
4745                            gen_lowpart (V8HImode, t[2]),
4746                            gen_lowpart (V8HImode, t[3])));
4747
4748   /* Extract the relevant bytes and merge them back together.  */
4749   emit_insn (gen_sse2_punpckhbw (t[6], t[5], t[4]));    /* ..AI..BJ..CK..DL */
4750   emit_insn (gen_sse2_punpcklbw (t[7], t[5], t[4]));    /* ..EM..FN..GO..HP */
4751   emit_insn (gen_sse2_punpckhbw (t[8], t[7], t[6]));    /* ....AEIM....BFJN */
4752   emit_insn (gen_sse2_punpcklbw (t[9], t[7], t[6]));    /* ....CGKO....DHLP */
4753   emit_insn (gen_sse2_punpckhbw (t[10], t[9], t[8]));   /* ........ACEGIKMO */
4754   emit_insn (gen_sse2_punpcklbw (t[11], t[9], t[8]));   /* ........BDFHJLNP */
4755
4756   op0 = operands[0];
4757   emit_insn (gen_sse2_punpcklbw (op0, t[11], t[10]));   /* ABCDEFGHIJKLMNOP */
4758   DONE;
4759 })
4760
4761 (define_expand "mulv8hi3"
4762   [(set (match_operand:V8HI 0 "register_operand" "")
4763         (mult:V8HI (match_operand:V8HI 1 "nonimmediate_operand" "")
4764                    (match_operand:V8HI 2 "nonimmediate_operand" "")))]
4765   "TARGET_SSE2"
4766   "ix86_fixup_binary_operands_no_copy (MULT, V8HImode, operands);")
4767
4768 (define_insn "*avx_mulv8hi3"
4769   [(set (match_operand:V8HI 0 "register_operand" "=x")
4770         (mult:V8HI (match_operand:V8HI 1 "nonimmediate_operand" "%x")
4771                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
4772   "TARGET_AVX && ix86_binary_operator_ok (MULT, V8HImode, operands)"
4773   "vpmullw\t{%2, %1, %0|%0, %1, %2}"
4774   [(set_attr "type" "sseimul")
4775    (set_attr "prefix" "vex")
4776    (set_attr "mode" "TI")])
4777
4778 (define_insn "*mulv8hi3"
4779   [(set (match_operand:V8HI 0 "register_operand" "=x")
4780         (mult:V8HI (match_operand:V8HI 1 "nonimmediate_operand" "%0")
4781                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
4782   "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V8HImode, operands)"
4783   "pmullw\t{%2, %0|%0, %2}"
4784   [(set_attr "type" "sseimul")
4785    (set_attr "prefix_data16" "1")
4786    (set_attr "mode" "TI")])
4787
4788 (define_expand "smulv8hi3_highpart"
4789   [(set (match_operand:V8HI 0 "register_operand" "")
4790         (truncate:V8HI
4791           (lshiftrt:V8SI
4792             (mult:V8SI
4793               (sign_extend:V8SI
4794                 (match_operand:V8HI 1 "nonimmediate_operand" ""))
4795               (sign_extend:V8SI
4796                 (match_operand:V8HI 2 "nonimmediate_operand" "")))
4797             (const_int 16))))]
4798   "TARGET_SSE2"
4799   "ix86_fixup_binary_operands_no_copy (MULT, V8HImode, operands);")
4800
4801 (define_insn "*avxv8hi3_highpart"
4802   [(set (match_operand:V8HI 0 "register_operand" "=x")
4803         (truncate:V8HI
4804           (lshiftrt:V8SI
4805             (mult:V8SI
4806               (sign_extend:V8SI
4807                 (match_operand:V8HI 1 "nonimmediate_operand" "%x"))
4808               (sign_extend:V8SI
4809                 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
4810             (const_int 16))))]
4811   "TARGET_AVX && ix86_binary_operator_ok (MULT, V8HImode, operands)"
4812   "vpmulhw\t{%2, %1, %0|%0, %1, %2}"
4813   [(set_attr "type" "sseimul")
4814    (set_attr "prefix" "vex")
4815    (set_attr "mode" "TI")])
4816
4817 (define_insn "*smulv8hi3_highpart"
4818   [(set (match_operand:V8HI 0 "register_operand" "=x")
4819         (truncate:V8HI
4820           (lshiftrt:V8SI
4821             (mult:V8SI
4822               (sign_extend:V8SI
4823                 (match_operand:V8HI 1 "nonimmediate_operand" "%0"))
4824               (sign_extend:V8SI
4825                 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
4826             (const_int 16))))]
4827   "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V8HImode, operands)"
4828   "pmulhw\t{%2, %0|%0, %2}"
4829   [(set_attr "type" "sseimul")
4830    (set_attr "prefix_data16" "1")
4831    (set_attr "mode" "TI")])
4832
4833 (define_expand "umulv8hi3_highpart"
4834   [(set (match_operand:V8HI 0 "register_operand" "")
4835         (truncate:V8HI
4836           (lshiftrt:V8SI
4837             (mult:V8SI
4838               (zero_extend:V8SI
4839                 (match_operand:V8HI 1 "nonimmediate_operand" ""))
4840               (zero_extend:V8SI
4841                 (match_operand:V8HI 2 "nonimmediate_operand" "")))
4842             (const_int 16))))]
4843   "TARGET_SSE2"
4844   "ix86_fixup_binary_operands_no_copy (MULT, V8HImode, operands);")
4845
4846 (define_insn "*avx_umulv8hi3_highpart"
4847   [(set (match_operand:V8HI 0 "register_operand" "=x")
4848         (truncate:V8HI
4849           (lshiftrt:V8SI
4850             (mult:V8SI
4851               (zero_extend:V8SI
4852                 (match_operand:V8HI 1 "nonimmediate_operand" "%x"))
4853               (zero_extend:V8SI
4854                 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
4855             (const_int 16))))]
4856   "TARGET_AVX && ix86_binary_operator_ok (MULT, V8HImode, operands)"
4857   "vpmulhuw\t{%2, %1, %0|%0, %1, %2}"
4858   [(set_attr "type" "sseimul")
4859    (set_attr "prefix" "vex")
4860    (set_attr "mode" "TI")])
4861
4862 (define_insn "*umulv8hi3_highpart"
4863   [(set (match_operand:V8HI 0 "register_operand" "=x")
4864         (truncate:V8HI
4865           (lshiftrt:V8SI
4866             (mult:V8SI
4867               (zero_extend:V8SI
4868                 (match_operand:V8HI 1 "nonimmediate_operand" "%0"))
4869               (zero_extend:V8SI
4870                 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
4871             (const_int 16))))]
4872   "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V8HImode, operands)"
4873   "pmulhuw\t{%2, %0|%0, %2}"
4874   [(set_attr "type" "sseimul")
4875    (set_attr "prefix_data16" "1")
4876    (set_attr "mode" "TI")])
4877
4878 (define_expand "sse2_umulv2siv2di3"
4879   [(set (match_operand:V2DI 0 "register_operand" "")
4880         (mult:V2DI
4881           (zero_extend:V2DI
4882             (vec_select:V2SI
4883               (match_operand:V4SI 1 "nonimmediate_operand" "")
4884               (parallel [(const_int 0) (const_int 2)])))
4885           (zero_extend:V2DI
4886             (vec_select:V2SI
4887               (match_operand:V4SI 2 "nonimmediate_operand" "")
4888               (parallel [(const_int 0) (const_int 2)])))))]
4889   "TARGET_SSE2"
4890   "ix86_fixup_binary_operands_no_copy (MULT, V4SImode, operands);")
4891
4892 (define_insn "*avx_umulv2siv2di3"
4893   [(set (match_operand:V2DI 0 "register_operand" "=x")
4894         (mult:V2DI
4895           (zero_extend:V2DI
4896             (vec_select:V2SI
4897               (match_operand:V4SI 1 "nonimmediate_operand" "%x")
4898               (parallel [(const_int 0) (const_int 2)])))
4899           (zero_extend:V2DI
4900             (vec_select:V2SI
4901               (match_operand:V4SI 2 "nonimmediate_operand" "xm")
4902               (parallel [(const_int 0) (const_int 2)])))))]
4903   "TARGET_AVX && ix86_binary_operator_ok (MULT, V4SImode, operands)"
4904   "vpmuludq\t{%2, %1, %0|%0, %1, %2}"
4905   [(set_attr "type" "sseimul")
4906    (set_attr "prefix" "vex")
4907    (set_attr "mode" "TI")])
4908
4909 (define_insn "*sse2_umulv2siv2di3"
4910   [(set (match_operand:V2DI 0 "register_operand" "=x")
4911         (mult:V2DI
4912           (zero_extend:V2DI
4913             (vec_select:V2SI
4914               (match_operand:V4SI 1 "nonimmediate_operand" "%0")
4915               (parallel [(const_int 0) (const_int 2)])))
4916           (zero_extend:V2DI
4917             (vec_select:V2SI
4918               (match_operand:V4SI 2 "nonimmediate_operand" "xm")
4919               (parallel [(const_int 0) (const_int 2)])))))]
4920   "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V4SImode, operands)"
4921   "pmuludq\t{%2, %0|%0, %2}"
4922   [(set_attr "type" "sseimul")
4923    (set_attr "prefix_data16" "1")
4924    (set_attr "mode" "TI")])
4925
4926 (define_expand "sse4_1_mulv2siv2di3"
4927   [(set (match_operand:V2DI 0 "register_operand" "")
4928         (mult:V2DI
4929           (sign_extend:V2DI
4930             (vec_select:V2SI
4931               (match_operand:V4SI 1 "nonimmediate_operand" "")
4932               (parallel [(const_int 0) (const_int 2)])))
4933           (sign_extend:V2DI
4934             (vec_select:V2SI
4935               (match_operand:V4SI 2 "nonimmediate_operand" "")
4936               (parallel [(const_int 0) (const_int 2)])))))]
4937   "TARGET_SSE4_1"
4938   "ix86_fixup_binary_operands_no_copy (MULT, V4SImode, operands);")
4939
4940 (define_insn "*avx_mulv2siv2di3"
4941   [(set (match_operand:V2DI 0 "register_operand" "=x")
4942         (mult:V2DI
4943           (sign_extend:V2DI
4944             (vec_select:V2SI
4945               (match_operand:V4SI 1 "nonimmediate_operand" "%x")
4946               (parallel [(const_int 0) (const_int 2)])))
4947           (sign_extend:V2DI
4948             (vec_select:V2SI
4949               (match_operand:V4SI 2 "nonimmediate_operand" "xm")
4950               (parallel [(const_int 0) (const_int 2)])))))]
4951   "TARGET_AVX && ix86_binary_operator_ok (MULT, V4SImode, operands)"
4952   "vpmuldq\t{%2, %1, %0|%0, %1, %2}"
4953   [(set_attr "type" "sseimul")
4954    (set_attr "prefix" "vex")
4955    (set_attr "mode" "TI")])
4956
4957 (define_insn "*sse4_1_mulv2siv2di3"
4958   [(set (match_operand:V2DI 0 "register_operand" "=x")
4959         (mult:V2DI
4960           (sign_extend:V2DI
4961             (vec_select:V2SI
4962               (match_operand:V4SI 1 "nonimmediate_operand" "%0")
4963               (parallel [(const_int 0) (const_int 2)])))
4964           (sign_extend:V2DI
4965             (vec_select:V2SI
4966               (match_operand:V4SI 2 "nonimmediate_operand" "xm")
4967               (parallel [(const_int 0) (const_int 2)])))))]
4968   "TARGET_SSE4_1 && ix86_binary_operator_ok (MULT, V4SImode, operands)"
4969   "pmuldq\t{%2, %0|%0, %2}"
4970   [(set_attr "type" "sseimul")
4971    (set_attr "prefix_extra" "1")
4972    (set_attr "mode" "TI")])
4973
4974 (define_expand "sse2_pmaddwd"
4975   [(set (match_operand:V4SI 0 "register_operand" "")
4976         (plus:V4SI
4977           (mult:V4SI
4978             (sign_extend:V4SI
4979               (vec_select:V4HI
4980                 (match_operand:V8HI 1 "nonimmediate_operand" "")
4981                 (parallel [(const_int 0)
4982                            (const_int 2)
4983                            (const_int 4)
4984                            (const_int 6)])))
4985             (sign_extend:V4SI
4986               (vec_select:V4HI
4987                 (match_operand:V8HI 2 "nonimmediate_operand" "")
4988                 (parallel [(const_int 0)
4989                            (const_int 2)
4990                            (const_int 4)
4991                            (const_int 6)]))))
4992           (mult:V4SI
4993             (sign_extend:V4SI
4994               (vec_select:V4HI (match_dup 1)
4995                 (parallel [(const_int 1)
4996                            (const_int 3)
4997                            (const_int 5)
4998                            (const_int 7)])))
4999             (sign_extend:V4SI
5000               (vec_select:V4HI (match_dup 2)
5001                 (parallel [(const_int 1)
5002                            (const_int 3)
5003                            (const_int 5)
5004                            (const_int 7)]))))))]
5005   "TARGET_SSE2"
5006   "ix86_fixup_binary_operands_no_copy (MULT, V8HImode, operands);")
5007
5008 (define_insn "*avx_pmaddwd"
5009   [(set (match_operand:V4SI 0 "register_operand" "=x")
5010         (plus:V4SI
5011           (mult:V4SI
5012             (sign_extend:V4SI
5013               (vec_select:V4HI
5014                 (match_operand:V8HI 1 "nonimmediate_operand" "%x")
5015                 (parallel [(const_int 0)
5016                            (const_int 2)
5017                            (const_int 4)
5018                            (const_int 6)])))
5019             (sign_extend:V4SI
5020               (vec_select:V4HI
5021                 (match_operand:V8HI 2 "nonimmediate_operand" "xm")
5022                 (parallel [(const_int 0)
5023                            (const_int 2)
5024                            (const_int 4)
5025                            (const_int 6)]))))
5026           (mult:V4SI
5027             (sign_extend:V4SI
5028               (vec_select:V4HI (match_dup 1)
5029                 (parallel [(const_int 1)
5030                            (const_int 3)
5031                            (const_int 5)
5032                            (const_int 7)])))
5033             (sign_extend:V4SI
5034               (vec_select:V4HI (match_dup 2)
5035                 (parallel [(const_int 1)
5036                            (const_int 3)
5037                            (const_int 5)
5038                            (const_int 7)]))))))]
5039   "TARGET_AVX && ix86_binary_operator_ok (MULT, V8HImode, operands)"
5040   "vpmaddwd\t{%2, %1, %0|%0, %1, %2}"
5041   [(set_attr "type" "sseiadd")
5042    (set_attr "prefix" "vex")
5043    (set_attr "mode" "TI")])
5044
5045 (define_insn "*sse2_pmaddwd"
5046   [(set (match_operand:V4SI 0 "register_operand" "=x")
5047         (plus:V4SI
5048           (mult:V4SI
5049             (sign_extend:V4SI
5050               (vec_select:V4HI
5051                 (match_operand:V8HI 1 "nonimmediate_operand" "%0")
5052                 (parallel [(const_int 0)
5053                            (const_int 2)
5054                            (const_int 4)
5055                            (const_int 6)])))
5056             (sign_extend:V4SI
5057               (vec_select:V4HI
5058                 (match_operand:V8HI 2 "nonimmediate_operand" "xm")
5059                 (parallel [(const_int 0)
5060                            (const_int 2)
5061                            (const_int 4)
5062                            (const_int 6)]))))
5063           (mult:V4SI
5064             (sign_extend:V4SI
5065               (vec_select:V4HI (match_dup 1)
5066                 (parallel [(const_int 1)
5067                            (const_int 3)
5068                            (const_int 5)
5069                            (const_int 7)])))
5070             (sign_extend:V4SI
5071               (vec_select:V4HI (match_dup 2)
5072                 (parallel [(const_int 1)
5073                            (const_int 3)
5074                            (const_int 5)
5075                            (const_int 7)]))))))]
5076   "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V8HImode, operands)"
5077   "pmaddwd\t{%2, %0|%0, %2}"
5078   [(set_attr "type" "sseiadd")
5079    (set_attr "atom_unit" "simul")
5080    (set_attr "prefix_data16" "1")
5081    (set_attr "mode" "TI")])
5082
5083 (define_expand "mulv4si3"
5084   [(set (match_operand:V4SI 0 "register_operand" "")
5085         (mult:V4SI (match_operand:V4SI 1 "register_operand" "")
5086                    (match_operand:V4SI 2 "register_operand" "")))]
5087   "TARGET_SSE2"
5088 {
5089   if (TARGET_SSE4_1 || TARGET_SSE5)
5090     ix86_fixup_binary_operands_no_copy (MULT, V4SImode, operands);
5091 })
5092
5093 (define_insn "*avx_mulv4si3"
5094   [(set (match_operand:V4SI 0 "register_operand" "=x")
5095         (mult:V4SI (match_operand:V4SI 1 "nonimmediate_operand" "%x")
5096                    (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
5097   "TARGET_AVX && ix86_binary_operator_ok (MULT, V4SImode, operands)"
5098   "vpmulld\t{%2, %1, %0|%0, %1, %2}"
5099   [(set_attr "type" "sseimul")
5100    (set_attr "prefix" "vex")
5101    (set_attr "mode" "TI")])
5102
5103 (define_insn "*sse4_1_mulv4si3"
5104   [(set (match_operand:V4SI 0 "register_operand" "=x")
5105         (mult:V4SI (match_operand:V4SI 1 "nonimmediate_operand" "%0")
5106                    (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
5107   "TARGET_SSE4_1 && ix86_binary_operator_ok (MULT, V4SImode, operands)"
5108   "pmulld\t{%2, %0|%0, %2}"
5109   [(set_attr "type" "sseimul")
5110    (set_attr "prefix_extra" "1")
5111    (set_attr "mode" "TI")])
5112
5113 ;; We don't have a straight 32-bit parallel multiply on SSE5, so fake it with a
5114 ;; multiply/add.  In general, we expect the define_split to occur before
5115 ;; register allocation, so we have to handle the corner case where the target
5116 ;; is the same as one of the inputs.
5117 (define_insn_and_split "*sse5_mulv4si3"
5118   [(set (match_operand:V4SI 0 "register_operand" "=&x")
5119         (mult:V4SI (match_operand:V4SI 1 "register_operand" "%x")
5120                    (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
5121   "TARGET_SSE5"
5122   "#"
5123   "&& (reload_completed
5124        || (!reg_mentioned_p (operands[0], operands[1])
5125            && !reg_mentioned_p (operands[0], operands[2])))"
5126   [(set (match_dup 0)
5127         (match_dup 3))
5128    (set (match_dup 0)
5129         (plus:V4SI (mult:V4SI (match_dup 1)
5130                               (match_dup 2))
5131                    (match_dup 0)))]
5132 {
5133   operands[3] = CONST0_RTX (V4SImode);
5134 }
5135   [(set_attr "type" "ssemuladd")
5136    (set_attr "mode" "TI")])
5137
5138 (define_insn_and_split "*sse2_mulv4si3"
5139   [(set (match_operand:V4SI 0 "register_operand" "")
5140         (mult:V4SI (match_operand:V4SI 1 "register_operand" "")
5141                    (match_operand:V4SI 2 "register_operand" "")))]
5142   "TARGET_SSE2 && !TARGET_SSE4_1 && !TARGET_SSE5
5143    && !(reload_completed || reload_in_progress)"
5144   "#"
5145   "&& 1"
5146   [(const_int 0)]
5147 {
5148   rtx t1, t2, t3, t4, t5, t6, thirtytwo;
5149   rtx op0, op1, op2;
5150
5151   op0 = operands[0];
5152   op1 = operands[1];
5153   op2 = operands[2];
5154   t1 = gen_reg_rtx (V4SImode);
5155   t2 = gen_reg_rtx (V4SImode);
5156   t3 = gen_reg_rtx (V4SImode);
5157   t4 = gen_reg_rtx (V4SImode);
5158   t5 = gen_reg_rtx (V4SImode);
5159   t6 = gen_reg_rtx (V4SImode);
5160   thirtytwo = GEN_INT (32);
5161
5162   /* Multiply elements 2 and 0.  */
5163   emit_insn (gen_sse2_umulv2siv2di3 (gen_lowpart (V2DImode, t1),
5164                                      op1, op2));
5165
5166   /* Shift both input vectors down one element, so that elements 3
5167      and 1 are now in the slots for elements 2 and 0.  For K8, at
5168      least, this is faster than using a shuffle.  */
5169   emit_insn (gen_sse2_lshrti3 (gen_lowpart (TImode, t2),
5170                                gen_lowpart (TImode, op1),
5171                                thirtytwo));
5172   emit_insn (gen_sse2_lshrti3 (gen_lowpart (TImode, t3),
5173                                gen_lowpart (TImode, op2),
5174                                thirtytwo));
5175   /* Multiply elements 3 and 1.  */
5176   emit_insn (gen_sse2_umulv2siv2di3 (gen_lowpart (V2DImode, t4),
5177                                      t2, t3));
5178
5179   /* Move the results in element 2 down to element 1; we don't care
5180      what goes in elements 2 and 3.  */
5181   emit_insn (gen_sse2_pshufd_1 (t5, t1, const0_rtx, const2_rtx,
5182                                 const0_rtx, const0_rtx));
5183   emit_insn (gen_sse2_pshufd_1 (t6, t4, const0_rtx, const2_rtx,
5184                                 const0_rtx, const0_rtx));
5185
5186   /* Merge the parts back together.  */
5187   emit_insn (gen_sse2_punpckldq (op0, t5, t6));
5188   DONE;
5189 })
5190
5191 (define_insn_and_split "mulv2di3"
5192   [(set (match_operand:V2DI 0 "register_operand" "")
5193         (mult:V2DI (match_operand:V2DI 1 "register_operand" "")
5194                    (match_operand:V2DI 2 "register_operand" "")))]
5195   "TARGET_SSE2
5196    && !(reload_completed || reload_in_progress)"
5197   "#"
5198   "&& 1"
5199   [(const_int 0)]
5200 {
5201   rtx t1, t2, t3, t4, t5, t6, thirtytwo;
5202   rtx op0, op1, op2;
5203
5204   if (TARGET_SSE5)
5205     {
5206       /* op1: A,B,C,D, op2: E,F,G,H */
5207       op0 = operands[0];
5208       op1 = gen_lowpart (V4SImode, operands[1]);
5209       op2 = gen_lowpart (V4SImode, operands[2]);
5210       t1 = gen_reg_rtx (V4SImode);
5211       t2 = gen_reg_rtx (V4SImode);
5212       t3 = gen_reg_rtx (V4SImode);
5213       t4 = gen_reg_rtx (V2DImode);
5214       t5 = gen_reg_rtx (V2DImode);
5215
5216       /* t1: B,A,D,C */
5217       emit_insn (gen_sse2_pshufd_1 (t1, op1,
5218                                     GEN_INT (1),
5219                                     GEN_INT (0),
5220                                     GEN_INT (3),
5221                                     GEN_INT (2)));
5222
5223       /* t2: 0 */
5224       emit_move_insn (t2, CONST0_RTX (V4SImode));
5225
5226       /* t3: (B*E),(A*F),(D*G),(C*H) */
5227       emit_insn (gen_sse5_pmacsdd (t3, t1, op2, t2));
5228
5229       /* t4: (B*E)+(A*F), (D*G)+(C*H) */
5230       emit_insn (gen_sse5_phadddq (t4, t3));
5231
5232       /* t5: ((B*E)+(A*F))<<32, ((D*G)+(C*H))<<32 */
5233       emit_insn (gen_ashlv2di3 (t5, t4, GEN_INT (32)));
5234
5235       /* op0: (((B*E)+(A*F))<<32)+(B*F), (((D*G)+(C*H))<<32)+(D*H) */
5236       emit_insn (gen_sse5_pmacsdql (op0, op1, op2, t5));
5237       DONE;
5238     }
5239
5240   op0 = operands[0];
5241   op1 = operands[1];
5242   op2 = operands[2];
5243   t1 = gen_reg_rtx (V2DImode);
5244   t2 = gen_reg_rtx (V2DImode);
5245   t3 = gen_reg_rtx (V2DImode);
5246   t4 = gen_reg_rtx (V2DImode);
5247   t5 = gen_reg_rtx (V2DImode);
5248   t6 = gen_reg_rtx (V2DImode);
5249   thirtytwo = GEN_INT (32);
5250
5251   /* Multiply low parts.  */
5252   emit_insn (gen_sse2_umulv2siv2di3 (t1, gen_lowpart (V4SImode, op1),
5253                                      gen_lowpart (V4SImode, op2)));
5254
5255   /* Shift input vectors left 32 bits so we can multiply high parts.  */
5256   emit_insn (gen_lshrv2di3 (t2, op1, thirtytwo));
5257   emit_insn (gen_lshrv2di3 (t3, op2, thirtytwo));
5258
5259   /* Multiply high parts by low parts.  */
5260   emit_insn (gen_sse2_umulv2siv2di3 (t4, gen_lowpart (V4SImode, op1),
5261                                      gen_lowpart (V4SImode, t3)));
5262   emit_insn (gen_sse2_umulv2siv2di3 (t5, gen_lowpart (V4SImode, op2),
5263                                      gen_lowpart (V4SImode, t2)));
5264
5265   /* Shift them back.  */
5266   emit_insn (gen_ashlv2di3 (t4, t4, thirtytwo));
5267   emit_insn (gen_ashlv2di3 (t5, t5, thirtytwo));
5268
5269   /* Add the three parts together.  */
5270   emit_insn (gen_addv2di3 (t6, t1, t4));
5271   emit_insn (gen_addv2di3 (op0, t6, t5));
5272   DONE;
5273 })
5274
5275 (define_expand "vec_widen_smult_hi_v8hi"
5276   [(match_operand:V4SI 0 "register_operand" "")
5277    (match_operand:V8HI 1 "register_operand" "")
5278    (match_operand:V8HI 2 "register_operand" "")]
5279   "TARGET_SSE2"
5280 {
5281   rtx op1, op2, t1, t2, dest;
5282
5283   op1 = operands[1];
5284   op2 = operands[2];
5285   t1 = gen_reg_rtx (V8HImode);
5286   t2 = gen_reg_rtx (V8HImode);
5287   dest = gen_lowpart (V8HImode, operands[0]);
5288
5289   emit_insn (gen_mulv8hi3 (t1, op1, op2));
5290   emit_insn (gen_smulv8hi3_highpart (t2, op1, op2));
5291   emit_insn (gen_vec_interleave_highv8hi (dest, t1, t2));
5292   DONE;
5293 })
5294
5295 (define_expand "vec_widen_smult_lo_v8hi"
5296   [(match_operand:V4SI 0 "register_operand" "")
5297    (match_operand:V8HI 1 "register_operand" "")
5298    (match_operand:V8HI 2 "register_operand" "")]
5299   "TARGET_SSE2"
5300 {
5301   rtx op1, op2, t1, t2, dest;
5302
5303   op1 = operands[1];
5304   op2 = operands[2];
5305   t1 = gen_reg_rtx (V8HImode);
5306   t2 = gen_reg_rtx (V8HImode);
5307   dest = gen_lowpart (V8HImode, operands[0]);
5308
5309   emit_insn (gen_mulv8hi3 (t1, op1, op2));
5310   emit_insn (gen_smulv8hi3_highpart (t2, op1, op2));
5311   emit_insn (gen_vec_interleave_lowv8hi (dest, t1, t2));
5312   DONE;
5313 })
5314
5315 (define_expand "vec_widen_umult_hi_v8hi"
5316   [(match_operand:V4SI 0 "register_operand" "")
5317    (match_operand:V8HI 1 "register_operand" "")
5318    (match_operand:V8HI 2 "register_operand" "")]
5319   "TARGET_SSE2"
5320 {
5321   rtx op1, op2, t1, t2, dest;
5322
5323   op1 = operands[1];
5324   op2 = operands[2];
5325   t1 = gen_reg_rtx (V8HImode);
5326   t2 = gen_reg_rtx (V8HImode);
5327   dest = gen_lowpart (V8HImode, operands[0]);
5328
5329   emit_insn (gen_mulv8hi3 (t1, op1, op2));
5330   emit_insn (gen_umulv8hi3_highpart (t2, op1, op2));
5331   emit_insn (gen_vec_interleave_highv8hi (dest, t1, t2));
5332   DONE;
5333 })
5334
5335 (define_expand "vec_widen_umult_lo_v8hi"
5336   [(match_operand:V4SI 0 "register_operand" "")
5337    (match_operand:V8HI 1 "register_operand" "")
5338    (match_operand:V8HI 2 "register_operand" "")]
5339   "TARGET_SSE2"
5340 {
5341   rtx op1, op2, t1, t2, dest;
5342
5343   op1 = operands[1];
5344   op2 = operands[2];
5345   t1 = gen_reg_rtx (V8HImode);
5346   t2 = gen_reg_rtx (V8HImode);
5347   dest = gen_lowpart (V8HImode, operands[0]);
5348
5349   emit_insn (gen_mulv8hi3 (t1, op1, op2));
5350   emit_insn (gen_umulv8hi3_highpart (t2, op1, op2));
5351   emit_insn (gen_vec_interleave_lowv8hi (dest, t1, t2));
5352   DONE;
5353 })
5354
5355 (define_expand "vec_widen_smult_hi_v4si"
5356   [(match_operand:V2DI 0 "register_operand" "")
5357    (match_operand:V4SI 1 "register_operand" "")
5358    (match_operand:V4SI 2 "register_operand" "")]
5359   "TARGET_SSE5"
5360 {
5361   rtx t1, t2;
5362
5363   t1 = gen_reg_rtx (V4SImode);
5364   t2 = gen_reg_rtx (V4SImode);
5365
5366   emit_insn (gen_sse2_pshufd_1 (t1, operands[1],
5367                                 GEN_INT (0),
5368                                 GEN_INT (2),
5369                                 GEN_INT (1),
5370                                 GEN_INT (3)));
5371   emit_insn (gen_sse2_pshufd_1 (t2, operands[2],
5372                                 GEN_INT (0),
5373                                 GEN_INT (2),
5374                                 GEN_INT (1),
5375                                 GEN_INT (3)));
5376   emit_insn (gen_sse5_mulv2div2di3_high (operands[0], t1, t2));
5377   DONE;
5378 })
5379
5380 (define_expand "vec_widen_smult_lo_v4si"
5381   [(match_operand:V2DI 0 "register_operand" "")
5382    (match_operand:V4SI 1 "register_operand" "")
5383    (match_operand:V4SI 2 "register_operand" "")]
5384   "TARGET_SSE5"
5385 {
5386   rtx t1, t2;
5387
5388   t1 = gen_reg_rtx (V4SImode);
5389   t2 = gen_reg_rtx (V4SImode);
5390
5391   emit_insn (gen_sse2_pshufd_1 (t1, operands[1],
5392                                 GEN_INT (0),
5393                                 GEN_INT (2),
5394                                 GEN_INT (1),
5395                                 GEN_INT (3)));
5396   emit_insn (gen_sse2_pshufd_1 (t2, operands[2],
5397                                 GEN_INT (0),
5398                                 GEN_INT (2),
5399                                 GEN_INT (1),
5400                                 GEN_INT (3)));
5401   emit_insn (gen_sse5_mulv2div2di3_low (operands[0], t1, t2));
5402   DONE;
5403   DONE;
5404 })
5405
5406 (define_expand "vec_widen_umult_hi_v4si"
5407   [(match_operand:V2DI 0 "register_operand" "")
5408    (match_operand:V4SI 1 "register_operand" "")
5409    (match_operand:V4SI 2 "register_operand" "")]
5410   "TARGET_SSE2"
5411 {
5412   rtx op1, op2, t1, t2;
5413
5414   op1 = operands[1];
5415   op2 = operands[2];
5416   t1 = gen_reg_rtx (V4SImode);
5417   t2 = gen_reg_rtx (V4SImode);
5418
5419   emit_insn (gen_vec_interleave_highv4si (t1, op1, op1));
5420   emit_insn (gen_vec_interleave_highv4si (t2, op2, op2));
5421   emit_insn (gen_sse2_umulv2siv2di3 (operands[0], t1, t2));
5422   DONE;
5423 })
5424
5425 (define_expand "vec_widen_umult_lo_v4si"
5426   [(match_operand:V2DI 0 "register_operand" "")
5427    (match_operand:V4SI 1 "register_operand" "")
5428    (match_operand:V4SI 2 "register_operand" "")]
5429   "TARGET_SSE2"
5430 {
5431   rtx op1, op2, t1, t2;
5432
5433   op1 = operands[1];
5434   op2 = operands[2];
5435   t1 = gen_reg_rtx (V4SImode);
5436   t2 = gen_reg_rtx (V4SImode);
5437
5438   emit_insn (gen_vec_interleave_lowv4si (t1, op1, op1));
5439   emit_insn (gen_vec_interleave_lowv4si (t2, op2, op2));
5440   emit_insn (gen_sse2_umulv2siv2di3 (operands[0], t1, t2));
5441   DONE;
5442 })
5443
5444 (define_expand "sdot_prodv8hi"
5445   [(match_operand:V4SI 0 "register_operand" "")
5446    (match_operand:V8HI 1 "register_operand" "")
5447    (match_operand:V8HI 2 "register_operand" "")
5448    (match_operand:V4SI 3 "register_operand" "")]
5449   "TARGET_SSE2"
5450 {
5451   rtx t = gen_reg_rtx (V4SImode);
5452   emit_insn (gen_sse2_pmaddwd (t, operands[1], operands[2]));
5453   emit_insn (gen_addv4si3 (operands[0], operands[3], t));
5454   DONE;
5455 })
5456
5457 (define_expand "udot_prodv4si"
5458   [(match_operand:V2DI 0 "register_operand" "")
5459    (match_operand:V4SI 1 "register_operand" "")
5460    (match_operand:V4SI 2 "register_operand" "")
5461    (match_operand:V2DI 3 "register_operand" "")]
5462   "TARGET_SSE2"
5463 {
5464   rtx t1, t2, t3, t4;
5465
5466   t1 = gen_reg_rtx (V2DImode);
5467   emit_insn (gen_sse2_umulv2siv2di3 (t1, operands[1], operands[2]));
5468   emit_insn (gen_addv2di3 (t1, t1, operands[3]));
5469
5470   t2 = gen_reg_rtx (V4SImode);
5471   t3 = gen_reg_rtx (V4SImode);
5472   emit_insn (gen_sse2_lshrti3 (gen_lowpart (TImode, t2),
5473                                gen_lowpart (TImode, operands[1]),
5474                                GEN_INT (32)));
5475   emit_insn (gen_sse2_lshrti3 (gen_lowpart (TImode, t3),
5476                                gen_lowpart (TImode, operands[2]),
5477                                GEN_INT (32)));
5478
5479   t4 = gen_reg_rtx (V2DImode);
5480   emit_insn (gen_sse2_umulv2siv2di3 (t4, t2, t3));
5481
5482   emit_insn (gen_addv2di3 (operands[0], t1, t4));
5483   DONE;
5484 })
5485
5486 (define_insn "*avx_ashr<mode>3"
5487   [(set (match_operand:SSEMODE24 0 "register_operand" "=x")
5488         (ashiftrt:SSEMODE24
5489           (match_operand:SSEMODE24 1 "register_operand" "x")
5490           (match_operand:SI 2 "nonmemory_operand" "xN")))]
5491   "TARGET_AVX"
5492   "vpsra<ssevecsize>\t{%2, %1, %0|%0, %1, %2}"
5493   [(set_attr "type" "sseishft")
5494    (set_attr "prefix" "vex")
5495    (set_attr "mode" "TI")])
5496
5497 (define_insn "ashr<mode>3"
5498   [(set (match_operand:SSEMODE24 0 "register_operand" "=x")
5499         (ashiftrt:SSEMODE24
5500           (match_operand:SSEMODE24 1 "register_operand" "0")
5501           (match_operand:SI 2 "nonmemory_operand" "xN")))]
5502   "TARGET_SSE2"
5503   "psra<ssevecsize>\t{%2, %0|%0, %2}"
5504   [(set_attr "type" "sseishft")
5505    (set_attr "prefix_data16" "1")
5506    (set_attr "mode" "TI")])
5507
5508 (define_insn "*avx_lshr<mode>3"
5509   [(set (match_operand:SSEMODE248 0 "register_operand" "=x")
5510         (lshiftrt:SSEMODE248
5511           (match_operand:SSEMODE248 1 "register_operand" "x")
5512           (match_operand:SI 2 "nonmemory_operand" "xN")))]
5513   "TARGET_AVX"
5514   "vpsrl<ssevecsize>\t{%2, %1, %0|%0, %1, %2}"
5515   [(set_attr "type" "sseishft")
5516    (set_attr "prefix" "vex")
5517    (set_attr "mode" "TI")])
5518
5519 (define_insn "lshr<mode>3"
5520   [(set (match_operand:SSEMODE248 0 "register_operand" "=x")
5521         (lshiftrt:SSEMODE248
5522           (match_operand:SSEMODE248 1 "register_operand" "0")
5523           (match_operand:SI 2 "nonmemory_operand" "xN")))]
5524   "TARGET_SSE2"
5525   "psrl<ssevecsize>\t{%2, %0|%0, %2}"
5526   [(set_attr "type" "sseishft")
5527    (set_attr "prefix_data16" "1")
5528    (set_attr "mode" "TI")])
5529
5530 (define_insn "*avx_ashl<mode>3"
5531   [(set (match_operand:SSEMODE248 0 "register_operand" "=x")
5532         (ashift:SSEMODE248
5533           (match_operand:SSEMODE248 1 "register_operand" "x")
5534           (match_operand:SI 2 "nonmemory_operand" "xN")))]
5535   "TARGET_AVX"
5536   "vpsll<ssevecsize>\t{%2, %1, %0|%0, %1, %2}"
5537   [(set_attr "type" "sseishft")
5538    (set_attr "prefix" "vex")
5539    (set_attr "mode" "TI")])
5540
5541 (define_insn "ashl<mode>3"
5542   [(set (match_operand:SSEMODE248 0 "register_operand" "=x")
5543         (ashift:SSEMODE248
5544           (match_operand:SSEMODE248 1 "register_operand" "0")
5545           (match_operand:SI 2 "nonmemory_operand" "xN")))]
5546   "TARGET_SSE2"
5547   "psll<ssevecsize>\t{%2, %0|%0, %2}"
5548   [(set_attr "type" "sseishft")
5549    (set_attr "prefix_data16" "1")
5550    (set_attr "mode" "TI")])
5551
5552 (define_expand "vec_shl_<mode>"
5553   [(set (match_operand:SSEMODEI 0 "register_operand" "")
5554         (ashift:TI (match_operand:SSEMODEI 1 "register_operand" "")
5555                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "")))]
5556   "TARGET_SSE2"
5557 {
5558   operands[0] = gen_lowpart (TImode, operands[0]);
5559   operands[1] = gen_lowpart (TImode, operands[1]);
5560 })
5561
5562 (define_expand "vec_shr_<mode>"
5563   [(set (match_operand:SSEMODEI 0 "register_operand" "")
5564         (lshiftrt:TI (match_operand:SSEMODEI 1 "register_operand" "")
5565                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "")))]
5566   "TARGET_SSE2"
5567 {
5568   operands[0] = gen_lowpart (TImode, operands[0]);
5569   operands[1] = gen_lowpart (TImode, operands[1]);
5570 })
5571
5572 (define_insn "*avx_<code><mode>3"
5573   [(set (match_operand:SSEMODE124 0 "register_operand" "=x")
5574         (maxmin:SSEMODE124
5575           (match_operand:SSEMODE124 1 "nonimmediate_operand" "%x")
5576           (match_operand:SSEMODE124 2 "nonimmediate_operand" "xm")))]
5577   "TARGET_AVX && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5578   "vp<maxminiprefix><ssevecsize>\t{%2, %1, %0|%0, %1, %2}"
5579   [(set_attr "type" "sseiadd")
5580    (set_attr "prefix" "vex")
5581    (set_attr "mode" "TI")])
5582
5583 (define_expand "<code>v16qi3"
5584   [(set (match_operand:V16QI 0 "register_operand" "")
5585         (umaxmin:V16QI
5586           (match_operand:V16QI 1 "nonimmediate_operand" "")
5587           (match_operand:V16QI 2 "nonimmediate_operand" "")))]
5588   "TARGET_SSE2"
5589   "ix86_fixup_binary_operands_no_copy (<CODE>, V16QImode, operands);")
5590
5591 (define_insn "*<code>v16qi3"
5592   [(set (match_operand:V16QI 0 "register_operand" "=x")
5593         (umaxmin:V16QI
5594           (match_operand:V16QI 1 "nonimmediate_operand" "%0")
5595           (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
5596   "TARGET_SSE2 && ix86_binary_operator_ok (<CODE>, V16QImode, operands)"
5597   "p<maxminiprefix>b\t{%2, %0|%0, %2}"
5598   [(set_attr "type" "sseiadd")
5599    (set_attr "prefix_data16" "1")
5600    (set_attr "mode" "TI")])
5601
5602 (define_expand "<code>v8hi3"
5603   [(set (match_operand:V8HI 0 "register_operand" "")
5604         (smaxmin:V8HI
5605           (match_operand:V8HI 1 "nonimmediate_operand" "")
5606           (match_operand:V8HI 2 "nonimmediate_operand" "")))]
5607   "TARGET_SSE2"
5608   "ix86_fixup_binary_operands_no_copy (<CODE>, V8HImode, operands);")
5609
5610 (define_insn "*<code>v8hi3"
5611   [(set (match_operand:V8HI 0 "register_operand" "=x")
5612         (smaxmin:V8HI
5613           (match_operand:V8HI 1 "nonimmediate_operand" "%0")
5614           (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
5615   "TARGET_SSE2 && ix86_binary_operator_ok (<CODE>, V8HImode, operands)"
5616   "p<maxminiprefix>w\t{%2, %0|%0, %2}"
5617   [(set_attr "type" "sseiadd")
5618    (set_attr "prefix_data16" "1")
5619    (set_attr "mode" "TI")])
5620
5621 (define_expand "umaxv8hi3"
5622   [(set (match_operand:V8HI 0 "register_operand" "")
5623         (umax:V8HI (match_operand:V8HI 1 "register_operand" "")
5624                    (match_operand:V8HI 2 "nonimmediate_operand" "")))]
5625   "TARGET_SSE2"
5626 {
5627   if (TARGET_SSE4_1)
5628     ix86_fixup_binary_operands_no_copy (UMAX, V8HImode, operands);
5629   else
5630     {
5631       rtx op0 = operands[0], op2 = operands[2], op3 = op0;
5632       if (rtx_equal_p (op3, op2))
5633         op3 = gen_reg_rtx (V8HImode);
5634       emit_insn (gen_sse2_ussubv8hi3 (op3, operands[1], op2));
5635       emit_insn (gen_addv8hi3 (op0, op3, op2));
5636       DONE;
5637     }
5638 })
5639
5640 (define_expand "smax<mode>3"
5641   [(set (match_operand:SSEMODE14 0 "register_operand" "")
5642         (smax:SSEMODE14 (match_operand:SSEMODE14 1 "register_operand" "")
5643                         (match_operand:SSEMODE14 2 "register_operand" "")))]
5644   "TARGET_SSE2"
5645 {
5646   if (TARGET_SSE4_1)
5647     ix86_fixup_binary_operands_no_copy (SMAX, <MODE>mode, operands);
5648   else
5649   {
5650     rtx xops[6];
5651     bool ok;
5652
5653     xops[0] = operands[0];
5654     xops[1] = operands[1];
5655     xops[2] = operands[2];
5656     xops[3] = gen_rtx_GT (VOIDmode, operands[1], operands[2]);
5657     xops[4] = operands[1];
5658     xops[5] = operands[2];
5659     ok = ix86_expand_int_vcond (xops);
5660     gcc_assert (ok);
5661     DONE;
5662   }
5663 })
5664
5665 (define_insn "*sse4_1_<code><mode>3"
5666   [(set (match_operand:SSEMODE14 0 "register_operand" "=x")
5667         (smaxmin:SSEMODE14
5668           (match_operand:SSEMODE14 1 "nonimmediate_operand" "%0")
5669           (match_operand:SSEMODE14 2 "nonimmediate_operand" "xm")))]
5670   "TARGET_SSE4_1 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5671   "p<maxminiprefix><ssevecsize>\t{%2, %0|%0, %2}"
5672   [(set_attr "type" "sseiadd")
5673    (set_attr "prefix_extra" "1")
5674    (set_attr "mode" "TI")])
5675
5676 (define_expand "umaxv4si3"
5677   [(set (match_operand:V4SI 0 "register_operand" "")
5678         (umax:V4SI (match_operand:V4SI 1 "register_operand" "")
5679                    (match_operand:V4SI 2 "register_operand" "")))]
5680   "TARGET_SSE2"
5681 {
5682   if (TARGET_SSE4_1)
5683     ix86_fixup_binary_operands_no_copy (UMAX, V4SImode, operands);
5684   else
5685   {
5686     rtx xops[6];
5687     bool ok;
5688
5689     xops[0] = operands[0];
5690     xops[1] = operands[1];
5691     xops[2] = operands[2];
5692     xops[3] = gen_rtx_GTU (VOIDmode, operands[1], operands[2]);
5693     xops[4] = operands[1];
5694     xops[5] = operands[2];
5695     ok = ix86_expand_int_vcond (xops);
5696     gcc_assert (ok);
5697     DONE;
5698   }
5699 })
5700
5701 (define_insn "*sse4_1_<code><mode>3"
5702   [(set (match_operand:SSEMODE24 0 "register_operand" "=x")
5703         (umaxmin:SSEMODE24
5704           (match_operand:SSEMODE24 1 "nonimmediate_operand" "%0")
5705           (match_operand:SSEMODE24 2 "nonimmediate_operand" "xm")))]
5706   "TARGET_SSE4_1 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5707   "p<maxminiprefix><ssevecsize>\t{%2, %0|%0, %2}"
5708   [(set_attr "type" "sseiadd")
5709    (set_attr "prefix_extra" "1")
5710    (set_attr "mode" "TI")])
5711
5712 (define_expand "smin<mode>3"
5713   [(set (match_operand:SSEMODE14 0 "register_operand" "")
5714         (smin:SSEMODE14 (match_operand:SSEMODE14 1 "register_operand" "")
5715                         (match_operand:SSEMODE14 2 "register_operand" "")))]
5716   "TARGET_SSE2"
5717 {
5718   if (TARGET_SSE4_1)
5719     ix86_fixup_binary_operands_no_copy (SMIN, <MODE>mode, operands);
5720   else
5721     {
5722       rtx xops[6];
5723       bool ok;
5724
5725       xops[0] = operands[0];
5726       xops[1] = operands[2];
5727       xops[2] = operands[1];
5728       xops[3] = gen_rtx_GT (VOIDmode, operands[1], operands[2]);
5729       xops[4] = operands[1];
5730       xops[5] = operands[2];
5731       ok = ix86_expand_int_vcond (xops);
5732       gcc_assert (ok);
5733       DONE;
5734     }
5735 })
5736
5737 (define_expand "umin<mode>3"
5738   [(set (match_operand:SSEMODE24 0 "register_operand" "")
5739         (umin:SSEMODE24 (match_operand:SSEMODE24 1 "register_operand" "")
5740                         (match_operand:SSEMODE24 2 "register_operand" "")))]
5741   "TARGET_SSE2"
5742 {
5743   if (TARGET_SSE4_1)
5744     ix86_fixup_binary_operands_no_copy (UMIN, <MODE>mode, operands);
5745   else
5746     {
5747       rtx xops[6];
5748       bool ok;
5749
5750       xops[0] = operands[0];
5751       xops[1] = operands[2];
5752       xops[2] = operands[1];
5753       xops[3] = gen_rtx_GTU (VOIDmode, operands[1], operands[2]);
5754       xops[4] = operands[1];
5755       xops[5] = operands[2];
5756       ok = ix86_expand_int_vcond (xops);
5757       gcc_assert (ok);
5758       DONE;
5759     }
5760 })
5761
5762 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5763 ;;
5764 ;; Parallel integral comparisons
5765 ;;
5766 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5767
5768 (define_expand "sse2_eq<mode>3"
5769   [(set (match_operand:SSEMODE124 0 "register_operand" "")
5770         (eq:SSEMODE124
5771           (match_operand:SSEMODE124 1 "nonimmediate_operand" "")
5772           (match_operand:SSEMODE124 2 "nonimmediate_operand" "")))]
5773   "TARGET_SSE2 && !TARGET_SSE5"
5774   "ix86_fixup_binary_operands_no_copy (EQ, <MODE>mode, operands);")
5775
5776 (define_insn "*avx_eq<mode>3"
5777   [(set (match_operand:SSEMODE1248 0 "register_operand" "=x")
5778         (eq:SSEMODE1248
5779           (match_operand:SSEMODE1248 1 "nonimmediate_operand" "%x")
5780           (match_operand:SSEMODE1248 2 "nonimmediate_operand" "xm")))]
5781   "TARGET_AVX && ix86_binary_operator_ok (EQ, <MODE>mode, operands)"
5782   "vpcmpeq<ssevecsize>\t{%2, %1, %0|%0, %1, %2}"
5783   [(set_attr "type" "ssecmp")
5784    (set_attr "prefix" "vex")
5785    (set_attr "mode" "TI")])
5786
5787 (define_insn "*sse2_eq<mode>3"
5788   [(set (match_operand:SSEMODE124 0 "register_operand" "=x")
5789         (eq:SSEMODE124
5790           (match_operand:SSEMODE124 1 "nonimmediate_operand" "%0")
5791           (match_operand:SSEMODE124 2 "nonimmediate_operand" "xm")))]
5792   "TARGET_SSE2 && !TARGET_SSE5
5793    && ix86_binary_operator_ok (EQ, <MODE>mode, operands)"
5794   "pcmpeq<ssevecsize>\t{%2, %0|%0, %2}"
5795   [(set_attr "type" "ssecmp")
5796    (set_attr "prefix_data16" "1")
5797    (set_attr "mode" "TI")])
5798
5799 (define_expand "sse4_1_eqv2di3"
5800   [(set (match_operand:V2DI 0 "register_operand" "")
5801         (eq:V2DI
5802           (match_operand:V2DI 1 "nonimmediate_operand" "")
5803           (match_operand:V2DI 2 "nonimmediate_operand" "")))]
5804   "TARGET_SSE4_1"
5805   "ix86_fixup_binary_operands_no_copy (EQ, V2DImode, operands);")
5806
5807 (define_insn "*sse4_1_eqv2di3"
5808   [(set (match_operand:V2DI 0 "register_operand" "=x")
5809         (eq:V2DI
5810           (match_operand:V2DI 1 "nonimmediate_operand" "%0")
5811           (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
5812   "TARGET_SSE4_1 && ix86_binary_operator_ok (EQ, V2DImode, operands)"
5813   "pcmpeqq\t{%2, %0|%0, %2}"
5814   [(set_attr "type" "ssecmp")
5815    (set_attr "prefix_extra" "1")
5816    (set_attr "mode" "TI")])
5817
5818 (define_insn "*avx_gt<mode>3"
5819   [(set (match_operand:SSEMODE1248 0 "register_operand" "=x")
5820         (gt:SSEMODE1248
5821           (match_operand:SSEMODE1248 1 "register_operand" "x")
5822           (match_operand:SSEMODE1248 2 "nonimmediate_operand" "xm")))]
5823   "TARGET_AVX"
5824   "vpcmpgt<ssevecsize>\t{%2, %1, %0|%0, %1, %2}"
5825   [(set_attr "type" "ssecmp")
5826    (set_attr "prefix" "vex")
5827    (set_attr "mode" "TI")])
5828
5829 (define_insn "sse2_gt<mode>3"
5830   [(set (match_operand:SSEMODE124 0 "register_operand" "=x")
5831         (gt:SSEMODE124
5832           (match_operand:SSEMODE124 1 "register_operand" "0")
5833           (match_operand:SSEMODE124 2 "nonimmediate_operand" "xm")))]
5834   "TARGET_SSE2 && !TARGET_SSE5"
5835   "pcmpgt<ssevecsize>\t{%2, %0|%0, %2}"
5836   [(set_attr "type" "ssecmp")
5837    (set_attr "prefix_data16" "1")
5838    (set_attr "mode" "TI")])
5839
5840 (define_insn "sse4_2_gtv2di3"
5841   [(set (match_operand:V2DI 0 "register_operand" "=x")
5842         (gt:V2DI
5843           (match_operand:V2DI 1 "register_operand" "0")
5844           (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
5845   "TARGET_SSE4_2"
5846   "pcmpgtq\t{%2, %0|%0, %2}"
5847   [(set_attr "type" "ssecmp")
5848    (set_attr "mode" "TI")])
5849
5850 (define_expand "vcond<mode>"
5851   [(set (match_operand:SSEMODEI 0 "register_operand" "")
5852         (if_then_else:SSEMODEI
5853           (match_operator 3 ""
5854             [(match_operand:SSEMODEI 4 "nonimmediate_operand" "")
5855              (match_operand:SSEMODEI 5 "nonimmediate_operand" "")])
5856           (match_operand:SSEMODEI 1 "general_operand" "")
5857           (match_operand:SSEMODEI 2 "general_operand" "")))]
5858   "TARGET_SSE2"
5859 {
5860   if (ix86_expand_int_vcond (operands))
5861     DONE;
5862   else
5863     FAIL;
5864 })
5865
5866 (define_expand "vcondu<mode>"
5867   [(set (match_operand:SSEMODEI 0 "register_operand" "")
5868         (if_then_else:SSEMODEI
5869           (match_operator 3 ""
5870             [(match_operand:SSEMODEI 4 "nonimmediate_operand" "")
5871              (match_operand:SSEMODEI 5 "nonimmediate_operand" "")])
5872           (match_operand:SSEMODEI 1 "general_operand" "")
5873           (match_operand:SSEMODEI 2 "general_operand" "")))]
5874   "TARGET_SSE2"
5875 {
5876   if (ix86_expand_int_vcond (operands))
5877     DONE;
5878   else
5879     FAIL;
5880 })
5881
5882 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5883 ;;
5884 ;; Parallel bitwise logical operations
5885 ;;
5886 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5887
5888 (define_expand "one_cmpl<mode>2"
5889   [(set (match_operand:SSEMODEI 0 "register_operand" "")
5890         (xor:SSEMODEI (match_operand:SSEMODEI 1 "nonimmediate_operand" "")
5891                       (match_dup 2)))]
5892   "TARGET_SSE2"
5893 {
5894   int i, n = GET_MODE_NUNITS (<MODE>mode);
5895   rtvec v = rtvec_alloc (n);
5896
5897   for (i = 0; i < n; ++i)
5898     RTVEC_ELT (v, i) = constm1_rtx;
5899
5900   operands[2] = force_reg (<MODE>mode, gen_rtx_CONST_VECTOR (<MODE>mode, v));
5901 })
5902
5903 (define_insn "*avx_andnot<mode>3"
5904   [(set (match_operand:AVX256MODEI 0 "register_operand" "=x")
5905         (and:AVX256MODEI
5906           (not:AVX256MODEI (match_operand:AVX256MODEI 1 "register_operand" "x"))
5907           (match_operand:AVX256MODEI 2 "nonimmediate_operand" "xm")))]
5908   "TARGET_AVX"
5909   "vandnps\t{%2, %1, %0|%0, %1, %2}"
5910   [(set_attr "type" "sselog")
5911    (set_attr "prefix" "vex")
5912    (set_attr "mode" "<avxvecpsmode>")])
5913
5914 (define_insn "*sse_andnot<mode>3"
5915   [(set (match_operand:SSEMODEI 0 "register_operand" "=x")
5916         (and:SSEMODEI
5917           (not:SSEMODEI (match_operand:SSEMODEI 1 "register_operand" "0"))
5918           (match_operand:SSEMODEI 2 "nonimmediate_operand" "xm")))]
5919   "(TARGET_SSE && !TARGET_SSE2)"
5920   "andnps\t{%2, %0|%0, %2}"
5921   [(set_attr "type" "sselog")
5922    (set_attr "mode" "V4SF")])
5923
5924 (define_insn "*avx_andnot<mode>3"
5925   [(set (match_operand:SSEMODEI 0 "register_operand" "=x")
5926         (and:SSEMODEI
5927           (not:SSEMODEI (match_operand:SSEMODEI 1 "register_operand" "x"))
5928           (match_operand:SSEMODEI 2 "nonimmediate_operand" "xm")))]
5929   "TARGET_AVX"
5930   "vpandn\t{%2, %1, %0|%0, %1, %2}"
5931   [(set_attr "type" "sselog")
5932    (set_attr "prefix" "vex")
5933    (set_attr "mode" "TI")])
5934
5935 (define_insn "sse2_andnot<mode>3"
5936   [(set (match_operand:SSEMODEI 0 "register_operand" "=x")
5937         (and:SSEMODEI
5938           (not:SSEMODEI (match_operand:SSEMODEI 1 "register_operand" "0"))
5939           (match_operand:SSEMODEI 2 "nonimmediate_operand" "xm")))]
5940   "TARGET_SSE2"
5941   "pandn\t{%2, %0|%0, %2}"
5942   [(set_attr "type" "sselog")
5943    (set_attr "prefix_data16" "1")
5944    (set_attr "mode" "TI")])
5945
5946 (define_insn "*andnottf3"
5947   [(set (match_operand:TF 0 "register_operand" "=x")
5948         (and:TF
5949           (not:TF (match_operand:TF 1 "register_operand" "0"))
5950           (match_operand:TF 2 "nonimmediate_operand" "xm")))]
5951   "TARGET_SSE2"
5952   "pandn\t{%2, %0|%0, %2}"
5953   [(set_attr "type" "sselog")
5954    (set_attr "prefix_data16" "1")
5955    (set_attr "mode" "TI")])
5956
5957 (define_expand "<code><mode>3"
5958   [(set (match_operand:SSEMODEI 0 "register_operand" "")
5959         (plogic:SSEMODEI
5960           (match_operand:SSEMODEI 1 "nonimmediate_operand" "")
5961           (match_operand:SSEMODEI 2 "nonimmediate_operand" "")))]
5962   "TARGET_SSE"
5963   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
5964
5965 (define_insn "*avx_<code><mode>3"
5966   [(set (match_operand:AVX256MODEI 0 "register_operand" "=x")
5967         (plogic:AVX256MODEI
5968           (match_operand:AVX256MODEI 1 "nonimmediate_operand" "%x")
5969           (match_operand:AVX256MODEI 2 "nonimmediate_operand" "xm")))]
5970   "TARGET_AVX
5971    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5972   "v<plogicprefix>ps\t{%2, %1, %0|%0, %1, %2}"
5973   [(set_attr "type" "sselog")
5974    (set_attr "prefix" "vex")
5975    (set_attr "mode" "<avxvecpsmode>")])
5976
5977 (define_insn "*sse_<code><mode>3"
5978   [(set (match_operand:SSEMODEI 0 "register_operand" "=x")
5979         (plogic:SSEMODEI
5980           (match_operand:SSEMODEI 1 "nonimmediate_operand" "%0")
5981           (match_operand:SSEMODEI 2 "nonimmediate_operand" "xm")))]
5982   "(TARGET_SSE && !TARGET_SSE2)
5983    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5984   "<plogicprefix>ps\t{%2, %0|%0, %2}"
5985   [(set_attr "type" "sselog")
5986    (set_attr "mode" "V4SF")])
5987
5988 (define_insn "*avx_<code><mode>3"
5989   [(set (match_operand:SSEMODEI 0 "register_operand" "=x")
5990         (plogic:SSEMODEI
5991           (match_operand:SSEMODEI 1 "nonimmediate_operand" "%x")
5992           (match_operand:SSEMODEI 2 "nonimmediate_operand" "xm")))]
5993   "TARGET_AVX
5994    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5995   "vp<plogicprefix>\t{%2, %1, %0|%0, %1, %2}"
5996   [(set_attr "type" "sselog")
5997    (set_attr "prefix" "vex")
5998    (set_attr "mode" "TI")])
5999
6000 (define_insn "*sse2_<code><mode>3"
6001   [(set (match_operand:SSEMODEI 0 "register_operand" "=x")
6002         (plogic:SSEMODEI
6003           (match_operand:SSEMODEI 1 "nonimmediate_operand" "%0")
6004           (match_operand:SSEMODEI 2 "nonimmediate_operand" "xm")))]
6005   "TARGET_SSE2 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6006   "p<plogicprefix>\t{%2, %0|%0, %2}"
6007   [(set_attr "type" "sselog")
6008    (set_attr "prefix_data16" "1")
6009    (set_attr "mode" "TI")])
6010
6011 (define_expand "<code>tf3"
6012   [(set (match_operand:TF 0 "register_operand" "")
6013         (plogic:TF
6014           (match_operand:TF 1 "nonimmediate_operand" "")
6015           (match_operand:TF 2 "nonimmediate_operand" "")))]
6016   "TARGET_SSE2"
6017   "ix86_fixup_binary_operands_no_copy (<CODE>, TFmode, operands);")
6018
6019 (define_insn "*<code>tf3"
6020   [(set (match_operand:TF 0 "register_operand" "=x")
6021         (plogic:TF
6022           (match_operand:TF 1 "nonimmediate_operand" "%0")
6023           (match_operand:TF 2 "nonimmediate_operand" "xm")))]
6024   "TARGET_SSE2 && ix86_binary_operator_ok (<CODE>, TFmode, operands)"
6025   "p<plogicprefix>\t{%2, %0|%0, %2}"
6026   [(set_attr "type" "sselog")
6027    (set_attr "prefix_data16" "1")
6028    (set_attr "mode" "TI")])
6029
6030 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6031 ;;
6032 ;; Parallel integral element swizzling
6033 ;;
6034 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6035
6036 ;; Reduce:
6037 ;;      op1 = abcdefghijklmnop
6038 ;;      op2 = qrstuvwxyz012345
6039 ;;       h1 = aqbrcsdteufvgwhx
6040 ;;       l1 = iyjzk0l1m2n3o4p5
6041 ;;       h2 = aiqybjrzcks0dlt1
6042 ;;       l2 = emu2fnv3gow4hpx5
6043 ;;       h3 = aeimquy2bfjnrvz3
6044 ;;       l3 = cgkosw04dhlptx15
6045 ;;   result = bdfhjlnprtvxz135
6046 (define_expand "vec_pack_trunc_v8hi"
6047   [(match_operand:V16QI 0 "register_operand" "")
6048    (match_operand:V8HI 1 "register_operand" "")
6049    (match_operand:V8HI 2 "register_operand" "")]
6050   "TARGET_SSE2"
6051 {
6052   rtx op1, op2, h1, l1, h2, l2, h3, l3;
6053
6054   if (TARGET_SSE5)
6055     {
6056       ix86_expand_sse5_pack (operands);
6057       DONE;     
6058     }   
6059  
6060   op1 = gen_lowpart (V16QImode, operands[1]);
6061   op2 = gen_lowpart (V16QImode, operands[2]);
6062   h1 = gen_reg_rtx (V16QImode);
6063   l1 = gen_reg_rtx (V16QImode);
6064   h2 = gen_reg_rtx (V16QImode);
6065   l2 = gen_reg_rtx (V16QImode);
6066   h3 = gen_reg_rtx (V16QImode);
6067   l3 = gen_reg_rtx (V16QImode);
6068
6069   emit_insn (gen_vec_interleave_highv16qi (h1, op1, op2));
6070   emit_insn (gen_vec_interleave_lowv16qi (l1, op1, op2));
6071   emit_insn (gen_vec_interleave_highv16qi (h2, l1, h1));
6072   emit_insn (gen_vec_interleave_lowv16qi (l2, l1, h1));
6073   emit_insn (gen_vec_interleave_highv16qi (h3, l2, h2));
6074   emit_insn (gen_vec_interleave_lowv16qi (l3, l2, h2));
6075   emit_insn (gen_vec_interleave_lowv16qi (operands[0], l3, h3));
6076   DONE;
6077 })
6078
6079 ;; Reduce:
6080 ;;      op1 = abcdefgh
6081 ;;      op2 = ijklmnop
6082 ;;       h1 = aibjckdl
6083 ;;       l1 = emfngohp
6084 ;;       h2 = aeimbfjn
6085 ;;       l2 = cgkodhlp
6086 ;;   result = bdfhjlnp
6087 (define_expand "vec_pack_trunc_v4si"
6088   [(match_operand:V8HI 0 "register_operand" "")
6089    (match_operand:V4SI 1 "register_operand" "")
6090    (match_operand:V4SI 2 "register_operand" "")]
6091   "TARGET_SSE2"
6092 {
6093   rtx op1, op2, h1, l1, h2, l2;
6094
6095   if (TARGET_SSE5)
6096     {
6097       ix86_expand_sse5_pack (operands);
6098       DONE;     
6099     }   
6100  
6101   op1 = gen_lowpart (V8HImode, operands[1]);
6102   op2 = gen_lowpart (V8HImode, operands[2]);
6103   h1 = gen_reg_rtx (V8HImode);
6104   l1 = gen_reg_rtx (V8HImode);
6105   h2 = gen_reg_rtx (V8HImode);
6106   l2 = gen_reg_rtx (V8HImode);
6107
6108   emit_insn (gen_vec_interleave_highv8hi (h1, op1, op2));
6109   emit_insn (gen_vec_interleave_lowv8hi (l1, op1, op2));
6110   emit_insn (gen_vec_interleave_highv8hi (h2, l1, h1));
6111   emit_insn (gen_vec_interleave_lowv8hi (l2, l1, h1));
6112   emit_insn (gen_vec_interleave_lowv8hi (operands[0], l2, h2));
6113   DONE;
6114 })
6115
6116 ;; Reduce:
6117 ;;     op1 = abcd
6118 ;;     op2 = efgh
6119 ;;      h1 = aebf
6120 ;;      l1 = cgdh
6121 ;;  result = bdfh
6122 (define_expand "vec_pack_trunc_v2di"
6123   [(match_operand:V4SI 0 "register_operand" "")
6124    (match_operand:V2DI 1 "register_operand" "")
6125    (match_operand:V2DI 2 "register_operand" "")]
6126   "TARGET_SSE2"
6127 {
6128   rtx op1, op2, h1, l1;
6129
6130   if (TARGET_SSE5)
6131     {
6132       ix86_expand_sse5_pack (operands);
6133       DONE;     
6134     }   
6135  
6136   op1 = gen_lowpart (V4SImode, operands[1]);
6137   op2 = gen_lowpart (V4SImode, operands[2]);
6138   h1 = gen_reg_rtx (V4SImode);
6139   l1 = gen_reg_rtx (V4SImode);
6140
6141   emit_insn (gen_vec_interleave_highv4si (h1, op1, op2));
6142   emit_insn (gen_vec_interleave_lowv4si (l1, op1, op2));
6143   emit_insn (gen_vec_interleave_lowv4si (operands[0], l1, h1));
6144   DONE;
6145 })
6146
6147 (define_expand "vec_interleave_highv16qi"
6148   [(set (match_operand:V16QI 0 "register_operand" "")
6149         (vec_select:V16QI
6150           (vec_concat:V32QI
6151             (match_operand:V16QI 1 "register_operand" "")
6152             (match_operand:V16QI 2 "nonimmediate_operand" ""))
6153           (parallel [(const_int 8)  (const_int 24)
6154                      (const_int 9)  (const_int 25)
6155                      (const_int 10) (const_int 26)
6156                      (const_int 11) (const_int 27)
6157                      (const_int 12) (const_int 28)
6158                      (const_int 13) (const_int 29)
6159                      (const_int 14) (const_int 30)
6160                      (const_int 15) (const_int 31)])))]
6161   "TARGET_SSE2"
6162 {
6163   emit_insn (gen_sse2_punpckhbw (operands[0], operands[1], operands[2]));
6164   DONE;
6165 })
6166
6167 (define_expand "vec_interleave_lowv16qi"
6168   [(set (match_operand:V16QI 0 "register_operand" "")
6169         (vec_select:V16QI
6170           (vec_concat:V32QI
6171             (match_operand:V16QI 1 "register_operand" "")
6172             (match_operand:V16QI 2 "nonimmediate_operand" ""))
6173           (parallel [(const_int 0) (const_int 16)
6174                      (const_int 1) (const_int 17)
6175                      (const_int 2) (const_int 18)
6176                      (const_int 3) (const_int 19)
6177                      (const_int 4) (const_int 20)
6178                      (const_int 5) (const_int 21)
6179                      (const_int 6) (const_int 22)
6180                      (const_int 7) (const_int 23)])))]
6181   "TARGET_SSE2"
6182 {
6183   emit_insn (gen_sse2_punpcklbw (operands[0], operands[1], operands[2]));
6184   DONE;
6185 })
6186
6187 (define_expand "vec_interleave_highv8hi"
6188   [(set (match_operand:V8HI 0 "register_operand" "=")
6189         (vec_select:V8HI
6190           (vec_concat:V16HI
6191             (match_operand:V8HI 1 "register_operand" "")
6192             (match_operand:V8HI 2 "nonimmediate_operand" ""))
6193           (parallel [(const_int 4) (const_int 12)
6194                      (const_int 5) (const_int 13)
6195                      (const_int 6) (const_int 14)
6196                      (const_int 7) (const_int 15)])))]
6197   "TARGET_SSE2"
6198 {
6199   emit_insn (gen_sse2_punpckhwd (operands[0], operands[1], operands[2]));
6200   DONE;
6201 })
6202
6203 (define_expand "vec_interleave_lowv8hi"
6204   [(set (match_operand:V8HI 0 "register_operand" "")
6205         (vec_select:V8HI
6206           (vec_concat:V16HI
6207             (match_operand:V8HI 1 "register_operand" "")
6208             (match_operand:V8HI 2 "nonimmediate_operand" ""))
6209           (parallel [(const_int 0) (const_int 8)
6210                      (const_int 1) (const_int 9)
6211                      (const_int 2) (const_int 10)
6212                      (const_int 3) (const_int 11)])))]
6213   "TARGET_SSE2"
6214 {
6215   emit_insn (gen_sse2_punpcklwd (operands[0], operands[1], operands[2]));
6216   DONE;
6217 })
6218
6219 (define_expand "vec_interleave_highv4si"
6220   [(set (match_operand:V4SI 0 "register_operand" "")
6221         (vec_select:V4SI
6222           (vec_concat:V8SI
6223             (match_operand:V4SI 1 "register_operand" "")
6224             (match_operand:V4SI 2 "nonimmediate_operand" ""))
6225           (parallel [(const_int 2) (const_int 6)
6226                      (const_int 3) (const_int 7)])))]
6227   "TARGET_SSE2"
6228 {
6229   emit_insn (gen_sse2_punpckhdq (operands[0], operands[1], operands[2]));
6230   DONE;
6231 })
6232
6233 (define_expand "vec_interleave_lowv4si"
6234   [(set (match_operand:V4SI 0 "register_operand" "")
6235         (vec_select:V4SI
6236           (vec_concat:V8SI
6237             (match_operand:V4SI 1 "register_operand" "")
6238             (match_operand:V4SI 2 "nonimmediate_operand" ""))
6239           (parallel [(const_int 0) (const_int 4)
6240                      (const_int 1) (const_int 5)])))]
6241   "TARGET_SSE2"
6242 {
6243   emit_insn (gen_sse2_punpckldq (operands[0], operands[1], operands[2]));
6244   DONE;
6245 })
6246
6247 (define_expand "vec_interleave_highv2di"
6248   [(set (match_operand:V2DI 0 "register_operand" "")
6249         (vec_select:V2DI
6250           (vec_concat:V4DI
6251             (match_operand:V2DI 1 "register_operand" "")
6252             (match_operand:V2DI 2 "nonimmediate_operand" ""))
6253           (parallel [(const_int 1)
6254                      (const_int 3)])))]
6255   "TARGET_SSE2"
6256 {
6257   emit_insn (gen_sse2_punpckhqdq (operands[0], operands[1], operands[2]));
6258   DONE;
6259 })
6260
6261 (define_expand "vec_interleave_lowv2di"
6262   [(set (match_operand:V2DI 0 "register_operand" "")
6263         (vec_select:V2DI
6264           (vec_concat:V4DI
6265             (match_operand:V2DI 1 "register_operand" "")
6266             (match_operand:V2DI 2 "nonimmediate_operand" ""))
6267           (parallel [(const_int 0)
6268                      (const_int 2)])))]
6269   "TARGET_SSE2"
6270 {
6271   emit_insn (gen_sse2_punpcklqdq (operands[0], operands[1], operands[2]));
6272   DONE;
6273 })
6274
6275 (define_expand "vec_interleave_highv4sf"
6276   [(set (match_operand:V4SF 0 "register_operand" "")
6277         (vec_select:V4SF
6278           (vec_concat:V8SF
6279             (match_operand:V4SF 1 "register_operand" "")
6280             (match_operand:V4SF 2 "nonimmediate_operand" ""))
6281           (parallel [(const_int 2) (const_int 6)
6282                      (const_int 3) (const_int 7)])))]
6283   "TARGET_SSE")
6284
6285 (define_expand "vec_interleave_lowv4sf"
6286   [(set (match_operand:V4SF 0 "register_operand" "")
6287         (vec_select:V4SF
6288           (vec_concat:V8SF
6289             (match_operand:V4SF 1 "register_operand" "")
6290             (match_operand:V4SF 2 "nonimmediate_operand" ""))
6291           (parallel [(const_int 0) (const_int 4)
6292                      (const_int 1) (const_int 5)])))]
6293   "TARGET_SSE")
6294
6295 (define_expand "vec_interleave_highv2df"
6296   [(set (match_operand:V2DF 0 "register_operand" "")
6297         (vec_select:V2DF
6298           (vec_concat:V4DF
6299             (match_operand:V2DF 1 "register_operand" "")
6300             (match_operand:V2DF 2 "nonimmediate_operand" ""))
6301           (parallel [(const_int 1)
6302                      (const_int 3)])))]
6303   "TARGET_SSE2")
6304
6305 (define_expand "vec_interleave_lowv2df"
6306   [(set (match_operand:V2DF 0 "register_operand" "")
6307         (vec_select:V2DF
6308           (vec_concat:V4DF
6309             (match_operand:V2DF 1 "register_operand" "")
6310             (match_operand:V2DF 2 "nonimmediate_operand" ""))
6311           (parallel [(const_int 0)
6312                      (const_int 2)])))]
6313   "TARGET_SSE2")
6314
6315 (define_insn "*avx_packsswb"
6316   [(set (match_operand:V16QI 0 "register_operand" "=x")
6317         (vec_concat:V16QI
6318           (ss_truncate:V8QI
6319             (match_operand:V8HI 1 "register_operand" "x"))
6320           (ss_truncate:V8QI
6321             (match_operand:V8HI 2 "nonimmediate_operand" "xm"))))]
6322   "TARGET_AVX"
6323   "vpacksswb\t{%2, %1, %0|%0, %1, %2}"
6324   [(set_attr "type" "sselog")
6325    (set_attr "prefix" "vex")
6326    (set_attr "mode" "TI")])
6327
6328 (define_insn "sse2_packsswb"
6329   [(set (match_operand:V16QI 0 "register_operand" "=x")
6330         (vec_concat:V16QI
6331           (ss_truncate:V8QI
6332             (match_operand:V8HI 1 "register_operand" "0"))
6333           (ss_truncate:V8QI
6334             (match_operand:V8HI 2 "nonimmediate_operand" "xm"))))]
6335   "TARGET_SSE2"
6336   "packsswb\t{%2, %0|%0, %2}"
6337   [(set_attr "type" "sselog")
6338    (set_attr "prefix_data16" "1")
6339    (set_attr "mode" "TI")])
6340
6341 (define_insn "*avx_packssdw"
6342   [(set (match_operand:V8HI 0 "register_operand" "=x")
6343         (vec_concat:V8HI
6344           (ss_truncate:V4HI
6345             (match_operand:V4SI 1 "register_operand" "x"))
6346           (ss_truncate:V4HI
6347             (match_operand:V4SI 2 "nonimmediate_operand" "xm"))))]
6348   "TARGET_AVX"
6349   "vpackssdw\t{%2, %1, %0|%0, %1, %2}"
6350   [(set_attr "type" "sselog")
6351    (set_attr "prefix" "vex")
6352    (set_attr "mode" "TI")])
6353
6354 (define_insn "sse2_packssdw"
6355   [(set (match_operand:V8HI 0 "register_operand" "=x")
6356         (vec_concat:V8HI
6357           (ss_truncate:V4HI
6358             (match_operand:V4SI 1 "register_operand" "0"))
6359           (ss_truncate:V4HI
6360             (match_operand:V4SI 2 "nonimmediate_operand" "xm"))))]
6361   "TARGET_SSE2"
6362   "packssdw\t{%2, %0|%0, %2}"
6363   [(set_attr "type" "sselog")
6364    (set_attr "prefix_data16" "1")
6365    (set_attr "mode" "TI")])
6366
6367 (define_insn "*avx_packuswb"
6368   [(set (match_operand:V16QI 0 "register_operand" "=x")
6369         (vec_concat:V16QI
6370           (us_truncate:V8QI
6371             (match_operand:V8HI 1 "register_operand" "x"))
6372           (us_truncate:V8QI
6373             (match_operand:V8HI 2 "nonimmediate_operand" "xm"))))]
6374   "TARGET_AVX"
6375   "vpackuswb\t{%2, %1, %0|%0, %1, %2}"
6376   [(set_attr "type" "sselog")
6377    (set_attr "prefix" "vex")
6378    (set_attr "mode" "TI")])
6379
6380 (define_insn "sse2_packuswb"
6381   [(set (match_operand:V16QI 0 "register_operand" "=x")
6382         (vec_concat:V16QI
6383           (us_truncate:V8QI
6384             (match_operand:V8HI 1 "register_operand" "0"))
6385           (us_truncate:V8QI
6386             (match_operand:V8HI 2 "nonimmediate_operand" "xm"))))]
6387   "TARGET_SSE2"
6388   "packuswb\t{%2, %0|%0, %2}"
6389   [(set_attr "type" "sselog")
6390    (set_attr "prefix_data16" "1")
6391    (set_attr "mode" "TI")])
6392
6393 (define_insn "*avx_punpckhbw"
6394   [(set (match_operand:V16QI 0 "register_operand" "=x")
6395         (vec_select:V16QI
6396           (vec_concat:V32QI
6397             (match_operand:V16QI 1 "register_operand" "x")
6398             (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
6399           (parallel [(const_int 8)  (const_int 24)
6400                      (const_int 9)  (const_int 25)
6401                      (const_int 10) (const_int 26)
6402                      (const_int 11) (const_int 27)
6403                      (const_int 12) (const_int 28)
6404                      (const_int 13) (const_int 29)
6405                      (const_int 14) (const_int 30)
6406                      (const_int 15) (const_int 31)])))]
6407   "TARGET_AVX"
6408   "vpunpckhbw\t{%2, %1, %0|%0, %1, %2}"
6409   [(set_attr "type" "sselog")
6410    (set_attr "prefix" "vex")
6411    (set_attr "mode" "TI")])
6412
6413 (define_insn "sse2_punpckhbw"
6414   [(set (match_operand:V16QI 0 "register_operand" "=x")
6415         (vec_select:V16QI
6416           (vec_concat:V32QI
6417             (match_operand:V16QI 1 "register_operand" "0")
6418             (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
6419           (parallel [(const_int 8)  (const_int 24)
6420                      (const_int 9)  (const_int 25)
6421                      (const_int 10) (const_int 26)
6422                      (const_int 11) (const_int 27)
6423                      (const_int 12) (const_int 28)
6424                      (const_int 13) (const_int 29)
6425                      (const_int 14) (const_int 30)
6426                      (const_int 15) (const_int 31)])))]
6427   "TARGET_SSE2"
6428   "punpckhbw\t{%2, %0|%0, %2}"
6429   [(set_attr "type" "sselog")
6430    (set_attr "prefix_data16" "1")
6431    (set_attr "mode" "TI")])
6432
6433 (define_insn "*avx_punpcklbw"
6434   [(set (match_operand:V16QI 0 "register_operand" "=x")
6435         (vec_select:V16QI
6436           (vec_concat:V32QI
6437             (match_operand:V16QI 1 "register_operand" "x")
6438             (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
6439           (parallel [(const_int 0) (const_int 16)
6440                      (const_int 1) (const_int 17)
6441                      (const_int 2) (const_int 18)
6442                      (const_int 3) (const_int 19)
6443                      (const_int 4) (const_int 20)
6444                      (const_int 5) (const_int 21)
6445                      (const_int 6) (const_int 22)
6446                      (const_int 7) (const_int 23)])))]
6447   "TARGET_AVX"
6448   "vpunpcklbw\t{%2, %1, %0|%0, %1, %2}"
6449   [(set_attr "type" "sselog")
6450    (set_attr "prefix" "vex")
6451    (set_attr "mode" "TI")])
6452
6453 (define_insn "sse2_punpcklbw"
6454   [(set (match_operand:V16QI 0 "register_operand" "=x")
6455         (vec_select:V16QI
6456           (vec_concat:V32QI
6457             (match_operand:V16QI 1 "register_operand" "0")
6458             (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
6459           (parallel [(const_int 0) (const_int 16)
6460                      (const_int 1) (const_int 17)
6461                      (const_int 2) (const_int 18)
6462                      (const_int 3) (const_int 19)
6463                      (const_int 4) (const_int 20)
6464                      (const_int 5) (const_int 21)
6465                      (const_int 6) (const_int 22)
6466                      (const_int 7) (const_int 23)])))]
6467   "TARGET_SSE2"
6468   "punpcklbw\t{%2, %0|%0, %2}"
6469   [(set_attr "type" "sselog")
6470    (set_attr "prefix_data16" "1")
6471    (set_attr "mode" "TI")])
6472
6473 (define_insn "*avx_punpckhwd"
6474   [(set (match_operand:V8HI 0 "register_operand" "=x")
6475         (vec_select:V8HI
6476           (vec_concat:V16HI
6477             (match_operand:V8HI 1 "register_operand" "x")
6478             (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
6479           (parallel [(const_int 4) (const_int 12)
6480                      (const_int 5) (const_int 13)
6481                      (const_int 6) (const_int 14)
6482                      (const_int 7) (const_int 15)])))]
6483   "TARGET_AVX"
6484   "vpunpckhwd\t{%2, %1, %0|%0, %1, %2}"
6485   [(set_attr "type" "sselog")
6486    (set_attr "prefix" "vex")
6487    (set_attr "mode" "TI")])
6488
6489 (define_insn "sse2_punpckhwd"
6490   [(set (match_operand:V8HI 0 "register_operand" "=x")
6491         (vec_select:V8HI
6492           (vec_concat:V16HI
6493             (match_operand:V8HI 1 "register_operand" "0")
6494             (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
6495           (parallel [(const_int 4) (const_int 12)
6496                      (const_int 5) (const_int 13)
6497                      (const_int 6) (const_int 14)
6498                      (const_int 7) (const_int 15)])))]
6499   "TARGET_SSE2"
6500   "punpckhwd\t{%2, %0|%0, %2}"
6501   [(set_attr "type" "sselog")
6502    (set_attr "prefix_data16" "1")
6503    (set_attr "mode" "TI")])
6504
6505 (define_insn "*avx_punpcklwd"
6506   [(set (match_operand:V8HI 0 "register_operand" "=x")
6507         (vec_select:V8HI
6508           (vec_concat:V16HI
6509             (match_operand:V8HI 1 "register_operand" "x")
6510             (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
6511           (parallel [(const_int 0) (const_int 8)
6512                      (const_int 1) (const_int 9)
6513                      (const_int 2) (const_int 10)
6514                      (const_int 3) (const_int 11)])))]
6515   "TARGET_AVX"
6516   "vpunpcklwd\t{%2, %1, %0|%0, %1, %2}"
6517   [(set_attr "type" "sselog")
6518    (set_attr "prefix" "vex")
6519    (set_attr "mode" "TI")])
6520
6521 (define_insn "sse2_punpcklwd"
6522   [(set (match_operand:V8HI 0 "register_operand" "=x")
6523         (vec_select:V8HI
6524           (vec_concat:V16HI
6525             (match_operand:V8HI 1 "register_operand" "0")
6526             (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
6527           (parallel [(const_int 0) (const_int 8)
6528                      (const_int 1) (const_int 9)
6529                      (const_int 2) (const_int 10)
6530                      (const_int 3) (const_int 11)])))]
6531   "TARGET_SSE2"
6532   "punpcklwd\t{%2, %0|%0, %2}"
6533   [(set_attr "type" "sselog")
6534    (set_attr "prefix_data16" "1")
6535    (set_attr "mode" "TI")])
6536
6537 (define_insn "*avx_punpckhdq"
6538   [(set (match_operand:V4SI 0 "register_operand" "=x")
6539         (vec_select:V4SI
6540           (vec_concat:V8SI
6541             (match_operand:V4SI 1 "register_operand" "x")
6542             (match_operand:V4SI 2 "nonimmediate_operand" "xm"))
6543           (parallel [(const_int 2) (const_int 6)
6544                      (const_int 3) (const_int 7)])))]
6545   "TARGET_AVX"
6546   "vpunpckhdq\t{%2, %1, %0|%0, %1, %2}"
6547   [(set_attr "type" "sselog")
6548    (set_attr "prefix" "vex")
6549    (set_attr "mode" "TI")])
6550
6551 (define_insn "sse2_punpckhdq"
6552   [(set (match_operand:V4SI 0 "register_operand" "=x")
6553         (vec_select:V4SI
6554           (vec_concat:V8SI
6555             (match_operand:V4SI 1 "register_operand" "0")
6556             (match_operand:V4SI 2 "nonimmediate_operand" "xm"))
6557           (parallel [(const_int 2) (const_int 6)
6558                      (const_int 3) (const_int 7)])))]
6559   "TARGET_SSE2"
6560   "punpckhdq\t{%2, %0|%0, %2}"
6561   [(set_attr "type" "sselog")
6562    (set_attr "prefix_data16" "1")
6563    (set_attr "mode" "TI")])
6564
6565 (define_insn "*avx_punpckldq"
6566   [(set (match_operand:V4SI 0 "register_operand" "=x")
6567         (vec_select:V4SI
6568           (vec_concat:V8SI
6569             (match_operand:V4SI 1 "register_operand" "x")
6570             (match_operand:V4SI 2 "nonimmediate_operand" "xm"))
6571           (parallel [(const_int 0) (const_int 4)
6572                      (const_int 1) (const_int 5)])))]
6573   "TARGET_AVX"
6574   "vpunpckldq\t{%2, %1, %0|%0, %1, %2}"
6575   [(set_attr "type" "sselog")
6576    (set_attr "prefix" "vex")
6577    (set_attr "mode" "TI")])
6578
6579 (define_insn "sse2_punpckldq"
6580   [(set (match_operand:V4SI 0 "register_operand" "=x")
6581         (vec_select:V4SI
6582           (vec_concat:V8SI
6583             (match_operand:V4SI 1 "register_operand" "0")
6584             (match_operand:V4SI 2 "nonimmediate_operand" "xm"))
6585           (parallel [(const_int 0) (const_int 4)
6586                      (const_int 1) (const_int 5)])))]
6587   "TARGET_SSE2"
6588   "punpckldq\t{%2, %0|%0, %2}"
6589   [(set_attr "type" "sselog")
6590    (set_attr "prefix_data16" "1")
6591    (set_attr "mode" "TI")])
6592
6593 (define_insn "*avx_pinsr<ssevecsize>"
6594   [(set (match_operand:SSEMODE124 0 "register_operand" "=x")
6595         (vec_merge:SSEMODE124
6596           (vec_duplicate:SSEMODE124
6597             (match_operand:<avxscalarmode> 2 "nonimmediate_operand" "rm"))
6598           (match_operand:SSEMODE124 1 "register_operand" "x")
6599           (match_operand:SI 3 "const_pow2_1_to_<pinsrbits>_operand" "n")))]
6600   "TARGET_AVX"
6601 {
6602   operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
6603   return "vpinsr<ssevecsize>\t{%3, %k2, %1, %0|%0, %1, %k2, %3}";
6604 }
6605   [(set_attr "type" "sselog")
6606    (set_attr "prefix" "vex")
6607    (set_attr "mode" "TI")])
6608
6609 (define_insn "*sse4_1_pinsrb"
6610   [(set (match_operand:V16QI 0 "register_operand" "=x")
6611         (vec_merge:V16QI
6612           (vec_duplicate:V16QI
6613             (match_operand:QI 2 "nonimmediate_operand" "rm"))
6614           (match_operand:V16QI 1 "register_operand" "0")
6615           (match_operand:SI 3 "const_pow2_1_to_32768_operand" "n")))]
6616   "TARGET_SSE4_1"
6617 {
6618   operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
6619   return "pinsrb\t{%3, %k2, %0|%0, %k2, %3}";
6620 }
6621   [(set_attr "type" "sselog")
6622    (set_attr "prefix_extra" "1")
6623    (set_attr "mode" "TI")])
6624
6625 (define_insn "*sse2_pinsrw"
6626   [(set (match_operand:V8HI 0 "register_operand" "=x")
6627         (vec_merge:V8HI
6628           (vec_duplicate:V8HI
6629             (match_operand:HI 2 "nonimmediate_operand" "rm"))
6630           (match_operand:V8HI 1 "register_operand" "0")
6631           (match_operand:SI 3 "const_pow2_1_to_128_operand" "n")))]
6632   "TARGET_SSE2"
6633 {
6634   operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
6635   return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}";
6636 }
6637   [(set_attr "type" "sselog")
6638    (set_attr "prefix_data16" "1")
6639    (set_attr "mode" "TI")])
6640
6641 ;; It must come before sse2_loadld since it is preferred.
6642 (define_insn "*sse4_1_pinsrd"
6643   [(set (match_operand:V4SI 0 "register_operand" "=x")
6644         (vec_merge:V4SI
6645           (vec_duplicate:V4SI
6646             (match_operand:SI 2 "nonimmediate_operand" "rm"))
6647           (match_operand:V4SI 1 "register_operand" "0")
6648           (match_operand:SI 3 "const_pow2_1_to_8_operand" "n")))]
6649   "TARGET_SSE4_1"
6650 {
6651   operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
6652   return "pinsrd\t{%3, %2, %0|%0, %2, %3}";
6653 }
6654   [(set_attr "type" "sselog")
6655    (set_attr "prefix_extra" "1")
6656    (set_attr "mode" "TI")])
6657
6658 (define_insn "*avx_pinsrq"
6659   [(set (match_operand:V2DI 0 "register_operand" "=x")
6660         (vec_merge:V2DI
6661           (vec_duplicate:V2DI
6662             (match_operand:DI 2 "nonimmediate_operand" "rm"))
6663           (match_operand:V2DI 1 "register_operand" "x")
6664           (match_operand:SI 3 "const_pow2_1_to_2_operand" "n")))]
6665   "TARGET_AVX && TARGET_64BIT"
6666 {
6667   operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
6668   return "vpinsrq\t{%3, %2, %1, %0|%0, %1, %2, %3}";
6669 }
6670   [(set_attr "type" "sselog")
6671    (set_attr "prefix" "vex")
6672    (set_attr "mode" "TI")])
6673
6674 (define_insn "*sse4_1_pinsrq"
6675   [(set (match_operand:V2DI 0 "register_operand" "=x")
6676         (vec_merge:V2DI
6677           (vec_duplicate:V2DI
6678             (match_operand:DI 2 "nonimmediate_operand" "rm"))
6679           (match_operand:V2DI 1 "register_operand" "0")
6680           (match_operand:SI 3 "const_pow2_1_to_2_operand" "n")))]
6681   "TARGET_SSE4_1 && TARGET_64BIT"
6682 {
6683   operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
6684   return "pinsrq\t{%3, %2, %0|%0, %2, %3}";
6685 }
6686   [(set_attr "type" "sselog")
6687    (set_attr "prefix_extra" "1")
6688    (set_attr "mode" "TI")])
6689
6690 (define_insn "*sse4_1_pextrb"
6691   [(set (match_operand:SI 0 "register_operand" "=r")
6692         (zero_extend:SI
6693           (vec_select:QI
6694             (match_operand:V16QI 1 "register_operand" "x")
6695             (parallel [(match_operand:SI 2 "const_0_to_15_operand" "n")]))))]
6696   "TARGET_SSE4_1"
6697   "%vpextrb\t{%2, %1, %0|%0, %1, %2}"
6698   [(set_attr "type" "sselog")
6699    (set_attr "prefix_extra" "1")
6700    (set_attr "prefix" "maybe_vex")
6701    (set_attr "mode" "TI")])
6702
6703 (define_insn "*sse4_1_pextrb_memory"
6704   [(set (match_operand:QI 0 "memory_operand" "=m")
6705         (vec_select:QI
6706           (match_operand:V16QI 1 "register_operand" "x")
6707           (parallel [(match_operand:SI 2 "const_0_to_15_operand" "n")])))]
6708   "TARGET_SSE4_1"
6709   "%vpextrb\t{%2, %1, %0|%0, %1, %2}"
6710   [(set_attr "type" "sselog")
6711    (set_attr "prefix_extra" "1")
6712    (set_attr "prefix" "maybe_vex")
6713    (set_attr "mode" "TI")])
6714
6715 (define_insn "*sse2_pextrw"
6716   [(set (match_operand:SI 0 "register_operand" "=r")
6717         (zero_extend:SI
6718           (vec_select:HI
6719             (match_operand:V8HI 1 "register_operand" "x")
6720             (parallel [(match_operand:SI 2 "const_0_to_7_operand" "n")]))))]
6721   "TARGET_SSE2"
6722   "%vpextrw\t{%2, %1, %0|%0, %1, %2}"
6723   [(set_attr "type" "sselog")
6724    (set_attr "prefix_data16" "1")
6725    (set_attr "prefix" "maybe_vex")
6726    (set_attr "mode" "TI")])
6727
6728 (define_insn "*sse4_1_pextrw_memory"
6729   [(set (match_operand:HI 0 "memory_operand" "=m")
6730         (vec_select:HI
6731           (match_operand:V8HI 1 "register_operand" "x")
6732           (parallel [(match_operand:SI 2 "const_0_to_7_operand" "n")])))]
6733   "TARGET_SSE4_1"
6734   "%vpextrw\t{%2, %1, %0|%0, %1, %2}"
6735   [(set_attr "type" "sselog")
6736    (set_attr "prefix_extra" "1")
6737    (set_attr "prefix" "maybe_vex")
6738    (set_attr "mode" "TI")])
6739
6740 (define_insn "*sse4_1_pextrd"
6741   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
6742         (vec_select:SI
6743           (match_operand:V4SI 1 "register_operand" "x")
6744           (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n")])))]
6745   "TARGET_SSE4_1"
6746   "%vpextrd\t{%2, %1, %0|%0, %1, %2}"
6747   [(set_attr "type" "sselog")
6748    (set_attr "prefix_extra" "1")
6749    (set_attr "prefix" "maybe_vex")
6750    (set_attr "mode" "TI")])
6751
6752 ;; It must come before *vec_extractv2di_1_sse since it is preferred.
6753 (define_insn "*sse4_1_pextrq"
6754   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
6755         (vec_select:DI
6756           (match_operand:V2DI 1 "register_operand" "x")
6757           (parallel [(match_operand:SI 2 "const_0_to_1_operand" "n")])))]
6758   "TARGET_SSE4_1 && TARGET_64BIT"
6759   "%vpextrq\t{%2, %1, %0|%0, %1, %2}"
6760   [(set_attr "type" "sselog")
6761    (set_attr "prefix_extra" "1")
6762    (set_attr "prefix" "maybe_vex")
6763    (set_attr "mode" "TI")])
6764
6765 (define_expand "sse2_pshufd"
6766   [(match_operand:V4SI 0 "register_operand" "")
6767    (match_operand:V4SI 1 "nonimmediate_operand" "")
6768    (match_operand:SI 2 "const_int_operand" "")]
6769   "TARGET_SSE2"
6770 {
6771   int mask = INTVAL (operands[2]);
6772   emit_insn (gen_sse2_pshufd_1 (operands[0], operands[1],
6773                                 GEN_INT ((mask >> 0) & 3),
6774                                 GEN_INT ((mask >> 2) & 3),
6775                                 GEN_INT ((mask >> 4) & 3),
6776                                 GEN_INT ((mask >> 6) & 3)));
6777   DONE;
6778 })
6779
6780 (define_insn "sse2_pshufd_1"
6781   [(set (match_operand:V4SI 0 "register_operand" "=x")
6782         (vec_select:V4SI
6783           (match_operand:V4SI 1 "nonimmediate_operand" "xm")
6784           (parallel [(match_operand 2 "const_0_to_3_operand" "")
6785                      (match_operand 3 "const_0_to_3_operand" "")
6786                      (match_operand 4 "const_0_to_3_operand" "")
6787                      (match_operand 5 "const_0_to_3_operand" "")])))]
6788   "TARGET_SSE2"
6789 {
6790   int mask = 0;
6791   mask |= INTVAL (operands[2]) << 0;
6792   mask |= INTVAL (operands[3]) << 2;
6793   mask |= INTVAL (operands[4]) << 4;
6794   mask |= INTVAL (operands[5]) << 6;
6795   operands[2] = GEN_INT (mask);
6796
6797   return "%vpshufd\t{%2, %1, %0|%0, %1, %2}";
6798 }
6799   [(set_attr "type" "sselog1")
6800    (set_attr "prefix_data16" "1")
6801    (set_attr "prefix" "vex")
6802    (set_attr "mode" "TI")])
6803
6804 (define_expand "sse2_pshuflw"
6805   [(match_operand:V8HI 0 "register_operand" "")
6806    (match_operand:V8HI 1 "nonimmediate_operand" "")
6807    (match_operand:SI 2 "const_int_operand" "")]
6808   "TARGET_SSE2"
6809 {
6810   int mask = INTVAL (operands[2]);
6811   emit_insn (gen_sse2_pshuflw_1 (operands[0], operands[1],
6812                                  GEN_INT ((mask >> 0) & 3),
6813                                  GEN_INT ((mask >> 2) & 3),
6814                                  GEN_INT ((mask >> 4) & 3),
6815                                  GEN_INT ((mask >> 6) & 3)));
6816   DONE;
6817 })
6818
6819 (define_insn "sse2_pshuflw_1"
6820   [(set (match_operand:V8HI 0 "register_operand" "=x")
6821         (vec_select:V8HI
6822           (match_operand:V8HI 1 "nonimmediate_operand" "xm")
6823           (parallel [(match_operand 2 "const_0_to_3_operand" "")
6824                      (match_operand 3 "const_0_to_3_operand" "")
6825                      (match_operand 4 "const_0_to_3_operand" "")
6826                      (match_operand 5 "const_0_to_3_operand" "")
6827                      (const_int 4)
6828                      (const_int 5)
6829                      (const_int 6)
6830                      (const_int 7)])))]
6831   "TARGET_SSE2"
6832 {
6833   int mask = 0;
6834   mask |= INTVAL (operands[2]) << 0;
6835   mask |= INTVAL (operands[3]) << 2;
6836   mask |= INTVAL (operands[4]) << 4;
6837   mask |= INTVAL (operands[5]) << 6;
6838   operands[2] = GEN_INT (mask);
6839
6840   return "%vpshuflw\t{%2, %1, %0|%0, %1, %2}";
6841 }
6842   [(set_attr "type" "sselog")
6843    (set_attr "prefix_rep" "1")
6844    (set_attr "prefix" "maybe_vex")
6845    (set_attr "mode" "TI")])
6846
6847 (define_expand "sse2_pshufhw"
6848   [(match_operand:V8HI 0 "register_operand" "")
6849    (match_operand:V8HI 1 "nonimmediate_operand" "")
6850    (match_operand:SI 2 "const_int_operand" "")]
6851   "TARGET_SSE2"
6852 {
6853   int mask = INTVAL (operands[2]);
6854   emit_insn (gen_sse2_pshufhw_1 (operands[0], operands[1],
6855                                  GEN_INT (((mask >> 0) & 3) + 4),
6856                                  GEN_INT (((mask >> 2) & 3) + 4),
6857                                  GEN_INT (((mask >> 4) & 3) + 4),
6858                                  GEN_INT (((mask >> 6) & 3) + 4)));
6859   DONE;
6860 })
6861
6862 (define_insn "sse2_pshufhw_1"
6863   [(set (match_operand:V8HI 0 "register_operand" "=x")
6864         (vec_select:V8HI
6865           (match_operand:V8HI 1 "nonimmediate_operand" "xm")
6866           (parallel [(const_int 0)
6867                      (const_int 1)
6868                      (const_int 2)
6869                      (const_int 3)
6870                      (match_operand 2 "const_4_to_7_operand" "")
6871                      (match_operand 3 "const_4_to_7_operand" "")
6872                      (match_operand 4 "const_4_to_7_operand" "")
6873                      (match_operand 5 "const_4_to_7_operand" "")])))]
6874   "TARGET_SSE2"
6875 {
6876   int mask = 0;
6877   mask |= (INTVAL (operands[2]) - 4) << 0;
6878   mask |= (INTVAL (operands[3]) - 4) << 2;
6879   mask |= (INTVAL (operands[4]) - 4) << 4;
6880   mask |= (INTVAL (operands[5]) - 4) << 6;
6881   operands[2] = GEN_INT (mask);
6882
6883   return "%vpshufhw\t{%2, %1, %0|%0, %1, %2}";
6884 }
6885   [(set_attr "type" "sselog")
6886    (set_attr "prefix_rep" "1")
6887    (set_attr "prefix" "maybe_vex")
6888    (set_attr "mode" "TI")])
6889
6890 (define_expand "sse2_loadd"
6891   [(set (match_operand:V4SI 0 "register_operand" "")
6892         (vec_merge:V4SI
6893           (vec_duplicate:V4SI
6894             (match_operand:SI 1 "nonimmediate_operand" ""))
6895           (match_dup 2)
6896           (const_int 1)))]
6897   "TARGET_SSE"
6898   "operands[2] = CONST0_RTX (V4SImode);")
6899
6900 (define_insn "*avx_loadld"
6901   [(set (match_operand:V4SI 0 "register_operand"       "=x,Yi,x")
6902         (vec_merge:V4SI
6903           (vec_duplicate:V4SI
6904             (match_operand:SI 2 "nonimmediate_operand" "m ,r ,x"))
6905           (match_operand:V4SI 1 "reg_or_0_operand"     "C ,C ,x")
6906           (const_int 1)))]
6907   "TARGET_AVX"
6908   "@
6909    vmovd\t{%2, %0|%0, %2}
6910    vmovd\t{%2, %0|%0, %2}
6911    vmovss\t{%2, %1, %0|%0, %1, %2}"
6912   [(set_attr "type" "ssemov")
6913    (set_attr "prefix" "vex")
6914    (set_attr "mode" "TI,TI,V4SF")])
6915
6916 (define_insn "sse2_loadld"
6917   [(set (match_operand:V4SI 0 "register_operand"       "=Y2,Yi,x,x")
6918         (vec_merge:V4SI
6919           (vec_duplicate:V4SI
6920             (match_operand:SI 2 "nonimmediate_operand" "m  ,r ,m,x"))
6921           (match_operand:V4SI 1 "reg_or_0_operand"     "C  ,C ,C,0")
6922           (const_int 1)))]
6923   "TARGET_SSE"
6924   "@
6925    movd\t{%2, %0|%0, %2}
6926    movd\t{%2, %0|%0, %2}
6927    movss\t{%2, %0|%0, %2}
6928    movss\t{%2, %0|%0, %2}"
6929   [(set_attr "type" "ssemov")
6930    (set_attr "mode" "TI,TI,V4SF,SF")])
6931
6932 (define_insn_and_split "sse2_stored"
6933   [(set (match_operand:SI 0 "nonimmediate_operand" "=mx,r")
6934         (vec_select:SI
6935           (match_operand:V4SI 1 "register_operand" "x,Yi")
6936           (parallel [(const_int 0)])))]
6937   "TARGET_SSE"
6938   "#"
6939   "&& reload_completed
6940    && (TARGET_INTER_UNIT_MOVES
6941        || MEM_P (operands [0])
6942        || !GENERAL_REGNO_P (true_regnum (operands [0])))"
6943   [(set (match_dup 0) (match_dup 1))]
6944 {
6945   operands[1] = gen_rtx_REG (SImode, REGNO (operands[1]));
6946 })
6947
6948 (define_insn_and_split "*vec_ext_v4si_mem"
6949   [(set (match_operand:SI 0 "register_operand" "=r")
6950         (vec_select:SI
6951           (match_operand:V4SI 1 "memory_operand" "o")
6952           (parallel [(match_operand 2 "const_0_to_3_operand" "")])))]
6953   ""
6954   "#"
6955   "reload_completed"
6956   [(const_int 0)]
6957 {
6958   int i = INTVAL (operands[2]);
6959
6960   emit_move_insn (operands[0], adjust_address (operands[1], SImode, i*4));
6961   DONE;
6962 })
6963
6964 (define_expand "sse_storeq"
6965   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6966         (vec_select:DI
6967           (match_operand:V2DI 1 "register_operand" "")
6968           (parallel [(const_int 0)])))]
6969   "TARGET_SSE"
6970   "")
6971
6972 (define_insn "*sse2_storeq_rex64"
6973   [(set (match_operand:DI 0 "nonimmediate_operand" "=mx,*r,r")
6974         (vec_select:DI
6975           (match_operand:V2DI 1 "nonimmediate_operand" "x,Yi,o")
6976           (parallel [(const_int 0)])))]
6977   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6978   "@
6979    #
6980    #
6981    %vmov{q}\t{%1, %0|%0, %1}"
6982   [(set_attr "type" "*,*,imov")
6983    (set_attr "prefix" "*,*,maybe_vex")
6984    (set_attr "mode" "*,*,DI")])
6985
6986 (define_insn "*sse2_storeq"
6987   [(set (match_operand:DI 0 "nonimmediate_operand" "=mx")
6988         (vec_select:DI
6989           (match_operand:V2DI 1 "register_operand" "x")
6990           (parallel [(const_int 0)])))]
6991   "TARGET_SSE"
6992   "#")
6993
6994 (define_split
6995   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6996         (vec_select:DI
6997           (match_operand:V2DI 1 "register_operand" "")
6998           (parallel [(const_int 0)])))]
6999   "TARGET_SSE
7000    && reload_completed
7001    && (TARGET_INTER_UNIT_MOVES
7002        || MEM_P (operands [0])
7003        || !GENERAL_REGNO_P (true_regnum (operands [0])))"
7004   [(set (match_dup 0) (match_dup 1))]
7005 {
7006   operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));
7007 })
7008
7009 (define_insn "*vec_extractv2di_1_rex64_avx"
7010   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,x,x,r")
7011         (vec_select:DI
7012           (match_operand:V2DI 1 "nonimmediate_operand" "x,x,o,o")
7013           (parallel [(const_int 1)])))]
7014   "TARGET_64BIT
7015    && TARGET_AVX
7016    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7017   "@
7018    vmovhps\t{%1, %0|%0, %1}
7019    vpsrldq\t{$8, %1, %0|%0, %1, 8}
7020    vmovq\t{%H1, %0|%0, %H1}
7021    vmov{q}\t{%H1, %0|%0, %H1}"
7022   [(set_attr "type" "ssemov,sseishft,ssemov,imov")
7023    (set_attr "memory" "*,none,*,*")
7024    (set_attr "prefix" "vex")
7025    (set_attr "mode" "V2SF,TI,TI,DI")])
7026
7027 (define_insn "*vec_extractv2di_1_rex64"
7028   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,x,x,r")
7029         (vec_select:DI
7030           (match_operand:V2DI 1 "nonimmediate_operand" "x,0,o,o")
7031           (parallel [(const_int 1)])))]
7032   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7033   "@
7034    movhps\t{%1, %0|%0, %1}
7035    psrldq\t{$8, %0|%0, 8}
7036    movq\t{%H1, %0|%0, %H1}
7037    mov{q}\t{%H1, %0|%0, %H1}"
7038   [(set_attr "type" "ssemov,sseishft,ssemov,imov")
7039    (set_attr "atom_unit" "*,sishuf,*,*")
7040    (set_attr "memory" "*,none,*,*")
7041    (set_attr "mode" "V2SF,TI,TI,DI")])
7042
7043 (define_insn "*vec_extractv2di_1_avx"
7044   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,x,x")
7045         (vec_select:DI
7046           (match_operand:V2DI 1 "nonimmediate_operand" "x,x,o")
7047           (parallel [(const_int 1)])))]
7048   "!TARGET_64BIT
7049    && TARGET_AVX
7050    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7051   "@
7052    vmovhps\t{%1, %0|%0, %1}
7053    vpsrldq\t{$8, %1, %0|%0, %1, 8}
7054    vmovq\t{%H1, %0|%0, %H1}"
7055   [(set_attr "type" "ssemov,sseishft,ssemov")
7056    (set_attr "memory" "*,none,*")
7057    (set_attr "prefix" "vex")
7058    (set_attr "mode" "V2SF,TI,TI")])
7059
7060 (define_insn "*vec_extractv2di_1_sse2"
7061   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,x,x")
7062         (vec_select:DI
7063           (match_operand:V2DI 1 "nonimmediate_operand" "x,0,o")
7064           (parallel [(const_int 1)])))]
7065   "!TARGET_64BIT
7066    && TARGET_SSE2 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7067   "@
7068    movhps\t{%1, %0|%0, %1}
7069    psrldq\t{$8, %0|%0, 8}
7070    movq\t{%H1, %0|%0, %H1}"
7071   [(set_attr "type" "ssemov,sseishft,ssemov")
7072    (set_attr "atom_unit" "*,sishuf,*")
7073    (set_attr "memory" "*,none,*")
7074    (set_attr "mode" "V2SF,TI,TI")])
7075
7076 ;; Not sure this is ever used, but it doesn't hurt to have it. -aoliva
7077 (define_insn "*vec_extractv2di_1_sse"
7078   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,x,x")
7079         (vec_select:DI
7080           (match_operand:V2DI 1 "nonimmediate_operand" "x,x,o")
7081           (parallel [(const_int 1)])))]
7082   "!TARGET_SSE2 && TARGET_SSE
7083    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7084   "@
7085    movhps\t{%1, %0|%0, %1}
7086    movhlps\t{%1, %0|%0, %1}
7087    movlps\t{%H1, %0|%0, %H1}"
7088   [(set_attr "type" "ssemov")
7089    (set_attr "mode" "V2SF,V4SF,V2SF")])
7090
7091 (define_insn "*vec_dupv4si"
7092   [(set (match_operand:V4SI 0 "register_operand" "=Y2,x")
7093         (vec_duplicate:V4SI
7094           (match_operand:SI 1 "register_operand" " Y2,0")))]
7095   "TARGET_SSE"
7096   "@
7097    %vpshufd\t{$0, %1, %0|%0, %1, 0}
7098    shufps\t{$0, %0, %0|%0, %0, 0}"
7099   [(set_attr "type" "sselog1")
7100    (set_attr "prefix" "maybe_vex,orig")
7101    (set_attr "mode" "TI,V4SF")])
7102
7103 (define_insn "*vec_dupv2di_avx"
7104   [(set (match_operand:V2DI 0 "register_operand" "=x")
7105         (vec_duplicate:V2DI
7106           (match_operand:DI 1 "register_operand" "x")))]
7107   "TARGET_AVX"
7108   "vpunpcklqdq\t{%1, %1, %0|%0, %1, %1}"
7109   [(set_attr "type" "sselog1")
7110    (set_attr "prefix" "vex")
7111    (set_attr "mode" "TI")])
7112
7113 (define_insn "*vec_dupv2di"
7114   [(set (match_operand:V2DI 0 "register_operand" "=Y2,x")
7115         (vec_duplicate:V2DI
7116           (match_operand:DI 1 "register_operand" " 0 ,0")))]
7117   "TARGET_SSE"
7118   "@
7119    punpcklqdq\t%0, %0
7120    movlhps\t%0, %0"
7121   [(set_attr "type" "sselog1,ssemov")
7122    (set_attr "mode" "TI,V4SF")])
7123
7124 (define_insn "*vec_concatv2si_avx"
7125   [(set (match_operand:V2SI 0 "register_operand"     "=x,x,x ,*y ,*y")
7126         (vec_concat:V2SI
7127           (match_operand:SI 1 "nonimmediate_operand" "x ,x,rm, 0 ,rm")
7128           (match_operand:SI 2 "vector_move_operand"  "rm,x,C ,*ym,C")))]
7129   "TARGET_AVX"
7130   "@
7131    vpinsrd\t{$0x1, %2, %1, %0|%0, %1, %2, 0x1}
7132    vpunpckldq\t{%2, %1, %0|%0, %1, %2}
7133    vmovd\t{%1, %0|%0, %1}
7134    punpckldq\t{%2, %0|%0, %2}
7135    movd\t{%1, %0|%0, %1}"
7136   [(set_attr "type" "sselog,sselog,ssemov,mmxcvt,mmxmov")
7137    (set (attr "prefix")
7138      (if_then_else (eq_attr "alternative" "3,4")
7139        (const_string "orig")
7140        (const_string "vex")))
7141    (set_attr "mode" "TI,TI,TI,DI,DI")])
7142
7143 (define_insn "*vec_concatv2si_sse4_1"
7144   [(set (match_operand:V2SI 0 "register_operand"     "=x,x,x ,*y ,*y")
7145         (vec_concat:V2SI
7146           (match_operand:SI 1 "nonimmediate_operand" "0 ,0,rm, 0 ,rm")
7147           (match_operand:SI 2 "vector_move_operand"  "rm,x,C ,*ym,C")))]
7148   "TARGET_SSE4_1"
7149   "@
7150    pinsrd\t{$0x1, %2, %0|%0, %2, 0x1}
7151    punpckldq\t{%2, %0|%0, %2}
7152    movd\t{%1, %0|%0, %1}
7153    punpckldq\t{%2, %0|%0, %2}
7154    movd\t{%1, %0|%0, %1}"
7155   [(set_attr "type" "sselog,sselog,ssemov,mmxcvt,mmxmov")
7156    (set_attr "prefix_extra" "1,*,*,*,*")
7157    (set_attr "mode" "TI,TI,TI,DI,DI")])
7158
7159 ;; ??? In theory we can match memory for the MMX alternative, but allowing
7160 ;; nonimmediate_operand for operand 2 and *not* allowing memory for the SSE
7161 ;; alternatives pretty much forces the MMX alternative to be chosen.
7162 (define_insn "*vec_concatv2si_sse2"
7163   [(set (match_operand:V2SI 0 "register_operand"     "=x,x ,*y,*y")
7164         (vec_concat:V2SI
7165           (match_operand:SI 1 "nonimmediate_operand" " 0,rm, 0,rm")
7166           (match_operand:SI 2 "reg_or_0_operand"     " x,C ,*y, C")))]
7167   "TARGET_SSE2"
7168   "@
7169    punpckldq\t{%2, %0|%0, %2}
7170    movd\t{%1, %0|%0, %1}
7171    punpckldq\t{%2, %0|%0, %2}
7172    movd\t{%1, %0|%0, %1}"
7173   [(set_attr "type" "sselog,ssemov,mmxcvt,mmxmov")
7174    (set_attr "mode" "TI,TI,DI,DI")])
7175
7176 (define_insn "*vec_concatv2si_sse"
7177   [(set (match_operand:V2SI 0 "register_operand"     "=x,x,*y,*y")
7178         (vec_concat:V2SI
7179           (match_operand:SI 1 "nonimmediate_operand" " 0,m, 0,*rm")
7180           (match_operand:SI 2 "reg_or_0_operand"     " x,C,*y,C")))]
7181   "TARGET_SSE"
7182   "@
7183    unpcklps\t{%2, %0|%0, %2}
7184    movss\t{%1, %0|%0, %1}
7185    punpckldq\t{%2, %0|%0, %2}
7186    movd\t{%1, %0|%0, %1}"
7187   [(set_attr "type" "sselog,ssemov,mmxcvt,mmxmov")
7188    (set_attr "mode" "V4SF,V4SF,DI,DI")])
7189
7190 (define_insn "*vec_concatv4si_1_avx"
7191   [(set (match_operand:V4SI 0 "register_operand"       "=x,x")
7192         (vec_concat:V4SI
7193           (match_operand:V2SI 1 "register_operand"     " x,x")
7194           (match_operand:V2SI 2 "nonimmediate_operand" " x,m")))]
7195   "TARGET_AVX"
7196   "@
7197    vpunpcklqdq\t{%2, %1, %0|%0, %1, %2}
7198    vmovhps\t{%2, %1, %0|%0, %1, %2}"
7199   [(set_attr "type" "sselog,ssemov")
7200    (set_attr "prefix" "vex")
7201    (set_attr "mode" "TI,V2SF")])
7202
7203 (define_insn "*vec_concatv4si_1"
7204   [(set (match_operand:V4SI 0 "register_operand"       "=Y2,x,x")
7205         (vec_concat:V4SI
7206           (match_operand:V2SI 1 "register_operand"     " 0 ,0,0")
7207           (match_operand:V2SI 2 "nonimmediate_operand" " Y2,x,m")))]
7208   "TARGET_SSE"
7209   "@
7210    punpcklqdq\t{%2, %0|%0, %2}
7211    movlhps\t{%2, %0|%0, %2}
7212    movhps\t{%2, %0|%0, %2}"
7213   [(set_attr "type" "sselog,ssemov,ssemov")
7214    (set_attr "mode" "TI,V4SF,V2SF")])
7215
7216 (define_insn "*vec_concatv2di_avx"
7217   [(set (match_operand:V2DI 0 "register_operand"     "=x,?x,x,x")
7218         (vec_concat:V2DI
7219           (match_operand:DI 1 "nonimmediate_operand" " m,*y,x,x")
7220           (match_operand:DI 2 "vector_move_operand"  " C, C,x,m")))]
7221   "!TARGET_64BIT && TARGET_AVX"
7222   "@
7223    vmovq\t{%1, %0|%0, %1}
7224    movq2dq\t{%1, %0|%0, %1}
7225    vpunpcklqdq\t{%2, %1, %0|%0, %1, %2}
7226    vmovhps\t{%2, %1, %0|%0, %1, %2}"
7227   [(set_attr "type" "ssemov,ssemov,sselog,ssemov")
7228    (set (attr "prefix")
7229      (if_then_else (eq_attr "alternative" "1")
7230        (const_string "orig")
7231        (const_string "vex")))
7232    (set_attr "mode" "TI,TI,TI,V2SF")])
7233
7234 (define_insn "vec_concatv2di"
7235   [(set (match_operand:V2DI 0 "register_operand"     "=Y2 ,?Y2,Y2,x,x")
7236         (vec_concat:V2DI
7237           (match_operand:DI 1 "nonimmediate_operand" " mY2,*y ,0 ,0,0")
7238           (match_operand:DI 2 "vector_move_operand"  " C  ,  C,Y2,x,m")))]
7239   "!TARGET_64BIT && TARGET_SSE"
7240   "@
7241    movq\t{%1, %0|%0, %1}
7242    movq2dq\t{%1, %0|%0, %1}
7243    punpcklqdq\t{%2, %0|%0, %2}
7244    movlhps\t{%2, %0|%0, %2}
7245    movhps\t{%2, %0|%0, %2}"
7246   [(set_attr "type" "ssemov,ssemov,sselog,ssemov,ssemov")
7247    (set_attr "mode" "TI,TI,TI,V4SF,V2SF")])
7248
7249 (define_insn "*vec_concatv2di_rex64_avx"
7250   [(set (match_operand:V2DI 0 "register_operand"     "=x,x,Yi,!x,x,x")
7251         (vec_concat:V2DI
7252           (match_operand:DI 1 "nonimmediate_operand" " x,m,r ,*y,x,x")
7253           (match_operand:DI 2 "vector_move_operand"  "rm,C,C ,C ,x,m")))]
7254   "TARGET_64BIT && TARGET_AVX"
7255   "@
7256    vpinsrq\t{$0x1, %2, %1, %0|%0, %1, %2, 0x1}
7257    vmovq\t{%1, %0|%0, %1}
7258    vmovq\t{%1, %0|%0, %1}
7259    movq2dq\t{%1, %0|%0, %1}
7260    vpunpcklqdq\t{%2, %1, %0|%0, %1, %2}
7261    vmovhps\t{%2, %1, %0|%0, %1, %2}"
7262   [(set_attr "type" "sselog,ssemov,ssemov,ssemov,sselog,ssemov")
7263    (set (attr "prefix")
7264      (if_then_else (eq_attr "alternative" "3")
7265        (const_string "orig")
7266        (const_string "vex")))
7267    (set_attr "mode" "TI,TI,TI,TI,TI,V2SF")])
7268
7269 (define_insn "*vec_concatv2di_rex64_sse4_1"
7270   [(set (match_operand:V2DI 0 "register_operand"     "=x ,x ,Yi,!x,x,x,x")
7271         (vec_concat:V2DI
7272           (match_operand:DI 1 "nonimmediate_operand" " 0 ,mx,r ,*y,0,0,0")
7273           (match_operand:DI 2 "vector_move_operand"  " rm,C ,C ,C ,x,x,m")))]
7274   "TARGET_64BIT && TARGET_SSE4_1"
7275   "@
7276    pinsrq\t{$0x1, %2, %0|%0, %2, 0x1}
7277    movq\t{%1, %0|%0, %1}
7278    movq\t{%1, %0|%0, %1}
7279    movq2dq\t{%1, %0|%0, %1}
7280    punpcklqdq\t{%2, %0|%0, %2}
7281    movlhps\t{%2, %0|%0, %2}
7282    movhps\t{%2, %0|%0, %2}"
7283   [(set_attr "type" "sselog,ssemov,ssemov,ssemov,sselog,ssemov,ssemov")
7284    (set_attr "prefix_extra" "1,*,*,*,*,*,*")
7285    (set_attr "mode" "TI,TI,TI,TI,TI,V4SF,V2SF")])
7286
7287 (define_insn "*vec_concatv2di_rex64_sse"
7288   [(set (match_operand:V2DI 0 "register_operand"     "=Y2 ,Yi,!Y2,Y2,x,x")
7289         (vec_concat:V2DI
7290           (match_operand:DI 1 "nonimmediate_operand" " mY2,r ,*y ,0 ,0,0")
7291           (match_operand:DI 2 "vector_move_operand"  " C  ,C ,C  ,Y2,x,m")))]
7292   "TARGET_64BIT && TARGET_SSE"
7293   "@
7294    movq\t{%1, %0|%0, %1}
7295    movq\t{%1, %0|%0, %1}
7296    movq2dq\t{%1, %0|%0, %1}
7297    punpcklqdq\t{%2, %0|%0, %2}
7298    movlhps\t{%2, %0|%0, %2}
7299    movhps\t{%2, %0|%0, %2}"
7300   [(set_attr "type" "ssemov,ssemov,ssemov,sselog,ssemov,ssemov")
7301    (set_attr "mode" "TI,TI,TI,TI,V4SF,V2SF")])
7302
7303 (define_expand "vec_unpacku_hi_v16qi"
7304   [(match_operand:V8HI 0 "register_operand" "")
7305    (match_operand:V16QI 1 "register_operand" "")]
7306   "TARGET_SSE2"
7307 {
7308   if (TARGET_SSE4_1)
7309     ix86_expand_sse4_unpack (operands, true, true);
7310   else if (TARGET_SSE5)
7311     ix86_expand_sse5_unpack (operands, true, true);
7312   else
7313     ix86_expand_sse_unpack (operands, true, true);
7314   DONE;
7315 })
7316
7317 (define_expand "vec_unpacks_hi_v16qi"
7318   [(match_operand:V8HI 0 "register_operand" "")
7319    (match_operand:V16QI 1 "register_operand" "")]
7320   "TARGET_SSE2"
7321 {
7322   if (TARGET_SSE4_1)
7323     ix86_expand_sse4_unpack (operands, false, true);
7324   else if (TARGET_SSE5)
7325     ix86_expand_sse5_unpack (operands, false, true);
7326   else
7327     ix86_expand_sse_unpack (operands, false, true);
7328   DONE;
7329 })
7330
7331 (define_expand "vec_unpacku_lo_v16qi"
7332   [(match_operand:V8HI 0 "register_operand" "")
7333    (match_operand:V16QI 1 "register_operand" "")]
7334   "TARGET_SSE2"
7335 {
7336   if (TARGET_SSE4_1)
7337     ix86_expand_sse4_unpack (operands, true, false);
7338   else if (TARGET_SSE5)
7339     ix86_expand_sse5_unpack (operands, true, false);
7340   else
7341     ix86_expand_sse_unpack (operands, true, false);
7342   DONE;
7343 })
7344
7345 (define_expand "vec_unpacks_lo_v16qi"
7346   [(match_operand:V8HI 0 "register_operand" "")
7347    (match_operand:V16QI 1 "register_operand" "")]
7348   "TARGET_SSE2"
7349 {
7350   if (TARGET_SSE4_1)
7351     ix86_expand_sse4_unpack (operands, false, false);
7352   else if (TARGET_SSE5)
7353     ix86_expand_sse5_unpack (operands, false, false);
7354   else
7355     ix86_expand_sse_unpack (operands, false, false);
7356   DONE;
7357 })
7358
7359 (define_expand "vec_unpacku_hi_v8hi"
7360   [(match_operand:V4SI 0 "register_operand" "")
7361    (match_operand:V8HI 1 "register_operand" "")]
7362   "TARGET_SSE2"
7363 {
7364   if (TARGET_SSE4_1)
7365     ix86_expand_sse4_unpack (operands, true, true);
7366   else if (TARGET_SSE5)
7367     ix86_expand_sse5_unpack (operands, true, true);
7368   else
7369     ix86_expand_sse_unpack (operands, true, true);
7370   DONE;
7371 })
7372
7373 (define_expand "vec_unpacks_hi_v8hi"
7374   [(match_operand:V4SI 0 "register_operand" "")
7375    (match_operand:V8HI 1 "register_operand" "")]
7376   "TARGET_SSE2"
7377 {
7378   if (TARGET_SSE4_1)
7379     ix86_expand_sse4_unpack (operands, false, true);
7380   else if (TARGET_SSE5)
7381     ix86_expand_sse5_unpack (operands, false, true);
7382   else
7383     ix86_expand_sse_unpack (operands, false, true);
7384   DONE;
7385 })
7386
7387 (define_expand "vec_unpacku_lo_v8hi"
7388   [(match_operand:V4SI 0 "register_operand" "")
7389    (match_operand:V8HI 1 "register_operand" "")]
7390   "TARGET_SSE2"
7391 {
7392   if (TARGET_SSE4_1)
7393     ix86_expand_sse4_unpack (operands, true, false);
7394   else if (TARGET_SSE5)
7395     ix86_expand_sse5_unpack (operands, true, false);
7396   else
7397     ix86_expand_sse_unpack (operands, true, false);
7398   DONE;
7399 })
7400
7401 (define_expand "vec_unpacks_lo_v8hi"
7402   [(match_operand:V4SI 0 "register_operand" "")
7403    (match_operand:V8HI 1 "register_operand" "")]
7404   "TARGET_SSE2"
7405 {
7406   if (TARGET_SSE4_1)
7407     ix86_expand_sse4_unpack (operands, false, false);
7408   else if (TARGET_SSE5)
7409     ix86_expand_sse5_unpack (operands, false, false);
7410   else
7411     ix86_expand_sse_unpack (operands, false, false);
7412   DONE;
7413 })
7414
7415 (define_expand "vec_unpacku_hi_v4si"
7416   [(match_operand:V2DI 0 "register_operand" "")
7417    (match_operand:V4SI 1 "register_operand" "")]
7418   "TARGET_SSE2"
7419 {
7420   if (TARGET_SSE4_1)
7421     ix86_expand_sse4_unpack (operands, true, true);
7422   else if (TARGET_SSE5)
7423     ix86_expand_sse5_unpack (operands, true, true);
7424   else
7425     ix86_expand_sse_unpack (operands, true, true);
7426   DONE;
7427 })
7428
7429 (define_expand "vec_unpacks_hi_v4si"
7430   [(match_operand:V2DI 0 "register_operand" "")
7431    (match_operand:V4SI 1 "register_operand" "")]
7432   "TARGET_SSE2"
7433 {
7434   if (TARGET_SSE4_1)
7435     ix86_expand_sse4_unpack (operands, false, true);
7436   else if (TARGET_SSE5)
7437     ix86_expand_sse5_unpack (operands, false, true);
7438   else
7439     ix86_expand_sse_unpack (operands, false, true);
7440   DONE;
7441 })
7442
7443 (define_expand "vec_unpacku_lo_v4si"
7444   [(match_operand:V2DI 0 "register_operand" "")
7445    (match_operand:V4SI 1 "register_operand" "")]
7446   "TARGET_SSE2"
7447 {
7448   if (TARGET_SSE4_1)
7449     ix86_expand_sse4_unpack (operands, true, false);
7450   else if (TARGET_SSE5)
7451     ix86_expand_sse5_unpack (operands, true, false);
7452   else
7453     ix86_expand_sse_unpack (operands, true, false);
7454   DONE;
7455 })
7456
7457 (define_expand "vec_unpacks_lo_v4si"
7458   [(match_operand:V2DI 0 "register_operand" "")
7459    (match_operand:V4SI 1 "register_operand" "")]
7460   "TARGET_SSE2"
7461 {
7462   if (TARGET_SSE4_1)
7463     ix86_expand_sse4_unpack (operands, false, false);
7464   else if (TARGET_SSE5)
7465     ix86_expand_sse5_unpack (operands, false, false);
7466   else
7467     ix86_expand_sse_unpack (operands, false, false);
7468   DONE;
7469 })
7470
7471 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7472 ;;
7473 ;; Miscellaneous
7474 ;;
7475 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7476
7477 (define_expand "sse2_uavgv16qi3"
7478   [(set (match_operand:V16QI 0 "register_operand" "")
7479         (truncate:V16QI
7480           (lshiftrt:V16HI
7481             (plus:V16HI
7482               (plus:V16HI
7483                 (zero_extend:V16HI
7484                   (match_operand:V16QI 1 "nonimmediate_operand" ""))
7485                 (zero_extend:V16HI
7486                   (match_operand:V16QI 2 "nonimmediate_operand" "")))
7487               (const_vector:V16QI [(const_int 1) (const_int 1)
7488                                    (const_int 1) (const_int 1)
7489                                    (const_int 1) (const_int 1)
7490                                    (const_int 1) (const_int 1)
7491                                    (const_int 1) (const_int 1)
7492                                    (const_int 1) (const_int 1)
7493                                    (const_int 1) (const_int 1)
7494                                    (const_int 1) (const_int 1)]))
7495             (const_int 1))))]
7496   "TARGET_SSE2"
7497   "ix86_fixup_binary_operands_no_copy (PLUS, V16QImode, operands);")
7498
7499 (define_insn "*avx_uavgv16qi3"
7500   [(set (match_operand:V16QI 0 "register_operand" "=x")
7501         (truncate:V16QI
7502           (lshiftrt:V16HI
7503             (plus:V16HI
7504               (plus:V16HI
7505                 (zero_extend:V16HI
7506                   (match_operand:V16QI 1 "nonimmediate_operand" "%x"))
7507                 (zero_extend:V16HI
7508                   (match_operand:V16QI 2 "nonimmediate_operand" "xm")))
7509               (const_vector:V16QI [(const_int 1) (const_int 1)
7510                                    (const_int 1) (const_int 1)
7511                                    (const_int 1) (const_int 1)
7512                                    (const_int 1) (const_int 1)
7513                                    (const_int 1) (const_int 1)
7514                                    (const_int 1) (const_int 1)
7515                                    (const_int 1) (const_int 1)
7516                                    (const_int 1) (const_int 1)]))
7517             (const_int 1))))]
7518   "TARGET_AVX && ix86_binary_operator_ok (PLUS, V16QImode, operands)"
7519   "vpavgb\t{%2, %1, %0|%0, %1, %2}"
7520   [(set_attr "type" "sseiadd")
7521    (set_attr "prefix" "vex")
7522    (set_attr "mode" "TI")])
7523
7524 (define_insn "*sse2_uavgv16qi3"
7525   [(set (match_operand:V16QI 0 "register_operand" "=x")
7526         (truncate:V16QI
7527           (lshiftrt:V16HI
7528             (plus:V16HI
7529               (plus:V16HI
7530                 (zero_extend:V16HI
7531                   (match_operand:V16QI 1 "nonimmediate_operand" "%0"))
7532                 (zero_extend:V16HI
7533                   (match_operand:V16QI 2 "nonimmediate_operand" "xm")))
7534               (const_vector:V16QI [(const_int 1) (const_int 1)
7535                                    (const_int 1) (const_int 1)
7536                                    (const_int 1) (const_int 1)
7537                                    (const_int 1) (const_int 1)
7538                                    (const_int 1) (const_int 1)
7539                                    (const_int 1) (const_int 1)
7540                                    (const_int 1) (const_int 1)
7541                                    (const_int 1) (const_int 1)]))
7542             (const_int 1))))]
7543   "TARGET_SSE2 && ix86_binary_operator_ok (PLUS, V16QImode, operands)"
7544   "pavgb\t{%2, %0|%0, %2}"
7545   [(set_attr "type" "sseiadd")
7546    (set_attr "prefix_data16" "1")
7547    (set_attr "mode" "TI")])
7548
7549 (define_expand "sse2_uavgv8hi3"
7550   [(set (match_operand:V8HI 0 "register_operand" "")
7551         (truncate:V8HI
7552           (lshiftrt:V8SI
7553             (plus:V8SI
7554               (plus:V8SI
7555                 (zero_extend:V8SI
7556                   (match_operand:V8HI 1 "nonimmediate_operand" ""))
7557                 (zero_extend:V8SI
7558                   (match_operand:V8HI 2 "nonimmediate_operand" "")))
7559               (const_vector:V8HI [(const_int 1) (const_int 1)
7560                                   (const_int 1) (const_int 1)
7561                                   (const_int 1) (const_int 1)
7562                                   (const_int 1) (const_int 1)]))
7563             (const_int 1))))]
7564   "TARGET_SSE2"
7565   "ix86_fixup_binary_operands_no_copy (PLUS, V8HImode, operands);")
7566
7567 (define_insn "*avx_uavgv8hi3"
7568   [(set (match_operand:V8HI 0 "register_operand" "=x")
7569         (truncate:V8HI
7570           (lshiftrt:V8SI
7571             (plus:V8SI
7572               (plus:V8SI
7573                 (zero_extend:V8SI
7574                   (match_operand:V8HI 1 "nonimmediate_operand" "%x"))
7575                 (zero_extend:V8SI
7576                   (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
7577               (const_vector:V8HI [(const_int 1) (const_int 1)
7578                                   (const_int 1) (const_int 1)
7579                                   (const_int 1) (const_int 1)
7580                                   (const_int 1) (const_int 1)]))
7581             (const_int 1))))]
7582   "TARGET_AVX && ix86_binary_operator_ok (PLUS, V8HImode, operands)"
7583   "vpavgw\t{%2, %1, %0|%0, %1, %2}"
7584   [(set_attr "type" "sseiadd")
7585    (set_attr "prefix" "vex")
7586    (set_attr "mode" "TI")])
7587
7588 (define_insn "*sse2_uavgv8hi3"
7589   [(set (match_operand:V8HI 0 "register_operand" "=x")
7590         (truncate:V8HI
7591           (lshiftrt:V8SI
7592             (plus:V8SI
7593               (plus:V8SI
7594                 (zero_extend:V8SI
7595                   (match_operand:V8HI 1 "nonimmediate_operand" "%0"))
7596                 (zero_extend:V8SI
7597                   (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
7598               (const_vector:V8HI [(const_int 1) (const_int 1)
7599                                   (const_int 1) (const_int 1)
7600                                   (const_int 1) (const_int 1)
7601                                   (const_int 1) (const_int 1)]))
7602             (const_int 1))))]
7603   "TARGET_SSE2 && ix86_binary_operator_ok (PLUS, V8HImode, operands)"
7604   "pavgw\t{%2, %0|%0, %2}"
7605   [(set_attr "type" "sseiadd")
7606    (set_attr "prefix_data16" "1")
7607    (set_attr "mode" "TI")])
7608
7609 ;; The correct representation for this is absolutely enormous, and
7610 ;; surely not generally useful.
7611 (define_insn "*avx_psadbw"
7612   [(set (match_operand:V2DI 0 "register_operand" "=x")
7613         (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "x")
7614                       (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
7615                      UNSPEC_PSADBW))]
7616   "TARGET_AVX"
7617   "vpsadbw\t{%2, %1, %0|%0, %1, %2}"
7618   [(set_attr "type" "sseiadd")
7619    (set_attr "prefix" "vex")
7620    (set_attr "mode" "TI")])
7621
7622 (define_insn "sse2_psadbw"
7623   [(set (match_operand:V2DI 0 "register_operand" "=x")
7624         (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
7625                       (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
7626                      UNSPEC_PSADBW))]
7627   "TARGET_SSE2"
7628   "psadbw\t{%2, %0|%0, %2}"
7629   [(set_attr "type" "sseiadd")
7630    (set_attr "atom_unit" "simul")
7631    (set_attr "prefix_data16" "1")
7632    (set_attr "mode" "TI")])
7633
7634 (define_insn "avx_movmskp<avxmodesuffixf2c>256"
7635   [(set (match_operand:SI 0 "register_operand" "=r")
7636         (unspec:SI
7637           [(match_operand:AVX256MODEF2P 1 "register_operand" "x")]
7638           UNSPEC_MOVMSK))]
7639   "AVX256_VEC_FLOAT_MODE_P (<MODE>mode)"
7640   "vmovmskp<avxmodesuffixf2c>\t{%1, %0|%0, %1}"
7641   [(set_attr "type" "ssecvt")
7642    (set_attr "prefix" "vex")
7643    (set_attr "mode" "<MODE>")])
7644
7645 (define_insn "<sse>_movmskp<ssemodesuffixf2c>"
7646   [(set (match_operand:SI 0 "register_operand" "=r")
7647         (unspec:SI
7648           [(match_operand:SSEMODEF2P 1 "register_operand" "x")]
7649           UNSPEC_MOVMSK))]
7650   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
7651   "%vmovmskp<ssemodesuffixf2c>\t{%1, %0|%0, %1}"
7652   [(set_attr "type" "ssemov")
7653    (set_attr "prefix" "maybe_vex")
7654    (set_attr "mode" "<MODE>")])
7655
7656 (define_insn "sse2_pmovmskb"
7657   [(set (match_operand:SI 0 "register_operand" "=r")
7658         (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
7659                    UNSPEC_MOVMSK))]
7660   "TARGET_SSE2"
7661   "%vpmovmskb\t{%1, %0|%0, %1}"
7662   [(set_attr "type" "ssemov")
7663    (set_attr "prefix_data16" "1")
7664    (set_attr "prefix" "maybe_vex")
7665    (set_attr "mode" "SI")])
7666
7667 (define_expand "sse2_maskmovdqu"
7668   [(set (match_operand:V16QI 0 "memory_operand" "")
7669         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "")
7670                        (match_operand:V16QI 2 "register_operand" "")
7671                        (match_dup 0)]
7672                       UNSPEC_MASKMOV))]
7673   "TARGET_SSE2"
7674   "")
7675
7676 (define_insn "*sse2_maskmovdqu"
7677   [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
7678         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
7679                        (match_operand:V16QI 2 "register_operand" "x")
7680                        (mem:V16QI (match_dup 0))]
7681                       UNSPEC_MASKMOV))]
7682   "TARGET_SSE2 && !TARGET_64BIT"
7683   ;; @@@ check ordering of operands in intel/nonintel syntax
7684   "%vmaskmovdqu\t{%2, %1|%1, %2}"
7685   [(set_attr "type" "ssemov")
7686    (set_attr "prefix_data16" "1")
7687    (set_attr "prefix" "maybe_vex")
7688    (set_attr "mode" "TI")])
7689
7690 (define_insn "*sse2_maskmovdqu_rex64"
7691   [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
7692         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
7693                        (match_operand:V16QI 2 "register_operand" "x")
7694                        (mem:V16QI (match_dup 0))]
7695                       UNSPEC_MASKMOV))]
7696   "TARGET_SSE2 && TARGET_64BIT"
7697   ;; @@@ check ordering of operands in intel/nonintel syntax
7698   "%vmaskmovdqu\t{%2, %1|%1, %2}"
7699   [(set_attr "type" "ssemov")
7700    (set_attr "prefix_data16" "1")
7701    (set_attr "prefix" "maybe_vex")
7702    (set_attr "mode" "TI")])
7703
7704 (define_insn "sse_ldmxcsr"
7705   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
7706                     UNSPECV_LDMXCSR)]
7707   "TARGET_SSE"
7708   "%vldmxcsr\t%0"
7709   [(set_attr "type" "sse")
7710    (set_attr "atom_sse_attr" "mxcsr")
7711    (set_attr "prefix" "maybe_vex")
7712    (set_attr "memory" "load")])
7713
7714 (define_insn "sse_stmxcsr"
7715   [(set (match_operand:SI 0 "memory_operand" "=m")
7716         (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
7717   "TARGET_SSE"
7718   "%vstmxcsr\t%0"
7719   [(set_attr "type" "sse")
7720    (set_attr "atom_sse_attr" "mxcsr")
7721    (set_attr "prefix" "maybe_vex")
7722    (set_attr "memory" "store")])
7723
7724 (define_expand "sse_sfence"
7725   [(set (match_dup 0)
7726         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
7727   "TARGET_SSE || TARGET_3DNOW_A"
7728 {
7729   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
7730   MEM_VOLATILE_P (operands[0]) = 1;
7731 })
7732
7733 (define_insn "*sse_sfence"
7734   [(set (match_operand:BLK 0 "" "")
7735         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
7736   "TARGET_SSE || TARGET_3DNOW_A"
7737   "sfence"
7738   [(set_attr "type" "sse")
7739    (set_attr "atom_sse_attr" "fence")
7740    (set_attr "memory" "unknown")])
7741
7742 (define_insn "sse2_clflush"
7743   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
7744                     UNSPECV_CLFLUSH)]
7745   "TARGET_SSE2"
7746   "clflush\t%a0"
7747   [(set_attr "type" "sse")
7748    (set_attr "atom_sse_attr" "fence")
7749    (set_attr "memory" "unknown")])
7750
7751 (define_expand "sse2_mfence"
7752   [(set (match_dup 0)
7753         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
7754   "TARGET_SSE2"
7755 {
7756   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
7757   MEM_VOLATILE_P (operands[0]) = 1;
7758 })
7759
7760 (define_insn "*sse2_mfence"
7761   [(set (match_operand:BLK 0 "" "")
7762         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
7763   "TARGET_64BIT || TARGET_SSE2"
7764   "mfence"
7765   [(set_attr "type" "sse")
7766    (set_attr "atom_sse_attr" "fence")
7767    (set_attr "memory" "unknown")])
7768
7769 (define_expand "sse2_lfence"
7770   [(set (match_dup 0)
7771         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
7772   "TARGET_SSE2"
7773 {
7774   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
7775   MEM_VOLATILE_P (operands[0]) = 1;
7776 })
7777
7778 (define_insn "*sse2_lfence"
7779   [(set (match_operand:BLK 0 "" "")
7780         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
7781   "TARGET_SSE2"
7782   "lfence"
7783   [(set_attr "type" "sse")
7784    (set_attr "atom_sse_attr" "lfence")
7785    (set_attr "memory" "unknown")])
7786
7787 (define_insn "sse3_mwait"
7788   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
7789                      (match_operand:SI 1 "register_operand" "c")]
7790                     UNSPECV_MWAIT)]
7791   "TARGET_SSE3"
7792 ;; 64bit version is "mwait %rax,%rcx". But only lower 32bits are used.
7793 ;; Since 32bit register operands are implicitly zero extended to 64bit,
7794 ;; we only need to set up 32bit registers.
7795   "mwait"
7796   [(set_attr "length" "3")])
7797
7798 (define_insn "sse3_monitor"
7799   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
7800                      (match_operand:SI 1 "register_operand" "c")
7801                      (match_operand:SI 2 "register_operand" "d")]
7802                     UNSPECV_MONITOR)]
7803   "TARGET_SSE3 && !TARGET_64BIT"
7804   "monitor\t%0, %1, %2"
7805   [(set_attr "length" "3")])
7806
7807 (define_insn "sse3_monitor64"
7808   [(unspec_volatile [(match_operand:DI 0 "register_operand" "a")
7809                      (match_operand:SI 1 "register_operand" "c")
7810                      (match_operand:SI 2 "register_operand" "d")]
7811                     UNSPECV_MONITOR)]
7812   "TARGET_SSE3 && TARGET_64BIT"
7813 ;; 64bit version is "monitor %rax,%rcx,%rdx". But only lower 32bits in
7814 ;; RCX and RDX are used.  Since 32bit register operands are implicitly
7815 ;; zero extended to 64bit, we only need to set up 32bit registers.
7816   "monitor"
7817   [(set_attr "length" "3")])
7818
7819 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7820 ;;
7821 ;; SSSE3 instructions
7822 ;;
7823 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7824
7825 (define_insn "*avx_phaddwv8hi3"
7826   [(set (match_operand:V8HI 0 "register_operand" "=x")
7827         (vec_concat:V8HI
7828           (vec_concat:V4HI
7829             (vec_concat:V2HI
7830               (plus:HI
7831                 (vec_select:HI
7832                   (match_operand:V8HI 1 "register_operand" "x")
7833                   (parallel [(const_int 0)]))
7834                 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
7835               (plus:HI
7836                 (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
7837                 (vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
7838             (vec_concat:V2HI
7839               (plus:HI
7840                 (vec_select:HI (match_dup 1) (parallel [(const_int 4)]))
7841                 (vec_select:HI (match_dup 1) (parallel [(const_int 5)])))
7842               (plus:HI
7843                 (vec_select:HI (match_dup 1) (parallel [(const_int 6)]))
7844                 (vec_select:HI (match_dup 1) (parallel [(const_int 7)])))))
7845           (vec_concat:V4HI
7846             (vec_concat:V2HI
7847               (plus:HI
7848                 (vec_select:HI
7849                   (match_operand:V8HI 2 "nonimmediate_operand" "xm")
7850                   (parallel [(const_int 0)]))
7851                 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
7852               (plus:HI
7853                 (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
7854                 (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))
7855             (vec_concat:V2HI
7856               (plus:HI
7857                 (vec_select:HI (match_dup 2) (parallel [(const_int 4)]))
7858                 (vec_select:HI (match_dup 2) (parallel [(const_int 5)])))
7859               (plus:HI
7860                 (vec_select:HI (match_dup 2) (parallel [(const_int 6)]))
7861                 (vec_select:HI (match_dup 2) (parallel [(const_int 7)])))))))]
7862   "TARGET_AVX"
7863   "vphaddw\t{%2, %1, %0|%0, %1, %2}"
7864   [(set_attr "type" "sseiadd")
7865    (set_attr "prefix" "vex")
7866    (set_attr "mode" "TI")])
7867
7868 (define_insn "ssse3_phaddwv8hi3"
7869   [(set (match_operand:V8HI 0 "register_operand" "=x")
7870         (vec_concat:V8HI
7871           (vec_concat:V4HI
7872             (vec_concat:V2HI
7873               (plus:HI
7874                 (vec_select:HI
7875                   (match_operand:V8HI 1 "register_operand" "0")
7876                   (parallel [(const_int 0)]))
7877                 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
7878               (plus:HI
7879                 (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
7880                 (vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
7881             (vec_concat:V2HI
7882               (plus:HI
7883                 (vec_select:HI (match_dup 1) (parallel [(const_int 4)]))
7884                 (vec_select:HI (match_dup 1) (parallel [(const_int 5)])))
7885               (plus:HI
7886                 (vec_select:HI (match_dup 1) (parallel [(const_int 6)]))
7887                 (vec_select:HI (match_dup 1) (parallel [(const_int 7)])))))
7888           (vec_concat:V4HI
7889             (vec_concat:V2HI
7890               (plus:HI
7891                 (vec_select:HI
7892                   (match_operand:V8HI 2 "nonimmediate_operand" "xm")
7893                   (parallel [(const_int 0)]))
7894                 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
7895               (plus:HI
7896                 (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
7897                 (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))
7898             (vec_concat:V2HI
7899               (plus:HI
7900                 (vec_select:HI (match_dup 2) (parallel [(const_int 4)]))
7901                 (vec_select:HI (match_dup 2) (parallel [(const_int 5)])))
7902               (plus:HI
7903                 (vec_select:HI (match_dup 2) (parallel [(const_int 6)]))
7904                 (vec_select:HI (match_dup 2) (parallel [(const_int 7)])))))))]
7905   "TARGET_SSSE3"
7906   "phaddw\t{%2, %0|%0, %2}"
7907   [(set_attr "type" "sseiadd")
7908    (set_attr "atom_unit" "complex")
7909    (set_attr "prefix_data16" "1")
7910    (set_attr "prefix_extra" "1")
7911    (set_attr "mode" "TI")])
7912
7913 (define_insn "ssse3_phaddwv4hi3"
7914   [(set (match_operand:V4HI 0 "register_operand" "=y")
7915         (vec_concat:V4HI
7916           (vec_concat:V2HI
7917             (plus:HI
7918               (vec_select:HI
7919                 (match_operand:V4HI 1 "register_operand" "0")
7920                 (parallel [(const_int 0)]))
7921               (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
7922             (plus:HI
7923               (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
7924               (vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
7925           (vec_concat:V2HI
7926             (plus:HI
7927               (vec_select:HI
7928                 (match_operand:V4HI 2 "nonimmediate_operand" "ym")
7929                 (parallel [(const_int 0)]))
7930               (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
7931             (plus:HI
7932               (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
7933               (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))))]
7934   "TARGET_SSSE3"
7935   "phaddw\t{%2, %0|%0, %2}"
7936   [(set_attr "type" "sseiadd")
7937    (set_attr "atom_unit" "complex")
7938    (set_attr "prefix_extra" "1")
7939    (set_attr "mode" "DI")])
7940
7941 (define_insn "*avx_phadddv4si3"
7942   [(set (match_operand:V4SI 0 "register_operand" "=x")
7943         (vec_concat:V4SI
7944           (vec_concat:V2SI
7945             (plus:SI
7946               (vec_select:SI
7947                 (match_operand:V4SI 1 "register_operand" "x")
7948                 (parallel [(const_int 0)]))
7949               (vec_select:SI (match_dup 1) (parallel [(const_int 1)])))
7950             (plus:SI
7951               (vec_select:SI (match_dup 1) (parallel [(const_int 2)]))
7952               (vec_select:SI (match_dup 1) (parallel [(const_int 3)]))))
7953           (vec_concat:V2SI
7954             (plus:SI
7955               (vec_select:SI
7956                 (match_operand:V4SI 2 "nonimmediate_operand" "xm")
7957                 (parallel [(const_int 0)]))
7958               (vec_select:SI (match_dup 2) (parallel [(const_int 1)])))
7959             (plus:SI
7960               (vec_select:SI (match_dup 2) (parallel [(const_int 2)]))
7961               (vec_select:SI (match_dup 2) (parallel [(const_int 3)]))))))]
7962   "TARGET_AVX"
7963   "vphaddd\t{%2, %1, %0|%0, %1, %2}"
7964   [(set_attr "type" "sseiadd")
7965    (set_attr "prefix" "vex")
7966    (set_attr "mode" "TI")])
7967
7968 (define_insn "ssse3_phadddv4si3"
7969   [(set (match_operand:V4SI 0 "register_operand" "=x")
7970         (vec_concat:V4SI
7971           (vec_concat:V2SI
7972             (plus:SI
7973               (vec_select:SI
7974                 (match_operand:V4SI 1 "register_operand" "0")
7975                 (parallel [(const_int 0)]))
7976               (vec_select:SI (match_dup 1) (parallel [(const_int 1)])))
7977             (plus:SI
7978               (vec_select:SI (match_dup 1) (parallel [(const_int 2)]))
7979               (vec_select:SI (match_dup 1) (parallel [(const_int 3)]))))
7980           (vec_concat:V2SI
7981             (plus:SI
7982               (vec_select:SI
7983                 (match_operand:V4SI 2 "nonimmediate_operand" "xm")
7984                 (parallel [(const_int 0)]))
7985               (vec_select:SI (match_dup 2) (parallel [(const_int 1)])))
7986             (plus:SI
7987               (vec_select:SI (match_dup 2) (parallel [(const_int 2)]))
7988               (vec_select:SI (match_dup 2) (parallel [(const_int 3)]))))))]
7989   "TARGET_SSSE3"
7990   "phaddd\t{%2, %0|%0, %2}"
7991   [(set_attr "type" "sseiadd")
7992    (set_attr "atom_unit" "complex")
7993    (set_attr "prefix_data16" "1")
7994    (set_attr "prefix_extra" "1")
7995    (set_attr "mode" "TI")])
7996
7997 (define_insn "ssse3_phadddv2si3"
7998   [(set (match_operand:V2SI 0 "register_operand" "=y")
7999         (vec_concat:V2SI
8000           (plus:SI
8001             (vec_select:SI
8002               (match_operand:V2SI 1 "register_operand" "0")
8003               (parallel [(const_int 0)]))
8004             (vec_select:SI (match_dup 1) (parallel [(const_int 1)])))
8005           (plus:SI
8006             (vec_select:SI
8007               (match_operand:V2SI 2 "nonimmediate_operand" "ym")
8008               (parallel [(const_int 0)]))
8009             (vec_select:SI (match_dup 2) (parallel [(const_int 1)])))))]
8010   "TARGET_SSSE3"
8011   "phaddd\t{%2, %0|%0, %2}"
8012   [(set_attr "type" "sseiadd")
8013    (set_attr "atom_unit" "complex")
8014    (set_attr "prefix_extra" "1")
8015    (set_attr "mode" "DI")])
8016
8017 (define_insn "*avx_phaddswv8hi3"
8018   [(set (match_operand:V8HI 0 "register_operand" "=x")
8019         (vec_concat:V8HI
8020           (vec_concat:V4HI
8021             (vec_concat:V2HI
8022               (ss_plus:HI
8023                 (vec_select:HI
8024                   (match_operand:V8HI 1 "register_operand" "x")
8025                   (parallel [(const_int 0)]))
8026                 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
8027               (ss_plus:HI
8028                 (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
8029                 (vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
8030             (vec_concat:V2HI
8031               (ss_plus:HI
8032                 (vec_select:HI (match_dup 1) (parallel [(const_int 4)]))
8033                 (vec_select:HI (match_dup 1) (parallel [(const_int 5)])))
8034               (ss_plus:HI
8035                 (vec_select:HI (match_dup 1) (parallel [(const_int 6)]))
8036                 (vec_select:HI (match_dup 1) (parallel [(const_int 7)])))))
8037           (vec_concat:V4HI
8038             (vec_concat:V2HI
8039               (ss_plus:HI
8040                 (vec_select:HI
8041                   (match_operand:V8HI 2 "nonimmediate_operand" "xm")
8042                   (parallel [(const_int 0)]))
8043                 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
8044               (ss_plus:HI
8045                 (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
8046                 (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))
8047             (vec_concat:V2HI
8048               (ss_plus:HI
8049                 (vec_select:HI (match_dup 2) (parallel [(const_int 4)]))
8050                 (vec_select:HI (match_dup 2) (parallel [(const_int 5)])))
8051               (ss_plus:HI
8052                 (vec_select:HI (match_dup 2) (parallel [(const_int 6)]))
8053                 (vec_select:HI (match_dup 2) (parallel [(const_int 7)])))))))]
8054   "TARGET_AVX"
8055   "vphaddsw\t{%2, %1, %0|%0, %1, %2}"
8056   [(set_attr "type" "sseiadd")
8057    (set_attr "prefix" "vex")
8058    (set_attr "mode" "TI")])
8059
8060 (define_insn "ssse3_phaddswv8hi3"
8061   [(set (match_operand:V8HI 0 "register_operand" "=x")
8062         (vec_concat:V8HI
8063           (vec_concat:V4HI
8064             (vec_concat:V2HI
8065               (ss_plus:HI
8066                 (vec_select:HI
8067                   (match_operand:V8HI 1 "register_operand" "0")
8068                   (parallel [(const_int 0)]))
8069                 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
8070               (ss_plus:HI
8071                 (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
8072                 (vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
8073             (vec_concat:V2HI
8074               (ss_plus:HI
8075                 (vec_select:HI (match_dup 1) (parallel [(const_int 4)]))
8076                 (vec_select:HI (match_dup 1) (parallel [(const_int 5)])))
8077               (ss_plus:HI
8078                 (vec_select:HI (match_dup 1) (parallel [(const_int 6)]))
8079                 (vec_select:HI (match_dup 1) (parallel [(const_int 7)])))))
8080           (vec_concat:V4HI
8081             (vec_concat:V2HI
8082               (ss_plus:HI
8083                 (vec_select:HI
8084                   (match_operand:V8HI 2 "nonimmediate_operand" "xm")
8085                   (parallel [(const_int 0)]))
8086                 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
8087               (ss_plus:HI
8088                 (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
8089                 (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))
8090             (vec_concat:V2HI
8091               (ss_plus:HI
8092                 (vec_select:HI (match_dup 2) (parallel [(const_int 4)]))
8093                 (vec_select:HI (match_dup 2) (parallel [(const_int 5)])))
8094               (ss_plus:HI
8095                 (vec_select:HI (match_dup 2) (parallel [(const_int 6)]))
8096                 (vec_select:HI (match_dup 2) (parallel [(const_int 7)])))))))]
8097   "TARGET_SSSE3"
8098   "phaddsw\t{%2, %0|%0, %2}"
8099   [(set_attr "type" "sseiadd")
8100    (set_attr "atom_unit" "complex")
8101    (set_attr "prefix_data16" "1")
8102    (set_attr "prefix_extra" "1")
8103    (set_attr "mode" "TI")])
8104
8105 (define_insn "ssse3_phaddswv4hi3"
8106   [(set (match_operand:V4HI 0 "register_operand" "=y")
8107         (vec_concat:V4HI
8108           (vec_concat:V2HI
8109             (ss_plus:HI
8110               (vec_select:HI
8111                 (match_operand:V4HI 1 "register_operand" "0")
8112                 (parallel [(const_int 0)]))
8113               (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
8114             (ss_plus:HI
8115               (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
8116               (vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
8117           (vec_concat:V2HI
8118             (ss_plus:HI
8119               (vec_select:HI
8120                 (match_operand:V4HI 2 "nonimmediate_operand" "ym")
8121                 (parallel [(const_int 0)]))
8122               (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
8123             (ss_plus:HI
8124               (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
8125               (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))))]
8126   "TARGET_SSSE3"
8127   "phaddsw\t{%2, %0|%0, %2}"
8128   [(set_attr "type" "sseiadd")
8129    (set_attr "atom_unit" "complex")
8130    (set_attr "prefix_extra" "1")
8131    (set_attr "mode" "DI")])
8132
8133 (define_insn "*avx_phsubwv8hi3"
8134   [(set (match_operand:V8HI 0 "register_operand" "=x")
8135         (vec_concat:V8HI
8136           (vec_concat:V4HI
8137             (vec_concat:V2HI
8138               (minus:HI
8139                 (vec_select:HI
8140                   (match_operand:V8HI 1 "register_operand" "x")
8141                   (parallel [(const_int 0)]))
8142                 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
8143               (minus:HI
8144                 (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
8145                 (vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
8146             (vec_concat:V2HI
8147               (minus:HI
8148                 (vec_select:HI (match_dup 1) (parallel [(const_int 4)]))
8149                 (vec_select:HI (match_dup 1) (parallel [(const_int 5)])))
8150               (minus:HI
8151                 (vec_select:HI (match_dup 1) (parallel [(const_int 6)]))
8152                 (vec_select:HI (match_dup 1) (parallel [(const_int 7)])))))
8153           (vec_concat:V4HI
8154             (vec_concat:V2HI
8155               (minus:HI
8156                 (vec_select:HI
8157                   (match_operand:V8HI 2 "nonimmediate_operand" "xm")
8158                   (parallel [(const_int 0)]))
8159                 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
8160               (minus:HI
8161                 (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
8162                 (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))
8163             (vec_concat:V2HI
8164               (minus:HI
8165                 (vec_select:HI (match_dup 2) (parallel [(const_int 4)]))
8166                 (vec_select:HI (match_dup 2) (parallel [(const_int 5)])))
8167               (minus:HI
8168                 (vec_select:HI (match_dup 2) (parallel [(const_int 6)]))
8169                 (vec_select:HI (match_dup 2) (parallel [(const_int 7)])))))))]
8170   "TARGET_AVX"
8171   "vphsubw\t{%2, %1, %0|%0, %1, %2}"
8172   [(set_attr "type" "sseiadd")
8173    (set_attr "prefix" "vex")
8174    (set_attr "mode" "TI")])
8175
8176 (define_insn "ssse3_phsubwv8hi3"
8177   [(set (match_operand:V8HI 0 "register_operand" "=x")
8178         (vec_concat:V8HI
8179           (vec_concat:V4HI
8180             (vec_concat:V2HI
8181               (minus:HI
8182                 (vec_select:HI
8183                   (match_operand:V8HI 1 "register_operand" "0")
8184                   (parallel [(const_int 0)]))
8185                 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
8186               (minus:HI
8187                 (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
8188                 (vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
8189             (vec_concat:V2HI
8190               (minus:HI
8191                 (vec_select:HI (match_dup 1) (parallel [(const_int 4)]))
8192                 (vec_select:HI (match_dup 1) (parallel [(const_int 5)])))
8193               (minus:HI
8194                 (vec_select:HI (match_dup 1) (parallel [(const_int 6)]))
8195                 (vec_select:HI (match_dup 1) (parallel [(const_int 7)])))))
8196           (vec_concat:V4HI
8197             (vec_concat:V2HI
8198               (minus:HI
8199                 (vec_select:HI
8200                   (match_operand:V8HI 2 "nonimmediate_operand" "xm")
8201                   (parallel [(const_int 0)]))
8202                 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
8203               (minus:HI
8204                 (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
8205                 (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))
8206             (vec_concat:V2HI
8207               (minus:HI
8208                 (vec_select:HI (match_dup 2) (parallel [(const_int 4)]))
8209                 (vec_select:HI (match_dup 2) (parallel [(const_int 5)])))
8210               (minus:HI
8211                 (vec_select:HI (match_dup 2) (parallel [(const_int 6)]))
8212                 (vec_select:HI (match_dup 2) (parallel [(const_int 7)])))))))]
8213   "TARGET_SSSE3"
8214   "phsubw\t{%2, %0|%0, %2}"
8215   [(set_attr "type" "sseiadd")
8216    (set_attr "atom_unit" "complex")
8217    (set_attr "prefix_data16" "1")
8218    (set_attr "prefix_extra" "1")
8219    (set_attr "mode" "TI")])
8220
8221 (define_insn "ssse3_phsubwv4hi3"
8222   [(set (match_operand:V4HI 0 "register_operand" "=y")
8223         (vec_concat:V4HI
8224           (vec_concat:V2HI
8225             (minus:HI
8226               (vec_select:HI
8227                 (match_operand:V4HI 1 "register_operand" "0")
8228                 (parallel [(const_int 0)]))
8229               (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
8230             (minus:HI
8231               (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
8232               (vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
8233           (vec_concat:V2HI
8234             (minus:HI
8235               (vec_select:HI
8236                 (match_operand:V4HI 2 "nonimmediate_operand" "ym")
8237                 (parallel [(const_int 0)]))
8238               (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
8239             (minus:HI
8240               (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
8241               (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))))]
8242   "TARGET_SSSE3"
8243   "phsubw\t{%2, %0|%0, %2}"
8244   [(set_attr "type" "sseiadd")
8245    (set_attr "atom_unit" "complex")
8246    (set_attr "prefix_extra" "1")
8247    (set_attr "mode" "DI")])
8248
8249 (define_insn "*avx_phsubdv4si3"
8250   [(set (match_operand:V4SI 0 "register_operand" "=x")
8251         (vec_concat:V4SI
8252           (vec_concat:V2SI
8253             (minus:SI
8254               (vec_select:SI
8255                 (match_operand:V4SI 1 "register_operand" "x")
8256                 (parallel [(const_int 0)]))
8257               (vec_select:SI (match_dup 1) (parallel [(const_int 1)])))
8258             (minus:SI
8259               (vec_select:SI (match_dup 1) (parallel [(const_int 2)]))
8260               (vec_select:SI (match_dup 1) (parallel [(const_int 3)]))))
8261           (vec_concat:V2SI
8262             (minus:SI
8263               (vec_select:SI
8264                 (match_operand:V4SI 2 "nonimmediate_operand" "xm")
8265                 (parallel [(const_int 0)]))
8266               (vec_select:SI (match_dup 2) (parallel [(const_int 1)])))
8267             (minus:SI
8268               (vec_select:SI (match_dup 2) (parallel [(const_int 2)]))
8269               (vec_select:SI (match_dup 2) (parallel [(const_int 3)]))))))]
8270   "TARGET_AVX"
8271   "vphsubd\t{%2, %1, %0|%0, %1, %2}"
8272   [(set_attr "type" "sseiadd")
8273    (set_attr "prefix" "vex")
8274    (set_attr "mode" "TI")])
8275
8276 (define_insn "ssse3_phsubdv4si3"
8277   [(set (match_operand:V4SI 0 "register_operand" "=x")
8278         (vec_concat:V4SI
8279           (vec_concat:V2SI
8280             (minus:SI
8281               (vec_select:SI
8282                 (match_operand:V4SI 1 "register_operand" "0")
8283                 (parallel [(const_int 0)]))
8284               (vec_select:SI (match_dup 1) (parallel [(const_int 1)])))
8285             (minus:SI
8286               (vec_select:SI (match_dup 1) (parallel [(const_int 2)]))
8287               (vec_select:SI (match_dup 1) (parallel [(const_int 3)]))))
8288           (vec_concat:V2SI
8289             (minus:SI
8290               (vec_select:SI
8291                 (match_operand:V4SI 2 "nonimmediate_operand" "xm")
8292                 (parallel [(const_int 0)]))
8293               (vec_select:SI (match_dup 2) (parallel [(const_int 1)])))
8294             (minus:SI
8295               (vec_select:SI (match_dup 2) (parallel [(const_int 2)]))
8296               (vec_select:SI (match_dup 2) (parallel [(const_int 3)]))))))]
8297   "TARGET_SSSE3"
8298   "phsubd\t{%2, %0|%0, %2}"
8299   [(set_attr "type" "sseiadd")
8300    (set_attr "atom_unit" "complex")
8301    (set_attr "prefix_data16" "1")
8302    (set_attr "prefix_extra" "1")
8303    (set_attr "mode" "TI")])
8304
8305 (define_insn "ssse3_phsubdv2si3"
8306   [(set (match_operand:V2SI 0 "register_operand" "=y")
8307         (vec_concat:V2SI
8308           (minus:SI
8309             (vec_select:SI
8310               (match_operand:V2SI 1 "register_operand" "0")
8311               (parallel [(const_int 0)]))
8312             (vec_select:SI (match_dup 1) (parallel [(const_int 1)])))
8313           (minus:SI
8314             (vec_select:SI
8315               (match_operand:V2SI 2 "nonimmediate_operand" "ym")
8316               (parallel [(const_int 0)]))
8317             (vec_select:SI (match_dup 2) (parallel [(const_int 1)])))))]
8318   "TARGET_SSSE3"
8319   "phsubd\t{%2, %0|%0, %2}"
8320   [(set_attr "type" "sseiadd")
8321    (set_attr "atom_unit" "complex")
8322    (set_attr "prefix_extra" "1")
8323    (set_attr "mode" "DI")])
8324
8325 (define_insn "*avx_phsubswv8hi3"
8326   [(set (match_operand:V8HI 0 "register_operand" "=x")
8327         (vec_concat:V8HI
8328           (vec_concat:V4HI
8329             (vec_concat:V2HI
8330               (ss_minus:HI
8331                 (vec_select:HI
8332                   (match_operand:V8HI 1 "register_operand" "x")
8333                   (parallel [(const_int 0)]))
8334                 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
8335               (ss_minus:HI
8336                 (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
8337                 (vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
8338             (vec_concat:V2HI
8339               (ss_minus:HI
8340                 (vec_select:HI (match_dup 1) (parallel [(const_int 4)]))
8341                 (vec_select:HI (match_dup 1) (parallel [(const_int 5)])))
8342               (ss_minus:HI
8343                 (vec_select:HI (match_dup 1) (parallel [(const_int 6)]))
8344                 (vec_select:HI (match_dup 1) (parallel [(const_int 7)])))))
8345           (vec_concat:V4HI
8346             (vec_concat:V2HI
8347               (ss_minus:HI
8348                 (vec_select:HI
8349                   (match_operand:V8HI 2 "nonimmediate_operand" "xm")
8350                   (parallel [(const_int 0)]))
8351                 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
8352               (ss_minus:HI
8353                 (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
8354                 (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))
8355             (vec_concat:V2HI
8356               (ss_minus:HI
8357                 (vec_select:HI (match_dup 2) (parallel [(const_int 4)]))
8358                 (vec_select:HI (match_dup 2) (parallel [(const_int 5)])))
8359               (ss_minus:HI
8360                 (vec_select:HI (match_dup 2) (parallel [(const_int 6)]))
8361                 (vec_select:HI (match_dup 2) (parallel [(const_int 7)])))))))]
8362   "TARGET_AVX"
8363   "vphsubsw\t{%2, %1, %0|%0, %1, %2}"
8364   [(set_attr "type" "sseiadd")
8365    (set_attr "prefix" "vex")
8366    (set_attr "mode" "TI")])
8367
8368 (define_insn "ssse3_phsubswv8hi3"
8369   [(set (match_operand:V8HI 0 "register_operand" "=x")
8370         (vec_concat:V8HI
8371           (vec_concat:V4HI
8372             (vec_concat:V2HI
8373               (ss_minus:HI
8374                 (vec_select:HI
8375                   (match_operand:V8HI 1 "register_operand" "0")
8376                   (parallel [(const_int 0)]))
8377                 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
8378               (ss_minus:HI
8379                 (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
8380                 (vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
8381             (vec_concat:V2HI
8382               (ss_minus:HI
8383                 (vec_select:HI (match_dup 1) (parallel [(const_int 4)]))
8384                 (vec_select:HI (match_dup 1) (parallel [(const_int 5)])))
8385               (ss_minus:HI
8386                 (vec_select:HI (match_dup 1) (parallel [(const_int 6)]))
8387                 (vec_select:HI (match_dup 1) (parallel [(const_int 7)])))))
8388           (vec_concat:V4HI
8389             (vec_concat:V2HI
8390               (ss_minus:HI
8391                 (vec_select:HI
8392                   (match_operand:V8HI 2 "nonimmediate_operand" "xm")
8393                   (parallel [(const_int 0)]))
8394                 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
8395               (ss_minus:HI
8396                 (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
8397                 (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))
8398             (vec_concat:V2HI
8399               (ss_minus:HI
8400                 (vec_select:HI (match_dup 2) (parallel [(const_int 4)]))
8401                 (vec_select:HI (match_dup 2) (parallel [(const_int 5)])))
8402               (ss_minus:HI
8403                 (vec_select:HI (match_dup 2) (parallel [(const_int 6)]))
8404                 (vec_select:HI (match_dup 2) (parallel [(const_int 7)])))))))]
8405   "TARGET_SSSE3"
8406   "phsubsw\t{%2, %0|%0, %2}"
8407   [(set_attr "type" "sseiadd")
8408    (set_attr "atom_unit" "complex")
8409    (set_attr "prefix_data16" "1")
8410    (set_attr "prefix_extra" "1")
8411    (set_attr "mode" "TI")])
8412
8413 (define_insn "ssse3_phsubswv4hi3"
8414   [(set (match_operand:V4HI 0 "register_operand" "=y")
8415         (vec_concat:V4HI
8416           (vec_concat:V2HI
8417             (ss_minus:HI
8418               (vec_select:HI
8419                 (match_operand:V4HI 1 "register_operand" "0")
8420                 (parallel [(const_int 0)]))
8421               (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
8422             (ss_minus:HI
8423               (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
8424               (vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
8425           (vec_concat:V2HI
8426             (ss_minus:HI
8427               (vec_select:HI
8428                 (match_operand:V4HI 2 "nonimmediate_operand" "ym")
8429                 (parallel [(const_int 0)]))
8430               (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
8431             (ss_minus:HI
8432               (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
8433               (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))))]
8434   "TARGET_SSSE3"
8435   "phsubsw\t{%2, %0|%0, %2}"
8436   [(set_attr "type" "sseiadd")
8437    (set_attr "atom_unit" "complex")
8438    (set_attr "prefix_extra" "1")
8439    (set_attr "mode" "DI")])
8440
8441 (define_insn "*avx_pmaddubsw128"
8442   [(set (match_operand:V8HI 0 "register_operand" "=x")
8443         (ss_plus:V8HI
8444           (mult:V8HI
8445             (zero_extend:V8HI
8446               (vec_select:V4QI
8447                 (match_operand:V16QI 1 "register_operand" "x")
8448                 (parallel [(const_int 0)
8449                            (const_int 2)
8450                            (const_int 4)
8451                            (const_int 6)
8452                            (const_int 8)
8453                            (const_int 10)
8454                            (const_int 12)
8455                            (const_int 14)])))
8456             (sign_extend:V8HI
8457               (vec_select:V8QI
8458                 (match_operand:V16QI 2 "nonimmediate_operand" "xm")
8459                 (parallel [(const_int 0)
8460                            (const_int 2)
8461                            (const_int 4)
8462                            (const_int 6)
8463                            (const_int 8)
8464                            (const_int 10)
8465                            (const_int 12)
8466                            (const_int 14)]))))
8467           (mult:V8HI
8468             (zero_extend:V8HI
8469               (vec_select:V16QI (match_dup 1)
8470                 (parallel [(const_int 1)
8471                            (const_int 3)
8472                            (const_int 5)
8473                            (const_int 7)
8474                            (const_int 9)
8475                            (const_int 11)
8476                            (const_int 13)
8477                            (const_int 15)])))
8478             (sign_extend:V8HI
8479               (vec_select:V16QI (match_dup 2)
8480                 (parallel [(const_int 1)
8481                            (const_int 3)
8482                            (const_int 5)
8483                            (const_int 7)
8484                            (const_int 9)
8485                            (const_int 11)
8486                            (const_int 13)
8487                            (const_int 15)]))))))]
8488   "TARGET_AVX"
8489   "vpmaddubsw\t{%2, %1, %0|%0, %1, %2}"
8490   [(set_attr "type" "sseiadd")
8491    (set_attr "prefix" "vex")
8492    (set_attr "mode" "TI")])
8493
8494 (define_insn "ssse3_pmaddubsw128"
8495   [(set (match_operand:V8HI 0 "register_operand" "=x")
8496         (ss_plus:V8HI
8497           (mult:V8HI
8498             (zero_extend:V8HI
8499               (vec_select:V4QI
8500                 (match_operand:V16QI 1 "register_operand" "0")
8501                 (parallel [(const_int 0)
8502                            (const_int 2)
8503                            (const_int 4)
8504                            (const_int 6)
8505                            (const_int 8)
8506                            (const_int 10)
8507                            (const_int 12)
8508                            (const_int 14)])))
8509             (sign_extend:V8HI
8510               (vec_select:V8QI
8511                 (match_operand:V16QI 2 "nonimmediate_operand" "xm")
8512                 (parallel [(const_int 0)
8513                            (const_int 2)
8514                            (const_int 4)
8515                            (const_int 6)
8516                            (const_int 8)
8517                            (const_int 10)
8518                            (const_int 12)
8519                            (const_int 14)]))))
8520           (mult:V8HI
8521             (zero_extend:V8HI
8522               (vec_select:V16QI (match_dup 1)
8523                 (parallel [(const_int 1)
8524                            (const_int 3)
8525                            (const_int 5)
8526                            (const_int 7)
8527                            (const_int 9)
8528                            (const_int 11)
8529                            (const_int 13)
8530                            (const_int 15)])))
8531             (sign_extend:V8HI
8532               (vec_select:V16QI (match_dup 2)
8533                 (parallel [(const_int 1)
8534                            (const_int 3)
8535                            (const_int 5)
8536                            (const_int 7)
8537                            (const_int 9)
8538                            (const_int 11)
8539                            (const_int 13)
8540                            (const_int 15)]))))))]
8541   "TARGET_SSSE3"
8542   "pmaddubsw\t{%2, %0|%0, %2}"
8543   [(set_attr "type" "sseiadd")
8544    (set_attr "atom_unit" "simul")
8545    (set_attr "prefix_data16" "1")
8546    (set_attr "prefix_extra" "1")
8547    (set_attr "mode" "TI")])
8548
8549 (define_insn "ssse3_pmaddubsw"
8550   [(set (match_operand:V4HI 0 "register_operand" "=y")
8551         (ss_plus:V4HI
8552           (mult:V4HI
8553             (zero_extend:V4HI
8554               (vec_select:V4QI
8555                 (match_operand:V8QI 1 "register_operand" "0")
8556                 (parallel [(const_int 0)
8557                            (const_int 2)
8558                            (const_int 4)
8559                            (const_int 6)])))
8560             (sign_extend:V4HI
8561               (vec_select:V4QI
8562                 (match_operand:V8QI 2 "nonimmediate_operand" "ym")
8563                 (parallel [(const_int 0)
8564                            (const_int 2)
8565                            (const_int 4)
8566                            (const_int 6)]))))
8567           (mult:V4HI
8568             (zero_extend:V4HI
8569               (vec_select:V8QI (match_dup 1)
8570                 (parallel [(const_int 1)
8571                            (const_int 3)
8572                            (const_int 5)
8573                            (const_int 7)])))
8574             (sign_extend:V4HI
8575               (vec_select:V8QI (match_dup 2)
8576                 (parallel [(const_int 1)
8577                            (const_int 3)
8578                            (const_int 5)
8579                            (const_int 7)]))))))]
8580   "TARGET_SSSE3"
8581   "pmaddubsw\t{%2, %0|%0, %2}"
8582   [(set_attr "type" "sseiadd")
8583    (set_attr "atom_unit" "simul")
8584    (set_attr "prefix_extra" "1")
8585    (set_attr "mode" "DI")])
8586
8587 (define_expand "ssse3_pmulhrswv8hi3"
8588   [(set (match_operand:V8HI 0 "register_operand" "")
8589         (truncate:V8HI
8590           (lshiftrt:V8SI
8591             (plus:V8SI
8592               (lshiftrt:V8SI
8593                 (mult:V8SI
8594                   (sign_extend:V8SI
8595                     (match_operand:V8HI 1 "nonimmediate_operand" ""))
8596                   (sign_extend:V8SI
8597                     (match_operand:V8HI 2 "nonimmediate_operand" "")))
8598                 (const_int 14))
8599               (const_vector:V8HI [(const_int 1) (const_int 1)
8600                                   (const_int 1) (const_int 1)
8601                                   (const_int 1) (const_int 1)
8602                                   (const_int 1) (const_int 1)]))
8603             (const_int 1))))]
8604   "TARGET_SSSE3"
8605   "ix86_fixup_binary_operands_no_copy (MULT, V8HImode, operands);")
8606
8607 (define_insn "*avx_pmulhrswv8hi3"
8608   [(set (match_operand:V8HI 0 "register_operand" "=x")
8609         (truncate:V8HI
8610           (lshiftrt:V8SI
8611             (plus:V8SI
8612               (lshiftrt:V8SI
8613                 (mult:V8SI
8614                   (sign_extend:V8SI
8615                     (match_operand:V8HI 1 "nonimmediate_operand" "%x"))
8616                   (sign_extend:V8SI
8617                     (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
8618                 (const_int 14))
8619               (const_vector:V8HI [(const_int 1) (const_int 1)
8620                                   (const_int 1) (const_int 1)
8621                                   (const_int 1) (const_int 1)
8622                                   (const_int 1) (const_int 1)]))
8623             (const_int 1))))]
8624   "TARGET_AVX && ix86_binary_operator_ok (MULT, V8HImode, operands)"
8625   "vpmulhrsw\t{%2, %1, %0|%0, %1, %2}"
8626   [(set_attr "type" "sseimul")
8627    (set_attr "prefix" "vex")
8628    (set_attr "mode" "TI")])
8629
8630 (define_insn "*ssse3_pmulhrswv8hi3"
8631   [(set (match_operand:V8HI 0 "register_operand" "=x")
8632         (truncate:V8HI
8633           (lshiftrt:V8SI
8634             (plus:V8SI
8635               (lshiftrt:V8SI
8636                 (mult:V8SI
8637                   (sign_extend:V8SI
8638                     (match_operand:V8HI 1 "nonimmediate_operand" "%0"))
8639                   (sign_extend:V8SI
8640                     (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
8641                 (const_int 14))
8642               (const_vector:V8HI [(const_int 1) (const_int 1)
8643                                   (const_int 1) (const_int 1)
8644                                   (const_int 1) (const_int 1)
8645                                   (const_int 1) (const_int 1)]))
8646             (const_int 1))))]
8647   "TARGET_SSSE3 && ix86_binary_operator_ok (MULT, V8HImode, operands)"
8648   "pmulhrsw\t{%2, %0|%0, %2}"
8649   [(set_attr "type" "sseimul")
8650    (set_attr "prefix_data16" "1")
8651    (set_attr "prefix_extra" "1")
8652    (set_attr "mode" "TI")])
8653
8654 (define_expand "ssse3_pmulhrswv4hi3"
8655   [(set (match_operand:V4HI 0 "register_operand" "")
8656         (truncate:V4HI
8657           (lshiftrt:V4SI
8658             (plus:V4SI
8659               (lshiftrt:V4SI
8660                 (mult:V4SI
8661                   (sign_extend:V4SI
8662                     (match_operand:V4HI 1 "nonimmediate_operand" ""))
8663                   (sign_extend:V4SI
8664                     (match_operand:V4HI 2 "nonimmediate_operand" "")))
8665                 (const_int 14))
8666               (const_vector:V4HI [(const_int 1) (const_int 1)
8667                                   (const_int 1) (const_int 1)]))
8668             (const_int 1))))]
8669   "TARGET_SSSE3"
8670   "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
8671
8672 (define_insn "*ssse3_pmulhrswv4hi3"
8673   [(set (match_operand:V4HI 0 "register_operand" "=y")
8674         (truncate:V4HI
8675           (lshiftrt:V4SI
8676             (plus:V4SI
8677               (lshiftrt:V4SI
8678                 (mult:V4SI
8679                   (sign_extend:V4SI
8680                     (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
8681                   (sign_extend:V4SI
8682                     (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
8683                 (const_int 14))
8684               (const_vector:V4HI [(const_int 1) (const_int 1)
8685                                   (const_int 1) (const_int 1)]))
8686             (const_int 1))))]
8687   "TARGET_SSSE3 && ix86_binary_operator_ok (MULT, V4HImode, operands)"
8688   "pmulhrsw\t{%2, %0|%0, %2}"
8689   [(set_attr "type" "sseimul")
8690    (set_attr "prefix_extra" "1")
8691    (set_attr "mode" "DI")])
8692
8693 (define_insn "*avx_pshufbv16qi3"
8694   [(set (match_operand:V16QI 0 "register_operand" "=x")
8695         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
8696                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
8697                       UNSPEC_PSHUFB))]
8698   "TARGET_AVX"
8699   "vpshufb\t{%2, %1, %0|%0, %1, %2}";
8700   [(set_attr "type" "sselog1")
8701    (set_attr "prefix" "vex")
8702    (set_attr "mode" "TI")])
8703
8704 (define_insn "ssse3_pshufbv16qi3"
8705   [(set (match_operand:V16QI 0 "register_operand" "=x")
8706         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "0")
8707                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
8708                       UNSPEC_PSHUFB))]
8709   "TARGET_SSSE3"
8710   "pshufb\t{%2, %0|%0, %2}";
8711   [(set_attr "type" "sselog1")
8712    (set_attr "prefix_data16" "1")
8713    (set_attr "prefix_extra" "1")
8714    (set_attr "mode" "TI")])
8715
8716 (define_insn "ssse3_pshufbv8qi3"
8717   [(set (match_operand:V8QI 0 "register_operand" "=y")
8718         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "0")
8719                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
8720                      UNSPEC_PSHUFB))]
8721   "TARGET_SSSE3"
8722   "pshufb\t{%2, %0|%0, %2}";
8723   [(set_attr "type" "sselog1")
8724    (set_attr "prefix_extra" "1")
8725    (set_attr "mode" "DI")])
8726
8727 (define_insn "*avx_psign<mode>3"
8728   [(set (match_operand:SSEMODE124 0 "register_operand" "=x")
8729         (unspec:SSEMODE124
8730           [(match_operand:SSEMODE124 1 "register_operand" "x")
8731            (match_operand:SSEMODE124 2 "nonimmediate_operand" "xm")]
8732           UNSPEC_PSIGN))]
8733   "TARGET_AVX"
8734   "vpsign<ssevecsize>\t{%2, %1, %0|%0, %1, %2}";
8735   [(set_attr "type" "sselog1")
8736    (set_attr "prefix" "vex")
8737    (set_attr "mode" "TI")])
8738
8739 (define_insn "ssse3_psign<mode>3"
8740   [(set (match_operand:SSEMODE124 0 "register_operand" "=x")
8741         (unspec:SSEMODE124
8742           [(match_operand:SSEMODE124 1 "register_operand" "0")
8743            (match_operand:SSEMODE124 2 "nonimmediate_operand" "xm")]
8744           UNSPEC_PSIGN))]
8745   "TARGET_SSSE3"
8746   "psign<ssevecsize>\t{%2, %0|%0, %2}";
8747   [(set_attr "type" "sselog1")
8748    (set_attr "prefix_data16" "1")
8749    (set_attr "prefix_extra" "1")
8750    (set_attr "mode" "TI")])
8751
8752 (define_insn "ssse3_psign<mode>3"
8753   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
8754         (unspec:MMXMODEI
8755           [(match_operand:MMXMODEI 1 "register_operand" "0")
8756            (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")]
8757           UNSPEC_PSIGN))]
8758   "TARGET_SSSE3"
8759   "psign<mmxvecsize>\t{%2, %0|%0, %2}";
8760   [(set_attr "type" "sselog1")
8761    (set_attr "prefix_extra" "1")
8762    (set_attr "mode" "DI")])
8763
8764 (define_insn "*avx_palignrti"
8765   [(set (match_operand:TI 0 "register_operand" "=x")
8766         (unspec:TI [(match_operand:TI 1 "register_operand" "x")
8767                     (match_operand:TI 2 "nonimmediate_operand" "xm")
8768                     (match_operand:SI 3 "const_0_to_255_mul_8_operand" "n")]
8769                    UNSPEC_PALIGNR))]
8770   "TARGET_AVX"
8771 {
8772   operands[3] = GEN_INT (INTVAL (operands[3]) / 8);
8773   return "vpalignr\t{%3, %2, %1, %0|%0, %1, %2, %3}";
8774 }
8775   [(set_attr "type" "sseishft")
8776    (set_attr "prefix" "vex")
8777    (set_attr "mode" "TI")])
8778
8779 (define_insn "ssse3_palignrti"
8780   [(set (match_operand:TI 0 "register_operand" "=x")
8781         (unspec:TI [(match_operand:TI 1 "register_operand" "0")
8782                     (match_operand:TI 2 "nonimmediate_operand" "xm")
8783                     (match_operand:SI 3 "const_0_to_255_mul_8_operand" "n")]
8784                    UNSPEC_PALIGNR))]
8785   "TARGET_SSSE3"
8786 {
8787   operands[3] = GEN_INT (INTVAL (operands[3]) / 8);
8788   return "palignr\t{%3, %2, %0|%0, %2, %3}";
8789 }
8790   [(set_attr "type" "sseishft")
8791    (set_attr "atom_unit" "sishuf")
8792    (set_attr "prefix_data16" "1")
8793    (set_attr "prefix_extra" "1")
8794    (set_attr "mode" "TI")])
8795
8796 (define_insn "ssse3_palignrdi"
8797   [(set (match_operand:DI 0 "register_operand" "=y")
8798         (unspec:DI [(match_operand:DI 1 "register_operand" "0")
8799                     (match_operand:DI 2 "nonimmediate_operand" "ym")
8800                     (match_operand:SI 3 "const_0_to_255_mul_8_operand" "n")]
8801                    UNSPEC_PALIGNR))]
8802   "TARGET_SSSE3"
8803 {
8804   operands[3] = GEN_INT (INTVAL (operands[3]) / 8);
8805   return "palignr\t{%3, %2, %0|%0, %2, %3}";
8806 }
8807   [(set_attr "type" "sseishft")
8808    (set_attr "atom_unit" "sishuf")
8809    (set_attr "prefix_extra" "1")
8810    (set_attr "mode" "DI")])
8811
8812 (define_insn "abs<mode>2"
8813   [(set (match_operand:SSEMODE124 0 "register_operand" "=x")
8814         (abs:SSEMODE124 (match_operand:SSEMODE124 1 "nonimmediate_operand" "xm")))]
8815   "TARGET_SSSE3"
8816   "%vpabs<ssevecsize>\t{%1, %0|%0, %1}"
8817   [(set_attr "type" "sselog1")
8818    (set_attr "prefix_data16" "1")
8819    (set_attr "prefix_extra" "1")
8820    (set_attr "prefix" "maybe_vex")
8821    (set_attr "mode" "TI")])
8822
8823 (define_insn "abs<mode>2"
8824   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
8825         (abs:MMXMODEI (match_operand:MMXMODEI 1 "nonimmediate_operand" "ym")))]
8826   "TARGET_SSSE3"
8827   "pabs<mmxvecsize>\t{%1, %0|%0, %1}";
8828   [(set_attr "type" "sselog1")
8829    (set_attr "prefix_extra" "1")
8830    (set_attr "mode" "DI")])
8831
8832 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8833 ;;
8834 ;; AMD SSE4A instructions
8835 ;;
8836 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8837
8838 (define_insn "sse4a_movnt<mode>"
8839   [(set (match_operand:MODEF 0 "memory_operand" "=m")
8840         (unspec:MODEF
8841           [(match_operand:MODEF 1 "register_operand" "x")]
8842           UNSPEC_MOVNT))]
8843   "TARGET_SSE4A"
8844   "movnts<ssemodefsuffix>\t{%1, %0|%0, %1}"
8845   [(set_attr "type" "ssemov")
8846    (set_attr "mode" "<MODE>")])
8847
8848 (define_insn "sse4a_vmmovnt<mode>"
8849   [(set (match_operand:<ssescalarmode> 0 "memory_operand" "=m")
8850         (unspec:<ssescalarmode>
8851           [(vec_select:<ssescalarmode>
8852              (match_operand:SSEMODEF2P 1 "register_operand" "x")
8853              (parallel [(const_int 0)]))]
8854           UNSPEC_MOVNT))]
8855   "TARGET_SSE4A"
8856   "movnts<ssemodesuffixf2c>\t{%1, %0|%0, %1}"
8857   [(set_attr "type" "ssemov")
8858    (set_attr "mode" "<ssescalarmode>")])
8859
8860 (define_insn "sse4a_extrqi"
8861   [(set (match_operand:V2DI 0 "register_operand" "=x")
8862         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0")
8863                       (match_operand 2 "const_int_operand" "")
8864                       (match_operand 3 "const_int_operand" "")]
8865                      UNSPEC_EXTRQI))]
8866   "TARGET_SSE4A"
8867   "extrq\t{%3, %2, %0|%0, %2, %3}"
8868   [(set_attr "type" "sse")
8869    (set_attr "prefix_data16" "1")
8870    (set_attr "mode" "TI")])
8871
8872 (define_insn "sse4a_extrq"
8873   [(set (match_operand:V2DI 0 "register_operand" "=x")
8874         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0")
8875                       (match_operand:V16QI 2 "register_operand" "x")]
8876                      UNSPEC_EXTRQ))]
8877   "TARGET_SSE4A"
8878   "extrq\t{%2, %0|%0, %2}"
8879   [(set_attr "type" "sse")
8880    (set_attr "prefix_data16" "1")
8881    (set_attr "mode" "TI")])
8882
8883 (define_insn "sse4a_insertqi"
8884   [(set (match_operand:V2DI 0 "register_operand" "=x")
8885         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0")
8886                       (match_operand:V2DI 2 "register_operand" "x")
8887                       (match_operand 3 "const_int_operand" "")
8888                       (match_operand 4 "const_int_operand" "")]
8889                      UNSPEC_INSERTQI))]
8890   "TARGET_SSE4A"
8891   "insertq\t{%4, %3, %2, %0|%0, %2, %3, %4}"
8892   [(set_attr "type" "sseins")
8893    (set_attr "prefix_rep" "1")
8894    (set_attr "mode" "TI")])
8895
8896 (define_insn "sse4a_insertq"
8897   [(set (match_operand:V2DI 0 "register_operand" "=x")
8898         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0")
8899                       (match_operand:V2DI 2 "register_operand" "x")]
8900                      UNSPEC_INSERTQ))]
8901   "TARGET_SSE4A"
8902   "insertq\t{%2, %0|%0, %2}"
8903   [(set_attr "type" "sseins")
8904    (set_attr "prefix_rep" "1")
8905    (set_attr "mode" "TI")])
8906
8907 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8908 ;;
8909 ;; Intel SSE4.1 instructions
8910 ;;
8911 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8912
8913 (define_insn "avx_blendp<avxmodesuffixf2c><avxmodesuffix>"
8914   [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x")
8915         (vec_merge:AVXMODEF2P
8916           (match_operand:AVXMODEF2P 2 "nonimmediate_operand" "xm")
8917           (match_operand:AVXMODEF2P 1 "register_operand" "x")
8918           (match_operand:SI 3 "const_0_to_<blendbits>_operand" "n")))]
8919   "TARGET_AVX"
8920   "vblendp<avxmodesuffixf2c>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
8921   [(set_attr "type" "ssemov")
8922    (set_attr "prefix" "vex")
8923    (set_attr "mode" "<avxvecmode>")])
8924
8925 (define_insn "avx_blendvp<avxmodesuffixf2c><avxmodesuffix>"
8926   [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x")
8927         (unspec:AVXMODEF2P
8928           [(match_operand:AVXMODEF2P 1 "register_operand" "x")
8929            (match_operand:AVXMODEF2P 2 "nonimmediate_operand" "xm")
8930            (match_operand:AVXMODEF2P 3 "register_operand" "x")]
8931           UNSPEC_BLENDV))]
8932   "TARGET_AVX"
8933   "vblendvp<avxmodesuffixf2c>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
8934   [(set_attr "type" "ssemov")
8935    (set_attr "prefix" "vex")
8936    (set_attr "mode" "<avxvecmode>")])
8937
8938 (define_insn "sse4_1_blendp<ssemodesuffixf2c>"
8939   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
8940         (vec_merge:SSEMODEF2P
8941           (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")
8942           (match_operand:SSEMODEF2P 1 "register_operand" "0")
8943           (match_operand:SI 3 "const_0_to_<blendbits>_operand" "n")))]
8944   "TARGET_SSE4_1"
8945   "blendp<ssemodesuffixf2c>\t{%3, %2, %0|%0, %2, %3}"
8946   [(set_attr "type" "ssemov")
8947    (set_attr "prefix_extra" "1")
8948    (set_attr "mode" "<MODE>")])
8949
8950 (define_insn "sse4_1_blendvp<ssemodesuffixf2c>"
8951   [(set (match_operand:SSEMODEF2P 0 "reg_not_xmm0_operand" "=x")
8952         (unspec:SSEMODEF2P
8953           [(match_operand:SSEMODEF2P 1 "reg_not_xmm0_operand" "0")
8954            (match_operand:SSEMODEF2P 2 "nonimm_not_xmm0_operand" "xm")
8955            (match_operand:SSEMODEF2P 3 "register_operand" "Yz")]
8956           UNSPEC_BLENDV))]
8957   "TARGET_SSE4_1"
8958   "blendvp<ssemodesuffixf2c>\t{%3, %2, %0|%0, %2, %3}"
8959   [(set_attr "type" "ssemov")
8960    (set_attr "prefix_extra" "1")
8961    (set_attr "mode" "<MODE>")])
8962
8963 (define_insn "avx_dpp<avxmodesuffixf2c><avxmodesuffix>"
8964   [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x")
8965         (unspec:AVXMODEF2P
8966           [(match_operand:AVXMODEF2P 1 "nonimmediate_operand" "%x")
8967            (match_operand:AVXMODEF2P 2 "nonimmediate_operand" "xm")
8968            (match_operand:SI 3 "const_0_to_255_operand" "n")]
8969           UNSPEC_DP))]
8970   "TARGET_AVX"
8971   "vdpp<avxmodesuffixf2c>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
8972   [(set_attr "type" "ssemul")
8973    (set_attr "prefix" "vex")
8974    (set_attr "mode" "<avxvecmode>")])
8975
8976 (define_insn "sse4_1_dpp<ssemodesuffixf2c>"
8977   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
8978         (unspec:SSEMODEF2P
8979           [(match_operand:SSEMODEF2P 1 "nonimmediate_operand" "%0")
8980            (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")
8981            (match_operand:SI 3 "const_0_to_255_operand" "n")]
8982           UNSPEC_DP))]
8983   "TARGET_SSE4_1"
8984   "dpp<ssemodesuffixf2c>\t{%3, %2, %0|%0, %2, %3}"
8985   [(set_attr "type" "ssemul")
8986    (set_attr "prefix_extra" "1")
8987    (set_attr "mode" "<MODE>")])
8988
8989 (define_insn "sse4_1_movntdqa"
8990   [(set (match_operand:V2DI 0 "register_operand" "=x")
8991         (unspec:V2DI [(match_operand:V2DI 1 "memory_operand" "m")]
8992                      UNSPEC_MOVNTDQA))]
8993   "TARGET_SSE4_1"
8994   "%vmovntdqa\t{%1, %0|%0, %1}"
8995   [(set_attr "type" "ssemov")
8996    (set_attr "prefix_extra" "1")
8997    (set_attr "prefix" "maybe_vex")
8998    (set_attr "mode" "TI")])
8999
9000 (define_insn "*avx_mpsadbw"
9001   [(set (match_operand:V16QI 0 "register_operand" "=x")
9002         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
9003                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")
9004                        (match_operand:SI 3 "const_0_to_255_operand" "n")]
9005                       UNSPEC_MPSADBW))]
9006   "TARGET_AVX"
9007   "vmpsadbw\t{%3, %2, %1, %0|%0, %1, %2, %3}"
9008   [(set_attr "type" "sselog1")
9009    (set_attr "prefix" "vex")
9010    (set_attr "mode" "TI")])
9011
9012 (define_insn "sse4_1_mpsadbw"
9013   [(set (match_operand:V16QI 0 "register_operand" "=x")
9014         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "0")
9015                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")
9016                        (match_operand:SI 3 "const_0_to_255_operand" "n")]
9017                       UNSPEC_MPSADBW))]
9018   "TARGET_SSE4_1"
9019   "mpsadbw\t{%3, %2, %0|%0, %2, %3}"
9020   [(set_attr "type" "sselog1")
9021    (set_attr "prefix_extra" "1")
9022    (set_attr "mode" "TI")])
9023
9024 (define_insn "*avx_packusdw"
9025   [(set (match_operand:V8HI 0 "register_operand" "=x")
9026         (vec_concat:V8HI
9027           (us_truncate:V4HI
9028             (match_operand:V4SI 1 "register_operand" "x"))
9029           (us_truncate:V4HI
9030             (match_operand:V4SI 2 "nonimmediate_operand" "xm"))))]
9031   "TARGET_AVX"
9032   "vpackusdw\t{%2, %1, %0|%0, %1, %2}"
9033   [(set_attr "type" "sselog")
9034    (set_attr "prefix" "vex")
9035    (set_attr "mode" "TI")])
9036
9037 (define_insn "sse4_1_packusdw"
9038   [(set (match_operand:V8HI 0 "register_operand" "=x")
9039         (vec_concat:V8HI
9040           (us_truncate:V4HI
9041             (match_operand:V4SI 1 "register_operand" "0"))
9042           (us_truncate:V4HI
9043             (match_operand:V4SI 2 "nonimmediate_operand" "xm"))))]
9044   "TARGET_SSE4_1"
9045   "packusdw\t{%2, %0|%0, %2}"
9046   [(set_attr "type" "sselog")
9047    (set_attr "prefix_extra" "1")
9048    (set_attr "mode" "TI")])
9049
9050 (define_insn "*avx_pblendvb"
9051   [(set (match_operand:V16QI 0 "register_operand" "=x")
9052         (unspec:V16QI [(match_operand:V16QI 1 "register_operand"  "x")
9053                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")
9054                        (match_operand:V16QI 3 "register_operand" "x")]
9055                       UNSPEC_BLENDV))]
9056   "TARGET_AVX"
9057   "vpblendvb\t{%3, %2, %1, %0|%0, %1, %2, %3}"
9058   [(set_attr "type" "ssemov")
9059    (set_attr "prefix" "vex")
9060    (set_attr "mode" "TI")])
9061
9062 (define_insn "sse4_1_pblendvb"
9063   [(set (match_operand:V16QI 0 "reg_not_xmm0_operand" "=x")
9064         (unspec:V16QI [(match_operand:V16QI 1 "reg_not_xmm0_operand"  "0")
9065                        (match_operand:V16QI 2 "nonimm_not_xmm0_operand" "xm")
9066                        (match_operand:V16QI 3 "register_operand" "Yz")]
9067                       UNSPEC_BLENDV))]
9068   "TARGET_SSE4_1"
9069   "pblendvb\t{%3, %2, %0|%0, %2, %3}"
9070   [(set_attr "type" "ssemov")
9071    (set_attr "prefix_extra" "1")
9072    (set_attr "mode" "TI")])
9073
9074 (define_insn "*avx_pblendw"
9075   [(set (match_operand:V8HI 0 "register_operand" "=x")
9076         (vec_merge:V8HI
9077           (match_operand:V8HI 2 "nonimmediate_operand" "xm")
9078           (match_operand:V8HI 1 "register_operand" "x")
9079           (match_operand:SI 3 "const_0_to_255_operand" "n")))]
9080   "TARGET_AVX"
9081   "vpblendw\t{%3, %2, %1, %0|%0, %1, %2, %3}"
9082   [(set_attr "type" "ssemov")
9083    (set_attr "prefix" "vex")
9084    (set_attr "mode" "TI")])
9085
9086 (define_insn "sse4_1_pblendw"
9087   [(set (match_operand:V8HI 0 "register_operand" "=x")
9088         (vec_merge:V8HI
9089           (match_operand:V8HI 2 "nonimmediate_operand" "xm")
9090           (match_operand:V8HI 1 "register_operand" "0")
9091           (match_operand:SI 3 "const_0_to_255_operand" "n")))]
9092   "TARGET_SSE4_1"
9093   "pblendw\t{%3, %2, %0|%0, %2, %3}"
9094   [(set_attr "type" "ssemov")
9095    (set_attr "prefix_extra" "1")
9096    (set_attr "mode" "TI")])
9097
9098 (define_insn "sse4_1_phminposuw"
9099   [(set (match_operand:V8HI 0 "register_operand" "=x")
9100         (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")]
9101                      UNSPEC_PHMINPOSUW))]
9102   "TARGET_SSE4_1"
9103   "%vphminposuw\t{%1, %0|%0, %1}"
9104   [(set_attr "type" "sselog1")
9105    (set_attr "prefix_extra" "1")
9106    (set_attr "prefix" "maybe_vex")
9107    (set_attr "mode" "TI")])
9108
9109 (define_insn "sse4_1_extendv8qiv8hi2"
9110   [(set (match_operand:V8HI 0 "register_operand" "=x")
9111         (sign_extend:V8HI
9112           (vec_select:V8QI
9113             (match_operand:V16QI 1 "register_operand" "x")
9114             (parallel [(const_int 0)
9115                        (const_int 1)
9116                        (const_int 2)
9117                        (const_int 3)
9118                        (const_int 4)
9119                        (const_int 5)
9120                        (const_int 6)
9121                        (const_int 7)]))))]
9122   "TARGET_SSE4_1"
9123   "%vpmovsxbw\t{%1, %0|%0, %1}"
9124   [(set_attr "type" "ssemov")
9125    (set_attr "prefix_extra" "1")
9126    (set_attr "prefix" "maybe_vex")
9127    (set_attr "mode" "TI")])
9128
9129 (define_insn "*sse4_1_extendv8qiv8hi2"
9130   [(set (match_operand:V8HI 0 "register_operand" "=x")
9131         (sign_extend:V8HI
9132           (vec_select:V8QI
9133             (vec_duplicate:V16QI
9134               (match_operand:V8QI 1 "nonimmediate_operand" "xm"))
9135             (parallel [(const_int 0)
9136                        (const_int 1)
9137                        (const_int 2)
9138                        (const_int 3)
9139                        (const_int 4)
9140                        (const_int 5)
9141                        (const_int 6)
9142                        (const_int 7)]))))]
9143   "TARGET_SSE4_1"
9144   "%vpmovsxbw\t{%1, %0|%0, %1}"
9145   [(set_attr "type" "ssemov")
9146    (set_attr "prefix_extra" "1")
9147    (set_attr "prefix" "maybe_vex")
9148    (set_attr "mode" "TI")])
9149
9150 (define_insn "sse4_1_extendv4qiv4si2"
9151   [(set (match_operand:V4SI 0 "register_operand" "=x")
9152         (sign_extend:V4SI
9153           (vec_select:V4QI
9154             (match_operand:V16QI 1 "register_operand" "x")
9155             (parallel [(const_int 0)
9156                        (const_int 1)
9157                        (const_int 2)
9158                        (const_int 3)]))))]
9159   "TARGET_SSE4_1"
9160   "%vpmovsxbd\t{%1, %0|%0, %1}"
9161   [(set_attr "type" "ssemov")
9162    (set_attr "prefix_extra" "1")
9163    (set_attr "prefix" "maybe_vex")
9164    (set_attr "mode" "TI")])
9165
9166 (define_insn "*sse4_1_extendv4qiv4si2"
9167   [(set (match_operand:V4SI 0 "register_operand" "=x")
9168         (sign_extend:V4SI
9169           (vec_select:V4QI
9170             (vec_duplicate:V16QI
9171               (match_operand:V4QI 1 "nonimmediate_operand" "xm"))
9172             (parallel [(const_int 0)
9173                        (const_int 1)
9174                        (const_int 2)
9175                        (const_int 3)]))))]
9176   "TARGET_SSE4_1"
9177   "%vpmovsxbd\t{%1, %0|%0, %1}"
9178   [(set_attr "type" "ssemov")
9179    (set_attr "prefix_extra" "1")
9180    (set_attr "prefix" "maybe_vex")
9181    (set_attr "mode" "TI")])
9182
9183 (define_insn "sse4_1_extendv2qiv2di2"
9184   [(set (match_operand:V2DI 0 "register_operand" "=x")
9185         (sign_extend:V2DI
9186           (vec_select:V2QI
9187             (match_operand:V16QI 1 "register_operand" "x")
9188             (parallel [(const_int 0)
9189                        (const_int 1)]))))]
9190   "TARGET_SSE4_1"
9191   "%vpmovsxbq\t{%1, %0|%0, %1}"
9192   [(set_attr "type" "ssemov")
9193    (set_attr "prefix_extra" "1")
9194    (set_attr "prefix" "maybe_vex")
9195    (set_attr "mode" "TI")])
9196
9197 (define_insn "*sse4_1_extendv2qiv2di2"
9198   [(set (match_operand:V2DI 0 "register_operand" "=x")
9199         (sign_extend:V2DI
9200           (vec_select:V2QI
9201             (vec_duplicate:V16QI
9202               (match_operand:V2QI 1 "nonimmediate_operand" "xm"))
9203             (parallel [(const_int 0)
9204                        (const_int 1)]))))]
9205   "TARGET_SSE4_1"
9206   "%vpmovsxbq\t{%1, %0|%0, %1}"
9207   [(set_attr "type" "ssemov")
9208    (set_attr "prefix_extra" "1")
9209    (set_attr "prefix" "maybe_vex")
9210    (set_attr "mode" "TI")])
9211
9212 (define_insn "sse4_1_extendv4hiv4si2"
9213   [(set (match_operand:V4SI 0 "register_operand" "=x")
9214         (sign_extend:V4SI
9215           (vec_select:V4HI
9216             (match_operand:V8HI 1 "register_operand" "x")
9217             (parallel [(const_int 0)
9218                        (const_int 1)
9219                        (const_int 2)
9220                        (const_int 3)]))))]
9221   "TARGET_SSE4_1"
9222   "%vpmovsxwd\t{%1, %0|%0, %1}"
9223   [(set_attr "type" "ssemov")
9224    (set_attr "prefix_extra" "1")
9225    (set_attr "prefix" "maybe_vex")
9226    (set_attr "mode" "TI")])
9227
9228 (define_insn "*sse4_1_extendv4hiv4si2"
9229   [(set (match_operand:V4SI 0 "register_operand" "=x")
9230         (sign_extend:V4SI
9231           (vec_select:V4HI
9232             (vec_duplicate:V8HI
9233               (match_operand:V2HI 1 "nonimmediate_operand" "xm"))
9234             (parallel [(const_int 0)
9235                        (const_int 1)
9236                        (const_int 2)
9237                        (const_int 3)]))))]
9238   "TARGET_SSE4_1"
9239   "%vpmovsxwd\t{%1, %0|%0, %1}"
9240   [(set_attr "type" "ssemov")
9241    (set_attr "prefix_extra" "1")
9242    (set_attr "prefix" "maybe_vex")
9243    (set_attr "mode" "TI")])
9244
9245 (define_insn "sse4_1_extendv2hiv2di2"
9246   [(set (match_operand:V2DI 0 "register_operand" "=x")
9247         (sign_extend:V2DI
9248           (vec_select:V2HI
9249             (match_operand:V8HI 1 "register_operand" "x")
9250             (parallel [(const_int 0)
9251                        (const_int 1)]))))]
9252   "TARGET_SSE4_1"
9253   "%vpmovsxwq\t{%1, %0|%0, %1}"
9254   [(set_attr "type" "ssemov")
9255    (set_attr "prefix_extra" "1")
9256    (set_attr "prefix" "maybe_vex")
9257    (set_attr "mode" "TI")])
9258
9259 (define_insn "*sse4_1_extendv2hiv2di2"
9260   [(set (match_operand:V2DI 0 "register_operand" "=x")
9261         (sign_extend:V2DI
9262           (vec_select:V2HI
9263             (vec_duplicate:V8HI
9264               (match_operand:V8HI 1 "nonimmediate_operand" "xm"))
9265             (parallel [(const_int 0)
9266                        (const_int 1)]))))]
9267   "TARGET_SSE4_1"
9268   "%vpmovsxwq\t{%1, %0|%0, %1}"
9269   [(set_attr "type" "ssemov")
9270    (set_attr "prefix_extra" "1")
9271    (set_attr "prefix" "maybe_vex")
9272    (set_attr "mode" "TI")])
9273
9274 (define_insn "sse4_1_extendv2siv2di2"
9275   [(set (match_operand:V2DI 0 "register_operand" "=x")
9276         (sign_extend:V2DI
9277           (vec_select:V2SI
9278             (match_operand:V4SI 1 "register_operand" "x")
9279             (parallel [(const_int 0)
9280                        (const_int 1)]))))]
9281   "TARGET_SSE4_1"
9282   "%vpmovsxdq\t{%1, %0|%0, %1}"
9283   [(set_attr "type" "ssemov")
9284    (set_attr "prefix_extra" "1")
9285    (set_attr "prefix" "maybe_vex")
9286    (set_attr "mode" "TI")])
9287
9288 (define_insn "*sse4_1_extendv2siv2di2"
9289   [(set (match_operand:V2DI 0 "register_operand" "=x")
9290         (sign_extend:V2DI
9291           (vec_select:V2SI
9292             (vec_duplicate:V4SI
9293               (match_operand:V2SI 1 "nonimmediate_operand" "xm"))
9294             (parallel [(const_int 0)
9295                        (const_int 1)]))))]
9296   "TARGET_SSE4_1"
9297   "%vpmovsxdq\t{%1, %0|%0, %1}"
9298   [(set_attr "type" "ssemov")
9299    (set_attr "prefix_extra" "1")
9300    (set_attr "prefix" "maybe_vex")
9301    (set_attr "mode" "TI")])
9302
9303 (define_insn "sse4_1_zero_extendv8qiv8hi2"
9304   [(set (match_operand:V8HI 0 "register_operand" "=x")
9305         (zero_extend:V8HI
9306           (vec_select:V8QI
9307             (match_operand:V16QI 1 "register_operand" "x")
9308             (parallel [(const_int 0)
9309                        (const_int 1)
9310                        (const_int 2)
9311                        (const_int 3)
9312                        (const_int 4)
9313                        (const_int 5)
9314                        (const_int 6)
9315                        (const_int 7)]))))]
9316   "TARGET_SSE4_1"
9317   "%vpmovzxbw\t{%1, %0|%0, %1}"
9318   [(set_attr "type" "ssemov")
9319    (set_attr "prefix_extra" "1")
9320    (set_attr "prefix" "maybe_vex")
9321    (set_attr "mode" "TI")])
9322
9323 (define_insn "*sse4_1_zero_extendv8qiv8hi2"
9324   [(set (match_operand:V8HI 0 "register_operand" "=x")
9325         (zero_extend:V8HI
9326           (vec_select:V8QI
9327             (vec_duplicate:V16QI
9328               (match_operand:V8QI 1 "nonimmediate_operand" "xm"))
9329             (parallel [(const_int 0)
9330                        (const_int 1)
9331                        (const_int 2)
9332                        (const_int 3)
9333                        (const_int 4)
9334                        (const_int 5)
9335                        (const_int 6)
9336                        (const_int 7)]))))]
9337   "TARGET_SSE4_1"
9338   "%vpmovzxbw\t{%1, %0|%0, %1}"
9339   [(set_attr "type" "ssemov")
9340    (set_attr "prefix_extra" "1")
9341    (set_attr "prefix" "maybe_vex")
9342    (set_attr "mode" "TI")])
9343
9344 (define_insn "sse4_1_zero_extendv4qiv4si2"
9345   [(set (match_operand:V4SI 0 "register_operand" "=x")
9346         (zero_extend:V4SI
9347           (vec_select:V4QI
9348             (match_operand:V16QI 1 "register_operand" "x")
9349             (parallel [(const_int 0)
9350                        (const_int 1)
9351                        (const_int 2)
9352                        (const_int 3)]))))]
9353   "TARGET_SSE4_1"
9354   "%vpmovzxbd\t{%1, %0|%0, %1}"
9355   [(set_attr "type" "ssemov")
9356    (set_attr "prefix_extra" "1")
9357    (set_attr "prefix" "maybe_vex")
9358    (set_attr "mode" "TI")])
9359
9360 (define_insn "*sse4_1_zero_extendv4qiv4si2"
9361   [(set (match_operand:V4SI 0 "register_operand" "=x")
9362         (zero_extend:V4SI
9363           (vec_select:V4QI
9364             (vec_duplicate:V16QI
9365               (match_operand:V4QI 1 "nonimmediate_operand" "xm"))
9366             (parallel [(const_int 0)
9367                        (const_int 1)
9368                        (const_int 2)
9369                        (const_int 3)]))))]
9370   "TARGET_SSE4_1"
9371   "%vpmovzxbd\t{%1, %0|%0, %1}"
9372   [(set_attr "type" "ssemov")
9373    (set_attr "prefix_extra" "1")
9374    (set_attr "prefix" "maybe_vex")
9375    (set_attr "mode" "TI")])
9376
9377 (define_insn "sse4_1_zero_extendv2qiv2di2"
9378   [(set (match_operand:V2DI 0 "register_operand" "=x")
9379         (zero_extend:V2DI
9380           (vec_select:V2QI
9381             (match_operand:V16QI 1 "register_operand" "x")
9382             (parallel [(const_int 0)
9383                        (const_int 1)]))))]
9384   "TARGET_SSE4_1"
9385   "%vpmovzxbq\t{%1, %0|%0, %1}"
9386   [(set_attr "type" "ssemov")
9387    (set_attr "prefix_extra" "1")
9388    (set_attr "prefix" "maybe_vex")
9389    (set_attr "mode" "TI")])
9390
9391 (define_insn "*sse4_1_zero_extendv2qiv2di2"
9392   [(set (match_operand:V2DI 0 "register_operand" "=x")
9393         (zero_extend:V2DI
9394           (vec_select:V2QI
9395             (vec_duplicate:V16QI
9396               (match_operand:V2QI 1 "nonimmediate_operand" "xm"))
9397             (parallel [(const_int 0)
9398                        (const_int 1)]))))]
9399   "TARGET_SSE4_1"
9400   "%vpmovzxbq\t{%1, %0|%0, %1}"
9401   [(set_attr "type" "ssemov")
9402    (set_attr "prefix_extra" "1")
9403    (set_attr "prefix" "maybe_vex")
9404    (set_attr "mode" "TI")])
9405
9406 (define_insn "sse4_1_zero_extendv4hiv4si2"
9407   [(set (match_operand:V4SI 0 "register_operand" "=x")
9408         (zero_extend:V4SI
9409           (vec_select:V4HI
9410             (match_operand:V8HI 1 "register_operand" "x")
9411             (parallel [(const_int 0)
9412                        (const_int 1)
9413                        (const_int 2)
9414                        (const_int 3)]))))]
9415   "TARGET_SSE4_1"
9416   "%vpmovzxwd\t{%1, %0|%0, %1}"
9417   [(set_attr "type" "ssemov")
9418    (set_attr "prefix_extra" "1")
9419    (set_attr "prefix" "maybe_vex")
9420    (set_attr "mode" "TI")])
9421
9422 (define_insn "*sse4_1_zero_extendv4hiv4si2"
9423   [(set (match_operand:V4SI 0 "register_operand" "=x")
9424         (zero_extend:V4SI
9425           (vec_select:V4HI
9426             (vec_duplicate:V8HI
9427               (match_operand:V4HI 1 "nonimmediate_operand" "xm"))
9428             (parallel [(const_int 0)
9429                        (const_int 1)
9430                        (const_int 2)
9431                        (const_int 3)]))))]
9432   "TARGET_SSE4_1"
9433   "%vpmovzxwd\t{%1, %0|%0, %1}"
9434   [(set_attr "type" "ssemov")
9435    (set_attr "prefix_extra" "1")
9436    (set_attr "prefix" "maybe_vex")
9437    (set_attr "mode" "TI")])
9438
9439 (define_insn "sse4_1_zero_extendv2hiv2di2"
9440   [(set (match_operand:V2DI 0 "register_operand" "=x")
9441         (zero_extend:V2DI
9442           (vec_select:V2HI
9443             (match_operand:V8HI 1 "register_operand" "x")
9444             (parallel [(const_int 0)
9445                        (const_int 1)]))))]
9446   "TARGET_SSE4_1"
9447   "%vpmovzxwq\t{%1, %0|%0, %1}"
9448   [(set_attr "type" "ssemov")
9449    (set_attr "prefix_extra" "1")
9450    (set_attr "prefix" "maybe_vex")
9451    (set_attr "mode" "TI")])
9452
9453 (define_insn "*sse4_1_zero_extendv2hiv2di2"
9454   [(set (match_operand:V2DI 0 "register_operand" "=x")
9455         (zero_extend:V2DI
9456           (vec_select:V2HI
9457             (vec_duplicate:V8HI
9458               (match_operand:V2HI 1 "nonimmediate_operand" "xm"))
9459             (parallel [(const_int 0)
9460                        (const_int 1)]))))]
9461   "TARGET_SSE4_1"
9462   "%vpmovzxwq\t{%1, %0|%0, %1}"
9463   [(set_attr "type" "ssemov")
9464    (set_attr "prefix_extra" "1")
9465    (set_attr "prefix" "maybe_vex")
9466    (set_attr "mode" "TI")])
9467
9468 (define_insn "sse4_1_zero_extendv2siv2di2"
9469   [(set (match_operand:V2DI 0 "register_operand" "=x")
9470         (zero_extend:V2DI
9471           (vec_select:V2SI
9472             (match_operand:V4SI 1 "register_operand" "x")
9473             (parallel [(const_int 0)
9474                        (const_int 1)]))))]
9475   "TARGET_SSE4_1"
9476   "%vpmovzxdq\t{%1, %0|%0, %1}"
9477   [(set_attr "type" "ssemov")
9478    (set_attr "prefix_extra" "1")
9479    (set_attr "prefix" "maybe_vex")
9480    (set_attr "mode" "TI")])
9481
9482 (define_insn "*sse4_1_zero_extendv2siv2di2"
9483   [(set (match_operand:V2DI 0 "register_operand" "=x")
9484         (zero_extend:V2DI
9485           (vec_select:V2SI
9486             (vec_duplicate:V4SI
9487               (match_operand:V2SI 1 "nonimmediate_operand" "xm"))
9488             (parallel [(const_int 0)
9489                        (const_int 1)]))))]
9490   "TARGET_SSE4_1"
9491   "%vpmovzxdq\t{%1, %0|%0, %1}"
9492   [(set_attr "type" "ssemov")
9493    (set_attr "prefix_extra" "1")
9494    (set_attr "prefix" "maybe_vex")
9495    (set_attr "mode" "TI")])
9496
9497 ;; ptestps/ptestpd are very similar to comiss and ucomiss when
9498 ;; setting FLAGS_REG. But it is not a really compare instruction.
9499 (define_insn "avx_vtestp<avxmodesuffixf2c><avxmodesuffix>"
9500   [(set (reg:CC FLAGS_REG)
9501         (unspec:CC [(match_operand:AVXMODEF2P 0 "register_operand" "x")
9502                     (match_operand:AVXMODEF2P 1 "nonimmediate_operand" "xm")]
9503                    UNSPEC_VTESTP))]
9504   "TARGET_AVX"
9505   "vtestp<avxmodesuffixf2c>\t{%1, %0|%0, %1}"
9506   [(set_attr "type" "ssecomi")
9507    (set_attr "prefix" "vex")
9508    (set_attr "mode" "<MODE>")])
9509
9510 ;; ptest is very similar to comiss and ucomiss when setting FLAGS_REG.
9511 ;; But it is not a really compare instruction.
9512 (define_insn "avx_ptest256"
9513   [(set (reg:CC FLAGS_REG)
9514         (unspec:CC [(match_operand:V4DI 0 "register_operand" "x")
9515                     (match_operand:V4DI 1 "nonimmediate_operand" "xm")]
9516                    UNSPEC_PTEST))]
9517   "TARGET_AVX"
9518   "vptest\t{%1, %0|%0, %1}"
9519   [(set_attr "type" "ssecomi")
9520    (set_attr "prefix" "vex")
9521    (set_attr "mode" "OI")])
9522
9523 (define_insn "sse4_1_ptest"
9524   [(set (reg:CC FLAGS_REG)
9525         (unspec:CC [(match_operand:V2DI 0 "register_operand" "x")
9526                     (match_operand:V2DI 1 "nonimmediate_operand" "xm")]
9527                    UNSPEC_PTEST))]
9528   "TARGET_SSE4_1"
9529   "%vptest\t{%1, %0|%0, %1}"
9530   [(set_attr "type" "ssecomi")
9531    (set_attr "prefix_extra" "1")
9532    (set_attr "prefix" "maybe_vex")
9533    (set_attr "mode" "TI")])
9534
9535 (define_insn "avx_roundp<avxmodesuffixf2c>256"
9536   [(set (match_operand:AVX256MODEF2P 0 "register_operand" "=x")
9537         (unspec:AVX256MODEF2P
9538           [(match_operand:AVX256MODEF2P 1 "nonimmediate_operand" "xm")
9539            (match_operand:SI 2 "const_0_to_15_operand" "n")]
9540           UNSPEC_ROUND))]
9541   "TARGET_AVX"
9542   "vroundp<avxmodesuffixf2c>\t{%2, %1, %0|%0, %1, %2}"
9543   [(set_attr "type" "ssecvt")
9544    (set_attr "prefix" "vex")
9545    (set_attr "mode" "<MODE>")])
9546
9547 (define_insn "sse4_1_roundp<ssemodesuffixf2c>"
9548   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
9549         (unspec:SSEMODEF2P
9550           [(match_operand:SSEMODEF2P 1 "nonimmediate_operand" "xm")
9551            (match_operand:SI 2 "const_0_to_15_operand" "n")]
9552           UNSPEC_ROUND))]
9553   "TARGET_ROUND"
9554   "%vroundp<ssemodesuffixf2c>\t{%2, %1, %0|%0, %1, %2}"
9555   [(set_attr "type" "ssecvt")
9556    (set_attr "prefix_extra" "1")
9557    (set_attr "prefix" "maybe_vex")
9558    (set_attr "mode" "<MODE>")])
9559
9560 (define_insn "*avx_rounds<ssemodesuffixf2c>"
9561   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
9562         (vec_merge:SSEMODEF2P
9563           (unspec:SSEMODEF2P
9564             [(match_operand:SSEMODEF2P 2 "register_operand" "x")
9565              (match_operand:SI 3 "const_0_to_15_operand" "n")]
9566             UNSPEC_ROUND)
9567           (match_operand:SSEMODEF2P 1 "register_operand" "x")
9568           (const_int 1)))]
9569   "TARGET_AVX"
9570   "vrounds<ssemodesuffixf2c>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
9571   [(set_attr "type" "ssecvt")
9572    (set_attr "prefix" "vex")
9573    (set_attr "mode" "<MODE>")])
9574
9575 (define_insn "sse4_1_rounds<ssemodesuffixf2c>"
9576   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
9577         (vec_merge:SSEMODEF2P
9578           (unspec:SSEMODEF2P
9579             [(match_operand:SSEMODEF2P 2 "register_operand" "x")
9580              (match_operand:SI 3 "const_0_to_15_operand" "n")]
9581             UNSPEC_ROUND)
9582           (match_operand:SSEMODEF2P 1 "register_operand" "0")
9583           (const_int 1)))]
9584   "TARGET_ROUND"
9585   "rounds<ssemodesuffixf2c>\t{%3, %2, %0|%0, %2, %3}"
9586   [(set_attr "type" "ssecvt")
9587    (set_attr "prefix_extra" "1")
9588    (set_attr "mode" "<MODE>")])
9589
9590 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9591 ;;
9592 ;; Intel SSE4.2 string/text processing instructions
9593 ;;
9594 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9595
9596 (define_insn_and_split "sse4_2_pcmpestr"
9597   [(set (match_operand:SI 0 "register_operand" "=c,c")
9598         (unspec:SI
9599           [(match_operand:V16QI 2 "reg_not_xmm0_operand" "x,x")
9600            (match_operand:SI 3 "register_operand" "a,a")
9601            (match_operand:V16QI 4 "nonimm_not_xmm0_operand" "x,m")
9602            (match_operand:SI 5 "register_operand" "d,d")
9603            (match_operand:SI 6 "const_0_to_255_operand" "n,n")]
9604           UNSPEC_PCMPESTR))
9605    (set (match_operand:V16QI 1 "register_operand" "=Yz,Yz")
9606         (unspec:V16QI
9607           [(match_dup 2)
9608            (match_dup 3)
9609            (match_dup 4)
9610            (match_dup 5)
9611            (match_dup 6)]
9612           UNSPEC_PCMPESTR))
9613    (set (reg:CC FLAGS_REG)
9614         (unspec:CC
9615           [(match_dup 2)
9616            (match_dup 3)
9617            (match_dup 4)
9618            (match_dup 5)
9619            (match_dup 6)]
9620           UNSPEC_PCMPESTR))]
9621   "TARGET_SSE4_2
9622    && !(reload_completed || reload_in_progress)"
9623   "#"
9624   "&& 1"
9625   [(const_int 0)]
9626 {
9627   int ecx = !find_regno_note (curr_insn, REG_UNUSED, REGNO (operands[0]));
9628   int xmm0 = !find_regno_note (curr_insn, REG_UNUSED, REGNO (operands[1]));
9629   int flags = !find_regno_note (curr_insn, REG_UNUSED, FLAGS_REG);
9630
9631   if (ecx)
9632     emit_insn (gen_sse4_2_pcmpestri (operands[0], operands[2],
9633                                      operands[3], operands[4],
9634                                      operands[5], operands[6]));
9635   if (xmm0)
9636     emit_insn (gen_sse4_2_pcmpestrm (operands[1], operands[2],
9637                                      operands[3], operands[4],
9638                                      operands[5], operands[6]));
9639   if (flags && !(ecx || xmm0))
9640     emit_insn (gen_sse4_2_pcmpestr_cconly (NULL, NULL,
9641                                            operands[2], operands[3],
9642                                            operands[4], operands[5],
9643                                            operands[6]));
9644   DONE;
9645 }
9646   [(set_attr "type" "sselog")
9647    (set_attr "prefix_data16" "1")
9648    (set_attr "prefix_extra" "1")
9649    (set_attr "memory" "none,load")
9650    (set_attr "mode" "TI")])
9651
9652 (define_insn "sse4_2_pcmpestri"
9653   [(set (match_operand:SI 0 "register_operand" "=c,c")
9654         (unspec:SI
9655           [(match_operand:V16QI 1 "register_operand" "x,x")
9656            (match_operand:SI 2 "register_operand" "a,a")
9657            (match_operand:V16QI 3 "nonimmediate_operand" "x,m")
9658            (match_operand:SI 4 "register_operand" "d,d")
9659            (match_operand:SI 5 "const_0_to_255_operand" "n,n")]
9660           UNSPEC_PCMPESTR))
9661    (set (reg:CC FLAGS_REG)
9662         (unspec:CC
9663           [(match_dup 1)
9664            (match_dup 2)
9665            (match_dup 3)
9666            (match_dup 4)
9667            (match_dup 5)]
9668           UNSPEC_PCMPESTR))]
9669   "TARGET_SSE4_2"
9670   "%vpcmpestri\t{%5, %3, %1|%1, %3, %5}"
9671   [(set_attr "type" "sselog")
9672    (set_attr "prefix_data16" "1")
9673    (set_attr "prefix_extra" "1")
9674    (set_attr "prefix" "maybe_vex")
9675    (set_attr "memory" "none,load")
9676    (set_attr "mode" "TI")])
9677
9678 (define_insn "sse4_2_pcmpestrm"
9679   [(set (match_operand:V16QI 0 "register_operand" "=Yz,Yz")
9680         (unspec:V16QI
9681           [(match_operand:V16QI 1 "register_operand" "x,x")
9682            (match_operand:SI 2 "register_operand" "a,a")
9683            (match_operand:V16QI 3 "nonimmediate_operand" "x,m")
9684            (match_operand:SI 4 "register_operand" "d,d")
9685            (match_operand:SI 5 "const_0_to_255_operand" "n,n")]
9686           UNSPEC_PCMPESTR))
9687    (set (reg:CC FLAGS_REG)
9688         (unspec:CC
9689           [(match_dup 1)
9690            (match_dup 2)
9691            (match_dup 3)
9692            (match_dup 4)
9693            (match_dup 5)]
9694           UNSPEC_PCMPESTR))]
9695   "TARGET_SSE4_2"
9696   "%vpcmpestrm\t{%5, %3, %1|%1, %3, %5}"
9697   [(set_attr "type" "sselog")
9698    (set_attr "prefix_data16" "1")
9699    (set_attr "prefix_extra" "1")
9700    (set_attr "prefix" "maybe_vex")
9701    (set_attr "memory" "none,load")
9702    (set_attr "mode" "TI")])
9703
9704 (define_insn "sse4_2_pcmpestr_cconly"
9705   [(set (reg:CC FLAGS_REG)
9706         (unspec:CC
9707           [(match_operand:V16QI 2 "register_operand" "x,x,x,x")
9708            (match_operand:SI 3 "register_operand" "a,a,a,a")
9709            (match_operand:V16QI 4 "nonimmediate_operand" "x,m,x,m")
9710            (match_operand:SI 5 "register_operand" "d,d,d,d")
9711            (match_operand:SI 6 "const_0_to_255_operand" "n,n,n,n")]
9712           UNSPEC_PCMPESTR))
9713    (clobber (match_scratch:V16QI 0 "=Yz,Yz,X,X"))
9714    (clobber (match_scratch:SI    1 "= X, X,c,c"))]
9715   "TARGET_SSE4_2"
9716   "@
9717    %vpcmpestrm\t{%6, %4, %2|%2, %4, %6}
9718    %vpcmpestrm\t{%6, %4, %2|%2, %4, %6}
9719    %vpcmpestri\t{%6, %4, %2|%2, %4, %6}
9720    %vpcmpestri\t{%6, %4, %2|%2, %4, %6}"
9721   [(set_attr "type" "sselog")
9722    (set_attr "prefix_data16" "1")
9723    (set_attr "prefix_extra" "1")
9724    (set_attr "memory" "none,load,none,load")
9725    (set_attr "prefix" "maybe_vex")
9726    (set_attr "mode" "TI")])
9727
9728 (define_insn_and_split "sse4_2_pcmpistr"
9729   [(set (match_operand:SI 0 "register_operand" "=c,c")
9730         (unspec:SI
9731           [(match_operand:V16QI 2 "reg_not_xmm0_operand" "x,x")
9732            (match_operand:V16QI 3 "nonimm_not_xmm0_operand" "x,m")
9733            (match_operand:SI 4 "const_0_to_255_operand" "n,n")]
9734           UNSPEC_PCMPISTR))
9735    (set (match_operand:V16QI 1 "register_operand" "=Yz,Yz")
9736         (unspec:V16QI
9737           [(match_dup 2)
9738            (match_dup 3)
9739            (match_dup 4)]
9740           UNSPEC_PCMPISTR))
9741    (set (reg:CC FLAGS_REG)
9742         (unspec:CC
9743           [(match_dup 2)
9744            (match_dup 3)
9745            (match_dup 4)]
9746           UNSPEC_PCMPISTR))]
9747   "TARGET_SSE4_2
9748    && !(reload_completed || reload_in_progress)"
9749   "#"
9750   "&& 1"
9751   [(const_int 0)]
9752 {
9753   int ecx = !find_regno_note (curr_insn, REG_UNUSED, REGNO (operands[0]));
9754   int xmm0 = !find_regno_note (curr_insn, REG_UNUSED, REGNO (operands[1]));
9755   int flags = !find_regno_note (curr_insn, REG_UNUSED, FLAGS_REG);
9756
9757   if (ecx)
9758     emit_insn (gen_sse4_2_pcmpistri (operands[0], operands[2],
9759                                      operands[3], operands[4]));
9760   if (xmm0)
9761     emit_insn (gen_sse4_2_pcmpistrm (operands[1], operands[2],
9762                                      operands[3], operands[4]));
9763   if (flags && !(ecx || xmm0))
9764     emit_insn (gen_sse4_2_pcmpistr_cconly (NULL, NULL,
9765                                            operands[2], operands[3],
9766                                            operands[4]));
9767   DONE;
9768 }
9769   [(set_attr "type" "sselog")
9770    (set_attr "prefix_data16" "1")
9771    (set_attr "prefix_extra" "1")
9772    (set_attr "memory" "none,load")
9773    (set_attr "mode" "TI")])
9774
9775 (define_insn "sse4_2_pcmpistri"
9776   [(set (match_operand:SI 0 "register_operand" "=c,c")
9777         (unspec:SI
9778           [(match_operand:V16QI 1 "register_operand" "x,x")
9779            (match_operand:V16QI 2 "nonimmediate_operand" "x,m")
9780            (match_operand:SI 3 "const_0_to_255_operand" "n,n")]
9781           UNSPEC_PCMPISTR))
9782    (set (reg:CC FLAGS_REG)
9783         (unspec:CC
9784           [(match_dup 1)
9785            (match_dup 2)
9786            (match_dup 3)]
9787           UNSPEC_PCMPISTR))]
9788   "TARGET_SSE4_2"
9789   "%vpcmpistri\t{%3, %2, %1|%1, %2, %3}"
9790   [(set_attr "type" "sselog")
9791    (set_attr "prefix_data16" "1")
9792    (set_attr "prefix_extra" "1")
9793    (set_attr "prefix" "maybe_vex")
9794    (set_attr "memory" "none,load")
9795    (set_attr "mode" "TI")])
9796
9797 (define_insn "sse4_2_pcmpistrm"
9798   [(set (match_operand:V16QI 0 "register_operand" "=Yz,Yz")
9799         (unspec:V16QI
9800           [(match_operand:V16QI 1 "register_operand" "x,x")
9801            (match_operand:V16QI 2 "nonimmediate_operand" "x,m")
9802            (match_operand:SI 3 "const_0_to_255_operand" "n,n")]
9803           UNSPEC_PCMPISTR))
9804    (set (reg:CC FLAGS_REG)
9805         (unspec:CC
9806           [(match_dup 1)
9807            (match_dup 2)
9808            (match_dup 3)]
9809           UNSPEC_PCMPISTR))]
9810   "TARGET_SSE4_2"
9811   "%vpcmpistrm\t{%3, %2, %1|%1, %2, %3}"
9812   [(set_attr "type" "sselog")
9813    (set_attr "prefix_data16" "1")
9814    (set_attr "prefix_extra" "1")
9815    (set_attr "prefix" "maybe_vex")
9816    (set_attr "memory" "none,load")
9817    (set_attr "mode" "TI")])
9818
9819 (define_insn "sse4_2_pcmpistr_cconly"
9820   [(set (reg:CC FLAGS_REG)
9821         (unspec:CC
9822           [(match_operand:V16QI 2 "register_operand" "x,x,x,x")
9823            (match_operand:V16QI 3 "nonimmediate_operand" "x,m,x,m")
9824            (match_operand:SI 4 "const_0_to_255_operand" "n,n,n,n")]
9825           UNSPEC_PCMPISTR))
9826    (clobber (match_scratch:V16QI 0 "=Yz,Yz,X,X"))
9827    (clobber (match_scratch:SI    1 "= X, X,c,c"))]
9828   "TARGET_SSE4_2"
9829   "@
9830    %vpcmpistrm\t{%4, %3, %2|%2, %3, %4}
9831    %vpcmpistrm\t{%4, %3, %2|%2, %3, %4}
9832    %vpcmpistri\t{%4, %3, %2|%2, %3, %4}
9833    %vpcmpistri\t{%4, %3, %2|%2, %3, %4}"
9834   [(set_attr "type" "sselog")
9835    (set_attr "prefix_data16" "1")
9836    (set_attr "prefix_extra" "1")
9837    (set_attr "memory" "none,load,none,load")
9838    (set_attr "prefix" "maybe_vex")
9839    (set_attr "mode" "TI")])
9840
9841 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9842 ;;
9843 ;; SSE5 instructions
9844 ;;
9845 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9846
9847 ;; SSE5 parallel integer multiply/add instructions.
9848 ;; Note the instruction does not allow the value being added to be a memory
9849 ;; operation.  However by pretending via the nonimmediate_operand predicate
9850 ;; that it does and splitting it later allows the following to be recognized:
9851 ;;      a[i] = b[i] * c[i] + d[i];
9852 (define_insn "sse5_pmacsww"
9853   [(set (match_operand:V8HI 0 "register_operand" "=x,x,x")
9854         (plus:V8HI
9855          (mult:V8HI
9856           (match_operand:V8HI 1 "nonimmediate_operand" "%x,x,xm")
9857           (match_operand:V8HI 2 "nonimmediate_operand" "x,xm,x"))
9858          (match_operand:V8HI 3 "register_operand" "0,0,0")))]
9859   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 2, true)"
9860   "@
9861    pmacsww\t{%3, %2, %1, %0|%0, %1, %2, %3}
9862    pmacsww\t{%3, %2, %1, %0|%0, %1, %2, %3}
9863    pmacsww\t{%3, %1, %2, %0|%0, %2, %1, %3}"
9864   [(set_attr "type" "ssemuladd")
9865    (set_attr "mode" "TI")])
9866
9867 ;; Split pmacsww with two memory operands into a load and the pmacsww.
9868 (define_split
9869   [(set (match_operand:V8HI 0 "register_operand" "")
9870         (plus:V8HI
9871          (mult:V8HI (match_operand:V8HI 1 "nonimmediate_operand" "")
9872                     (match_operand:V8HI 2 "nonimmediate_operand" ""))
9873          (match_operand:V8HI 3 "nonimmediate_operand" "")))]
9874   "TARGET_SSE5
9875    && !ix86_sse5_valid_op_p (operands, insn, 4, false, 1, true)
9876    && ix86_sse5_valid_op_p (operands, insn, 4, false, 2, true)
9877    && !reg_mentioned_p (operands[0], operands[1])
9878    && !reg_mentioned_p (operands[0], operands[2])
9879    && !reg_mentioned_p (operands[0], operands[3])"
9880   [(const_int 0)]
9881 {
9882   ix86_expand_sse5_multiple_memory (operands, 4, V8HImode);
9883   emit_insn (gen_sse5_pmacsww (operands[0], operands[1], operands[2],
9884                                operands[3]));
9885   DONE;
9886 })
9887
9888 (define_insn "sse5_pmacssww"
9889   [(set (match_operand:V8HI 0 "register_operand" "=x,x,x")
9890         (ss_plus:V8HI
9891          (mult:V8HI (match_operand:V8HI 1 "nonimmediate_operand" "%x,x,m")
9892                     (match_operand:V8HI 2 "nonimmediate_operand" "x,m,x"))
9893          (match_operand:V8HI 3 "register_operand" "0,0,0")))]
9894   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1, true)"
9895   "@
9896    pmacssww\t{%3, %2, %1, %0|%0, %1, %2, %3}
9897    pmacssww\t{%3, %2, %1, %0|%0, %1, %2, %3}
9898    pmacssww\t{%3, %1, %2, %0|%0, %2, %1, %3}"
9899   [(set_attr "type" "ssemuladd")
9900    (set_attr "mode" "TI")])
9901
9902 ;; Note the instruction does not allow the value being added to be a memory
9903 ;; operation.  However by pretending via the nonimmediate_operand predicate
9904 ;; that it does and splitting it later allows the following to be recognized:
9905 ;;      a[i] = b[i] * c[i] + d[i];
9906 (define_insn "sse5_pmacsdd"
9907   [(set (match_operand:V4SI 0 "register_operand" "=x,x,x")
9908         (plus:V4SI
9909          (mult:V4SI
9910           (match_operand:V4SI 1 "nonimmediate_operand" "%x,x,m")
9911           (match_operand:V4SI 2 "nonimmediate_operand" "x,m,x"))
9912          (match_operand:V4SI 3 "register_operand" "0,0,0")))]
9913   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 2, true)"
9914   "@
9915    pmacsdd\t{%3, %2, %1, %0|%0, %1, %2, %3}
9916    pmacsdd\t{%3, %2, %1, %0|%0, %1, %2, %3}
9917    pmacsdd\t{%3, %1, %2, %0|%0, %2, %1, %3}"
9918   [(set_attr "type" "ssemuladd")
9919    (set_attr "mode" "TI")])
9920
9921 ;; Split pmacsdd with two memory operands into a load and the pmacsdd.
9922 (define_split
9923   [(set (match_operand:V4SI 0 "register_operand" "")
9924         (plus:V4SI
9925          (mult:V4SI (match_operand:V4SI 1 "nonimmediate_operand" "")
9926                     (match_operand:V4SI 2 "nonimmediate_operand" ""))
9927          (match_operand:V4SI 3 "nonimmediate_operand" "")))]
9928   "TARGET_SSE5
9929    && !ix86_sse5_valid_op_p (operands, insn, 4, false, 1, true)
9930    && ix86_sse5_valid_op_p (operands, insn, 4, false, 2, true)
9931    && !reg_mentioned_p (operands[0], operands[1])
9932    && !reg_mentioned_p (operands[0], operands[2])
9933    && !reg_mentioned_p (operands[0], operands[3])"
9934   [(const_int 0)]
9935 {
9936   ix86_expand_sse5_multiple_memory (operands, 4, V4SImode);
9937   emit_insn (gen_sse5_pmacsdd (operands[0], operands[1], operands[2],
9938                                operands[3]));
9939   DONE;
9940 })
9941
9942 (define_insn "sse5_pmacssdd"
9943   [(set (match_operand:V4SI 0 "register_operand" "=x,x,x")
9944         (ss_plus:V4SI
9945          (mult:V4SI (match_operand:V4SI 1 "nonimmediate_operand" "%x,x,m")
9946                     (match_operand:V4SI 2 "nonimmediate_operand" "x,m,x"))
9947          (match_operand:V4SI 3 "register_operand" "0,0,0")))]
9948   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1, true)"
9949   "@
9950    pmacssdd\t{%3, %2, %1, %0|%0, %1, %2, %3}
9951    pmacssdd\t{%3, %2, %1, %0|%0, %1, %2, %3}
9952    pmacssdd\t{%3, %1, %2, %0|%0, %2, %1, %3}"
9953   [(set_attr "type" "ssemuladd")
9954    (set_attr "mode" "TI")])
9955
9956 (define_insn "sse5_pmacssdql"
9957   [(set (match_operand:V2DI 0 "register_operand" "=x,x,x")
9958         (ss_plus:V2DI
9959          (mult:V2DI
9960           (sign_extend:V2DI
9961            (vec_select:V2SI
9962             (match_operand:V4SI 1 "nonimmediate_operand" "%x,x,m")
9963             (parallel [(const_int 1)
9964                        (const_int 3)])))
9965            (vec_select:V2SI
9966             (match_operand:V4SI 2 "nonimmediate_operand" "x,m,x")
9967             (parallel [(const_int 1)
9968                        (const_int 3)])))
9969          (match_operand:V2DI 3 "register_operand" "0,0,0")))]
9970   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1, true)"
9971   "@
9972    pmacssdql\t{%3, %2, %1, %0|%0, %1, %2, %3}
9973    pmacssdql\t{%3, %2, %1, %0|%0, %1, %2, %3}
9974    pmacssdql\t{%3, %1, %2, %0|%0, %2, %1, %3}"
9975   [(set_attr "type" "ssemuladd")
9976    (set_attr "mode" "TI")])
9977
9978 (define_insn "sse5_pmacssdqh"
9979   [(set (match_operand:V2DI 0 "register_operand" "=x,x,x")
9980         (ss_plus:V2DI
9981          (mult:V2DI
9982           (sign_extend:V2DI
9983            (vec_select:V2SI
9984             (match_operand:V4SI 1 "nonimmediate_operand" "%x,x,m")
9985             (parallel [(const_int 0)
9986                        (const_int 2)])))
9987           (sign_extend:V2DI
9988            (vec_select:V2SI
9989             (match_operand:V4SI 2 "nonimmediate_operand" "x,m,x")
9990             (parallel [(const_int 0)
9991                        (const_int 2)]))))
9992          (match_operand:V2DI 3 "register_operand" "0,0,0")))]
9993   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1, true)"
9994   "@
9995    pmacssdqh\t{%3, %2, %1, %0|%0, %1, %2, %3}
9996    pmacssdqh\t{%3, %2, %1, %0|%0, %1, %2, %3}
9997    pmacssdqh\t{%3, %1, %2, %0|%0, %2, %1, %3}"
9998   [(set_attr "type" "ssemuladd")
9999    (set_attr "mode" "TI")])
10000
10001 (define_insn "sse5_pmacsdql"
10002   [(set (match_operand:V2DI 0 "register_operand" "=x,x,x")
10003         (plus:V2DI
10004          (mult:V2DI
10005           (sign_extend:V2DI
10006            (vec_select:V2SI
10007             (match_operand:V4SI 1 "nonimmediate_operand" "%x,x,m")
10008             (parallel [(const_int 1)
10009                        (const_int 3)])))
10010           (sign_extend:V2DI
10011            (vec_select:V2SI
10012             (match_operand:V4SI 2 "nonimmediate_operand" "x,m,x")
10013             (parallel [(const_int 1)
10014                        (const_int 3)]))))
10015          (match_operand:V2DI 3 "register_operand" "0,0,0")))]
10016   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1, true)"
10017   "@
10018    pmacsdql\t{%3, %2, %1, %0|%0, %1, %2, %3}
10019    pmacsdql\t{%3, %2, %1, %0|%0, %1, %2, %3}
10020    pmacsdql\t{%3, %1, %2, %0|%0, %2, %1, %3}"
10021   [(set_attr "type" "ssemuladd")
10022    (set_attr "mode" "TI")])
10023
10024 (define_insn_and_split "*sse5_pmacsdql_mem"
10025   [(set (match_operand:V2DI 0 "register_operand" "=&x,&x,&x")
10026         (plus:V2DI
10027          (mult:V2DI
10028           (sign_extend:V2DI
10029            (vec_select:V2SI
10030             (match_operand:V4SI 1 "nonimmediate_operand" "%x,x,m")
10031             (parallel [(const_int 1)
10032                        (const_int 3)])))
10033           (sign_extend:V2DI
10034            (vec_select:V2SI
10035             (match_operand:V4SI 2 "nonimmediate_operand" "x,m,x")
10036             (parallel [(const_int 1)
10037                        (const_int 3)]))))
10038          (match_operand:V2DI 3 "memory_operand" "m,m,m")))]
10039   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, -1, true)"
10040   "#"
10041   "&& (reload_completed
10042        || (!reg_mentioned_p (operands[0], operands[1])
10043            && !reg_mentioned_p (operands[0], operands[2])))"
10044   [(set (match_dup 0)
10045         (match_dup 3))
10046    (set (match_dup 0)
10047         (plus:V2DI
10048          (mult:V2DI
10049           (sign_extend:V2DI
10050            (vec_select:V2SI
10051             (match_dup 1)
10052             (parallel [(const_int 1)
10053                        (const_int 3)])))
10054           (sign_extend:V2DI
10055            (vec_select:V2SI
10056             (match_dup 2)
10057             (parallel [(const_int 1)
10058                        (const_int 3)]))))
10059          (match_dup 0)))])
10060
10061 ;; We don't have a straight 32-bit parallel multiply and extend on SSE5, so
10062 ;; fake it with a multiply/add.  In general, we expect the define_split to
10063 ;; occur before register allocation, so we have to handle the corner case where
10064 ;; the target is the same as operands 1/2
10065 (define_insn_and_split "sse5_mulv2div2di3_low"
10066   [(set (match_operand:V2DI 0 "register_operand" "=&x")
10067         (mult:V2DI
10068           (sign_extend:V2DI
10069             (vec_select:V2SI
10070               (match_operand:V4SI 1 "nonimmediate_operand" "%x")
10071               (parallel [(const_int 1)
10072                          (const_int 3)])))
10073           (sign_extend:V2DI
10074             (vec_select:V2SI
10075               (match_operand:V4SI 2 "nonimmediate_operand" "xm")
10076               (parallel [(const_int 1)
10077                          (const_int 3)])))))]
10078   "TARGET_SSE5"
10079   "#"
10080   "&& (reload_completed
10081        || (!reg_mentioned_p (operands[0], operands[1])
10082            && !reg_mentioned_p (operands[0], operands[2])))"
10083   [(set (match_dup 0)
10084         (match_dup 3))
10085    (set (match_dup 0)
10086         (plus:V2DI
10087          (mult:V2DI
10088           (sign_extend:V2DI
10089            (vec_select:V2SI
10090             (match_dup 1)
10091             (parallel [(const_int 1)
10092                        (const_int 3)])))
10093           (sign_extend:V2DI
10094            (vec_select:V2SI
10095             (match_dup 2)
10096             (parallel [(const_int 1)
10097                        (const_int 3)]))))
10098          (match_dup 0)))]
10099 {
10100   operands[3] = CONST0_RTX (V2DImode);
10101 }
10102   [(set_attr "type" "ssemuladd")
10103    (set_attr "mode" "TI")])
10104
10105 (define_insn "sse5_pmacsdqh"
10106   [(set (match_operand:V2DI 0 "register_operand" "=x,x,x")
10107         (plus:V2DI
10108          (mult:V2DI
10109           (sign_extend:V2DI
10110            (vec_select:V2SI
10111             (match_operand:V4SI 1 "nonimmediate_operand" "%x,x,m")
10112             (parallel [(const_int 0)
10113                        (const_int 2)])))
10114           (sign_extend:V2DI
10115            (vec_select:V2SI
10116             (match_operand:V4SI 2 "nonimmediate_operand" "x,m,x")
10117             (parallel [(const_int 0)
10118                        (const_int 2)]))))
10119          (match_operand:V2DI 3 "register_operand" "0,0,0")))]
10120   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1, true)"
10121   "@
10122    pmacsdqh\t{%3, %2, %1, %0|%0, %1, %2, %3}
10123    pmacsdqh\t{%3, %2, %1, %0|%0, %1, %2, %3}
10124    pmacsdqh\t{%3, %1, %2, %0|%0, %2, %1, %3}"
10125   [(set_attr "type" "ssemuladd")
10126    (set_attr "mode" "TI")])
10127
10128 (define_insn_and_split "*sse5_pmacsdqh_mem"
10129   [(set (match_operand:V2DI 0 "register_operand" "=&x,&x,&x")
10130         (plus:V2DI
10131          (mult:V2DI
10132           (sign_extend:V2DI
10133            (vec_select:V2SI
10134             (match_operand:V4SI 1 "nonimmediate_operand" "%x,x,m")
10135             (parallel [(const_int 0)
10136                        (const_int 2)])))
10137           (sign_extend:V2DI
10138            (vec_select:V2SI
10139             (match_operand:V4SI 2 "nonimmediate_operand" "x,m,x")
10140             (parallel [(const_int 0)
10141                        (const_int 2)]))))
10142          (match_operand:V2DI 3 "memory_operand" "m,m,m")))]
10143   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, -1, true)"
10144   "#"
10145   "&& (reload_completed
10146        || (!reg_mentioned_p (operands[0], operands[1])
10147            && !reg_mentioned_p (operands[0], operands[2])))"
10148   [(set (match_dup 0)
10149         (match_dup 3))
10150    (set (match_dup 0)
10151         (plus:V2DI
10152          (mult:V2DI
10153           (sign_extend:V2DI
10154            (vec_select:V2SI
10155             (match_dup 1)
10156             (parallel [(const_int 0)
10157                        (const_int 2)])))
10158           (sign_extend:V2DI
10159            (vec_select:V2SI
10160             (match_dup 2)
10161             (parallel [(const_int 0)
10162                        (const_int 2)]))))
10163          (match_dup 0)))])
10164
10165 ;; We don't have a straight 32-bit parallel multiply and extend on SSE5, so
10166 ;; fake it with a multiply/add.  In general, we expect the define_split to
10167 ;; occur before register allocation, so we have to handle the corner case where
10168 ;; the target is the same as either operands[1] or operands[2]
10169 (define_insn_and_split "sse5_mulv2div2di3_high"
10170   [(set (match_operand:V2DI 0 "register_operand" "=&x")
10171         (mult:V2DI
10172           (sign_extend:V2DI
10173             (vec_select:V2SI
10174               (match_operand:V4SI 1 "nonimmediate_operand" "%x")
10175               (parallel [(const_int 0)
10176                          (const_int 2)])))
10177           (sign_extend:V2DI
10178             (vec_select:V2SI
10179               (match_operand:V4SI 2 "nonimmediate_operand" "xm")
10180               (parallel [(const_int 0)
10181                          (const_int 2)])))))]
10182   "TARGET_SSE5"
10183   "#"
10184   "&& (reload_completed
10185        || (!reg_mentioned_p (operands[0], operands[1])
10186            && !reg_mentioned_p (operands[0], operands[2])))"
10187   [(set (match_dup 0)
10188         (match_dup 3))
10189    (set (match_dup 0)
10190         (plus:V2DI
10191          (mult:V2DI
10192           (sign_extend:V2DI
10193            (vec_select:V2SI
10194             (match_dup 1)
10195             (parallel [(const_int 0)
10196                        (const_int 2)])))
10197           (sign_extend:V2DI
10198            (vec_select:V2SI
10199             (match_dup 2)
10200             (parallel [(const_int 0)
10201                        (const_int 2)]))))
10202          (match_dup 0)))]
10203 {
10204   operands[3] = CONST0_RTX (V2DImode);
10205 }
10206   [(set_attr "type" "ssemuladd")
10207    (set_attr "mode" "TI")])
10208
10209 ;; SSE5 parallel integer multiply/add instructions for the intrinisics
10210 (define_insn "sse5_pmacsswd"
10211   [(set (match_operand:V4SI 0 "register_operand" "=x,x,x")
10212         (ss_plus:V4SI
10213          (mult:V4SI
10214           (sign_extend:V4SI
10215            (vec_select:V4HI
10216             (match_operand:V8HI 1 "nonimmediate_operand" "%x,x,m")
10217             (parallel [(const_int 1)
10218                        (const_int 3)
10219                        (const_int 5)
10220                        (const_int 7)])))
10221           (sign_extend:V4SI
10222            (vec_select:V4HI
10223             (match_operand:V8HI 2 "nonimmediate_operand" "x,m,x")
10224             (parallel [(const_int 1)
10225                        (const_int 3)
10226                        (const_int 5)
10227                        (const_int 7)]))))
10228          (match_operand:V4SI 3 "register_operand" "0,0,0")))]
10229   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1, true)"
10230   "@
10231    pmacsswd\t{%3, %2, %1, %0|%0, %1, %2, %3}
10232    pmacsswd\t{%3, %2, %1, %0|%0, %1, %2, %3}
10233    pmacsswd\t{%3, %1, %2, %0|%0, %2, %1, %3}"
10234   [(set_attr "type" "ssemuladd")
10235    (set_attr "mode" "TI")])
10236
10237 (define_insn "sse5_pmacswd"
10238   [(set (match_operand:V4SI 0 "register_operand" "=x,x,x")
10239         (plus:V4SI
10240          (mult:V4SI
10241           (sign_extend:V4SI
10242            (vec_select:V4HI
10243             (match_operand:V8HI 1 "nonimmediate_operand" "%x,x,m")
10244             (parallel [(const_int 1)
10245                        (const_int 3)
10246                        (const_int 5)
10247                        (const_int 7)])))
10248           (sign_extend:V4SI
10249            (vec_select:V4HI
10250             (match_operand:V8HI 2 "nonimmediate_operand" "x,m,x")
10251             (parallel [(const_int 1)
10252                        (const_int 3)
10253                        (const_int 5)
10254                        (const_int 7)]))))
10255          (match_operand:V4SI 3 "register_operand" "0,0,0")))]
10256   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1, true)"
10257   "@
10258    pmacswd\t{%3, %2, %1, %0|%0, %1, %2, %3}
10259    pmacswd\t{%3, %2, %1, %0|%0, %1, %2, %3}
10260    pmacswd\t{%3, %1, %2, %0|%0, %2, %1, %3}"
10261   [(set_attr "type" "ssemuladd")
10262    (set_attr "mode" "TI")])
10263
10264 (define_insn "sse5_pmadcsswd"
10265   [(set (match_operand:V4SI 0 "register_operand" "=x,x,x")
10266         (ss_plus:V4SI
10267          (plus:V4SI
10268           (mult:V4SI
10269            (sign_extend:V4SI
10270             (vec_select:V4HI
10271              (match_operand:V8HI 1 "nonimmediate_operand" "%x,x,m")
10272              (parallel [(const_int 0)
10273                         (const_int 2)
10274                         (const_int 4)
10275                         (const_int 6)])))
10276            (sign_extend:V4SI
10277             (vec_select:V4HI
10278              (match_operand:V8HI 2 "nonimmediate_operand" "x,m,x")
10279              (parallel [(const_int 0)
10280                         (const_int 2)
10281                         (const_int 4)
10282                         (const_int 6)]))))
10283           (mult:V4SI
10284            (sign_extend:V4SI
10285             (vec_select:V4HI
10286              (match_dup 1)
10287              (parallel [(const_int 1)
10288                         (const_int 3)
10289                         (const_int 5)
10290                         (const_int 7)])))
10291            (sign_extend:V4SI
10292             (vec_select:V4HI
10293              (match_dup 2)
10294              (parallel [(const_int 1)
10295                         (const_int 3)
10296                         (const_int 5)
10297                         (const_int 7)])))))
10298          (match_operand:V4SI 3 "register_operand" "0,0,0")))]
10299   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1, true)"
10300   "@
10301    pmadcsswd\t{%3, %2, %1, %0|%0, %1, %2, %3}
10302    pmadcsswd\t{%3, %2, %1, %0|%0, %1, %2, %3}
10303    pmadcsswd\t{%3, %1, %2, %0|%0, %2, %1, %3}"
10304   [(set_attr "type" "ssemuladd")
10305    (set_attr "mode" "TI")])
10306
10307 (define_insn "sse5_pmadcswd"
10308   [(set (match_operand:V4SI 0 "register_operand" "=x,x,x")
10309         (plus:V4SI
10310          (plus:V4SI
10311           (mult:V4SI
10312            (sign_extend:V4SI
10313             (vec_select:V4HI
10314              (match_operand:V8HI 1 "nonimmediate_operand" "%x,x,m")
10315              (parallel [(const_int 0)
10316                         (const_int 2)
10317                         (const_int 4)
10318                         (const_int 6)])))
10319            (sign_extend:V4SI
10320             (vec_select:V4HI
10321              (match_operand:V8HI 2 "nonimmediate_operand" "x,m,x")
10322              (parallel [(const_int 0)
10323                         (const_int 2)
10324                         (const_int 4)
10325                         (const_int 6)]))))
10326           (mult:V4SI
10327            (sign_extend:V4SI
10328             (vec_select:V4HI
10329              (match_dup 1)
10330              (parallel [(const_int 1)
10331                         (const_int 3)
10332                         (const_int 5)
10333                         (const_int 7)])))
10334            (sign_extend:V4SI
10335             (vec_select:V4HI
10336              (match_dup 2)
10337              (parallel [(const_int 1)
10338                         (const_int 3)
10339                         (const_int 5)
10340                         (const_int 7)])))))
10341          (match_operand:V4SI 3 "register_operand" "0,0,0")))]
10342   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1, true)"
10343   "@
10344    pmadcswd\t{%3, %2, %1, %0|%0, %1, %2, %3}
10345    pmadcswd\t{%3, %2, %1, %0|%0, %1, %2, %3}
10346    pmadcswd\t{%3, %1, %2, %0|%0, %2, %1, %3}"
10347   [(set_attr "type" "ssemuladd")
10348    (set_attr "mode" "TI")])
10349
10350 ;; SSE5 parallel XMM conditional moves
10351 (define_insn "sse5_pcmov_<mode>"
10352   [(set (match_operand:SSEMODE 0 "register_operand" "=x,x,x,x")
10353         (if_then_else:SSEMODE
10354           (match_operand:SSEMODE 3 "nonimmediate_operand" "0,0,xm,x")
10355           (match_operand:SSEMODE 1 "vector_move_operand" "x,xm,0,0")
10356           (match_operand:SSEMODE 2 "vector_move_operand" "xm,x,x,xm")))]
10357   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
10358   "@
10359    pcmov\t{%3, %2, %1, %0|%0, %1, %2, %3}
10360    pcmov\t{%3, %2, %1, %0|%0, %1, %2, %3}
10361    pcmov\t{%3, %2, %1, %0|%0, %1, %2, %3}
10362    pcmov\t{%3, %2, %1, %0|%0, %1, %2, %3}"
10363   [(set_attr "type" "sse4arg")])
10364
10365 ;; SSE5 horizontal add/subtract instructions
10366 (define_insn "sse5_phaddbw"
10367   [(set (match_operand:V8HI 0 "register_operand" "=x")
10368         (plus:V8HI
10369          (sign_extend:V8HI
10370           (vec_select:V8QI
10371            (match_operand:V16QI 1 "nonimmediate_operand" "xm")
10372            (parallel [(const_int 0)
10373                       (const_int 2)
10374                       (const_int 4)
10375                       (const_int 6)
10376                       (const_int 8)
10377                       (const_int 10)
10378                       (const_int 12)
10379                       (const_int 14)])))
10380          (sign_extend:V8HI
10381           (vec_select:V8QI
10382            (match_dup 1)
10383            (parallel [(const_int 1)
10384                       (const_int 3)
10385                       (const_int 5)
10386                       (const_int 7)
10387                       (const_int 9)
10388                       (const_int 11)
10389                       (const_int 13)
10390                       (const_int 15)])))))]
10391   "TARGET_SSE5"
10392   "phaddbw\t{%1, %0|%0, %1}"
10393   [(set_attr "type" "sseiadd1")])
10394
10395 (define_insn "sse5_phaddbd"
10396   [(set (match_operand:V4SI 0 "register_operand" "=x")
10397         (plus:V4SI
10398          (plus:V4SI
10399           (sign_extend:V4SI
10400            (vec_select:V4QI
10401             (match_operand:V16QI 1 "nonimmediate_operand" "xm")
10402             (parallel [(const_int 0)
10403                        (const_int 4)
10404                        (const_int 8)
10405                        (const_int 12)])))
10406           (sign_extend:V4SI
10407            (vec_select:V4QI
10408             (match_dup 1)
10409             (parallel [(const_int 1)
10410                        (const_int 5)
10411                        (const_int 9)
10412                        (const_int 13)]))))
10413          (plus:V4SI
10414           (sign_extend:V4SI
10415            (vec_select:V4QI
10416             (match_dup 1)
10417             (parallel [(const_int 2)
10418                        (const_int 6)
10419                        (const_int 10)
10420                        (const_int 14)])))
10421           (sign_extend:V4SI
10422            (vec_select:V4QI
10423             (match_dup 1)
10424             (parallel [(const_int 3)
10425                        (const_int 7)
10426                        (const_int 11)
10427                        (const_int 15)]))))))]
10428   "TARGET_SSE5"
10429   "phaddbd\t{%1, %0|%0, %1}"
10430   [(set_attr "type" "sseiadd1")])
10431
10432 (define_insn "sse5_phaddbq"
10433   [(set (match_operand:V2DI 0 "register_operand" "=x")
10434         (plus:V2DI
10435          (plus:V2DI
10436           (plus:V2DI
10437            (sign_extend:V2DI
10438             (vec_select:V2QI
10439              (match_operand:V16QI 1 "nonimmediate_operand" "xm")
10440              (parallel [(const_int 0)
10441                         (const_int 4)])))
10442            (sign_extend:V2DI
10443             (vec_select:V2QI
10444              (match_dup 1)
10445              (parallel [(const_int 1)
10446                         (const_int 5)]))))
10447           (plus:V2DI
10448            (sign_extend:V2DI
10449             (vec_select:V2QI
10450              (match_dup 1)
10451              (parallel [(const_int 2)
10452                         (const_int 6)])))
10453            (sign_extend:V2DI
10454             (vec_select:V2QI
10455              (match_dup 1)
10456              (parallel [(const_int 3)
10457                         (const_int 7)])))))
10458          (plus:V2DI
10459           (plus:V2DI
10460            (sign_extend:V2DI
10461             (vec_select:V2QI
10462              (match_dup 1)
10463              (parallel [(const_int 8)
10464                         (const_int 12)])))
10465            (sign_extend:V2DI
10466             (vec_select:V2QI
10467              (match_dup 1)
10468              (parallel [(const_int 9)
10469                         (const_int 13)]))))
10470           (plus:V2DI
10471            (sign_extend:V2DI
10472             (vec_select:V2QI
10473              (match_dup 1)
10474              (parallel [(const_int 10)
10475                         (const_int 14)])))
10476            (sign_extend:V2DI
10477             (vec_select:V2QI
10478              (match_dup 1)
10479              (parallel [(const_int 11)
10480                         (const_int 15)])))))))]
10481   "TARGET_SSE5"
10482   "phaddbq\t{%1, %0|%0, %1}"
10483   [(set_attr "type" "sseiadd1")])
10484
10485 (define_insn "sse5_phaddwd"
10486   [(set (match_operand:V4SI 0 "register_operand" "=x")
10487         (plus:V4SI
10488          (sign_extend:V4SI
10489           (vec_select:V4HI
10490            (match_operand:V8HI 1 "nonimmediate_operand" "xm")
10491            (parallel [(const_int 0)
10492                       (const_int 2)
10493                       (const_int 4)
10494                       (const_int 6)])))
10495          (sign_extend:V4SI
10496           (vec_select:V4HI
10497            (match_dup 1)
10498            (parallel [(const_int 1)
10499                       (const_int 3)
10500                       (const_int 5)
10501                       (const_int 7)])))))]
10502   "TARGET_SSE5"
10503   "phaddwd\t{%1, %0|%0, %1}"
10504   [(set_attr "type" "sseiadd1")])
10505
10506 (define_insn "sse5_phaddwq"
10507   [(set (match_operand:V2DI 0 "register_operand" "=x")
10508         (plus:V2DI
10509          (plus:V2DI
10510           (sign_extend:V2DI
10511            (vec_select:V2HI
10512             (match_operand:V8HI 1 "nonimmediate_operand" "xm")
10513             (parallel [(const_int 0)
10514                        (const_int 4)])))
10515           (sign_extend:V2DI
10516            (vec_select:V2HI
10517             (match_dup 1)
10518             (parallel [(const_int 1)
10519                        (const_int 5)]))))
10520          (plus:V2DI
10521           (sign_extend:V2DI
10522            (vec_select:V2HI
10523             (match_dup 1)
10524             (parallel [(const_int 2)
10525                        (const_int 6)])))
10526           (sign_extend:V2DI
10527            (vec_select:V2HI
10528             (match_dup 1)
10529             (parallel [(const_int 3)
10530                        (const_int 7)]))))))]
10531   "TARGET_SSE5"
10532   "phaddwq\t{%1, %0|%0, %1}"
10533   [(set_attr "type" "sseiadd1")])
10534
10535 (define_insn "sse5_phadddq"
10536   [(set (match_operand:V2DI 0 "register_operand" "=x")
10537         (plus:V2DI
10538          (sign_extend:V2DI
10539           (vec_select:V2SI
10540            (match_operand:V4SI 1 "nonimmediate_operand" "xm")
10541            (parallel [(const_int 0)
10542                       (const_int 2)])))
10543          (sign_extend:V2DI
10544           (vec_select:V2SI
10545            (match_dup 1)
10546            (parallel [(const_int 1)
10547                       (const_int 3)])))))]
10548   "TARGET_SSE5"
10549   "phadddq\t{%1, %0|%0, %1}"
10550   [(set_attr "type" "sseiadd1")])
10551
10552 (define_insn "sse5_phaddubw"
10553   [(set (match_operand:V8HI 0 "register_operand" "=x")
10554         (plus:V8HI
10555          (zero_extend:V8HI
10556           (vec_select:V8QI
10557            (match_operand:V16QI 1 "nonimmediate_operand" "xm")
10558            (parallel [(const_int 0)
10559                       (const_int 2)
10560                       (const_int 4)
10561                       (const_int 6)
10562                       (const_int 8)
10563                       (const_int 10)
10564                       (const_int 12)
10565                       (const_int 14)])))
10566          (zero_extend:V8HI
10567           (vec_select:V8QI
10568            (match_dup 1)
10569            (parallel [(const_int 1)
10570                       (const_int 3)
10571                       (const_int 5)
10572                       (const_int 7)
10573                       (const_int 9)
10574                       (const_int 11)
10575                       (const_int 13)
10576                       (const_int 15)])))))]
10577   "TARGET_SSE5"
10578   "phaddubw\t{%1, %0|%0, %1}"
10579   [(set_attr "type" "sseiadd1")])
10580
10581 (define_insn "sse5_phaddubd"
10582   [(set (match_operand:V4SI 0 "register_operand" "=x")
10583         (plus:V4SI
10584          (plus:V4SI
10585           (zero_extend:V4SI
10586            (vec_select:V4QI
10587             (match_operand:V16QI 1 "nonimmediate_operand" "xm")
10588             (parallel [(const_int 0)
10589                        (const_int 4)
10590                        (const_int 8)
10591                        (const_int 12)])))
10592           (zero_extend:V4SI
10593            (vec_select:V4QI
10594             (match_dup 1)
10595             (parallel [(const_int 1)
10596                        (const_int 5)
10597                        (const_int 9)
10598                        (const_int 13)]))))
10599          (plus:V4SI
10600           (zero_extend:V4SI
10601            (vec_select:V4QI
10602             (match_dup 1)
10603             (parallel [(const_int 2)
10604                        (const_int 6)
10605                        (const_int 10)
10606                        (const_int 14)])))
10607           (zero_extend:V4SI
10608            (vec_select:V4QI
10609             (match_dup 1)
10610             (parallel [(const_int 3)
10611                        (const_int 7)
10612                        (const_int 11)
10613                        (const_int 15)]))))))]
10614   "TARGET_SSE5"
10615   "phaddubd\t{%1, %0|%0, %1}"
10616   [(set_attr "type" "sseiadd1")])
10617
10618 (define_insn "sse5_phaddubq"
10619   [(set (match_operand:V2DI 0 "register_operand" "=x")
10620         (plus:V2DI
10621          (plus:V2DI
10622           (plus:V2DI
10623            (zero_extend:V2DI
10624             (vec_select:V2QI
10625              (match_operand:V16QI 1 "nonimmediate_operand" "xm")
10626              (parallel [(const_int 0)
10627                         (const_int 4)])))
10628            (sign_extend:V2DI
10629             (vec_select:V2QI
10630              (match_dup 1)
10631              (parallel [(const_int 1)
10632                         (const_int 5)]))))
10633           (plus:V2DI
10634            (zero_extend:V2DI
10635             (vec_select:V2QI
10636              (match_dup 1)
10637              (parallel [(const_int 2)
10638                         (const_int 6)])))
10639            (zero_extend:V2DI
10640             (vec_select:V2QI
10641              (match_dup 1)
10642              (parallel [(const_int 3)
10643                         (const_int 7)])))))
10644          (plus:V2DI
10645           (plus:V2DI
10646            (zero_extend:V2DI
10647             (vec_select:V2QI
10648              (match_dup 1)
10649              (parallel [(const_int 8)
10650                         (const_int 12)])))
10651            (sign_extend:V2DI
10652             (vec_select:V2QI
10653              (match_dup 1)
10654              (parallel [(const_int 9)
10655                         (const_int 13)]))))
10656           (plus:V2DI
10657            (zero_extend:V2DI
10658             (vec_select:V2QI
10659              (match_dup 1)
10660              (parallel [(const_int 10)
10661                         (const_int 14)])))
10662            (zero_extend:V2DI
10663             (vec_select:V2QI
10664              (match_dup 1)
10665              (parallel [(const_int 11)
10666                         (const_int 15)])))))))]
10667   "TARGET_SSE5"
10668   "phaddubq\t{%1, %0|%0, %1}"
10669   [(set_attr "type" "sseiadd1")])
10670
10671 (define_insn "sse5_phadduwd"
10672   [(set (match_operand:V4SI 0 "register_operand" "=x")
10673         (plus:V4SI
10674          (zero_extend:V4SI
10675           (vec_select:V4HI
10676            (match_operand:V8HI 1 "nonimmediate_operand" "xm")
10677            (parallel [(const_int 0)
10678                       (const_int 2)
10679                       (const_int 4)
10680                       (const_int 6)])))
10681          (zero_extend:V4SI
10682           (vec_select:V4HI
10683            (match_dup 1)
10684            (parallel [(const_int 1)
10685                       (const_int 3)
10686                       (const_int 5)
10687                       (const_int 7)])))))]
10688   "TARGET_SSE5"
10689   "phadduwd\t{%1, %0|%0, %1}"
10690   [(set_attr "type" "sseiadd1")])
10691
10692 (define_insn "sse5_phadduwq"
10693   [(set (match_operand:V2DI 0 "register_operand" "=x")
10694         (plus:V2DI
10695          (plus:V2DI
10696           (zero_extend:V2DI
10697            (vec_select:V2HI
10698             (match_operand:V8HI 1 "nonimmediate_operand" "xm")
10699             (parallel [(const_int 0)
10700                        (const_int 4)])))
10701           (zero_extend:V2DI
10702            (vec_select:V2HI
10703             (match_dup 1)
10704             (parallel [(const_int 1)
10705                        (const_int 5)]))))
10706          (plus:V2DI
10707           (zero_extend:V2DI
10708            (vec_select:V2HI
10709             (match_dup 1)
10710             (parallel [(const_int 2)
10711                        (const_int 6)])))
10712           (zero_extend:V2DI
10713            (vec_select:V2HI
10714             (match_dup 1)
10715             (parallel [(const_int 3)
10716                        (const_int 7)]))))))]
10717   "TARGET_SSE5"
10718   "phadduwq\t{%1, %0|%0, %1}"
10719   [(set_attr "type" "sseiadd1")])
10720
10721 (define_insn "sse5_phaddudq"
10722   [(set (match_operand:V2DI 0 "register_operand" "=x")
10723         (plus:V2DI
10724          (zero_extend:V2DI
10725           (vec_select:V2SI
10726            (match_operand:V4SI 1 "nonimmediate_operand" "xm")
10727            (parallel [(const_int 0)
10728                       (const_int 2)])))
10729          (zero_extend:V2DI
10730           (vec_select:V2SI
10731            (match_dup 1)
10732            (parallel [(const_int 1)
10733                       (const_int 3)])))))]
10734   "TARGET_SSE5"
10735   "phaddudq\t{%1, %0|%0, %1}"
10736   [(set_attr "type" "sseiadd1")])
10737
10738 (define_insn "sse5_phsubbw"
10739   [(set (match_operand:V8HI 0 "register_operand" "=x")
10740         (minus:V8HI
10741          (sign_extend:V8HI
10742           (vec_select:V8QI
10743            (match_operand:V16QI 1 "nonimmediate_operand" "xm")
10744            (parallel [(const_int 0)
10745                       (const_int 2)
10746                       (const_int 4)
10747                       (const_int 6)
10748                       (const_int 8)
10749                       (const_int 10)
10750                       (const_int 12)
10751                       (const_int 14)])))
10752          (sign_extend:V8HI
10753           (vec_select:V8QI
10754            (match_dup 1)
10755            (parallel [(const_int 1)
10756                       (const_int 3)
10757                       (const_int 5)
10758                       (const_int 7)
10759                       (const_int 9)
10760                       (const_int 11)
10761                       (const_int 13)
10762                       (const_int 15)])))))]
10763   "TARGET_SSE5"
10764   "phsubbw\t{%1, %0|%0, %1}"
10765   [(set_attr "type" "sseiadd1")])
10766
10767 (define_insn "sse5_phsubwd"
10768   [(set (match_operand:V4SI 0 "register_operand" "=x")
10769         (minus:V4SI
10770          (sign_extend:V4SI
10771           (vec_select:V4HI
10772            (match_operand:V8HI 1 "nonimmediate_operand" "xm")
10773            (parallel [(const_int 0)
10774                       (const_int 2)
10775                       (const_int 4)
10776                       (const_int 6)])))
10777          (sign_extend:V4SI
10778           (vec_select:V4HI
10779            (match_dup 1)
10780            (parallel [(const_int 1)
10781                       (const_int 3)
10782                       (const_int 5)
10783                       (const_int 7)])))))]
10784   "TARGET_SSE5"
10785   "phsubwd\t{%1, %0|%0, %1}"
10786   [(set_attr "type" "sseiadd1")])
10787
10788 (define_insn "sse5_phsubdq"
10789   [(set (match_operand:V2DI 0 "register_operand" "=x")
10790         (minus:V2DI
10791          (sign_extend:V2DI
10792           (vec_select:V2SI
10793            (match_operand:V4SI 1 "nonimmediate_operand" "xm")
10794            (parallel [(const_int 0)
10795                       (const_int 2)])))
10796          (sign_extend:V2DI
10797           (vec_select:V2SI
10798            (match_dup 1)
10799            (parallel [(const_int 1)
10800                       (const_int 3)])))))]
10801   "TARGET_SSE5"
10802   "phsubdq\t{%1, %0|%0, %1}"
10803   [(set_attr "type" "sseiadd1")])
10804
10805 ;; SSE5 permute instructions
10806 (define_insn "sse5_pperm"
10807   [(set (match_operand:V16QI 0 "register_operand" "=x,x,x,x")
10808         (unspec:V16QI
10809           [(match_operand:V16QI 1 "nonimmediate_operand" "0,0,x,xm")
10810            (match_operand:V16QI 2 "nonimmediate_operand" "x,xm,xm,x")
10811            (match_operand:V16QI 3 "nonimmediate_operand" "xm,x,0,0")]
10812           UNSPEC_SSE5_PERMUTE))]
10813   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
10814   "pperm\t{%3, %2, %1, %0|%0, %1, %2, %3}"
10815   [(set_attr "type" "sse4arg")
10816    (set_attr "mode" "TI")])
10817
10818 ;; The following are for the various unpack insns which doesn't need the first
10819 ;; source operand, so we can just use the output operand for the first operand.
10820 ;; This allows either of the other two operands to be a memory operand.  We
10821 ;; can't just use the first operand as an argument to the normal pperm because
10822 ;; then an output only argument, suddenly becomes an input operand.
10823 (define_insn "sse5_pperm_zero_v16qi_v8hi"
10824   [(set (match_operand:V8HI 0 "register_operand" "=x,x")
10825         (zero_extend:V8HI
10826          (vec_select:V8QI
10827           (match_operand:V16QI 1 "nonimmediate_operand" "xm,x")
10828           (match_operand 2 "" ""))))    ;; parallel with const_int's
10829    (use (match_operand:V16QI 3 "nonimmediate_operand" "x,xm"))]
10830   "TARGET_SSE5
10831    && (register_operand (operands[1], V16QImode)
10832        || register_operand (operands[2], V16QImode))"
10833   "pperm\t{%3, %1, %0, %0|%0, %0, %1, %3}"
10834   [(set_attr "type" "sseadd")
10835    (set_attr "mode" "TI")])
10836
10837 (define_insn "sse5_pperm_sign_v16qi_v8hi"
10838   [(set (match_operand:V8HI 0 "register_operand" "=x,x")
10839         (sign_extend:V8HI
10840          (vec_select:V8QI
10841           (match_operand:V16QI 1 "nonimmediate_operand" "xm,x")
10842           (match_operand 2 "" ""))))    ;; parallel with const_int's
10843    (use (match_operand:V16QI 3 "nonimmediate_operand" "x,xm"))]
10844   "TARGET_SSE5
10845    && (register_operand (operands[1], V16QImode)
10846        || register_operand (operands[2], V16QImode))"
10847   "pperm\t{%3, %1, %0, %0|%0, %0, %1, %3}"
10848   [(set_attr "type" "sseadd")
10849    (set_attr "mode" "TI")])
10850
10851 (define_insn "sse5_pperm_zero_v8hi_v4si"
10852   [(set (match_operand:V4SI 0 "register_operand" "=x,x")
10853         (zero_extend:V4SI
10854          (vec_select:V4HI
10855           (match_operand:V8HI 1 "nonimmediate_operand" "xm,x")
10856           (match_operand 2 "" ""))))    ;; parallel with const_int's
10857    (use (match_operand:V16QI 3 "nonimmediate_operand" "x,xm"))]
10858   "TARGET_SSE5
10859    && (register_operand (operands[1], V8HImode)
10860        || register_operand (operands[2], V16QImode))"
10861   "pperm\t{%3, %1, %0, %0|%0, %0, %1, %3}"
10862   [(set_attr "type" "sseadd")
10863    (set_attr "mode" "TI")])
10864
10865 (define_insn "sse5_pperm_sign_v8hi_v4si"
10866   [(set (match_operand:V4SI 0 "register_operand" "=x,x")
10867         (sign_extend:V4SI
10868          (vec_select:V4HI
10869           (match_operand:V8HI 1 "nonimmediate_operand" "xm,x")
10870           (match_operand 2 "" ""))))    ;; parallel with const_int's
10871    (use (match_operand:V16QI 3 "nonimmediate_operand" "x,xm"))]
10872   "TARGET_SSE5
10873    && (register_operand (operands[1], V8HImode)
10874        || register_operand (operands[2], V16QImode))"
10875   "pperm\t{%3, %1, %0, %0|%0, %0, %1, %3}"
10876   [(set_attr "type" "sseadd")
10877    (set_attr "mode" "TI")])
10878
10879 (define_insn "sse5_pperm_zero_v4si_v2di"
10880   [(set (match_operand:V2DI 0 "register_operand" "=x,x")
10881         (zero_extend:V2DI
10882          (vec_select:V2SI
10883           (match_operand:V4SI 1 "nonimmediate_operand" "xm,x")
10884           (match_operand 2 "" ""))))    ;; parallel with const_int's
10885    (use (match_operand:V16QI 3 "nonimmediate_operand" "x,xm"))]
10886   "TARGET_SSE5
10887    && (register_operand (operands[1], V4SImode)
10888        || register_operand (operands[2], V16QImode))"
10889   "pperm\t{%3, %1, %0, %0|%0, %0, %1, %3}"
10890   [(set_attr "type" "sseadd")
10891    (set_attr "mode" "TI")])
10892
10893 (define_insn "sse5_pperm_sign_v4si_v2di"
10894   [(set (match_operand:V2DI 0 "register_operand" "=x,x")
10895         (sign_extend:V2DI
10896          (vec_select:V2SI
10897           (match_operand:V4SI 1 "nonimmediate_operand" "xm,x")
10898           (match_operand 2 "" ""))))    ;; parallel with const_int's
10899    (use (match_operand:V16QI 3 "nonimmediate_operand" "x,xm"))]
10900   "TARGET_SSE5
10901    && (register_operand (operands[1], V4SImode)
10902        || register_operand (operands[2], V16QImode))"
10903   "pperm\t{%3, %1, %0, %0|%0, %0, %1, %3}"
10904   [(set_attr "type" "sseadd")
10905    (set_attr "mode" "TI")])
10906
10907 ;; SSE5 pack instructions that combine two vectors into a smaller vector
10908 (define_insn "sse5_pperm_pack_v2di_v4si"
10909   [(set (match_operand:V4SI 0 "register_operand" "=x,x,x,x")
10910         (vec_concat:V4SI
10911          (truncate:V2SI
10912           (match_operand:V2DI 1 "nonimmediate_operand" "0,0,x,xm"))
10913          (truncate:V2SI
10914           (match_operand:V2DI 2 "nonimmediate_operand" "x,xm,xm,x"))))
10915    (use (match_operand:V16QI 3 "nonimmediate_operand" "xm,x,0,0"))]
10916   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
10917   "pperm\t{%3, %2, %1, %0|%0, %1, %2, %3}"
10918   [(set_attr "type" "sse4arg")
10919    (set_attr "mode" "TI")])
10920
10921 (define_insn "sse5_pperm_pack_v4si_v8hi"
10922   [(set (match_operand:V8HI 0 "register_operand" "=x,x,x,x")
10923         (vec_concat:V8HI
10924          (truncate:V4HI
10925           (match_operand:V4SI 1 "nonimmediate_operand" "0,0,x,xm"))
10926          (truncate:V4HI
10927           (match_operand:V4SI 2 "nonimmediate_operand" "x,xm,xm,x"))))
10928    (use (match_operand:V16QI 3 "nonimmediate_operand" "xm,x,0,0"))]
10929   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
10930   "pperm\t{%3, %2, %1, %0|%0, %1, %2, %3}"
10931   [(set_attr "type" "sse4arg")
10932    (set_attr "mode" "TI")])
10933
10934 (define_insn "sse5_pperm_pack_v8hi_v16qi"
10935   [(set (match_operand:V16QI 0 "register_operand" "=x,x,x,x")
10936         (vec_concat:V16QI
10937          (truncate:V8QI
10938           (match_operand:V8HI 1 "nonimmediate_operand" "0,0,x,xm"))
10939          (truncate:V8QI
10940           (match_operand:V8HI 2 "nonimmediate_operand" "x,xm,xm,x"))))
10941    (use (match_operand:V16QI 3 "nonimmediate_operand" "xm,x,0,0"))]
10942   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
10943   "pperm\t{%3, %2, %1, %0|%0, %1, %2, %3}"
10944   [(set_attr "type" "sse4arg")
10945    (set_attr "mode" "TI")])
10946
10947 ;; Floating point permutation (permps, permpd)
10948 (define_insn "sse5_perm<mode>"
10949   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x,x,x")
10950         (unspec:SSEMODEF2P
10951          [(match_operand:SSEMODEF2P 1 "nonimmediate_operand" "0,0,x,xm")
10952           (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm,xm,x")
10953           (match_operand:V16QI 3 "nonimmediate_operand" "xm,x,0,0")]
10954          UNSPEC_SSE5_PERMUTE))]
10955   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
10956   "perm<ssemodesuffixf4>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
10957   [(set_attr "type" "sse4arg")
10958    (set_attr "mode" "<MODE>")])
10959
10960 ;; SSE5 packed rotate instructions
10961 (define_expand "rotl<mode>3"
10962   [(set (match_operand:SSEMODE1248 0 "register_operand" "")
10963         (rotate:SSEMODE1248
10964          (match_operand:SSEMODE1248 1 "nonimmediate_operand" "")
10965          (match_operand:SI 2 "general_operand")))]
10966   "TARGET_SSE5"
10967 {
10968   /* If we were given a scalar, convert it to parallel */
10969   if (! const_0_to_<sserotatemax>_operand (operands[2], SImode))
10970     {
10971       rtvec vs = rtvec_alloc (<ssescalarnum>);
10972       rtx par = gen_rtx_PARALLEL (<MODE>mode, vs);
10973       rtx reg = gen_reg_rtx (<MODE>mode);
10974       rtx op2 = operands[2];
10975       int i;
10976
10977       if (GET_MODE (op2) != <ssescalarmode>mode)
10978         {
10979           op2 = gen_reg_rtx (<ssescalarmode>mode);
10980           convert_move (op2, operands[2], false);
10981         }
10982
10983       for (i = 0; i < <ssescalarnum>; i++)
10984         RTVEC_ELT (vs, i) = op2;
10985
10986       emit_insn (gen_vec_init<mode> (reg, par));
10987       emit_insn (gen_sse5_vrotl<mode>3 (operands[0], operands[1], reg));
10988       DONE;
10989     }
10990 })
10991
10992 (define_expand "rotr<mode>3"
10993   [(set (match_operand:SSEMODE1248 0 "register_operand" "")
10994         (rotatert:SSEMODE1248
10995          (match_operand:SSEMODE1248 1 "nonimmediate_operand" "")
10996          (match_operand:SI 2 "general_operand")))]
10997   "TARGET_SSE5"
10998 {
10999   /* If we were given a scalar, convert it to parallel */
11000   if (! const_0_to_<sserotatemax>_operand (operands[2], SImode))
11001     {
11002       rtvec vs = rtvec_alloc (<ssescalarnum>);
11003       rtx par = gen_rtx_PARALLEL (<MODE>mode, vs);
11004       rtx neg = gen_reg_rtx (<MODE>mode);
11005       rtx reg = gen_reg_rtx (<MODE>mode);
11006       rtx op2 = operands[2];
11007       int i;
11008
11009       if (GET_MODE (op2) != <ssescalarmode>mode)
11010         {
11011           op2 = gen_reg_rtx (<ssescalarmode>mode);
11012           convert_move (op2, operands[2], false);
11013         }
11014
11015       for (i = 0; i < <ssescalarnum>; i++)
11016         RTVEC_ELT (vs, i) = op2;
11017
11018       emit_insn (gen_vec_init<mode> (reg, par));
11019       emit_insn (gen_neg<mode>2 (neg, reg));
11020       emit_insn (gen_sse5_vrotl<mode>3 (operands[0], operands[1], neg));
11021       DONE;
11022     }
11023 })
11024
11025 (define_insn "sse5_rotl<mode>3"
11026   [(set (match_operand:SSEMODE1248 0 "register_operand" "=x")
11027         (rotate:SSEMODE1248
11028          (match_operand:SSEMODE1248 1 "nonimmediate_operand" "xm")
11029          (match_operand:SI 2 "const_0_to_<sserotatemax>_operand" "n")))]
11030   "TARGET_SSE5"
11031   "prot<ssevecsize>\t{%2, %1, %0|%0, %1, %2}"
11032   [(set_attr "type" "sseishft")
11033    (set_attr "mode" "TI")])
11034
11035 (define_insn "sse5_rotr<mode>3"
11036   [(set (match_operand:SSEMODE1248 0 "register_operand" "=x")
11037         (rotatert:SSEMODE1248
11038          (match_operand:SSEMODE1248 1 "nonimmediate_operand" "xm")
11039          (match_operand:SI 2 "const_0_to_<sserotatemax>_operand" "n")))]
11040   "TARGET_SSE5"
11041 {
11042   operands[3] = GEN_INT ((<ssescalarnum> * 8) - INTVAL (operands[2]));
11043   return \"prot<ssevecsize>\t{%3, %1, %0|%0, %1, %3}\";
11044 }
11045   [(set_attr "type" "sseishft")
11046    (set_attr "mode" "TI")])
11047
11048 (define_expand "vrotr<mode>3"
11049   [(match_operand:SSEMODE1248 0 "register_operand" "")
11050    (match_operand:SSEMODE1248 1 "register_operand" "")
11051    (match_operand:SSEMODE1248 2 "register_operand" "")]
11052   "TARGET_SSE5"
11053 {
11054   rtx reg = gen_reg_rtx (<MODE>mode);
11055   emit_insn (gen_neg<mode>2 (reg, operands[2]));
11056   emit_insn (gen_sse5_vrotl<mode>3 (operands[0], operands[1], reg));
11057   DONE;
11058 })
11059
11060 (define_expand "vrotl<mode>3"
11061   [(match_operand:SSEMODE1248 0 "register_operand" "")
11062    (match_operand:SSEMODE1248 1 "register_operand" "")
11063    (match_operand:SSEMODE1248 2 "register_operand" "")]
11064   "TARGET_SSE5"
11065 {
11066   emit_insn (gen_sse5_vrotl<mode>3 (operands[0], operands[1], operands[2]));
11067   DONE;
11068 })
11069
11070 (define_insn "sse5_vrotl<mode>3"
11071   [(set (match_operand:SSEMODE1248 0 "register_operand" "=x,x")
11072         (if_then_else:SSEMODE1248
11073          (ge:SSEMODE1248
11074           (match_operand:SSEMODE1248 2 "nonimmediate_operand" "xm,x")
11075           (const_int 0))
11076          (rotate:SSEMODE1248
11077           (match_operand:SSEMODE1248 1 "nonimmediate_operand" "x,xm")
11078           (match_dup 2))
11079          (rotatert:SSEMODE1248
11080           (match_dup 1)
11081           (neg:SSEMODE1248 (match_dup 2)))))]
11082   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 3, true, 1, false)"
11083   "prot<ssevecsize>\t{%2, %1, %0|%0, %1, %2}"
11084   [(set_attr "type" "sseishft")
11085    (set_attr "mode" "TI")])
11086
11087 ;; SSE5 packed shift instructions.
11088 ;; FIXME: add V2DI back in
11089 (define_expand "vlshr<mode>3"
11090   [(match_operand:SSEMODE124 0 "register_operand" "")
11091    (match_operand:SSEMODE124 1 "register_operand" "")
11092    (match_operand:SSEMODE124 2 "register_operand" "")]
11093   "TARGET_SSE5"
11094 {
11095   rtx neg = gen_reg_rtx (<MODE>mode);
11096   emit_insn (gen_neg<mode>2 (neg, operands[2]));
11097   emit_insn (gen_sse5_lshl<mode>3 (operands[0], operands[1], neg));
11098   DONE;
11099 })
11100
11101 (define_expand "vashr<mode>3"
11102   [(match_operand:SSEMODE124 0 "register_operand" "")
11103    (match_operand:SSEMODE124 1 "register_operand" "")
11104    (match_operand:SSEMODE124 2 "register_operand" "")]
11105   "TARGET_SSE5"
11106 {
11107   rtx neg = gen_reg_rtx (<MODE>mode);
11108   emit_insn (gen_neg<mode>2 (neg, operands[2]));
11109   emit_insn (gen_sse5_ashl<mode>3 (operands[0], operands[1], neg));
11110   DONE;
11111 })
11112
11113 (define_expand "vashl<mode>3"
11114   [(match_operand:SSEMODE124 0 "register_operand" "")
11115    (match_operand:SSEMODE124 1 "register_operand" "")
11116    (match_operand:SSEMODE124 2 "register_operand" "")]
11117   "TARGET_SSE5"
11118 {
11119   emit_insn (gen_sse5_ashl<mode>3 (operands[0], operands[1], operands[2]));
11120   DONE;
11121 })
11122
11123 (define_insn "sse5_ashl<mode>3"
11124   [(set (match_operand:SSEMODE1248 0 "register_operand" "=x,x")
11125         (if_then_else:SSEMODE1248
11126          (ge:SSEMODE1248
11127           (match_operand:SSEMODE1248 2 "nonimmediate_operand" "xm,x")
11128           (const_int 0))
11129          (ashift:SSEMODE1248
11130           (match_operand:SSEMODE1248 1 "nonimmediate_operand" "x,xm")
11131           (match_dup 2))
11132          (ashiftrt:SSEMODE1248
11133           (match_dup 1)
11134           (neg:SSEMODE1248 (match_dup 2)))))]
11135   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 3, true, 1, false)"
11136   "psha<ssevecsize>\t{%2, %1, %0|%0, %1, %2}"
11137   [(set_attr "type" "sseishft")
11138    (set_attr "mode" "TI")])
11139
11140 (define_insn "sse5_lshl<mode>3"
11141   [(set (match_operand:SSEMODE1248 0 "register_operand" "=x,x")
11142         (if_then_else:SSEMODE1248
11143          (ge:SSEMODE1248
11144           (match_operand:SSEMODE1248 2 "nonimmediate_operand" "xm,x")
11145           (const_int 0))
11146          (ashift:SSEMODE1248
11147           (match_operand:SSEMODE1248 1 "nonimmediate_operand" "x,xm")
11148           (match_dup 2))
11149          (lshiftrt:SSEMODE1248
11150           (match_dup 1)
11151           (neg:SSEMODE1248 (match_dup 2)))))]
11152   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 3, true, 1, false)"
11153   "pshl<ssevecsize>\t{%2, %1, %0|%0, %1, %2}"
11154   [(set_attr "type" "sseishft")
11155    (set_attr "mode" "TI")])
11156
11157 ;; SSE2 doesn't have some shift varients, so define versions for SSE5
11158 (define_expand "ashlv16qi3"
11159   [(match_operand:V16QI 0 "register_operand" "")
11160    (match_operand:V16QI 1 "register_operand" "")
11161    (match_operand:SI 2 "nonmemory_operand" "")]
11162   "TARGET_SSE5"
11163 {
11164   rtvec vs = rtvec_alloc (16);
11165   rtx par = gen_rtx_PARALLEL (V16QImode, vs);
11166   rtx reg = gen_reg_rtx (V16QImode);
11167   int i;
11168   for (i = 0; i < 16; i++)
11169     RTVEC_ELT (vs, i) = operands[2];
11170
11171   emit_insn (gen_vec_initv16qi (reg, par));
11172   emit_insn (gen_sse5_ashlv16qi3 (operands[0], operands[1], reg));
11173   DONE;
11174 })
11175
11176 (define_expand "lshlv16qi3"
11177   [(match_operand:V16QI 0 "register_operand" "")
11178    (match_operand:V16QI 1 "register_operand" "")
11179    (match_operand:SI 2 "nonmemory_operand" "")]
11180   "TARGET_SSE5"
11181 {
11182   rtvec vs = rtvec_alloc (16);
11183   rtx par = gen_rtx_PARALLEL (V16QImode, vs);
11184   rtx reg = gen_reg_rtx (V16QImode);
11185   int i;
11186   for (i = 0; i < 16; i++)
11187     RTVEC_ELT (vs, i) = operands[2];
11188
11189   emit_insn (gen_vec_initv16qi (reg, par));
11190   emit_insn (gen_sse5_lshlv16qi3 (operands[0], operands[1], reg));
11191   DONE;
11192 })
11193
11194 (define_expand "ashrv16qi3"
11195   [(match_operand:V16QI 0 "register_operand" "")
11196    (match_operand:V16QI 1 "register_operand" "")
11197    (match_operand:SI 2 "nonmemory_operand" "")]
11198   "TARGET_SSE5"
11199 {
11200   rtvec vs = rtvec_alloc (16);
11201   rtx par = gen_rtx_PARALLEL (V16QImode, vs);
11202   rtx reg = gen_reg_rtx (V16QImode);
11203   int i;
11204   rtx ele = ((GET_CODE (operands[2]) == CONST_INT)
11205              ? GEN_INT (- INTVAL (operands[2]))
11206              : operands[2]);
11207
11208   for (i = 0; i < 16; i++)
11209     RTVEC_ELT (vs, i) = ele;
11210
11211   emit_insn (gen_vec_initv16qi (reg, par));
11212
11213   if (GET_CODE (operands[2]) != CONST_INT)
11214     {
11215       rtx neg = gen_reg_rtx (V16QImode);
11216       emit_insn (gen_negv16qi2 (neg, reg));
11217       emit_insn (gen_sse5_ashlv16qi3 (operands[0], operands[1], neg));
11218     }
11219   else
11220     emit_insn (gen_sse5_ashlv16qi3 (operands[0], operands[1], reg));
11221
11222   DONE;
11223 })
11224
11225 (define_expand "ashrv2di3"
11226   [(match_operand:V2DI 0 "register_operand" "")
11227    (match_operand:V2DI 1 "register_operand" "")
11228    (match_operand:DI 2 "nonmemory_operand" "")]
11229   "TARGET_SSE5"
11230 {
11231   rtvec vs = rtvec_alloc (2);
11232   rtx par = gen_rtx_PARALLEL (V2DImode, vs);
11233   rtx reg = gen_reg_rtx (V2DImode);
11234   rtx ele;
11235
11236   if (GET_CODE (operands[2]) == CONST_INT)
11237     ele = GEN_INT (- INTVAL (operands[2]));
11238   else if (GET_MODE (operands[2]) != DImode)
11239     {
11240       rtx move = gen_reg_rtx (DImode);
11241       ele = gen_reg_rtx (DImode);
11242       convert_move (move, operands[2], false);
11243       emit_insn (gen_negdi2 (ele, move));
11244     }
11245   else
11246     {
11247       ele = gen_reg_rtx (DImode);
11248       emit_insn (gen_negdi2 (ele, operands[2]));
11249     }
11250
11251   RTVEC_ELT (vs, 0) = ele;
11252   RTVEC_ELT (vs, 1) = ele;
11253   emit_insn (gen_vec_initv2di (reg, par));
11254   emit_insn (gen_sse5_ashlv2di3 (operands[0], operands[1], reg));
11255   DONE;
11256 })
11257
11258 ;; SSE5 FRCZ support
11259 ;; parallel insns
11260 (define_insn "sse5_frcz<mode>2"
11261   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
11262         (unspec:SSEMODEF2P
11263          [(match_operand:SSEMODEF2P 1 "nonimmediate_operand" "xm")]
11264          UNSPEC_FRCZ))]
11265   "TARGET_SSE5"
11266   "frcz<ssemodesuffixf4>\t{%1, %0|%0, %1}"
11267   [(set_attr "type" "ssecvt1")
11268    (set_attr "prefix_extra" "1")
11269    (set_attr "mode" "<MODE>")])
11270
11271 ;; scalar insns
11272 (define_insn "sse5_vmfrcz<mode>2"
11273   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
11274         (vec_merge:SSEMODEF2P
11275           (unspec:SSEMODEF2P
11276            [(match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")]
11277            UNSPEC_FRCZ)
11278           (match_operand:SSEMODEF2P 1 "register_operand" "0")
11279           (const_int 1)))]
11280   "TARGET_SSE5"
11281   "frcz<ssemodesuffixf2s>\t{%2, %0|%0, %2}"
11282   [(set_attr "type" "ssecvt1")
11283    (set_attr "prefix_extra" "1")
11284    (set_attr "mode" "<MODE>")])
11285
11286 (define_insn "sse5_cvtph2ps"
11287   [(set (match_operand:V4SF 0 "register_operand" "=x")
11288         (unspec:V4SF [(match_operand:V4HI 1 "nonimmediate_operand" "xm")]
11289                      UNSPEC_CVTPH2PS))]
11290   "TARGET_SSE5"
11291   "cvtph2ps\t{%1, %0|%0, %1}"
11292   [(set_attr "type" "ssecvt")
11293    (set_attr "mode" "V4SF")])
11294
11295 (define_insn "sse5_cvtps2ph"
11296   [(set (match_operand:V4HI 0 "nonimmediate_operand" "=xm")
11297         (unspec:V4HI [(match_operand:V4SF 1 "register_operand" "x")]
11298                      UNSPEC_CVTPS2PH))]
11299   "TARGET_SSE5"
11300   "cvtps2ph\t{%1, %0|%0, %1}"
11301   [(set_attr "type" "ssecvt")
11302    (set_attr "mode" "V4SF")])
11303
11304 ;; Scalar versions of the com instructions that use vector types that are
11305 ;; called from the intrinsics.  Unlike the the other s{s,d} instructions, the
11306 ;; com instructions fill in 0's in the upper bits instead of leaving them
11307 ;; unmodified, so we use const_vector of 0 instead of match_dup.
11308 (define_expand "sse5_vmmaskcmp<mode>3"
11309   [(set (match_operand:SSEMODEF2P 0 "register_operand" "")
11310         (vec_merge:SSEMODEF2P
11311          (match_operator:SSEMODEF2P 1 "sse5_comparison_float_operator"
11312           [(match_operand:SSEMODEF2P 2 "register_operand" "")
11313            (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "")])
11314          (match_dup 4)
11315          (const_int 1)))]
11316   "TARGET_SSE5"
11317 {
11318   operands[4] = CONST0_RTX (<MODE>mode);
11319 })
11320
11321 (define_insn "*sse5_vmmaskcmp<mode>3"
11322   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
11323         (vec_merge:SSEMODEF2P
11324          (match_operator:SSEMODEF2P 1 "sse5_comparison_float_operator"
11325           [(match_operand:SSEMODEF2P 2 "register_operand" "x")
11326            (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm")])
11327           (match_operand:SSEMODEF2P 4 "")
11328           (const_int 1)))]
11329   "TARGET_SSE5"
11330   "com%Y1<ssemodesuffixf2s>\t{%3, %2, %0|%0, %2, %3}"
11331   [(set_attr "type" "sse4arg")
11332    (set_attr "mode" "<ssescalarmode>")])
11333
11334 ;; We don't have a comparison operator that always returns true/false, so
11335 ;; handle comfalse and comtrue specially.
11336 (define_insn "sse5_com_tf<mode>3"
11337   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
11338         (unspec:SSEMODEF2P
11339          [(match_operand:SSEMODEF2P 1 "register_operand" "x")
11340           (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")
11341           (match_operand:SI 3 "const_int_operand" "n")]
11342          UNSPEC_SSE5_TRUEFALSE))]
11343   "TARGET_SSE5"
11344 {
11345   const char *ret = NULL;
11346
11347   switch (INTVAL (operands[3]))
11348     {
11349     case COM_FALSE_S:
11350       ret = \"comfalses<ssemodesuffixf2c>\t{%2, %1, %0|%0, %1, %2}\";
11351       break;
11352
11353     case COM_FALSE_P:
11354       ret = \"comfalsep<ssemodesuffixf2c>\t{%2, %1, %0|%0, %1, %2}\";
11355       break;
11356
11357     case COM_TRUE_S:
11358       ret = \"comfalses<ssemodesuffixf2c>\t{%2, %1, %0|%0, %1, %2}\";
11359       break;
11360
11361     case COM_TRUE_P:
11362       ret = \"comfalsep<ssemodesuffixf2c>\t{%2, %1, %0|%0, %1, %2}\";
11363       break;
11364
11365     default:
11366       gcc_unreachable ();
11367     }
11368
11369   return ret;
11370 }
11371   [(set_attr "type" "ssecmp")
11372    (set_attr "mode" "<MODE>")])
11373
11374 (define_insn "sse5_maskcmp<mode>3"
11375   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
11376         (match_operator:SSEMODEF2P 1 "sse5_comparison_float_operator"
11377          [(match_operand:SSEMODEF2P 2 "register_operand" "x")
11378           (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm")]))]
11379   "TARGET_SSE5"
11380   "com%Y1<ssemodesuffixf4>\t{%3, %2, %0|%0, %2, %3}"
11381   [(set_attr "type" "ssecmp")
11382    (set_attr "mode" "<MODE>")])
11383
11384 (define_insn "sse5_maskcmp<mode>3"
11385   [(set (match_operand:SSEMODE1248 0 "register_operand" "=x")
11386         (match_operator:SSEMODE1248 1 "ix86_comparison_int_operator"
11387          [(match_operand:SSEMODE1248 2 "register_operand" "x")
11388           (match_operand:SSEMODE1248 3 "nonimmediate_operand" "xm")]))]
11389   "TARGET_SSE5"
11390   "pcom%Y1<ssevecsize>\t{%3, %2, %0|%0, %2, %3}"
11391   [(set_attr "type" "sse4arg")
11392    (set_attr "mode" "TI")])
11393
11394 (define_insn "sse5_maskcmp_uns<mode>3"
11395   [(set (match_operand:SSEMODE1248 0 "register_operand" "=x")
11396         (match_operator:SSEMODE1248 1 "ix86_comparison_uns_operator"
11397          [(match_operand:SSEMODE1248 2 "register_operand" "x")
11398           (match_operand:SSEMODE1248 3 "nonimmediate_operand" "xm")]))]
11399   "TARGET_SSE5"
11400   "pcom%Y1u<ssevecsize>\t{%3, %2, %0|%0, %2, %3}"
11401   [(set_attr "type" "ssecmp")
11402    (set_attr "mode" "TI")])
11403
11404 ;; Version of pcom*u* that is called from the intrinsics that allows pcomequ*
11405 ;; and pcomneu* not to be converted to the signed ones in case somebody needs
11406 ;; the exact instruction generated for the intrinsic.
11407 (define_insn "sse5_maskcmp_uns2<mode>3"
11408   [(set (match_operand:SSEMODE1248 0 "register_operand" "=x")
11409         (unspec:SSEMODE1248
11410          [(match_operator:SSEMODE1248 1 "ix86_comparison_uns_operator"
11411           [(match_operand:SSEMODE1248 2 "register_operand" "x")
11412            (match_operand:SSEMODE1248 3 "nonimmediate_operand" "xm")])]
11413          UNSPEC_SSE5_UNSIGNED_CMP))]
11414   "TARGET_SSE5"
11415   "pcom%Y1u<ssevecsize>\t{%3, %2, %0|%0, %2, %3}"
11416   [(set_attr "type" "ssecmp")
11417    (set_attr "mode" "TI")])
11418
11419 ;; Pcomtrue and pcomfalse support.  These are useless instructions, but are
11420 ;; being added here to be complete.
11421 (define_insn "sse5_pcom_tf<mode>3"
11422   [(set (match_operand:SSEMODE1248 0 "register_operand" "=x")
11423         (unspec:SSEMODE1248
11424           [(match_operand:SSEMODE1248 1 "register_operand" "x")
11425            (match_operand:SSEMODE1248 2 "nonimmediate_operand" "xm")
11426            (match_operand:SI 3 "const_int_operand" "n")]
11427           UNSPEC_SSE5_TRUEFALSE))]
11428   "TARGET_SSE5"
11429 {
11430   return ((INTVAL (operands[3]) != 0)
11431           ? "pcomtrue<ssevecsize>\t{%2, %1, %0|%0, %1, %2}"
11432           : "pcomfalse<ssevecsize>\t{%2, %1, %0|%0, %1, %2}");
11433 }
11434   [(set_attr "type" "ssecmp")
11435    (set_attr "mode" "TI")])
11436
11437 (define_insn "*avx_aesenc"
11438   [(set (match_operand:V2DI 0 "register_operand" "=x")
11439         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")
11440                        (match_operand:V2DI 2 "nonimmediate_operand" "xm")]
11441                       UNSPEC_AESENC))]
11442   "TARGET_AES && TARGET_AVX"
11443   "vaesenc\t{%2, %1, %0|%0, %1, %2}"
11444   [(set_attr "type" "sselog1")
11445    (set_attr "prefix" "vex")
11446    (set_attr "mode" "TI")])
11447
11448 (define_insn "aesenc"
11449   [(set (match_operand:V2DI 0 "register_operand" "=x")
11450         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0")
11451                        (match_operand:V2DI 2 "nonimmediate_operand" "xm")]
11452                       UNSPEC_AESENC))]
11453   "TARGET_AES"
11454   "aesenc\t{%2, %0|%0, %2}"
11455   [(set_attr "type" "sselog1")
11456    (set_attr "prefix_extra" "1")
11457    (set_attr "mode" "TI")])
11458
11459 (define_insn "*avx_aesenclast"
11460   [(set (match_operand:V2DI 0 "register_operand" "=x")
11461         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")
11462                        (match_operand:V2DI 2 "nonimmediate_operand" "xm")]
11463                       UNSPEC_AESENCLAST))]
11464   "TARGET_AES && TARGET_AVX"
11465   "vaesenclast\t{%2, %1, %0|%0, %1, %2}"
11466   [(set_attr "type" "sselog1")
11467    (set_attr "prefix" "vex")
11468    (set_attr "mode" "TI")])
11469
11470 (define_insn "aesenclast"
11471   [(set (match_operand:V2DI 0 "register_operand" "=x")
11472         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0")
11473                        (match_operand:V2DI 2 "nonimmediate_operand" "xm")]
11474                       UNSPEC_AESENCLAST))]
11475   "TARGET_AES"
11476   "aesenclast\t{%2, %0|%0, %2}"
11477   [(set_attr "type" "sselog1")
11478    (set_attr "prefix_extra" "1")
11479    (set_attr "mode" "TI")])
11480
11481 (define_insn "*avx_aesdec"
11482   [(set (match_operand:V2DI 0 "register_operand" "=x")
11483         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")
11484                        (match_operand:V2DI 2 "nonimmediate_operand" "xm")]
11485                       UNSPEC_AESDEC))]
11486   "TARGET_AES && TARGET_AVX"
11487   "vaesdec\t{%2, %1, %0|%0, %1, %2}"
11488   [(set_attr "type" "sselog1")
11489    (set_attr "prefix" "vex")
11490    (set_attr "mode" "TI")])
11491
11492 (define_insn "aesdec"
11493   [(set (match_operand:V2DI 0 "register_operand" "=x")
11494         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0")
11495                        (match_operand:V2DI 2 "nonimmediate_operand" "xm")]
11496                       UNSPEC_AESDEC))]
11497   "TARGET_AES"
11498   "aesdec\t{%2, %0|%0, %2}"
11499   [(set_attr "type" "sselog1")
11500    (set_attr "prefix_extra" "1")
11501    (set_attr "mode" "TI")])
11502
11503 (define_insn "*avx_aesdeclast"
11504   [(set (match_operand:V2DI 0 "register_operand" "=x")
11505         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")
11506                        (match_operand:V2DI 2 "nonimmediate_operand" "xm")]
11507                       UNSPEC_AESDECLAST))]
11508   "TARGET_AES && TARGET_AVX"
11509   "vaesdeclast\t{%2, %1, %0|%0, %1, %2}"
11510   [(set_attr "type" "sselog1")
11511    (set_attr "prefix" "vex")
11512    (set_attr "mode" "TI")])
11513
11514 (define_insn "aesdeclast"
11515   [(set (match_operand:V2DI 0 "register_operand" "=x")
11516         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0")
11517                        (match_operand:V2DI 2 "nonimmediate_operand" "xm")]
11518                       UNSPEC_AESDECLAST))]
11519   "TARGET_AES"
11520   "aesdeclast\t{%2, %0|%0, %2}"
11521   [(set_attr "type" "sselog1")
11522    (set_attr "prefix_extra" "1")
11523    (set_attr "mode" "TI")])
11524
11525 (define_insn "aesimc"
11526   [(set (match_operand:V2DI 0 "register_operand" "=x")
11527         (unspec:V2DI [(match_operand:V2DI 1 "nonimmediate_operand" "xm")]
11528                       UNSPEC_AESIMC))]
11529   "TARGET_AES"
11530   "%vaesimc\t{%1, %0|%0, %1}"
11531   [(set_attr "type" "sselog1")
11532    (set_attr "prefix_extra" "1")
11533    (set_attr "prefix" "maybe_vex")
11534    (set_attr "mode" "TI")])
11535
11536 (define_insn "aeskeygenassist"
11537   [(set (match_operand:V2DI 0 "register_operand" "=x")
11538         (unspec:V2DI [(match_operand:V2DI 1 "nonimmediate_operand" "xm")
11539                       (match_operand:SI 2 "const_0_to_255_operand" "n")]
11540                      UNSPEC_AESKEYGENASSIST))]
11541   "TARGET_AES"
11542   "%vaeskeygenassist\t{%2, %1, %0|%0, %1, %2}"
11543   [(set_attr "type" "sselog1")
11544    (set_attr "prefix_extra" "1")
11545    (set_attr "prefix" "maybe_vex")
11546    (set_attr "mode" "TI")])
11547
11548 (define_insn "*vpclmulqdq"
11549   [(set (match_operand:V2DI 0 "register_operand" "=x")
11550         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")
11551                       (match_operand:V2DI 2 "nonimmediate_operand" "xm")
11552                       (match_operand:SI 3 "const_0_to_255_operand" "n")]
11553                      UNSPEC_PCLMUL))]
11554   "TARGET_PCLMUL && TARGET_AVX"
11555   "vpclmulqdq\t{%3, %2, %1, %0|%0, %1, %2, %3}"
11556   [(set_attr "type" "sselog1")
11557    (set_attr "prefix" "vex")
11558    (set_attr "mode" "TI")])
11559
11560 (define_insn "pclmulqdq"
11561   [(set (match_operand:V2DI 0 "register_operand" "=x")
11562         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0")
11563                       (match_operand:V2DI 2 "nonimmediate_operand" "xm")
11564                       (match_operand:SI 3 "const_0_to_255_operand" "n")]
11565                      UNSPEC_PCLMUL))]
11566   "TARGET_PCLMUL"
11567   "pclmulqdq\t{%3, %2, %0|%0, %2, %3}"
11568   [(set_attr "type" "sselog1")
11569    (set_attr "prefix_extra" "1")
11570    (set_attr "mode" "TI")])
11571
11572 (define_expand "avx_vzeroall"
11573   [(match_par_dup 0 [(const_int 0)])]
11574   "TARGET_AVX"
11575 {
11576   int nregs = TARGET_64BIT ? 16 : 8;
11577   int regno;
11578
11579   operands[0] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nregs + 1));
11580
11581   XVECEXP (operands[0], 0, 0)
11582     = gen_rtx_UNSPEC_VOLATILE (VOIDmode, gen_rtvec (1, const0_rtx),
11583                                UNSPECV_VZEROALL);
11584
11585   for (regno = 0; regno < nregs; regno++)
11586     XVECEXP (operands[0], 0, regno + 1)
11587       = gen_rtx_SET (VOIDmode,
11588                      gen_rtx_REG (V8SImode, SSE_REGNO (regno)),
11589                      CONST0_RTX (V8SImode));
11590 })
11591
11592 (define_insn "*avx_vzeroall"
11593   [(match_parallel 0 "vzeroall_operation"
11594     [(unspec_volatile [(const_int 0)] UNSPECV_VZEROALL)
11595      (set (match_operand 1 "register_operand" "=x")
11596           (match_operand 2 "const0_operand" "X"))])]
11597   "TARGET_AVX"
11598   "vzeroall"
11599   [(set_attr "type" "sse")
11600    (set_attr "memory" "none")
11601    (set_attr "prefix" "vex")
11602    (set_attr "mode" "OI")])
11603
11604 ;; vzeroupper clobbers the upper 128bits of AVX registers.
11605 (define_insn "avx_vzeroupper"
11606   [(unspec_volatile [(const_int 0)] UNSPECV_VZEROUPPER)
11607    (clobber (reg:V8SI XMM0_REG))
11608    (clobber (reg:V8SI XMM1_REG))
11609    (clobber (reg:V8SI XMM2_REG))
11610    (clobber (reg:V8SI XMM3_REG))
11611    (clobber (reg:V8SI XMM4_REG))
11612    (clobber (reg:V8SI XMM5_REG))
11613    (clobber (reg:V8SI XMM6_REG))
11614    (clobber (reg:V8SI XMM7_REG))]
11615   "TARGET_AVX && !TARGET_64BIT"
11616   "vzeroupper"
11617   [(set_attr "type" "sse")
11618    (set_attr "memory" "none")
11619    (set_attr "prefix" "vex")
11620    (set_attr "mode" "OI")])
11621
11622 (define_insn "avx_vzeroupper_rex64"
11623   [(unspec_volatile [(const_int 0)] UNSPECV_VZEROUPPER)
11624    (clobber (reg:V8SI XMM0_REG))
11625    (clobber (reg:V8SI XMM1_REG))
11626    (clobber (reg:V8SI XMM2_REG))
11627    (clobber (reg:V8SI XMM3_REG))
11628    (clobber (reg:V8SI XMM4_REG))
11629    (clobber (reg:V8SI XMM5_REG))
11630    (clobber (reg:V8SI XMM6_REG))
11631    (clobber (reg:V8SI XMM7_REG))
11632    (clobber (reg:V8SI XMM8_REG))
11633    (clobber (reg:V8SI XMM9_REG))
11634    (clobber (reg:V8SI XMM10_REG))
11635    (clobber (reg:V8SI XMM11_REG))
11636    (clobber (reg:V8SI XMM12_REG))
11637    (clobber (reg:V8SI XMM13_REG))
11638    (clobber (reg:V8SI XMM14_REG))
11639    (clobber (reg:V8SI XMM15_REG))]
11640   "TARGET_AVX && TARGET_64BIT"
11641   "vzeroupper"
11642   [(set_attr "type" "sse")
11643    (set_attr "memory" "none")
11644    (set_attr "prefix" "vex")
11645    (set_attr "mode" "OI")])
11646
11647 (define_insn "avx_vpermil<mode>"
11648   [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x")
11649         (unspec:AVXMODEF2P
11650           [(match_operand:AVXMODEF2P 1 "register_operand" "xm")
11651            (match_operand:SI 2 "const_0_to_<vpermilbits>_operand" "n")]
11652           UNSPEC_VPERMIL))]
11653   "TARGET_AVX"
11654   "vpermilp<avxmodesuffixf2c>\t{%2, %1, %0|%0, %1, %2}"
11655   [(set_attr "type" "sselog")
11656    (set_attr "prefix" "vex")
11657    (set_attr "mode" "<MODE>")])
11658
11659 (define_insn "avx_vpermilvar<mode>3"
11660   [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x")
11661         (unspec:AVXMODEF2P
11662           [(match_operand:AVXMODEF2P 1 "register_operand" "x")
11663            (match_operand:<avxpermvecmode> 2 "nonimmediate_operand" "xm")]
11664           UNSPEC_VPERMIL))]
11665   "TARGET_AVX"
11666   "vpermilp<avxmodesuffixf2c>\t{%2, %1, %0|%0, %1, %2}"
11667   [(set_attr "type" "sselog")
11668    (set_attr "prefix" "vex")
11669    (set_attr "mode" "<MODE>")])
11670
11671 (define_insn "avx_vperm2f128<mode>3"
11672   [(set (match_operand:AVX256MODE2P 0 "register_operand" "=x")
11673         (unspec:AVX256MODE2P
11674           [(match_operand:AVX256MODE2P 1 "register_operand" "x")
11675            (match_operand:AVX256MODE2P 2 "nonimmediate_operand" "xm")
11676            (match_operand:SI 3 "const_0_to_255_operand" "n")]
11677           UNSPEC_VPERMIL2F128))]
11678   "TARGET_AVX"
11679   "vperm2f128\t{%3, %2, %1, %0|%0, %1, %2, %3}"
11680   [(set_attr "type" "sselog")
11681    (set_attr "prefix" "vex")
11682    (set_attr "mode" "V8SF")])
11683
11684 (define_insn "avx_vbroadcasts<avxmodesuffixf2c><avxmodesuffix>"
11685   [(set (match_operand:AVXMODEF4P 0 "register_operand" "=x")
11686         (vec_concat:AVXMODEF4P
11687           (vec_concat:<avxhalfvecmode>
11688             (match_operand:<avxscalarmode> 1 "memory_operand" "m")
11689             (match_dup 1))
11690           (vec_concat:<avxhalfvecmode>
11691             (match_dup 1)
11692             (match_dup 1))))]
11693   "TARGET_AVX"
11694   "vbroadcasts<avxmodesuffixf2c>\t{%1, %0|%0, %1}"
11695   [(set_attr "type" "ssemov")
11696    (set_attr "prefix" "vex")
11697    (set_attr "mode" "<avxscalarmode>")])
11698
11699 (define_insn "avx_vbroadcastss256"
11700   [(set (match_operand:V8SF 0 "register_operand" "=x")
11701         (vec_concat:V8SF
11702           (vec_concat:V4SF
11703             (vec_concat:V2SF
11704               (match_operand:SF 1 "memory_operand" "m")
11705               (match_dup 1))
11706             (vec_concat:V2SF
11707               (match_dup 1)
11708               (match_dup 1)))
11709           (vec_concat:V4SF
11710             (vec_concat:V2SF
11711               (match_dup 1)
11712               (match_dup 1))
11713             (vec_concat:V2SF
11714               (match_dup 1)
11715               (match_dup 1)))))]
11716   "TARGET_AVX"
11717   "vbroadcastss\t{%1, %0|%0, %1}"
11718   [(set_attr "type" "ssemov")
11719    (set_attr "prefix" "vex")
11720    (set_attr "mode" "SF")])
11721
11722 (define_insn "avx_vbroadcastf128_p<avxmodesuffixf2c>256"
11723   [(set (match_operand:AVX256MODEF2P 0 "register_operand" "=x")
11724         (vec_concat:AVX256MODEF2P
11725           (match_operand:<avxhalfvecmode> 1 "memory_operand" "m")
11726           (match_dup 1)))]
11727   "TARGET_AVX"
11728   "vbroadcastf128\t{%1, %0|%0, %1}"
11729   [(set_attr "type" "ssemov")
11730    (set_attr "prefix" "vex")
11731    (set_attr "mode" "V4SF")])
11732
11733 (define_expand "avx_vinsertf128<mode>"
11734   [(match_operand:AVX256MODE 0 "register_operand" "")
11735    (match_operand:AVX256MODE 1 "register_operand" "")
11736    (match_operand:<avxhalfvecmode> 2 "nonimmediate_operand" "")
11737    (match_operand:SI 3 "const_0_to_1_operand" "")]
11738   "TARGET_AVX"
11739 {
11740   switch (INTVAL (operands[3]))
11741     {
11742     case 0:
11743       emit_insn (gen_vec_set_lo_<mode> (operands[0], operands[1],
11744                                         operands[2]));
11745       break;
11746     case 1:
11747       emit_insn (gen_vec_set_hi_<mode> (operands[0], operands[1],
11748                                         operands[2]));
11749       break;
11750     default:
11751       gcc_unreachable ();
11752     }
11753   DONE;
11754 })
11755
11756 (define_insn "vec_set_lo_<mode>"
11757   [(set (match_operand:AVX256MODE4P 0 "register_operand" "=x")
11758         (vec_concat:AVX256MODE4P
11759           (match_operand:<avxhalfvecmode> 2 "nonimmediate_operand" "xm")
11760           (vec_select:<avxhalfvecmode>
11761             (match_operand:AVX256MODE4P 1 "register_operand" "x")
11762             (parallel [(const_int 2) (const_int 3)]))))]
11763   "TARGET_AVX"
11764   "vinsertf128\t{$0x0, %2, %1, %0|%0, %1, %2, 0x0}"
11765   [(set_attr "type" "sselog")
11766    (set_attr "prefix" "vex")
11767    (set_attr "mode" "V8SF")])
11768
11769 (define_insn "vec_set_hi_<mode>"
11770   [(set (match_operand:AVX256MODE4P 0 "register_operand" "=x")
11771         (vec_concat:AVX256MODE4P
11772           (vec_select:<avxhalfvecmode>
11773             (match_operand:AVX256MODE4P 1 "register_operand" "x")
11774             (parallel [(const_int 0) (const_int 1)]))
11775           (match_operand:<avxhalfvecmode> 2 "nonimmediate_operand" "xm")))]
11776   "TARGET_AVX"
11777   "vinsertf128\t{$0x1, %2, %1, %0|%0, %1, %2, 0x1}"
11778   [(set_attr "type" "sselog")
11779    (set_attr "prefix" "vex")
11780    (set_attr "mode" "V8SF")])
11781
11782 (define_insn "vec_set_lo_<mode>"
11783   [(set (match_operand:AVX256MODE8P 0 "register_operand" "=x")
11784         (vec_concat:AVX256MODE8P
11785           (match_operand:<avxhalfvecmode> 2 "nonimmediate_operand" "xm")
11786           (vec_select:<avxhalfvecmode>
11787             (match_operand:AVX256MODE8P 1 "register_operand" "x")
11788             (parallel [(const_int 4) (const_int 5)
11789                        (const_int 6) (const_int 7)]))))]
11790   "TARGET_AVX"
11791   "vinsertf128\t{$0x0, %2, %1, %0|%0, %1, %2, 0x0}"
11792   [(set_attr "type" "sselog")
11793    (set_attr "prefix" "vex")
11794    (set_attr "mode" "V8SF")])
11795
11796 (define_insn "vec_set_hi_<mode>"
11797   [(set (match_operand:AVX256MODE8P 0 "register_operand" "=x")
11798         (vec_concat:AVX256MODE8P
11799           (vec_select:<avxhalfvecmode>
11800             (match_operand:AVX256MODE8P 1 "register_operand" "x")
11801             (parallel [(const_int 0) (const_int 1)
11802                        (const_int 2) (const_int 3)]))
11803           (match_operand:<avxhalfvecmode> 2 "nonimmediate_operand" "xm")))]
11804   "TARGET_AVX"
11805   "vinsertf128\t{$0x1, %2, %1, %0|%0, %1, %2, 0x1}"
11806   [(set_attr "type" "sselog")
11807    (set_attr "prefix" "vex")
11808    (set_attr "mode" "V8SF")])
11809
11810 (define_insn "vec_set_lo_v16hi"
11811   [(set (match_operand:V16HI 0 "register_operand" "=x")
11812         (vec_concat:V16HI
11813           (match_operand:V8HI 2 "nonimmediate_operand" "xm")
11814           (vec_select:V8HI
11815             (match_operand:V16HI 1 "register_operand" "x")
11816             (parallel [(const_int 8) (const_int 9)
11817                        (const_int 10) (const_int 11)
11818                        (const_int 12) (const_int 13)
11819                        (const_int 14) (const_int 15)]))))]
11820   "TARGET_AVX"
11821   "vinsertf128\t{$0x0, %2, %1, %0|%0, %1, %2, 0x0}"
11822   [(set_attr "type" "sselog")
11823    (set_attr "prefix" "vex")
11824    (set_attr "mode" "V8SF")])
11825
11826 (define_insn "vec_set_hi_v16hi"
11827   [(set (match_operand:V16HI 0 "register_operand" "=x")
11828         (vec_concat:V16HI
11829           (vec_select:V8HI
11830             (match_operand:V16HI 1 "register_operand" "x")
11831             (parallel [(const_int 0) (const_int 1)
11832                        (const_int 2) (const_int 3)
11833                        (const_int 4) (const_int 5)
11834                        (const_int 6) (const_int 7)]))
11835           (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
11836   "TARGET_AVX"
11837   "vinsertf128\t{$0x1, %2, %1, %0|%0, %1, %2, 0x1}"
11838   [(set_attr "type" "sselog")
11839    (set_attr "prefix" "vex")
11840    (set_attr "mode" "V8SF")])
11841
11842 (define_insn "vec_set_lo_v32qi"
11843   [(set (match_operand:V32QI 0 "register_operand" "=x")
11844         (vec_concat:V32QI
11845           (match_operand:V16QI 2 "nonimmediate_operand" "xm")
11846           (vec_select:V16QI
11847             (match_operand:V32QI 1 "register_operand" "x")
11848             (parallel [(const_int 16) (const_int 17)
11849                        (const_int 18) (const_int 19)
11850                        (const_int 20) (const_int 21)
11851                        (const_int 22) (const_int 23)
11852                        (const_int 24) (const_int 25)
11853                        (const_int 26) (const_int 27)
11854                        (const_int 28) (const_int 29)
11855                        (const_int 30) (const_int 31)]))))]
11856   "TARGET_AVX"
11857   "vinsertf128\t{$0x0, %2, %1, %0|%0, %1, %2, 0x0}"
11858   [(set_attr "type" "sselog")
11859    (set_attr "prefix" "vex")
11860    (set_attr "mode" "V8SF")])
11861
11862 (define_insn "vec_set_hi_v32qi"
11863   [(set (match_operand:V32QI 0 "register_operand" "=x")
11864         (vec_concat:V32QI
11865           (vec_select:V16QI
11866             (match_operand:V32QI 1 "register_operand" "x")
11867             (parallel [(const_int 0) (const_int 1)
11868                        (const_int 2) (const_int 3)
11869                        (const_int 4) (const_int 5)
11870                        (const_int 6) (const_int 7)
11871                        (const_int 8) (const_int 9)
11872                        (const_int 10) (const_int 11)
11873                        (const_int 12) (const_int 13)
11874                        (const_int 14) (const_int 15)]))
11875           (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
11876   "TARGET_AVX"
11877   "vinsertf128\t{$0x1, %2, %1, %0|%0, %1, %2, 0x1}"
11878   [(set_attr "type" "sselog")
11879    (set_attr "prefix" "vex")
11880    (set_attr "mode" "V8SF")])
11881
11882 (define_insn "avx_maskloadp<avxmodesuffixf2c><avxmodesuffix>"
11883   [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x")
11884         (unspec:AVXMODEF2P
11885           [(match_operand:AVXMODEF2P 1 "memory_operand" "m")
11886            (match_operand:AVXMODEF2P 2 "register_operand" "x")
11887            (match_dup 0)]
11888           UNSPEC_MASKLOAD))]
11889   "TARGET_AVX"
11890   "vmaskmovp<avxmodesuffixf2c>\t{%1, %2, %0|%0, %2, %1}"
11891   [(set_attr "type" "sselog1")
11892    (set_attr "prefix" "vex")
11893    (set_attr "mode" "<MODE>")])
11894
11895 (define_insn "avx_maskstorep<avxmodesuffixf2c><avxmodesuffix>"
11896   [(set (match_operand:AVXMODEF2P 0 "memory_operand" "=m")
11897         (unspec:AVXMODEF2P
11898           [(match_operand:AVXMODEF2P 1 "register_operand" "x")
11899            (match_operand:AVXMODEF2P 2 "register_operand" "x")
11900            (match_dup 0)]
11901           UNSPEC_MASKSTORE))]
11902   "TARGET_AVX"
11903   "vmaskmovp<avxmodesuffixf2c>\t{%2, %1, %0|%0, %1, %2}"
11904   [(set_attr "type" "sselog1")
11905    (set_attr "prefix" "vex")
11906    (set_attr "mode" "<MODE>")])
11907
11908 (define_insn "avx_<avxmodesuffixp><avxmodesuffix>_<avxmodesuffixp>"
11909   [(set (match_operand:AVX256MODE2P 0 "register_operand" "=x,x")
11910         (unspec:AVX256MODE2P
11911           [(match_operand:<avxhalfvecmode> 1 "nonimmediate_operand" "0,xm")]
11912           UNSPEC_CAST))]
11913   "TARGET_AVX"
11914 {
11915   switch (which_alternative)
11916     {
11917     case 0:
11918       return "";
11919     case 1:
11920       switch (get_attr_mode (insn))
11921         {
11922         case MODE_V8SF:
11923           return "vmovaps\t{%1, %x0|%x0, %1}";
11924         case MODE_V4DF:
11925           return "vmovapd\t{%1, %x0|%x0, %1}";
11926         case MODE_OI:
11927           return "vmovdqa\t{%1, %x0|%x0, %1}";
11928         default:
11929           break;
11930         }
11931     default:
11932       break;
11933     }
11934   gcc_unreachable ();
11935 }
11936   [(set_attr "type" "ssemov")
11937    (set_attr "prefix" "vex")
11938    (set_attr "mode" "<avxvecmode>")
11939    (set (attr "length")
11940     (if_then_else (eq_attr "alternative" "0")
11941        (const_string "0")
11942        (const_string "*")))])
11943
11944 (define_insn "avx_<avxmodesuffixp>_<avxmodesuffixp><avxmodesuffix>"
11945   [(set (match_operand:<avxhalfvecmode> 0 "register_operand" "=x,x")
11946         (unspec:<avxhalfvecmode>
11947           [(match_operand:AVX256MODE2P 1 "nonimmediate_operand" "0,xm")]
11948           UNSPEC_CAST))]
11949   "TARGET_AVX"
11950 {
11951   switch (which_alternative)
11952     {
11953     case 0:
11954       return "";
11955     case 1:
11956       switch (get_attr_mode (insn))
11957         {
11958         case MODE_V8SF:
11959           return "vmovaps\t{%x1, %0|%0, %x1}";
11960         case MODE_V4DF:
11961           return "vmovapd\t{%x1, %0|%0, %x1}";
11962         case MODE_OI:
11963           return "vmovdqa\t{%x1, %0|%0, %x1}";
11964         default:
11965           break;
11966         }
11967     default:
11968       break;
11969     }
11970   gcc_unreachable ();
11971 }
11972   [(set_attr "type" "ssemov")
11973    (set_attr "prefix" "vex")
11974    (set_attr "mode" "<avxvecmode>")
11975    (set (attr "length")
11976     (if_then_else (eq_attr "alternative" "0")
11977        (const_string "0")
11978        (const_string "*")))])
11979
11980 (define_expand "vec_init<mode>"
11981   [(match_operand:AVX256MODE 0 "register_operand" "")
11982    (match_operand 1 "" "")]
11983   "TARGET_AVX"
11984 {
11985   ix86_expand_vector_init (false, operands[0], operands[1]);
11986   DONE;
11987 })
11988
11989 (define_insn "*vec_concat<mode>_avx"
11990   [(set (match_operand:AVX256MODE 0 "register_operand"   "=x,x")
11991         (vec_concat:AVX256MODE
11992           (match_operand:<avxhalfvecmode> 1 "register_operand" "x,x")
11993           (match_operand:<avxhalfvecmode> 2 "vector_move_operand" "xm,C")))]
11994   "TARGET_AVX"
11995 {
11996   switch (which_alternative)
11997     {
11998     case 0:
11999       return "vinsertf128\t{$0x1, %2, %t1, %0|%0, %t1, %2, 0x1}";
12000     case 1:
12001       switch (get_attr_mode (insn))
12002         {
12003         case MODE_V8SF:
12004           return "vmovaps\t{%1, %x0|%x0, %1}";
12005         case MODE_V4DF:
12006           return "vmovapd\t{%1, %x0|%x0, %1}";
12007         default:
12008           return "vmovdqa\t{%1, %x0|%x0, %1}";
12009         }
12010     default:
12011       gcc_unreachable ();
12012     }
12013 }
12014   [(set_attr "type" "sselog,ssemov")
12015    (set_attr "prefix" "vex")
12016    (set_attr "mode" "<avxvecmode>")])