OSDN Git Service

* config/i386/i386.c: Remove traling spaces.
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / sse.md
1 ;; GCC machine description for SSE instructions
2 ;; Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011
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 ;; All vector modes including V1TImode, used in move patterns.
22 (define_mode_iterator V16
23   [(V32QI "TARGET_AVX") V16QI
24    (V16HI "TARGET_AVX") V8HI
25    (V8SI "TARGET_AVX") V4SI
26    (V4DI "TARGET_AVX") V2DI
27    V1TI
28    (V8SF "TARGET_AVX") V4SF
29    (V4DF "TARGET_AVX") V2DF])
30
31 ;; All vector modes
32 (define_mode_iterator V
33   [(V32QI "TARGET_AVX") V16QI
34    (V16HI "TARGET_AVX") V8HI
35    (V8SI "TARGET_AVX") V4SI
36    (V4DI "TARGET_AVX") V2DI
37    (V8SF "TARGET_AVX") V4SF
38    (V4DF "TARGET_AVX") (V2DF "TARGET_SSE2")])
39
40 ;; All 128bit vector modes
41 (define_mode_iterator V_128
42   [V16QI V8HI V4SI V2DI V4SF (V2DF "TARGET_SSE2")])
43
44 ;; All 256bit vector modes
45 (define_mode_iterator V_256
46   [V32QI V16HI V8SI V4DI V8SF V4DF])
47
48 ;; All vector float modes
49 (define_mode_iterator VF
50   [(V8SF "TARGET_AVX") V4SF
51    (V4DF "TARGET_AVX") (V2DF "TARGET_SSE2")])
52
53 ;; All SFmode vector float modes
54 (define_mode_iterator VF1
55   [(V8SF "TARGET_AVX") V4SF])
56
57 ;; All DFmode vector float modes
58 (define_mode_iterator VF2
59   [(V4DF "TARGET_AVX") V2DF])
60
61 ;; All 128bit vector float modes
62 (define_mode_iterator VF_128
63   [V4SF (V2DF "TARGET_SSE2")])
64
65 ;; All 256bit vector float modes
66 (define_mode_iterator VF_256
67   [V8SF V4DF])
68
69 ;; All vector integer modes
70 (define_mode_iterator VI
71   [(V32QI "TARGET_AVX") V16QI
72    (V16HI "TARGET_AVX") V8HI
73    (V8SI "TARGET_AVX") V4SI
74    (V4DI "TARGET_AVX") V2DI])
75
76 ;; All QImode vector integer modes
77 (define_mode_iterator VI1
78   [(V32QI "TARGET_AVX") V16QI])
79
80 ;; All DImode vector integer modes
81 (define_mode_iterator VI8
82   [(V4DI "TARGET_AVX") V2DI])
83
84 ;; All 128bit vector integer modes
85 (define_mode_iterator VI_128 [V16QI V8HI V4SI V2DI])
86
87 ;; Random 128bit vector integer mode combinations
88 (define_mode_iterator VI12_128 [V16QI V8HI])
89 (define_mode_iterator VI14_128 [V16QI V4SI])
90 (define_mode_iterator VI124_128 [V16QI V8HI V4SI])
91 (define_mode_iterator VI24_128 [V8HI V4SI])
92 (define_mode_iterator VI248_128 [V8HI V4SI V2DI])
93
94 ;; Int-float size matches
95 (define_mode_iterator VI4F_128 [V4SI V4SF])
96 (define_mode_iterator VI8F_128 [V2DI V2DF])
97 (define_mode_iterator VI4F_256 [V8SI V8SF])
98 (define_mode_iterator VI8F_256 [V4DI V4DF])
99
100 ;; Mapping from float mode to required SSE level
101 (define_mode_attr sse
102   [(SF "sse") (DF "sse2")
103    (V4SF "sse") (V2DF "sse2")
104    (V8SF "avx") (V4DF "avx")])
105
106 (define_mode_attr sse2
107   [(V16QI "sse2") (V32QI "avx")
108    (V2DI "sse2") (V4DI "avx")])
109
110 (define_mode_attr sse3
111   [(V16QI "sse3") (V32QI "avx")])
112
113 (define_mode_attr sse4_1
114   [(V4SF "sse4_1") (V2DF "sse4_1")
115    (V8SF "avx") (V4DF "avx")])
116
117 (define_mode_attr avxsizesuffix
118   [(V32QI "256") (V16HI "256") (V8SI "256") (V4DI "256")
119    (V16QI "") (V8HI "") (V4SI "") (V2DI "")
120    (V8SF "256") (V4DF "256")
121    (V4SF "") (V2DF "")])
122
123 ;; SSE instruction mode
124 (define_mode_attr sseinsnmode
125   [(V32QI "OI") (V16HI "OI") (V8SI "OI") (V4DI "OI")
126    (V16QI "TI") (V8HI "TI") (V4SI "TI") (V2DI "TI") (V1TI "TI")
127    (V8SF "V8SF") (V4DF "V4DF")
128    (V4SF "V4SF") (V2DF "V2DF")])
129
130 ;; Mapping of vector float modes to an integer mode of the same size
131 (define_mode_attr sseintvecmode
132   [(V8SF "V8SI") (V4DF "V4DI")
133    (V4SF "V4SI") (V2DF "V2DI")])
134
135 ;; Mapping of vector modes to a vector mode of double size
136 (define_mode_attr ssedoublevecmode
137   [(V32QI "V64QI") (V16HI "V32HI") (V8SI "V16SI") (V4DI "V8DI")
138    (V16QI "V32QI") (V8HI "V16HI") (V4SI "V8SI") (V2DI "V4DI")
139    (V8SF "V16SF") (V4DF "V8DF")
140    (V4SF "V8SF") (V2DF "V4DF")])
141
142 ;; Mapping of vector modes to a vector mode of half size
143 (define_mode_attr ssehalfvecmode
144   [(V32QI "V16QI") (V16HI "V8HI") (V8SI "V4SI") (V4DI "V2DI")
145    (V16QI  "V8QI") (V8HI  "V4HI") (V4SI "V2SI")
146    (V8SF "V4SF") (V4DF "V2DF")
147    (V4SF "V2SF")])
148
149 ;; Mapping of vector modes back to the scalar modes
150 (define_mode_attr ssescalarmode
151   [(V32QI "QI") (V16HI "HI") (V8SI "SI") (V4DI "DI")
152    (V16QI "QI") (V8HI "HI") (V4SI "SI") (V2DI "DI")
153    (V8SF "SF") (V4DF "DF")
154    (V4SF "SF") (V2DF "DF")])
155
156 ;; Number of scalar elements in each vector type
157 (define_mode_attr ssescalarnum
158   [(V32QI "32") (V16HI "16") (V8SI "8") (V4DI "4")
159    (V16QI "16") (V8HI "8") (V4SI "4") (V2DI "2")
160    (V8SF "8") (V4DF "4")
161    (V4SF "4") (V2DF "2")])
162
163 ;; SSE scalar suffix for vector modes
164 (define_mode_attr ssescalarmodesuffix
165   [(V8SF "ss") (V4DF "sd")
166    (V4SF "ss") (V2DF "sd")
167    (V8SI "ss") (V4DI "sd")
168    (V4SI "d")])
169
170 ;; Pack/unpack vector modes
171 (define_mode_attr sseunpackmode
172   [(V16QI "V8HI") (V8HI "V4SI") (V4SI "V2DI")])
173
174 (define_mode_attr ssepackmode
175   [(V8HI "V16QI") (V4SI "V8HI") (V2DI "V4SI")])
176
177 ;; Mapping of the max integer size for xop rotate immediate constraint
178 (define_mode_attr sserotatemax
179   [(V16QI "7") (V8HI "15") (V4SI "31") (V2DI "63")])
180
181 ;; Mapping of mode to cast intrinsic name
182 (define_mode_attr castmode [(V8SI "si") (V8SF "ps") (V4DF "pd")])
183
184 ;; Instruction suffix for sign and zero extensions.
185 (define_code_attr extsuffix [(sign_extend "sx") (zero_extend "zx")])
186
187
188
189 ;; Mix-n-match
190 (define_mode_iterator AVX256MODE2P [V8SI V8SF V4DF])
191
192 (define_mode_iterator FMAMODE [SF DF V4SF V2DF V8SF V4DF])
193
194 ;; Mapping of immediate bits for blend instructions
195 (define_mode_attr blendbits
196   [(V8SF "255") (V4SF "15") (V4DF "15") (V2DF "3")])
197
198 ;; Patterns whose name begins with "sse{,2,3}_" are invoked by intrinsics.
199
200 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
201 ;;
202 ;; Move patterns
203 ;;
204 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
205
206 ;; All of these patterns are enabled for SSE1 as well as SSE2.
207 ;; This is essential for maintaining stable calling conventions.
208
209 (define_expand "mov<mode>"
210   [(set (match_operand:V16 0 "nonimmediate_operand" "")
211         (match_operand:V16 1 "nonimmediate_operand" ""))]
212   "TARGET_SSE"
213 {
214   ix86_expand_vector_move (<MODE>mode, operands);
215   DONE;
216 })
217
218 (define_insn "*mov<mode>_internal"
219   [(set (match_operand:V16 0 "nonimmediate_operand" "=x,x ,m")
220         (match_operand:V16 1 "nonimmediate_or_sse_const_operand"  "C ,xm,x"))]
221   "TARGET_SSE
222    && (register_operand (operands[0], <MODE>mode)
223        || register_operand (operands[1], <MODE>mode))"
224 {
225   switch (which_alternative)
226     {
227     case 0:
228       return standard_sse_constant_opcode (insn, operands[1]);
229     case 1:
230     case 2:
231       switch (get_attr_mode (insn))
232         {
233         case MODE_V8SF:
234         case MODE_V4SF:
235           if (TARGET_AVX
236               && (misaligned_operand (operands[0], <MODE>mode)
237                   || misaligned_operand (operands[1], <MODE>mode)))
238             return "vmovups\t{%1, %0|%0, %1}";
239           else
240             return "%vmovaps\t{%1, %0|%0, %1}";
241
242         case MODE_V4DF:
243         case MODE_V2DF:
244           if (TARGET_AVX
245               && (misaligned_operand (operands[0], <MODE>mode)
246                   || misaligned_operand (operands[1], <MODE>mode)))
247             return "vmovupd\t{%1, %0|%0, %1}";
248           else if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
249             return "%vmovaps\t{%1, %0|%0, %1}";
250           else
251             return "%vmovapd\t{%1, %0|%0, %1}";
252
253         case MODE_OI:
254         case MODE_TI:
255           if (TARGET_AVX
256               && (misaligned_operand (operands[0], <MODE>mode)
257                   || misaligned_operand (operands[1], <MODE>mode)))
258             return "vmovdqu\t{%1, %0|%0, %1}";
259           else if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
260             return "%vmovaps\t{%1, %0|%0, %1}";
261           else
262             return "%vmovdqa\t{%1, %0|%0, %1}";
263
264         default:
265           gcc_unreachable ();
266         }
267     default:
268       gcc_unreachable ();
269     }
270 }
271   [(set_attr "type" "sselog1,ssemov,ssemov")
272    (set_attr "prefix" "maybe_vex")
273    (set (attr "mode")
274         (cond [(ne (symbol_ref "TARGET_AVX") (const_int 0))
275                  (const_string "<sseinsnmode>")
276                (ior (ior
277                       (ne (symbol_ref "optimize_function_for_size_p (cfun)")
278                           (const_int 0))
279                       (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
280                     (and (eq_attr "alternative" "2")
281                          (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
282                              (const_int 0))))
283                  (const_string "V4SF")
284                (eq (const_string "<MODE>mode") (const_string "V4SFmode"))
285                  (const_string "V4SF")
286                (eq (const_string "<MODE>mode") (const_string "V2DFmode"))
287                  (const_string "V2DF")
288               ]
289           (const_string "TI")))])
290
291 (define_insn "sse2_movq128"
292   [(set (match_operand:V2DI 0 "register_operand" "=x")
293         (vec_concat:V2DI
294           (vec_select:DI
295             (match_operand:V2DI 1 "nonimmediate_operand" "xm")
296             (parallel [(const_int 0)]))
297           (const_int 0)))]
298   "TARGET_SSE2"
299   "%vmovq\t{%1, %0|%0, %1}"
300   [(set_attr "type" "ssemov")
301    (set_attr "prefix" "maybe_vex")
302    (set_attr "mode" "TI")])
303
304 ;; Move a DI from a 32-bit register pair (e.g. %edx:%eax) to an xmm.
305 ;; We'd rather avoid this entirely; if the 32-bit reg pair was loaded
306 ;; from memory, we'd prefer to load the memory directly into the %xmm
307 ;; register.  To facilitate this happy circumstance, this pattern won't
308 ;; split until after register allocation.  If the 64-bit value didn't
309 ;; come from memory, this is the best we can do.  This is much better
310 ;; than storing %edx:%eax into a stack temporary and loading an %xmm
311 ;; from there.
312
313 (define_insn_and_split "movdi_to_sse"
314   [(parallel
315     [(set (match_operand:V4SI 0 "register_operand" "=?x,x")
316           (subreg:V4SI (match_operand:DI 1 "nonimmediate_operand" "r,m") 0))
317      (clobber (match_scratch:V4SI 2 "=&x,X"))])]
318   "!TARGET_64BIT && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES"
319   "#"
320   "&& reload_completed"
321   [(const_int 0)]
322 {
323  if (register_operand (operands[1], DImode))
324    {
325       /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
326          Assemble the 64-bit DImode value in an xmm register.  */
327       emit_insn (gen_sse2_loadld (operands[0], CONST0_RTX (V4SImode),
328                                   gen_rtx_SUBREG (SImode, operands[1], 0)));
329       emit_insn (gen_sse2_loadld (operands[2], CONST0_RTX (V4SImode),
330                                   gen_rtx_SUBREG (SImode, operands[1], 4)));
331       emit_insn (gen_vec_interleave_lowv4si (operands[0], operands[0],
332                                              operands[2]));
333     }
334  else if (memory_operand (operands[1], DImode))
335    emit_insn (gen_vec_concatv2di (gen_lowpart (V2DImode, operands[0]),
336                                   operands[1], const0_rtx));
337  else
338    gcc_unreachable ();
339 })
340
341 (define_split
342   [(set (match_operand:V4SF 0 "register_operand" "")
343         (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
344   "TARGET_SSE && reload_completed"
345   [(set (match_dup 0)
346         (vec_merge:V4SF
347           (vec_duplicate:V4SF (match_dup 1))
348           (match_dup 2)
349           (const_int 1)))]
350 {
351   operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
352   operands[2] = CONST0_RTX (V4SFmode);
353 })
354
355 (define_split
356   [(set (match_operand:V2DF 0 "register_operand" "")
357         (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
358   "TARGET_SSE2 && reload_completed"
359   [(set (match_dup 0) (vec_concat:V2DF (match_dup 1) (match_dup 2)))]
360 {
361   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
362   operands[2] = CONST0_RTX (DFmode);
363 })
364
365 (define_expand "push<mode>1"
366   [(match_operand:V16 0 "register_operand" "")]
367   "TARGET_SSE"
368 {
369   ix86_expand_push (<MODE>mode, operands[0]);
370   DONE;
371 })
372
373 (define_expand "movmisalign<mode>"
374   [(set (match_operand:V16 0 "nonimmediate_operand" "")
375         (match_operand:V16 1 "nonimmediate_operand" ""))]
376   "TARGET_SSE"
377 {
378   ix86_expand_vector_move_misalign (<MODE>mode, operands);
379   DONE;
380 })
381
382 (define_expand "<sse>_movu<ssemodesuffix><avxsizesuffix>"
383   [(set (match_operand:VF 0 "nonimmediate_operand" "")
384         (unspec:VF
385           [(match_operand:VF 1 "nonimmediate_operand" "")]
386           UNSPEC_MOVU))]
387   "TARGET_SSE"
388 {
389   if (MEM_P (operands[0]) && MEM_P (operands[1]))
390     operands[1] = force_reg (<MODE>mode, operands[1]);
391 })
392
393 (define_insn "*<sse>_movu<ssemodesuffix><avxsizesuffix>"
394   [(set (match_operand:VF 0 "nonimmediate_operand" "=x,m")
395         (unspec:VF
396           [(match_operand:VF 1 "nonimmediate_operand" "xm,x")]
397           UNSPEC_MOVU))]
398   "TARGET_SSE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
399   "%vmovu<ssemodesuffix>\t{%1, %0|%0, %1}"
400   [(set_attr "type" "ssemov")
401    (set_attr "movu" "1")
402    (set_attr "prefix" "maybe_vex")
403    (set_attr "mode" "<MODE>")])
404
405 (define_expand "<sse2>_movdqu<avxsizesuffix>"
406   [(set (match_operand:VI1 0 "nonimmediate_operand" "")
407         (unspec:VI1 [(match_operand:VI1 1 "nonimmediate_operand" "")]
408                     UNSPEC_MOVU))]
409   "TARGET_SSE2"
410 {
411   if (MEM_P (operands[0]) && MEM_P (operands[1]))
412     operands[1] = force_reg (<MODE>mode, operands[1]);
413 })
414
415 (define_insn "*<sse2>_movdqu<avxsizesuffix>"
416   [(set (match_operand:VI1 0 "nonimmediate_operand" "=x,m")
417         (unspec:VI1 [(match_operand:VI1 1 "nonimmediate_operand" "xm,x")]
418                     UNSPEC_MOVU))]
419   "TARGET_SSE2 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
420   "%vmovdqu\t{%1, %0|%0, %1}"
421   [(set_attr "type" "ssemov")
422    (set_attr "movu" "1")
423    (set (attr "prefix_data16")
424      (if_then_else
425        (ne (symbol_ref "TARGET_AVX") (const_int 0))
426      (const_string "*")
427      (const_string "1")))
428    (set_attr "prefix" "maybe_vex")
429    (set_attr "mode" "<sseinsnmode>")])
430
431 (define_insn "<sse3>_lddqu<avxsizesuffix>"
432   [(set (match_operand:VI1 0 "register_operand" "=x")
433         (unspec:VI1 [(match_operand:VI1 1 "memory_operand" "m")]
434                     UNSPEC_LDDQU))]
435   "TARGET_SSE3"
436   "%vlddqu\t{%1, %0|%0, %1}"
437   [(set_attr "type" "ssemov")
438    (set_attr "movu" "1")
439    (set (attr "prefix_data16")
440      (if_then_else
441        (ne (symbol_ref "TARGET_AVX") (const_int 0))
442      (const_string "*")
443      (const_string "0")))
444    (set (attr "prefix_rep")
445      (if_then_else
446        (ne (symbol_ref "TARGET_AVX") (const_int 0))
447      (const_string "*")
448      (const_string "1")))
449    (set_attr "prefix" "maybe_vex")
450    (set_attr "mode" "<sseinsnmode>")])
451
452 (define_insn "sse2_movntsi"
453   [(set (match_operand:SI 0 "memory_operand" "=m")
454         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
455                    UNSPEC_MOVNT))]
456   "TARGET_SSE2"
457   "movnti\t{%1, %0|%0, %1}"
458   [(set_attr "type" "ssemov")
459    (set_attr "prefix_data16" "0")
460    (set_attr "mode" "V2DF")])
461
462 (define_insn "<sse>_movnt<mode>"
463   [(set (match_operand:VF 0 "memory_operand" "=m")
464         (unspec:VF [(match_operand:VF 1 "register_operand" "x")]
465                    UNSPEC_MOVNT))]
466   "TARGET_SSE"
467   "%vmovnt<ssemodesuffix>\t{%1, %0|%0, %1}"
468   [(set_attr "type" "ssemov")
469    (set_attr "prefix" "maybe_vex")
470    (set_attr "mode" "<MODE>")])
471
472 (define_insn "<sse2>_movnt<mode>"
473   [(set (match_operand:VI8 0 "memory_operand" "=m")
474         (unspec:VI8 [(match_operand:VI8 1 "register_operand" "x")]
475                     UNSPEC_MOVNT))]
476   "TARGET_SSE2"
477   "%vmovntdq\t{%1, %0|%0, %1}"
478   [(set_attr "type" "ssecvt")
479    (set (attr "prefix_data16")
480      (if_then_else
481        (ne (symbol_ref "TARGET_AVX") (const_int 0))
482      (const_string "*")
483      (const_string "1")))
484    (set_attr "prefix" "maybe_vex")
485    (set_attr "mode" "<sseinsnmode>")])
486
487 ; Expand patterns for non-temporal stores.  At the moment, only those
488 ; that directly map to insns are defined; it would be possible to
489 ; define patterns for other modes that would expand to several insns.
490
491 ;; Modes handled by storent patterns.
492 (define_mode_iterator STORENT_MODE
493   [(SI "TARGET_SSE2") (SF "TARGET_SSE4A") (DF "TARGET_SSE4A")
494    (V2DI "TARGET_SSE2")
495    (V8SF "TARGET_AVX") V4SF
496    (V4DF "TARGET_AVX") (V2DF "TARGET_SSE2")])
497
498 (define_expand "storent<mode>"
499   [(set (match_operand:STORENT_MODE 0 "memory_operand" "")
500         (unspec:STORENT_MODE
501           [(match_operand:STORENT_MODE 1 "register_operand" "")]
502           UNSPEC_MOVNT))]
503   "TARGET_SSE")
504
505 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
506 ;;
507 ;; Parallel floating point arithmetic
508 ;;
509 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
510
511 (define_expand "<code><mode>2"
512   [(set (match_operand:VF 0 "register_operand" "")
513         (absneg:VF
514           (match_operand:VF 1 "register_operand" "")))]
515   "TARGET_SSE"
516   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
517
518 (define_insn_and_split "*absneg<mode>2"
519   [(set (match_operand:VF 0 "register_operand" "=x,x,x,x")
520         (match_operator:VF 3 "absneg_operator"
521           [(match_operand:VF 1 "nonimmediate_operand" "0, xm,x, m")]))
522    (use (match_operand:VF 2 "nonimmediate_operand"    "xm,0, xm,x"))]
523   "TARGET_SSE"
524   "#"
525   "reload_completed"
526   [(const_int 0)]
527 {
528   enum rtx_code absneg_op;
529   rtx op1, op2;
530   rtx t;
531
532   if (TARGET_AVX)
533     {
534       if (MEM_P (operands[1]))
535         op1 = operands[2], op2 = operands[1];
536       else
537         op1 = operands[1], op2 = operands[2];
538     }
539   else
540     {
541       op1 = operands[0];
542       if (rtx_equal_p (operands[0], operands[1]))
543         op2 = operands[2];
544       else
545         op2 = operands[1];
546     }
547
548   absneg_op = GET_CODE (operands[3]) == NEG ? XOR : AND;
549   t = gen_rtx_fmt_ee (absneg_op, <MODE>mode, op1, op2);
550   t = gen_rtx_SET (VOIDmode, operands[0], t);
551   emit_insn (t);
552   DONE;
553 }
554   [(set_attr "isa" "noavx,noavx,avx,avx")])
555
556 (define_expand "<plusminus_insn><mode>3"
557   [(set (match_operand:VF 0 "register_operand" "")
558         (plusminus:VF
559           (match_operand:VF 1 "nonimmediate_operand" "")
560           (match_operand:VF 2 "nonimmediate_operand" "")))]
561   "TARGET_SSE"
562   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
563
564 (define_insn "*<plusminus_insn><mode>3"
565   [(set (match_operand:VF 0 "register_operand" "=x,x")
566         (plusminus:VF
567           (match_operand:VF 1 "nonimmediate_operand" "<comm>0,x")
568           (match_operand:VF 2 "nonimmediate_operand" "xm,xm")))]
569   "TARGET_SSE && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
570   "@
571    <plusminus_mnemonic><ssemodesuffix>\t{%2, %0|%0, %2}
572    v<plusminus_mnemonic><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
573   [(set_attr "isa" "noavx,avx")
574    (set_attr "type" "sseadd")
575    (set_attr "prefix" "orig,vex")
576    (set_attr "mode" "<MODE>")])
577
578 (define_insn "<sse>_vm<plusminus_insn><mode>3"
579   [(set (match_operand:VF_128 0 "register_operand" "=x,x")
580         (vec_merge:VF_128
581           (plusminus:VF_128
582             (match_operand:VF_128 1 "register_operand" "0,x")
583             (match_operand:VF_128 2 "nonimmediate_operand" "xm,xm"))
584           (match_dup 1)
585           (const_int 1)))]
586   "TARGET_SSE"
587   "@
588    <plusminus_mnemonic><ssescalarmodesuffix>\t{%2, %0|%0, %2}
589    v<plusminus_mnemonic><ssescalarmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
590   [(set_attr "isa" "noavx,avx")
591    (set_attr "type" "sseadd")
592    (set_attr "prefix" "orig,vex")
593    (set_attr "mode" "<ssescalarmode>")])
594
595 (define_expand "mul<mode>3"
596   [(set (match_operand:VF 0 "register_operand" "")
597         (mult:VF
598           (match_operand:VF 1 "nonimmediate_operand" "")
599           (match_operand:VF 2 "nonimmediate_operand" "")))]
600   "TARGET_SSE"
601   "ix86_fixup_binary_operands_no_copy (MULT, <MODE>mode, operands);")
602
603 (define_insn "*mul<mode>3"
604   [(set (match_operand:VF 0 "register_operand" "=x,x")
605         (mult:VF
606           (match_operand:VF 1 "nonimmediate_operand" "%0,x")
607           (match_operand:VF 2 "nonimmediate_operand" "xm,xm")))]
608   "TARGET_SSE && ix86_binary_operator_ok (MULT, <MODE>mode, operands)"
609   "@
610    mul<ssemodesuffix>\t{%2, %0|%0, %2}
611    vmul<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
612   [(set_attr "isa" "noavx,avx")
613    (set_attr "type" "ssemul")
614    (set_attr "prefix" "orig,vex")
615    (set_attr "mode" "<MODE>")])
616
617 (define_insn "<sse>_vmmul<mode>3"
618   [(set (match_operand:VF_128 0 "register_operand" "=x,x")
619         (vec_merge:VF_128
620           (mult:VF_128
621             (match_operand:VF_128 1 "register_operand" "0,x")
622             (match_operand:VF_128 2 "nonimmediate_operand" "xm,xm"))
623           (match_dup 1)
624           (const_int 1)))]
625   "TARGET_SSE"
626   "@
627    mul<ssescalarmodesuffix>\t{%2, %0|%0, %2}
628    vmul<ssescalarmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
629   [(set_attr "isa" "noavx,avx")
630    (set_attr "type" "ssemul")
631    (set_attr "prefix" "orig,vex")
632    (set_attr "mode" "<ssescalarmode>")])
633
634 (define_expand "div<mode>3"
635   [(set (match_operand:VF2 0 "register_operand" "")
636         (div:VF2 (match_operand:VF2 1 "register_operand" "")
637                  (match_operand:VF2 2 "nonimmediate_operand" "")))]
638   "TARGET_SSE2"
639   "ix86_fixup_binary_operands_no_copy (DIV, <MODE>mode, operands);")
640
641 (define_expand "div<mode>3"
642   [(set (match_operand:VF1 0 "register_operand" "")
643         (div:VF1 (match_operand:VF1 1 "register_operand" "")
644                  (match_operand:VF1 2 "nonimmediate_operand" "")))]
645   "TARGET_SSE"
646 {
647   ix86_fixup_binary_operands_no_copy (DIV, <MODE>mode, operands);
648
649   if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_insn_for_size_p ()
650       && flag_finite_math_only && !flag_trapping_math
651       && flag_unsafe_math_optimizations)
652     {
653       ix86_emit_swdivsf (operands[0], operands[1], operands[2], <MODE>mode);
654       DONE;
655     }
656 })
657
658 (define_insn "<sse>_div<mode>3"
659   [(set (match_operand:VF 0 "register_operand" "=x,x")
660         (div:VF
661           (match_operand:VF 1 "register_operand" "0,x")
662           (match_operand:VF 2 "nonimmediate_operand" "xm,xm")))]
663   "TARGET_SSE"
664   "@
665    div<ssemodesuffix>\t{%2, %0|%0, %2}
666    vdiv<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
667   [(set_attr "isa" "noavx,avx")
668    (set_attr "type" "ssediv")
669    (set_attr "prefix" "orig,vex")
670    (set_attr "mode" "<MODE>")])
671
672 (define_insn "<sse>_vmdiv<mode>3"
673   [(set (match_operand:VF_128 0 "register_operand" "=x,x")
674         (vec_merge:VF_128
675           (div:VF_128
676             (match_operand:VF_128 1 "register_operand" "0,x")
677             (match_operand:VF_128 2 "nonimmediate_operand" "xm,xm"))
678           (match_dup 1)
679           (const_int 1)))]
680   "TARGET_SSE"
681   "@
682    div<ssescalarmodesuffix>\t{%2, %0|%0, %2}
683    vdiv<ssescalarmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
684   [(set_attr "isa" "noavx,avx")
685    (set_attr "type" "ssediv")
686    (set_attr "prefix" "orig,vex")
687    (set_attr "mode" "<ssescalarmode>")])
688
689 (define_insn "<sse>_rcp<mode>2"
690   [(set (match_operand:VF1 0 "register_operand" "=x")
691         (unspec:VF1
692           [(match_operand:VF1 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
693   "TARGET_SSE"
694   "%vrcpps\t{%1, %0|%0, %1}"
695   [(set_attr "type" "sse")
696    (set_attr "atom_sse_attr" "rcp")
697    (set_attr "prefix" "maybe_vex")
698    (set_attr "mode" "<MODE>")])
699
700 (define_insn "sse_vmrcpv4sf2"
701   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
702         (vec_merge:V4SF
703           (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,xm")]
704                        UNSPEC_RCP)
705           (match_operand:V4SF 2 "register_operand" "0,x")
706           (const_int 1)))]
707   "TARGET_SSE"
708   "@
709    rcpss\t{%1, %0|%0, %1}
710    vrcpss\t{%1, %2, %0|%0, %2, %1}"
711   [(set_attr "isa" "noavx,avx")
712    (set_attr "type" "sse")
713    (set_attr "atom_sse_attr" "rcp")
714    (set_attr "prefix" "orig,vex")
715    (set_attr "mode" "SF")])
716
717 (define_expand "sqrt<mode>2"
718   [(set (match_operand:VF2 0 "register_operand" "")
719         (sqrt:VF2 (match_operand:VF2 1 "nonimmediate_operand" "")))]
720   "TARGET_SSE2")
721
722 (define_expand "sqrt<mode>2"
723   [(set (match_operand:VF1 0 "register_operand" "")
724         (sqrt:VF1 (match_operand:VF1 1 "nonimmediate_operand" "")))]
725   "TARGET_SSE"
726 {
727   if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_insn_for_size_p ()
728       && flag_finite_math_only && !flag_trapping_math
729       && flag_unsafe_math_optimizations)
730     {
731       ix86_emit_swsqrtsf (operands[0], operands[1], <MODE>mode, false);
732       DONE;
733     }
734 })
735
736 (define_insn "<sse>_sqrt<mode>2"
737   [(set (match_operand:VF 0 "register_operand" "=x")
738         (sqrt:VF (match_operand:VF 1 "nonimmediate_operand" "xm")))]
739   "TARGET_SSE"
740   "%vsqrt<ssemodesuffix>\t{%1, %0|%0, %1}"
741   [(set_attr "type" "sse")
742    (set_attr "atom_sse_attr" "sqrt")
743    (set_attr "prefix" "maybe_vex")
744    (set_attr "mode" "<MODE>")])
745
746 (define_insn "<sse>_vmsqrt<mode>2"
747   [(set (match_operand:VF_128 0 "register_operand" "=x,x")
748         (vec_merge:VF_128
749           (sqrt:VF_128
750             (match_operand:VF_128 1 "nonimmediate_operand" "xm,xm"))
751           (match_operand:VF_128 2 "register_operand" "0,x")
752           (const_int 1)))]
753   "TARGET_SSE"
754   "@
755    sqrt<ssescalarmodesuffix>\t{%1, %0|%0, %1}
756    vsqrt<ssescalarmodesuffix>\t{%1, %2, %0|%0, %2, %1}"
757   [(set_attr "isa" "noavx,avx")
758    (set_attr "type" "sse")
759    (set_attr "atom_sse_attr" "sqrt")
760    (set_attr "prefix" "orig,vex")
761    (set_attr "mode" "<ssescalarmode>")])
762
763 (define_expand "rsqrt<mode>2"
764   [(set (match_operand:VF1 0 "register_operand" "")
765         (unspec:VF1
766           [(match_operand:VF1 1 "nonimmediate_operand" "")] UNSPEC_RSQRT))]
767   "TARGET_SSE_MATH"
768 {
769   ix86_emit_swsqrtsf (operands[0], operands[1], <MODE>mode, true);
770   DONE;
771 })
772
773 (define_insn "<sse>_rsqrt<mode>2"
774   [(set (match_operand:VF1 0 "register_operand" "=x")
775         (unspec:VF1
776           [(match_operand:VF1 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
777   "TARGET_SSE"
778   "%vrsqrtps\t{%1, %0|%0, %1}"
779   [(set_attr "type" "sse")
780    (set_attr "prefix" "maybe_vex")
781    (set_attr "mode" "<MODE>")])
782
783 (define_insn "sse_vmrsqrtv4sf2"
784   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
785         (vec_merge:V4SF
786           (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,xm")]
787                        UNSPEC_RSQRT)
788           (match_operand:V4SF 2 "register_operand" "0,x")
789           (const_int 1)))]
790   "TARGET_SSE"
791   "@
792    rsqrtss\t{%1, %0|%0, %1}
793    vrsqrtss\t{%1, %2, %0|%0, %2, %1}"
794   [(set_attr "isa" "noavx,avx")
795    (set_attr "type" "sse")
796    (set_attr "prefix" "orig,vex")
797    (set_attr "mode" "SF")])
798
799 ;; ??? For !flag_finite_math_only, the representation with SMIN/SMAX
800 ;; isn't really correct, as those rtl operators aren't defined when
801 ;; applied to NaNs.  Hopefully the optimizers won't get too smart on us.
802
803 (define_expand "<code><mode>3"
804   [(set (match_operand:VF 0 "register_operand" "")
805         (smaxmin:VF
806           (match_operand:VF 1 "nonimmediate_operand" "")
807           (match_operand:VF 2 "nonimmediate_operand" "")))]
808   "TARGET_SSE"
809 {
810   if (!flag_finite_math_only)
811     operands[1] = force_reg (<MODE>mode, operands[1]);
812   ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);
813 })
814
815 (define_insn "*<code><mode>3_finite"
816   [(set (match_operand:VF 0 "register_operand" "=x,x")
817         (smaxmin:VF
818           (match_operand:VF 1 "nonimmediate_operand" "%0,x")
819           (match_operand:VF 2 "nonimmediate_operand" "xm,xm")))]
820   "TARGET_SSE && flag_finite_math_only
821    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
822   "@
823    <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
824    v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
825   [(set_attr "isa" "noavx,avx")
826    (set_attr "type" "sseadd")
827    (set_attr "prefix" "orig,vex")
828    (set_attr "mode" "<MODE>")])
829
830 (define_insn "*<code><mode>3"
831   [(set (match_operand:VF 0 "register_operand" "=x,x")
832         (smaxmin:VF
833           (match_operand:VF 1 "register_operand" "0,x")
834           (match_operand:VF 2 "nonimmediate_operand" "xm,xm")))]
835   "TARGET_SSE && !flag_finite_math_only"
836   "@
837    <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
838    v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
839   [(set_attr "isa" "noavx,avx")
840    (set_attr "type" "sseadd")
841    (set_attr "prefix" "orig,vex")
842    (set_attr "mode" "<MODE>")])
843
844 (define_insn "<sse>_vm<code><mode>3"
845   [(set (match_operand:VF_128 0 "register_operand" "=x,x")
846         (vec_merge:VF_128
847           (smaxmin:VF_128
848             (match_operand:VF_128 1 "register_operand" "0,x")
849             (match_operand:VF_128 2 "nonimmediate_operand" "xm,xm"))
850          (match_dup 1)
851          (const_int 1)))]
852   "TARGET_SSE"
853   "@
854    <maxmin_float><ssescalarmodesuffix>\t{%2, %0|%0, %2}
855    v<maxmin_float><ssescalarmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
856   [(set_attr "isa" "noavx,avx")
857    (set_attr "type" "sse")
858    (set_attr "prefix" "orig,vex")
859    (set_attr "mode" "<ssescalarmode>")])
860
861 ;; These versions of the min/max patterns implement exactly the operations
862 ;;   min = (op1 < op2 ? op1 : op2)
863 ;;   max = (!(op1 < op2) ? op1 : op2)
864 ;; Their operands are not commutative, and thus they may be used in the
865 ;; presence of -0.0 and NaN.
866
867 (define_insn "*ieee_smin<mode>3"
868   [(set (match_operand:VF 0 "register_operand" "=x,x")
869         (unspec:VF
870           [(match_operand:VF 1 "register_operand" "0,x")
871            (match_operand:VF 2 "nonimmediate_operand" "xm,xm")]
872          UNSPEC_IEEE_MIN))]
873   "TARGET_SSE"
874   "@
875    min<ssemodesuffix>\t{%2, %0|%0, %2}
876    vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
877   [(set_attr "isa" "noavx,avx")
878    (set_attr "type" "sseadd")
879    (set_attr "prefix" "orig,vex")
880    (set_attr "mode" "<MODE>")])
881
882 (define_insn "*ieee_smax<mode>3"
883   [(set (match_operand:VF 0 "register_operand" "=x,x")
884         (unspec:VF
885           [(match_operand:VF 1 "register_operand" "0,x")
886            (match_operand:VF 2 "nonimmediate_operand" "xm,xm")]
887          UNSPEC_IEEE_MAX))]
888   "TARGET_SSE"
889   "@
890    max<ssemodesuffix>\t{%2, %0|%0, %2}
891    vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
892   [(set_attr "isa" "noavx,avx")
893    (set_attr "type" "sseadd")
894    (set_attr "prefix" "orig,vex")
895    (set_attr "mode" "<MODE>")])
896
897 (define_insn "avx_addsubv4df3"
898   [(set (match_operand:V4DF 0 "register_operand" "=x")
899         (vec_merge:V4DF
900           (plus:V4DF
901             (match_operand:V4DF 1 "register_operand" "x")
902             (match_operand:V4DF 2 "nonimmediate_operand" "xm"))
903           (minus:V4DF (match_dup 1) (match_dup 2))
904           (const_int 10)))]
905   "TARGET_AVX"
906   "vaddsubpd\t{%2, %1, %0|%0, %1, %2}"
907   [(set_attr "type" "sseadd")
908    (set_attr "prefix" "vex")
909    (set_attr "mode" "V4DF")])
910
911 (define_insn "sse3_addsubv2df3"
912   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
913         (vec_merge:V2DF
914           (plus:V2DF
915             (match_operand:V2DF 1 "register_operand" "0,x")
916             (match_operand:V2DF 2 "nonimmediate_operand" "xm,xm"))
917           (minus:V2DF (match_dup 1) (match_dup 2))
918           (const_int 2)))]
919   "TARGET_SSE3"
920   "@
921    addsubpd\t{%2, %0|%0, %2}
922    vaddsubpd\t{%2, %1, %0|%0, %1, %2}"
923   [(set_attr "isa" "noavx,avx")
924    (set_attr "type" "sseadd")
925    (set_attr "atom_unit" "complex")
926    (set_attr "prefix" "orig,vex")
927    (set_attr "mode" "V2DF")])
928
929 (define_insn "avx_addsubv8sf3"
930   [(set (match_operand:V8SF 0 "register_operand" "=x")
931         (vec_merge:V8SF
932           (plus:V8SF
933             (match_operand:V8SF 1 "register_operand" "x")
934             (match_operand:V8SF 2 "nonimmediate_operand" "xm"))
935           (minus:V8SF (match_dup 1) (match_dup 2))
936           (const_int 170)))]
937   "TARGET_AVX"
938   "vaddsubps\t{%2, %1, %0|%0, %1, %2}"
939   [(set_attr "type" "sseadd")
940    (set_attr "prefix" "vex")
941    (set_attr "mode" "V8SF")])
942
943 (define_insn "sse3_addsubv4sf3"
944   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
945         (vec_merge:V4SF
946           (plus:V4SF
947             (match_operand:V4SF 1 "register_operand" "0,x")
948             (match_operand:V4SF 2 "nonimmediate_operand" "xm,xm"))
949           (minus:V4SF (match_dup 1) (match_dup 2))
950           (const_int 10)))]
951   "TARGET_SSE3"
952   "@
953    addsubps\t{%2, %0|%0, %2}
954    vaddsubps\t{%2, %1, %0|%0, %1, %2}"
955   [(set_attr "isa" "noavx,avx")
956    (set_attr "type" "sseadd")
957    (set_attr "prefix" "orig,vex")
958    (set_attr "prefix_rep" "1,*")
959    (set_attr "mode" "V4SF")])
960
961 (define_insn "avx_h<plusminus_insn>v4df3"
962   [(set (match_operand:V4DF 0 "register_operand" "=x")
963         (vec_concat:V4DF
964           (vec_concat:V2DF
965             (plusminus:DF
966               (vec_select:DF
967                 (match_operand:V4DF 1 "register_operand" "x")
968                 (parallel [(const_int 0)]))
969               (vec_select:DF (match_dup 1) (parallel [(const_int 1)])))
970             (plusminus:DF
971               (vec_select:DF (match_dup 1) (parallel [(const_int 2)]))
972               (vec_select:DF (match_dup 1) (parallel [(const_int 3)]))))
973           (vec_concat:V2DF
974             (plusminus:DF
975               (vec_select:DF
976                 (match_operand:V4DF 2 "nonimmediate_operand" "xm")
977                 (parallel [(const_int 0)]))
978               (vec_select:DF (match_dup 2) (parallel [(const_int 1)])))
979             (plusminus:DF
980               (vec_select:DF (match_dup 2) (parallel [(const_int 2)]))
981               (vec_select:DF (match_dup 2) (parallel [(const_int 3)]))))))]
982   "TARGET_AVX"
983   "vh<plusminus_mnemonic>pd\t{%2, %1, %0|%0, %1, %2}"
984   [(set_attr "type" "sseadd")
985    (set_attr "prefix" "vex")
986    (set_attr "mode" "V4DF")])
987
988 (define_insn "sse3_h<plusminus_insn>v2df3"
989   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
990         (vec_concat:V2DF
991           (plusminus:DF
992             (vec_select:DF
993               (match_operand:V2DF 1 "register_operand" "0,x")
994               (parallel [(const_int 0)]))
995             (vec_select:DF (match_dup 1) (parallel [(const_int 1)])))
996           (plusminus:DF
997             (vec_select:DF
998               (match_operand:V2DF 2 "nonimmediate_operand" "xm,xm")
999               (parallel [(const_int 0)]))
1000             (vec_select:DF (match_dup 2) (parallel [(const_int 1)])))))]
1001   "TARGET_SSE3"
1002   "@
1003    h<plusminus_mnemonic>pd\t{%2, %0|%0, %2}
1004    vh<plusminus_mnemonic>pd\t{%2, %1, %0|%0, %1, %2}"
1005   [(set_attr "isa" "noavx,avx")
1006    (set_attr "type" "sseadd")
1007    (set_attr "prefix" "orig,vex")
1008    (set_attr "mode" "V2DF")])
1009
1010 (define_insn "avx_h<plusminus_insn>v8sf3"
1011   [(set (match_operand:V8SF 0 "register_operand" "=x")
1012         (vec_concat:V8SF
1013           (vec_concat:V4SF
1014             (vec_concat:V2SF
1015               (plusminus:SF
1016                 (vec_select:SF
1017                   (match_operand:V8SF 1 "register_operand" "x")
1018                   (parallel [(const_int 0)]))
1019                 (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
1020               (plusminus:SF
1021                 (vec_select:SF (match_dup 1) (parallel [(const_int 2)]))
1022                 (vec_select:SF (match_dup 1) (parallel [(const_int 3)]))))
1023             (vec_concat:V2SF
1024               (plusminus:SF
1025                 (vec_select:SF
1026                   (match_operand:V8SF 2 "nonimmediate_operand" "xm")
1027                   (parallel [(const_int 0)]))
1028                 (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))
1029               (plusminus:SF
1030                 (vec_select:SF (match_dup 2) (parallel [(const_int 2)]))
1031                 (vec_select:SF (match_dup 2) (parallel [(const_int 3)])))))
1032           (vec_concat:V4SF
1033             (vec_concat:V2SF
1034               (plusminus:SF
1035                 (vec_select:SF (match_dup 1) (parallel [(const_int 4)]))
1036                 (vec_select:SF (match_dup 1) (parallel [(const_int 5)])))
1037               (plusminus:SF
1038                 (vec_select:SF (match_dup 1) (parallel [(const_int 6)]))
1039                 (vec_select:SF (match_dup 1) (parallel [(const_int 7)]))))
1040             (vec_concat:V2SF
1041               (plusminus:SF
1042                 (vec_select:SF (match_dup 2) (parallel [(const_int 4)]))
1043                 (vec_select:SF (match_dup 2) (parallel [(const_int 5)])))
1044               (plusminus:SF
1045                 (vec_select:SF (match_dup 2) (parallel [(const_int 6)]))
1046                 (vec_select:SF (match_dup 2) (parallel [(const_int 7)])))))))]
1047   "TARGET_AVX"
1048   "vh<plusminus_mnemonic>ps\t{%2, %1, %0|%0, %1, %2}"
1049   [(set_attr "type" "sseadd")
1050    (set_attr "prefix" "vex")
1051    (set_attr "mode" "V8SF")])
1052
1053 (define_insn "sse3_h<plusminus_insn>v4sf3"
1054   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
1055         (vec_concat:V4SF
1056           (vec_concat:V2SF
1057             (plusminus:SF
1058               (vec_select:SF
1059                 (match_operand:V4SF 1 "register_operand" "0,x")
1060                 (parallel [(const_int 0)]))
1061               (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
1062             (plusminus:SF
1063               (vec_select:SF (match_dup 1) (parallel [(const_int 2)]))
1064               (vec_select:SF (match_dup 1) (parallel [(const_int 3)]))))
1065           (vec_concat:V2SF
1066             (plusminus:SF
1067               (vec_select:SF
1068                 (match_operand:V4SF 2 "nonimmediate_operand" "xm,xm")
1069                 (parallel [(const_int 0)]))
1070               (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))
1071             (plusminus:SF
1072               (vec_select:SF (match_dup 2) (parallel [(const_int 2)]))
1073               (vec_select:SF (match_dup 2) (parallel [(const_int 3)]))))))]
1074   "TARGET_SSE3"
1075   "@
1076    h<plusminus_mnemonic>ps\t{%2, %0|%0, %2}
1077    vh<plusminus_mnemonic>ps\t{%2, %1, %0|%0, %1, %2}"
1078   [(set_attr "isa" "noavx,avx")
1079    (set_attr "type" "sseadd")
1080    (set_attr "atom_unit" "complex")
1081    (set_attr "prefix" "orig,vex")
1082    (set_attr "prefix_rep" "1,*")
1083    (set_attr "mode" "V4SF")])
1084
1085 (define_expand "reduc_splus_v4df"
1086   [(match_operand:V4DF 0 "register_operand" "")
1087    (match_operand:V4DF 1 "register_operand" "")]
1088   "TARGET_AVX"
1089 {
1090   rtx tmp = gen_reg_rtx (V4DFmode);
1091   rtx tmp2 = gen_reg_rtx (V4DFmode);
1092   emit_insn (gen_avx_haddv4df3 (tmp, operands[1], operands[1]));
1093   emit_insn (gen_avx_vperm2f128v4df3 (tmp2, tmp, tmp, GEN_INT (1)));
1094   emit_insn (gen_addv4df3 (operands[0], tmp, tmp2));
1095   DONE;
1096 })
1097
1098 (define_expand "reduc_splus_v2df"
1099   [(match_operand:V2DF 0 "register_operand" "")
1100    (match_operand:V2DF 1 "register_operand" "")]
1101   "TARGET_SSE3"
1102 {
1103   emit_insn (gen_sse3_haddv2df3 (operands[0], operands[1], operands[1]));
1104   DONE;
1105 })
1106
1107 (define_expand "reduc_splus_v8sf"
1108   [(match_operand:V8SF 0 "register_operand" "")
1109    (match_operand:V8SF 1 "register_operand" "")]
1110   "TARGET_AVX"
1111 {
1112   rtx tmp = gen_reg_rtx (V8SFmode);
1113   rtx tmp2 = gen_reg_rtx (V8SFmode);
1114   emit_insn (gen_avx_haddv8sf3 (tmp, operands[1], operands[1]));
1115   emit_insn (gen_avx_haddv8sf3 (tmp2, tmp, tmp));
1116   emit_insn (gen_avx_vperm2f128v8sf3 (tmp, tmp2, tmp2, GEN_INT (1)));
1117   emit_insn (gen_addv8sf3 (operands[0], tmp, tmp2));
1118   DONE;
1119 })
1120
1121 (define_expand "reduc_splus_v4sf"
1122   [(match_operand:V4SF 0 "register_operand" "")
1123    (match_operand:V4SF 1 "register_operand" "")]
1124   "TARGET_SSE"
1125 {
1126   if (TARGET_SSE3)
1127     {
1128       rtx tmp = gen_reg_rtx (V4SFmode);
1129       emit_insn (gen_sse3_haddv4sf3 (tmp, operands[1], operands[1]));
1130       emit_insn (gen_sse3_haddv4sf3 (operands[0], tmp, tmp));
1131     }
1132   else
1133     ix86_expand_reduc_v4sf (gen_addv4sf3, operands[0], operands[1]);
1134   DONE;
1135 })
1136
1137
1138 (define_expand "reduc_smax_v4sf"
1139   [(match_operand:V4SF 0 "register_operand" "")
1140    (match_operand:V4SF 1 "register_operand" "")]
1141   "TARGET_SSE"
1142 {
1143   ix86_expand_reduc_v4sf (gen_smaxv4sf3, operands[0], operands[1]);
1144   DONE;
1145 })
1146
1147 (define_expand "reduc_smin_v4sf"
1148   [(match_operand:V4SF 0 "register_operand" "")
1149    (match_operand:V4SF 1 "register_operand" "")]
1150   "TARGET_SSE"
1151 {
1152   ix86_expand_reduc_v4sf (gen_sminv4sf3, operands[0], operands[1]);
1153   DONE;
1154 })
1155
1156 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1157 ;;
1158 ;; Parallel floating point comparisons
1159 ;;
1160 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1161
1162 (define_insn "avx_cmp<mode>3"
1163   [(set (match_operand:VF 0 "register_operand" "=x")
1164         (unspec:VF
1165           [(match_operand:VF 1 "register_operand" "x")
1166            (match_operand:VF 2 "nonimmediate_operand" "xm")
1167            (match_operand:SI 3 "const_0_to_31_operand" "n")]
1168           UNSPEC_PCMP))]
1169   "TARGET_AVX"
1170   "vcmp<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1171   [(set_attr "type" "ssecmp")
1172    (set_attr "length_immediate" "1")
1173    (set_attr "prefix" "vex")
1174    (set_attr "mode" "<MODE>")])
1175
1176 (define_insn "avx_vmcmp<mode>3"
1177   [(set (match_operand:VF_128 0 "register_operand" "=x")
1178         (vec_merge:VF_128
1179           (unspec:VF_128
1180             [(match_operand:VF_128 1 "register_operand" "x")
1181              (match_operand:VF_128 2 "nonimmediate_operand" "xm")
1182              (match_operand:SI 3 "const_0_to_31_operand" "n")]
1183             UNSPEC_PCMP)
1184          (match_dup 1)
1185          (const_int 1)))]
1186   "TARGET_AVX"
1187   "vcmp<ssescalarmodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1188   [(set_attr "type" "ssecmp")
1189    (set_attr "length_immediate" "1")
1190    (set_attr "prefix" "vex")
1191    (set_attr "mode" "<ssescalarmode>")])
1192
1193 (define_insn "*<sse>_maskcmp<mode>3_comm"
1194   [(set (match_operand:VF 0 "register_operand" "=x,x")
1195         (match_operator:VF 3 "sse_comparison_operator"
1196           [(match_operand:VF 1 "register_operand" "%0,x")
1197            (match_operand:VF 2 "nonimmediate_operand" "xm,xm")]))]
1198   "TARGET_SSE
1199    && GET_RTX_CLASS (GET_CODE (operands[3])) == RTX_COMM_COMPARE"
1200   "@
1201    cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
1202    vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
1203   [(set_attr "isa" "noavx,avx")
1204    (set_attr "type" "ssecmp")
1205    (set_attr "length_immediate" "1")
1206    (set_attr "prefix" "orig,vex")
1207    (set_attr "mode" "<MODE>")])
1208
1209 (define_insn "<sse>_maskcmp<mode>3"
1210   [(set (match_operand:VF 0 "register_operand" "=x,x")
1211         (match_operator:VF 3 "sse_comparison_operator"
1212           [(match_operand:VF 1 "register_operand" "0,x")
1213            (match_operand:VF 2 "nonimmediate_operand" "xm,xm")]))]
1214   "TARGET_SSE"
1215   "@
1216    cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
1217    vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
1218   [(set_attr "isa" "noavx,avx")
1219    (set_attr "type" "ssecmp")
1220    (set_attr "length_immediate" "1")
1221    (set_attr "prefix" "orig,vex")
1222    (set_attr "mode" "<MODE>")])
1223
1224 (define_insn "<sse>_vmmaskcmp<mode>3"
1225   [(set (match_operand:VF_128 0 "register_operand" "=x,x")
1226         (vec_merge:VF_128
1227          (match_operator:VF_128 3 "sse_comparison_operator"
1228            [(match_operand:VF_128 1 "register_operand" "0,x")
1229             (match_operand:VF_128 2 "nonimmediate_operand" "xm,xm")])
1230          (match_dup 1)
1231          (const_int 1)))]
1232   "TARGET_SSE"
1233   "@
1234    cmp%D3<ssescalarmodesuffix>\t{%2, %0|%0, %2}
1235    vcmp%D3<ssescalarmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
1236   [(set_attr "isa" "noavx,avx")
1237    (set_attr "type" "ssecmp")
1238    (set_attr "length_immediate" "1,*")
1239    (set_attr "prefix" "orig,vex")
1240    (set_attr "mode" "<ssescalarmode>")])
1241
1242 (define_insn "<sse>_comi"
1243   [(set (reg:CCFP FLAGS_REG)
1244         (compare:CCFP
1245           (vec_select:MODEF
1246             (match_operand:<ssevecmode> 0 "register_operand" "x")
1247             (parallel [(const_int 0)]))
1248           (vec_select:MODEF
1249             (match_operand:<ssevecmode> 1 "nonimmediate_operand" "xm")
1250             (parallel [(const_int 0)]))))]
1251   "SSE_FLOAT_MODE_P (<MODE>mode)"
1252   "%vcomi<ssemodesuffix>\t{%1, %0|%0, %1}"
1253   [(set_attr "type" "ssecomi")
1254    (set_attr "prefix" "maybe_vex")
1255    (set_attr "prefix_rep" "0")
1256    (set (attr "prefix_data16")
1257         (if_then_else (eq_attr "mode" "DF")
1258                       (const_string "1")
1259                       (const_string "0")))
1260    (set_attr "mode" "<MODE>")])
1261
1262 (define_insn "<sse>_ucomi"
1263   [(set (reg:CCFPU FLAGS_REG)
1264         (compare:CCFPU
1265           (vec_select:MODEF
1266             (match_operand:<ssevecmode> 0 "register_operand" "x")
1267             (parallel [(const_int 0)]))
1268           (vec_select:MODEF
1269             (match_operand:<ssevecmode> 1 "nonimmediate_operand" "xm")
1270             (parallel [(const_int 0)]))))]
1271   "SSE_FLOAT_MODE_P (<MODE>mode)"
1272   "%vucomi<ssemodesuffix>\t{%1, %0|%0, %1}"
1273   [(set_attr "type" "ssecomi")
1274    (set_attr "prefix" "maybe_vex")
1275    (set_attr "prefix_rep" "0")
1276    (set (attr "prefix_data16")
1277         (if_then_else (eq_attr "mode" "DF")
1278                       (const_string "1")
1279                       (const_string "0")))
1280    (set_attr "mode" "<MODE>")])
1281
1282 (define_expand "vcond<mode>"
1283   [(set (match_operand:VF 0 "register_operand" "")
1284         (if_then_else:VF
1285           (match_operator 3 ""
1286             [(match_operand:VF 4 "nonimmediate_operand" "")
1287              (match_operand:VF 5 "nonimmediate_operand" "")])
1288           (match_operand:VF 1 "general_operand" "")
1289           (match_operand:VF 2 "general_operand" "")))]
1290   "TARGET_SSE"
1291 {
1292   bool ok = ix86_expand_fp_vcond (operands);
1293   gcc_assert (ok);
1294   DONE;
1295 })
1296
1297 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1298 ;;
1299 ;; Parallel floating point logical operations
1300 ;;
1301 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1302
1303 (define_insn "<sse>_andnot<mode>3"
1304   [(set (match_operand:VF 0 "register_operand" "=x,x")
1305         (and:VF
1306           (not:VF
1307             (match_operand:VF 1 "register_operand" "0,x"))
1308           (match_operand:VF 2 "nonimmediate_operand" "xm,xm")))]
1309   "TARGET_SSE"
1310 {
1311   static char buf[32];
1312   const char *insn;
1313   const char *suffix
1314     = TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL ? "ps" : "<ssemodesuffix>";
1315
1316   switch (which_alternative)
1317     {
1318     case 0:
1319       insn = "andn%s\t{%%2, %%0|%%0, %%2}";
1320       break;
1321     case 1:
1322       insn = "vandn%s\t{%%2, %%1, %%0|%%0, %%1, %%2}";
1323       break;
1324     default:
1325       gcc_unreachable ();
1326     }
1327
1328   snprintf (buf, sizeof (buf), insn, suffix);
1329   return buf;
1330 }
1331   [(set_attr "isa" "noavx,avx")
1332    (set_attr "type" "sselog")
1333    (set_attr "prefix" "orig,vex")
1334    (set_attr "mode" "<MODE>")])
1335
1336 (define_expand "<code><mode>3"
1337   [(set (match_operand:VF 0 "register_operand" "")
1338         (any_logic:VF
1339           (match_operand:VF 1 "nonimmediate_operand" "")
1340           (match_operand:VF 2 "nonimmediate_operand" "")))]
1341   "TARGET_SSE"
1342   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
1343
1344 (define_insn "*<code><mode>3"
1345   [(set (match_operand:VF 0 "register_operand" "=x,x")
1346         (any_logic:VF
1347           (match_operand:VF 1 "nonimmediate_operand" "%0,x")
1348           (match_operand:VF 2 "nonimmediate_operand" "xm,xm")))]
1349   "TARGET_SSE && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
1350 {
1351   static char buf[32];
1352   const char *insn;
1353   const char *suffix
1354     = TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL ? "ps" : "<ssemodesuffix>";
1355
1356   switch (which_alternative)
1357     {
1358     case 0:
1359       insn = "<logic>%s\t{%%2, %%0|%%0, %%2}";
1360       break;
1361     case 1:
1362       insn = "v<logic>%s\t{%%2, %%1, %%0|%%0, %%1, %%2}";
1363       break;
1364     default:
1365       gcc_unreachable ();
1366     }
1367
1368   snprintf (buf, sizeof (buf), insn, suffix);
1369   return buf;
1370 }
1371   [(set_attr "isa" "noavx,avx")
1372    (set_attr "type" "sselog")
1373    (set_attr "prefix" "orig,vex")
1374    (set_attr "mode" "<MODE>")])
1375
1376 (define_expand "copysign<mode>3"
1377   [(set (match_dup 4)
1378         (and:VF
1379           (not:VF (match_dup 3))
1380           (match_operand:VF 1 "nonimmediate_operand" "")))
1381    (set (match_dup 5)
1382         (and:VF (match_dup 3)
1383                 (match_operand:VF 2 "nonimmediate_operand" "")))
1384    (set (match_operand:VF 0 "register_operand" "")
1385         (ior:VF (match_dup 4) (match_dup 5)))]
1386   "TARGET_SSE"
1387 {
1388   operands[3] = ix86_build_signbit_mask (<MODE>mode, 1, 0);
1389
1390   operands[4] = gen_reg_rtx (<MODE>mode);
1391   operands[5] = gen_reg_rtx (<MODE>mode);
1392 })
1393
1394 ;; Also define scalar versions.  These are used for abs, neg, and
1395 ;; conditional move.  Using subregs into vector modes causes register
1396 ;; allocation lossage.  These patterns do not allow memory operands
1397 ;; because the native instructions read the full 128-bits.
1398
1399 (define_insn "*andnot<mode>3"
1400   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
1401         (and:MODEF
1402           (not:MODEF
1403             (match_operand:MODEF 1 "register_operand" "0,x"))
1404             (match_operand:MODEF 2 "register_operand" "x,x")))]
1405   "SSE_FLOAT_MODE_P (<MODE>mode)"
1406 {
1407   static char buf[32];
1408   const char *insn;
1409   const char *suffix
1410     = TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL ? "ps" : "<ssevecmodesuffix>";
1411
1412   switch (which_alternative)
1413     {
1414     case 0:
1415       insn = "andn%s\t{%%2, %%0|%%0, %%2}";
1416       break;
1417     case 1:
1418       insn = "vandn%s\t{%%2, %%1, %%0|%%0, %%1, %%2}";
1419       break;
1420     default:
1421       gcc_unreachable ();
1422     }
1423
1424   snprintf (buf, sizeof (buf), insn, suffix);
1425   return buf;
1426 }
1427   [(set_attr "isa" "noavx,avx")
1428    (set_attr "type" "sselog")
1429    (set_attr "prefix" "orig,vex")
1430    (set_attr "mode" "<ssevecmode>")])
1431
1432 (define_insn "*<code><mode>3"
1433   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
1434         (any_logic:MODEF
1435           (match_operand:MODEF 1 "register_operand" "%0,x")
1436           (match_operand:MODEF 2 "register_operand" "x,x")))]
1437   "SSE_FLOAT_MODE_P (<MODE>mode)"
1438 {
1439   static char buf[32];
1440   const char *insn;
1441   const char *suffix
1442     = TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL ? "ps" : "<ssevecmodesuffix>";
1443
1444   switch (which_alternative)
1445     {
1446     case 0:
1447       insn = "<logic>%s\t{%%2, %%0|%%0, %%2}";
1448       break;
1449     case 1:
1450       insn = "v<logic>%s\t{%%2, %%1, %%0|%%0, %%1, %%2}";
1451       break;
1452     default:
1453       gcc_unreachable ();
1454     }
1455
1456   snprintf (buf, sizeof (buf), insn, suffix);
1457   return buf;
1458 }
1459   [(set_attr "isa" "noavx,avx")
1460    (set_attr "type" "sselog")
1461    (set_attr "prefix" "orig,vex")
1462    (set_attr "mode" "<ssevecmode>")])
1463
1464 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1465 ;;
1466 ;; FMA4 floating point multiply/accumulate instructions.  This
1467 ;; includes the scalar version of the instructions as well as the
1468 ;; vector.
1469 ;;
1470 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1471
1472 ;; In order to match (*a * *b) + *c, particularly when vectorizing, allow
1473 ;; combine to generate a multiply/add with two memory references.  We then
1474 ;; split this insn, into loading up the destination register with one of the
1475 ;; memory operations.  If we don't manage to split the insn, reload will
1476 ;; generate the appropriate moves.  The reason this is needed, is that combine
1477 ;; has already folded one of the memory references into both the multiply and
1478 ;; add insns, and it can't generate a new pseudo.  I.e.:
1479 ;;      (set (reg1) (mem (addr1)))
1480 ;;      (set (reg2) (mult (reg1) (mem (addr2))))
1481 ;;      (set (reg3) (plus (reg2) (mem (addr3))))
1482 ;;
1483 ;; ??? This is historic, pre-dating the gimple fma transformation.
1484 ;; We could now properly represent that only one memory operand is
1485 ;; allowed and not be penalized during optimization.
1486
1487 ;; Intrinsic FMA operations.
1488
1489 ;; The standard names for fma is only available with SSE math enabled.
1490 (define_expand "fma<mode>4"
1491   [(set (match_operand:FMAMODE 0 "register_operand")
1492         (fma:FMAMODE
1493           (match_operand:FMAMODE 1 "nonimmediate_operand")
1494           (match_operand:FMAMODE 2 "nonimmediate_operand")
1495           (match_operand:FMAMODE 3 "nonimmediate_operand")))]
1496   "(TARGET_FMA || TARGET_FMA4) && TARGET_SSE_MATH")
1497
1498 (define_expand "fms<mode>4"
1499   [(set (match_operand:FMAMODE 0 "register_operand")
1500         (fma:FMAMODE
1501           (match_operand:FMAMODE 1 "nonimmediate_operand")
1502           (match_operand:FMAMODE 2 "nonimmediate_operand")
1503           (neg:FMAMODE (match_operand:FMAMODE 3 "nonimmediate_operand"))))]
1504   "(TARGET_FMA || TARGET_FMA4) && TARGET_SSE_MATH")
1505
1506 (define_expand "fnma<mode>4"
1507   [(set (match_operand:FMAMODE 0 "register_operand")
1508         (fma:FMAMODE
1509           (neg:FMAMODE (match_operand:FMAMODE 1 "nonimmediate_operand"))
1510           (match_operand:FMAMODE 2 "nonimmediate_operand")
1511           (match_operand:FMAMODE 3 "nonimmediate_operand")))]
1512   "(TARGET_FMA || TARGET_FMA4) && TARGET_SSE_MATH")
1513
1514 (define_expand "fnms<mode>4"
1515   [(set (match_operand:FMAMODE 0 "register_operand")
1516         (fma:FMAMODE
1517           (neg:FMAMODE (match_operand:FMAMODE 1 "nonimmediate_operand"))
1518           (match_operand:FMAMODE 2 "nonimmediate_operand")
1519           (neg:FMAMODE (match_operand:FMAMODE 3 "nonimmediate_operand"))))]
1520   "(TARGET_FMA || TARGET_FMA4) && TARGET_SSE_MATH")
1521
1522 ;; The builtin for fma4intrin.h is not constrained by SSE math enabled.
1523 (define_expand "fma4i_fmadd_<mode>"
1524   [(set (match_operand:FMAMODE 0 "register_operand")
1525         (fma:FMAMODE
1526           (match_operand:FMAMODE 1 "nonimmediate_operand")
1527           (match_operand:FMAMODE 2 "nonimmediate_operand")
1528           (match_operand:FMAMODE 3 "nonimmediate_operand")))]
1529   "TARGET_FMA || TARGET_FMA4")
1530
1531 (define_insn "*fma4i_fmadd_<mode>"
1532   [(set (match_operand:FMAMODE 0 "register_operand" "=x,x")
1533         (fma:FMAMODE
1534           (match_operand:FMAMODE 1 "nonimmediate_operand" "%x,x")
1535           (match_operand:FMAMODE 2 "nonimmediate_operand" " x,m")
1536           (match_operand:FMAMODE 3 "nonimmediate_operand" "xm,x")))]
1537   "TARGET_FMA4"
1538   "vfmadd<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1539   [(set_attr "type" "ssemuladd")
1540    (set_attr "mode" "<MODE>")])
1541
1542 (define_insn "*fma4i_fmsub_<mode>"
1543   [(set (match_operand:FMAMODE 0 "register_operand" "=x,x")
1544         (fma:FMAMODE
1545           (match_operand:FMAMODE 1 "nonimmediate_operand" "%x,x")
1546           (match_operand:FMAMODE 2 "nonimmediate_operand" " x,m")
1547           (neg:FMAMODE
1548             (match_operand:FMAMODE 3 "nonimmediate_operand" "xm,x"))))]
1549   "TARGET_FMA4"
1550   "vfmsub<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1551   [(set_attr "type" "ssemuladd")
1552    (set_attr "mode" "<MODE>")])
1553
1554 (define_insn "*fma4i_fnmadd_<mode>"
1555   [(set (match_operand:FMAMODE 0 "register_operand" "=x,x")
1556         (fma:FMAMODE
1557           (neg:FMAMODE
1558             (match_operand:FMAMODE 1 "nonimmediate_operand" "%x,x"))
1559           (match_operand:FMAMODE   2 "nonimmediate_operand" " x,m")
1560           (match_operand:FMAMODE   3 "nonimmediate_operand" "xm,x")))]
1561   "TARGET_FMA4"
1562   "vfnmadd<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1563   [(set_attr "type" "ssemuladd")
1564    (set_attr "mode" "<MODE>")])
1565
1566 (define_insn "*fma4i_fnmsub_<mode>"
1567   [(set (match_operand:FMAMODE 0 "register_operand" "=x,x")
1568         (fma:FMAMODE
1569           (neg:FMAMODE
1570             (match_operand:FMAMODE 1 "nonimmediate_operand" "%x,x"))
1571           (match_operand:FMAMODE   2 "nonimmediate_operand" " x,m")
1572           (neg:FMAMODE
1573             (match_operand:FMAMODE 3 "nonimmediate_operand" "xm,x"))))]
1574   "TARGET_FMA4"
1575   "vfnmsub<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1576   [(set_attr "type" "ssemuladd")
1577    (set_attr "mode" "<MODE>")])
1578
1579 ;; Scalar versions of the above.  Unlike ADDSS et al, these write the
1580 ;; entire destination register, with the high-order elements zeroed.
1581
1582 (define_expand "fma4i_vmfmadd_<mode>"
1583   [(set (match_operand:VF_128 0 "register_operand")
1584         (vec_merge:VF_128
1585           (fma:VF_128
1586             (match_operand:VF_128 1 "nonimmediate_operand")
1587             (match_operand:VF_128 2 "nonimmediate_operand")
1588             (match_operand:VF_128 3 "nonimmediate_operand"))
1589           (match_dup 4)
1590           (const_int 1)))]
1591   "TARGET_FMA4"
1592 {
1593   operands[4] = CONST0_RTX (<MODE>mode);
1594 })
1595
1596 (define_insn "*fma4i_vmfmadd_<mode>"
1597   [(set (match_operand:VF_128 0 "register_operand" "=x,x")
1598         (vec_merge:VF_128
1599           (fma:VF_128
1600             (match_operand:VF_128 1 "nonimmediate_operand" "%x,x")
1601             (match_operand:VF_128 2 "nonimmediate_operand" " x,m")
1602             (match_operand:VF_128 3 "nonimmediate_operand" "xm,x"))
1603           (match_operand:VF_128 4 "const0_operand" "")
1604           (const_int 1)))]
1605   "TARGET_FMA4"
1606   "vfmadd<ssescalarmodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1607   [(set_attr "type" "ssemuladd")
1608    (set_attr "mode" "<MODE>")])
1609
1610 (define_insn "*fma4i_vmfmsub_<mode>"
1611   [(set (match_operand:VF_128 0 "register_operand" "=x,x")
1612         (vec_merge:VF_128
1613           (fma:VF_128
1614             (match_operand:VF_128 1 "nonimmediate_operand" "%x,x")
1615             (match_operand:VF_128 2 "nonimmediate_operand" " x,m")
1616             (neg:VF_128
1617               (match_operand:VF_128 3 "nonimmediate_operand" "xm,x")))
1618           (match_operand:VF_128 4 "const0_operand" "")
1619           (const_int 1)))]
1620   "TARGET_FMA4"
1621   "vfmsub<ssescalarmodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1622   [(set_attr "type" "ssemuladd")
1623    (set_attr "mode" "<MODE>")])
1624
1625 (define_insn "*fma4i_vmfnmadd_<mode>"
1626   [(set (match_operand:VF_128 0 "register_operand" "=x,x")
1627         (vec_merge:VF_128
1628           (fma:VF_128
1629             (neg:VF_128
1630               (match_operand:VF_128 1 "nonimmediate_operand" "%x,x"))
1631             (match_operand:VF_128   2 "nonimmediate_operand" " x,m")
1632             (match_operand:VF_128   3 "nonimmediate_operand" "xm,x"))
1633           (match_operand:VF_128 4 "const0_operand" "")
1634           (const_int 1)))]
1635   "TARGET_FMA4"
1636   "vfnmadd<ssescalarmodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1637   [(set_attr "type" "ssemuladd")
1638    (set_attr "mode" "<MODE>")])
1639
1640 (define_insn "*fma4i_vmfnmsub_<mode>"
1641   [(set (match_operand:VF_128 0 "register_operand" "=x,x")
1642         (vec_merge:VF_128
1643           (fma:VF_128
1644             (neg:VF_128
1645               (match_operand:VF_128 1 "nonimmediate_operand" "%x,x"))
1646             (match_operand:VF_128   2 "nonimmediate_operand" " x,m")
1647             (neg:VF_128
1648               (match_operand:VF_128   3 "nonimmediate_operand" "xm,x")))
1649           (match_operand:VF_128 4 "const0_operand" "")
1650           (const_int 1)))]
1651   "TARGET_FMA4"
1652   "vfnmsub<ssescalarmodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1653   [(set_attr "type" "ssemuladd")
1654    (set_attr "mode" "<MODE>")])
1655
1656 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1657 ;;
1658 ;; FMA4 Parallel floating point multiply addsub and subadd operations.
1659 ;;
1660 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1661
1662 ;; It would be possible to represent these without the UNSPEC as
1663 ;;
1664 ;; (vec_merge
1665 ;;   (fma op1 op2 op3)
1666 ;;   (fma op1 op2 (neg op3))
1667 ;;   (merge-const))
1668 ;;
1669 ;; But this doesn't seem useful in practice.
1670
1671 (define_expand "fmaddsub_<mode>"
1672   [(set (match_operand:VF 0 "register_operand")
1673         (unspec:VF
1674           [(match_operand:VF 1 "nonimmediate_operand")
1675            (match_operand:VF 2 "nonimmediate_operand")
1676            (match_operand:VF 3 "nonimmediate_operand")]
1677           UNSPEC_FMADDSUB))]
1678   "TARGET_FMA || TARGET_FMA4")
1679
1680 (define_insn "*fma4_fmaddsub_<mode>"
1681   [(set (match_operand:VF 0 "register_operand" "=x,x")
1682         (unspec:VF
1683           [(match_operand:VF 1 "nonimmediate_operand" "%x,x")
1684            (match_operand:VF 2 "nonimmediate_operand" " x,m")
1685            (match_operand:VF 3 "nonimmediate_operand" "xm,x")]
1686           UNSPEC_FMADDSUB))]
1687   "TARGET_FMA4"
1688   "vfmaddsub<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1689   [(set_attr "type" "ssemuladd")
1690    (set_attr "mode" "<MODE>")])
1691
1692 (define_insn "*fma4_fmsubadd_<mode>"
1693   [(set (match_operand:VF 0 "register_operand" "=x,x")
1694         (unspec:VF
1695           [(match_operand:VF 1 "nonimmediate_operand" "%x,x")
1696            (match_operand:VF 2 "nonimmediate_operand" " x,m")
1697            (neg:VF
1698              (match_operand:VF 3 "nonimmediate_operand" "xm,x"))]
1699           UNSPEC_FMADDSUB))]
1700   "TARGET_FMA4"
1701   "vfmsubadd<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1702   [(set_attr "type" "ssemuladd")
1703    (set_attr "mode" "<MODE>")])
1704
1705 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1706 ;;
1707 ;; FMA3 floating point multiply/accumulate instructions.
1708 ;;
1709 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1710
1711 (define_insn "*fma_fmadd_<mode>"
1712   [(set (match_operand:FMAMODE 0 "register_operand" "=x,x,x")
1713         (fma:FMAMODE
1714           (match_operand:FMAMODE 1 "nonimmediate_operand" "%0, 0,x")
1715           (match_operand:FMAMODE 2 "nonimmediate_operand" "xm, x,xm")
1716           (match_operand:FMAMODE 3 "nonimmediate_operand" " x,xm,0")))]
1717   "TARGET_FMA"
1718   "@
1719    vfmadd132<ssemodesuffix>\t{%2, %3, %0|%0, %3, %2}
1720    vfmadd213<ssemodesuffix>\t{%3, %2, %0|%0, %2, %3}
1721    vfmadd231<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
1722   [(set_attr "type" "ssemuladd")
1723    (set_attr "mode" "<MODE>")])
1724
1725 (define_insn "*fma_fmsub_<mode>"
1726   [(set (match_operand:FMAMODE 0 "register_operand" "=x,x,x")
1727         (fma:FMAMODE
1728           (match_operand:FMAMODE   1 "nonimmediate_operand" "%0, 0,x")
1729           (match_operand:FMAMODE   2 "nonimmediate_operand" "xm, x,xm")
1730           (neg:FMAMODE
1731             (match_operand:FMAMODE 3 "nonimmediate_operand" " x,xm,0"))))]
1732   "TARGET_FMA"
1733   "@
1734    vfmsub132<ssemodesuffix>\t{%2, %3, %0|%0, %3, %2}
1735    vfmsub213<ssemodesuffix>\t{%3, %2, %0|%0, %2, %3}
1736    vfmsub231<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
1737   [(set_attr "type" "ssemuladd")
1738    (set_attr "mode" "<MODE>")])
1739
1740 (define_insn "*fma_fnmadd_<mode>"
1741   [(set (match_operand:FMAMODE 0 "register_operand" "=x,x,x")
1742         (fma:FMAMODE
1743           (neg:FMAMODE
1744             (match_operand:FMAMODE 1 "nonimmediate_operand" "%0, 0,x"))
1745           (match_operand:FMAMODE   2 "nonimmediate_operand" "xm, x,xm")
1746           (match_operand:FMAMODE   3 "nonimmediate_operand" " x,xm,0")))]
1747   "TARGET_FMA"
1748   "@
1749    vfnmadd132<ssemodesuffix>\t{%2, %3, %0|%0, %3, %2}
1750    vfnmadd213<ssemodesuffix>\t{%3, %2, %0|%0, %2, %3}
1751    vfnmadd231<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
1752   [(set_attr "type" "ssemuladd")
1753    (set_attr "mode" "<MODE>")])
1754
1755 (define_insn "*fma_fnmsub_<mode>"
1756   [(set (match_operand:FMAMODE 0 "register_operand" "=x,x,x")
1757         (fma:FMAMODE
1758           (neg:FMAMODE
1759             (match_operand:FMAMODE 1 "nonimmediate_operand" "%0, 0,x"))
1760           (match_operand:FMAMODE   2 "nonimmediate_operand" "xm, x,xm")
1761           (neg:FMAMODE
1762             (match_operand:FMAMODE 3 "nonimmediate_operand" " x,xm,0"))))]
1763   "TARGET_FMA"
1764   "@
1765    vfnmsub132<ssemodesuffix>\t{%2, %3, %0|%0, %3, %2}
1766    vfnmsub231<ssemodesuffix>\t{%3, %2, %0|%0, %2, %3}
1767    vfnmsub231<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
1768   [(set_attr "type" "ssemuladd")
1769    (set_attr "mode" "<MODE>")])
1770
1771 (define_insn "*fma_fmaddsub_<mode>"
1772   [(set (match_operand:VF 0 "register_operand" "=x,x,x")
1773         (unspec:VF
1774           [(match_operand:VF 1 "nonimmediate_operand" "%0, 0,x")
1775            (match_operand:VF 2 "nonimmediate_operand" "xm, x,xm")
1776            (match_operand:VF 3 "nonimmediate_operand" " x,xm,0")]
1777           UNSPEC_FMADDSUB))]
1778   "TARGET_FMA"
1779   "@
1780    vfmaddsub132<ssemodesuffix>\t{%2, %3, %0|%0, %3, %2}
1781    vfmaddsub213<ssemodesuffix>\t{%3, %2, %0|%0, %2, %3}
1782    vfmaddsub231<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
1783   [(set_attr "type" "ssemuladd")
1784    (set_attr "mode" "<MODE>")])
1785
1786 (define_insn "*fma_fmsubadd_<mode>"
1787   [(set (match_operand:VF 0 "register_operand" "=x,x,x")
1788         (unspec:VF
1789           [(match_operand:VF   1 "nonimmediate_operand" "%0, 0,x")
1790            (match_operand:VF   2 "nonimmediate_operand" "xm, x,xm")
1791            (neg:VF
1792              (match_operand:VF 3 "nonimmediate_operand" " x,xm,0"))]
1793           UNSPEC_FMADDSUB))]
1794   "TARGET_FMA"
1795   "@
1796    vfmsubadd132<ssemodesuffix>\t{%2, %3, %0|%0, %3, %2}
1797    vfmsubadd213<ssemodesuffix>\t{%3, %2, %0|%0, %2, %3}
1798    vfmsubadd231<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
1799   [(set_attr "type" "ssemuladd")
1800    (set_attr "mode" "<MODE>")])
1801
1802 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1803 ;;
1804 ;; Parallel single-precision floating point conversion operations
1805 ;;
1806 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1807
1808 (define_insn "sse_cvtpi2ps"
1809   [(set (match_operand:V4SF 0 "register_operand" "=x")
1810         (vec_merge:V4SF
1811           (vec_duplicate:V4SF
1812             (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
1813           (match_operand:V4SF 1 "register_operand" "0")
1814           (const_int 3)))]
1815   "TARGET_SSE"
1816   "cvtpi2ps\t{%2, %0|%0, %2}"
1817   [(set_attr "type" "ssecvt")
1818    (set_attr "mode" "V4SF")])
1819
1820 (define_insn "sse_cvtps2pi"
1821   [(set (match_operand:V2SI 0 "register_operand" "=y")
1822         (vec_select:V2SI
1823           (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
1824                        UNSPEC_FIX_NOTRUNC)
1825           (parallel [(const_int 0) (const_int 1)])))]
1826   "TARGET_SSE"
1827   "cvtps2pi\t{%1, %0|%0, %1}"
1828   [(set_attr "type" "ssecvt")
1829    (set_attr "unit" "mmx")
1830    (set_attr "mode" "DI")])
1831
1832 (define_insn "sse_cvttps2pi"
1833   [(set (match_operand:V2SI 0 "register_operand" "=y")
1834         (vec_select:V2SI
1835           (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
1836           (parallel [(const_int 0) (const_int 1)])))]
1837   "TARGET_SSE"
1838   "cvttps2pi\t{%1, %0|%0, %1}"
1839   [(set_attr "type" "ssecvt")
1840    (set_attr "unit" "mmx")
1841    (set_attr "prefix_rep" "0")
1842    (set_attr "mode" "SF")])
1843
1844 (define_insn "sse_cvtsi2ss"
1845   [(set (match_operand:V4SF 0 "register_operand" "=x,x,x")
1846         (vec_merge:V4SF
1847           (vec_duplicate:V4SF
1848             (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,m,rm")))
1849           (match_operand:V4SF 1 "register_operand" "0,0,x")
1850           (const_int 1)))]
1851   "TARGET_SSE"
1852   "@
1853    cvtsi2ss\t{%2, %0|%0, %2}
1854    cvtsi2ss\t{%2, %0|%0, %2}
1855    vcvtsi2ss\t{%2, %1, %0|%0, %1, %2}"
1856   [(set_attr "isa" "noavx,noavx,avx")
1857    (set_attr "type" "sseicvt")
1858    (set_attr "athlon_decode" "vector,double,*")
1859    (set_attr "amdfam10_decode" "vector,double,*")
1860    (set_attr "bdver1_decode" "double,direct,*")
1861    (set_attr "prefix" "orig,orig,vex")
1862    (set_attr "mode" "SF")])
1863
1864 (define_insn "sse_cvtsi2ssq"
1865   [(set (match_operand:V4SF 0 "register_operand" "=x,x,x")
1866         (vec_merge:V4SF
1867           (vec_duplicate:V4SF
1868             (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,m,rm")))
1869           (match_operand:V4SF 1 "register_operand" "0,0,x")
1870           (const_int 1)))]
1871   "TARGET_SSE && TARGET_64BIT"
1872   "@
1873    cvtsi2ssq\t{%2, %0|%0, %2}
1874    cvtsi2ssq\t{%2, %0|%0, %2}
1875    vcvtsi2ssq\t{%2, %1, %0|%0, %1, %2}"
1876   [(set_attr "isa" "noavx,noavx,avx")
1877    (set_attr "type" "sseicvt")
1878    (set_attr "athlon_decode" "vector,double,*")
1879    (set_attr "amdfam10_decode" "vector,double,*")
1880    (set_attr "bdver1_decode" "double,direct,*")
1881    (set_attr "length_vex" "*,*,4")
1882    (set_attr "prefix_rex" "1,1,*")
1883    (set_attr "prefix" "orig,orig,vex")
1884    (set_attr "mode" "SF")])
1885
1886 (define_insn "sse_cvtss2si"
1887   [(set (match_operand:SI 0 "register_operand" "=r,r")
1888         (unspec:SI
1889           [(vec_select:SF
1890              (match_operand:V4SF 1 "nonimmediate_operand" "x,m")
1891              (parallel [(const_int 0)]))]
1892           UNSPEC_FIX_NOTRUNC))]
1893   "TARGET_SSE"
1894   "%vcvtss2si\t{%1, %0|%0, %1}"
1895   [(set_attr "type" "sseicvt")
1896    (set_attr "athlon_decode" "double,vector")
1897    (set_attr "bdver1_decode" "double,double")
1898    (set_attr "prefix_rep" "1")
1899    (set_attr "prefix" "maybe_vex")
1900    (set_attr "mode" "SI")])
1901
1902 (define_insn "sse_cvtss2si_2"
1903   [(set (match_operand:SI 0 "register_operand" "=r,r")
1904         (unspec:SI [(match_operand:SF 1 "nonimmediate_operand" "x,m")]
1905                    UNSPEC_FIX_NOTRUNC))]
1906   "TARGET_SSE"
1907   "%vcvtss2si\t{%1, %0|%0, %1}"
1908   [(set_attr "type" "sseicvt")
1909    (set_attr "athlon_decode" "double,vector")
1910    (set_attr "amdfam10_decode" "double,double")
1911    (set_attr "bdver1_decode" "double,double")
1912    (set_attr "prefix_rep" "1")
1913    (set_attr "prefix" "maybe_vex")
1914    (set_attr "mode" "SI")])
1915
1916 (define_insn "sse_cvtss2siq"
1917   [(set (match_operand:DI 0 "register_operand" "=r,r")
1918         (unspec:DI
1919           [(vec_select:SF
1920              (match_operand:V4SF 1 "nonimmediate_operand" "x,m")
1921              (parallel [(const_int 0)]))]
1922           UNSPEC_FIX_NOTRUNC))]
1923   "TARGET_SSE && TARGET_64BIT"
1924   "%vcvtss2si{q}\t{%1, %0|%0, %1}"
1925   [(set_attr "type" "sseicvt")
1926    (set_attr "athlon_decode" "double,vector")
1927    (set_attr "bdver1_decode" "double,double")
1928    (set_attr "prefix_rep" "1")
1929    (set_attr "prefix" "maybe_vex")
1930    (set_attr "mode" "DI")])
1931
1932 (define_insn "sse_cvtss2siq_2"
1933   [(set (match_operand:DI 0 "register_operand" "=r,r")
1934         (unspec:DI [(match_operand:SF 1 "nonimmediate_operand" "x,m")]
1935                    UNSPEC_FIX_NOTRUNC))]
1936   "TARGET_SSE && TARGET_64BIT"
1937   "%vcvtss2si{q}\t{%1, %0|%0, %1}"
1938   [(set_attr "type" "sseicvt")
1939    (set_attr "athlon_decode" "double,vector")
1940    (set_attr "amdfam10_decode" "double,double")
1941    (set_attr "bdver1_decode" "double,double")
1942    (set_attr "prefix_rep" "1")
1943    (set_attr "prefix" "maybe_vex")
1944    (set_attr "mode" "DI")])
1945
1946 (define_insn "sse_cvttss2si"
1947   [(set (match_operand:SI 0 "register_operand" "=r,r")
1948         (fix:SI
1949           (vec_select:SF
1950             (match_operand:V4SF 1 "nonimmediate_operand" "x,m")
1951             (parallel [(const_int 0)]))))]
1952   "TARGET_SSE"
1953   "%vcvttss2si\t{%1, %0|%0, %1}"
1954   [(set_attr "type" "sseicvt")
1955    (set_attr "athlon_decode" "double,vector")
1956    (set_attr "amdfam10_decode" "double,double")
1957    (set_attr "bdver1_decode" "double,double")
1958    (set_attr "prefix_rep" "1")
1959    (set_attr "prefix" "maybe_vex")
1960    (set_attr "mode" "SI")])
1961
1962 (define_insn "sse_cvttss2siq"
1963   [(set (match_operand:DI 0 "register_operand" "=r,r")
1964         (fix:DI
1965           (vec_select:SF
1966             (match_operand:V4SF 1 "nonimmediate_operand" "x,m")
1967             (parallel [(const_int 0)]))))]
1968   "TARGET_SSE && TARGET_64BIT"
1969   "%vcvttss2si{q}\t{%1, %0|%0, %1}"
1970   [(set_attr "type" "sseicvt")
1971    (set_attr "athlon_decode" "double,vector")
1972    (set_attr "amdfam10_decode" "double,double")
1973    (set_attr "bdver1_decode" "double,double")
1974    (set_attr "prefix_rep" "1")
1975    (set_attr "prefix" "maybe_vex")
1976    (set_attr "mode" "DI")])
1977
1978 (define_insn "avx_cvtdq2ps256"
1979   [(set (match_operand:V8SF 0 "register_operand" "=x")
1980         (float:V8SF (match_operand:V8SI 1 "nonimmediate_operand" "xm")))]
1981   "TARGET_AVX"
1982   "vcvtdq2ps\t{%1, %0|%0, %1}"
1983   [(set_attr "type" "ssecvt")
1984    (set_attr "prefix" "vex")
1985    (set_attr "mode" "V8SF")])
1986
1987 (define_insn "sse2_cvtdq2ps"
1988   [(set (match_operand:V4SF 0 "register_operand" "=x")
1989         (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
1990   "TARGET_SSE2"
1991   "%vcvtdq2ps\t{%1, %0|%0, %1}"
1992   [(set_attr "type" "ssecvt")
1993    (set_attr "prefix" "maybe_vex")
1994    (set_attr "mode" "V4SF")])
1995
1996 (define_expand "sse2_cvtudq2ps"
1997   [(set (match_dup 5)
1998         (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "")))
1999    (set (match_dup 6)
2000         (lt:V4SF (match_dup 5) (match_dup 3)))
2001    (set (match_dup 7)
2002         (and:V4SF (match_dup 6) (match_dup 4)))
2003    (set (match_operand:V4SF 0 "register_operand" "")
2004         (plus:V4SF (match_dup 5) (match_dup 7)))]
2005   "TARGET_SSE2"
2006 {
2007   REAL_VALUE_TYPE TWO32r;
2008   rtx x;
2009   int i;
2010
2011   real_ldexp (&TWO32r, &dconst1, 32);
2012   x = const_double_from_real_value (TWO32r, SFmode);
2013
2014   operands[3] = force_reg (V4SFmode, CONST0_RTX (V4SFmode));
2015   operands[4] = force_reg (V4SFmode,
2016                            ix86_build_const_vector (V4SFmode, 1, x));
2017
2018   for (i = 5; i < 8; i++)
2019     operands[i] = gen_reg_rtx (V4SFmode);
2020 })
2021
2022 (define_insn "avx_cvtps2dq256"
2023   [(set (match_operand:V8SI 0 "register_operand" "=x")
2024         (unspec:V8SI [(match_operand:V8SF 1 "nonimmediate_operand" "xm")]
2025                      UNSPEC_FIX_NOTRUNC))]
2026   "TARGET_AVX"
2027   "vcvtps2dq\t{%1, %0|%0, %1}"
2028   [(set_attr "type" "ssecvt")
2029    (set_attr "prefix" "vex")
2030    (set_attr "mode" "OI")])
2031
2032 (define_insn "sse2_cvtps2dq"
2033   [(set (match_operand:V4SI 0 "register_operand" "=x")
2034         (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
2035                      UNSPEC_FIX_NOTRUNC))]
2036   "TARGET_SSE2"
2037   "%vcvtps2dq\t{%1, %0|%0, %1}"
2038   [(set_attr "type" "ssecvt")
2039    (set (attr "prefix_data16")
2040      (if_then_else
2041        (ne (symbol_ref "TARGET_AVX") (const_int 0))
2042      (const_string "*")
2043      (const_string "1")))
2044    (set_attr "prefix" "maybe_vex")
2045    (set_attr "mode" "TI")])
2046
2047 (define_insn "avx_cvttps2dq256"
2048   [(set (match_operand:V8SI 0 "register_operand" "=x")
2049         (fix:V8SI (match_operand:V8SF 1 "nonimmediate_operand" "xm")))]
2050   "TARGET_AVX"
2051   "vcvttps2dq\t{%1, %0|%0, %1}"
2052   [(set_attr "type" "ssecvt")
2053    (set_attr "prefix" "vex")
2054    (set_attr "mode" "OI")])
2055
2056 (define_insn "sse2_cvttps2dq"
2057   [(set (match_operand:V4SI 0 "register_operand" "=x")
2058         (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
2059   "TARGET_SSE2"
2060   "%vcvttps2dq\t{%1, %0|%0, %1}"
2061   [(set_attr "type" "ssecvt")
2062    (set (attr "prefix_rep")
2063      (if_then_else
2064        (ne (symbol_ref "TARGET_AVX") (const_int 0))
2065      (const_string "*")
2066      (const_string "1")))
2067    (set (attr "prefix_data16")
2068      (if_then_else
2069        (ne (symbol_ref "TARGET_AVX") (const_int 0))
2070      (const_string "*")
2071      (const_string "0")))
2072    (set_attr "prefix_data16" "0")
2073    (set_attr "prefix" "maybe_vex")
2074    (set_attr "mode" "TI")])
2075
2076 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2077 ;;
2078 ;; Parallel double-precision floating point conversion operations
2079 ;;
2080 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2081
2082 (define_insn "sse2_cvtpi2pd"
2083   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
2084         (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "y,m")))]
2085   "TARGET_SSE2"
2086   "cvtpi2pd\t{%1, %0|%0, %1}"
2087   [(set_attr "type" "ssecvt")
2088    (set_attr "unit" "mmx,*")
2089    (set_attr "prefix_data16" "1,*")
2090    (set_attr "mode" "V2DF")])
2091
2092 (define_insn "sse2_cvtpd2pi"
2093   [(set (match_operand:V2SI 0 "register_operand" "=y")
2094         (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
2095                      UNSPEC_FIX_NOTRUNC))]
2096   "TARGET_SSE2"
2097   "cvtpd2pi\t{%1, %0|%0, %1}"
2098   [(set_attr "type" "ssecvt")
2099    (set_attr "unit" "mmx")
2100    (set_attr "bdver1_decode" "double")
2101    (set_attr "prefix_data16" "1")
2102    (set_attr "mode" "DI")])
2103
2104 (define_insn "sse2_cvttpd2pi"
2105   [(set (match_operand:V2SI 0 "register_operand" "=y")
2106         (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
2107   "TARGET_SSE2"
2108   "cvttpd2pi\t{%1, %0|%0, %1}"
2109   [(set_attr "type" "ssecvt")
2110    (set_attr "unit" "mmx")
2111    (set_attr "bdver1_decode" "double")
2112    (set_attr "prefix_data16" "1")
2113    (set_attr "mode" "TI")])
2114
2115 (define_insn "sse2_cvtsi2sd"
2116   [(set (match_operand:V2DF 0 "register_operand" "=x,x,x")
2117         (vec_merge:V2DF
2118           (vec_duplicate:V2DF
2119             (float:DF (match_operand:SI 2 "nonimmediate_operand" "r,m,rm")))
2120           (match_operand:V2DF 1 "register_operand" "0,0,x")
2121           (const_int 1)))]
2122   "TARGET_SSE2"
2123   "@
2124    cvtsi2sd\t{%2, %0|%0, %2}
2125    cvtsi2sd\t{%2, %0|%0, %2}
2126    vcvtsi2sd\t{%2, %1, %0|%0, %1, %2}"
2127   [(set_attr "isa" "noavx,noavx,avx")
2128    (set_attr "type" "sseicvt")
2129    (set_attr "athlon_decode" "double,direct,*")
2130    (set_attr "amdfam10_decode" "vector,double,*")
2131    (set_attr "bdver1_decode" "double,direct,*")
2132    (set_attr "prefix" "orig,orig,vex")
2133    (set_attr "mode" "DF")])
2134
2135 (define_insn "sse2_cvtsi2sdq"
2136   [(set (match_operand:V2DF 0 "register_operand" "=x,x,x")
2137         (vec_merge:V2DF
2138           (vec_duplicate:V2DF
2139             (float:DF (match_operand:DI 2 "nonimmediate_operand" "r,m,rm")))
2140           (match_operand:V2DF 1 "register_operand" "0,0,x")
2141           (const_int 1)))]
2142   "TARGET_SSE2 && TARGET_64BIT"
2143   "@
2144    cvtsi2sdq\t{%2, %0|%0, %2}
2145    cvtsi2sdq\t{%2, %0|%0, %2}
2146    vcvtsi2sdq\t{%2, %1, %0|%0, %1, %2}"
2147   [(set_attr "isa" "noavx,noavx,avx")
2148    (set_attr "type" "sseicvt")
2149    (set_attr "athlon_decode" "double,direct,*")
2150    (set_attr "amdfam10_decode" "vector,double,*")
2151    (set_attr "bdver1_decode" "double,direct,*")
2152    (set_attr "length_vex" "*,*,4")
2153    (set_attr "prefix_rex" "1,1,*")
2154    (set_attr "prefix" "orig,orig,vex")
2155    (set_attr "mode" "DF")])
2156
2157 (define_insn "sse2_cvtsd2si"
2158   [(set (match_operand:SI 0 "register_operand" "=r,r")
2159         (unspec:SI
2160           [(vec_select:DF
2161              (match_operand:V2DF 1 "nonimmediate_operand" "x,m")
2162              (parallel [(const_int 0)]))]
2163           UNSPEC_FIX_NOTRUNC))]
2164   "TARGET_SSE2"
2165   "%vcvtsd2si\t{%1, %0|%0, %1}"
2166   [(set_attr "type" "sseicvt")
2167    (set_attr "athlon_decode" "double,vector")
2168    (set_attr "bdver1_decode" "double,double")
2169    (set_attr "prefix_rep" "1")
2170    (set_attr "prefix" "maybe_vex")
2171    (set_attr "mode" "SI")])
2172
2173 (define_insn "sse2_cvtsd2si_2"
2174   [(set (match_operand:SI 0 "register_operand" "=r,r")
2175         (unspec:SI [(match_operand:DF 1 "nonimmediate_operand" "x,m")]
2176                    UNSPEC_FIX_NOTRUNC))]
2177   "TARGET_SSE2"
2178   "%vcvtsd2si\t{%1, %0|%0, %1}"
2179   [(set_attr "type" "sseicvt")
2180    (set_attr "athlon_decode" "double,vector")
2181    (set_attr "amdfam10_decode" "double,double")
2182    (set_attr "bdver1_decode" "double,double")
2183    (set_attr "prefix_rep" "1")
2184    (set_attr "prefix" "maybe_vex")
2185    (set_attr "mode" "SI")])
2186
2187 (define_insn "sse2_cvtsd2siq"
2188   [(set (match_operand:DI 0 "register_operand" "=r,r")
2189         (unspec:DI
2190           [(vec_select:DF
2191              (match_operand:V2DF 1 "nonimmediate_operand" "x,m")
2192              (parallel [(const_int 0)]))]
2193           UNSPEC_FIX_NOTRUNC))]
2194   "TARGET_SSE2 && TARGET_64BIT"
2195   "%vcvtsd2si{q}\t{%1, %0|%0, %1}"
2196   [(set_attr "type" "sseicvt")
2197    (set_attr "athlon_decode" "double,vector")
2198    (set_attr "bdver1_decode" "double,double")
2199    (set_attr "prefix_rep" "1")
2200    (set_attr "prefix" "maybe_vex")
2201    (set_attr "mode" "DI")])
2202
2203 (define_insn "sse2_cvtsd2siq_2"
2204   [(set (match_operand:DI 0 "register_operand" "=r,r")
2205         (unspec:DI [(match_operand:DF 1 "nonimmediate_operand" "x,m")]
2206                    UNSPEC_FIX_NOTRUNC))]
2207   "TARGET_SSE2 && TARGET_64BIT"
2208   "%vcvtsd2si{q}\t{%1, %0|%0, %1}"
2209   [(set_attr "type" "sseicvt")
2210    (set_attr "athlon_decode" "double,vector")
2211    (set_attr "amdfam10_decode" "double,double")
2212    (set_attr "bdver1_decode" "double,double")
2213    (set_attr "prefix_rep" "1")
2214    (set_attr "prefix" "maybe_vex")
2215    (set_attr "mode" "DI")])
2216
2217 (define_insn "sse2_cvttsd2si"
2218   [(set (match_operand:SI 0 "register_operand" "=r,r")
2219         (fix:SI
2220           (vec_select:DF
2221             (match_operand:V2DF 1 "nonimmediate_operand" "x,m")
2222             (parallel [(const_int 0)]))))]
2223   "TARGET_SSE2"
2224   "%vcvttsd2si\t{%1, %0|%0, %1}"
2225   [(set_attr "type" "sseicvt")
2226    (set_attr "athlon_decode" "double,vector")
2227    (set_attr "amdfam10_decode" "double,double")
2228    (set_attr "bdver1_decode" "double,double")
2229    (set_attr "prefix_rep" "1")
2230    (set_attr "prefix" "maybe_vex")
2231    (set_attr "mode" "SI")])
2232
2233 (define_insn "sse2_cvttsd2siq"
2234   [(set (match_operand:DI 0 "register_operand" "=r,r")
2235         (fix:DI
2236           (vec_select:DF
2237             (match_operand:V2DF 1 "nonimmediate_operand" "x,m")
2238             (parallel [(const_int 0)]))))]
2239   "TARGET_SSE2 && TARGET_64BIT"
2240   "%vcvttsd2si{q}\t{%1, %0|%0, %1}"
2241   [(set_attr "type" "sseicvt")
2242    (set_attr "athlon_decode" "double,vector")
2243    (set_attr "amdfam10_decode" "double,double")
2244    (set_attr "bdver1_decode" "double,double")
2245    (set_attr "prefix_rep" "1")
2246    (set_attr "prefix" "maybe_vex")
2247    (set_attr "mode" "DI")])
2248
2249 (define_insn "avx_cvtdq2pd256"
2250   [(set (match_operand:V4DF 0 "register_operand" "=x")
2251         (float:V4DF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
2252   "TARGET_AVX"
2253   "vcvtdq2pd\t{%1, %0|%0, %1}"
2254   [(set_attr "type" "ssecvt")
2255    (set_attr "prefix" "vex")
2256    (set_attr "mode" "V4DF")])
2257
2258 (define_insn "*avx_cvtdq2pd256_2"
2259   [(set (match_operand:V4DF 0 "register_operand" "=x")
2260         (float:V4DF
2261           (vec_select:V4SI
2262             (match_operand:V8SI 1 "nonimmediate_operand" "xm")
2263             (parallel [(const_int 0) (const_int 1)
2264                        (const_int 2) (const_int 3)]))))]
2265   "TARGET_AVX"
2266   "vcvtdq2pd\t{%x1, %0|%0, %x1}"
2267   [(set_attr "type" "ssecvt")
2268    (set_attr "prefix" "vex")
2269    (set_attr "mode" "V4DF")])
2270
2271 (define_insn "sse2_cvtdq2pd"
2272   [(set (match_operand:V2DF 0 "register_operand" "=x")
2273         (float:V2DF
2274           (vec_select:V2SI
2275             (match_operand:V4SI 1 "nonimmediate_operand" "xm")
2276             (parallel [(const_int 0) (const_int 1)]))))]
2277   "TARGET_SSE2"
2278   "%vcvtdq2pd\t{%1, %0|%0, %1}"
2279   [(set_attr "type" "ssecvt")
2280    (set_attr "prefix" "maybe_vex")
2281    (set_attr "mode" "V2DF")])
2282
2283 (define_insn "avx_cvtpd2dq256"
2284   [(set (match_operand:V4SI 0 "register_operand" "=x")
2285         (unspec:V4SI [(match_operand:V4DF 1 "nonimmediate_operand" "xm")]
2286                      UNSPEC_FIX_NOTRUNC))]
2287   "TARGET_AVX"
2288   "vcvtpd2dq{y}\t{%1, %0|%0, %1}"
2289   [(set_attr "type" "ssecvt")
2290    (set_attr "prefix" "vex")
2291    (set_attr "mode" "OI")])
2292
2293 (define_expand "sse2_cvtpd2dq"
2294   [(set (match_operand:V4SI 0 "register_operand" "")
2295         (vec_concat:V4SI
2296           (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "")]
2297                        UNSPEC_FIX_NOTRUNC)
2298           (match_dup 2)))]
2299   "TARGET_SSE2"
2300   "operands[2] = CONST0_RTX (V2SImode);")
2301
2302 (define_insn "*sse2_cvtpd2dq"
2303   [(set (match_operand:V4SI 0 "register_operand" "=x")
2304         (vec_concat:V4SI
2305           (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
2306                        UNSPEC_FIX_NOTRUNC)
2307           (match_operand:V2SI 2 "const0_operand" "")))]
2308   "TARGET_SSE2"
2309 {
2310   if (TARGET_AVX)
2311     return "vcvtpd2dq{x}\t{%1, %0|%0, %1}";
2312   else
2313     return "cvtpd2dq\t{%1, %0|%0, %1}";
2314 }
2315   [(set_attr "type" "ssecvt")
2316    (set_attr "prefix_rep" "1")
2317    (set_attr "prefix_data16" "0")
2318    (set_attr "prefix" "maybe_vex")
2319    (set_attr "mode" "TI")
2320    (set_attr "amdfam10_decode" "double")
2321    (set_attr "athlon_decode" "vector")
2322    (set_attr "bdver1_decode" "double")])
2323
2324 (define_insn "avx_cvttpd2dq256"
2325   [(set (match_operand:V4SI 0 "register_operand" "=x")
2326         (fix:V4SI (match_operand:V4DF 1 "nonimmediate_operand" "xm")))]
2327   "TARGET_AVX"
2328   "vcvttpd2dq{y}\t{%1, %0|%0, %1}"
2329   [(set_attr "type" "ssecvt")
2330    (set_attr "prefix" "vex")
2331    (set_attr "mode" "OI")])
2332
2333 (define_expand "sse2_cvttpd2dq"
2334   [(set (match_operand:V4SI 0 "register_operand" "")
2335         (vec_concat:V4SI
2336           (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" ""))
2337           (match_dup 2)))]
2338   "TARGET_SSE2"
2339   "operands[2] = CONST0_RTX (V2SImode);")
2340
2341 (define_insn "*sse2_cvttpd2dq"
2342   [(set (match_operand:V4SI 0 "register_operand" "=x")
2343         (vec_concat:V4SI
2344           (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
2345           (match_operand:V2SI 2 "const0_operand" "")))]
2346   "TARGET_SSE2"
2347 {
2348   if (TARGET_AVX)
2349     return "vcvttpd2dq{x}\t{%1, %0|%0, %1}";
2350   else
2351     return "cvttpd2dq\t{%1, %0|%0, %1}";
2352 }
2353   [(set_attr "type" "ssecvt")
2354    (set_attr "amdfam10_decode" "double")
2355    (set_attr "athlon_decode" "vector")
2356    (set_attr "bdver1_decode" "double")
2357    (set_attr "prefix" "maybe_vex")
2358    (set_attr "mode" "TI")])
2359
2360 (define_insn "sse2_cvtsd2ss"
2361   [(set (match_operand:V4SF 0 "register_operand" "=x,x,x")
2362         (vec_merge:V4SF
2363           (vec_duplicate:V4SF
2364             (float_truncate:V2SF
2365               (match_operand:V2DF 2 "nonimmediate_operand" "x,m,xm")))
2366           (match_operand:V4SF 1 "register_operand" "0,0,x")
2367           (const_int 1)))]
2368   "TARGET_SSE2"
2369   "@
2370    cvtsd2ss\t{%2, %0|%0, %2}
2371    cvtsd2ss\t{%2, %0|%0, %2}
2372    vcvtsd2ss\t{%2, %1, %0|%0, %1, %2}"
2373   [(set_attr "isa" "noavx,noavx,avx")
2374    (set_attr "type" "ssecvt")
2375    (set_attr "athlon_decode" "vector,double,*")
2376    (set_attr "amdfam10_decode" "vector,double,*")
2377    (set_attr "bdver1_decode" "direct,direct,*")
2378    (set_attr "prefix" "orig,orig,vex")
2379    (set_attr "mode" "SF")])
2380
2381 (define_insn "sse2_cvtss2sd"
2382   [(set (match_operand:V2DF 0 "register_operand" "=x,x,x")
2383         (vec_merge:V2DF
2384           (float_extend:V2DF
2385             (vec_select:V2SF
2386               (match_operand:V4SF 2 "nonimmediate_operand" "x,m,xm")
2387               (parallel [(const_int 0) (const_int 1)])))
2388           (match_operand:V2DF 1 "register_operand" "0,0,x")
2389           (const_int 1)))]
2390   "TARGET_SSE2"
2391   "@
2392    cvtss2sd\t{%2, %0|%0, %2}
2393    cvtss2sd\t{%2, %0|%0, %2}
2394    vcvtss2sd\t{%2, %1, %0|%0, %1, %2}"
2395   [(set_attr "isa" "noavx,noavx,avx")
2396    (set_attr "type" "ssecvt")
2397    (set_attr "amdfam10_decode" "vector,double,*")
2398    (set_attr "athlon_decode" "direct,direct,*")
2399    (set_attr "bdver1_decode" "direct,direct,*")
2400    (set_attr "prefix" "orig,orig,vex")
2401    (set_attr "mode" "DF")])
2402
2403 (define_insn "avx_cvtpd2ps256"
2404   [(set (match_operand:V4SF 0 "register_operand" "=x")
2405         (float_truncate:V4SF
2406           (match_operand:V4DF 1 "nonimmediate_operand" "xm")))]
2407   "TARGET_AVX"
2408   "vcvtpd2ps{y}\t{%1, %0|%0, %1}"
2409   [(set_attr "type" "ssecvt")
2410    (set_attr "prefix" "vex")
2411    (set_attr "mode" "V4SF")])
2412
2413 (define_expand "sse2_cvtpd2ps"
2414   [(set (match_operand:V4SF 0 "register_operand" "")
2415         (vec_concat:V4SF
2416           (float_truncate:V2SF
2417             (match_operand:V2DF 1 "nonimmediate_operand" ""))
2418           (match_dup 2)))]
2419   "TARGET_SSE2"
2420   "operands[2] = CONST0_RTX (V2SFmode);")
2421
2422 (define_insn "*sse2_cvtpd2ps"
2423   [(set (match_operand:V4SF 0 "register_operand" "=x")
2424         (vec_concat:V4SF
2425           (float_truncate:V2SF
2426             (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
2427           (match_operand:V2SF 2 "const0_operand" "")))]
2428   "TARGET_SSE2"
2429 {
2430   if (TARGET_AVX)
2431     return "vcvtpd2ps{x}\t{%1, %0|%0, %1}";
2432   else
2433     return "cvtpd2ps\t{%1, %0|%0, %1}";
2434 }
2435   [(set_attr "type" "ssecvt")
2436    (set_attr "amdfam10_decode" "double")
2437    (set_attr "athlon_decode" "vector")
2438    (set_attr "bdver1_decode" "double")
2439    (set_attr "prefix_data16" "1")
2440    (set_attr "prefix" "maybe_vex")
2441    (set_attr "mode" "V4SF")])
2442
2443 (define_insn "avx_cvtps2pd256"
2444   [(set (match_operand:V4DF 0 "register_operand" "=x")
2445         (float_extend:V4DF
2446           (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
2447   "TARGET_AVX"
2448   "vcvtps2pd\t{%1, %0|%0, %1}"
2449   [(set_attr "type" "ssecvt")
2450    (set_attr "prefix" "vex")
2451    (set_attr "mode" "V4DF")])
2452
2453 (define_insn "*avx_cvtps2pd256_2"
2454   [(set (match_operand:V4DF 0 "register_operand" "=x")
2455         (float_extend:V4DF
2456           (vec_select:V4SF
2457             (match_operand:V8SF 1 "nonimmediate_operand" "xm")
2458             (parallel [(const_int 0) (const_int 1)
2459                        (const_int 2) (const_int 3)]))))]
2460   "TARGET_AVX"
2461   "vcvtps2pd\t{%x1, %0|%0, %x1}"
2462   [(set_attr "type" "ssecvt")
2463    (set_attr "prefix" "vex")
2464    (set_attr "mode" "V4DF")])
2465
2466 (define_insn "sse2_cvtps2pd"
2467   [(set (match_operand:V2DF 0 "register_operand" "=x")
2468         (float_extend:V2DF
2469           (vec_select:V2SF
2470             (match_operand:V4SF 1 "nonimmediate_operand" "xm")
2471             (parallel [(const_int 0) (const_int 1)]))))]
2472   "TARGET_SSE2"
2473   "%vcvtps2pd\t{%1, %0|%0, %1}"
2474   [(set_attr "type" "ssecvt")
2475    (set_attr "amdfam10_decode" "direct")
2476    (set_attr "athlon_decode" "double")
2477    (set_attr "bdver1_decode" "double")
2478    (set_attr "prefix_data16" "0")
2479    (set_attr "prefix" "maybe_vex")
2480    (set_attr "mode" "V2DF")])
2481
2482 (define_expand "vec_unpacks_hi_v4sf"
2483   [(set (match_dup 2)
2484    (vec_select:V4SF
2485      (vec_concat:V8SF
2486        (match_dup 2)
2487        (match_operand:V4SF 1 "nonimmediate_operand" ""))
2488      (parallel [(const_int 6) (const_int 7)
2489                 (const_int 2) (const_int 3)])))
2490   (set (match_operand:V2DF 0 "register_operand" "")
2491    (float_extend:V2DF
2492      (vec_select:V2SF
2493        (match_dup 2)
2494        (parallel [(const_int 0) (const_int 1)]))))]
2495   "TARGET_SSE2"
2496   "operands[2] = gen_reg_rtx (V4SFmode);")
2497
2498 (define_expand "vec_unpacks_hi_v8sf"
2499   [(set (match_dup 2)
2500         (vec_select:V4SF
2501           (match_operand:V8SF 1 "nonimmediate_operand" "")
2502           (parallel [(const_int 4) (const_int 5)
2503                      (const_int 6) (const_int 7)])))
2504    (set (match_operand:V4DF 0 "register_operand" "")
2505         (float_extend:V4DF
2506           (match_dup 2)))]
2507   "TARGET_AVX"
2508   "operands[2] = gen_reg_rtx (V4SFmode);")
2509
2510 (define_expand "vec_unpacks_lo_v4sf"
2511   [(set (match_operand:V2DF 0 "register_operand" "")
2512         (float_extend:V2DF
2513           (vec_select:V2SF
2514             (match_operand:V4SF 1 "nonimmediate_operand" "")
2515             (parallel [(const_int 0) (const_int 1)]))))]
2516   "TARGET_SSE2")
2517
2518 (define_expand "vec_unpacks_lo_v8sf"
2519   [(set (match_operand:V4DF 0 "register_operand" "")
2520         (float_extend:V4DF
2521           (vec_select:V4SF
2522             (match_operand:V8SF 1 "nonimmediate_operand" "")
2523             (parallel [(const_int 0) (const_int 1)
2524                        (const_int 2) (const_int 3)]))))]
2525   "TARGET_AVX")
2526
2527 (define_expand "vec_unpacks_float_hi_v8hi"
2528   [(match_operand:V4SF 0 "register_operand" "")
2529    (match_operand:V8HI 1 "register_operand" "")]
2530   "TARGET_SSE2"
2531 {
2532   rtx tmp = gen_reg_rtx (V4SImode);
2533
2534   emit_insn (gen_vec_unpacks_hi_v8hi (tmp, operands[1]));
2535   emit_insn (gen_sse2_cvtdq2ps (operands[0], tmp));
2536   DONE;
2537 })
2538
2539 (define_expand "vec_unpacks_float_lo_v8hi"
2540   [(match_operand:V4SF 0 "register_operand" "")
2541    (match_operand:V8HI 1 "register_operand" "")]
2542   "TARGET_SSE2"
2543 {
2544   rtx tmp = gen_reg_rtx (V4SImode);
2545
2546   emit_insn (gen_vec_unpacks_lo_v8hi (tmp, operands[1]));
2547   emit_insn (gen_sse2_cvtdq2ps (operands[0], tmp));
2548   DONE;
2549 })
2550
2551 (define_expand "vec_unpacku_float_hi_v8hi"
2552   [(match_operand:V4SF 0 "register_operand" "")
2553    (match_operand:V8HI 1 "register_operand" "")]
2554   "TARGET_SSE2"
2555 {
2556   rtx tmp = gen_reg_rtx (V4SImode);
2557
2558   emit_insn (gen_vec_unpacku_hi_v8hi (tmp, operands[1]));
2559   emit_insn (gen_sse2_cvtdq2ps (operands[0], tmp));
2560   DONE;
2561 })
2562
2563 (define_expand "vec_unpacku_float_lo_v8hi"
2564   [(match_operand:V4SF 0 "register_operand" "")
2565    (match_operand:V8HI 1 "register_operand" "")]
2566   "TARGET_SSE2"
2567 {
2568   rtx tmp = gen_reg_rtx (V4SImode);
2569
2570   emit_insn (gen_vec_unpacku_lo_v8hi (tmp, operands[1]));
2571   emit_insn (gen_sse2_cvtdq2ps (operands[0], tmp));
2572   DONE;
2573 })
2574
2575 (define_expand "vec_unpacks_float_hi_v4si"
2576   [(set (match_dup 2)
2577         (vec_select:V4SI
2578           (match_operand:V4SI 1 "nonimmediate_operand" "")
2579           (parallel [(const_int 2) (const_int 3)
2580                      (const_int 2) (const_int 3)])))
2581    (set (match_operand:V2DF 0 "register_operand" "")
2582         (float:V2DF
2583           (vec_select:V2SI
2584           (match_dup 2)
2585             (parallel [(const_int 0) (const_int 1)]))))]
2586   "TARGET_SSE2"
2587   "operands[2] = gen_reg_rtx (V4SImode);")
2588
2589 (define_expand "vec_unpacks_float_lo_v4si"
2590   [(set (match_operand:V2DF 0 "register_operand" "")
2591         (float:V2DF
2592           (vec_select:V2SI
2593             (match_operand:V4SI 1 "nonimmediate_operand" "")
2594             (parallel [(const_int 0) (const_int 1)]))))]
2595   "TARGET_SSE2")
2596
2597 (define_expand "vec_unpacks_float_hi_v8si"
2598   [(set (match_dup 2)
2599         (vec_select:V4SI
2600           (match_operand:V8SI 1 "nonimmediate_operand" "")
2601           (parallel [(const_int 4) (const_int 5)
2602                      (const_int 6) (const_int 7)])))
2603    (set (match_operand:V4DF 0 "register_operand" "")
2604         (float:V4DF
2605           (match_dup 2)))]
2606   "TARGET_AVX"
2607   "operands[2] = gen_reg_rtx (V4SImode);")
2608
2609 (define_expand "vec_unpacks_float_lo_v8si"
2610   [(set (match_operand:V4DF 0 "register_operand" "")
2611         (float:V4DF
2612           (vec_select:V4SI
2613             (match_operand:V8SI 1 "nonimmediate_operand" "")
2614             (parallel [(const_int 0) (const_int 1)
2615                        (const_int 2) (const_int 3)]))))]
2616   "TARGET_AVX")
2617
2618 (define_expand "vec_unpacku_float_hi_v4si"
2619   [(set (match_dup 5)
2620         (vec_select:V4SI
2621           (match_operand:V4SI 1 "nonimmediate_operand" "")
2622           (parallel [(const_int 2) (const_int 3)
2623                      (const_int 2) (const_int 3)])))
2624    (set (match_dup 6)
2625         (float:V2DF
2626           (vec_select:V2SI
2627           (match_dup 5)
2628             (parallel [(const_int 0) (const_int 1)]))))
2629    (set (match_dup 7)
2630         (lt:V2DF (match_dup 6) (match_dup 3)))
2631    (set (match_dup 8)
2632         (and:V2DF (match_dup 7) (match_dup 4)))
2633    (set (match_operand:V2DF 0 "register_operand" "")
2634         (plus:V2DF (match_dup 6) (match_dup 8)))]
2635   "TARGET_SSE2"
2636 {
2637   REAL_VALUE_TYPE TWO32r;
2638   rtx x;
2639   int i;
2640
2641   real_ldexp (&TWO32r, &dconst1, 32);
2642   x = const_double_from_real_value (TWO32r, DFmode);
2643
2644   operands[3] = force_reg (V2DFmode, CONST0_RTX (V2DFmode));
2645   operands[4] = force_reg (V2DFmode,
2646                            ix86_build_const_vector (V2DFmode, 1, x));
2647
2648   operands[5] = gen_reg_rtx (V4SImode);
2649
2650   for (i = 6; i < 9; i++)
2651     operands[i] = gen_reg_rtx (V2DFmode);
2652 })
2653
2654 (define_expand "vec_unpacku_float_lo_v4si"
2655   [(set (match_dup 5)
2656         (float:V2DF
2657           (vec_select:V2SI
2658             (match_operand:V4SI 1 "nonimmediate_operand" "")
2659             (parallel [(const_int 0) (const_int 1)]))))
2660    (set (match_dup 6)
2661         (lt:V2DF (match_dup 5) (match_dup 3)))
2662    (set (match_dup 7)
2663         (and:V2DF (match_dup 6) (match_dup 4)))
2664    (set (match_operand:V2DF 0 "register_operand" "")
2665         (plus:V2DF (match_dup 5) (match_dup 7)))]
2666   "TARGET_SSE2"
2667 {
2668   REAL_VALUE_TYPE TWO32r;
2669   rtx x;
2670   int i;
2671
2672   real_ldexp (&TWO32r, &dconst1, 32);
2673   x = const_double_from_real_value (TWO32r, DFmode);
2674
2675   operands[3] = force_reg (V2DFmode, CONST0_RTX (V2DFmode));
2676   operands[4] = force_reg (V2DFmode,
2677                            ix86_build_const_vector (V2DFmode, 1, x));
2678
2679   for (i = 5; i < 8; i++)
2680     operands[i] = gen_reg_rtx (V2DFmode);
2681 })
2682
2683 (define_expand "vec_pack_trunc_v4df"
2684   [(set (match_dup 3)
2685         (float_truncate:V4SF
2686           (match_operand:V4DF 1 "nonimmediate_operand" "")))
2687    (set (match_dup 4)
2688         (float_truncate:V4SF
2689           (match_operand:V4DF 2 "nonimmediate_operand" "")))
2690    (set (match_operand:V8SF 0 "register_operand" "")
2691         (vec_concat:V8SF
2692           (match_dup 3)
2693           (match_dup 4)))]
2694   "TARGET_AVX"
2695 {
2696   operands[3] = gen_reg_rtx (V4SFmode);
2697   operands[4] = gen_reg_rtx (V4SFmode);
2698 })
2699
2700 (define_expand "vec_pack_trunc_v2df"
2701   [(match_operand:V4SF 0 "register_operand" "")
2702    (match_operand:V2DF 1 "nonimmediate_operand" "")
2703    (match_operand:V2DF 2 "nonimmediate_operand" "")]
2704   "TARGET_SSE2"
2705 {
2706   rtx r1, r2;
2707
2708   r1 = gen_reg_rtx (V4SFmode);
2709   r2 = gen_reg_rtx (V4SFmode);
2710
2711   emit_insn (gen_sse2_cvtpd2ps (r1, operands[1]));
2712   emit_insn (gen_sse2_cvtpd2ps (r2, operands[2]));
2713   emit_insn (gen_sse_movlhps (operands[0], r1, r2));
2714   DONE;
2715 })
2716
2717 (define_expand "vec_pack_sfix_trunc_v2df"
2718   [(match_operand:V4SI 0 "register_operand" "")
2719    (match_operand:V2DF 1 "nonimmediate_operand" "")
2720    (match_operand:V2DF 2 "nonimmediate_operand" "")]
2721   "TARGET_SSE2"
2722 {
2723   rtx r1, r2;
2724
2725   r1 = gen_reg_rtx (V4SImode);
2726   r2 = gen_reg_rtx (V4SImode);
2727
2728   emit_insn (gen_sse2_cvttpd2dq (r1, operands[1]));
2729   emit_insn (gen_sse2_cvttpd2dq (r2, operands[2]));
2730   emit_insn (gen_vec_interleave_lowv2di (gen_lowpart (V2DImode, operands[0]),
2731                                          gen_lowpart (V2DImode, r1),
2732                                          gen_lowpart (V2DImode, r2)));
2733   DONE;
2734 })
2735
2736 (define_expand "vec_pack_sfix_v2df"
2737   [(match_operand:V4SI 0 "register_operand" "")
2738    (match_operand:V2DF 1 "nonimmediate_operand" "")
2739    (match_operand:V2DF 2 "nonimmediate_operand" "")]
2740   "TARGET_SSE2"
2741 {
2742   rtx r1, r2;
2743
2744   r1 = gen_reg_rtx (V4SImode);
2745   r2 = gen_reg_rtx (V4SImode);
2746
2747   emit_insn (gen_sse2_cvtpd2dq (r1, operands[1]));
2748   emit_insn (gen_sse2_cvtpd2dq (r2, operands[2]));
2749   emit_insn (gen_vec_interleave_lowv2di (gen_lowpart (V2DImode, operands[0]),
2750                                          gen_lowpart (V2DImode, r1),
2751                                          gen_lowpart (V2DImode, r2)));
2752   DONE;
2753 })
2754
2755 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2756 ;;
2757 ;; Parallel single-precision floating point element swizzling
2758 ;;
2759 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2760
2761 (define_expand "sse_movhlps_exp"
2762   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
2763         (vec_select:V4SF
2764           (vec_concat:V8SF
2765             (match_operand:V4SF 1 "nonimmediate_operand" "")
2766             (match_operand:V4SF 2 "nonimmediate_operand" ""))
2767           (parallel [(const_int 6)
2768                      (const_int 7)
2769                      (const_int 2)
2770                      (const_int 3)])))]
2771   "TARGET_SSE"
2772 {
2773   rtx dst = ix86_fixup_binary_operands (UNKNOWN, V4SFmode, operands);
2774
2775   emit_insn (gen_sse_movhlps (dst, operands[1], operands[2]));
2776
2777   /* Fix up the destination if needed.  */
2778   if (dst != operands[0])
2779     emit_move_insn (operands[0], dst);
2780
2781   DONE;
2782 })
2783
2784 (define_insn "sse_movhlps"
2785   [(set (match_operand:V4SF 0 "nonimmediate_operand"     "=x,x,x,x,m")
2786         (vec_select:V4SF
2787           (vec_concat:V8SF
2788             (match_operand:V4SF 1 "nonimmediate_operand" " 0,x,0,x,0")
2789             (match_operand:V4SF 2 "nonimmediate_operand" " x,x,o,o,x"))
2790           (parallel [(const_int 6)
2791                      (const_int 7)
2792                      (const_int 2)
2793                      (const_int 3)])))]
2794   "TARGET_SSE && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
2795   "@
2796    movhlps\t{%2, %0|%0, %2}
2797    vmovhlps\t{%2, %1, %0|%0, %1, %2}
2798    movlps\t{%H2, %0|%0, %H2}
2799    vmovlps\t{%H2, %1, %0|%0, %1, %H2}
2800    %vmovhps\t{%2, %0|%0, %2}"
2801   [(set_attr "isa" "noavx,avx,noavx,avx,*")
2802    (set_attr "type" "ssemov")
2803    (set_attr "prefix" "orig,vex,orig,vex,maybe_vex")
2804    (set_attr "mode" "V4SF,V4SF,V2SF,V2SF,V2SF")])
2805
2806 (define_expand "sse_movlhps_exp"
2807   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
2808         (vec_select:V4SF
2809           (vec_concat:V8SF
2810             (match_operand:V4SF 1 "nonimmediate_operand" "")
2811             (match_operand:V4SF 2 "nonimmediate_operand" ""))
2812           (parallel [(const_int 0)
2813                      (const_int 1)
2814                      (const_int 4)
2815                      (const_int 5)])))]
2816   "TARGET_SSE"
2817 {
2818   rtx dst = ix86_fixup_binary_operands (UNKNOWN, V4SFmode, operands);
2819
2820   emit_insn (gen_sse_movlhps (dst, operands[1], operands[2]));
2821
2822   /* Fix up the destination if needed.  */
2823   if (dst != operands[0])
2824     emit_move_insn (operands[0], dst);
2825
2826   DONE;
2827 })
2828
2829 (define_insn "sse_movlhps"
2830   [(set (match_operand:V4SF 0 "nonimmediate_operand"     "=x,x,x,x,o")
2831         (vec_select:V4SF
2832           (vec_concat:V8SF
2833             (match_operand:V4SF 1 "nonimmediate_operand" " 0,x,0,x,0")
2834             (match_operand:V4SF 2 "nonimmediate_operand" " x,x,m,x,x"))
2835           (parallel [(const_int 0)
2836                      (const_int 1)
2837                      (const_int 4)
2838                      (const_int 5)])))]
2839   "TARGET_SSE && ix86_binary_operator_ok (UNKNOWN, V4SFmode, operands)"
2840   "@
2841    movlhps\t{%2, %0|%0, %2}
2842    vmovlhps\t{%2, %1, %0|%0, %1, %2}
2843    movhps\t{%2, %0|%0, %2}
2844    vmovhps\t{%2, %1, %0|%0, %1, %2}
2845    %vmovlps\t{%2, %H0|%H0, %2}"
2846   [(set_attr "isa" "noavx,avx,noavx,avx,*")
2847    (set_attr "type" "ssemov")
2848    (set_attr "prefix" "orig,vex,orig,vex,maybe_vex")
2849    (set_attr "mode" "V4SF,V4SF,V2SF,V2SF,V2SF")])
2850
2851 ;; Recall that the 256-bit unpck insns only shuffle within their lanes.
2852 (define_insn "avx_unpckhps256"
2853   [(set (match_operand:V8SF 0 "register_operand" "=x")
2854         (vec_select:V8SF
2855           (vec_concat:V16SF
2856             (match_operand:V8SF 1 "register_operand" "x")
2857             (match_operand:V8SF 2 "nonimmediate_operand" "xm"))
2858           (parallel [(const_int 2) (const_int 10)
2859                      (const_int 3) (const_int 11)
2860                      (const_int 6) (const_int 14)
2861                      (const_int 7) (const_int 15)])))]
2862   "TARGET_AVX"
2863   "vunpckhps\t{%2, %1, %0|%0, %1, %2}"
2864   [(set_attr "type" "sselog")
2865    (set_attr "prefix" "vex")
2866    (set_attr "mode" "V8SF")])
2867
2868 (define_expand "vec_interleave_highv8sf"
2869   [(set (match_dup 3)
2870         (vec_select:V8SF
2871           (vec_concat:V16SF
2872             (match_operand:V8SF 1 "register_operand" "x")
2873             (match_operand:V8SF 2 "nonimmediate_operand" "xm"))
2874           (parallel [(const_int 0) (const_int 8)
2875                      (const_int 1) (const_int 9)
2876                      (const_int 4) (const_int 12)
2877                      (const_int 5) (const_int 13)])))
2878    (set (match_dup 4)
2879         (vec_select:V8SF
2880           (vec_concat:V16SF
2881             (match_dup 1)
2882             (match_dup 2))
2883           (parallel [(const_int 2) (const_int 10)
2884                      (const_int 3) (const_int 11)
2885                      (const_int 6) (const_int 14)
2886                      (const_int 7) (const_int 15)])))
2887    (set (match_operand:V8SF 0 "register_operand" "")
2888         (vec_select:V8SF
2889           (vec_concat:V16SF
2890             (match_dup 3)
2891             (match_dup 4))
2892           (parallel [(const_int 4) (const_int 5)
2893                      (const_int 6) (const_int 7)
2894                      (const_int 12) (const_int 13)
2895                      (const_int 14) (const_int 15)])))]
2896  "TARGET_AVX"
2897 {
2898   operands[3] = gen_reg_rtx (V8SFmode);
2899   operands[4] = gen_reg_rtx (V8SFmode);
2900 })
2901
2902 (define_insn "vec_interleave_highv4sf"
2903   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
2904         (vec_select:V4SF
2905           (vec_concat:V8SF
2906             (match_operand:V4SF 1 "register_operand" "0,x")
2907             (match_operand:V4SF 2 "nonimmediate_operand" "xm,xm"))
2908           (parallel [(const_int 2) (const_int 6)
2909                      (const_int 3) (const_int 7)])))]
2910   "TARGET_SSE"
2911   "@
2912    unpckhps\t{%2, %0|%0, %2}
2913    vunpckhps\t{%2, %1, %0|%0, %1, %2}"
2914   [(set_attr "isa" "noavx,avx")
2915    (set_attr "type" "sselog")
2916    (set_attr "prefix" "orig,vex")
2917    (set_attr "mode" "V4SF")])
2918
2919 ;; Recall that the 256-bit unpck insns only shuffle within their lanes.
2920 (define_insn "avx_unpcklps256"
2921   [(set (match_operand:V8SF 0 "register_operand" "=x")
2922         (vec_select:V8SF
2923           (vec_concat:V16SF
2924             (match_operand:V8SF 1 "register_operand" "x")
2925             (match_operand:V8SF 2 "nonimmediate_operand" "xm"))
2926           (parallel [(const_int 0) (const_int 8)
2927                      (const_int 1) (const_int 9)
2928                      (const_int 4) (const_int 12)
2929                      (const_int 5) (const_int 13)])))]
2930   "TARGET_AVX"
2931   "vunpcklps\t{%2, %1, %0|%0, %1, %2}"
2932   [(set_attr "type" "sselog")
2933    (set_attr "prefix" "vex")
2934    (set_attr "mode" "V8SF")])
2935
2936 (define_expand "vec_interleave_lowv8sf"
2937   [(set (match_dup 3)
2938         (vec_select:V8SF
2939           (vec_concat:V16SF
2940             (match_operand:V8SF 1 "register_operand" "x")
2941             (match_operand:V8SF 2 "nonimmediate_operand" "xm"))
2942           (parallel [(const_int 0) (const_int 8)
2943                      (const_int 1) (const_int 9)
2944                      (const_int 4) (const_int 12)
2945                      (const_int 5) (const_int 13)])))
2946    (set (match_dup 4)
2947         (vec_select:V8SF
2948           (vec_concat:V16SF
2949             (match_dup 1)
2950             (match_dup 2))
2951           (parallel [(const_int 2) (const_int 10)
2952                      (const_int 3) (const_int 11)
2953                      (const_int 6) (const_int 14)
2954                      (const_int 7) (const_int 15)])))
2955    (set (match_operand:V8SF 0 "register_operand" "")
2956         (vec_select:V8SF
2957           (vec_concat:V16SF
2958             (match_dup 3)
2959             (match_dup 4))
2960           (parallel [(const_int 0) (const_int 1)
2961                      (const_int 2) (const_int 3)
2962                      (const_int 8) (const_int 9)
2963                      (const_int 10) (const_int 11)])))]
2964  "TARGET_AVX"
2965 {
2966   operands[3] = gen_reg_rtx (V8SFmode);
2967   operands[4] = gen_reg_rtx (V8SFmode);
2968 })
2969
2970 (define_insn "vec_interleave_lowv4sf"
2971   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
2972         (vec_select:V4SF
2973           (vec_concat:V8SF
2974             (match_operand:V4SF 1 "register_operand" "0,x")
2975             (match_operand:V4SF 2 "nonimmediate_operand" "xm,xm"))
2976           (parallel [(const_int 0) (const_int 4)
2977                      (const_int 1) (const_int 5)])))]
2978   "TARGET_SSE"
2979   "@
2980    unpcklps\t{%2, %0|%0, %2}
2981    vunpcklps\t{%2, %1, %0|%0, %1, %2}"
2982   [(set_attr "isa" "noavx,avx")
2983    (set_attr "type" "sselog")
2984    (set_attr "prefix" "orig,vex")
2985    (set_attr "mode" "V4SF")])
2986
2987 ;; These are modeled with the same vec_concat as the others so that we
2988 ;; capture users of shufps that can use the new instructions
2989 (define_insn "avx_movshdup256"
2990   [(set (match_operand:V8SF 0 "register_operand" "=x")
2991         (vec_select:V8SF
2992           (vec_concat:V16SF
2993             (match_operand:V8SF 1 "nonimmediate_operand" "xm")
2994             (match_dup 1))
2995           (parallel [(const_int 1) (const_int 1)
2996                      (const_int 3) (const_int 3)
2997                      (const_int 5) (const_int 5)
2998                      (const_int 7) (const_int 7)])))]
2999   "TARGET_AVX"
3000   "vmovshdup\t{%1, %0|%0, %1}"
3001   [(set_attr "type" "sse")
3002    (set_attr "prefix" "vex")
3003    (set_attr "mode" "V8SF")])
3004
3005 (define_insn "sse3_movshdup"
3006   [(set (match_operand:V4SF 0 "register_operand" "=x")
3007         (vec_select:V4SF
3008           (vec_concat:V8SF
3009             (match_operand:V4SF 1 "nonimmediate_operand" "xm")
3010             (match_dup 1))
3011           (parallel [(const_int 1)
3012                      (const_int 1)
3013                      (const_int 7)
3014                      (const_int 7)])))]
3015   "TARGET_SSE3"
3016   "%vmovshdup\t{%1, %0|%0, %1}"
3017   [(set_attr "type" "sse")
3018    (set_attr "prefix_rep" "1")
3019    (set_attr "prefix" "maybe_vex")
3020    (set_attr "mode" "V4SF")])
3021
3022 (define_insn "avx_movsldup256"
3023   [(set (match_operand:V8SF 0 "register_operand" "=x")
3024         (vec_select:V8SF
3025           (vec_concat:V16SF
3026             (match_operand:V8SF 1 "nonimmediate_operand" "xm")
3027             (match_dup 1))
3028           (parallel [(const_int 0) (const_int 0)
3029                      (const_int 2) (const_int 2)
3030                      (const_int 4) (const_int 4)
3031                      (const_int 6) (const_int 6)])))]
3032   "TARGET_AVX"
3033   "vmovsldup\t{%1, %0|%0, %1}"
3034   [(set_attr "type" "sse")
3035    (set_attr "prefix" "vex")
3036    (set_attr "mode" "V8SF")])
3037
3038 (define_insn "sse3_movsldup"
3039   [(set (match_operand:V4SF 0 "register_operand" "=x")
3040         (vec_select:V4SF
3041           (vec_concat:V8SF
3042             (match_operand:V4SF 1 "nonimmediate_operand" "xm")
3043             (match_dup 1))
3044           (parallel [(const_int 0)
3045                      (const_int 0)
3046                      (const_int 6)
3047                      (const_int 6)])))]
3048   "TARGET_SSE3"
3049   "%vmovsldup\t{%1, %0|%0, %1}"
3050   [(set_attr "type" "sse")
3051    (set_attr "prefix_rep" "1")
3052    (set_attr "prefix" "maybe_vex")
3053    (set_attr "mode" "V4SF")])
3054
3055 (define_expand "avx_shufps256"
3056   [(match_operand:V8SF 0 "register_operand" "")
3057    (match_operand:V8SF 1 "register_operand" "")
3058    (match_operand:V8SF 2 "nonimmediate_operand" "")
3059    (match_operand:SI 3 "const_int_operand" "")]
3060   "TARGET_AVX"
3061 {
3062   int mask = INTVAL (operands[3]);
3063   emit_insn (gen_avx_shufps256_1 (operands[0], operands[1], operands[2],
3064                                   GEN_INT ((mask >> 0) & 3),
3065                                   GEN_INT ((mask >> 2) & 3),
3066                                   GEN_INT (((mask >> 4) & 3) + 8),
3067                                   GEN_INT (((mask >> 6) & 3) + 8),
3068                                   GEN_INT (((mask >> 0) & 3) + 4),
3069                                   GEN_INT (((mask >> 2) & 3) + 4),
3070                                   GEN_INT (((mask >> 4) & 3) + 12),
3071                                   GEN_INT (((mask >> 6) & 3) + 12)));
3072   DONE;
3073 })
3074
3075 ;; One bit in mask selects 2 elements.
3076 (define_insn "avx_shufps256_1"
3077   [(set (match_operand:V8SF 0 "register_operand" "=x")
3078         (vec_select:V8SF
3079           (vec_concat:V16SF
3080             (match_operand:V8SF 1 "register_operand" "x")
3081             (match_operand:V8SF 2 "nonimmediate_operand" "xm"))
3082           (parallel [(match_operand 3  "const_0_to_3_operand"   "")
3083                      (match_operand 4  "const_0_to_3_operand"   "")
3084                      (match_operand 5  "const_8_to_11_operand"  "")
3085                      (match_operand 6  "const_8_to_11_operand"  "")
3086                      (match_operand 7  "const_4_to_7_operand"   "")
3087                      (match_operand 8  "const_4_to_7_operand"   "")
3088                      (match_operand 9  "const_12_to_15_operand" "")
3089                      (match_operand 10 "const_12_to_15_operand" "")])))]
3090   "TARGET_AVX
3091    && (INTVAL (operands[3]) == (INTVAL (operands[7]) - 4)
3092        && INTVAL (operands[4]) == (INTVAL (operands[8]) - 4)
3093        && INTVAL (operands[5]) == (INTVAL (operands[9]) - 4)
3094        && INTVAL (operands[6]) == (INTVAL (operands[10]) - 4))"
3095 {
3096   int mask;
3097   mask = INTVAL (operands[3]);
3098   mask |= INTVAL (operands[4]) << 2;
3099   mask |= (INTVAL (operands[5]) - 8) << 4;
3100   mask |= (INTVAL (operands[6]) - 8) << 6;
3101   operands[3] = GEN_INT (mask);
3102
3103   return "vshufps\t{%3, %2, %1, %0|%0, %1, %2, %3}";
3104 }
3105   [(set_attr "type" "sselog")
3106    (set_attr "length_immediate" "1")
3107    (set_attr "prefix" "vex")
3108    (set_attr "mode" "V8SF")])
3109
3110 (define_expand "sse_shufps"
3111   [(match_operand:V4SF 0 "register_operand" "")
3112    (match_operand:V4SF 1 "register_operand" "")
3113    (match_operand:V4SF 2 "nonimmediate_operand" "")
3114    (match_operand:SI 3 "const_int_operand" "")]
3115   "TARGET_SSE"
3116 {
3117   int mask = INTVAL (operands[3]);
3118   emit_insn (gen_sse_shufps_v4sf (operands[0], operands[1], operands[2],
3119                                GEN_INT ((mask >> 0) & 3),
3120                                GEN_INT ((mask >> 2) & 3),
3121                                GEN_INT (((mask >> 4) & 3) + 4),
3122                                GEN_INT (((mask >> 6) & 3) + 4)));
3123   DONE;
3124 })
3125
3126 (define_insn "sse_shufps_<mode>"
3127   [(set (match_operand:VI4F_128 0 "register_operand" "=x,x")
3128         (vec_select:VI4F_128
3129           (vec_concat:<ssedoublevecmode>
3130             (match_operand:VI4F_128 1 "register_operand" "0,x")
3131             (match_operand:VI4F_128 2 "nonimmediate_operand" "xm,xm"))
3132           (parallel [(match_operand 3 "const_0_to_3_operand" "")
3133                      (match_operand 4 "const_0_to_3_operand" "")
3134                      (match_operand 5 "const_4_to_7_operand" "")
3135                      (match_operand 6 "const_4_to_7_operand" "")])))]
3136   "TARGET_SSE"
3137 {
3138   int mask = 0;
3139   mask |= INTVAL (operands[3]) << 0;
3140   mask |= INTVAL (operands[4]) << 2;
3141   mask |= (INTVAL (operands[5]) - 4) << 4;
3142   mask |= (INTVAL (operands[6]) - 4) << 6;
3143   operands[3] = GEN_INT (mask);
3144
3145   switch (which_alternative)
3146     {
3147     case 0:
3148       return "shufps\t{%3, %2, %0|%0, %2, %3}";
3149     case 1:
3150       return "vshufps\t{%3, %2, %1, %0|%0, %1, %2, %3}";
3151     default:
3152       gcc_unreachable ();
3153     }
3154 }
3155   [(set_attr "isa" "noavx,avx")
3156    (set_attr "type" "sselog")
3157    (set_attr "length_immediate" "1")
3158    (set_attr "prefix" "orig,vex")
3159    (set_attr "mode" "V4SF")])
3160
3161 (define_insn "sse_storehps"
3162   [(set (match_operand:V2SF 0 "nonimmediate_operand" "=m,x,x")
3163         (vec_select:V2SF
3164           (match_operand:V4SF 1 "nonimmediate_operand" "x,x,o")
3165           (parallel [(const_int 2) (const_int 3)])))]
3166   "TARGET_SSE"
3167   "@
3168    %vmovhps\t{%1, %0|%0, %1}
3169    %vmovhlps\t{%1, %d0|%d0, %1}
3170    %vmovlps\t{%H1, %d0|%d0, %H1}"
3171   [(set_attr "type" "ssemov")
3172    (set_attr "prefix" "maybe_vex")
3173    (set_attr "mode" "V2SF,V4SF,V2SF")])
3174
3175 (define_expand "sse_loadhps_exp"
3176   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
3177         (vec_concat:V4SF
3178           (vec_select:V2SF
3179             (match_operand:V4SF 1 "nonimmediate_operand" "")
3180             (parallel [(const_int 0) (const_int 1)]))
3181           (match_operand:V2SF 2 "nonimmediate_operand" "")))]
3182   "TARGET_SSE"
3183 {
3184   rtx dst = ix86_fixup_binary_operands (UNKNOWN, V4SFmode, operands);
3185
3186   emit_insn (gen_sse_loadhps (dst, operands[1], operands[2]));
3187
3188   /* Fix up the destination if needed.  */
3189   if (dst != operands[0])
3190     emit_move_insn (operands[0], dst);
3191
3192   DONE;
3193 })
3194
3195 (define_insn "sse_loadhps"
3196   [(set (match_operand:V4SF 0 "nonimmediate_operand"     "=x,x,x,x,o")
3197         (vec_concat:V4SF
3198           (vec_select:V2SF
3199             (match_operand:V4SF 1 "nonimmediate_operand" " 0,x,0,x,0")
3200             (parallel [(const_int 0) (const_int 1)]))
3201           (match_operand:V2SF 2 "nonimmediate_operand"   " m,m,x,x,x")))]
3202   "TARGET_SSE"
3203   "@
3204    movhps\t{%2, %0|%0, %2}
3205    vmovhps\t{%2, %1, %0|%0, %1, %2}
3206    movlhps\t{%2, %0|%0, %2}
3207    vmovlhps\t{%2, %1, %0|%0, %1, %2}
3208    %vmovlps\t{%2, %H0|%H0, %2}"
3209   [(set_attr "isa" "noavx,avx,noavx,avx,*")
3210    (set_attr "type" "ssemov")
3211    (set_attr "prefix" "orig,vex,orig,vex,maybe_vex")
3212    (set_attr "mode" "V2SF,V2SF,V4SF,V4SF,V2SF")])
3213
3214 (define_insn "sse_storelps"
3215   [(set (match_operand:V2SF 0 "nonimmediate_operand"   "=m,x,x")
3216         (vec_select:V2SF
3217           (match_operand:V4SF 1 "nonimmediate_operand" " x,x,m")
3218           (parallel [(const_int 0) (const_int 1)])))]
3219   "TARGET_SSE"
3220   "@
3221    %vmovlps\t{%1, %0|%0, %1}
3222    %vmovaps\t{%1, %0|%0, %1}
3223    %vmovlps\t{%1, %d0|%d0, %1}"
3224   [(set_attr "type" "ssemov")
3225    (set_attr "prefix" "maybe_vex")
3226    (set_attr "mode" "V2SF,V4SF,V2SF")])
3227
3228 (define_expand "sse_loadlps_exp"
3229   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
3230         (vec_concat:V4SF
3231           (match_operand:V2SF 2 "nonimmediate_operand" "")
3232           (vec_select:V2SF
3233             (match_operand:V4SF 1 "nonimmediate_operand" "")
3234             (parallel [(const_int 2) (const_int 3)]))))]
3235   "TARGET_SSE"
3236 {
3237   rtx dst = ix86_fixup_binary_operands (UNKNOWN, V4SFmode, operands);
3238
3239   emit_insn (gen_sse_loadlps (dst, operands[1], operands[2]));
3240
3241   /* Fix up the destination if needed.  */
3242   if (dst != operands[0])
3243     emit_move_insn (operands[0], dst);
3244
3245   DONE;
3246 })
3247
3248 (define_insn "sse_loadlps"
3249   [(set (match_operand:V4SF 0 "nonimmediate_operand"     "=x,x,x,x,m")
3250         (vec_concat:V4SF
3251           (match_operand:V2SF 2 "nonimmediate_operand"   " 0,x,m,x,x")
3252           (vec_select:V2SF
3253             (match_operand:V4SF 1 "nonimmediate_operand" " x,x,0,x,0")
3254             (parallel [(const_int 2) (const_int 3)]))))]
3255   "TARGET_SSE"
3256   "@
3257    shufps\t{$0xe4, %1, %0|%0, %1, 0xe4}
3258    vshufps\t{$0xe4, %1, %2, %0|%0, %2, %1, 0xe4}
3259    movlps\t{%2, %0|%0, %2}
3260    vmovlps\t{%2, %1, %0|%0, %1, %2}
3261    %vmovlps\t{%2, %0|%0, %2}"
3262   [(set_attr "isa" "noavx,avx,noavx,avx,*")
3263    (set_attr "type" "sselog,sselog,ssemov,ssemov,ssemov")
3264    (set_attr "length_immediate" "1,1,*,*,*")
3265    (set_attr "prefix" "orig,vex,orig,vex,maybe_vex")
3266    (set_attr "mode" "V4SF,V4SF,V2SF,V2SF,V2SF")])
3267
3268 (define_insn "sse_movss"
3269   [(set (match_operand:V4SF 0 "register_operand"   "=x,x")
3270         (vec_merge:V4SF
3271           (match_operand:V4SF 2 "register_operand" " x,x")
3272           (match_operand:V4SF 1 "register_operand" " 0,x")
3273           (const_int 1)))]
3274   "TARGET_SSE"
3275   "@
3276    movss\t{%2, %0|%0, %2}
3277    vmovss\t{%2, %1, %0|%0, %1, %2}"
3278   [(set_attr "isa" "noavx,avx")
3279    (set_attr "type" "ssemov")
3280    (set_attr "prefix" "orig,vex")
3281    (set_attr "mode" "SF")])
3282
3283 (define_expand "vec_dupv4sf"
3284   [(set (match_operand:V4SF 0 "register_operand" "")
3285         (vec_duplicate:V4SF
3286           (match_operand:SF 1 "nonimmediate_operand" "")))]
3287   "TARGET_SSE"
3288 {
3289   if (!TARGET_AVX)
3290     operands[1] = force_reg (SFmode, operands[1]);
3291 })
3292
3293 (define_insn "*vec_dupv4sf_avx"
3294   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
3295         (vec_duplicate:V4SF
3296           (match_operand:SF 1 "nonimmediate_operand" "x,m")))]
3297   "TARGET_AVX"
3298   "@
3299    vshufps\t{$0, %1, %1, %0|%0, %1, %1, 0}
3300    vbroadcastss\t{%1, %0|%0, %1}"
3301   [(set_attr "type" "sselog1,ssemov")
3302    (set_attr "length_immediate" "1,0")
3303    (set_attr "prefix_extra" "0,1")
3304    (set_attr "prefix" "vex")
3305    (set_attr "mode" "V4SF")])
3306
3307 (define_insn "*vec_dupv4sf"
3308   [(set (match_operand:V4SF 0 "register_operand" "=x")
3309         (vec_duplicate:V4SF
3310           (match_operand:SF 1 "register_operand" "0")))]
3311   "TARGET_SSE"
3312   "shufps\t{$0, %0, %0|%0, %0, 0}"
3313   [(set_attr "type" "sselog1")
3314    (set_attr "length_immediate" "1")
3315    (set_attr "mode" "V4SF")])
3316
3317 ;; Although insertps takes register source, we prefer
3318 ;; unpcklps with register source since it is shorter.
3319 (define_insn "*vec_concatv2sf_sse4_1"
3320   [(set (match_operand:V2SF 0 "register_operand"     "=x,x,x,x,x,*y ,*y")
3321         (vec_concat:V2SF
3322           (match_operand:SF 1 "nonimmediate_operand" " 0,x,0,x,m, 0 , m")
3323           (match_operand:SF 2 "vector_move_operand"  " x,x,m,m,C,*ym, C")))]
3324   "TARGET_SSE4_1"
3325   "@
3326    unpcklps\t{%2, %0|%0, %2}
3327    vunpcklps\t{%2, %1, %0|%0, %1, %2}
3328    insertps\t{$0x10, %2, %0|%0, %2, 0x10}
3329    vinsertps\t{$0x10, %2, %1, %0|%0, %1, %2, 0x10}
3330    %vmovss\t{%1, %0|%0, %1}
3331    punpckldq\t{%2, %0|%0, %2}
3332    movd\t{%1, %0|%0, %1}"
3333   [(set_attr "isa" "noavx,avx,noavx,avx,*,*,*")
3334    (set_attr "type" "sselog,sselog,sselog,sselog,ssemov,mmxcvt,mmxmov")
3335    (set_attr "prefix_data16" "*,*,1,*,*,*,*")
3336    (set_attr "prefix_extra" "*,*,1,1,*,*,*")
3337    (set_attr "length_immediate" "*,*,1,1,*,*,*")
3338    (set_attr "prefix" "orig,vex,orig,vex,maybe_vex,orig,orig")
3339    (set_attr "mode" "V4SF,V4SF,V4SF,V4SF,SF,DI,DI")])
3340
3341 ;; ??? In theory we can match memory for the MMX alternative, but allowing
3342 ;; nonimmediate_operand for operand 2 and *not* allowing memory for the SSE
3343 ;; alternatives pretty much forces the MMX alternative to be chosen.
3344 (define_insn "*vec_concatv2sf_sse"
3345   [(set (match_operand:V2SF 0 "register_operand"     "=x,x,*y,*y")
3346         (vec_concat:V2SF
3347           (match_operand:SF 1 "nonimmediate_operand" " 0,m, 0, m")
3348           (match_operand:SF 2 "reg_or_0_operand"     " x,C,*y, C")))]
3349   "TARGET_SSE"
3350   "@
3351    unpcklps\t{%2, %0|%0, %2}
3352    movss\t{%1, %0|%0, %1}
3353    punpckldq\t{%2, %0|%0, %2}
3354    movd\t{%1, %0|%0, %1}"
3355   [(set_attr "type" "sselog,ssemov,mmxcvt,mmxmov")
3356    (set_attr "mode" "V4SF,SF,DI,DI")])
3357
3358 (define_insn "*vec_concatv4sf"
3359   [(set (match_operand:V4SF 0 "register_operand"       "=x,x,x,x")
3360         (vec_concat:V4SF
3361           (match_operand:V2SF 1 "register_operand"     " 0,x,0,x")
3362           (match_operand:V2SF 2 "nonimmediate_operand" " x,x,m,m")))]
3363   "TARGET_SSE"
3364   "@
3365    movlhps\t{%2, %0|%0, %2}
3366    vmovlhps\t{%2, %1, %0|%0, %1, %2}
3367    movhps\t{%2, %0|%0, %2}
3368    vmovhps\t{%2, %1, %0|%0, %1, %2}"
3369   [(set_attr "isa" "noavx,avx,noavx,avx")
3370    (set_attr "type" "ssemov")
3371    (set_attr "prefix" "orig,vex,orig,vex")
3372    (set_attr "mode" "V4SF,V4SF,V2SF,V2SF")])
3373
3374 (define_expand "vec_init<mode>"
3375   [(match_operand:V_128 0 "register_operand" "")
3376    (match_operand 1 "" "")]
3377   "TARGET_SSE"
3378 {
3379   ix86_expand_vector_init (false, operands[0], operands[1]);
3380   DONE;
3381 })
3382
3383 ;; Avoid combining registers from different units in a single alternative,
3384 ;; see comment above inline_secondary_memory_needed function in i386.c
3385 (define_insn "vec_set<mode>_0"
3386   [(set (match_operand:VI4F_128 0 "nonimmediate_operand"
3387           "=Y4,Y2,Y2,x,x,x,Y4 ,x  ,m,m ,m")
3388         (vec_merge:VI4F_128
3389           (vec_duplicate:VI4F_128
3390             (match_operand:<ssescalarmode> 2 "general_operand"
3391           " Y4,m ,*r,m,x,x,*rm,*rm,x,fF,*r"))
3392           (match_operand:VI4F_128 1 "vector_move_operand"
3393           " C ,C ,C ,C,0,x,0  ,x  ,0,0 ,0")
3394           (const_int 1)))]
3395   "TARGET_SSE"
3396   "@
3397    %vinsertps\t{$0xe, %d2, %0|%0, %d2, 0xe}
3398    %vmov<ssescalarmodesuffix>\t{%2, %0|%0, %2}
3399    %vmovd\t{%2, %0|%0, %2}
3400    movss\t{%2, %0|%0, %2}
3401    movss\t{%2, %0|%0, %2}
3402    vmovss\t{%2, %1, %0|%0, %1, %2}
3403    pinsrd\t{$0, %2, %0|%0, %2, 0}
3404    vpinsrd\t{$0, %2, %1, %0|%0, %1, %2, 0}
3405    #
3406    #
3407    #"
3408   [(set_attr "isa" "*,*,*,noavx,noavx,avx,noavx,avx,*,*,*")
3409    (set (attr "type")
3410      (cond [(eq_attr "alternative" "0,6,7")
3411               (const_string "sselog")
3412             (eq_attr "alternative" "9")
3413               (const_string "fmov")
3414             (eq_attr "alternative" "10")
3415               (const_string "imov")
3416            ]
3417            (const_string "ssemov")))
3418    (set_attr "prefix_extra" "*,*,*,*,*,*,1,1,*,*,*")
3419    (set_attr "length_immediate" "*,*,*,*,*,*,1,1,*,*,*")
3420    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,orig,orig,vex,orig,vex,*,*,*")
3421    (set_attr "mode" "SF,<ssescalarmode>,SI,SF,SF,SF,TI,TI,*,*,*")])
3422
3423 ;; A subset is vec_setv4sf.
3424 (define_insn "*vec_setv4sf_sse4_1"
3425   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
3426         (vec_merge:V4SF
3427           (vec_duplicate:V4SF
3428             (match_operand:SF 2 "nonimmediate_operand" "xm,xm"))
3429           (match_operand:V4SF 1 "register_operand" "0,x")
3430           (match_operand:SI 3 "const_int_operand" "")))]
3431   "TARGET_SSE4_1
3432    && ((unsigned) exact_log2 (INTVAL (operands[3]))
3433        < GET_MODE_NUNITS (V4SFmode))"
3434 {
3435   operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])) << 4);
3436   switch (which_alternative)
3437     {
3438     case 0:
3439       return "insertps\t{%3, %2, %0|%0, %2, %3}";
3440     case 1:
3441       return "vinsertps\t{%3, %2, %1, %0|%0, %1, %2, %3}";
3442     default:
3443       gcc_unreachable ();
3444     }
3445 }
3446   [(set_attr "isa" "noavx,avx")
3447    (set_attr "type" "sselog")
3448    (set_attr "prefix_data16" "1,*")
3449    (set_attr "prefix_extra" "1")
3450    (set_attr "length_immediate" "1")
3451    (set_attr "prefix" "orig,vex")
3452    (set_attr "mode" "V4SF")])
3453
3454 (define_insn "sse4_1_insertps"
3455   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
3456         (unspec:V4SF [(match_operand:V4SF 2 "nonimmediate_operand" "xm,xm")
3457                       (match_operand:V4SF 1 "register_operand" "0,x")
3458                       (match_operand:SI 3 "const_0_to_255_operand" "n,n")]
3459                      UNSPEC_INSERTPS))]
3460   "TARGET_SSE4_1"
3461 {
3462   if (MEM_P (operands[2]))
3463     {
3464       unsigned count_s = INTVAL (operands[3]) >> 6;
3465       if (count_s)
3466         operands[3] = GEN_INT (INTVAL (operands[3]) & 0x3f);
3467       operands[2] = adjust_address_nv (operands[2], SFmode, count_s * 4);
3468     }
3469   switch (which_alternative)
3470     {
3471     case 0:
3472       return "insertps\t{%3, %2, %0|%0, %2, %3}";
3473     case 1:
3474       return "vinsertps\t{%3, %2, %1, %0|%0, %1, %2, %3}";
3475     default:
3476       gcc_unreachable ();
3477     }
3478 }
3479   [(set_attr "isa" "noavx,avx")
3480    (set_attr "type" "sselog")
3481    (set_attr "prefix_data16" "1,*")
3482    (set_attr "prefix_extra" "1")
3483    (set_attr "length_immediate" "1")
3484    (set_attr "prefix" "orig,vex")
3485    (set_attr "mode" "V4SF")])
3486
3487 (define_split
3488   [(set (match_operand:VI4F_128 0 "memory_operand" "")
3489         (vec_merge:VI4F_128
3490           (vec_duplicate:VI4F_128
3491             (match_operand:<ssescalarmode> 1 "nonmemory_operand" ""))
3492           (match_dup 0)
3493           (const_int 1)))]
3494   "TARGET_SSE && reload_completed"
3495   [(const_int 0)]
3496 {
3497   emit_move_insn (adjust_address (operands[0], <ssescalarmode>mode, 0),
3498                   operands[1]);
3499   DONE;
3500 })
3501
3502 (define_expand "vec_set<mode>"
3503   [(match_operand:V_128 0 "register_operand" "")
3504    (match_operand:<ssescalarmode> 1 "register_operand" "")
3505    (match_operand 2 "const_int_operand" "")]
3506   "TARGET_SSE"
3507 {
3508   ix86_expand_vector_set (false, operands[0], operands[1],
3509                           INTVAL (operands[2]));
3510   DONE;
3511 })
3512
3513 (define_insn_and_split "*vec_extractv4sf_0"
3514   [(set (match_operand:SF 0 "nonimmediate_operand" "=x,m,f,r")
3515         (vec_select:SF
3516           (match_operand:V4SF 1 "nonimmediate_operand" "xm,x,m,m")
3517           (parallel [(const_int 0)])))]
3518   "TARGET_SSE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3519   "#"
3520   "&& reload_completed"
3521   [(const_int 0)]
3522 {
3523   rtx op1 = operands[1];
3524   if (REG_P (op1))
3525     op1 = gen_rtx_REG (SFmode, REGNO (op1));
3526   else
3527     op1 = gen_lowpart (SFmode, op1);
3528   emit_move_insn (operands[0], op1);
3529   DONE;
3530 })
3531
3532 (define_expand "avx_vextractf128<mode>"
3533   [(match_operand:<ssehalfvecmode> 0 "nonimmediate_operand" "")
3534    (match_operand:V_256 1 "register_operand" "")
3535    (match_operand:SI 2 "const_0_to_1_operand" "")]
3536   "TARGET_AVX"
3537 {
3538   rtx (*insn)(rtx, rtx);
3539
3540   switch (INTVAL (operands[2]))
3541     {
3542     case 0:
3543       insn = gen_vec_extract_lo_<mode>;
3544       break;
3545     case 1:
3546       insn = gen_vec_extract_hi_<mode>;
3547       break;
3548     default:
3549       gcc_unreachable ();
3550     }
3551
3552   emit_insn (insn (operands[0], operands[1]));
3553   DONE;
3554 })
3555
3556 (define_insn_and_split "vec_extract_lo_<mode>"
3557   [(set (match_operand:<ssehalfvecmode> 0 "nonimmediate_operand" "=x,m")
3558         (vec_select:<ssehalfvecmode>
3559           (match_operand:VI8F_256 1 "nonimmediate_operand" "xm,x")
3560           (parallel [(const_int 0) (const_int 1)])))]
3561   "TARGET_AVX"
3562   "#"
3563   "&& reload_completed"
3564   [(const_int 0)]
3565 {
3566   rtx op1 = operands[1];
3567   if (REG_P (op1))
3568     op1 = gen_rtx_REG (<ssehalfvecmode>mode, REGNO (op1));
3569   else
3570     op1 = gen_lowpart (<ssehalfvecmode>mode, op1);
3571   emit_move_insn (operands[0], op1);
3572   DONE;
3573 })
3574
3575 (define_insn "vec_extract_hi_<mode>"
3576   [(set (match_operand:<ssehalfvecmode> 0 "nonimmediate_operand" "=x,m")
3577         (vec_select:<ssehalfvecmode>
3578           (match_operand:VI8F_256 1 "register_operand" "x,x")
3579           (parallel [(const_int 2) (const_int 3)])))]
3580   "TARGET_AVX"
3581   "vextractf128\t{$0x1, %1, %0|%0, %1, 0x1}"
3582   [(set_attr "type" "sselog")
3583    (set_attr "prefix_extra" "1")
3584    (set_attr "length_immediate" "1")
3585    (set_attr "memory" "none,store")
3586    (set_attr "prefix" "vex")
3587    (set_attr "mode" "V8SF")])
3588
3589 (define_insn_and_split "vec_extract_lo_<mode>"
3590   [(set (match_operand:<ssehalfvecmode> 0 "nonimmediate_operand" "=x,m")
3591         (vec_select:<ssehalfvecmode>
3592           (match_operand:VI4F_256 1 "nonimmediate_operand" "xm,x")
3593           (parallel [(const_int 0) (const_int 1)
3594                      (const_int 2) (const_int 3)])))]
3595   "TARGET_AVX"
3596   "#"
3597   "&& reload_completed"
3598   [(const_int 0)]
3599 {
3600   rtx op1 = operands[1];
3601   if (REG_P (op1))
3602     op1 = gen_rtx_REG (<ssehalfvecmode>mode, REGNO (op1));
3603   else
3604     op1 = gen_lowpart (<ssehalfvecmode>mode, op1);
3605   emit_move_insn (operands[0], op1);
3606   DONE;
3607 })
3608
3609 (define_insn "vec_extract_hi_<mode>"
3610   [(set (match_operand:<ssehalfvecmode> 0 "nonimmediate_operand" "=x,m")
3611         (vec_select:<ssehalfvecmode>
3612           (match_operand:VI4F_256 1 "register_operand" "x,x")
3613           (parallel [(const_int 4) (const_int 5)
3614                      (const_int 6) (const_int 7)])))]
3615   "TARGET_AVX"
3616   "vextractf128\t{$0x1, %1, %0|%0, %1, 0x1}"
3617   [(set_attr "type" "sselog")
3618    (set_attr "prefix_extra" "1")
3619    (set_attr "length_immediate" "1")
3620    (set_attr "memory" "none,store")
3621    (set_attr "prefix" "vex")
3622    (set_attr "mode" "V8SF")])
3623
3624 (define_insn_and_split "vec_extract_lo_v16hi"
3625   [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,m")
3626         (vec_select:V8HI
3627           (match_operand:V16HI 1 "nonimmediate_operand" "xm,x")
3628           (parallel [(const_int 0) (const_int 1)
3629                      (const_int 2) (const_int 3)
3630                      (const_int 4) (const_int 5)
3631                      (const_int 6) (const_int 7)])))]
3632   "TARGET_AVX"
3633   "#"
3634   "&& reload_completed"
3635   [(const_int 0)]
3636 {
3637   rtx op1 = operands[1];
3638   if (REG_P (op1))
3639     op1 = gen_rtx_REG (V8HImode, REGNO (op1));
3640   else
3641     op1 = gen_lowpart (V8HImode, op1);
3642   emit_move_insn (operands[0], op1);
3643   DONE;
3644 })
3645
3646 (define_insn "vec_extract_hi_v16hi"
3647   [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,m")
3648         (vec_select:V8HI
3649           (match_operand:V16HI 1 "register_operand" "x,x")
3650           (parallel [(const_int 8) (const_int 9)
3651                      (const_int 10) (const_int 11)
3652                      (const_int 12) (const_int 13)
3653                      (const_int 14) (const_int 15)])))]
3654   "TARGET_AVX"
3655   "vextractf128\t{$0x1, %1, %0|%0, %1, 0x1}"
3656   [(set_attr "type" "sselog")
3657    (set_attr "prefix_extra" "1")
3658    (set_attr "length_immediate" "1")
3659    (set_attr "memory" "none,store")
3660    (set_attr "prefix" "vex")
3661    (set_attr "mode" "V8SF")])
3662
3663 (define_insn_and_split "vec_extract_lo_v32qi"
3664   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
3665         (vec_select:V16QI
3666           (match_operand:V32QI 1 "nonimmediate_operand" "xm,x")
3667           (parallel [(const_int 0) (const_int 1)
3668                      (const_int 2) (const_int 3)
3669                      (const_int 4) (const_int 5)
3670                      (const_int 6) (const_int 7)
3671                      (const_int 8) (const_int 9)
3672                      (const_int 10) (const_int 11)
3673                      (const_int 12) (const_int 13)
3674                      (const_int 14) (const_int 15)])))]
3675   "TARGET_AVX"
3676   "#"
3677   "&& reload_completed"
3678   [(const_int 0)]
3679 {
3680   rtx op1 = operands[1];
3681   if (REG_P (op1))
3682     op1 = gen_rtx_REG (V16QImode, REGNO (op1));
3683   else
3684     op1 = gen_lowpart (V16QImode, op1);
3685   emit_move_insn (operands[0], op1);
3686   DONE;
3687 })
3688
3689 (define_insn "vec_extract_hi_v32qi"
3690   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
3691         (vec_select:V16QI
3692           (match_operand:V32QI 1 "register_operand" "x,x")
3693           (parallel [(const_int 16) (const_int 17)
3694                      (const_int 18) (const_int 19)
3695                      (const_int 20) (const_int 21)
3696                      (const_int 22) (const_int 23)
3697                      (const_int 24) (const_int 25)
3698                      (const_int 26) (const_int 27)
3699                      (const_int 28) (const_int 29)
3700                      (const_int 30) (const_int 31)])))]
3701   "TARGET_AVX"
3702   "vextractf128\t{$0x1, %1, %0|%0, %1, 0x1}"
3703   [(set_attr "type" "sselog")
3704    (set_attr "prefix_extra" "1")
3705    (set_attr "length_immediate" "1")
3706    (set_attr "memory" "none,store")
3707    (set_attr "prefix" "vex")
3708    (set_attr "mode" "V8SF")])
3709
3710 (define_insn "*sse4_1_extractps"
3711   [(set (match_operand:SF 0 "nonimmediate_operand" "=rm")
3712         (vec_select:SF
3713           (match_operand:V4SF 1 "register_operand" "x")
3714           (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n")])))]
3715   "TARGET_SSE4_1"
3716   "%vextractps\t{%2, %1, %0|%0, %1, %2}"
3717   [(set_attr "type" "sselog")
3718    (set_attr "prefix_data16" "1")
3719    (set_attr "prefix_extra" "1")
3720    (set_attr "length_immediate" "1")
3721    (set_attr "prefix" "maybe_vex")
3722    (set_attr "mode" "V4SF")])
3723
3724 (define_insn_and_split "*vec_extract_v4sf_mem"
3725   [(set (match_operand:SF 0 "register_operand" "=x*rf")
3726        (vec_select:SF
3727          (match_operand:V4SF 1 "memory_operand" "o")
3728          (parallel [(match_operand 2 "const_0_to_3_operand" "n")])))]
3729   ""
3730   "#"
3731   "reload_completed"
3732   [(const_int 0)]
3733 {
3734   int i = INTVAL (operands[2]);
3735
3736   emit_move_insn (operands[0], adjust_address (operands[1], SFmode, i*4));
3737   DONE;
3738 })
3739
3740 ;; Modes handled by vec_extract patterns.
3741 (define_mode_iterator VEC_EXTRACT_MODE
3742   [V16QI V8HI V4SI V2DI
3743    (V8SF "TARGET_AVX") V4SF
3744    (V4DF "TARGET_AVX") V2DF])
3745
3746 (define_expand "vec_extract<mode>"
3747   [(match_operand:<ssescalarmode> 0 "register_operand" "")
3748    (match_operand:VEC_EXTRACT_MODE 1 "register_operand" "")
3749    (match_operand 2 "const_int_operand" "")]
3750   "TARGET_SSE"
3751 {
3752   ix86_expand_vector_extract (false, operands[0], operands[1],
3753                               INTVAL (operands[2]));
3754   DONE;
3755 })
3756
3757 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3758 ;;
3759 ;; Parallel double-precision floating point element swizzling
3760 ;;
3761 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3762
3763 ;; Recall that the 256-bit unpck insns only shuffle within their lanes.
3764 (define_insn "avx_unpckhpd256"
3765   [(set (match_operand:V4DF 0 "register_operand" "=x")
3766         (vec_select:V4DF
3767           (vec_concat:V8DF
3768             (match_operand:V4DF 1 "register_operand" "x")
3769             (match_operand:V4DF 2 "nonimmediate_operand" "xm"))
3770           (parallel [(const_int 1) (const_int 5)
3771                      (const_int 3) (const_int 7)])))]
3772   "TARGET_AVX"
3773   "vunpckhpd\t{%2, %1, %0|%0, %1, %2}"
3774   [(set_attr "type" "sselog")
3775    (set_attr "prefix" "vex")
3776    (set_attr "mode" "V4DF")])
3777
3778 (define_expand "vec_interleave_highv4df"
3779   [(set (match_dup 3)
3780         (vec_select:V4DF
3781           (vec_concat:V8DF
3782             (match_operand:V4DF 1 "register_operand" "x")
3783             (match_operand:V4DF 2 "nonimmediate_operand" "xm"))
3784           (parallel [(const_int 0) (const_int 4)
3785                      (const_int 2) (const_int 6)])))
3786    (set (match_dup 4)
3787         (vec_select:V4DF
3788           (vec_concat:V8DF
3789             (match_dup 1)
3790             (match_dup 2))
3791           (parallel [(const_int 1) (const_int 5)
3792                      (const_int 3) (const_int 7)])))
3793    (set (match_operand:V4DF 0 "register_operand" "")
3794         (vec_select:V4DF
3795           (vec_concat:V8DF
3796             (match_dup 3)
3797             (match_dup 4))
3798           (parallel [(const_int 2) (const_int 3)
3799                      (const_int 6) (const_int 7)])))]
3800  "TARGET_AVX"
3801 {
3802   operands[3] = gen_reg_rtx (V4DFmode);
3803   operands[4] = gen_reg_rtx (V4DFmode);
3804 })
3805
3806
3807 (define_expand "vec_interleave_highv2df"
3808   [(set (match_operand:V2DF 0 "register_operand" "")
3809         (vec_select:V2DF
3810           (vec_concat:V4DF
3811             (match_operand:V2DF 1 "nonimmediate_operand" "")
3812             (match_operand:V2DF 2 "nonimmediate_operand" ""))
3813           (parallel [(const_int 1)
3814                      (const_int 3)])))]
3815   "TARGET_SSE2"
3816 {
3817   if (!ix86_vec_interleave_v2df_operator_ok (operands, 1))
3818     operands[2] = force_reg (V2DFmode, operands[2]);
3819 })
3820
3821 (define_insn "*vec_interleave_highv2df"
3822   [(set (match_operand:V2DF 0 "nonimmediate_operand"     "=x,x,Y3,x,x,m")
3823         (vec_select:V2DF
3824           (vec_concat:V4DF
3825             (match_operand:V2DF 1 "nonimmediate_operand" " 0,x,o ,o,o,x")
3826             (match_operand:V2DF 2 "nonimmediate_operand" " x,x,1 ,0,x,0"))
3827           (parallel [(const_int 1)
3828                      (const_int 3)])))]
3829   "TARGET_SSE2 && ix86_vec_interleave_v2df_operator_ok (operands, 1)"
3830   "@
3831    unpckhpd\t{%2, %0|%0, %2}
3832    vunpckhpd\t{%2, %1, %0|%0, %1, %2}
3833    %vmovddup\t{%H1, %0|%0, %H1}
3834    movlpd\t{%H1, %0|%0, %H1}
3835    vmovlpd\t{%H1, %2, %0|%0, %2, %H1}
3836    %vmovhpd\t{%1, %0|%0, %1}"
3837   [(set_attr "isa" "noavx,avx,*,noavx,avx,*")
3838   (set_attr "type" "sselog,sselog,sselog,ssemov,ssemov,ssemov")
3839    (set_attr "prefix_data16" "*,*,*,1,*,1")
3840    (set_attr "prefix" "orig,vex,maybe_vex,orig,vex,maybe_vex")
3841    (set_attr "mode" "V2DF,V2DF,V2DF,V1DF,V1DF,V1DF")])
3842
3843 ;; Recall that the 256-bit unpck insns only shuffle within their lanes.
3844 (define_expand "avx_movddup256"
3845   [(set (match_operand:V4DF 0 "register_operand" "")
3846         (vec_select:V4DF
3847           (vec_concat:V8DF
3848             (match_operand:V4DF 1 "nonimmediate_operand" "")
3849             (match_dup 1))
3850           (parallel [(const_int 0) (const_int 4)
3851                      (const_int 2) (const_int 6)])))]
3852   "TARGET_AVX")
3853
3854 (define_expand "avx_unpcklpd256"
3855   [(set (match_operand:V4DF 0 "register_operand" "")
3856         (vec_select:V4DF
3857           (vec_concat:V8DF
3858             (match_operand:V4DF 1 "register_operand" "")
3859             (match_operand:V4DF 2 "nonimmediate_operand" ""))
3860           (parallel [(const_int 0) (const_int 4)
3861                      (const_int 2) (const_int 6)])))]
3862   "TARGET_AVX")
3863
3864 (define_insn "*avx_unpcklpd256"
3865   [(set (match_operand:V4DF 0 "register_operand"         "=x,x")
3866         (vec_select:V4DF
3867           (vec_concat:V8DF
3868             (match_operand:V4DF 1 "nonimmediate_operand" "xm,x")
3869             (match_operand:V4DF 2 "nonimmediate_operand" " 1,xm"))
3870           (parallel [(const_int 0) (const_int 4)
3871                      (const_int 2) (const_int 6)])))]
3872   "TARGET_AVX
3873    && (!MEM_P (operands[1]) || rtx_equal_p (operands[1], operands[2]))"
3874   "@
3875    vmovddup\t{%1, %0|%0, %1}
3876    vunpcklpd\t{%2, %1, %0|%0, %1, %2}"
3877   [(set_attr "type" "sselog")
3878    (set_attr "prefix" "vex")
3879    (set_attr "mode" "V4DF")])
3880
3881 (define_expand "vec_interleave_lowv4df"
3882   [(set (match_dup 3)
3883         (vec_select:V4DF
3884           (vec_concat:V8DF
3885             (match_operand:V4DF 1 "register_operand" "x")
3886             (match_operand:V4DF 2 "nonimmediate_operand" "xm"))
3887           (parallel [(const_int 0) (const_int 4)
3888                      (const_int 2) (const_int 6)])))
3889    (set (match_dup 4)
3890         (vec_select:V4DF
3891           (vec_concat:V8DF
3892             (match_dup 1)
3893             (match_dup 2))
3894           (parallel [(const_int 1) (const_int 5)
3895                      (const_int 3) (const_int 7)])))
3896    (set (match_operand:V4DF 0 "register_operand" "")
3897         (vec_select:V4DF
3898           (vec_concat:V8DF
3899             (match_dup 3)
3900             (match_dup 4))
3901           (parallel [(const_int 0) (const_int 1)
3902                      (const_int 4) (const_int 5)])))]
3903  "TARGET_AVX"
3904 {
3905   operands[3] = gen_reg_rtx (V4DFmode);
3906   operands[4] = gen_reg_rtx (V4DFmode);
3907 })
3908
3909 (define_expand "vec_interleave_lowv2df"
3910   [(set (match_operand:V2DF 0 "register_operand" "")
3911         (vec_select:V2DF
3912           (vec_concat:V4DF
3913             (match_operand:V2DF 1 "nonimmediate_operand" "")
3914             (match_operand:V2DF 2 "nonimmediate_operand" ""))
3915           (parallel [(const_int 0)
3916                      (const_int 2)])))]
3917   "TARGET_SSE2"
3918 {
3919   if (!ix86_vec_interleave_v2df_operator_ok (operands, 0))
3920     operands[1] = force_reg (V2DFmode, operands[1]);
3921 })
3922
3923 (define_insn "*vec_interleave_lowv2df"
3924   [(set (match_operand:V2DF 0 "nonimmediate_operand"     "=x,x,Y3,x,x,o")
3925         (vec_select:V2DF
3926           (vec_concat:V4DF
3927             (match_operand:V2DF 1 "nonimmediate_operand" " 0,x,m ,0,x,0")
3928             (match_operand:V2DF 2 "nonimmediate_operand" " x,x,1 ,m,m,x"))
3929           (parallel [(const_int 0)
3930                      (const_int 2)])))]
3931   "TARGET_SSE2 && ix86_vec_interleave_v2df_operator_ok (operands, 0)"
3932   "@
3933    unpcklpd\t{%2, %0|%0, %2}
3934    vunpcklpd\t{%2, %1, %0|%0, %1, %2}
3935    %vmovddup\t{%1, %0|%0, %1}
3936    movhpd\t{%2, %0|%0, %2}
3937    vmovhpd\t{%2, %1, %0|%0, %1, %2}
3938    %vmovlpd\t{%2, %H0|%H0, %2}"
3939   [(set_attr "isa" "noavx,avx,*,noavx,avx,*")
3940    (set_attr "type" "sselog,sselog,sselog,ssemov,ssemov,ssemov")
3941    (set_attr "prefix_data16" "*,*,*,1,*,1")
3942    (set_attr "prefix" "orig,vex,maybe_vex,orig,vex,maybe_vex")
3943    (set_attr "mode" "V2DF,V2DF,V2DF,V1DF,V1DF,V1DF")])
3944
3945 (define_split
3946   [(set (match_operand:V2DF 0 "memory_operand" "")
3947         (vec_select:V2DF
3948           (vec_concat:V4DF
3949             (match_operand:V2DF 1 "register_operand" "")
3950             (match_dup 1))
3951           (parallel [(const_int 0)
3952                      (const_int 2)])))]
3953   "TARGET_SSE3 && reload_completed"
3954   [(const_int 0)]
3955 {
3956   rtx low = gen_rtx_REG (DFmode, REGNO (operands[1]));
3957   emit_move_insn (adjust_address (operands[0], DFmode, 0), low);
3958   emit_move_insn (adjust_address (operands[0], DFmode, 8), low);
3959   DONE;
3960 })
3961
3962 (define_split
3963   [(set (match_operand:V2DF 0 "register_operand" "")
3964         (vec_select:V2DF
3965           (vec_concat:V4DF
3966             (match_operand:V2DF 1 "memory_operand" "")
3967             (match_dup 1))
3968           (parallel [(match_operand:SI 2 "const_0_to_1_operand" "")
3969                      (match_operand:SI 3 "const_int_operand" "")])))]
3970   "TARGET_SSE3 && INTVAL (operands[2]) + 2 == INTVAL (operands[3])"
3971   [(set (match_dup 0) (vec_duplicate:V2DF (match_dup 1)))]
3972 {
3973   operands[1] = adjust_address (operands[1], DFmode, INTVAL (operands[2]) * 8);
3974 })
3975
3976 (define_expand "avx_shufpd256"
3977   [(match_operand:V4DF 0 "register_operand" "")
3978    (match_operand:V4DF 1 "register_operand" "")
3979    (match_operand:V4DF 2 "nonimmediate_operand" "")
3980    (match_operand:SI 3 "const_int_operand" "")]
3981   "TARGET_AVX"
3982 {
3983   int mask = INTVAL (operands[3]);
3984   emit_insn (gen_avx_shufpd256_1 (operands[0], operands[1], operands[2],
3985                                    GEN_INT (mask & 1),
3986                                    GEN_INT (mask & 2 ? 5 : 4),
3987                                    GEN_INT (mask & 4 ? 3 : 2),
3988                                    GEN_INT (mask & 8 ? 7 : 6)));
3989   DONE;
3990 })
3991
3992 (define_insn "avx_shufpd256_1"
3993   [(set (match_operand:V4DF 0 "register_operand" "=x")
3994         (vec_select:V4DF
3995           (vec_concat:V8DF
3996             (match_operand:V4DF 1 "register_operand" "x")
3997             (match_operand:V4DF 2 "nonimmediate_operand" "xm"))
3998           (parallel [(match_operand 3 "const_0_to_1_operand" "")
3999                      (match_operand 4 "const_4_to_5_operand" "")
4000                      (match_operand 5 "const_2_to_3_operand" "")
4001                      (match_operand 6 "const_6_to_7_operand" "")])))]
4002   "TARGET_AVX"
4003 {
4004   int mask;
4005   mask = INTVAL (operands[3]);
4006   mask |= (INTVAL (operands[4]) - 4) << 1;
4007   mask |= (INTVAL (operands[5]) - 2) << 2;
4008   mask |= (INTVAL (operands[6]) - 6) << 3;
4009   operands[3] = GEN_INT (mask);
4010
4011   return "vshufpd\t{%3, %2, %1, %0|%0, %1, %2, %3}";
4012 }
4013   [(set_attr "type" "sselog")
4014    (set_attr "length_immediate" "1")
4015    (set_attr "prefix" "vex")
4016    (set_attr "mode" "V4DF")])
4017
4018 (define_expand "sse2_shufpd"
4019   [(match_operand:V2DF 0 "register_operand" "")
4020    (match_operand:V2DF 1 "register_operand" "")
4021    (match_operand:V2DF 2 "nonimmediate_operand" "")
4022    (match_operand:SI 3 "const_int_operand" "")]
4023   "TARGET_SSE2"
4024 {
4025   int mask = INTVAL (operands[3]);
4026   emit_insn (gen_sse2_shufpd_v2df (operands[0], operands[1], operands[2],
4027                                 GEN_INT (mask & 1),
4028                                 GEN_INT (mask & 2 ? 3 : 2)));
4029   DONE;
4030 })
4031
4032 ;; Modes handled by vec_extract_even/odd pattern.
4033 (define_mode_iterator VEC_EXTRACT_EVENODD_MODE
4034   [(V16QI "TARGET_SSE2")
4035    (V8HI "TARGET_SSE2")
4036    (V4SI "TARGET_SSE2")
4037    (V2DI "TARGET_SSE2")
4038    (V8SF "TARGET_AVX") V4SF
4039    (V4DF "TARGET_AVX") (V2DF "TARGET_SSE2")])
4040
4041 (define_expand "vec_extract_even<mode>"
4042   [(match_operand:VEC_EXTRACT_EVENODD_MODE 0 "register_operand" "")
4043    (match_operand:VEC_EXTRACT_EVENODD_MODE 1 "register_operand" "")
4044    (match_operand:VEC_EXTRACT_EVENODD_MODE 2 "register_operand" "")]
4045   "TARGET_SSE"
4046 {
4047   ix86_expand_vec_extract_even_odd (operands[0], operands[1], operands[2], 0);
4048   DONE;
4049 })
4050
4051 (define_expand "vec_extract_odd<mode>"
4052   [(match_operand:VEC_EXTRACT_EVENODD_MODE 0 "register_operand" "")
4053    (match_operand:VEC_EXTRACT_EVENODD_MODE 1 "register_operand" "")
4054    (match_operand:VEC_EXTRACT_EVENODD_MODE 2 "register_operand" "")]
4055   "TARGET_SSE"
4056 {
4057   ix86_expand_vec_extract_even_odd (operands[0], operands[1], operands[2], 1);
4058   DONE;
4059 })
4060
4061 ;; punpcklqdq and punpckhqdq are shorter than shufpd.
4062
4063 (define_insn "vec_interleave_highv2di"
4064   [(set (match_operand:V2DI 0 "register_operand" "=x,x")
4065         (vec_select:V2DI
4066           (vec_concat:V4DI
4067             (match_operand:V2DI 1 "register_operand" "0,x")
4068             (match_operand:V2DI 2 "nonimmediate_operand" "xm,xm"))
4069           (parallel [(const_int 1)
4070                      (const_int 3)])))]
4071   "TARGET_SSE2"
4072   "@
4073    punpckhqdq\t{%2, %0|%0, %2}
4074    vpunpckhqdq\t{%2, %1, %0|%0, %1, %2}"
4075   [(set_attr "isa" "noavx,avx")
4076    (set_attr "type" "sselog")
4077    (set_attr "prefix_data16" "1,*")
4078    (set_attr "prefix" "orig,vex")
4079    (set_attr "mode" "TI")])
4080
4081 (define_insn "vec_interleave_lowv2di"
4082   [(set (match_operand:V2DI 0 "register_operand" "=x,x")
4083         (vec_select:V2DI
4084           (vec_concat:V4DI
4085             (match_operand:V2DI 1 "register_operand" "0,x")
4086             (match_operand:V2DI 2 "nonimmediate_operand" "xm,xm"))
4087           (parallel [(const_int 0)
4088                      (const_int 2)])))]
4089   "TARGET_SSE2"
4090   "@
4091    punpcklqdq\t{%2, %0|%0, %2}
4092    vpunpcklqdq\t{%2, %1, %0|%0, %1, %2}"
4093   [(set_attr "isa" "noavx,avx")
4094    (set_attr "type" "sselog")
4095    (set_attr "prefix_data16" "1,*")
4096    (set_attr "prefix" "orig,vex")
4097    (set_attr "mode" "TI")])
4098
4099 (define_insn "sse2_shufpd_<mode>"
4100   [(set (match_operand:VI8F_128 0 "register_operand" "=x,x")
4101         (vec_select:VI8F_128
4102           (vec_concat:<ssedoublevecmode>
4103             (match_operand:VI8F_128 1 "register_operand" "0,x")
4104             (match_operand:VI8F_128 2 "nonimmediate_operand" "xm,xm"))
4105           (parallel [(match_operand 3 "const_0_to_1_operand" "")
4106                      (match_operand 4 "const_2_to_3_operand" "")])))]
4107   "TARGET_SSE2"
4108 {
4109   int mask;
4110   mask = INTVAL (operands[3]);
4111   mask |= (INTVAL (operands[4]) - 2) << 1;
4112   operands[3] = GEN_INT (mask);
4113
4114   switch (which_alternative)
4115     {
4116     case 0:
4117       return "shufpd\t{%3, %2, %0|%0, %2, %3}";
4118     case 1:
4119       return "vshufpd\t{%3, %2, %1, %0|%0, %1, %2, %3}";
4120     default:
4121       gcc_unreachable ();
4122     }
4123 }
4124   [(set_attr "isa" "noavx,avx")
4125    (set_attr "type" "sselog")
4126    (set_attr "length_immediate" "1")
4127    (set_attr "prefix" "orig,vex")
4128    (set_attr "mode" "V2DF")])
4129
4130 ;; Avoid combining registers from different units in a single alternative,
4131 ;; see comment above inline_secondary_memory_needed function in i386.c
4132 (define_insn "sse2_storehpd"
4133   [(set (match_operand:DF 0 "nonimmediate_operand"     "=m,x,x,x,*f,r")
4134         (vec_select:DF
4135           (match_operand:V2DF 1 "nonimmediate_operand" " x,0,x,o,o,o")
4136           (parallel [(const_int 1)])))]
4137   "TARGET_SSE2 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
4138   "@
4139    %vmovhpd\t{%1, %0|%0, %1}
4140    unpckhpd\t%0, %0
4141    vunpckhpd\t{%d1, %0|%0, %d1}
4142    #
4143    #
4144    #"
4145   [(set_attr "isa" "*,noavx,avx,*,*,*")
4146    (set_attr "type" "ssemov,sselog1,sselog1,ssemov,fmov,imov")
4147    (set (attr "prefix_data16")
4148      (if_then_else
4149        (and (eq_attr "alternative" "0")
4150             (eq (symbol_ref "TARGET_AVX") (const_int 0)))
4151        (const_string "1")
4152        (const_string "*")))
4153    (set_attr "prefix" "maybe_vex,orig,vex,*,*,*")
4154    (set_attr "mode" "V1DF,V1DF,V2DF,DF,DF,DF")])
4155
4156 (define_split
4157   [(set (match_operand:DF 0 "register_operand" "")
4158         (vec_select:DF
4159           (match_operand:V2DF 1 "memory_operand" "")
4160           (parallel [(const_int 1)])))]
4161   "TARGET_SSE2 && reload_completed"
4162   [(set (match_dup 0) (match_dup 1))]
4163   "operands[1] = adjust_address (operands[1], DFmode, 8);")
4164
4165 (define_insn "*vec_extractv2df_1_sse"
4166   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,x,x")
4167         (vec_select:DF
4168           (match_operand:V2DF 1 "nonimmediate_operand" "x,x,o")
4169           (parallel [(const_int 1)])))]
4170   "!TARGET_SSE2 && TARGET_SSE
4171    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
4172   "@
4173    movhps\t{%1, %0|%0, %1}
4174    movhlps\t{%1, %0|%0, %1}
4175    movlps\t{%H1, %0|%0, %H1}"
4176   [(set_attr "type" "ssemov")
4177    (set_attr "mode" "V2SF,V4SF,V2SF")])
4178
4179 ;; Avoid combining registers from different units in a single alternative,
4180 ;; see comment above inline_secondary_memory_needed function in i386.c
4181 (define_insn "sse2_storelpd"
4182   [(set (match_operand:DF 0 "nonimmediate_operand"     "=m,x,x,*f,r")
4183         (vec_select:DF
4184           (match_operand:V2DF 1 "nonimmediate_operand" " x,x,m,m,m")
4185           (parallel [(const_int 0)])))]
4186   "TARGET_SSE2 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
4187   "@
4188    %vmovlpd\t{%1, %0|%0, %1}
4189    #
4190    #
4191    #
4192    #"
4193   [(set_attr "type" "ssemov,ssemov,ssemov,fmov,imov")
4194    (set_attr "prefix_data16" "1,*,*,*,*")
4195    (set_attr "prefix" "maybe_vex")
4196    (set_attr "mode" "V1DF,DF,DF,DF,DF")])
4197
4198 (define_split
4199   [(set (match_operand:DF 0 "register_operand" "")
4200         (vec_select:DF
4201           (match_operand:V2DF 1 "nonimmediate_operand" "")
4202           (parallel [(const_int 0)])))]
4203   "TARGET_SSE2 && reload_completed"
4204   [(const_int 0)]
4205 {
4206   rtx op1 = operands[1];
4207   if (REG_P (op1))
4208     op1 = gen_rtx_REG (DFmode, REGNO (op1));
4209   else
4210     op1 = gen_lowpart (DFmode, op1);
4211   emit_move_insn (operands[0], op1);
4212   DONE;
4213 })
4214
4215 (define_insn "*vec_extractv2df_0_sse"
4216   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,x,x")
4217         (vec_select:DF
4218           (match_operand:V2DF 1 "nonimmediate_operand" "x,x,m")
4219           (parallel [(const_int 0)])))]
4220   "!TARGET_SSE2 && TARGET_SSE
4221    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
4222   "@
4223    movlps\t{%1, %0|%0, %1}
4224    movaps\t{%1, %0|%0, %1}
4225    movlps\t{%1, %0|%0, %1}"
4226   [(set_attr "type" "ssemov")
4227    (set_attr "mode" "V2SF,V4SF,V2SF")])
4228
4229 (define_expand "sse2_loadhpd_exp"
4230   [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
4231         (vec_concat:V2DF
4232           (vec_select:DF
4233             (match_operand:V2DF 1 "nonimmediate_operand" "")
4234             (parallel [(const_int 0)]))
4235           (match_operand:DF 2 "nonimmediate_operand" "")))]
4236   "TARGET_SSE2"
4237 {
4238   rtx dst = ix86_fixup_binary_operands (UNKNOWN, V2DFmode, operands);
4239
4240   emit_insn (gen_sse2_loadhpd (dst, operands[1], operands[2]));
4241
4242   /* Fix up the destination if needed.  */
4243   if (dst != operands[0])
4244     emit_move_insn (operands[0], dst);
4245
4246   DONE;
4247 })
4248
4249 ;; Avoid combining registers from different units in a single alternative,
4250 ;; see comment above inline_secondary_memory_needed function in i386.c
4251 (define_insn "sse2_loadhpd"
4252   [(set (match_operand:V2DF 0 "nonimmediate_operand"
4253           "=x,x,x,x,o,o ,o")
4254         (vec_concat:V2DF
4255           (vec_select:DF
4256             (match_operand:V2DF 1 "nonimmediate_operand"
4257           " 0,x,0,x,0,0 ,0")
4258             (parallel [(const_int 0)]))
4259           (match_operand:DF 2 "nonimmediate_operand"
4260           " m,m,x,x,x,*f,r")))]
4261   "TARGET_SSE2 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
4262   "@
4263    movhpd\t{%2, %0|%0, %2}
4264    vmovhpd\t{%2, %1, %0|%0, %1, %2}
4265    unpcklpd\t{%2, %0|%0, %2}
4266    vunpcklpd\t{%2, %1, %0|%0, %1, %2}
4267    #
4268    #
4269    #"
4270   [(set_attr "isa" "noavx,avx,noavx,avx,*,*,*")
4271    (set_attr "type" "ssemov,ssemov,sselog,sselog,ssemov,fmov,imov")
4272    (set_attr "prefix_data16" "1,*,*,*,*,*,*")
4273    (set_attr "prefix" "orig,vex,orig,vex,*,*,*")
4274    (set_attr "mode" "V1DF,V1DF,V2DF,V2DF,DF,DF,DF")])
4275
4276 (define_split
4277   [(set (match_operand:V2DF 0 "memory_operand" "")
4278         (vec_concat:V2DF
4279           (vec_select:DF (match_dup 0) (parallel [(const_int 0)]))
4280           (match_operand:DF 1 "register_operand" "")))]
4281   "TARGET_SSE2 && reload_completed"
4282   [(set (match_dup 0) (match_dup 1))]
4283   "operands[0] = adjust_address (operands[0], DFmode, 8);")
4284
4285 (define_expand "sse2_loadlpd_exp"
4286   [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
4287         (vec_concat:V2DF
4288           (match_operand:DF 2 "nonimmediate_operand" "")
4289           (vec_select:DF
4290             (match_operand:V2DF 1 "nonimmediate_operand" "")
4291             (parallel [(const_int 1)]))))]
4292   "TARGET_SSE2"
4293 {
4294   rtx dst = ix86_fixup_binary_operands (UNKNOWN, V2DFmode, operands);
4295
4296   emit_insn (gen_sse2_loadlpd (dst, operands[1], operands[2]));
4297
4298   /* Fix up the destination if needed.  */
4299   if (dst != operands[0])
4300     emit_move_insn (operands[0], dst);
4301
4302   DONE;
4303 })
4304
4305 ;; Avoid combining registers from different units in a single alternative,
4306 ;; see comment above inline_secondary_memory_needed function in i386.c
4307 (define_insn "sse2_loadlpd"
4308   [(set (match_operand:V2DF 0 "nonimmediate_operand"
4309           "=x,x,x,x,x,x,x,x,m,m ,m")
4310         (vec_concat:V2DF
4311           (match_operand:DF 2 "nonimmediate_operand"
4312           " m,m,m,x,x,0,0,x,x,*f,r")
4313           (vec_select:DF
4314             (match_operand:V2DF 1 "vector_move_operand"
4315           " C,0,x,0,x,x,o,o,0,0 ,0")
4316             (parallel [(const_int 1)]))))]
4317   "TARGET_SSE2 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
4318   "@
4319    %vmovsd\t{%2, %0|%0, %2}
4320    movlpd\t{%2, %0|%0, %2}
4321    vmovlpd\t{%2, %1, %0|%0, %1, %2}
4322    movsd\t{%2, %0|%0, %2}
4323    vmovsd\t{%2, %1, %0|%0, %1, %2}
4324    shufpd\t{$2, %1, %0|%0, %1, 2}
4325    movhpd\t{%H1, %0|%0, %H1}
4326    vmovhpd\t{%H1, %2, %0|%0, %2, %H1}
4327    #
4328    #
4329    #"
4330   [(set_attr "isa" "*,noavx,avx,noavx,avx,noavx,noavx,avx,*,*,*")
4331    (set (attr "type")
4332      (cond [(eq_attr "alternative" "5")
4333               (const_string "sselog")
4334             (eq_attr "alternative" "9")
4335               (const_string "fmov")
4336             (eq_attr "alternative" "10")
4337               (const_string "imov")
4338            ]
4339            (const_string "ssemov")))
4340    (set_attr "prefix_data16" "*,1,*,*,*,*,1,*,*,*,*")
4341    (set_attr "length_immediate" "*,*,*,*,*,1,*,*,*,*,*")
4342    (set_attr "prefix" "maybe_vex,orig,vex,orig,vex,orig,orig,vex,*,*,*")
4343    (set_attr "mode" "DF,V1DF,V1DF,V1DF,V1DF,V2DF,V1DF,V1DF,DF,DF,DF")])
4344
4345 (define_split
4346   [(set (match_operand:V2DF 0 "memory_operand" "")
4347         (vec_concat:V2DF
4348           (match_operand:DF 1 "register_operand" "")
4349           (vec_select:DF (match_dup 0) (parallel [(const_int 1)]))))]
4350   "TARGET_SSE2 && reload_completed"
4351   [(set (match_dup 0) (match_dup 1))]
4352   "operands[0] = adjust_address (operands[0], DFmode, 8);")
4353
4354 (define_insn "sse2_movsd"
4355   [(set (match_operand:V2DF 0 "nonimmediate_operand"   "=x,x,x,x,m,x,x,x,o")
4356         (vec_merge:V2DF
4357           (match_operand:V2DF 2 "nonimmediate_operand" " x,x,m,m,x,0,0,x,0")
4358           (match_operand:V2DF 1 "nonimmediate_operand" " 0,x,0,x,0,x,o,o,x")
4359           (const_int 1)))]
4360   "TARGET_SSE2"
4361   "@
4362    movsd\t{%2, %0|%0, %2}
4363    vmovsd\t{%2, %1, %0|%0, %1, %2}
4364    movlpd\t{%2, %0|%0, %2}
4365    vmovlpd\t{%2, %1, %0|%0, %1, %2}
4366    %vmovlpd\t{%2, %0|%0, %2}
4367    shufpd\t{$2, %1, %0|%0, %1, 2}
4368    movhps\t{%H1, %0|%0, %H1}
4369    vmovhps\t{%H1, %2, %0|%0, %2, %H1}
4370    %vmovhps\t{%1, %H0|%H0, %1}"
4371   [(set_attr "isa" "noavx,avx,noavx,avx,*,noavx,noavx,avx,*")
4372    (set (attr "type")
4373      (if_then_else
4374        (eq_attr "alternative" "5")
4375        (const_string "sselog")
4376        (const_string "ssemov")))
4377    (set (attr "prefix_data16")
4378      (if_then_else
4379        (and (eq_attr "alternative" "2,4")
4380             (eq (symbol_ref "TARGET_AVX") (const_int 0)))
4381        (const_string "1")
4382        (const_string "*")))
4383    (set_attr "length_immediate" "*,*,*,*,*,1,*,*,*")
4384    (set_attr "prefix" "orig,vex,orig,vex,maybe_vex,orig,orig,vex,maybe_vex")
4385    (set_attr "mode" "DF,DF,V1DF,V1DF,V1DF,V2DF,V1DF,V1DF,V1DF")])
4386
4387 (define_expand "vec_dupv2df"
4388   [(set (match_operand:V2DF 0 "register_operand" "")
4389         (vec_duplicate:V2DF
4390           (match_operand:DF 1 "nonimmediate_operand" "")))]
4391   "TARGET_SSE2"
4392 {
4393   if (!TARGET_SSE3)
4394     operands[1] = force_reg (DFmode, operands[1]);
4395 })
4396
4397 (define_insn "*vec_dupv2df_sse3"
4398   [(set (match_operand:V2DF 0 "register_operand" "=x")
4399         (vec_duplicate:V2DF
4400           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4401   "TARGET_SSE3"
4402   "%vmovddup\t{%1, %0|%0, %1}"
4403   [(set_attr "type" "sselog1")
4404    (set_attr "prefix" "maybe_vex")
4405    (set_attr "mode" "DF")])
4406
4407 (define_insn "*vec_dupv2df"
4408   [(set (match_operand:V2DF 0 "register_operand" "=x")
4409         (vec_duplicate:V2DF
4410           (match_operand:DF 1 "register_operand" "0")))]
4411   "TARGET_SSE2"
4412   "unpcklpd\t%0, %0"
4413   [(set_attr "type" "sselog1")
4414    (set_attr "mode" "V2DF")])
4415
4416 (define_insn "*vec_concatv2df_sse3"
4417   [(set (match_operand:V2DF 0 "register_operand" "=x")
4418         (vec_concat:V2DF
4419           (match_operand:DF 1 "nonimmediate_operand" "xm")
4420           (match_dup 1)))]
4421   "TARGET_SSE3"
4422   "%vmovddup\t{%1, %0|%0, %1}"
4423   [(set_attr "type" "sselog1")
4424    (set_attr "prefix" "maybe_vex")
4425    (set_attr "mode" "DF")])
4426
4427 (define_insn "*vec_concatv2df"
4428   [(set (match_operand:V2DF 0 "register_operand"     "=Y2,x,Y2,x,Y2,x,x")
4429         (vec_concat:V2DF
4430           (match_operand:DF 1 "nonimmediate_operand" " 0 ,x,0 ,x,m ,0,0")
4431           (match_operand:DF 2 "vector_move_operand"  " Y2,x,m ,m,C ,x,m")))]
4432   "TARGET_SSE"
4433   "@
4434    unpcklpd\t{%2, %0|%0, %2}
4435    vunpcklpd\t{%2, %1, %0|%0, %1, %2}
4436    movhpd\t{%2, %0|%0, %2}
4437    vmovhpd\t{%2, %1, %0|%0, %1, %2}
4438    %vmovsd\t{%1, %0|%0, %1}
4439    movlhps\t{%2, %0|%0, %2}
4440    movhps\t{%2, %0|%0, %2}"
4441   [(set_attr "isa" "noavx,avx,noavx,avx,*,noavx,noavx")
4442    (set (attr "type")
4443      (if_then_else
4444        (eq_attr "alternative" "0,1")
4445        (const_string "sselog")
4446        (const_string "ssemov")))
4447    (set_attr "prefix_data16" "*,*,1,*,*,*,*")
4448    (set_attr "prefix" "orig,vex,orig,vex,maybe_vex,orig,orig")
4449    (set_attr "mode" "V2DF,V2DF,V1DF,V1DF,DF,V4SF,V2SF")])
4450
4451 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4452 ;;
4453 ;; Parallel integral arithmetic
4454 ;;
4455 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4456
4457 (define_expand "neg<mode>2"
4458   [(set (match_operand:VI_128 0 "register_operand" "")
4459         (minus:VI_128
4460           (match_dup 2)
4461           (match_operand:VI_128 1 "nonimmediate_operand" "")))]
4462   "TARGET_SSE2"
4463   "operands[2] = force_reg (<MODE>mode, CONST0_RTX (<MODE>mode));")
4464
4465 (define_expand "<plusminus_insn><mode>3"
4466   [(set (match_operand:VI_128 0 "register_operand" "")
4467         (plusminus:VI_128
4468           (match_operand:VI_128 1 "nonimmediate_operand" "")
4469           (match_operand:VI_128 2 "nonimmediate_operand" "")))]
4470   "TARGET_SSE2"
4471   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
4472
4473 (define_insn "*<plusminus_insn><mode>3"
4474   [(set (match_operand:VI_128 0 "register_operand" "=x,x")
4475         (plusminus:VI_128
4476           (match_operand:VI_128 1 "nonimmediate_operand" "<comm>0,x")
4477           (match_operand:VI_128 2 "nonimmediate_operand" "xm,xm")))]
4478   "TARGET_SSE2 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
4479   "@
4480    p<plusminus_mnemonic><ssemodesuffix>\t{%2, %0|%0, %2}
4481    vp<plusminus_mnemonic><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
4482   [(set_attr "isa" "noavx,avx")
4483    (set_attr "type" "sseiadd")
4484    (set_attr "prefix_data16" "1,*")
4485    (set_attr "prefix" "orig,vex")
4486    (set_attr "mode" "TI")])
4487
4488 (define_expand "sse2_<plusminus_insn><mode>3"
4489   [(set (match_operand:VI12_128 0 "register_operand" "")
4490         (sat_plusminus:VI12_128
4491           (match_operand:VI12_128 1 "nonimmediate_operand" "")
4492           (match_operand:VI12_128 2 "nonimmediate_operand" "")))]
4493   "TARGET_SSE2"
4494   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
4495
4496 (define_insn "*sse2_<plusminus_insn><mode>3"
4497   [(set (match_operand:VI12_128 0 "register_operand" "=x,x")
4498         (sat_plusminus:VI12_128
4499           (match_operand:VI12_128 1 "nonimmediate_operand" "<comm>0,x")
4500           (match_operand:VI12_128 2 "nonimmediate_operand" "xm,xm")))]
4501   "TARGET_SSE2 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
4502   "@
4503    p<plusminus_mnemonic><ssemodesuffix>\t{%2, %0|%0, %2}
4504    vp<plusminus_mnemonic><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
4505   [(set_attr "isa" "noavx,avx")
4506    (set_attr "type" "sseiadd")
4507    (set_attr "prefix_data16" "1,*")
4508    (set_attr "prefix" "orig,vex")
4509    (set_attr "mode" "TI")])
4510
4511 (define_insn_and_split "mulv16qi3"
4512   [(set (match_operand:V16QI 0 "register_operand" "")
4513         (mult:V16QI (match_operand:V16QI 1 "register_operand" "")
4514                     (match_operand:V16QI 2 "register_operand" "")))]
4515   "TARGET_SSE2
4516    && can_create_pseudo_p ()"
4517   "#"
4518   "&& 1"
4519   [(const_int 0)]
4520 {
4521   rtx t[6];
4522   int i;
4523
4524   for (i = 0; i < 6; ++i)
4525     t[i] = gen_reg_rtx (V16QImode);
4526
4527   /* Unpack data such that we've got a source byte in each low byte of
4528      each word.  We don't care what goes into the high byte of each word.
4529      Rather than trying to get zero in there, most convenient is to let
4530      it be a copy of the low byte.  */
4531   emit_insn (gen_vec_interleave_highv16qi (t[0], operands[1], operands[1]));
4532   emit_insn (gen_vec_interleave_highv16qi (t[1], operands[2], operands[2]));
4533   emit_insn (gen_vec_interleave_lowv16qi (t[2], operands[1], operands[1]));
4534   emit_insn (gen_vec_interleave_lowv16qi (t[3], operands[2], operands[2]));
4535
4536   /* Multiply words.  The end-of-line annotations here give a picture of what
4537      the output of that instruction looks like.  Dot means don't care; the
4538      letters are the bytes of the result with A being the most significant.  */
4539   emit_insn (gen_mulv8hi3 (gen_lowpart (V8HImode, t[4]), /* .A.B.C.D.E.F.G.H */
4540                            gen_lowpart (V8HImode, t[0]),
4541                            gen_lowpart (V8HImode, t[1])));
4542   emit_insn (gen_mulv8hi3 (gen_lowpart (V8HImode, t[5]), /* .I.J.K.L.M.N.O.P */
4543                            gen_lowpart (V8HImode, t[2]),
4544                            gen_lowpart (V8HImode, t[3])));
4545
4546   /* Extract the even bytes and merge them back together.  */
4547   ix86_expand_vec_extract_even_odd (operands[0], t[5], t[4], 0);
4548   DONE;
4549 })
4550
4551 (define_expand "mulv8hi3"
4552   [(set (match_operand:V8HI 0 "register_operand" "")
4553         (mult:V8HI (match_operand:V8HI 1 "nonimmediate_operand" "")
4554                    (match_operand:V8HI 2 "nonimmediate_operand" "")))]
4555   "TARGET_SSE2"
4556   "ix86_fixup_binary_operands_no_copy (MULT, V8HImode, operands);")
4557
4558 (define_insn "*mulv8hi3"
4559   [(set (match_operand:V8HI 0 "register_operand" "=x,x")
4560         (mult:V8HI (match_operand:V8HI 1 "nonimmediate_operand" "%0,x")
4561                    (match_operand:V8HI 2 "nonimmediate_operand" "xm,xm")))]
4562   "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V8HImode, operands)"
4563   "@
4564    pmullw\t{%2, %0|%0, %2}
4565    vpmullw\t{%2, %1, %0|%0, %1, %2}"
4566   [(set_attr "isa" "noavx,avx")
4567    (set_attr "type" "sseimul")
4568    (set_attr "prefix_data16" "1,*")
4569    (set_attr "prefix" "orig,vex")
4570    (set_attr "mode" "TI")])
4571
4572 (define_expand "<s>mulv8hi3_highpart"
4573   [(set (match_operand:V8HI 0 "register_operand" "")
4574         (truncate:V8HI
4575           (lshiftrt:V8SI
4576             (mult:V8SI
4577               (any_extend:V8SI
4578                 (match_operand:V8HI 1 "nonimmediate_operand" ""))
4579               (any_extend:V8SI
4580                 (match_operand:V8HI 2 "nonimmediate_operand" "")))
4581             (const_int 16))))]
4582   "TARGET_SSE2"
4583   "ix86_fixup_binary_operands_no_copy (MULT, V8HImode, operands);")
4584
4585 (define_insn "*<s>mulv8hi3_highpart"
4586   [(set (match_operand:V8HI 0 "register_operand" "=x,x")
4587         (truncate:V8HI
4588           (lshiftrt:V8SI
4589             (mult:V8SI
4590               (any_extend:V8SI
4591                 (match_operand:V8HI 1 "nonimmediate_operand" "%0,x"))
4592               (any_extend:V8SI
4593                 (match_operand:V8HI 2 "nonimmediate_operand" "xm,xm")))
4594             (const_int 16))))]
4595   "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V8HImode, operands)"
4596   "@
4597    pmulh<u>w\t{%2, %0|%0, %2}
4598    vpmulh<u>w\t{%2, %1, %0|%0, %1, %2}"
4599   [(set_attr "isa" "noavx,avx")
4600    (set_attr "type" "sseimul")
4601    (set_attr "prefix_data16" "1,*")
4602    (set_attr "prefix" "orig,vex")
4603    (set_attr "mode" "TI")])
4604
4605 (define_expand "sse2_umulv2siv2di3"
4606   [(set (match_operand:V2DI 0 "register_operand" "")
4607         (mult:V2DI
4608           (zero_extend:V2DI
4609             (vec_select:V2SI
4610               (match_operand:V4SI 1 "nonimmediate_operand" "")
4611               (parallel [(const_int 0) (const_int 2)])))
4612           (zero_extend:V2DI
4613             (vec_select:V2SI
4614               (match_operand:V4SI 2 "nonimmediate_operand" "")
4615               (parallel [(const_int 0) (const_int 2)])))))]
4616   "TARGET_SSE2"
4617   "ix86_fixup_binary_operands_no_copy (MULT, V4SImode, operands);")
4618
4619 (define_insn "*sse2_umulv2siv2di3"
4620   [(set (match_operand:V2DI 0 "register_operand" "=x,x")
4621         (mult:V2DI
4622           (zero_extend:V2DI
4623             (vec_select:V2SI
4624               (match_operand:V4SI 1 "nonimmediate_operand" "%0,x")
4625               (parallel [(const_int 0) (const_int 2)])))
4626           (zero_extend:V2DI
4627             (vec_select:V2SI
4628               (match_operand:V4SI 2 "nonimmediate_operand" "xm,xm")
4629               (parallel [(const_int 0) (const_int 2)])))))]
4630   "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V4SImode, operands)"
4631   "@
4632    pmuludq\t{%2, %0|%0, %2}
4633    vpmuludq\t{%2, %1, %0|%0, %1, %2}"
4634   [(set_attr "isa" "noavx,avx")
4635    (set_attr "type" "sseimul")
4636    (set_attr "prefix_data16" "1,*")
4637    (set_attr "prefix" "orig,vex")
4638    (set_attr "mode" "TI")])
4639
4640 (define_expand "sse4_1_mulv2siv2di3"
4641   [(set (match_operand:V2DI 0 "register_operand" "")
4642         (mult:V2DI
4643           (sign_extend:V2DI
4644             (vec_select:V2SI
4645               (match_operand:V4SI 1 "nonimmediate_operand" "")
4646               (parallel [(const_int 0) (const_int 2)])))
4647           (sign_extend:V2DI
4648             (vec_select:V2SI
4649               (match_operand:V4SI 2 "nonimmediate_operand" "")
4650               (parallel [(const_int 0) (const_int 2)])))))]
4651   "TARGET_SSE4_1"
4652   "ix86_fixup_binary_operands_no_copy (MULT, V4SImode, operands);")
4653
4654 (define_insn "*sse4_1_mulv2siv2di3"
4655   [(set (match_operand:V2DI 0 "register_operand" "=x,x")
4656         (mult:V2DI
4657           (sign_extend:V2DI
4658             (vec_select:V2SI
4659               (match_operand:V4SI 1 "nonimmediate_operand" "%0,x")
4660               (parallel [(const_int 0) (const_int 2)])))
4661           (sign_extend:V2DI
4662             (vec_select:V2SI
4663               (match_operand:V4SI 2 "nonimmediate_operand" "xm,xm")
4664               (parallel [(const_int 0) (const_int 2)])))))]
4665   "TARGET_SSE4_1 && ix86_binary_operator_ok (MULT, V4SImode, operands)"
4666   "@
4667    pmuldq\t{%2, %0|%0, %2}
4668    vpmuldq\t{%2, %1, %0|%0, %1, %2}"
4669   [(set_attr "isa" "noavx,avx")
4670    (set_attr "type" "sseimul")
4671    (set_attr "prefix_data16" "1,*")
4672    (set_attr "prefix_extra" "1")
4673    (set_attr "prefix" "orig,vex")
4674    (set_attr "mode" "TI")])
4675
4676 (define_expand "sse2_pmaddwd"
4677   [(set (match_operand:V4SI 0 "register_operand" "")
4678         (plus:V4SI
4679           (mult:V4SI
4680             (sign_extend:V4SI
4681               (vec_select:V4HI
4682                 (match_operand:V8HI 1 "nonimmediate_operand" "")
4683                 (parallel [(const_int 0)
4684                            (const_int 2)
4685                            (const_int 4)
4686                            (const_int 6)])))
4687             (sign_extend:V4SI
4688               (vec_select:V4HI
4689                 (match_operand:V8HI 2 "nonimmediate_operand" "")
4690                 (parallel [(const_int 0)
4691                            (const_int 2)
4692                            (const_int 4)
4693                            (const_int 6)]))))
4694           (mult:V4SI
4695             (sign_extend:V4SI
4696               (vec_select:V4HI (match_dup 1)
4697                 (parallel [(const_int 1)
4698                            (const_int 3)
4699                            (const_int 5)
4700                            (const_int 7)])))
4701             (sign_extend:V4SI
4702               (vec_select:V4HI (match_dup 2)
4703                 (parallel [(const_int 1)
4704                            (const_int 3)
4705                            (const_int 5)
4706                            (const_int 7)]))))))]
4707   "TARGET_SSE2"
4708   "ix86_fixup_binary_operands_no_copy (MULT, V8HImode, operands);")
4709
4710 (define_insn "*sse2_pmaddwd"
4711   [(set (match_operand:V4SI 0 "register_operand" "=x,x")
4712         (plus:V4SI
4713           (mult:V4SI
4714             (sign_extend:V4SI
4715               (vec_select:V4HI
4716                 (match_operand:V8HI 1 "nonimmediate_operand" "%0,x")
4717                 (parallel [(const_int 0)
4718                            (const_int 2)
4719                            (const_int 4)
4720                            (const_int 6)])))
4721             (sign_extend:V4SI
4722               (vec_select:V4HI
4723                 (match_operand:V8HI 2 "nonimmediate_operand" "xm,xm")
4724                 (parallel [(const_int 0)
4725                            (const_int 2)
4726                            (const_int 4)
4727                            (const_int 6)]))))
4728           (mult:V4SI
4729             (sign_extend:V4SI
4730               (vec_select:V4HI (match_dup 1)
4731                 (parallel [(const_int 1)
4732                            (const_int 3)
4733                            (const_int 5)
4734                            (const_int 7)])))
4735             (sign_extend:V4SI
4736               (vec_select:V4HI (match_dup 2)
4737                 (parallel [(const_int 1)
4738                            (const_int 3)
4739                            (const_int 5)
4740                            (const_int 7)]))))))]
4741   "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V8HImode, operands)"
4742   "@
4743    pmaddwd\t{%2, %0|%0, %2}
4744    vpmaddwd\t{%2, %1, %0|%0, %1, %2}"
4745   [(set_attr "isa" "noavx,avx")
4746    (set_attr "type" "sseiadd")
4747    (set_attr "atom_unit" "simul")
4748    (set_attr "prefix_data16" "1,*")
4749    (set_attr "prefix" "orig,vex")
4750    (set_attr "mode" "TI")])
4751
4752 (define_expand "mulv4si3"
4753   [(set (match_operand:V4SI 0 "register_operand" "")
4754         (mult:V4SI (match_operand:V4SI 1 "register_operand" "")
4755                    (match_operand:V4SI 2 "register_operand" "")))]
4756   "TARGET_SSE2"
4757 {
4758   if (TARGET_SSE4_1 || TARGET_AVX)
4759     ix86_fixup_binary_operands_no_copy (MULT, V4SImode, operands);
4760 })
4761
4762 (define_insn "*sse4_1_mulv4si3"
4763   [(set (match_operand:V4SI 0 "register_operand" "=x,x")
4764         (mult:V4SI (match_operand:V4SI 1 "nonimmediate_operand" "%0,x")
4765                    (match_operand:V4SI 2 "nonimmediate_operand" "xm,xm")))]
4766   "TARGET_SSE4_1 && ix86_binary_operator_ok (MULT, V4SImode, operands)"
4767   "@
4768    pmulld\t{%2, %0|%0, %2}
4769    vpmulld\t{%2, %1, %0|%0, %1, %2}"
4770   [(set_attr "isa" "noavx,avx")
4771    (set_attr "type" "sseimul")
4772    (set_attr "prefix_extra" "1")
4773    (set_attr "prefix" "orig,vex")
4774    (set_attr "mode" "TI")])
4775
4776 (define_insn_and_split "*sse2_mulv4si3"
4777   [(set (match_operand:V4SI 0 "register_operand" "")
4778         (mult:V4SI (match_operand:V4SI 1 "register_operand" "")
4779                    (match_operand:V4SI 2 "register_operand" "")))]
4780   "TARGET_SSE2 && !TARGET_SSE4_1 && !TARGET_AVX
4781    && can_create_pseudo_p ()"
4782   "#"
4783   "&& 1"
4784   [(const_int 0)]
4785 {
4786   rtx t1, t2, t3, t4, t5, t6, thirtytwo;
4787   rtx op0, op1, op2;
4788
4789   op0 = operands[0];
4790   op1 = operands[1];
4791   op2 = operands[2];
4792   t1 = gen_reg_rtx (V4SImode);
4793   t2 = gen_reg_rtx (V4SImode);
4794   t3 = gen_reg_rtx (V4SImode);
4795   t4 = gen_reg_rtx (V4SImode);
4796   t5 = gen_reg_rtx (V4SImode);
4797   t6 = gen_reg_rtx (V4SImode);
4798   thirtytwo = GEN_INT (32);
4799
4800   /* Multiply elements 2 and 0.  */
4801   emit_insn (gen_sse2_umulv2siv2di3 (gen_lowpart (V2DImode, t1),
4802                                      op1, op2));
4803
4804   /* Shift both input vectors down one element, so that elements 3
4805      and 1 are now in the slots for elements 2 and 0.  For K8, at
4806      least, this is faster than using a shuffle.  */
4807   emit_insn (gen_sse2_lshrv1ti3 (gen_lowpart (V1TImode, t2),
4808                                  gen_lowpart (V1TImode, op1),
4809                                  thirtytwo));
4810   emit_insn (gen_sse2_lshrv1ti3 (gen_lowpart (V1TImode, t3),
4811                                  gen_lowpart (V1TImode, op2),
4812                                  thirtytwo));
4813   /* Multiply elements 3 and 1.  */
4814   emit_insn (gen_sse2_umulv2siv2di3 (gen_lowpart (V2DImode, t4),
4815                                      t2, t3));
4816
4817   /* Move the results in element 2 down to element 1; we don't care
4818      what goes in elements 2 and 3.  */
4819   emit_insn (gen_sse2_pshufd_1 (t5, t1, const0_rtx, const2_rtx,
4820                                 const0_rtx, const0_rtx));
4821   emit_insn (gen_sse2_pshufd_1 (t6, t4, const0_rtx, const2_rtx,
4822                                 const0_rtx, const0_rtx));
4823
4824   /* Merge the parts back together.  */
4825   emit_insn (gen_vec_interleave_lowv4si (op0, t5, t6));
4826   DONE;
4827 })
4828
4829 (define_insn_and_split "mulv2di3"
4830   [(set (match_operand:V2DI 0 "register_operand" "")
4831         (mult:V2DI (match_operand:V2DI 1 "register_operand" "")
4832                    (match_operand:V2DI 2 "register_operand" "")))]
4833   "TARGET_SSE2
4834    && can_create_pseudo_p ()"
4835   "#"
4836   "&& 1"
4837   [(const_int 0)]
4838 {
4839   rtx t1, t2, t3, t4, t5, t6, thirtytwo;
4840   rtx op0, op1, op2;
4841
4842   op0 = operands[0];
4843   op1 = operands[1];
4844   op2 = operands[2];
4845
4846   if (TARGET_XOP)
4847     {
4848       /* op1: A,B,C,D, op2: E,F,G,H */
4849       op1 = gen_lowpart (V4SImode, op1);
4850       op2 = gen_lowpart (V4SImode, op2);
4851
4852       t1 = gen_reg_rtx (V4SImode);
4853       t2 = gen_reg_rtx (V4SImode);
4854       t3 = gen_reg_rtx (V2DImode);
4855       t4 = gen_reg_rtx (V2DImode);
4856
4857       /* t1: B,A,D,C */
4858       emit_insn (gen_sse2_pshufd_1 (t1, op1,
4859                                     GEN_INT (1),
4860                                     GEN_INT (0),
4861                                     GEN_INT (3),
4862                                     GEN_INT (2)));
4863
4864       /* t2: (B*E),(A*F),(D*G),(C*H) */
4865       emit_insn (gen_mulv4si3 (t2, t1, op2));
4866
4867       /* t4: (B*E)+(A*F), (D*G)+(C*H) */
4868       emit_insn (gen_xop_phadddq (t3, t2));
4869
4870       /* t5: ((B*E)+(A*F))<<32, ((D*G)+(C*H))<<32 */
4871       emit_insn (gen_ashlv2di3 (t4, t3, GEN_INT (32)));
4872
4873       /* op0: (((B*E)+(A*F))<<32)+(B*F), (((D*G)+(C*H))<<32)+(D*H) */
4874       emit_insn (gen_xop_pmacsdql (op0, op1, op2, t4));
4875     }
4876   else
4877     {
4878       t1 = gen_reg_rtx (V2DImode);
4879       t2 = gen_reg_rtx (V2DImode);
4880       t3 = gen_reg_rtx (V2DImode);
4881       t4 = gen_reg_rtx (V2DImode);
4882       t5 = gen_reg_rtx (V2DImode);
4883       t6 = gen_reg_rtx (V2DImode);
4884       thirtytwo = GEN_INT (32);
4885
4886       /* Multiply low parts.  */
4887       emit_insn (gen_sse2_umulv2siv2di3 (t1, gen_lowpart (V4SImode, op1),
4888                                          gen_lowpart (V4SImode, op2)));
4889
4890       /* Shift input vectors left 32 bits so we can multiply high parts.  */
4891       emit_insn (gen_lshrv2di3 (t2, op1, thirtytwo));
4892       emit_insn (gen_lshrv2di3 (t3, op2, thirtytwo));
4893
4894       /* Multiply high parts by low parts.  */
4895       emit_insn (gen_sse2_umulv2siv2di3 (t4, gen_lowpart (V4SImode, op1),
4896                                          gen_lowpart (V4SImode, t3)));
4897       emit_insn (gen_sse2_umulv2siv2di3 (t5, gen_lowpart (V4SImode, op2),
4898                                          gen_lowpart (V4SImode, t2)));
4899
4900       /* Shift them back.  */
4901       emit_insn (gen_ashlv2di3 (t4, t4, thirtytwo));
4902       emit_insn (gen_ashlv2di3 (t5, t5, thirtytwo));
4903
4904       /* Add the three parts together.  */
4905       emit_insn (gen_addv2di3 (t6, t1, t4));
4906       emit_insn (gen_addv2di3 (op0, t6, t5));
4907     }
4908   DONE;
4909 })
4910
4911 (define_expand "vec_widen_smult_hi_v8hi"
4912   [(match_operand:V4SI 0 "register_operand" "")
4913    (match_operand:V8HI 1 "register_operand" "")
4914    (match_operand:V8HI 2 "register_operand" "")]
4915   "TARGET_SSE2"
4916 {
4917   rtx op1, op2, t1, t2, dest;
4918
4919   op1 = operands[1];
4920   op2 = operands[2];
4921   t1 = gen_reg_rtx (V8HImode);
4922   t2 = gen_reg_rtx (V8HImode);
4923   dest = gen_lowpart (V8HImode, operands[0]);
4924
4925   emit_insn (gen_mulv8hi3 (t1, op1, op2));
4926   emit_insn (gen_smulv8hi3_highpart (t2, op1, op2));
4927   emit_insn (gen_vec_interleave_highv8hi (dest, t1, t2));
4928   DONE;
4929 })
4930
4931 (define_expand "vec_widen_smult_lo_v8hi"
4932   [(match_operand:V4SI 0 "register_operand" "")
4933    (match_operand:V8HI 1 "register_operand" "")
4934    (match_operand:V8HI 2 "register_operand" "")]
4935   "TARGET_SSE2"
4936 {
4937   rtx op1, op2, t1, t2, dest;
4938
4939   op1 = operands[1];
4940   op2 = operands[2];
4941   t1 = gen_reg_rtx (V8HImode);
4942   t2 = gen_reg_rtx (V8HImode);
4943   dest = gen_lowpart (V8HImode, operands[0]);
4944
4945   emit_insn (gen_mulv8hi3 (t1, op1, op2));
4946   emit_insn (gen_smulv8hi3_highpart (t2, op1, op2));
4947   emit_insn (gen_vec_interleave_lowv8hi (dest, t1, t2));
4948   DONE;
4949 })
4950
4951 (define_expand "vec_widen_umult_hi_v8hi"
4952   [(match_operand:V4SI 0 "register_operand" "")
4953    (match_operand:V8HI 1 "register_operand" "")
4954    (match_operand:V8HI 2 "register_operand" "")]
4955   "TARGET_SSE2"
4956 {
4957   rtx op1, op2, t1, t2, dest;
4958
4959   op1 = operands[1];
4960   op2 = operands[2];
4961   t1 = gen_reg_rtx (V8HImode);
4962   t2 = gen_reg_rtx (V8HImode);
4963   dest = gen_lowpart (V8HImode, operands[0]);
4964
4965   emit_insn (gen_mulv8hi3 (t1, op1, op2));
4966   emit_insn (gen_umulv8hi3_highpart (t2, op1, op2));
4967   emit_insn (gen_vec_interleave_highv8hi (dest, t1, t2));
4968   DONE;
4969 })
4970
4971 (define_expand "vec_widen_umult_lo_v8hi"
4972   [(match_operand:V4SI 0 "register_operand" "")
4973    (match_operand:V8HI 1 "register_operand" "")
4974    (match_operand:V8HI 2 "register_operand" "")]
4975   "TARGET_SSE2"
4976 {
4977   rtx op1, op2, t1, t2, dest;
4978
4979   op1 = operands[1];
4980   op2 = operands[2];
4981   t1 = gen_reg_rtx (V8HImode);
4982   t2 = gen_reg_rtx (V8HImode);
4983   dest = gen_lowpart (V8HImode, operands[0]);
4984
4985   emit_insn (gen_mulv8hi3 (t1, op1, op2));
4986   emit_insn (gen_umulv8hi3_highpart (t2, op1, op2));
4987   emit_insn (gen_vec_interleave_lowv8hi (dest, t1, t2));
4988   DONE;
4989 })
4990
4991 (define_expand "vec_widen_smult_hi_v4si"
4992   [(match_operand:V2DI 0 "register_operand" "")
4993    (match_operand:V4SI 1 "register_operand" "")
4994    (match_operand:V4SI 2 "register_operand" "")]
4995   "TARGET_XOP"
4996 {
4997   rtx t1, t2;
4998
4999   t1 = gen_reg_rtx (V4SImode);
5000   t2 = gen_reg_rtx (V4SImode);
5001
5002   emit_insn (gen_sse2_pshufd_1 (t1, operands[1],
5003                                 GEN_INT (0),
5004                                 GEN_INT (2),
5005                                 GEN_INT (1),
5006                                 GEN_INT (3)));
5007   emit_insn (gen_sse2_pshufd_1 (t2, operands[2],
5008                                 GEN_INT (0),
5009                                 GEN_INT (2),
5010                                 GEN_INT (1),
5011                                 GEN_INT (3)));
5012   emit_insn (gen_xop_mulv2div2di3_high (operands[0], t1, t2));
5013   DONE;
5014 })
5015
5016 (define_expand "vec_widen_smult_lo_v4si"
5017   [(match_operand:V2DI 0 "register_operand" "")
5018    (match_operand:V4SI 1 "register_operand" "")
5019    (match_operand:V4SI 2 "register_operand" "")]
5020   "TARGET_XOP"
5021 {
5022   rtx t1, t2;
5023
5024   t1 = gen_reg_rtx (V4SImode);
5025   t2 = gen_reg_rtx (V4SImode);
5026
5027   emit_insn (gen_sse2_pshufd_1 (t1, operands[1],
5028                                 GEN_INT (0),
5029                                 GEN_INT (2),
5030                                 GEN_INT (1),
5031                                 GEN_INT (3)));
5032   emit_insn (gen_sse2_pshufd_1 (t2, operands[2],
5033                                 GEN_INT (0),
5034                                 GEN_INT (2),
5035                                 GEN_INT (1),
5036                                 GEN_INT (3)));
5037   emit_insn (gen_xop_mulv2div2di3_low (operands[0], t1, t2));
5038   DONE;
5039 })
5040
5041 (define_expand "vec_widen_umult_hi_v4si"
5042   [(match_operand:V2DI 0 "register_operand" "")
5043    (match_operand:V4SI 1 "register_operand" "")
5044    (match_operand:V4SI 2 "register_operand" "")]
5045   "TARGET_SSE2"
5046 {
5047   rtx op1, op2, t1, t2;
5048
5049   op1 = operands[1];
5050   op2 = operands[2];
5051   t1 = gen_reg_rtx (V4SImode);
5052   t2 = gen_reg_rtx (V4SImode);
5053
5054   emit_insn (gen_vec_interleave_highv4si (t1, op1, op1));
5055   emit_insn (gen_vec_interleave_highv4si (t2, op2, op2));
5056   emit_insn (gen_sse2_umulv2siv2di3 (operands[0], t1, t2));
5057   DONE;
5058 })
5059
5060 (define_expand "vec_widen_umult_lo_v4si"
5061   [(match_operand:V2DI 0 "register_operand" "")
5062    (match_operand:V4SI 1 "register_operand" "")
5063    (match_operand:V4SI 2 "register_operand" "")]
5064   "TARGET_SSE2"
5065 {
5066   rtx op1, op2, t1, t2;
5067
5068   op1 = operands[1];
5069   op2 = operands[2];
5070   t1 = gen_reg_rtx (V4SImode);
5071   t2 = gen_reg_rtx (V4SImode);
5072
5073   emit_insn (gen_vec_interleave_lowv4si (t1, op1, op1));
5074   emit_insn (gen_vec_interleave_lowv4si (t2, op2, op2));
5075   emit_insn (gen_sse2_umulv2siv2di3 (operands[0], t1, t2));
5076   DONE;
5077 })
5078
5079 (define_expand "sdot_prodv8hi"
5080   [(match_operand:V4SI 0 "register_operand" "")
5081    (match_operand:V8HI 1 "register_operand" "")
5082    (match_operand:V8HI 2 "register_operand" "")
5083    (match_operand:V4SI 3 "register_operand" "")]
5084   "TARGET_SSE2"
5085 {
5086   rtx t = gen_reg_rtx (V4SImode);
5087   emit_insn (gen_sse2_pmaddwd (t, operands[1], operands[2]));
5088   emit_insn (gen_addv4si3 (operands[0], operands[3], t));
5089   DONE;
5090 })
5091
5092 (define_expand "udot_prodv4si"
5093   [(match_operand:V2DI 0 "register_operand" "")
5094    (match_operand:V4SI 1 "register_operand" "")
5095    (match_operand:V4SI 2 "register_operand" "")
5096    (match_operand:V2DI 3 "register_operand" "")]
5097   "TARGET_SSE2"
5098 {
5099   rtx t1, t2, t3, t4;
5100
5101   t1 = gen_reg_rtx (V2DImode);
5102   emit_insn (gen_sse2_umulv2siv2di3 (t1, operands[1], operands[2]));
5103   emit_insn (gen_addv2di3 (t1, t1, operands[3]));
5104
5105   t2 = gen_reg_rtx (V4SImode);
5106   t3 = gen_reg_rtx (V4SImode);
5107   emit_insn (gen_sse2_lshrv1ti3 (gen_lowpart (V1TImode, t2),
5108                                  gen_lowpart (V1TImode, operands[1]),
5109                                  GEN_INT (32)));
5110   emit_insn (gen_sse2_lshrv1ti3 (gen_lowpart (V1TImode, t3),
5111                                  gen_lowpart (V1TImode, operands[2]),
5112                                  GEN_INT (32)));
5113
5114   t4 = gen_reg_rtx (V2DImode);
5115   emit_insn (gen_sse2_umulv2siv2di3 (t4, t2, t3));
5116
5117   emit_insn (gen_addv2di3 (operands[0], t1, t4));
5118   DONE;
5119 })
5120
5121 (define_insn "ashr<mode>3"
5122   [(set (match_operand:VI24_128 0 "register_operand" "=x,x")
5123         (ashiftrt:VI24_128
5124           (match_operand:VI24_128 1 "register_operand" "0,x")
5125           (match_operand:SI 2 "nonmemory_operand" "xN,xN")))]
5126   "TARGET_SSE2"
5127   "@
5128    psra<ssemodesuffix>\t{%2, %0|%0, %2}
5129    vpsra<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
5130   [(set_attr "isa" "noavx,avx")
5131    (set_attr "type" "sseishft")
5132    (set (attr "length_immediate")
5133      (if_then_else (match_operand 2 "const_int_operand" "")
5134        (const_string "1")
5135        (const_string "0")))
5136    (set_attr "prefix_data16" "1,*")
5137    (set_attr "prefix" "orig,vex")
5138    (set_attr "mode" "TI")])
5139
5140 (define_insn "lshr<mode>3"
5141   [(set (match_operand:VI248_128 0 "register_operand" "=x,x")
5142         (lshiftrt:VI248_128
5143           (match_operand:VI248_128 1 "register_operand" "0,x")
5144           (match_operand:SI 2 "nonmemory_operand" "xN,xN")))]
5145   "TARGET_SSE2"
5146   "@
5147    psrl<ssemodesuffix>\t{%2, %0|%0, %2}
5148    vpsrl<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
5149   [(set_attr "isa" "noavx,avx")
5150    (set_attr "type" "sseishft")
5151    (set (attr "length_immediate")
5152      (if_then_else (match_operand 2 "const_int_operand" "")
5153        (const_string "1")
5154        (const_string "0")))
5155    (set_attr "prefix_data16" "1,*")
5156    (set_attr "prefix" "orig,vex")
5157    (set_attr "mode" "TI")])
5158
5159 (define_insn "ashl<mode>3"
5160   [(set (match_operand:VI248_128 0 "register_operand" "=x,x")
5161         (ashift:VI248_128
5162           (match_operand:VI248_128 1 "register_operand" "0,x")
5163           (match_operand:SI 2 "nonmemory_operand" "xN,xN")))]
5164   "TARGET_SSE2"
5165   "@
5166    psll<ssemodesuffix>\t{%2, %0|%0, %2}
5167    vpsll<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
5168   [(set_attr "isa" "noavx,avx")
5169    (set_attr "type" "sseishft")
5170    (set (attr "length_immediate")
5171      (if_then_else (match_operand 2 "const_int_operand" "")
5172        (const_string "1")
5173        (const_string "0")))
5174    (set_attr "prefix_data16" "1,*")
5175    (set_attr "prefix" "orig,vex")
5176    (set_attr "mode" "TI")])
5177
5178 (define_expand "vec_shl_<mode>"
5179   [(set (match_operand:VI_128 0 "register_operand" "")
5180         (ashift:V1TI
5181          (match_operand:VI_128 1 "register_operand" "")
5182          (match_operand:SI 2 "const_0_to_255_mul_8_operand" "")))]
5183   "TARGET_SSE2"
5184 {
5185   operands[0] = gen_lowpart (V1TImode, operands[0]);
5186   operands[1] = gen_lowpart (V1TImode, operands[1]);
5187 })
5188
5189 (define_insn "sse2_ashlv1ti3"
5190   [(set (match_operand:V1TI 0 "register_operand" "=x,x")
5191         (ashift:V1TI
5192          (match_operand:V1TI 1 "register_operand" "0,x")
5193          (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n,n")))]
5194   "TARGET_SSE2"
5195 {
5196   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
5197
5198   switch (which_alternative)
5199     {
5200     case 0:
5201       return "pslldq\t{%2, %0|%0, %2}";
5202     case 1:
5203       return "vpslldq\t{%2, %1, %0|%0, %1, %2}";
5204     default:
5205       gcc_unreachable ();
5206     }
5207 }
5208   [(set_attr "isa" "noavx,avx")
5209    (set_attr "type" "sseishft")
5210    (set_attr "length_immediate" "1")
5211    (set_attr "prefix_data16" "1,*")
5212    (set_attr "prefix" "orig,vex")
5213    (set_attr "mode" "TI")])
5214
5215 (define_expand "vec_shr_<mode>"
5216   [(set (match_operand:VI_128 0 "register_operand" "")
5217         (lshiftrt:V1TI
5218          (match_operand:VI_128 1 "register_operand" "")
5219          (match_operand:SI 2 "const_0_to_255_mul_8_operand" "")))]
5220   "TARGET_SSE2"
5221 {
5222   operands[0] = gen_lowpart (V1TImode, operands[0]);
5223   operands[1] = gen_lowpart (V1TImode, operands[1]);
5224 })
5225
5226 (define_insn "sse2_lshrv1ti3"
5227   [(set (match_operand:V1TI 0 "register_operand" "=x,x")
5228         (lshiftrt:V1TI
5229          (match_operand:V1TI 1 "register_operand" "0,x")
5230          (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n,n")))]
5231   "TARGET_SSE2"
5232 {
5233   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
5234
5235   switch (which_alternative)
5236     {
5237     case 0:
5238       return "psrldq\t{%2, %0|%0, %2}";
5239     case 1:
5240       return "vpsrldq\t{%2, %1, %0|%0, %1, %2}";
5241     default:
5242       gcc_unreachable ();
5243     }
5244 }
5245   [(set_attr "isa" "noavx,avx")
5246    (set_attr "type" "sseishft")
5247    (set_attr "length_immediate" "1")
5248    (set_attr "atom_unit" "sishuf")
5249    (set_attr "prefix_data16" "1,*")
5250    (set_attr "prefix" "orig,vex")
5251    (set_attr "mode" "TI")])
5252
5253 (define_insn "*sse4_1_<code><mode>3"
5254   [(set (match_operand:VI14_128 0 "register_operand" "=x,x")
5255         (smaxmin:VI14_128
5256           (match_operand:VI14_128 1 "nonimmediate_operand" "%0,x")
5257           (match_operand:VI14_128 2 "nonimmediate_operand" "xm,xm")))]
5258   "TARGET_SSE4_1 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5259   "@
5260    p<maxmin_int><ssemodesuffix>\t{%2, %0|%0, %2}
5261    vp<maxmin_int><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
5262   [(set_attr "isa" "noavx,avx")
5263    (set_attr "type" "sseiadd")
5264    (set_attr "prefix_extra" "1,*")
5265    (set_attr "prefix" "orig,vex")
5266    (set_attr "mode" "TI")])
5267
5268 (define_insn "*<code>v8hi3"
5269   [(set (match_operand:V8HI 0 "register_operand" "=x,x")
5270         (smaxmin:V8HI
5271           (match_operand:V8HI 1 "nonimmediate_operand" "%0,x")
5272           (match_operand:V8HI 2 "nonimmediate_operand" "xm,xm")))]
5273   "TARGET_SSE2 && ix86_binary_operator_ok (<CODE>, V8HImode, operands)"
5274   "@
5275    p<maxmin_int>w\t{%2, %0|%0, %2}
5276    vp<maxmin_int>w\t{%2, %1, %0|%0, %1, %2}"
5277   [(set_attr "isa" "noavx,avx")
5278    (set_attr "type" "sseiadd")
5279    (set_attr "prefix_data16" "1,*")
5280    (set_attr "prefix_extra" "*,1")
5281    (set_attr "prefix" "orig,vex")
5282    (set_attr "mode" "TI")])
5283
5284 (define_expand "smax<mode>3"
5285   [(set (match_operand:VI14_128 0 "register_operand" "")
5286         (smax:VI14_128 (match_operand:VI14_128 1 "register_operand" "")
5287                        (match_operand:VI14_128 2 "register_operand" "")))]
5288   "TARGET_SSE2"
5289 {
5290   if (TARGET_SSE4_1)
5291     ix86_fixup_binary_operands_no_copy (SMAX, <MODE>mode, operands);
5292   else
5293     {
5294       rtx xops[6];
5295       bool ok;
5296
5297       xops[0] = operands[0];
5298       xops[1] = operands[1];
5299       xops[2] = operands[2];
5300       xops[3] = gen_rtx_GT (VOIDmode, operands[1], operands[2]);
5301       xops[4] = operands[1];
5302       xops[5] = operands[2];
5303       ok = ix86_expand_int_vcond (xops);
5304       gcc_assert (ok);
5305       DONE;
5306     }
5307 })
5308
5309 (define_expand "smin<mode>3"
5310   [(set (match_operand:VI14_128 0 "register_operand" "")
5311         (smin:VI14_128 (match_operand:VI14_128 1 "register_operand" "")
5312                        (match_operand:VI14_128 2 "register_operand" "")))]
5313   "TARGET_SSE2"
5314 {
5315   if (TARGET_SSE4_1)
5316     ix86_fixup_binary_operands_no_copy (SMIN, <MODE>mode, operands);
5317   else
5318     {
5319       rtx xops[6];
5320       bool ok;
5321
5322       xops[0] = operands[0];
5323       xops[1] = operands[2];
5324       xops[2] = operands[1];
5325       xops[3] = gen_rtx_GT (VOIDmode, operands[1], operands[2]);
5326       xops[4] = operands[1];
5327       xops[5] = operands[2];
5328       ok = ix86_expand_int_vcond (xops);
5329       gcc_assert (ok);
5330       DONE;
5331     }
5332 })
5333
5334 (define_expand "<code>v8hi3"
5335   [(set (match_operand:V8HI 0 "register_operand" "")
5336         (smaxmin:V8HI
5337           (match_operand:V8HI 1 "nonimmediate_operand" "")
5338           (match_operand:V8HI 2 "nonimmediate_operand" "")))]
5339   "TARGET_SSE2"
5340   "ix86_fixup_binary_operands_no_copy (<CODE>, V8HImode, operands);")
5341
5342 (define_expand "smaxv2di3"
5343   [(set (match_operand:V2DI 0 "register_operand" "")
5344         (smax:V2DI (match_operand:V2DI 1 "register_operand" "")
5345                    (match_operand:V2DI 2 "register_operand" "")))]
5346   "TARGET_SSE4_2"
5347 {
5348   rtx xops[6];
5349   bool ok;
5350
5351   xops[0] = operands[0];
5352   xops[1] = operands[1];
5353   xops[2] = operands[2];
5354   xops[3] = gen_rtx_GT (VOIDmode, operands[1], operands[2]);
5355   xops[4] = operands[1];
5356   xops[5] = operands[2];
5357   ok = ix86_expand_int_vcond (xops);
5358   gcc_assert (ok);
5359   DONE;
5360 })
5361
5362 (define_expand "sminv2di3"
5363   [(set (match_operand:V2DI 0 "register_operand" "")
5364         (smin:V2DI (match_operand:V2DI 1 "register_operand" "")
5365                    (match_operand:V2DI 2 "register_operand" "")))]
5366   "TARGET_SSE4_2"
5367 {
5368   rtx xops[6];
5369   bool ok;
5370
5371   xops[0] = operands[0];
5372   xops[1] = operands[2];
5373   xops[2] = operands[1];
5374   xops[3] = gen_rtx_GT (VOIDmode, operands[1], operands[2]);
5375   xops[4] = operands[1];
5376   xops[5] = operands[2];
5377   ok = ix86_expand_int_vcond (xops);
5378   gcc_assert (ok);
5379   DONE;
5380 })
5381
5382 (define_insn "*sse4_1_<code><mode>3"
5383   [(set (match_operand:VI24_128 0 "register_operand" "=x,x")
5384         (umaxmin:VI24_128
5385           (match_operand:VI24_128 1 "nonimmediate_operand" "%0,x")
5386           (match_operand:VI24_128 2 "nonimmediate_operand" "xm,xm")))]
5387   "TARGET_SSE4_1 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5388   "@
5389    p<maxmin_int><ssemodesuffix>\t{%2, %0|%0, %2}
5390    vp<maxmin_int><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
5391   [(set_attr "isa" "noavx,avx")
5392    (set_attr "type" "sseiadd")
5393    (set_attr "prefix_extra" "1,*")
5394    (set_attr "prefix" "orig,vex")
5395    (set_attr "mode" "TI")])
5396
5397 (define_insn "*<code>v16qi3"
5398   [(set (match_operand:V16QI 0 "register_operand" "=x,x")
5399         (umaxmin:V16QI
5400           (match_operand:V16QI 1 "nonimmediate_operand" "%0,x")
5401           (match_operand:V16QI 2 "nonimmediate_operand" "xm,xm")))]
5402   "TARGET_SSE2 && ix86_binary_operator_ok (<CODE>, V16QImode, operands)"
5403   "@
5404    p<maxmin_int>b\t{%2, %0|%0, %2}
5405    vp<maxmin_int>b\t{%2, %1, %0|%0, %1, %2}"
5406   [(set_attr "isa" "noavx,avx")
5407    (set_attr "type" "sseiadd")
5408    (set_attr "prefix_data16" "1,*")
5409    (set_attr "prefix_extra" "*,1")
5410    (set_attr "prefix" "orig,vex")
5411    (set_attr "mode" "TI")])
5412
5413 (define_expand "<code>v16qi3"
5414   [(set (match_operand:V16QI 0 "register_operand" "")
5415         (umaxmin:V16QI
5416           (match_operand:V16QI 1 "nonimmediate_operand" "")
5417           (match_operand:V16QI 2 "nonimmediate_operand" "")))]
5418   "TARGET_SSE2"
5419   "ix86_fixup_binary_operands_no_copy (<CODE>, V16QImode, operands);")
5420
5421 (define_expand "umaxv8hi3"
5422   [(set (match_operand:V8HI 0 "register_operand" "")
5423         (umax:V8HI (match_operand:V8HI 1 "register_operand" "")
5424                    (match_operand:V8HI 2 "nonimmediate_operand" "")))]
5425   "TARGET_SSE2"
5426 {
5427   if (TARGET_SSE4_1)
5428     ix86_fixup_binary_operands_no_copy (UMAX, V8HImode, operands);
5429   else
5430     {
5431       rtx op0 = operands[0], op2 = operands[2], op3 = op0;
5432       if (rtx_equal_p (op3, op2))
5433         op3 = gen_reg_rtx (V8HImode);
5434       emit_insn (gen_sse2_ussubv8hi3 (op3, operands[1], op2));
5435       emit_insn (gen_addv8hi3 (op0, op3, op2));
5436       DONE;
5437     }
5438 })
5439
5440 (define_expand "umaxv4si3"
5441   [(set (match_operand:V4SI 0 "register_operand" "")
5442         (umax:V4SI (match_operand:V4SI 1 "register_operand" "")
5443                    (match_operand:V4SI 2 "register_operand" "")))]
5444   "TARGET_SSE2"
5445 {
5446   if (TARGET_SSE4_1)
5447     ix86_fixup_binary_operands_no_copy (UMAX, V4SImode, operands);
5448   else
5449     {
5450       rtx xops[6];
5451       bool ok;
5452
5453       xops[0] = operands[0];
5454       xops[1] = operands[1];
5455       xops[2] = operands[2];
5456       xops[3] = gen_rtx_GTU (VOIDmode, operands[1], operands[2]);
5457       xops[4] = operands[1];
5458       xops[5] = operands[2];
5459       ok = ix86_expand_int_vcond (xops);
5460       gcc_assert (ok);
5461       DONE;
5462     }
5463 })
5464
5465 (define_expand "umin<mode>3"
5466   [(set (match_operand:VI24_128 0 "register_operand" "")
5467         (umin:VI24_128 (match_operand:VI24_128 1 "register_operand" "")
5468                        (match_operand:VI24_128 2 "register_operand" "")))]
5469   "TARGET_SSE2"
5470 {
5471   if (TARGET_SSE4_1)
5472     ix86_fixup_binary_operands_no_copy (UMIN, <MODE>mode, operands);
5473   else
5474     {
5475       rtx xops[6];
5476       bool ok;
5477
5478       xops[0] = operands[0];
5479       xops[1] = operands[2];
5480       xops[2] = operands[1];
5481       xops[3] = gen_rtx_GTU (VOIDmode, operands[1], operands[2]);
5482       xops[4] = operands[1];
5483       xops[5] = operands[2];
5484       ok = ix86_expand_int_vcond (xops);
5485       gcc_assert (ok);
5486       DONE;
5487     }
5488 })
5489
5490 (define_expand "umaxv2di3"
5491   [(set (match_operand:V2DI 0 "register_operand" "")
5492         (umax:V2DI (match_operand:V2DI 1 "register_operand" "")
5493                    (match_operand:V2DI 2 "register_operand" "")))]
5494   "TARGET_SSE4_2"
5495 {
5496   rtx xops[6];
5497   bool ok;
5498
5499   xops[0] = operands[0];
5500   xops[1] = operands[1];
5501   xops[2] = operands[2];
5502   xops[3] = gen_rtx_GTU (VOIDmode, operands[1], operands[2]);
5503   xops[4] = operands[1];
5504   xops[5] = operands[2];
5505   ok = ix86_expand_int_vcond (xops);
5506   gcc_assert (ok);
5507   DONE;
5508 })
5509
5510 (define_expand "uminv2di3"
5511   [(set (match_operand:V2DI 0 "register_operand" "")
5512         (umin:V2DI (match_operand:V2DI 1 "register_operand" "")
5513                    (match_operand:V2DI 2 "register_operand" "")))]
5514   "TARGET_SSE4_2"
5515 {
5516   rtx xops[6];
5517   bool ok;
5518
5519   xops[0] = operands[0];
5520   xops[1] = operands[2];
5521   xops[2] = operands[1];
5522   xops[3] = gen_rtx_GTU (VOIDmode, operands[1], operands[2]);
5523   xops[4] = operands[1];
5524   xops[5] = operands[2];
5525   ok = ix86_expand_int_vcond (xops);
5526   gcc_assert (ok);
5527   DONE;
5528 })
5529
5530 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5531 ;;
5532 ;; Parallel integral comparisons
5533 ;;
5534 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5535
5536 (define_insn "*sse4_1_eqv2di3"
5537   [(set (match_operand:V2DI 0 "register_operand" "=x,x")
5538         (eq:V2DI
5539           (match_operand:V2DI 1 "nonimmediate_operand" "%0,x")
5540           (match_operand:V2DI 2 "nonimmediate_operand" "xm,xm")))]
5541   "TARGET_SSE4_1 && ix86_binary_operator_ok (EQ, V2DImode, operands)"
5542   "@
5543    pcmpeqq\t{%2, %0|%0, %2}
5544    vpcmpeqq\t{%2, %1, %0|%0, %1, %2}"
5545   [(set_attr "isa" "noavx,avx")
5546    (set_attr "type" "ssecmp")
5547    (set_attr "prefix_extra" "1")
5548    (set_attr "prefix" "orig,vex")
5549    (set_attr "mode" "TI")])
5550
5551 (define_insn "*sse2_eq<mode>3"
5552   [(set (match_operand:VI124_128 0 "register_operand" "=x,x")
5553         (eq:VI124_128
5554           (match_operand:VI124_128 1 "nonimmediate_operand" "%0,x")
5555           (match_operand:VI124_128 2 "nonimmediate_operand" "xm,xm")))]
5556   "TARGET_SSE2 && !TARGET_XOP
5557    && ix86_binary_operator_ok (EQ, <MODE>mode, operands)"
5558   "@
5559    pcmpeq<ssemodesuffix>\t{%2, %0|%0, %2}
5560    vpcmpeq<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
5561   [(set_attr "isa" "noavx,avx")
5562    (set_attr "type" "ssecmp")
5563    (set_attr "prefix_data16" "1,*")
5564    (set_attr "prefix" "orig,vex")
5565    (set_attr "mode" "TI")])
5566
5567 (define_expand "sse2_eq<mode>3"
5568   [(set (match_operand:VI124_128 0 "register_operand" "")
5569         (eq:VI124_128
5570           (match_operand:VI124_128 1 "nonimmediate_operand" "")
5571           (match_operand:VI124_128 2 "nonimmediate_operand" "")))]
5572   "TARGET_SSE2 && !TARGET_XOP "
5573   "ix86_fixup_binary_operands_no_copy (EQ, <MODE>mode, operands);")
5574
5575 (define_expand "sse4_1_eqv2di3"
5576   [(set (match_operand:V2DI 0 "register_operand" "")
5577         (eq:V2DI
5578           (match_operand:V2DI 1 "nonimmediate_operand" "")
5579           (match_operand:V2DI 2 "nonimmediate_operand" "")))]
5580   "TARGET_SSE4_1"
5581   "ix86_fixup_binary_operands_no_copy (EQ, V2DImode, operands);")
5582
5583 (define_insn "sse4_2_gtv2di3"
5584   [(set (match_operand:V2DI 0 "register_operand" "=x,x")
5585         (gt:V2DI
5586           (match_operand:V2DI 1 "register_operand" "0,x")
5587           (match_operand:V2DI 2 "nonimmediate_operand" "xm,xm")))]
5588   "TARGET_SSE4_2"
5589   "@
5590    pcmpgtq\t{%2, %0|%0, %2}
5591    vpcmpgtq\t{%2, %1, %0|%0, %1, %2}"
5592   [(set_attr "isa" "noavx,avx")
5593    (set_attr "type" "ssecmp")
5594    (set_attr "prefix_extra" "1")
5595    (set_attr "prefix" "orig,vex")
5596    (set_attr "mode" "TI")])
5597
5598 (define_insn "sse2_gt<mode>3"
5599   [(set (match_operand:VI124_128 0 "register_operand" "=x,x")
5600         (gt:VI124_128
5601           (match_operand:VI124_128 1 "register_operand" "0,x")
5602           (match_operand:VI124_128 2 "nonimmediate_operand" "xm,xm")))]
5603   "TARGET_SSE2 && !TARGET_XOP"
5604   "@
5605    pcmpgt<ssemodesuffix>\t{%2, %0|%0, %2}
5606    vpcmpgt<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
5607   [(set_attr "isa" "noavx,avx")
5608    (set_attr "type" "ssecmp")
5609    (set_attr "prefix_data16" "1,*")
5610    (set_attr "prefix" "orig,vex")
5611    (set_attr "mode" "TI")])
5612
5613 (define_expand "vcond<mode>"
5614   [(set (match_operand:VI124_128 0 "register_operand" "")
5615         (if_then_else:VI124_128
5616           (match_operator 3 ""
5617             [(match_operand:VI124_128 4 "nonimmediate_operand" "")
5618              (match_operand:VI124_128 5 "nonimmediate_operand" "")])
5619           (match_operand:VI124_128 1 "general_operand" "")
5620           (match_operand:VI124_128 2 "general_operand" "")))]
5621   "TARGET_SSE2"
5622 {
5623   bool ok = ix86_expand_int_vcond (operands);
5624   gcc_assert (ok);
5625   DONE;
5626 })
5627
5628 (define_expand "vcondv2di"
5629   [(set (match_operand:V2DI 0 "register_operand" "")
5630         (if_then_else:V2DI
5631           (match_operator 3 ""
5632             [(match_operand:V2DI 4 "nonimmediate_operand" "")
5633              (match_operand:V2DI 5 "nonimmediate_operand" "")])
5634           (match_operand:V2DI 1 "general_operand" "")
5635           (match_operand:V2DI 2 "general_operand" "")))]
5636   "TARGET_SSE4_2"
5637 {
5638   bool ok = ix86_expand_int_vcond (operands);
5639   gcc_assert (ok);
5640   DONE;
5641 })
5642
5643 (define_expand "vcondu<mode>"
5644   [(set (match_operand:VI124_128 0 "register_operand" "")
5645         (if_then_else:VI124_128
5646           (match_operator 3 ""
5647             [(match_operand:VI124_128 4 "nonimmediate_operand" "")
5648              (match_operand:VI124_128 5 "nonimmediate_operand" "")])
5649           (match_operand:VI124_128 1 "general_operand" "")
5650           (match_operand:VI124_128 2 "general_operand" "")))]
5651   "TARGET_SSE2"
5652 {
5653   bool ok = ix86_expand_int_vcond (operands);
5654   gcc_assert (ok);
5655   DONE;
5656 })
5657
5658 (define_expand "vconduv2di"
5659   [(set (match_operand:V2DI 0 "register_operand" "")
5660         (if_then_else:V2DI
5661           (match_operator 3 ""
5662             [(match_operand:V2DI 4 "nonimmediate_operand" "")
5663              (match_operand:V2DI 5 "nonimmediate_operand" "")])
5664           (match_operand:V2DI 1 "general_operand" "")
5665           (match_operand:V2DI 2 "general_operand" "")))]
5666   "TARGET_SSE4_2"
5667 {
5668   bool ok = ix86_expand_int_vcond (operands);
5669   gcc_assert (ok);
5670   DONE;
5671 })
5672
5673 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5674 ;;
5675 ;; Parallel bitwise logical operations
5676 ;;
5677 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5678
5679 (define_expand "one_cmpl<mode>2"
5680   [(set (match_operand:VI 0 "register_operand" "")
5681         (xor:VI (match_operand:VI 1 "nonimmediate_operand" "")
5682                 (match_dup 2)))]
5683   "TARGET_SSE"
5684 {
5685   int i, n = GET_MODE_NUNITS (<MODE>mode);
5686   rtvec v = rtvec_alloc (n);
5687
5688   for (i = 0; i < n; ++i)
5689     RTVEC_ELT (v, i) = constm1_rtx;
5690
5691   operands[2] = force_reg (<MODE>mode, gen_rtx_CONST_VECTOR (<MODE>mode, v));
5692 })
5693
5694 (define_expand "sse2_andnot<mode>3"
5695   [(set (match_operand:VI_128 0 "register_operand" "")
5696         (and:VI_128
5697           (not:VI_128 (match_operand:VI_128 1 "register_operand" ""))
5698           (match_operand:VI_128 2 "nonimmediate_operand" "")))]
5699   "TARGET_SSE2")
5700
5701 (define_insn "*andnot<mode>3"
5702   [(set (match_operand:VI 0 "register_operand" "=x,x")
5703         (and:VI
5704           (not:VI (match_operand:VI 1 "register_operand" "0,x"))
5705           (match_operand:VI 2 "nonimmediate_operand" "xm,xm")))]
5706   "TARGET_SSE"
5707 {
5708   static char buf[32];
5709   const char *ops;
5710   const char *tmp
5711     = (get_attr_mode (insn) == MODE_TI) ? "pandn" : "andnps";
5712
5713   switch (which_alternative)
5714     {
5715     case 0:
5716       ops = "%s\t{%%2, %%0|%%0, %%2}";
5717       break;
5718     case 1:
5719       ops = "v%s\t{%%2, %%1, %%0|%%0, %%1, %%2}";
5720       break;
5721     default:
5722       gcc_unreachable ();
5723     }
5724
5725   snprintf (buf, sizeof (buf), ops, tmp);
5726   return buf;
5727 }
5728   [(set_attr "isa" "noavx,avx")
5729    (set_attr "type" "sselog")
5730    (set (attr "prefix_data16")
5731      (if_then_else
5732        (and (eq_attr "alternative" "0")
5733             (eq_attr "mode" "TI"))
5734        (const_string "1")
5735        (const_string "*")))
5736    (set_attr "prefix" "orig,vex")
5737    (set (attr "mode")
5738      (cond [(ne (symbol_ref "GET_MODE_SIZE (<MODE>mode) > 128") (const_int 0))
5739               (const_string "V8SF")
5740             (ne (symbol_ref "TARGET_SSE2") (const_int 0))
5741               (const_string "TI")
5742            ]
5743            (const_string "V4SF")))])
5744
5745 (define_expand "<code><mode>3"
5746   [(set (match_operand:VI 0 "register_operand" "")
5747         (any_logic:VI
5748           (match_operand:VI 1 "nonimmediate_operand" "")
5749           (match_operand:VI 2 "nonimmediate_operand" "")))]
5750   "TARGET_SSE"
5751   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
5752
5753 (define_insn "*<code><mode>3"
5754   [(set (match_operand:VI 0 "register_operand" "=x,x")
5755         (any_logic:VI
5756           (match_operand:VI 1 "nonimmediate_operand" "%0,x")
5757           (match_operand:VI 2 "nonimmediate_operand" "xm,xm")))]
5758   "TARGET_SSE
5759    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5760 {
5761   static char buf[32];
5762   const char *ops;
5763   const char *tmp
5764     = (get_attr_mode (insn) == MODE_TI) ? "p<logic>" : "<logic>ps";
5765
5766   switch (which_alternative)
5767     {
5768     case 0:
5769       ops = "%s\t{%%2, %%0|%%0, %%2}";
5770       break;
5771     case 1:
5772       ops = "v%s\t{%%2, %%1, %%0|%%0, %%1, %%2}";
5773       break;
5774     default:
5775       gcc_unreachable ();
5776     }
5777
5778   snprintf (buf, sizeof (buf), ops, tmp);
5779   return buf;
5780 }
5781   [(set_attr "isa" "noavx,avx")
5782    (set_attr "type" "sselog")
5783    (set (attr "prefix_data16")
5784      (if_then_else
5785        (and (eq_attr "alternative" "0")
5786             (eq_attr "mode" "TI"))
5787        (const_string "1")
5788        (const_string "*")))
5789    (set_attr "prefix" "orig,vex")
5790    (set (attr "mode")
5791      (cond [(ne (symbol_ref "GET_MODE_SIZE (<MODE>mode) > 128") (const_int 0))
5792               (const_string "V8SF")
5793             (ne (symbol_ref "TARGET_SSE2") (const_int 0))
5794               (const_string "TI")
5795            ]
5796            (const_string "V4SF")))])
5797
5798 (define_insn "*andnottf3"
5799   [(set (match_operand:TF 0 "register_operand" "=x,x")
5800         (and:TF
5801           (not:TF (match_operand:TF 1 "register_operand" "0,x"))
5802           (match_operand:TF 2 "nonimmediate_operand" "xm,xm")))]
5803   "TARGET_SSE2"
5804   "@
5805    pandn\t{%2, %0|%0, %2}
5806    vpandn\t{%2, %1, %0|%0, %1, %2}"
5807   [(set_attr "isa" "noavx,avx")
5808    (set_attr "type" "sselog")
5809    (set_attr "prefix_data16" "1,*")
5810    (set_attr "prefix" "orig,vex")
5811    (set_attr "mode" "TI")])
5812
5813 (define_expand "<code>tf3"
5814   [(set (match_operand:TF 0 "register_operand" "")
5815         (any_logic:TF
5816           (match_operand:TF 1 "nonimmediate_operand" "")
5817           (match_operand:TF 2 "nonimmediate_operand" "")))]
5818   "TARGET_SSE2"
5819   "ix86_fixup_binary_operands_no_copy (<CODE>, TFmode, operands);")
5820
5821 (define_insn "*<code>tf3"
5822   [(set (match_operand:TF 0 "register_operand" "=x,x")
5823         (any_logic:TF
5824           (match_operand:TF 1 "nonimmediate_operand" "%0,x")
5825           (match_operand:TF 2 "nonimmediate_operand" "xm,xm")))]
5826   "TARGET_SSE2
5827    && ix86_binary_operator_ok (<CODE>, TFmode, operands)"
5828   "@
5829    p<logic>\t{%2, %0|%0, %2}
5830    vp<logic>\t{%2, %1, %0|%0, %1, %2}"
5831   [(set_attr "isa" "noavx,avx")
5832    (set_attr "type" "sselog")
5833    (set_attr "prefix_data16" "1,*")
5834    (set_attr "prefix" "orig,vex")
5835    (set_attr "mode" "TI")])
5836
5837 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5838 ;;
5839 ;; Parallel integral element swizzling
5840 ;;
5841 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5842
5843 (define_expand "vec_pack_trunc_<mode>"
5844   [(match_operand:<ssepackmode> 0 "register_operand" "")
5845    (match_operand:VI248_128 1 "register_operand" "")
5846    (match_operand:VI248_128 2 "register_operand" "")]
5847   "TARGET_SSE2"
5848 {
5849   rtx op1 = gen_lowpart (<ssepackmode>mode, operands[1]);
5850   rtx op2 = gen_lowpart (<ssepackmode>mode, operands[2]);
5851   ix86_expand_vec_extract_even_odd (operands[0], op1, op2, 0);
5852   DONE;
5853 })
5854
5855 (define_insn "sse2_packsswb"
5856   [(set (match_operand:V16QI 0 "register_operand" "=x,x")
5857         (vec_concat:V16QI
5858           (ss_truncate:V8QI
5859             (match_operand:V8HI 1 "register_operand" "0,x"))
5860           (ss_truncate:V8QI
5861             (match_operand:V8HI 2 "nonimmediate_operand" "xm,xm"))))]
5862   "TARGET_SSE2"
5863   "@
5864    packsswb\t{%2, %0|%0, %2}
5865    vpacksswb\t{%2, %1, %0|%0, %1, %2}"
5866   [(set_attr "isa" "noavx,avx")
5867    (set_attr "type" "sselog")
5868    (set_attr "prefix_data16" "1,*")
5869    (set_attr "prefix" "orig,vex")
5870    (set_attr "mode" "TI")])
5871
5872 (define_insn "sse2_packssdw"
5873   [(set (match_operand:V8HI 0 "register_operand" "=x,x")
5874         (vec_concat:V8HI
5875           (ss_truncate:V4HI
5876             (match_operand:V4SI 1 "register_operand" "0,x"))
5877           (ss_truncate:V4HI
5878             (match_operand:V4SI 2 "nonimmediate_operand" "xm,xm"))))]
5879   "TARGET_SSE2"
5880   "@
5881    packssdw\t{%2, %0|%0, %2}
5882    vpackssdw\t{%2, %1, %0|%0, %1, %2}"
5883   [(set_attr "isa" "noavx,avx")
5884    (set_attr "type" "sselog")
5885    (set_attr "prefix_data16" "1,*")
5886    (set_attr "prefix" "orig,vex")
5887    (set_attr "mode" "TI")])
5888
5889 (define_insn "sse2_packuswb"
5890   [(set (match_operand:V16QI 0 "register_operand" "=x,x")
5891         (vec_concat:V16QI
5892           (us_truncate:V8QI
5893             (match_operand:V8HI 1 "register_operand" "0,x"))
5894           (us_truncate:V8QI
5895             (match_operand:V8HI 2 "nonimmediate_operand" "xm,xm"))))]
5896   "TARGET_SSE2"
5897   "@
5898    packuswb\t{%2, %0|%0, %2}
5899    vpackuswb\t{%2, %1, %0|%0, %1, %2}"
5900   [(set_attr "isa" "noavx,avx")
5901    (set_attr "type" "sselog")
5902    (set_attr "prefix_data16" "1,*")
5903    (set_attr "prefix" "orig,vex")
5904    (set_attr "mode" "TI")])
5905
5906 (define_insn "vec_interleave_highv16qi"
5907   [(set (match_operand:V16QI 0 "register_operand" "=x,x")
5908         (vec_select:V16QI
5909           (vec_concat:V32QI
5910             (match_operand:V16QI 1 "register_operand" "0,x")
5911             (match_operand:V16QI 2 "nonimmediate_operand" "xm,xm"))
5912           (parallel [(const_int 8)  (const_int 24)
5913                      (const_int 9)  (const_int 25)
5914                      (const_int 10) (const_int 26)
5915                      (const_int 11) (const_int 27)
5916                      (const_int 12) (const_int 28)
5917                      (const_int 13) (const_int 29)
5918                      (const_int 14) (const_int 30)
5919                      (const_int 15) (const_int 31)])))]
5920   "TARGET_SSE2"
5921   "@
5922    punpckhbw\t{%2, %0|%0, %2}
5923    vpunpckhbw\t{%2, %1, %0|%0, %1, %2}"
5924   [(set_attr "isa" "noavx,avx")
5925    (set_attr "type" "sselog")
5926    (set_attr "prefix_data16" "1,*")
5927    (set_attr "prefix" "orig,vex")
5928    (set_attr "mode" "TI")])
5929
5930 (define_insn "vec_interleave_lowv16qi"
5931   [(set (match_operand:V16QI 0 "register_operand" "=x,x")
5932         (vec_select:V16QI
5933           (vec_concat:V32QI
5934             (match_operand:V16QI 1 "register_operand" "0,x")
5935             (match_operand:V16QI 2 "nonimmediate_operand" "xm,xm"))
5936           (parallel [(const_int 0) (const_int 16)
5937                      (const_int 1) (const_int 17)
5938                      (const_int 2) (const_int 18)
5939                      (const_int 3) (const_int 19)
5940                      (const_int 4) (const_int 20)
5941                      (const_int 5) (const_int 21)
5942                      (const_int 6) (const_int 22)
5943                      (const_int 7) (const_int 23)])))]
5944   "TARGET_SSE2"
5945   "@
5946    punpcklbw\t{%2, %0|%0, %2}
5947    vpunpcklbw\t{%2, %1, %0|%0, %1, %2}"
5948   [(set_attr "isa" "noavx,avx")
5949    (set_attr "type" "sselog")
5950    (set_attr "prefix_data16" "1,*")
5951    (set_attr "prefix" "orig,vex")
5952    (set_attr "mode" "TI")])
5953
5954 (define_insn "vec_interleave_highv8hi"
5955   [(set (match_operand:V8HI 0 "register_operand" "=x,x")
5956         (vec_select:V8HI
5957           (vec_concat:V16HI
5958             (match_operand:V8HI 1 "register_operand" "0,x")
5959             (match_operand:V8HI 2 "nonimmediate_operand" "xm,xm"))
5960           (parallel [(const_int 4) (const_int 12)
5961                      (const_int 5) (const_int 13)
5962                      (const_int 6) (const_int 14)
5963                      (const_int 7) (const_int 15)])))]
5964   "TARGET_SSE2"
5965   "@
5966    punpckhwd\t{%2, %0|%0, %2}
5967    vpunpckhwd\t{%2, %1, %0|%0, %1, %2}"
5968   [(set_attr "isa" "noavx,avx")
5969    (set_attr "type" "sselog")
5970    (set_attr "prefix_data16" "1,*")
5971    (set_attr "prefix" "orig,vex")
5972    (set_attr "mode" "TI")])
5973
5974 (define_insn "vec_interleave_lowv8hi"
5975   [(set (match_operand:V8HI 0 "register_operand" "=x,x")
5976         (vec_select:V8HI
5977           (vec_concat:V16HI
5978             (match_operand:V8HI 1 "register_operand" "0,x")
5979             (match_operand:V8HI 2 "nonimmediate_operand" "xm,xm"))
5980           (parallel [(const_int 0) (const_int 8)
5981                      (const_int 1) (const_int 9)
5982                      (const_int 2) (const_int 10)
5983                      (const_int 3) (const_int 11)])))]
5984   "TARGET_SSE2"
5985   "@
5986    punpcklwd\t{%2, %0|%0, %2}
5987    vpunpcklwd\t{%2, %1, %0|%0, %1, %2}"
5988   [(set_attr "isa" "noavx,avx")
5989    (set_attr "type" "sselog")
5990    (set_attr "prefix_data16" "1,*")
5991    (set_attr "prefix" "orig,vex")
5992    (set_attr "mode" "TI")])
5993
5994 (define_insn "vec_interleave_highv4si"
5995   [(set (match_operand:V4SI 0 "register_operand" "=x,x")
5996         (vec_select:V4SI
5997           (vec_concat:V8SI
5998             (match_operand:V4SI 1 "register_operand" "0,x")
5999             (match_operand:V4SI 2 "nonimmediate_operand" "xm,xm"))
6000           (parallel [(const_int 2) (const_int 6)
6001                      (const_int 3) (const_int 7)])))]
6002   "TARGET_SSE2"
6003   "@
6004    punpckhdq\t{%2, %0|%0, %2}
6005    vpunpckhdq\t{%2, %1, %0|%0, %1, %2}"
6006   [(set_attr "isa" "noavx,avx")
6007    (set_attr "type" "sselog")
6008    (set_attr "prefix_data16" "1,*")
6009    (set_attr "prefix" "orig,vex")
6010    (set_attr "mode" "TI")])
6011
6012 (define_insn "vec_interleave_lowv4si"
6013   [(set (match_operand:V4SI 0 "register_operand" "=x,x")
6014         (vec_select:V4SI
6015           (vec_concat:V8SI
6016             (match_operand:V4SI 1 "register_operand" "0,x")
6017             (match_operand:V4SI 2 "nonimmediate_operand" "xm,xm"))
6018           (parallel [(const_int 0) (const_int 4)
6019                      (const_int 1) (const_int 5)])))]
6020   "TARGET_SSE2"
6021   "@
6022    punpckldq\t{%2, %0|%0, %2}
6023    vpunpckldq\t{%2, %1, %0|%0, %1, %2}"
6024   [(set_attr "isa" "noavx,avx")
6025    (set_attr "type" "sselog")
6026    (set_attr "prefix_data16" "1,*")
6027    (set_attr "prefix" "orig,vex")
6028    (set_attr "mode" "TI")])
6029
6030 ;; Modes handled by pinsr patterns.
6031 (define_mode_iterator PINSR_MODE
6032   [(V16QI "TARGET_SSE4_1") V8HI
6033    (V4SI "TARGET_SSE4_1")
6034    (V2DI "TARGET_SSE4_1 && TARGET_64BIT")])
6035
6036 (define_mode_attr sse2p4_1
6037   [(V16QI "sse4_1") (V8HI "sse2")
6038    (V4SI "sse4_1") (V2DI "sse4_1")])
6039
6040 ;; sse4_1_pinsrd must come before sse2_loadld since it is preferred.
6041 (define_insn "<sse2p4_1>_pinsr<ssemodesuffix>"
6042   [(set (match_operand:PINSR_MODE 0 "register_operand" "=x,x,x,x")
6043         (vec_merge:PINSR_MODE
6044           (vec_duplicate:PINSR_MODE
6045             (match_operand:<ssescalarmode> 2 "nonimmediate_operand" "r,m,r,m"))
6046           (match_operand:PINSR_MODE 1 "register_operand" "0,0,x,x")
6047           (match_operand:SI 3 "const_int_operand" "")))]
6048   "TARGET_SSE2
6049    && ((unsigned) exact_log2 (INTVAL (operands[3]))
6050        < GET_MODE_NUNITS (<MODE>mode))"
6051 {
6052   operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
6053
6054   switch (which_alternative)
6055     {
6056     case 0:
6057       if (GET_MODE_SIZE (<ssescalarmode>mode) < GET_MODE_SIZE (SImode))
6058         return "pinsr<ssemodesuffix>\t{%3, %k2, %0|%0, %k2, %3}";
6059       /* FALLTHRU */
6060     case 1:
6061       return "pinsr<ssemodesuffix>\t{%3, %2, %0|%0, %2, %3}";
6062     case 2:
6063       if (GET_MODE_SIZE (<ssescalarmode>mode) < GET_MODE_SIZE (SImode))
6064         return "vpinsr<ssemodesuffix>\t{%3, %k2, %1, %0|%0, %1, %k2, %3}";
6065       /* FALLTHRU */
6066     case 3:
6067       return "vpinsr<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}";
6068     default:
6069       gcc_unreachable ();
6070     }
6071 }
6072   [(set_attr "isa" "noavx,noavx,avx,avx")
6073    (set_attr "type" "sselog")
6074    (set (attr "prefix_rex")
6075      (if_then_else
6076        (and (eq (symbol_ref "TARGET_AVX") (const_int 0))
6077             (eq (const_string "<MODE>mode") (const_string "V2DImode")))
6078        (const_string "1")
6079        (const_string "*")))
6080    (set (attr "prefix_data16")
6081      (if_then_else
6082        (and (eq (symbol_ref "TARGET_AVX") (const_int 0))
6083             (eq (const_string "<MODE>mode") (const_string "V8HImode")))
6084        (const_string "1")
6085        (const_string "*")))
6086    (set (attr "prefix_extra")
6087      (if_then_else
6088        (and (eq (symbol_ref "TARGET_AVX") (const_int 0))
6089             (eq (const_string "<MODE>mode") (const_string "V8HImode")))
6090        (const_string "*")
6091        (const_string "1")))
6092    (set_attr "length_immediate" "1")
6093    (set_attr "prefix" "orig,orig,vex,vex")
6094    (set_attr "mode" "TI")])
6095
6096 (define_insn "*sse4_1_pextrb_<mode>"
6097   [(set (match_operand:SWI48 0 "register_operand" "=r")
6098         (zero_extend:SWI48
6099           (vec_select:QI
6100             (match_operand:V16QI 1 "register_operand" "x")
6101             (parallel [(match_operand:SI 2 "const_0_to_15_operand" "n")]))))]
6102   "TARGET_SSE4_1"
6103   "%vpextrb\t{%2, %1, %k0|%k0, %1, %2}"
6104   [(set_attr "type" "sselog")
6105    (set_attr "prefix_extra" "1")
6106    (set_attr "length_immediate" "1")
6107    (set_attr "prefix" "maybe_vex")
6108    (set_attr "mode" "TI")])
6109
6110 (define_insn "*sse4_1_pextrb_memory"
6111   [(set (match_operand:QI 0 "memory_operand" "=m")
6112         (vec_select:QI
6113           (match_operand:V16QI 1 "register_operand" "x")
6114           (parallel [(match_operand:SI 2 "const_0_to_15_operand" "n")])))]
6115   "TARGET_SSE4_1"
6116   "%vpextrb\t{%2, %1, %0|%0, %1, %2}"
6117   [(set_attr "type" "sselog")
6118    (set_attr "prefix_extra" "1")
6119    (set_attr "length_immediate" "1")
6120    (set_attr "prefix" "maybe_vex")
6121    (set_attr "mode" "TI")])
6122
6123 (define_insn "*sse2_pextrw_<mode>"
6124   [(set (match_operand:SWI48 0 "register_operand" "=r")
6125         (zero_extend:SWI48
6126           (vec_select:HI
6127             (match_operand:V8HI 1 "register_operand" "x")
6128             (parallel [(match_operand:SI 2 "const_0_to_7_operand" "n")]))))]
6129   "TARGET_SSE2"
6130   "%vpextrw\t{%2, %1, %k0|%k0, %1, %2}"
6131   [(set_attr "type" "sselog")
6132    (set_attr "prefix_data16" "1")
6133    (set_attr "length_immediate" "1")
6134    (set_attr "prefix" "maybe_vex")
6135    (set_attr "mode" "TI")])
6136
6137 (define_insn "*sse4_1_pextrw_memory"
6138   [(set (match_operand:HI 0 "memory_operand" "=m")
6139         (vec_select:HI
6140           (match_operand:V8HI 1 "register_operand" "x")
6141           (parallel [(match_operand:SI 2 "const_0_to_7_operand" "n")])))]
6142   "TARGET_SSE4_1"
6143   "%vpextrw\t{%2, %1, %0|%0, %1, %2}"
6144   [(set_attr "type" "sselog")
6145    (set_attr "prefix_extra" "1")
6146    (set_attr "length_immediate" "1")
6147    (set_attr "prefix" "maybe_vex")
6148    (set_attr "mode" "TI")])
6149
6150 (define_insn "*sse4_1_pextrd"
6151   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
6152         (vec_select:SI
6153           (match_operand:V4SI 1 "register_operand" "x")
6154           (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n")])))]
6155   "TARGET_SSE4_1"
6156   "%vpextrd\t{%2, %1, %0|%0, %1, %2}"
6157   [(set_attr "type" "sselog")
6158    (set_attr "prefix_extra" "1")
6159    (set_attr "length_immediate" "1")
6160    (set_attr "prefix" "maybe_vex")
6161    (set_attr "mode" "TI")])
6162
6163 (define_insn "*sse4_1_pextrd_zext"
6164   [(set (match_operand:DI 0 "register_operand" "=r")
6165         (zero_extend:DI
6166           (vec_select:SI
6167             (match_operand:V4SI 1 "register_operand" "x")
6168             (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n")]))))]
6169   "TARGET_64BIT && TARGET_SSE4_1"
6170   "%vpextrd\t{%2, %1, %k0|%k0, %1, %2}"
6171   [(set_attr "type" "sselog")
6172    (set_attr "prefix_extra" "1")
6173    (set_attr "length_immediate" "1")
6174    (set_attr "prefix" "maybe_vex")
6175    (set_attr "mode" "TI")])
6176
6177 ;; It must come before *vec_extractv2di_1_rex64 since it is preferred.
6178 (define_insn "*sse4_1_pextrq"
6179   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
6180         (vec_select:DI
6181           (match_operand:V2DI 1 "register_operand" "x")
6182           (parallel [(match_operand:SI 2 "const_0_to_1_operand" "n")])))]
6183   "TARGET_SSE4_1 && TARGET_64BIT"
6184   "%vpextrq\t{%2, %1, %0|%0, %1, %2}"
6185   [(set_attr "type" "sselog")
6186    (set_attr "prefix_rex" "1")
6187    (set_attr "prefix_extra" "1")
6188    (set_attr "length_immediate" "1")
6189    (set_attr "prefix" "maybe_vex")
6190    (set_attr "mode" "TI")])
6191
6192 (define_expand "sse2_pshufd"
6193   [(match_operand:V4SI 0 "register_operand" "")
6194    (match_operand:V4SI 1 "nonimmediate_operand" "")
6195    (match_operand:SI 2 "const_int_operand" "")]
6196   "TARGET_SSE2"
6197 {
6198   int mask = INTVAL (operands[2]);
6199   emit_insn (gen_sse2_pshufd_1 (operands[0], operands[1],
6200                                 GEN_INT ((mask >> 0) & 3),
6201                                 GEN_INT ((mask >> 2) & 3),
6202                                 GEN_INT ((mask >> 4) & 3),
6203                                 GEN_INT ((mask >> 6) & 3)));
6204   DONE;
6205 })
6206
6207 (define_insn "sse2_pshufd_1"
6208   [(set (match_operand:V4SI 0 "register_operand" "=x")
6209         (vec_select:V4SI
6210           (match_operand:V4SI 1 "nonimmediate_operand" "xm")
6211           (parallel [(match_operand 2 "const_0_to_3_operand" "")
6212                      (match_operand 3 "const_0_to_3_operand" "")
6213                      (match_operand 4 "const_0_to_3_operand" "")
6214                      (match_operand 5 "const_0_to_3_operand" "")])))]
6215   "TARGET_SSE2"
6216 {
6217   int mask = 0;
6218   mask |= INTVAL (operands[2]) << 0;
6219   mask |= INTVAL (operands[3]) << 2;
6220   mask |= INTVAL (operands[4]) << 4;
6221   mask |= INTVAL (operands[5]) << 6;
6222   operands[2] = GEN_INT (mask);
6223
6224   return "%vpshufd\t{%2, %1, %0|%0, %1, %2}";
6225 }
6226   [(set_attr "type" "sselog1")
6227    (set_attr "prefix_data16" "1")
6228    (set_attr "prefix" "maybe_vex")
6229    (set_attr "length_immediate" "1")
6230    (set_attr "mode" "TI")])
6231
6232 (define_expand "sse2_pshuflw"
6233   [(match_operand:V8HI 0 "register_operand" "")
6234    (match_operand:V8HI 1 "nonimmediate_operand" "")
6235    (match_operand:SI 2 "const_int_operand" "")]
6236   "TARGET_SSE2"
6237 {
6238   int mask = INTVAL (operands[2]);
6239   emit_insn (gen_sse2_pshuflw_1 (operands[0], operands[1],
6240                                  GEN_INT ((mask >> 0) & 3),
6241                                  GEN_INT ((mask >> 2) & 3),
6242                                  GEN_INT ((mask >> 4) & 3),
6243                                  GEN_INT ((mask >> 6) & 3)));
6244   DONE;
6245 })
6246
6247 (define_insn "sse2_pshuflw_1"
6248   [(set (match_operand:V8HI 0 "register_operand" "=x")
6249         (vec_select:V8HI
6250           (match_operand:V8HI 1 "nonimmediate_operand" "xm")
6251           (parallel [(match_operand 2 "const_0_to_3_operand" "")
6252                      (match_operand 3 "const_0_to_3_operand" "")
6253                      (match_operand 4 "const_0_to_3_operand" "")
6254                      (match_operand 5 "const_0_to_3_operand" "")
6255                      (const_int 4)
6256                      (const_int 5)
6257                      (const_int 6)
6258                      (const_int 7)])))]
6259   "TARGET_SSE2"
6260 {
6261   int mask = 0;
6262   mask |= INTVAL (operands[2]) << 0;
6263   mask |= INTVAL (operands[3]) << 2;
6264   mask |= INTVAL (operands[4]) << 4;
6265   mask |= INTVAL (operands[5]) << 6;
6266   operands[2] = GEN_INT (mask);
6267
6268   return "%vpshuflw\t{%2, %1, %0|%0, %1, %2}";
6269 }
6270   [(set_attr "type" "sselog")
6271    (set_attr "prefix_data16" "0")
6272    (set_attr "prefix_rep" "1")
6273    (set_attr "prefix" "maybe_vex")
6274    (set_attr "length_immediate" "1")
6275    (set_attr "mode" "TI")])
6276
6277 (define_expand "sse2_pshufhw"
6278   [(match_operand:V8HI 0 "register_operand" "")
6279    (match_operand:V8HI 1 "nonimmediate_operand" "")
6280    (match_operand:SI 2 "const_int_operand" "")]
6281   "TARGET_SSE2"
6282 {
6283   int mask = INTVAL (operands[2]);
6284   emit_insn (gen_sse2_pshufhw_1 (operands[0], operands[1],
6285                                  GEN_INT (((mask >> 0) & 3) + 4),
6286                                  GEN_INT (((mask >> 2) & 3) + 4),
6287                                  GEN_INT (((mask >> 4) & 3) + 4),
6288                                  GEN_INT (((mask >> 6) & 3) + 4)));
6289   DONE;
6290 })
6291
6292 (define_insn "sse2_pshufhw_1"
6293   [(set (match_operand:V8HI 0 "register_operand" "=x")
6294         (vec_select:V8HI
6295           (match_operand:V8HI 1 "nonimmediate_operand" "xm")
6296           (parallel [(const_int 0)
6297                      (const_int 1)
6298                      (const_int 2)
6299                      (const_int 3)
6300                      (match_operand 2 "const_4_to_7_operand" "")
6301                      (match_operand 3 "const_4_to_7_operand" "")
6302                      (match_operand 4 "const_4_to_7_operand" "")
6303                      (match_operand 5 "const_4_to_7_operand" "")])))]
6304   "TARGET_SSE2"
6305 {
6306   int mask = 0;
6307   mask |= (INTVAL (operands[2]) - 4) << 0;
6308   mask |= (INTVAL (operands[3]) - 4) << 2;
6309   mask |= (INTVAL (operands[4]) - 4) << 4;
6310   mask |= (INTVAL (operands[5]) - 4) << 6;
6311   operands[2] = GEN_INT (mask);
6312
6313   return "%vpshufhw\t{%2, %1, %0|%0, %1, %2}";
6314 }
6315   [(set_attr "type" "sselog")
6316    (set_attr "prefix_rep" "1")
6317    (set_attr "prefix_data16" "0")
6318    (set_attr "prefix" "maybe_vex")
6319    (set_attr "length_immediate" "1")
6320    (set_attr "mode" "TI")])
6321
6322 (define_expand "sse2_loadd"
6323   [(set (match_operand:V4SI 0 "register_operand" "")
6324         (vec_merge:V4SI
6325           (vec_duplicate:V4SI
6326             (match_operand:SI 1 "nonimmediate_operand" ""))
6327           (match_dup 2)
6328           (const_int 1)))]
6329   "TARGET_SSE"
6330   "operands[2] = CONST0_RTX (V4SImode);")
6331
6332 (define_insn "sse2_loadld"
6333   [(set (match_operand:V4SI 0 "register_operand"       "=Y2,Yi,x,x,x")
6334         (vec_merge:V4SI
6335           (vec_duplicate:V4SI
6336             (match_operand:SI 2 "nonimmediate_operand" "m  ,r ,m,x,x"))
6337           (match_operand:V4SI 1 "reg_or_0_operand"     "C  ,C ,C,0,x")
6338           (const_int 1)))]
6339   "TARGET_SSE"
6340   "@
6341    %vmovd\t{%2, %0|%0, %2}
6342    %vmovd\t{%2, %0|%0, %2}
6343    movss\t{%2, %0|%0, %2}
6344    movss\t{%2, %0|%0, %2}
6345    vmovss\t{%2, %1, %0|%0, %1, %2}"
6346   [(set_attr "isa" "*,*,noavx,noavx,avx")
6347    (set_attr "type" "ssemov")
6348    (set_attr "prefix" "maybe_vex,maybe_vex,orig,orig,vex")
6349    (set_attr "mode" "TI,TI,V4SF,SF,SF")])
6350
6351 (define_insn_and_split "sse2_stored"
6352   [(set (match_operand:SI 0 "nonimmediate_operand" "=xm,r")
6353         (vec_select:SI
6354           (match_operand:V4SI 1 "register_operand" "x,Yi")
6355           (parallel [(const_int 0)])))]
6356   "TARGET_SSE"
6357   "#"
6358   "&& reload_completed
6359    && (TARGET_INTER_UNIT_MOVES
6360        || MEM_P (operands [0])
6361        || !GENERAL_REGNO_P (true_regnum (operands [0])))"
6362   [(set (match_dup 0) (match_dup 1))]
6363   "operands[1] = gen_rtx_REG (SImode, REGNO (operands[1]));")
6364
6365 (define_insn_and_split "*vec_ext_v4si_mem"
6366   [(set (match_operand:SI 0 "register_operand" "=r")
6367         (vec_select:SI
6368           (match_operand:V4SI 1 "memory_operand" "o")
6369           (parallel [(match_operand 2 "const_0_to_3_operand" "")])))]
6370   ""
6371   "#"
6372   "reload_completed"
6373   [(const_int 0)]
6374 {
6375   int i = INTVAL (operands[2]);
6376
6377   emit_move_insn (operands[0], adjust_address (operands[1], SImode, i*4));
6378   DONE;
6379 })
6380
6381 (define_expand "sse_storeq"
6382   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6383         (vec_select:DI
6384           (match_operand:V2DI 1 "register_operand" "")
6385           (parallel [(const_int 0)])))]
6386   "TARGET_SSE")
6387
6388 (define_insn "*sse2_storeq_rex64"
6389   [(set (match_operand:DI 0 "nonimmediate_operand" "=xm,*r,r")
6390         (vec_select:DI
6391           (match_operand:V2DI 1 "nonimmediate_operand" "x,Yi,o")
6392           (parallel [(const_int 0)])))]
6393   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6394   "@
6395    #
6396    #
6397    mov{q}\t{%1, %0|%0, %1}"
6398   [(set_attr "type" "*,*,imov")
6399    (set_attr "mode" "*,*,DI")])
6400
6401 (define_insn "*sse2_storeq"
6402   [(set (match_operand:DI 0 "nonimmediate_operand" "=xm")
6403         (vec_select:DI
6404           (match_operand:V2DI 1 "register_operand" "x")
6405           (parallel [(const_int 0)])))]
6406   "TARGET_SSE"
6407   "#")
6408
6409 (define_split
6410   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6411         (vec_select:DI
6412           (match_operand:V2DI 1 "register_operand" "")
6413           (parallel [(const_int 0)])))]
6414   "TARGET_SSE
6415    && reload_completed
6416    && (TARGET_INTER_UNIT_MOVES
6417        || MEM_P (operands [0])
6418        || !GENERAL_REGNO_P (true_regnum (operands [0])))"
6419   [(set (match_dup 0) (match_dup 1))]
6420   "operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
6421
6422 (define_insn "*vec_extractv2di_1_rex64"
6423   [(set (match_operand:DI 0 "nonimmediate_operand"     "=m,x,x,x,r")
6424         (vec_select:DI
6425           (match_operand:V2DI 1 "nonimmediate_operand" " x,0,x,o,o")
6426           (parallel [(const_int 1)])))]
6427   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6428   "@
6429    %vmovhps\t{%1, %0|%0, %1}
6430    psrldq\t{$8, %0|%0, 8}
6431    vpsrldq\t{$8, %1, %0|%0, %1, 8}
6432    %vmovq\t{%H1, %0|%0, %H1}
6433    mov{q}\t{%H1, %0|%0, %H1}"
6434   [(set_attr "isa" "*,noavx,avx,*,*")
6435    (set_attr "type" "ssemov,sseishft1,sseishft1,ssemov,imov")
6436    (set_attr "length_immediate" "*,1,1,*,*")
6437    (set_attr "memory" "*,none,none,*,*")
6438    (set_attr "prefix" "maybe_vex,orig,vex,maybe_vex,orig")
6439    (set_attr "mode" "V2SF,TI,TI,TI,DI")])
6440
6441 (define_insn "*vec_extractv2di_1"
6442   [(set (match_operand:DI 0 "nonimmediate_operand"     "=m,Y2,Y2,Y2,x,x")
6443         (vec_select:DI
6444           (match_operand:V2DI 1 "nonimmediate_operand" " x,0 ,Y2,o ,x,o")
6445           (parallel [(const_int 1)])))]
6446   "!TARGET_64BIT && TARGET_SSE
6447    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6448   "@
6449    %vmovhps\t{%1, %0|%0, %1}
6450    psrldq\t{$8, %0|%0, 8}
6451    vpsrldq\t{$8, %1, %0|%0, %1, 8}
6452    %vmovq\t{%H1, %0|%0, %H1}
6453    movhlps\t{%1, %0|%0, %1}
6454    movlps\t{%H1, %0|%0, %H1}"
6455   [(set_attr "isa" "*,noavx,avx,*,noavx,noavx")
6456    (set_attr "type" "ssemov,sseishft1,sseishft1,ssemov,ssemov,ssemov")
6457    (set_attr "length_immediate" "*,1,1,*,*,*")
6458    (set_attr "memory" "*,none,none,*,*,*")
6459    (set_attr "prefix" "maybe_vex,orig,vex,maybe_vex,orig,orig")
6460    (set_attr "mode" "V2SF,TI,TI,TI,V4SF,V2SF")])
6461
6462 (define_insn "*vec_dupv4si_avx"
6463   [(set (match_operand:V4SI 0 "register_operand"     "=x,x")
6464         (vec_duplicate:V4SI
6465           (match_operand:SI 1 "nonimmediate_operand" " x,m")))]
6466   "TARGET_AVX"
6467   "@
6468    vpshufd\t{$0, %1, %0|%0, %1, 0}
6469    vbroadcastss\t{%1, %0|%0, %1}"
6470   [(set_attr "type" "sselog1,ssemov")
6471    (set_attr "length_immediate" "1,0")
6472    (set_attr "prefix_extra" "0,1")
6473    (set_attr "prefix" "vex")
6474    (set_attr "mode" "TI,V4SF")])
6475
6476 (define_insn "*vec_dupv4si"
6477   [(set (match_operand:V4SI 0 "register_operand" "=Y2,x")
6478         (vec_duplicate:V4SI
6479           (match_operand:SI 1 "register_operand" " Y2,0")))]
6480   "TARGET_SSE"
6481   "@
6482    pshufd\t{$0, %1, %0|%0, %1, 0}
6483    shufps\t{$0, %0, %0|%0, %0, 0}"
6484   [(set_attr "type" "sselog1")
6485    (set_attr "length_immediate" "1")
6486    (set_attr "mode" "TI,V4SF")])
6487
6488 (define_insn "*vec_dupv2di_sse3"
6489   [(set (match_operand:V2DI 0 "register_operand"     "=x,x,x")
6490         (vec_duplicate:V2DI
6491           (match_operand:DI 1 "nonimmediate_operand" " 0,x,m")))]
6492   "TARGET_SSE3"
6493   "@
6494    punpcklqdq\t%0, %0
6495    vpunpcklqdq\t{%d1, %0|%0, %d1}
6496    %vmovddup\t{%1, %0|%0, %1}"
6497   [(set_attr "isa" "noavx,avx,*")
6498    (set_attr "type" "sselog1")
6499    (set_attr "prefix" "orig,vex,maybe_vex")
6500    (set_attr "mode" "TI,TI,DF")])
6501
6502 (define_insn "*vec_dupv2di"
6503   [(set (match_operand:V2DI 0 "register_operand" "=Y2,x")
6504         (vec_duplicate:V2DI
6505           (match_operand:DI 1 "register_operand" " 0 ,0")))]
6506   "TARGET_SSE"
6507   "@
6508    punpcklqdq\t%0, %0
6509    movlhps\t%0, %0"
6510   [(set_attr "type" "sselog1,ssemov")
6511    (set_attr "mode" "TI,V4SF")])
6512
6513 (define_insn "*vec_concatv2si_sse4_1"
6514   [(set (match_operand:V2SI 0 "register_operand"     "=x, x,x,x, x, *y,*y")
6515         (vec_concat:V2SI
6516           (match_operand:SI 1 "nonimmediate_operand" " 0, x,0,x,rm,  0,rm")
6517           (match_operand:SI 2 "vector_move_operand"  "rm,rm,x,x, C,*ym, C")))]
6518   "TARGET_SSE4_1"
6519   "@
6520    pinsrd\t{$1, %2, %0|%0, %2, 1}
6521    vpinsrd\t{$1, %2, %1, %0|%0, %1, %2, 1}
6522    punpckldq\t{%2, %0|%0, %2}
6523    vpunpckldq\t{%2, %1, %0|%0, %1, %2}
6524    %vmovd\t{%1, %0|%0, %1}
6525    punpckldq\t{%2, %0|%0, %2}
6526    movd\t{%1, %0|%0, %1}"
6527   [(set_attr "isa" "noavx,avx,noavx,avx,*,*,*")
6528    (set_attr "type" "sselog,sselog,sselog,sselog,ssemov,mmxcvt,mmxmov")
6529    (set_attr "prefix_extra" "1,1,*,*,*,*,*")
6530    (set_attr "length_immediate" "1,1,*,*,*,*,*")
6531    (set_attr "prefix" "orig,vex,orig,vex,maybe_vex,orig,orig")
6532    (set_attr "mode" "TI,TI,TI,TI,TI,DI,DI")])
6533
6534 ;; ??? In theory we can match memory for the MMX alternative, but allowing
6535 ;; nonimmediate_operand for operand 2 and *not* allowing memory for the SSE
6536 ;; alternatives pretty much forces the MMX alternative to be chosen.
6537 (define_insn "*vec_concatv2si_sse2"
6538   [(set (match_operand:V2SI 0 "register_operand"     "=x,x ,*y,*y")
6539         (vec_concat:V2SI
6540           (match_operand:SI 1 "nonimmediate_operand" " 0,rm, 0,rm")
6541           (match_operand:SI 2 "reg_or_0_operand"     " x,C ,*y, C")))]
6542   "TARGET_SSE2"
6543   "@
6544    punpckldq\t{%2, %0|%0, %2}
6545    movd\t{%1, %0|%0, %1}
6546    punpckldq\t{%2, %0|%0, %2}
6547    movd\t{%1, %0|%0, %1}"
6548   [(set_attr "type" "sselog,ssemov,mmxcvt,mmxmov")
6549    (set_attr "mode" "TI,TI,DI,DI")])
6550
6551 (define_insn "*vec_concatv2si_sse"
6552   [(set (match_operand:V2SI 0 "register_operand"     "=x,x,*y,*y")
6553         (vec_concat:V2SI
6554           (match_operand:SI 1 "nonimmediate_operand" " 0,m, 0,*rm")
6555           (match_operand:SI 2 "reg_or_0_operand"     " x,C,*y,C")))]
6556   "TARGET_SSE"
6557   "@
6558    unpcklps\t{%2, %0|%0, %2}
6559    movss\t{%1, %0|%0, %1}
6560    punpckldq\t{%2, %0|%0, %2}
6561    movd\t{%1, %0|%0, %1}"
6562   [(set_attr "type" "sselog,ssemov,mmxcvt,mmxmov")
6563    (set_attr "mode" "V4SF,V4SF,DI,DI")])
6564
6565 (define_insn "*vec_concatv4si"
6566   [(set (match_operand:V4SI 0 "register_operand"       "=Y2,x,x,x,x")
6567         (vec_concat:V4SI
6568           (match_operand:V2SI 1 "register_operand"     " 0 ,x,0,0,x")
6569           (match_operand:V2SI 2 "nonimmediate_operand" " Y2,x,x,m,m")))]
6570   "TARGET_SSE"
6571   "@
6572    punpcklqdq\t{%2, %0|%0, %2}
6573    vpunpcklqdq\t{%2, %1, %0|%0, %1, %2}
6574    movlhps\t{%2, %0|%0, %2}
6575    movhps\t{%2, %0|%0, %2}
6576    vmovhps\t{%2, %1, %0|%0, %1, %2}"
6577   [(set_attr "isa" "noavx,avx,noavx,noavx,avx")
6578    (set_attr "type" "sselog,sselog,ssemov,ssemov,ssemov")
6579    (set_attr "prefix" "orig,vex,orig,orig,vex")
6580    (set_attr "mode" "TI,TI,V4SF,V2SF,V2SF")])
6581
6582 ;; movd instead of movq is required to handle broken assemblers.
6583 (define_insn "*vec_concatv2di_rex64"
6584   [(set (match_operand:V2DI 0 "register_operand"
6585           "=Y4,x ,x ,Yi,!x,x,x,x,x")
6586         (vec_concat:V2DI
6587           (match_operand:DI 1 "nonimmediate_operand"
6588           " 0 ,x ,xm,r ,*y,0,x,0,x")
6589           (match_operand:DI 2 "vector_move_operand"
6590           " rm,rm,C ,C ,C ,x,x,m,m")))]
6591   "TARGET_64BIT"
6592   "@
6593    pinsrq\t{$1, %2, %0|%0, %2, 1}
6594    vpinsrq\t{$1, %2, %1, %0|%0, %1, %2, 1}
6595    %vmovq\t{%1, %0|%0, %1}
6596    %vmovd\t{%1, %0|%0, %1}
6597    movq2dq\t{%1, %0|%0, %1}
6598    punpcklqdq\t{%2, %0|%0, %2}
6599    vpunpcklqdq\t{%2, %1, %0|%0, %1, %2}
6600    movhps\t{%2, %0|%0, %2}
6601    vmovhps\t{%2, %1, %0|%0, %1, %2}"
6602   [(set_attr "isa" "noavx,avx,*,*,*,noavx,avx,noavx,avx")
6603    (set (attr "type")
6604      (if_then_else
6605        (eq_attr "alternative" "0,1,5,6")
6606        (const_string "sselog")
6607        (const_string "ssemov")))
6608    (set (attr "prefix_rex")
6609      (if_then_else
6610        (and (eq_attr "alternative" "0,3")
6611             (eq (symbol_ref "TARGET_AVX") (const_int 0)))
6612        (const_string "1")
6613        (const_string "*")))
6614    (set_attr "prefix_extra" "1,1,*,*,*,*,*,*,*")
6615    (set_attr "length_immediate" "1,1,*,*,*,*,*,*,*")
6616    (set_attr "prefix" "orig,vex,maybe_vex,maybe_vex,orig,orig,vex,orig,vex")
6617    (set_attr "mode" "TI,TI,TI,TI,TI,TI,TI,V2SF,V2SF")])
6618
6619 (define_insn "vec_concatv2di"
6620   [(set (match_operand:V2DI 0 "register_operand"     "=Y2,?Y2,Y2,x,x,x,x")
6621         (vec_concat:V2DI
6622           (match_operand:DI 1 "nonimmediate_operand" "Y2m,*y , 0,x,0,0,x")
6623           (match_operand:DI 2 "vector_move_operand"  " C , C ,Y2,x,x,m,m")))]
6624   "!TARGET_64BIT && TARGET_SSE"
6625   "@
6626    %vmovq\t{%1, %0|%0, %1}
6627    movq2dq\t{%1, %0|%0, %1}
6628    punpcklqdq\t{%2, %0|%0, %2}
6629    vpunpcklqdq\t{%2, %1, %0|%0, %1, %2}
6630    movlhps\t{%2, %0|%0, %2}
6631    movhps\t{%2, %0|%0, %2}
6632    vmovhps\t{%2, %1, %0|%0, %1, %2}"
6633   [(set_attr "isa" "*,*,noavx,avx,noavx,noavx,avx")
6634    (set_attr "type" "ssemov,ssemov,sselog,sselog,ssemov,ssemov,ssemov")
6635    (set_attr "prefix" "maybe_vex,orig,orig,vex,orig,orig,vex")
6636    (set_attr "mode" "TI,TI,TI,TI,V4SF,V2SF,V2SF")])
6637
6638 (define_expand "vec_unpacks_lo_<mode>"
6639   [(match_operand:<sseunpackmode> 0 "register_operand" "")
6640    (match_operand:VI124_128 1 "register_operand" "")]
6641   "TARGET_SSE2"
6642   "ix86_expand_sse_unpack (operands, false, false); DONE;")
6643
6644 (define_expand "vec_unpacks_hi_<mode>"
6645   [(match_operand:<sseunpackmode> 0 "register_operand" "")
6646    (match_operand:VI124_128 1 "register_operand" "")]
6647   "TARGET_SSE2"
6648   "ix86_expand_sse_unpack (operands, false, true); DONE;")
6649
6650 (define_expand "vec_unpacku_lo_<mode>"
6651   [(match_operand:<sseunpackmode> 0 "register_operand" "")
6652    (match_operand:VI124_128 1 "register_operand" "")]
6653   "TARGET_SSE2"
6654   "ix86_expand_sse_unpack (operands, true, false); DONE;")
6655
6656 (define_expand "vec_unpacku_hi_<mode>"
6657   [(match_operand:<sseunpackmode> 0 "register_operand" "")
6658    (match_operand:VI124_128 1 "register_operand" "")]
6659   "TARGET_SSE2"
6660   "ix86_expand_sse_unpack (operands, true, true); DONE;")
6661
6662 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6663 ;;
6664 ;; Miscellaneous
6665 ;;
6666 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6667
6668 (define_expand "sse2_uavgv16qi3"
6669   [(set (match_operand:V16QI 0 "register_operand" "")
6670         (truncate:V16QI
6671           (lshiftrt:V16HI
6672             (plus:V16HI
6673               (plus:V16HI
6674                 (zero_extend:V16HI
6675                   (match_operand:V16QI 1 "nonimmediate_operand" ""))
6676                 (zero_extend:V16HI
6677                   (match_operand:V16QI 2 "nonimmediate_operand" "")))
6678               (const_vector:V16QI [(const_int 1) (const_int 1)
6679                                    (const_int 1) (const_int 1)
6680                                    (const_int 1) (const_int 1)
6681                                    (const_int 1) (const_int 1)
6682                                    (const_int 1) (const_int 1)
6683                                    (const_int 1) (const_int 1)
6684                                    (const_int 1) (const_int 1)
6685                                    (const_int 1) (const_int 1)]))
6686             (const_int 1))))]
6687   "TARGET_SSE2"
6688   "ix86_fixup_binary_operands_no_copy (PLUS, V16QImode, operands);")
6689
6690 (define_insn "*sse2_uavgv16qi3"
6691   [(set (match_operand:V16QI 0 "register_operand" "=x,x")
6692         (truncate:V16QI
6693           (lshiftrt:V16HI
6694             (plus:V16HI
6695               (plus:V16HI
6696                 (zero_extend:V16HI
6697                   (match_operand:V16QI 1 "nonimmediate_operand" "%0,x"))
6698                 (zero_extend:V16HI
6699                   (match_operand:V16QI 2 "nonimmediate_operand" "xm,xm")))
6700               (const_vector:V16QI [(const_int 1) (const_int 1)
6701                                    (const_int 1) (const_int 1)
6702                                    (const_int 1) (const_int 1)
6703                                    (const_int 1) (const_int 1)
6704                                    (const_int 1) (const_int 1)
6705                                    (const_int 1) (const_int 1)
6706                                    (const_int 1) (const_int 1)
6707                                    (const_int 1) (const_int 1)]))
6708             (const_int 1))))]
6709   "TARGET_SSE2 && ix86_binary_operator_ok (PLUS, V16QImode, operands)"
6710   "@
6711    pavgb\t{%2, %0|%0, %2}
6712    vpavgb\t{%2, %1, %0|%0, %1, %2}"
6713   [(set_attr "isa" "noavx,avx")
6714    (set_attr "type" "sseiadd")
6715    (set_attr "prefix_data16" "1,*")
6716    (set_attr "prefix" "orig,vex")
6717    (set_attr "mode" "TI")])
6718
6719 (define_expand "sse2_uavgv8hi3"
6720   [(set (match_operand:V8HI 0 "register_operand" "")
6721         (truncate:V8HI
6722           (lshiftrt:V8SI
6723             (plus:V8SI
6724               (plus:V8SI
6725                 (zero_extend:V8SI
6726                   (match_operand:V8HI 1 "nonimmediate_operand" ""))
6727                 (zero_extend:V8SI
6728                   (match_operand:V8HI 2 "nonimmediate_operand" "")))
6729               (const_vector:V8HI [(const_int 1) (const_int 1)
6730                                   (const_int 1) (const_int 1)
6731                                   (const_int 1) (const_int 1)
6732                                   (const_int 1) (const_int 1)]))
6733             (const_int 1))))]
6734   "TARGET_SSE2"
6735   "ix86_fixup_binary_operands_no_copy (PLUS, V8HImode, operands);")
6736
6737 (define_insn "*sse2_uavgv8hi3"
6738   [(set (match_operand:V8HI 0 "register_operand" "=x,x")
6739         (truncate:V8HI
6740           (lshiftrt:V8SI
6741             (plus:V8SI
6742               (plus:V8SI
6743                 (zero_extend:V8SI
6744                   (match_operand:V8HI 1 "nonimmediate_operand" "%0,x"))
6745                 (zero_extend:V8SI
6746                   (match_operand:V8HI 2 "nonimmediate_operand" "xm,xm")))
6747               (const_vector:V8HI [(const_int 1) (const_int 1)
6748                                   (const_int 1) (const_int 1)
6749                                   (const_int 1) (const_int 1)
6750                                   (const_int 1) (const_int 1)]))
6751             (const_int 1))))]
6752   "TARGET_SSE2 && ix86_binary_operator_ok (PLUS, V8HImode, operands)"
6753   "@
6754    pavgw\t{%2, %0|%0, %2}
6755    vpavgw\t{%2, %1, %0|%0, %1, %2}"
6756   [(set_attr "isa" "noavx,avx")
6757    (set_attr "type" "sseiadd")
6758    (set_attr "prefix_data16" "1,*")
6759    (set_attr "prefix" "orig,vex")
6760    (set_attr "mode" "TI")])
6761
6762 ;; The correct representation for this is absolutely enormous, and
6763 ;; surely not generally useful.
6764 (define_insn "sse2_psadbw"
6765   [(set (match_operand:V2DI 0 "register_operand" "=x,x")
6766         (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0,x")
6767                       (match_operand:V16QI 2 "nonimmediate_operand" "xm,xm")]
6768                      UNSPEC_PSADBW))]
6769   "TARGET_SSE2"
6770   "@
6771    psadbw\t{%2, %0|%0, %2}
6772    vpsadbw\t{%2, %1, %0|%0, %1, %2}"
6773   [(set_attr "isa" "noavx,avx")
6774    (set_attr "type" "sseiadd")
6775    (set_attr "atom_unit" "simul")
6776    (set_attr "prefix_data16" "1,*")
6777    (set_attr "prefix" "orig,vex")
6778    (set_attr "mode" "TI")])
6779
6780 (define_insn "<sse>_movmsk<ssemodesuffix><avxsizesuffix>"
6781   [(set (match_operand:SI 0 "register_operand" "=r")
6782         (unspec:SI
6783           [(match_operand:VF 1 "register_operand" "x")]
6784           UNSPEC_MOVMSK))]
6785   "TARGET_SSE"
6786   "%vmovmsk<ssemodesuffix>\t{%1, %0|%0, %1}"
6787   [(set_attr "type" "ssemov")
6788    (set_attr "prefix" "maybe_vex")
6789    (set_attr "mode" "<MODE>")])
6790
6791 (define_insn "sse2_pmovmskb"
6792   [(set (match_operand:SI 0 "register_operand" "=r")
6793         (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
6794                    UNSPEC_MOVMSK))]
6795   "TARGET_SSE2"
6796   "%vpmovmskb\t{%1, %0|%0, %1}"
6797   [(set_attr "type" "ssemov")
6798    (set_attr "prefix_data16" "1")
6799    (set_attr "prefix" "maybe_vex")
6800    (set_attr "mode" "SI")])
6801
6802 (define_expand "sse2_maskmovdqu"
6803   [(set (match_operand:V16QI 0 "memory_operand" "")
6804         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "")
6805                        (match_operand:V16QI 2 "register_operand" "")
6806                        (match_dup 0)]
6807                       UNSPEC_MASKMOV))]
6808   "TARGET_SSE2")
6809
6810 (define_insn "*sse2_maskmovdqu"
6811   [(set (mem:V16QI (match_operand:P 0 "register_operand" "D"))
6812         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
6813                        (match_operand:V16QI 2 "register_operand" "x")
6814                        (mem:V16QI (match_dup 0))]
6815                       UNSPEC_MASKMOV))]
6816   "TARGET_SSE2"
6817   "%vmaskmovdqu\t{%2, %1|%1, %2}"
6818   [(set_attr "type" "ssemov")
6819    (set_attr "prefix_data16" "1")
6820    ;; The implicit %rdi operand confuses default length_vex computation.
6821    (set (attr "length_vex")
6822      (symbol_ref ("3 + REX_SSE_REGNO_P (REGNO (operands[2]))")))
6823    (set_attr "prefix" "maybe_vex")
6824    (set_attr "mode" "TI")])
6825
6826 (define_insn "sse_ldmxcsr"
6827   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
6828                     UNSPECV_LDMXCSR)]
6829   "TARGET_SSE"
6830   "%vldmxcsr\t%0"
6831   [(set_attr "type" "sse")
6832    (set_attr "atom_sse_attr" "mxcsr")
6833    (set_attr "prefix" "maybe_vex")
6834    (set_attr "memory" "load")])
6835
6836 (define_insn "sse_stmxcsr"
6837   [(set (match_operand:SI 0 "memory_operand" "=m")
6838         (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
6839   "TARGET_SSE"
6840   "%vstmxcsr\t%0"
6841   [(set_attr "type" "sse")
6842    (set_attr "atom_sse_attr" "mxcsr")
6843    (set_attr "prefix" "maybe_vex")
6844    (set_attr "memory" "store")])
6845
6846 (define_expand "sse_sfence"
6847   [(set (match_dup 0)
6848         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
6849   "TARGET_SSE || TARGET_3DNOW_A"
6850 {
6851   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
6852   MEM_VOLATILE_P (operands[0]) = 1;
6853 })
6854
6855 (define_insn "*sse_sfence"
6856   [(set (match_operand:BLK 0 "" "")
6857         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
6858   "TARGET_SSE || TARGET_3DNOW_A"
6859   "sfence"
6860   [(set_attr "type" "sse")
6861    (set_attr "length_address" "0")
6862    (set_attr "atom_sse_attr" "fence")
6863    (set_attr "memory" "unknown")])
6864
6865 (define_insn "sse2_clflush"
6866   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
6867                     UNSPECV_CLFLUSH)]
6868   "TARGET_SSE2"
6869   "clflush\t%a0"
6870   [(set_attr "type" "sse")
6871    (set_attr "atom_sse_attr" "fence")
6872    (set_attr "memory" "unknown")])
6873
6874 (define_expand "sse2_mfence"
6875   [(set (match_dup 0)
6876         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
6877   "TARGET_SSE2"
6878 {
6879   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
6880   MEM_VOLATILE_P (operands[0]) = 1;
6881 })
6882
6883 (define_insn "*sse2_mfence"
6884   [(set (match_operand:BLK 0 "" "")
6885         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
6886   "TARGET_64BIT || TARGET_SSE2"
6887   "mfence"
6888   [(set_attr "type" "sse")
6889    (set_attr "length_address" "0")
6890    (set_attr "atom_sse_attr" "fence")
6891    (set_attr "memory" "unknown")])
6892
6893 (define_expand "sse2_lfence"
6894   [(set (match_dup 0)
6895         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
6896   "TARGET_SSE2"
6897 {
6898   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
6899   MEM_VOLATILE_P (operands[0]) = 1;
6900 })
6901
6902 (define_insn "*sse2_lfence"
6903   [(set (match_operand:BLK 0 "" "")
6904         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
6905   "TARGET_SSE2"
6906   "lfence"
6907   [(set_attr "type" "sse")
6908    (set_attr "length_address" "0")
6909    (set_attr "atom_sse_attr" "lfence")
6910    (set_attr "memory" "unknown")])
6911
6912 (define_insn "sse3_mwait"
6913   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
6914                      (match_operand:SI 1 "register_operand" "c")]
6915                     UNSPECV_MWAIT)]
6916   "TARGET_SSE3"
6917 ;; 64bit version is "mwait %rax,%rcx". But only lower 32bits are used.
6918 ;; Since 32bit register operands are implicitly zero extended to 64bit,
6919 ;; we only need to set up 32bit registers.
6920   "mwait"
6921   [(set_attr "length" "3")])
6922
6923 (define_insn "sse3_monitor"
6924   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
6925                      (match_operand:SI 1 "register_operand" "c")
6926                      (match_operand:SI 2 "register_operand" "d")]
6927                     UNSPECV_MONITOR)]
6928   "TARGET_SSE3 && !TARGET_64BIT"
6929   "monitor\t%0, %1, %2"
6930   [(set_attr "length" "3")])
6931
6932 (define_insn "sse3_monitor64"
6933   [(unspec_volatile [(match_operand:DI 0 "register_operand" "a")
6934                      (match_operand:SI 1 "register_operand" "c")
6935                      (match_operand:SI 2 "register_operand" "d")]
6936                     UNSPECV_MONITOR)]
6937   "TARGET_SSE3 && TARGET_64BIT"
6938 ;; 64bit version is "monitor %rax,%rcx,%rdx". But only lower 32bits in
6939 ;; RCX and RDX are used.  Since 32bit register operands are implicitly
6940 ;; zero extended to 64bit, we only need to set up 32bit registers.
6941   "monitor"
6942   [(set_attr "length" "3")])
6943
6944 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6945 ;;
6946 ;; SSSE3 instructions
6947 ;;
6948 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6949
6950 (define_insn "ssse3_phaddwv8hi3"
6951   [(set (match_operand:V8HI 0 "register_operand" "=x,x")
6952         (vec_concat:V8HI
6953           (vec_concat:V4HI
6954             (vec_concat:V2HI
6955               (plus:HI
6956                 (vec_select:HI
6957                   (match_operand:V8HI 1 "register_operand" "0,x")
6958                   (parallel [(const_int 0)]))
6959                 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
6960               (plus:HI
6961                 (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
6962                 (vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
6963             (vec_concat:V2HI
6964               (plus:HI
6965                 (vec_select:HI (match_dup 1) (parallel [(const_int 4)]))
6966                 (vec_select:HI (match_dup 1) (parallel [(const_int 5)])))
6967               (plus:HI
6968                 (vec_select:HI (match_dup 1) (parallel [(const_int 6)]))
6969                 (vec_select:HI (match_dup 1) (parallel [(const_int 7)])))))
6970           (vec_concat:V4HI
6971             (vec_concat:V2HI
6972               (plus:HI
6973                 (vec_select:HI
6974                   (match_operand:V8HI 2 "nonimmediate_operand" "xm,xm")
6975                   (parallel [(const_int 0)]))
6976                 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
6977               (plus:HI
6978                 (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
6979                 (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))
6980             (vec_concat:V2HI
6981               (plus:HI
6982                 (vec_select:HI (match_dup 2) (parallel [(const_int 4)]))
6983                 (vec_select:HI (match_dup 2) (parallel [(const_int 5)])))
6984               (plus:HI
6985                 (vec_select:HI (match_dup 2) (parallel [(const_int 6)]))
6986                 (vec_select:HI (match_dup 2) (parallel [(const_int 7)])))))))]
6987   "TARGET_SSSE3"
6988   "@
6989    phaddw\t{%2, %0|%0, %2}
6990    vphaddw\t{%2, %1, %0|%0, %1, %2}"
6991   [(set_attr "isa" "noavx,avx")
6992    (set_attr "type" "sseiadd")
6993    (set_attr "atom_unit" "complex")
6994    (set_attr "prefix_data16" "1,*")
6995    (set_attr "prefix_extra" "1")
6996    (set_attr "prefix" "orig,vex")
6997    (set_attr "mode" "TI")])
6998
6999 (define_insn "ssse3_phaddwv4hi3"
7000   [(set (match_operand:V4HI 0 "register_operand" "=y")
7001         (vec_concat:V4HI
7002           (vec_concat:V2HI
7003             (plus:HI
7004               (vec_select:HI
7005                 (match_operand:V4HI 1 "register_operand" "0")
7006                 (parallel [(const_int 0)]))
7007               (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
7008             (plus:HI
7009               (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
7010               (vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
7011           (vec_concat:V2HI
7012             (plus:HI
7013               (vec_select:HI
7014                 (match_operand:V4HI 2 "nonimmediate_operand" "ym")
7015                 (parallel [(const_int 0)]))
7016               (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
7017             (plus:HI
7018               (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
7019               (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))))]
7020   "TARGET_SSSE3"
7021   "phaddw\t{%2, %0|%0, %2}"
7022   [(set_attr "type" "sseiadd")
7023    (set_attr "atom_unit" "complex")
7024    (set_attr "prefix_extra" "1")
7025    (set (attr "prefix_rex") (symbol_ref "x86_extended_reg_mentioned_p (insn)"))
7026    (set_attr "mode" "DI")])
7027
7028 (define_insn "ssse3_phadddv4si3"
7029   [(set (match_operand:V4SI 0 "register_operand" "=x,x")
7030         (vec_concat:V4SI
7031           (vec_concat:V2SI
7032             (plus:SI
7033               (vec_select:SI
7034                 (match_operand:V4SI 1 "register_operand" "0,x")
7035                 (parallel [(const_int 0)]))
7036               (vec_select:SI (match_dup 1) (parallel [(const_int 1)])))
7037             (plus:SI
7038               (vec_select:SI (match_dup 1) (parallel [(const_int 2)]))
7039               (vec_select:SI (match_dup 1) (parallel [(const_int 3)]))))
7040           (vec_concat:V2SI
7041             (plus:SI
7042               (vec_select:SI
7043                 (match_operand:V4SI 2 "nonimmediate_operand" "xm,xm")
7044                 (parallel [(const_int 0)]))
7045               (vec_select:SI (match_dup 2) (parallel [(const_int 1)])))
7046             (plus:SI
7047               (vec_select:SI (match_dup 2) (parallel [(const_int 2)]))
7048               (vec_select:SI (match_dup 2) (parallel [(const_int 3)]))))))]
7049   "TARGET_SSSE3"
7050   "@
7051    phaddd\t{%2, %0|%0, %2}
7052    vphaddd\t{%2, %1, %0|%0, %1, %2}"
7053   [(set_attr "isa" "noavx,avx")
7054    (set_attr "type" "sseiadd")
7055    (set_attr "atom_unit" "complex")
7056    (set_attr "prefix_data16" "1,*")
7057    (set_attr "prefix_extra" "1")
7058    (set_attr "prefix" "orig,vex")
7059    (set_attr "mode" "TI")])
7060
7061 (define_insn "ssse3_phadddv2si3"
7062   [(set (match_operand:V2SI 0 "register_operand" "=y")
7063         (vec_concat:V2SI
7064           (plus:SI
7065             (vec_select:SI
7066               (match_operand:V2SI 1 "register_operand" "0")
7067               (parallel [(const_int 0)]))
7068             (vec_select:SI (match_dup 1) (parallel [(const_int 1)])))
7069           (plus:SI
7070             (vec_select:SI
7071               (match_operand:V2SI 2 "nonimmediate_operand" "ym")
7072               (parallel [(const_int 0)]))
7073             (vec_select:SI (match_dup 2) (parallel [(const_int 1)])))))]
7074   "TARGET_SSSE3"
7075   "phaddd\t{%2, %0|%0, %2}"
7076   [(set_attr "type" "sseiadd")
7077    (set_attr "atom_unit" "complex")
7078    (set_attr "prefix_extra" "1")
7079    (set (attr "prefix_rex") (symbol_ref "x86_extended_reg_mentioned_p (insn)"))
7080    (set_attr "mode" "DI")])
7081
7082 (define_insn "ssse3_phaddswv8hi3"
7083   [(set (match_operand:V8HI 0 "register_operand" "=x,x")
7084         (vec_concat:V8HI
7085           (vec_concat:V4HI
7086             (vec_concat:V2HI
7087               (ss_plus:HI
7088                 (vec_select:HI
7089                   (match_operand:V8HI 1 "register_operand" "0,x")
7090                   (parallel [(const_int 0)]))
7091                 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
7092               (ss_plus:HI
7093                 (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
7094                 (vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
7095             (vec_concat:V2HI
7096               (ss_plus:HI
7097                 (vec_select:HI (match_dup 1) (parallel [(const_int 4)]))
7098                 (vec_select:HI (match_dup 1) (parallel [(const_int 5)])))
7099               (ss_plus:HI
7100                 (vec_select:HI (match_dup 1) (parallel [(const_int 6)]))
7101                 (vec_select:HI (match_dup 1) (parallel [(const_int 7)])))))
7102           (vec_concat:V4HI
7103             (vec_concat:V2HI
7104               (ss_plus:HI
7105                 (vec_select:HI
7106                   (match_operand:V8HI 2 "nonimmediate_operand" "xm,xm")
7107                   (parallel [(const_int 0)]))
7108                 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
7109               (ss_plus:HI
7110                 (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
7111                 (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))
7112             (vec_concat:V2HI
7113               (ss_plus:HI
7114                 (vec_select:HI (match_dup 2) (parallel [(const_int 4)]))
7115                 (vec_select:HI (match_dup 2) (parallel [(const_int 5)])))
7116               (ss_plus:HI
7117                 (vec_select:HI (match_dup 2) (parallel [(const_int 6)]))
7118                 (vec_select:HI (match_dup 2) (parallel [(const_int 7)])))))))]
7119   "TARGET_SSSE3"
7120   "@
7121    phaddsw\t{%2, %0|%0, %2}
7122    vphaddsw\t{%2, %1, %0|%0, %1, %2}"
7123   [(set_attr "isa" "noavx,avx")
7124    (set_attr "type" "sseiadd")
7125    (set_attr "atom_unit" "complex")
7126    (set_attr "prefix_data16" "1,*")
7127    (set_attr "prefix_extra" "1")
7128    (set_attr "prefix" "orig,vex")
7129    (set_attr "mode" "TI")])
7130
7131 (define_insn "ssse3_phaddswv4hi3"
7132   [(set (match_operand:V4HI 0 "register_operand" "=y")
7133         (vec_concat:V4HI
7134           (vec_concat:V2HI
7135             (ss_plus:HI
7136               (vec_select:HI
7137                 (match_operand:V4HI 1 "register_operand" "0")
7138                 (parallel [(const_int 0)]))
7139               (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
7140             (ss_plus:HI
7141               (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
7142               (vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
7143           (vec_concat:V2HI
7144             (ss_plus:HI
7145               (vec_select:HI
7146                 (match_operand:V4HI 2 "nonimmediate_operand" "ym")
7147                 (parallel [(const_int 0)]))
7148               (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
7149             (ss_plus:HI
7150               (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
7151               (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))))]
7152   "TARGET_SSSE3"
7153   "phaddsw\t{%2, %0|%0, %2}"
7154   [(set_attr "type" "sseiadd")
7155    (set_attr "atom_unit" "complex")
7156    (set_attr "prefix_extra" "1")
7157    (set (attr "prefix_rex") (symbol_ref "x86_extended_reg_mentioned_p (insn)"))
7158    (set_attr "mode" "DI")])
7159
7160 (define_insn "ssse3_phsubwv8hi3"
7161   [(set (match_operand:V8HI 0 "register_operand" "=x,x")
7162         (vec_concat:V8HI
7163           (vec_concat:V4HI
7164             (vec_concat:V2HI
7165               (minus:HI
7166                 (vec_select:HI
7167                   (match_operand:V8HI 1 "register_operand" "0,x")
7168                   (parallel [(const_int 0)]))
7169                 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
7170               (minus:HI
7171                 (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
7172                 (vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
7173             (vec_concat:V2HI
7174               (minus:HI
7175                 (vec_select:HI (match_dup 1) (parallel [(const_int 4)]))
7176                 (vec_select:HI (match_dup 1) (parallel [(const_int 5)])))
7177               (minus:HI
7178                 (vec_select:HI (match_dup 1) (parallel [(const_int 6)]))
7179                 (vec_select:HI (match_dup 1) (parallel [(const_int 7)])))))
7180           (vec_concat:V4HI
7181             (vec_concat:V2HI
7182               (minus:HI
7183                 (vec_select:HI
7184                   (match_operand:V8HI 2 "nonimmediate_operand" "xm,xm")
7185                   (parallel [(const_int 0)]))
7186                 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
7187               (minus:HI
7188                 (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
7189                 (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))
7190             (vec_concat:V2HI
7191               (minus:HI
7192                 (vec_select:HI (match_dup 2) (parallel [(const_int 4)]))
7193                 (vec_select:HI (match_dup 2) (parallel [(const_int 5)])))
7194               (minus:HI
7195                 (vec_select:HI (match_dup 2) (parallel [(const_int 6)]))
7196                 (vec_select:HI (match_dup 2) (parallel [(const_int 7)])))))))]
7197   "TARGET_SSSE3"
7198   "@
7199    phsubw\t{%2, %0|%0, %2}
7200    vphsubw\t{%2, %1, %0|%0, %1, %2}"
7201   [(set_attr "isa" "noavx,avx")
7202    (set_attr "type" "sseiadd")
7203    (set_attr "atom_unit" "complex")
7204    (set_attr "prefix_data16" "1,*")
7205    (set_attr "prefix_extra" "1")
7206    (set_attr "prefix" "orig,vex")
7207    (set_attr "mode" "TI")])
7208
7209 (define_insn "ssse3_phsubwv4hi3"
7210   [(set (match_operand:V4HI 0 "register_operand" "=y")
7211         (vec_concat:V4HI
7212           (vec_concat:V2HI
7213             (minus:HI
7214               (vec_select:HI
7215                 (match_operand:V4HI 1 "register_operand" "0")
7216                 (parallel [(const_int 0)]))
7217               (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
7218             (minus:HI
7219               (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
7220               (vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
7221           (vec_concat:V2HI
7222             (minus:HI
7223               (vec_select:HI
7224                 (match_operand:V4HI 2 "nonimmediate_operand" "ym")
7225                 (parallel [(const_int 0)]))
7226               (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
7227             (minus:HI
7228               (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
7229               (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))))]
7230   "TARGET_SSSE3"
7231   "phsubw\t{%2, %0|%0, %2}"
7232   [(set_attr "type" "sseiadd")
7233    (set_attr "atom_unit" "complex")
7234    (set_attr "prefix_extra" "1")
7235    (set (attr "prefix_rex") (symbol_ref "x86_extended_reg_mentioned_p (insn)"))
7236    (set_attr "mode" "DI")])
7237
7238 (define_insn "ssse3_phsubdv4si3"
7239   [(set (match_operand:V4SI 0 "register_operand" "=x,x")
7240         (vec_concat:V4SI
7241           (vec_concat:V2SI
7242             (minus:SI
7243               (vec_select:SI
7244                 (match_operand:V4SI 1 "register_operand" "0,x")
7245                 (parallel [(const_int 0)]))
7246               (vec_select:SI (match_dup 1) (parallel [(const_int 1)])))
7247             (minus:SI
7248               (vec_select:SI (match_dup 1) (parallel [(const_int 2)]))
7249               (vec_select:SI (match_dup 1) (parallel [(const_int 3)]))))
7250           (vec_concat:V2SI
7251             (minus:SI
7252               (vec_select:SI
7253                 (match_operand:V4SI 2 "nonimmediate_operand" "xm,xm")
7254                 (parallel [(const_int 0)]))
7255               (vec_select:SI (match_dup 2) (parallel [(const_int 1)])))
7256             (minus:SI
7257               (vec_select:SI (match_dup 2) (parallel [(const_int 2)]))
7258               (vec_select:SI (match_dup 2) (parallel [(const_int 3)]))))))]
7259   "TARGET_SSSE3"
7260   "@
7261    phsubd\t{%2, %0|%0, %2}
7262    vphsubd\t{%2, %1, %0|%0, %1, %2}"
7263
7264   [(set_attr "isa" "noavx,avx")
7265    (set_attr "type" "sseiadd")
7266    (set_attr "atom_unit" "complex")
7267    (set_attr "prefix_data16" "1,*")
7268    (set_attr "prefix_extra" "1")
7269    (set_attr "prefix" "orig,vex")
7270    (set_attr "mode" "TI")])
7271
7272 (define_insn "ssse3_phsubdv2si3"
7273   [(set (match_operand:V2SI 0 "register_operand" "=y")
7274         (vec_concat:V2SI
7275           (minus:SI
7276             (vec_select:SI
7277               (match_operand:V2SI 1 "register_operand" "0")
7278               (parallel [(const_int 0)]))
7279             (vec_select:SI (match_dup 1) (parallel [(const_int 1)])))
7280           (minus:SI
7281             (vec_select:SI
7282               (match_operand:V2SI 2 "nonimmediate_operand" "ym")
7283               (parallel [(const_int 0)]))
7284             (vec_select:SI (match_dup 2) (parallel [(const_int 1)])))))]
7285   "TARGET_SSSE3"
7286   "phsubd\t{%2, %0|%0, %2}"
7287   [(set_attr "type" "sseiadd")
7288    (set_attr "atom_unit" "complex")
7289    (set_attr "prefix_extra" "1")
7290    (set (attr "prefix_rex") (symbol_ref "x86_extended_reg_mentioned_p (insn)"))
7291    (set_attr "mode" "DI")])
7292
7293 (define_insn "ssse3_phsubswv8hi3"
7294   [(set (match_operand:V8HI 0 "register_operand" "=x,x")
7295         (vec_concat:V8HI
7296           (vec_concat:V4HI
7297             (vec_concat:V2HI
7298               (ss_minus:HI
7299                 (vec_select:HI
7300                   (match_operand:V8HI 1 "register_operand" "0,x")
7301                   (parallel [(const_int 0)]))
7302                 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
7303               (ss_minus:HI
7304                 (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
7305                 (vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
7306             (vec_concat:V2HI
7307               (ss_minus:HI
7308                 (vec_select:HI (match_dup 1) (parallel [(const_int 4)]))
7309                 (vec_select:HI (match_dup 1) (parallel [(const_int 5)])))
7310               (ss_minus:HI
7311                 (vec_select:HI (match_dup 1) (parallel [(const_int 6)]))
7312                 (vec_select:HI (match_dup 1) (parallel [(const_int 7)])))))
7313           (vec_concat:V4HI
7314             (vec_concat:V2HI
7315               (ss_minus:HI
7316                 (vec_select:HI
7317                   (match_operand:V8HI 2 "nonimmediate_operand" "xm,xm")
7318                   (parallel [(const_int 0)]))
7319                 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
7320               (ss_minus:HI
7321                 (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
7322                 (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))
7323             (vec_concat:V2HI
7324               (ss_minus:HI
7325                 (vec_select:HI (match_dup 2) (parallel [(const_int 4)]))
7326                 (vec_select:HI (match_dup 2) (parallel [(const_int 5)])))
7327               (ss_minus:HI
7328                 (vec_select:HI (match_dup 2) (parallel [(const_int 6)]))
7329                 (vec_select:HI (match_dup 2) (parallel [(const_int 7)])))))))]
7330   "TARGET_SSSE3"
7331   "@
7332    phsubsw\t{%2, %0|%0, %2}
7333    vphsubsw\t{%2, %1, %0|%0, %1, %2}"
7334   [(set_attr "isa" "noavx,avx")
7335    (set_attr "type" "sseiadd")
7336    (set_attr "atom_unit" "complex")
7337    (set_attr "prefix_data16" "1,*")
7338    (set_attr "prefix_extra" "1")
7339    (set_attr "prefix" "orig,vex")
7340    (set_attr "mode" "TI")])
7341
7342 (define_insn "ssse3_phsubswv4hi3"
7343   [(set (match_operand:V4HI 0 "register_operand" "=y")
7344         (vec_concat:V4HI
7345           (vec_concat:V2HI
7346             (ss_minus:HI
7347               (vec_select:HI
7348                 (match_operand:V4HI 1 "register_operand" "0")
7349                 (parallel [(const_int 0)]))
7350               (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
7351             (ss_minus:HI
7352               (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
7353               (vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
7354           (vec_concat:V2HI
7355             (ss_minus:HI
7356               (vec_select:HI
7357                 (match_operand:V4HI 2 "nonimmediate_operand" "ym")
7358                 (parallel [(const_int 0)]))
7359               (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
7360             (ss_minus:HI
7361               (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
7362               (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))))]
7363   "TARGET_SSSE3"
7364   "phsubsw\t{%2, %0|%0, %2}"
7365   [(set_attr "type" "sseiadd")
7366    (set_attr "atom_unit" "complex")
7367    (set_attr "prefix_extra" "1")
7368    (set (attr "prefix_rex") (symbol_ref "x86_extended_reg_mentioned_p (insn)"))
7369    (set_attr "mode" "DI")])
7370
7371 (define_insn "ssse3_pmaddubsw128"
7372   [(set (match_operand:V8HI 0 "register_operand" "=x,x")
7373         (ss_plus:V8HI
7374           (mult:V8HI
7375             (zero_extend:V8HI
7376               (vec_select:V8QI
7377                 (match_operand:V16QI 1 "register_operand" "0,x")
7378                 (parallel [(const_int 0)
7379                            (const_int 2)
7380                            (const_int 4)
7381                            (const_int 6)
7382                            (const_int 8)
7383                            (const_int 10)
7384                            (const_int 12)
7385                            (const_int 14)])))
7386             (sign_extend:V8HI
7387               (vec_select:V8QI
7388                 (match_operand:V16QI 2 "nonimmediate_operand" "xm,xm")
7389                 (parallel [(const_int 0)
7390                            (const_int 2)
7391                            (const_int 4)
7392                            (const_int 6)
7393                            (const_int 8)
7394                            (const_int 10)
7395                            (const_int 12)
7396                            (const_int 14)]))))
7397           (mult:V8HI
7398             (zero_extend:V8HI
7399               (vec_select:V8QI (match_dup 1)
7400                 (parallel [(const_int 1)
7401                            (const_int 3)
7402                            (const_int 5)
7403                            (const_int 7)
7404                            (const_int 9)
7405                            (const_int 11)
7406                            (const_int 13)
7407                            (const_int 15)])))
7408             (sign_extend:V8HI
7409               (vec_select:V8QI (match_dup 2)
7410                 (parallel [(const_int 1)
7411                            (const_int 3)
7412                            (const_int 5)
7413                            (const_int 7)
7414                            (const_int 9)
7415                            (const_int 11)
7416                            (const_int 13)
7417                            (const_int 15)]))))))]
7418   "TARGET_SSSE3"
7419   "@
7420    pmaddubsw\t{%2, %0|%0, %2}
7421    vpmaddubsw\t{%2, %1, %0|%0, %1, %2}"
7422   [(set_attr "isa" "noavx,avx")
7423    (set_attr "type" "sseiadd")
7424    (set_attr "atom_unit" "simul")
7425    (set_attr "prefix_data16" "1,*")
7426    (set_attr "prefix_extra" "1")
7427    (set_attr "prefix" "orig,vex")
7428    (set_attr "mode" "TI")])
7429
7430 (define_insn "ssse3_pmaddubsw"
7431   [(set (match_operand:V4HI 0 "register_operand" "=y")
7432         (ss_plus:V4HI
7433           (mult:V4HI
7434             (zero_extend:V4HI
7435               (vec_select:V4QI
7436                 (match_operand:V8QI 1 "register_operand" "0")
7437                 (parallel [(const_int 0)
7438                            (const_int 2)
7439                            (const_int 4)
7440                            (const_int 6)])))
7441             (sign_extend:V4HI
7442               (vec_select:V4QI
7443                 (match_operand:V8QI 2 "nonimmediate_operand" "ym")
7444                 (parallel [(const_int 0)
7445                            (const_int 2)
7446                            (const_int 4)
7447                            (const_int 6)]))))
7448           (mult:V4HI
7449             (zero_extend:V4HI
7450               (vec_select:V4QI (match_dup 1)
7451                 (parallel [(const_int 1)
7452                            (const_int 3)
7453                            (const_int 5)
7454                            (const_int 7)])))
7455             (sign_extend:V4HI
7456               (vec_select:V4QI (match_dup 2)
7457                 (parallel [(const_int 1)
7458                            (const_int 3)
7459                            (const_int 5)
7460                            (const_int 7)]))))))]
7461   "TARGET_SSSE3"
7462   "pmaddubsw\t{%2, %0|%0, %2}"
7463   [(set_attr "type" "sseiadd")
7464    (set_attr "atom_unit" "simul")
7465    (set_attr "prefix_extra" "1")
7466    (set (attr "prefix_rex") (symbol_ref "x86_extended_reg_mentioned_p (insn)"))
7467    (set_attr "mode" "DI")])
7468
7469 (define_expand "ssse3_pmulhrswv8hi3"
7470   [(set (match_operand:V8HI 0 "register_operand" "")
7471         (truncate:V8HI
7472           (lshiftrt:V8SI
7473             (plus:V8SI
7474               (lshiftrt:V8SI
7475                 (mult:V8SI
7476                   (sign_extend:V8SI
7477                     (match_operand:V8HI 1 "nonimmediate_operand" ""))
7478                   (sign_extend:V8SI
7479                     (match_operand:V8HI 2 "nonimmediate_operand" "")))
7480                 (const_int 14))
7481               (const_vector:V8HI [(const_int 1) (const_int 1)
7482                                   (const_int 1) (const_int 1)
7483                                   (const_int 1) (const_int 1)
7484                                   (const_int 1) (const_int 1)]))
7485             (const_int 1))))]
7486   "TARGET_SSSE3"
7487   "ix86_fixup_binary_operands_no_copy (MULT, V8HImode, operands);")
7488
7489 (define_insn "*ssse3_pmulhrswv8hi3"
7490   [(set (match_operand:V8HI 0 "register_operand" "=x,x")
7491         (truncate:V8HI
7492           (lshiftrt:V8SI
7493             (plus:V8SI
7494               (lshiftrt:V8SI
7495                 (mult:V8SI
7496                   (sign_extend:V8SI
7497                     (match_operand:V8HI 1 "nonimmediate_operand" "%0,x"))
7498                   (sign_extend:V8SI
7499                     (match_operand:V8HI 2 "nonimmediate_operand" "xm,xm")))
7500                 (const_int 14))
7501               (const_vector:V8HI [(const_int 1) (const_int 1)
7502                                   (const_int 1) (const_int 1)
7503                                   (const_int 1) (const_int 1)
7504                                   (const_int 1) (const_int 1)]))
7505             (const_int 1))))]
7506   "TARGET_SSSE3 && ix86_binary_operator_ok (MULT, V8HImode, operands)"
7507   "@
7508    pmulhrsw\t{%2, %0|%0, %2}
7509    vpmulhrsw\t{%2, %1, %0|%0, %1, %2}"
7510   [(set_attr "isa" "noavx,avx")
7511    (set_attr "type" "sseimul")
7512    (set_attr "prefix_data16" "1,*")
7513    (set_attr "prefix_extra" "1")
7514    (set_attr "prefix" "orig,vex")
7515    (set_attr "mode" "TI")])
7516
7517 (define_expand "ssse3_pmulhrswv4hi3"
7518   [(set (match_operand:V4HI 0 "register_operand" "")
7519         (truncate:V4HI
7520           (lshiftrt:V4SI
7521             (plus:V4SI
7522               (lshiftrt:V4SI
7523                 (mult:V4SI
7524                   (sign_extend:V4SI
7525                     (match_operand:V4HI 1 "nonimmediate_operand" ""))
7526                   (sign_extend:V4SI
7527                     (match_operand:V4HI 2 "nonimmediate_operand" "")))
7528                 (const_int 14))
7529               (const_vector:V4HI [(const_int 1) (const_int 1)
7530                                   (const_int 1) (const_int 1)]))
7531             (const_int 1))))]
7532   "TARGET_SSSE3"
7533   "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
7534
7535 (define_insn "*ssse3_pmulhrswv4hi3"
7536   [(set (match_operand:V4HI 0 "register_operand" "=y")
7537         (truncate:V4HI
7538           (lshiftrt:V4SI
7539             (plus:V4SI
7540               (lshiftrt:V4SI
7541                 (mult:V4SI
7542                   (sign_extend:V4SI
7543                     (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
7544                   (sign_extend:V4SI
7545                     (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
7546                 (const_int 14))
7547               (const_vector:V4HI [(const_int 1) (const_int 1)
7548                                   (const_int 1) (const_int 1)]))
7549             (const_int 1))))]
7550   "TARGET_SSSE3 && ix86_binary_operator_ok (MULT, V4HImode, operands)"
7551   "pmulhrsw\t{%2, %0|%0, %2}"
7552   [(set_attr "type" "sseimul")
7553    (set_attr "prefix_extra" "1")
7554    (set (attr "prefix_rex") (symbol_ref "x86_extended_reg_mentioned_p (insn)"))
7555    (set_attr "mode" "DI")])
7556
7557 (define_insn "ssse3_pshufbv16qi3"
7558   [(set (match_operand:V16QI 0 "register_operand" "=x,x")
7559         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "0,x")
7560                        (match_operand:V16QI 2 "nonimmediate_operand" "xm,xm")]
7561                       UNSPEC_PSHUFB))]
7562   "TARGET_SSSE3"
7563   "@
7564    pshufb\t{%2, %0|%0, %2}
7565    vpshufb\t{%2, %1, %0|%0, %1, %2}"
7566   [(set_attr "isa" "noavx,avx")
7567    (set_attr "type" "sselog1")
7568    (set_attr "prefix_data16" "1,*")
7569    (set_attr "prefix_extra" "1")
7570    (set_attr "prefix" "orig,vex")
7571    (set_attr "mode" "TI")])
7572
7573 (define_insn "ssse3_pshufbv8qi3"
7574   [(set (match_operand:V8QI 0 "register_operand" "=y")
7575         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "0")
7576                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
7577                      UNSPEC_PSHUFB))]
7578   "TARGET_SSSE3"
7579   "pshufb\t{%2, %0|%0, %2}";
7580   [(set_attr "type" "sselog1")
7581    (set_attr "prefix_extra" "1")
7582    (set (attr "prefix_rex") (symbol_ref "x86_extended_reg_mentioned_p (insn)"))
7583    (set_attr "mode" "DI")])
7584
7585 (define_insn "ssse3_psign<mode>3"
7586   [(set (match_operand:VI124_128 0 "register_operand" "=x,x")
7587         (unspec:VI124_128
7588           [(match_operand:VI124_128 1 "register_operand" "0,x")
7589            (match_operand:VI124_128 2 "nonimmediate_operand" "xm,xm")]
7590           UNSPEC_PSIGN))]
7591   "TARGET_SSSE3"
7592   "@
7593    psign<ssemodesuffix>\t{%2, %0|%0, %2}
7594    vpsign<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
7595   [(set_attr "isa" "noavx,avx")
7596    (set_attr "type" "sselog1")
7597    (set_attr "prefix_data16" "1,*")
7598    (set_attr "prefix_extra" "1")
7599    (set_attr "prefix" "orig,vex")
7600    (set_attr "mode" "TI")])
7601
7602 (define_insn "ssse3_psign<mode>3"
7603   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
7604         (unspec:MMXMODEI
7605           [(match_operand:MMXMODEI 1 "register_operand" "0")
7606            (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")]
7607           UNSPEC_PSIGN))]
7608   "TARGET_SSSE3"
7609   "psign<mmxvecsize>\t{%2, %0|%0, %2}";
7610   [(set_attr "type" "sselog1")
7611    (set_attr "prefix_extra" "1")
7612    (set (attr "prefix_rex") (symbol_ref "x86_extended_reg_mentioned_p (insn)"))
7613    (set_attr "mode" "DI")])
7614
7615 (define_insn "ssse3_palignrti"
7616   [(set (match_operand:TI 0 "register_operand" "=x,x")
7617         (unspec:TI [(match_operand:TI 1 "register_operand" "0,x")
7618                     (match_operand:TI 2 "nonimmediate_operand" "xm,xm")
7619                     (match_operand:SI 3 "const_0_to_255_mul_8_operand" "n,n")]
7620                    UNSPEC_PALIGNR))]
7621   "TARGET_SSSE3"
7622 {
7623   operands[3] = GEN_INT (INTVAL (operands[3]) / 8);
7624
7625   switch (which_alternative)
7626     {
7627     case 0:
7628       return "palignr\t{%3, %2, %0|%0, %2, %3}";
7629     case 1:
7630       return "vpalignr\t{%3, %2, %1, %0|%0, %1, %2, %3}";
7631     default:
7632       gcc_unreachable ();
7633     }
7634 }
7635   [(set_attr "isa" "noavx,avx")
7636    (set_attr "type" "sseishft")
7637    (set_attr "atom_unit" "sishuf")
7638    (set_attr "prefix_data16" "1,*")
7639    (set_attr "prefix_extra" "1")
7640    (set_attr "length_immediate" "1")
7641    (set_attr "prefix" "orig,vex")
7642    (set_attr "mode" "TI")])
7643
7644 (define_insn "ssse3_palignrdi"
7645   [(set (match_operand:DI 0 "register_operand" "=y")
7646         (unspec:DI [(match_operand:DI 1 "register_operand" "0")
7647                     (match_operand:DI 2 "nonimmediate_operand" "ym")
7648                     (match_operand:SI 3 "const_0_to_255_mul_8_operand" "n")]
7649                    UNSPEC_PALIGNR))]
7650   "TARGET_SSSE3"
7651 {
7652   operands[3] = GEN_INT (INTVAL (operands[3]) / 8);
7653   return "palignr\t{%3, %2, %0|%0, %2, %3}";
7654 }
7655   [(set_attr "type" "sseishft")
7656    (set_attr "atom_unit" "sishuf")
7657    (set_attr "prefix_extra" "1")
7658    (set_attr "length_immediate" "1")
7659    (set (attr "prefix_rex") (symbol_ref "x86_extended_reg_mentioned_p (insn)"))
7660    (set_attr "mode" "DI")])
7661
7662 (define_insn "abs<mode>2"
7663   [(set (match_operand:VI124_128 0 "register_operand" "=x")
7664         (abs:VI124_128
7665           (match_operand:VI124_128 1 "nonimmediate_operand" "xm")))]
7666   "TARGET_SSSE3"
7667   "%vpabs<ssemodesuffix>\t{%1, %0|%0, %1}"
7668   [(set_attr "type" "sselog1")
7669    (set_attr "prefix_data16" "1")
7670    (set_attr "prefix_extra" "1")
7671    (set_attr "prefix" "maybe_vex")
7672    (set_attr "mode" "TI")])
7673
7674 (define_insn "abs<mode>2"
7675   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
7676         (abs:MMXMODEI
7677           (match_operand:MMXMODEI 1 "nonimmediate_operand" "ym")))]
7678   "TARGET_SSSE3"
7679   "pabs<mmxvecsize>\t{%1, %0|%0, %1}";
7680   [(set_attr "type" "sselog1")
7681    (set_attr "prefix_rep" "0")
7682    (set_attr "prefix_extra" "1")
7683    (set (attr "prefix_rex") (symbol_ref "x86_extended_reg_mentioned_p (insn)"))
7684    (set_attr "mode" "DI")])
7685
7686 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7687 ;;
7688 ;; AMD SSE4A instructions
7689 ;;
7690 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7691
7692 (define_insn "sse4a_movnt<mode>"
7693   [(set (match_operand:MODEF 0 "memory_operand" "=m")
7694         (unspec:MODEF
7695           [(match_operand:MODEF 1 "register_operand" "x")]
7696           UNSPEC_MOVNT))]
7697   "TARGET_SSE4A"
7698   "movnt<ssemodesuffix>\t{%1, %0|%0, %1}"
7699   [(set_attr "type" "ssemov")
7700    (set_attr "mode" "<MODE>")])
7701
7702 (define_insn "sse4a_vmmovnt<mode>"
7703   [(set (match_operand:<ssescalarmode> 0 "memory_operand" "=m")
7704         (unspec:<ssescalarmode>
7705           [(vec_select:<ssescalarmode>
7706              (match_operand:VF_128 1 "register_operand" "x")
7707              (parallel [(const_int 0)]))]
7708           UNSPEC_MOVNT))]
7709   "TARGET_SSE4A"
7710   "movnt<ssescalarmodesuffix>\t{%1, %0|%0, %1}"
7711   [(set_attr "type" "ssemov")
7712    (set_attr "mode" "<ssescalarmode>")])
7713
7714 (define_insn "sse4a_extrqi"
7715   [(set (match_operand:V2DI 0 "register_operand" "=x")
7716         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0")
7717                       (match_operand 2 "const_0_to_255_operand" "")
7718                       (match_operand 3 "const_0_to_255_operand" "")]
7719                      UNSPEC_EXTRQI))]
7720   "TARGET_SSE4A"
7721   "extrq\t{%3, %2, %0|%0, %2, %3}"
7722   [(set_attr "type" "sse")
7723    (set_attr "prefix_data16" "1")
7724    (set_attr "length_immediate" "2")
7725    (set_attr "mode" "TI")])
7726
7727 (define_insn "sse4a_extrq"
7728   [(set (match_operand:V2DI 0 "register_operand" "=x")
7729         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0")
7730                       (match_operand:V16QI 2 "register_operand" "x")]
7731                      UNSPEC_EXTRQ))]
7732   "TARGET_SSE4A"
7733   "extrq\t{%2, %0|%0, %2}"
7734   [(set_attr "type" "sse")
7735    (set_attr "prefix_data16" "1")
7736    (set_attr "mode" "TI")])
7737
7738 (define_insn "sse4a_insertqi"
7739   [(set (match_operand:V2DI 0 "register_operand" "=x")
7740         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0")
7741                       (match_operand:V2DI 2 "register_operand" "x")
7742                       (match_operand 3 "const_0_to_255_operand" "")
7743                       (match_operand 4 "const_0_to_255_operand" "")]
7744                      UNSPEC_INSERTQI))]
7745   "TARGET_SSE4A"
7746   "insertq\t{%4, %3, %2, %0|%0, %2, %3, %4}"
7747   [(set_attr "type" "sseins")
7748    (set_attr "prefix_data16" "0")
7749    (set_attr "prefix_rep" "1")
7750    (set_attr "length_immediate" "2")
7751    (set_attr "mode" "TI")])
7752
7753 (define_insn "sse4a_insertq"
7754   [(set (match_operand:V2DI 0 "register_operand" "=x")
7755         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0")
7756                       (match_operand:V2DI 2 "register_operand" "x")]
7757                      UNSPEC_INSERTQ))]
7758   "TARGET_SSE4A"
7759   "insertq\t{%2, %0|%0, %2}"
7760   [(set_attr "type" "sseins")
7761    (set_attr "prefix_data16" "0")
7762    (set_attr "prefix_rep" "1")
7763    (set_attr "mode" "TI")])
7764
7765 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7766 ;;
7767 ;; Intel SSE4.1 instructions
7768 ;;
7769 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7770
7771 (define_insn "<sse4_1>_blend<ssemodesuffix><avxsizesuffix>"
7772   [(set (match_operand:VF 0 "register_operand" "=x,x")
7773         (vec_merge:VF
7774           (match_operand:VF 2 "nonimmediate_operand" "xm,xm")
7775           (match_operand:VF 1 "register_operand" "0,x")
7776           (match_operand:SI 3 "const_0_to_<blendbits>_operand" "")))]
7777   "TARGET_SSE4_1"
7778   "@
7779    blend<ssemodesuffix>\t{%3, %2, %0|%0, %2, %3}
7780    vblend<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
7781   [(set_attr "isa" "noavx,avx")
7782    (set_attr "type" "ssemov")
7783    (set_attr "length_immediate" "1")
7784    (set_attr "prefix_data16" "1,*")
7785    (set_attr "prefix_extra" "1")
7786    (set_attr "prefix" "orig,vex")
7787    (set_attr "mode" "<MODE>")])
7788
7789 (define_insn "<sse4_1>_blendv<ssemodesuffix><avxsizesuffix>"
7790   [(set (match_operand:VF 0 "reg_not_xmm0_operand_maybe_avx" "=x,x")
7791         (unspec:VF
7792           [(match_operand:VF 1 "reg_not_xmm0_operand_maybe_avx" "0,x")
7793            (match_operand:VF 2 "nonimm_not_xmm0_operand_maybe_avx" "xm,xm")
7794            (match_operand:VF 3 "register_operand" "Yz,x")]
7795           UNSPEC_BLENDV))]
7796   "TARGET_SSE4_1"
7797   "@
7798    blendv<ssemodesuffix>\t{%3, %2, %0|%0, %2, %3}
7799    vblendv<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
7800   [(set_attr "isa" "noavx,avx")
7801    (set_attr "type" "ssemov")
7802    (set_attr "length_immediate" "1")
7803    (set_attr "prefix_data16" "1,*")
7804    (set_attr "prefix_extra" "1")
7805    (set_attr "prefix" "orig,vex")
7806    (set_attr "mode" "<MODE>")])
7807
7808 (define_insn "<sse4_1>_dp<ssemodesuffix><avxsizesuffix>"
7809   [(set (match_operand:VF 0 "register_operand" "=x,x")
7810         (unspec:VF
7811           [(match_operand:VF 1 "nonimmediate_operand" "%0,x")
7812            (match_operand:VF 2 "nonimmediate_operand" "xm,xm")
7813            (match_operand:SI 3 "const_0_to_255_operand" "n,n")]
7814           UNSPEC_DP))]
7815   "TARGET_SSE4_1"
7816   "@
7817    dp<ssemodesuffix>\t{%3, %2, %0|%0, %2, %3}
7818    vdp<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
7819   [(set_attr "isa" "noavx,avx")
7820    (set_attr "type" "ssemul")
7821    (set_attr "length_immediate" "1")
7822    (set_attr "prefix_data16" "1,*")
7823    (set_attr "prefix_extra" "1")
7824    (set_attr "prefix" "orig,vex")
7825    (set_attr "mode" "<MODE>")])
7826
7827 (define_insn "sse4_1_movntdqa"
7828   [(set (match_operand:V2DI 0 "register_operand" "=x")
7829         (unspec:V2DI [(match_operand:V2DI 1 "memory_operand" "m")]
7830                      UNSPEC_MOVNTDQA))]
7831   "TARGET_SSE4_1"
7832   "%vmovntdqa\t{%1, %0|%0, %1}"
7833   [(set_attr "type" "ssemov")
7834    (set_attr "prefix_extra" "1")
7835    (set_attr "prefix" "maybe_vex")
7836    (set_attr "mode" "TI")])
7837
7838 (define_insn "sse4_1_mpsadbw"
7839   [(set (match_operand:V16QI 0 "register_operand" "=x,x")
7840         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "0,x")
7841                        (match_operand:V16QI 2 "nonimmediate_operand" "xm,xm")
7842                        (match_operand:SI 3 "const_0_to_255_operand" "n,n")]
7843                       UNSPEC_MPSADBW))]
7844   "TARGET_SSE4_1"
7845   "@
7846    mpsadbw\t{%3, %2, %0|%0, %2, %3}
7847    vmpsadbw\t{%3, %2, %1, %0|%0, %1, %2, %3}"
7848   [(set_attr "isa" "noavx,avx")
7849    (set_attr "type" "sselog1")
7850    (set_attr "length_immediate" "1")
7851    (set_attr "prefix_extra" "1")
7852    (set_attr "prefix" "orig,vex")
7853    (set_attr "mode" "TI")])
7854
7855 (define_insn "sse4_1_packusdw"
7856   [(set (match_operand:V8HI 0 "register_operand" "=x,x")
7857         (vec_concat:V8HI
7858           (us_truncate:V4HI
7859             (match_operand:V4SI 1 "register_operand" "0,x"))
7860           (us_truncate:V4HI
7861             (match_operand:V4SI 2 "nonimmediate_operand" "xm,xm"))))]
7862   "TARGET_SSE4_1"
7863   "@
7864    packusdw\t{%2, %0|%0, %2}
7865    vpackusdw\t{%2, %1, %0|%0, %1, %2}"
7866   [(set_attr "isa" "noavx,avx")
7867    (set_attr "type" "sselog")
7868    (set_attr "prefix_extra" "1")
7869    (set_attr "prefix" "orig,vex")
7870    (set_attr "mode" "TI")])
7871
7872 (define_insn "sse4_1_pblendvb"
7873   [(set (match_operand:V16QI 0 "reg_not_xmm0_operand" "=x,x")
7874         (unspec:V16QI
7875           [(match_operand:V16QI 1 "reg_not_xmm0_operand_maybe_avx" "0,x")
7876            (match_operand:V16QI 2 "nonimm_not_xmm0_operand_maybe_avx" "xm,xm")
7877            (match_operand:V16QI 3 "register_operand" "Yz,x")]
7878           UNSPEC_BLENDV))]
7879   "TARGET_SSE4_1"
7880   "@
7881    pblendvb\t{%3, %2, %0|%0, %2, %3}
7882    vpblendvb\t{%3, %2, %1, %0|%0, %1, %2, %3}"
7883   [(set_attr "isa" "noavx,avx")
7884    (set_attr "type" "ssemov")
7885    (set_attr "prefix_extra" "1")
7886    (set_attr "length_immediate" "*,1")
7887    (set_attr "prefix" "orig,vex")
7888    (set_attr "mode" "TI")])
7889
7890 (define_insn "sse4_1_pblendw"
7891   [(set (match_operand:V8HI 0 "register_operand" "=x,x")
7892         (vec_merge:V8HI
7893           (match_operand:V8HI 2 "nonimmediate_operand" "xm,xm")
7894           (match_operand:V8HI 1 "register_operand" "0,x")
7895           (match_operand:SI 3 "const_0_to_255_operand" "n,n")))]
7896   "TARGET_SSE4_1"
7897   "@
7898    pblendw\t{%3, %2, %0|%0, %2, %3}
7899    vpblendw\t{%3, %2, %1, %0|%0, %1, %2, %3}"
7900   [(set_attr "isa" "noavx,avx")
7901    (set_attr "type" "ssemov")
7902    (set_attr "prefix_extra" "1")
7903    (set_attr "length_immediate" "1")
7904    (set_attr "prefix" "orig,vex")
7905    (set_attr "mode" "TI")])
7906
7907 (define_insn "sse4_1_phminposuw"
7908   [(set (match_operand:V8HI 0 "register_operand" "=x")
7909         (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")]
7910                      UNSPEC_PHMINPOSUW))]
7911   "TARGET_SSE4_1"
7912   "%vphminposuw\t{%1, %0|%0, %1}"
7913   [(set_attr "type" "sselog1")
7914    (set_attr "prefix_extra" "1")
7915    (set_attr "prefix" "maybe_vex")
7916    (set_attr "mode" "TI")])
7917
7918 (define_insn "sse4_1_<code>v8qiv8hi2"
7919   [(set (match_operand:V8HI 0 "register_operand" "=x")
7920         (any_extend:V8HI
7921           (vec_select:V8QI
7922             (match_operand:V16QI 1 "nonimmediate_operand" "xm")
7923             (parallel [(const_int 0)
7924                        (const_int 1)
7925                        (const_int 2)
7926                        (const_int 3)
7927                        (const_int 4)
7928                        (const_int 5)
7929                        (const_int 6)
7930                        (const_int 7)]))))]
7931   "TARGET_SSE4_1"
7932   "%vpmov<extsuffix>bw\t{%1, %0|%0, %1}"
7933   [(set_attr "type" "ssemov")
7934    (set_attr "prefix_extra" "1")
7935    (set_attr "prefix" "maybe_vex")
7936    (set_attr "mode" "TI")])
7937
7938 (define_insn "sse4_1_<code>v4qiv4si2"
7939   [(set (match_operand:V4SI 0 "register_operand" "=x")
7940         (any_extend:V4SI
7941           (vec_select:V4QI
7942             (match_operand:V16QI 1 "nonimmediate_operand" "xm")
7943             (parallel [(const_int 0)
7944                        (const_int 1)
7945                        (const_int 2)
7946                        (const_int 3)]))))]
7947   "TARGET_SSE4_1"
7948   "%vpmov<extsuffix>bd\t{%1, %0|%0, %1}"
7949   [(set_attr "type" "ssemov")
7950    (set_attr "prefix_extra" "1")
7951    (set_attr "prefix" "maybe_vex")
7952    (set_attr "mode" "TI")])
7953
7954 (define_insn "sse4_1_<code>v4hiv4si2"
7955   [(set (match_operand:V4SI 0 "register_operand" "=x")
7956         (any_extend:V4SI
7957           (vec_select:V4HI
7958             (match_operand:V8HI 1 "nonimmediate_operand" "xm")
7959             (parallel [(const_int 0)
7960                        (const_int 1)
7961                        (const_int 2)
7962                        (const_int 3)]))))]
7963   "TARGET_SSE4_1"
7964   "%vpmov<extsuffix>wd\t{%1, %0|%0, %1}"
7965   [(set_attr "type" "ssemov")
7966    (set_attr "prefix_extra" "1")
7967    (set_attr "prefix" "maybe_vex")
7968    (set_attr "mode" "TI")])
7969
7970 (define_insn "sse4_1_<code>v2qiv2di2"
7971   [(set (match_operand:V2DI 0 "register_operand" "=x")
7972         (any_extend:V2DI
7973           (vec_select:V2QI
7974             (match_operand:V16QI 1 "nonimmediate_operand" "xm")
7975             (parallel [(const_int 0)
7976                        (const_int 1)]))))]
7977   "TARGET_SSE4_1"
7978   "%vpmov<extsuffix>bq\t{%1, %0|%0, %1}"
7979   [(set_attr "type" "ssemov")
7980    (set_attr "prefix_extra" "1")
7981    (set_attr "prefix" "maybe_vex")
7982    (set_attr "mode" "TI")])
7983
7984 (define_insn "sse4_1_<code>v2hiv2di2"
7985   [(set (match_operand:V2DI 0 "register_operand" "=x")
7986         (any_extend:V2DI
7987           (vec_select:V2HI
7988             (match_operand:V8HI 1 "nonimmediate_operand" "xm")
7989             (parallel [(const_int 0)
7990                        (const_int 1)]))))]
7991   "TARGET_SSE4_1"
7992   "%vpmov<extsuffix>wq\t{%1, %0|%0, %1}"
7993   [(set_attr "type" "ssemov")
7994    (set_attr "prefix_extra" "1")
7995    (set_attr "prefix" "maybe_vex")
7996    (set_attr "mode" "TI")])
7997
7998 (define_insn "sse4_1_<code>v2siv2di2"
7999   [(set (match_operand:V2DI 0 "register_operand" "=x")
8000         (any_extend:V2DI
8001           (vec_select:V2SI
8002             (match_operand:V4SI 1 "nonimmediate_operand" "xm")
8003             (parallel [(const_int 0)
8004                        (const_int 1)]))))]
8005   "TARGET_SSE4_1"
8006   "%vpmov<extsuffix>dq\t{%1, %0|%0, %1}"
8007   [(set_attr "type" "ssemov")
8008    (set_attr "prefix_extra" "1")
8009    (set_attr "prefix" "maybe_vex")
8010    (set_attr "mode" "TI")])
8011
8012 ;; ptestps/ptestpd are very similar to comiss and ucomiss when
8013 ;; setting FLAGS_REG. But it is not a really compare instruction.
8014 (define_insn "avx_vtest<ssemodesuffix><avxsizesuffix>"
8015   [(set (reg:CC FLAGS_REG)
8016         (unspec:CC [(match_operand:VF 0 "register_operand" "x")
8017                     (match_operand:VF 1 "nonimmediate_operand" "xm")]
8018                    UNSPEC_VTESTP))]
8019   "TARGET_AVX"
8020   "vtest<ssemodesuffix>\t{%1, %0|%0, %1}"
8021   [(set_attr "type" "ssecomi")
8022    (set_attr "prefix_extra" "1")
8023    (set_attr "prefix" "vex")
8024    (set_attr "mode" "<MODE>")])
8025
8026 ;; ptest is very similar to comiss and ucomiss when setting FLAGS_REG.
8027 ;; But it is not a really compare instruction.
8028 (define_insn "avx_ptest256"
8029   [(set (reg:CC FLAGS_REG)
8030         (unspec:CC [(match_operand:V4DI 0 "register_operand" "x")
8031                     (match_operand:V4DI 1 "nonimmediate_operand" "xm")]
8032                    UNSPEC_PTEST))]
8033   "TARGET_AVX"
8034   "vptest\t{%1, %0|%0, %1}"
8035   [(set_attr "type" "ssecomi")
8036    (set_attr "prefix_extra" "1")
8037    (set_attr "prefix" "vex")
8038    (set_attr "mode" "OI")])
8039
8040 (define_insn "sse4_1_ptest"
8041   [(set (reg:CC FLAGS_REG)
8042         (unspec:CC [(match_operand:V2DI 0 "register_operand" "x")
8043                     (match_operand:V2DI 1 "nonimmediate_operand" "xm")]
8044                    UNSPEC_PTEST))]
8045   "TARGET_SSE4_1"
8046   "%vptest\t{%1, %0|%0, %1}"
8047   [(set_attr "type" "ssecomi")
8048    (set_attr "prefix_extra" "1")
8049    (set_attr "prefix" "maybe_vex")
8050    (set_attr "mode" "TI")])
8051
8052 (define_insn "<sse4_1>_round<ssemodesuffix><avxsizesuffix>"
8053   [(set (match_operand:VF 0 "register_operand" "=x")
8054         (unspec:VF
8055           [(match_operand:VF 1 "nonimmediate_operand" "xm")
8056            (match_operand:SI 2 "const_0_to_15_operand" "n")]
8057           UNSPEC_ROUND))]
8058   "TARGET_ROUND"
8059   "%vround<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8060   [(set_attr "type" "ssecvt")
8061    (set (attr "prefix_data16")
8062      (if_then_else
8063        (ne (symbol_ref "TARGET_AVX") (const_int 0))
8064      (const_string "*")
8065      (const_string "1")))
8066    (set_attr "prefix_extra" "1")
8067    (set_attr "length_immediate" "1")
8068    (set_attr "prefix" "maybe_vex")
8069    (set_attr "mode" "<MODE>")])
8070
8071 (define_insn "sse4_1_round<ssescalarmodesuffix>"
8072   [(set (match_operand:VF_128 0 "register_operand" "=x,x")
8073         (vec_merge:VF_128
8074           (unspec:VF_128
8075             [(match_operand:VF_128 2 "register_operand" "x,x")
8076              (match_operand:SI 3 "const_0_to_15_operand" "n,n")]
8077             UNSPEC_ROUND)
8078           (match_operand:VF_128 1 "register_operand" "0,x")
8079           (const_int 1)))]
8080   "TARGET_ROUND"
8081   "@
8082    round<ssescalarmodesuffix>\t{%3, %2, %0|%0, %2, %3}
8083    vround<ssescalarmodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
8084   [(set_attr "isa" "noavx,avx")
8085    (set_attr "type" "ssecvt")
8086    (set_attr "length_immediate" "1")
8087    (set_attr "prefix_data16" "1,*")
8088    (set_attr "prefix_extra" "1")
8089    (set_attr "prefix" "orig,vex")
8090    (set_attr "mode" "<MODE>")])
8091
8092 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8093 ;;
8094 ;; Intel SSE4.2 string/text processing instructions
8095 ;;
8096 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8097
8098 (define_insn_and_split "sse4_2_pcmpestr"
8099   [(set (match_operand:SI 0 "register_operand" "=c,c")
8100         (unspec:SI
8101           [(match_operand:V16QI 2 "reg_not_xmm0_operand" "x,x")
8102            (match_operand:SI 3 "register_operand" "a,a")
8103            (match_operand:V16QI 4 "nonimm_not_xmm0_operand" "x,m")
8104            (match_operand:SI 5 "register_operand" "d,d")
8105            (match_operand:SI 6 "const_0_to_255_operand" "n,n")]
8106           UNSPEC_PCMPESTR))
8107    (set (match_operand:V16QI 1 "register_operand" "=Yz,Yz")
8108         (unspec:V16QI
8109           [(match_dup 2)
8110            (match_dup 3)
8111            (match_dup 4)
8112            (match_dup 5)
8113            (match_dup 6)]
8114           UNSPEC_PCMPESTR))
8115    (set (reg:CC FLAGS_REG)
8116         (unspec:CC
8117           [(match_dup 2)
8118            (match_dup 3)
8119            (match_dup 4)
8120            (match_dup 5)
8121            (match_dup 6)]
8122           UNSPEC_PCMPESTR))]
8123   "TARGET_SSE4_2
8124    && can_create_pseudo_p ()"
8125   "#"
8126   "&& 1"
8127   [(const_int 0)]
8128 {
8129   int ecx = !find_regno_note (curr_insn, REG_UNUSED, REGNO (operands[0]));
8130   int xmm0 = !find_regno_note (curr_insn, REG_UNUSED, REGNO (operands[1]));
8131   int flags = !find_regno_note (curr_insn, REG_UNUSED, FLAGS_REG);
8132
8133   if (ecx)
8134     emit_insn (gen_sse4_2_pcmpestri (operands[0], operands[2],
8135                                      operands[3], operands[4],
8136                                      operands[5], operands[6]));
8137   if (xmm0)
8138     emit_insn (gen_sse4_2_pcmpestrm (operands[1], operands[2],
8139                                      operands[3], operands[4],
8140                                      operands[5], operands[6]));
8141   if (flags && !(ecx || xmm0))
8142     emit_insn (gen_sse4_2_pcmpestr_cconly (NULL, NULL,
8143                                            operands[2], operands[3],
8144                                            operands[4], operands[5],
8145                                            operands[6]));
8146   DONE;
8147 }
8148   [(set_attr "type" "sselog")
8149    (set_attr "prefix_data16" "1")
8150    (set_attr "prefix_extra" "1")
8151    (set_attr "length_immediate" "1")
8152    (set_attr "memory" "none,load")
8153    (set_attr "mode" "TI")])
8154
8155 (define_insn "sse4_2_pcmpestri"
8156   [(set (match_operand:SI 0 "register_operand" "=c,c")
8157         (unspec:SI
8158           [(match_operand:V16QI 1 "register_operand" "x,x")
8159            (match_operand:SI 2 "register_operand" "a,a")
8160            (match_operand:V16QI 3 "nonimmediate_operand" "x,m")
8161            (match_operand:SI 4 "register_operand" "d,d")
8162            (match_operand:SI 5 "const_0_to_255_operand" "n,n")]
8163           UNSPEC_PCMPESTR))
8164    (set (reg:CC FLAGS_REG)
8165         (unspec:CC
8166           [(match_dup 1)
8167            (match_dup 2)
8168            (match_dup 3)
8169            (match_dup 4)
8170            (match_dup 5)]
8171           UNSPEC_PCMPESTR))]
8172   "TARGET_SSE4_2"
8173   "%vpcmpestri\t{%5, %3, %1|%1, %3, %5}"
8174   [(set_attr "type" "sselog")
8175    (set_attr "prefix_data16" "1")
8176    (set_attr "prefix_extra" "1")
8177    (set_attr "prefix" "maybe_vex")
8178    (set_attr "length_immediate" "1")
8179    (set_attr "memory" "none,load")
8180    (set_attr "mode" "TI")])
8181
8182 (define_insn "sse4_2_pcmpestrm"
8183   [(set (match_operand:V16QI 0 "register_operand" "=Yz,Yz")
8184         (unspec:V16QI
8185           [(match_operand:V16QI 1 "register_operand" "x,x")
8186            (match_operand:SI 2 "register_operand" "a,a")
8187            (match_operand:V16QI 3 "nonimmediate_operand" "x,m")
8188            (match_operand:SI 4 "register_operand" "d,d")
8189            (match_operand:SI 5 "const_0_to_255_operand" "n,n")]
8190           UNSPEC_PCMPESTR))
8191    (set (reg:CC FLAGS_REG)
8192         (unspec:CC
8193           [(match_dup 1)
8194            (match_dup 2)
8195            (match_dup 3)
8196            (match_dup 4)
8197            (match_dup 5)]
8198           UNSPEC_PCMPESTR))]
8199   "TARGET_SSE4_2"
8200   "%vpcmpestrm\t{%5, %3, %1|%1, %3, %5}"
8201   [(set_attr "type" "sselog")
8202    (set_attr "prefix_data16" "1")
8203    (set_attr "prefix_extra" "1")
8204    (set_attr "length_immediate" "1")
8205    (set_attr "prefix" "maybe_vex")
8206    (set_attr "memory" "none,load")
8207    (set_attr "mode" "TI")])
8208
8209 (define_insn "sse4_2_pcmpestr_cconly"
8210   [(set (reg:CC FLAGS_REG)
8211         (unspec:CC
8212           [(match_operand:V16QI 2 "register_operand" "x,x,x,x")
8213            (match_operand:SI 3 "register_operand" "a,a,a,a")
8214            (match_operand:V16QI 4 "nonimmediate_operand" "x,m,x,m")
8215            (match_operand:SI 5 "register_operand" "d,d,d,d")
8216            (match_operand:SI 6 "const_0_to_255_operand" "n,n,n,n")]
8217           UNSPEC_PCMPESTR))
8218    (clobber (match_scratch:V16QI 0 "=Yz,Yz,X,X"))
8219    (clobber (match_scratch:SI    1 "= X, X,c,c"))]
8220   "TARGET_SSE4_2"
8221   "@
8222    %vpcmpestrm\t{%6, %4, %2|%2, %4, %6}
8223    %vpcmpestrm\t{%6, %4, %2|%2, %4, %6}
8224    %vpcmpestri\t{%6, %4, %2|%2, %4, %6}
8225    %vpcmpestri\t{%6, %4, %2|%2, %4, %6}"
8226   [(set_attr "type" "sselog")
8227    (set_attr "prefix_data16" "1")
8228    (set_attr "prefix_extra" "1")
8229    (set_attr "length_immediate" "1")
8230    (set_attr "memory" "none,load,none,load")
8231    (set_attr "prefix" "maybe_vex")
8232    (set_attr "mode" "TI")])
8233
8234 (define_insn_and_split "sse4_2_pcmpistr"
8235   [(set (match_operand:SI 0 "register_operand" "=c,c")
8236         (unspec:SI
8237           [(match_operand:V16QI 2 "reg_not_xmm0_operand" "x,x")
8238            (match_operand:V16QI 3 "nonimm_not_xmm0_operand" "x,m")
8239            (match_operand:SI 4 "const_0_to_255_operand" "n,n")]
8240           UNSPEC_PCMPISTR))
8241    (set (match_operand:V16QI 1 "register_operand" "=Yz,Yz")
8242         (unspec:V16QI
8243           [(match_dup 2)
8244            (match_dup 3)
8245            (match_dup 4)]
8246           UNSPEC_PCMPISTR))
8247    (set (reg:CC FLAGS_REG)
8248         (unspec:CC
8249           [(match_dup 2)
8250            (match_dup 3)
8251            (match_dup 4)]
8252           UNSPEC_PCMPISTR))]
8253   "TARGET_SSE4_2
8254    && can_create_pseudo_p ()"
8255   "#"
8256   "&& 1"
8257   [(const_int 0)]
8258 {
8259   int ecx = !find_regno_note (curr_insn, REG_UNUSED, REGNO (operands[0]));
8260   int xmm0 = !find_regno_note (curr_insn, REG_UNUSED, REGNO (operands[1]));
8261   int flags = !find_regno_note (curr_insn, REG_UNUSED, FLAGS_REG);
8262
8263   if (ecx)
8264     emit_insn (gen_sse4_2_pcmpistri (operands[0], operands[2],
8265                                      operands[3], operands[4]));
8266   if (xmm0)
8267     emit_insn (gen_sse4_2_pcmpistrm (operands[1], operands[2],
8268                                      operands[3], operands[4]));
8269   if (flags && !(ecx || xmm0))
8270     emit_insn (gen_sse4_2_pcmpistr_cconly (NULL, NULL,
8271                                            operands[2], operands[3],
8272                                            operands[4]));
8273   DONE;
8274 }
8275   [(set_attr "type" "sselog")
8276    (set_attr "prefix_data16" "1")
8277    (set_attr "prefix_extra" "1")
8278    (set_attr "length_immediate" "1")
8279    (set_attr "memory" "none,load")
8280    (set_attr "mode" "TI")])
8281
8282 (define_insn "sse4_2_pcmpistri"
8283   [(set (match_operand:SI 0 "register_operand" "=c,c")
8284         (unspec:SI
8285           [(match_operand:V16QI 1 "register_operand" "x,x")
8286            (match_operand:V16QI 2 "nonimmediate_operand" "x,m")
8287            (match_operand:SI 3 "const_0_to_255_operand" "n,n")]
8288           UNSPEC_PCMPISTR))
8289    (set (reg:CC FLAGS_REG)
8290         (unspec:CC
8291           [(match_dup 1)
8292            (match_dup 2)
8293            (match_dup 3)]
8294           UNSPEC_PCMPISTR))]
8295   "TARGET_SSE4_2"
8296   "%vpcmpistri\t{%3, %2, %1|%1, %2, %3}"
8297   [(set_attr "type" "sselog")
8298    (set_attr "prefix_data16" "1")
8299    (set_attr "prefix_extra" "1")
8300    (set_attr "length_immediate" "1")
8301    (set_attr "prefix" "maybe_vex")
8302    (set_attr "memory" "none,load")
8303    (set_attr "mode" "TI")])
8304
8305 (define_insn "sse4_2_pcmpistrm"
8306   [(set (match_operand:V16QI 0 "register_operand" "=Yz,Yz")
8307         (unspec:V16QI
8308           [(match_operand:V16QI 1 "register_operand" "x,x")
8309            (match_operand:V16QI 2 "nonimmediate_operand" "x,m")
8310            (match_operand:SI 3 "const_0_to_255_operand" "n,n")]
8311           UNSPEC_PCMPISTR))
8312    (set (reg:CC FLAGS_REG)
8313         (unspec:CC
8314           [(match_dup 1)
8315            (match_dup 2)
8316            (match_dup 3)]
8317           UNSPEC_PCMPISTR))]
8318   "TARGET_SSE4_2"
8319   "%vpcmpistrm\t{%3, %2, %1|%1, %2, %3}"
8320   [(set_attr "type" "sselog")
8321    (set_attr "prefix_data16" "1")
8322    (set_attr "prefix_extra" "1")
8323    (set_attr "length_immediate" "1")
8324    (set_attr "prefix" "maybe_vex")
8325    (set_attr "memory" "none,load")
8326    (set_attr "mode" "TI")])
8327
8328 (define_insn "sse4_2_pcmpistr_cconly"
8329   [(set (reg:CC FLAGS_REG)
8330         (unspec:CC
8331           [(match_operand:V16QI 2 "register_operand" "x,x,x,x")
8332            (match_operand:V16QI 3 "nonimmediate_operand" "x,m,x,m")
8333            (match_operand:SI 4 "const_0_to_255_operand" "n,n,n,n")]
8334           UNSPEC_PCMPISTR))
8335    (clobber (match_scratch:V16QI 0 "=Yz,Yz,X,X"))
8336    (clobber (match_scratch:SI    1 "= X, X,c,c"))]
8337   "TARGET_SSE4_2"
8338   "@
8339    %vpcmpistrm\t{%4, %3, %2|%2, %3, %4}
8340    %vpcmpistrm\t{%4, %3, %2|%2, %3, %4}
8341    %vpcmpistri\t{%4, %3, %2|%2, %3, %4}
8342    %vpcmpistri\t{%4, %3, %2|%2, %3, %4}"
8343   [(set_attr "type" "sselog")
8344    (set_attr "prefix_data16" "1")
8345    (set_attr "prefix_extra" "1")
8346    (set_attr "length_immediate" "1")
8347    (set_attr "memory" "none,load,none,load")
8348    (set_attr "prefix" "maybe_vex")
8349    (set_attr "mode" "TI")])
8350
8351 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8352 ;;
8353 ;; XOP instructions
8354 ;;
8355 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8356
8357 ;; XOP parallel integer multiply/add instructions.
8358 ;; Note the XOP multiply/add instructions
8359 ;;     a[i] = b[i] * c[i] + d[i];
8360 ;; do not allow the value being added to be a memory operation.
8361 (define_insn "xop_pmacsww"
8362   [(set (match_operand:V8HI 0 "register_operand" "=x")
8363         (plus:V8HI
8364          (mult:V8HI
8365           (match_operand:V8HI 1 "nonimmediate_operand" "%x")
8366           (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
8367          (match_operand:V8HI 3 "nonimmediate_operand" "x")))]
8368   "TARGET_XOP"
8369   "vpmacsww\t{%3, %2, %1, %0|%0, %1, %2, %3}"
8370   [(set_attr "type" "ssemuladd")
8371    (set_attr "mode" "TI")])
8372
8373 (define_insn "xop_pmacssww"
8374   [(set (match_operand:V8HI 0 "register_operand" "=x")
8375         (ss_plus:V8HI
8376          (mult:V8HI (match_operand:V8HI 1 "nonimmediate_operand" "%x")
8377                     (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
8378          (match_operand:V8HI 3 "nonimmediate_operand" "x")))]
8379   "TARGET_XOP"
8380   "vpmacssww\t{%3, %2, %1, %0|%0, %1, %2, %3}"
8381   [(set_attr "type" "ssemuladd")
8382    (set_attr "mode" "TI")])
8383
8384 (define_insn "xop_pmacsdd"
8385   [(set (match_operand:V4SI 0 "register_operand" "=x")
8386         (plus:V4SI
8387          (mult:V4SI
8388           (match_operand:V4SI 1 "nonimmediate_operand" "%x")
8389           (match_operand:V4SI 2 "nonimmediate_operand" "xm"))
8390          (match_operand:V4SI 3 "nonimmediate_operand" "x")))]
8391   "TARGET_XOP"
8392   "vpmacsdd\t{%3, %2, %1, %0|%0, %1, %2, %3}"
8393   [(set_attr "type" "ssemuladd")
8394    (set_attr "mode" "TI")])
8395
8396 (define_insn "xop_pmacssdd"
8397   [(set (match_operand:V4SI 0 "register_operand" "=x")
8398         (ss_plus:V4SI
8399          (mult:V4SI (match_operand:V4SI 1 "nonimmediate_operand" "%x")
8400                     (match_operand:V4SI 2 "nonimmediate_operand" "xm"))
8401          (match_operand:V4SI 3 "nonimmediate_operand" "x")))]
8402   "TARGET_XOP"
8403   "vpmacssdd\t{%3, %2, %1, %0|%0, %1, %2, %3}"
8404   [(set_attr "type" "ssemuladd")
8405    (set_attr "mode" "TI")])
8406
8407 (define_insn "xop_pmacssdql"
8408   [(set (match_operand:V2DI 0 "register_operand" "=x")
8409         (ss_plus:V2DI
8410          (mult:V2DI
8411           (sign_extend:V2DI
8412            (vec_select:V2SI
8413             (match_operand:V4SI 1 "nonimmediate_operand" "%x")
8414             (parallel [(const_int 1)
8415                        (const_int 3)])))
8416           (vec_select:V2SI
8417            (match_operand:V4SI 2 "nonimmediate_operand" "xm")
8418            (parallel [(const_int 1)
8419                       (const_int 3)])))
8420          (match_operand:V2DI 3 "nonimmediate_operand" "x")))]
8421   "TARGET_XOP"
8422   "vpmacssdql\t{%3, %2, %1, %0|%0, %1, %2, %3}"
8423   [(set_attr "type" "ssemuladd")
8424    (set_attr "mode" "TI")])
8425
8426 (define_insn "xop_pmacssdqh"
8427   [(set (match_operand:V2DI 0 "register_operand" "=x")
8428         (ss_plus:V2DI
8429          (mult:V2DI
8430           (sign_extend:V2DI
8431            (vec_select:V2SI
8432             (match_operand:V4SI 1 "nonimmediate_operand" "%x")
8433             (parallel [(const_int 0)
8434                        (const_int 2)])))
8435           (sign_extend:V2DI
8436            (vec_select:V2SI
8437             (match_operand:V4SI 2 "nonimmediate_operand" "xm")
8438             (parallel [(const_int 0)
8439                        (const_int 2)]))))
8440          (match_operand:V2DI 3 "nonimmediate_operand" "x")))]
8441   "TARGET_XOP"
8442   "vpmacssdqh\t{%3, %2, %1, %0|%0, %1, %2, %3}"
8443   [(set_attr "type" "ssemuladd")
8444    (set_attr "mode" "TI")])
8445
8446 (define_insn "xop_pmacsdql"
8447   [(set (match_operand:V2DI 0 "register_operand" "=x")
8448         (plus:V2DI
8449          (mult:V2DI
8450           (sign_extend:V2DI
8451            (vec_select:V2SI
8452             (match_operand:V4SI 1 "nonimmediate_operand" "%x")
8453             (parallel [(const_int 1)
8454                        (const_int 3)])))
8455           (sign_extend:V2DI
8456            (vec_select:V2SI
8457             (match_operand:V4SI 2 "nonimmediate_operand" "xm")
8458             (parallel [(const_int 1)
8459                        (const_int 3)]))))
8460          (match_operand:V2DI 3 "nonimmediate_operand" "x")))]
8461   "TARGET_XOP"
8462   "vpmacsdql\t{%3, %2, %1, %0|%0, %1, %2, %3}"
8463   [(set_attr "type" "ssemuladd")
8464    (set_attr "mode" "TI")])
8465
8466 ;; We don't have a straight 32-bit parallel multiply and extend on XOP, so
8467 ;; fake it with a multiply/add.  In general, we expect the define_split to
8468 ;; occur before register allocation, so we have to handle the corner case where
8469 ;; the target is the same as operands 1/2
8470 (define_insn_and_split "xop_mulv2div2di3_low"
8471   [(set (match_operand:V2DI 0 "register_operand" "=&x")
8472         (mult:V2DI
8473           (sign_extend:V2DI
8474             (vec_select:V2SI
8475               (match_operand:V4SI 1 "register_operand" "%x")
8476               (parallel [(const_int 1)
8477                          (const_int 3)])))
8478           (sign_extend:V2DI
8479             (vec_select:V2SI
8480               (match_operand:V4SI 2 "nonimmediate_operand" "xm")
8481               (parallel [(const_int 1)
8482                          (const_int 3)])))))]
8483   "TARGET_XOP"
8484   "#"
8485   "&& reload_completed"
8486   [(set (match_dup 0)
8487         (match_dup 3))
8488    (set (match_dup 0)
8489         (plus:V2DI
8490          (mult:V2DI
8491           (sign_extend:V2DI
8492            (vec_select:V2SI
8493             (match_dup 1)
8494             (parallel [(const_int 1)
8495                        (const_int 3)])))
8496           (sign_extend:V2DI
8497            (vec_select:V2SI
8498             (match_dup 2)
8499             (parallel [(const_int 1)
8500                        (const_int 3)]))))
8501          (match_dup 0)))]
8502 {
8503   operands[3] = CONST0_RTX (V2DImode);
8504 }
8505   [(set_attr "type" "ssemul")
8506    (set_attr "mode" "TI")])
8507
8508 (define_insn "xop_pmacsdqh"
8509   [(set (match_operand:V2DI 0 "register_operand" "=x")
8510         (plus:V2DI
8511          (mult:V2DI
8512           (sign_extend:V2DI
8513            (vec_select:V2SI
8514             (match_operand:V4SI 1 "nonimmediate_operand" "%x")
8515             (parallel [(const_int 0)
8516                        (const_int 2)])))
8517           (sign_extend:V2DI
8518            (vec_select:V2SI
8519             (match_operand:V4SI 2 "nonimmediate_operand" "xm")
8520             (parallel [(const_int 0)
8521                        (const_int 2)]))))
8522          (match_operand:V2DI 3 "nonimmediate_operand" "x")))]
8523   "TARGET_XOP"
8524   "vpmacsdqh\t{%3, %2, %1, %0|%0, %1, %2, %3}"
8525   [(set_attr "type" "ssemuladd")
8526    (set_attr "mode" "TI")])
8527
8528 ;; We don't have a straight 32-bit parallel multiply and extend on XOP, so
8529 ;; fake it with a multiply/add.  In general, we expect the define_split to
8530 ;; occur before register allocation, so we have to handle the corner case where
8531 ;; the target is the same as either operands[1] or operands[2]
8532 (define_insn_and_split "xop_mulv2div2di3_high"
8533   [(set (match_operand:V2DI 0 "register_operand" "=&x")
8534         (mult:V2DI
8535           (sign_extend:V2DI
8536             (vec_select:V2SI
8537               (match_operand:V4SI 1 "register_operand" "%x")
8538               (parallel [(const_int 0)
8539                          (const_int 2)])))
8540           (sign_extend:V2DI
8541             (vec_select:V2SI
8542               (match_operand:V4SI 2 "nonimmediate_operand" "xm")
8543               (parallel [(const_int 0)
8544                          (const_int 2)])))))]
8545   "TARGET_XOP"
8546   "#"
8547   "&& reload_completed"
8548   [(set (match_dup 0)
8549         (match_dup 3))
8550    (set (match_dup 0)
8551         (plus:V2DI
8552          (mult:V2DI
8553           (sign_extend:V2DI
8554            (vec_select:V2SI
8555             (match_dup 1)
8556             (parallel [(const_int 0)
8557                        (const_int 2)])))
8558           (sign_extend:V2DI
8559            (vec_select:V2SI
8560             (match_dup 2)
8561             (parallel [(const_int 0)
8562                        (const_int 2)]))))
8563          (match_dup 0)))]
8564 {
8565   operands[3] = CONST0_RTX (V2DImode);
8566 }
8567   [(set_attr "type" "ssemul")
8568    (set_attr "mode" "TI")])
8569
8570 ;; XOP parallel integer multiply/add instructions for the intrinisics
8571 (define_insn "xop_pmacsswd"
8572   [(set (match_operand:V4SI 0 "register_operand" "=x")
8573         (ss_plus:V4SI
8574          (mult:V4SI
8575           (sign_extend:V4SI
8576            (vec_select:V4HI
8577             (match_operand:V8HI 1 "nonimmediate_operand" "%x")
8578             (parallel [(const_int 1)
8579                        (const_int 3)
8580                        (const_int 5)
8581                        (const_int 7)])))
8582           (sign_extend:V4SI
8583            (vec_select:V4HI
8584             (match_operand:V8HI 2 "nonimmediate_operand" "xm")
8585             (parallel [(const_int 1)
8586                        (const_int 3)
8587                        (const_int 5)
8588                        (const_int 7)]))))
8589          (match_operand:V4SI 3 "nonimmediate_operand" "x")))]
8590   "TARGET_XOP"
8591   "vpmacsswd\t{%3, %2, %1, %0|%0, %1, %2, %3}"
8592   [(set_attr "type" "ssemuladd")
8593    (set_attr "mode" "TI")])
8594
8595 (define_insn "xop_pmacswd"
8596   [(set (match_operand:V4SI 0 "register_operand" "=x")
8597         (plus:V4SI
8598          (mult:V4SI
8599           (sign_extend:V4SI
8600            (vec_select:V4HI
8601             (match_operand:V8HI 1 "nonimmediate_operand" "%x")
8602             (parallel [(const_int 1)
8603                        (const_int 3)
8604                        (const_int 5)
8605                        (const_int 7)])))
8606           (sign_extend:V4SI
8607            (vec_select:V4HI
8608             (match_operand:V8HI 2 "nonimmediate_operand" "xm")
8609             (parallel [(const_int 1)
8610                        (const_int 3)
8611                        (const_int 5)
8612                        (const_int 7)]))))
8613          (match_operand:V4SI 3 "nonimmediate_operand" "x")))]
8614   "TARGET_XOP"
8615   "vpmacswd\t{%3, %2, %1, %0|%0, %1, %2, %3}"
8616   [(set_attr "type" "ssemuladd")
8617    (set_attr "mode" "TI")])
8618
8619 (define_insn "xop_pmadcsswd"
8620   [(set (match_operand:V4SI 0 "register_operand" "=x")
8621         (ss_plus:V4SI
8622          (plus:V4SI
8623           (mult:V4SI
8624            (sign_extend:V4SI
8625             (vec_select:V4HI
8626              (match_operand:V8HI 1 "nonimmediate_operand" "%x")
8627              (parallel [(const_int 0)
8628                         (const_int 2)
8629                         (const_int 4)
8630                         (const_int 6)])))
8631            (sign_extend:V4SI
8632             (vec_select:V4HI
8633              (match_operand:V8HI 2 "nonimmediate_operand" "xm")
8634              (parallel [(const_int 0)
8635                         (const_int 2)
8636                         (const_int 4)
8637                         (const_int 6)]))))
8638           (mult:V4SI
8639            (sign_extend:V4SI
8640             (vec_select:V4HI
8641              (match_dup 1)
8642              (parallel [(const_int 1)
8643                         (const_int 3)
8644                         (const_int 5)
8645                         (const_int 7)])))
8646            (sign_extend:V4SI
8647             (vec_select:V4HI
8648              (match_dup 2)
8649              (parallel [(const_int 1)
8650                         (const_int 3)
8651                         (const_int 5)
8652                         (const_int 7)])))))
8653          (match_operand:V4SI 3 "nonimmediate_operand" "x")))]
8654   "TARGET_XOP"
8655   "vpmadcsswd\t{%3, %2, %1, %0|%0, %1, %2, %3}"
8656   [(set_attr "type" "ssemuladd")
8657    (set_attr "mode" "TI")])
8658
8659 (define_insn "xop_pmadcswd"
8660   [(set (match_operand:V4SI 0 "register_operand" "=x")
8661         (plus:V4SI
8662          (plus:V4SI
8663           (mult:V4SI
8664            (sign_extend:V4SI
8665             (vec_select:V4HI
8666              (match_operand:V8HI 1 "nonimmediate_operand" "%x")
8667              (parallel [(const_int 0)
8668                         (const_int 2)
8669                         (const_int 4)
8670                         (const_int 6)])))
8671            (sign_extend:V4SI
8672             (vec_select:V4HI
8673              (match_operand:V8HI 2 "nonimmediate_operand" "xm")
8674              (parallel [(const_int 0)
8675                         (const_int 2)
8676                         (const_int 4)
8677                         (const_int 6)]))))
8678           (mult:V4SI
8679            (sign_extend:V4SI
8680             (vec_select:V4HI
8681              (match_dup 1)
8682              (parallel [(const_int 1)
8683                         (const_int 3)
8684                         (const_int 5)
8685                         (const_int 7)])))
8686            (sign_extend:V4SI
8687             (vec_select:V4HI
8688              (match_dup 2)
8689              (parallel [(const_int 1)
8690                         (const_int 3)
8691                         (const_int 5)
8692                         (const_int 7)])))))
8693          (match_operand:V4SI 3 "nonimmediate_operand" "x")))]
8694   "TARGET_XOP"
8695   "vpmadcswd\t{%3, %2, %1, %0|%0, %1, %2, %3}"
8696   [(set_attr "type" "ssemuladd")
8697    (set_attr "mode" "TI")])
8698
8699 ;; XOP parallel XMM conditional moves
8700 (define_insn "xop_pcmov_<mode><avxsizesuffix>"
8701   [(set (match_operand:V 0 "register_operand" "=x,x")
8702         (if_then_else:V
8703           (match_operand:V 3 "nonimmediate_operand" "x,m")
8704           (match_operand:V 1 "vector_move_operand" "x,x")
8705           (match_operand:V 2 "vector_move_operand" "xm,x")))]
8706   "TARGET_XOP"
8707   "vpcmov\t{%3, %2, %1, %0|%0, %1, %2, %3}"
8708   [(set_attr "type" "sse4arg")])
8709
8710 ;; XOP horizontal add/subtract instructions
8711 (define_insn "xop_phaddbw"
8712   [(set (match_operand:V8HI 0 "register_operand" "=x")
8713         (plus:V8HI
8714          (sign_extend:V8HI
8715           (vec_select:V8QI
8716            (match_operand:V16QI 1 "nonimmediate_operand" "xm")
8717            (parallel [(const_int 0)
8718                       (const_int 2)
8719                       (const_int 4)
8720                       (const_int 6)
8721                       (const_int 8)
8722                       (const_int 10)
8723                       (const_int 12)
8724                       (const_int 14)])))
8725          (sign_extend:V8HI
8726           (vec_select:V8QI
8727            (match_dup 1)
8728            (parallel [(const_int 1)
8729                       (const_int 3)
8730                       (const_int 5)
8731                       (const_int 7)
8732                       (const_int 9)
8733                       (const_int 11)
8734                       (const_int 13)
8735                       (const_int 15)])))))]
8736   "TARGET_XOP"
8737   "vphaddbw\t{%1, %0|%0, %1}"
8738   [(set_attr "type" "sseiadd1")])
8739
8740 (define_insn "xop_phaddbd"
8741   [(set (match_operand:V4SI 0 "register_operand" "=x")
8742         (plus:V4SI
8743          (plus:V4SI
8744           (sign_extend:V4SI
8745            (vec_select:V4QI
8746             (match_operand:V16QI 1 "nonimmediate_operand" "xm")
8747             (parallel [(const_int 0)
8748                        (const_int 4)
8749                        (const_int 8)
8750                        (const_int 12)])))
8751           (sign_extend:V4SI
8752            (vec_select:V4QI
8753             (match_dup 1)
8754             (parallel [(const_int 1)
8755                        (const_int 5)
8756                        (const_int 9)
8757                        (const_int 13)]))))
8758          (plus:V4SI
8759           (sign_extend:V4SI
8760            (vec_select:V4QI
8761             (match_dup 1)
8762             (parallel [(const_int 2)
8763                        (const_int 6)
8764                        (const_int 10)
8765                        (const_int 14)])))
8766           (sign_extend:V4SI
8767            (vec_select:V4QI
8768             (match_dup 1)
8769             (parallel [(const_int 3)
8770                        (const_int 7)
8771                        (const_int 11)
8772                        (const_int 15)]))))))]
8773   "TARGET_XOP"
8774   "vphaddbd\t{%1, %0|%0, %1}"
8775   [(set_attr "type" "sseiadd1")])
8776
8777 (define_insn "xop_phaddbq"
8778   [(set (match_operand:V2DI 0 "register_operand" "=x")
8779         (plus:V2DI
8780          (plus:V2DI
8781           (plus:V2DI
8782            (sign_extend:V2DI
8783             (vec_select:V2QI
8784              (match_operand:V16QI 1 "nonimmediate_operand" "xm")
8785              (parallel [(const_int 0)
8786                         (const_int 4)])))
8787            (sign_extend:V2DI
8788             (vec_select:V2QI
8789              (match_dup 1)
8790              (parallel [(const_int 1)
8791                         (const_int 5)]))))
8792           (plus:V2DI
8793            (sign_extend:V2DI
8794             (vec_select:V2QI
8795              (match_dup 1)
8796              (parallel [(const_int 2)
8797                         (const_int 6)])))
8798            (sign_extend:V2DI
8799             (vec_select:V2QI
8800              (match_dup 1)
8801              (parallel [(const_int 3)
8802                         (const_int 7)])))))
8803          (plus:V2DI
8804           (plus:V2DI
8805            (sign_extend:V2DI
8806             (vec_select:V2QI
8807              (match_dup 1)
8808              (parallel [(const_int 8)
8809                         (const_int 12)])))
8810            (sign_extend:V2DI
8811             (vec_select:V2QI
8812              (match_dup 1)
8813              (parallel [(const_int 9)
8814                         (const_int 13)]))))
8815           (plus:V2DI
8816            (sign_extend:V2DI
8817             (vec_select:V2QI
8818              (match_dup 1)
8819              (parallel [(const_int 10)
8820                         (const_int 14)])))
8821            (sign_extend:V2DI
8822             (vec_select:V2QI
8823              (match_dup 1)
8824              (parallel [(const_int 11)
8825                         (const_int 15)])))))))]
8826   "TARGET_XOP"
8827   "vphaddbq\t{%1, %0|%0, %1}"
8828   [(set_attr "type" "sseiadd1")])
8829
8830 (define_insn "xop_phaddwd"
8831   [(set (match_operand:V4SI 0 "register_operand" "=x")
8832         (plus:V4SI
8833          (sign_extend:V4SI
8834           (vec_select:V4HI
8835            (match_operand:V8HI 1 "nonimmediate_operand" "xm")
8836            (parallel [(const_int 0)
8837                       (const_int 2)
8838                       (const_int 4)
8839                       (const_int 6)])))
8840          (sign_extend:V4SI
8841           (vec_select:V4HI
8842            (match_dup 1)
8843            (parallel [(const_int 1)
8844                       (const_int 3)
8845                       (const_int 5)
8846                       (const_int 7)])))))]
8847   "TARGET_XOP"
8848   "vphaddwd\t{%1, %0|%0, %1}"
8849   [(set_attr "type" "sseiadd1")])
8850
8851 (define_insn "xop_phaddwq"
8852   [(set (match_operand:V2DI 0 "register_operand" "=x")
8853         (plus:V2DI
8854          (plus:V2DI
8855           (sign_extend:V2DI
8856            (vec_select:V2HI
8857             (match_operand:V8HI 1 "nonimmediate_operand" "xm")
8858             (parallel [(const_int 0)
8859                        (const_int 4)])))
8860           (sign_extend:V2DI
8861            (vec_select:V2HI
8862             (match_dup 1)
8863             (parallel [(const_int 1)
8864                        (const_int 5)]))))
8865          (plus:V2DI
8866           (sign_extend:V2DI
8867            (vec_select:V2HI
8868             (match_dup 1)
8869             (parallel [(const_int 2)
8870                        (const_int 6)])))
8871           (sign_extend:V2DI
8872            (vec_select:V2HI
8873             (match_dup 1)
8874             (parallel [(const_int 3)
8875                        (const_int 7)]))))))]
8876   "TARGET_XOP"
8877   "vphaddwq\t{%1, %0|%0, %1}"
8878   [(set_attr "type" "sseiadd1")])
8879
8880 (define_insn "xop_phadddq"
8881   [(set (match_operand:V2DI 0 "register_operand" "=x")
8882         (plus:V2DI
8883          (sign_extend:V2DI
8884           (vec_select:V2SI
8885            (match_operand:V4SI 1 "nonimmediate_operand" "xm")
8886            (parallel [(const_int 0)
8887                       (const_int 2)])))
8888          (sign_extend:V2DI
8889           (vec_select:V2SI
8890            (match_dup 1)
8891            (parallel [(const_int 1)
8892                       (const_int 3)])))))]
8893   "TARGET_XOP"
8894   "vphadddq\t{%1, %0|%0, %1}"
8895   [(set_attr "type" "sseiadd1")])
8896
8897 (define_insn "xop_phaddubw"
8898   [(set (match_operand:V8HI 0 "register_operand" "=x")
8899         (plus:V8HI
8900          (zero_extend:V8HI
8901           (vec_select:V8QI
8902            (match_operand:V16QI 1 "nonimmediate_operand" "xm")
8903            (parallel [(const_int 0)
8904                       (const_int 2)
8905                       (const_int 4)
8906                       (const_int 6)
8907                       (const_int 8)
8908                       (const_int 10)
8909                       (const_int 12)
8910                       (const_int 14)])))
8911          (zero_extend:V8HI
8912           (vec_select:V8QI
8913            (match_dup 1)
8914            (parallel [(const_int 1)
8915                       (const_int 3)
8916                       (const_int 5)
8917                       (const_int 7)
8918                       (const_int 9)
8919                       (const_int 11)
8920                       (const_int 13)
8921                       (const_int 15)])))))]
8922   "TARGET_XOP"
8923   "vphaddubw\t{%1, %0|%0, %1}"
8924   [(set_attr "type" "sseiadd1")])
8925
8926 (define_insn "xop_phaddubd"
8927   [(set (match_operand:V4SI 0 "register_operand" "=x")
8928         (plus:V4SI
8929          (plus:V4SI
8930           (zero_extend:V4SI
8931            (vec_select:V4QI
8932             (match_operand:V16QI 1 "nonimmediate_operand" "xm")
8933             (parallel [(const_int 0)
8934                        (const_int 4)
8935                        (const_int 8)
8936                        (const_int 12)])))
8937           (zero_extend:V4SI
8938            (vec_select:V4QI
8939             (match_dup 1)
8940             (parallel [(const_int 1)
8941                        (const_int 5)
8942                        (const_int 9)
8943                        (const_int 13)]))))
8944          (plus:V4SI
8945           (zero_extend:V4SI
8946            (vec_select:V4QI
8947             (match_dup 1)
8948             (parallel [(const_int 2)
8949                        (const_int 6)
8950                        (const_int 10)
8951                        (const_int 14)])))
8952           (zero_extend:V4SI
8953            (vec_select:V4QI
8954             (match_dup 1)
8955             (parallel [(const_int 3)
8956                        (const_int 7)
8957                        (const_int 11)
8958                        (const_int 15)]))))))]
8959   "TARGET_XOP"
8960   "vphaddubd\t{%1, %0|%0, %1}"
8961   [(set_attr "type" "sseiadd1")])
8962
8963 (define_insn "xop_phaddubq"
8964   [(set (match_operand:V2DI 0 "register_operand" "=x")
8965         (plus:V2DI
8966          (plus:V2DI
8967           (plus:V2DI
8968            (zero_extend:V2DI
8969             (vec_select:V2QI
8970              (match_operand:V16QI 1 "nonimmediate_operand" "xm")
8971              (parallel [(const_int 0)
8972                         (const_int 4)])))
8973            (sign_extend:V2DI
8974             (vec_select:V2QI
8975              (match_dup 1)
8976              (parallel [(const_int 1)
8977                         (const_int 5)]))))
8978           (plus:V2DI
8979            (zero_extend:V2DI
8980             (vec_select:V2QI
8981              (match_dup 1)
8982              (parallel [(const_int 2)
8983                         (const_int 6)])))
8984            (zero_extend:V2DI
8985             (vec_select:V2QI
8986              (match_dup 1)
8987              (parallel [(const_int 3)
8988                         (const_int 7)])))))
8989          (plus:V2DI
8990           (plus:V2DI
8991            (zero_extend:V2DI
8992             (vec_select:V2QI
8993              (match_dup 1)
8994              (parallel [(const_int 8)
8995                         (const_int 12)])))
8996            (sign_extend:V2DI
8997             (vec_select:V2QI
8998              (match_dup 1)
8999              (parallel [(const_int 9)
9000                         (const_int 13)]))))
9001           (plus:V2DI
9002            (zero_extend:V2DI
9003             (vec_select:V2QI
9004              (match_dup 1)
9005              (parallel [(const_int 10)
9006                         (const_int 14)])))
9007            (zero_extend:V2DI
9008             (vec_select:V2QI
9009              (match_dup 1)
9010              (parallel [(const_int 11)
9011                         (const_int 15)])))))))]
9012   "TARGET_XOP"
9013   "vphaddubq\t{%1, %0|%0, %1}"
9014   [(set_attr "type" "sseiadd1")])
9015
9016 (define_insn "xop_phadduwd"
9017   [(set (match_operand:V4SI 0 "register_operand" "=x")
9018         (plus:V4SI
9019          (zero_extend:V4SI
9020           (vec_select:V4HI
9021            (match_operand:V8HI 1 "nonimmediate_operand" "xm")
9022            (parallel [(const_int 0)
9023                       (const_int 2)
9024                       (const_int 4)
9025                       (const_int 6)])))
9026          (zero_extend:V4SI
9027           (vec_select:V4HI
9028            (match_dup 1)
9029            (parallel [(const_int 1)
9030                       (const_int 3)
9031                       (const_int 5)
9032                       (const_int 7)])))))]
9033   "TARGET_XOP"
9034   "vphadduwd\t{%1, %0|%0, %1}"
9035   [(set_attr "type" "sseiadd1")])
9036
9037 (define_insn "xop_phadduwq"
9038   [(set (match_operand:V2DI 0 "register_operand" "=x")
9039         (plus:V2DI
9040          (plus:V2DI
9041           (zero_extend:V2DI
9042            (vec_select:V2HI
9043             (match_operand:V8HI 1 "nonimmediate_operand" "xm")
9044             (parallel [(const_int 0)
9045                        (const_int 4)])))
9046           (zero_extend:V2DI
9047            (vec_select:V2HI
9048             (match_dup 1)
9049             (parallel [(const_int 1)
9050                        (const_int 5)]))))
9051          (plus:V2DI
9052           (zero_extend:V2DI
9053            (vec_select:V2HI
9054             (match_dup 1)
9055             (parallel [(const_int 2)
9056                        (const_int 6)])))
9057           (zero_extend:V2DI
9058            (vec_select:V2HI
9059             (match_dup 1)
9060             (parallel [(const_int 3)
9061                        (const_int 7)]))))))]
9062   "TARGET_XOP"
9063   "vphadduwq\t{%1, %0|%0, %1}"
9064   [(set_attr "type" "sseiadd1")])
9065
9066 (define_insn "xop_phaddudq"
9067   [(set (match_operand:V2DI 0 "register_operand" "=x")
9068         (plus:V2DI
9069          (zero_extend:V2DI
9070           (vec_select:V2SI
9071            (match_operand:V4SI 1 "nonimmediate_operand" "xm")
9072            (parallel [(const_int 0)
9073                       (const_int 2)])))
9074          (zero_extend:V2DI
9075           (vec_select:V2SI
9076            (match_dup 1)
9077            (parallel [(const_int 1)
9078                       (const_int 3)])))))]
9079   "TARGET_XOP"
9080   "vphaddudq\t{%1, %0|%0, %1}"
9081   [(set_attr "type" "sseiadd1")])
9082
9083 (define_insn "xop_phsubbw"
9084   [(set (match_operand:V8HI 0 "register_operand" "=x")
9085         (minus:V8HI
9086          (sign_extend:V8HI
9087           (vec_select:V8QI
9088            (match_operand:V16QI 1 "nonimmediate_operand" "xm")
9089            (parallel [(const_int 0)
9090                       (const_int 2)
9091                       (const_int 4)
9092                       (const_int 6)
9093                       (const_int 8)
9094                       (const_int 10)
9095                       (const_int 12)
9096                       (const_int 14)])))
9097          (sign_extend:V8HI
9098           (vec_select:V8QI
9099            (match_dup 1)
9100            (parallel [(const_int 1)
9101                       (const_int 3)
9102                       (const_int 5)
9103                       (const_int 7)
9104                       (const_int 9)
9105                       (const_int 11)
9106                       (const_int 13)
9107                       (const_int 15)])))))]
9108   "TARGET_XOP"
9109   "vphsubbw\t{%1, %0|%0, %1}"
9110   [(set_attr "type" "sseiadd1")])
9111
9112 (define_insn "xop_phsubwd"
9113   [(set (match_operand:V4SI 0 "register_operand" "=x")
9114         (minus:V4SI
9115          (sign_extend:V4SI
9116           (vec_select:V4HI
9117            (match_operand:V8HI 1 "nonimmediate_operand" "xm")
9118            (parallel [(const_int 0)
9119                       (const_int 2)
9120                       (const_int 4)
9121                       (const_int 6)])))
9122          (sign_extend:V4SI
9123           (vec_select:V4HI
9124            (match_dup 1)
9125            (parallel [(const_int 1)
9126                       (const_int 3)
9127                       (const_int 5)
9128                       (const_int 7)])))))]
9129   "TARGET_XOP"
9130   "vphsubwd\t{%1, %0|%0, %1}"
9131   [(set_attr "type" "sseiadd1")])
9132
9133 (define_insn "xop_phsubdq"
9134   [(set (match_operand:V2DI 0 "register_operand" "=x")
9135         (minus:V2DI
9136          (sign_extend:V2DI
9137           (vec_select:V2SI
9138            (match_operand:V4SI 1 "nonimmediate_operand" "xm")
9139            (parallel [(const_int 0)
9140                       (const_int 2)])))
9141          (sign_extend:V2DI
9142           (vec_select:V2SI
9143            (match_dup 1)
9144            (parallel [(const_int 1)
9145                       (const_int 3)])))))]
9146   "TARGET_XOP"
9147   "vphsubdq\t{%1, %0|%0, %1}"
9148   [(set_attr "type" "sseiadd1")])
9149
9150 ;; XOP permute instructions
9151 (define_insn "xop_pperm"
9152   [(set (match_operand:V16QI 0 "register_operand" "=x,x")
9153         (unspec:V16QI
9154           [(match_operand:V16QI 1 "register_operand" "x,x")
9155            (match_operand:V16QI 2 "nonimmediate_operand" "x,m")
9156            (match_operand:V16QI 3 "nonimmediate_operand" "xm,x")]
9157           UNSPEC_XOP_PERMUTE))]
9158   "TARGET_XOP && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
9159   "vpperm\t{%3, %2, %1, %0|%0, %1, %2, %3}"
9160   [(set_attr "type" "sse4arg")
9161    (set_attr "mode" "TI")])
9162
9163 ;; XOP pack instructions that combine two vectors into a smaller vector
9164 (define_insn "xop_pperm_pack_v2di_v4si"
9165   [(set (match_operand:V4SI 0 "register_operand" "=x,x")
9166         (vec_concat:V4SI
9167          (truncate:V2SI
9168           (match_operand:V2DI 1 "register_operand" "x,x"))
9169          (truncate:V2SI
9170           (match_operand:V2DI 2 "nonimmediate_operand" "x,m"))))
9171    (use (match_operand:V16QI 3 "nonimmediate_operand" "xm,x"))]
9172   "TARGET_XOP && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
9173   "vpperm\t{%3, %2, %1, %0|%0, %1, %2, %3}"
9174   [(set_attr "type" "sse4arg")
9175    (set_attr "mode" "TI")])
9176
9177 (define_insn "xop_pperm_pack_v4si_v8hi"
9178   [(set (match_operand:V8HI 0 "register_operand" "=x,x")
9179         (vec_concat:V8HI
9180          (truncate:V4HI
9181           (match_operand:V4SI 1 "register_operand" "x,x"))
9182          (truncate:V4HI
9183           (match_operand:V4SI 2 "nonimmediate_operand" "x,m"))))
9184    (use (match_operand:V16QI 3 "nonimmediate_operand" "xm,x"))]
9185   "TARGET_XOP && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
9186   "vpperm\t{%3, %2, %1, %0|%0, %1, %2, %3}"
9187   [(set_attr "type" "sse4arg")
9188    (set_attr "mode" "TI")])
9189
9190 (define_insn "xop_pperm_pack_v8hi_v16qi"
9191   [(set (match_operand:V16QI 0 "register_operand" "=x,x")
9192         (vec_concat:V16QI
9193          (truncate:V8QI
9194           (match_operand:V8HI 1 "register_operand" "x,x"))
9195          (truncate:V8QI
9196           (match_operand:V8HI 2 "nonimmediate_operand" "x,m"))))
9197    (use (match_operand:V16QI 3 "nonimmediate_operand" "xm,x"))]
9198   "TARGET_XOP && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
9199   "vpperm\t{%3, %2, %1, %0|%0, %1, %2, %3}"
9200   [(set_attr "type" "sse4arg")
9201    (set_attr "mode" "TI")])
9202
9203 ;; XOP packed rotate instructions
9204 (define_expand "rotl<mode>3"
9205   [(set (match_operand:VI_128 0 "register_operand" "")
9206         (rotate:VI_128
9207          (match_operand:VI_128 1 "nonimmediate_operand" "")
9208          (match_operand:SI 2 "general_operand")))]
9209   "TARGET_XOP"
9210 {
9211   /* If we were given a scalar, convert it to parallel */
9212   if (! const_0_to_<sserotatemax>_operand (operands[2], SImode))
9213     {
9214       rtvec vs = rtvec_alloc (<ssescalarnum>);
9215       rtx par = gen_rtx_PARALLEL (<MODE>mode, vs);
9216       rtx reg = gen_reg_rtx (<MODE>mode);
9217       rtx op2 = operands[2];
9218       int i;
9219
9220       if (GET_MODE (op2) != <ssescalarmode>mode)
9221         {
9222           op2 = gen_reg_rtx (<ssescalarmode>mode);
9223           convert_move (op2, operands[2], false);
9224         }
9225
9226       for (i = 0; i < <ssescalarnum>; i++)
9227         RTVEC_ELT (vs, i) = op2;
9228
9229       emit_insn (gen_vec_init<mode> (reg, par));
9230       emit_insn (gen_xop_vrotl<mode>3 (operands[0], operands[1], reg));
9231       DONE;
9232     }
9233 })
9234
9235 (define_expand "rotr<mode>3"
9236   [(set (match_operand:VI_128 0 "register_operand" "")
9237         (rotatert:VI_128
9238          (match_operand:VI_128 1 "nonimmediate_operand" "")
9239          (match_operand:SI 2 "general_operand")))]
9240   "TARGET_XOP"
9241 {
9242   /* If we were given a scalar, convert it to parallel */
9243   if (! const_0_to_<sserotatemax>_operand (operands[2], SImode))
9244     {
9245       rtvec vs = rtvec_alloc (<ssescalarnum>);
9246       rtx par = gen_rtx_PARALLEL (<MODE>mode, vs);
9247       rtx neg = gen_reg_rtx (<MODE>mode);
9248       rtx reg = gen_reg_rtx (<MODE>mode);
9249       rtx op2 = operands[2];
9250       int i;
9251
9252       if (GET_MODE (op2) != <ssescalarmode>mode)
9253         {
9254           op2 = gen_reg_rtx (<ssescalarmode>mode);
9255           convert_move (op2, operands[2], false);
9256         }
9257
9258       for (i = 0; i < <ssescalarnum>; i++)
9259         RTVEC_ELT (vs, i) = op2;
9260
9261       emit_insn (gen_vec_init<mode> (reg, par));
9262       emit_insn (gen_neg<mode>2 (neg, reg));
9263       emit_insn (gen_xop_vrotl<mode>3 (operands[0], operands[1], neg));
9264       DONE;
9265     }
9266 })
9267
9268 (define_insn "xop_rotl<mode>3"
9269   [(set (match_operand:VI_128 0 "register_operand" "=x")
9270         (rotate:VI_128
9271          (match_operand:VI_128 1 "nonimmediate_operand" "xm")
9272          (match_operand:SI 2 "const_0_to_<sserotatemax>_operand" "n")))]
9273   "TARGET_XOP"
9274   "vprot<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
9275   [(set_attr "type" "sseishft")
9276    (set_attr "length_immediate" "1")
9277    (set_attr "mode" "TI")])
9278
9279 (define_insn "xop_rotr<mode>3"
9280   [(set (match_operand:VI_128 0 "register_operand" "=x")
9281         (rotatert:VI_128
9282          (match_operand:VI_128 1 "nonimmediate_operand" "xm")
9283          (match_operand:SI 2 "const_0_to_<sserotatemax>_operand" "n")))]
9284   "TARGET_XOP"
9285 {
9286   operands[3] = GEN_INT ((<ssescalarnum> * 8) - INTVAL (operands[2]));
9287   return \"vprot<ssemodesuffix>\t{%3, %1, %0|%0, %1, %3}\";
9288 }
9289   [(set_attr "type" "sseishft")
9290    (set_attr "length_immediate" "1")
9291    (set_attr "mode" "TI")])
9292
9293 (define_expand "vrotr<mode>3"
9294   [(match_operand:VI_128 0 "register_operand" "")
9295    (match_operand:VI_128 1 "register_operand" "")
9296    (match_operand:VI_128 2 "register_operand" "")]
9297   "TARGET_XOP"
9298 {
9299   rtx reg = gen_reg_rtx (<MODE>mode);
9300   emit_insn (gen_neg<mode>2 (reg, operands[2]));
9301   emit_insn (gen_xop_vrotl<mode>3 (operands[0], operands[1], reg));
9302   DONE;
9303 })
9304
9305 (define_expand "vrotl<mode>3"
9306   [(match_operand:VI_128 0 "register_operand" "")
9307    (match_operand:VI_128 1 "register_operand" "")
9308    (match_operand:VI_128 2 "register_operand" "")]
9309   "TARGET_XOP"
9310 {
9311   emit_insn (gen_xop_vrotl<mode>3 (operands[0], operands[1], operands[2]));
9312   DONE;
9313 })
9314
9315 (define_insn "xop_vrotl<mode>3"
9316   [(set (match_operand:VI_128 0 "register_operand" "=x,x")
9317         (if_then_else:VI_128
9318          (ge:VI_128
9319           (match_operand:VI_128 2 "nonimmediate_operand" "x,m")
9320           (const_int 0))
9321          (rotate:VI_128
9322           (match_operand:VI_128 1 "nonimmediate_operand" "xm,x")
9323           (match_dup 2))
9324          (rotatert:VI_128
9325           (match_dup 1)
9326           (neg:VI_128 (match_dup 2)))))]
9327   "TARGET_XOP && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9328   "vprot<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
9329   [(set_attr "type" "sseishft")
9330    (set_attr "prefix_data16" "0")
9331    (set_attr "prefix_extra" "2")
9332    (set_attr "mode" "TI")])
9333
9334 ;; XOP packed shift instructions.
9335 ;; FIXME: add V2DI back in
9336 (define_expand "vlshr<mode>3"
9337   [(match_operand:VI124_128 0 "register_operand" "")
9338    (match_operand:VI124_128 1 "register_operand" "")
9339    (match_operand:VI124_128 2 "register_operand" "")]
9340   "TARGET_XOP"
9341 {
9342   rtx neg = gen_reg_rtx (<MODE>mode);
9343   emit_insn (gen_neg<mode>2 (neg, operands[2]));
9344   emit_insn (gen_xop_lshl<mode>3 (operands[0], operands[1], neg));
9345   DONE;
9346 })
9347
9348 (define_expand "vashr<mode>3"
9349   [(match_operand:VI124_128 0 "register_operand" "")
9350    (match_operand:VI124_128 1 "register_operand" "")
9351    (match_operand:VI124_128 2 "register_operand" "")]
9352   "TARGET_XOP"
9353 {
9354   rtx neg = gen_reg_rtx (<MODE>mode);
9355   emit_insn (gen_neg<mode>2 (neg, operands[2]));
9356   emit_insn (gen_xop_ashl<mode>3 (operands[0], operands[1], neg));
9357   DONE;
9358 })
9359
9360 (define_expand "vashl<mode>3"
9361   [(match_operand:VI124_128 0 "register_operand" "")
9362    (match_operand:VI124_128 1 "register_operand" "")
9363    (match_operand:VI124_128 2 "register_operand" "")]
9364   "TARGET_XOP"
9365 {
9366   emit_insn (gen_xop_ashl<mode>3 (operands[0], operands[1], operands[2]));
9367   DONE;
9368 })
9369
9370 (define_insn "xop_ashl<mode>3"
9371   [(set (match_operand:VI_128 0 "register_operand" "=x,x")
9372         (if_then_else:VI_128
9373          (ge:VI_128
9374           (match_operand:VI_128 2 "nonimmediate_operand" "x,m")
9375           (const_int 0))
9376          (ashift:VI_128
9377           (match_operand:VI_128 1 "nonimmediate_operand" "xm,x")
9378           (match_dup 2))
9379          (ashiftrt:VI_128
9380           (match_dup 1)
9381           (neg:VI_128 (match_dup 2)))))]
9382   "TARGET_XOP && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9383   "vpsha<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
9384   [(set_attr "type" "sseishft")
9385    (set_attr "prefix_data16" "0")
9386    (set_attr "prefix_extra" "2")
9387    (set_attr "mode" "TI")])
9388
9389 (define_insn "xop_lshl<mode>3"
9390   [(set (match_operand:VI_128 0 "register_operand" "=x,x")
9391         (if_then_else:VI_128
9392          (ge:VI_128
9393           (match_operand:VI_128 2 "nonimmediate_operand" "x,m")
9394           (const_int 0))
9395          (ashift:VI_128
9396           (match_operand:VI_128 1 "nonimmediate_operand" "xm,x")
9397           (match_dup 2))
9398          (lshiftrt:VI_128
9399           (match_dup 1)
9400           (neg:VI_128 (match_dup 2)))))]
9401   "TARGET_XOP && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9402   "vpshl<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
9403   [(set_attr "type" "sseishft")
9404    (set_attr "prefix_data16" "0")
9405    (set_attr "prefix_extra" "2")
9406    (set_attr "mode" "TI")])
9407
9408 ;; SSE2 doesn't have some shift varients, so define versions for XOP
9409 (define_expand "ashlv16qi3"
9410   [(match_operand:V16QI 0 "register_operand" "")
9411    (match_operand:V16QI 1 "register_operand" "")
9412    (match_operand:SI 2 "nonmemory_operand" "")]
9413   "TARGET_XOP"
9414 {
9415   rtvec vs = rtvec_alloc (16);
9416   rtx par = gen_rtx_PARALLEL (V16QImode, vs);
9417   rtx reg = gen_reg_rtx (V16QImode);
9418   int i;
9419   for (i = 0; i < 16; i++)
9420     RTVEC_ELT (vs, i) = operands[2];
9421
9422   emit_insn (gen_vec_initv16qi (reg, par));
9423   emit_insn (gen_xop_ashlv16qi3 (operands[0], operands[1], reg));
9424   DONE;
9425 })
9426
9427 (define_expand "lshlv16qi3"
9428   [(match_operand:V16QI 0 "register_operand" "")
9429    (match_operand:V16QI 1 "register_operand" "")
9430    (match_operand:SI 2 "nonmemory_operand" "")]
9431   "TARGET_XOP"
9432 {
9433   rtvec vs = rtvec_alloc (16);
9434   rtx par = gen_rtx_PARALLEL (V16QImode, vs);
9435   rtx reg = gen_reg_rtx (V16QImode);
9436   int i;
9437   for (i = 0; i < 16; i++)
9438     RTVEC_ELT (vs, i) = operands[2];
9439
9440   emit_insn (gen_vec_initv16qi (reg, par));
9441   emit_insn (gen_xop_lshlv16qi3 (operands[0], operands[1], reg));
9442   DONE;
9443 })
9444
9445 (define_expand "ashrv16qi3"
9446   [(match_operand:V16QI 0 "register_operand" "")
9447    (match_operand:V16QI 1 "register_operand" "")
9448    (match_operand:SI 2 "nonmemory_operand" "")]
9449   "TARGET_XOP"
9450 {
9451   rtvec vs = rtvec_alloc (16);
9452   rtx par = gen_rtx_PARALLEL (V16QImode, vs);
9453   rtx reg = gen_reg_rtx (V16QImode);
9454   int i;
9455   rtx ele = ((CONST_INT_P (operands[2]))
9456              ? GEN_INT (- INTVAL (operands[2]))
9457              : operands[2]);
9458
9459   for (i = 0; i < 16; i++)
9460     RTVEC_ELT (vs, i) = ele;
9461
9462   emit_insn (gen_vec_initv16qi (reg, par));
9463
9464   if (!CONST_INT_P (operands[2]))
9465     {
9466       rtx neg = gen_reg_rtx (V16QImode);
9467       emit_insn (gen_negv16qi2 (neg, reg));
9468       emit_insn (gen_xop_ashlv16qi3 (operands[0], operands[1], neg));
9469     }
9470   else
9471     emit_insn (gen_xop_ashlv16qi3 (operands[0], operands[1], reg));
9472
9473   DONE;
9474 })
9475
9476 (define_expand "ashrv2di3"
9477   [(match_operand:V2DI 0 "register_operand" "")
9478    (match_operand:V2DI 1 "register_operand" "")
9479    (match_operand:DI 2 "nonmemory_operand" "")]
9480   "TARGET_XOP"
9481 {
9482   rtvec vs = rtvec_alloc (2);
9483   rtx par = gen_rtx_PARALLEL (V2DImode, vs);
9484   rtx reg = gen_reg_rtx (V2DImode);
9485   rtx ele;
9486
9487   if (CONST_INT_P (operands[2]))
9488     ele = GEN_INT (- INTVAL (operands[2]));
9489   else if (GET_MODE (operands[2]) != DImode)
9490     {
9491       rtx move = gen_reg_rtx (DImode);
9492       ele = gen_reg_rtx (DImode);
9493       convert_move (move, operands[2], false);
9494       emit_insn (gen_negdi2 (ele, move));
9495     }
9496   else
9497     {
9498       ele = gen_reg_rtx (DImode);
9499       emit_insn (gen_negdi2 (ele, operands[2]));
9500     }
9501
9502   RTVEC_ELT (vs, 0) = ele;
9503   RTVEC_ELT (vs, 1) = ele;
9504   emit_insn (gen_vec_initv2di (reg, par));
9505   emit_insn (gen_xop_ashlv2di3 (operands[0], operands[1], reg));
9506   DONE;
9507 })
9508
9509 ;; XOP FRCZ support
9510 (define_insn "xop_frcz<mode>2"
9511   [(set (match_operand:FMAMODE 0 "register_operand" "=x")
9512         (unspec:FMAMODE
9513          [(match_operand:FMAMODE 1 "nonimmediate_operand" "xm")]
9514          UNSPEC_FRCZ))]
9515   "TARGET_XOP"
9516   "vfrcz<ssemodesuffix>\t{%1, %0|%0, %1}"
9517   [(set_attr "type" "ssecvt1")
9518    (set_attr "mode" "<MODE>")])
9519
9520 ;; scalar insns
9521 (define_expand "xop_vmfrcz<mode>2"
9522   [(set (match_operand:VF_128 0 "register_operand")
9523         (vec_merge:VF_128
9524           (unspec:VF_128
9525            [(match_operand:VF_128 1 "nonimmediate_operand")]
9526            UNSPEC_FRCZ)
9527           (match_dup 3)
9528           (const_int 1)))]
9529   "TARGET_XOP"
9530 {
9531   operands[3] = CONST0_RTX (<MODE>mode);
9532 })
9533
9534 (define_insn "*xop_vmfrcz_<mode>"
9535   [(set (match_operand:VF_128 0 "register_operand" "=x")
9536         (vec_merge:VF_128
9537           (unspec:VF_128
9538            [(match_operand:VF_128 1 "nonimmediate_operand" "xm")]
9539            UNSPEC_FRCZ)
9540           (match_operand:VF_128 2 "const0_operand")
9541           (const_int 1)))]
9542   "TARGET_XOP"
9543   "vfrcz<ssescalarmodesuffix>\t{%1, %0|%0, %1}"
9544   [(set_attr "type" "ssecvt1")
9545    (set_attr "mode" "<MODE>")])
9546
9547 (define_insn "xop_maskcmp<mode>3"
9548   [(set (match_operand:VI_128 0 "register_operand" "=x")
9549         (match_operator:VI_128 1 "ix86_comparison_int_operator"
9550          [(match_operand:VI_128 2 "register_operand" "x")
9551           (match_operand:VI_128 3 "nonimmediate_operand" "xm")]))]
9552   "TARGET_XOP"
9553   "vpcom%Y1<ssemodesuffix>\t{%3, %2, %0|%0, %2, %3}"
9554   [(set_attr "type" "sse4arg")
9555    (set_attr "prefix_data16" "0")
9556    (set_attr "prefix_rep" "0")
9557    (set_attr "prefix_extra" "2")
9558    (set_attr "length_immediate" "1")
9559    (set_attr "mode" "TI")])
9560
9561 (define_insn "xop_maskcmp_uns<mode>3"
9562   [(set (match_operand:VI_128 0 "register_operand" "=x")
9563         (match_operator:VI_128 1 "ix86_comparison_uns_operator"
9564          [(match_operand:VI_128 2 "register_operand" "x")
9565           (match_operand:VI_128 3 "nonimmediate_operand" "xm")]))]
9566   "TARGET_XOP"
9567   "vpcom%Y1u<ssemodesuffix>\t{%3, %2, %0|%0, %2, %3}"
9568   [(set_attr "type" "ssecmp")
9569    (set_attr "prefix_data16" "0")
9570    (set_attr "prefix_rep" "0")
9571    (set_attr "prefix_extra" "2")
9572    (set_attr "length_immediate" "1")
9573    (set_attr "mode" "TI")])
9574
9575 ;; Version of pcom*u* that is called from the intrinsics that allows pcomequ*
9576 ;; and pcomneu* not to be converted to the signed ones in case somebody needs
9577 ;; the exact instruction generated for the intrinsic.
9578 (define_insn "xop_maskcmp_uns2<mode>3"
9579   [(set (match_operand:VI_128 0 "register_operand" "=x")
9580         (unspec:VI_128
9581          [(match_operator:VI_128 1 "ix86_comparison_uns_operator"
9582           [(match_operand:VI_128 2 "register_operand" "x")
9583            (match_operand:VI_128 3 "nonimmediate_operand" "xm")])]
9584          UNSPEC_XOP_UNSIGNED_CMP))]
9585   "TARGET_XOP"
9586   "vpcom%Y1u<ssemodesuffix>\t{%3, %2, %0|%0, %2, %3}"
9587   [(set_attr "type" "ssecmp")
9588    (set_attr "prefix_data16" "0")
9589    (set_attr "prefix_extra" "2")
9590    (set_attr "length_immediate" "1")
9591    (set_attr "mode" "TI")])
9592
9593 ;; Pcomtrue and pcomfalse support.  These are useless instructions, but are
9594 ;; being added here to be complete.
9595 (define_insn "xop_pcom_tf<mode>3"
9596   [(set (match_operand:VI_128 0 "register_operand" "=x")
9597         (unspec:VI_128
9598           [(match_operand:VI_128 1 "register_operand" "x")
9599            (match_operand:VI_128 2 "nonimmediate_operand" "xm")
9600            (match_operand:SI 3 "const_int_operand" "n")]
9601           UNSPEC_XOP_TRUEFALSE))]
9602   "TARGET_XOP"
9603 {
9604   return ((INTVAL (operands[3]) != 0)
9605           ? "vpcomtrue<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
9606           : "vpcomfalse<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}");
9607 }
9608   [(set_attr "type" "ssecmp")
9609    (set_attr "prefix_data16" "0")
9610    (set_attr "prefix_extra" "2")
9611    (set_attr "length_immediate" "1")
9612    (set_attr "mode" "TI")])
9613
9614 (define_insn "xop_vpermil2<mode>3"
9615   [(set (match_operand:VF 0 "register_operand" "=x")
9616         (unspec:VF
9617           [(match_operand:VF 1 "register_operand" "x")
9618            (match_operand:VF 2 "nonimmediate_operand" "%x")
9619            (match_operand:<sseintvecmode> 3 "nonimmediate_operand" "xm")
9620            (match_operand:SI 4 "const_0_to_3_operand" "n")]
9621           UNSPEC_VPERMIL2))]
9622   "TARGET_XOP"
9623   "vpermil2<ssemodesuffix>\t{%4, %3, %2, %1, %0|%0, %1, %2, %3, %4}"
9624   [(set_attr "type" "sse4arg")
9625    (set_attr "length_immediate" "1")
9626    (set_attr "mode" "<MODE>")])
9627
9628 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9629
9630 (define_insn "aesenc"
9631   [(set (match_operand:V2DI 0 "register_operand" "=x,x")
9632         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0,x")
9633                        (match_operand:V2DI 2 "nonimmediate_operand" "xm,xm")]
9634                       UNSPEC_AESENC))]
9635   "TARGET_AES"
9636   "@
9637    aesenc\t{%2, %0|%0, %2}
9638    vaesenc\t{%2, %1, %0|%0, %1, %2}"
9639   [(set_attr "isa" "noavx,avx")
9640    (set_attr "type" "sselog1")
9641    (set_attr "prefix_extra" "1")
9642    (set_attr "prefix" "orig,vex")
9643    (set_attr "mode" "TI")])
9644
9645 (define_insn "aesenclast"
9646   [(set (match_operand:V2DI 0 "register_operand" "=x,x")
9647         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0,x")
9648                        (match_operand:V2DI 2 "nonimmediate_operand" "xm,xm")]
9649                       UNSPEC_AESENCLAST))]
9650   "TARGET_AES"
9651   "@
9652    aesenclast\t{%2, %0|%0, %2}
9653    vaesenclast\t{%2, %1, %0|%0, %1, %2}"
9654   [(set_attr "isa" "noavx,avx")
9655    (set_attr "type" "sselog1")
9656    (set_attr "prefix_extra" "1")
9657    (set_attr "prefix" "orig,vex")
9658    (set_attr "mode" "TI")])
9659
9660 (define_insn "aesdec"
9661   [(set (match_operand:V2DI 0 "register_operand" "=x,x")
9662         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0,x")
9663                        (match_operand:V2DI 2 "nonimmediate_operand" "xm,xm")]
9664                       UNSPEC_AESDEC))]
9665   "TARGET_AES"
9666   "@
9667    aesdec\t{%2, %0|%0, %2}
9668    vaesdec\t{%2, %1, %0|%0, %1, %2}"
9669   [(set_attr "isa" "noavx,avx")
9670    (set_attr "type" "sselog1")
9671    (set_attr "prefix_extra" "1")
9672    (set_attr "prefix" "orig,vex")
9673    (set_attr "mode" "TI")])
9674
9675 (define_insn "aesdeclast"
9676   [(set (match_operand:V2DI 0 "register_operand" "=x,x")
9677         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0,x")
9678                        (match_operand:V2DI 2 "nonimmediate_operand" "xm,xm")]
9679                       UNSPEC_AESDECLAST))]
9680   "TARGET_AES"
9681   "@
9682    aesdeclast\t{%2, %0|%0, %2}
9683    vaesdeclast\t{%2, %1, %0|%0, %1, %2}"
9684   [(set_attr "isa" "noavx,avx")
9685    (set_attr "type" "sselog1")
9686    (set_attr "prefix_extra" "1")
9687    (set_attr "prefix" "orig,vex")
9688    (set_attr "mode" "TI")])
9689
9690 (define_insn "aesimc"
9691   [(set (match_operand:V2DI 0 "register_operand" "=x")
9692         (unspec:V2DI [(match_operand:V2DI 1 "nonimmediate_operand" "xm")]
9693                       UNSPEC_AESIMC))]
9694   "TARGET_AES"
9695   "%vaesimc\t{%1, %0|%0, %1}"
9696   [(set_attr "type" "sselog1")
9697    (set_attr "prefix_extra" "1")
9698    (set_attr "prefix" "maybe_vex")
9699    (set_attr "mode" "TI")])
9700
9701 (define_insn "aeskeygenassist"
9702   [(set (match_operand:V2DI 0 "register_operand" "=x")
9703         (unspec:V2DI [(match_operand:V2DI 1 "nonimmediate_operand" "xm")
9704                       (match_operand:SI 2 "const_0_to_255_operand" "n")]
9705                      UNSPEC_AESKEYGENASSIST))]
9706   "TARGET_AES"
9707   "%vaeskeygenassist\t{%2, %1, %0|%0, %1, %2}"
9708   [(set_attr "type" "sselog1")
9709    (set_attr "prefix_extra" "1")
9710    (set_attr "length_immediate" "1")
9711    (set_attr "prefix" "maybe_vex")
9712    (set_attr "mode" "TI")])
9713
9714 (define_insn "pclmulqdq"
9715   [(set (match_operand:V2DI 0 "register_operand" "=x,x")
9716         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0,x")
9717                       (match_operand:V2DI 2 "nonimmediate_operand" "xm,xm")
9718                       (match_operand:SI 3 "const_0_to_255_operand" "n,n")]
9719                      UNSPEC_PCLMUL))]
9720   "TARGET_PCLMUL"
9721   "@
9722    pclmulqdq\t{%3, %2, %0|%0, %2, %3}
9723    vpclmulqdq\t{%3, %2, %1, %0|%0, %1, %2, %3}"
9724   [(set_attr "isa" "noavx,avx")
9725    (set_attr "type" "sselog1")
9726    (set_attr "prefix_extra" "1")
9727    (set_attr "length_immediate" "1")
9728    (set_attr "prefix" "orig,vex")
9729    (set_attr "mode" "TI")])
9730
9731 (define_expand "avx_vzeroall"
9732   [(match_par_dup 0 [(const_int 0)])]
9733   "TARGET_AVX"
9734 {
9735   int nregs = TARGET_64BIT ? 16 : 8;
9736   int regno;
9737
9738   operands[0] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nregs + 1));
9739
9740   XVECEXP (operands[0], 0, 0)
9741     = gen_rtx_UNSPEC_VOLATILE (VOIDmode, gen_rtvec (1, const0_rtx),
9742                                UNSPECV_VZEROALL);
9743
9744   for (regno = 0; regno < nregs; regno++)
9745     XVECEXP (operands[0], 0, regno + 1)
9746       = gen_rtx_SET (VOIDmode,
9747                      gen_rtx_REG (V8SImode, SSE_REGNO (regno)),
9748                      CONST0_RTX (V8SImode));
9749 })
9750
9751 (define_insn "*avx_vzeroall"
9752   [(match_parallel 0 "vzeroall_operation"
9753     [(unspec_volatile [(const_int 0)] UNSPECV_VZEROALL)])]
9754   "TARGET_AVX"
9755   "vzeroall"
9756   [(set_attr "type" "sse")
9757    (set_attr "modrm" "0")
9758    (set_attr "memory" "none")
9759    (set_attr "prefix" "vex")
9760    (set_attr "mode" "OI")])
9761
9762 ;; Clear the upper 128bits of AVX registers, equivalent to a NOP
9763 ;; if the upper 128bits are unused.
9764 (define_insn "avx_vzeroupper"
9765   [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
9766                     UNSPECV_VZEROUPPER)]
9767   "TARGET_AVX"
9768   "vzeroupper"
9769   [(set_attr "type" "sse")
9770    (set_attr "modrm" "0")
9771    (set_attr "memory" "none")
9772    (set_attr "prefix" "vex")
9773    (set_attr "mode" "OI")])
9774
9775 ;; Modes handled by AVX vec_dup patterns.
9776 (define_mode_iterator AVX_VEC_DUP_MODE
9777   [V8SI V8SF V4DI V4DF])
9778
9779 (define_insn "vec_dup<mode>"
9780   [(set (match_operand:AVX_VEC_DUP_MODE 0 "register_operand" "=x,x")
9781         (vec_duplicate:AVX_VEC_DUP_MODE
9782           (match_operand:<ssescalarmode> 1 "nonimmediate_operand" "m,?x")))]
9783   "TARGET_AVX"
9784   "@
9785    vbroadcast<ssescalarmodesuffix>\t{%1, %0|%0, %1}
9786    #"
9787   [(set_attr "type" "ssemov")
9788    (set_attr "prefix_extra" "1")
9789    (set_attr "prefix" "vex")
9790    (set_attr "mode" "V8SF")])
9791
9792 (define_split
9793   [(set (match_operand:AVX_VEC_DUP_MODE 0 "register_operand" "")
9794         (vec_duplicate:AVX_VEC_DUP_MODE
9795           (match_operand:<ssescalarmode> 1 "register_operand" "")))]
9796   "TARGET_AVX && reload_completed"
9797   [(set (match_dup 2)
9798         (vec_duplicate:<ssehalfvecmode> (match_dup 1)))
9799    (set (match_dup 0)
9800         (vec_concat:AVX_VEC_DUP_MODE (match_dup 2) (match_dup 2)))]
9801   "operands[2] = gen_rtx_REG (<ssehalfvecmode>mode, REGNO (operands[0]));")
9802
9803 (define_insn "avx_vbroadcastf128_<mode>"
9804   [(set (match_operand:V_256 0 "register_operand" "=x,x,x")
9805         (vec_concat:V_256
9806           (match_operand:<ssehalfvecmode> 1 "nonimmediate_operand" "m,0,?x")
9807           (match_dup 1)))]
9808   "TARGET_AVX"
9809   "@
9810    vbroadcastf128\t{%1, %0|%0, %1}
9811    vinsertf128\t{$1, %1, %0, %0|%0, %0, %1, 1}
9812    vperm2f128\t{$0, %t1, %t1, %0|%0, %t1, %t1, 0}"
9813   [(set_attr "type" "ssemov,sselog1,sselog1")
9814    (set_attr "prefix_extra" "1")
9815    (set_attr "length_immediate" "0,1,1")
9816    (set_attr "prefix" "vex")
9817    (set_attr "mode" "V4SF,V8SF,V8SF")])
9818
9819 ;; Recognize broadcast as a vec_select as produced by builtin_vec_perm.
9820 ;; If it so happens that the input is in memory, use vbroadcast.
9821 ;; Otherwise use vpermilp (and in the case of 256-bit modes, vperm2f128).
9822 (define_insn "*avx_vperm_broadcast_v4sf"
9823   [(set (match_operand:V4SF 0 "register_operand" "=x,x,x")
9824         (vec_select:V4SF
9825           (match_operand:V4SF 1 "nonimmediate_operand" "m,o,x")
9826           (match_parallel 2 "avx_vbroadcast_operand"
9827             [(match_operand 3 "const_int_operand" "C,n,n")])))]
9828   "TARGET_AVX"
9829 {
9830   int elt = INTVAL (operands[3]);
9831   switch (which_alternative)
9832     {
9833     case 0:
9834     case 1:
9835       operands[1] = adjust_address_nv (operands[1], SFmode, elt * 4);
9836       return "vbroadcastss\t{%1, %0|%0, %1}";
9837     case 2:
9838       operands[2] = GEN_INT (elt * 0x55);
9839       return "vpermilps\t{%2, %1, %0|%0, %1, %2}";
9840     default:
9841       gcc_unreachable ();
9842     }
9843 }
9844   [(set_attr "type" "ssemov,ssemov,sselog1")
9845    (set_attr "prefix_extra" "1")
9846    (set_attr "length_immediate" "0,0,1")
9847    (set_attr "prefix" "vex")
9848    (set_attr "mode" "SF,SF,V4SF")])
9849
9850 (define_insn_and_split "*avx_vperm_broadcast_<mode>"
9851   [(set (match_operand:VF_256 0 "register_operand" "=x,x,x")
9852         (vec_select:VF_256
9853           (match_operand:VF_256 1 "nonimmediate_operand" "m,o,?x")
9854           (match_parallel 2 "avx_vbroadcast_operand"
9855             [(match_operand 3 "const_int_operand" "C,n,n")])))]
9856   "TARGET_AVX"
9857   "#"
9858   "&& reload_completed"
9859   [(set (match_dup 0) (vec_duplicate:VF_256 (match_dup 1)))]
9860 {
9861   rtx op0 = operands[0], op1 = operands[1];
9862   int elt = INTVAL (operands[3]);
9863
9864   if (REG_P (op1))
9865     {
9866       int mask;
9867
9868       /* Shuffle element we care about into all elements of the 128-bit lane.
9869          The other lane gets shuffled too, but we don't care.  */
9870       if (<MODE>mode == V4DFmode)
9871         mask = (elt & 1 ? 15 : 0);
9872       else
9873         mask = (elt & 3) * 0x55;
9874       emit_insn (gen_avx_vpermil<mode> (op0, op1, GEN_INT (mask)));
9875
9876       /* Shuffle the lane we care about into both lanes of the dest.  */
9877       mask = (elt / (<ssescalarnum> / 2)) * 0x11;
9878       emit_insn (gen_avx_vperm2f128<mode>3 (op0, op0, op0, GEN_INT (mask)));
9879       DONE;
9880     }
9881
9882   operands[1] = adjust_address_nv (op1, <ssescalarmode>mode,
9883                                    elt * GET_MODE_SIZE (<ssescalarmode>mode));
9884 })
9885
9886 (define_expand "avx_vpermil<mode>"
9887   [(set (match_operand:VF2 0 "register_operand" "")
9888         (vec_select:VF2
9889           (match_operand:VF2 1 "nonimmediate_operand" "")
9890           (match_operand:SI 2 "const_0_to_255_operand" "")))]
9891   "TARGET_AVX"
9892 {
9893   int mask = INTVAL (operands[2]);
9894   rtx perm[<ssescalarnum>];
9895
9896   perm[0] = GEN_INT (mask & 1);
9897   perm[1] = GEN_INT ((mask >> 1) & 1);
9898   if (<MODE>mode == V4DFmode)
9899     {
9900       perm[2] = GEN_INT (((mask >> 2) & 1) + 2);
9901       perm[3] = GEN_INT (((mask >> 3) & 1) + 2);
9902     }
9903
9904   operands[2]
9905     = gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (<ssescalarnum>, perm));
9906 })
9907
9908 (define_expand "avx_vpermil<mode>"
9909   [(set (match_operand:VF1 0 "register_operand" "")
9910         (vec_select:VF1
9911           (match_operand:VF1 1 "nonimmediate_operand" "")
9912           (match_operand:SI 2 "const_0_to_255_operand" "")))]
9913   "TARGET_AVX"
9914 {
9915   int mask = INTVAL (operands[2]);
9916   rtx perm[<ssescalarnum>];
9917
9918   perm[0] = GEN_INT (mask & 3);
9919   perm[1] = GEN_INT ((mask >> 2) & 3);
9920   perm[2] = GEN_INT ((mask >> 4) & 3);
9921   perm[3] = GEN_INT ((mask >> 6) & 3);
9922   if (<MODE>mode == V8SFmode)
9923     {
9924       perm[4] = GEN_INT ((mask & 3) + 4);
9925       perm[5] = GEN_INT (((mask >> 2) & 3) + 4);
9926       perm[6] = GEN_INT (((mask >> 4) & 3) + 4);
9927       perm[7] = GEN_INT (((mask >> 6) & 3) + 4);
9928     }
9929
9930   operands[2]
9931     = gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (<ssescalarnum>, perm));
9932 })
9933
9934 (define_insn "*avx_vpermilp<mode>"
9935   [(set (match_operand:VF 0 "register_operand" "=x")
9936         (vec_select:VF
9937           (match_operand:VF 1 "nonimmediate_operand" "xm")
9938           (match_parallel 2 ""
9939             [(match_operand 3 "const_int_operand" "")])))]
9940   "TARGET_AVX
9941    && avx_vpermilp_parallel (operands[2], <MODE>mode)"
9942 {
9943   int mask = avx_vpermilp_parallel (operands[2], <MODE>mode) - 1;
9944   operands[2] = GEN_INT (mask);
9945   return "vpermil<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}";
9946 }
9947   [(set_attr "type" "sselog")
9948    (set_attr "prefix_extra" "1")
9949    (set_attr "length_immediate" "1")
9950    (set_attr "prefix" "vex")
9951    (set_attr "mode" "<MODE>")])
9952
9953 (define_insn "avx_vpermilvar<mode>3"
9954   [(set (match_operand:VF 0 "register_operand" "=x")
9955         (unspec:VF
9956           [(match_operand:VF 1 "register_operand" "x")
9957            (match_operand:<sseintvecmode> 2 "nonimmediate_operand" "xm")]
9958           UNSPEC_VPERMIL))]
9959   "TARGET_AVX"
9960   "vpermil<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
9961   [(set_attr "type" "sselog")
9962    (set_attr "prefix_extra" "1")
9963    (set_attr "prefix" "vex")
9964    (set_attr "mode" "<MODE>")])
9965
9966 (define_expand "avx_vperm2f128<mode>3"
9967   [(set (match_operand:AVX256MODE2P 0 "register_operand" "")
9968         (unspec:AVX256MODE2P
9969           [(match_operand:AVX256MODE2P 1 "register_operand" "")
9970            (match_operand:AVX256MODE2P 2 "nonimmediate_operand" "")
9971            (match_operand:SI 3 "const_0_to_255_operand" "")]
9972           UNSPEC_VPERMIL2F128))]
9973   "TARGET_AVX"
9974 {
9975   int mask = INTVAL (operands[3]);
9976   if ((mask & 0x88) == 0)
9977     {
9978       rtx perm[<ssescalarnum>], t1, t2;
9979       int i, base, nelt = <ssescalarnum>, nelt2 = nelt / 2;
9980
9981       base = (mask & 3) * nelt2;
9982       for (i = 0; i < nelt2; ++i)
9983         perm[i] = GEN_INT (base + i);
9984
9985       base = ((mask >> 4) & 3) * nelt2;
9986       for (i = 0; i < nelt2; ++i)
9987         perm[i + nelt2] = GEN_INT (base + i);
9988
9989       t2 = gen_rtx_VEC_CONCAT (<ssedoublevecmode>mode,
9990                                operands[1], operands[2]);
9991       t1 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelt, perm));
9992       t2 = gen_rtx_VEC_SELECT (<MODE>mode, t2, t1);
9993       t2 = gen_rtx_SET (VOIDmode, operands[0], t2);
9994       emit_insn (t2);
9995       DONE;
9996     }
9997 })
9998
9999 ;; Note that bits 7 and 3 of the imm8 allow lanes to be zeroed, which
10000 ;; means that in order to represent this properly in rtl we'd have to
10001 ;; nest *another* vec_concat with a zero operand and do the select from
10002 ;; a 4x wide vector.  That doesn't seem very nice.
10003 (define_insn "*avx_vperm2f128<mode>_full"
10004   [(set (match_operand:AVX256MODE2P 0 "register_operand" "=x")
10005         (unspec:AVX256MODE2P
10006           [(match_operand:AVX256MODE2P 1 "register_operand" "x")
10007            (match_operand:AVX256MODE2P 2 "nonimmediate_operand" "xm")
10008            (match_operand:SI 3 "const_0_to_255_operand" "n")]
10009           UNSPEC_VPERMIL2F128))]
10010   "TARGET_AVX"
10011   "vperm2f128\t{%3, %2, %1, %0|%0, %1, %2, %3}"
10012   [(set_attr "type" "sselog")
10013    (set_attr "prefix_extra" "1")
10014    (set_attr "length_immediate" "1")
10015    (set_attr "prefix" "vex")
10016    (set_attr "mode" "V8SF")])
10017
10018 (define_insn "*avx_vperm2f128<mode>_nozero"
10019   [(set (match_operand:AVX256MODE2P 0 "register_operand" "=x")
10020         (vec_select:AVX256MODE2P
10021           (vec_concat:<ssedoublevecmode>
10022             (match_operand:AVX256MODE2P 1 "register_operand" "x")
10023             (match_operand:AVX256MODE2P 2 "nonimmediate_operand" "xm"))
10024           (match_parallel 3 ""
10025             [(match_operand 4 "const_int_operand" "")])))]
10026   "TARGET_AVX
10027    && avx_vperm2f128_parallel (operands[3], <MODE>mode)"
10028 {
10029   int mask = avx_vperm2f128_parallel (operands[3], <MODE>mode) - 1;
10030   operands[3] = GEN_INT (mask);
10031   return "vperm2f128\t{%3, %2, %1, %0|%0, %1, %2, %3}";
10032 }
10033   [(set_attr "type" "sselog")
10034    (set_attr "prefix_extra" "1")
10035    (set_attr "length_immediate" "1")
10036    (set_attr "prefix" "vex")
10037    (set_attr "mode" "V8SF")])
10038
10039 (define_expand "avx_vinsertf128<mode>"
10040   [(match_operand:V_256 0 "register_operand" "")
10041    (match_operand:V_256 1 "register_operand" "")
10042    (match_operand:<ssehalfvecmode> 2 "nonimmediate_operand" "")
10043    (match_operand:SI 3 "const_0_to_1_operand" "")]
10044   "TARGET_AVX"
10045 {
10046   rtx (*insn)(rtx, rtx, rtx);
10047
10048   switch (INTVAL (operands[3]))
10049     {
10050     case 0:
10051       insn = gen_vec_set_lo_<mode>;
10052       break;
10053     case 1:
10054       insn = gen_vec_set_hi_<mode>;
10055       break;
10056     default:
10057       gcc_unreachable ();
10058     }
10059
10060   emit_insn (insn (operands[0], operands[1], operands[2]));
10061   DONE;
10062 })
10063
10064 (define_insn "vec_set_lo_<mode>"
10065   [(set (match_operand:VI8F_256 0 "register_operand" "=x")
10066         (vec_concat:VI8F_256
10067           (match_operand:<ssehalfvecmode> 2 "nonimmediate_operand" "xm")
10068           (vec_select:<ssehalfvecmode>
10069             (match_operand:VI8F_256 1 "register_operand" "x")
10070             (parallel [(const_int 2) (const_int 3)]))))]
10071   "TARGET_AVX"
10072   "vinsertf128\t{$0x0, %2, %1, %0|%0, %1, %2, 0x0}"
10073   [(set_attr "type" "sselog")
10074    (set_attr "prefix_extra" "1")
10075    (set_attr "length_immediate" "1")
10076    (set_attr "prefix" "vex")
10077    (set_attr "mode" "V8SF")])
10078
10079 (define_insn "vec_set_hi_<mode>"
10080   [(set (match_operand:VI8F_256 0 "register_operand" "=x")
10081         (vec_concat:VI8F_256
10082           (vec_select:<ssehalfvecmode>
10083             (match_operand:VI8F_256 1 "register_operand" "x")
10084             (parallel [(const_int 0) (const_int 1)]))
10085           (match_operand:<ssehalfvecmode> 2 "nonimmediate_operand" "xm")))]
10086   "TARGET_AVX"
10087   "vinsertf128\t{$0x1, %2, %1, %0|%0, %1, %2, 0x1}"
10088   [(set_attr "type" "sselog")
10089    (set_attr "prefix_extra" "1")
10090    (set_attr "length_immediate" "1")
10091    (set_attr "prefix" "vex")
10092    (set_attr "mode" "V8SF")])
10093
10094 (define_insn "vec_set_lo_<mode>"
10095   [(set (match_operand:VI4F_256 0 "register_operand" "=x")
10096         (vec_concat:VI4F_256
10097           (match_operand:<ssehalfvecmode> 2 "nonimmediate_operand" "xm")
10098           (vec_select:<ssehalfvecmode>
10099             (match_operand:VI4F_256 1 "register_operand" "x")
10100             (parallel [(const_int 4) (const_int 5)
10101                        (const_int 6) (const_int 7)]))))]
10102   "TARGET_AVX"
10103   "vinsertf128\t{$0x0, %2, %1, %0|%0, %1, %2, 0x0}"
10104   [(set_attr "type" "sselog")
10105    (set_attr "prefix_extra" "1")
10106    (set_attr "length_immediate" "1")
10107    (set_attr "prefix" "vex")
10108    (set_attr "mode" "V8SF")])
10109
10110 (define_insn "vec_set_hi_<mode>"
10111   [(set (match_operand:VI4F_256 0 "register_operand" "=x")
10112         (vec_concat:VI4F_256
10113           (vec_select:<ssehalfvecmode>
10114             (match_operand:VI4F_256 1 "register_operand" "x")
10115             (parallel [(const_int 0) (const_int 1)
10116                        (const_int 2) (const_int 3)]))
10117           (match_operand:<ssehalfvecmode> 2 "nonimmediate_operand" "xm")))]
10118   "TARGET_AVX"
10119   "vinsertf128\t{$0x1, %2, %1, %0|%0, %1, %2, 0x1}"
10120   [(set_attr "type" "sselog")
10121    (set_attr "prefix_extra" "1")
10122    (set_attr "length_immediate" "1")
10123    (set_attr "prefix" "vex")
10124    (set_attr "mode" "V8SF")])
10125
10126 (define_insn "vec_set_lo_v16hi"
10127   [(set (match_operand:V16HI 0 "register_operand" "=x")
10128         (vec_concat:V16HI
10129           (match_operand:V8HI 2 "nonimmediate_operand" "xm")
10130           (vec_select:V8HI
10131             (match_operand:V16HI 1 "register_operand" "x")
10132             (parallel [(const_int 8) (const_int 9)
10133                        (const_int 10) (const_int 11)
10134                        (const_int 12) (const_int 13)
10135                        (const_int 14) (const_int 15)]))))]
10136   "TARGET_AVX"
10137   "vinsertf128\t{$0x0, %2, %1, %0|%0, %1, %2, 0x0}"
10138   [(set_attr "type" "sselog")
10139    (set_attr "prefix_extra" "1")
10140    (set_attr "length_immediate" "1")
10141    (set_attr "prefix" "vex")
10142    (set_attr "mode" "V8SF")])
10143
10144 (define_insn "vec_set_hi_v16hi"
10145   [(set (match_operand:V16HI 0 "register_operand" "=x")
10146         (vec_concat:V16HI
10147           (vec_select:V8HI
10148             (match_operand:V16HI 1 "register_operand" "x")
10149             (parallel [(const_int 0) (const_int 1)
10150                        (const_int 2) (const_int 3)
10151                        (const_int 4) (const_int 5)
10152                        (const_int 6) (const_int 7)]))
10153           (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
10154   "TARGET_AVX"
10155   "vinsertf128\t{$0x1, %2, %1, %0|%0, %1, %2, 0x1}"
10156   [(set_attr "type" "sselog")
10157    (set_attr "prefix_extra" "1")
10158    (set_attr "length_immediate" "1")
10159    (set_attr "prefix" "vex")
10160    (set_attr "mode" "V8SF")])
10161
10162 (define_insn "vec_set_lo_v32qi"
10163   [(set (match_operand:V32QI 0 "register_operand" "=x")
10164         (vec_concat:V32QI
10165           (match_operand:V16QI 2 "nonimmediate_operand" "xm")
10166           (vec_select:V16QI
10167             (match_operand:V32QI 1 "register_operand" "x")
10168             (parallel [(const_int 16) (const_int 17)
10169                        (const_int 18) (const_int 19)
10170                        (const_int 20) (const_int 21)
10171                        (const_int 22) (const_int 23)
10172                        (const_int 24) (const_int 25)
10173                        (const_int 26) (const_int 27)
10174                        (const_int 28) (const_int 29)
10175                        (const_int 30) (const_int 31)]))))]
10176   "TARGET_AVX"
10177   "vinsertf128\t{$0x0, %2, %1, %0|%0, %1, %2, 0x0}"
10178   [(set_attr "type" "sselog")
10179    (set_attr "prefix_extra" "1")
10180    (set_attr "length_immediate" "1")
10181    (set_attr "prefix" "vex")
10182    (set_attr "mode" "V8SF")])
10183
10184 (define_insn "vec_set_hi_v32qi"
10185   [(set (match_operand:V32QI 0 "register_operand" "=x")
10186         (vec_concat:V32QI
10187           (vec_select:V16QI
10188             (match_operand:V32QI 1 "register_operand" "x")
10189             (parallel [(const_int 0) (const_int 1)
10190                        (const_int 2) (const_int 3)
10191                        (const_int 4) (const_int 5)
10192                        (const_int 6) (const_int 7)
10193                        (const_int 8) (const_int 9)
10194                        (const_int 10) (const_int 11)
10195                        (const_int 12) (const_int 13)
10196                        (const_int 14) (const_int 15)]))
10197           (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
10198   "TARGET_AVX"
10199   "vinsertf128\t{$0x1, %2, %1, %0|%0, %1, %2, 0x1}"
10200   [(set_attr "type" "sselog")
10201    (set_attr "prefix_extra" "1")
10202    (set_attr "length_immediate" "1")
10203    (set_attr "prefix" "vex")
10204    (set_attr "mode" "V8SF")])
10205
10206 (define_expand "avx_maskload<ssemodesuffix><avxsizesuffix>"
10207   [(set (match_operand:VF 0 "register_operand" "")
10208         (unspec:VF
10209           [(match_operand:<sseintvecmode> 2 "register_operand" "")
10210            (match_operand:VF 1 "memory_operand" "")
10211            (match_dup 0)]
10212           UNSPEC_MASKMOV))]
10213   "TARGET_AVX")
10214
10215 (define_expand "avx_maskstore<ssemodesuffix><avxsizesuffix>"
10216   [(set (match_operand:VF 0 "memory_operand" "")
10217         (unspec:VF
10218           [(match_operand:<sseintvecmode> 1 "register_operand" "")
10219            (match_operand:VF 2 "register_operand" "")
10220            (match_dup 0)]
10221           UNSPEC_MASKMOV))]
10222   "TARGET_AVX")
10223
10224 (define_insn "*avx_maskmov<ssemodesuffix><avxsizesuffix>"
10225   [(set (match_operand:VF 0 "nonimmediate_operand" "=x,m")
10226         (unspec:VF
10227           [(match_operand:<sseintvecmode> 1 "register_operand" "x,x")
10228            (match_operand:VF 2 "nonimmediate_operand" "m,x")
10229            (match_dup 0)]
10230           UNSPEC_MASKMOV))]
10231   "TARGET_AVX
10232    && (REG_P (operands[0]) == MEM_P (operands[2]))"
10233   "vmaskmov<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10234   [(set_attr "type" "sselog1")
10235    (set_attr "prefix_extra" "1")
10236    (set_attr "prefix" "vex")
10237    (set_attr "mode" "<MODE>")])
10238
10239 (define_insn_and_split "avx_<castmode><avxsizesuffix>_<castmode>"
10240   [(set (match_operand:AVX256MODE2P 0 "nonimmediate_operand" "=x,m")
10241         (unspec:AVX256MODE2P
10242           [(match_operand:<ssehalfvecmode> 1 "nonimmediate_operand" "xm,x")]
10243           UNSPEC_CAST))]
10244   "TARGET_AVX"
10245   "#"
10246   "&& reload_completed"
10247   [(const_int 0)]
10248 {
10249   rtx op0 = operands[0];
10250   rtx op1 = operands[1];
10251   if (REG_P (op0))
10252     op0 = gen_rtx_REG (<ssehalfvecmode>mode, REGNO (op0));
10253   else
10254     op1 = gen_rtx_REG (<MODE>mode, REGNO (op1));
10255   emit_move_insn (op0, op1);
10256   DONE;
10257 })
10258
10259 (define_expand "vec_init<mode>"
10260   [(match_operand:V_256 0 "register_operand" "")
10261    (match_operand 1 "" "")]
10262   "TARGET_AVX"
10263 {
10264   ix86_expand_vector_init (false, operands[0], operands[1]);
10265   DONE;
10266 })
10267
10268 (define_insn "*vec_concat<mode>_avx"
10269   [(set (match_operand:V_256 0 "register_operand" "=x,x")
10270         (vec_concat:V_256
10271           (match_operand:<ssehalfvecmode> 1 "register_operand" "x,x")
10272           (match_operand:<ssehalfvecmode> 2 "vector_move_operand" "xm,C")))]
10273   "TARGET_AVX"
10274 {
10275   switch (which_alternative)
10276     {
10277     case 0:
10278       return "vinsertf128\t{$0x1, %2, %t1, %0|%0, %t1, %2, 0x1}";
10279     case 1:
10280       switch (get_attr_mode (insn))
10281         {
10282         case MODE_V8SF:
10283           return "vmovaps\t{%1, %x0|%x0, %1}";
10284         case MODE_V4DF:
10285           return "vmovapd\t{%1, %x0|%x0, %1}";
10286         default:
10287           return "vmovdqa\t{%1, %x0|%x0, %1}";
10288         }
10289     default:
10290       gcc_unreachable ();
10291     }
10292 }
10293   [(set_attr "type" "sselog,ssemov")
10294    (set_attr "prefix_extra" "1,*")
10295    (set_attr "length_immediate" "1,*")
10296    (set_attr "prefix" "vex")
10297    (set_attr "mode" "<sseinsnmode>")])
10298
10299 (define_insn "vcvtph2ps"
10300   [(set (match_operand:V4SF 0 "register_operand" "=x")
10301         (vec_select:V4SF
10302           (unspec:V8SF [(match_operand:V8HI 1 "register_operand" "x")]
10303                        UNSPEC_VCVTPH2PS)
10304           (parallel [(const_int 0) (const_int 1)
10305                      (const_int 1) (const_int 2)])))]
10306   "TARGET_F16C"
10307   "vcvtph2ps\t{%1, %0|%0, %1}"
10308   [(set_attr "type" "ssecvt")
10309    (set_attr "prefix" "vex")
10310    (set_attr "mode" "V4SF")])
10311
10312 (define_insn "*vcvtph2ps_load"
10313   [(set (match_operand:V4SF 0 "register_operand" "=x")
10314         (unspec:V4SF [(match_operand:V4HI 1 "memory_operand" "m")]
10315                      UNSPEC_VCVTPH2PS))]
10316   "TARGET_F16C"
10317   "vcvtph2ps\t{%1, %0|%0, %1}"
10318   [(set_attr "type" "ssecvt")
10319    (set_attr "prefix" "vex")
10320    (set_attr "mode" "V8SF")])
10321
10322 (define_insn "vcvtph2ps256"
10323   [(set (match_operand:V8SF 0 "register_operand" "=x")
10324         (unspec:V8SF [(match_operand:V8HI 1 "nonimmediate_operand" "xm")]
10325                      UNSPEC_VCVTPH2PS))]
10326   "TARGET_F16C"
10327   "vcvtph2ps\t{%1, %0|%0, %1}"
10328   [(set_attr "type" "ssecvt")
10329    (set_attr "prefix" "vex")
10330    (set_attr "mode" "V8SF")])
10331
10332 (define_expand "vcvtps2ph"
10333   [(set (match_operand:V8HI 0 "register_operand" "")
10334         (vec_concat:V8HI
10335           (unspec:V4HI [(match_operand:V4SF 1 "register_operand" "")
10336                         (match_operand:SI 2 "const_0_to_255_operand" "")]
10337                        UNSPEC_VCVTPS2PH)
10338           (match_dup 3)))]
10339   "TARGET_F16C"
10340   "operands[3] = CONST0_RTX (V4HImode);")
10341
10342 (define_insn "*vcvtps2ph"
10343   [(set (match_operand:V8HI 0 "register_operand" "=x")
10344         (vec_concat:V8HI
10345           (unspec:V4HI [(match_operand:V4SF 1 "register_operand" "x")
10346                         (match_operand:SI 2 "const_0_to_255_operand" "N")]
10347                        UNSPEC_VCVTPS2PH)
10348           (match_operand:V4HI 3 "const0_operand" "")))]
10349   "TARGET_F16C"
10350   "vcvtps2ph\t{%2, %1, %0|%0, %1, %2}"
10351   [(set_attr "type" "ssecvt")
10352    (set_attr "prefix" "vex")
10353    (set_attr "mode" "V4SF")])
10354
10355 (define_insn "*vcvtps2ph_store"
10356   [(set (match_operand:V4HI 0 "memory_operand" "=m")
10357         (unspec:V4HI [(match_operand:V4SF 1 "register_operand" "x")
10358                       (match_operand:SI 2 "const_0_to_255_operand" "N")]
10359                      UNSPEC_VCVTPS2PH))]
10360   "TARGET_F16C"
10361   "vcvtps2ph\t{%2, %1, %0|%0, %1, %2}"
10362   [(set_attr "type" "ssecvt")
10363    (set_attr "prefix" "vex")
10364    (set_attr "mode" "V4SF")])
10365
10366 (define_insn "vcvtps2ph256"
10367   [(set (match_operand:V8HI 0 "nonimmediate_operand" "=xm")
10368         (unspec:V8HI [(match_operand:V8SF 1 "register_operand" "x")
10369                       (match_operand:SI 2 "const_0_to_255_operand" "N")]
10370                      UNSPEC_VCVTPS2PH))]
10371   "TARGET_F16C"
10372   "vcvtps2ph\t{%2, %1, %0|%0, %1, %2}"
10373   [(set_attr "type" "ssecvt")
10374    (set_attr "prefix" "vex")
10375    (set_attr "mode" "V8SF")])