OSDN Git Service

2010-11-04 Richard Guenther <rguenther@suse.de>
[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
3 ;; Free Software Foundation, Inc.
4 ;;
5 ;; This file is part of GCC.
6 ;;
7 ;; GCC is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 3, or (at your option)
10 ;; any later version.
11 ;;
12 ;; GCC is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 ;; GNU General Public License for more details.
16 ;;
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3.  If not see
19 ;; <http://www.gnu.org/licenses/>.
20
21
22 ;; Instruction suffix for sign and zero extensions.
23 (define_code_attr extsuffix [(sign_extend "sx") (zero_extend "zx")])
24
25 ;; 16 byte integral modes handled by SSE
26 (define_mode_iterator SSEMODEI [V16QI V8HI V4SI V2DI])
27
28 ;; All 16-byte vector modes handled by SSE
29 (define_mode_iterator SSEMODE [V16QI V8HI V4SI V2DI V4SF V2DF])
30 (define_mode_iterator SSEMODE16 [V16QI V8HI V4SI V2DI V1TI V4SF V2DF])
31
32 ;; 32 byte integral vector modes handled by AVX
33 (define_mode_iterator AVX256MODEI [V32QI V16HI V8SI V4DI])
34
35 ;; All 32-byte vector modes handled by AVX
36 (define_mode_iterator AVX256MODE [V32QI V16HI V8SI V4DI V8SF V4DF])
37
38 ;; All QI vector modes handled by AVX
39 (define_mode_iterator AVXMODEQI [V32QI V16QI])
40
41 ;; All DI vector modes handled by AVX
42 (define_mode_iterator AVXMODEDI [V4DI V2DI])
43
44 ;; All vector modes handled by AVX
45 (define_mode_iterator AVXMODE
46   [V16QI V8HI V4SI V2DI V4SF V2DF V32QI V16HI V8SI V4DI V8SF V4DF])
47 (define_mode_iterator AVXMODE16
48   [V16QI V8HI V4SI V2DI V1TI V4SF V2DF V32QI V16HI V8SI V4DI V8SF V4DF])
49
50 ;; Mix-n-match
51 (define_mode_iterator SSEMODE12 [V16QI V8HI])
52 (define_mode_iterator SSEMODE24 [V8HI V4SI])
53 (define_mode_iterator SSEMODE14 [V16QI V4SI])
54 (define_mode_iterator SSEMODE124 [V16QI V8HI V4SI])
55 (define_mode_iterator SSEMODE248 [V8HI V4SI V2DI])
56 (define_mode_iterator SSEMODE1248 [V16QI V8HI V4SI V2DI])
57 (define_mode_iterator SSEMODEF4 [SF DF V4SF V2DF])
58 (define_mode_iterator SSEMODEF2P [V4SF V2DF])
59
60 (define_mode_iterator AVX256MODEF2P [V8SF V4DF])
61 (define_mode_iterator AVX256MODE2P [V8SI V8SF V4DF])
62 (define_mode_iterator AVX256MODE24P [V8SI V8SF V4DI V4DF])
63 (define_mode_iterator AVX256MODE4P [V4DI V4DF])
64 (define_mode_iterator AVX256MODE8P [V8SI V8SF])
65 (define_mode_iterator AVXMODEF2P [V4SF V2DF V8SF V4DF])
66 (define_mode_iterator AVXMODEF4P [V4SF V4DF])
67 (define_mode_iterator AVXMODEFDP [V2DF V4DF])
68 (define_mode_iterator AVXMODEFSP [V4SF V8SF])
69 (define_mode_iterator AVXMODEDCVTDQ2PS [V4SF V8SF])
70 (define_mode_iterator AVXMODEDCVTPS2DQ [V4SI V8SI])
71
72 (define_mode_iterator FMAMODE [SF DF V4SF V2DF V8SF V4DF])
73
74 ;; Int-float size matches
75 (define_mode_iterator SSEMODE4S [V4SF V4SI])
76 (define_mode_iterator SSEMODE2D [V2DF V2DI])
77
78 ;; Modes handled by integer vcond pattern
79 (define_mode_iterator SSEMODE124C8 [V16QI V8HI V4SI
80                                     (V2DI "TARGET_SSE4_2")])
81
82 ;; Modes handled by vec_extract_even/odd pattern.
83 (define_mode_iterator SSEMODE_EO
84   [(V4SF "TARGET_SSE")
85    (V2DF "TARGET_SSE2")
86    (V2DI "TARGET_SSE2") (V4SI "TARGET_SSE2")
87    (V8HI "TARGET_SSE2") (V16QI "TARGET_SSE2")
88    (V4DF "TARGET_AVX") (V8SF "TARGET_AVX")])
89
90 ;; Modes handled by storent patterns.
91 (define_mode_iterator STORENT_MODE
92   [(SF "TARGET_SSE4A") (DF "TARGET_SSE4A")
93    (SI "TARGET_SSE2") (V2DI "TARGET_SSE2") (V2DF "TARGET_SSE2")
94    (V4SF "TARGET_SSE")
95    (V4DF "TARGET_AVX") (V8SF "TARGET_AVX")])
96
97 ;; Modes handled by vector float patterns.
98 (define_mode_iterator VEC_FLOAT_MODE
99   [(V2DF "TARGET_SSE2") (V4SF "TARGET_SSE")
100    (V4DF "TARGET_AVX") (V8SF "TARGET_AVX")])
101
102 ;; Modes handled by vector extract patterns.
103 (define_mode_iterator VEC_EXTRACT_MODE
104   [(V2DI "TARGET_SSE") (V4SI "TARGET_SSE")
105    (V8HI "TARGET_SSE") (V16QI "TARGET_SSE")
106    (V2DF "TARGET_SSE") (V4SF "TARGET_SSE")
107    (V4DF "TARGET_AVX") (V8SF "TARGET_AVX")])
108
109 ;; Mapping from float mode to required SSE level
110 (define_mode_attr sse [(SF "sse") (DF "sse2") (V4SF "sse") (V2DF "sse2")])
111
112 ;; Mapping from integer vector mode to mnemonic suffix
113 (define_mode_attr ssevecsize [(V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")])
114
115 ;; Mapping of the insn mnemonic suffix
116 (define_mode_attr ssemodesuffix
117   [(SF "ss") (DF "sd") (V4SF "ps") (V2DF "pd") (V8SF "ps") (V4DF "pd")
118    (V8SI "ps") (V4DI "pd")])
119 (define_mode_attr ssescalarmodesuffix 
120   [(SF "ss") (DF "sd") (V4SF "ss") (V2DF "sd") (V8SF "ss") (V8SI "ss")
121    (V4DF "sd") (V4SI "d") (V4DI "sd")])
122
123 ;; Mapping of the max integer size for xop rotate immediate constraint
124 (define_mode_attr sserotatemax [(V16QI "7") (V8HI "15") (V4SI "31") (V2DI "63")])
125
126 ;; Mapping of vector modes back to the scalar modes
127 (define_mode_attr ssescalarmode [(V4SF "SF") (V2DF "DF")
128                                  (V16QI "QI") (V8HI "HI")
129                                  (V4SI "SI") (V2DI "DI")])
130
131 ;; Mapping of vector modes to a vector mode of double size
132 (define_mode_attr ssedoublesizemode
133   [(V2DF "V4DF") (V2DI "V4DI") (V4SF "V8SF") (V4SI "V8SI")
134    (V8HI "V16HI") (V16QI "V32QI")
135    (V4DF "V8DF") (V8SF "V16SF")
136    (V4DI "V8DI") (V8SI "V16SI") (V16HI "V32HI") (V32QI "V64QI")])
137
138 ;; Number of scalar elements in each vector type
139 (define_mode_attr ssescalarnum
140   [(V4SF "4") (V2DF "2") (V16QI "16") (V8HI "8") (V4SI "4") (V2DI "2")
141    (V8SF "8") (V4DF "4") (V32QI "32") (V16HI "16") (V8SI "8") (V4DI "4")])
142
143 ;; Mapping for AVX
144 (define_mode_attr avxvecmode
145   [(V16QI "TI") (V8HI "TI") (V4SI "TI") (V2DI "TI") (V1TI "TI")
146    (V4SF "V4SF") (V8SF "V8SF") (V2DF "V2DF") (V4DF "V4DF")
147    (V32QI "OI") (V16HI "OI") (V8SI "OI") (V4DI "OI")])
148 (define_mode_attr avxvecpsmode
149   [(V16QI "V4SF") (V8HI "V4SF") (V4SI "V4SF") (V2DI "V4SF")
150    (V32QI "V8SF") (V16HI "V8SF") (V8SI "V8SF") (V4DI "V8SF")])
151 (define_mode_attr avxhalfvecmode
152   [(V32QI "V16QI") (V16HI "V8HI") (V8SI "V4SI") (V4DI "V2DI")
153    (V8SF "V4SF") (V4DF "V2DF")
154    (V16QI  "V8QI") (V8HI  "V4HI") (V4SI "V2SI") (V4SF "V2SF")])
155 (define_mode_attr avxscalarmode
156   [(V16QI "QI") (V8HI  "HI") (V4SI "SI") (V2DI "DI") (V4SF "SF") (V2DF "DF")
157    (V32QI "QI") (V16HI "HI") (V8SI "SI") (V4DI "DI") (V8SF "SF") (V4DF "DF")])
158 (define_mode_attr avxcvtvecmode
159   [(V4SF "V4SI") (V8SF "V8SI") (V4SI "V4SF") (V8SI "V8SF")])
160 (define_mode_attr avxpermvecmode
161   [(V2DF "V2DI") (V4SF "V4SI") (V4DF "V4DI") (V8SF "V8SI")])
162 (define_mode_attr avxmodesuffixp
163  [(V2DF "pd") (V4SI "si") (V4SF "ps") (V8SF "ps") (V8SI "si")
164   (V4DF "pd")])
165 (define_mode_attr avxmodesuffix
166   [(V16QI "") (V32QI "256") (V4SI "") (V4SF "") (V2DF "")
167    (V8SI "256") (V8SF "256") (V4DF "256")])
168
169 ;; Mapping of immediate bits for blend instructions
170 (define_mode_attr blendbits
171   [(V8SF "255") (V4SF "15") (V4DF "15") (V2DF "3")])
172
173 ;; Mapping of immediate bits for pinsr instructions
174 (define_mode_attr pinsrbits [(V16QI "32768") (V8HI "128") (V4SI "8")])
175
176 ;; Patterns whose name begins with "sse{,2,3}_" are invoked by intrinsics.
177
178 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
179 ;;
180 ;; Move patterns
181 ;;
182 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
183
184 (define_expand "mov<mode>"
185   [(set (match_operand:AVX256MODE 0 "nonimmediate_operand" "")
186         (match_operand:AVX256MODE 1 "nonimmediate_operand" ""))]
187   "TARGET_AVX"
188 {
189   ix86_expand_vector_move (<MODE>mode, operands);
190   DONE;
191 })
192
193 (define_insn "*avx_mov<mode>_internal"
194   [(set (match_operand:AVXMODE16 0 "nonimmediate_operand" "=x,x ,m")
195         (match_operand:AVXMODE16 1 "nonimmediate_or_sse_const_operand"  "C ,xm,x"))]
196   "TARGET_AVX
197    && (register_operand (operands[0], <MODE>mode)
198        || register_operand (operands[1], <MODE>mode))"
199 {
200   switch (which_alternative)
201     {
202     case 0:
203       return standard_sse_constant_opcode (insn, operands[1]);
204     case 1:
205     case 2:
206       switch (get_attr_mode (insn))
207         {
208         case MODE_V8SF:
209         case MODE_V4SF:
210           return "vmovaps\t{%1, %0|%0, %1}";
211         case MODE_V4DF:
212         case MODE_V2DF:
213           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
214             return "vmovaps\t{%1, %0|%0, %1}";
215           else
216             return "vmovapd\t{%1, %0|%0, %1}";
217         default:
218           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
219             return "vmovaps\t{%1, %0|%0, %1}";
220           else
221             return "vmovdqa\t{%1, %0|%0, %1}";
222         }
223     default:
224       gcc_unreachable ();
225     }
226 }
227   [(set_attr "type" "sselog1,ssemov,ssemov")
228    (set_attr "prefix" "vex")
229    (set_attr "mode" "<avxvecmode>")])
230
231 ;; All of these patterns are enabled for SSE1 as well as SSE2.
232 ;; This is essential for maintaining stable calling conventions.
233
234 (define_expand "mov<mode>"
235   [(set (match_operand:SSEMODE16 0 "nonimmediate_operand" "")
236         (match_operand:SSEMODE16 1 "nonimmediate_operand" ""))]
237   "TARGET_SSE"
238 {
239   ix86_expand_vector_move (<MODE>mode, operands);
240   DONE;
241 })
242
243 (define_insn "*mov<mode>_internal"
244   [(set (match_operand:SSEMODE16 0 "nonimmediate_operand" "=x,x ,m")
245         (match_operand:SSEMODE16 1 "nonimmediate_or_sse_const_operand"  "C ,xm,x"))]
246   "TARGET_SSE
247    && (register_operand (operands[0], <MODE>mode)
248        || register_operand (operands[1], <MODE>mode))"
249 {
250   switch (which_alternative)
251     {
252     case 0:
253       return standard_sse_constant_opcode (insn, operands[1]);
254     case 1:
255     case 2:
256       switch (get_attr_mode (insn))
257         {
258         case MODE_V4SF:
259           return "movaps\t{%1, %0|%0, %1}";
260         case MODE_V2DF:
261           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
262             return "movaps\t{%1, %0|%0, %1}";
263           else
264             return "movapd\t{%1, %0|%0, %1}";
265         default:
266           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
267             return "movaps\t{%1, %0|%0, %1}";
268           else
269             return "movdqa\t{%1, %0|%0, %1}";
270         }
271     default:
272       gcc_unreachable ();
273     }
274 }
275   [(set_attr "type" "sselog1,ssemov,ssemov")
276    (set (attr "mode")
277         (cond [(ior (ior (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
278                          (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
279                     (and (eq_attr "alternative" "2")
280                          (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
281                              (const_int 0))))
282                  (const_string "V4SF")
283                (eq (const_string "<MODE>mode") (const_string "V4SFmode"))
284                  (const_string "V4SF")
285                (eq (const_string "<MODE>mode") (const_string "V2DFmode"))
286                  (const_string "V2DF")
287               ]
288           (const_string "TI")))])
289
290 ;; Move a DI from a 32-bit register pair (e.g. %edx:%eax) to an xmm.
291 ;; We'd rather avoid this entirely; if the 32-bit reg pair was loaded
292 ;; from memory, we'd prefer to load the memory directly into the %xmm
293 ;; register.  To facilitate this happy circumstance, this pattern won't
294 ;; split until after register allocation.  If the 64-bit value didn't
295 ;; come from memory, this is the best we can do.  This is much better
296 ;; than storing %edx:%eax into a stack temporary and loading an %xmm
297 ;; from there.
298
299 (define_insn_and_split "movdi_to_sse"
300   [(parallel
301     [(set (match_operand:V4SI 0 "register_operand" "=?x,x")
302           (subreg:V4SI (match_operand:DI 1 "nonimmediate_operand" "r,m") 0))
303      (clobber (match_scratch:V4SI 2 "=&x,X"))])]
304   "!TARGET_64BIT && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES"
305   "#"
306   "&& reload_completed"
307   [(const_int 0)]
308 {
309  if (register_operand (operands[1], DImode))
310    {
311       /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
312          Assemble the 64-bit DImode value in an xmm register.  */
313       emit_insn (gen_sse2_loadld (operands[0], CONST0_RTX (V4SImode),
314                                   gen_rtx_SUBREG (SImode, operands[1], 0)));
315       emit_insn (gen_sse2_loadld (operands[2], CONST0_RTX (V4SImode),
316                                   gen_rtx_SUBREG (SImode, operands[1], 4)));
317       emit_insn (gen_vec_interleave_lowv4si (operands[0], operands[0],
318                                              operands[2]));
319     }
320  else if (memory_operand (operands[1], DImode))
321    emit_insn (gen_vec_concatv2di (gen_lowpart (V2DImode, operands[0]),
322                                   operands[1], const0_rtx));
323  else
324    gcc_unreachable ();
325 })
326
327 (define_split
328   [(set (match_operand:V4SF 0 "register_operand" "")
329         (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
330   "TARGET_SSE && reload_completed"
331   [(set (match_dup 0)
332         (vec_merge:V4SF
333           (vec_duplicate:V4SF (match_dup 1))
334           (match_dup 2)
335           (const_int 1)))]
336 {
337   operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
338   operands[2] = CONST0_RTX (V4SFmode);
339 })
340
341 (define_split
342   [(set (match_operand:V2DF 0 "register_operand" "")
343         (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
344   "TARGET_SSE2 && reload_completed"
345   [(set (match_dup 0) (vec_concat:V2DF (match_dup 1) (match_dup 2)))]
346 {
347   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
348   operands[2] = CONST0_RTX (DFmode);
349 })
350
351 (define_expand "push<mode>1"
352   [(match_operand:AVX256MODE 0 "register_operand" "")]
353   "TARGET_AVX"
354 {
355   ix86_expand_push (<MODE>mode, operands[0]);
356   DONE;
357 })
358
359 (define_expand "push<mode>1"
360   [(match_operand:SSEMODE16 0 "register_operand" "")]
361   "TARGET_SSE"
362 {
363   ix86_expand_push (<MODE>mode, operands[0]);
364   DONE;
365 })
366
367 (define_expand "movmisalign<mode>"
368   [(set (match_operand:AVX256MODE 0 "nonimmediate_operand" "")
369         (match_operand:AVX256MODE 1 "nonimmediate_operand" ""))]
370   "TARGET_AVX"
371 {
372   ix86_expand_vector_move_misalign (<MODE>mode, operands);
373   DONE;
374 })
375
376 (define_expand "movmisalign<mode>"
377   [(set (match_operand:SSEMODE16 0 "nonimmediate_operand" "")
378         (match_operand:SSEMODE16 1 "nonimmediate_operand" ""))]
379   "TARGET_SSE"
380 {
381   ix86_expand_vector_move_misalign (<MODE>mode, operands);
382   DONE;
383 })
384
385 (define_expand "avx_movu<ssemodesuffix><avxmodesuffix>"
386   [(set (match_operand:AVXMODEF2P 0 "nonimmediate_operand" "")
387         (unspec:AVXMODEF2P
388           [(match_operand:AVXMODEF2P 1 "nonimmediate_operand" "")]
389           UNSPEC_MOVU))]
390   "AVX_VEC_FLOAT_MODE_P (<MODE>mode)"
391 {
392   if (MEM_P (operands[0]) && MEM_P (operands[1]))
393     operands[1] = force_reg (<MODE>mode, operands[1]);
394 })
395
396 (define_insn "*avx_movu<ssemodesuffix><avxmodesuffix>"
397   [(set (match_operand:AVXMODEF2P 0 "nonimmediate_operand" "=x,m")
398         (unspec:AVXMODEF2P
399           [(match_operand:AVXMODEF2P 1 "nonimmediate_operand" "xm,x")]
400           UNSPEC_MOVU))]
401   "AVX_VEC_FLOAT_MODE_P (<MODE>mode)
402    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
403   "vmovu<ssemodesuffix>\t{%1, %0|%0, %1}"
404   [(set_attr "type" "ssemov")
405    (set_attr "movu" "1")
406    (set_attr "prefix" "vex")
407    (set_attr "mode" "<MODE>")])
408
409 (define_insn "sse2_movq128"
410   [(set (match_operand:V2DI 0 "register_operand" "=x")
411         (vec_concat:V2DI
412           (vec_select:DI
413             (match_operand:V2DI 1 "nonimmediate_operand" "xm")
414             (parallel [(const_int 0)]))
415           (const_int 0)))]
416   "TARGET_SSE2"
417   "%vmovq\t{%1, %0|%0, %1}"
418   [(set_attr "type" "ssemov")
419    (set_attr "prefix" "maybe_vex")
420    (set_attr "mode" "TI")])
421
422 (define_expand "<sse>_movu<ssemodesuffix>"
423   [(set (match_operand:SSEMODEF2P 0 "nonimmediate_operand" "")
424         (unspec:SSEMODEF2P
425           [(match_operand:SSEMODEF2P 1 "nonimmediate_operand" "")]
426           UNSPEC_MOVU))]
427   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
428 {
429   if (MEM_P (operands[0]) && MEM_P (operands[1]))
430     operands[1] = force_reg (<MODE>mode, operands[1]);
431 })
432
433 (define_insn "*<sse>_movu<ssemodesuffix>"
434   [(set (match_operand:SSEMODEF2P 0 "nonimmediate_operand" "=x,m")
435         (unspec:SSEMODEF2P
436           [(match_operand:SSEMODEF2P 1 "nonimmediate_operand" "xm,x")]
437           UNSPEC_MOVU))]
438   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)
439    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
440   "movu<ssemodesuffix>\t{%1, %0|%0, %1}"
441   [(set_attr "type" "ssemov")
442    (set_attr "movu" "1")
443    (set_attr "mode" "<MODE>")])
444
445 (define_expand "avx_movdqu<avxmodesuffix>"
446   [(set (match_operand:AVXMODEQI 0 "nonimmediate_operand" "")
447         (unspec:AVXMODEQI
448           [(match_operand:AVXMODEQI 1 "nonimmediate_operand" "")]
449           UNSPEC_MOVU))]
450   "TARGET_AVX"
451 {
452   if (MEM_P (operands[0]) && MEM_P (operands[1]))
453     operands[1] = force_reg (<MODE>mode, operands[1]);
454 })
455
456 (define_insn "*avx_movdqu<avxmodesuffix>"
457   [(set (match_operand:AVXMODEQI 0 "nonimmediate_operand" "=x,m")
458         (unspec:AVXMODEQI
459           [(match_operand:AVXMODEQI 1 "nonimmediate_operand" "xm,x")]
460           UNSPEC_MOVU))]
461   "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
462   "vmovdqu\t{%1, %0|%0, %1}"
463   [(set_attr "type" "ssemov")
464    (set_attr "movu" "1")
465    (set_attr "prefix" "vex")
466    (set_attr "mode" "<avxvecmode>")])
467
468 (define_expand "sse2_movdqu"
469   [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
470         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "")]
471                       UNSPEC_MOVU))]
472   "TARGET_SSE2"
473 {
474   if (MEM_P (operands[0]) && MEM_P (operands[1]))
475     operands[1] = force_reg (V16QImode, operands[1]);
476 })
477
478 (define_insn "*sse2_movdqu"
479   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
480         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
481                       UNSPEC_MOVU))]
482   "TARGET_SSE2 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
483   "movdqu\t{%1, %0|%0, %1}"
484   [(set_attr "type" "ssemov")
485    (set_attr "movu" "1")
486    (set_attr "prefix_data16" "1")
487    (set_attr "mode" "TI")])
488
489 (define_insn "avx_movnt<mode>"
490   [(set (match_operand:AVXMODEF2P 0 "memory_operand" "=m")
491         (unspec:AVXMODEF2P
492           [(match_operand:AVXMODEF2P 1 "register_operand" "x")]
493           UNSPEC_MOVNT))]
494   "AVX_VEC_FLOAT_MODE_P (<MODE>mode)"
495   "vmovnt<ssemodesuffix>\t{%1, %0|%0, %1}"
496   [(set_attr "type" "ssemov")
497    (set_attr "prefix" "vex")
498    (set_attr "mode" "<MODE>")])
499
500 (define_insn "<sse>_movnt<mode>"
501   [(set (match_operand:SSEMODEF2P 0 "memory_operand" "=m")
502         (unspec:SSEMODEF2P
503           [(match_operand:SSEMODEF2P 1 "register_operand" "x")]
504           UNSPEC_MOVNT))]
505   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
506   "movnt<ssemodesuffix>\t{%1, %0|%0, %1}"
507   [(set_attr "type" "ssemov")
508    (set_attr "mode" "<MODE>")])
509
510 (define_insn "avx_movnt<mode>"
511   [(set (match_operand:AVXMODEDI 0 "memory_operand" "=m")
512         (unspec:AVXMODEDI
513           [(match_operand:AVXMODEDI 1 "register_operand" "x")]
514           UNSPEC_MOVNT))]
515   "TARGET_AVX"
516   "vmovntdq\t{%1, %0|%0, %1}"
517   [(set_attr "type" "ssecvt")
518    (set_attr "prefix" "vex")
519    (set_attr "mode" "<avxvecmode>")])
520
521 (define_insn "sse2_movntv2di"
522   [(set (match_operand:V2DI 0 "memory_operand" "=m")
523         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
524                      UNSPEC_MOVNT))]
525   "TARGET_SSE2"
526   "movntdq\t{%1, %0|%0, %1}"
527   [(set_attr "type" "ssemov")
528    (set_attr "prefix_data16" "1")
529    (set_attr "mode" "TI")])
530
531 (define_insn "sse2_movntsi"
532   [(set (match_operand:SI 0 "memory_operand" "=m")
533         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
534                    UNSPEC_MOVNT))]
535   "TARGET_SSE2"
536   "movnti\t{%1, %0|%0, %1}"
537   [(set_attr "type" "ssemov")
538    (set_attr "prefix_data16" "0")
539    (set_attr "mode" "V2DF")])
540
541 (define_insn "avx_lddqu<avxmodesuffix>"
542   [(set (match_operand:AVXMODEQI 0 "register_operand" "=x")
543         (unspec:AVXMODEQI
544           [(match_operand:AVXMODEQI 1 "memory_operand" "m")]
545           UNSPEC_LDDQU))]
546   "TARGET_AVX"
547   "vlddqu\t{%1, %0|%0, %1}"
548   [(set_attr "type" "ssecvt")
549    (set_attr "movu" "1")
550    (set_attr "prefix" "vex")
551    (set_attr "mode" "<avxvecmode>")])
552
553 (define_insn "sse3_lddqu"
554   [(set (match_operand:V16QI 0 "register_operand" "=x")
555         (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
556                       UNSPEC_LDDQU))]
557   "TARGET_SSE3"
558   "lddqu\t{%1, %0|%0, %1}"
559   [(set_attr "type" "ssemov")
560    (set_attr "movu" "1")
561    (set_attr "prefix_data16" "0")
562    (set_attr "prefix_rep" "1")
563    (set_attr "mode" "TI")])
564
565 ; Expand patterns for non-temporal stores.  At the moment, only those
566 ; that directly map to insns are defined; it would be possible to
567 ; define patterns for other modes that would expand to several insns.
568
569 (define_expand "storent<mode>"
570   [(set (match_operand:STORENT_MODE 0 "memory_operand" "")
571         (unspec:STORENT_MODE
572           [(match_operand:STORENT_MODE 1 "register_operand" "")]
573           UNSPEC_MOVNT))])
574
575 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
576 ;;
577 ;; Parallel floating point arithmetic
578 ;;
579 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
580
581 (define_expand "<code><mode>2"
582   [(set (match_operand:VEC_FLOAT_MODE 0 "register_operand" "")
583         (absneg:VEC_FLOAT_MODE
584           (match_operand:VEC_FLOAT_MODE 1 "register_operand" "")))]
585   ""
586   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
587
588 (define_insn_and_split "*avx_absneg<mode>2"
589   [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x,x")
590         (match_operator:AVXMODEF2P 3 "absneg_operator"
591           [(match_operand:AVXMODEF2P 1 "nonimmediate_operand" "x,m")]))
592    (use (match_operand:AVXMODEF2P 2 "nonimmediate_operand" "xm,x"))]
593   "AVX_VEC_FLOAT_MODE_P (<MODE>mode)"
594   "#"
595   "&& reload_completed"
596   [(const_int 0)]
597 {
598   rtx t;
599
600   if (MEM_P (operands[1]))
601     t = gen_rtx_fmt_ee (GET_CODE (operands[3]) == NEG ? XOR : AND,
602                         <MODE>mode, operands[2], operands[1]);
603   else
604     t = gen_rtx_fmt_ee (GET_CODE (operands[3]) == NEG ? XOR : AND,
605                         <MODE>mode, operands[1], operands[2]);
606   t = gen_rtx_SET (VOIDmode, operands[0], t);
607   emit_insn (t);
608   DONE;
609 })
610
611 (define_insn_and_split "*sse_absneg<mode>2"
612   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x")
613         (match_operator:SSEMODEF2P 3 "absneg_operator"
614           [(match_operand:SSEMODEF2P 1 "nonimmediate_operand" "0,xm")]))
615    (use (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm,0"))]
616   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
617   "#"
618   "&& reload_completed"
619   [(const_int 0)]
620 {
621   rtx t;
622
623   t = operands[rtx_equal_p (operands[0], operands[1]) ? 2 : 1];
624   t = gen_rtx_fmt_ee (GET_CODE (operands[3]) == NEG ? XOR : AND,
625                       <MODE>mode, operands[0], t);
626   t = gen_rtx_SET (VOIDmode, operands[0], t);
627   emit_insn (t);
628   DONE;
629 })
630
631 (define_expand "<plusminus_insn><mode>3"
632   [(set (match_operand:AVX256MODEF2P 0 "register_operand" "")
633         (plusminus:AVX256MODEF2P
634           (match_operand:AVX256MODEF2P 1 "nonimmediate_operand" "")
635           (match_operand:AVX256MODEF2P 2 "nonimmediate_operand" "")))]
636   "AVX256_VEC_FLOAT_MODE_P (<MODE>mode)"
637   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
638
639 (define_insn "*avx_<plusminus_insn><mode>3"
640   [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x")
641         (plusminus:AVXMODEF2P
642           (match_operand:AVXMODEF2P 1 "nonimmediate_operand" "<comm>x")
643           (match_operand:AVXMODEF2P 2 "nonimmediate_operand" "xm")))]
644   "AVX_VEC_FLOAT_MODE_P (<MODE>mode)
645    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
646   "v<plusminus_mnemonic><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
647   [(set_attr "type" "sseadd")
648    (set_attr "prefix" "vex")
649    (set_attr "mode" "<avxvecmode>")])
650
651 (define_expand "<plusminus_insn><mode>3"
652   [(set (match_operand:SSEMODEF2P 0 "register_operand" "")
653         (plusminus:SSEMODEF2P
654           (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "")
655           (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "")))]
656   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
657   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
658
659 (define_insn "*<plusminus_insn><mode>3"
660   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
661         (plusminus:SSEMODEF2P
662           (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "<comm>0")
663           (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")))]
664   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)
665    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
666   "<plusminus_mnemonic><ssemodesuffix>\t{%2, %0|%0, %2}"
667   [(set_attr "type" "sseadd")
668    (set_attr "mode" "<MODE>")])
669
670 (define_insn "*avx_vm<plusminus_insn><mode>3"
671   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
672         (vec_merge:SSEMODEF2P
673           (plusminus:SSEMODEF2P
674             (match_operand:SSEMODEF2P 1 "register_operand" "x")
675             (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm"))
676           (match_dup 1)
677           (const_int 1)))]
678   "AVX128_VEC_FLOAT_MODE_P (<MODE>mode)"
679   "v<plusminus_mnemonic><ssescalarmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
680   [(set_attr "type" "sseadd")
681    (set_attr "prefix" "vex")
682    (set_attr "mode" "<ssescalarmode>")])
683
684 (define_insn "<sse>_vm<plusminus_insn><mode>3"
685   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
686         (vec_merge:SSEMODEF2P
687           (plusminus:SSEMODEF2P
688             (match_operand:SSEMODEF2P 1 "register_operand" "0")
689             (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm"))
690           (match_dup 1)
691           (const_int 1)))]
692   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
693   "<plusminus_mnemonic><ssescalarmodesuffix>\t{%2, %0|%0, %2}"
694   [(set_attr "type" "sseadd")
695    (set_attr "mode" "<ssescalarmode>")])
696
697 (define_expand "mul<mode>3"
698   [(set (match_operand:AVX256MODEF2P 0 "register_operand" "")
699         (mult:AVX256MODEF2P
700           (match_operand:AVX256MODEF2P 1 "nonimmediate_operand" "")
701           (match_operand:AVX256MODEF2P 2 "nonimmediate_operand" "")))]
702   "AVX256_VEC_FLOAT_MODE_P (<MODE>mode)"
703   "ix86_fixup_binary_operands_no_copy (MULT, <MODE>mode, operands);")
704
705 (define_insn "*avx_mul<mode>3"
706   [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x")
707         (mult:AVXMODEF2P
708           (match_operand:AVXMODEF2P 1 "nonimmediate_operand" "%x")
709           (match_operand:AVXMODEF2P 2 "nonimmediate_operand" "xm")))]
710   "AVX_VEC_FLOAT_MODE_P (<MODE>mode)
711    && ix86_binary_operator_ok (MULT, <MODE>mode, operands)"
712   "vmul<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
713   [(set_attr "type" "ssemul")
714    (set_attr "prefix" "vex")
715    (set_attr "mode" "<avxvecmode>")])
716
717 (define_expand "mul<mode>3"
718   [(set (match_operand:SSEMODEF2P 0 "register_operand" "")
719         (mult:SSEMODEF2P
720           (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "")
721           (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "")))]
722   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
723   "ix86_fixup_binary_operands_no_copy (MULT, <MODE>mode, operands);")
724
725 (define_insn "*mul<mode>3"
726   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
727         (mult:SSEMODEF2P
728           (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "%0")
729           (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")))]
730   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)
731    && ix86_binary_operator_ok (MULT, <MODE>mode, operands)"
732   "mul<ssemodesuffix>\t{%2, %0|%0, %2}"
733   [(set_attr "type" "ssemul")
734    (set_attr "mode" "<MODE>")])
735
736 (define_insn "*avx_vmmul<mode>3"
737   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
738         (vec_merge:SSEMODEF2P
739           (mult:SSEMODEF2P
740             (match_operand:SSEMODEF2P 1 "register_operand" "x")
741             (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm"))
742           (match_dup 1)
743           (const_int 1)))]
744   "AVX_VEC_FLOAT_MODE_P (<MODE>mode)"
745   "vmul<ssescalarmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
746   [(set_attr "type" "ssemul")
747    (set_attr "prefix" "vex")
748    (set_attr "mode" "<ssescalarmode>")])
749
750 (define_insn "<sse>_vmmul<mode>3"
751   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
752         (vec_merge:SSEMODEF2P
753           (mult:SSEMODEF2P
754             (match_operand:SSEMODEF2P 1 "register_operand" "0")
755             (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm"))
756           (match_dup 1)
757           (const_int 1)))]
758   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
759   "mul<ssescalarmodesuffix>\t{%2, %0|%0, %2}"
760   [(set_attr "type" "ssemul")
761    (set_attr "mode" "<ssescalarmode>")])
762
763 (define_expand "divv8sf3"
764   [(set (match_operand:V8SF 0 "register_operand" "")
765         (div:V8SF (match_operand:V8SF 1 "register_operand" "")
766                   (match_operand:V8SF 2 "nonimmediate_operand" "")))]
767   "TARGET_AVX"
768 {
769   ix86_fixup_binary_operands_no_copy (DIV, V8SFmode, operands);
770
771   if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_insn_for_size_p ()
772       && flag_finite_math_only && !flag_trapping_math
773       && flag_unsafe_math_optimizations)
774     {
775       ix86_emit_swdivsf (operands[0], operands[1],
776                          operands[2], V8SFmode);
777       DONE;
778     }
779 })
780
781 (define_expand "divv4df3"
782   [(set (match_operand:V4DF 0 "register_operand" "")
783         (div:V4DF (match_operand:V4DF 1 "register_operand" "")
784                   (match_operand:V4DF 2 "nonimmediate_operand" "")))]
785   "TARGET_AVX"
786   "ix86_fixup_binary_operands_no_copy (DIV, V4DFmode, operands);")
787
788 (define_insn "avx_div<mode>3"
789   [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x")
790         (div:AVXMODEF2P
791           (match_operand:AVXMODEF2P 1 "register_operand" "x")
792           (match_operand:AVXMODEF2P 2 "nonimmediate_operand" "xm")))]
793   "AVX_VEC_FLOAT_MODE_P (<MODE>mode)"
794   "vdiv<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
795   [(set_attr "type" "ssediv")
796    (set_attr "prefix" "vex")
797    (set_attr "mode" "<MODE>")])
798
799 (define_expand "divv4sf3"
800   [(set (match_operand:V4SF 0 "register_operand" "")
801         (div:V4SF (match_operand:V4SF 1 "register_operand" "")
802                   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
803   "TARGET_SSE"
804 {
805   if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
806       && flag_finite_math_only && !flag_trapping_math
807       && flag_unsafe_math_optimizations)
808     {
809       ix86_emit_swdivsf (operands[0], operands[1],
810                          operands[2], V4SFmode);
811       DONE;
812     }
813 })
814
815 (define_expand "divv2df3"
816   [(set (match_operand:V2DF 0 "register_operand" "")
817         (div:V2DF (match_operand:V2DF 1 "register_operand" "")
818                   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
819   "TARGET_SSE2")
820
821 (define_insn "*avx_div<mode>3"
822   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
823         (div:SSEMODEF2P
824           (match_operand:SSEMODEF2P 1 "register_operand" "x")
825           (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")))]
826   "AVX128_VEC_FLOAT_MODE_P (<MODE>mode)"
827   "vdiv<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
828   [(set_attr "type" "ssediv")
829    (set_attr "prefix" "vex")
830    (set_attr "mode" "<MODE>")])
831
832 (define_insn "<sse>_div<mode>3"
833   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
834         (div:SSEMODEF2P
835           (match_operand:SSEMODEF2P 1 "register_operand" "0")
836           (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")))]
837   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
838   "div<ssemodesuffix>\t{%2, %0|%0, %2}"
839   [(set_attr "type" "ssediv")
840    (set_attr "mode" "<MODE>")])
841
842 (define_insn "*avx_vmdiv<mode>3"
843   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
844         (vec_merge:SSEMODEF2P
845           (div:SSEMODEF2P
846             (match_operand:SSEMODEF2P 1 "register_operand" "x")
847             (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm"))
848           (match_dup 1)
849           (const_int 1)))]
850   "AVX128_VEC_FLOAT_MODE_P (<MODE>mode)"
851   "vdiv<ssescalarmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
852   [(set_attr "type" "ssediv")
853    (set_attr "prefix" "vex")
854    (set_attr "mode" "<ssescalarmode>")])
855
856 (define_insn "<sse>_vmdiv<mode>3"
857   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
858         (vec_merge:SSEMODEF2P
859           (div:SSEMODEF2P
860             (match_operand:SSEMODEF2P 1 "register_operand" "0")
861             (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm"))
862           (match_dup 1)
863           (const_int 1)))]
864   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
865   "div<ssescalarmodesuffix>\t{%2, %0|%0, %2}"
866   [(set_attr "type" "ssediv")
867    (set_attr "mode" "<ssescalarmode>")])
868
869 (define_insn "avx_rcpv8sf2"
870   [(set (match_operand:V8SF 0 "register_operand" "=x")
871         (unspec:V8SF
872           [(match_operand:V8SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
873   "TARGET_AVX"
874   "vrcpps\t{%1, %0|%0, %1}"
875   [(set_attr "type" "sse")
876    (set_attr "prefix" "vex")
877    (set_attr "mode" "V8SF")])
878
879 (define_insn "sse_rcpv4sf2"
880   [(set (match_operand:V4SF 0 "register_operand" "=x")
881         (unspec:V4SF
882           [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
883   "TARGET_SSE"
884   "%vrcpps\t{%1, %0|%0, %1}"
885   [(set_attr "type" "sse")
886    (set_attr "atom_sse_attr" "rcp")
887    (set_attr "prefix" "maybe_vex")
888    (set_attr "mode" "V4SF")])
889
890 (define_insn "*avx_vmrcpv4sf2"
891   [(set (match_operand:V4SF 0 "register_operand" "=x")
892         (vec_merge:V4SF
893           (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
894                        UNSPEC_RCP)
895           (match_operand:V4SF 2 "register_operand" "x")
896           (const_int 1)))]
897   "TARGET_AVX"
898   "vrcpss\t{%1, %2, %0|%0, %2, %1}"
899   [(set_attr "type" "sse")
900    (set_attr "prefix" "vex")
901    (set_attr "mode" "SF")])
902
903 (define_insn "sse_vmrcpv4sf2"
904   [(set (match_operand:V4SF 0 "register_operand" "=x")
905         (vec_merge:V4SF
906           (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
907                        UNSPEC_RCP)
908           (match_operand:V4SF 2 "register_operand" "0")
909           (const_int 1)))]
910   "TARGET_SSE"
911   "rcpss\t{%1, %0|%0, %1}"
912   [(set_attr "type" "sse")
913    (set_attr "atom_sse_attr" "rcp")
914    (set_attr "mode" "SF")])
915
916 (define_expand "sqrtv8sf2"
917   [(set (match_operand:V8SF 0 "register_operand" "")
918         (sqrt:V8SF (match_operand:V8SF 1 "nonimmediate_operand" "")))]
919   "TARGET_AVX"
920 {
921   if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_insn_for_size_p ()
922       && flag_finite_math_only && !flag_trapping_math
923       && flag_unsafe_math_optimizations)
924     {
925       ix86_emit_swsqrtsf (operands[0], operands[1], V8SFmode, 0);
926       DONE;
927     }
928 })
929
930 (define_insn "avx_sqrtv8sf2"
931   [(set (match_operand:V8SF 0 "register_operand" "=x")
932         (sqrt:V8SF (match_operand:V8SF 1 "nonimmediate_operand" "xm")))]
933   "TARGET_AVX"
934   "vsqrtps\t{%1, %0|%0, %1}"
935   [(set_attr "type" "sse")
936    (set_attr "prefix" "vex")
937    (set_attr "mode" "V8SF")])
938
939 (define_expand "sqrtv4sf2"
940   [(set (match_operand:V4SF 0 "register_operand" "")
941         (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "")))]
942   "TARGET_SSE"
943 {
944   if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
945       && flag_finite_math_only && !flag_trapping_math
946       && flag_unsafe_math_optimizations)
947     {
948       ix86_emit_swsqrtsf (operands[0], operands[1], V4SFmode, 0);
949       DONE;
950     }
951 })
952
953 (define_insn "sse_sqrtv4sf2"
954   [(set (match_operand:V4SF 0 "register_operand" "=x")
955         (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
956   "TARGET_SSE"
957   "%vsqrtps\t{%1, %0|%0, %1}"
958   [(set_attr "type" "sse")
959    (set_attr "atom_sse_attr" "sqrt")
960    (set_attr "prefix" "maybe_vex")
961    (set_attr "mode" "V4SF")])
962
963 (define_insn "sqrtv4df2"
964   [(set (match_operand:V4DF 0 "register_operand" "=x")
965         (sqrt:V4DF (match_operand:V4DF 1 "nonimmediate_operand" "xm")))]
966   "TARGET_AVX"
967   "vsqrtpd\t{%1, %0|%0, %1}"
968   [(set_attr "type" "sse")
969    (set_attr "prefix" "vex")
970    (set_attr "mode" "V4DF")])
971
972 (define_insn "sqrtv2df2"
973   [(set (match_operand:V2DF 0 "register_operand" "=x")
974         (sqrt:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
975   "TARGET_SSE2"
976   "%vsqrtpd\t{%1, %0|%0, %1}"
977   [(set_attr "type" "sse")
978    (set_attr "prefix" "maybe_vex")
979    (set_attr "mode" "V2DF")])
980
981 (define_insn "*avx_vmsqrt<mode>2"
982   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
983         (vec_merge:SSEMODEF2P
984           (sqrt:SSEMODEF2P
985             (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "xm"))
986           (match_operand:SSEMODEF2P 2 "register_operand" "x")
987           (const_int 1)))]
988   "AVX_VEC_FLOAT_MODE_P (<MODE>mode)"
989   "vsqrt<ssescalarmodesuffix>\t{%1, %2, %0|%0, %2, %1}"
990   [(set_attr "type" "sse")
991    (set_attr "prefix" "vex")
992    (set_attr "mode" "<ssescalarmode>")])
993
994 (define_insn "<sse>_vmsqrt<mode>2"
995   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
996         (vec_merge:SSEMODEF2P
997           (sqrt:SSEMODEF2P
998             (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "xm"))
999           (match_operand:SSEMODEF2P 2 "register_operand" "0")
1000           (const_int 1)))]
1001   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
1002   "sqrt<ssescalarmodesuffix>\t{%1, %0|%0, %1}"
1003   [(set_attr "type" "sse")
1004    (set_attr "atom_sse_attr" "sqrt")
1005    (set_attr "mode" "<ssescalarmode>")])
1006
1007 (define_expand "rsqrtv8sf2"
1008   [(set (match_operand:V8SF 0 "register_operand" "")
1009         (unspec:V8SF
1010           [(match_operand:V8SF 1 "nonimmediate_operand" "")] UNSPEC_RSQRT))]
1011   "TARGET_AVX && TARGET_SSE_MATH"
1012 {
1013   ix86_emit_swsqrtsf (operands[0], operands[1], V8SFmode, 1);
1014   DONE;
1015 })
1016
1017 (define_insn "avx_rsqrtv8sf2"
1018   [(set (match_operand:V8SF 0 "register_operand" "=x")
1019         (unspec:V8SF
1020           [(match_operand:V8SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
1021   "TARGET_AVX"
1022   "vrsqrtps\t{%1, %0|%0, %1}"
1023   [(set_attr "type" "sse")
1024    (set_attr "prefix" "vex")
1025    (set_attr "mode" "V8SF")])
1026
1027 (define_expand "rsqrtv4sf2"
1028   [(set (match_operand:V4SF 0 "register_operand" "")
1029         (unspec:V4SF
1030           [(match_operand:V4SF 1 "nonimmediate_operand" "")] UNSPEC_RSQRT))]
1031   "TARGET_SSE_MATH"
1032 {
1033   ix86_emit_swsqrtsf (operands[0], operands[1], V4SFmode, 1);
1034   DONE;
1035 })
1036
1037 (define_insn "sse_rsqrtv4sf2"
1038   [(set (match_operand:V4SF 0 "register_operand" "=x")
1039         (unspec:V4SF
1040           [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
1041   "TARGET_SSE"
1042   "%vrsqrtps\t{%1, %0|%0, %1}"
1043   [(set_attr "type" "sse")
1044    (set_attr "prefix" "maybe_vex")
1045    (set_attr "mode" "V4SF")])
1046
1047 (define_insn "*avx_vmrsqrtv4sf2"
1048   [(set (match_operand:V4SF 0 "register_operand" "=x")
1049         (vec_merge:V4SF
1050           (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
1051                        UNSPEC_RSQRT)
1052           (match_operand:V4SF 2 "register_operand" "x")
1053           (const_int 1)))]
1054   "TARGET_AVX"
1055   "vrsqrtss\t{%1, %2, %0|%0, %2, %1}"
1056   [(set_attr "type" "sse")
1057    (set_attr "prefix" "vex")
1058    (set_attr "mode" "SF")])
1059
1060 (define_insn "sse_vmrsqrtv4sf2"
1061   [(set (match_operand:V4SF 0 "register_operand" "=x")
1062         (vec_merge:V4SF
1063           (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
1064                        UNSPEC_RSQRT)
1065           (match_operand:V4SF 2 "register_operand" "0")
1066           (const_int 1)))]
1067   "TARGET_SSE"
1068   "rsqrtss\t{%1, %0|%0, %1}"
1069   [(set_attr "type" "sse")
1070    (set_attr "mode" "SF")])
1071
1072 ;; ??? For !flag_finite_math_only, the representation with SMIN/SMAX
1073 ;; isn't really correct, as those rtl operators aren't defined when
1074 ;; applied to NaNs.  Hopefully the optimizers won't get too smart on us.
1075
1076 (define_expand "<code><mode>3"
1077   [(set (match_operand:AVX256MODEF2P 0 "register_operand" "")
1078         (smaxmin:AVX256MODEF2P
1079           (match_operand:AVX256MODEF2P 1 "nonimmediate_operand" "")
1080           (match_operand:AVX256MODEF2P 2 "nonimmediate_operand" "")))]
1081   "AVX256_VEC_FLOAT_MODE_P (<MODE>mode)"
1082 {
1083   if (!flag_finite_math_only)
1084     operands[1] = force_reg (<MODE>mode, operands[1]);
1085   ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);
1086 })
1087
1088 (define_expand "<code><mode>3"
1089   [(set (match_operand:SSEMODEF2P 0 "register_operand" "")
1090         (smaxmin:SSEMODEF2P
1091           (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "")
1092           (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "")))]
1093   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
1094 {
1095   if (!flag_finite_math_only)
1096     operands[1] = force_reg (<MODE>mode, operands[1]);
1097   ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);
1098 })
1099
1100 (define_insn "*avx_<code><mode>3_finite"
1101   [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x")
1102         (smaxmin:AVXMODEF2P
1103           (match_operand:AVXMODEF2P 1 "nonimmediate_operand" "%x")
1104           (match_operand:AVXMODEF2P 2 "nonimmediate_operand" "xm")))]
1105   "AVX_VEC_FLOAT_MODE_P (<MODE>mode) && flag_finite_math_only
1106    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
1107   "v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
1108   [(set_attr "type" "sseadd")
1109    (set_attr "prefix" "vex")
1110    (set_attr "mode" "<MODE>")])
1111
1112 (define_insn "*<code><mode>3_finite"
1113   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
1114         (smaxmin:SSEMODEF2P
1115           (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "%0")
1116           (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")))]
1117   "SSE_VEC_FLOAT_MODE_P (<MODE>mode) && flag_finite_math_only
1118    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
1119   "<maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}"
1120   [(set_attr "type" "sseadd")
1121    (set_attr "mode" "<MODE>")])
1122
1123 (define_insn "*avx_<code><mode>3"
1124   [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x")
1125         (smaxmin:AVXMODEF2P
1126           (match_operand:AVXMODEF2P 1 "nonimmediate_operand" "%x")
1127           (match_operand:AVXMODEF2P 2 "nonimmediate_operand" "xm")))]
1128   "AVX_VEC_FLOAT_MODE_P (<MODE>mode)"
1129   "v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
1130   [(set_attr "type" "sseadd")
1131    (set_attr "prefix" "vex")
1132    (set_attr "mode" "<avxvecmode>")])
1133
1134 (define_insn "*<code><mode>3"
1135   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
1136         (smaxmin:SSEMODEF2P
1137           (match_operand:SSEMODEF2P 1 "register_operand" "0")
1138           (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")))]
1139   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
1140   "<maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}"
1141   [(set_attr "type" "sseadd")
1142    (set_attr "mode" "<MODE>")])
1143
1144 (define_insn "*avx_vm<code><mode>3"
1145   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
1146         (vec_merge:SSEMODEF2P
1147           (smaxmin:SSEMODEF2P
1148             (match_operand:SSEMODEF2P 1 "register_operand" "x")
1149             (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm"))
1150          (match_dup 1)
1151          (const_int 1)))]
1152   "AVX128_VEC_FLOAT_MODE_P (<MODE>mode)"
1153   "v<maxmin_float><ssescalarmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
1154   [(set_attr "type" "sse")
1155    (set_attr "prefix" "vex")
1156    (set_attr "mode" "<ssescalarmode>")])
1157
1158 (define_insn "<sse>_vm<code><mode>3"
1159   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
1160         (vec_merge:SSEMODEF2P
1161           (smaxmin:SSEMODEF2P
1162             (match_operand:SSEMODEF2P 1 "register_operand" "0")
1163             (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm"))
1164          (match_dup 1)
1165          (const_int 1)))]
1166   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
1167   "<maxmin_float><ssescalarmodesuffix>\t{%2, %0|%0, %2}"
1168   [(set_attr "type" "sseadd")
1169    (set_attr "mode" "<ssescalarmode>")])
1170
1171 ;; These versions of the min/max patterns implement exactly the operations
1172 ;;   min = (op1 < op2 ? op1 : op2)
1173 ;;   max = (!(op1 < op2) ? op1 : op2)
1174 ;; Their operands are not commutative, and thus they may be used in the
1175 ;; presence of -0.0 and NaN.
1176
1177 (define_insn "*avx_ieee_smin<mode>3"
1178   [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x")
1179         (unspec:AVXMODEF2P
1180           [(match_operand:AVXMODEF2P 1 "register_operand" "x")
1181            (match_operand:AVXMODEF2P 2 "nonimmediate_operand" "xm")]
1182          UNSPEC_IEEE_MIN))]
1183   "AVX_VEC_FLOAT_MODE_P (<MODE>mode)"
1184   "vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
1185   [(set_attr "type" "sseadd")
1186    (set_attr "prefix" "vex")
1187    (set_attr "mode" "<avxvecmode>")])
1188
1189 (define_insn "*avx_ieee_smax<mode>3"
1190   [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x")
1191         (unspec:AVXMODEF2P
1192           [(match_operand:AVXMODEF2P 1 "register_operand" "x")
1193            (match_operand:AVXMODEF2P 2 "nonimmediate_operand" "xm")]
1194          UNSPEC_IEEE_MAX))]
1195   "AVX_VEC_FLOAT_MODE_P (<MODE>mode)"
1196   "vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
1197   [(set_attr "type" "sseadd")
1198    (set_attr "prefix" "vex")
1199    (set_attr "mode" "<avxvecmode>")])
1200
1201 (define_insn "*ieee_smin<mode>3"
1202   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
1203         (unspec:SSEMODEF2P
1204           [(match_operand:SSEMODEF2P 1 "register_operand" "0")
1205            (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")]
1206          UNSPEC_IEEE_MIN))]
1207   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
1208   "min<ssemodesuffix>\t{%2, %0|%0, %2}"
1209   [(set_attr "type" "sseadd")
1210    (set_attr "mode" "<MODE>")])
1211
1212 (define_insn "*ieee_smax<mode>3"
1213   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
1214         (unspec:SSEMODEF2P
1215           [(match_operand:SSEMODEF2P 1 "register_operand" "0")
1216            (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")]
1217          UNSPEC_IEEE_MAX))]
1218   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
1219   "max<ssemodesuffix>\t{%2, %0|%0, %2}"
1220   [(set_attr "type" "sseadd")
1221    (set_attr "mode" "<MODE>")])
1222
1223 (define_insn "avx_addsubv8sf3"
1224   [(set (match_operand:V8SF 0 "register_operand" "=x")
1225         (vec_merge:V8SF
1226           (plus:V8SF
1227             (match_operand:V8SF 1 "register_operand" "x")
1228             (match_operand:V8SF 2 "nonimmediate_operand" "xm"))
1229           (minus:V8SF (match_dup 1) (match_dup 2))
1230           (const_int 170)))]
1231   "TARGET_AVX"
1232   "vaddsubps\t{%2, %1, %0|%0, %1, %2}"
1233   [(set_attr "type" "sseadd")
1234    (set_attr "prefix" "vex")
1235    (set_attr "mode" "V8SF")])
1236
1237 (define_insn "avx_addsubv4df3"
1238   [(set (match_operand:V4DF 0 "register_operand" "=x")
1239         (vec_merge:V4DF
1240           (plus:V4DF
1241             (match_operand:V4DF 1 "register_operand" "x")
1242             (match_operand:V4DF 2 "nonimmediate_operand" "xm"))
1243           (minus:V4DF (match_dup 1) (match_dup 2))
1244           (const_int 10)))]
1245   "TARGET_AVX"
1246   "vaddsubpd\t{%2, %1, %0|%0, %1, %2}"
1247   [(set_attr "type" "sseadd")
1248    (set_attr "prefix" "vex")
1249    (set_attr "mode" "V4DF")])
1250
1251 (define_insn "*avx_addsubv4sf3"
1252   [(set (match_operand:V4SF 0 "register_operand" "=x")
1253         (vec_merge:V4SF
1254           (plus:V4SF
1255             (match_operand:V4SF 1 "register_operand" "x")
1256             (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
1257           (minus:V4SF (match_dup 1) (match_dup 2))
1258           (const_int 10)))]
1259   "TARGET_AVX"
1260   "vaddsubps\t{%2, %1, %0|%0, %1, %2}"
1261   [(set_attr "type" "sseadd")
1262    (set_attr "prefix" "vex")
1263    (set_attr "mode" "V4SF")])
1264
1265 (define_insn "sse3_addsubv4sf3"
1266   [(set (match_operand:V4SF 0 "register_operand" "=x")
1267         (vec_merge:V4SF
1268           (plus:V4SF
1269             (match_operand:V4SF 1 "register_operand" "0")
1270             (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
1271           (minus:V4SF (match_dup 1) (match_dup 2))
1272           (const_int 10)))]
1273   "TARGET_SSE3"
1274   "addsubps\t{%2, %0|%0, %2}"
1275   [(set_attr "type" "sseadd")
1276    (set_attr "prefix_rep" "1")
1277    (set_attr "mode" "V4SF")])
1278
1279 (define_insn "*avx_addsubv2df3"
1280   [(set (match_operand:V2DF 0 "register_operand" "=x")
1281         (vec_merge:V2DF
1282           (plus:V2DF
1283             (match_operand:V2DF 1 "register_operand" "x")
1284             (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
1285           (minus:V2DF (match_dup 1) (match_dup 2))
1286           (const_int 2)))]
1287   "TARGET_AVX"
1288   "vaddsubpd\t{%2, %1, %0|%0, %1, %2}"
1289   [(set_attr "type" "sseadd")
1290    (set_attr "prefix" "vex")
1291    (set_attr "mode" "V2DF")])
1292
1293 (define_insn "sse3_addsubv2df3"
1294   [(set (match_operand:V2DF 0 "register_operand" "=x")
1295         (vec_merge:V2DF
1296           (plus:V2DF
1297             (match_operand:V2DF 1 "register_operand" "0")
1298             (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
1299           (minus:V2DF (match_dup 1) (match_dup 2))
1300           (const_int 2)))]
1301   "TARGET_SSE3"
1302   "addsubpd\t{%2, %0|%0, %2}"
1303   [(set_attr "type" "sseadd")
1304    (set_attr "atom_unit" "complex")
1305    (set_attr "mode" "V2DF")])
1306
1307 (define_insn "avx_h<plusminus_insn>v4df3"
1308   [(set (match_operand:V4DF 0 "register_operand" "=x")
1309         (vec_concat:V4DF
1310           (vec_concat:V2DF
1311             (plusminus:DF
1312               (vec_select:DF
1313                 (match_operand:V4DF 1 "register_operand" "x")
1314                 (parallel [(const_int 0)]))
1315               (vec_select:DF (match_dup 1) (parallel [(const_int 1)])))
1316             (plusminus:DF
1317               (vec_select:DF (match_dup 1) (parallel [(const_int 2)]))
1318               (vec_select:DF (match_dup 1) (parallel [(const_int 3)]))))
1319           (vec_concat:V2DF
1320             (plusminus:DF
1321               (vec_select:DF
1322                 (match_operand:V4DF 2 "nonimmediate_operand" "xm")
1323                 (parallel [(const_int 0)]))
1324               (vec_select:DF (match_dup 2) (parallel [(const_int 1)])))
1325             (plusminus:DF
1326               (vec_select:DF (match_dup 2) (parallel [(const_int 2)]))
1327               (vec_select:DF (match_dup 2) (parallel [(const_int 3)]))))))]
1328   "TARGET_AVX"
1329   "vh<plusminus_mnemonic>pd\t{%2, %1, %0|%0, %1, %2}"
1330   [(set_attr "type" "sseadd")
1331    (set_attr "prefix" "vex")
1332    (set_attr "mode" "V4DF")])
1333
1334 (define_insn "avx_h<plusminus_insn>v8sf3"
1335   [(set (match_operand:V8SF 0 "register_operand" "=x")
1336         (vec_concat:V8SF
1337           (vec_concat:V4SF
1338             (vec_concat:V2SF
1339               (plusminus:SF
1340                 (vec_select:SF
1341                   (match_operand:V8SF 1 "register_operand" "x")
1342                   (parallel [(const_int 0)]))
1343                 (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
1344               (plusminus:SF
1345                 (vec_select:SF (match_dup 1) (parallel [(const_int 2)]))
1346                 (vec_select:SF (match_dup 1) (parallel [(const_int 3)]))))
1347             (vec_concat:V2SF
1348               (plusminus:SF
1349                 (vec_select:SF
1350                   (match_operand:V8SF 2 "nonimmediate_operand" "xm")
1351                   (parallel [(const_int 0)]))
1352                 (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))
1353               (plusminus:SF
1354                 (vec_select:SF (match_dup 2) (parallel [(const_int 2)]))
1355                 (vec_select:SF (match_dup 2) (parallel [(const_int 3)])))))
1356           (vec_concat:V4SF
1357             (vec_concat:V2SF
1358               (plusminus:SF
1359                 (vec_select:SF (match_dup 1) (parallel [(const_int 4)]))
1360                 (vec_select:SF (match_dup 1) (parallel [(const_int 5)])))
1361               (plusminus:SF
1362                 (vec_select:SF (match_dup 1) (parallel [(const_int 6)]))
1363                 (vec_select:SF (match_dup 1) (parallel [(const_int 7)]))))
1364             (vec_concat:V2SF
1365               (plusminus:SF
1366                 (vec_select:SF (match_dup 2) (parallel [(const_int 4)]))
1367                 (vec_select:SF (match_dup 2) (parallel [(const_int 5)])))
1368               (plusminus:SF
1369                 (vec_select:SF (match_dup 2) (parallel [(const_int 6)]))
1370                 (vec_select:SF (match_dup 2) (parallel [(const_int 7)])))))))]
1371   "TARGET_AVX"
1372   "vh<plusminus_mnemonic>ps\t{%2, %1, %0|%0, %1, %2}"
1373   [(set_attr "type" "sseadd")
1374    (set_attr "prefix" "vex")
1375    (set_attr "mode" "V8SF")])
1376
1377 (define_insn "*avx_h<plusminus_insn>v4sf3"
1378   [(set (match_operand:V4SF 0 "register_operand" "=x")
1379         (vec_concat:V4SF
1380           (vec_concat:V2SF
1381             (plusminus:SF
1382               (vec_select:SF
1383                 (match_operand:V4SF 1 "register_operand" "x")
1384                 (parallel [(const_int 0)]))
1385               (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
1386             (plusminus:SF
1387               (vec_select:SF (match_dup 1) (parallel [(const_int 2)]))
1388               (vec_select:SF (match_dup 1) (parallel [(const_int 3)]))))
1389           (vec_concat:V2SF
1390             (plusminus:SF
1391               (vec_select:SF
1392                 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
1393                 (parallel [(const_int 0)]))
1394               (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))
1395             (plusminus:SF
1396               (vec_select:SF (match_dup 2) (parallel [(const_int 2)]))
1397               (vec_select:SF (match_dup 2) (parallel [(const_int 3)]))))))]
1398   "TARGET_AVX"
1399   "vh<plusminus_mnemonic>ps\t{%2, %1, %0|%0, %1, %2}"
1400   [(set_attr "type" "sseadd")
1401    (set_attr "prefix" "vex")
1402    (set_attr "mode" "V4SF")])
1403
1404 (define_insn "sse3_h<plusminus_insn>v4sf3"
1405   [(set (match_operand:V4SF 0 "register_operand" "=x")
1406         (vec_concat:V4SF
1407           (vec_concat:V2SF
1408             (plusminus:SF
1409               (vec_select:SF
1410                 (match_operand:V4SF 1 "register_operand" "0")
1411                 (parallel [(const_int 0)]))
1412               (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
1413             (plusminus:SF
1414               (vec_select:SF (match_dup 1) (parallel [(const_int 2)]))
1415               (vec_select:SF (match_dup 1) (parallel [(const_int 3)]))))
1416           (vec_concat:V2SF
1417             (plusminus:SF
1418               (vec_select:SF
1419                 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
1420                 (parallel [(const_int 0)]))
1421               (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))
1422             (plusminus:SF
1423               (vec_select:SF (match_dup 2) (parallel [(const_int 2)]))
1424               (vec_select:SF (match_dup 2) (parallel [(const_int 3)]))))))]
1425   "TARGET_SSE3"
1426   "h<plusminus_mnemonic>ps\t{%2, %0|%0, %2}"
1427   [(set_attr "type" "sseadd")
1428    (set_attr "atom_unit" "complex")
1429    (set_attr "prefix_rep" "1")
1430    (set_attr "mode" "V4SF")])
1431
1432 (define_insn "*avx_h<plusminus_insn>v2df3"
1433   [(set (match_operand:V2DF 0 "register_operand" "=x")
1434         (vec_concat:V2DF
1435           (plusminus:DF
1436             (vec_select:DF
1437               (match_operand:V2DF 1 "register_operand" "x")
1438               (parallel [(const_int 0)]))
1439             (vec_select:DF (match_dup 1) (parallel [(const_int 1)])))
1440           (plusminus:DF
1441             (vec_select:DF
1442               (match_operand:V2DF 2 "nonimmediate_operand" "xm")
1443               (parallel [(const_int 0)]))
1444             (vec_select:DF (match_dup 2) (parallel [(const_int 1)])))))]
1445   "TARGET_AVX"
1446   "vh<plusminus_mnemonic>pd\t{%2, %1, %0|%0, %1, %2}"
1447   [(set_attr "type" "sseadd")
1448    (set_attr "prefix" "vex")
1449    (set_attr "mode" "V2DF")])
1450
1451 (define_insn "sse3_h<plusminus_insn>v2df3"
1452   [(set (match_operand:V2DF 0 "register_operand" "=x")
1453         (vec_concat:V2DF
1454           (plusminus:DF
1455             (vec_select:DF
1456               (match_operand:V2DF 1 "register_operand" "0")
1457               (parallel [(const_int 0)]))
1458             (vec_select:DF (match_dup 1) (parallel [(const_int 1)])))
1459           (plusminus:DF
1460             (vec_select:DF
1461               (match_operand:V2DF 2 "nonimmediate_operand" "xm")
1462               (parallel [(const_int 0)]))
1463             (vec_select:DF (match_dup 2) (parallel [(const_int 1)])))))]
1464   "TARGET_SSE3"
1465   "h<plusminus_mnemonic>pd\t{%2, %0|%0, %2}"
1466   [(set_attr "type" "sseadd")
1467    (set_attr "mode" "V2DF")])
1468
1469 (define_expand "reduc_splus_v8sf"
1470   [(match_operand:V8SF 0 "register_operand" "")
1471    (match_operand:V8SF 1 "register_operand" "")]
1472   "TARGET_AVX"
1473 {
1474   rtx tmp = gen_reg_rtx (V8SFmode);
1475   rtx tmp2 = gen_reg_rtx (V8SFmode);
1476   emit_insn (gen_avx_haddv8sf3 (tmp, operands[1], operands[1]));
1477   emit_insn (gen_avx_haddv8sf3 (tmp2, tmp, tmp));
1478   emit_insn (gen_avx_vperm2f128v8sf3 (tmp, tmp2, tmp2, GEN_INT (1)));
1479   emit_insn (gen_addv8sf3 (operands[0], tmp, tmp2));
1480   DONE;
1481 })
1482
1483 (define_expand "reduc_splus_v4sf"
1484   [(match_operand:V4SF 0 "register_operand" "")
1485    (match_operand:V4SF 1 "register_operand" "")]
1486   "TARGET_SSE"
1487 {
1488   if (TARGET_SSE3)
1489     {
1490       rtx tmp = gen_reg_rtx (V4SFmode);
1491       emit_insn (gen_sse3_haddv4sf3 (tmp, operands[1], operands[1]));
1492       emit_insn (gen_sse3_haddv4sf3 (operands[0], tmp, tmp));
1493     }
1494   else
1495     ix86_expand_reduc_v4sf (gen_addv4sf3, operands[0], operands[1]);
1496   DONE;
1497 })
1498
1499 (define_expand "reduc_splus_v4df"
1500   [(match_operand:V4DF 0 "register_operand" "")
1501    (match_operand:V4DF 1 "register_operand" "")]
1502   "TARGET_AVX"
1503 {
1504   rtx tmp = gen_reg_rtx (V4DFmode);
1505   rtx tmp2 = gen_reg_rtx (V4DFmode);
1506   emit_insn (gen_avx_haddv4df3 (tmp, operands[1], operands[1]));
1507   emit_insn (gen_avx_vperm2f128v4df3 (tmp2, tmp, tmp, GEN_INT (1)));
1508   emit_insn (gen_addv4df3 (operands[0], tmp, tmp2));
1509   DONE;
1510 })
1511
1512 (define_expand "reduc_splus_v2df"
1513   [(match_operand:V2DF 0 "register_operand" "")
1514    (match_operand:V2DF 1 "register_operand" "")]
1515   "TARGET_SSE3"
1516 {
1517   emit_insn (gen_sse3_haddv2df3 (operands[0], operands[1], operands[1]));
1518   DONE;
1519 })
1520
1521 (define_expand "reduc_smax_v4sf"
1522   [(match_operand:V4SF 0 "register_operand" "")
1523    (match_operand:V4SF 1 "register_operand" "")]
1524   "TARGET_SSE"
1525 {
1526   ix86_expand_reduc_v4sf (gen_smaxv4sf3, operands[0], operands[1]);
1527   DONE;
1528 })
1529
1530 (define_expand "reduc_smin_v4sf"
1531   [(match_operand:V4SF 0 "register_operand" "")
1532    (match_operand:V4SF 1 "register_operand" "")]
1533   "TARGET_SSE"
1534 {
1535   ix86_expand_reduc_v4sf (gen_sminv4sf3, operands[0], operands[1]);
1536   DONE;
1537 })
1538
1539 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1540 ;;
1541 ;; Parallel floating point comparisons
1542 ;;
1543 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1544
1545 (define_insn "avx_cmp<ssemodesuffix><mode>3"
1546   [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x")
1547         (unspec:AVXMODEF2P
1548           [(match_operand:AVXMODEF2P 1 "register_operand" "x")
1549            (match_operand:AVXMODEF2P 2 "nonimmediate_operand" "xm")
1550            (match_operand:SI 3 "const_0_to_31_operand" "n")]
1551           UNSPEC_PCMP))]
1552   "TARGET_AVX"
1553   "vcmp<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1554   [(set_attr "type" "ssecmp")
1555    (set_attr "length_immediate" "1")
1556    (set_attr "prefix" "vex")
1557    (set_attr "mode" "<MODE>")])
1558
1559 (define_insn "avx_cmp<ssescalarmodesuffix><mode>3"
1560   [(set (match_operand:SSEMODEF2P 0 "register_operand" "")
1561         (vec_merge:SSEMODEF2P
1562           (unspec:SSEMODEF2P
1563             [(match_operand:SSEMODEF2P 1 "register_operand" "x")
1564              (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")
1565              (match_operand:SI 3 "const_0_to_31_operand" "n")]
1566             UNSPEC_PCMP)
1567          (match_dup 1)
1568          (const_int 1)))]
1569   "TARGET_AVX"
1570   "vcmp<ssescalarmodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1571   [(set_attr "type" "ssecmp")
1572    (set_attr "length_immediate" "1")
1573    (set_attr "prefix" "vex")
1574    (set_attr "mode" "<ssescalarmode>")])
1575
1576 ;; We don't promote 128bit vector compare intrinsics. But vectorizer
1577 ;; may generate 256bit vector compare instructions.
1578 (define_insn "*avx_maskcmp<mode>3"
1579   [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x")
1580         (match_operator:AVXMODEF2P 3 "avx_comparison_float_operator"
1581                 [(match_operand:AVXMODEF2P 1 "register_operand" "x")
1582                  (match_operand:AVXMODEF2P 2 "nonimmediate_operand" "xm")]))]
1583   "AVX_VEC_FLOAT_MODE_P (<MODE>mode)"
1584   "vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
1585   [(set_attr "type" "ssecmp")
1586    (set_attr "prefix" "vex")
1587    (set_attr "length_immediate" "1")
1588    (set_attr "mode" "<avxvecmode>")])
1589
1590 (define_insn "<sse>_maskcmp<mode>3"
1591   [(set (match_operand:SSEMODEF4 0 "register_operand" "=x")
1592         (match_operator:SSEMODEF4 3 "sse_comparison_operator"
1593                 [(match_operand:SSEMODEF4 1 "register_operand" "0")
1594                  (match_operand:SSEMODEF4 2 "nonimmediate_operand" "xm")]))]
1595   "!TARGET_XOP 
1596   && (SSE_FLOAT_MODE_P (<MODE>mode) || SSE_VEC_FLOAT_MODE_P (<MODE>mode))"
1597   "cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}"
1598   [(set_attr "type" "ssecmp")
1599    (set_attr "length_immediate" "1")
1600    (set_attr "mode" "<MODE>")])
1601
1602 (define_insn "*avx_vmmaskcmp<mode>3"
1603   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
1604         (vec_merge:SSEMODEF2P
1605          (match_operator:SSEMODEF2P 3 "sse_comparison_operator"
1606                 [(match_operand:SSEMODEF2P 1 "register_operand" "x")
1607                  (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")])
1608          (match_dup 1)
1609          (const_int 1)))]
1610   "AVX_VEC_FLOAT_MODE_P (<MODE>mode)"
1611   "vcmp%D3<ssescalarmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
1612   [(set_attr "type" "ssecmp")
1613    (set_attr "prefix" "vex")
1614    (set_attr "mode" "<ssescalarmode>")])
1615
1616 (define_insn "<sse>_vmmaskcmp<mode>3"
1617   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
1618         (vec_merge:SSEMODEF2P
1619          (match_operator:SSEMODEF2P 3 "sse_comparison_operator"
1620                 [(match_operand:SSEMODEF2P 1 "register_operand" "0")
1621                  (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")])
1622          (match_dup 1)
1623          (const_int 1)))]
1624   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
1625   "cmp%D3<ssescalarmodesuffix>\t{%2, %0|%0, %2}"
1626   [(set_attr "type" "ssecmp")
1627    (set_attr "length_immediate" "1")
1628    (set_attr "mode" "<ssescalarmode>")])
1629
1630 (define_insn "<sse>_comi"
1631   [(set (reg:CCFP FLAGS_REG)
1632         (compare:CCFP
1633           (vec_select:MODEF
1634             (match_operand:<ssevecmode> 0 "register_operand" "x")
1635             (parallel [(const_int 0)]))
1636           (vec_select:MODEF
1637             (match_operand:<ssevecmode> 1 "nonimmediate_operand" "xm")
1638             (parallel [(const_int 0)]))))]
1639   "SSE_FLOAT_MODE_P (<MODE>mode)"
1640   "%vcomis<ssemodefsuffix>\t{%1, %0|%0, %1}"
1641   [(set_attr "type" "ssecomi")
1642    (set_attr "prefix" "maybe_vex")
1643    (set_attr "prefix_rep" "0")
1644    (set (attr "prefix_data16")
1645         (if_then_else (eq_attr "mode" "DF")
1646                       (const_string "1")
1647                       (const_string "0")))
1648    (set_attr "mode" "<MODE>")])
1649
1650 (define_insn "<sse>_ucomi"
1651   [(set (reg:CCFPU FLAGS_REG)
1652         (compare:CCFPU
1653           (vec_select:MODEF
1654             (match_operand:<ssevecmode> 0 "register_operand" "x")
1655             (parallel [(const_int 0)]))
1656           (vec_select:MODEF
1657             (match_operand:<ssevecmode> 1 "nonimmediate_operand" "xm")
1658             (parallel [(const_int 0)]))))]
1659   "SSE_FLOAT_MODE_P (<MODE>mode)"
1660   "%vucomis<ssemodefsuffix>\t{%1, %0|%0, %1}"
1661   [(set_attr "type" "ssecomi")
1662    (set_attr "prefix" "maybe_vex")
1663    (set_attr "prefix_rep" "0")
1664    (set (attr "prefix_data16")
1665         (if_then_else (eq_attr "mode" "DF")
1666                       (const_string "1")
1667                       (const_string "0")))
1668    (set_attr "mode" "<MODE>")])
1669
1670 (define_expand "vcond<mode>"
1671   [(set (match_operand:AVXMODEF2P 0 "register_operand" "")
1672         (if_then_else:AVXMODEF2P
1673           (match_operator 3 ""
1674             [(match_operand:AVXMODEF2P 4 "nonimmediate_operand" "")
1675              (match_operand:AVXMODEF2P 5 "nonimmediate_operand" "")])
1676           (match_operand:AVXMODEF2P 1 "general_operand" "")
1677           (match_operand:AVXMODEF2P 2 "general_operand" "")))]
1678   "(SSE_VEC_FLOAT_MODE_P (<MODE>mode)
1679     || AVX_VEC_FLOAT_MODE_P (<MODE>mode))"
1680 {
1681   bool ok = ix86_expand_fp_vcond (operands);
1682   gcc_assert (ok);
1683   DONE;
1684 })
1685
1686 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1687 ;;
1688 ;; Parallel floating point logical operations
1689 ;;
1690 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1691
1692 (define_insn "avx_andnot<mode>3"
1693   [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x")
1694         (and:AVXMODEF2P
1695           (not:AVXMODEF2P
1696             (match_operand:AVXMODEF2P 1 "register_operand" "x"))
1697           (match_operand:AVXMODEF2P 2 "nonimmediate_operand" "xm")))]
1698   "AVX_VEC_FLOAT_MODE_P (<MODE>mode)"
1699   "vandn<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
1700   [(set_attr "type" "sselog")
1701    (set_attr "prefix" "vex")
1702    (set_attr "mode" "<avxvecmode>")])
1703
1704 (define_insn "<sse>_andnot<mode>3"
1705   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
1706         (and:SSEMODEF2P
1707           (not:SSEMODEF2P
1708             (match_operand:SSEMODEF2P 1 "register_operand" "0"))
1709           (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")))]
1710   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
1711   "andn<ssemodesuffix>\t{%2, %0|%0, %2}"
1712   [(set_attr "type" "sselog")
1713    (set_attr "mode" "<MODE>")])
1714
1715 (define_expand "<code><mode>3"
1716   [(set (match_operand:AVX256MODEF2P 0 "register_operand" "")
1717         (any_logic:AVX256MODEF2P
1718           (match_operand:AVX256MODEF2P 1 "nonimmediate_operand" "")
1719           (match_operand:AVX256MODEF2P 2 "nonimmediate_operand" "")))]
1720   "AVX256_VEC_FLOAT_MODE_P (<MODE>mode)"
1721   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
1722
1723 (define_insn "*avx_<code><mode>3"
1724   [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x")
1725         (any_logic:AVXMODEF2P
1726           (match_operand:AVXMODEF2P 1 "nonimmediate_operand" "%x")
1727           (match_operand:AVXMODEF2P 2 "nonimmediate_operand" "xm")))]
1728   "AVX_VEC_FLOAT_MODE_P (<MODE>mode)
1729    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
1730 {
1731   if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
1732     return "v<logic>ps\t{%2, %1, %0|%0, %1, %2}";
1733   else
1734     return "v<logic><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}";
1735 }
1736   [(set_attr "type" "sselog")
1737    (set_attr "prefix" "vex")
1738    (set_attr "mode" "<avxvecmode>")])
1739
1740 (define_expand "<code><mode>3"
1741   [(set (match_operand:SSEMODEF2P 0 "register_operand" "")
1742         (any_logic:SSEMODEF2P
1743           (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "")
1744           (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "")))]
1745   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
1746   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
1747
1748 (define_insn "*<code><mode>3"
1749   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
1750         (any_logic:SSEMODEF2P
1751           (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "%0")
1752           (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")))]
1753   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)
1754    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
1755 {
1756   if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
1757     return "<logic>ps\t{%2, %0|%0, %2}";
1758   else
1759     return "<logic><ssemodesuffix>\t{%2, %0|%0, %2}";
1760 }
1761   [(set_attr "type" "sselog")
1762    (set_attr "mode" "<MODE>")])
1763
1764 (define_expand "copysign<mode>3"
1765   [(set (match_dup 4)
1766         (and:VEC_FLOAT_MODE
1767           (not:VEC_FLOAT_MODE (match_dup 3))
1768           (match_operand:VEC_FLOAT_MODE 1 "nonimmediate_operand" "")))
1769    (set (match_dup 5)
1770         (and:VEC_FLOAT_MODE (match_dup 3)
1771                             (match_operand:VEC_FLOAT_MODE 2 "nonimmediate_operand" "")))
1772    (set (match_operand:VEC_FLOAT_MODE 0 "register_operand" "")
1773         (ior:VEC_FLOAT_MODE (match_dup 4) (match_dup 5)))]
1774   ""
1775 {
1776   operands[3] = ix86_build_signbit_mask (<MODE>mode, 1, 0);
1777
1778   operands[4] = gen_reg_rtx (<MODE>mode);
1779   operands[5] = gen_reg_rtx (<MODE>mode);
1780 })
1781
1782 ;; Also define scalar versions.  These are used for abs, neg, and
1783 ;; conditional move.  Using subregs into vector modes causes register
1784 ;; allocation lossage.  These patterns do not allow memory operands
1785 ;; because the native instructions read the full 128-bits.
1786
1787 (define_insn "*avx_andnot<mode>3"
1788   [(set (match_operand:MODEF 0 "register_operand" "=x")
1789         (and:MODEF
1790           (not:MODEF
1791             (match_operand:MODEF 1 "register_operand" "x"))
1792             (match_operand:MODEF 2 "register_operand" "x")))]
1793   "AVX_FLOAT_MODE_P (<MODE>mode)"
1794   "vandnp<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
1795   [(set_attr "type" "sselog")
1796    (set_attr "prefix" "vex")
1797    (set_attr "mode" "<ssevecmode>")])
1798
1799 (define_insn "*andnot<mode>3"
1800   [(set (match_operand:MODEF 0 "register_operand" "=x")
1801         (and:MODEF
1802           (not:MODEF
1803             (match_operand:MODEF 1 "register_operand" "0"))
1804             (match_operand:MODEF 2 "register_operand" "x")))]
1805   "SSE_FLOAT_MODE_P (<MODE>mode)"
1806   "andnp<ssemodefsuffix>\t{%2, %0|%0, %2}"
1807   [(set_attr "type" "sselog")
1808    (set_attr "mode" "<ssevecmode>")])
1809
1810 (define_insn "*avx_<code><mode>3"
1811   [(set (match_operand:MODEF 0 "register_operand" "=x")
1812         (any_logic:MODEF
1813           (match_operand:MODEF 1 "register_operand" "x")
1814           (match_operand:MODEF 2 "register_operand" "x")))]
1815   "AVX_FLOAT_MODE_P (<MODE>mode)"
1816 {
1817   if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
1818     return "v<logic>ps\t{%2, %1, %0|%0, %1, %2}";
1819   else
1820     return "v<logic>p<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}";
1821 }
1822   [(set_attr "type" "sselog")
1823    (set_attr "prefix" "vex")
1824    (set_attr "mode" "<ssevecmode>")])
1825
1826 (define_insn "*<code><mode>3"
1827   [(set (match_operand:MODEF 0 "register_operand" "=x")
1828         (any_logic:MODEF
1829           (match_operand:MODEF 1 "register_operand" "0")
1830           (match_operand:MODEF 2 "register_operand" "x")))]
1831   "SSE_FLOAT_MODE_P (<MODE>mode)"
1832 {
1833   if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
1834     return "<logic>ps\t{%2, %0|%0, %2}";
1835   else
1836     return "<logic>p<ssemodefsuffix>\t{%2, %0|%0, %2}";
1837 }
1838   [(set_attr "type" "sselog")
1839    (set_attr "mode" "<ssevecmode>")])
1840
1841 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1842 ;;
1843 ;; FMA4 floating point multiply/accumulate instructions.  This
1844 ;; includes the scalar version of the instructions as well as the
1845 ;; vector.
1846 ;;
1847 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1848
1849 ;; In order to match (*a * *b) + *c, particularly when vectorizing, allow
1850 ;; combine to generate a multiply/add with two memory references.  We then
1851 ;; split this insn, into loading up the destination register with one of the
1852 ;; memory operations.  If we don't manage to split the insn, reload will
1853 ;; generate the appropriate moves.  The reason this is needed, is that combine
1854 ;; has already folded one of the memory references into both the multiply and
1855 ;; add insns, and it can't generate a new pseudo.  I.e.:
1856 ;;      (set (reg1) (mem (addr1)))
1857 ;;      (set (reg2) (mult (reg1) (mem (addr2))))
1858 ;;      (set (reg3) (plus (reg2) (mem (addr3))))
1859
1860 ;; Intrinsic FMA operations.
1861
1862 ;; The standard names for fma is only available with SSE math enabled.
1863 (define_expand "fma<mode>4"
1864   [(set (match_operand:FMAMODE 0 "register_operand")
1865         (fma:FMAMODE
1866           (match_operand:FMAMODE 1 "nonimmediate_operand")
1867           (match_operand:FMAMODE 2 "nonimmediate_operand")
1868           (match_operand:FMAMODE 3 "nonimmediate_operand")))]
1869   "(TARGET_FMA || TARGET_FMA4) && TARGET_SSE_MATH"
1870   "")
1871
1872 (define_expand "fms<mode>4"
1873   [(set (match_operand:FMAMODE 0 "register_operand")
1874         (fma:FMAMODE
1875           (match_operand:FMAMODE 1 "nonimmediate_operand")
1876           (match_operand:FMAMODE 2 "nonimmediate_operand")
1877           (neg:FMAMODE (match_operand:FMAMODE 3 "nonimmediate_operand"))))]
1878   "(TARGET_FMA || TARGET_FMA4) && TARGET_SSE_MATH"
1879   "")
1880
1881 (define_expand "fnma<mode>4"
1882   [(set (match_operand:FMAMODE 0 "register_operand")
1883         (fma:FMAMODE
1884           (neg:FMAMODE (match_operand:FMAMODE 1 "nonimmediate_operand"))
1885           (match_operand:FMAMODE 2 "nonimmediate_operand")
1886           (match_operand:FMAMODE 3 "nonimmediate_operand")))]
1887   "(TARGET_FMA || TARGET_FMA4) && TARGET_SSE_MATH"
1888   "")
1889
1890 (define_expand "fnms<mode>4"
1891   [(set (match_operand:FMAMODE 0 "register_operand")
1892         (fma:FMAMODE
1893           (neg:FMAMODE (match_operand:FMAMODE 1 "nonimmediate_operand"))
1894           (match_operand:FMAMODE 2 "nonimmediate_operand")
1895           (neg:FMAMODE (match_operand:FMAMODE 3 "nonimmediate_operand"))))]
1896   "(TARGET_FMA || TARGET_FMA4) && TARGET_SSE_MATH"
1897   "")
1898
1899 ;; The builtin for fma4intrin.h is not constrained by SSE math enabled.
1900 (define_expand "fma4i_fmadd_<mode>"
1901   [(set (match_operand:FMAMODE 0 "register_operand")
1902         (fma:FMAMODE
1903           (match_operand:FMAMODE 1 "nonimmediate_operand")
1904           (match_operand:FMAMODE 2 "nonimmediate_operand")
1905           (match_operand:FMAMODE 3 "nonimmediate_operand")))]
1906   "TARGET_FMA || TARGET_FMA4"
1907   "")
1908
1909 (define_insn "*fma4i_fmadd_<mode>"
1910   [(set (match_operand:FMAMODE 0 "register_operand" "=x,x")
1911         (fma:FMAMODE
1912           (match_operand:FMAMODE 1 "nonimmediate_operand" "%x,x")
1913           (match_operand:FMAMODE 2 "nonimmediate_operand" " x,m")
1914           (match_operand:FMAMODE 3 "nonimmediate_operand" "xm,x")))]
1915   "TARGET_FMA4"
1916   "vfmadd<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1917   [(set_attr "type" "ssemuladd")
1918    (set_attr "mode" "<MODE>")])
1919
1920 (define_insn "*fma4i_fmsub_<mode>"
1921   [(set (match_operand:FMAMODE 0 "register_operand" "=x,x")
1922         (fma:FMAMODE
1923           (match_operand:FMAMODE 1 "nonimmediate_operand" "%x,x")
1924           (match_operand:FMAMODE 2 "nonimmediate_operand" " x,m")
1925           (neg:FMAMODE
1926             (match_operand:FMAMODE 3 "nonimmediate_operand" "xm,x"))))]
1927   "TARGET_FMA4"
1928   "vfmsub<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1929   [(set_attr "type" "ssemuladd")
1930    (set_attr "mode" "<MODE>")])
1931
1932 (define_insn "*fma4i_fnmadd_<mode>"
1933   [(set (match_operand:FMAMODE 0 "register_operand" "=x,x")
1934         (fma:FMAMODE
1935           (neg:FMAMODE
1936             (match_operand:FMAMODE 1 "nonimmediate_operand" "%x,x"))
1937           (match_operand:FMAMODE   2 "nonimmediate_operand" " x,m")
1938           (match_operand:FMAMODE   3 "nonimmediate_operand" "xm,x")))]
1939   "TARGET_FMA4"
1940   "vfnmadd<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1941   [(set_attr "type" "ssemuladd")
1942    (set_attr "mode" "<MODE>")])
1943
1944 (define_insn "*fma4i_fnmsub_<mode>"
1945   [(set (match_operand:FMAMODE 0 "register_operand" "=x,x")
1946         (fma:FMAMODE
1947           (neg:FMAMODE
1948             (match_operand:FMAMODE 1 "nonimmediate_operand" "%x,x"))
1949           (match_operand:FMAMODE   2 "nonimmediate_operand" " x,m")
1950           (neg:FMAMODE
1951             (match_operand:FMAMODE 3 "nonimmediate_operand" "xm,x"))))]
1952   "TARGET_FMA4"
1953   "vfnmsub<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1954   [(set_attr "type" "ssemuladd")
1955    (set_attr "mode" "<MODE>")])
1956
1957 ;; Scalar versions of the above.  Unlike ADDSS et al, these write the
1958 ;; entire destination register, with the high-order elements zeroed.
1959
1960 (define_expand "fma4i_vmfmadd_<mode>"
1961   [(set (match_operand:SSEMODEF2P 0 "register_operand")
1962         (vec_merge:SSEMODEF2P
1963           (fma:SSEMODEF2P
1964             (match_operand:SSEMODEF2P 1 "nonimmediate_operand")
1965             (match_operand:SSEMODEF2P 2 "nonimmediate_operand")
1966             (match_operand:SSEMODEF2P 3 "nonimmediate_operand"))
1967           (match_dup 4)
1968           (const_int 1)))]
1969   "TARGET_FMA4"
1970 {
1971   operands[4] = CONST0_RTX (<MODE>mode);
1972 })
1973
1974 (define_insn "*fma4i_vmfmadd_<mode>"
1975   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x")
1976         (vec_merge:SSEMODEF2P
1977           (fma:SSEMODEF2P
1978             (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "%x,x")
1979             (match_operand:SSEMODEF2P 2 "nonimmediate_operand" " x,m")
1980             (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x"))
1981           (match_operand:SSEMODEF2P 4 "const0_operand" "")
1982           (const_int 1)))]
1983   "TARGET_FMA4"
1984   "vfmadd<ssescalarmodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1985   [(set_attr "type" "ssemuladd")
1986    (set_attr "mode" "<MODE>")])
1987
1988 (define_insn "*fma4i_vmfmsub_<mode>"
1989   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x")
1990         (vec_merge:SSEMODEF2P
1991           (fma:SSEMODEF2P
1992             (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "%x,x")
1993             (match_operand:SSEMODEF2P 2 "nonimmediate_operand" " x,m")
1994             (neg:SSEMODEF2P
1995               (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x")))
1996           (match_operand:SSEMODEF2P 4 "const0_operand" "")
1997           (const_int 1)))]
1998   "TARGET_FMA4"
1999   "vfmsub<ssescalarmodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
2000   [(set_attr "type" "ssemuladd")
2001    (set_attr "mode" "<MODE>")])
2002
2003 (define_insn "*fma4i_vmfnmadd_<mode>"
2004   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x")
2005         (vec_merge:SSEMODEF2P
2006           (fma:SSEMODEF2P
2007             (neg:SSEMODEF2P
2008               (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "%x,x"))
2009             (match_operand:SSEMODEF2P   2 "nonimmediate_operand" " x,m")
2010             (match_operand:SSEMODEF2P   3 "nonimmediate_operand" "xm,x"))
2011           (match_operand:SSEMODEF2P 4 "const0_operand" "")
2012           (const_int 1)))]
2013   "TARGET_FMA4"
2014   "vfnmadd<ssescalarmodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
2015   [(set_attr "type" "ssemuladd")
2016    (set_attr "mode" "<MODE>")])
2017
2018 (define_insn "*fma4i_vmfnmsub_<mode>"
2019   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x")
2020         (vec_merge:SSEMODEF2P
2021           (fma:SSEMODEF2P
2022             (neg:SSEMODEF2P
2023               (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "%x,x"))
2024             (match_operand:SSEMODEF2P   2 "nonimmediate_operand" " x,m")
2025             (neg:SSEMODEF2P
2026               (match_operand:SSEMODEF2P   3 "nonimmediate_operand" "xm,x")))
2027           (match_operand:SSEMODEF2P 4 "const0_operand" "")
2028           (const_int 1)))]
2029   "TARGET_FMA4"
2030   "vfnmsub<ssescalarmodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
2031   [(set_attr "type" "ssemuladd")
2032    (set_attr "mode" "<MODE>")])
2033
2034 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2035 ;;
2036 ;; FMA4 Parallel floating point multiply addsub and subadd operations.
2037 ;;
2038 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2039
2040 ;; It would be possible to represent these without the UNSPEC as
2041 ;;
2042 ;; (vec_merge
2043 ;;   (fma op1 op2 op3)
2044 ;;   (fma op1 op2 (neg op3))
2045 ;;   (merge-const))
2046 ;;
2047 ;; But this doesn't seem useful in practice.
2048
2049 (define_expand "fmaddsub_<mode>"
2050   [(set (match_operand:AVXMODEF2P 0 "register_operand")
2051         (unspec:AVXMODEF2P
2052           [(match_operand:AVXMODEF2P 1 "nonimmediate_operand")
2053            (match_operand:AVXMODEF2P 2 "nonimmediate_operand")
2054            (match_operand:AVXMODEF2P 3 "nonimmediate_operand")]
2055           UNSPEC_FMADDSUB))]
2056   "TARGET_FMA || TARGET_FMA4"
2057   "")
2058
2059 (define_insn "*fma4_fmaddsub_<mode>"
2060   [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x,x")
2061         (unspec:AVXMODEF2P
2062           [(match_operand:AVXMODEF2P 1 "nonimmediate_operand" "%x,x")
2063            (match_operand:AVXMODEF2P 2 "nonimmediate_operand" " x,m")
2064            (match_operand:AVXMODEF2P 3 "nonimmediate_operand" "xm,x")]
2065           UNSPEC_FMADDSUB))]
2066   "TARGET_FMA4"
2067   "vfmaddsubps\t{%3, %2, %1, %0|%0, %1, %2, %3}"
2068   [(set_attr "type" "ssemuladd")
2069    (set_attr "mode" "<MODE>")])
2070
2071 (define_insn "*fma4_fmsubadd_<mode>"
2072   [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x,x")
2073         (unspec:AVXMODEF2P
2074           [(match_operand:AVXMODEF2P 1 "nonimmediate_operand" "%x,x")
2075            (match_operand:AVXMODEF2P 2 "nonimmediate_operand" " x,m")
2076            (neg:AVXMODEF2P
2077              (match_operand:AVXMODEF2P 3 "nonimmediate_operand" "xm,x"))]
2078           UNSPEC_FMADDSUB))]
2079   "TARGET_FMA4"
2080   "vfmsubaddps\t{%3, %2, %1, %0|%0, %1, %2, %3}"
2081   [(set_attr "type" "ssemuladd")
2082    (set_attr "mode" "<MODE>")])
2083
2084 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2085 ;;
2086 ;; FMA3 floating point multiply/accumulate instructions.
2087 ;;
2088 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2089
2090 (define_insn "*fma_fmadd_<mode>"
2091   [(set (match_operand:FMAMODE 0 "register_operand" "=x,x,x")
2092         (fma:FMAMODE
2093           (match_operand:FMAMODE 1 "nonimmediate_operand" "%0, 0,x")
2094           (match_operand:FMAMODE 2 "nonimmediate_operand" "xm, x,xm")
2095           (match_operand:FMAMODE 3 "nonimmediate_operand" " x,xm,0")))]
2096   "TARGET_FMA"
2097   "@
2098    vfmadd132<ssemodesuffix>\t{%2, %3, %0|%0, %3, %2}
2099    vfmadd312<ssemodesuffix>\t{%3, %2, %0|%0, %2, %3}
2100    vfmadd231<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
2101   [(set_attr "type" "ssemuladd")
2102    (set_attr "mode" "<MODE>")])
2103
2104 (define_insn "*fma_fmsub_<mode>"
2105   [(set (match_operand:FMAMODE 0 "register_operand" "=x,x,x")
2106         (fma:FMAMODE
2107           (match_operand:FMAMODE   1 "nonimmediate_operand" "%0, 0,x")
2108           (match_operand:FMAMODE   2 "nonimmediate_operand" "xm, x,xm")
2109           (neg:FMAMODE
2110             (match_operand:FMAMODE 3 "nonimmediate_operand" " x,xm,0"))))]
2111   "TARGET_FMA"
2112   "@
2113    vfmsub132<ssemodesuffix>\t{%2, %3, %0|%0, %3, %2}
2114    vfmsub312<ssemodesuffix>\t{%3, %2, %0|%0, %2, %3}
2115    vfmsub231<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
2116   [(set_attr "type" "ssemuladd")
2117    (set_attr "mode" "<MODE>")])
2118
2119 (define_insn "*fma_fmadd_<mode>"
2120   [(set (match_operand:FMAMODE 0 "register_operand" "=x,x,x")
2121         (fma:FMAMODE
2122           (neg:FMAMODE
2123             (match_operand:FMAMODE 1 "nonimmediate_operand" "%0, 0,x"))
2124           (match_operand:FMAMODE   2 "nonimmediate_operand" "xm, x,xm")
2125           (match_operand:FMAMODE   3 "nonimmediate_operand" " x,xm,0")))]
2126   "TARGET_FMA"
2127   "@
2128    vfnmadd132<ssemodesuffix>\t{%2, %3, %0|%0, %3, %2}
2129    vfnmadd312<ssemodesuffix>\t{%3, %2, %0|%0, %2, %3}
2130    vfnmadd231<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
2131   [(set_attr "type" "ssemuladd")
2132    (set_attr "mode" "<MODE>")])
2133
2134 (define_insn "*fma_fmsub_<mode>"
2135   [(set (match_operand:FMAMODE 0 "register_operand" "=x,x,x")
2136         (fma:FMAMODE
2137           (neg:FMAMODE
2138             (match_operand:FMAMODE 1 "nonimmediate_operand" "%0, 0,x"))
2139           (match_operand:FMAMODE   2 "nonimmediate_operand" "xm, x,xm")
2140           (neg:FMAMODE
2141             (match_operand:FMAMODE 3 "nonimmediate_operand" " x,xm,0"))))]
2142   "TARGET_FMA"
2143   "@
2144    vfnmsub132<ssemodesuffix>\t{%2, %3, %0|%0, %3, %2}
2145    vfnmsub312<ssemodesuffix>\t{%3, %2, %0|%0, %2, %3}
2146    vfnmsub231<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
2147   [(set_attr "type" "ssemuladd")
2148    (set_attr "mode" "<MODE>")])
2149
2150 (define_insn "*fma_fmaddsub_<mode>"
2151   [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x,x,x")
2152         (unspec:AVXMODEF2P
2153           [(match_operand:AVXMODEF2P 1 "nonimmediate_operand" "%0, 0,x")
2154            (match_operand:AVXMODEF2P 2 "nonimmediate_operand" "xm, x,xm")
2155            (match_operand:AVXMODEF2P 3 "nonimmediate_operand" " x,xm,0")]
2156           UNSPEC_FMADDSUB))]
2157   "TARGET_FMA"
2158   "@
2159    vfmaddsub132<ssemodesuffix>\t{%2, %3, %0|%0, %3, %2}
2160    vfmaddsub213<ssemodesuffix>\t{%3, %2, %0|%0, %2, %3}
2161    vfmaddsub231<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
2162   [(set_attr "type" "ssemuladd")
2163    (set_attr "mode" "<MODE>")])
2164
2165 (define_insn "*fma_fmsubadd_<mode>"
2166   [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x,x,x")
2167         (unspec:AVXMODEF2P
2168           [(match_operand:AVXMODEF2P   1 "nonimmediate_operand" "%0, 0,x")
2169            (match_operand:AVXMODEF2P   2 "nonimmediate_operand" "xm, x,xm")
2170            (neg:AVXMODEF2P
2171              (match_operand:AVXMODEF2P 3 "nonimmediate_operand" " x,xm,0"))]
2172           UNSPEC_FMADDSUB))]
2173   "TARGET_FMA"
2174   "@
2175    vfmsubadd132<ssemodesuffix>\t{%2, %3, %0|%0, %3, %2}
2176    vfmsubadd213<ssemodesuffix>\t{%3, %2, %0|%0, %2, %3}
2177    vfmsubadd231<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
2178   [(set_attr "type" "ssemuladd")
2179    (set_attr "mode" "<MODE>")])
2180
2181 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2182 ;;
2183 ;; Non-intrinsic versions, matched when fused-multiply-add is allowed.
2184 ;;
2185 ;; ??? If fused-madd were a generic flag, combine could do this without
2186 ;; needing splitters here in the backend.  Irritatingly, combine won't
2187 ;; recognize many of these with mere splits, since only 3 or more insns
2188 ;; are allowed to split during combine.  Thankfully, there's always a
2189 ;; split_all_insns pass that runs before reload.
2190 ;;
2191 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2192
2193 (define_insn_and_split "*split_fma"
2194   [(set (match_operand:FMAMODE 0 "register_operand")
2195         (plus:FMAMODE
2196           (mult:FMAMODE
2197             (match_operand:FMAMODE 1 "nonimmediate_operand")
2198             (match_operand:FMAMODE 2 "nonimmediate_operand"))
2199           (match_operand:FMAMODE 3 "nonimmediate_operand")))]
2200   "TARGET_SSE_MATH && TARGET_FUSED_MADD
2201    && (TARGET_FMA || TARGET_FMA4)
2202    && !(reload_in_progress || reload_completed)"
2203   { gcc_unreachable (); }
2204   "&& 1"
2205   [(set (match_dup 0)
2206         (fma:FMAMODE
2207           (match_dup 1)
2208           (match_dup 2)
2209           (match_dup 3)))]
2210   "")
2211
2212 ;; Floating multiply and subtract.
2213 (define_insn_and_split "*split_fms"
2214   [(set (match_operand:FMAMODE 0 "register_operand")
2215         (minus:FMAMODE
2216           (mult:FMAMODE
2217             (match_operand:FMAMODE 1 "nonimmediate_operand")
2218             (match_operand:FMAMODE 2 "nonimmediate_operand"))
2219           (match_operand:FMAMODE 3 "nonimmediate_operand")))]
2220   "TARGET_SSE_MATH && TARGET_FUSED_MADD
2221    && (TARGET_FMA || TARGET_FMA4)
2222    && !(reload_in_progress || reload_completed)"
2223   { gcc_unreachable (); }
2224   "&& 1"
2225   [(set (match_dup 0)
2226         (fma:FMAMODE
2227           (match_dup 1)
2228           (match_dup 2)
2229           (neg:FMAMODE (match_dup 3))))]
2230   "")
2231
2232 ;; Floating point negative multiply and add.
2233 ;; Recognize (-a * b + c) via the canonical form: c - (a * b).
2234 (define_insn_and_split "*split_fnma"
2235   [(set (match_operand:FMAMODE 0 "register_operand")
2236         (minus:FMAMODE
2237          (match_operand:FMAMODE 3 "nonimmediate_operand")
2238          (mult:FMAMODE
2239           (match_operand:FMAMODE 1 "nonimmediate_operand")
2240           (match_operand:FMAMODE 2 "nonimmediate_operand"))))]
2241   "TARGET_SSE_MATH && TARGET_FUSED_MADD
2242    && (TARGET_FMA || TARGET_FMA4)
2243    && !(reload_in_progress || reload_completed)"
2244   { gcc_unreachable (); }
2245   "&& 1"
2246   [(set (match_dup 0)
2247         (fma:FMAMODE
2248           (neg:FMAMODE (match_dup 1))
2249           (match_dup 2)
2250           (match_dup 3)))]
2251   "")
2252
2253 ;; Floating point negative multiply and subtract.
2254 ;; Recognize (-a * b - c) via the canonical form: c - (-a * b).
2255 (define_insn_and_split "*split_fnms"
2256   [(set (match_operand:FMAMODE 0 "register_operand")
2257         (minus:FMAMODE
2258           (mult:FMAMODE
2259             (neg:FMAMODE
2260               (match_operand:FMAMODE 1 "nonimmediate_operand"))
2261             (match_operand:FMAMODE 2 "nonimmediate_operand"))
2262          (match_operand:FMAMODE 3 "nonimmediate_operand")))]
2263   "TARGET_SSE_MATH && TARGET_FUSED_MADD
2264    && (TARGET_FMA || TARGET_FMA4)
2265    && !(reload_in_progress || reload_completed)"
2266   { gcc_unreachable (); }
2267   "&& 1"
2268   [(set (match_dup 0)
2269         (fma:FMAMODE
2270           (neg:FMAMODE (match_dup 1))
2271           (match_dup 2)
2272           (neg:FMAMODE (match_dup 3))))]
2273   "")
2274
2275 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2276 ;;
2277 ;; Parallel single-precision floating point conversion operations
2278 ;;
2279 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2280
2281 (define_insn "sse_cvtpi2ps"
2282   [(set (match_operand:V4SF 0 "register_operand" "=x")
2283         (vec_merge:V4SF
2284           (vec_duplicate:V4SF
2285             (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
2286           (match_operand:V4SF 1 "register_operand" "0")
2287           (const_int 3)))]
2288   "TARGET_SSE"
2289   "cvtpi2ps\t{%2, %0|%0, %2}"
2290   [(set_attr "type" "ssecvt")
2291    (set_attr "mode" "V4SF")])
2292
2293 (define_insn "sse_cvtps2pi"
2294   [(set (match_operand:V2SI 0 "register_operand" "=y")
2295         (vec_select:V2SI
2296           (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
2297                        UNSPEC_FIX_NOTRUNC)
2298           (parallel [(const_int 0) (const_int 1)])))]
2299   "TARGET_SSE"
2300   "cvtps2pi\t{%1, %0|%0, %1}"
2301   [(set_attr "type" "ssecvt")
2302    (set_attr "unit" "mmx")
2303    (set_attr "mode" "DI")])
2304
2305 (define_insn "sse_cvttps2pi"
2306   [(set (match_operand:V2SI 0 "register_operand" "=y")
2307         (vec_select:V2SI
2308           (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
2309           (parallel [(const_int 0) (const_int 1)])))]
2310   "TARGET_SSE"
2311   "cvttps2pi\t{%1, %0|%0, %1}"
2312   [(set_attr "type" "ssecvt")
2313    (set_attr "unit" "mmx")
2314    (set_attr "prefix_rep" "0")
2315    (set_attr "mode" "SF")])
2316
2317 (define_insn "*avx_cvtsi2ss"
2318   [(set (match_operand:V4SF 0 "register_operand" "=x")
2319         (vec_merge:V4SF
2320           (vec_duplicate:V4SF
2321             (float:SF (match_operand:SI 2 "nonimmediate_operand" "rm")))
2322           (match_operand:V4SF 1 "register_operand" "x")
2323           (const_int 1)))]
2324   "TARGET_AVX"
2325   "vcvtsi2ss\t{%2, %1, %0|%0, %1, %2}"
2326   [(set_attr "type" "sseicvt")
2327    (set_attr "prefix" "vex")
2328    (set_attr "mode" "SF")])
2329
2330 (define_insn "sse_cvtsi2ss"
2331   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
2332         (vec_merge:V4SF
2333           (vec_duplicate:V4SF
2334             (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,m")))
2335           (match_operand:V4SF 1 "register_operand" "0,0")
2336           (const_int 1)))]
2337   "TARGET_SSE"
2338   "cvtsi2ss\t{%2, %0|%0, %2}"
2339   [(set_attr "type" "sseicvt")
2340    (set_attr "athlon_decode" "vector,double")
2341    (set_attr "amdfam10_decode" "vector,double")
2342    (set_attr "bdver1_decode" "double,direct")
2343    (set_attr "mode" "SF")])
2344
2345 (define_insn "*avx_cvtsi2ssq"
2346   [(set (match_operand:V4SF 0 "register_operand" "=x")
2347         (vec_merge:V4SF
2348           (vec_duplicate:V4SF
2349             (float:SF (match_operand:DI 2 "nonimmediate_operand" "rm")))
2350           (match_operand:V4SF 1 "register_operand" "x")
2351           (const_int 1)))]
2352   "TARGET_AVX && TARGET_64BIT"
2353   "vcvtsi2ssq\t{%2, %1, %0|%0, %1, %2}"
2354   [(set_attr "type" "sseicvt")
2355    (set_attr "length_vex" "4")
2356    (set_attr "prefix" "vex")
2357    (set_attr "mode" "SF")])
2358
2359 (define_insn "sse_cvtsi2ssq"
2360   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
2361         (vec_merge:V4SF
2362           (vec_duplicate:V4SF
2363             (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
2364           (match_operand:V4SF 1 "register_operand" "0,0")
2365           (const_int 1)))]
2366   "TARGET_SSE && TARGET_64BIT"
2367   "cvtsi2ssq\t{%2, %0|%0, %2}"
2368   [(set_attr "type" "sseicvt")
2369    (set_attr "prefix_rex" "1")
2370    (set_attr "athlon_decode" "vector,double")
2371    (set_attr "amdfam10_decode" "vector,double")
2372    (set_attr "bdver1_decode" "double,direct")
2373    (set_attr "mode" "SF")])
2374
2375 (define_insn "sse_cvtss2si"
2376   [(set (match_operand:SI 0 "register_operand" "=r,r")
2377         (unspec:SI
2378           [(vec_select:SF
2379              (match_operand:V4SF 1 "nonimmediate_operand" "x,m")
2380              (parallel [(const_int 0)]))]
2381           UNSPEC_FIX_NOTRUNC))]
2382   "TARGET_SSE"
2383   "%vcvtss2si\t{%1, %0|%0, %1}"
2384   [(set_attr "type" "sseicvt")
2385    (set_attr "athlon_decode" "double,vector")
2386    (set_attr "bdver1_decode" "double,double")
2387    (set_attr "prefix_rep" "1")
2388    (set_attr "prefix" "maybe_vex")
2389    (set_attr "mode" "SI")])
2390
2391 (define_insn "sse_cvtss2si_2"
2392   [(set (match_operand:SI 0 "register_operand" "=r,r")
2393         (unspec:SI [(match_operand:SF 1 "nonimmediate_operand" "x,m")]
2394                    UNSPEC_FIX_NOTRUNC))]
2395   "TARGET_SSE"
2396   "%vcvtss2si\t{%1, %0|%0, %1}"
2397   [(set_attr "type" "sseicvt")
2398    (set_attr "athlon_decode" "double,vector")
2399    (set_attr "amdfam10_decode" "double,double")
2400    (set_attr "bdver1_decode" "double,double")
2401    (set_attr "prefix_rep" "1")
2402    (set_attr "prefix" "maybe_vex")
2403    (set_attr "mode" "SI")])
2404
2405 (define_insn "sse_cvtss2siq"
2406   [(set (match_operand:DI 0 "register_operand" "=r,r")
2407         (unspec:DI
2408           [(vec_select:SF
2409              (match_operand:V4SF 1 "nonimmediate_operand" "x,m")
2410              (parallel [(const_int 0)]))]
2411           UNSPEC_FIX_NOTRUNC))]
2412   "TARGET_SSE && TARGET_64BIT"
2413   "%vcvtss2si{q}\t{%1, %0|%0, %1}"
2414   [(set_attr "type" "sseicvt")
2415    (set_attr "athlon_decode" "double,vector")
2416    (set_attr "bdver1_decode" "double,double")
2417    (set_attr "prefix_rep" "1")
2418    (set_attr "prefix" "maybe_vex")
2419    (set_attr "mode" "DI")])
2420
2421 (define_insn "sse_cvtss2siq_2"
2422   [(set (match_operand:DI 0 "register_operand" "=r,r")
2423         (unspec:DI [(match_operand:SF 1 "nonimmediate_operand" "x,m")]
2424                    UNSPEC_FIX_NOTRUNC))]
2425   "TARGET_SSE && TARGET_64BIT"
2426   "%vcvtss2si{q}\t{%1, %0|%0, %1}"
2427   [(set_attr "type" "sseicvt")
2428    (set_attr "athlon_decode" "double,vector")
2429    (set_attr "amdfam10_decode" "double,double")
2430    (set_attr "bdver1_decode" "double,double")
2431    (set_attr "prefix_rep" "1")
2432    (set_attr "prefix" "maybe_vex")
2433    (set_attr "mode" "DI")])
2434
2435 (define_insn "sse_cvttss2si"
2436   [(set (match_operand:SI 0 "register_operand" "=r,r")
2437         (fix:SI
2438           (vec_select:SF
2439             (match_operand:V4SF 1 "nonimmediate_operand" "x,m")
2440             (parallel [(const_int 0)]))))]
2441   "TARGET_SSE"
2442   "%vcvttss2si\t{%1, %0|%0, %1}"
2443   [(set_attr "type" "sseicvt")
2444    (set_attr "athlon_decode" "double,vector")
2445    (set_attr "amdfam10_decode" "double,double")
2446    (set_attr "bdver1_decode" "double,double")
2447    (set_attr "prefix_rep" "1")
2448    (set_attr "prefix" "maybe_vex")
2449    (set_attr "mode" "SI")])
2450
2451 (define_insn "sse_cvttss2siq"
2452   [(set (match_operand:DI 0 "register_operand" "=r,r")
2453         (fix:DI
2454           (vec_select:SF
2455             (match_operand:V4SF 1 "nonimmediate_operand" "x,m")
2456             (parallel [(const_int 0)]))))]
2457   "TARGET_SSE && TARGET_64BIT"
2458   "%vcvttss2si{q}\t{%1, %0|%0, %1}"
2459   [(set_attr "type" "sseicvt")
2460    (set_attr "athlon_decode" "double,vector")
2461    (set_attr "amdfam10_decode" "double,double")
2462    (set_attr "bdver1_decode" "double,double")
2463    (set_attr "prefix_rep" "1")
2464    (set_attr "prefix" "maybe_vex")
2465    (set_attr "mode" "DI")])
2466
2467 (define_insn "avx_cvtdq2ps<avxmodesuffix>"
2468   [(set (match_operand:AVXMODEDCVTDQ2PS 0 "register_operand" "=x")
2469         (float:AVXMODEDCVTDQ2PS
2470           (match_operand:<avxcvtvecmode> 1 "nonimmediate_operand" "xm")))]
2471   "TARGET_AVX"
2472   "vcvtdq2ps\t{%1, %0|%0, %1}"
2473   [(set_attr "type" "ssecvt")
2474    (set_attr "prefix" "vex")
2475    (set_attr "mode" "<avxvecmode>")])
2476
2477 (define_insn "sse2_cvtdq2ps"
2478   [(set (match_operand:V4SF 0 "register_operand" "=x")
2479         (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
2480   "TARGET_SSE2"
2481   "cvtdq2ps\t{%1, %0|%0, %1}"
2482   [(set_attr "type" "ssecvt")
2483    (set_attr "mode" "V4SF")])
2484
2485 (define_expand "sse2_cvtudq2ps"
2486   [(set (match_dup 5)
2487         (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "")))
2488    (set (match_dup 6)
2489         (lt:V4SF (match_dup 5) (match_dup 3)))
2490    (set (match_dup 7)
2491         (and:V4SF (match_dup 6) (match_dup 4)))
2492    (set (match_operand:V4SF 0 "register_operand" "")
2493         (plus:V4SF (match_dup 5) (match_dup 7)))]
2494   "TARGET_SSE2"
2495 {
2496   REAL_VALUE_TYPE TWO32r;
2497   rtx x;
2498   int i;
2499
2500   real_ldexp (&TWO32r, &dconst1, 32);
2501   x = const_double_from_real_value (TWO32r, SFmode);
2502
2503   operands[3] = force_reg (V4SFmode, CONST0_RTX (V4SFmode));
2504   operands[4] = force_reg (V4SFmode,
2505                            ix86_build_const_vector (V4SFmode, 1, x));
2506
2507   for (i = 5; i < 8; i++)
2508     operands[i] = gen_reg_rtx (V4SFmode);
2509 })
2510
2511 (define_insn "avx_cvtps2dq<avxmodesuffix>"
2512   [(set (match_operand:AVXMODEDCVTPS2DQ 0 "register_operand" "=x")
2513         (unspec:AVXMODEDCVTPS2DQ
2514           [(match_operand:<avxcvtvecmode> 1 "nonimmediate_operand" "xm")]
2515           UNSPEC_FIX_NOTRUNC))]
2516   "TARGET_AVX"
2517   "vcvtps2dq\t{%1, %0|%0, %1}"
2518   [(set_attr "type" "ssecvt")
2519    (set_attr "prefix" "vex")
2520    (set_attr "mode" "<avxvecmode>")])
2521
2522 (define_insn "sse2_cvtps2dq"
2523   [(set (match_operand:V4SI 0 "register_operand" "=x")
2524         (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
2525                      UNSPEC_FIX_NOTRUNC))]
2526   "TARGET_SSE2"
2527   "cvtps2dq\t{%1, %0|%0, %1}"
2528   [(set_attr "type" "ssecvt")
2529    (set_attr "prefix_data16" "1")
2530    (set_attr "mode" "TI")])
2531
2532 (define_insn "avx_cvttps2dq<avxmodesuffix>"
2533   [(set (match_operand:AVXMODEDCVTPS2DQ 0 "register_operand" "=x")
2534         (fix:AVXMODEDCVTPS2DQ
2535           (match_operand:<avxcvtvecmode> 1 "nonimmediate_operand" "xm")))]
2536   "TARGET_AVX"
2537   "vcvttps2dq\t{%1, %0|%0, %1}"
2538   [(set_attr "type" "ssecvt")
2539    (set_attr "prefix" "vex")
2540    (set_attr "mode" "<avxvecmode>")])
2541
2542 (define_insn "sse2_cvttps2dq"
2543   [(set (match_operand:V4SI 0 "register_operand" "=x")
2544         (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
2545   "TARGET_SSE2"
2546   "cvttps2dq\t{%1, %0|%0, %1}"
2547   [(set_attr "type" "ssecvt")
2548    (set_attr "prefix_rep" "1")
2549    (set_attr "prefix_data16" "0")
2550    (set_attr "mode" "TI")])
2551
2552 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2553 ;;
2554 ;; Parallel double-precision floating point conversion operations
2555 ;;
2556 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2557
2558 (define_insn "sse2_cvtpi2pd"
2559   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
2560         (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "y,m")))]
2561   "TARGET_SSE2"
2562   "cvtpi2pd\t{%1, %0|%0, %1}"
2563   [(set_attr "type" "ssecvt")
2564    (set_attr "unit" "mmx,*")
2565    (set_attr "prefix_data16" "1,*")
2566    (set_attr "mode" "V2DF")])
2567
2568 (define_insn "sse2_cvtpd2pi"
2569   [(set (match_operand:V2SI 0 "register_operand" "=y")
2570         (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
2571                      UNSPEC_FIX_NOTRUNC))]
2572   "TARGET_SSE2"
2573   "cvtpd2pi\t{%1, %0|%0, %1}"
2574   [(set_attr "type" "ssecvt")
2575    (set_attr "unit" "mmx")
2576    (set_attr "prefix_data16" "1")
2577    (set_attr "mode" "DI")
2578    (set_attr "bdver1_decode" "double")])
2579
2580 (define_insn "sse2_cvttpd2pi"
2581   [(set (match_operand:V2SI 0 "register_operand" "=y")
2582         (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
2583   "TARGET_SSE2"
2584   "cvttpd2pi\t{%1, %0|%0, %1}"
2585   [(set_attr "type" "ssecvt")
2586    (set_attr "unit" "mmx")
2587    (set_attr "prefix_data16" "1")
2588    (set_attr "mode" "TI")
2589    (set_attr "bdver1_decode" "double")])
2590
2591 (define_insn "*avx_cvtsi2sd"
2592   [(set (match_operand:V2DF 0 "register_operand" "=x")
2593         (vec_merge:V2DF
2594           (vec_duplicate:V2DF
2595             (float:DF (match_operand:SI 2 "nonimmediate_operand" "rm")))
2596           (match_operand:V2DF 1 "register_operand" "x")
2597           (const_int 1)))]
2598   "TARGET_AVX"
2599   "vcvtsi2sd\t{%2, %1, %0|%0, %1, %2}"
2600   [(set_attr "type" "sseicvt")
2601    (set_attr "prefix" "vex")
2602    (set_attr "mode" "DF")])
2603
2604 (define_insn "sse2_cvtsi2sd"
2605   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
2606         (vec_merge:V2DF
2607           (vec_duplicate:V2DF
2608             (float:DF (match_operand:SI 2 "nonimmediate_operand" "r,m")))
2609           (match_operand:V2DF 1 "register_operand" "0,0")
2610           (const_int 1)))]
2611   "TARGET_SSE2"
2612   "cvtsi2sd\t{%2, %0|%0, %2}"
2613   [(set_attr "type" "sseicvt")
2614    (set_attr "mode" "DF")
2615    (set_attr "athlon_decode" "double,direct")
2616    (set_attr "amdfam10_decode" "vector,double")
2617    (set_attr "bdver1_decode" "double,direct")])
2618
2619 (define_insn "*avx_cvtsi2sdq"
2620   [(set (match_operand:V2DF 0 "register_operand" "=x")
2621         (vec_merge:V2DF
2622           (vec_duplicate:V2DF
2623             (float:DF (match_operand:DI 2 "nonimmediate_operand" "rm")))
2624           (match_operand:V2DF 1 "register_operand" "x")
2625           (const_int 1)))]
2626   "TARGET_AVX && TARGET_64BIT"
2627   "vcvtsi2sdq\t{%2, %1, %0|%0, %1, %2}"
2628   [(set_attr "type" "sseicvt")
2629    (set_attr "length_vex" "4")
2630    (set_attr "prefix" "vex")
2631    (set_attr "mode" "DF")])
2632
2633 (define_insn "sse2_cvtsi2sdq"
2634   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
2635         (vec_merge:V2DF
2636           (vec_duplicate:V2DF
2637             (float:DF (match_operand:DI 2 "nonimmediate_operand" "r,m")))
2638           (match_operand:V2DF 1 "register_operand" "0,0")
2639           (const_int 1)))]
2640   "TARGET_SSE2 && TARGET_64BIT"
2641   "cvtsi2sdq\t{%2, %0|%0, %2}"
2642   [(set_attr "type" "sseicvt")
2643    (set_attr "prefix_rex" "1")
2644    (set_attr "mode" "DF")
2645    (set_attr "athlon_decode" "double,direct")
2646    (set_attr "amdfam10_decode" "vector,double")
2647    (set_attr "bdver1_decode" "double,direct")])
2648
2649 (define_insn "sse2_cvtsd2si"
2650   [(set (match_operand:SI 0 "register_operand" "=r,r")
2651         (unspec:SI
2652           [(vec_select:DF
2653              (match_operand:V2DF 1 "nonimmediate_operand" "x,m")
2654              (parallel [(const_int 0)]))]
2655           UNSPEC_FIX_NOTRUNC))]
2656   "TARGET_SSE2"
2657   "%vcvtsd2si\t{%1, %0|%0, %1}"
2658   [(set_attr "type" "sseicvt")
2659    (set_attr "athlon_decode" "double,vector")
2660    (set_attr "bdver1_decode" "double,double")
2661    (set_attr "prefix_rep" "1")
2662    (set_attr "prefix" "maybe_vex")
2663    (set_attr "mode" "SI")])
2664
2665 (define_insn "sse2_cvtsd2si_2"
2666   [(set (match_operand:SI 0 "register_operand" "=r,r")
2667         (unspec:SI [(match_operand:DF 1 "nonimmediate_operand" "x,m")]
2668                    UNSPEC_FIX_NOTRUNC))]
2669   "TARGET_SSE2"
2670   "%vcvtsd2si\t{%1, %0|%0, %1}"
2671   [(set_attr "type" "sseicvt")
2672    (set_attr "athlon_decode" "double,vector")
2673    (set_attr "amdfam10_decode" "double,double")
2674    (set_attr "bdver1_decode" "double,double")
2675    (set_attr "prefix_rep" "1")
2676    (set_attr "prefix" "maybe_vex")
2677    (set_attr "mode" "SI")])
2678
2679 (define_insn "sse2_cvtsd2siq"
2680   [(set (match_operand:DI 0 "register_operand" "=r,r")
2681         (unspec:DI
2682           [(vec_select:DF
2683              (match_operand:V2DF 1 "nonimmediate_operand" "x,m")
2684              (parallel [(const_int 0)]))]
2685           UNSPEC_FIX_NOTRUNC))]
2686   "TARGET_SSE2 && TARGET_64BIT"
2687   "%vcvtsd2siq\t{%1, %0|%0, %1}"
2688   [(set_attr "type" "sseicvt")
2689    (set_attr "athlon_decode" "double,vector")
2690    (set_attr "bdver1_decode" "double,double")
2691    (set_attr "prefix_rep" "1")
2692    (set_attr "prefix" "maybe_vex")
2693    (set_attr "mode" "DI")])
2694
2695 (define_insn "sse2_cvtsd2siq_2"
2696   [(set (match_operand:DI 0 "register_operand" "=r,r")
2697         (unspec:DI [(match_operand:DF 1 "nonimmediate_operand" "x,m")]
2698                    UNSPEC_FIX_NOTRUNC))]
2699   "TARGET_SSE2 && TARGET_64BIT"
2700   "%vcvtsd2siq\t{%1, %0|%0, %1}"
2701   [(set_attr "type" "sseicvt")
2702    (set_attr "athlon_decode" "double,vector")
2703    (set_attr "amdfam10_decode" "double,double")
2704    (set_attr "bdver1_decode" "double,double")
2705    (set_attr "prefix_rep" "1")
2706    (set_attr "prefix" "maybe_vex")
2707    (set_attr "mode" "DI")])
2708
2709 (define_insn "sse2_cvttsd2si"
2710   [(set (match_operand:SI 0 "register_operand" "=r,r")
2711         (fix:SI
2712           (vec_select:DF
2713             (match_operand:V2DF 1 "nonimmediate_operand" "x,m")
2714             (parallel [(const_int 0)]))))]
2715   "TARGET_SSE2"
2716   "%vcvttsd2si\t{%1, %0|%0, %1}"
2717   [(set_attr "type" "sseicvt")
2718    (set_attr "prefix_rep" "1")
2719    (set_attr "prefix" "maybe_vex")
2720    (set_attr "mode" "SI")
2721    (set_attr "athlon_decode" "double,vector")
2722    (set_attr "amdfam10_decode" "double,double")
2723    (set_attr "bdver1_decode" "double,double")])
2724
2725 (define_insn "sse2_cvttsd2siq"
2726   [(set (match_operand:DI 0 "register_operand" "=r,r")
2727         (fix:DI
2728           (vec_select:DF
2729             (match_operand:V2DF 1 "nonimmediate_operand" "x,m")
2730             (parallel [(const_int 0)]))))]
2731   "TARGET_SSE2 && TARGET_64BIT"
2732   "%vcvttsd2siq\t{%1, %0|%0, %1}"
2733   [(set_attr "type" "sseicvt")
2734    (set_attr "prefix_rep" "1")
2735    (set_attr "prefix" "maybe_vex")
2736    (set_attr "mode" "DI")
2737    (set_attr "athlon_decode" "double,vector")
2738    (set_attr "amdfam10_decode" "double,double")
2739    (set_attr "bdver1_decode" "double,double")])
2740
2741 (define_insn "avx_cvtdq2pd256"
2742   [(set (match_operand:V4DF 0 "register_operand" "=x")
2743         (float:V4DF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
2744   "TARGET_AVX"
2745   "vcvtdq2pd\t{%1, %0|%0, %1}"
2746   [(set_attr "type" "ssecvt")
2747    (set_attr "prefix" "vex")
2748    (set_attr "mode" "V4DF")])
2749
2750 (define_insn "*avx_cvtdq2pd256_2"
2751   [(set (match_operand:V4DF 0 "register_operand" "=x")
2752         (float:V4DF
2753           (vec_select:V4SI
2754             (match_operand:V8SI 1 "nonimmediate_operand" "xm")
2755             (parallel [(const_int 0) (const_int 1) (const_int 2) (const_int 3)]))))]
2756   "TARGET_AVX"
2757   "vcvtdq2pd\t{%x1, %0|%0, %x1}"
2758   [(set_attr "type" "ssecvt")
2759    (set_attr "prefix" "vex")
2760    (set_attr "mode" "V4DF")])
2761
2762 (define_insn "sse2_cvtdq2pd"
2763   [(set (match_operand:V2DF 0 "register_operand" "=x")
2764         (float:V2DF
2765           (vec_select:V2SI
2766             (match_operand:V4SI 1 "nonimmediate_operand" "xm")
2767             (parallel [(const_int 0) (const_int 1)]))))]
2768   "TARGET_SSE2"
2769   "%vcvtdq2pd\t{%1, %0|%0, %1}"
2770   [(set_attr "type" "ssecvt")
2771    (set_attr "prefix" "maybe_vex")
2772    (set_attr "mode" "V2DF")])
2773
2774 (define_insn "avx_cvtpd2dq256"
2775   [(set (match_operand:V4SI 0 "register_operand" "=x")
2776         (unspec:V4SI [(match_operand:V4DF 1 "nonimmediate_operand" "xm")]
2777                      UNSPEC_FIX_NOTRUNC))]
2778   "TARGET_AVX"
2779   "vcvtpd2dq{y}\t{%1, %0|%0, %1}"
2780   [(set_attr "type" "ssecvt")
2781    (set_attr "prefix" "vex")
2782    (set_attr "mode" "OI")])
2783
2784 (define_expand "sse2_cvtpd2dq"
2785   [(set (match_operand:V4SI 0 "register_operand" "")
2786         (vec_concat:V4SI
2787           (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "")]
2788                        UNSPEC_FIX_NOTRUNC)
2789           (match_dup 2)))]
2790   "TARGET_SSE2"
2791   "operands[2] = CONST0_RTX (V2SImode);")
2792
2793 (define_insn "*sse2_cvtpd2dq"
2794   [(set (match_operand:V4SI 0 "register_operand" "=x")
2795         (vec_concat:V4SI
2796           (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
2797                        UNSPEC_FIX_NOTRUNC)
2798           (match_operand:V2SI 2 "const0_operand" "")))]
2799   "TARGET_SSE2"
2800   "* return TARGET_AVX ? \"vcvtpd2dq{x}\t{%1, %0|%0, %1}\"
2801                        : \"cvtpd2dq\t{%1, %0|%0, %1}\";"
2802   [(set_attr "type" "ssecvt")
2803    (set_attr "prefix_rep" "1")
2804    (set_attr "prefix_data16" "0")
2805    (set_attr "prefix" "maybe_vex")
2806    (set_attr "mode" "TI")
2807    (set_attr "amdfam10_decode" "double")
2808    (set_attr "bdver1_decode" "double")])
2809
2810 (define_insn "avx_cvttpd2dq256"
2811   [(set (match_operand:V4SI 0 "register_operand" "=x")
2812         (fix:V4SI (match_operand:V4DF 1 "nonimmediate_operand" "xm")))]
2813   "TARGET_AVX"
2814   "vcvttpd2dq{y}\t{%1, %0|%0, %1}"
2815   [(set_attr "type" "ssecvt")
2816    (set_attr "prefix" "vex")
2817    (set_attr "mode" "OI")])
2818
2819 (define_expand "sse2_cvttpd2dq"
2820   [(set (match_operand:V4SI 0 "register_operand" "")
2821         (vec_concat:V4SI
2822           (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" ""))
2823           (match_dup 2)))]
2824   "TARGET_SSE2"
2825   "operands[2] = CONST0_RTX (V2SImode);")
2826
2827 (define_insn "*sse2_cvttpd2dq"
2828   [(set (match_operand:V4SI 0 "register_operand" "=x")
2829         (vec_concat:V4SI
2830           (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
2831           (match_operand:V2SI 2 "const0_operand" "")))]
2832   "TARGET_SSE2"
2833   "* return TARGET_AVX ? \"vcvttpd2dq{x}\t{%1, %0|%0, %1}\"
2834                        : \"cvttpd2dq\t{%1, %0|%0, %1}\";"
2835   [(set_attr "type" "ssecvt")
2836    (set_attr "prefix" "maybe_vex")
2837    (set_attr "mode" "TI")
2838    (set_attr "amdfam10_decode" "double")
2839    (set_attr "bdver1_decode" "double")])
2840
2841 (define_insn "*avx_cvtsd2ss"
2842   [(set (match_operand:V4SF 0 "register_operand" "=x")
2843         (vec_merge:V4SF
2844           (vec_duplicate:V4SF
2845             (float_truncate:V2SF
2846               (match_operand:V2DF 2 "nonimmediate_operand" "xm")))
2847           (match_operand:V4SF 1 "register_operand" "x")
2848           (const_int 1)))]
2849   "TARGET_AVX"
2850   "vcvtsd2ss\t{%2, %1, %0|%0, %1, %2}"
2851   [(set_attr "type" "ssecvt")
2852    (set_attr "prefix" "vex")
2853    (set_attr "mode" "SF")])
2854
2855 (define_insn "sse2_cvtsd2ss"
2856   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
2857         (vec_merge:V4SF
2858           (vec_duplicate:V4SF
2859             (float_truncate:V2SF
2860               (match_operand:V2DF 2 "nonimmediate_operand" "x,m")))
2861           (match_operand:V4SF 1 "register_operand" "0,0")
2862           (const_int 1)))]
2863   "TARGET_SSE2"
2864   "cvtsd2ss\t{%2, %0|%0, %2}"
2865   [(set_attr "type" "ssecvt")
2866    (set_attr "athlon_decode" "vector,double")
2867    (set_attr "amdfam10_decode" "vector,double")
2868    (set_attr "bdver1_decode" "direct,direct")
2869    (set_attr "mode" "SF")])
2870
2871 (define_insn "*avx_cvtss2sd"
2872   [(set (match_operand:V2DF 0 "register_operand" "=x")
2873         (vec_merge:V2DF
2874           (float_extend:V2DF
2875             (vec_select:V2SF
2876               (match_operand:V4SF 2 "nonimmediate_operand" "xm")
2877               (parallel [(const_int 0) (const_int 1)])))
2878           (match_operand:V2DF 1 "register_operand" "x")
2879           (const_int 1)))]
2880   "TARGET_AVX"
2881   "vcvtss2sd\t{%2, %1, %0|%0, %1, %2}"
2882   [(set_attr "type" "ssecvt")
2883    (set_attr "prefix" "vex")
2884    (set_attr "mode" "DF")])
2885
2886 (define_insn "sse2_cvtss2sd"
2887   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
2888         (vec_merge:V2DF
2889           (float_extend:V2DF
2890             (vec_select:V2SF
2891               (match_operand:V4SF 2 "nonimmediate_operand" "x,m")
2892               (parallel [(const_int 0) (const_int 1)])))
2893           (match_operand:V2DF 1 "register_operand" "0,0")
2894           (const_int 1)))]
2895   "TARGET_SSE2"
2896   "cvtss2sd\t{%2, %0|%0, %2}"
2897   [(set_attr "type" "ssecvt")
2898    (set_attr "amdfam10_decode" "vector,double")
2899    (set_attr "bdver1_decode" "direct,direct")
2900    (set_attr "mode" "DF")])
2901
2902 (define_insn "avx_cvtpd2ps256"
2903   [(set (match_operand:V4SF 0 "register_operand" "=x")
2904         (float_truncate:V4SF
2905           (match_operand:V4DF 1 "nonimmediate_operand" "xm")))]
2906   "TARGET_AVX"
2907   "vcvtpd2ps{y}\t{%1, %0|%0, %1}"
2908   [(set_attr "type" "ssecvt")
2909    (set_attr "prefix" "vex")
2910    (set_attr "mode" "V4SF")])
2911
2912 (define_expand "sse2_cvtpd2ps"
2913   [(set (match_operand:V4SF 0 "register_operand" "")
2914         (vec_concat:V4SF
2915           (float_truncate:V2SF
2916             (match_operand:V2DF 1 "nonimmediate_operand" ""))
2917           (match_dup 2)))]
2918   "TARGET_SSE2"
2919   "operands[2] = CONST0_RTX (V2SFmode);")
2920
2921 (define_insn "*sse2_cvtpd2ps"
2922   [(set (match_operand:V4SF 0 "register_operand" "=x")
2923         (vec_concat:V4SF
2924           (float_truncate:V2SF
2925             (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
2926           (match_operand:V2SF 2 "const0_operand" "")))]
2927   "TARGET_SSE2"
2928   "* return TARGET_AVX ? \"vcvtpd2ps{x}\t{%1, %0|%0, %1}\"
2929                        : \"cvtpd2ps\t{%1, %0|%0, %1}\";"
2930   [(set_attr "type" "ssecvt")
2931    (set_attr "prefix_data16" "1")
2932    (set_attr "prefix" "maybe_vex")
2933    (set_attr "mode" "V4SF")
2934    (set_attr "amdfam10_decode" "double")
2935    (set_attr "bdver1_decode" "double")])
2936
2937 (define_insn "avx_cvtps2pd256"
2938   [(set (match_operand:V4DF 0 "register_operand" "=x")
2939         (float_extend:V4DF
2940           (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
2941   "TARGET_AVX"
2942   "vcvtps2pd\t{%1, %0|%0, %1}"
2943   [(set_attr "type" "ssecvt")
2944    (set_attr "prefix" "vex")
2945    (set_attr "mode" "V4DF")])
2946
2947 (define_insn "*avx_cvtps2pd256_2"
2948   [(set (match_operand:V4DF 0 "register_operand" "=x")
2949         (float_extend:V4DF
2950           (vec_select:V4SF
2951             (match_operand:V8SF 1 "nonimmediate_operand" "xm")
2952             (parallel [(const_int 0) (const_int 1) (const_int 2) (const_int 3)]))))]
2953   "TARGET_AVX"
2954   "vcvtps2pd\t{%x1, %0|%0, %x1}"
2955   [(set_attr "type" "ssecvt")
2956    (set_attr "prefix" "vex")
2957    (set_attr "mode" "V4DF")])
2958
2959 (define_insn "sse2_cvtps2pd"
2960   [(set (match_operand:V2DF 0 "register_operand" "=x")
2961         (float_extend:V2DF
2962           (vec_select:V2SF
2963             (match_operand:V4SF 1 "nonimmediate_operand" "xm")
2964             (parallel [(const_int 0) (const_int 1)]))))]
2965   "TARGET_SSE2"
2966   "%vcvtps2pd\t{%1, %0|%0, %1}"
2967   [(set_attr "type" "ssecvt")
2968    (set_attr "prefix" "maybe_vex")
2969    (set_attr "mode" "V2DF")
2970    (set_attr "prefix_data16" "0")
2971    (set_attr "amdfam10_decode" "direct")
2972    (set_attr "bdver1_decode" "double")])
2973
2974 (define_expand "vec_unpacks_hi_v4sf"
2975   [(set (match_dup 2)
2976    (vec_select:V4SF
2977      (vec_concat:V8SF
2978        (match_dup 2)
2979        (match_operand:V4SF 1 "nonimmediate_operand" ""))
2980      (parallel [(const_int 6)
2981                 (const_int 7)
2982                 (const_int 2)
2983                 (const_int 3)])))
2984   (set (match_operand:V2DF 0 "register_operand" "")
2985    (float_extend:V2DF
2986      (vec_select:V2SF
2987        (match_dup 2)
2988        (parallel [(const_int 0) (const_int 1)]))))]
2989   "TARGET_SSE2"
2990   "operands[2] = gen_reg_rtx (V4SFmode);")
2991
2992 (define_expand "vec_unpacks_hi_v8sf"
2993   [(set (match_dup 2)
2994         (vec_select:V4SF
2995           (match_operand:V8SF 1 "nonimmediate_operand" "")
2996           (parallel [(const_int 4)
2997                      (const_int 5)
2998                      (const_int 6)
2999                      (const_int 7)])))
3000    (set (match_operand:V4DF 0 "register_operand" "")
3001         (float_extend:V4DF
3002           (match_dup 2)))]
3003   "TARGET_AVX"
3004 {
3005   operands[2] = gen_reg_rtx (V4SFmode);
3006 })
3007
3008 (define_expand "vec_unpacks_lo_v4sf"
3009   [(set (match_operand:V2DF 0 "register_operand" "")
3010         (float_extend:V2DF
3011           (vec_select:V2SF
3012             (match_operand:V4SF 1 "nonimmediate_operand" "")
3013             (parallel [(const_int 0) (const_int 1)]))))]
3014   "TARGET_SSE2")
3015
3016 (define_expand "vec_unpacks_lo_v8sf"
3017   [(set (match_operand:V4DF 0 "register_operand" "")
3018         (float_extend:V4DF
3019           (vec_select:V4SF
3020             (match_operand:V8SF 1 "nonimmediate_operand" "")
3021             (parallel [(const_int 0) (const_int 1) (const_int 2) (const_int 3)]))))]
3022   "TARGET_AVX")
3023
3024 (define_expand "vec_unpacks_float_hi_v8hi"
3025   [(match_operand:V4SF 0 "register_operand" "")
3026    (match_operand:V8HI 1 "register_operand" "")]
3027   "TARGET_SSE2"
3028 {
3029   rtx tmp = gen_reg_rtx (V4SImode);
3030
3031   emit_insn (gen_vec_unpacks_hi_v8hi (tmp, operands[1]));
3032   emit_insn (gen_sse2_cvtdq2ps (operands[0], tmp));
3033   DONE;
3034 })
3035
3036 (define_expand "vec_unpacks_float_lo_v8hi"
3037   [(match_operand:V4SF 0 "register_operand" "")
3038    (match_operand:V8HI 1 "register_operand" "")]
3039   "TARGET_SSE2"
3040 {
3041   rtx tmp = gen_reg_rtx (V4SImode);
3042
3043   emit_insn (gen_vec_unpacks_lo_v8hi (tmp, operands[1]));
3044   emit_insn (gen_sse2_cvtdq2ps (operands[0], tmp));
3045   DONE;
3046 })
3047
3048 (define_expand "vec_unpacku_float_hi_v8hi"
3049   [(match_operand:V4SF 0 "register_operand" "")
3050    (match_operand:V8HI 1 "register_operand" "")]
3051   "TARGET_SSE2"
3052 {
3053   rtx tmp = gen_reg_rtx (V4SImode);
3054
3055   emit_insn (gen_vec_unpacku_hi_v8hi (tmp, operands[1]));
3056   emit_insn (gen_sse2_cvtdq2ps (operands[0], tmp));
3057   DONE;
3058 })
3059
3060 (define_expand "vec_unpacku_float_lo_v8hi"
3061   [(match_operand:V4SF 0 "register_operand" "")
3062    (match_operand:V8HI 1 "register_operand" "")]
3063   "TARGET_SSE2"
3064 {
3065   rtx tmp = gen_reg_rtx (V4SImode);
3066
3067   emit_insn (gen_vec_unpacku_lo_v8hi (tmp, operands[1]));
3068   emit_insn (gen_sse2_cvtdq2ps (operands[0], tmp));
3069   DONE;
3070 })
3071
3072 (define_expand "vec_unpacks_float_hi_v4si"
3073   [(set (match_dup 2)
3074         (vec_select:V4SI
3075           (match_operand:V4SI 1 "nonimmediate_operand" "")
3076           (parallel [(const_int 2)
3077                      (const_int 3)
3078                      (const_int 2)
3079                      (const_int 3)])))
3080    (set (match_operand:V2DF 0 "register_operand" "")
3081         (float:V2DF
3082           (vec_select:V2SI
3083           (match_dup 2)
3084             (parallel [(const_int 0) (const_int 1)]))))]
3085   "TARGET_SSE2"
3086   "operands[2] = gen_reg_rtx (V4SImode);")
3087
3088 (define_expand "vec_unpacks_float_lo_v4si"
3089   [(set (match_operand:V2DF 0 "register_operand" "")
3090         (float:V2DF
3091           (vec_select:V2SI
3092             (match_operand:V4SI 1 "nonimmediate_operand" "")
3093             (parallel [(const_int 0) (const_int 1)]))))]
3094   "TARGET_SSE2")
3095
3096 (define_expand "vec_unpacks_float_hi_v8si"
3097   [(set (match_dup 2)
3098         (vec_select:V4SI
3099           (match_operand:V8SI 1 "nonimmediate_operand" "")
3100           (parallel [(const_int 4)
3101                      (const_int 5)
3102                      (const_int 6)
3103                      (const_int 7)])))
3104    (set (match_operand:V4DF 0 "register_operand" "")
3105         (float:V4DF
3106           (match_dup 2)))]
3107   "TARGET_AVX"
3108   "operands[2] = gen_reg_rtx (V4SImode);")
3109
3110 (define_expand "vec_unpacks_float_lo_v8si"
3111   [(set (match_operand:V4DF 0 "register_operand" "")
3112         (float:V4DF
3113           (vec_select:V4SI
3114             (match_operand:V8SI 1 "nonimmediate_operand" "")
3115             (parallel [(const_int 0) (const_int 1) (const_int 2) (const_int 3)]))))]
3116   "TARGET_AVX")
3117
3118 (define_expand "vec_unpacku_float_hi_v4si"
3119   [(set (match_dup 5)
3120         (vec_select:V4SI
3121           (match_operand:V4SI 1 "nonimmediate_operand" "")
3122           (parallel [(const_int 2)
3123                      (const_int 3)
3124                      (const_int 2)
3125                      (const_int 3)])))
3126    (set (match_dup 6)
3127         (float:V2DF
3128           (vec_select:V2SI
3129           (match_dup 5)
3130             (parallel [(const_int 0) (const_int 1)]))))
3131    (set (match_dup 7)
3132         (lt:V2DF (match_dup 6) (match_dup 3)))
3133    (set (match_dup 8)
3134         (and:V2DF (match_dup 7) (match_dup 4)))
3135    (set (match_operand:V2DF 0 "register_operand" "")
3136         (plus:V2DF (match_dup 6) (match_dup 8)))]
3137   "TARGET_SSE2"
3138 {
3139   REAL_VALUE_TYPE TWO32r;
3140   rtx x;
3141   int i;
3142
3143   real_ldexp (&TWO32r, &dconst1, 32);
3144   x = const_double_from_real_value (TWO32r, DFmode);
3145
3146   operands[3] = force_reg (V2DFmode, CONST0_RTX (V2DFmode));
3147   operands[4] = force_reg (V2DFmode,
3148                            ix86_build_const_vector (V2DFmode, 1, x));
3149
3150   operands[5] = gen_reg_rtx (V4SImode);
3151  
3152   for (i = 6; i < 9; i++)
3153     operands[i] = gen_reg_rtx (V2DFmode);
3154 })
3155
3156 (define_expand "vec_unpacku_float_lo_v4si"
3157   [(set (match_dup 5)
3158         (float:V2DF
3159           (vec_select:V2SI
3160             (match_operand:V4SI 1 "nonimmediate_operand" "")
3161             (parallel [(const_int 0) (const_int 1)]))))
3162    (set (match_dup 6)
3163         (lt:V2DF (match_dup 5) (match_dup 3)))
3164    (set (match_dup 7)
3165         (and:V2DF (match_dup 6) (match_dup 4)))
3166    (set (match_operand:V2DF 0 "register_operand" "")
3167         (plus:V2DF (match_dup 5) (match_dup 7)))]
3168   "TARGET_SSE2"
3169 {
3170   REAL_VALUE_TYPE TWO32r;
3171   rtx x;
3172   int i;
3173
3174   real_ldexp (&TWO32r, &dconst1, 32);
3175   x = const_double_from_real_value (TWO32r, DFmode);
3176
3177   operands[3] = force_reg (V2DFmode, CONST0_RTX (V2DFmode));
3178   operands[4] = force_reg (V2DFmode,
3179                            ix86_build_const_vector (V2DFmode, 1, x));
3180
3181   for (i = 5; i < 8; i++)
3182     operands[i] = gen_reg_rtx (V2DFmode);
3183 })
3184
3185 (define_expand "vec_pack_trunc_v4df"
3186   [(set (match_dup 3)
3187         (float_truncate:V4SF
3188           (match_operand:V4DF 1 "nonimmediate_operand" "")))
3189    (set (match_dup 4)
3190         (float_truncate:V4SF
3191           (match_operand:V4DF 2 "nonimmediate_operand" "")))
3192    (set (match_operand:V8SF 0 "register_operand" "")
3193         (vec_concat:V8SF
3194           (match_dup 3)
3195           (match_dup 4)))]
3196   "TARGET_AVX"
3197 {
3198   operands[3] = gen_reg_rtx (V4SFmode);
3199   operands[4] = gen_reg_rtx (V4SFmode);
3200 })
3201
3202 (define_expand "vec_pack_trunc_v2df"
3203   [(match_operand:V4SF 0 "register_operand" "")
3204    (match_operand:V2DF 1 "nonimmediate_operand" "")
3205    (match_operand:V2DF 2 "nonimmediate_operand" "")]
3206   "TARGET_SSE2"
3207 {
3208   rtx r1, r2;
3209
3210   r1 = gen_reg_rtx (V4SFmode);
3211   r2 = gen_reg_rtx (V4SFmode);
3212
3213   emit_insn (gen_sse2_cvtpd2ps (r1, operands[1]));
3214   emit_insn (gen_sse2_cvtpd2ps (r2, operands[2]));
3215   emit_insn (gen_sse_movlhps (operands[0], r1, r2));
3216   DONE;
3217 })
3218
3219 (define_expand "vec_pack_sfix_trunc_v2df"
3220   [(match_operand:V4SI 0 "register_operand" "")
3221    (match_operand:V2DF 1 "nonimmediate_operand" "")
3222    (match_operand:V2DF 2 "nonimmediate_operand" "")]
3223   "TARGET_SSE2"
3224 {
3225   rtx r1, r2;
3226
3227   r1 = gen_reg_rtx (V4SImode);
3228   r2 = gen_reg_rtx (V4SImode);
3229
3230   emit_insn (gen_sse2_cvttpd2dq (r1, operands[1]));
3231   emit_insn (gen_sse2_cvttpd2dq (r2, operands[2]));
3232   emit_insn (gen_vec_interleave_lowv2di (gen_lowpart (V2DImode, operands[0]),
3233                                          gen_lowpart (V2DImode, r1),
3234                                          gen_lowpart (V2DImode, r2)));
3235   DONE;
3236 })
3237
3238 (define_expand "vec_pack_sfix_v2df"
3239   [(match_operand:V4SI 0 "register_operand" "")
3240    (match_operand:V2DF 1 "nonimmediate_operand" "")
3241    (match_operand:V2DF 2 "nonimmediate_operand" "")]
3242   "TARGET_SSE2"
3243 {
3244   rtx r1, r2;
3245
3246   r1 = gen_reg_rtx (V4SImode);
3247   r2 = gen_reg_rtx (V4SImode);
3248
3249   emit_insn (gen_sse2_cvtpd2dq (r1, operands[1]));
3250   emit_insn (gen_sse2_cvtpd2dq (r2, operands[2]));
3251   emit_insn (gen_vec_interleave_lowv2di (gen_lowpart (V2DImode, operands[0]),
3252                                          gen_lowpart (V2DImode, r1),
3253                                          gen_lowpart (V2DImode, r2)));
3254   DONE;
3255 })
3256
3257 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3258 ;;
3259 ;; Parallel single-precision floating point element swizzling
3260 ;;
3261 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3262
3263 (define_expand "sse_movhlps_exp"
3264   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
3265         (vec_select:V4SF
3266           (vec_concat:V8SF
3267             (match_operand:V4SF 1 "nonimmediate_operand" "")
3268             (match_operand:V4SF 2 "nonimmediate_operand" ""))
3269           (parallel [(const_int 6)
3270                      (const_int 7)
3271                      (const_int 2)
3272                      (const_int 3)])))]
3273   "TARGET_SSE"
3274 {
3275   rtx dst = ix86_fixup_binary_operands (UNKNOWN, V4SFmode, operands);
3276   
3277   emit_insn (gen_sse_movhlps (dst, operands[1], operands[2]));
3278
3279   /* Fix up the destination if needed.  */
3280   if (dst != operands[0])
3281     emit_move_insn (operands[0], dst);
3282
3283   DONE;
3284 })
3285
3286 (define_insn "*avx_movhlps"
3287   [(set (match_operand:V4SF 0 "nonimmediate_operand"     "=x,x,m")
3288         (vec_select:V4SF
3289           (vec_concat:V8SF
3290             (match_operand:V4SF 1 "nonimmediate_operand" " x,x,0")
3291             (match_operand:V4SF 2 "nonimmediate_operand" " x,o,x"))
3292           (parallel [(const_int 6)
3293                      (const_int 7)
3294                      (const_int 2)
3295                      (const_int 3)])))]
3296   "TARGET_AVX && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
3297   "@
3298    vmovhlps\t{%2, %1, %0|%0, %1, %2}
3299    vmovlps\t{%H2, %1, %0|%0, %1, %H2}
3300    vmovhps\t{%2, %0|%0, %2}"
3301   [(set_attr "type" "ssemov")
3302    (set_attr "prefix" "vex")
3303    (set_attr "mode" "V4SF,V2SF,V2SF")])
3304
3305 (define_insn "sse_movhlps"
3306   [(set (match_operand:V4SF 0 "nonimmediate_operand"     "=x,x,m")
3307         (vec_select:V4SF
3308           (vec_concat:V8SF
3309             (match_operand:V4SF 1 "nonimmediate_operand" " 0,0,0")
3310             (match_operand:V4SF 2 "nonimmediate_operand" " x,o,x"))
3311           (parallel [(const_int 6)
3312                      (const_int 7)
3313                      (const_int 2)
3314                      (const_int 3)])))]
3315   "TARGET_SSE && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
3316   "@
3317    movhlps\t{%2, %0|%0, %2}
3318    movlps\t{%H2, %0|%0, %H2}
3319    movhps\t{%2, %0|%0, %2}"
3320   [(set_attr "type" "ssemov")
3321    (set_attr "mode" "V4SF,V2SF,V2SF")])
3322
3323 (define_expand "sse_movlhps_exp"
3324   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
3325         (vec_select:V4SF
3326           (vec_concat:V8SF
3327             (match_operand:V4SF 1 "nonimmediate_operand" "")
3328             (match_operand:V4SF 2 "nonimmediate_operand" ""))
3329           (parallel [(const_int 0)
3330                      (const_int 1)
3331                      (const_int 4)
3332                      (const_int 5)])))]
3333   "TARGET_SSE"
3334 {
3335   rtx dst = ix86_fixup_binary_operands (UNKNOWN, V4SFmode, operands);
3336   
3337   emit_insn (gen_sse_movlhps (dst, operands[1], operands[2]));
3338
3339   /* Fix up the destination if needed.  */
3340   if (dst != operands[0])
3341     emit_move_insn (operands[0], dst);
3342
3343   DONE;
3344 })
3345
3346 (define_insn "*avx_movlhps"
3347   [(set (match_operand:V4SF 0 "nonimmediate_operand"     "=x,x,o")
3348         (vec_select:V4SF
3349           (vec_concat:V8SF
3350             (match_operand:V4SF 1 "nonimmediate_operand" " x,x,0")
3351             (match_operand:V4SF 2 "nonimmediate_operand" " x,m,x"))
3352           (parallel [(const_int 0)
3353                      (const_int 1)
3354                      (const_int 4)
3355                      (const_int 5)])))]
3356   "TARGET_AVX && ix86_binary_operator_ok (UNKNOWN, V4SFmode, operands)"
3357   "@
3358    vmovlhps\t{%2, %1, %0|%0, %1, %2}
3359    vmovhps\t{%2, %1, %0|%0, %1, %2}
3360    vmovlps\t{%2, %H0|%H0, %2}"
3361   [(set_attr "type" "ssemov")
3362    (set_attr "prefix" "vex")
3363    (set_attr "mode" "V4SF,V2SF,V2SF")])
3364
3365 (define_insn "sse_movlhps"
3366   [(set (match_operand:V4SF 0 "nonimmediate_operand"     "=x,x,o")
3367         (vec_select:V4SF
3368           (vec_concat:V8SF
3369             (match_operand:V4SF 1 "nonimmediate_operand" " 0,0,0")
3370             (match_operand:V4SF 2 "nonimmediate_operand" " x,m,x"))
3371           (parallel [(const_int 0)
3372                      (const_int 1)
3373                      (const_int 4)
3374                      (const_int 5)])))]
3375   "TARGET_SSE && ix86_binary_operator_ok (UNKNOWN, V4SFmode, operands)"
3376   "@
3377    movlhps\t{%2, %0|%0, %2}
3378    movhps\t{%2, %0|%0, %2}
3379    movlps\t{%2, %H0|%H0, %2}"
3380   [(set_attr "type" "ssemov")
3381    (set_attr "mode" "V4SF,V2SF,V2SF")])
3382
3383 ;; Recall that the 256-bit unpck insns only shuffle within their lanes.
3384 (define_insn "avx_unpckhps256"
3385   [(set (match_operand:V8SF 0 "register_operand" "=x")
3386         (vec_select:V8SF
3387           (vec_concat:V16SF
3388             (match_operand:V8SF 1 "register_operand" "x")
3389             (match_operand:V8SF 2 "nonimmediate_operand" "xm"))
3390           (parallel [(const_int 2) (const_int 10)
3391                      (const_int 3) (const_int 11)
3392                      (const_int 6) (const_int 14)
3393                      (const_int 7) (const_int 15)])))]
3394   "TARGET_AVX"
3395   "vunpckhps\t{%2, %1, %0|%0, %1, %2}"
3396   [(set_attr "type" "sselog")
3397    (set_attr "prefix" "vex")
3398    (set_attr "mode" "V8SF")])
3399
3400 (define_insn "*avx_interleave_highv4sf"
3401   [(set (match_operand:V4SF 0 "register_operand" "=x")
3402         (vec_select:V4SF
3403           (vec_concat:V8SF
3404             (match_operand:V4SF 1 "register_operand" "x")
3405             (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
3406           (parallel [(const_int 2) (const_int 6)
3407                      (const_int 3) (const_int 7)])))]
3408   "TARGET_AVX"
3409   "vunpckhps\t{%2, %1, %0|%0, %1, %2}"
3410   [(set_attr "type" "sselog")
3411    (set_attr "prefix" "vex")
3412    (set_attr "mode" "V4SF")])
3413
3414 (define_expand "vec_interleave_highv8sf"
3415   [(set (match_dup 3)
3416         (vec_select:V8SF
3417           (vec_concat:V16SF
3418             (match_operand:V8SF 1 "register_operand" "x")
3419             (match_operand:V8SF 2 "nonimmediate_operand" "xm"))
3420           (parallel [(const_int 0) (const_int 8)
3421                      (const_int 1) (const_int 9)
3422                      (const_int 4) (const_int 12)
3423                      (const_int 5) (const_int 13)])))
3424    (set (match_dup 4)
3425         (vec_select:V8SF
3426           (vec_concat:V16SF
3427             (match_dup 1)
3428             (match_dup 2))
3429           (parallel [(const_int 2) (const_int 10)
3430                      (const_int 3) (const_int 11)
3431                      (const_int 6) (const_int 14)
3432                      (const_int 7) (const_int 15)])))
3433    (set (match_operand:V8SF 0 "register_operand" "")
3434         (vec_select:V8SF
3435           (vec_concat:V16SF
3436             (match_dup 3)
3437             (match_dup 4))
3438           (parallel [(const_int 4) (const_int 5)
3439                      (const_int 6) (const_int 7)
3440                      (const_int 12) (const_int 13)
3441                      (const_int 14) (const_int 15)])))]
3442  "TARGET_AVX"
3443 {
3444   operands[3] = gen_reg_rtx (V8SFmode);
3445   operands[4] = gen_reg_rtx (V8SFmode);
3446 })
3447
3448 (define_insn "vec_interleave_highv4sf"
3449   [(set (match_operand:V4SF 0 "register_operand" "=x")
3450         (vec_select:V4SF
3451           (vec_concat:V8SF
3452             (match_operand:V4SF 1 "register_operand" "0")
3453             (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
3454           (parallel [(const_int 2) (const_int 6)
3455                      (const_int 3) (const_int 7)])))]
3456   "TARGET_SSE"
3457   "unpckhps\t{%2, %0|%0, %2}"
3458   [(set_attr "type" "sselog")
3459    (set_attr "mode" "V4SF")])
3460
3461 ;; Recall that the 256-bit unpck insns only shuffle within their lanes.
3462 (define_insn "avx_unpcklps256"
3463   [(set (match_operand:V8SF 0 "register_operand" "=x")
3464         (vec_select:V8SF
3465           (vec_concat:V16SF
3466             (match_operand:V8SF 1 "register_operand" "x")
3467             (match_operand:V8SF 2 "nonimmediate_operand" "xm"))
3468           (parallel [(const_int 0) (const_int 8)
3469                      (const_int 1) (const_int 9)
3470                      (const_int 4) (const_int 12)
3471                      (const_int 5) (const_int 13)])))]
3472   "TARGET_AVX"
3473   "vunpcklps\t{%2, %1, %0|%0, %1, %2}"
3474   [(set_attr "type" "sselog")
3475    (set_attr "prefix" "vex")
3476    (set_attr "mode" "V8SF")])
3477
3478 (define_insn "*avx_interleave_lowv4sf"
3479   [(set (match_operand:V4SF 0 "register_operand" "=x")
3480         (vec_select:V4SF
3481           (vec_concat:V8SF
3482             (match_operand:V4SF 1 "register_operand" "x")
3483             (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
3484           (parallel [(const_int 0) (const_int 4)
3485                      (const_int 1) (const_int 5)])))]
3486   "TARGET_AVX"
3487   "vunpcklps\t{%2, %1, %0|%0, %1, %2}"
3488   [(set_attr "type" "sselog")
3489    (set_attr "prefix" "vex")
3490    (set_attr "mode" "V4SF")])
3491
3492 (define_expand "vec_interleave_lowv8sf"
3493   [(set (match_dup 3)
3494         (vec_select:V8SF
3495           (vec_concat:V16SF
3496             (match_operand:V8SF 1 "register_operand" "x")
3497             (match_operand:V8SF 2 "nonimmediate_operand" "xm"))
3498           (parallel [(const_int 0) (const_int 8)
3499                      (const_int 1) (const_int 9)
3500                      (const_int 4) (const_int 12)
3501                      (const_int 5) (const_int 13)])))
3502    (set (match_dup 4)
3503         (vec_select:V8SF
3504           (vec_concat:V16SF
3505             (match_dup 1)
3506             (match_dup 2))
3507           (parallel [(const_int 2) (const_int 10)
3508                      (const_int 3) (const_int 11)
3509                      (const_int 6) (const_int 14)
3510                      (const_int 7) (const_int 15)])))
3511    (set (match_operand:V8SF 0 "register_operand" "")
3512         (vec_select:V8SF
3513           (vec_concat:V16SF
3514             (match_dup 3)
3515             (match_dup 4))
3516           (parallel [(const_int 0) (const_int 1)
3517                      (const_int 2) (const_int 3)
3518                      (const_int 8) (const_int 9)
3519                      (const_int 10) (const_int 11)])))]
3520  "TARGET_AVX"
3521 {
3522   operands[3] = gen_reg_rtx (V8SFmode);
3523   operands[4] = gen_reg_rtx (V8SFmode);
3524 })
3525
3526 (define_insn "vec_interleave_lowv4sf"
3527   [(set (match_operand:V4SF 0 "register_operand" "=x")
3528         (vec_select:V4SF
3529           (vec_concat:V8SF
3530             (match_operand:V4SF 1 "register_operand" "0")
3531             (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
3532           (parallel [(const_int 0) (const_int 4)
3533                      (const_int 1) (const_int 5)])))]
3534   "TARGET_SSE"
3535   "unpcklps\t{%2, %0|%0, %2}"
3536   [(set_attr "type" "sselog")
3537    (set_attr "mode" "V4SF")])
3538
3539 ;; These are modeled with the same vec_concat as the others so that we
3540 ;; capture users of shufps that can use the new instructions
3541 (define_insn "avx_movshdup256"
3542   [(set (match_operand:V8SF 0 "register_operand" "=x")
3543         (vec_select:V8SF
3544           (vec_concat:V16SF
3545             (match_operand:V8SF 1 "nonimmediate_operand" "xm")
3546             (match_dup 1))
3547           (parallel [(const_int 1) (const_int 1)
3548                      (const_int 3) (const_int 3)
3549                      (const_int 5) (const_int 5)
3550                      (const_int 7) (const_int 7)])))]
3551   "TARGET_AVX"
3552   "vmovshdup\t{%1, %0|%0, %1}"
3553   [(set_attr "type" "sse")
3554    (set_attr "prefix" "vex")
3555    (set_attr "mode" "V8SF")])
3556
3557 (define_insn "sse3_movshdup"
3558   [(set (match_operand:V4SF 0 "register_operand" "=x")
3559         (vec_select:V4SF
3560           (vec_concat:V8SF
3561             (match_operand:V4SF 1 "nonimmediate_operand" "xm")
3562             (match_dup 1))
3563           (parallel [(const_int 1)
3564                      (const_int 1)
3565                      (const_int 7)
3566                      (const_int 7)])))]
3567   "TARGET_SSE3"
3568   "%vmovshdup\t{%1, %0|%0, %1}"
3569   [(set_attr "type" "sse")
3570    (set_attr "prefix_rep" "1")
3571    (set_attr "prefix" "maybe_vex")
3572    (set_attr "mode" "V4SF")])
3573
3574 (define_insn "avx_movsldup256"
3575   [(set (match_operand:V8SF 0 "register_operand" "=x")
3576         (vec_select:V8SF
3577           (vec_concat:V16SF
3578             (match_operand:V8SF 1 "nonimmediate_operand" "xm")
3579             (match_dup 1))
3580           (parallel [(const_int 0) (const_int 0)
3581                      (const_int 2) (const_int 2)
3582                      (const_int 4) (const_int 4)
3583                      (const_int 6) (const_int 6)])))]
3584   "TARGET_AVX"
3585   "vmovsldup\t{%1, %0|%0, %1}"
3586   [(set_attr "type" "sse")
3587    (set_attr "prefix" "vex")
3588    (set_attr "mode" "V8SF")])
3589
3590 (define_insn "sse3_movsldup"
3591   [(set (match_operand:V4SF 0 "register_operand" "=x")
3592         (vec_select:V4SF
3593           (vec_concat:V8SF
3594             (match_operand:V4SF 1 "nonimmediate_operand" "xm")
3595             (match_dup 1))
3596           (parallel [(const_int 0)
3597                      (const_int 0)
3598                      (const_int 6)
3599                      (const_int 6)])))]
3600   "TARGET_SSE3"
3601   "%vmovsldup\t{%1, %0|%0, %1}"
3602   [(set_attr "type" "sse")
3603    (set_attr "prefix_rep" "1")
3604    (set_attr "prefix" "maybe_vex")
3605    (set_attr "mode" "V4SF")])
3606
3607 (define_expand "avx_shufps256"
3608   [(match_operand:V8SF 0 "register_operand" "")
3609    (match_operand:V8SF 1 "register_operand" "")
3610    (match_operand:V8SF 2 "nonimmediate_operand" "")
3611    (match_operand:SI 3 "const_int_operand" "")]
3612   "TARGET_AVX"
3613 {
3614   int mask = INTVAL (operands[3]);
3615   emit_insn (gen_avx_shufps256_1 (operands[0], operands[1], operands[2],
3616                                   GEN_INT ((mask >> 0) & 3),
3617                                   GEN_INT ((mask >> 2) & 3),
3618                                   GEN_INT (((mask >> 4) & 3) + 8),
3619                                   GEN_INT (((mask >> 6) & 3) + 8),
3620                                   GEN_INT (((mask >> 0) & 3) + 4),
3621                                   GEN_INT (((mask >> 2) & 3) + 4),
3622                                   GEN_INT (((mask >> 4) & 3) + 12),
3623                                   GEN_INT (((mask >> 6) & 3) + 12)));
3624   DONE;
3625 })
3626
3627 ;; One bit in mask selects 2 elements.
3628 (define_insn "avx_shufps256_1"
3629   [(set (match_operand:V8SF 0 "register_operand" "=x")
3630         (vec_select:V8SF
3631           (vec_concat:V16SF
3632             (match_operand:V8SF 1 "register_operand" "x")
3633             (match_operand:V8SF 2 "nonimmediate_operand" "xm"))
3634           (parallel [(match_operand 3  "const_0_to_3_operand"   "")
3635                      (match_operand 4  "const_0_to_3_operand"   "")
3636                      (match_operand 5  "const_8_to_11_operand"  "")
3637                      (match_operand 6  "const_8_to_11_operand"  "")
3638                      (match_operand 7  "const_4_to_7_operand"   "")
3639                      (match_operand 8  "const_4_to_7_operand"   "")
3640                      (match_operand 9  "const_12_to_15_operand" "")
3641                      (match_operand 10 "const_12_to_15_operand" "")])))]
3642   "TARGET_AVX
3643    && (INTVAL (operands[3]) == (INTVAL (operands[7]) - 4)
3644        && INTVAL (operands[4]) == (INTVAL (operands[8]) - 4)
3645        && INTVAL (operands[5]) == (INTVAL (operands[9]) - 4)
3646        && INTVAL (operands[6]) == (INTVAL (operands[10]) - 4))"
3647 {
3648   int mask;
3649   mask = INTVAL (operands[3]);
3650   mask |= INTVAL (operands[4]) << 2;
3651   mask |= (INTVAL (operands[5]) - 8) << 4;
3652   mask |= (INTVAL (operands[6]) - 8) << 6;
3653   operands[3] = GEN_INT (mask);
3654
3655   return "vshufps\t{%3, %2, %1, %0|%0, %1, %2, %3}";
3656 }
3657   [(set_attr "type" "sselog")
3658    (set_attr "length_immediate" "1")
3659    (set_attr "prefix" "vex")
3660    (set_attr "mode" "V8SF")])
3661
3662 (define_expand "sse_shufps"
3663   [(match_operand:V4SF 0 "register_operand" "")
3664    (match_operand:V4SF 1 "register_operand" "")
3665    (match_operand:V4SF 2 "nonimmediate_operand" "")
3666    (match_operand:SI 3 "const_int_operand" "")]
3667   "TARGET_SSE"
3668 {
3669   int mask = INTVAL (operands[3]);
3670   emit_insn (gen_sse_shufps_v4sf (operands[0], operands[1], operands[2],
3671                                GEN_INT ((mask >> 0) & 3),
3672                                GEN_INT ((mask >> 2) & 3),
3673                                GEN_INT (((mask >> 4) & 3) + 4),
3674                                GEN_INT (((mask >> 6) & 3) + 4)));
3675   DONE;
3676 })
3677
3678 (define_insn "*avx_shufps_<mode>"
3679   [(set (match_operand:SSEMODE4S 0 "register_operand" "=x")
3680         (vec_select:SSEMODE4S
3681           (vec_concat:<ssedoublesizemode>
3682             (match_operand:SSEMODE4S 1 "register_operand" "x")
3683             (match_operand:SSEMODE4S 2 "nonimmediate_operand" "xm"))
3684           (parallel [(match_operand 3 "const_0_to_3_operand" "")
3685                      (match_operand 4 "const_0_to_3_operand" "")
3686                      (match_operand 5 "const_4_to_7_operand" "")
3687                      (match_operand 6 "const_4_to_7_operand" "")])))]
3688   "TARGET_AVX"
3689 {
3690   int mask = 0;
3691   mask |= INTVAL (operands[3]) << 0;
3692   mask |= INTVAL (operands[4]) << 2;
3693   mask |= (INTVAL (operands[5]) - 4) << 4;
3694   mask |= (INTVAL (operands[6]) - 4) << 6;
3695   operands[3] = GEN_INT (mask);
3696
3697   return "vshufps\t{%3, %2, %1, %0|%0, %1, %2, %3}";
3698 }
3699   [(set_attr "type" "sselog")
3700    (set_attr "length_immediate" "1")
3701    (set_attr "prefix" "vex")
3702    (set_attr "mode" "V4SF")])
3703
3704 (define_insn "sse_shufps_<mode>"
3705   [(set (match_operand:SSEMODE4S 0 "register_operand" "=x")
3706         (vec_select:SSEMODE4S
3707           (vec_concat:<ssedoublesizemode>
3708             (match_operand:SSEMODE4S 1 "register_operand" "0")
3709             (match_operand:SSEMODE4S 2 "nonimmediate_operand" "xm"))
3710           (parallel [(match_operand 3 "const_0_to_3_operand" "")
3711                      (match_operand 4 "const_0_to_3_operand" "")
3712                      (match_operand 5 "const_4_to_7_operand" "")
3713                      (match_operand 6 "const_4_to_7_operand" "")])))]
3714   "TARGET_SSE"
3715 {
3716   int mask = 0;
3717   mask |= INTVAL (operands[3]) << 0;
3718   mask |= INTVAL (operands[4]) << 2;
3719   mask |= (INTVAL (operands[5]) - 4) << 4;
3720   mask |= (INTVAL (operands[6]) - 4) << 6;
3721   operands[3] = GEN_INT (mask);
3722
3723   return "shufps\t{%3, %2, %0|%0, %2, %3}";
3724 }
3725   [(set_attr "type" "sselog")
3726    (set_attr "length_immediate" "1")
3727    (set_attr "mode" "V4SF")])
3728
3729 (define_insn "sse_storehps"
3730   [(set (match_operand:V2SF 0 "nonimmediate_operand" "=m,x,x")
3731         (vec_select:V2SF
3732           (match_operand:V4SF 1 "nonimmediate_operand" "x,x,o")
3733           (parallel [(const_int 2) (const_int 3)])))]
3734   "TARGET_SSE"
3735   "@
3736    %vmovhps\t{%1, %0|%0, %1}
3737    %vmovhlps\t{%1, %d0|%d0, %1}
3738    %vmovlps\t{%H1, %d0|%d0, %H1}"
3739   [(set_attr "type" "ssemov")
3740    (set_attr "prefix" "maybe_vex")
3741    (set_attr "mode" "V2SF,V4SF,V2SF")])
3742
3743 (define_expand "sse_loadhps_exp"
3744   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
3745         (vec_concat:V4SF
3746           (vec_select:V2SF
3747             (match_operand:V4SF 1 "nonimmediate_operand" "")
3748             (parallel [(const_int 0) (const_int 1)]))
3749           (match_operand:V2SF 2 "nonimmediate_operand" "")))]
3750   "TARGET_SSE"
3751 {
3752   rtx dst = ix86_fixup_binary_operands (UNKNOWN, V4SFmode, operands);
3753   
3754   emit_insn (gen_sse_loadhps (dst, operands[1], operands[2]));
3755
3756   /* Fix up the destination if needed.  */
3757   if (dst != operands[0])
3758     emit_move_insn (operands[0], dst);
3759
3760   DONE;
3761 })
3762
3763 (define_insn "*avx_loadhps"
3764   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,o")
3765         (vec_concat:V4SF
3766           (vec_select:V2SF
3767             (match_operand:V4SF 1 "nonimmediate_operand" "x,x,0")
3768             (parallel [(const_int 0) (const_int 1)]))
3769           (match_operand:V2SF 2 "nonimmediate_operand" "m,x,x")))]
3770   "TARGET_AVX"
3771   "@
3772    vmovhps\t{%2, %1, %0|%0, %1, %2}
3773    vmovlhps\t{%2, %1, %0|%0, %1, %2}
3774    vmovlps\t{%2, %H0|%H0, %2}"
3775   [(set_attr "type" "ssemov")
3776    (set_attr "prefix" "vex")
3777    (set_attr "mode" "V2SF,V4SF,V2SF")])
3778
3779 (define_insn "sse_loadhps"
3780   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,o")
3781         (vec_concat:V4SF
3782           (vec_select:V2SF
3783             (match_operand:V4SF 1 "nonimmediate_operand" "0,0,0")
3784             (parallel [(const_int 0) (const_int 1)]))
3785           (match_operand:V2SF 2 "nonimmediate_operand" "m,x,x")))]
3786   "TARGET_SSE"
3787   "@
3788    movhps\t{%2, %0|%0, %2}
3789    movlhps\t{%2, %0|%0, %2}
3790    movlps\t{%2, %H0|%H0, %2}"
3791   [(set_attr "type" "ssemov")
3792    (set_attr "mode" "V2SF,V4SF,V2SF")])
3793
3794 (define_insn "*avx_storelps"
3795   [(set (match_operand:V2SF 0 "nonimmediate_operand" "=m,x,x")
3796         (vec_select:V2SF
3797           (match_operand:V4SF 1 "nonimmediate_operand" "x,x,m")
3798           (parallel [(const_int 0) (const_int 1)])))]
3799   "TARGET_AVX"
3800   "@
3801    vmovlps\t{%1, %0|%0, %1}
3802    vmovaps\t{%1, %0|%0, %1}
3803    vmovlps\t{%1, %0, %0|%0, %0, %1}"
3804   [(set_attr "type" "ssemov")
3805    (set_attr "prefix" "vex")
3806    (set_attr "mode" "V2SF,V2DF,V2SF")])
3807
3808 (define_insn "sse_storelps"
3809   [(set (match_operand:V2SF 0 "nonimmediate_operand" "=m,x,x")
3810         (vec_select:V2SF
3811           (match_operand:V4SF 1 "nonimmediate_operand" "x,x,m")
3812           (parallel [(const_int 0) (const_int 1)])))]
3813   "TARGET_SSE"
3814   "@
3815    movlps\t{%1, %0|%0, %1}
3816    movaps\t{%1, %0|%0, %1}
3817    movlps\t{%1, %0|%0, %1}"
3818   [(set_attr "type" "ssemov")
3819    (set_attr "mode" "V2SF,V4SF,V2SF")])
3820
3821 (define_expand "sse_loadlps_exp"
3822   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
3823         (vec_concat:V4SF
3824           (match_operand:V2SF 2 "nonimmediate_operand" "")
3825           (vec_select:V2SF
3826             (match_operand:V4SF 1 "nonimmediate_operand" "")
3827             (parallel [(const_int 2) (const_int 3)]))))]
3828   "TARGET_SSE"
3829 {
3830   rtx dst = ix86_fixup_binary_operands (UNKNOWN, V4SFmode, operands);
3831   
3832   emit_insn (gen_sse_loadlps (dst, operands[1], operands[2]));
3833
3834   /* Fix up the destination if needed.  */
3835   if (dst != operands[0])
3836     emit_move_insn (operands[0], dst);
3837
3838   DONE;
3839 })
3840
3841 (define_insn "*avx_loadlps"
3842   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
3843         (vec_concat:V4SF
3844           (match_operand:V2SF 2 "nonimmediate_operand" "x,m,x")
3845           (vec_select:V2SF
3846             (match_operand:V4SF 1 "nonimmediate_operand" "x,x,0")
3847             (parallel [(const_int 2) (const_int 3)]))))]
3848   "TARGET_AVX"
3849   "@
3850    shufps\t{$0xe4, %1, %2, %0|%0, %2, %1, 0xe4}
3851    vmovlps\t{%2, %1, %0|%0, %1, %2}
3852    vmovlps\t{%2, %0|%0, %2}"
3853   [(set_attr "type" "sselog,ssemov,ssemov")
3854    (set_attr "length_immediate" "1,*,*")
3855    (set_attr "prefix" "vex")
3856    (set_attr "mode" "V4SF,V2SF,V2SF")])
3857
3858 (define_insn "sse_loadlps"
3859   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
3860         (vec_concat:V4SF
3861           (match_operand:V2SF 2 "nonimmediate_operand" "0,m,x")
3862           (vec_select:V2SF
3863             (match_operand:V4SF 1 "nonimmediate_operand" "x,0,0")
3864             (parallel [(const_int 2) (const_int 3)]))))]
3865   "TARGET_SSE"
3866   "@
3867    shufps\t{$0xe4, %1, %0|%0, %1, 0xe4}
3868    movlps\t{%2, %0|%0, %2}
3869    movlps\t{%2, %0|%0, %2}"
3870   [(set_attr "type" "sselog,ssemov,ssemov")
3871    (set_attr "length_immediate" "1,*,*")
3872    (set_attr "mode" "V4SF,V2SF,V2SF")])
3873
3874 (define_insn "*avx_movss"
3875   [(set (match_operand:V4SF 0 "register_operand" "=x")
3876         (vec_merge:V4SF
3877           (match_operand:V4SF 2 "register_operand" "x")
3878           (match_operand:V4SF 1 "register_operand" "x")
3879           (const_int 1)))]
3880   "TARGET_AVX"
3881   "vmovss\t{%2, %1, %0|%0, %1, %2}"
3882   [(set_attr "type" "ssemov")
3883    (set_attr "prefix" "vex")
3884    (set_attr "mode" "SF")])
3885
3886 (define_insn "sse_movss"
3887   [(set (match_operand:V4SF 0 "register_operand" "=x")
3888         (vec_merge:V4SF
3889           (match_operand:V4SF 2 "register_operand" "x")
3890           (match_operand:V4SF 1 "register_operand" "0")
3891           (const_int 1)))]
3892   "TARGET_SSE"
3893   "movss\t{%2, %0|%0, %2}"
3894   [(set_attr "type" "ssemov")
3895    (set_attr "mode" "SF")])
3896
3897 (define_expand "vec_dupv4sf"
3898   [(set (match_operand:V4SF 0 "register_operand" "")
3899         (vec_duplicate:V4SF
3900           (match_operand:SF 1 "nonimmediate_operand" "")))]
3901   "TARGET_SSE"
3902 {
3903   if (!TARGET_AVX)
3904     operands[1] = force_reg (V4SFmode, operands[1]);
3905 })
3906
3907 (define_insn "*vec_dupv4sf_avx"
3908   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
3909         (vec_duplicate:V4SF
3910           (match_operand:SF 1 "nonimmediate_operand" "x,m")))]
3911   "TARGET_AVX"
3912   "@
3913    vshufps\t{$0, %1, %1, %0|%0, %1, %1, 0}
3914    vbroadcastss\t{%1, %0|%0, %1}"
3915   [(set_attr "type" "sselog1,ssemov")
3916    (set_attr "length_immediate" "1,0")
3917    (set_attr "prefix_extra" "0,1")
3918    (set_attr "prefix" "vex")
3919    (set_attr "mode" "V4SF")])
3920
3921 (define_insn "*vec_dupv4sf"
3922   [(set (match_operand:V4SF 0 "register_operand" "=x")
3923         (vec_duplicate:V4SF
3924           (match_operand:SF 1 "register_operand" "0")))]
3925   "TARGET_SSE"
3926   "shufps\t{$0, %0, %0|%0, %0, 0}"
3927   [(set_attr "type" "sselog1")
3928    (set_attr "length_immediate" "1")
3929    (set_attr "mode" "V4SF")])
3930
3931 (define_insn "*vec_concatv2sf_avx"
3932   [(set (match_operand:V2SF 0 "register_operand"     "=x,x,x,*y ,*y")
3933         (vec_concat:V2SF
3934           (match_operand:SF 1 "nonimmediate_operand" " x,x,m, x , m")
3935           (match_operand:SF 2 "vector_move_operand"  " x,m,C,*ym, C")))]
3936   "TARGET_AVX"
3937   "@
3938    vunpcklps\t{%2, %1, %0|%0, %1, %2}
3939    vinsertps\t{$0x10, %2, %1, %0|%0, %1, %2, 0x10}
3940    vmovss\t{%1, %0|%0, %1}
3941    punpckldq\t{%2, %0|%0, %2}
3942    movd\t{%1, %0|%0, %1}"
3943   [(set_attr "type" "sselog,sselog,ssemov,mmxcvt,mmxmov")
3944    (set_attr "length_immediate" "*,1,*,*,*")
3945    (set_attr "prefix_extra" "*,1,*,*,*")
3946    (set (attr "prefix")
3947      (if_then_else (eq_attr "alternative" "3,4")
3948        (const_string "orig")
3949        (const_string "vex")))
3950    (set_attr "mode" "V4SF,V4SF,SF,DI,DI")])
3951
3952 ;; Although insertps takes register source, we prefer
3953 ;; unpcklps with register source since it is shorter.
3954 (define_insn "*vec_concatv2sf_sse4_1"
3955   [(set (match_operand:V2SF 0 "register_operand"     "=x,x,x,*y ,*y")
3956         (vec_concat:V2SF
3957           (match_operand:SF 1 "nonimmediate_operand" " 0,0,m, 0 , m")
3958           (match_operand:SF 2 "vector_move_operand"  " x,m,C,*ym, C")))]
3959   "TARGET_SSE4_1"
3960   "@
3961    unpcklps\t{%2, %0|%0, %2}
3962    insertps\t{$0x10, %2, %0|%0, %2, 0x10}
3963    movss\t{%1, %0|%0, %1}
3964    punpckldq\t{%2, %0|%0, %2}
3965    movd\t{%1, %0|%0, %1}"
3966   [(set_attr "type" "sselog,sselog,ssemov,mmxcvt,mmxmov")
3967    (set_attr "prefix_data16" "*,1,*,*,*")
3968    (set_attr "prefix_extra" "*,1,*,*,*")
3969    (set_attr "length_immediate" "*,1,*,*,*")
3970    (set_attr "mode" "V4SF,V4SF,SF,DI,DI")])
3971
3972 ;; ??? In theory we can match memory for the MMX alternative, but allowing
3973 ;; nonimmediate_operand for operand 2 and *not* allowing memory for the SSE
3974 ;; alternatives pretty much forces the MMX alternative to be chosen.
3975 (define_insn "*vec_concatv2sf_sse"
3976   [(set (match_operand:V2SF 0 "register_operand"     "=x,x,*y,*y")
3977         (vec_concat:V2SF
3978           (match_operand:SF 1 "nonimmediate_operand" " 0,m, 0, m")
3979           (match_operand:SF 2 "reg_or_0_operand"     " x,C,*y, C")))]
3980   "TARGET_SSE"
3981   "@
3982    unpcklps\t{%2, %0|%0, %2}
3983    movss\t{%1, %0|%0, %1}
3984    punpckldq\t{%2, %0|%0, %2}
3985    movd\t{%1, %0|%0, %1}"
3986   [(set_attr "type" "sselog,ssemov,mmxcvt,mmxmov")
3987    (set_attr "mode" "V4SF,SF,DI,DI")])
3988
3989 (define_insn "*vec_concatv4sf_avx"
3990   [(set (match_operand:V4SF 0 "register_operand"   "=x,x")
3991         (vec_concat:V4SF
3992           (match_operand:V2SF 1 "register_operand" " x,x")
3993           (match_operand:V2SF 2 "nonimmediate_operand" " x,m")))]
3994   "TARGET_AVX"
3995   "@
3996    vmovlhps\t{%2, %1, %0|%0, %1, %2}
3997    vmovhps\t{%2, %1, %0|%0, %1, %2}"
3998   [(set_attr "type" "ssemov")
3999    (set_attr "prefix" "vex")
4000    (set_attr "mode" "V4SF,V2SF")])
4001
4002 (define_insn "*vec_concatv4sf_sse"
4003   [(set (match_operand:V4SF 0 "register_operand"   "=x,x")
4004         (vec_concat:V4SF
4005           (match_operand:V2SF 1 "register_operand" " 0,0")
4006           (match_operand:V2SF 2 "nonimmediate_operand" " x,m")))]
4007   "TARGET_SSE"
4008   "@
4009    movlhps\t{%2, %0|%0, %2}
4010    movhps\t{%2, %0|%0, %2}"
4011   [(set_attr "type" "ssemov")
4012    (set_attr "mode" "V4SF,V2SF")])
4013
4014 (define_expand "vec_init<mode>"
4015   [(match_operand:SSEMODE 0 "register_operand" "")
4016    (match_operand 1 "" "")]
4017   "TARGET_SSE"
4018 {
4019   ix86_expand_vector_init (false, operands[0], operands[1]);
4020   DONE;
4021 })
4022
4023 (define_insn "*vec_set<mode>_0_avx"
4024   [(set (match_operand:SSEMODE4S 0 "nonimmediate_operand"  "=x,x, x,x,  x,m")
4025         (vec_merge:SSEMODE4S
4026           (vec_duplicate:SSEMODE4S
4027             (match_operand:<ssescalarmode> 2
4028               "general_operand"                            " x,m,*r,x,*rm,x*rfF"))
4029           (match_operand:SSEMODE4S 1 "vector_move_operand" " C,C, C,x,  x,0")
4030           (const_int 1)))]
4031   "TARGET_AVX"
4032   "@
4033    vinsertps\t{$0xe, %2, %2, %0|%0, %2, %2, 0xe}
4034    vmov<ssescalarmodesuffix>\t{%2, %0|%0, %2}
4035    vmovd\t{%2, %0|%0, %2}
4036    vmovss\t{%2, %1, %0|%0, %1, %2}
4037    vpinsrd\t{$0, %2, %1, %0|%0, %1, %2, 0}
4038    #"
4039   [(set_attr "type" "sselog,ssemov,ssemov,ssemov,sselog,*")
4040    (set_attr "prefix_extra" "*,*,*,*,1,*")
4041    (set_attr "length_immediate" "*,*,*,*,1,*")
4042    (set_attr "prefix" "vex")
4043    (set_attr "mode" "SF,<ssescalarmode>,SI,SF,TI,*")])
4044
4045 (define_insn "*vec_set<mode>_0_sse4_1"
4046   [(set (match_operand:SSEMODE4S 0 "nonimmediate_operand"  "=x,x, x,x,  x,m")
4047         (vec_merge:SSEMODE4S
4048           (vec_duplicate:SSEMODE4S
4049             (match_operand:<ssescalarmode> 2
4050               "general_operand"                            " x,m,*r,x,*rm,*rfF"))
4051           (match_operand:SSEMODE4S 1 "vector_move_operand" " C,C, C,0,  0,0")
4052           (const_int 1)))]
4053   "TARGET_SSE4_1"
4054   "@
4055    insertps\t{$0xe, %2, %0|%0, %2, 0xe}
4056    mov<ssescalarmodesuffix>\t{%2, %0|%0, %2}
4057    movd\t{%2, %0|%0, %2}
4058    movss\t{%2, %0|%0, %2}
4059    pinsrd\t{$0, %2, %0|%0, %2, 0}
4060    #"
4061   [(set_attr "type" "sselog,ssemov,ssemov,ssemov,sselog,*")
4062    (set_attr "prefix_extra" "*,*,*,*,1,*")
4063    (set_attr "length_immediate" "*,*,*,*,1,*")
4064    (set_attr "mode" "SF,<ssescalarmode>,SI,SF,TI,*")])
4065
4066 (define_insn "*vec_set<mode>_0_sse2"
4067   [(set (match_operand:SSEMODE4S 0 "nonimmediate_operand"  "=x, x,x,m")
4068         (vec_merge:SSEMODE4S
4069           (vec_duplicate:SSEMODE4S
4070             (match_operand:<ssescalarmode> 2
4071               "general_operand"                            " m,*r,x,x*rfF"))
4072           (match_operand:SSEMODE4S 1 "vector_move_operand" " C, C,0,0")
4073           (const_int 1)))]
4074   "TARGET_SSE2"
4075   "@
4076    mov<ssescalarmodesuffix>\t{%2, %0|%0, %2}
4077    movd\t{%2, %0|%0, %2}
4078    movss\t{%2, %0|%0, %2}
4079    #"
4080   [(set_attr "type" "ssemov")
4081    (set_attr "mode" "<ssescalarmode>,SI,SF,*")])
4082
4083 (define_insn "vec_set<mode>_0"
4084   [(set (match_operand:SSEMODE4S 0 "nonimmediate_operand"  "=x,x,m")
4085         (vec_merge:SSEMODE4S
4086           (vec_duplicate:SSEMODE4S
4087             (match_operand:<ssescalarmode> 2
4088               "general_operand"                            " m,x,x*rfF"))
4089           (match_operand:SSEMODE4S 1 "vector_move_operand" " C,0,0")
4090           (const_int 1)))]
4091   "TARGET_SSE"
4092   "@
4093    movss\t{%2, %0|%0, %2}
4094    movss\t{%2, %0|%0, %2}
4095    #"
4096   [(set_attr "type" "ssemov")
4097    (set_attr "mode" "SF,SF,*")])
4098
4099 ;; A subset is vec_setv4sf.
4100 (define_insn "*vec_setv4sf_avx"
4101   [(set (match_operand:V4SF 0 "register_operand" "=x")
4102         (vec_merge:V4SF
4103           (vec_duplicate:V4SF
4104             (match_operand:SF 2 "nonimmediate_operand" "xm"))
4105           (match_operand:V4SF 1 "register_operand" "x")
4106           (match_operand:SI 3 "const_pow2_1_to_8_operand" "n")))]
4107   "TARGET_AVX"
4108 {
4109   operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])) << 4);
4110   return "vinsertps\t{%3, %2, %1, %0|%0, %1, %2, %3}";
4111 }
4112   [(set_attr "type" "sselog")
4113    (set_attr "prefix_extra" "1")
4114    (set_attr "length_immediate" "1")
4115    (set_attr "prefix" "vex")
4116    (set_attr "mode" "V4SF")])
4117
4118 (define_insn "*vec_setv4sf_sse4_1"
4119   [(set (match_operand:V4SF 0 "register_operand" "=x")
4120         (vec_merge:V4SF
4121           (vec_duplicate:V4SF
4122             (match_operand:SF 2 "nonimmediate_operand" "xm"))
4123           (match_operand:V4SF 1 "register_operand" "0")
4124           (match_operand:SI 3 "const_pow2_1_to_8_operand" "n")))]
4125   "TARGET_SSE4_1"
4126 {
4127   operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])) << 4);
4128   return "insertps\t{%3, %2, %0|%0, %2, %3}";
4129 }
4130   [(set_attr "type" "sselog")
4131    (set_attr "prefix_data16" "1")
4132    (set_attr "prefix_extra" "1")
4133    (set_attr "length_immediate" "1")
4134    (set_attr "mode" "V4SF")])
4135
4136 (define_insn "*avx_insertps"
4137   [(set (match_operand:V4SF 0 "register_operand" "=x")
4138         (unspec:V4SF [(match_operand:V4SF 2 "nonimmediate_operand" "xm")
4139                       (match_operand:V4SF 1 "register_operand" "x")
4140                       (match_operand:SI 3 "const_0_to_255_operand" "n")]
4141                      UNSPEC_INSERTPS))]
4142   "TARGET_AVX"
4143   "vinsertps\t{%3, %2, %1, %0|%0, %1, %2, %3}";
4144   [(set_attr "type" "sselog")
4145    (set_attr "prefix" "vex")
4146    (set_attr "prefix_extra" "1")
4147    (set_attr "length_immediate" "1")
4148    (set_attr "mode" "V4SF")])
4149
4150 (define_insn "sse4_1_insertps"
4151   [(set (match_operand:V4SF 0 "register_operand" "=x")
4152         (unspec:V4SF [(match_operand:V4SF 2 "register_operand" "x")
4153                       (match_operand:V4SF 1 "register_operand" "0")
4154                       (match_operand:SI 3 "const_0_to_255_operand" "n")]
4155                      UNSPEC_INSERTPS))]
4156   "TARGET_SSE4_1"
4157   "insertps\t{%3, %2, %0|%0, %2, %3}";
4158   [(set_attr "type" "sselog")
4159    (set_attr "prefix_data16" "1")
4160    (set_attr "prefix_extra" "1")
4161    (set_attr "length_immediate" "1")
4162    (set_attr "mode" "V4SF")])
4163
4164 (define_split
4165   [(set (match_operand:SSEMODE4S 0 "memory_operand" "")
4166         (vec_merge:SSEMODE4S
4167           (vec_duplicate:SSEMODE4S
4168             (match_operand:<ssescalarmode> 1 "nonmemory_operand" ""))
4169           (match_dup 0)
4170           (const_int 1)))]
4171   "TARGET_SSE && reload_completed"
4172   [(const_int 0)]
4173 {
4174   emit_move_insn (adjust_address (operands[0], <ssescalarmode>mode, 0),
4175                   operands[1]);
4176   DONE;
4177 })
4178
4179 (define_expand "vec_set<mode>"
4180   [(match_operand:SSEMODE 0 "register_operand" "")
4181    (match_operand:<ssescalarmode> 1 "register_operand" "")
4182    (match_operand 2 "const_int_operand" "")]
4183   "TARGET_SSE"
4184 {
4185   ix86_expand_vector_set (false, operands[0], operands[1],
4186                           INTVAL (operands[2]));
4187   DONE;
4188 })
4189
4190 (define_insn_and_split "*vec_extractv4sf_0"
4191   [(set (match_operand:SF 0 "nonimmediate_operand" "=x,m,f,r")
4192         (vec_select:SF
4193           (match_operand:V4SF 1 "nonimmediate_operand" "xm,x,m,m")
4194           (parallel [(const_int 0)])))]
4195   "TARGET_SSE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
4196   "#"
4197   "&& reload_completed"
4198   [(const_int 0)]
4199 {
4200   rtx op1 = operands[1];
4201   if (REG_P (op1))
4202     op1 = gen_rtx_REG (SFmode, REGNO (op1));
4203   else
4204     op1 = gen_lowpart (SFmode, op1);
4205   emit_move_insn (operands[0], op1);
4206   DONE;
4207 })
4208
4209 (define_expand "avx_vextractf128<mode>"
4210   [(match_operand:<avxhalfvecmode> 0 "nonimmediate_operand" "")
4211    (match_operand:AVX256MODE 1 "register_operand" "")
4212    (match_operand:SI 2 "const_0_to_1_operand" "")]
4213   "TARGET_AVX"
4214 {
4215   switch (INTVAL (operands[2]))
4216     {
4217     case 0:
4218       emit_insn (gen_vec_extract_lo_<mode> (operands[0], operands[1]));
4219       break;
4220     case 1:
4221       emit_insn (gen_vec_extract_hi_<mode> (operands[0], operands[1]));
4222       break;
4223     default:
4224       gcc_unreachable ();
4225     }
4226   DONE;
4227 })
4228
4229 (define_insn_and_split "vec_extract_lo_<mode>"
4230   [(set (match_operand:<avxhalfvecmode> 0 "nonimmediate_operand" "=x,m")
4231         (vec_select:<avxhalfvecmode>
4232           (match_operand:AVX256MODE4P 1 "nonimmediate_operand" "xm,x")
4233           (parallel [(const_int 0) (const_int 1)])))]
4234   "TARGET_AVX"
4235   "#"
4236   "&& reload_completed"
4237   [(const_int 0)]
4238 {
4239   rtx op1 = operands[1];
4240   if (REG_P (op1))
4241     op1 = gen_rtx_REG (<avxhalfvecmode>mode, REGNO (op1));
4242   else
4243     op1 = gen_lowpart (<avxhalfvecmode>mode, op1);
4244   emit_move_insn (operands[0], op1);
4245   DONE;
4246 })
4247
4248 (define_insn "vec_extract_hi_<mode>"
4249   [(set (match_operand:<avxhalfvecmode> 0 "nonimmediate_operand" "=x,m")
4250         (vec_select:<avxhalfvecmode>
4251           (match_operand:AVX256MODE4P 1 "register_operand" "x,x")
4252           (parallel [(const_int 2) (const_int 3)])))]
4253   "TARGET_AVX"
4254   "vextractf128\t{$0x1, %1, %0|%0, %1, 0x1}"
4255   [(set_attr "type" "sselog")
4256    (set_attr "prefix_extra" "1")
4257    (set_attr "length_immediate" "1")
4258    (set_attr "memory" "none,store")
4259    (set_attr "prefix" "vex")
4260    (set_attr "mode" "V8SF")])
4261
4262 (define_insn_and_split "vec_extract_lo_<mode>"
4263   [(set (match_operand:<avxhalfvecmode> 0 "nonimmediate_operand" "=x,m")
4264         (vec_select:<avxhalfvecmode>
4265           (match_operand:AVX256MODE8P 1 "nonimmediate_operand" "xm,x")
4266           (parallel [(const_int 0) (const_int 1)
4267                      (const_int 2) (const_int 3)])))]
4268   "TARGET_AVX"
4269   "#"
4270   "&& reload_completed"
4271   [(const_int 0)]
4272 {
4273   rtx op1 = operands[1];
4274   if (REG_P (op1))
4275     op1 = gen_rtx_REG (<avxhalfvecmode>mode, REGNO (op1));
4276   else
4277     op1 = gen_lowpart (<avxhalfvecmode>mode, op1);
4278   emit_move_insn (operands[0], op1);
4279   DONE;
4280 })
4281
4282 (define_insn "vec_extract_hi_<mode>"
4283   [(set (match_operand:<avxhalfvecmode> 0 "nonimmediate_operand" "=x,m")
4284         (vec_select:<avxhalfvecmode>
4285           (match_operand:AVX256MODE8P 1 "register_operand" "x,x")
4286           (parallel [(const_int 4) (const_int 5)
4287                      (const_int 6) (const_int 7)])))]
4288   "TARGET_AVX"
4289   "vextractf128\t{$0x1, %1, %0|%0, %1, 0x1}"
4290   [(set_attr "type" "sselog")
4291    (set_attr "prefix_extra" "1")
4292    (set_attr "length_immediate" "1")
4293    (set_attr "memory" "none,store")
4294    (set_attr "prefix" "vex")
4295    (set_attr "mode" "V8SF")])
4296
4297 (define_insn_and_split "vec_extract_lo_v16hi"
4298   [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,m")
4299         (vec_select:V8HI
4300           (match_operand:V16HI 1 "nonimmediate_operand" "xm,x")
4301           (parallel [(const_int 0) (const_int 1)
4302                      (const_int 2) (const_int 3)
4303                      (const_int 4) (const_int 5)
4304                      (const_int 6) (const_int 7)])))]
4305   "TARGET_AVX"
4306   "#"
4307   "&& reload_completed"
4308   [(const_int 0)]
4309 {
4310   rtx op1 = operands[1];
4311   if (REG_P (op1))
4312     op1 = gen_rtx_REG (V8HImode, REGNO (op1));
4313   else
4314     op1 = gen_lowpart (V8HImode, op1);
4315   emit_move_insn (operands[0], op1);
4316   DONE;
4317 })
4318
4319 (define_insn "vec_extract_hi_v16hi"
4320   [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,m")
4321         (vec_select:V8HI
4322           (match_operand:V16HI 1 "register_operand" "x,x")
4323           (parallel [(const_int 8) (const_int 9)
4324                      (const_int 10) (const_int 11)
4325                      (const_int 12) (const_int 13)
4326                      (const_int 14) (const_int 15)])))]
4327   "TARGET_AVX"
4328   "vextractf128\t{$0x1, %1, %0|%0, %1, 0x1}"
4329   [(set_attr "type" "sselog")
4330    (set_attr "prefix_extra" "1")
4331    (set_attr "length_immediate" "1")
4332    (set_attr "memory" "none,store")
4333    (set_attr "prefix" "vex")
4334    (set_attr "mode" "V8SF")])
4335
4336 (define_insn_and_split "vec_extract_lo_v32qi"
4337   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
4338         (vec_select:V16QI
4339           (match_operand:V32QI 1 "nonimmediate_operand" "xm,x")
4340           (parallel [(const_int 0) (const_int 1)
4341                      (const_int 2) (const_int 3)
4342                      (const_int 4) (const_int 5)
4343                      (const_int 6) (const_int 7)
4344                      (const_int 8) (const_int 9)
4345                      (const_int 10) (const_int 11)
4346                      (const_int 12) (const_int 13)
4347                      (const_int 14) (const_int 15)])))]
4348   "TARGET_AVX"
4349   "#"
4350   "&& reload_completed"
4351   [(const_int 0)]
4352 {
4353   rtx op1 = operands[1];
4354   if (REG_P (op1))
4355     op1 = gen_rtx_REG (V16QImode, REGNO (op1));
4356   else
4357     op1 = gen_lowpart (V16QImode, op1);
4358   emit_move_insn (operands[0], op1);
4359   DONE;
4360 })
4361
4362 (define_insn "vec_extract_hi_v32qi"
4363   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
4364         (vec_select:V16QI
4365           (match_operand:V32QI 1 "register_operand" "x,x")
4366           (parallel [(const_int 16) (const_int 17)
4367                      (const_int 18) (const_int 19)
4368                      (const_int 20) (const_int 21)
4369                      (const_int 22) (const_int 23)
4370                      (const_int 24) (const_int 25)
4371                      (const_int 26) (const_int 27)
4372                      (const_int 28) (const_int 29)
4373                      (const_int 30) (const_int 31)])))]
4374   "TARGET_AVX"
4375   "vextractf128\t{$0x1, %1, %0|%0, %1, 0x1}"
4376   [(set_attr "type" "sselog")
4377    (set_attr "prefix_extra" "1")
4378    (set_attr "length_immediate" "1")
4379    (set_attr "memory" "none,store")
4380    (set_attr "prefix" "vex")
4381    (set_attr "mode" "V8SF")])
4382
4383 (define_insn "*sse4_1_extractps"
4384   [(set (match_operand:SF 0 "nonimmediate_operand" "=rm")
4385         (vec_select:SF
4386           (match_operand:V4SF 1 "register_operand" "x")
4387           (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n")])))]
4388   "TARGET_SSE4_1"
4389   "%vextractps\t{%2, %1, %0|%0, %1, %2}"
4390   [(set_attr "type" "sselog")
4391    (set_attr "prefix_data16" "1")
4392    (set_attr "prefix_extra" "1")
4393    (set_attr "length_immediate" "1")
4394    (set_attr "prefix" "maybe_vex")
4395    (set_attr "mode" "V4SF")])
4396
4397 (define_insn_and_split "*vec_extract_v4sf_mem"
4398   [(set (match_operand:SF 0 "register_operand" "=x*rf")
4399        (vec_select:SF
4400          (match_operand:V4SF 1 "memory_operand" "o")
4401          (parallel [(match_operand 2 "const_0_to_3_operand" "n")])))]
4402   ""
4403   "#"
4404   "reload_completed"
4405   [(const_int 0)]
4406 {
4407   int i = INTVAL (operands[2]);
4408
4409   emit_move_insn (operands[0], adjust_address (operands[1], SFmode, i*4));
4410   DONE;
4411 })
4412
4413 (define_expand "vec_extract<mode>"
4414   [(match_operand:<avxscalarmode> 0 "register_operand" "")
4415    (match_operand:VEC_EXTRACT_MODE 1 "register_operand" "")
4416    (match_operand 2 "const_int_operand" "")]
4417   "TARGET_SSE"
4418 {
4419   ix86_expand_vector_extract (false, operands[0], operands[1],
4420                               INTVAL (operands[2]));
4421   DONE;
4422 })
4423
4424 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4425 ;;
4426 ;; Parallel double-precision floating point element swizzling
4427 ;;
4428 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4429
4430 ;; Recall that the 256-bit unpck insns only shuffle within their lanes.
4431 (define_insn "avx_unpckhpd256"
4432   [(set (match_operand:V4DF 0 "register_operand" "=x")
4433         (vec_select:V4DF
4434           (vec_concat:V8DF
4435             (match_operand:V4DF 1 "register_operand" "x")
4436             (match_operand:V4DF 2 "nonimmediate_operand" "xm"))
4437           (parallel [(const_int 1) (const_int 5)
4438                      (const_int 3) (const_int 7)])))]
4439   "TARGET_AVX"
4440   "vunpckhpd\t{%2, %1, %0|%0, %1, %2}"
4441   [(set_attr "type" "sselog")
4442    (set_attr "prefix" "vex")
4443    (set_attr "mode" "V4DF")])
4444
4445 (define_expand "vec_interleave_highv4df"
4446   [(set (match_dup 3)
4447         (vec_select:V4DF
4448           (vec_concat:V8DF
4449             (match_operand:V4DF 1 "register_operand" "x")
4450             (match_operand:V4DF 2 "nonimmediate_operand" "xm"))
4451           (parallel [(const_int 0) (const_int 4)
4452                      (const_int 2) (const_int 6)])))
4453    (set (match_dup 4)
4454         (vec_select:V4DF
4455           (vec_concat:V8DF
4456             (match_dup 1)
4457             (match_dup 2))
4458           (parallel [(const_int 1) (const_int 5)
4459                      (const_int 3) (const_int 7)])))
4460    (set (match_operand:V4DF 0 "register_operand" "")
4461         (vec_select:V4DF
4462           (vec_concat:V8DF
4463             (match_dup 3)
4464             (match_dup 4))
4465           (parallel [(const_int 2) (const_int 3)
4466                      (const_int 6) (const_int 7)])))]
4467  "TARGET_AVX"
4468 {
4469   operands[3] = gen_reg_rtx (V4DFmode);
4470   operands[4] = gen_reg_rtx (V4DFmode);
4471 })
4472
4473
4474 (define_expand "vec_interleave_highv2df"
4475   [(set (match_operand:V2DF 0 "register_operand" "")
4476         (vec_select:V2DF
4477           (vec_concat:V4DF
4478             (match_operand:V2DF 1 "nonimmediate_operand" "")
4479             (match_operand:V2DF 2 "nonimmediate_operand" ""))
4480           (parallel [(const_int 1)
4481                      (const_int 3)])))]
4482   "TARGET_SSE2"
4483 {
4484   if (!ix86_vec_interleave_v2df_operator_ok (operands, 1))
4485     operands[2] = force_reg (V2DFmode, operands[2]);
4486 })
4487
4488 (define_insn "*avx_interleave_highv2df"
4489   [(set (match_operand:V2DF 0 "nonimmediate_operand"     "=x,x,x,m")
4490         (vec_select:V2DF
4491           (vec_concat:V4DF
4492             (match_operand:V2DF 1 "nonimmediate_operand" " x,o,o,x")
4493             (match_operand:V2DF 2 "nonimmediate_operand" " x,1,x,0"))
4494           (parallel [(const_int 1)
4495                      (const_int 3)])))]
4496   "TARGET_AVX && ix86_vec_interleave_v2df_operator_ok (operands, 1)"
4497   "@
4498    vunpckhpd\t{%2, %1, %0|%0, %1, %2}
4499    vmovddup\t{%H1, %0|%0, %H1}
4500    vmovlpd\t{%H1, %2, %0|%0, %2, %H1}
4501    vmovhpd\t{%1, %0|%0, %1}"
4502   [(set_attr "type" "sselog,sselog,ssemov,ssemov")
4503    (set_attr "prefix" "vex")
4504    (set_attr "mode" "V2DF,V2DF,V1DF,V1DF")])
4505
4506 (define_insn "*sse3_interleave_highv2df"
4507   [(set (match_operand:V2DF 0 "nonimmediate_operand"     "=x,x,x,m")
4508         (vec_select:V2DF
4509           (vec_concat:V4DF
4510             (match_operand:V2DF 1 "nonimmediate_operand" " 0,o,o,x")
4511             (match_operand:V2DF 2 "nonimmediate_operand" " x,1,0,0"))
4512           (parallel [(const_int 1)
4513                      (const_int 3)])))]
4514   "TARGET_SSE3 && ix86_vec_interleave_v2df_operator_ok (operands, 1)"
4515   "@
4516    unpckhpd\t{%2, %0|%0, %2}
4517    movddup\t{%H1, %0|%0, %H1}
4518    movlpd\t{%H1, %0|%0, %H1}
4519    movhpd\t{%1, %0|%0, %1}"
4520   [(set_attr "type" "sselog,sselog,ssemov,ssemov")
4521    (set_attr "prefix_data16" "*,*,1,1")
4522    (set_attr "mode" "V2DF,V2DF,V1DF,V1DF")])
4523
4524 (define_insn "*sse2_interleave_highv2df"
4525   [(set (match_operand:V2DF 0 "nonimmediate_operand"     "=x,x,m")
4526         (vec_select:V2DF
4527           (vec_concat:V4DF
4528             (match_operand:V2DF 1 "nonimmediate_operand" " 0,o,x")
4529             (match_operand:V2DF 2 "nonimmediate_operand" " x,0,0"))
4530           (parallel [(const_int 1)
4531                      (const_int 3)])))]
4532   "TARGET_SSE2 && ix86_vec_interleave_v2df_operator_ok (operands, 1)"
4533   "@
4534    unpckhpd\t{%2, %0|%0, %2}
4535    movlpd\t{%H1, %0|%0, %H1}
4536    movhpd\t{%1, %0|%0, %1}"
4537   [(set_attr "type" "sselog,ssemov,ssemov")
4538    (set_attr "prefix_data16" "*,1,1")
4539    (set_attr "mode" "V2DF,V1DF,V1DF")])
4540
4541 ;; Recall that the 256-bit unpck insns only shuffle within their lanes.
4542 (define_expand "avx_movddup256"
4543   [(set (match_operand:V4DF 0 "register_operand" "")
4544         (vec_select:V4DF
4545           (vec_concat:V8DF
4546             (match_operand:V4DF 1 "nonimmediate_operand" "")
4547             (match_dup 1))
4548           (parallel [(const_int 0) (const_int 4)
4549                      (const_int 2) (const_int 6)])))]
4550   "TARGET_AVX")
4551
4552 (define_expand "avx_unpcklpd256"
4553   [(set (match_operand:V4DF 0 "register_operand" "")
4554         (vec_select:V4DF
4555           (vec_concat:V8DF
4556             (match_operand:V4DF 1 "register_operand" "")
4557             (match_operand:V4DF 2 "nonimmediate_operand" ""))
4558           (parallel [(const_int 0) (const_int 4)
4559                      (const_int 2) (const_int 6)])))]
4560   "TARGET_AVX")
4561
4562 (define_insn "*avx_unpcklpd256"
4563   [(set (match_operand:V4DF 0 "register_operand"         "=x,x")
4564         (vec_select:V4DF
4565           (vec_concat:V8DF
4566             (match_operand:V4DF 1 "nonimmediate_operand" "xm,x")
4567             (match_operand:V4DF 2 "nonimmediate_operand" " 1,xm"))
4568           (parallel [(const_int 0) (const_int 4)
4569                      (const_int 2) (const_int 6)])))]
4570   "TARGET_AVX
4571    && (!MEM_P (operands[1]) || rtx_equal_p (operands[1], operands[2]))"
4572   "@
4573    vmovddup\t{%1, %0|%0, %1}
4574    vunpcklpd\t{%2, %1, %0|%0, %1, %2}"
4575   [(set_attr "type" "sselog")
4576    (set_attr "prefix" "vex")
4577    (set_attr "mode" "V4DF")])
4578
4579 (define_expand "vec_interleave_lowv4df"
4580   [(set (match_dup 3)
4581         (vec_select:V4DF
4582           (vec_concat:V8DF
4583             (match_operand:V4DF 1 "register_operand" "x")
4584             (match_operand:V4DF 2 "nonimmediate_operand" "xm"))
4585           (parallel [(const_int 0) (const_int 4)
4586                      (const_int 2) (const_int 6)])))
4587    (set (match_dup 4)
4588         (vec_select:V4DF
4589           (vec_concat:V8DF
4590             (match_dup 1)
4591             (match_dup 2))
4592           (parallel [(const_int 1) (const_int 5)
4593                      (const_int 3) (const_int 7)])))
4594    (set (match_operand:V4DF 0 "register_operand" "")
4595         (vec_select:V4DF
4596           (vec_concat:V8DF
4597             (match_dup 3)
4598             (match_dup 4))
4599           (parallel [(const_int 0) (const_int 1)
4600                      (const_int 4) (const_int 5)])))]
4601  "TARGET_AVX"
4602 {
4603   operands[3] = gen_reg_rtx (V4DFmode);
4604   operands[4] = gen_reg_rtx (V4DFmode);
4605 })
4606
4607 (define_expand "vec_interleave_lowv2df"
4608   [(set (match_operand:V2DF 0 "register_operand" "")
4609         (vec_select:V2DF
4610           (vec_concat:V4DF
4611             (match_operand:V2DF 1 "nonimmediate_operand" "")
4612             (match_operand:V2DF 2 "nonimmediate_operand" ""))
4613           (parallel [(const_int 0)
4614                      (const_int 2)])))]
4615   "TARGET_SSE2"
4616 {
4617   if (!ix86_vec_interleave_v2df_operator_ok (operands, 0))
4618     operands[1] = force_reg (V2DFmode, operands[1]);
4619 })
4620
4621 (define_insn "*avx_interleave_lowv2df"
4622   [(set (match_operand:V2DF 0 "nonimmediate_operand"     "=x,x,x,o")
4623         (vec_select:V2DF
4624           (vec_concat:V4DF
4625             (match_operand:V2DF 1 "nonimmediate_operand" " x,m,x,0")
4626             (match_operand:V2DF 2 "nonimmediate_operand" " x,1,m,x"))
4627           (parallel [(const_int 0)
4628                      (const_int 2)])))]
4629   "TARGET_AVX && ix86_vec_interleave_v2df_operator_ok (operands, 0)"
4630   "@
4631    vunpcklpd\t{%2, %1, %0|%0, %1, %2}
4632    vmovddup\t{%1, %0|%0, %1}
4633    vmovhpd\t{%2, %1, %0|%0, %1, %2}
4634    vmovlpd\t{%2, %H0|%H0, %2}"
4635   [(set_attr "type" "sselog,sselog,ssemov,ssemov")
4636    (set_attr "prefix" "vex")
4637    (set_attr "mode" "V2DF,V2DF,V1DF,V1DF")])
4638
4639 (define_insn "*sse3_interleave_lowv2df"
4640   [(set (match_operand:V2DF 0 "nonimmediate_operand"     "=x,x,x,o")
4641         (vec_select:V2DF
4642           (vec_concat:V4DF
4643             (match_operand:V2DF 1 "nonimmediate_operand" " 0,m,0,0")
4644             (match_operand:V2DF 2 "nonimmediate_operand" " x,1,m,x"))
4645           (parallel [(const_int 0)
4646                      (const_int 2)])))]
4647   "TARGET_SSE3 && ix86_vec_interleave_v2df_operator_ok (operands, 0)"
4648   "@
4649    unpcklpd\t{%2, %0|%0, %2}
4650    movddup\t{%1, %0|%0, %1}
4651    movhpd\t{%2, %0|%0, %2}
4652    movlpd\t{%2, %H0|%H0, %2}"
4653   [(set_attr "type" "sselog,sselog,ssemov,ssemov")
4654    (set_attr "prefix_data16" "*,*,1,1")
4655    (set_attr "mode" "V2DF,V2DF,V1DF,V1DF")])
4656
4657 (define_insn "*sse2_interleave_lowv2df"
4658   [(set (match_operand:V2DF 0 "nonimmediate_operand"     "=x,x,o")
4659         (vec_select:V2DF
4660           (vec_concat:V4DF
4661             (match_operand:V2DF 1 "nonimmediate_operand" " 0,0,0")
4662             (match_operand:V2DF 2 "nonimmediate_operand" " x,m,x"))
4663           (parallel [(const_int 0)
4664                      (const_int 2)])))]
4665   "TARGET_SSE2 && ix86_vec_interleave_v2df_operator_ok (operands, 0)"
4666   "@
4667    unpcklpd\t{%2, %0|%0, %2}
4668    movhpd\t{%2, %0|%0, %2}
4669    movlpd\t{%2, %H0|%H0, %2}"
4670   [(set_attr "type" "sselog,ssemov,ssemov")
4671    (set_attr "prefix_data16" "*,1,1")
4672    (set_attr "mode" "V2DF,V1DF,V1DF")])
4673
4674 (define_split
4675   [(set (match_operand:V2DF 0 "memory_operand" "")
4676         (vec_select:V2DF
4677           (vec_concat:V4DF
4678             (match_operand:V2DF 1 "register_operand" "")
4679             (match_dup 1))
4680           (parallel [(const_int 0)
4681                      (const_int 2)])))]
4682   "TARGET_SSE3 && reload_completed"
4683   [(const_int 0)]
4684 {
4685   rtx low = gen_rtx_REG (DFmode, REGNO (operands[1]));
4686   emit_move_insn (adjust_address (operands[0], DFmode, 0), low);
4687   emit_move_insn (adjust_address (operands[0], DFmode, 8), low);
4688   DONE;
4689 })
4690
4691 (define_split
4692   [(set (match_operand:V2DF 0 "register_operand" "")
4693         (vec_select:V2DF
4694           (vec_concat:V4DF
4695             (match_operand:V2DF 1 "memory_operand" "")
4696             (match_dup 1))
4697           (parallel [(match_operand:SI 2 "const_0_to_1_operand" "")
4698                      (match_operand:SI 3 "const_int_operand" "")])))]
4699   "TARGET_SSE3 && INTVAL (operands[2]) + 2 == INTVAL (operands[3])"
4700   [(set (match_dup 0) (vec_duplicate:V2DF (match_dup 1)))]
4701 {
4702   operands[1] = adjust_address (operands[1], DFmode, INTVAL (operands[2]) * 8);
4703 })
4704
4705 (define_expand "avx_shufpd256"
4706   [(match_operand:V4DF 0 "register_operand" "")
4707    (match_operand:V4DF 1 "register_operand" "")
4708    (match_operand:V4DF 2 "nonimmediate_operand" "")
4709    (match_operand:SI 3 "const_int_operand" "")]
4710   "TARGET_AVX"
4711 {
4712   int mask = INTVAL (operands[3]);
4713   emit_insn (gen_avx_shufpd256_1 (operands[0], operands[1], operands[2],
4714                                    GEN_INT (mask & 1),
4715                                    GEN_INT (mask & 2 ? 5 : 4),
4716                                    GEN_INT (mask & 4 ? 3 : 2),
4717                                    GEN_INT (mask & 8 ? 7 : 6)));
4718   DONE;
4719 })
4720
4721 (define_insn "avx_shufpd256_1"
4722   [(set (match_operand:V4DF 0 "register_operand" "=x")
4723         (vec_select:V4DF
4724           (vec_concat:V8DF
4725             (match_operand:V4DF 1 "register_operand" "x")
4726             (match_operand:V4DF 2 "nonimmediate_operand" "xm"))
4727           (parallel [(match_operand 3 "const_0_to_1_operand" "")
4728                      (match_operand 4 "const_4_to_5_operand" "")
4729                      (match_operand 5 "const_2_to_3_operand" "")
4730                      (match_operand 6 "const_6_to_7_operand" "")])))]
4731   "TARGET_AVX"
4732 {
4733   int mask;
4734   mask = INTVAL (operands[3]);
4735   mask |= (INTVAL (operands[4]) - 4) << 1;
4736   mask |= (INTVAL (operands[5]) - 2) << 2;
4737   mask |= (INTVAL (operands[6]) - 6) << 3;
4738   operands[3] = GEN_INT (mask);
4739
4740   return "vshufpd\t{%3, %2, %1, %0|%0, %1, %2, %3}";
4741 }
4742   [(set_attr "type" "sselog")
4743    (set_attr "length_immediate" "1")
4744    (set_attr "prefix" "vex")
4745    (set_attr "mode" "V4DF")])
4746
4747 (define_expand "sse2_shufpd"
4748   [(match_operand:V2DF 0 "register_operand" "")
4749    (match_operand:V2DF 1 "register_operand" "")
4750    (match_operand:V2DF 2 "nonimmediate_operand" "")
4751    (match_operand:SI 3 "const_int_operand" "")]
4752   "TARGET_SSE2"
4753 {
4754   int mask = INTVAL (operands[3]);
4755   emit_insn (gen_sse2_shufpd_v2df (operands[0], operands[1], operands[2],
4756                                 GEN_INT (mask & 1),
4757                                 GEN_INT (mask & 2 ? 3 : 2)));
4758   DONE;
4759 })
4760
4761 (define_expand "vec_extract_even<mode>"
4762   [(match_operand:SSEMODE_EO 0 "register_operand" "")
4763    (match_operand:SSEMODE_EO 1 "register_operand" "")
4764    (match_operand:SSEMODE_EO 2 "register_operand" "")]
4765   ""
4766 {
4767   ix86_expand_vec_extract_even_odd (operands[0], operands[1], operands[2], 0);
4768   DONE;
4769 })
4770
4771 (define_expand "vec_extract_odd<mode>"
4772   [(match_operand:SSEMODE_EO 0 "register_operand" "")
4773    (match_operand:SSEMODE_EO 1 "register_operand" "")
4774    (match_operand:SSEMODE_EO 2 "register_operand" "")]
4775   ""
4776 {
4777   ix86_expand_vec_extract_even_odd (operands[0], operands[1], operands[2], 1);
4778   DONE;
4779 })
4780
4781 ;; punpcklqdq and punpckhqdq are shorter than shufpd.
4782 (define_insn "*avx_interleave_highv2di"
4783   [(set (match_operand:V2DI 0 "register_operand" "=x")
4784         (vec_select:V2DI
4785           (vec_concat:V4DI
4786             (match_operand:V2DI 1 "register_operand" "x")
4787             (match_operand:V2DI 2 "nonimmediate_operand" "xm"))
4788           (parallel [(const_int 1)
4789                      (const_int 3)])))]
4790   "TARGET_AVX"
4791   "vpunpckhqdq\t{%2, %1, %0|%0, %1, %2}"
4792   [(set_attr "type" "sselog")
4793    (set_attr "prefix" "vex")
4794    (set_attr "mode" "TI")])
4795
4796 (define_insn "vec_interleave_highv2di"
4797   [(set (match_operand:V2DI 0 "register_operand" "=x")
4798         (vec_select:V2DI
4799           (vec_concat:V4DI
4800             (match_operand:V2DI 1 "register_operand" "0")
4801             (match_operand:V2DI 2 "nonimmediate_operand" "xm"))
4802           (parallel [(const_int 1)
4803                      (const_int 3)])))]
4804   "TARGET_SSE2"
4805   "punpckhqdq\t{%2, %0|%0, %2}"
4806   [(set_attr "type" "sselog")
4807    (set_attr "prefix_data16" "1")
4808    (set_attr "mode" "TI")])
4809
4810 (define_insn "*avx_interleave_lowv2di"
4811   [(set (match_operand:V2DI 0 "register_operand" "=x")
4812         (vec_select:V2DI
4813           (vec_concat:V4DI
4814             (match_operand:V2DI 1 "register_operand" "x")
4815             (match_operand:V2DI 2 "nonimmediate_operand" "xm"))
4816           (parallel [(const_int 0)
4817                      (const_int 2)])))]
4818   "TARGET_AVX"
4819   "vpunpcklqdq\t{%2, %1, %0|%0, %1, %2}"
4820   [(set_attr "type" "sselog")
4821    (set_attr "prefix" "vex")
4822    (set_attr "mode" "TI")])
4823
4824 (define_insn "vec_interleave_lowv2di"
4825   [(set (match_operand:V2DI 0 "register_operand" "=x")
4826         (vec_select:V2DI
4827           (vec_concat:V4DI
4828             (match_operand:V2DI 1 "register_operand" "0")
4829             (match_operand:V2DI 2 "nonimmediate_operand" "xm"))
4830           (parallel [(const_int 0)
4831                      (const_int 2)])))]
4832   "TARGET_SSE2"
4833   "punpcklqdq\t{%2, %0|%0, %2}"
4834   [(set_attr "type" "sselog")
4835    (set_attr "prefix_data16" "1")
4836    (set_attr "mode" "TI")])
4837
4838 (define_insn "*avx_shufpd_<mode>"
4839   [(set (match_operand:SSEMODE2D 0 "register_operand" "=x")
4840         (vec_select:SSEMODE2D
4841           (vec_concat:<ssedoublesizemode>
4842             (match_operand:SSEMODE2D 1 "register_operand" "x")
4843             (match_operand:SSEMODE2D 2 "nonimmediate_operand" "xm"))
4844           (parallel [(match_operand 3 "const_0_to_1_operand" "")
4845                      (match_operand 4 "const_2_to_3_operand" "")])))]
4846   "TARGET_AVX"
4847 {
4848   int mask;
4849   mask = INTVAL (operands[3]);
4850   mask |= (INTVAL (operands[4]) - 2) << 1;
4851   operands[3] = GEN_INT (mask);
4852
4853   return "vshufpd\t{%3, %2, %1, %0|%0, %1, %2, %3}";
4854 }
4855   [(set_attr "type" "sselog")
4856    (set_attr "length_immediate" "1")
4857    (set_attr "prefix" "vex")
4858    (set_attr "mode" "V2DF")])
4859
4860 (define_insn "sse2_shufpd_<mode>"
4861   [(set (match_operand:SSEMODE2D 0 "register_operand" "=x")
4862         (vec_select:SSEMODE2D
4863           (vec_concat:<ssedoublesizemode>
4864             (match_operand:SSEMODE2D 1 "register_operand" "0")
4865             (match_operand:SSEMODE2D 2 "nonimmediate_operand" "xm"))
4866           (parallel [(match_operand 3 "const_0_to_1_operand" "")
4867                      (match_operand 4 "const_2_to_3_operand" "")])))]
4868   "TARGET_SSE2"
4869 {
4870   int mask;
4871   mask = INTVAL (operands[3]);
4872   mask |= (INTVAL (operands[4]) - 2) << 1;
4873   operands[3] = GEN_INT (mask);
4874
4875   return "shufpd\t{%3, %2, %0|%0, %2, %3}";
4876 }
4877   [(set_attr "type" "sselog")
4878    (set_attr "length_immediate" "1")
4879    (set_attr "mode" "V2DF")])
4880
4881 ;; Avoid combining registers from different units in a single alternative,
4882 ;; see comment above inline_secondary_memory_needed function in i386.c
4883 (define_insn "*avx_storehpd"
4884   [(set (match_operand:DF 0 "nonimmediate_operand"     "=m,x,x,*f,r")
4885         (vec_select:DF
4886           (match_operand:V2DF 1 "nonimmediate_operand" " x,x,o,o,o")
4887           (parallel [(const_int 1)])))]
4888   "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
4889   "@
4890    vmovhpd\t{%1, %0|%0, %1}
4891    vunpckhpd\t{%1, %1, %0|%0, %1, %1}
4892    #
4893    #
4894    #"
4895   [(set_attr "type" "ssemov,sselog1,ssemov,fmov,imov")
4896    (set_attr "prefix" "vex")
4897    (set_attr "mode" "V1DF,V2DF,DF,DF,DF")])
4898
4899 (define_insn "sse2_storehpd"
4900   [(set (match_operand:DF 0 "nonimmediate_operand"     "=m,x,x,*f,r")
4901         (vec_select:DF
4902           (match_operand:V2DF 1 "nonimmediate_operand" " x,0,o,o,o")
4903           (parallel [(const_int 1)])))]
4904   "TARGET_SSE2 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
4905   "@
4906    movhpd\t{%1, %0|%0, %1}
4907    unpckhpd\t%0, %0
4908    #
4909    #
4910    #"
4911   [(set_attr "type" "ssemov,sselog1,ssemov,fmov,imov")
4912    (set_attr "prefix_data16" "1,*,*,*,*")
4913    (set_attr "mode" "V1DF,V2DF,DF,DF,DF")])
4914
4915 (define_split
4916   [(set (match_operand:DF 0 "register_operand" "")
4917         (vec_select:DF
4918           (match_operand:V2DF 1 "memory_operand" "")
4919           (parallel [(const_int 1)])))]
4920   "TARGET_SSE2 && reload_completed"
4921   [(set (match_dup 0) (match_dup 1))]
4922   "operands[1] = adjust_address (operands[1], DFmode, 8);")
4923
4924 ;; Avoid combining registers from different units in a single alternative,
4925 ;; see comment above inline_secondary_memory_needed function in i386.c
4926 (define_insn "sse2_storelpd"
4927   [(set (match_operand:DF 0 "nonimmediate_operand"     "=m,x,x,*f,r")
4928         (vec_select:DF
4929           (match_operand:V2DF 1 "nonimmediate_operand" " x,x,m,m,m")
4930           (parallel [(const_int 0)])))]
4931   "TARGET_SSE2 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
4932   "@
4933    %vmovlpd\t{%1, %0|%0, %1}
4934    #
4935    #
4936    #
4937    #"
4938   [(set_attr "type" "ssemov,ssemov,ssemov,fmov,imov")
4939    (set_attr "prefix_data16" "1,*,*,*,*")
4940    (set_attr "prefix" "maybe_vex")
4941    (set_attr "mode" "V1DF,DF,DF,DF,DF")])
4942
4943 (define_split
4944   [(set (match_operand:DF 0 "register_operand" "")
4945         (vec_select:DF
4946           (match_operand:V2DF 1 "nonimmediate_operand" "")
4947           (parallel [(const_int 0)])))]
4948   "TARGET_SSE2 && reload_completed"
4949   [(const_int 0)]
4950 {
4951   rtx op1 = operands[1];
4952   if (REG_P (op1))
4953     op1 = gen_rtx_REG (DFmode, REGNO (op1));
4954   else
4955     op1 = gen_lowpart (DFmode, op1);
4956   emit_move_insn (operands[0], op1);
4957   DONE;
4958 })
4959
4960 (define_expand "sse2_loadhpd_exp"
4961   [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
4962         (vec_concat:V2DF
4963           (vec_select:DF
4964             (match_operand:V2DF 1 "nonimmediate_operand" "")
4965             (parallel [(const_int 0)]))
4966           (match_operand:DF 2 "nonimmediate_operand" "")))]
4967   "TARGET_SSE2"
4968 {
4969   rtx dst = ix86_fixup_binary_operands (UNKNOWN, V2DFmode, operands);
4970   
4971   emit_insn (gen_sse2_loadhpd (dst, operands[1], operands[2]));
4972
4973   /* Fix up the destination if needed.  */
4974   if (dst != operands[0])
4975     emit_move_insn (operands[0], dst);
4976
4977   DONE;
4978 })
4979
4980 ;; Avoid combining registers from different units in a single alternative,
4981 ;; see comment above inline_secondary_memory_needed function in i386.c
4982 (define_insn "*avx_loadhpd"
4983   [(set (match_operand:V2DF 0 "nonimmediate_operand"     "=x,x,o,o,o")
4984         (vec_concat:V2DF
4985           (vec_select:DF
4986             (match_operand:V2DF 1 "nonimmediate_operand" " x,x,0,0,0")
4987             (parallel [(const_int 0)]))
4988           (match_operand:DF 2 "nonimmediate_operand"     " m,x,x,*f,r")))]
4989   "TARGET_AVX && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
4990   "@
4991    vmovhpd\t{%2, %1, %0|%0, %1, %2}
4992    vunpcklpd\t{%2, %1, %0|%0, %1, %2}
4993    #
4994    #
4995    #"
4996   [(set_attr "type" "ssemov,sselog,ssemov,fmov,imov")
4997    (set_attr "prefix" "vex")
4998    (set_attr "mode" "V1DF,V2DF,DF,DF,DF")])
4999
5000 (define_insn "sse2_loadhpd"
5001   [(set (match_operand:V2DF 0 "nonimmediate_operand"     "=x,x,x,o,o,o")
5002         (vec_concat:V2DF
5003           (vec_select:DF
5004             (match_operand:V2DF 1 "nonimmediate_operand" " 0,0,x,0,0,0")
5005             (parallel [(const_int 0)]))
5006           (match_operand:DF 2 "nonimmediate_operand"     " m,x,0,x,*f,r")))]
5007   "TARGET_SSE2 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5008   "@
5009    movhpd\t{%2, %0|%0, %2}
5010    unpcklpd\t{%2, %0|%0, %2}
5011    shufpd\t{$1, %1, %0|%0, %1, 1}
5012    #
5013    #
5014    #"
5015   [(set_attr "type" "ssemov,sselog,sselog,ssemov,fmov,imov")
5016    (set_attr "prefix_data16" "1,*,*,*,*,*")
5017    (set_attr "length_immediate" "*,*,1,*,*,*")
5018    (set_attr "mode" "V1DF,V2DF,V2DF,DF,DF,DF")])
5019
5020 (define_split
5021   [(set (match_operand:V2DF 0 "memory_operand" "")
5022         (vec_concat:V2DF
5023           (vec_select:DF (match_dup 0) (parallel [(const_int 0)]))
5024           (match_operand:DF 1 "register_operand" "")))]
5025   "TARGET_SSE2 && reload_completed"
5026   [(set (match_dup 0) (match_dup 1))]
5027   "operands[0] = adjust_address (operands[0], DFmode, 8);")
5028
5029 (define_expand "sse2_loadlpd_exp"
5030   [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
5031         (vec_concat:V2DF
5032           (match_operand:DF 2 "nonimmediate_operand" "")
5033           (vec_select:DF
5034             (match_operand:V2DF 1 "nonimmediate_operand" "")
5035             (parallel [(const_int 1)]))))]
5036   "TARGET_SSE2"
5037 {
5038   rtx dst = ix86_fixup_binary_operands (UNKNOWN, V2DFmode, operands);
5039   
5040   emit_insn (gen_sse2_loadlpd (dst, operands[1], operands[2]));
5041
5042   /* Fix up the destination if needed.  */
5043   if (dst != operands[0])
5044     emit_move_insn (operands[0], dst);
5045
5046   DONE;
5047 })
5048
5049 ;; Avoid combining registers from different units in a single alternative,
5050 ;; see comment above inline_secondary_memory_needed function in i386.c
5051 (define_insn "*avx_loadlpd"
5052   [(set (match_operand:V2DF 0 "nonimmediate_operand"    "=x,x,x,x,m,m,m")
5053         (vec_concat:V2DF
5054           (match_operand:DF 2 "nonimmediate_operand"    " m,m,x,x,x,*f,r")
5055           (vec_select:DF
5056             (match_operand:V2DF 1 "vector_move_operand" " C,x,x,o,0,0,0")
5057             (parallel [(const_int 1)]))))]
5058   "TARGET_AVX && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5059   "@
5060    vmovsd\t{%2, %0|%0, %2}
5061    vmovlpd\t{%2, %1, %0|%0, %1, %2}
5062    vmovsd\t{%2, %1, %0|%0, %1, %2}
5063    vmovhpd\t{%H1, %2, %0|%0, %2, %H1}
5064    #
5065    #
5066    #"
5067   [(set_attr "type" "ssemov,ssemov,ssemov,ssemov,ssemov,fmov,imov")
5068    (set_attr "prefix" "vex")
5069    (set_attr "mode" "DF,V1DF,V1DF,V1DF,DF,DF,DF")])
5070
5071 (define_insn "sse2_loadlpd"
5072   [(set (match_operand:V2DF 0 "nonimmediate_operand"    "=x,x,x,x,x,m,m,m")
5073         (vec_concat:V2DF
5074           (match_operand:DF 2 "nonimmediate_operand"    " m,m,x,0,0,x,*f,r")
5075           (vec_select:DF
5076             (match_operand:V2DF 1 "vector_move_operand" " C,0,0,x,o,0,0,0")
5077             (parallel [(const_int 1)]))))]
5078   "TARGET_SSE2 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5079   "@
5080    movsd\t{%2, %0|%0, %2}
5081    movlpd\t{%2, %0|%0, %2}
5082    movsd\t{%2, %0|%0, %2}
5083    shufpd\t{$2, %2, %0|%0, %2, 2}
5084    movhpd\t{%H1, %0|%0, %H1}
5085    #
5086    #
5087    #"
5088   [(set_attr "type" "ssemov,ssemov,ssemov,sselog,ssemov,ssemov,fmov,imov")
5089    (set_attr "prefix_data16" "*,1,*,*,1,*,*,*")
5090    (set_attr "length_immediate" "*,*,*,1,*,*,*,*")
5091    (set_attr "mode" "DF,V1DF,V1DF,V2DF,V1DF,DF,DF,DF")])
5092
5093 (define_split
5094   [(set (match_operand:V2DF 0 "memory_operand" "")
5095         (vec_concat:V2DF
5096           (match_operand:DF 1 "register_operand" "")
5097           (vec_select:DF (match_dup 0) (parallel [(const_int 1)]))))]
5098   "TARGET_SSE2 && reload_completed"
5099   [(set (match_dup 0) (match_dup 1))]
5100   "operands[0] = adjust_address (operands[0], DFmode, 8);")
5101
5102 ;; Not sure these two are ever used, but it doesn't hurt to have
5103 ;; them. -aoliva
5104 (define_insn "*vec_extractv2df_1_sse"
5105   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,x,x")
5106         (vec_select:DF
5107           (match_operand:V2DF 1 "nonimmediate_operand" "x,x,o")
5108           (parallel [(const_int 1)])))]
5109   "!TARGET_SSE2 && TARGET_SSE
5110    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5111   "@
5112    movhps\t{%1, %0|%0, %1}
5113    movhlps\t{%1, %0|%0, %1}
5114    movlps\t{%H1, %0|%0, %H1}"
5115   [(set_attr "type" "ssemov")
5116    (set_attr "mode" "V2SF,V4SF,V2SF")])
5117
5118 (define_insn "*vec_extractv2df_0_sse"
5119   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,x,x")
5120         (vec_select:DF
5121           (match_operand:V2DF 1 "nonimmediate_operand" "x,x,m")
5122           (parallel [(const_int 0)])))]
5123   "!TARGET_SSE2 && TARGET_SSE
5124    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5125   "@
5126    movlps\t{%1, %0|%0, %1}
5127    movaps\t{%1, %0|%0, %1}
5128    movlps\t{%1, %0|%0, %1}"
5129   [(set_attr "type" "ssemov")
5130    (set_attr "mode" "V2SF,V4SF,V2SF")])
5131
5132 (define_insn "*avx_movsd"
5133   [(set (match_operand:V2DF 0 "nonimmediate_operand"   "=x,x,m,x,o")
5134         (vec_merge:V2DF
5135           (match_operand:V2DF 2 "nonimmediate_operand" " x,m,x,x,0")
5136           (match_operand:V2DF 1 "nonimmediate_operand" " x,x,0,o,x")
5137           (const_int 1)))]
5138   "TARGET_AVX"
5139   "@
5140    vmovsd\t{%2, %1, %0|%0, %1, %2}
5141    vmovlpd\t{%2, %1, %0|%0, %1, %2}
5142    vmovlpd\t{%2, %0|%0, %2}
5143    vmovhps\t{%H1, %2, %0|%0, %2, %H1}
5144    vmovhps\t{%1, %H0|%H0, %1}"
5145   [(set_attr "type" "ssemov,ssemov,ssemov,ssemov,ssemov")
5146    (set_attr "prefix" "vex")
5147    (set_attr "mode" "DF,V1DF,V1DF,V1DF,V1DF")])
5148
5149 (define_insn "sse2_movsd"
5150   [(set (match_operand:V2DF 0 "nonimmediate_operand"   "=x,x,m,x,x,o")
5151         (vec_merge:V2DF
5152           (match_operand:V2DF 2 "nonimmediate_operand" " x,m,x,0,0,0")
5153           (match_operand:V2DF 1 "nonimmediate_operand" " 0,0,0,x,o,x")
5154           (const_int 1)))]
5155   "TARGET_SSE2"
5156   "@
5157    movsd\t{%2, %0|%0, %2}
5158    movlpd\t{%2, %0|%0, %2}
5159    movlpd\t{%2, %0|%0, %2}
5160    shufpd\t{$2, %2, %0|%0, %2, 2}
5161    movhps\t{%H1, %0|%0, %H1}
5162    movhps\t{%1, %H0|%H0, %1}"
5163   [(set_attr "type" "ssemov,ssemov,ssemov,sselog,ssemov,ssemov")
5164    (set_attr "prefix_data16" "*,1,1,*,*,*")
5165    (set_attr "length_immediate" "*,*,*,1,*,*")
5166    (set_attr "mode" "DF,V1DF,V1DF,V2DF,V1DF,V1DF")])
5167
5168 (define_insn "*vec_dupv2df_sse3"
5169   [(set (match_operand:V2DF 0 "register_operand" "=x")
5170         (vec_duplicate:V2DF
5171           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
5172   "TARGET_SSE3"
5173   "%vmovddup\t{%1, %0|%0, %1}"
5174   [(set_attr "type" "sselog1")
5175    (set_attr "prefix" "maybe_vex")
5176    (set_attr "mode" "DF")])
5177
5178 (define_insn "vec_dupv2df"
5179   [(set (match_operand:V2DF 0 "register_operand" "=x")
5180         (vec_duplicate:V2DF
5181           (match_operand:DF 1 "register_operand" "0")))]
5182   "TARGET_SSE2"
5183   "unpcklpd\t%0, %0"
5184   [(set_attr "type" "sselog1")
5185    (set_attr "mode" "V2DF")])
5186
5187 (define_insn "*vec_concatv2df_sse3"
5188   [(set (match_operand:V2DF 0 "register_operand" "=x")
5189         (vec_concat:V2DF
5190           (match_operand:DF 1 "nonimmediate_operand" "xm")
5191           (match_dup 1)))]
5192   "TARGET_SSE3"
5193   "%vmovddup\t{%1, %0|%0, %1}"
5194   [(set_attr "type" "sselog1")
5195    (set_attr "prefix" "maybe_vex")
5196    (set_attr "mode" "DF")])
5197
5198 (define_insn "*vec_concatv2df_avx"
5199   [(set (match_operand:V2DF 0 "register_operand"     "=x,x,x")
5200         (vec_concat:V2DF
5201           (match_operand:DF 1 "nonimmediate_operand" " x,x,m")
5202           (match_operand:DF 2 "vector_move_operand"  " x,m,C")))]
5203   "TARGET_AVX"
5204   "@
5205    vunpcklpd\t{%2, %1, %0|%0, %1, %2}
5206    vmovhpd\t{%2, %1, %0|%0, %1, %2}
5207    vmovsd\t{%1, %0|%0, %1}"
5208   [(set_attr "type" "ssemov")
5209    (set_attr "prefix" "vex")
5210    (set_attr "mode" "DF,V1DF,DF")])
5211
5212 (define_insn "*vec_concatv2df"
5213   [(set (match_operand:V2DF 0 "register_operand"     "=Y2,Y2,Y2,x,x")
5214         (vec_concat:V2DF
5215           (match_operand:DF 1 "nonimmediate_operand" " 0 ,0 ,m ,0,0")
5216           (match_operand:DF 2 "vector_move_operand"  " Y2,m ,C ,x,m")))]
5217   "TARGET_SSE"
5218   "@
5219    unpcklpd\t{%2, %0|%0, %2}
5220    movhpd\t{%2, %0|%0, %2}
5221    movsd\t{%1, %0|%0, %1}
5222    movlhps\t{%2, %0|%0, %2}
5223    movhps\t{%2, %0|%0, %2}"
5224   [(set_attr "type" "sselog,ssemov,ssemov,ssemov,ssemov")
5225    (set_attr "prefix_data16" "*,1,*,*,*")
5226    (set_attr "mode" "V2DF,V1DF,DF,V4SF,V2SF")])
5227
5228 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5229 ;;
5230 ;; Parallel integral arithmetic
5231 ;;
5232 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5233
5234 (define_expand "neg<mode>2"
5235   [(set (match_operand:SSEMODEI 0 "register_operand" "")
5236         (minus:SSEMODEI
5237           (match_dup 2)
5238           (match_operand:SSEMODEI 1 "nonimmediate_operand" "")))]
5239   "TARGET_SSE2"
5240   "operands[2] = force_reg (<MODE>mode, CONST0_RTX (<MODE>mode));")
5241
5242 (define_expand "<plusminus_insn><mode>3"
5243   [(set (match_operand:SSEMODEI 0 "register_operand" "")
5244         (plusminus:SSEMODEI
5245           (match_operand:SSEMODEI 1 "nonimmediate_operand" "")
5246           (match_operand:SSEMODEI 2 "nonimmediate_operand" "")))]
5247   "TARGET_SSE2"
5248   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
5249
5250 (define_insn "*avx_<plusminus_insn><mode>3"
5251   [(set (match_operand:SSEMODEI 0 "register_operand" "=x")
5252         (plusminus:SSEMODEI
5253           (match_operand:SSEMODEI 1 "nonimmediate_operand" "<comm>x")
5254           (match_operand:SSEMODEI 2 "nonimmediate_operand" "xm")))]
5255   "TARGET_AVX && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5256   "vp<plusminus_mnemonic><ssevecsize>\t{%2, %1, %0|%0, %1, %2}"
5257   [(set_attr "type" "sseiadd")
5258    (set_attr "prefix" "vex")
5259    (set_attr "mode" "TI")])
5260
5261 (define_insn "*<plusminus_insn><mode>3"
5262   [(set (match_operand:SSEMODEI 0 "register_operand" "=x")
5263         (plusminus:SSEMODEI
5264           (match_operand:SSEMODEI 1 "nonimmediate_operand" "<comm>0")
5265           (match_operand:SSEMODEI 2 "nonimmediate_operand" "xm")))]
5266   "TARGET_SSE2 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5267   "p<plusminus_mnemonic><ssevecsize>\t{%2, %0|%0, %2}"
5268   [(set_attr "type" "sseiadd")
5269    (set_attr "prefix_data16" "1")
5270    (set_attr "mode" "TI")])
5271
5272 (define_expand "sse2_<plusminus_insn><mode>3"
5273   [(set (match_operand:SSEMODE12 0 "register_operand" "")
5274         (sat_plusminus:SSEMODE12
5275           (match_operand:SSEMODE12 1 "nonimmediate_operand" "")
5276           (match_operand:SSEMODE12 2 "nonimmediate_operand" "")))]
5277   "TARGET_SSE2"
5278   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
5279
5280 (define_insn "*avx_<plusminus_insn><mode>3"
5281   [(set (match_operand:SSEMODE12 0 "register_operand" "=x")
5282         (sat_plusminus:SSEMODE12
5283           (match_operand:SSEMODE12 1 "nonimmediate_operand" "<comm>x")
5284           (match_operand:SSEMODE12 2 "nonimmediate_operand" "xm")))]
5285   "TARGET_AVX && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5286   "vp<plusminus_mnemonic><ssevecsize>\t{%2, %1, %0|%0, %1, %2}"
5287   [(set_attr "type" "sseiadd")
5288    (set_attr "prefix" "vex")
5289    (set_attr "mode" "TI")])
5290
5291 (define_insn "*sse2_<plusminus_insn><mode>3"
5292   [(set (match_operand:SSEMODE12 0 "register_operand" "=x")
5293         (sat_plusminus:SSEMODE12
5294           (match_operand:SSEMODE12 1 "nonimmediate_operand" "<comm>0")
5295           (match_operand:SSEMODE12 2 "nonimmediate_operand" "xm")))]
5296   "TARGET_SSE2 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5297   "p<plusminus_mnemonic><ssevecsize>\t{%2, %0|%0, %2}"
5298   [(set_attr "type" "sseiadd")
5299    (set_attr "prefix_data16" "1")
5300    (set_attr "mode" "TI")])
5301
5302 (define_insn_and_split "mulv16qi3"
5303   [(set (match_operand:V16QI 0 "register_operand" "")
5304         (mult:V16QI (match_operand:V16QI 1 "register_operand" "")
5305                     (match_operand:V16QI 2 "register_operand" "")))]
5306   "TARGET_SSE2
5307    && can_create_pseudo_p ()"
5308   "#"
5309   "&& 1"
5310   [(const_int 0)]
5311 {
5312   rtx t[6];
5313   int i;
5314
5315   for (i = 0; i < 6; ++i)
5316     t[i] = gen_reg_rtx (V16QImode);
5317
5318   /* Unpack data such that we've got a source byte in each low byte of
5319      each word.  We don't care what goes into the high byte of each word.
5320      Rather than trying to get zero in there, most convenient is to let
5321      it be a copy of the low byte.  */
5322   emit_insn (gen_vec_interleave_highv16qi (t[0], operands[1], operands[1]));
5323   emit_insn (gen_vec_interleave_highv16qi (t[1], operands[2], operands[2]));
5324   emit_insn (gen_vec_interleave_lowv16qi (t[2], operands[1], operands[1]));
5325   emit_insn (gen_vec_interleave_lowv16qi (t[3], operands[2], operands[2]));
5326
5327   /* Multiply words.  The end-of-line annotations here give a picture of what
5328      the output of that instruction looks like.  Dot means don't care; the
5329      letters are the bytes of the result with A being the most significant.  */
5330   emit_insn (gen_mulv8hi3 (gen_lowpart (V8HImode, t[4]), /* .A.B.C.D.E.F.G.H */
5331                            gen_lowpart (V8HImode, t[0]),
5332                            gen_lowpart (V8HImode, t[1])));
5333   emit_insn (gen_mulv8hi3 (gen_lowpart (V8HImode, t[5]), /* .I.J.K.L.M.N.O.P */
5334                            gen_lowpart (V8HImode, t[2]),
5335                            gen_lowpart (V8HImode, t[3])));
5336
5337   /* Extract the even bytes and merge them back together.  */
5338   ix86_expand_vec_extract_even_odd (operands[0], t[5], t[4], 0);
5339   DONE;
5340 })
5341
5342 (define_expand "mulv8hi3"
5343   [(set (match_operand:V8HI 0 "register_operand" "")
5344         (mult:V8HI (match_operand:V8HI 1 "nonimmediate_operand" "")
5345                    (match_operand:V8HI 2 "nonimmediate_operand" "")))]
5346   "TARGET_SSE2"
5347   "ix86_fixup_binary_operands_no_copy (MULT, V8HImode, operands);")
5348
5349 (define_insn "*avx_mulv8hi3"
5350   [(set (match_operand:V8HI 0 "register_operand" "=x")
5351         (mult:V8HI (match_operand:V8HI 1 "nonimmediate_operand" "%x")
5352                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
5353   "TARGET_AVX && ix86_binary_operator_ok (MULT, V8HImode, operands)"
5354   "vpmullw\t{%2, %1, %0|%0, %1, %2}"
5355   [(set_attr "type" "sseimul")
5356    (set_attr "prefix" "vex")
5357    (set_attr "mode" "TI")])
5358
5359 (define_insn "*mulv8hi3"
5360   [(set (match_operand:V8HI 0 "register_operand" "=x")
5361         (mult:V8HI (match_operand:V8HI 1 "nonimmediate_operand" "%0")
5362                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
5363   "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V8HImode, operands)"
5364   "pmullw\t{%2, %0|%0, %2}"
5365   [(set_attr "type" "sseimul")
5366    (set_attr "prefix_data16" "1")
5367    (set_attr "mode" "TI")])
5368
5369 (define_expand "<s>mulv8hi3_highpart"
5370   [(set (match_operand:V8HI 0 "register_operand" "")
5371         (truncate:V8HI
5372           (lshiftrt:V8SI
5373             (mult:V8SI
5374               (any_extend:V8SI
5375                 (match_operand:V8HI 1 "nonimmediate_operand" ""))
5376               (any_extend:V8SI
5377                 (match_operand:V8HI 2 "nonimmediate_operand" "")))
5378             (const_int 16))))]
5379   "TARGET_SSE2"
5380   "ix86_fixup_binary_operands_no_copy (MULT, V8HImode, operands);")
5381
5382 (define_insn "*avx_<s>mulv8hi3_highpart"
5383   [(set (match_operand:V8HI 0 "register_operand" "=x")
5384         (truncate:V8HI
5385           (lshiftrt:V8SI
5386             (mult:V8SI
5387               (any_extend:V8SI
5388                 (match_operand:V8HI 1 "nonimmediate_operand" "%x"))
5389               (any_extend:V8SI
5390                 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
5391             (const_int 16))))]
5392   "TARGET_AVX && ix86_binary_operator_ok (MULT, V8HImode, operands)"
5393   "vpmulh<u>w\t{%2, %1, %0|%0, %1, %2}"
5394   [(set_attr "type" "sseimul")
5395    (set_attr "prefix" "vex")
5396    (set_attr "mode" "TI")])
5397
5398 (define_insn "*<s>mulv8hi3_highpart"
5399   [(set (match_operand:V8HI 0 "register_operand" "=x")
5400         (truncate:V8HI
5401           (lshiftrt:V8SI
5402             (mult:V8SI
5403               (any_extend:V8SI
5404                 (match_operand:V8HI 1 "nonimmediate_operand" "%0"))
5405               (any_extend:V8SI
5406                 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
5407             (const_int 16))))]
5408   "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V8HImode, operands)"
5409   "pmulh<u>w\t{%2, %0|%0, %2}"
5410   [(set_attr "type" "sseimul")
5411    (set_attr "prefix_data16" "1")
5412    (set_attr "mode" "TI")])
5413
5414 (define_expand "sse2_umulv2siv2di3"
5415   [(set (match_operand:V2DI 0 "register_operand" "")
5416         (mult:V2DI
5417           (zero_extend:V2DI
5418             (vec_select:V2SI
5419               (match_operand:V4SI 1 "nonimmediate_operand" "")
5420               (parallel [(const_int 0) (const_int 2)])))
5421           (zero_extend:V2DI
5422             (vec_select:V2SI
5423               (match_operand:V4SI 2 "nonimmediate_operand" "")
5424               (parallel [(const_int 0) (const_int 2)])))))]
5425   "TARGET_SSE2"
5426   "ix86_fixup_binary_operands_no_copy (MULT, V4SImode, operands);")
5427
5428 (define_insn "*avx_umulv2siv2di3"
5429   [(set (match_operand:V2DI 0 "register_operand" "=x")
5430         (mult:V2DI
5431           (zero_extend:V2DI
5432             (vec_select:V2SI
5433               (match_operand:V4SI 1 "nonimmediate_operand" "%x")
5434               (parallel [(const_int 0) (const_int 2)])))
5435           (zero_extend:V2DI
5436             (vec_select:V2SI
5437               (match_operand:V4SI 2 "nonimmediate_operand" "xm")
5438               (parallel [(const_int 0) (const_int 2)])))))]
5439   "TARGET_AVX && ix86_binary_operator_ok (MULT, V4SImode, operands)"
5440   "vpmuludq\t{%2, %1, %0|%0, %1, %2}"
5441   [(set_attr "type" "sseimul")
5442    (set_attr "prefix" "vex")
5443    (set_attr "mode" "TI")])
5444
5445 (define_insn "*sse2_umulv2siv2di3"
5446   [(set (match_operand:V2DI 0 "register_operand" "=x")
5447         (mult:V2DI
5448           (zero_extend:V2DI
5449             (vec_select:V2SI
5450               (match_operand:V4SI 1 "nonimmediate_operand" "%0")
5451               (parallel [(const_int 0) (const_int 2)])))
5452           (zero_extend:V2DI
5453             (vec_select:V2SI
5454               (match_operand:V4SI 2 "nonimmediate_operand" "xm")
5455               (parallel [(const_int 0) (const_int 2)])))))]
5456   "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V4SImode, operands)"
5457   "pmuludq\t{%2, %0|%0, %2}"
5458   [(set_attr "type" "sseimul")
5459    (set_attr "prefix_data16" "1")
5460    (set_attr "mode" "TI")])
5461
5462 (define_expand "sse4_1_mulv2siv2di3"
5463   [(set (match_operand:V2DI 0 "register_operand" "")
5464         (mult:V2DI
5465           (sign_extend:V2DI
5466             (vec_select:V2SI
5467               (match_operand:V4SI 1 "nonimmediate_operand" "")
5468               (parallel [(const_int 0) (const_int 2)])))
5469           (sign_extend:V2DI
5470             (vec_select:V2SI
5471               (match_operand:V4SI 2 "nonimmediate_operand" "")
5472               (parallel [(const_int 0) (const_int 2)])))))]
5473   "TARGET_SSE4_1"
5474   "ix86_fixup_binary_operands_no_copy (MULT, V4SImode, operands);")
5475
5476 (define_insn "*avx_mulv2siv2di3"
5477   [(set (match_operand:V2DI 0 "register_operand" "=x")
5478         (mult:V2DI
5479           (sign_extend:V2DI
5480             (vec_select:V2SI
5481               (match_operand:V4SI 1 "nonimmediate_operand" "%x")
5482               (parallel [(const_int 0) (const_int 2)])))
5483           (sign_extend:V2DI
5484             (vec_select:V2SI
5485               (match_operand:V4SI 2 "nonimmediate_operand" "xm")
5486               (parallel [(const_int 0) (const_int 2)])))))]
5487   "TARGET_AVX && ix86_binary_operator_ok (MULT, V4SImode, operands)"
5488   "vpmuldq\t{%2, %1, %0|%0, %1, %2}"
5489   [(set_attr "type" "sseimul")
5490    (set_attr "prefix_extra" "1")
5491    (set_attr "prefix" "vex")
5492    (set_attr "mode" "TI")])
5493
5494 (define_insn "*sse4_1_mulv2siv2di3"
5495   [(set (match_operand:V2DI 0 "register_operand" "=x")
5496         (mult:V2DI
5497           (sign_extend:V2DI
5498             (vec_select:V2SI
5499               (match_operand:V4SI 1 "nonimmediate_operand" "%0")
5500               (parallel [(const_int 0) (const_int 2)])))
5501           (sign_extend:V2DI
5502             (vec_select:V2SI
5503               (match_operand:V4SI 2 "nonimmediate_operand" "xm")
5504               (parallel [(const_int 0) (const_int 2)])))))]
5505   "TARGET_SSE4_1 && ix86_binary_operator_ok (MULT, V4SImode, operands)"
5506   "pmuldq\t{%2, %0|%0, %2}"
5507   [(set_attr "type" "sseimul")
5508    (set_attr "prefix_extra" "1")
5509    (set_attr "mode" "TI")])
5510
5511 (define_expand "sse2_pmaddwd"
5512   [(set (match_operand:V4SI 0 "register_operand" "")
5513         (plus:V4SI
5514           (mult:V4SI
5515             (sign_extend:V4SI
5516               (vec_select:V4HI
5517                 (match_operand:V8HI 1 "nonimmediate_operand" "")
5518                 (parallel [(const_int 0)
5519                            (const_int 2)
5520                            (const_int 4)
5521                            (const_int 6)])))
5522             (sign_extend:V4SI
5523               (vec_select:V4HI
5524                 (match_operand:V8HI 2 "nonimmediate_operand" "")
5525                 (parallel [(const_int 0)
5526                            (const_int 2)
5527                            (const_int 4)
5528                            (const_int 6)]))))
5529           (mult:V4SI
5530             (sign_extend:V4SI
5531               (vec_select:V4HI (match_dup 1)
5532                 (parallel [(const_int 1)
5533                            (const_int 3)
5534                            (const_int 5)
5535                            (const_int 7)])))
5536             (sign_extend:V4SI
5537               (vec_select:V4HI (match_dup 2)
5538                 (parallel [(const_int 1)
5539                            (const_int 3)
5540                            (const_int 5)
5541                            (const_int 7)]))))))]
5542   "TARGET_SSE2"
5543   "ix86_fixup_binary_operands_no_copy (MULT, V8HImode, operands);")
5544
5545 (define_insn "*avx_pmaddwd"
5546   [(set (match_operand:V4SI 0 "register_operand" "=x")
5547         (plus:V4SI
5548           (mult:V4SI
5549             (sign_extend:V4SI
5550               (vec_select:V4HI
5551                 (match_operand:V8HI 1 "nonimmediate_operand" "%x")
5552                 (parallel [(const_int 0)
5553                            (const_int 2)
5554                            (const_int 4)
5555                            (const_int 6)])))
5556             (sign_extend:V4SI
5557               (vec_select:V4HI
5558                 (match_operand:V8HI 2 "nonimmediate_operand" "xm")
5559                 (parallel [(const_int 0)
5560                            (const_int 2)
5561                            (const_int 4)
5562                            (const_int 6)]))))
5563           (mult:V4SI
5564             (sign_extend:V4SI
5565               (vec_select:V4HI (match_dup 1)
5566                 (parallel [(const_int 1)
5567                            (const_int 3)
5568                            (const_int 5)
5569                            (const_int 7)])))
5570             (sign_extend:V4SI
5571               (vec_select:V4HI (match_dup 2)
5572                 (parallel [(const_int 1)
5573                            (const_int 3)
5574                            (const_int 5)
5575                            (const_int 7)]))))))]
5576   "TARGET_AVX && ix86_binary_operator_ok (MULT, V8HImode, operands)"
5577   "vpmaddwd\t{%2, %1, %0|%0, %1, %2}"
5578   [(set_attr "type" "sseiadd")
5579    (set_attr "prefix" "vex")
5580    (set_attr "mode" "TI")])
5581
5582 (define_insn "*sse2_pmaddwd"
5583   [(set (match_operand:V4SI 0 "register_operand" "=x")
5584         (plus:V4SI
5585           (mult:V4SI
5586             (sign_extend:V4SI
5587               (vec_select:V4HI
5588                 (match_operand:V8HI 1 "nonimmediate_operand" "%0")
5589                 (parallel [(const_int 0)
5590                            (const_int 2)
5591                            (const_int 4)
5592                            (const_int 6)])))
5593             (sign_extend:V4SI
5594               (vec_select:V4HI
5595                 (match_operand:V8HI 2 "nonimmediate_operand" "xm")
5596                 (parallel [(const_int 0)
5597                            (const_int 2)
5598                            (const_int 4)
5599                            (const_int 6)]))))
5600           (mult:V4SI
5601             (sign_extend:V4SI
5602               (vec_select:V4HI (match_dup 1)
5603                 (parallel [(const_int 1)
5604                            (const_int 3)
5605                            (const_int 5)
5606                            (const_int 7)])))
5607             (sign_extend:V4SI
5608               (vec_select:V4HI (match_dup 2)
5609                 (parallel [(const_int 1)
5610                            (const_int 3)
5611                            (const_int 5)
5612                            (const_int 7)]))))))]
5613   "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V8HImode, operands)"
5614   "pmaddwd\t{%2, %0|%0, %2}"
5615   [(set_attr "type" "sseiadd")
5616    (set_attr "atom_unit" "simul")
5617    (set_attr "prefix_data16" "1")
5618    (set_attr "mode" "TI")])
5619
5620 (define_expand "mulv4si3"
5621   [(set (match_operand:V4SI 0 "register_operand" "")
5622         (mult:V4SI (match_operand:V4SI 1 "register_operand" "")
5623                    (match_operand:V4SI 2 "register_operand" "")))]
5624   "TARGET_SSE2"
5625 {
5626   if (TARGET_SSE4_1 || TARGET_AVX)
5627     ix86_fixup_binary_operands_no_copy (MULT, V4SImode, operands);
5628 })
5629
5630 (define_insn "*avx_mulv4si3"
5631   [(set (match_operand:V4SI 0 "register_operand" "=x")
5632         (mult:V4SI (match_operand:V4SI 1 "nonimmediate_operand" "%x")
5633                    (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
5634   "TARGET_AVX && ix86_binary_operator_ok (MULT, V4SImode, operands)"
5635   "vpmulld\t{%2, %1, %0|%0, %1, %2}"
5636   [(set_attr "type" "sseimul")
5637    (set_attr "prefix_extra" "1")
5638    (set_attr "prefix" "vex")
5639    (set_attr "mode" "TI")])
5640
5641 (define_insn "*sse4_1_mulv4si3"
5642   [(set (match_operand:V4SI 0 "register_operand" "=x")
5643         (mult:V4SI (match_operand:V4SI 1 "nonimmediate_operand" "%0")
5644                    (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
5645   "TARGET_SSE4_1 && ix86_binary_operator_ok (MULT, V4SImode, operands)"
5646   "pmulld\t{%2, %0|%0, %2}"
5647   [(set_attr "type" "sseimul")
5648    (set_attr "prefix_extra" "1")
5649    (set_attr "mode" "TI")])
5650
5651 (define_insn_and_split "*sse2_mulv4si3"
5652   [(set (match_operand:V4SI 0 "register_operand" "")
5653         (mult:V4SI (match_operand:V4SI 1 "register_operand" "")
5654                    (match_operand:V4SI 2 "register_operand" "")))]
5655   "TARGET_SSE2 && !TARGET_SSE4_1 && !TARGET_AVX
5656    && can_create_pseudo_p ()"
5657   "#"
5658   "&& 1"
5659   [(const_int 0)]
5660 {
5661   rtx t1, t2, t3, t4, t5, t6, thirtytwo;
5662   rtx op0, op1, op2;
5663
5664   op0 = operands[0];
5665   op1 = operands[1];
5666   op2 = operands[2];
5667   t1 = gen_reg_rtx (V4SImode);
5668   t2 = gen_reg_rtx (V4SImode);
5669   t3 = gen_reg_rtx (V4SImode);
5670   t4 = gen_reg_rtx (V4SImode);
5671   t5 = gen_reg_rtx (V4SImode);
5672   t6 = gen_reg_rtx (V4SImode);
5673   thirtytwo = GEN_INT (32);
5674
5675   /* Multiply elements 2 and 0.  */
5676   emit_insn (gen_sse2_umulv2siv2di3 (gen_lowpart (V2DImode, t1),
5677                                      op1, op2));
5678
5679   /* Shift both input vectors down one element, so that elements 3
5680      and 1 are now in the slots for elements 2 and 0.  For K8, at
5681      least, this is faster than using a shuffle.  */
5682   emit_insn (gen_sse2_lshrv1ti3 (gen_lowpart (V1TImode, t2),
5683                                  gen_lowpart (V1TImode, op1),
5684                                  thirtytwo));
5685   emit_insn (gen_sse2_lshrv1ti3 (gen_lowpart (V1TImode, t3),
5686                                  gen_lowpart (V1TImode, op2),
5687                                  thirtytwo));
5688   /* Multiply elements 3 and 1.  */
5689   emit_insn (gen_sse2_umulv2siv2di3 (gen_lowpart (V2DImode, t4),
5690                                      t2, t3));
5691
5692   /* Move the results in element 2 down to element 1; we don't care
5693      what goes in elements 2 and 3.  */
5694   emit_insn (gen_sse2_pshufd_1 (t5, t1, const0_rtx, const2_rtx,
5695                                 const0_rtx, const0_rtx));
5696   emit_insn (gen_sse2_pshufd_1 (t6, t4, const0_rtx, const2_rtx,
5697                                 const0_rtx, const0_rtx));
5698
5699   /* Merge the parts back together.  */
5700   emit_insn (gen_vec_interleave_lowv4si (op0, t5, t6));
5701   DONE;
5702 })
5703
5704 (define_insn_and_split "mulv2di3"
5705   [(set (match_operand:V2DI 0 "register_operand" "")
5706         (mult:V2DI (match_operand:V2DI 1 "register_operand" "")
5707                    (match_operand:V2DI 2 "register_operand" "")))]
5708   "TARGET_SSE2
5709    && can_create_pseudo_p ()"
5710   "#"
5711   "&& 1"
5712   [(const_int 0)]
5713 {
5714   rtx t1, t2, t3, t4, t5, t6, thirtytwo;
5715   rtx op0, op1, op2;
5716
5717   op0 = operands[0];
5718   op1 = operands[1];
5719   op2 = operands[2];
5720
5721   if (TARGET_XOP)
5722     {
5723       /* op1: A,B,C,D, op2: E,F,G,H */
5724       op1 = gen_lowpart (V4SImode, op1);
5725       op2 = gen_lowpart (V4SImode, op2);
5726
5727       t1 = gen_reg_rtx (V4SImode);
5728       t2 = gen_reg_rtx (V4SImode);
5729       t3 = gen_reg_rtx (V2DImode);
5730       t4 = gen_reg_rtx (V2DImode);
5731
5732       /* t1: B,A,D,C */
5733       emit_insn (gen_sse2_pshufd_1 (t1, op1,
5734                                     GEN_INT (1),
5735                                     GEN_INT (0),
5736                                     GEN_INT (3),
5737                                     GEN_INT (2)));
5738
5739       /* t2: (B*E),(A*F),(D*G),(C*H) */
5740       emit_insn (gen_mulv4si3 (t2, t1, op2));
5741
5742       /* t4: (B*E)+(A*F), (D*G)+(C*H) */
5743       emit_insn (gen_xop_phadddq (t3, t2));
5744
5745       /* t5: ((B*E)+(A*F))<<32, ((D*G)+(C*H))<<32 */
5746       emit_insn (gen_ashlv2di3 (t4, t3, GEN_INT (32)));
5747
5748       /* op0: (((B*E)+(A*F))<<32)+(B*F), (((D*G)+(C*H))<<32)+(D*H) */
5749       emit_insn (gen_xop_pmacsdql (op0, op1, op2, t4));
5750     }
5751   else
5752     {
5753       t1 = gen_reg_rtx (V2DImode);
5754       t2 = gen_reg_rtx (V2DImode);
5755       t3 = gen_reg_rtx (V2DImode);
5756       t4 = gen_reg_rtx (V2DImode);
5757       t5 = gen_reg_rtx (V2DImode);
5758       t6 = gen_reg_rtx (V2DImode);
5759       thirtytwo = GEN_INT (32);
5760
5761       /* Multiply low parts.  */
5762       emit_insn (gen_sse2_umulv2siv2di3 (t1, gen_lowpart (V4SImode, op1),
5763                                          gen_lowpart (V4SImode, op2)));
5764
5765       /* Shift input vectors left 32 bits so we can multiply high parts.  */
5766       emit_insn (gen_lshrv2di3 (t2, op1, thirtytwo));
5767       emit_insn (gen_lshrv2di3 (t3, op2, thirtytwo));
5768
5769       /* Multiply high parts by low parts.  */
5770       emit_insn (gen_sse2_umulv2siv2di3 (t4, gen_lowpart (V4SImode, op1),
5771                                          gen_lowpart (V4SImode, t3)));
5772       emit_insn (gen_sse2_umulv2siv2di3 (t5, gen_lowpart (V4SImode, op2),
5773                                          gen_lowpart (V4SImode, t2)));
5774
5775       /* Shift them back.  */
5776       emit_insn (gen_ashlv2di3 (t4, t4, thirtytwo));
5777       emit_insn (gen_ashlv2di3 (t5, t5, thirtytwo));
5778
5779       /* Add the three parts together.  */
5780       emit_insn (gen_addv2di3 (t6, t1, t4));
5781       emit_insn (gen_addv2di3 (op0, t6, t5));
5782     }
5783   DONE;
5784 })
5785
5786 (define_expand "vec_widen_smult_hi_v8hi"
5787   [(match_operand:V4SI 0 "register_operand" "")
5788    (match_operand:V8HI 1 "register_operand" "")
5789    (match_operand:V8HI 2 "register_operand" "")]
5790   "TARGET_SSE2"
5791 {
5792   rtx op1, op2, t1, t2, dest;
5793
5794   op1 = operands[1];
5795   op2 = operands[2];
5796   t1 = gen_reg_rtx (V8HImode);
5797   t2 = gen_reg_rtx (V8HImode);
5798   dest = gen_lowpart (V8HImode, operands[0]);
5799
5800   emit_insn (gen_mulv8hi3 (t1, op1, op2));
5801   emit_insn (gen_smulv8hi3_highpart (t2, op1, op2));
5802   emit_insn (gen_vec_interleave_highv8hi (dest, t1, t2));
5803   DONE;
5804 })
5805
5806 (define_expand "vec_widen_smult_lo_v8hi"
5807   [(match_operand:V4SI 0 "register_operand" "")
5808    (match_operand:V8HI 1 "register_operand" "")
5809    (match_operand:V8HI 2 "register_operand" "")]
5810   "TARGET_SSE2"
5811 {
5812   rtx op1, op2, t1, t2, dest;
5813
5814   op1 = operands[1];
5815   op2 = operands[2];
5816   t1 = gen_reg_rtx (V8HImode);
5817   t2 = gen_reg_rtx (V8HImode);
5818   dest = gen_lowpart (V8HImode, operands[0]);
5819
5820   emit_insn (gen_mulv8hi3 (t1, op1, op2));
5821   emit_insn (gen_smulv8hi3_highpart (t2, op1, op2));
5822   emit_insn (gen_vec_interleave_lowv8hi (dest, t1, t2));
5823   DONE;
5824 })
5825
5826 (define_expand "vec_widen_umult_hi_v8hi"
5827   [(match_operand:V4SI 0 "register_operand" "")
5828    (match_operand:V8HI 1 "register_operand" "")
5829    (match_operand:V8HI 2 "register_operand" "")]
5830   "TARGET_SSE2"
5831 {
5832   rtx op1, op2, t1, t2, dest;
5833
5834   op1 = operands[1];
5835   op2 = operands[2];
5836   t1 = gen_reg_rtx (V8HImode);
5837   t2 = gen_reg_rtx (V8HImode);
5838   dest = gen_lowpart (V8HImode, operands[0]);
5839
5840   emit_insn (gen_mulv8hi3 (t1, op1, op2));
5841   emit_insn (gen_umulv8hi3_highpart (t2, op1, op2));
5842   emit_insn (gen_vec_interleave_highv8hi (dest, t1, t2));
5843   DONE;
5844 })
5845
5846 (define_expand "vec_widen_umult_lo_v8hi"
5847   [(match_operand:V4SI 0 "register_operand" "")
5848    (match_operand:V8HI 1 "register_operand" "")
5849    (match_operand:V8HI 2 "register_operand" "")]
5850   "TARGET_SSE2"
5851 {
5852   rtx op1, op2, t1, t2, dest;
5853
5854   op1 = operands[1];
5855   op2 = operands[2];
5856   t1 = gen_reg_rtx (V8HImode);
5857   t2 = gen_reg_rtx (V8HImode);
5858   dest = gen_lowpart (V8HImode, operands[0]);
5859
5860   emit_insn (gen_mulv8hi3 (t1, op1, op2));
5861   emit_insn (gen_umulv8hi3_highpart (t2, op1, op2));
5862   emit_insn (gen_vec_interleave_lowv8hi (dest, t1, t2));
5863   DONE;
5864 })
5865
5866 (define_expand "vec_widen_smult_hi_v4si"
5867   [(match_operand:V2DI 0 "register_operand" "")
5868    (match_operand:V4SI 1 "register_operand" "")
5869    (match_operand:V4SI 2 "register_operand" "")]
5870   "TARGET_XOP"
5871 {
5872   rtx t1, t2;
5873
5874   t1 = gen_reg_rtx (V4SImode);
5875   t2 = gen_reg_rtx (V4SImode);
5876
5877   emit_insn (gen_sse2_pshufd_1 (t1, operands[1],
5878                                 GEN_INT (0),
5879                                 GEN_INT (2),
5880                                 GEN_INT (1),
5881                                 GEN_INT (3)));
5882   emit_insn (gen_sse2_pshufd_1 (t2, operands[2],
5883                                 GEN_INT (0),
5884                                 GEN_INT (2),
5885                                 GEN_INT (1),
5886                                 GEN_INT (3)));
5887   emit_insn (gen_xop_mulv2div2di3_high (operands[0], t1, t2));
5888   DONE;
5889 })
5890
5891 (define_expand "vec_widen_smult_lo_v4si"
5892   [(match_operand:V2DI 0 "register_operand" "")
5893    (match_operand:V4SI 1 "register_operand" "")
5894    (match_operand:V4SI 2 "register_operand" "")]
5895   "TARGET_XOP"
5896 {
5897   rtx t1, t2;
5898
5899   t1 = gen_reg_rtx (V4SImode);
5900   t2 = gen_reg_rtx (V4SImode);
5901
5902   emit_insn (gen_sse2_pshufd_1 (t1, operands[1],
5903                                 GEN_INT (0),
5904                                 GEN_INT (2),
5905                                 GEN_INT (1),
5906                                 GEN_INT (3)));
5907   emit_insn (gen_sse2_pshufd_1 (t2, operands[2],
5908                                 GEN_INT (0),
5909                                 GEN_INT (2),
5910                                 GEN_INT (1),
5911                                 GEN_INT (3)));
5912   emit_insn (gen_xop_mulv2div2di3_low (operands[0], t1, t2));
5913   DONE;
5914 })
5915
5916 (define_expand "vec_widen_umult_hi_v4si"
5917   [(match_operand:V2DI 0 "register_operand" "")
5918    (match_operand:V4SI 1 "register_operand" "")
5919    (match_operand:V4SI 2 "register_operand" "")]
5920   "TARGET_SSE2"
5921 {
5922   rtx op1, op2, t1, t2;
5923
5924   op1 = operands[1];
5925   op2 = operands[2];
5926   t1 = gen_reg_rtx (V4SImode);
5927   t2 = gen_reg_rtx (V4SImode);
5928
5929   emit_insn (gen_vec_interleave_highv4si (t1, op1, op1));
5930   emit_insn (gen_vec_interleave_highv4si (t2, op2, op2));
5931   emit_insn (gen_sse2_umulv2siv2di3 (operands[0], t1, t2));
5932   DONE;
5933 })
5934
5935 (define_expand "vec_widen_umult_lo_v4si"
5936   [(match_operand:V2DI 0 "register_operand" "")
5937    (match_operand:V4SI 1 "register_operand" "")
5938    (match_operand:V4SI 2 "register_operand" "")]
5939   "TARGET_SSE2"
5940 {
5941   rtx op1, op2, t1, t2;
5942
5943   op1 = operands[1];
5944   op2 = operands[2];
5945   t1 = gen_reg_rtx (V4SImode);
5946   t2 = gen_reg_rtx (V4SImode);
5947
5948   emit_insn (gen_vec_interleave_lowv4si (t1, op1, op1));
5949   emit_insn (gen_vec_interleave_lowv4si (t2, op2, op2));
5950   emit_insn (gen_sse2_umulv2siv2di3 (operands[0], t1, t2));
5951   DONE;
5952 })
5953
5954 (define_expand "sdot_prodv8hi"
5955   [(match_operand:V4SI 0 "register_operand" "")
5956    (match_operand:V8HI 1 "register_operand" "")
5957    (match_operand:V8HI 2 "register_operand" "")
5958    (match_operand:V4SI 3 "register_operand" "")]
5959   "TARGET_SSE2"
5960 {
5961   rtx t = gen_reg_rtx (V4SImode);
5962   emit_insn (gen_sse2_pmaddwd (t, operands[1], operands[2]));
5963   emit_insn (gen_addv4si3 (operands[0], operands[3], t));
5964   DONE;
5965 })
5966
5967 (define_expand "udot_prodv4si"
5968   [(match_operand:V2DI 0 "register_operand" "")
5969    (match_operand:V4SI 1 "register_operand" "")
5970    (match_operand:V4SI 2 "register_operand" "")
5971    (match_operand:V2DI 3 "register_operand" "")]
5972   "TARGET_SSE2"
5973 {
5974   rtx t1, t2, t3, t4;
5975
5976   t1 = gen_reg_rtx (V2DImode);
5977   emit_insn (gen_sse2_umulv2siv2di3 (t1, operands[1], operands[2]));
5978   emit_insn (gen_addv2di3 (t1, t1, operands[3]));
5979
5980   t2 = gen_reg_rtx (V4SImode);
5981   t3 = gen_reg_rtx (V4SImode);
5982   emit_insn (gen_sse2_lshrv1ti3 (gen_lowpart (V1TImode, t2),
5983                                  gen_lowpart (V1TImode, operands[1]),
5984                                  GEN_INT (32)));
5985   emit_insn (gen_sse2_lshrv1ti3 (gen_lowpart (V1TImode, t3),
5986                                  gen_lowpart (V1TImode, operands[2]),
5987                                  GEN_INT (32)));
5988
5989   t4 = gen_reg_rtx (V2DImode);
5990   emit_insn (gen_sse2_umulv2siv2di3 (t4, t2, t3));
5991
5992   emit_insn (gen_addv2di3 (operands[0], t1, t4));
5993   DONE;
5994 })
5995
5996 (define_insn "*avx_ashr<mode>3"
5997   [(set (match_operand:SSEMODE24 0 "register_operand" "=x")
5998         (ashiftrt:SSEMODE24
5999           (match_operand:SSEMODE24 1 "register_operand" "x")
6000           (match_operand:SI 2 "nonmemory_operand" "xN")))]
6001   "TARGET_AVX"
6002   "vpsra<ssevecsize>\t{%2, %1, %0|%0, %1, %2}"
6003   [(set_attr "type" "sseishft")
6004    (set_attr "prefix" "vex")
6005    (set (attr "length_immediate")
6006      (if_then_else (match_operand 2 "const_int_operand" "")
6007        (const_string "1")
6008        (const_string "0")))
6009    (set_attr "mode" "TI")])
6010
6011 (define_insn "ashr<mode>3"
6012   [(set (match_operand:SSEMODE24 0 "register_operand" "=x")
6013         (ashiftrt:SSEMODE24
6014           (match_operand:SSEMODE24 1 "register_operand" "0")
6015           (match_operand:SI 2 "nonmemory_operand" "xN")))]
6016   "TARGET_SSE2"
6017   "psra<ssevecsize>\t{%2, %0|%0, %2}"
6018   [(set_attr "type" "sseishft")
6019    (set_attr "prefix_data16" "1")
6020    (set (attr "length_immediate")
6021      (if_then_else (match_operand 2 "const_int_operand" "")
6022        (const_string "1")
6023        (const_string "0")))
6024    (set_attr "mode" "TI")])
6025
6026 (define_insn "*avx_lshrv1ti3"
6027   [(set (match_operand:V1TI 0 "register_operand" "=x")
6028         (lshiftrt:V1TI
6029          (match_operand:V1TI 1 "register_operand" "x")
6030          (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
6031   "TARGET_AVX"
6032 {
6033   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
6034   return "vpsrldq\t{%2, %1, %0|%0, %1, %2}";
6035 }
6036   [(set_attr "type" "sseishft")
6037    (set_attr "prefix" "vex")
6038    (set_attr "length_immediate" "1")
6039    (set_attr "mode" "TI")])
6040
6041 (define_insn "*avx_lshr<mode>3"
6042   [(set (match_operand:SSEMODE248 0 "register_operand" "=x")
6043         (lshiftrt:SSEMODE248
6044           (match_operand:SSEMODE248 1 "register_operand" "x")
6045           (match_operand:SI 2 "nonmemory_operand" "xN")))]
6046   "TARGET_AVX"
6047   "vpsrl<ssevecsize>\t{%2, %1, %0|%0, %1, %2}"
6048   [(set_attr "type" "sseishft")
6049    (set_attr "prefix" "vex")
6050    (set (attr "length_immediate")
6051      (if_then_else (match_operand 2 "const_int_operand" "")
6052        (const_string "1")
6053        (const_string "0")))
6054    (set_attr "mode" "TI")])
6055
6056 (define_insn "sse2_lshrv1ti3"
6057   [(set (match_operand:V1TI 0 "register_operand" "=x")
6058         (lshiftrt:V1TI
6059          (match_operand:V1TI 1 "register_operand" "0")
6060          (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
6061   "TARGET_SSE2"
6062 {
6063   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
6064   return "psrldq\t{%2, %0|%0, %2}";
6065 }
6066   [(set_attr "type" "sseishft")
6067    (set_attr "prefix_data16" "1")
6068    (set_attr "length_immediate" "1")
6069    (set_attr "atom_unit" "sishuf")
6070    (set_attr "mode" "TI")])
6071
6072 (define_insn "lshr<mode>3"
6073   [(set (match_operand:SSEMODE248 0 "register_operand" "=x")
6074         (lshiftrt:SSEMODE248
6075           (match_operand:SSEMODE248 1 "register_operand" "0")
6076           (match_operand:SI 2 "nonmemory_operand" "xN")))]
6077   "TARGET_SSE2"
6078   "psrl<ssevecsize>\t{%2, %0|%0, %2}"
6079   [(set_attr "type" "sseishft")
6080    (set_attr "prefix_data16" "1")
6081    (set (attr "length_immediate")
6082      (if_then_else (match_operand 2 "const_int_operand" "")
6083        (const_string "1")
6084        (const_string "0")))
6085    (set_attr "mode" "TI")])
6086
6087 (define_insn "*avx_ashlv1ti3"
6088   [(set (match_operand:V1TI 0 "register_operand" "=x")
6089         (ashift:V1TI (match_operand:V1TI 1 "register_operand" "x")
6090                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
6091   "TARGET_AVX"
6092 {
6093   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
6094   return "vpslldq\t{%2, %1, %0|%0, %1, %2}";
6095 }
6096   [(set_attr "type" "sseishft")
6097    (set_attr "prefix" "vex")
6098    (set_attr "length_immediate" "1")
6099    (set_attr "mode" "TI")])
6100
6101 (define_insn "*avx_ashl<mode>3"
6102   [(set (match_operand:SSEMODE248 0 "register_operand" "=x")
6103         (ashift:SSEMODE248
6104           (match_operand:SSEMODE248 1 "register_operand" "x")
6105           (match_operand:SI 2 "nonmemory_operand" "xN")))]
6106   "TARGET_AVX"
6107   "vpsll<ssevecsize>\t{%2, %1, %0|%0, %1, %2}"
6108   [(set_attr "type" "sseishft")
6109    (set_attr "prefix" "vex")
6110    (set (attr "length_immediate")
6111      (if_then_else (match_operand 2 "const_int_operand" "")
6112        (const_string "1")
6113        (const_string "0")))
6114    (set_attr "mode" "TI")])
6115
6116 (define_insn "sse2_ashlv1ti3"
6117   [(set (match_operand:V1TI 0 "register_operand" "=x")
6118         (ashift:V1TI (match_operand:V1TI 1 "register_operand" "0")
6119                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
6120   "TARGET_SSE2"
6121 {
6122   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
6123   return "pslldq\t{%2, %0|%0, %2}";
6124 }
6125   [(set_attr "type" "sseishft")
6126    (set_attr "prefix_data16" "1")
6127    (set_attr "length_immediate" "1")
6128    (set_attr "mode" "TI")])
6129
6130 (define_insn "ashl<mode>3"
6131   [(set (match_operand:SSEMODE248 0 "register_operand" "=x")
6132         (ashift:SSEMODE248
6133           (match_operand:SSEMODE248 1 "register_operand" "0")
6134           (match_operand:SI 2 "nonmemory_operand" "xN")))]
6135   "TARGET_SSE2"
6136   "psll<ssevecsize>\t{%2, %0|%0, %2}"
6137   [(set_attr "type" "sseishft")
6138    (set_attr "prefix_data16" "1")
6139    (set (attr "length_immediate")
6140      (if_then_else (match_operand 2 "const_int_operand" "")
6141        (const_string "1")
6142        (const_string "0")))
6143    (set_attr "mode" "TI")])
6144
6145 (define_expand "vec_shl_<mode>"
6146   [(set (match_operand:SSEMODEI 0 "register_operand" "")
6147         (ashift:V1TI
6148          (match_operand:SSEMODEI 1 "register_operand" "")
6149          (match_operand:SI 2 "const_0_to_255_mul_8_operand" "")))]
6150   "TARGET_SSE2"
6151 {
6152   operands[0] = gen_lowpart (V1TImode, operands[0]);
6153   operands[1] = gen_lowpart (V1TImode, operands[1]);
6154 })
6155
6156 (define_expand "vec_shr_<mode>"
6157   [(set (match_operand:SSEMODEI 0 "register_operand" "")
6158         (lshiftrt:V1TI
6159          (match_operand:SSEMODEI 1 "register_operand" "")
6160          (match_operand:SI 2 "const_0_to_255_mul_8_operand" "")))]
6161   "TARGET_SSE2"
6162 {
6163   operands[0] = gen_lowpart (V1TImode, operands[0]);
6164   operands[1] = gen_lowpart (V1TImode, operands[1]);
6165 })
6166
6167 (define_insn "*avx_<code><mode>3"
6168   [(set (match_operand:SSEMODE124 0 "register_operand" "=x")
6169         (umaxmin:SSEMODE124
6170           (match_operand:SSEMODE124 1 "nonimmediate_operand" "%x")
6171           (match_operand:SSEMODE124 2 "nonimmediate_operand" "xm")))]
6172   "TARGET_AVX && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6173   "vp<maxmin_int><ssevecsize>\t{%2, %1, %0|%0, %1, %2}"
6174   [(set_attr "type" "sseiadd")
6175    (set (attr "prefix_extra")
6176      (if_then_else (match_operand:V16QI 0 "" "")
6177        (const_string "0")
6178        (const_string "1")))
6179    (set_attr "prefix" "vex")
6180    (set_attr "mode" "TI")])
6181
6182 (define_expand "<code>v16qi3"
6183   [(set (match_operand:V16QI 0 "register_operand" "")
6184         (umaxmin:V16QI
6185           (match_operand:V16QI 1 "nonimmediate_operand" "")
6186           (match_operand:V16QI 2 "nonimmediate_operand" "")))]
6187   "TARGET_SSE2"
6188   "ix86_fixup_binary_operands_no_copy (<CODE>, V16QImode, operands);")
6189
6190 (define_insn "*<code>v16qi3"
6191   [(set (match_operand:V16QI 0 "register_operand" "=x")
6192         (umaxmin:V16QI
6193           (match_operand:V16QI 1 "nonimmediate_operand" "%0")
6194           (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
6195   "TARGET_SSE2 && ix86_binary_operator_ok (<CODE>, V16QImode, operands)"
6196   "p<maxmin_int>b\t{%2, %0|%0, %2}"
6197   [(set_attr "type" "sseiadd")
6198    (set_attr "prefix_data16" "1")
6199    (set_attr "mode" "TI")])
6200
6201 (define_insn "*avx_<code><mode>3"
6202   [(set (match_operand:SSEMODE124 0 "register_operand" "=x")
6203         (smaxmin:SSEMODE124
6204           (match_operand:SSEMODE124 1 "nonimmediate_operand" "%x")
6205           (match_operand:SSEMODE124 2 "nonimmediate_operand" "xm")))]
6206   "TARGET_AVX && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6207   "vp<maxmin_int><ssevecsize>\t{%2, %1, %0|%0, %1, %2}"
6208   [(set_attr "type" "sseiadd")
6209    (set (attr "prefix_extra")
6210      (if_then_else (match_operand:V8HI 0 "" "")
6211        (const_string "0")
6212        (const_string "1")))
6213    (set_attr "prefix" "vex")
6214    (set_attr "mode" "TI")])
6215
6216 (define_expand "<code>v8hi3"
6217   [(set (match_operand:V8HI 0 "register_operand" "")
6218         (smaxmin:V8HI
6219           (match_operand:V8HI 1 "nonimmediate_operand" "")
6220           (match_operand:V8HI 2 "nonimmediate_operand" "")))]
6221   "TARGET_SSE2"
6222   "ix86_fixup_binary_operands_no_copy (<CODE>, V8HImode, operands);")
6223
6224 (define_insn "*<code>v8hi3"
6225   [(set (match_operand:V8HI 0 "register_operand" "=x")
6226         (smaxmin:V8HI
6227           (match_operand:V8HI 1 "nonimmediate_operand" "%0")
6228           (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
6229   "TARGET_SSE2 && ix86_binary_operator_ok (<CODE>, V8HImode, operands)"
6230   "p<maxmin_int>w\t{%2, %0|%0, %2}"
6231   [(set_attr "type" "sseiadd")
6232    (set_attr "prefix_data16" "1")
6233    (set_attr "mode" "TI")])
6234
6235 (define_expand "umaxv8hi3"
6236   [(set (match_operand:V8HI 0 "register_operand" "")
6237         (umax:V8HI (match_operand:V8HI 1 "register_operand" "")
6238                    (match_operand:V8HI 2 "nonimmediate_operand" "")))]
6239   "TARGET_SSE2"
6240 {
6241   if (TARGET_SSE4_1)
6242     ix86_fixup_binary_operands_no_copy (UMAX, V8HImode, operands);
6243   else
6244     {
6245       rtx op0 = operands[0], op2 = operands[2], op3 = op0;
6246       if (rtx_equal_p (op3, op2))
6247         op3 = gen_reg_rtx (V8HImode);
6248       emit_insn (gen_sse2_ussubv8hi3 (op3, operands[1], op2));
6249       emit_insn (gen_addv8hi3 (op0, op3, op2));
6250       DONE;
6251     }
6252 })
6253
6254 (define_expand "smax<mode>3"
6255   [(set (match_operand:SSEMODE14 0 "register_operand" "")
6256         (smax:SSEMODE14 (match_operand:SSEMODE14 1 "register_operand" "")
6257                         (match_operand:SSEMODE14 2 "register_operand" "")))]
6258   "TARGET_SSE2"
6259 {
6260   if (TARGET_SSE4_1)
6261     ix86_fixup_binary_operands_no_copy (SMAX, <MODE>mode, operands);
6262   else
6263     {
6264       rtx xops[6];
6265       bool ok;
6266
6267       xops[0] = operands[0];
6268       xops[1] = operands[1];
6269       xops[2] = operands[2];
6270       xops[3] = gen_rtx_GT (VOIDmode, operands[1], operands[2]);
6271       xops[4] = operands[1];
6272       xops[5] = operands[2];
6273       ok = ix86_expand_int_vcond (xops);
6274       gcc_assert (ok);
6275       DONE;
6276     }
6277 })
6278
6279 (define_insn "*sse4_1_<code><mode>3"
6280   [(set (match_operand:SSEMODE14 0 "register_operand" "=x")
6281         (smaxmin:SSEMODE14
6282           (match_operand:SSEMODE14 1 "nonimmediate_operand" "%0")
6283           (match_operand:SSEMODE14 2 "nonimmediate_operand" "xm")))]
6284   "TARGET_SSE4_1 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6285   "p<maxmin_int><ssevecsize>\t{%2, %0|%0, %2}"
6286   [(set_attr "type" "sseiadd")
6287    (set_attr "prefix_extra" "1")
6288    (set_attr "mode" "TI")])
6289
6290 (define_expand "smaxv2di3"
6291   [(set (match_operand:V2DI 0 "register_operand" "")
6292         (smax:V2DI (match_operand:V2DI 1 "register_operand" "")
6293                    (match_operand:V2DI 2 "register_operand" "")))]
6294   "TARGET_SSE4_2"
6295 {
6296   rtx xops[6];
6297   bool ok;
6298
6299   xops[0] = operands[0];
6300   xops[1] = operands[1];
6301   xops[2] = operands[2];
6302   xops[3] = gen_rtx_GT (VOIDmode, operands[1], operands[2]);
6303   xops[4] = operands[1];
6304   xops[5] = operands[2];
6305   ok = ix86_expand_int_vcond (xops);
6306   gcc_assert (ok);
6307   DONE;
6308 })
6309
6310 (define_expand "umaxv4si3"
6311   [(set (match_operand:V4SI 0 "register_operand" "")
6312         (umax:V4SI (match_operand:V4SI 1 "register_operand" "")
6313                    (match_operand:V4SI 2 "register_operand" "")))]
6314   "TARGET_SSE2"
6315 {
6316   if (TARGET_SSE4_1)
6317     ix86_fixup_binary_operands_no_copy (UMAX, V4SImode, operands);
6318   else
6319     {
6320       rtx xops[6];
6321       bool ok;
6322
6323       xops[0] = operands[0];
6324       xops[1] = operands[1];
6325       xops[2] = operands[2];
6326       xops[3] = gen_rtx_GTU (VOIDmode, operands[1], operands[2]);
6327       xops[4] = operands[1];
6328       xops[5] = operands[2];
6329       ok = ix86_expand_int_vcond (xops);
6330       gcc_assert (ok);
6331       DONE;
6332     }
6333 })
6334
6335 (define_insn "*sse4_1_<code><mode>3"
6336   [(set (match_operand:SSEMODE24 0 "register_operand" "=x")
6337         (umaxmin:SSEMODE24
6338           (match_operand:SSEMODE24 1 "nonimmediate_operand" "%0")
6339           (match_operand:SSEMODE24 2 "nonimmediate_operand" "xm")))]
6340   "TARGET_SSE4_1 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6341   "p<maxmin_int><ssevecsize>\t{%2, %0|%0, %2}"
6342   [(set_attr "type" "sseiadd")
6343    (set_attr "prefix_extra" "1")
6344    (set_attr "mode" "TI")])
6345
6346 (define_expand "umaxv2di3"
6347   [(set (match_operand:V2DI 0 "register_operand" "")
6348         (umax:V2DI (match_operand:V2DI 1 "register_operand" "")
6349                    (match_operand:V2DI 2 "register_operand" "")))]
6350   "TARGET_SSE4_2"
6351 {
6352   rtx xops[6];
6353   bool ok;
6354
6355   xops[0] = operands[0];
6356   xops[1] = operands[1];
6357   xops[2] = operands[2];
6358   xops[3] = gen_rtx_GTU (VOIDmode, operands[1], operands[2]);
6359   xops[4] = operands[1];
6360   xops[5] = operands[2];
6361   ok = ix86_expand_int_vcond (xops);
6362   gcc_assert (ok);
6363   DONE;
6364 })
6365
6366 (define_expand "smin<mode>3"
6367   [(set (match_operand:SSEMODE14 0 "register_operand" "")
6368         (smin:SSEMODE14 (match_operand:SSEMODE14 1 "register_operand" "")
6369                         (match_operand:SSEMODE14 2 "register_operand" "")))]
6370   "TARGET_SSE2"
6371 {
6372   if (TARGET_SSE4_1)
6373     ix86_fixup_binary_operands_no_copy (SMIN, <MODE>mode, operands);
6374   else
6375     {
6376       rtx xops[6];
6377       bool ok;
6378
6379       xops[0] = operands[0];
6380       xops[1] = operands[2];
6381       xops[2] = operands[1];
6382       xops[3] = gen_rtx_GT (VOIDmode, operands[1], operands[2]);
6383       xops[4] = operands[1];
6384       xops[5] = operands[2];
6385       ok = ix86_expand_int_vcond (xops);
6386       gcc_assert (ok);
6387       DONE;
6388     }
6389 })
6390
6391 (define_expand "sminv2di3"
6392   [(set (match_operand:V2DI 0 "register_operand" "")
6393         (smin:V2DI (match_operand:V2DI 1 "register_operand" "")
6394                    (match_operand:V2DI 2 "register_operand" "")))]
6395   "TARGET_SSE4_2"
6396 {
6397   rtx xops[6];
6398   bool ok;
6399
6400   xops[0] = operands[0];
6401   xops[1] = operands[2];
6402   xops[2] = operands[1];
6403   xops[3] = gen_rtx_GT (VOIDmode, operands[1], operands[2]);
6404   xops[4] = operands[1];
6405   xops[5] = operands[2];
6406   ok = ix86_expand_int_vcond (xops);
6407   gcc_assert (ok);
6408   DONE;
6409 })
6410
6411 (define_expand "umin<mode>3"
6412   [(set (match_operand:SSEMODE24 0 "register_operand" "")
6413         (umin:SSEMODE24 (match_operand:SSEMODE24 1 "register_operand" "")
6414                         (match_operand:SSEMODE24 2 "register_operand" "")))]
6415   "TARGET_SSE2"
6416 {
6417   if (TARGET_SSE4_1)
6418     ix86_fixup_binary_operands_no_copy (UMIN, <MODE>mode, operands);
6419   else
6420     {
6421       rtx xops[6];
6422       bool ok;
6423
6424       xops[0] = operands[0];
6425       xops[1] = operands[2];
6426       xops[2] = operands[1];
6427       xops[3] = gen_rtx_GTU (VOIDmode, operands[1], operands[2]);
6428       xops[4] = operands[1];
6429       xops[5] = operands[2];
6430       ok = ix86_expand_int_vcond (xops);
6431       gcc_assert (ok);
6432       DONE;
6433     }
6434 })
6435
6436 (define_expand "uminv2di3"
6437   [(set (match_operand:V2DI 0 "register_operand" "")
6438         (umin:V2DI (match_operand:V2DI 1 "register_operand" "")
6439                    (match_operand:V2DI 2 "register_operand" "")))]
6440   "TARGET_SSE4_2"
6441 {
6442   rtx xops[6];
6443   bool ok;
6444
6445   xops[0] = operands[0];
6446   xops[1] = operands[2];
6447   xops[2] = operands[1];
6448   xops[3] = gen_rtx_GTU (VOIDmode, operands[1], operands[2]);
6449   xops[4] = operands[1];
6450   xops[5] = operands[2];
6451   ok = ix86_expand_int_vcond (xops);
6452   gcc_assert (ok);
6453   DONE;
6454 })
6455
6456 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6457 ;;
6458 ;; Parallel integral comparisons
6459 ;;
6460 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6461
6462 (define_expand "sse2_eq<mode>3"
6463   [(set (match_operand:SSEMODE124 0 "register_operand" "")
6464         (eq:SSEMODE124
6465           (match_operand:SSEMODE124 1 "nonimmediate_operand" "")
6466           (match_operand:SSEMODE124 2 "nonimmediate_operand" "")))]
6467   "TARGET_SSE2 && !TARGET_XOP "
6468   "ix86_fixup_binary_operands_no_copy (EQ, <MODE>mode, operands);")
6469
6470 (define_insn "*avx_eq<mode>3"
6471   [(set (match_operand:SSEMODE1248 0 "register_operand" "=x")
6472         (eq:SSEMODE1248
6473           (match_operand:SSEMODE1248 1 "nonimmediate_operand" "%x")
6474           (match_operand:SSEMODE1248 2 "nonimmediate_operand" "xm")))]
6475   "TARGET_AVX && ix86_binary_operator_ok (EQ, <MODE>mode, operands)"
6476   "vpcmpeq<ssevecsize>\t{%2, %1, %0|%0, %1, %2}"
6477   [(set_attr "type" "ssecmp")
6478    (set (attr "prefix_extra")
6479      (if_then_else (match_operand:V2DI 0 "" "")
6480        (const_string "1")
6481        (const_string "*")))
6482    (set_attr "prefix" "vex")
6483    (set_attr "mode" "TI")])
6484
6485 (define_insn "*sse2_eq<mode>3"
6486   [(set (match_operand:SSEMODE124 0 "register_operand" "=x")
6487         (eq:SSEMODE124
6488           (match_operand:SSEMODE124 1 "nonimmediate_operand" "%0")
6489           (match_operand:SSEMODE124 2 "nonimmediate_operand" "xm")))]
6490   "TARGET_SSE2 && !TARGET_XOP
6491    && ix86_binary_operator_ok (EQ, <MODE>mode, operands)"
6492   "pcmpeq<ssevecsize>\t{%2, %0|%0, %2}"
6493   [(set_attr "type" "ssecmp")
6494    (set_attr "prefix_data16" "1")
6495    (set_attr "mode" "TI")])
6496
6497 (define_expand "sse4_1_eqv2di3"
6498   [(set (match_operand:V2DI 0 "register_operand" "")
6499         (eq:V2DI
6500           (match_operand:V2DI 1 "nonimmediate_operand" "")
6501           (match_operand:V2DI 2 "nonimmediate_operand" "")))]
6502   "TARGET_SSE4_1"
6503   "ix86_fixup_binary_operands_no_copy (EQ, V2DImode, operands);")
6504
6505 (define_insn "*sse4_1_eqv2di3"
6506   [(set (match_operand:V2DI 0 "register_operand" "=x")
6507         (eq:V2DI
6508           (match_operand:V2DI 1 "nonimmediate_operand" "%0")
6509           (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
6510   "TARGET_SSE4_1 && ix86_binary_operator_ok (EQ, V2DImode, operands)"
6511   "pcmpeqq\t{%2, %0|%0, %2}"
6512   [(set_attr "type" "ssecmp")
6513    (set_attr "prefix_extra" "1")
6514    (set_attr "mode" "TI")])
6515
6516 (define_insn "*avx_gt<mode>3"
6517   [(set (match_operand:SSEMODE1248 0 "register_operand" "=x")
6518         (gt:SSEMODE1248
6519           (match_operand:SSEMODE1248 1 "register_operand" "x")
6520           (match_operand:SSEMODE1248 2 "nonimmediate_operand" "xm")))]
6521   "TARGET_AVX"
6522   "vpcmpgt<ssevecsize>\t{%2, %1, %0|%0, %1, %2}"
6523   [(set_attr "type" "ssecmp")
6524    (set (attr "prefix_extra")
6525      (if_then_else (match_operand:V2DI 0 "" "")
6526        (const_string "1")
6527        (const_string "*")))
6528    (set_attr "prefix" "vex")
6529    (set_attr "mode" "TI")])
6530
6531 (define_insn "sse2_gt<mode>3"
6532   [(set (match_operand:SSEMODE124 0 "register_operand" "=x")
6533         (gt:SSEMODE124
6534           (match_operand:SSEMODE124 1 "register_operand" "0")
6535           (match_operand:SSEMODE124 2 "nonimmediate_operand" "xm")))]
6536   "TARGET_SSE2 && !TARGET_XOP"
6537   "pcmpgt<ssevecsize>\t{%2, %0|%0, %2}"
6538   [(set_attr "type" "ssecmp")
6539    (set_attr "prefix_data16" "1")
6540    (set_attr "mode" "TI")])
6541
6542 (define_insn "sse4_2_gtv2di3"
6543   [(set (match_operand:V2DI 0 "register_operand" "=x")
6544         (gt:V2DI
6545           (match_operand:V2DI 1 "register_operand" "0")
6546           (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
6547   "TARGET_SSE4_2"
6548   "pcmpgtq\t{%2, %0|%0, %2}"
6549   [(set_attr "type" "ssecmp")
6550    (set_attr "prefix_extra" "1")
6551    (set_attr "mode" "TI")])
6552
6553 (define_expand "vcond<mode>"
6554   [(set (match_operand:SSEMODE124C8 0 "register_operand" "")
6555         (if_then_else:SSEMODE124C8
6556           (match_operator 3 ""
6557             [(match_operand:SSEMODE124C8 4 "nonimmediate_operand" "")
6558              (match_operand:SSEMODE124C8 5 "nonimmediate_operand" "")])
6559           (match_operand:SSEMODE124C8 1 "general_operand" "")
6560           (match_operand:SSEMODE124C8 2 "general_operand" "")))]
6561   "TARGET_SSE2"
6562 {
6563   bool ok = ix86_expand_int_vcond (operands);
6564   gcc_assert (ok);
6565   DONE;
6566 })
6567
6568 (define_expand "vcondu<mode>"
6569   [(set (match_operand:SSEMODE124C8 0 "register_operand" "")
6570         (if_then_else:SSEMODE124C8
6571           (match_operator 3 ""
6572             [(match_operand:SSEMODE124C8 4 "nonimmediate_operand" "")
6573              (match_operand:SSEMODE124C8 5 "nonimmediate_operand" "")])
6574           (match_operand:SSEMODE124C8 1 "general_operand" "")
6575           (match_operand:SSEMODE124C8 2 "general_operand" "")))]
6576   "TARGET_SSE2"
6577 {
6578   bool ok = ix86_expand_int_vcond (operands);
6579   gcc_assert (ok);
6580   DONE;
6581 })
6582
6583 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6584 ;;
6585 ;; Parallel bitwise logical operations
6586 ;;
6587 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6588
6589 (define_expand "one_cmpl<mode>2"
6590   [(set (match_operand:SSEMODEI 0 "register_operand" "")
6591         (xor:SSEMODEI (match_operand:SSEMODEI 1 "nonimmediate_operand" "")
6592                       (match_dup 2)))]
6593   "TARGET_SSE2"
6594 {
6595   int i, n = GET_MODE_NUNITS (<MODE>mode);
6596   rtvec v = rtvec_alloc (n);
6597
6598   for (i = 0; i < n; ++i)
6599     RTVEC_ELT (v, i) = constm1_rtx;
6600
6601   operands[2] = force_reg (<MODE>mode, gen_rtx_CONST_VECTOR (<MODE>mode, v));
6602 })
6603
6604 (define_insn "*avx_andnot<mode>3"
6605   [(set (match_operand:AVX256MODEI 0 "register_operand" "=x")
6606         (and:AVX256MODEI
6607           (not:AVX256MODEI (match_operand:AVX256MODEI 1 "register_operand" "x"))
6608           (match_operand:AVX256MODEI 2 "nonimmediate_operand" "xm")))]
6609   "TARGET_AVX"
6610   "vandnps\t{%2, %1, %0|%0, %1, %2}"
6611   [(set_attr "type" "sselog")
6612    (set_attr "prefix" "vex")
6613    (set_attr "mode" "<avxvecpsmode>")])
6614
6615 (define_insn "*sse_andnot<mode>3"
6616   [(set (match_operand:SSEMODEI 0 "register_operand" "=x")
6617         (and:SSEMODEI
6618           (not:SSEMODEI (match_operand:SSEMODEI 1 "register_operand" "0"))
6619           (match_operand:SSEMODEI 2 "nonimmediate_operand" "xm")))]
6620   "(TARGET_SSE && !TARGET_SSE2)"
6621   "andnps\t{%2, %0|%0, %2}"
6622   [(set_attr "type" "sselog")
6623    (set_attr "mode" "V4SF")])
6624
6625 (define_insn "*avx_andnot<mode>3"
6626   [(set (match_operand:SSEMODEI 0 "register_operand" "=x")
6627         (and:SSEMODEI
6628           (not:SSEMODEI (match_operand:SSEMODEI 1 "register_operand" "x"))
6629           (match_operand:SSEMODEI 2 "nonimmediate_operand" "xm")))]
6630   "TARGET_AVX"
6631   "vpandn\t{%2, %1, %0|%0, %1, %2}"
6632   [(set_attr "type" "sselog")
6633    (set_attr "prefix" "vex")
6634    (set_attr "mode" "TI")])
6635
6636 (define_insn "sse2_andnot<mode>3"
6637   [(set (match_operand:SSEMODEI 0 "register_operand" "=x")
6638         (and:SSEMODEI
6639           (not:SSEMODEI (match_operand:SSEMODEI 1 "register_operand" "0"))
6640           (match_operand:SSEMODEI 2 "nonimmediate_operand" "xm")))]
6641   "TARGET_SSE2"
6642   "pandn\t{%2, %0|%0, %2}"
6643   [(set_attr "type" "sselog")
6644    (set_attr "prefix_data16" "1")
6645    (set_attr "mode" "TI")])
6646
6647 (define_insn "*andnottf3"
6648   [(set (match_operand:TF 0 "register_operand" "=x")
6649         (and:TF
6650           (not:TF (match_operand:TF 1 "register_operand" "0"))
6651           (match_operand:TF 2 "nonimmediate_operand" "xm")))]
6652   "TARGET_SSE2"
6653   "pandn\t{%2, %0|%0, %2}"
6654   [(set_attr "type" "sselog")
6655    (set_attr "prefix_data16" "1")
6656    (set_attr "mode" "TI")])
6657
6658 (define_expand "<code><mode>3"
6659   [(set (match_operand:SSEMODEI 0 "register_operand" "")
6660         (any_logic:SSEMODEI
6661           (match_operand:SSEMODEI 1 "nonimmediate_operand" "")
6662           (match_operand:SSEMODEI 2 "nonimmediate_operand" "")))]
6663   "TARGET_SSE"
6664   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
6665
6666 (define_insn "*avx_<code><mode>3"
6667   [(set (match_operand:AVX256MODEI 0 "register_operand" "=x")
6668         (any_logic:AVX256MODEI
6669           (match_operand:AVX256MODEI 1 "nonimmediate_operand" "%x")
6670           (match_operand:AVX256MODEI 2 "nonimmediate_operand" "xm")))]
6671   "TARGET_AVX
6672    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6673   "v<logic>ps\t{%2, %1, %0|%0, %1, %2}"
6674   [(set_attr "type" "sselog")
6675    (set_attr "prefix" "vex")
6676    (set_attr "mode" "<avxvecpsmode>")])
6677
6678 (define_insn "*sse_<code><mode>3"
6679   [(set (match_operand:SSEMODEI 0 "register_operand" "=x")
6680         (any_logic:SSEMODEI
6681           (match_operand:SSEMODEI 1 "nonimmediate_operand" "%0")
6682           (match_operand:SSEMODEI 2 "nonimmediate_operand" "xm")))]
6683   "(TARGET_SSE && !TARGET_SSE2)
6684    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6685   "<logic>ps\t{%2, %0|%0, %2}"
6686   [(set_attr "type" "sselog")
6687    (set_attr "mode" "V4SF")])
6688
6689 (define_insn "*avx_<code><mode>3"
6690   [(set (match_operand:SSEMODEI 0 "register_operand" "=x")
6691         (any_logic:SSEMODEI
6692           (match_operand:SSEMODEI 1 "nonimmediate_operand" "%x")
6693           (match_operand:SSEMODEI 2 "nonimmediate_operand" "xm")))]
6694   "TARGET_AVX
6695    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6696   "vp<logic>\t{%2, %1, %0|%0, %1, %2}"
6697   [(set_attr "type" "sselog")
6698    (set_attr "prefix" "vex")
6699    (set_attr "mode" "TI")])
6700
6701 (define_insn "*sse2_<code><mode>3"
6702   [(set (match_operand:SSEMODEI 0 "register_operand" "=x")
6703         (any_logic:SSEMODEI
6704           (match_operand:SSEMODEI 1 "nonimmediate_operand" "%0")
6705           (match_operand:SSEMODEI 2 "nonimmediate_operand" "xm")))]
6706   "TARGET_SSE2 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6707   "p<logic>\t{%2, %0|%0, %2}"
6708   [(set_attr "type" "sselog")
6709    (set_attr "prefix_data16" "1")
6710    (set_attr "mode" "TI")])
6711
6712 (define_expand "<code>tf3"
6713   [(set (match_operand:TF 0 "register_operand" "")
6714         (any_logic:TF
6715           (match_operand:TF 1 "nonimmediate_operand" "")
6716           (match_operand:TF 2 "nonimmediate_operand" "")))]
6717   "TARGET_SSE2"
6718   "ix86_fixup_binary_operands_no_copy (<CODE>, TFmode, operands);")
6719
6720 (define_insn "*<code>tf3"
6721   [(set (match_operand:TF 0 "register_operand" "=x")
6722         (any_logic:TF
6723           (match_operand:TF 1 "nonimmediate_operand" "%0")
6724           (match_operand:TF 2 "nonimmediate_operand" "xm")))]
6725   "TARGET_SSE2 && ix86_binary_operator_ok (<CODE>, TFmode, operands)"
6726   "p<logic>\t{%2, %0|%0, %2}"
6727   [(set_attr "type" "sselog")
6728    (set_attr "prefix_data16" "1")
6729    (set_attr "mode" "TI")])
6730
6731 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6732 ;;
6733 ;; Parallel integral element swizzling
6734 ;;
6735 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6736
6737 (define_expand "vec_pack_trunc_v8hi"
6738   [(match_operand:V16QI 0 "register_operand" "")
6739    (match_operand:V8HI 1 "register_operand" "")
6740    (match_operand:V8HI 2 "register_operand" "")]
6741   "TARGET_SSE2"
6742 {
6743   rtx op1 = gen_lowpart (V16QImode, operands[1]);
6744   rtx op2 = gen_lowpart (V16QImode, operands[2]);
6745   ix86_expand_vec_extract_even_odd (operands[0], op1, op2, 0);
6746   DONE;
6747 })
6748
6749 (define_expand "vec_pack_trunc_v4si"
6750   [(match_operand:V8HI 0 "register_operand" "")
6751    (match_operand:V4SI 1 "register_operand" "")
6752    (match_operand:V4SI 2 "register_operand" "")]
6753   "TARGET_SSE2"
6754 {
6755   rtx op1 = gen_lowpart (V8HImode, operands[1]);
6756   rtx op2 = gen_lowpart (V8HImode, operands[2]);
6757   ix86_expand_vec_extract_even_odd (operands[0], op1, op2, 0);
6758   DONE;
6759 })
6760
6761 (define_expand "vec_pack_trunc_v2di"
6762   [(match_operand:V4SI 0 "register_operand" "")
6763    (match_operand:V2DI 1 "register_operand" "")
6764    (match_operand:V2DI 2 "register_operand" "")]
6765   "TARGET_SSE2"
6766 {
6767   rtx op1 = gen_lowpart (V4SImode, operands[1]);
6768   rtx op2 = gen_lowpart (V4SImode, operands[2]);
6769   ix86_expand_vec_extract_even_odd (operands[0], op1, op2, 0);
6770   DONE;
6771 })
6772
6773 (define_insn "*avx_packsswb"
6774   [(set (match_operand:V16QI 0 "register_operand" "=x")
6775         (vec_concat:V16QI
6776           (ss_truncate:V8QI
6777             (match_operand:V8HI 1 "register_operand" "x"))
6778           (ss_truncate:V8QI
6779             (match_operand:V8HI 2 "nonimmediate_operand" "xm"))))]
6780   "TARGET_AVX"
6781   "vpacksswb\t{%2, %1, %0|%0, %1, %2}"
6782   [(set_attr "type" "sselog")
6783    (set_attr "prefix" "vex")
6784    (set_attr "mode" "TI")])
6785
6786 (define_insn "sse2_packsswb"
6787   [(set (match_operand:V16QI 0 "register_operand" "=x")
6788         (vec_concat:V16QI
6789           (ss_truncate:V8QI
6790             (match_operand:V8HI 1 "register_operand" "0"))
6791           (ss_truncate:V8QI
6792             (match_operand:V8HI 2 "nonimmediate_operand" "xm"))))]
6793   "TARGET_SSE2"
6794   "packsswb\t{%2, %0|%0, %2}"
6795   [(set_attr "type" "sselog")
6796    (set_attr "prefix_data16" "1")
6797    (set_attr "mode" "TI")])
6798
6799 (define_insn "*avx_packssdw"
6800   [(set (match_operand:V8HI 0 "register_operand" "=x")
6801         (vec_concat:V8HI
6802           (ss_truncate:V4HI
6803             (match_operand:V4SI 1 "register_operand" "x"))
6804           (ss_truncate:V4HI
6805             (match_operand:V4SI 2 "nonimmediate_operand" "xm"))))]
6806   "TARGET_AVX"
6807   "vpackssdw\t{%2, %1, %0|%0, %1, %2}"
6808   [(set_attr "type" "sselog")
6809    (set_attr "prefix" "vex")
6810    (set_attr "mode" "TI")])
6811
6812 (define_insn "sse2_packssdw"
6813   [(set (match_operand:V8HI 0 "register_operand" "=x")
6814         (vec_concat:V8HI
6815           (ss_truncate:V4HI
6816             (match_operand:V4SI 1 "register_operand" "0"))
6817           (ss_truncate:V4HI
6818             (match_operand:V4SI 2 "nonimmediate_operand" "xm"))))]
6819   "TARGET_SSE2"
6820   "packssdw\t{%2, %0|%0, %2}"
6821   [(set_attr "type" "sselog")
6822    (set_attr "prefix_data16" "1")
6823    (set_attr "mode" "TI")])
6824
6825 (define_insn "*avx_packuswb"
6826   [(set (match_operand:V16QI 0 "register_operand" "=x")
6827         (vec_concat:V16QI
6828           (us_truncate:V8QI
6829             (match_operand:V8HI 1 "register_operand" "x"))
6830           (us_truncate:V8QI
6831             (match_operand:V8HI 2 "nonimmediate_operand" "xm"))))]
6832   "TARGET_AVX"
6833   "vpackuswb\t{%2, %1, %0|%0, %1, %2}"
6834   [(set_attr "type" "sselog")
6835    (set_attr "prefix" "vex")
6836    (set_attr "mode" "TI")])
6837
6838 (define_insn "sse2_packuswb"
6839   [(set (match_operand:V16QI 0 "register_operand" "=x")
6840         (vec_concat:V16QI
6841           (us_truncate:V8QI
6842             (match_operand:V8HI 1 "register_operand" "0"))
6843           (us_truncate:V8QI
6844             (match_operand:V8HI 2 "nonimmediate_operand" "xm"))))]
6845   "TARGET_SSE2"
6846   "packuswb\t{%2, %0|%0, %2}"
6847   [(set_attr "type" "sselog")
6848    (set_attr "prefix_data16" "1")
6849    (set_attr "mode" "TI")])
6850
6851 (define_insn "*avx_interleave_highv16qi"
6852   [(set (match_operand:V16QI 0 "register_operand" "=x")
6853         (vec_select:V16QI
6854           (vec_concat:V32QI
6855             (match_operand:V16QI 1 "register_operand" "x")
6856             (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
6857           (parallel [(const_int 8)  (const_int 24)
6858                      (const_int 9)  (const_int 25)
6859                      (const_int 10) (const_int 26)
6860                      (const_int 11) (const_int 27)
6861                      (const_int 12) (const_int 28)
6862                      (const_int 13) (const_int 29)
6863                      (const_int 14) (const_int 30)
6864                      (const_int 15) (const_int 31)])))]
6865   "TARGET_AVX"
6866   "vpunpckhbw\t{%2, %1, %0|%0, %1, %2}"
6867   [(set_attr "type" "sselog")
6868    (set_attr "prefix" "vex")
6869    (set_attr "mode" "TI")])
6870
6871 (define_insn "vec_interleave_highv16qi"
6872   [(set (match_operand:V16QI 0 "register_operand" "=x")
6873         (vec_select:V16QI
6874           (vec_concat:V32QI
6875             (match_operand:V16QI 1 "register_operand" "0")
6876             (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
6877           (parallel [(const_int 8)  (const_int 24)
6878                      (const_int 9)  (const_int 25)
6879                      (const_int 10) (const_int 26)
6880                      (const_int 11) (const_int 27)
6881                      (const_int 12) (const_int 28)
6882                      (const_int 13) (const_int 29)
6883                      (const_int 14) (const_int 30)
6884                      (const_int 15) (const_int 31)])))]
6885   "TARGET_SSE2"
6886   "punpckhbw\t{%2, %0|%0, %2}"
6887   [(set_attr "type" "sselog")
6888    (set_attr "prefix_data16" "1")
6889    (set_attr "mode" "TI")])
6890
6891 (define_insn "*avx_interleave_lowv16qi"
6892   [(set (match_operand:V16QI 0 "register_operand" "=x")
6893         (vec_select:V16QI
6894           (vec_concat:V32QI
6895             (match_operand:V16QI 1 "register_operand" "x")
6896             (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
6897           (parallel [(const_int 0) (const_int 16)
6898                      (const_int 1) (const_int 17)
6899                      (const_int 2) (const_int 18)
6900                      (const_int 3) (const_int 19)
6901                      (const_int 4) (const_int 20)
6902                      (const_int 5) (const_int 21)
6903                      (const_int 6) (const_int 22)
6904                      (const_int 7) (const_int 23)])))]
6905   "TARGET_AVX"
6906   "vpunpcklbw\t{%2, %1, %0|%0, %1, %2}"
6907   [(set_attr "type" "sselog")
6908    (set_attr "prefix" "vex")
6909    (set_attr "mode" "TI")])
6910
6911 (define_insn "vec_interleave_lowv16qi"
6912   [(set (match_operand:V16QI 0 "register_operand" "=x")
6913         (vec_select:V16QI
6914           (vec_concat:V32QI
6915             (match_operand:V16QI 1 "register_operand" "0")
6916             (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
6917           (parallel [(const_int 0) (const_int 16)
6918                      (const_int 1) (const_int 17)
6919                      (const_int 2) (const_int 18)
6920                      (const_int 3) (const_int 19)
6921                      (const_int 4) (const_int 20)
6922                      (const_int 5) (const_int 21)
6923                      (const_int 6) (const_int 22)
6924                      (const_int 7) (const_int 23)])))]
6925   "TARGET_SSE2"
6926   "punpcklbw\t{%2, %0|%0, %2}"
6927   [(set_attr "type" "sselog")
6928    (set_attr "prefix_data16" "1")
6929    (set_attr "mode" "TI")])
6930
6931 (define_insn "*avx_interleave_highv8hi"
6932   [(set (match_operand:V8HI 0 "register_operand" "=x")
6933         (vec_select:V8HI
6934           (vec_concat:V16HI
6935             (match_operand:V8HI 1 "register_operand" "x")
6936             (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
6937           (parallel [(const_int 4) (const_int 12)
6938                      (const_int 5) (const_int 13)
6939                      (const_int 6) (const_int 14)
6940                      (const_int 7) (const_int 15)])))]
6941   "TARGET_AVX"
6942   "vpunpckhwd\t{%2, %1, %0|%0, %1, %2}"
6943   [(set_attr "type" "sselog")
6944    (set_attr "prefix" "vex")
6945    (set_attr "mode" "TI")])
6946
6947 (define_insn "vec_interleave_highv8hi"
6948   [(set (match_operand:V8HI 0 "register_operand" "=x")
6949         (vec_select:V8HI
6950           (vec_concat:V16HI
6951             (match_operand:V8HI 1 "register_operand" "0")
6952             (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
6953           (parallel [(const_int 4) (const_int 12)
6954                      (const_int 5) (const_int 13)
6955                      (const_int 6) (const_int 14)
6956                      (const_int 7) (const_int 15)])))]
6957   "TARGET_SSE2"
6958   "punpckhwd\t{%2, %0|%0, %2}"
6959   [(set_attr "type" "sselog")
6960    (set_attr "prefix_data16" "1")
6961    (set_attr "mode" "TI")])
6962
6963 (define_insn "*avx_interleave_lowv8hi"
6964   [(set (match_operand:V8HI 0 "register_operand" "=x")
6965         (vec_select:V8HI
6966           (vec_concat:V16HI
6967             (match_operand:V8HI 1 "register_operand" "x")
6968             (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
6969           (parallel [(const_int 0) (const_int 8)
6970                      (const_int 1) (const_int 9)
6971                      (const_int 2) (const_int 10)
6972                      (const_int 3) (const_int 11)])))]
6973   "TARGET_AVX"
6974   "vpunpcklwd\t{%2, %1, %0|%0, %1, %2}"
6975   [(set_attr "type" "sselog")
6976    (set_attr "prefix" "vex")
6977    (set_attr "mode" "TI")])
6978
6979 (define_insn "vec_interleave_lowv8hi"
6980   [(set (match_operand:V8HI 0 "register_operand" "=x")
6981         (vec_select:V8HI
6982           (vec_concat:V16HI
6983             (match_operand:V8HI 1 "register_operand" "0")
6984             (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
6985           (parallel [(const_int 0) (const_int 8)
6986                      (const_int 1) (const_int 9)
6987                      (const_int 2) (const_int 10)
6988                      (const_int 3) (const_int 11)])))]
6989   "TARGET_SSE2"
6990   "punpcklwd\t{%2, %0|%0, %2}"
6991   [(set_attr "type" "sselog")
6992    (set_attr "prefix_data16" "1")
6993    (set_attr "mode" "TI")])
6994
6995 (define_insn "*avx_interleave_highv4si"
6996   [(set (match_operand:V4SI 0 "register_operand" "=x")
6997         (vec_select:V4SI
6998           (vec_concat:V8SI
6999             (match_operand:V4SI 1 "register_operand" "x")
7000             (match_operand:V4SI 2 "nonimmediate_operand" "xm"))
7001           (parallel [(const_int 2) (const_int 6)
7002                      (const_int 3) (const_int 7)])))]
7003   "TARGET_AVX"
7004   "vpunpckhdq\t{%2, %1, %0|%0, %1, %2}"
7005   [(set_attr "type" "sselog")
7006    (set_attr "prefix" "vex")
7007    (set_attr "mode" "TI")])
7008
7009 (define_insn "vec_interleave_highv4si"
7010   [(set (match_operand:V4SI 0 "register_operand" "=x")
7011         (vec_select:V4SI
7012           (vec_concat:V8SI
7013             (match_operand:V4SI 1 "register_operand" "0")
7014             (match_operand:V4SI 2 "nonimmediate_operand" "xm"))
7015           (parallel [(const_int 2) (const_int 6)
7016                      (const_int 3) (const_int 7)])))]
7017   "TARGET_SSE2"
7018   "punpckhdq\t{%2, %0|%0, %2}"
7019   [(set_attr "type" "sselog")
7020    (set_attr "prefix_data16" "1")
7021    (set_attr "mode" "TI")])
7022
7023 (define_insn "*avx_interleave_lowv4si"
7024   [(set (match_operand:V4SI 0 "register_operand" "=x")
7025         (vec_select:V4SI
7026           (vec_concat:V8SI
7027             (match_operand:V4SI 1 "register_operand" "x")
7028             (match_operand:V4SI 2 "nonimmediate_operand" "xm"))
7029           (parallel [(const_int 0) (const_int 4)
7030                      (const_int 1) (const_int 5)])))]
7031   "TARGET_AVX"
7032   "vpunpckldq\t{%2, %1, %0|%0, %1, %2}"
7033   [(set_attr "type" "sselog")
7034    (set_attr "prefix" "vex")
7035    (set_attr "mode" "TI")])
7036
7037 (define_insn "vec_interleave_lowv4si"
7038   [(set (match_operand:V4SI 0 "register_operand" "=x")
7039         (vec_select:V4SI
7040           (vec_concat:V8SI
7041             (match_operand:V4SI 1 "register_operand" "0")
7042             (match_operand:V4SI 2 "nonimmediate_operand" "xm"))
7043           (parallel [(const_int 0) (const_int 4)
7044                      (const_int 1) (const_int 5)])))]
7045   "TARGET_SSE2"
7046   "punpckldq\t{%2, %0|%0, %2}"
7047   [(set_attr "type" "sselog")
7048    (set_attr "prefix_data16" "1")
7049    (set_attr "mode" "TI")])
7050
7051 (define_insn "*avx_pinsr<ssevecsize>"
7052   [(set (match_operand:SSEMODE124 0 "register_operand" "=x")
7053         (vec_merge:SSEMODE124
7054           (vec_duplicate:SSEMODE124
7055             (match_operand:<avxscalarmode> 2 "nonimmediate_operand" "rm"))
7056           (match_operand:SSEMODE124 1 "register_operand" "x")
7057           (match_operand:SI 3 "const_pow2_1_to_<pinsrbits>_operand" "n")))]
7058   "TARGET_AVX"
7059 {
7060   operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
7061   if (MEM_P (operands[2]))
7062     return "vpinsr<ssevecsize>\t{%3, %2, %1, %0|%0, %1, %2, %3}";
7063   else
7064     return "vpinsr<ssevecsize>\t{%3, %k2, %1, %0|%0, %1, %k2, %3}";
7065 }
7066   [(set_attr "type" "sselog")
7067    (set (attr "prefix_extra")
7068      (if_then_else (match_operand:V8HI 0 "" "")
7069        (const_string "0")
7070        (const_string "1")))
7071    (set_attr "length_immediate" "1")
7072    (set_attr "prefix" "vex")
7073    (set_attr "mode" "TI")])
7074
7075 (define_insn "*sse4_1_pinsrb"
7076   [(set (match_operand:V16QI 0 "register_operand" "=x")
7077         (vec_merge:V16QI
7078           (vec_duplicate:V16QI
7079             (match_operand:QI 2 "nonimmediate_operand" "rm"))
7080           (match_operand:V16QI 1 "register_operand" "0")
7081           (match_operand:SI 3 "const_pow2_1_to_32768_operand" "n")))]
7082   "TARGET_SSE4_1"
7083 {
7084   operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
7085   if (MEM_P (operands[2]))
7086     return "pinsrb\t{%3, %2, %0|%0, %2, %3}";
7087   else
7088     return "pinsrb\t{%3, %k2, %0|%0, %k2, %3}";
7089 }
7090   [(set_attr "type" "sselog")
7091    (set_attr "prefix_extra" "1")
7092    (set_attr "length_immediate" "1")
7093    (set_attr "mode" "TI")])
7094
7095 (define_insn "*sse2_pinsrw"
7096   [(set (match_operand:V8HI 0 "register_operand" "=x")
7097         (vec_merge:V8HI
7098           (vec_duplicate:V8HI
7099             (match_operand:HI 2 "nonimmediate_operand" "rm"))
7100           (match_operand:V8HI 1 "register_operand" "0")
7101           (match_operand:SI 3 "const_pow2_1_to_128_operand" "n")))]
7102   "TARGET_SSE2"
7103 {
7104   operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
7105   if (MEM_P (operands[2]))
7106     return "pinsrw\t{%3, %2, %0|%0, %2, %3}";
7107   else
7108     return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}";
7109 }
7110   [(set_attr "type" "sselog")
7111    (set_attr "prefix_data16" "1")
7112    (set_attr "length_immediate" "1")
7113    (set_attr "mode" "TI")])
7114
7115 ;; It must come before sse2_loadld since it is preferred.
7116 (define_insn "*sse4_1_pinsrd"
7117   [(set (match_operand:V4SI 0 "register_operand" "=x")
7118         (vec_merge:V4SI
7119           (vec_duplicate:V4SI
7120             (match_operand:SI 2 "nonimmediate_operand" "rm"))
7121           (match_operand:V4SI 1 "register_operand" "0")
7122           (match_operand:SI 3 "const_pow2_1_to_8_operand" "n")))]
7123   "TARGET_SSE4_1"
7124 {
7125   operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
7126   return "pinsrd\t{%3, %2, %0|%0, %2, %3}";
7127 }
7128   [(set_attr "type" "sselog")
7129    (set_attr "prefix_extra" "1")
7130    (set_attr "length_immediate" "1")
7131    (set_attr "mode" "TI")])
7132
7133 (define_insn "*avx_pinsrq"
7134   [(set (match_operand:V2DI 0 "register_operand" "=x")
7135         (vec_merge:V2DI
7136           (vec_duplicate:V2DI
7137             (match_operand:DI 2 "nonimmediate_operand" "rm"))
7138           (match_operand:V2DI 1 "register_operand" "x")
7139           (match_operand:SI 3 "const_pow2_1_to_2_operand" "n")))]
7140   "TARGET_AVX && TARGET_64BIT"
7141 {
7142   operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
7143   return "vpinsrq\t{%3, %2, %1, %0|%0, %1, %2, %3}";
7144 }
7145   [(set_attr "type" "sselog")
7146    (set_attr "prefix_extra" "1")
7147    (set_attr "length_immediate" "1")
7148    (set_attr "prefix" "vex")
7149    (set_attr "mode" "TI")])
7150
7151 (define_insn "*sse4_1_pinsrq"
7152   [(set (match_operand:V2DI 0 "register_operand" "=x")
7153         (vec_merge:V2DI
7154           (vec_duplicate:V2DI
7155             (match_operand:DI 2 "nonimmediate_operand" "rm"))
7156           (match_operand:V2DI 1 "register_operand" "0")
7157           (match_operand:SI 3 "const_pow2_1_to_2_operand" "n")))]
7158   "TARGET_SSE4_1 && TARGET_64BIT"
7159 {
7160   operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
7161   return "pinsrq\t{%3, %2, %0|%0, %2, %3}";
7162 }
7163   [(set_attr "type" "sselog")
7164    (set_attr "prefix_rex" "1")
7165    (set_attr "prefix_extra" "1")
7166    (set_attr "length_immediate" "1")
7167    (set_attr "mode" "TI")])
7168
7169 (define_insn "*sse4_1_pextrb_<mode>"
7170   [(set (match_operand:SWI48 0 "register_operand" "=r")
7171         (zero_extend:SWI48
7172           (vec_select:QI
7173             (match_operand:V16QI 1 "register_operand" "x")
7174             (parallel [(match_operand:SI 2 "const_0_to_15_operand" "n")]))))]
7175   "TARGET_SSE4_1"
7176   "%vpextrb\t{%2, %1, %k0|%k0, %1, %2}"
7177   [(set_attr "type" "sselog")
7178    (set_attr "prefix_extra" "1")
7179    (set_attr "length_immediate" "1")
7180    (set_attr "prefix" "maybe_vex")
7181    (set_attr "mode" "TI")])
7182
7183 (define_insn "*sse4_1_pextrb_memory"
7184   [(set (match_operand:QI 0 "memory_operand" "=m")
7185         (vec_select:QI
7186           (match_operand:V16QI 1 "register_operand" "x")
7187           (parallel [(match_operand:SI 2 "const_0_to_15_operand" "n")])))]
7188   "TARGET_SSE4_1"
7189   "%vpextrb\t{%2, %1, %0|%0, %1, %2}"
7190   [(set_attr "type" "sselog")
7191    (set_attr "prefix_extra" "1")
7192    (set_attr "length_immediate" "1")
7193    (set_attr "prefix" "maybe_vex")
7194    (set_attr "mode" "TI")])
7195
7196 (define_insn "*sse2_pextrw_<mode>"
7197   [(set (match_operand:SWI48 0 "register_operand" "=r")
7198         (zero_extend:SWI48
7199           (vec_select:HI
7200             (match_operand:V8HI 1 "register_operand" "x")
7201             (parallel [(match_operand:SI 2 "const_0_to_7_operand" "n")]))))]
7202   "TARGET_SSE2"
7203   "%vpextrw\t{%2, %1, %k0|%k0, %1, %2}"
7204   [(set_attr "type" "sselog")
7205    (set_attr "prefix_data16" "1")
7206    (set_attr "length_immediate" "1")
7207    (set_attr "prefix" "maybe_vex")
7208    (set_attr "mode" "TI")])
7209
7210 (define_insn "*sse4_1_pextrw_memory"
7211   [(set (match_operand:HI 0 "memory_operand" "=m")
7212         (vec_select:HI
7213           (match_operand:V8HI 1 "register_operand" "x")
7214           (parallel [(match_operand:SI 2 "const_0_to_7_operand" "n")])))]
7215   "TARGET_SSE4_1"
7216   "%vpextrw\t{%2, %1, %0|%0, %1, %2}"
7217   [(set_attr "type" "sselog")
7218    (set_attr "prefix_extra" "1")
7219    (set_attr "length_immediate" "1")
7220    (set_attr "prefix" "maybe_vex")
7221    (set_attr "mode" "TI")])
7222
7223 (define_insn "*sse4_1_pextrd"
7224   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
7225         (vec_select:SI
7226           (match_operand:V4SI 1 "register_operand" "x")
7227           (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n")])))]
7228   "TARGET_SSE4_1"
7229   "%vpextrd\t{%2, %1, %0|%0, %1, %2}"
7230   [(set_attr "type" "sselog")
7231    (set_attr "prefix_extra" "1")
7232    (set_attr "length_immediate" "1")
7233    (set_attr "prefix" "maybe_vex")
7234    (set_attr "mode" "TI")])
7235
7236 (define_insn "*sse4_1_pextrd_zext"
7237   [(set (match_operand:DI 0 "register_operand" "=r")
7238         (zero_extend:DI
7239           (vec_select:SI
7240             (match_operand:V4SI 1 "register_operand" "x")
7241             (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n")]))))]
7242   "TARGET_64BIT && TARGET_SSE4_1"
7243   "%vpextrd\t{%2, %1, %k0|%k0, %1, %2}"
7244   [(set_attr "type" "sselog")
7245    (set_attr "prefix_extra" "1")
7246    (set_attr "length_immediate" "1")
7247    (set_attr "prefix" "maybe_vex")
7248    (set_attr "mode" "TI")])
7249
7250 ;; It must come before *vec_extractv2di_1_sse since it is preferred.
7251 (define_insn "*sse4_1_pextrq"
7252   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
7253         (vec_select:DI
7254           (match_operand:V2DI 1 "register_operand" "x")
7255           (parallel [(match_operand:SI 2 "const_0_to_1_operand" "n")])))]
7256   "TARGET_SSE4_1 && TARGET_64BIT"
7257   "%vpextrq\t{%2, %1, %0|%0, %1, %2}"
7258   [(set_attr "type" "sselog")
7259    (set_attr "prefix_rex" "1")
7260    (set_attr "prefix_extra" "1")
7261    (set_attr "length_immediate" "1")
7262    (set_attr "prefix" "maybe_vex")
7263    (set_attr "mode" "TI")])
7264
7265 (define_expand "sse2_pshufd"
7266   [(match_operand:V4SI 0 "register_operand" "")
7267    (match_operand:V4SI 1 "nonimmediate_operand" "")
7268    (match_operand:SI 2 "const_int_operand" "")]
7269   "TARGET_SSE2"
7270 {
7271   int mask = INTVAL (operands[2]);
7272   emit_insn (gen_sse2_pshufd_1 (operands[0], operands[1],
7273                                 GEN_INT ((mask >> 0) & 3),
7274                                 GEN_INT ((mask >> 2) & 3),
7275                                 GEN_INT ((mask >> 4) & 3),
7276                                 GEN_INT ((mask >> 6) & 3)));
7277   DONE;
7278 })
7279
7280 (define_insn "sse2_pshufd_1"
7281   [(set (match_operand:V4SI 0 "register_operand" "=x")
7282         (vec_select:V4SI
7283           (match_operand:V4SI 1 "nonimmediate_operand" "xm")
7284           (parallel [(match_operand 2 "const_0_to_3_operand" "")
7285                      (match_operand 3 "const_0_to_3_operand" "")
7286                      (match_operand 4 "const_0_to_3_operand" "")
7287                      (match_operand 5 "const_0_to_3_operand" "")])))]
7288   "TARGET_SSE2"
7289 {
7290   int mask = 0;
7291   mask |= INTVAL (operands[2]) << 0;
7292   mask |= INTVAL (operands[3]) << 2;
7293   mask |= INTVAL (operands[4]) << 4;
7294   mask |= INTVAL (operands[5]) << 6;
7295   operands[2] = GEN_INT (mask);
7296
7297   return "%vpshufd\t{%2, %1, %0|%0, %1, %2}";
7298 }
7299   [(set_attr "type" "sselog1")
7300    (set_attr "prefix_data16" "1")
7301    (set_attr "prefix" "maybe_vex")
7302    (set_attr "length_immediate" "1")
7303    (set_attr "mode" "TI")])
7304
7305 (define_expand "sse2_pshuflw"
7306   [(match_operand:V8HI 0 "register_operand" "")
7307    (match_operand:V8HI 1 "nonimmediate_operand" "")
7308    (match_operand:SI 2 "const_int_operand" "")]
7309   "TARGET_SSE2"
7310 {
7311   int mask = INTVAL (operands[2]);
7312   emit_insn (gen_sse2_pshuflw_1 (operands[0], operands[1],
7313                                  GEN_INT ((mask >> 0) & 3),
7314                                  GEN_INT ((mask >> 2) & 3),
7315                                  GEN_INT ((mask >> 4) & 3),
7316                                  GEN_INT ((mask >> 6) & 3)));
7317   DONE;
7318 })
7319
7320 (define_insn "sse2_pshuflw_1"
7321   [(set (match_operand:V8HI 0 "register_operand" "=x")
7322         (vec_select:V8HI
7323           (match_operand:V8HI 1 "nonimmediate_operand" "xm")
7324           (parallel [(match_operand 2 "const_0_to_3_operand" "")
7325                      (match_operand 3 "const_0_to_3_operand" "")
7326                      (match_operand 4 "const_0_to_3_operand" "")
7327                      (match_operand 5 "const_0_to_3_operand" "")
7328                      (const_int 4)
7329                      (const_int 5)
7330                      (const_int 6)
7331                      (const_int 7)])))]
7332   "TARGET_SSE2"
7333 {
7334   int mask = 0;
7335   mask |= INTVAL (operands[2]) << 0;
7336   mask |= INTVAL (operands[3]) << 2;
7337   mask |= INTVAL (operands[4]) << 4;
7338   mask |= INTVAL (operands[5]) << 6;
7339   operands[2] = GEN_INT (mask);
7340
7341   return "%vpshuflw\t{%2, %1, %0|%0, %1, %2}";
7342 }
7343   [(set_attr "type" "sselog")
7344    (set_attr "prefix_data16" "0")
7345    (set_attr "prefix_rep" "1")
7346    (set_attr "prefix" "maybe_vex")
7347    (set_attr "length_immediate" "1")
7348    (set_attr "mode" "TI")])
7349
7350 (define_expand "sse2_pshufhw"
7351   [(match_operand:V8HI 0 "register_operand" "")
7352    (match_operand:V8HI 1 "nonimmediate_operand" "")
7353    (match_operand:SI 2 "const_int_operand" "")]
7354   "TARGET_SSE2"
7355 {
7356   int mask = INTVAL (operands[2]);
7357   emit_insn (gen_sse2_pshufhw_1 (operands[0], operands[1],
7358                                  GEN_INT (((mask >> 0) & 3) + 4),
7359                                  GEN_INT (((mask >> 2) & 3) + 4),
7360                                  GEN_INT (((mask >> 4) & 3) + 4),
7361                                  GEN_INT (((mask >> 6) & 3) + 4)));
7362   DONE;
7363 })
7364
7365 (define_insn "sse2_pshufhw_1"
7366   [(set (match_operand:V8HI 0 "register_operand" "=x")
7367         (vec_select:V8HI
7368           (match_operand:V8HI 1 "nonimmediate_operand" "xm")
7369           (parallel [(const_int 0)
7370                      (const_int 1)
7371                      (const_int 2)
7372                      (const_int 3)
7373                      (match_operand 2 "const_4_to_7_operand" "")
7374                      (match_operand 3 "const_4_to_7_operand" "")
7375                      (match_operand 4 "const_4_to_7_operand" "")
7376                      (match_operand 5 "const_4_to_7_operand" "")])))]
7377   "TARGET_SSE2"
7378 {
7379   int mask = 0;
7380   mask |= (INTVAL (operands[2]) - 4) << 0;
7381   mask |= (INTVAL (operands[3]) - 4) << 2;
7382   mask |= (INTVAL (operands[4]) - 4) << 4;
7383   mask |= (INTVAL (operands[5]) - 4) << 6;
7384   operands[2] = GEN_INT (mask);
7385
7386   return "%vpshufhw\t{%2, %1, %0|%0, %1, %2}";
7387 }
7388   [(set_attr "type" "sselog")
7389    (set_attr "prefix_rep" "1")
7390    (set_attr "prefix_data16" "0")
7391    (set_attr "prefix" "maybe_vex")
7392    (set_attr "length_immediate" "1")
7393    (set_attr "mode" "TI")])
7394
7395 (define_expand "sse2_loadd"
7396   [(set (match_operand:V4SI 0 "register_operand" "")
7397         (vec_merge:V4SI
7398           (vec_duplicate:V4SI
7399             (match_operand:SI 1 "nonimmediate_operand" ""))
7400           (match_dup 2)
7401           (const_int 1)))]
7402   "TARGET_SSE"
7403   "operands[2] = CONST0_RTX (V4SImode);")
7404
7405 (define_insn "*avx_loadld"
7406   [(set (match_operand:V4SI 0 "register_operand"       "=x,Yi,x")
7407         (vec_merge:V4SI
7408           (vec_duplicate:V4SI
7409             (match_operand:SI 2 "nonimmediate_operand" "m ,r ,x"))
7410           (match_operand:V4SI 1 "reg_or_0_operand"     "C ,C ,x")
7411           (const_int 1)))]
7412   "TARGET_AVX"
7413   "@
7414    vmovd\t{%2, %0|%0, %2}
7415    vmovd\t{%2, %0|%0, %2}
7416    vmovss\t{%2, %1, %0|%0, %1, %2}"
7417   [(set_attr "type" "ssemov")
7418    (set_attr "prefix" "vex")
7419    (set_attr "mode" "TI,TI,V4SF")])
7420
7421 (define_insn "sse2_loadld"
7422   [(set (match_operand:V4SI 0 "register_operand"       "=Y2,Yi,x,x")
7423         (vec_merge:V4SI
7424           (vec_duplicate:V4SI
7425             (match_operand:SI 2 "nonimmediate_operand" "m  ,r ,m,x"))
7426           (match_operand:V4SI 1 "reg_or_0_operand"     "C  ,C ,C,0")
7427           (const_int 1)))]
7428   "TARGET_SSE"
7429   "@
7430    movd\t{%2, %0|%0, %2}
7431    movd\t{%2, %0|%0, %2}
7432    movss\t{%2, %0|%0, %2}
7433    movss\t{%2, %0|%0, %2}"
7434   [(set_attr "type" "ssemov")
7435    (set_attr "mode" "TI,TI,V4SF,SF")])
7436
7437 (define_insn_and_split "sse2_stored"
7438   [(set (match_operand:SI 0 "nonimmediate_operand" "=mx,r")
7439         (vec_select:SI
7440           (match_operand:V4SI 1 "register_operand" "x,Yi")
7441           (parallel [(const_int 0)])))]
7442   "TARGET_SSE"
7443   "#"
7444   "&& reload_completed
7445    && (TARGET_INTER_UNIT_MOVES
7446        || MEM_P (operands [0])
7447        || !GENERAL_REGNO_P (true_regnum (operands [0])))"
7448   [(set (match_dup 0) (match_dup 1))]
7449   "operands[1] = gen_rtx_REG (SImode, REGNO (operands[1]));")
7450
7451 (define_insn_and_split "*vec_ext_v4si_mem"
7452   [(set (match_operand:SI 0 "register_operand" "=r")
7453         (vec_select:SI
7454           (match_operand:V4SI 1 "memory_operand" "o")
7455           (parallel [(match_operand 2 "const_0_to_3_operand" "")])))]
7456   ""
7457   "#"
7458   "reload_completed"
7459   [(const_int 0)]
7460 {
7461   int i = INTVAL (operands[2]);
7462
7463   emit_move_insn (operands[0], adjust_address (operands[1], SImode, i*4));
7464   DONE;
7465 })
7466
7467 (define_expand "sse_storeq"
7468   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7469         (vec_select:DI
7470           (match_operand:V2DI 1 "register_operand" "")
7471           (parallel [(const_int 0)])))]
7472   "TARGET_SSE")
7473
7474 (define_insn "*sse2_storeq_rex64"
7475   [(set (match_operand:DI 0 "nonimmediate_operand" "=mx,*r,r")
7476         (vec_select:DI
7477           (match_operand:V2DI 1 "nonimmediate_operand" "x,Yi,o")
7478           (parallel [(const_int 0)])))]
7479   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7480   "@
7481    #
7482    #
7483    %vmov{q}\t{%1, %0|%0, %1}"
7484   [(set_attr "type" "*,*,imov")
7485    (set_attr "prefix" "*,*,maybe_vex")
7486    (set_attr "mode" "*,*,DI")])
7487
7488 (define_insn "*sse2_storeq"
7489   [(set (match_operand:DI 0 "nonimmediate_operand" "=mx")
7490         (vec_select:DI
7491           (match_operand:V2DI 1 "register_operand" "x")
7492           (parallel [(const_int 0)])))]
7493   "TARGET_SSE"
7494   "#")
7495
7496 (define_split
7497   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7498         (vec_select:DI
7499           (match_operand:V2DI 1 "register_operand" "")
7500           (parallel [(const_int 0)])))]
7501   "TARGET_SSE
7502    && reload_completed
7503    && (TARGET_INTER_UNIT_MOVES
7504        || MEM_P (operands [0])
7505        || !GENERAL_REGNO_P (true_regnum (operands [0])))"
7506   [(set (match_dup 0) (match_dup 1))]
7507   "operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
7508
7509 (define_insn "*vec_extractv2di_1_rex64_avx"
7510   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,x,x,r")
7511         (vec_select:DI
7512           (match_operand:V2DI 1 "nonimmediate_operand" "x,x,o,o")
7513           (parallel [(const_int 1)])))]
7514   "TARGET_64BIT
7515    && TARGET_AVX
7516    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7517   "@
7518    vmovhps\t{%1, %0|%0, %1}
7519    vpsrldq\t{$8, %1, %0|%0, %1, 8}
7520    vmovq\t{%H1, %0|%0, %H1}
7521    vmov{q}\t{%H1, %0|%0, %H1}"
7522   [(set_attr "type" "ssemov,sseishft1,ssemov,imov")
7523    (set_attr "length_immediate" "*,1,*,*")
7524    (set_attr "memory" "*,none,*,*")
7525    (set_attr "prefix" "vex")
7526    (set_attr "mode" "V2SF,TI,TI,DI")])
7527
7528 (define_insn "*vec_extractv2di_1_rex64"
7529   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,x,x,r")
7530         (vec_select:DI
7531           (match_operand:V2DI 1 "nonimmediate_operand" "x,0,o,o")
7532           (parallel [(const_int 1)])))]
7533   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7534   "@
7535    movhps\t{%1, %0|%0, %1}
7536    psrldq\t{$8, %0|%0, 8}
7537    movq\t{%H1, %0|%0, %H1}
7538    mov{q}\t{%H1, %0|%0, %H1}"
7539   [(set_attr "type" "ssemov,sseishft1,ssemov,imov")
7540    (set_attr "length_immediate" "*,1,*,*")
7541    (set_attr "memory" "*,none,*,*")
7542    (set_attr "mode" "V2SF,TI,TI,DI")])
7543
7544 (define_insn "*vec_extractv2di_1_avx"
7545   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,x,x")
7546         (vec_select:DI
7547           (match_operand:V2DI 1 "nonimmediate_operand" "x,x,o")
7548           (parallel [(const_int 1)])))]
7549   "!TARGET_64BIT
7550    && TARGET_AVX
7551    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7552   "@
7553    vmovhps\t{%1, %0|%0, %1}
7554    vpsrldq\t{$8, %1, %0|%0, %1, 8}
7555    vmovq\t{%H1, %0|%0, %H1}"
7556   [(set_attr "type" "ssemov,sseishft1,ssemov")
7557    (set_attr "length_immediate" "*,1,*")
7558    (set_attr "memory" "*,none,*")
7559    (set_attr "prefix" "vex")
7560    (set_attr "mode" "V2SF,TI,TI")])
7561
7562 (define_insn "*vec_extractv2di_1_sse2"
7563   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,x,x")
7564         (vec_select:DI
7565           (match_operand:V2DI 1 "nonimmediate_operand" "x,0,o")
7566           (parallel [(const_int 1)])))]
7567   "!TARGET_64BIT
7568    && TARGET_SSE2 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7569   "@
7570    movhps\t{%1, %0|%0, %1}
7571    psrldq\t{$8, %0|%0, 8}
7572    movq\t{%H1, %0|%0, %H1}"
7573   [(set_attr "type" "ssemov,sseishft1,ssemov")
7574    (set_attr "length_immediate" "*,1,*")
7575    (set_attr "memory" "*,none,*")
7576    (set_attr "mode" "V2SF,TI,TI")])
7577
7578 ;; Not sure this is ever used, but it doesn't hurt to have it. -aoliva
7579 (define_insn "*vec_extractv2di_1_sse"
7580   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,x,x")
7581         (vec_select:DI
7582           (match_operand:V2DI 1 "nonimmediate_operand" "x,x,o")
7583           (parallel [(const_int 1)])))]
7584   "!TARGET_SSE2 && TARGET_SSE
7585    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7586   "@
7587    movhps\t{%1, %0|%0, %1}
7588    movhlps\t{%1, %0|%0, %1}
7589    movlps\t{%H1, %0|%0, %H1}"
7590   [(set_attr "type" "ssemov")
7591    (set_attr "mode" "V2SF,V4SF,V2SF")])
7592
7593 (define_insn "*vec_dupv4si_avx"
7594   [(set (match_operand:V4SI 0 "register_operand" "=x,x")
7595         (vec_duplicate:V4SI
7596           (match_operand:SI 1 "register_operand" "x,m")))]
7597   "TARGET_AVX"
7598   "@
7599    vpshufd\t{$0, %1, %0|%0, %1, 0}
7600    vbroadcastss\t{%1, %0|%0, %1}"
7601   [(set_attr "type" "sselog1,ssemov")
7602    (set_attr "length_immediate" "1,0")
7603    (set_attr "prefix_extra" "0,1")
7604    (set_attr "prefix" "vex")
7605    (set_attr "mode" "TI,V4SF")])
7606
7607 (define_insn "*vec_dupv4si"
7608   [(set (match_operand:V4SI 0 "register_operand" "=Y2,x")
7609         (vec_duplicate:V4SI
7610           (match_operand:SI 1 "register_operand" " Y2,0")))]
7611   "TARGET_SSE"
7612   "@
7613    %vpshufd\t{$0, %1, %0|%0, %1, 0}
7614    shufps\t{$0, %0, %0|%0, %0, 0}"
7615   [(set_attr "type" "sselog1")
7616    (set_attr "length_immediate" "1")
7617    (set_attr "mode" "TI,V4SF")])
7618
7619 (define_insn "*vec_dupv2di_avx"
7620   [(set (match_operand:V2DI 0 "register_operand"     "=x,x")
7621         (vec_duplicate:V2DI
7622           (match_operand:DI 1 "nonimmediate_operand" " x,m")))]
7623   "TARGET_AVX"
7624   "@
7625    vpunpcklqdq\t{%1, %1, %0|%0, %1, %1}
7626    vmovddup\t{%1, %0|%0, %1}"
7627   [(set_attr "type" "sselog1")
7628    (set_attr "prefix" "vex")
7629    (set_attr "mode" "TI,DF")])
7630
7631 (define_insn "*vec_dupv2di_sse3"
7632   [(set (match_operand:V2DI 0 "register_operand"     "=x,x")
7633         (vec_duplicate:V2DI
7634           (match_operand:DI 1 "nonimmediate_operand" " 0,m")))]
7635   "TARGET_SSE3"
7636   "@
7637    punpcklqdq\t%0, %0
7638    movddup\t{%1, %0|%0, %1}"
7639   [(set_attr "type" "sselog1")
7640    (set_attr "mode" "TI,DF")])
7641
7642 (define_insn "*vec_dupv2di"
7643   [(set (match_operand:V2DI 0 "register_operand" "=Y2,x")
7644         (vec_duplicate:V2DI
7645           (match_operand:DI 1 "register_operand" " 0 ,0")))]
7646   "TARGET_SSE"
7647   "@
7648    punpcklqdq\t%0, %0
7649    movlhps\t%0, %0"
7650   [(set_attr "type" "sselog1,ssemov")
7651    (set_attr "mode" "TI,V4SF")])
7652
7653 (define_insn "*vec_concatv2si_avx"
7654   [(set (match_operand:V2SI 0 "register_operand"     "=x,x,x ,*y ,*y")
7655         (vec_concat:V2SI
7656           (match_operand:SI 1 "nonimmediate_operand" "x ,x,rm, 0 ,rm")
7657           (match_operand:SI 2 "vector_move_operand"  "rm,x,C ,*ym,C")))]
7658   "TARGET_AVX"
7659   "@
7660    vpinsrd\t{$0x1, %2, %1, %0|%0, %1, %2, 0x1}
7661    vpunpckldq\t{%2, %1, %0|%0, %1, %2}
7662    vmovd\t{%1, %0|%0, %1}
7663    punpckldq\t{%2, %0|%0, %2}
7664    movd\t{%1, %0|%0, %1}"
7665   [(set_attr "type" "sselog,sselog,ssemov,mmxcvt,mmxmov")
7666    (set_attr "prefix_extra" "1,*,*,*,*")
7667    (set_attr "length_immediate" "1,*,*,*,*")
7668    (set (attr "prefix")
7669      (if_then_else (eq_attr "alternative" "3,4")
7670        (const_string "orig")
7671        (const_string "vex")))
7672    (set_attr "mode" "TI,TI,TI,DI,DI")])
7673
7674 (define_insn "*vec_concatv2si_sse4_1"
7675   [(set (match_operand:V2SI 0 "register_operand"     "=x,x,x ,*y ,*y")
7676         (vec_concat:V2SI
7677           (match_operand:SI 1 "nonimmediate_operand" "0 ,0,rm, 0 ,rm")
7678           (match_operand:SI 2 "vector_move_operand"  "rm,x,C ,*ym,C")))]
7679   "TARGET_SSE4_1"
7680   "@
7681    pinsrd\t{$0x1, %2, %0|%0, %2, 0x1}
7682    punpckldq\t{%2, %0|%0, %2}
7683    movd\t{%1, %0|%0, %1}
7684    punpckldq\t{%2, %0|%0, %2}
7685    movd\t{%1, %0|%0, %1}"
7686   [(set_attr "type" "sselog,sselog,ssemov,mmxcvt,mmxmov")
7687    (set_attr "prefix_extra" "1,*,*,*,*")
7688    (set_attr "length_immediate" "1,*,*,*,*")
7689    (set_attr "mode" "TI,TI,TI,DI,DI")])
7690
7691 ;; ??? In theory we can match memory for the MMX alternative, but allowing
7692 ;; nonimmediate_operand for operand 2 and *not* allowing memory for the SSE
7693 ;; alternatives pretty much forces the MMX alternative to be chosen.
7694 (define_insn "*vec_concatv2si_sse2"
7695   [(set (match_operand:V2SI 0 "register_operand"     "=x,x ,*y,*y")
7696         (vec_concat:V2SI
7697           (match_operand:SI 1 "nonimmediate_operand" " 0,rm, 0,rm")
7698           (match_operand:SI 2 "reg_or_0_operand"     " x,C ,*y, C")))]
7699   "TARGET_SSE2"
7700   "@
7701    punpckldq\t{%2, %0|%0, %2}
7702    movd\t{%1, %0|%0, %1}
7703    punpckldq\t{%2, %0|%0, %2}
7704    movd\t{%1, %0|%0, %1}"
7705   [(set_attr "type" "sselog,ssemov,mmxcvt,mmxmov")
7706    (set_attr "mode" "TI,TI,DI,DI")])
7707
7708 (define_insn "*vec_concatv2si_sse"
7709   [(set (match_operand:V2SI 0 "register_operand"     "=x,x,*y,*y")
7710         (vec_concat:V2SI
7711           (match_operand:SI 1 "nonimmediate_operand" " 0,m, 0,*rm")
7712           (match_operand:SI 2 "reg_or_0_operand"     " x,C,*y,C")))]
7713   "TARGET_SSE"
7714   "@
7715    unpcklps\t{%2, %0|%0, %2}
7716    movss\t{%1, %0|%0, %1}
7717    punpckldq\t{%2, %0|%0, %2}
7718    movd\t{%1, %0|%0, %1}"
7719   [(set_attr "type" "sselog,ssemov,mmxcvt,mmxmov")
7720    (set_attr "mode" "V4SF,V4SF,DI,DI")])
7721
7722 (define_insn "*vec_concatv4si_1_avx"
7723   [(set (match_operand:V4SI 0 "register_operand"       "=x,x")
7724         (vec_concat:V4SI
7725           (match_operand:V2SI 1 "register_operand"     " x,x")
7726           (match_operand:V2SI 2 "nonimmediate_operand" " x,m")))]
7727   "TARGET_AVX"
7728   "@
7729    vpunpcklqdq\t{%2, %1, %0|%0, %1, %2}
7730    vmovhps\t{%2, %1, %0|%0, %1, %2}"
7731   [(set_attr "type" "sselog,ssemov")
7732    (set_attr "prefix" "vex")
7733    (set_attr "mode" "TI,V2SF")])
7734
7735 (define_insn "*vec_concatv4si_1"
7736   [(set (match_operand:V4SI 0 "register_operand"       "=Y2,x,x")
7737         (vec_concat:V4SI
7738           (match_operand:V2SI 1 "register_operand"     " 0 ,0,0")
7739           (match_operand:V2SI 2 "nonimmediate_operand" " Y2,x,m")))]
7740   "TARGET_SSE"
7741   "@
7742    punpcklqdq\t{%2, %0|%0, %2}
7743    movlhps\t{%2, %0|%0, %2}
7744    movhps\t{%2, %0|%0, %2}"
7745   [(set_attr "type" "sselog,ssemov,ssemov")
7746    (set_attr "mode" "TI,V4SF,V2SF")])
7747
7748 (define_insn "*vec_concatv2di_avx"
7749   [(set (match_operand:V2DI 0 "register_operand"     "=x,?x,x,x")
7750         (vec_concat:V2DI
7751           (match_operand:DI 1 "nonimmediate_operand" " m,*y,x,x")
7752           (match_operand:DI 2 "vector_move_operand"  " C, C,x,m")))]
7753   "!TARGET_64BIT && TARGET_AVX"
7754   "@
7755    vmovq\t{%1, %0|%0, %1}
7756    movq2dq\t{%1, %0|%0, %1}
7757    vpunpcklqdq\t{%2, %1, %0|%0, %1, %2}
7758    vmovhps\t{%2, %1, %0|%0, %1, %2}"
7759   [(set_attr "type" "ssemov,ssemov,sselog,ssemov")
7760    (set (attr "prefix")
7761      (if_then_else (eq_attr "alternative" "1")
7762        (const_string "orig")
7763        (const_string "vex")))
7764    (set_attr "mode" "TI,TI,TI,V2SF")])
7765
7766 (define_insn "vec_concatv2di"
7767   [(set (match_operand:V2DI 0 "register_operand"     "=Y2 ,?Y2,Y2,x,x")
7768         (vec_concat:V2DI
7769           (match_operand:DI 1 "nonimmediate_operand" " mY2,*y ,0 ,0,0")
7770           (match_operand:DI 2 "vector_move_operand"  " C  ,  C,Y2,x,m")))]
7771   "!TARGET_64BIT && TARGET_SSE"
7772   "@
7773    movq\t{%1, %0|%0, %1}
7774    movq2dq\t{%1, %0|%0, %1}
7775    punpcklqdq\t{%2, %0|%0, %2}
7776    movlhps\t{%2, %0|%0, %2}
7777    movhps\t{%2, %0|%0, %2}"
7778   [(set_attr "type" "ssemov,ssemov,sselog,ssemov,ssemov")
7779    (set_attr "mode" "TI,TI,TI,V4SF,V2SF")])
7780
7781 (define_insn "*vec_concatv2di_rex64_avx"
7782   [(set (match_operand:V2DI 0 "register_operand"     "=x,x,Yi,!x,x,x")
7783         (vec_concat:V2DI
7784           (match_operand:DI 1 "nonimmediate_operand" " x,m,r ,*y,x,x")
7785           (match_operand:DI 2 "vector_move_operand"  "rm,C,C ,C ,x,m")))]
7786   "TARGET_64BIT && TARGET_AVX"
7787   "@
7788    vpinsrq\t{$0x1, %2, %1, %0|%0, %1, %2, 0x1}
7789    vmovq\t{%1, %0|%0, %1}
7790    vmovq\t{%1, %0|%0, %1}
7791    movq2dq\t{%1, %0|%0, %1}
7792    vpunpcklqdq\t{%2, %1, %0|%0, %1, %2}
7793    vmovhps\t{%2, %1, %0|%0, %1, %2}"
7794   [(set_attr "type" "sselog,ssemov,ssemov,ssemov,sselog,ssemov")
7795    (set_attr "prefix_extra" "1,*,*,*,*,*")
7796    (set_attr "length_immediate" "1,*,*,*,*,*")
7797    (set (attr "prefix")
7798      (if_then_else (eq_attr "alternative" "3")
7799        (const_string "orig")
7800        (const_string "vex")))
7801    (set_attr "mode" "TI,TI,TI,TI,TI,V2SF")])
7802
7803 (define_insn "*vec_concatv2di_rex64_sse4_1"
7804   [(set (match_operand:V2DI 0 "register_operand"     "=x ,x ,Yi,!x,x,x,x")
7805         (vec_concat:V2DI
7806           (match_operand:DI 1 "nonimmediate_operand" " 0 ,mx,r ,*y,0,0,0")
7807           (match_operand:DI 2 "vector_move_operand"  " rm,C ,C ,C ,x,x,m")))]
7808   "TARGET_64BIT && TARGET_SSE4_1"
7809   "@
7810    pinsrq\t{$0x1, %2, %0|%0, %2, 0x1}
7811    movq\t{%1, %0|%0, %1}
7812    movq\t{%1, %0|%0, %1}
7813    movq2dq\t{%1, %0|%0, %1}
7814    punpcklqdq\t{%2, %0|%0, %2}
7815    movlhps\t{%2, %0|%0, %2}
7816    movhps\t{%2, %0|%0, %2}"
7817   [(set_attr "type" "sselog,ssemov,ssemov,ssemov,sselog,ssemov,ssemov")
7818    (set_attr "prefix_rex" "1,*,1,*,*,*,*")
7819    (set_attr "prefix_extra" "1,*,*,*,*,*,*")
7820    (set_attr "length_immediate" "1,*,*,*,*,*,*")
7821    (set_attr "mode" "TI,TI,TI,TI,TI,V4SF,V2SF")])
7822
7823 (define_insn "*vec_concatv2di_rex64_sse"
7824   [(set (match_operand:V2DI 0 "register_operand"     "=Y2 ,Yi,!Y2,Y2,x,x")
7825         (vec_concat:V2DI
7826           (match_operand:DI 1 "nonimmediate_operand" " mY2,r ,*y ,0 ,0,0")
7827           (match_operand:DI 2 "vector_move_operand"  " C  ,C ,C  ,Y2,x,m")))]
7828   "TARGET_64BIT && TARGET_SSE"
7829   "@
7830    movq\t{%1, %0|%0, %1}
7831    movq\t{%1, %0|%0, %1}
7832    movq2dq\t{%1, %0|%0, %1}
7833    punpcklqdq\t{%2, %0|%0, %2}
7834    movlhps\t{%2, %0|%0, %2}
7835    movhps\t{%2, %0|%0, %2}"
7836   [(set_attr "type" "ssemov,ssemov,ssemov,sselog,ssemov,ssemov")
7837    (set_attr "prefix_rex" "*,1,*,*,*,*")
7838    (set_attr "mode" "TI,TI,TI,TI,V4SF,V2SF")])
7839
7840 (define_expand "vec_unpacku_hi_v16qi"
7841   [(match_operand:V8HI 0 "register_operand" "")
7842    (match_operand:V16QI 1 "register_operand" "")]
7843   "TARGET_SSE2"
7844 {
7845   if (TARGET_SSE4_1)
7846     ix86_expand_sse4_unpack (operands, true, true);
7847   else
7848     ix86_expand_sse_unpack (operands, true, true);
7849   DONE;
7850 })
7851
7852 (define_expand "vec_unpacks_hi_v16qi"
7853   [(match_operand:V8HI 0 "register_operand" "")
7854    (match_operand:V16QI 1 "register_operand" "")]
7855   "TARGET_SSE2"
7856 {
7857   if (TARGET_SSE4_1)
7858     ix86_expand_sse4_unpack (operands, false, true);
7859   else
7860     ix86_expand_sse_unpack (operands, false, true);
7861   DONE;
7862 })
7863
7864 (define_expand "vec_unpacku_lo_v16qi"
7865   [(match_operand:V8HI 0 "register_operand" "")
7866    (match_operand:V16QI 1 "register_operand" "")]
7867   "TARGET_SSE2"
7868 {
7869   if (TARGET_SSE4_1)
7870     ix86_expand_sse4_unpack (operands, true, false);
7871   else
7872     ix86_expand_sse_unpack (operands, true, false);
7873   DONE;
7874 })
7875
7876 (define_expand "vec_unpacks_lo_v16qi"
7877   [(match_operand:V8HI 0 "register_operand" "")
7878    (match_operand:V16QI 1 "register_operand" "")]
7879   "TARGET_SSE2"
7880 {
7881   if (TARGET_SSE4_1)
7882     ix86_expand_sse4_unpack (operands, false, false);
7883   else
7884     ix86_expand_sse_unpack (operands, false, false);
7885   DONE;
7886 })
7887
7888 (define_expand "vec_unpacku_hi_v8hi"
7889   [(match_operand:V4SI 0 "register_operand" "")
7890    (match_operand:V8HI 1 "register_operand" "")]
7891   "TARGET_SSE2"
7892 {
7893   if (TARGET_SSE4_1)
7894     ix86_expand_sse4_unpack (operands, true, true);
7895   else
7896     ix86_expand_sse_unpack (operands, true, true);
7897   DONE;
7898 })
7899
7900 (define_expand "vec_unpacks_hi_v8hi"
7901   [(match_operand:V4SI 0 "register_operand" "")
7902    (match_operand:V8HI 1 "register_operand" "")]
7903   "TARGET_SSE2"
7904 {
7905   if (TARGET_SSE4_1)
7906     ix86_expand_sse4_unpack (operands, false, true);
7907   else
7908     ix86_expand_sse_unpack (operands, false, true);
7909   DONE;
7910 })
7911
7912 (define_expand "vec_unpacku_lo_v8hi"
7913   [(match_operand:V4SI 0 "register_operand" "")
7914    (match_operand:V8HI 1 "register_operand" "")]
7915   "TARGET_SSE2"
7916 {
7917   if (TARGET_SSE4_1)
7918     ix86_expand_sse4_unpack (operands, true, false);
7919   else
7920     ix86_expand_sse_unpack (operands, true, false);
7921   DONE;
7922 })
7923
7924 (define_expand "vec_unpacks_lo_v8hi"
7925   [(match_operand:V4SI 0 "register_operand" "")
7926    (match_operand:V8HI 1 "register_operand" "")]
7927   "TARGET_SSE2"
7928 {
7929   if (TARGET_SSE4_1)
7930     ix86_expand_sse4_unpack (operands, false, false);
7931   else
7932     ix86_expand_sse_unpack (operands, false, false);
7933   DONE;
7934 })
7935
7936 (define_expand "vec_unpacku_hi_v4si"
7937   [(match_operand:V2DI 0 "register_operand" "")
7938    (match_operand:V4SI 1 "register_operand" "")]
7939   "TARGET_SSE2"
7940 {
7941   if (TARGET_SSE4_1)
7942     ix86_expand_sse4_unpack (operands, true, true);
7943   else
7944     ix86_expand_sse_unpack (operands, true, true);
7945   DONE;
7946 })
7947
7948 (define_expand "vec_unpacks_hi_v4si"
7949   [(match_operand:V2DI 0 "register_operand" "")
7950    (match_operand:V4SI 1 "register_operand" "")]
7951   "TARGET_SSE2"
7952 {
7953   if (TARGET_SSE4_1)
7954     ix86_expand_sse4_unpack (operands, false, true);
7955   else
7956     ix86_expand_sse_unpack (operands, false, true);
7957   DONE;
7958 })
7959
7960 (define_expand "vec_unpacku_lo_v4si"
7961   [(match_operand:V2DI 0 "register_operand" "")
7962    (match_operand:V4SI 1 "register_operand" "")]
7963   "TARGET_SSE2"
7964 {
7965   if (TARGET_SSE4_1)
7966     ix86_expand_sse4_unpack (operands, true, false);
7967   else
7968     ix86_expand_sse_unpack (operands, true, false);
7969   DONE;
7970 })
7971
7972 (define_expand "vec_unpacks_lo_v4si"
7973   [(match_operand:V2DI 0 "register_operand" "")
7974    (match_operand:V4SI 1 "register_operand" "")]
7975   "TARGET_SSE2"
7976 {
7977   if (TARGET_SSE4_1)
7978     ix86_expand_sse4_unpack (operands, false, false);
7979   else
7980     ix86_expand_sse_unpack (operands, false, false);
7981   DONE;
7982 })
7983
7984 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7985 ;;
7986 ;; Miscellaneous
7987 ;;
7988 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7989
7990 (define_expand "sse2_uavgv16qi3"
7991   [(set (match_operand:V16QI 0 "register_operand" "")
7992         (truncate:V16QI
7993           (lshiftrt:V16HI
7994             (plus:V16HI
7995               (plus:V16HI
7996                 (zero_extend:V16HI
7997                   (match_operand:V16QI 1 "nonimmediate_operand" ""))
7998                 (zero_extend:V16HI
7999                   (match_operand:V16QI 2 "nonimmediate_operand" "")))
8000               (const_vector:V16QI [(const_int 1) (const_int 1)
8001                                    (const_int 1) (const_int 1)
8002                                    (const_int 1) (const_int 1)
8003                                    (const_int 1) (const_int 1)
8004                                    (const_int 1) (const_int 1)
8005                                    (const_int 1) (const_int 1)
8006                                    (const_int 1) (const_int 1)
8007                                    (const_int 1) (const_int 1)]))
8008             (const_int 1))))]
8009   "TARGET_SSE2"
8010   "ix86_fixup_binary_operands_no_copy (PLUS, V16QImode, operands);")
8011
8012 (define_insn "*avx_uavgv16qi3"
8013   [(set (match_operand:V16QI 0 "register_operand" "=x")
8014         (truncate:V16QI
8015           (lshiftrt:V16HI
8016             (plus:V16HI
8017               (plus:V16HI
8018                 (zero_extend:V16HI
8019                   (match_operand:V16QI 1 "nonimmediate_operand" "%x"))
8020                 (zero_extend:V16HI
8021                   (match_operand:V16QI 2 "nonimmediate_operand" "xm")))
8022               (const_vector:V16QI [(const_int 1) (const_int 1)
8023                                    (const_int 1) (const_int 1)
8024                                    (const_int 1) (const_int 1)
8025                                    (const_int 1) (const_int 1)
8026                                    (const_int 1) (const_int 1)
8027                                    (const_int 1) (const_int 1)
8028                                    (const_int 1) (const_int 1)
8029                                    (const_int 1) (const_int 1)]))
8030             (const_int 1))))]
8031   "TARGET_AVX && ix86_binary_operator_ok (PLUS, V16QImode, operands)"
8032   "vpavgb\t{%2, %1, %0|%0, %1, %2}"
8033   [(set_attr "type" "sseiadd")
8034    (set_attr "prefix" "vex")
8035    (set_attr "mode" "TI")])
8036
8037 (define_insn "*sse2_uavgv16qi3"
8038   [(set (match_operand:V16QI 0 "register_operand" "=x")
8039         (truncate:V16QI
8040           (lshiftrt:V16HI
8041             (plus:V16HI
8042               (plus:V16HI
8043                 (zero_extend:V16HI
8044                   (match_operand:V16QI 1 "nonimmediate_operand" "%0"))
8045                 (zero_extend:V16HI
8046                   (match_operand:V16QI 2 "nonimmediate_operand" "xm")))
8047               (const_vector:V16QI [(const_int 1) (const_int 1)
8048                                    (const_int 1) (const_int 1)
8049                                    (const_int 1) (const_int 1)
8050                                    (const_int 1) (const_int 1)
8051                                    (const_int 1) (const_int 1)
8052                                    (const_int 1) (const_int 1)
8053                                    (const_int 1) (const_int 1)
8054                                    (const_int 1) (const_int 1)]))
8055             (const_int 1))))]
8056   "TARGET_SSE2 && ix86_binary_operator_ok (PLUS, V16QImode, operands)"
8057   "pavgb\t{%2, %0|%0, %2}"
8058   [(set_attr "type" "sseiadd")
8059    (set_attr "prefix_data16" "1")
8060    (set_attr "mode" "TI")])
8061
8062 (define_expand "sse2_uavgv8hi3"
8063   [(set (match_operand:V8HI 0 "register_operand" "")
8064         (truncate:V8HI
8065           (lshiftrt:V8SI
8066             (plus:V8SI
8067               (plus:V8SI
8068                 (zero_extend:V8SI
8069                   (match_operand:V8HI 1 "nonimmediate_operand" ""))
8070                 (zero_extend:V8SI
8071                   (match_operand:V8HI 2 "nonimmediate_operand" "")))
8072               (const_vector:V8HI [(const_int 1) (const_int 1)
8073                                   (const_int 1) (const_int 1)
8074                                   (const_int 1) (const_int 1)
8075                                   (const_int 1) (const_int 1)]))
8076             (const_int 1))))]
8077   "TARGET_SSE2"
8078   "ix86_fixup_binary_operands_no_copy (PLUS, V8HImode, operands);")
8079
8080 (define_insn "*avx_uavgv8hi3"
8081   [(set (match_operand:V8HI 0 "register_operand" "=x")
8082         (truncate:V8HI
8083           (lshiftrt:V8SI
8084             (plus:V8SI
8085               (plus:V8SI
8086                 (zero_extend:V8SI
8087                   (match_operand:V8HI 1 "nonimmediate_operand" "%x"))
8088                 (zero_extend:V8SI
8089                   (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
8090               (const_vector:V8HI [(const_int 1) (const_int 1)
8091                                   (const_int 1) (const_int 1)
8092                                   (const_int 1) (const_int 1)
8093                                   (const_int 1) (const_int 1)]))
8094             (const_int 1))))]
8095   "TARGET_AVX && ix86_binary_operator_ok (PLUS, V8HImode, operands)"
8096   "vpavgw\t{%2, %1, %0|%0, %1, %2}"
8097   [(set_attr "type" "sseiadd")
8098    (set_attr "prefix" "vex")
8099    (set_attr "mode" "TI")])
8100
8101 (define_insn "*sse2_uavgv8hi3"
8102   [(set (match_operand:V8HI 0 "register_operand" "=x")
8103         (truncate:V8HI
8104           (lshiftrt:V8SI
8105             (plus:V8SI
8106               (plus:V8SI
8107                 (zero_extend:V8SI
8108                   (match_operand:V8HI 1 "nonimmediate_operand" "%0"))
8109                 (zero_extend:V8SI
8110                   (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
8111               (const_vector:V8HI [(const_int 1) (const_int 1)
8112                                   (const_int 1) (const_int 1)
8113                                   (const_int 1) (const_int 1)
8114                                   (const_int 1) (const_int 1)]))
8115             (const_int 1))))]
8116   "TARGET_SSE2 && ix86_binary_operator_ok (PLUS, V8HImode, operands)"
8117   "pavgw\t{%2, %0|%0, %2}"
8118   [(set_attr "type" "sseiadd")
8119    (set_attr "prefix_data16" "1")
8120    (set_attr "mode" "TI")])
8121
8122 ;; The correct representation for this is absolutely enormous, and
8123 ;; surely not generally useful.
8124 (define_insn "*avx_psadbw"
8125   [(set (match_operand:V2DI 0 "register_operand" "=x")
8126         (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "x")
8127                       (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
8128                      UNSPEC_PSADBW))]
8129   "TARGET_AVX"
8130   "vpsadbw\t{%2, %1, %0|%0, %1, %2}"
8131   [(set_attr "type" "sseiadd")
8132    (set_attr "prefix" "vex")
8133    (set_attr "mode" "TI")])
8134
8135 (define_insn "sse2_psadbw"
8136   [(set (match_operand:V2DI 0 "register_operand" "=x")
8137         (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
8138                       (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
8139                      UNSPEC_PSADBW))]
8140   "TARGET_SSE2"
8141   "psadbw\t{%2, %0|%0, %2}"
8142   [(set_attr "type" "sseiadd")
8143    (set_attr "atom_unit" "simul")
8144    (set_attr "prefix_data16" "1")
8145    (set_attr "mode" "TI")])
8146
8147 (define_insn "avx_movmsk<ssemodesuffix>256"
8148   [(set (match_operand:SI 0 "register_operand" "=r")
8149         (unspec:SI
8150           [(match_operand:AVX256MODEF2P 1 "register_operand" "x")]
8151           UNSPEC_MOVMSK))]
8152   "AVX256_VEC_FLOAT_MODE_P (<MODE>mode)"
8153   "vmovmsk<ssemodesuffix>\t{%1, %0|%0, %1}"
8154   [(set_attr "type" "ssecvt")
8155    (set_attr "prefix" "vex")
8156    (set_attr "mode" "<MODE>")])
8157
8158 (define_insn "<sse>_movmsk<ssemodesuffix>"
8159   [(set (match_operand:SI 0 "register_operand" "=r")
8160         (unspec:SI
8161           [(match_operand:SSEMODEF2P 1 "register_operand" "x")]
8162           UNSPEC_MOVMSK))]
8163   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
8164   "%vmovmsk<ssemodesuffix>\t{%1, %0|%0, %1}"
8165   [(set_attr "type" "ssemov")
8166    (set_attr "prefix" "maybe_vex")
8167    (set_attr "mode" "<MODE>")])
8168
8169 (define_insn "sse2_pmovmskb"
8170   [(set (match_operand:SI 0 "register_operand" "=r")
8171         (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
8172                    UNSPEC_MOVMSK))]
8173   "TARGET_SSE2"
8174   "%vpmovmskb\t{%1, %0|%0, %1}"
8175   [(set_attr "type" "ssemov")
8176    (set_attr "prefix_data16" "1")
8177    (set_attr "prefix" "maybe_vex")
8178    (set_attr "mode" "SI")])
8179
8180 (define_expand "sse2_maskmovdqu"
8181   [(set (match_operand:V16QI 0 "memory_operand" "")
8182         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "")
8183                        (match_operand:V16QI 2 "register_operand" "")
8184                        (match_dup 0)]
8185                       UNSPEC_MASKMOV))]
8186   "TARGET_SSE2")
8187
8188 (define_insn "*sse2_maskmovdqu"
8189   [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
8190         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
8191                        (match_operand:V16QI 2 "register_operand" "x")
8192                        (mem:V16QI (match_dup 0))]
8193                       UNSPEC_MASKMOV))]
8194   "TARGET_SSE2 && !TARGET_64BIT"
8195   ;; @@@ check ordering of operands in intel/nonintel syntax
8196   "%vmaskmovdqu\t{%2, %1|%1, %2}"
8197   [(set_attr "type" "ssemov")
8198    (set_attr "prefix_data16" "1")
8199    ;; The implicit %rdi operand confuses default length_vex computation.
8200    (set_attr "length_vex" "3")
8201    (set_attr "prefix" "maybe_vex")
8202    (set_attr "mode" "TI")])
8203
8204 (define_insn "*sse2_maskmovdqu_rex64"
8205   [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
8206         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
8207                        (match_operand:V16QI 2 "register_operand" "x")
8208                        (mem:V16QI (match_dup 0))]
8209                       UNSPEC_MASKMOV))]
8210   "TARGET_SSE2 && TARGET_64BIT"
8211   ;; @@@ check ordering of operands in intel/nonintel syntax
8212   "%vmaskmovdqu\t{%2, %1|%1, %2}"
8213   [(set_attr "type" "ssemov")
8214    (set_attr "prefix_data16" "1")
8215    ;; The implicit %rdi operand confuses default length_vex computation.
8216    (set (attr "length_vex")
8217      (symbol_ref ("REGNO (operands[2]) >= FIRST_REX_SSE_REG ? 3 + 1 : 2 + 1")))
8218    (set_attr "prefix" "maybe_vex")
8219    (set_attr "mode" "TI")])
8220
8221 (define_insn "sse_ldmxcsr"
8222   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
8223                     UNSPECV_LDMXCSR)]
8224   "TARGET_SSE"
8225   "%vldmxcsr\t%0"
8226   [(set_attr "type" "sse")
8227    (set_attr "atom_sse_attr" "mxcsr")
8228    (set_attr "prefix" "maybe_vex")
8229    (set_attr "memory" "load")])
8230
8231 (define_insn "sse_stmxcsr"
8232   [(set (match_operand:SI 0 "memory_operand" "=m")
8233         (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
8234   "TARGET_SSE"
8235   "%vstmxcsr\t%0"
8236   [(set_attr "type" "sse")
8237    (set_attr "atom_sse_attr" "mxcsr")
8238    (set_attr "prefix" "maybe_vex")
8239    (set_attr "memory" "store")])
8240
8241 (define_expand "sse_sfence"
8242   [(set (match_dup 0)
8243         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
8244   "TARGET_SSE || TARGET_3DNOW_A"
8245 {
8246   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
8247   MEM_VOLATILE_P (operands[0]) = 1;
8248 })
8249
8250 (define_insn "*sse_sfence"
8251   [(set (match_operand:BLK 0 "" "")
8252         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
8253   "TARGET_SSE || TARGET_3DNOW_A"
8254   "sfence"
8255   [(set_attr "type" "sse")
8256    (set_attr "length_address" "0")
8257    (set_attr "atom_sse_attr" "fence")
8258    (set_attr "memory" "unknown")])
8259
8260 (define_insn "sse2_clflush"
8261   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
8262                     UNSPECV_CLFLUSH)]
8263   "TARGET_SSE2"
8264   "clflush\t%a0"
8265   [(set_attr "type" "sse")
8266    (set_attr "atom_sse_attr" "fence")
8267    (set_attr "memory" "unknown")])
8268
8269 (define_expand "sse2_mfence"
8270   [(set (match_dup 0)
8271         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
8272   "TARGET_SSE2"
8273 {
8274   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
8275   MEM_VOLATILE_P (operands[0]) = 1;
8276 })
8277
8278 (define_insn "*sse2_mfence"
8279   [(set (match_operand:BLK 0 "" "")
8280         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
8281   "TARGET_64BIT || TARGET_SSE2"
8282   "mfence"
8283   [(set_attr "type" "sse")
8284    (set_attr "length_address" "0")
8285    (set_attr "atom_sse_attr" "fence")
8286    (set_attr "memory" "unknown")])
8287
8288 (define_expand "sse2_lfence"
8289   [(set (match_dup 0)
8290         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
8291   "TARGET_SSE2"
8292 {
8293   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
8294   MEM_VOLATILE_P (operands[0]) = 1;
8295 })
8296
8297 (define_insn "*sse2_lfence"
8298   [(set (match_operand:BLK 0 "" "")
8299         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
8300   "TARGET_SSE2"
8301   "lfence"
8302   [(set_attr "type" "sse")
8303    (set_attr "length_address" "0")
8304    (set_attr "atom_sse_attr" "lfence")
8305    (set_attr "memory" "unknown")])
8306
8307 (define_insn "sse3_mwait"
8308   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
8309                      (match_operand:SI 1 "register_operand" "c")]
8310                     UNSPECV_MWAIT)]
8311   "TARGET_SSE3"
8312 ;; 64bit version is "mwait %rax,%rcx". But only lower 32bits are used.
8313 ;; Since 32bit register operands are implicitly zero extended to 64bit,
8314 ;; we only need to set up 32bit registers.
8315   "mwait"
8316   [(set_attr "length" "3")])
8317
8318 (define_insn "sse3_monitor"
8319   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
8320                      (match_operand:SI 1 "register_operand" "c")
8321                      (match_operand:SI 2 "register_operand" "d")]
8322                     UNSPECV_MONITOR)]
8323   "TARGET_SSE3 && !TARGET_64BIT"
8324   "monitor\t%0, %1, %2"
8325   [(set_attr "length" "3")])
8326
8327 (define_insn "sse3_monitor64"
8328   [(unspec_volatile [(match_operand:DI 0 "register_operand" "a")
8329                      (match_operand:SI 1 "register_operand" "c")
8330                      (match_operand:SI 2 "register_operand" "d")]
8331                     UNSPECV_MONITOR)]
8332   "TARGET_SSE3 && TARGET_64BIT"
8333 ;; 64bit version is "monitor %rax,%rcx,%rdx". But only lower 32bits in
8334 ;; RCX and RDX are used.  Since 32bit register operands are implicitly
8335 ;; zero extended to 64bit, we only need to set up 32bit registers.
8336   "monitor"
8337   [(set_attr "length" "3")])
8338
8339 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8340 ;;
8341 ;; SSSE3 instructions
8342 ;;
8343 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8344
8345 (define_insn "*avx_phaddwv8hi3"
8346   [(set (match_operand:V8HI 0 "register_operand" "=x")
8347         (vec_concat:V8HI
8348           (vec_concat:V4HI
8349             (vec_concat:V2HI
8350               (plus:HI
8351                 (vec_select:HI
8352                   (match_operand:V8HI 1 "register_operand" "x")
8353                   (parallel [(const_int 0)]))
8354                 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
8355               (plus:HI
8356                 (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
8357                 (vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
8358             (vec_concat:V2HI
8359               (plus:HI
8360                 (vec_select:HI (match_dup 1) (parallel [(const_int 4)]))
8361                 (vec_select:HI (match_dup 1) (parallel [(const_int 5)])))
8362               (plus:HI
8363                 (vec_select:HI (match_dup 1) (parallel [(const_int 6)]))
8364                 (vec_select:HI (match_dup 1) (parallel [(const_int 7)])))))
8365           (vec_concat:V4HI
8366             (vec_concat:V2HI
8367               (plus:HI
8368                 (vec_select:HI
8369                   (match_operand:V8HI 2 "nonimmediate_operand" "xm")
8370                   (parallel [(const_int 0)]))
8371                 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
8372               (plus:HI
8373                 (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
8374                 (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))
8375             (vec_concat:V2HI
8376               (plus:HI
8377                 (vec_select:HI (match_dup 2) (parallel [(const_int 4)]))
8378                 (vec_select:HI (match_dup 2) (parallel [(const_int 5)])))
8379               (plus:HI
8380                 (vec_select:HI (match_dup 2) (parallel [(const_int 6)]))
8381                 (vec_select:HI (match_dup 2) (parallel [(const_int 7)])))))))]
8382   "TARGET_AVX"
8383   "vphaddw\t{%2, %1, %0|%0, %1, %2}"
8384   [(set_attr "type" "sseiadd")
8385    (set_attr "prefix_extra" "1")
8386    (set_attr "prefix" "vex")
8387    (set_attr "mode" "TI")])
8388
8389 (define_insn "ssse3_phaddwv8hi3"
8390   [(set (match_operand:V8HI 0 "register_operand" "=x")
8391         (vec_concat:V8HI
8392           (vec_concat:V4HI
8393             (vec_concat:V2HI
8394               (plus:HI
8395                 (vec_select:HI
8396                   (match_operand:V8HI 1 "register_operand" "0")
8397                   (parallel [(const_int 0)]))
8398                 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
8399               (plus:HI
8400                 (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
8401                 (vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
8402             (vec_concat:V2HI
8403               (plus:HI
8404                 (vec_select:HI (match_dup 1) (parallel [(const_int 4)]))
8405                 (vec_select:HI (match_dup 1) (parallel [(const_int 5)])))
8406               (plus:HI
8407                 (vec_select:HI (match_dup 1) (parallel [(const_int 6)]))
8408                 (vec_select:HI (match_dup 1) (parallel [(const_int 7)])))))
8409           (vec_concat:V4HI
8410             (vec_concat:V2HI
8411               (plus:HI
8412                 (vec_select:HI
8413                   (match_operand:V8HI 2 "nonimmediate_operand" "xm")
8414                   (parallel [(const_int 0)]))
8415                 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
8416               (plus:HI
8417                 (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
8418                 (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))
8419             (vec_concat:V2HI
8420               (plus:HI
8421                 (vec_select:HI (match_dup 2) (parallel [(const_int 4)]))
8422                 (vec_select:HI (match_dup 2) (parallel [(const_int 5)])))
8423               (plus:HI
8424                 (vec_select:HI (match_dup 2) (parallel [(const_int 6)]))
8425                 (vec_select:HI (match_dup 2) (parallel [(const_int 7)])))))))]
8426   "TARGET_SSSE3"
8427   "phaddw\t{%2, %0|%0, %2}"
8428   [(set_attr "type" "sseiadd")
8429    (set_attr "atom_unit" "complex")
8430    (set_attr "prefix_data16" "1")
8431    (set_attr "prefix_extra" "1")
8432    (set_attr "mode" "TI")])
8433
8434 (define_insn "ssse3_phaddwv4hi3"
8435   [(set (match_operand:V4HI 0 "register_operand" "=y")
8436         (vec_concat:V4HI
8437           (vec_concat:V2HI
8438             (plus:HI
8439               (vec_select:HI
8440                 (match_operand:V4HI 1 "register_operand" "0")
8441                 (parallel [(const_int 0)]))
8442               (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
8443             (plus:HI
8444               (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
8445               (vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
8446           (vec_concat:V2HI
8447             (plus:HI
8448               (vec_select:HI
8449                 (match_operand:V4HI 2 "nonimmediate_operand" "ym")
8450                 (parallel [(const_int 0)]))
8451               (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
8452             (plus:HI
8453               (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
8454               (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))))]
8455   "TARGET_SSSE3"
8456   "phaddw\t{%2, %0|%0, %2}"
8457   [(set_attr "type" "sseiadd")
8458    (set_attr "atom_unit" "complex")
8459    (set_attr "prefix_extra" "1")
8460    (set (attr "prefix_rex") (symbol_ref "x86_extended_reg_mentioned_p (insn)"))
8461    (set_attr "mode" "DI")])
8462
8463 (define_insn "*avx_phadddv4si3"
8464   [(set (match_operand:V4SI 0 "register_operand" "=x")
8465         (vec_concat:V4SI
8466           (vec_concat:V2SI
8467             (plus:SI
8468               (vec_select:SI
8469                 (match_operand:V4SI 1 "register_operand" "x")
8470                 (parallel [(const_int 0)]))
8471               (vec_select:SI (match_dup 1) (parallel [(const_int 1)])))
8472             (plus:SI
8473               (vec_select:SI (match_dup 1) (parallel [(const_int 2)]))
8474               (vec_select:SI (match_dup 1) (parallel [(const_int 3)]))))
8475           (vec_concat:V2SI
8476             (plus:SI
8477               (vec_select:SI
8478                 (match_operand:V4SI 2 "nonimmediate_operand" "xm")
8479                 (parallel [(const_int 0)]))
8480               (vec_select:SI (match_dup 2) (parallel [(const_int 1)])))
8481             (plus:SI
8482               (vec_select:SI (match_dup 2) (parallel [(const_int 2)]))
8483               (vec_select:SI (match_dup 2) (parallel [(const_int 3)]))))))]
8484   "TARGET_AVX"
8485   "vphaddd\t{%2, %1, %0|%0, %1, %2}"
8486   [(set_attr "type" "sseiadd")
8487    (set_attr "prefix_extra" "1")
8488    (set_attr "prefix" "vex")
8489    (set_attr "mode" "TI")])
8490
8491 (define_insn "ssse3_phadddv4si3"
8492   [(set (match_operand:V4SI 0 "register_operand" "=x")
8493         (vec_concat:V4SI
8494           (vec_concat:V2SI
8495             (plus:SI
8496               (vec_select:SI
8497                 (match_operand:V4SI 1 "register_operand" "0")
8498                 (parallel [(const_int 0)]))
8499               (vec_select:SI (match_dup 1) (parallel [(const_int 1)])))
8500             (plus:SI
8501               (vec_select:SI (match_dup 1) (parallel [(const_int 2)]))
8502               (vec_select:SI (match_dup 1) (parallel [(const_int 3)]))))
8503           (vec_concat:V2SI
8504             (plus:SI
8505               (vec_select:SI
8506                 (match_operand:V4SI 2 "nonimmediate_operand" "xm")
8507                 (parallel [(const_int 0)]))
8508               (vec_select:SI (match_dup 2) (parallel [(const_int 1)])))
8509             (plus:SI
8510               (vec_select:SI (match_dup 2) (parallel [(const_int 2)]))
8511               (vec_select:SI (match_dup 2) (parallel [(const_int 3)]))))))]
8512   "TARGET_SSSE3"
8513   "phaddd\t{%2, %0|%0, %2}"
8514   [(set_attr "type" "sseiadd")
8515    (set_attr "atom_unit" "complex")
8516    (set_attr "prefix_data16" "1")
8517    (set_attr "prefix_extra" "1")
8518    (set_attr "mode" "TI")])
8519
8520 (define_insn "ssse3_phadddv2si3"
8521   [(set (match_operand:V2SI 0 "register_operand" "=y")
8522         (vec_concat:V2SI
8523           (plus:SI
8524             (vec_select:SI
8525               (match_operand:V2SI 1 "register_operand" "0")
8526               (parallel [(const_int 0)]))
8527             (vec_select:SI (match_dup 1) (parallel [(const_int 1)])))
8528           (plus:SI
8529             (vec_select:SI
8530               (match_operand:V2SI 2 "nonimmediate_operand" "ym")
8531               (parallel [(const_int 0)]))
8532             (vec_select:SI (match_dup 2) (parallel [(const_int 1)])))))]
8533   "TARGET_SSSE3"
8534   "phaddd\t{%2, %0|%0, %2}"
8535   [(set_attr "type" "sseiadd")
8536    (set_attr "atom_unit" "complex")
8537    (set_attr "prefix_extra" "1")
8538    (set (attr "prefix_rex") (symbol_ref "x86_extended_reg_mentioned_p (insn)"))
8539    (set_attr "mode" "DI")])
8540
8541 (define_insn "*avx_phaddswv8hi3"
8542   [(set (match_operand:V8HI 0 "register_operand" "=x")
8543         (vec_concat:V8HI
8544           (vec_concat:V4HI
8545             (vec_concat:V2HI
8546               (ss_plus:HI
8547                 (vec_select:HI
8548                   (match_operand:V8HI 1 "register_operand" "x")
8549                   (parallel [(const_int 0)]))
8550                 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
8551               (ss_plus:HI
8552                 (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
8553                 (vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
8554             (vec_concat:V2HI
8555               (ss_plus:HI
8556                 (vec_select:HI (match_dup 1) (parallel [(const_int 4)]))
8557                 (vec_select:HI (match_dup 1) (parallel [(const_int 5)])))
8558               (ss_plus:HI
8559                 (vec_select:HI (match_dup 1) (parallel [(const_int 6)]))
8560                 (vec_select:HI (match_dup 1) (parallel [(const_int 7)])))))
8561           (vec_concat:V4HI
8562             (vec_concat:V2HI
8563               (ss_plus:HI
8564                 (vec_select:HI
8565                   (match_operand:V8HI 2 "nonimmediate_operand" "xm")
8566                   (parallel [(const_int 0)]))
8567                 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
8568               (ss_plus:HI
8569                 (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
8570                 (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))
8571             (vec_concat:V2HI
8572               (ss_plus:HI
8573                 (vec_select:HI (match_dup 2) (parallel [(const_int 4)]))
8574                 (vec_select:HI (match_dup 2) (parallel [(const_int 5)])))
8575               (ss_plus:HI
8576                 (vec_select:HI (match_dup 2) (parallel [(const_int 6)]))
8577                 (vec_select:HI (match_dup 2) (parallel [(const_int 7)])))))))]
8578   "TARGET_AVX"
8579   "vphaddsw\t{%2, %1, %0|%0, %1, %2}"
8580   [(set_attr "type" "sseiadd")
8581    (set_attr "prefix_extra" "1")
8582    (set_attr "prefix" "vex")
8583    (set_attr "mode" "TI")])
8584
8585 (define_insn "ssse3_phaddswv8hi3"
8586   [(set (match_operand:V8HI 0 "register_operand" "=x")
8587         (vec_concat:V8HI
8588           (vec_concat:V4HI
8589             (vec_concat:V2HI
8590               (ss_plus:HI
8591                 (vec_select:HI
8592                   (match_operand:V8HI 1 "register_operand" "0")
8593                   (parallel [(const_int 0)]))
8594                 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
8595               (ss_plus:HI
8596                 (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
8597                 (vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
8598             (vec_concat:V2HI
8599               (ss_plus:HI
8600                 (vec_select:HI (match_dup 1) (parallel [(const_int 4)]))
8601                 (vec_select:HI (match_dup 1) (parallel [(const_int 5)])))
8602               (ss_plus:HI
8603                 (vec_select:HI (match_dup 1) (parallel [(const_int 6)]))
8604                 (vec_select:HI (match_dup 1) (parallel [(const_int 7)])))))
8605           (vec_concat:V4HI
8606             (vec_concat:V2HI
8607               (ss_plus:HI
8608                 (vec_select:HI
8609                   (match_operand:V8HI 2 "nonimmediate_operand" "xm")
8610                   (parallel [(const_int 0)]))
8611                 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
8612               (ss_plus:HI
8613                 (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
8614                 (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))
8615             (vec_concat:V2HI
8616               (ss_plus:HI
8617                 (vec_select:HI (match_dup 2) (parallel [(const_int 4)]))
8618                 (vec_select:HI (match_dup 2) (parallel [(const_int 5)])))
8619               (ss_plus:HI
8620                 (vec_select:HI (match_dup 2) (parallel [(const_int 6)]))
8621                 (vec_select:HI (match_dup 2) (parallel [(const_int 7)])))))))]
8622   "TARGET_SSSE3"
8623   "phaddsw\t{%2, %0|%0, %2}"
8624   [(set_attr "type" "sseiadd")
8625    (set_attr "atom_unit" "complex")
8626    (set_attr "prefix_data16" "1")
8627    (set_attr "prefix_extra" "1")
8628    (set_attr "mode" "TI")])
8629
8630 (define_insn "ssse3_phaddswv4hi3"
8631   [(set (match_operand:V4HI 0 "register_operand" "=y")
8632         (vec_concat:V4HI
8633           (vec_concat:V2HI
8634             (ss_plus:HI
8635               (vec_select:HI
8636                 (match_operand:V4HI 1 "register_operand" "0")
8637                 (parallel [(const_int 0)]))
8638               (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
8639             (ss_plus:HI
8640               (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
8641               (vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
8642           (vec_concat:V2HI
8643             (ss_plus:HI
8644               (vec_select:HI
8645                 (match_operand:V4HI 2 "nonimmediate_operand" "ym")
8646                 (parallel [(const_int 0)]))
8647               (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
8648             (ss_plus:HI
8649               (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
8650               (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))))]
8651   "TARGET_SSSE3"
8652   "phaddsw\t{%2, %0|%0, %2}"
8653   [(set_attr "type" "sseiadd")
8654    (set_attr "atom_unit" "complex")
8655    (set_attr "prefix_extra" "1")
8656    (set (attr "prefix_rex") (symbol_ref "x86_extended_reg_mentioned_p (insn)"))
8657    (set_attr "mode" "DI")])
8658
8659 (define_insn "*avx_phsubwv8hi3"
8660   [(set (match_operand:V8HI 0 "register_operand" "=x")
8661         (vec_concat:V8HI
8662           (vec_concat:V4HI
8663             (vec_concat:V2HI
8664               (minus:HI
8665                 (vec_select:HI
8666                   (match_operand:V8HI 1 "register_operand" "x")
8667                   (parallel [(const_int 0)]))
8668                 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
8669               (minus:HI
8670                 (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
8671                 (vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
8672             (vec_concat:V2HI
8673               (minus:HI
8674                 (vec_select:HI (match_dup 1) (parallel [(const_int 4)]))
8675                 (vec_select:HI (match_dup 1) (parallel [(const_int 5)])))
8676               (minus:HI
8677                 (vec_select:HI (match_dup 1) (parallel [(const_int 6)]))
8678                 (vec_select:HI (match_dup 1) (parallel [(const_int 7)])))))
8679           (vec_concat:V4HI
8680             (vec_concat:V2HI
8681               (minus:HI
8682                 (vec_select:HI
8683                   (match_operand:V8HI 2 "nonimmediate_operand" "xm")
8684                   (parallel [(const_int 0)]))
8685                 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
8686               (minus:HI
8687                 (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
8688                 (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))
8689             (vec_concat:V2HI
8690               (minus:HI
8691                 (vec_select:HI (match_dup 2) (parallel [(const_int 4)]))
8692                 (vec_select:HI (match_dup 2) (parallel [(const_int 5)])))
8693               (minus:HI
8694                 (vec_select:HI (match_dup 2) (parallel [(const_int 6)]))
8695                 (vec_select:HI (match_dup 2) (parallel [(const_int 7)])))))))]
8696   "TARGET_AVX"
8697   "vphsubw\t{%2, %1, %0|%0, %1, %2}"
8698   [(set_attr "type" "sseiadd")
8699    (set_attr "prefix_extra" "1")
8700    (set_attr "prefix" "vex")
8701    (set_attr "mode" "TI")])
8702
8703 (define_insn "ssse3_phsubwv8hi3"
8704   [(set (match_operand:V8HI 0 "register_operand" "=x")
8705         (vec_concat:V8HI
8706           (vec_concat:V4HI
8707             (vec_concat:V2HI
8708               (minus:HI
8709                 (vec_select:HI
8710                   (match_operand:V8HI 1 "register_operand" "0")
8711                   (parallel [(const_int 0)]))
8712                 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
8713               (minus:HI
8714                 (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
8715                 (vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
8716             (vec_concat:V2HI
8717               (minus:HI
8718                 (vec_select:HI (match_dup 1) (parallel [(const_int 4)]))
8719                 (vec_select:HI (match_dup 1) (parallel [(const_int 5)])))
8720               (minus:HI
8721                 (vec_select:HI (match_dup 1) (parallel [(const_int 6)]))
8722                 (vec_select:HI (match_dup 1) (parallel [(const_int 7)])))))
8723           (vec_concat:V4HI
8724             (vec_concat:V2HI
8725               (minus:HI
8726                 (vec_select:HI
8727                   (match_operand:V8HI 2 "nonimmediate_operand" "xm")
8728                   (parallel [(const_int 0)]))
8729                 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
8730               (minus:HI
8731                 (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
8732                 (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))
8733             (vec_concat:V2HI
8734               (minus:HI
8735                 (vec_select:HI (match_dup 2) (parallel [(const_int 4)]))
8736                 (vec_select:HI (match_dup 2) (parallel [(const_int 5)])))
8737               (minus:HI
8738                 (vec_select:HI (match_dup 2) (parallel [(const_int 6)]))
8739                 (vec_select:HI (match_dup 2) (parallel [(const_int 7)])))))))]
8740   "TARGET_SSSE3"
8741   "phsubw\t{%2, %0|%0, %2}"
8742   [(set_attr "type" "sseiadd")
8743    (set_attr "atom_unit" "complex")
8744    (set_attr "prefix_data16" "1")
8745    (set_attr "prefix_extra" "1")
8746    (set_attr "mode" "TI")])
8747
8748 (define_insn "ssse3_phsubwv4hi3"
8749   [(set (match_operand:V4HI 0 "register_operand" "=y")
8750         (vec_concat:V4HI
8751           (vec_concat:V2HI
8752             (minus:HI
8753               (vec_select:HI
8754                 (match_operand:V4HI 1 "register_operand" "0")
8755                 (parallel [(const_int 0)]))
8756               (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
8757             (minus:HI
8758               (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
8759               (vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
8760           (vec_concat:V2HI
8761             (minus:HI
8762               (vec_select:HI
8763                 (match_operand:V4HI 2 "nonimmediate_operand" "ym")
8764                 (parallel [(const_int 0)]))
8765               (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
8766             (minus:HI
8767               (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
8768               (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))))]
8769   "TARGET_SSSE3"
8770   "phsubw\t{%2, %0|%0, %2}"
8771   [(set_attr "type" "sseiadd")
8772    (set_attr "atom_unit" "complex")
8773    (set_attr "prefix_extra" "1")
8774    (set (attr "prefix_rex") (symbol_ref "x86_extended_reg_mentioned_p (insn)"))
8775    (set_attr "mode" "DI")])
8776
8777 (define_insn "*avx_phsubdv4si3"
8778   [(set (match_operand:V4SI 0 "register_operand" "=x")
8779         (vec_concat:V4SI
8780           (vec_concat:V2SI
8781             (minus:SI
8782               (vec_select:SI
8783                 (match_operand:V4SI 1 "register_operand" "x")
8784                 (parallel [(const_int 0)]))
8785               (vec_select:SI (match_dup 1) (parallel [(const_int 1)])))
8786             (minus:SI
8787               (vec_select:SI (match_dup 1) (parallel [(const_int 2)]))
8788               (vec_select:SI (match_dup 1) (parallel [(const_int 3)]))))
8789           (vec_concat:V2SI
8790             (minus:SI
8791               (vec_select:SI
8792                 (match_operand:V4SI 2 "nonimmediate_operand" "xm")
8793                 (parallel [(const_int 0)]))
8794               (vec_select:SI (match_dup 2) (parallel [(const_int 1)])))
8795             (minus:SI
8796               (vec_select:SI (match_dup 2) (parallel [(const_int 2)]))
8797               (vec_select:SI (match_dup 2) (parallel [(const_int 3)]))))))]
8798   "TARGET_AVX"
8799   "vphsubd\t{%2, %1, %0|%0, %1, %2}"
8800   [(set_attr "type" "sseiadd")
8801    (set_attr "prefix_extra" "1")
8802    (set_attr "prefix" "vex")
8803    (set_attr "mode" "TI")])
8804
8805 (define_insn "ssse3_phsubdv4si3"
8806   [(set (match_operand:V4SI 0 "register_operand" "=x")
8807         (vec_concat:V4SI
8808           (vec_concat:V2SI
8809             (minus:SI
8810               (vec_select:SI
8811                 (match_operand:V4SI 1 "register_operand" "0")
8812                 (parallel [(const_int 0)]))
8813               (vec_select:SI (match_dup 1) (parallel [(const_int 1)])))
8814             (minus:SI
8815               (vec_select:SI (match_dup 1) (parallel [(const_int 2)]))
8816               (vec_select:SI (match_dup 1) (parallel [(const_int 3)]))))
8817           (vec_concat:V2SI
8818             (minus:SI
8819               (vec_select:SI
8820                 (match_operand:V4SI 2 "nonimmediate_operand" "xm")
8821                 (parallel [(const_int 0)]))
8822               (vec_select:SI (match_dup 2) (parallel [(const_int 1)])))
8823             (minus:SI
8824               (vec_select:SI (match_dup 2) (parallel [(const_int 2)]))
8825               (vec_select:SI (match_dup 2) (parallel [(const_int 3)]))))))]
8826   "TARGET_SSSE3"
8827   "phsubd\t{%2, %0|%0, %2}"
8828   [(set_attr "type" "sseiadd")
8829    (set_attr "atom_unit" "complex")
8830    (set_attr "prefix_data16" "1")
8831    (set_attr "prefix_extra" "1")
8832    (set_attr "mode" "TI")])
8833
8834 (define_insn "ssse3_phsubdv2si3"
8835   [(set (match_operand:V2SI 0 "register_operand" "=y")
8836         (vec_concat:V2SI
8837           (minus:SI
8838             (vec_select:SI
8839               (match_operand:V2SI 1 "register_operand" "0")
8840               (parallel [(const_int 0)]))
8841             (vec_select:SI (match_dup 1) (parallel [(const_int 1)])))
8842           (minus:SI
8843             (vec_select:SI
8844               (match_operand:V2SI 2 "nonimmediate_operand" "ym")
8845               (parallel [(const_int 0)]))
8846             (vec_select:SI (match_dup 2) (parallel [(const_int 1)])))))]
8847   "TARGET_SSSE3"
8848   "phsubd\t{%2, %0|%0, %2}"
8849   [(set_attr "type" "sseiadd")
8850    (set_attr "atom_unit" "complex")
8851    (set_attr "prefix_extra" "1")
8852    (set (attr "prefix_rex") (symbol_ref "x86_extended_reg_mentioned_p (insn)"))
8853    (set_attr "mode" "DI")])
8854
8855 (define_insn "*avx_phsubswv8hi3"
8856   [(set (match_operand:V8HI 0 "register_operand" "=x")
8857         (vec_concat:V8HI
8858           (vec_concat:V4HI
8859             (vec_concat:V2HI
8860               (ss_minus:HI
8861                 (vec_select:HI
8862                   (match_operand:V8HI 1 "register_operand" "x")
8863                   (parallel [(const_int 0)]))
8864                 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
8865               (ss_minus:HI
8866                 (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
8867                 (vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
8868             (vec_concat:V2HI
8869               (ss_minus:HI
8870                 (vec_select:HI (match_dup 1) (parallel [(const_int 4)]))
8871                 (vec_select:HI (match_dup 1) (parallel [(const_int 5)])))
8872               (ss_minus:HI
8873                 (vec_select:HI (match_dup 1) (parallel [(const_int 6)]))
8874                 (vec_select:HI (match_dup 1) (parallel [(const_int 7)])))))
8875           (vec_concat:V4HI
8876             (vec_concat:V2HI
8877               (ss_minus:HI
8878                 (vec_select:HI
8879                   (match_operand:V8HI 2 "nonimmediate_operand" "xm")
8880                   (parallel [(const_int 0)]))
8881                 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
8882               (ss_minus:HI
8883                 (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
8884                 (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))
8885             (vec_concat:V2HI
8886               (ss_minus:HI
8887                 (vec_select:HI (match_dup 2) (parallel [(const_int 4)]))
8888                 (vec_select:HI (match_dup 2) (parallel [(const_int 5)])))
8889               (ss_minus:HI
8890                 (vec_select:HI (match_dup 2) (parallel [(const_int 6)]))
8891                 (vec_select:HI (match_dup 2) (parallel [(const_int 7)])))))))]
8892   "TARGET_AVX"
8893   "vphsubsw\t{%2, %1, %0|%0, %1, %2}"
8894   [(set_attr "type" "sseiadd")
8895    (set_attr "prefix_extra" "1")
8896    (set_attr "prefix" "vex")
8897    (set_attr "mode" "TI")])
8898
8899 (define_insn "ssse3_phsubswv8hi3"
8900   [(set (match_operand:V8HI 0 "register_operand" "=x")
8901         (vec_concat:V8HI
8902           (vec_concat:V4HI
8903             (vec_concat:V2HI
8904               (ss_minus:HI
8905                 (vec_select:HI
8906                   (match_operand:V8HI 1 "register_operand" "0")
8907                   (parallel [(const_int 0)]))
8908                 (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
8909               (ss_minus:HI
8910                 (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
8911                 (vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
8912             (vec_concat:V2HI
8913               (ss_minus:HI
8914                 (vec_select:HI (match_dup 1) (parallel [(const_int 4)]))
8915                 (vec_select:HI (match_dup 1) (parallel [(const_int 5)])))
8916               (ss_minus:HI
8917                 (vec_select:HI (match_dup 1) (parallel [(const_int 6)]))
8918                 (vec_select:HI (match_dup 1) (parallel [(const_int 7)])))))
8919           (vec_concat:V4HI
8920             (vec_concat:V2HI
8921               (ss_minus:HI
8922                 (vec_select:HI
8923                   (match_operand:V8HI 2 "nonimmediate_operand" "xm")
8924                   (parallel [(const_int 0)]))
8925                 (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
8926               (ss_minus:HI
8927                 (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
8928                 (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))
8929             (vec_concat:V2HI
8930               (ss_minus:HI
8931                 (vec_select:HI (match_dup 2) (parallel [(const_int 4)]))
8932                 (vec_select:HI (match_dup 2) (parallel [(const_int 5)])))
8933               (ss_minus:HI
8934                 (vec_select:HI (match_dup 2) (parallel [(const_int 6)]))
8935                 (vec_select:HI (match_dup 2) (parallel [(const_int 7)])))))))]
8936   "TARGET_SSSE3"
8937   "phsubsw\t{%2, %0|%0, %2}"
8938   [(set_attr "type" "sseiadd")
8939    (set_attr "atom_unit" "complex")
8940    (set_attr "prefix_data16" "1")
8941    (set_attr "prefix_extra" "1")
8942    (set_attr "mode" "TI")])
8943
8944 (define_insn "ssse3_phsubswv4hi3"
8945   [(set (match_operand:V4HI 0 "register_operand" "=y")
8946         (vec_concat:V4HI
8947           (vec_concat:V2HI
8948             (ss_minus:HI
8949               (vec_select:HI
8950                 (match_operand:V4HI 1 "register_operand" "0")
8951                 (parallel [(const_int 0)]))
8952               (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
8953             (ss_minus:HI
8954               (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
8955               (vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
8956           (vec_concat:V2HI
8957             (ss_minus:HI
8958               (vec_select:HI
8959                 (match_operand:V4HI 2 "nonimmediate_operand" "ym")
8960                 (parallel [(const_int 0)]))
8961               (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
8962             (ss_minus:HI
8963               (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
8964               (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))))]
8965   "TARGET_SSSE3"
8966   "phsubsw\t{%2, %0|%0, %2}"
8967   [(set_attr "type" "sseiadd")
8968    (set_attr "atom_unit" "complex")
8969    (set_attr "prefix_extra" "1")
8970    (set (attr "prefix_rex") (symbol_ref "x86_extended_reg_mentioned_p (insn)"))
8971    (set_attr "mode" "DI")])
8972
8973 (define_insn "*avx_pmaddubsw128"
8974   [(set (match_operand:V8HI 0 "register_operand" "=x")
8975         (ss_plus:V8HI
8976           (mult:V8HI
8977             (zero_extend:V8HI
8978               (vec_select:V4QI
8979                 (match_operand:V16QI 1 "register_operand" "x")
8980                 (parallel [(const_int 0)
8981                            (const_int 2)
8982                            (const_int 4)
8983                            (const_int 6)
8984                            (const_int 8)
8985                            (const_int 10)
8986                            (const_int 12)
8987                            (const_int 14)])))
8988             (sign_extend:V8HI
8989               (vec_select:V8QI
8990                 (match_operand:V16QI 2 "nonimmediate_operand" "xm")
8991                 (parallel [(const_int 0)
8992                            (const_int 2)
8993                            (const_int 4)
8994                            (const_int 6)
8995                            (const_int 8)
8996                            (const_int 10)
8997                            (const_int 12)
8998                            (const_int 14)]))))
8999           (mult:V8HI
9000             (zero_extend:V8HI
9001               (vec_select:V16QI (match_dup 1)
9002                 (parallel [(const_int 1)
9003                            (const_int 3)
9004                            (const_int 5)
9005                            (const_int 7)
9006                            (const_int 9)
9007                            (const_int 11)
9008                            (const_int 13)
9009                            (const_int 15)])))
9010             (sign_extend:V8HI
9011               (vec_select:V16QI (match_dup 2)
9012                 (parallel [(const_int 1)
9013                            (const_int 3)
9014                            (const_int 5)
9015                            (const_int 7)
9016                            (const_int 9)
9017                            (const_int 11)
9018                            (const_int 13)
9019                            (const_int 15)]))))))]
9020   "TARGET_AVX"
9021   "vpmaddubsw\t{%2, %1, %0|%0, %1, %2}"
9022   [(set_attr "type" "sseiadd")
9023    (set_attr "prefix_extra" "1")
9024    (set_attr "prefix" "vex")
9025    (set_attr "mode" "TI")])
9026
9027 (define_insn "ssse3_pmaddubsw128"
9028   [(set (match_operand:V8HI 0 "register_operand" "=x")
9029         (ss_plus:V8HI
9030           (mult:V8HI
9031             (zero_extend:V8HI
9032               (vec_select:V4QI
9033                 (match_operand:V16QI 1 "register_operand" "0")
9034                 (parallel [(const_int 0)
9035                            (const_int 2)
9036                            (const_int 4)
9037                            (const_int 6)
9038                            (const_int 8)
9039                            (const_int 10)
9040                            (const_int 12)
9041                            (const_int 14)])))
9042             (sign_extend:V8HI
9043               (vec_select:V8QI
9044                 (match_operand:V16QI 2 "nonimmediate_operand" "xm")
9045                 (parallel [(const_int 0)
9046                            (const_int 2)
9047                            (const_int 4)
9048                            (const_int 6)
9049                            (const_int 8)
9050                            (const_int 10)
9051                            (const_int 12)
9052                            (const_int 14)]))))
9053           (mult:V8HI
9054             (zero_extend:V8HI
9055               (vec_select:V16QI (match_dup 1)
9056                 (parallel [(const_int 1)
9057                            (const_int 3)
9058                            (const_int 5)
9059                            (const_int 7)
9060                            (const_int 9)
9061                            (const_int 11)
9062                            (const_int 13)
9063                            (const_int 15)])))
9064             (sign_extend:V8HI
9065               (vec_select:V16QI (match_dup 2)
9066                 (parallel [(const_int 1)
9067                            (const_int 3)
9068                            (const_int 5)
9069                            (const_int 7)
9070                            (const_int 9)
9071                            (const_int 11)
9072                            (const_int 13)
9073                            (const_int 15)]))))))]
9074   "TARGET_SSSE3"
9075   "pmaddubsw\t{%2, %0|%0, %2}"
9076   [(set_attr "type" "sseiadd")
9077    (set_attr "atom_unit" "simul")
9078    (set_attr "prefix_data16" "1")
9079    (set_attr "prefix_extra" "1")
9080    (set_attr "mode" "TI")])
9081
9082 (define_insn "ssse3_pmaddubsw"
9083   [(set (match_operand:V4HI 0 "register_operand" "=y")
9084         (ss_plus:V4HI
9085           (mult:V4HI
9086             (zero_extend:V4HI
9087               (vec_select:V4QI
9088                 (match_operand:V8QI 1 "register_operand" "0")
9089                 (parallel [(const_int 0)
9090                            (const_int 2)
9091                            (const_int 4)
9092                            (const_int 6)])))
9093             (sign_extend:V4HI
9094               (vec_select:V4QI
9095                 (match_operand:V8QI 2 "nonimmediate_operand" "ym")
9096                 (parallel [(const_int 0)
9097                            (const_int 2)
9098                            (const_int 4)
9099                            (const_int 6)]))))
9100           (mult:V4HI
9101             (zero_extend:V4HI
9102               (vec_select:V8QI (match_dup 1)
9103                 (parallel [(const_int 1)
9104                            (const_int 3)
9105                            (const_int 5)
9106                            (const_int 7)])))
9107             (sign_extend:V4HI
9108               (vec_select:V8QI (match_dup 2)
9109                 (parallel [(const_int 1)
9110                            (const_int 3)
9111                            (const_int 5)
9112                            (const_int 7)]))))))]
9113   "TARGET_SSSE3"
9114   "pmaddubsw\t{%2, %0|%0, %2}"
9115   [(set_attr "type" "sseiadd")
9116    (set_attr "atom_unit" "simul")
9117    (set_attr "prefix_extra" "1")
9118    (set (attr "prefix_rex") (symbol_ref "x86_extended_reg_mentioned_p (insn)"))
9119    (set_attr "mode" "DI")])
9120
9121 (define_expand "ssse3_pmulhrswv8hi3"
9122   [(set (match_operand:V8HI 0 "register_operand" "")
9123         (truncate:V8HI
9124           (lshiftrt:V8SI
9125             (plus:V8SI
9126               (lshiftrt:V8SI
9127                 (mult:V8SI
9128                   (sign_extend:V8SI
9129                     (match_operand:V8HI 1 "nonimmediate_operand" ""))
9130                   (sign_extend:V8SI
9131                     (match_operand:V8HI 2 "nonimmediate_operand" "")))
9132                 (const_int 14))
9133               (const_vector:V8HI [(const_int 1) (const_int 1)
9134                                   (const_int 1) (const_int 1)
9135                                   (const_int 1) (const_int 1)
9136                                   (const_int 1) (const_int 1)]))
9137             (const_int 1))))]
9138   "TARGET_SSSE3"
9139   "ix86_fixup_binary_operands_no_copy (MULT, V8HImode, operands);")
9140
9141 (define_insn "*avx_pmulhrswv8hi3"
9142   [(set (match_operand:V8HI 0 "register_operand" "=x")
9143         (truncate:V8HI
9144           (lshiftrt:V8SI
9145             (plus:V8SI
9146               (lshiftrt:V8SI
9147                 (mult:V8SI
9148                   (sign_extend:V8SI
9149                     (match_operand:V8HI 1 "nonimmediate_operand" "%x"))
9150                   (sign_extend:V8SI
9151                     (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
9152                 (const_int 14))
9153               (const_vector:V8HI [(const_int 1) (const_int 1)
9154                                   (const_int 1) (const_int 1)
9155                                   (const_int 1) (const_int 1)
9156                                   (const_int 1) (const_int 1)]))
9157             (const_int 1))))]
9158   "TARGET_AVX && ix86_binary_operator_ok (MULT, V8HImode, operands)"
9159   "vpmulhrsw\t{%2, %1, %0|%0, %1, %2}"
9160   [(set_attr "type" "sseimul")
9161    (set_attr "prefix_extra" "1")
9162    (set_attr "prefix" "vex")
9163    (set_attr "mode" "TI")])
9164
9165 (define_insn "*ssse3_pmulhrswv8hi3"
9166   [(set (match_operand:V8HI 0 "register_operand" "=x")
9167         (truncate:V8HI
9168           (lshiftrt:V8SI
9169             (plus:V8SI
9170               (lshiftrt:V8SI
9171                 (mult:V8SI
9172                   (sign_extend:V8SI
9173                     (match_operand:V8HI 1 "nonimmediate_operand" "%0"))
9174                   (sign_extend:V8SI
9175                     (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
9176                 (const_int 14))
9177               (const_vector:V8HI [(const_int 1) (const_int 1)
9178                                   (const_int 1) (const_int 1)
9179                                   (const_int 1) (const_int 1)
9180                                   (const_int 1) (const_int 1)]))
9181             (const_int 1))))]
9182   "TARGET_SSSE3 && ix86_binary_operator_ok (MULT, V8HImode, operands)"
9183   "pmulhrsw\t{%2, %0|%0, %2}"
9184   [(set_attr "type" "sseimul")
9185    (set_attr "prefix_data16" "1")
9186    (set_attr "prefix_extra" "1")
9187    (set_attr "mode" "TI")])
9188
9189 (define_expand "ssse3_pmulhrswv4hi3"
9190   [(set (match_operand:V4HI 0 "register_operand" "")
9191         (truncate:V4HI
9192           (lshiftrt:V4SI
9193             (plus:V4SI
9194               (lshiftrt:V4SI
9195                 (mult:V4SI
9196                   (sign_extend:V4SI
9197                     (match_operand:V4HI 1 "nonimmediate_operand" ""))
9198                   (sign_extend:V4SI
9199                     (match_operand:V4HI 2 "nonimmediate_operand" "")))
9200                 (const_int 14))
9201               (const_vector:V4HI [(const_int 1) (const_int 1)
9202                                   (const_int 1) (const_int 1)]))
9203             (const_int 1))))]
9204   "TARGET_SSSE3"
9205   "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
9206
9207 (define_insn "*ssse3_pmulhrswv4hi3"
9208   [(set (match_operand:V4HI 0 "register_operand" "=y")
9209         (truncate:V4HI
9210           (lshiftrt:V4SI
9211             (plus:V4SI
9212               (lshiftrt:V4SI
9213                 (mult:V4SI
9214                   (sign_extend:V4SI
9215                     (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
9216                   (sign_extend:V4SI
9217                     (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
9218                 (const_int 14))
9219               (const_vector:V4HI [(const_int 1) (const_int 1)
9220                                   (const_int 1) (const_int 1)]))
9221             (const_int 1))))]
9222   "TARGET_SSSE3 && ix86_binary_operator_ok (MULT, V4HImode, operands)"
9223   "pmulhrsw\t{%2, %0|%0, %2}"
9224   [(set_attr "type" "sseimul")
9225    (set_attr "prefix_extra" "1")
9226    (set (attr "prefix_rex") (symbol_ref "x86_extended_reg_mentioned_p (insn)"))
9227    (set_attr "mode" "DI")])
9228
9229 (define_insn "*avx_pshufbv16qi3"
9230   [(set (match_operand:V16QI 0 "register_operand" "=x")
9231         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
9232                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
9233                       UNSPEC_PSHUFB))]
9234   "TARGET_AVX"
9235   "vpshufb\t{%2, %1, %0|%0, %1, %2}";
9236   [(set_attr "type" "sselog1")
9237    (set_attr "prefix_extra" "1")
9238    (set_attr "prefix" "vex")
9239    (set_attr "mode" "TI")])
9240
9241 (define_insn "ssse3_pshufbv16qi3"
9242   [(set (match_operand:V16QI 0 "register_operand" "=x")
9243         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "0")
9244                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
9245                       UNSPEC_PSHUFB))]
9246   "TARGET_SSSE3"
9247   "pshufb\t{%2, %0|%0, %2}";
9248   [(set_attr "type" "sselog1")
9249    (set_attr "prefix_data16" "1")
9250    (set_attr "prefix_extra" "1")
9251    (set_attr "mode" "TI")])
9252
9253 (define_insn "ssse3_pshufbv8qi3"
9254   [(set (match_operand:V8QI 0 "register_operand" "=y")
9255         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "0")
9256                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
9257                      UNSPEC_PSHUFB))]
9258   "TARGET_SSSE3"
9259   "pshufb\t{%2, %0|%0, %2}";
9260   [(set_attr "type" "sselog1")
9261    (set_attr "prefix_extra" "1")
9262    (set (attr "prefix_rex") (symbol_ref "x86_extended_reg_mentioned_p (insn)"))
9263    (set_attr "mode" "DI")])
9264
9265 (define_insn "*avx_psign<mode>3"
9266   [(set (match_operand:SSEMODE124 0 "register_operand" "=x")
9267         (unspec:SSEMODE124
9268           [(match_operand:SSEMODE124 1 "register_operand" "x")
9269            (match_operand:SSEMODE124 2 "nonimmediate_operand" "xm")]
9270           UNSPEC_PSIGN))]
9271   "TARGET_AVX"
9272   "vpsign<ssevecsize>\t{%2, %1, %0|%0, %1, %2}";
9273   [(set_attr "type" "sselog1")
9274    (set_attr "prefix_extra" "1")
9275    (set_attr "prefix" "vex")
9276    (set_attr "mode" "TI")])
9277
9278 (define_insn "ssse3_psign<mode>3"
9279   [(set (match_operand:SSEMODE124 0 "register_operand" "=x")
9280         (unspec:SSEMODE124
9281           [(match_operand:SSEMODE124 1 "register_operand" "0")
9282            (match_operand:SSEMODE124 2 "nonimmediate_operand" "xm")]
9283           UNSPEC_PSIGN))]
9284   "TARGET_SSSE3"
9285   "psign<ssevecsize>\t{%2, %0|%0, %2}";
9286   [(set_attr "type" "sselog1")
9287    (set_attr "prefix_data16" "1")
9288    (set_attr "prefix_extra" "1")
9289    (set_attr "mode" "TI")])
9290
9291 (define_insn "ssse3_psign<mode>3"
9292   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
9293         (unspec:MMXMODEI
9294           [(match_operand:MMXMODEI 1 "register_operand" "0")
9295            (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")]
9296           UNSPEC_PSIGN))]
9297   "TARGET_SSSE3"
9298   "psign<mmxvecsize>\t{%2, %0|%0, %2}";
9299   [(set_attr "type" "sselog1")
9300    (set_attr "prefix_extra" "1")
9301    (set (attr "prefix_rex") (symbol_ref "x86_extended_reg_mentioned_p (insn)"))
9302    (set_attr "mode" "DI")])
9303
9304 (define_insn "*avx_palignrti"
9305   [(set (match_operand:TI 0 "register_operand" "=x")
9306         (unspec:TI [(match_operand:TI 1 "register_operand" "x")
9307                     (match_operand:TI 2 "nonimmediate_operand" "xm")
9308                     (match_operand:SI 3 "const_0_to_255_mul_8_operand" "n")]
9309                    UNSPEC_PALIGNR))]
9310   "TARGET_AVX"
9311 {
9312   operands[3] = GEN_INT (INTVAL (operands[3]) / 8);
9313   return "vpalignr\t{%3, %2, %1, %0|%0, %1, %2, %3}";
9314 }
9315   [(set_attr "type" "sseishft")
9316    (set_attr "prefix_extra" "1")
9317    (set_attr "length_immediate" "1")
9318    (set_attr "prefix" "vex")
9319    (set_attr "mode" "TI")])
9320
9321 (define_insn "ssse3_palignrti"
9322   [(set (match_operand:TI 0 "register_operand" "=x")
9323         (unspec:TI [(match_operand:TI 1 "register_operand" "0")
9324                     (match_operand:TI 2 "nonimmediate_operand" "xm")
9325                     (match_operand:SI 3 "const_0_to_255_mul_8_operand" "n")]
9326                    UNSPEC_PALIGNR))]
9327   "TARGET_SSSE3"
9328 {
9329   operands[3] = GEN_INT (INTVAL (operands[3]) / 8);
9330   return "palignr\t{%3, %2, %0|%0, %2, %3}";
9331 }
9332   [(set_attr "type" "sseishft")
9333    (set_attr "atom_unit" "sishuf")
9334    (set_attr "prefix_data16" "1")
9335    (set_attr "prefix_extra" "1")
9336    (set_attr "length_immediate" "1")
9337    (set_attr "mode" "TI")])
9338
9339 (define_insn "ssse3_palignrdi"
9340   [(set (match_operand:DI 0 "register_operand" "=y")
9341         (unspec:DI [(match_operand:DI 1 "register_operand" "0")
9342                     (match_operand:DI 2 "nonimmediate_operand" "ym")
9343                     (match_operand:SI 3 "const_0_to_255_mul_8_operand" "n")]
9344                    UNSPEC_PALIGNR))]
9345   "TARGET_SSSE3"
9346 {
9347   operands[3] = GEN_INT (INTVAL (operands[3]) / 8);
9348   return "palignr\t{%3, %2, %0|%0, %2, %3}";
9349 }
9350   [(set_attr "type" "sseishft")
9351    (set_attr "atom_unit" "sishuf")
9352    (set_attr "prefix_extra" "1")
9353    (set_attr "length_immediate" "1")
9354    (set (attr "prefix_rex") (symbol_ref "x86_extended_reg_mentioned_p (insn)"))
9355    (set_attr "mode" "DI")])
9356
9357 (define_insn "abs<mode>2"
9358   [(set (match_operand:SSEMODE124 0 "register_operand" "=x")
9359         (abs:SSEMODE124 (match_operand:SSEMODE124 1 "nonimmediate_operand" "xm")))]
9360   "TARGET_SSSE3"
9361   "%vpabs<ssevecsize>\t{%1, %0|%0, %1}"
9362   [(set_attr "type" "sselog1")
9363    (set_attr "prefix_data16" "1")
9364    (set_attr "prefix_extra" "1")
9365    (set_attr "prefix" "maybe_vex")
9366    (set_attr "mode" "TI")])
9367
9368 (define_insn "abs<mode>2"
9369   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
9370         (abs:MMXMODEI (match_operand:MMXMODEI 1 "nonimmediate_operand" "ym")))]
9371   "TARGET_SSSE3"
9372   "pabs<mmxvecsize>\t{%1, %0|%0, %1}";
9373   [(set_attr "type" "sselog1")
9374    (set_attr "prefix_rep" "0")
9375    (set_attr "prefix_extra" "1")
9376    (set (attr "prefix_rex") (symbol_ref "x86_extended_reg_mentioned_p (insn)"))
9377    (set_attr "mode" "DI")])
9378
9379 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9380 ;;
9381 ;; AMD SSE4A instructions
9382 ;;
9383 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9384
9385 (define_insn "sse4a_movnt<mode>"
9386   [(set (match_operand:MODEF 0 "memory_operand" "=m")
9387         (unspec:MODEF
9388           [(match_operand:MODEF 1 "register_operand" "x")]
9389           UNSPEC_MOVNT))]
9390   "TARGET_SSE4A"
9391   "movnts<ssemodefsuffix>\t{%1, %0|%0, %1}"
9392   [(set_attr "type" "ssemov")
9393    (set_attr "mode" "<MODE>")])
9394
9395 (define_insn "sse4a_vmmovnt<mode>"
9396   [(set (match_operand:<ssescalarmode> 0 "memory_operand" "=m")
9397         (unspec:<ssescalarmode>
9398           [(vec_select:<ssescalarmode>
9399              (match_operand:SSEMODEF2P 1 "register_operand" "x")
9400              (parallel [(const_int 0)]))]
9401           UNSPEC_MOVNT))]
9402   "TARGET_SSE4A"
9403   "movnt<ssescalarmodesuffix>\t{%1, %0|%0, %1}"
9404   [(set_attr "type" "ssemov")
9405    (set_attr "mode" "<ssescalarmode>")])
9406
9407 (define_insn "sse4a_extrqi"
9408   [(set (match_operand:V2DI 0 "register_operand" "=x")
9409         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0")
9410                       (match_operand 2 "const_int_operand" "")
9411                       (match_operand 3 "const_int_operand" "")]
9412                      UNSPEC_EXTRQI))]
9413   "TARGET_SSE4A"
9414   "extrq\t{%3, %2, %0|%0, %2, %3}"
9415   [(set_attr "type" "sse")
9416    (set_attr "prefix_data16" "1")
9417    (set_attr "length_immediate" "2")
9418    (set_attr "mode" "TI")])
9419
9420 (define_insn "sse4a_extrq"
9421   [(set (match_operand:V2DI 0 "register_operand" "=x")
9422         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0")
9423                       (match_operand:V16QI 2 "register_operand" "x")]
9424                      UNSPEC_EXTRQ))]
9425   "TARGET_SSE4A"
9426   "extrq\t{%2, %0|%0, %2}"
9427   [(set_attr "type" "sse")
9428    (set_attr "prefix_data16" "1")
9429    (set_attr "mode" "TI")])
9430
9431 (define_insn "sse4a_insertqi"
9432   [(set (match_operand:V2DI 0 "register_operand" "=x")
9433         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0")
9434                       (match_operand:V2DI 2 "register_operand" "x")
9435                       (match_operand 3 "const_int_operand" "")
9436                       (match_operand 4 "const_int_operand" "")]
9437                      UNSPEC_INSERTQI))]
9438   "TARGET_SSE4A"
9439   "insertq\t{%4, %3, %2, %0|%0, %2, %3, %4}"
9440   [(set_attr "type" "sseins")
9441    (set_attr "prefix_data16" "0")
9442    (set_attr "prefix_rep" "1")
9443    (set_attr "length_immediate" "2")
9444    (set_attr "mode" "TI")])
9445
9446 (define_insn "sse4a_insertq"
9447   [(set (match_operand:V2DI 0 "register_operand" "=x")
9448         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0")
9449                       (match_operand:V2DI 2 "register_operand" "x")]
9450                      UNSPEC_INSERTQ))]
9451   "TARGET_SSE4A"
9452   "insertq\t{%2, %0|%0, %2}"
9453   [(set_attr "type" "sseins")
9454    (set_attr "prefix_data16" "0")
9455    (set_attr "prefix_rep" "1")
9456    (set_attr "mode" "TI")])
9457
9458 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9459 ;;
9460 ;; Intel SSE4.1 instructions
9461 ;;
9462 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9463
9464 (define_insn "avx_blend<ssemodesuffix><avxmodesuffix>"
9465   [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x")
9466         (vec_merge:AVXMODEF2P
9467           (match_operand:AVXMODEF2P 2 "nonimmediate_operand" "xm")
9468           (match_operand:AVXMODEF2P 1 "register_operand" "x")
9469           (match_operand:SI 3 "const_0_to_<blendbits>_operand" "n")))]
9470   "TARGET_AVX"
9471   "vblend<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
9472   [(set_attr "type" "ssemov")
9473    (set_attr "prefix_extra" "1")
9474    (set_attr "length_immediate" "1")
9475    (set_attr "prefix" "vex")
9476    (set_attr "mode" "<avxvecmode>")])
9477
9478 (define_insn "avx_blendv<ssemodesuffix><avxmodesuffix>"
9479   [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x")
9480         (unspec:AVXMODEF2P
9481           [(match_operand:AVXMODEF2P 1 "register_operand" "x")
9482            (match_operand:AVXMODEF2P 2 "nonimmediate_operand" "xm")
9483            (match_operand:AVXMODEF2P 3 "register_operand" "x")]
9484           UNSPEC_BLENDV))]
9485   "TARGET_AVX"
9486   "vblendv<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
9487   [(set_attr "type" "ssemov")
9488    (set_attr "prefix_extra" "1")
9489    (set_attr "length_immediate" "1")
9490    (set_attr "prefix" "vex")
9491    (set_attr "mode" "<avxvecmode>")])
9492
9493 (define_insn "sse4_1_blend<ssemodesuffix>"
9494   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
9495         (vec_merge:SSEMODEF2P
9496           (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")
9497           (match_operand:SSEMODEF2P 1 "register_operand" "0")
9498           (match_operand:SI 3 "const_0_to_<blendbits>_operand" "n")))]
9499   "TARGET_SSE4_1"
9500   "blend<ssemodesuffix>\t{%3, %2, %0|%0, %2, %3}"
9501   [(set_attr "type" "ssemov")
9502    (set_attr "prefix_data16" "1")
9503    (set_attr "prefix_extra" "1")
9504    (set_attr "length_immediate" "1")
9505    (set_attr "mode" "<MODE>")])
9506
9507 (define_insn "sse4_1_blendv<ssemodesuffix>"
9508   [(set (match_operand:SSEMODEF2P 0 "reg_not_xmm0_operand" "=x")
9509         (unspec:SSEMODEF2P
9510           [(match_operand:SSEMODEF2P 1 "reg_not_xmm0_operand" "0")
9511            (match_operand:SSEMODEF2P 2 "nonimm_not_xmm0_operand" "xm")
9512            (match_operand:SSEMODEF2P 3 "register_operand" "Yz")]
9513           UNSPEC_BLENDV))]
9514   "TARGET_SSE4_1"
9515   "blendv<ssemodesuffix>\t{%3, %2, %0|%0, %2, %3}"
9516   [(set_attr "type" "ssemov")
9517    (set_attr "prefix_data16" "1")
9518    (set_attr "prefix_extra" "1")
9519    (set_attr "mode" "<MODE>")])
9520
9521 (define_insn "avx_dp<ssemodesuffix><avxmodesuffix>"
9522   [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x")
9523         (unspec:AVXMODEF2P
9524           [(match_operand:AVXMODEF2P 1 "nonimmediate_operand" "%x")
9525            (match_operand:AVXMODEF2P 2 "nonimmediate_operand" "xm")
9526            (match_operand:SI 3 "const_0_to_255_operand" "n")]
9527           UNSPEC_DP))]
9528   "TARGET_AVX"
9529   "vdp<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
9530   [(set_attr "type" "ssemul")
9531    (set_attr "prefix" "vex")
9532    (set_attr "prefix_extra" "1")
9533    (set_attr "length_immediate" "1")
9534    (set_attr "mode" "<avxvecmode>")])
9535
9536 (define_insn "sse4_1_dp<ssemodesuffix>"
9537   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
9538         (unspec:SSEMODEF2P
9539           [(match_operand:SSEMODEF2P 1 "nonimmediate_operand" "%0")
9540            (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")
9541            (match_operand:SI 3 "const_0_to_255_operand" "n")]
9542           UNSPEC_DP))]
9543   "TARGET_SSE4_1"
9544   "dp<ssemodesuffix>\t{%3, %2, %0|%0, %2, %3}"
9545   [(set_attr "type" "ssemul")
9546    (set_attr "prefix_data16" "1")
9547    (set_attr "prefix_extra" "1")
9548    (set_attr "length_immediate" "1")
9549    (set_attr "mode" "<MODE>")])
9550
9551 (define_insn "sse4_1_movntdqa"
9552   [(set (match_operand:V2DI 0 "register_operand" "=x")
9553         (unspec:V2DI [(match_operand:V2DI 1 "memory_operand" "m")]
9554                      UNSPEC_MOVNTDQA))]
9555   "TARGET_SSE4_1"
9556   "%vmovntdqa\t{%1, %0|%0, %1}"
9557   [(set_attr "type" "ssemov")
9558    (set_attr "prefix_extra" "1")
9559    (set_attr "prefix" "maybe_vex")
9560    (set_attr "mode" "TI")])
9561
9562 (define_insn "*avx_mpsadbw"
9563   [(set (match_operand:V16QI 0 "register_operand" "=x")
9564         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
9565                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")
9566                        (match_operand:SI 3 "const_0_to_255_operand" "n")]
9567                       UNSPEC_MPSADBW))]
9568   "TARGET_AVX"
9569   "vmpsadbw\t{%3, %2, %1, %0|%0, %1, %2, %3}"
9570   [(set_attr "type" "sselog1")
9571    (set_attr "prefix" "vex")
9572    (set_attr "prefix_extra" "1")
9573    (set_attr "length_immediate" "1")
9574    (set_attr "mode" "TI")])
9575
9576 (define_insn "sse4_1_mpsadbw"
9577   [(set (match_operand:V16QI 0 "register_operand" "=x")
9578         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "0")
9579                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")
9580                        (match_operand:SI 3 "const_0_to_255_operand" "n")]
9581                       UNSPEC_MPSADBW))]
9582   "TARGET_SSE4_1"
9583   "mpsadbw\t{%3, %2, %0|%0, %2, %3}"
9584   [(set_attr "type" "sselog1")
9585    (set_attr "prefix_extra" "1")
9586    (set_attr "length_immediate" "1")
9587    (set_attr "mode" "TI")])
9588
9589 (define_insn "*avx_packusdw"
9590   [(set (match_operand:V8HI 0 "register_operand" "=x")
9591         (vec_concat:V8HI
9592           (us_truncate:V4HI
9593             (match_operand:V4SI 1 "register_operand" "x"))
9594           (us_truncate:V4HI
9595             (match_operand:V4SI 2 "nonimmediate_operand" "xm"))))]
9596   "TARGET_AVX"
9597   "vpackusdw\t{%2, %1, %0|%0, %1, %2}"
9598   [(set_attr "type" "sselog")
9599    (set_attr "prefix_extra" "1")
9600    (set_attr "prefix" "vex")
9601    (set_attr "mode" "TI")])
9602
9603 (define_insn "sse4_1_packusdw"
9604   [(set (match_operand:V8HI 0 "register_operand" "=x")
9605         (vec_concat:V8HI
9606           (us_truncate:V4HI
9607             (match_operand:V4SI 1 "register_operand" "0"))
9608           (us_truncate:V4HI
9609             (match_operand:V4SI 2 "nonimmediate_operand" "xm"))))]
9610   "TARGET_SSE4_1"
9611   "packusdw\t{%2, %0|%0, %2}"
9612   [(set_attr "type" "sselog")
9613    (set_attr "prefix_extra" "1")
9614    (set_attr "mode" "TI")])
9615
9616 (define_insn "*avx_pblendvb"
9617   [(set (match_operand:V16QI 0 "register_operand" "=x")
9618         (unspec:V16QI [(match_operand:V16QI 1 "register_operand"  "x")
9619                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")
9620                        (match_operand:V16QI 3 "register_operand" "x")]
9621                       UNSPEC_BLENDV))]
9622   "TARGET_AVX"
9623   "vpblendvb\t{%3, %2, %1, %0|%0, %1, %2, %3}"
9624   [(set_attr "type" "ssemov")
9625    (set_attr "prefix_extra" "1")
9626    (set_attr "length_immediate" "1")
9627    (set_attr "prefix" "vex")
9628    (set_attr "mode" "TI")])
9629
9630 (define_insn "sse4_1_pblendvb"
9631   [(set (match_operand:V16QI 0 "reg_not_xmm0_operand" "=x")
9632         (unspec:V16QI [(match_operand:V16QI 1 "reg_not_xmm0_operand"  "0")
9633                        (match_operand:V16QI 2 "nonimm_not_xmm0_operand" "xm")
9634                        (match_operand:V16QI 3 "register_operand" "Yz")]
9635                       UNSPEC_BLENDV))]
9636   "TARGET_SSE4_1"
9637   "pblendvb\t{%3, %2, %0|%0, %2, %3}"
9638   [(set_attr "type" "ssemov")
9639    (set_attr "prefix_extra" "1")
9640    (set_attr "mode" "TI")])
9641
9642 (define_insn "*avx_pblendw"
9643   [(set (match_operand:V8HI 0 "register_operand" "=x")
9644         (vec_merge:V8HI
9645           (match_operand:V8HI 2 "nonimmediate_operand" "xm")
9646           (match_operand:V8HI 1 "register_operand" "x")
9647           (match_operand:SI 3 "const_0_to_255_operand" "n")))]
9648   "TARGET_AVX"
9649   "vpblendw\t{%3, %2, %1, %0|%0, %1, %2, %3}"
9650   [(set_attr "type" "ssemov")
9651    (set_attr "prefix" "vex")
9652    (set_attr "prefix_extra" "1")
9653    (set_attr "length_immediate" "1")
9654    (set_attr "mode" "TI")])
9655
9656 (define_insn "sse4_1_pblendw"
9657   [(set (match_operand:V8HI 0 "register_operand" "=x")
9658         (vec_merge:V8HI
9659           (match_operand:V8HI 2 "nonimmediate_operand" "xm")
9660           (match_operand:V8HI 1 "register_operand" "0")
9661           (match_operand:SI 3 "const_0_to_255_operand" "n")))]
9662   "TARGET_SSE4_1"
9663   "pblendw\t{%3, %2, %0|%0, %2, %3}"
9664   [(set_attr "type" "ssemov")
9665    (set_attr "prefix_extra" "1")
9666    (set_attr "length_immediate" "1")
9667    (set_attr "mode" "TI")])
9668
9669 (define_insn "sse4_1_phminposuw"
9670   [(set (match_operand:V8HI 0 "register_operand" "=x")
9671         (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")]
9672                      UNSPEC_PHMINPOSUW))]
9673   "TARGET_SSE4_1"
9674   "%vphminposuw\t{%1, %0|%0, %1}"
9675   [(set_attr "type" "sselog1")
9676    (set_attr "prefix_extra" "1")
9677    (set_attr "prefix" "maybe_vex")
9678    (set_attr "mode" "TI")])
9679
9680 (define_insn "sse4_1_<code>v8qiv8hi2"
9681   [(set (match_operand:V8HI 0 "register_operand" "=x")
9682         (any_extend:V8HI
9683           (vec_select:V8QI
9684             (match_operand:V16QI 1 "nonimmediate_operand" "xm")
9685             (parallel [(const_int 0)
9686                        (const_int 1)
9687                        (const_int 2)
9688                        (const_int 3)
9689                        (const_int 4)
9690                        (const_int 5)
9691                        (const_int 6)
9692                        (const_int 7)]))))]
9693   "TARGET_SSE4_1"
9694   "%vpmov<extsuffix>bw\t{%1, %0|%0, %1}"
9695   [(set_attr "type" "ssemov")
9696    (set_attr "prefix_extra" "1")
9697    (set_attr "prefix" "maybe_vex")
9698    (set_attr "mode" "TI")])
9699
9700 (define_insn "sse4_1_<code>v4qiv4si2"
9701   [(set (match_operand:V4SI 0 "register_operand" "=x")
9702         (any_extend:V4SI
9703           (vec_select:V4QI
9704             (match_operand:V16QI 1 "nonimmediate_operand" "xm")
9705             (parallel [(const_int 0)
9706                        (const_int 1)
9707                        (const_int 2)
9708                        (const_int 3)]))))]
9709   "TARGET_SSE4_1"
9710   "%vpmov<extsuffix>bd\t{%1, %0|%0, %1}"
9711   [(set_attr "type" "ssemov")
9712    (set_attr "prefix_extra" "1")
9713    (set_attr "prefix" "maybe_vex")
9714    (set_attr "mode" "TI")])
9715
9716 (define_insn "sse4_1_<code>v4hiv4si2"
9717   [(set (match_operand:V4SI 0 "register_operand" "=x")
9718         (any_extend:V4SI
9719           (vec_select:V4HI
9720             (match_operand:V8HI 1 "nonimmediate_operand" "xm")
9721             (parallel [(const_int 0)
9722                        (const_int 1)
9723                        (const_int 2)
9724                        (const_int 3)]))))]
9725   "TARGET_SSE4_1"
9726   "%vpmov<extsuffix>wd\t{%1, %0|%0, %1}"
9727   [(set_attr "type" "ssemov")
9728    (set_attr "prefix_extra" "1")
9729    (set_attr "prefix" "maybe_vex")
9730    (set_attr "mode" "TI")])
9731
9732 (define_insn "sse4_1_<code>v2qiv2di2"
9733   [(set (match_operand:V2DI 0 "register_operand" "=x")
9734         (any_extend:V2DI
9735           (vec_select:V2QI
9736             (match_operand:V16QI 1 "nonimmediate_operand" "xm")
9737             (parallel [(const_int 0)
9738                        (const_int 1)]))))]
9739   "TARGET_SSE4_1"
9740   "%vpmov<extsuffix>bq\t{%1, %0|%0, %1}"
9741   [(set_attr "type" "ssemov")
9742    (set_attr "prefix_extra" "1")
9743    (set_attr "prefix" "maybe_vex")
9744    (set_attr "mode" "TI")])
9745
9746 (define_insn "sse4_1_<code>v2hiv2di2"
9747   [(set (match_operand:V2DI 0 "register_operand" "=x")
9748         (any_extend:V2DI
9749           (vec_select:V2HI
9750             (match_operand:V8HI 1 "nonimmediate_operand" "xm")
9751             (parallel [(const_int 0)
9752                        (const_int 1)]))))]
9753   "TARGET_SSE4_1"
9754   "%vpmov<extsuffix>wq\t{%1, %0|%0, %1}"
9755   [(set_attr "type" "ssemov")
9756    (set_attr "prefix_extra" "1")
9757    (set_attr "prefix" "maybe_vex")
9758    (set_attr "mode" "TI")])
9759
9760 (define_insn "sse4_1_<code>v2siv2di2"
9761   [(set (match_operand:V2DI 0 "register_operand" "=x")
9762         (any_extend:V2DI
9763           (vec_select:V2SI
9764             (match_operand:V4SI 1 "nonimmediate_operand" "xm")
9765             (parallel [(const_int 0)
9766                        (const_int 1)]))))]
9767   "TARGET_SSE4_1"
9768   "%vpmov<extsuffix>dq\t{%1, %0|%0, %1}"
9769   [(set_attr "type" "ssemov")
9770    (set_attr "prefix_extra" "1")
9771    (set_attr "prefix" "maybe_vex")
9772    (set_attr "mode" "TI")])
9773
9774 ;; ptestps/ptestpd are very similar to comiss and ucomiss when
9775 ;; setting FLAGS_REG. But it is not a really compare instruction.
9776 (define_insn "avx_vtest<ssemodesuffix><avxmodesuffix>"
9777   [(set (reg:CC FLAGS_REG)
9778         (unspec:CC [(match_operand:AVXMODEF2P 0 "register_operand" "x")
9779                     (match_operand:AVXMODEF2P 1 "nonimmediate_operand" "xm")]
9780                    UNSPEC_VTESTP))]
9781   "TARGET_AVX"
9782   "vtest<ssemodesuffix>\t{%1, %0|%0, %1}"
9783   [(set_attr "type" "ssecomi")
9784    (set_attr "prefix_extra" "1")
9785    (set_attr "prefix" "vex")
9786    (set_attr "mode" "<MODE>")])
9787
9788 ;; ptest is very similar to comiss and ucomiss when setting FLAGS_REG.
9789 ;; But it is not a really compare instruction.
9790 (define_insn "avx_ptest256"
9791   [(set (reg:CC FLAGS_REG)
9792         (unspec:CC [(match_operand:V4DI 0 "register_operand" "x")
9793                     (match_operand:V4DI 1 "nonimmediate_operand" "xm")]
9794                    UNSPEC_PTEST))]
9795   "TARGET_AVX"
9796   "vptest\t{%1, %0|%0, %1}"
9797   [(set_attr "type" "ssecomi")
9798    (set_attr "prefix_extra" "1")
9799    (set_attr "prefix" "vex")
9800    (set_attr "mode" "OI")])
9801
9802 (define_insn "sse4_1_ptest"
9803   [(set (reg:CC FLAGS_REG)
9804         (unspec:CC [(match_operand:V2DI 0 "register_operand" "x")
9805                     (match_operand:V2DI 1 "nonimmediate_operand" "xm")]
9806                    UNSPEC_PTEST))]
9807   "TARGET_SSE4_1"
9808   "%vptest\t{%1, %0|%0, %1}"
9809   [(set_attr "type" "ssecomi")
9810    (set_attr "prefix_extra" "1")
9811    (set_attr "prefix" "maybe_vex")
9812    (set_attr "mode" "TI")])
9813
9814 (define_insn "avx_round<ssemodesuffix>256"
9815   [(set (match_operand:AVX256MODEF2P 0 "register_operand" "=x")
9816         (unspec:AVX256MODEF2P
9817           [(match_operand:AVX256MODEF2P 1 "nonimmediate_operand" "xm")
9818            (match_operand:SI 2 "const_0_to_15_operand" "n")]
9819           UNSPEC_ROUND))]
9820   "TARGET_AVX"
9821   "vround<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
9822   [(set_attr "type" "ssecvt")
9823    (set_attr "prefix_extra" "1")
9824    (set_attr "length_immediate" "1")
9825    (set_attr "prefix" "vex")
9826    (set_attr "mode" "<MODE>")])
9827
9828 (define_insn "sse4_1_round<ssemodesuffix>"
9829   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
9830         (unspec:SSEMODEF2P
9831           [(match_operand:SSEMODEF2P 1 "nonimmediate_operand" "xm")
9832            (match_operand:SI 2 "const_0_to_15_operand" "n")]
9833           UNSPEC_ROUND))]
9834   "TARGET_ROUND"
9835   "%vround<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
9836   [(set_attr "type" "ssecvt")
9837    (set_attr "prefix_data16" "1")
9838    (set_attr "prefix_extra" "1")
9839    (set_attr "length_immediate" "1")
9840    (set_attr "prefix" "maybe_vex")
9841    (set_attr "mode" "<MODE>")])
9842
9843 (define_insn "*avx_round<ssescalarmodesuffix>"
9844   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
9845         (vec_merge:SSEMODEF2P
9846           (unspec:SSEMODEF2P
9847             [(match_operand:SSEMODEF2P 2 "register_operand" "x")
9848              (match_operand:SI 3 "const_0_to_15_operand" "n")]
9849             UNSPEC_ROUND)
9850           (match_operand:SSEMODEF2P 1 "register_operand" "x")
9851           (const_int 1)))]
9852   "TARGET_AVX"
9853   "vround<ssescalarmodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
9854   [(set_attr "type" "ssecvt")
9855    (set_attr "prefix_extra" "1")
9856    (set_attr "length_immediate" "1")
9857    (set_attr "prefix" "vex")
9858    (set_attr "mode" "<MODE>")])
9859
9860 (define_insn "sse4_1_round<ssescalarmodesuffix>"
9861   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
9862         (vec_merge:SSEMODEF2P
9863           (unspec:SSEMODEF2P
9864             [(match_operand:SSEMODEF2P 2 "register_operand" "x")
9865              (match_operand:SI 3 "const_0_to_15_operand" "n")]
9866             UNSPEC_ROUND)
9867           (match_operand:SSEMODEF2P 1 "register_operand" "0")
9868           (const_int 1)))]
9869   "TARGET_ROUND"
9870   "round<ssescalarmodesuffix>\t{%3, %2, %0|%0, %2, %3}"
9871   [(set_attr "type" "ssecvt")
9872    (set_attr "prefix_data16" "1")
9873    (set_attr "prefix_extra" "1")
9874    (set_attr "length_immediate" "1")
9875    (set_attr "mode" "<MODE>")])
9876
9877 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9878 ;;
9879 ;; Intel SSE4.2 string/text processing instructions
9880 ;;
9881 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9882
9883 (define_insn_and_split "sse4_2_pcmpestr"
9884   [(set (match_operand:SI 0 "register_operand" "=c,c")
9885         (unspec:SI
9886           [(match_operand:V16QI 2 "reg_not_xmm0_operand" "x,x")
9887            (match_operand:SI 3 "register_operand" "a,a")
9888            (match_operand:V16QI 4 "nonimm_not_xmm0_operand" "x,m")
9889            (match_operand:SI 5 "register_operand" "d,d")
9890            (match_operand:SI 6 "const_0_to_255_operand" "n,n")]
9891           UNSPEC_PCMPESTR))
9892    (set (match_operand:V16QI 1 "register_operand" "=Yz,Yz")
9893         (unspec:V16QI
9894           [(match_dup 2)
9895            (match_dup 3)
9896            (match_dup 4)
9897            (match_dup 5)
9898            (match_dup 6)]
9899           UNSPEC_PCMPESTR))
9900    (set (reg:CC FLAGS_REG)
9901         (unspec:CC
9902           [(match_dup 2)
9903            (match_dup 3)
9904            (match_dup 4)
9905            (match_dup 5)
9906            (match_dup 6)]
9907           UNSPEC_PCMPESTR))]
9908   "TARGET_SSE4_2
9909    && can_create_pseudo_p ()"
9910   "#"
9911   "&& 1"
9912   [(const_int 0)]
9913 {
9914   int ecx = !find_regno_note (curr_insn, REG_UNUSED, REGNO (operands[0]));
9915   int xmm0 = !find_regno_note (curr_insn, REG_UNUSED, REGNO (operands[1]));
9916   int flags = !find_regno_note (curr_insn, REG_UNUSED, FLAGS_REG);
9917
9918   if (ecx)
9919     emit_insn (gen_sse4_2_pcmpestri (operands[0], operands[2],
9920                                      operands[3], operands[4],
9921                                      operands[5], operands[6]));
9922   if (xmm0)
9923     emit_insn (gen_sse4_2_pcmpestrm (operands[1], operands[2],
9924                                      operands[3], operands[4],
9925                                      operands[5], operands[6]));
9926   if (flags && !(ecx || xmm0))
9927     emit_insn (gen_sse4_2_pcmpestr_cconly (NULL, NULL,
9928                                            operands[2], operands[3],
9929                                            operands[4], operands[5],
9930                                            operands[6]));
9931   DONE;
9932 }
9933   [(set_attr "type" "sselog")
9934    (set_attr "prefix_data16" "1")
9935    (set_attr "prefix_extra" "1")
9936    (set_attr "length_immediate" "1")
9937    (set_attr "memory" "none,load")
9938    (set_attr "mode" "TI")])
9939
9940 (define_insn "sse4_2_pcmpestri"
9941   [(set (match_operand:SI 0 "register_operand" "=c,c")
9942         (unspec:SI
9943           [(match_operand:V16QI 1 "register_operand" "x,x")
9944            (match_operand:SI 2 "register_operand" "a,a")
9945            (match_operand:V16QI 3 "nonimmediate_operand" "x,m")
9946            (match_operand:SI 4 "register_operand" "d,d")
9947            (match_operand:SI 5 "const_0_to_255_operand" "n,n")]
9948           UNSPEC_PCMPESTR))
9949    (set (reg:CC FLAGS_REG)
9950         (unspec:CC
9951           [(match_dup 1)
9952            (match_dup 2)
9953            (match_dup 3)
9954            (match_dup 4)
9955            (match_dup 5)]
9956           UNSPEC_PCMPESTR))]
9957   "TARGET_SSE4_2"
9958   "%vpcmpestri\t{%5, %3, %1|%1, %3, %5}"
9959   [(set_attr "type" "sselog")
9960    (set_attr "prefix_data16" "1")
9961    (set_attr "prefix_extra" "1")
9962    (set_attr "prefix" "maybe_vex")
9963    (set_attr "length_immediate" "1")
9964    (set_attr "memory" "none,load")
9965    (set_attr "mode" "TI")])
9966
9967 (define_insn "sse4_2_pcmpestrm"
9968   [(set (match_operand:V16QI 0 "register_operand" "=Yz,Yz")
9969         (unspec:V16QI
9970           [(match_operand:V16QI 1 "register_operand" "x,x")
9971            (match_operand:SI 2 "register_operand" "a,a")
9972            (match_operand:V16QI 3 "nonimmediate_operand" "x,m")
9973            (match_operand:SI 4 "register_operand" "d,d")
9974            (match_operand:SI 5 "const_0_to_255_operand" "n,n")]
9975           UNSPEC_PCMPESTR))
9976    (set (reg:CC FLAGS_REG)
9977         (unspec:CC
9978           [(match_dup 1)
9979            (match_dup 2)
9980            (match_dup 3)
9981            (match_dup 4)
9982            (match_dup 5)]
9983           UNSPEC_PCMPESTR))]
9984   "TARGET_SSE4_2"
9985   "%vpcmpestrm\t{%5, %3, %1|%1, %3, %5}"
9986   [(set_attr "type" "sselog")
9987    (set_attr "prefix_data16" "1")
9988    (set_attr "prefix_extra" "1")
9989    (set_attr "length_immediate" "1")
9990    (set_attr "prefix" "maybe_vex")
9991    (set_attr "memory" "none,load")
9992    (set_attr "mode" "TI")])
9993
9994 (define_insn "sse4_2_pcmpestr_cconly"
9995   [(set (reg:CC FLAGS_REG)
9996         (unspec:CC
9997           [(match_operand:V16QI 2 "register_operand" "x,x,x,x")
9998            (match_operand:SI 3 "register_operand" "a,a,a,a")
9999            (match_operand:V16QI 4 "nonimmediate_operand" "x,m,x,m")
10000            (match_operand:SI 5 "register_operand" "d,d,d,d")
10001            (match_operand:SI 6 "const_0_to_255_operand" "n,n,n,n")]
10002           UNSPEC_PCMPESTR))
10003    (clobber (match_scratch:V16QI 0 "=Yz,Yz,X,X"))
10004    (clobber (match_scratch:SI    1 "= X, X,c,c"))]
10005   "TARGET_SSE4_2"
10006   "@
10007    %vpcmpestrm\t{%6, %4, %2|%2, %4, %6}
10008    %vpcmpestrm\t{%6, %4, %2|%2, %4, %6}
10009    %vpcmpestri\t{%6, %4, %2|%2, %4, %6}
10010    %vpcmpestri\t{%6, %4, %2|%2, %4, %6}"
10011   [(set_attr "type" "sselog")
10012    (set_attr "prefix_data16" "1")
10013    (set_attr "prefix_extra" "1")
10014    (set_attr "length_immediate" "1")
10015    (set_attr "memory" "none,load,none,load")
10016    (set_attr "prefix" "maybe_vex")
10017    (set_attr "mode" "TI")])
10018
10019 (define_insn_and_split "sse4_2_pcmpistr"
10020   [(set (match_operand:SI 0 "register_operand" "=c,c")
10021         (unspec:SI
10022           [(match_operand:V16QI 2 "reg_not_xmm0_operand" "x,x")
10023            (match_operand:V16QI 3 "nonimm_not_xmm0_operand" "x,m")
10024            (match_operand:SI 4 "const_0_to_255_operand" "n,n")]
10025           UNSPEC_PCMPISTR))
10026    (set (match_operand:V16QI 1 "register_operand" "=Yz,Yz")
10027         (unspec:V16QI
10028           [(match_dup 2)
10029            (match_dup 3)
10030            (match_dup 4)]
10031           UNSPEC_PCMPISTR))
10032    (set (reg:CC FLAGS_REG)
10033         (unspec:CC
10034           [(match_dup 2)
10035            (match_dup 3)
10036            (match_dup 4)]
10037           UNSPEC_PCMPISTR))]
10038   "TARGET_SSE4_2
10039    && can_create_pseudo_p ()"
10040   "#"
10041   "&& 1"
10042   [(const_int 0)]
10043 {
10044   int ecx = !find_regno_note (curr_insn, REG_UNUSED, REGNO (operands[0]));
10045   int xmm0 = !find_regno_note (curr_insn, REG_UNUSED, REGNO (operands[1]));
10046   int flags = !find_regno_note (curr_insn, REG_UNUSED, FLAGS_REG);
10047
10048   if (ecx)
10049     emit_insn (gen_sse4_2_pcmpistri (operands[0], operands[2],
10050                                      operands[3], operands[4]));
10051   if (xmm0)
10052     emit_insn (gen_sse4_2_pcmpistrm (operands[1], operands[2],
10053                                      operands[3], operands[4]));
10054   if (flags && !(ecx || xmm0))
10055     emit_insn (gen_sse4_2_pcmpistr_cconly (NULL, NULL,
10056                                            operands[2], operands[3],
10057                                            operands[4]));
10058   DONE;
10059 }
10060   [(set_attr "type" "sselog")
10061    (set_attr "prefix_data16" "1")
10062    (set_attr "prefix_extra" "1")
10063    (set_attr "length_immediate" "1")
10064    (set_attr "memory" "none,load")
10065    (set_attr "mode" "TI")])
10066
10067 (define_insn "sse4_2_pcmpistri"
10068   [(set (match_operand:SI 0 "register_operand" "=c,c")
10069         (unspec:SI
10070           [(match_operand:V16QI 1 "register_operand" "x,x")
10071            (match_operand:V16QI 2 "nonimmediate_operand" "x,m")
10072            (match_operand:SI 3 "const_0_to_255_operand" "n,n")]
10073           UNSPEC_PCMPISTR))
10074    (set (reg:CC FLAGS_REG)
10075         (unspec:CC
10076           [(match_dup 1)
10077            (match_dup 2)
10078            (match_dup 3)]
10079           UNSPEC_PCMPISTR))]
10080   "TARGET_SSE4_2"
10081   "%vpcmpistri\t{%3, %2, %1|%1, %2, %3}"
10082   [(set_attr "type" "sselog")
10083    (set_attr "prefix_data16" "1")
10084    (set_attr "prefix_extra" "1")
10085    (set_attr "length_immediate" "1")
10086    (set_attr "prefix" "maybe_vex")
10087    (set_attr "memory" "none,load")
10088    (set_attr "mode" "TI")])
10089
10090 (define_insn "sse4_2_pcmpistrm"
10091   [(set (match_operand:V16QI 0 "register_operand" "=Yz,Yz")
10092         (unspec:V16QI
10093           [(match_operand:V16QI 1 "register_operand" "x,x")
10094            (match_operand:V16QI 2 "nonimmediate_operand" "x,m")
10095            (match_operand:SI 3 "const_0_to_255_operand" "n,n")]
10096           UNSPEC_PCMPISTR))
10097    (set (reg:CC FLAGS_REG)
10098         (unspec:CC
10099           [(match_dup 1)
10100            (match_dup 2)
10101            (match_dup 3)]
10102           UNSPEC_PCMPISTR))]
10103   "TARGET_SSE4_2"
10104   "%vpcmpistrm\t{%3, %2, %1|%1, %2, %3}"
10105   [(set_attr "type" "sselog")
10106    (set_attr "prefix_data16" "1")
10107    (set_attr "prefix_extra" "1")
10108    (set_attr "length_immediate" "1")
10109    (set_attr "prefix" "maybe_vex")
10110    (set_attr "memory" "none,load")
10111    (set_attr "mode" "TI")])
10112
10113 (define_insn "sse4_2_pcmpistr_cconly"
10114   [(set (reg:CC FLAGS_REG)
10115         (unspec:CC
10116           [(match_operand:V16QI 2 "register_operand" "x,x,x,x")
10117            (match_operand:V16QI 3 "nonimmediate_operand" "x,m,x,m")
10118            (match_operand:SI 4 "const_0_to_255_operand" "n,n,n,n")]
10119           UNSPEC_PCMPISTR))
10120    (clobber (match_scratch:V16QI 0 "=Yz,Yz,X,X"))
10121    (clobber (match_scratch:SI    1 "= X, X,c,c"))]
10122   "TARGET_SSE4_2"
10123   "@
10124    %vpcmpistrm\t{%4, %3, %2|%2, %3, %4}
10125    %vpcmpistrm\t{%4, %3, %2|%2, %3, %4}
10126    %vpcmpistri\t{%4, %3, %2|%2, %3, %4}
10127    %vpcmpistri\t{%4, %3, %2|%2, %3, %4}"
10128   [(set_attr "type" "sselog")
10129    (set_attr "prefix_data16" "1")
10130    (set_attr "prefix_extra" "1")
10131    (set_attr "length_immediate" "1")
10132    (set_attr "memory" "none,load,none,load")
10133    (set_attr "prefix" "maybe_vex")
10134    (set_attr "mode" "TI")])
10135
10136 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
10137 ;;
10138 ;; XOP instructions
10139 ;;
10140 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
10141
10142 ;; XOP parallel integer multiply/add instructions.
10143 ;; Note the XOP multiply/add instructions
10144 ;;     a[i] = b[i] * c[i] + d[i];
10145 ;; do not allow the value being added to be a memory operation.
10146 (define_insn "xop_pmacsww"
10147   [(set (match_operand:V8HI 0 "register_operand" "=x")
10148         (plus:V8HI
10149          (mult:V8HI
10150           (match_operand:V8HI 1 "nonimmediate_operand" "%x")
10151           (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
10152          (match_operand:V8HI 3 "nonimmediate_operand" "x")))]
10153   "TARGET_XOP"
10154   "vpmacsww\t{%3, %2, %1, %0|%0, %1, %2, %3}"
10155   [(set_attr "type" "ssemuladd")
10156    (set_attr "mode" "TI")])
10157
10158 (define_insn "xop_pmacssww"
10159   [(set (match_operand:V8HI 0 "register_operand" "=x")
10160         (ss_plus:V8HI
10161          (mult:V8HI (match_operand:V8HI 1 "nonimmediate_operand" "%x")
10162                     (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
10163          (match_operand:V8HI 3 "nonimmediate_operand" "x")))]
10164   "TARGET_XOP"
10165   "vpmacssww\t{%3, %2, %1, %0|%0, %1, %2, %3}"
10166   [(set_attr "type" "ssemuladd")
10167    (set_attr "mode" "TI")])
10168
10169 (define_insn "xop_pmacsdd"
10170   [(set (match_operand:V4SI 0 "register_operand" "=x")
10171         (plus:V4SI
10172          (mult:V4SI
10173           (match_operand:V4SI 1 "nonimmediate_operand" "%x")
10174           (match_operand:V4SI 2 "nonimmediate_operand" "xm"))
10175          (match_operand:V4SI 3 "nonimmediate_operand" "x")))]
10176   "TARGET_XOP"
10177   "vpmacsdd\t{%3, %2, %1, %0|%0, %1, %2, %3}"
10178   [(set_attr "type" "ssemuladd")
10179    (set_attr "mode" "TI")])
10180
10181 (define_insn "xop_pmacssdd"
10182   [(set (match_operand:V4SI 0 "register_operand" "=x")
10183         (ss_plus:V4SI
10184          (mult:V4SI (match_operand:V4SI 1 "nonimmediate_operand" "%x")
10185                     (match_operand:V4SI 2 "nonimmediate_operand" "xm"))
10186          (match_operand:V4SI 3 "nonimmediate_operand" "x")))]
10187   "TARGET_XOP"
10188   "vpmacssdd\t{%3, %2, %1, %0|%0, %1, %2, %3}"
10189   [(set_attr "type" "ssemuladd")
10190    (set_attr "mode" "TI")])
10191
10192 (define_insn "xop_pmacssdql"
10193   [(set (match_operand:V2DI 0 "register_operand" "=x")
10194         (ss_plus:V2DI
10195          (mult:V2DI
10196           (sign_extend:V2DI
10197            (vec_select:V2SI
10198             (match_operand:V4SI 1 "nonimmediate_operand" "%x")
10199             (parallel [(const_int 1)
10200                        (const_int 3)])))
10201           (vec_select:V2SI
10202            (match_operand:V4SI 2 "nonimmediate_operand" "xm")
10203            (parallel [(const_int 1)
10204                       (const_int 3)])))
10205          (match_operand:V2DI 3 "nonimmediate_operand" "x")))]
10206   "TARGET_XOP"
10207   "vpmacssdql\t{%3, %2, %1, %0|%0, %1, %2, %3}"
10208   [(set_attr "type" "ssemuladd")
10209    (set_attr "mode" "TI")])
10210
10211 (define_insn "xop_pmacssdqh"
10212   [(set (match_operand:V2DI 0 "register_operand" "=x")
10213         (ss_plus:V2DI
10214          (mult:V2DI
10215           (sign_extend:V2DI
10216            (vec_select:V2SI
10217             (match_operand:V4SI 1 "nonimmediate_operand" "%x")
10218             (parallel [(const_int 0)
10219                        (const_int 2)])))
10220           (sign_extend:V2DI
10221            (vec_select:V2SI
10222             (match_operand:V4SI 2 "nonimmediate_operand" "xm")
10223             (parallel [(const_int 0)
10224                        (const_int 2)]))))
10225          (match_operand:V2DI 3 "nonimmediate_operand" "x")))]
10226   "TARGET_XOP"
10227   "vpmacssdqh\t{%3, %2, %1, %0|%0, %1, %2, %3}"
10228   [(set_attr "type" "ssemuladd")
10229    (set_attr "mode" "TI")])
10230
10231 (define_insn "xop_pmacsdql"
10232   [(set (match_operand:V2DI 0 "register_operand" "=x")
10233         (plus:V2DI
10234          (mult:V2DI
10235           (sign_extend:V2DI
10236            (vec_select:V2SI
10237             (match_operand:V4SI 1 "nonimmediate_operand" "%x")
10238             (parallel [(const_int 1)
10239                        (const_int 3)])))
10240           (sign_extend:V2DI
10241            (vec_select:V2SI
10242             (match_operand:V4SI 2 "nonimmediate_operand" "xm")
10243             (parallel [(const_int 1)
10244                        (const_int 3)]))))
10245          (match_operand:V2DI 3 "nonimmediate_operand" "x")))]
10246   "TARGET_XOP"
10247   "vpmacsdql\t{%3, %2, %1, %0|%0, %1, %2, %3}"
10248   [(set_attr "type" "ssemuladd")
10249    (set_attr "mode" "TI")])
10250
10251 ;; We don't have a straight 32-bit parallel multiply and extend on XOP, so
10252 ;; fake it with a multiply/add.  In general, we expect the define_split to
10253 ;; occur before register allocation, so we have to handle the corner case where
10254 ;; the target is the same as operands 1/2
10255 (define_insn_and_split "xop_mulv2div2di3_low"
10256   [(set (match_operand:V2DI 0 "register_operand" "=&x")
10257         (mult:V2DI
10258           (sign_extend:V2DI
10259             (vec_select:V2SI
10260               (match_operand:V4SI 1 "register_operand" "%x")
10261               (parallel [(const_int 1)
10262                          (const_int 3)])))
10263           (sign_extend:V2DI
10264             (vec_select:V2SI
10265               (match_operand:V4SI 2 "nonimmediate_operand" "xm")
10266               (parallel [(const_int 1)
10267                          (const_int 3)])))))]
10268   "TARGET_XOP"
10269   "#"
10270   "&& reload_completed"
10271   [(set (match_dup 0)
10272         (match_dup 3))
10273    (set (match_dup 0)
10274         (plus:V2DI
10275          (mult:V2DI
10276           (sign_extend:V2DI
10277            (vec_select:V2SI
10278             (match_dup 1)
10279             (parallel [(const_int 1)
10280                        (const_int 3)])))
10281           (sign_extend:V2DI
10282            (vec_select:V2SI
10283             (match_dup 2)
10284             (parallel [(const_int 1)
10285                        (const_int 3)]))))
10286          (match_dup 0)))]
10287 {
10288   operands[3] = CONST0_RTX (V2DImode);
10289 }
10290   [(set_attr "type" "ssemul")
10291    (set_attr "mode" "TI")])
10292
10293 (define_insn "xop_pmacsdqh"
10294   [(set (match_operand:V2DI 0 "register_operand" "=x")
10295         (plus:V2DI
10296          (mult:V2DI
10297           (sign_extend:V2DI
10298            (vec_select:V2SI
10299             (match_operand:V4SI 1 "nonimmediate_operand" "%x")
10300             (parallel [(const_int 0)
10301                        (const_int 2)])))
10302           (sign_extend:V2DI
10303            (vec_select:V2SI
10304             (match_operand:V4SI 2 "nonimmediate_operand" "xm")
10305             (parallel [(const_int 0)
10306                        (const_int 2)]))))
10307          (match_operand:V2DI 3 "nonimmediate_operand" "x")))]
10308   "TARGET_XOP"
10309   "vpmacsdqh\t{%3, %2, %1, %0|%0, %1, %2, %3}"
10310   [(set_attr "type" "ssemuladd")
10311    (set_attr "mode" "TI")])
10312
10313 ;; We don't have a straight 32-bit parallel multiply and extend on XOP, so
10314 ;; fake it with a multiply/add.  In general, we expect the define_split to
10315 ;; occur before register allocation, so we have to handle the corner case where
10316 ;; the target is the same as either operands[1] or operands[2]
10317 (define_insn_and_split "xop_mulv2div2di3_high"
10318   [(set (match_operand:V2DI 0 "register_operand" "=&x")
10319         (mult:V2DI
10320           (sign_extend:V2DI
10321             (vec_select:V2SI
10322               (match_operand:V4SI 1 "register_operand" "%x")
10323               (parallel [(const_int 0)
10324                          (const_int 2)])))
10325           (sign_extend:V2DI
10326             (vec_select:V2SI
10327               (match_operand:V4SI 2 "nonimmediate_operand" "xm")
10328               (parallel [(const_int 0)
10329                          (const_int 2)])))))]
10330   "TARGET_XOP"
10331   "#"
10332   "&& reload_completed"
10333   [(set (match_dup 0)
10334         (match_dup 3))
10335    (set (match_dup 0)
10336         (plus:V2DI
10337          (mult:V2DI
10338           (sign_extend:V2DI
10339            (vec_select:V2SI
10340             (match_dup 1)
10341             (parallel [(const_int 0)
10342                        (const_int 2)])))
10343           (sign_extend:V2DI
10344            (vec_select:V2SI
10345             (match_dup 2)
10346             (parallel [(const_int 0)
10347                        (const_int 2)]))))
10348          (match_dup 0)))]
10349 {
10350   operands[3] = CONST0_RTX (V2DImode);
10351 }
10352   [(set_attr "type" "ssemul")
10353    (set_attr "mode" "TI")])
10354
10355 ;; XOP parallel integer multiply/add instructions for the intrinisics
10356 (define_insn "xop_pmacsswd"
10357   [(set (match_operand:V4SI 0 "register_operand" "=x")
10358         (ss_plus:V4SI
10359          (mult:V4SI
10360           (sign_extend:V4SI
10361            (vec_select:V4HI
10362             (match_operand:V8HI 1 "nonimmediate_operand" "%x")
10363             (parallel [(const_int 1)
10364                        (const_int 3)
10365                        (const_int 5)
10366                        (const_int 7)])))
10367           (sign_extend:V4SI
10368            (vec_select:V4HI
10369             (match_operand:V8HI 2 "nonimmediate_operand" "xm")
10370             (parallel [(const_int 1)
10371                        (const_int 3)
10372                        (const_int 5)
10373                        (const_int 7)]))))
10374          (match_operand:V4SI 3 "nonimmediate_operand" "x")))]
10375   "TARGET_XOP"
10376   "vpmacsswd\t{%3, %2, %1, %0|%0, %1, %2, %3}"
10377   [(set_attr "type" "ssemuladd")
10378    (set_attr "mode" "TI")])
10379
10380 (define_insn "xop_pmacswd"
10381   [(set (match_operand:V4SI 0 "register_operand" "=x")
10382         (plus:V4SI
10383          (mult:V4SI
10384           (sign_extend:V4SI
10385            (vec_select:V4HI
10386             (match_operand:V8HI 1 "nonimmediate_operand" "%x")
10387             (parallel [(const_int 1)
10388                        (const_int 3)
10389                        (const_int 5)
10390                        (const_int 7)])))
10391           (sign_extend:V4SI
10392            (vec_select:V4HI
10393             (match_operand:V8HI 2 "nonimmediate_operand" "xm")
10394             (parallel [(const_int 1)
10395                        (const_int 3)
10396                        (const_int 5)
10397                        (const_int 7)]))))
10398          (match_operand:V4SI 3 "nonimmediate_operand" "x")))]
10399   "TARGET_XOP"
10400   "vpmacswd\t{%3, %2, %1, %0|%0, %1, %2, %3}"
10401   [(set_attr "type" "ssemuladd")
10402    (set_attr "mode" "TI")])
10403
10404 (define_insn "xop_pmadcsswd"
10405   [(set (match_operand:V4SI 0 "register_operand" "=x")
10406         (ss_plus:V4SI
10407          (plus:V4SI
10408           (mult:V4SI
10409            (sign_extend:V4SI
10410             (vec_select:V4HI
10411              (match_operand:V8HI 1 "nonimmediate_operand" "%x")
10412              (parallel [(const_int 0)
10413                         (const_int 2)
10414                         (const_int 4)
10415                         (const_int 6)])))
10416            (sign_extend:V4SI
10417             (vec_select:V4HI
10418              (match_operand:V8HI 2 "nonimmediate_operand" "xm")
10419              (parallel [(const_int 0)
10420                         (const_int 2)
10421                         (const_int 4)
10422                         (const_int 6)]))))
10423           (mult:V4SI
10424            (sign_extend:V4SI
10425             (vec_select:V4HI
10426              (match_dup 1)
10427              (parallel [(const_int 1)
10428                         (const_int 3)
10429                         (const_int 5)
10430                         (const_int 7)])))
10431            (sign_extend:V4SI
10432             (vec_select:V4HI
10433              (match_dup 2)
10434              (parallel [(const_int 1)
10435                         (const_int 3)
10436                         (const_int 5)
10437                         (const_int 7)])))))
10438          (match_operand:V4SI 3 "nonimmediate_operand" "x")))]
10439   "TARGET_XOP"
10440   "vpmadcsswd\t{%3, %2, %1, %0|%0, %1, %2, %3}"
10441   [(set_attr "type" "ssemuladd")
10442    (set_attr "mode" "TI")])
10443
10444 (define_insn "xop_pmadcswd"
10445   [(set (match_operand:V4SI 0 "register_operand" "=x")
10446         (plus:V4SI
10447          (plus:V4SI
10448           (mult:V4SI
10449            (sign_extend:V4SI
10450             (vec_select:V4HI
10451              (match_operand:V8HI 1 "nonimmediate_operand" "%x")
10452              (parallel [(const_int 0)
10453                         (const_int 2)
10454                         (const_int 4)
10455                         (const_int 6)])))
10456            (sign_extend:V4SI
10457             (vec_select:V4HI
10458              (match_operand:V8HI 2 "nonimmediate_operand" "xm")
10459              (parallel [(const_int 0)
10460                         (const_int 2)
10461                         (const_int 4)
10462                         (const_int 6)]))))
10463           (mult:V4SI
10464            (sign_extend:V4SI
10465             (vec_select:V4HI
10466              (match_dup 1)
10467              (parallel [(const_int 1)
10468                         (const_int 3)
10469                         (const_int 5)
10470                         (const_int 7)])))
10471            (sign_extend:V4SI
10472             (vec_select:V4HI
10473              (match_dup 2)
10474              (parallel [(const_int 1)
10475                         (const_int 3)
10476                         (const_int 5)
10477                         (const_int 7)])))))
10478          (match_operand:V4SI 3 "nonimmediate_operand" "x")))]
10479   "TARGET_XOP"
10480   "vpmadcswd\t{%3, %2, %1, %0|%0, %1, %2, %3}"
10481   [(set_attr "type" "ssemuladd")
10482    (set_attr "mode" "TI")])
10483
10484 ;; XOP parallel XMM conditional moves
10485 (define_insn "xop_pcmov_<mode>"
10486   [(set (match_operand:SSEMODE 0 "register_operand" "=x,x")
10487         (if_then_else:SSEMODE
10488           (match_operand:SSEMODE 3 "nonimmediate_operand" "x,m")
10489           (match_operand:SSEMODE 1 "vector_move_operand" "x,x")
10490           (match_operand:SSEMODE 2 "vector_move_operand" "xm,x")))]
10491   "TARGET_XOP"
10492   "vpcmov\t{%3, %2, %1, %0|%0, %1, %2, %3}"
10493   [(set_attr "type" "sse4arg")])
10494
10495 (define_insn "xop_pcmov_<mode>256"
10496   [(set (match_operand:AVX256MODE 0 "register_operand" "=x,x")
10497         (if_then_else:AVX256MODE
10498           (match_operand:AVX256MODE 3 "nonimmediate_operand" "x,m")
10499           (match_operand:AVX256MODE 1 "vector_move_operand" "x,x")
10500           (match_operand:AVX256MODE 2 "vector_move_operand" "xm,x")))]
10501   "TARGET_XOP"
10502   "vpcmov\t{%3, %2, %1, %0|%0, %1, %2, %3}"
10503   [(set_attr "type" "sse4arg")])
10504
10505 ;; XOP horizontal add/subtract instructions
10506 (define_insn "xop_phaddbw"
10507   [(set (match_operand:V8HI 0 "register_operand" "=x")
10508         (plus:V8HI
10509          (sign_extend:V8HI
10510           (vec_select:V8QI
10511            (match_operand:V16QI 1 "nonimmediate_operand" "xm")
10512            (parallel [(const_int 0)
10513                       (const_int 2)
10514                       (const_int 4)
10515                       (const_int 6)
10516                       (const_int 8)
10517                       (const_int 10)
10518                       (const_int 12)
10519                       (const_int 14)])))
10520          (sign_extend:V8HI
10521           (vec_select:V8QI
10522            (match_dup 1)
10523            (parallel [(const_int 1)
10524                       (const_int 3)
10525                       (const_int 5)
10526                       (const_int 7)
10527                       (const_int 9)
10528                       (const_int 11)
10529                       (const_int 13)
10530                       (const_int 15)])))))]
10531   "TARGET_XOP"
10532   "vphaddbw\t{%1, %0|%0, %1}"
10533   [(set_attr "type" "sseiadd1")])
10534
10535 (define_insn "xop_phaddbd"
10536   [(set (match_operand:V4SI 0 "register_operand" "=x")
10537         (plus:V4SI
10538          (plus:V4SI
10539           (sign_extend:V4SI
10540            (vec_select:V4QI
10541             (match_operand:V16QI 1 "nonimmediate_operand" "xm")
10542             (parallel [(const_int 0)
10543                        (const_int 4)
10544                        (const_int 8)
10545                        (const_int 12)])))
10546           (sign_extend:V4SI
10547            (vec_select:V4QI
10548             (match_dup 1)
10549             (parallel [(const_int 1)
10550                        (const_int 5)
10551                        (const_int 9)
10552                        (const_int 13)]))))
10553          (plus:V4SI
10554           (sign_extend:V4SI
10555            (vec_select:V4QI
10556             (match_dup 1)
10557             (parallel [(const_int 2)
10558                        (const_int 6)
10559                        (const_int 10)
10560                        (const_int 14)])))
10561           (sign_extend:V4SI
10562            (vec_select:V4QI
10563             (match_dup 1)
10564             (parallel [(const_int 3)
10565                        (const_int 7)
10566                        (const_int 11)
10567                        (const_int 15)]))))))]
10568   "TARGET_XOP"
10569   "vphaddbd\t{%1, %0|%0, %1}"
10570   [(set_attr "type" "sseiadd1")])
10571
10572 (define_insn "xop_phaddbq"
10573   [(set (match_operand:V2DI 0 "register_operand" "=x")
10574         (plus:V2DI
10575          (plus:V2DI
10576           (plus:V2DI
10577            (sign_extend:V2DI
10578             (vec_select:V2QI
10579              (match_operand:V16QI 1 "nonimmediate_operand" "xm")
10580              (parallel [(const_int 0)
10581                         (const_int 4)])))
10582            (sign_extend:V2DI
10583             (vec_select:V2QI
10584              (match_dup 1)
10585              (parallel [(const_int 1)
10586                         (const_int 5)]))))
10587           (plus:V2DI
10588            (sign_extend:V2DI
10589             (vec_select:V2QI
10590              (match_dup 1)
10591              (parallel [(const_int 2)
10592                         (const_int 6)])))
10593            (sign_extend:V2DI
10594             (vec_select:V2QI
10595              (match_dup 1)
10596              (parallel [(const_int 3)
10597                         (const_int 7)])))))
10598          (plus:V2DI
10599           (plus:V2DI
10600            (sign_extend:V2DI
10601             (vec_select:V2QI
10602              (match_dup 1)
10603              (parallel [(const_int 8)
10604                         (const_int 12)])))
10605            (sign_extend:V2DI
10606             (vec_select:V2QI
10607              (match_dup 1)
10608              (parallel [(const_int 9)
10609                         (const_int 13)]))))
10610           (plus:V2DI
10611            (sign_extend:V2DI
10612             (vec_select:V2QI
10613              (match_dup 1)
10614              (parallel [(const_int 10)
10615                         (const_int 14)])))
10616            (sign_extend:V2DI
10617             (vec_select:V2QI
10618              (match_dup 1)
10619              (parallel [(const_int 11)
10620                         (const_int 15)])))))))]
10621   "TARGET_XOP"
10622   "vphaddbq\t{%1, %0|%0, %1}"
10623   [(set_attr "type" "sseiadd1")])
10624
10625 (define_insn "xop_phaddwd"
10626   [(set (match_operand:V4SI 0 "register_operand" "=x")
10627         (plus:V4SI
10628          (sign_extend:V4SI
10629           (vec_select:V4HI
10630            (match_operand:V8HI 1 "nonimmediate_operand" "xm")
10631            (parallel [(const_int 0)
10632                       (const_int 2)
10633                       (const_int 4)
10634                       (const_int 6)])))
10635          (sign_extend:V4SI
10636           (vec_select:V4HI
10637            (match_dup 1)
10638            (parallel [(const_int 1)
10639                       (const_int 3)
10640                       (const_int 5)
10641                       (const_int 7)])))))]
10642   "TARGET_XOP"
10643   "vphaddwd\t{%1, %0|%0, %1}"
10644   [(set_attr "type" "sseiadd1")])
10645
10646 (define_insn "xop_phaddwq"
10647   [(set (match_operand:V2DI 0 "register_operand" "=x")
10648         (plus:V2DI
10649          (plus:V2DI
10650           (sign_extend:V2DI
10651            (vec_select:V2HI
10652             (match_operand:V8HI 1 "nonimmediate_operand" "xm")
10653             (parallel [(const_int 0)
10654                        (const_int 4)])))
10655           (sign_extend:V2DI
10656            (vec_select:V2HI
10657             (match_dup 1)
10658             (parallel [(const_int 1)
10659                        (const_int 5)]))))
10660          (plus:V2DI
10661           (sign_extend:V2DI
10662            (vec_select:V2HI
10663             (match_dup 1)
10664             (parallel [(const_int 2)
10665                        (const_int 6)])))
10666           (sign_extend:V2DI
10667            (vec_select:V2HI
10668             (match_dup 1)
10669             (parallel [(const_int 3)
10670                        (const_int 7)]))))))]
10671   "TARGET_XOP"
10672   "vphaddwq\t{%1, %0|%0, %1}"
10673   [(set_attr "type" "sseiadd1")])
10674
10675 (define_insn "xop_phadddq"
10676   [(set (match_operand:V2DI 0 "register_operand" "=x")
10677         (plus:V2DI
10678          (sign_extend:V2DI
10679           (vec_select:V2SI
10680            (match_operand:V4SI 1 "nonimmediate_operand" "xm")
10681            (parallel [(const_int 0)
10682                       (const_int 2)])))
10683          (sign_extend:V2DI
10684           (vec_select:V2SI
10685            (match_dup 1)
10686            (parallel [(const_int 1)
10687                       (const_int 3)])))))]
10688   "TARGET_XOP"
10689   "vphadddq\t{%1, %0|%0, %1}"
10690   [(set_attr "type" "sseiadd1")])
10691
10692 (define_insn "xop_phaddubw"
10693   [(set (match_operand:V8HI 0 "register_operand" "=x")
10694         (plus:V8HI
10695          (zero_extend:V8HI
10696           (vec_select:V8QI
10697            (match_operand:V16QI 1 "nonimmediate_operand" "xm")
10698            (parallel [(const_int 0)
10699                       (const_int 2)
10700                       (const_int 4)
10701                       (const_int 6)
10702                       (const_int 8)
10703                       (const_int 10)
10704                       (const_int 12)
10705                       (const_int 14)])))
10706          (zero_extend:V8HI
10707           (vec_select:V8QI
10708            (match_dup 1)
10709            (parallel [(const_int 1)
10710                       (const_int 3)
10711                       (const_int 5)
10712                       (const_int 7)
10713                       (const_int 9)
10714                       (const_int 11)
10715                       (const_int 13)
10716                       (const_int 15)])))))]
10717   "TARGET_XOP"
10718   "vphaddubw\t{%1, %0|%0, %1}"
10719   [(set_attr "type" "sseiadd1")])
10720
10721 (define_insn "xop_phaddubd"
10722   [(set (match_operand:V4SI 0 "register_operand" "=x")
10723         (plus:V4SI
10724          (plus:V4SI
10725           (zero_extend:V4SI
10726            (vec_select:V4QI
10727             (match_operand:V16QI 1 "nonimmediate_operand" "xm")
10728             (parallel [(const_int 0)
10729                        (const_int 4)
10730                        (const_int 8)
10731                        (const_int 12)])))
10732           (zero_extend:V4SI
10733            (vec_select:V4QI
10734             (match_dup 1)
10735             (parallel [(const_int 1)
10736                        (const_int 5)
10737                        (const_int 9)
10738                        (const_int 13)]))))
10739          (plus:V4SI
10740           (zero_extend:V4SI
10741            (vec_select:V4QI
10742             (match_dup 1)
10743             (parallel [(const_int 2)
10744                        (const_int 6)
10745                        (const_int 10)
10746                        (const_int 14)])))
10747           (zero_extend:V4SI
10748            (vec_select:V4QI
10749             (match_dup 1)
10750             (parallel [(const_int 3)
10751                        (const_int 7)
10752                        (const_int 11)
10753                        (const_int 15)]))))))]
10754   "TARGET_XOP"
10755   "vphaddubd\t{%1, %0|%0, %1}"
10756   [(set_attr "type" "sseiadd1")])
10757
10758 (define_insn "xop_phaddubq"
10759   [(set (match_operand:V2DI 0 "register_operand" "=x")
10760         (plus:V2DI
10761          (plus:V2DI
10762           (plus:V2DI
10763            (zero_extend:V2DI
10764             (vec_select:V2QI
10765              (match_operand:V16QI 1 "nonimmediate_operand" "xm")
10766              (parallel [(const_int 0)
10767                         (const_int 4)])))
10768            (sign_extend:V2DI
10769             (vec_select:V2QI
10770              (match_dup 1)
10771              (parallel [(const_int 1)
10772                         (const_int 5)]))))
10773           (plus:V2DI
10774            (zero_extend:V2DI
10775             (vec_select:V2QI
10776              (match_dup 1)
10777              (parallel [(const_int 2)
10778                         (const_int 6)])))
10779            (zero_extend:V2DI
10780             (vec_select:V2QI
10781              (match_dup 1)
10782              (parallel [(const_int 3)
10783                         (const_int 7)])))))
10784          (plus:V2DI
10785           (plus:V2DI
10786            (zero_extend:V2DI
10787             (vec_select:V2QI
10788              (match_dup 1)
10789              (parallel [(const_int 8)
10790                         (const_int 12)])))
10791            (sign_extend:V2DI
10792             (vec_select:V2QI
10793              (match_dup 1)
10794              (parallel [(const_int 9)
10795                         (const_int 13)]))))
10796           (plus:V2DI
10797            (zero_extend:V2DI
10798             (vec_select:V2QI
10799              (match_dup 1)
10800              (parallel [(const_int 10)
10801                         (const_int 14)])))
10802            (zero_extend:V2DI
10803             (vec_select:V2QI
10804              (match_dup 1)
10805              (parallel [(const_int 11)
10806                         (const_int 15)])))))))]
10807   "TARGET_XOP"
10808   "vphaddubq\t{%1, %0|%0, %1}"
10809   [(set_attr "type" "sseiadd1")])
10810
10811 (define_insn "xop_phadduwd"
10812   [(set (match_operand:V4SI 0 "register_operand" "=x")
10813         (plus:V4SI
10814          (zero_extend:V4SI
10815           (vec_select:V4HI
10816            (match_operand:V8HI 1 "nonimmediate_operand" "xm")
10817            (parallel [(const_int 0)
10818                       (const_int 2)
10819                       (const_int 4)
10820                       (const_int 6)])))
10821          (zero_extend:V4SI
10822           (vec_select:V4HI
10823            (match_dup 1)
10824            (parallel [(const_int 1)
10825                       (const_int 3)
10826                       (const_int 5)
10827                       (const_int 7)])))))]
10828   "TARGET_XOP"
10829   "vphadduwd\t{%1, %0|%0, %1}"
10830   [(set_attr "type" "sseiadd1")])
10831
10832 (define_insn "xop_phadduwq"
10833   [(set (match_operand:V2DI 0 "register_operand" "=x")
10834         (plus:V2DI
10835          (plus:V2DI
10836           (zero_extend:V2DI
10837            (vec_select:V2HI
10838             (match_operand:V8HI 1 "nonimmediate_operand" "xm")
10839             (parallel [(const_int 0)
10840                        (const_int 4)])))
10841           (zero_extend:V2DI
10842            (vec_select:V2HI
10843             (match_dup 1)
10844             (parallel [(const_int 1)
10845                        (const_int 5)]))))
10846          (plus:V2DI
10847           (zero_extend:V2DI
10848            (vec_select:V2HI
10849             (match_dup 1)
10850             (parallel [(const_int 2)
10851                        (const_int 6)])))
10852           (zero_extend:V2DI
10853            (vec_select:V2HI
10854             (match_dup 1)
10855             (parallel [(const_int 3)
10856                        (const_int 7)]))))))]
10857   "TARGET_XOP"
10858   "vphadduwq\t{%1, %0|%0, %1}"
10859   [(set_attr "type" "sseiadd1")])
10860
10861 (define_insn "xop_phaddudq"
10862   [(set (match_operand:V2DI 0 "register_operand" "=x")
10863         (plus:V2DI
10864          (zero_extend:V2DI
10865           (vec_select:V2SI
10866            (match_operand:V4SI 1 "nonimmediate_operand" "xm")
10867            (parallel [(const_int 0)
10868                       (const_int 2)])))
10869          (zero_extend:V2DI
10870           (vec_select:V2SI
10871            (match_dup 1)
10872            (parallel [(const_int 1)
10873                       (const_int 3)])))))]
10874   "TARGET_XOP"
10875   "vphaddudq\t{%1, %0|%0, %1}"
10876   [(set_attr "type" "sseiadd1")])
10877
10878 (define_insn "xop_phsubbw"
10879   [(set (match_operand:V8HI 0 "register_operand" "=x")
10880         (minus:V8HI
10881          (sign_extend:V8HI
10882           (vec_select:V8QI
10883            (match_operand:V16QI 1 "nonimmediate_operand" "xm")
10884            (parallel [(const_int 0)
10885                       (const_int 2)
10886                       (const_int 4)
10887                       (const_int 6)
10888                       (const_int 8)
10889                       (const_int 10)
10890                       (const_int 12)
10891                       (const_int 14)])))
10892          (sign_extend:V8HI
10893           (vec_select:V8QI
10894            (match_dup 1)
10895            (parallel [(const_int 1)
10896                       (const_int 3)
10897                       (const_int 5)
10898                       (const_int 7)
10899                       (const_int 9)
10900                       (const_int 11)
10901                       (const_int 13)
10902                       (const_int 15)])))))]
10903   "TARGET_XOP"
10904   "vphsubbw\t{%1, %0|%0, %1}"
10905   [(set_attr "type" "sseiadd1")])
10906
10907 (define_insn "xop_phsubwd"
10908   [(set (match_operand:V4SI 0 "register_operand" "=x")
10909         (minus:V4SI
10910          (sign_extend:V4SI
10911           (vec_select:V4HI
10912            (match_operand:V8HI 1 "nonimmediate_operand" "xm")
10913            (parallel [(const_int 0)
10914                       (const_int 2)
10915                       (const_int 4)
10916                       (const_int 6)])))
10917          (sign_extend:V4SI
10918           (vec_select:V4HI
10919            (match_dup 1)
10920            (parallel [(const_int 1)
10921                       (const_int 3)
10922                       (const_int 5)
10923                       (const_int 7)])))))]
10924   "TARGET_XOP"
10925   "vphsubwd\t{%1, %0|%0, %1}"
10926   [(set_attr "type" "sseiadd1")])
10927
10928 (define_insn "xop_phsubdq"
10929   [(set (match_operand:V2DI 0 "register_operand" "=x")
10930         (minus:V2DI
10931          (sign_extend:V2DI
10932           (vec_select:V2SI
10933            (match_operand:V4SI 1 "nonimmediate_operand" "xm")
10934            (parallel [(const_int 0)
10935                       (const_int 2)])))
10936          (sign_extend:V2DI
10937           (vec_select:V2SI
10938            (match_dup 1)
10939            (parallel [(const_int 1)
10940                       (const_int 3)])))))]
10941   "TARGET_XOP"
10942   "vphsubdq\t{%1, %0|%0, %1}"
10943   [(set_attr "type" "sseiadd1")])
10944
10945 ;; XOP permute instructions
10946 (define_insn "xop_pperm"
10947   [(set (match_operand:V16QI 0 "register_operand" "=x,x")
10948         (unspec:V16QI
10949           [(match_operand:V16QI 1 "register_operand" "x,x")
10950            (match_operand:V16QI 2 "nonimmediate_operand" "x,m")
10951            (match_operand:V16QI 3 "nonimmediate_operand" "xm,x")]
10952           UNSPEC_XOP_PERMUTE))]
10953   "TARGET_XOP && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
10954   "vpperm\t{%3, %2, %1, %0|%0, %1, %2, %3}"
10955   [(set_attr "type" "sse4arg")
10956    (set_attr "mode" "TI")])
10957
10958 ;; XOP pack instructions that combine two vectors into a smaller vector
10959 (define_insn "xop_pperm_pack_v2di_v4si"
10960   [(set (match_operand:V4SI 0 "register_operand" "=x,x")
10961         (vec_concat:V4SI
10962          (truncate:V2SI
10963           (match_operand:V2DI 1 "register_operand" "x,x"))
10964          (truncate:V2SI
10965           (match_operand:V2DI 2 "nonimmediate_operand" "x,m"))))
10966    (use (match_operand:V16QI 3 "nonimmediate_operand" "xm,x"))]
10967   "TARGET_XOP && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
10968   "vpperm\t{%3, %2, %1, %0|%0, %1, %2, %3}"
10969   [(set_attr "type" "sse4arg")
10970    (set_attr "mode" "TI")])
10971
10972 (define_insn "xop_pperm_pack_v4si_v8hi"
10973   [(set (match_operand:V8HI 0 "register_operand" "=x,x")
10974         (vec_concat:V8HI
10975          (truncate:V4HI
10976           (match_operand:V4SI 1 "register_operand" "x,x"))
10977          (truncate:V4HI
10978           (match_operand:V4SI 2 "nonimmediate_operand" "x,m"))))
10979    (use (match_operand:V16QI 3 "nonimmediate_operand" "xm,x"))]
10980   "TARGET_XOP && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
10981   "vpperm\t{%3, %2, %1, %0|%0, %1, %2, %3}"
10982   [(set_attr "type" "sse4arg")
10983    (set_attr "mode" "TI")])
10984
10985 (define_insn "xop_pperm_pack_v8hi_v16qi"
10986   [(set (match_operand:V16QI 0 "register_operand" "=x,x")
10987         (vec_concat:V16QI
10988          (truncate:V8QI
10989           (match_operand:V8HI 1 "register_operand" "x,x"))
10990          (truncate:V8QI
10991           (match_operand:V8HI 2 "nonimmediate_operand" "x,m"))))
10992    (use (match_operand:V16QI 3 "nonimmediate_operand" "xm,x"))]
10993   "TARGET_XOP && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
10994   "vpperm\t{%3, %2, %1, %0|%0, %1, %2, %3}"
10995   [(set_attr "type" "sse4arg")
10996    (set_attr "mode" "TI")])
10997
10998 ;; XOP packed rotate instructions
10999 (define_expand "rotl<mode>3"
11000   [(set (match_operand:SSEMODE1248 0 "register_operand" "")
11001         (rotate:SSEMODE1248
11002          (match_operand:SSEMODE1248 1 "nonimmediate_operand" "")
11003          (match_operand:SI 2 "general_operand")))]
11004   "TARGET_XOP"
11005 {
11006   /* If we were given a scalar, convert it to parallel */
11007   if (! const_0_to_<sserotatemax>_operand (operands[2], SImode))
11008     {
11009       rtvec vs = rtvec_alloc (<ssescalarnum>);
11010       rtx par = gen_rtx_PARALLEL (<MODE>mode, vs);
11011       rtx reg = gen_reg_rtx (<MODE>mode);
11012       rtx op2 = operands[2];
11013       int i;
11014
11015       if (GET_MODE (op2) != <ssescalarmode>mode)
11016         {
11017           op2 = gen_reg_rtx (<ssescalarmode>mode);
11018           convert_move (op2, operands[2], false);
11019         }
11020
11021       for (i = 0; i < <ssescalarnum>; i++)
11022         RTVEC_ELT (vs, i) = op2;
11023
11024       emit_insn (gen_vec_init<mode> (reg, par));
11025       emit_insn (gen_xop_vrotl<mode>3 (operands[0], operands[1], reg));
11026       DONE;
11027     }
11028 })
11029
11030 (define_expand "rotr<mode>3"
11031   [(set (match_operand:SSEMODE1248 0 "register_operand" "")
11032         (rotatert:SSEMODE1248
11033          (match_operand:SSEMODE1248 1 "nonimmediate_operand" "")
11034          (match_operand:SI 2 "general_operand")))]
11035   "TARGET_XOP"
11036 {
11037   /* If we were given a scalar, convert it to parallel */
11038   if (! const_0_to_<sserotatemax>_operand (operands[2], SImode))
11039     {
11040       rtvec vs = rtvec_alloc (<ssescalarnum>);
11041       rtx par = gen_rtx_PARALLEL (<MODE>mode, vs);
11042       rtx neg = gen_reg_rtx (<MODE>mode);
11043       rtx reg = gen_reg_rtx (<MODE>mode);
11044       rtx op2 = operands[2];
11045       int i;
11046
11047       if (GET_MODE (op2) != <ssescalarmode>mode)
11048         {
11049           op2 = gen_reg_rtx (<ssescalarmode>mode);
11050           convert_move (op2, operands[2], false);
11051         }
11052
11053       for (i = 0; i < <ssescalarnum>; i++)
11054         RTVEC_ELT (vs, i) = op2;
11055
11056       emit_insn (gen_vec_init<mode> (reg, par));
11057       emit_insn (gen_neg<mode>2 (neg, reg));
11058       emit_insn (gen_xop_vrotl<mode>3 (operands[0], operands[1], neg));
11059       DONE;
11060     }
11061 })
11062
11063 (define_insn "xop_rotl<mode>3"
11064   [(set (match_operand:SSEMODE1248 0 "register_operand" "=x")
11065         (rotate:SSEMODE1248
11066          (match_operand:SSEMODE1248 1 "nonimmediate_operand" "xm")
11067          (match_operand:SI 2 "const_0_to_<sserotatemax>_operand" "n")))]
11068   "TARGET_XOP"
11069   "vprot<ssevecsize>\t{%2, %1, %0|%0, %1, %2}"
11070   [(set_attr "type" "sseishft")
11071    (set_attr "length_immediate" "1")
11072    (set_attr "mode" "TI")])
11073
11074 (define_insn "xop_rotr<mode>3"
11075   [(set (match_operand:SSEMODE1248 0 "register_operand" "=x")
11076         (rotatert:SSEMODE1248
11077          (match_operand:SSEMODE1248 1 "nonimmediate_operand" "xm")
11078          (match_operand:SI 2 "const_0_to_<sserotatemax>_operand" "n")))]
11079   "TARGET_XOP"
11080 {
11081   operands[3] = GEN_INT ((<ssescalarnum> * 8) - INTVAL (operands[2]));
11082   return \"vprot<ssevecsize>\t{%3, %1, %0|%0, %1, %3}\";
11083 }
11084   [(set_attr "type" "sseishft")
11085    (set_attr "length_immediate" "1")
11086    (set_attr "mode" "TI")])
11087
11088 (define_expand "vrotr<mode>3"
11089   [(match_operand:SSEMODE1248 0 "register_operand" "")
11090    (match_operand:SSEMODE1248 1 "register_operand" "")
11091    (match_operand:SSEMODE1248 2 "register_operand" "")]
11092   "TARGET_XOP"
11093 {
11094   rtx reg = gen_reg_rtx (<MODE>mode);
11095   emit_insn (gen_neg<mode>2 (reg, operands[2]));
11096   emit_insn (gen_xop_vrotl<mode>3 (operands[0], operands[1], reg));
11097   DONE;
11098 })
11099
11100 (define_expand "vrotl<mode>3"
11101   [(match_operand:SSEMODE1248 0 "register_operand" "")
11102    (match_operand:SSEMODE1248 1 "register_operand" "")
11103    (match_operand:SSEMODE1248 2 "register_operand" "")]
11104   "TARGET_XOP"
11105 {
11106   emit_insn (gen_xop_vrotl<mode>3 (operands[0], operands[1], operands[2]));
11107   DONE;
11108 })
11109
11110 (define_insn "xop_vrotl<mode>3"
11111   [(set (match_operand:SSEMODE1248 0 "register_operand" "=x,x")
11112         (if_then_else:SSEMODE1248
11113          (ge:SSEMODE1248
11114           (match_operand:SSEMODE1248 2 "nonimmediate_operand" "x,m")
11115           (const_int 0))
11116          (rotate:SSEMODE1248
11117           (match_operand:SSEMODE1248 1 "nonimmediate_operand" "xm,x")
11118           (match_dup 2))
11119          (rotatert:SSEMODE1248
11120           (match_dup 1)
11121           (neg:SSEMODE1248 (match_dup 2)))))]
11122   "TARGET_XOP && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
11123   "vprot<ssevecsize>\t{%2, %1, %0|%0, %1, %2}"
11124   [(set_attr "type" "sseishft")
11125    (set_attr "prefix_data16" "0")
11126    (set_attr "prefix_extra" "2")
11127    (set_attr "mode" "TI")])
11128
11129 ;; XOP packed shift instructions.
11130 ;; FIXME: add V2DI back in
11131 (define_expand "vlshr<mode>3"
11132   [(match_operand:SSEMODE124 0 "register_operand" "")
11133    (match_operand:SSEMODE124 1 "register_operand" "")
11134    (match_operand:SSEMODE124 2 "register_operand" "")]
11135   "TARGET_XOP"
11136 {
11137   rtx neg = gen_reg_rtx (<MODE>mode);
11138   emit_insn (gen_neg<mode>2 (neg, operands[2]));
11139   emit_insn (gen_xop_lshl<mode>3 (operands[0], operands[1], neg));
11140   DONE;
11141 })
11142
11143 (define_expand "vashr<mode>3"
11144   [(match_operand:SSEMODE124 0 "register_operand" "")
11145    (match_operand:SSEMODE124 1 "register_operand" "")
11146    (match_operand:SSEMODE124 2 "register_operand" "")]
11147   "TARGET_XOP"
11148 {
11149   rtx neg = gen_reg_rtx (<MODE>mode);
11150   emit_insn (gen_neg<mode>2 (neg, operands[2]));
11151   emit_insn (gen_xop_ashl<mode>3 (operands[0], operands[1], neg));
11152   DONE;
11153 })
11154
11155 (define_expand "vashl<mode>3"
11156   [(match_operand:SSEMODE124 0 "register_operand" "")
11157    (match_operand:SSEMODE124 1 "register_operand" "")
11158    (match_operand:SSEMODE124 2 "register_operand" "")]
11159   "TARGET_XOP"
11160 {
11161   emit_insn (gen_xop_ashl<mode>3 (operands[0], operands[1], operands[2]));
11162   DONE;
11163 })
11164
11165 (define_insn "xop_ashl<mode>3"
11166   [(set (match_operand:SSEMODE1248 0 "register_operand" "=x,x")
11167         (if_then_else:SSEMODE1248
11168          (ge:SSEMODE1248
11169           (match_operand:SSEMODE1248 2 "nonimmediate_operand" "x,m")
11170           (const_int 0))
11171          (ashift:SSEMODE1248
11172           (match_operand:SSEMODE1248 1 "nonimmediate_operand" "xm,x")
11173           (match_dup 2))
11174          (ashiftrt:SSEMODE1248
11175           (match_dup 1)
11176           (neg:SSEMODE1248 (match_dup 2)))))]
11177   "TARGET_XOP && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
11178   "vpsha<ssevecsize>\t{%2, %1, %0|%0, %1, %2}"
11179   [(set_attr "type" "sseishft")
11180    (set_attr "prefix_data16" "0")
11181    (set_attr "prefix_extra" "2")
11182    (set_attr "mode" "TI")])
11183
11184 (define_insn "xop_lshl<mode>3"
11185   [(set (match_operand:SSEMODE1248 0 "register_operand" "=x,x")
11186         (if_then_else:SSEMODE1248
11187          (ge:SSEMODE1248
11188           (match_operand:SSEMODE1248 2 "nonimmediate_operand" "x,m")
11189           (const_int 0))
11190          (ashift:SSEMODE1248
11191           (match_operand:SSEMODE1248 1 "nonimmediate_operand" "xm,x")
11192           (match_dup 2))
11193          (lshiftrt:SSEMODE1248
11194           (match_dup 1)
11195           (neg:SSEMODE1248 (match_dup 2)))))]
11196   "TARGET_XOP && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
11197   "vpshl<ssevecsize>\t{%2, %1, %0|%0, %1, %2}"
11198   [(set_attr "type" "sseishft")
11199    (set_attr "prefix_data16" "0")
11200    (set_attr "prefix_extra" "2")
11201    (set_attr "mode" "TI")])
11202
11203 ;; SSE2 doesn't have some shift varients, so define versions for XOP
11204 (define_expand "ashlv16qi3"
11205   [(match_operand:V16QI 0 "register_operand" "")
11206    (match_operand:V16QI 1 "register_operand" "")
11207    (match_operand:SI 2 "nonmemory_operand" "")]
11208   "TARGET_XOP"
11209 {
11210   rtvec vs = rtvec_alloc (16);
11211   rtx par = gen_rtx_PARALLEL (V16QImode, vs);
11212   rtx reg = gen_reg_rtx (V16QImode);
11213   int i;
11214   for (i = 0; i < 16; i++)
11215     RTVEC_ELT (vs, i) = operands[2];
11216
11217   emit_insn (gen_vec_initv16qi (reg, par));
11218   emit_insn (gen_xop_ashlv16qi3 (operands[0], operands[1], reg));
11219   DONE;
11220 })
11221
11222 (define_expand "lshlv16qi3"
11223   [(match_operand:V16QI 0 "register_operand" "")
11224    (match_operand:V16QI 1 "register_operand" "")
11225    (match_operand:SI 2 "nonmemory_operand" "")]
11226   "TARGET_XOP"
11227 {
11228   rtvec vs = rtvec_alloc (16);
11229   rtx par = gen_rtx_PARALLEL (V16QImode, vs);
11230   rtx reg = gen_reg_rtx (V16QImode);
11231   int i;
11232   for (i = 0; i < 16; i++)
11233     RTVEC_ELT (vs, i) = operands[2];
11234
11235   emit_insn (gen_vec_initv16qi (reg, par));
11236   emit_insn (gen_xop_lshlv16qi3 (operands[0], operands[1], reg));
11237   DONE;
11238 })
11239
11240 (define_expand "ashrv16qi3"
11241   [(match_operand:V16QI 0 "register_operand" "")
11242    (match_operand:V16QI 1 "register_operand" "")
11243    (match_operand:SI 2 "nonmemory_operand" "")]
11244   "TARGET_XOP"
11245 {
11246   rtvec vs = rtvec_alloc (16);
11247   rtx par = gen_rtx_PARALLEL (V16QImode, vs);
11248   rtx reg = gen_reg_rtx (V16QImode);
11249   int i;
11250   rtx ele = ((CONST_INT_P (operands[2]))
11251              ? GEN_INT (- INTVAL (operands[2]))
11252              : operands[2]);
11253
11254   for (i = 0; i < 16; i++)
11255     RTVEC_ELT (vs, i) = ele;
11256
11257   emit_insn (gen_vec_initv16qi (reg, par));
11258
11259   if (!CONST_INT_P (operands[2]))
11260     {
11261       rtx neg = gen_reg_rtx (V16QImode);
11262       emit_insn (gen_negv16qi2 (neg, reg));
11263       emit_insn (gen_xop_ashlv16qi3 (operands[0], operands[1], neg));
11264     }
11265   else
11266     emit_insn (gen_xop_ashlv16qi3 (operands[0], operands[1], reg));
11267
11268   DONE;
11269 })
11270
11271 (define_expand "ashrv2di3"
11272   [(match_operand:V2DI 0 "register_operand" "")
11273    (match_operand:V2DI 1 "register_operand" "")
11274    (match_operand:DI 2 "nonmemory_operand" "")]
11275   "TARGET_XOP"
11276 {
11277   rtvec vs = rtvec_alloc (2);
11278   rtx par = gen_rtx_PARALLEL (V2DImode, vs);
11279   rtx reg = gen_reg_rtx (V2DImode);
11280   rtx ele;
11281
11282   if (CONST_INT_P (operands[2]))
11283     ele = GEN_INT (- INTVAL (operands[2]));
11284   else if (GET_MODE (operands[2]) != DImode)
11285     {
11286       rtx move = gen_reg_rtx (DImode);
11287       ele = gen_reg_rtx (DImode);
11288       convert_move (move, operands[2], false);
11289       emit_insn (gen_negdi2 (ele, move));
11290     }
11291   else
11292     {
11293       ele = gen_reg_rtx (DImode);
11294       emit_insn (gen_negdi2 (ele, operands[2]));
11295     }
11296
11297   RTVEC_ELT (vs, 0) = ele;
11298   RTVEC_ELT (vs, 1) = ele;
11299   emit_insn (gen_vec_initv2di (reg, par));
11300   emit_insn (gen_xop_ashlv2di3 (operands[0], operands[1], reg));
11301   DONE;
11302 })
11303
11304 ;; XOP FRCZ support
11305 (define_insn "xop_frcz<mode>2"
11306   [(set (match_operand:FMAMODE 0 "register_operand" "=x")
11307         (unspec:FMAMODE
11308          [(match_operand:FMAMODE 1 "nonimmediate_operand" "xm")]
11309          UNSPEC_FRCZ))]
11310   "TARGET_XOP"
11311   "vfrcz<ssemodesuffix>\t{%1, %0|%0, %1}"
11312   [(set_attr "type" "ssecvt1")
11313    (set_attr "mode" "<MODE>")])
11314
11315 ;; scalar insns
11316 (define_expand "xop_vmfrcz<mode>2"
11317   [(set (match_operand:SSEMODEF2P 0 "register_operand")
11318         (vec_merge:SSEMODEF2P
11319           (unspec:SSEMODEF2P
11320            [(match_operand:SSEMODEF2P 1 "nonimmediate_operand")]
11321            UNSPEC_FRCZ)
11322           (match_dup 3)
11323           (const_int 1)))]
11324   "TARGET_XOP"
11325 {
11326   operands[3] = CONST0_RTX (<MODE>mode);
11327 })
11328
11329 (define_insn "*xop_vmfrcz_<mode>"
11330   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
11331         (vec_merge:SSEMODEF2P
11332           (unspec:SSEMODEF2P
11333            [(match_operand:SSEMODEF2P 1 "nonimmediate_operand" "xm")]
11334            UNSPEC_FRCZ)
11335           (match_operand:SSEMODEF2P 2 "const0_operand")
11336           (const_int 1)))]
11337   "TARGET_XOP"
11338   "vfrcz<ssescalarmodesuffix>\t{%1, %0|%0, %1}"
11339   [(set_attr "type" "ssecvt1")
11340    (set_attr "mode" "<MODE>")])
11341
11342 (define_insn "xop_maskcmp<mode>3"
11343   [(set (match_operand:SSEMODE1248 0 "register_operand" "=x")
11344         (match_operator:SSEMODE1248 1 "ix86_comparison_int_operator"
11345          [(match_operand:SSEMODE1248 2 "register_operand" "x")
11346           (match_operand:SSEMODE1248 3 "nonimmediate_operand" "xm")]))]
11347   "TARGET_XOP"
11348   "vpcom%Y1<ssevecsize>\t{%3, %2, %0|%0, %2, %3}"
11349   [(set_attr "type" "sse4arg")
11350    (set_attr "prefix_data16" "0")
11351    (set_attr "prefix_rep" "0")
11352    (set_attr "prefix_extra" "2")
11353    (set_attr "length_immediate" "1")
11354    (set_attr "mode" "TI")])
11355
11356 (define_insn "xop_maskcmp_uns<mode>3"
11357   [(set (match_operand:SSEMODE1248 0 "register_operand" "=x")
11358         (match_operator:SSEMODE1248 1 "ix86_comparison_uns_operator"
11359          [(match_operand:SSEMODE1248 2 "register_operand" "x")
11360           (match_operand:SSEMODE1248 3 "nonimmediate_operand" "xm")]))]
11361   "TARGET_XOP"
11362   "vpcom%Y1u<ssevecsize>\t{%3, %2, %0|%0, %2, %3}"
11363   [(set_attr "type" "ssecmp")
11364    (set_attr "prefix_data16" "0")
11365    (set_attr "prefix_rep" "0")
11366    (set_attr "prefix_extra" "2")
11367    (set_attr "length_immediate" "1")
11368    (set_attr "mode" "TI")])
11369
11370 ;; Version of pcom*u* that is called from the intrinsics that allows pcomequ*
11371 ;; and pcomneu* not to be converted to the signed ones in case somebody needs
11372 ;; the exact instruction generated for the intrinsic.
11373 (define_insn "xop_maskcmp_uns2<mode>3"
11374   [(set (match_operand:SSEMODE1248 0 "register_operand" "=x")
11375         (unspec:SSEMODE1248
11376          [(match_operator:SSEMODE1248 1 "ix86_comparison_uns_operator"
11377           [(match_operand:SSEMODE1248 2 "register_operand" "x")
11378            (match_operand:SSEMODE1248 3 "nonimmediate_operand" "xm")])]
11379          UNSPEC_XOP_UNSIGNED_CMP))]
11380   "TARGET_XOP"
11381   "vpcom%Y1u<ssevecsize>\t{%3, %2, %0|%0, %2, %3}"
11382   [(set_attr "type" "ssecmp")
11383    (set_attr "prefix_data16" "0")
11384    (set_attr "prefix_extra" "2")
11385    (set_attr "length_immediate" "1")
11386    (set_attr "mode" "TI")])
11387
11388 ;; Pcomtrue and pcomfalse support.  These are useless instructions, but are
11389 ;; being added here to be complete.
11390 (define_insn "xop_pcom_tf<mode>3"
11391   [(set (match_operand:SSEMODE1248 0 "register_operand" "=x")
11392         (unspec:SSEMODE1248
11393           [(match_operand:SSEMODE1248 1 "register_operand" "x")
11394            (match_operand:SSEMODE1248 2 "nonimmediate_operand" "xm")
11395            (match_operand:SI 3 "const_int_operand" "n")]
11396           UNSPEC_XOP_TRUEFALSE))]
11397   "TARGET_XOP"
11398 {
11399   return ((INTVAL (operands[3]) != 0)
11400           ? "vpcomtrue<ssevecsize>\t{%2, %1, %0|%0, %1, %2}"
11401           : "vpcomfalse<ssevecsize>\t{%2, %1, %0|%0, %1, %2}");
11402 }
11403   [(set_attr "type" "ssecmp")
11404    (set_attr "prefix_data16" "0")
11405    (set_attr "prefix_extra" "2")
11406    (set_attr "length_immediate" "1")
11407    (set_attr "mode" "TI")])
11408
11409 (define_insn "xop_vpermil2<mode>3"
11410   [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x")
11411         (unspec:AVXMODEF2P
11412           [(match_operand:AVXMODEF2P 1 "register_operand" "x")
11413            (match_operand:AVXMODEF2P 2 "nonimmediate_operand" "%x")
11414            (match_operand:<avxpermvecmode> 3 "nonimmediate_operand" "xm")
11415            (match_operand:SI 4 "const_0_to_3_operand" "n")]
11416           UNSPEC_VPERMIL2))]
11417   "TARGET_XOP"
11418   "vpermil2<ssemodesuffix>\t{%4, %3, %2, %1, %0|%0, %1, %2, %3, %4}"
11419   [(set_attr "type" "sse4arg")
11420    (set_attr "length_immediate" "1")
11421    (set_attr "mode" "<MODE>")])
11422
11423 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
11424 (define_insn "*avx_aesenc"
11425   [(set (match_operand:V2DI 0 "register_operand" "=x")
11426         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")
11427                        (match_operand:V2DI 2 "nonimmediate_operand" "xm")]
11428                       UNSPEC_AESENC))]
11429   "TARGET_AES && TARGET_AVX"
11430   "vaesenc\t{%2, %1, %0|%0, %1, %2}"
11431   [(set_attr "type" "sselog1")
11432    (set_attr "prefix_extra" "1")
11433    (set_attr "prefix" "vex")
11434    (set_attr "mode" "TI")])
11435
11436 (define_insn "aesenc"
11437   [(set (match_operand:V2DI 0 "register_operand" "=x")
11438         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0")
11439                        (match_operand:V2DI 2 "nonimmediate_operand" "xm")]
11440                       UNSPEC_AESENC))]
11441   "TARGET_AES"
11442   "aesenc\t{%2, %0|%0, %2}"
11443   [(set_attr "type" "sselog1")
11444    (set_attr "prefix_extra" "1")
11445    (set_attr "mode" "TI")])
11446
11447 (define_insn "*avx_aesenclast"
11448   [(set (match_operand:V2DI 0 "register_operand" "=x")
11449         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")
11450                        (match_operand:V2DI 2 "nonimmediate_operand" "xm")]
11451                       UNSPEC_AESENCLAST))]
11452   "TARGET_AES && TARGET_AVX"
11453   "vaesenclast\t{%2, %1, %0|%0, %1, %2}"
11454   [(set_attr "type" "sselog1")
11455    (set_attr "prefix_extra" "1")
11456    (set_attr "prefix" "vex")
11457    (set_attr "mode" "TI")])
11458
11459 (define_insn "aesenclast"
11460   [(set (match_operand:V2DI 0 "register_operand" "=x")
11461         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0")
11462                        (match_operand:V2DI 2 "nonimmediate_operand" "xm")]
11463                       UNSPEC_AESENCLAST))]
11464   "TARGET_AES"
11465   "aesenclast\t{%2, %0|%0, %2}"
11466   [(set_attr "type" "sselog1")
11467    (set_attr "prefix_extra" "1")
11468    (set_attr "mode" "TI")])
11469
11470 (define_insn "*avx_aesdec"
11471   [(set (match_operand:V2DI 0 "register_operand" "=x")
11472         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")
11473                        (match_operand:V2DI 2 "nonimmediate_operand" "xm")]
11474                       UNSPEC_AESDEC))]
11475   "TARGET_AES && TARGET_AVX"
11476   "vaesdec\t{%2, %1, %0|%0, %1, %2}"
11477   [(set_attr "type" "sselog1")
11478    (set_attr "prefix_extra" "1")
11479    (set_attr "prefix" "vex")
11480    (set_attr "mode" "TI")])
11481
11482 (define_insn "aesdec"
11483   [(set (match_operand:V2DI 0 "register_operand" "=x")
11484         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0")
11485                        (match_operand:V2DI 2 "nonimmediate_operand" "xm")]
11486                       UNSPEC_AESDEC))]
11487   "TARGET_AES"
11488   "aesdec\t{%2, %0|%0, %2}"
11489   [(set_attr "type" "sselog1")
11490    (set_attr "prefix_extra" "1")
11491    (set_attr "mode" "TI")])
11492
11493 (define_insn "*avx_aesdeclast"
11494   [(set (match_operand:V2DI 0 "register_operand" "=x")
11495         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")
11496                        (match_operand:V2DI 2 "nonimmediate_operand" "xm")]
11497                       UNSPEC_AESDECLAST))]
11498   "TARGET_AES && TARGET_AVX"
11499   "vaesdeclast\t{%2, %1, %0|%0, %1, %2}"
11500   [(set_attr "type" "sselog1")
11501    (set_attr "prefix_extra" "1")
11502    (set_attr "prefix" "vex")
11503    (set_attr "mode" "TI")])
11504
11505 (define_insn "aesdeclast"
11506   [(set (match_operand:V2DI 0 "register_operand" "=x")
11507         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0")
11508                        (match_operand:V2DI 2 "nonimmediate_operand" "xm")]
11509                       UNSPEC_AESDECLAST))]
11510   "TARGET_AES"
11511   "aesdeclast\t{%2, %0|%0, %2}"
11512   [(set_attr "type" "sselog1")
11513    (set_attr "prefix_extra" "1")
11514    (set_attr "mode" "TI")])
11515
11516 (define_insn "aesimc"
11517   [(set (match_operand:V2DI 0 "register_operand" "=x")
11518         (unspec:V2DI [(match_operand:V2DI 1 "nonimmediate_operand" "xm")]
11519                       UNSPEC_AESIMC))]
11520   "TARGET_AES"
11521   "%vaesimc\t{%1, %0|%0, %1}"
11522   [(set_attr "type" "sselog1")
11523    (set_attr "prefix_extra" "1")
11524    (set_attr "prefix" "maybe_vex")
11525    (set_attr "mode" "TI")])
11526
11527 (define_insn "aeskeygenassist"
11528   [(set (match_operand:V2DI 0 "register_operand" "=x")
11529         (unspec:V2DI [(match_operand:V2DI 1 "nonimmediate_operand" "xm")
11530                       (match_operand:SI 2 "const_0_to_255_operand" "n")]
11531                      UNSPEC_AESKEYGENASSIST))]
11532   "TARGET_AES"
11533   "%vaeskeygenassist\t{%2, %1, %0|%0, %1, %2}"
11534   [(set_attr "type" "sselog1")
11535    (set_attr "prefix_extra" "1")
11536    (set_attr "length_immediate" "1")
11537    (set_attr "prefix" "maybe_vex")
11538    (set_attr "mode" "TI")])
11539
11540 (define_insn "*vpclmulqdq"
11541   [(set (match_operand:V2DI 0 "register_operand" "=x")
11542         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")
11543                       (match_operand:V2DI 2 "nonimmediate_operand" "xm")
11544                       (match_operand:SI 3 "const_0_to_255_operand" "n")]
11545                      UNSPEC_PCLMUL))]
11546   "TARGET_PCLMUL && TARGET_AVX"
11547   "vpclmulqdq\t{%3, %2, %1, %0|%0, %1, %2, %3}"
11548   [(set_attr "type" "sselog1")
11549    (set_attr "prefix_extra" "1")
11550    (set_attr "length_immediate" "1")
11551    (set_attr "prefix" "vex")
11552    (set_attr "mode" "TI")])
11553
11554 (define_insn "pclmulqdq"
11555   [(set (match_operand:V2DI 0 "register_operand" "=x")
11556         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0")
11557                       (match_operand:V2DI 2 "nonimmediate_operand" "xm")
11558                       (match_operand:SI 3 "const_0_to_255_operand" "n")]
11559                      UNSPEC_PCLMUL))]
11560   "TARGET_PCLMUL"
11561   "pclmulqdq\t{%3, %2, %0|%0, %2, %3}"
11562   [(set_attr "type" "sselog1")
11563    (set_attr "prefix_extra" "1")
11564    (set_attr "length_immediate" "1")
11565    (set_attr "mode" "TI")])
11566
11567 (define_expand "avx_vzeroall"
11568   [(match_par_dup 0 [(const_int 0)])]
11569   "TARGET_AVX"
11570 {
11571   int nregs = TARGET_64BIT ? 16 : 8;
11572   int regno;
11573
11574   operands[0] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nregs + 1));
11575
11576   XVECEXP (operands[0], 0, 0)
11577     = gen_rtx_UNSPEC_VOLATILE (VOIDmode, gen_rtvec (1, const0_rtx),
11578                                UNSPECV_VZEROALL);
11579
11580   for (regno = 0; regno < nregs; regno++)
11581     XVECEXP (operands[0], 0, regno + 1)
11582       = gen_rtx_SET (VOIDmode,
11583                      gen_rtx_REG (V8SImode, SSE_REGNO (regno)),
11584                      CONST0_RTX (V8SImode));
11585 })
11586
11587 (define_insn "*avx_vzeroall"
11588   [(match_parallel 0 "vzeroall_operation"
11589     [(unspec_volatile [(const_int 0)] UNSPECV_VZEROALL)])]
11590   "TARGET_AVX"
11591   "vzeroall"
11592   [(set_attr "type" "sse")
11593    (set_attr "modrm" "0")
11594    (set_attr "memory" "none")
11595    (set_attr "prefix" "vex")
11596    (set_attr "mode" "OI")])
11597
11598 ;; Clear the upper 128bits of AVX registers, equivalent to a NOP
11599 ;; if the upper 128bits are unused.
11600 (define_insn "avx_vzeroupper"
11601   [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11602                     UNSPECV_VZEROUPPER)]
11603   "TARGET_AVX"
11604   "vzeroupper"
11605   [(set_attr "type" "sse")
11606    (set_attr "modrm" "0")
11607    (set_attr "memory" "none")
11608    (set_attr "prefix" "vex")
11609    (set_attr "mode" "OI")])
11610
11611 (define_insn_and_split "vec_dup<mode>"
11612   [(set (match_operand:AVX256MODE24P 0 "register_operand" "=x,x")
11613         (vec_duplicate:AVX256MODE24P
11614           (match_operand:<avxscalarmode> 1 "nonimmediate_operand" "m,?x")))]
11615   "TARGET_AVX"
11616   "@
11617    vbroadcast<ssescalarmodesuffix>\t{%1, %0|%0, %1}
11618    #"
11619   "&& reload_completed && REG_P (operands[1])"
11620   [(set (match_dup 2) (vec_duplicate:<avxhalfvecmode> (match_dup 1)))
11621    (set (match_dup 0) (vec_concat:AVX256MODE24P (match_dup 2) (match_dup 2)))]
11622   "operands[2] = gen_rtx_REG (<avxhalfvecmode>mode, REGNO (operands[0]));"
11623   [(set_attr "type" "ssemov")
11624    (set_attr "prefix_extra" "1")
11625    (set_attr "prefix" "vex")
11626    (set_attr "mode" "V8SF")])
11627
11628 (define_insn "avx_vbroadcastf128_<mode>"
11629   [(set (match_operand:AVX256MODE 0 "register_operand" "=x,x,x")
11630         (vec_concat:AVX256MODE
11631           (match_operand:<avxhalfvecmode> 1 "nonimmediate_operand" "m,0,?x")
11632           (match_dup 1)))]
11633   "TARGET_AVX"
11634   "@
11635    vbroadcastf128\t{%1, %0|%0, %1}
11636    vinsertf128\t{$1, %1, %0, %0|%0, %0, %1, 1}
11637    vperm2f128\t{$0, %t1, %t1, %0|%0, %t1, %t1, 0}"
11638   [(set_attr "type" "ssemov,sselog1,sselog1")
11639    (set_attr "prefix_extra" "1")
11640    (set_attr "length_immediate" "0,1,1")
11641    (set_attr "prefix" "vex")
11642    (set_attr "mode" "V4SF,V8SF,V8SF")])
11643
11644 ;; Recognize broadcast as a vec_select as produced by builtin_vec_perm.
11645 ;; If it so happens that the input is in memory, use vbroadcast.
11646 ;; Otherwise use vpermilp (and in the case of 256-bit modes, vperm2f128).
11647 (define_insn "*avx_vperm_broadcast_v4sf"
11648   [(set (match_operand:V4SF 0 "register_operand" "=x,x,x")
11649         (vec_select:V4SF
11650           (match_operand:V4SF 1 "nonimmediate_operand" "m,o,x")
11651           (match_parallel 2 "avx_vbroadcast_operand"
11652             [(match_operand 3 "const_int_operand" "C,n,n")])))]
11653   "TARGET_AVX"
11654 {
11655   int elt = INTVAL (operands[3]);
11656   switch (which_alternative)
11657     {
11658     case 0:
11659     case 1:
11660       operands[1] = adjust_address_nv (operands[1], SFmode, elt * 4);
11661       return "vbroadcastss\t{%1, %0|%0, %1}";
11662     case 2:
11663       operands[2] = GEN_INT (elt * 0x55);
11664       return "vpermilps\t{%2, %1, %0|%0, %1, %2}";
11665     default:
11666       gcc_unreachable ();
11667     }
11668 }
11669   [(set_attr "type" "ssemov,ssemov,sselog1")
11670    (set_attr "prefix_extra" "1")
11671    (set_attr "length_immediate" "0,0,1")
11672    (set_attr "prefix" "vex")
11673    (set_attr "mode" "SF,SF,V4SF")])
11674
11675 (define_insn_and_split "*avx_vperm_broadcast_<mode>"
11676   [(set (match_operand:AVX256MODEF2P 0 "register_operand" "=x,x,x")
11677         (vec_select:AVX256MODEF2P
11678           (match_operand:AVX256MODEF2P 1 "nonimmediate_operand" "m,o,?x")
11679           (match_parallel 2 "avx_vbroadcast_operand"
11680             [(match_operand 3 "const_int_operand" "C,n,n")])))]
11681   "TARGET_AVX"
11682   "#"
11683   "&& reload_completed"
11684   [(set (match_dup 0) (vec_duplicate:AVX256MODEF2P (match_dup 1)))]
11685 {
11686   rtx op0 = operands[0], op1 = operands[1];
11687   int elt = INTVAL (operands[3]);
11688
11689   if (REG_P (op1))
11690     {
11691       int mask;
11692
11693       /* Shuffle element we care about into all elements of the 128-bit lane.
11694          The other lane gets shuffled too, but we don't care.  */
11695       if (<MODE>mode == V4DFmode)
11696         mask = (elt & 1 ? 15 : 0);
11697       else
11698         mask = (elt & 3) * 0x55;
11699       emit_insn (gen_avx_vpermil<mode> (op0, op1, GEN_INT (mask)));
11700
11701       /* Shuffle the lane we care about into both lanes of the dest.  */
11702       mask = (elt / (<ssescalarnum> / 2)) * 0x11;
11703       emit_insn (gen_avx_vperm2f128<mode>3 (op0, op0, op0, GEN_INT (mask)));
11704       DONE;
11705     }
11706
11707   operands[1] = adjust_address_nv (op1, <avxscalarmode>mode,
11708                                    elt * GET_MODE_SIZE (<avxscalarmode>mode));
11709 })
11710
11711 (define_expand "avx_vpermil<mode>"
11712   [(set (match_operand:AVXMODEFDP 0 "register_operand" "")
11713         (vec_select:AVXMODEFDP
11714           (match_operand:AVXMODEFDP 1 "nonimmediate_operand" "")
11715           (match_operand:SI 2 "const_0_to_255_operand" "")))]
11716   "TARGET_AVX"
11717 {
11718   int mask = INTVAL (operands[2]);
11719   rtx perm[<ssescalarnum>];
11720
11721   perm[0] = GEN_INT (mask & 1);
11722   perm[1] = GEN_INT ((mask >> 1) & 1);
11723   if (<MODE>mode == V4DFmode)
11724     {
11725       perm[2] = GEN_INT (((mask >> 2) & 1) + 2);
11726       perm[3] = GEN_INT (((mask >> 3) & 1) + 2);
11727     }
11728
11729   operands[2]
11730     = gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (<ssescalarnum>, perm));
11731 })
11732
11733 (define_expand "avx_vpermil<mode>"
11734   [(set (match_operand:AVXMODEFSP 0 "register_operand" "")
11735         (vec_select:AVXMODEFSP
11736           (match_operand:AVXMODEFSP 1 "nonimmediate_operand" "")
11737           (match_operand:SI 2 "const_0_to_255_operand" "")))]
11738   "TARGET_AVX"
11739 {
11740   int mask = INTVAL (operands[2]);
11741   rtx perm[<ssescalarnum>];
11742
11743   perm[0] = GEN_INT (mask & 3);
11744   perm[1] = GEN_INT ((mask >> 2) & 3);
11745   perm[2] = GEN_INT ((mask >> 4) & 3);
11746   perm[3] = GEN_INT ((mask >> 6) & 3);
11747   if (<MODE>mode == V8SFmode)
11748     {
11749       perm[4] = GEN_INT ((mask & 3) + 4);
11750       perm[5] = GEN_INT (((mask >> 2) & 3) + 4);
11751       perm[6] = GEN_INT (((mask >> 4) & 3) + 4);
11752       perm[7] = GEN_INT (((mask >> 6) & 3) + 4);
11753     }
11754
11755   operands[2]
11756     = gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (<ssescalarnum>, perm));
11757 })
11758
11759 (define_insn "*avx_vpermilp<mode>"
11760   [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x")
11761         (vec_select:AVXMODEF2P
11762           (match_operand:AVXMODEF2P 1 "nonimmediate_operand" "xm")
11763           (match_parallel 2 "avx_vpermilp_<mode>_operand"
11764             [(match_operand 3 "const_int_operand" "")])))]
11765   "TARGET_AVX"
11766 {
11767   int mask = avx_vpermilp_parallel (operands[2], <MODE>mode) - 1;
11768   operands[2] = GEN_INT (mask);
11769   return "vpermil<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}";
11770 }
11771   [(set_attr "type" "sselog")
11772    (set_attr "prefix_extra" "1")
11773    (set_attr "length_immediate" "1")
11774    (set_attr "prefix" "vex")
11775    (set_attr "mode" "<MODE>")])
11776
11777 (define_insn "avx_vpermilvar<mode>3"
11778   [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x")
11779         (unspec:AVXMODEF2P
11780           [(match_operand:AVXMODEF2P 1 "register_operand" "x")
11781            (match_operand:<avxpermvecmode> 2 "nonimmediate_operand" "xm")]
11782           UNSPEC_VPERMIL))]
11783   "TARGET_AVX"
11784   "vpermil<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
11785   [(set_attr "type" "sselog")
11786    (set_attr "prefix_extra" "1")
11787    (set_attr "prefix" "vex")
11788    (set_attr "mode" "<MODE>")])
11789
11790 (define_expand "avx_vperm2f128<mode>3"
11791   [(set (match_operand:AVX256MODE2P 0 "register_operand" "")
11792         (unspec:AVX256MODE2P
11793           [(match_operand:AVX256MODE2P 1 "register_operand" "")
11794            (match_operand:AVX256MODE2P 2 "nonimmediate_operand" "")
11795            (match_operand:SI 3 "const_0_to_255_operand" "")]
11796           UNSPEC_VPERMIL2F128))]
11797   "TARGET_AVX"
11798 {
11799   int mask = INTVAL (operands[3]);
11800   if ((mask & 0x88) == 0)
11801     {
11802       rtx perm[<ssescalarnum>], t1, t2;
11803       int i, base, nelt = <ssescalarnum>, nelt2 = nelt / 2;
11804
11805       base = (mask & 3) * nelt2;
11806       for (i = 0; i < nelt2; ++i)
11807         perm[i] = GEN_INT (base + i);
11808
11809       base = ((mask >> 4) & 3) * nelt2;
11810       for (i = 0; i < nelt2; ++i)
11811         perm[i + nelt2] = GEN_INT (base + i);
11812
11813       t2 = gen_rtx_VEC_CONCAT (<ssedoublesizemode>mode,
11814                                operands[1], operands[2]);
11815       t1 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelt, perm));
11816       t2 = gen_rtx_VEC_SELECT (<MODE>mode, t2, t1);
11817       t2 = gen_rtx_SET (VOIDmode, operands[0], t2);
11818       emit_insn (t2);
11819       DONE;
11820     }
11821 })
11822
11823 ;; Note that bits 7 and 3 of the imm8 allow lanes to be zeroed, which
11824 ;; means that in order to represent this properly in rtl we'd have to
11825 ;; nest *another* vec_concat with a zero operand and do the select from
11826 ;; a 4x wide vector.  That doesn't seem very nice.
11827 (define_insn "*avx_vperm2f128<mode>_full"
11828   [(set (match_operand:AVX256MODE2P 0 "register_operand" "=x")
11829         (unspec:AVX256MODE2P
11830           [(match_operand:AVX256MODE2P 1 "register_operand" "x")
11831            (match_operand:AVX256MODE2P 2 "nonimmediate_operand" "xm")
11832            (match_operand:SI 3 "const_0_to_255_operand" "n")]
11833           UNSPEC_VPERMIL2F128))]
11834   "TARGET_AVX"
11835   "vperm2f128\t{%3, %2, %1, %0|%0, %1, %2, %3}"
11836   [(set_attr "type" "sselog")
11837    (set_attr "prefix_extra" "1")
11838    (set_attr "length_immediate" "1")
11839    (set_attr "prefix" "vex")
11840    (set_attr "mode" "V8SF")])
11841
11842 (define_insn "*avx_vperm2f128<mode>_nozero"
11843   [(set (match_operand:AVX256MODE2P 0 "register_operand" "=x")
11844         (vec_select:AVX256MODE2P
11845           (vec_concat:<ssedoublesizemode>
11846             (match_operand:AVX256MODE2P 1 "register_operand" "x")
11847             (match_operand:AVX256MODE2P 2 "nonimmediate_operand" "xm"))
11848           (match_parallel 3 "avx_vperm2f128_<mode>_operand"
11849             [(match_operand 4 "const_int_operand" "")])))]
11850   "TARGET_AVX"
11851 {
11852   int mask = avx_vperm2f128_parallel (operands[3], <MODE>mode) - 1;
11853   operands[3] = GEN_INT (mask);
11854   return "vperm2f128\t{%3, %2, %1, %0|%0, %1, %2, %3}";
11855 }
11856   [(set_attr "type" "sselog")
11857    (set_attr "prefix_extra" "1")
11858    (set_attr "length_immediate" "1")
11859    (set_attr "prefix" "vex")
11860    (set_attr "mode" "V8SF")])
11861
11862 (define_expand "avx_vinsertf128<mode>"
11863   [(match_operand:AVX256MODE 0 "register_operand" "")
11864    (match_operand:AVX256MODE 1 "register_operand" "")
11865    (match_operand:<avxhalfvecmode> 2 "nonimmediate_operand" "")
11866    (match_operand:SI 3 "const_0_to_1_operand" "")]
11867   "TARGET_AVX"
11868 {
11869   switch (INTVAL (operands[3]))
11870     {
11871     case 0:
11872       emit_insn (gen_vec_set_lo_<mode> (operands[0], operands[1],
11873                                         operands[2]));
11874       break;
11875     case 1:
11876       emit_insn (gen_vec_set_hi_<mode> (operands[0], operands[1],
11877                                         operands[2]));
11878       break;
11879     default:
11880       gcc_unreachable ();
11881     }
11882   DONE;
11883 })
11884
11885 (define_insn "vec_set_lo_<mode>"
11886   [(set (match_operand:AVX256MODE4P 0 "register_operand" "=x")
11887         (vec_concat:AVX256MODE4P
11888           (match_operand:<avxhalfvecmode> 2 "nonimmediate_operand" "xm")
11889           (vec_select:<avxhalfvecmode>
11890             (match_operand:AVX256MODE4P 1 "register_operand" "x")
11891             (parallel [(const_int 2) (const_int 3)]))))]
11892   "TARGET_AVX"
11893   "vinsertf128\t{$0x0, %2, %1, %0|%0, %1, %2, 0x0}"
11894   [(set_attr "type" "sselog")
11895    (set_attr "prefix_extra" "1")
11896    (set_attr "length_immediate" "1")
11897    (set_attr "prefix" "vex")
11898    (set_attr "mode" "V8SF")])
11899
11900 (define_insn "vec_set_hi_<mode>"
11901   [(set (match_operand:AVX256MODE4P 0 "register_operand" "=x")
11902         (vec_concat:AVX256MODE4P
11903           (vec_select:<avxhalfvecmode>
11904             (match_operand:AVX256MODE4P 1 "register_operand" "x")
11905             (parallel [(const_int 0) (const_int 1)]))
11906           (match_operand:<avxhalfvecmode> 2 "nonimmediate_operand" "xm")))]
11907   "TARGET_AVX"
11908   "vinsertf128\t{$0x1, %2, %1, %0|%0, %1, %2, 0x1}"
11909   [(set_attr "type" "sselog")
11910    (set_attr "prefix_extra" "1")
11911    (set_attr "length_immediate" "1")
11912    (set_attr "prefix" "vex")
11913    (set_attr "mode" "V8SF")])
11914
11915 (define_insn "vec_set_lo_<mode>"
11916   [(set (match_operand:AVX256MODE8P 0 "register_operand" "=x")
11917         (vec_concat:AVX256MODE8P
11918           (match_operand:<avxhalfvecmode> 2 "nonimmediate_operand" "xm")
11919           (vec_select:<avxhalfvecmode>
11920             (match_operand:AVX256MODE8P 1 "register_operand" "x")
11921             (parallel [(const_int 4) (const_int 5)
11922                        (const_int 6) (const_int 7)]))))]
11923   "TARGET_AVX"
11924   "vinsertf128\t{$0x0, %2, %1, %0|%0, %1, %2, 0x0}"
11925   [(set_attr "type" "sselog")
11926    (set_attr "prefix_extra" "1")
11927    (set_attr "length_immediate" "1")
11928    (set_attr "prefix" "vex")
11929    (set_attr "mode" "V8SF")])
11930
11931 (define_insn "vec_set_hi_<mode>"
11932   [(set (match_operand:AVX256MODE8P 0 "register_operand" "=x")
11933         (vec_concat:AVX256MODE8P
11934           (vec_select:<avxhalfvecmode>
11935             (match_operand:AVX256MODE8P 1 "register_operand" "x")
11936             (parallel [(const_int 0) (const_int 1)
11937                        (const_int 2) (const_int 3)]))
11938           (match_operand:<avxhalfvecmode> 2 "nonimmediate_operand" "xm")))]
11939   "TARGET_AVX"
11940   "vinsertf128\t{$0x1, %2, %1, %0|%0, %1, %2, 0x1}"
11941   [(set_attr "type" "sselog")
11942    (set_attr "prefix_extra" "1")
11943    (set_attr "length_immediate" "1")
11944    (set_attr "prefix" "vex")
11945    (set_attr "mode" "V8SF")])
11946
11947 (define_insn "vec_set_lo_v16hi"
11948   [(set (match_operand:V16HI 0 "register_operand" "=x")
11949         (vec_concat:V16HI
11950           (match_operand:V8HI 2 "nonimmediate_operand" "xm")
11951           (vec_select:V8HI
11952             (match_operand:V16HI 1 "register_operand" "x")
11953             (parallel [(const_int 8) (const_int 9)
11954                        (const_int 10) (const_int 11)
11955                        (const_int 12) (const_int 13)
11956                        (const_int 14) (const_int 15)]))))]
11957   "TARGET_AVX"
11958   "vinsertf128\t{$0x0, %2, %1, %0|%0, %1, %2, 0x0}"
11959   [(set_attr "type" "sselog")
11960    (set_attr "prefix_extra" "1")
11961    (set_attr "length_immediate" "1")
11962    (set_attr "prefix" "vex")
11963    (set_attr "mode" "V8SF")])
11964
11965 (define_insn "vec_set_hi_v16hi"
11966   [(set (match_operand:V16HI 0 "register_operand" "=x")
11967         (vec_concat:V16HI
11968           (vec_select:V8HI
11969             (match_operand:V16HI 1 "register_operand" "x")
11970             (parallel [(const_int 0) (const_int 1)
11971                        (const_int 2) (const_int 3)
11972                        (const_int 4) (const_int 5)
11973                        (const_int 6) (const_int 7)]))
11974           (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
11975   "TARGET_AVX"
11976   "vinsertf128\t{$0x1, %2, %1, %0|%0, %1, %2, 0x1}"
11977   [(set_attr "type" "sselog")
11978    (set_attr "prefix_extra" "1")
11979    (set_attr "length_immediate" "1")
11980    (set_attr "prefix" "vex")
11981    (set_attr "mode" "V8SF")])
11982
11983 (define_insn "vec_set_lo_v32qi"
11984   [(set (match_operand:V32QI 0 "register_operand" "=x")
11985         (vec_concat:V32QI
11986           (match_operand:V16QI 2 "nonimmediate_operand" "xm")
11987           (vec_select:V16QI
11988             (match_operand:V32QI 1 "register_operand" "x")
11989             (parallel [(const_int 16) (const_int 17)
11990                        (const_int 18) (const_int 19)
11991                        (const_int 20) (const_int 21)
11992                        (const_int 22) (const_int 23)
11993                        (const_int 24) (const_int 25)
11994                        (const_int 26) (const_int 27)
11995                        (const_int 28) (const_int 29)
11996                        (const_int 30) (const_int 31)]))))]
11997   "TARGET_AVX"
11998   "vinsertf128\t{$0x0, %2, %1, %0|%0, %1, %2, 0x0}"
11999   [(set_attr "type" "sselog")
12000    (set_attr "prefix_extra" "1")
12001    (set_attr "length_immediate" "1")
12002    (set_attr "prefix" "vex")
12003    (set_attr "mode" "V8SF")])
12004
12005 (define_insn "vec_set_hi_v32qi"
12006   [(set (match_operand:V32QI 0 "register_operand" "=x")
12007         (vec_concat:V32QI
12008           (vec_select:V16QI
12009             (match_operand:V32QI 1 "register_operand" "x")
12010             (parallel [(const_int 0) (const_int 1)
12011                        (const_int 2) (const_int 3)
12012                        (const_int 4) (const_int 5)
12013                        (const_int 6) (const_int 7)
12014                        (const_int 8) (const_int 9)
12015                        (const_int 10) (const_int 11)
12016                        (const_int 12) (const_int 13)
12017                        (const_int 14) (const_int 15)]))
12018           (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
12019   "TARGET_AVX"
12020   "vinsertf128\t{$0x1, %2, %1, %0|%0, %1, %2, 0x1}"
12021   [(set_attr "type" "sselog")
12022    (set_attr "prefix_extra" "1")
12023    (set_attr "length_immediate" "1")
12024    (set_attr "prefix" "vex")
12025    (set_attr "mode" "V8SF")])
12026
12027 (define_insn "avx_maskload<ssemodesuffix><avxmodesuffix>"
12028   [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x")
12029         (unspec:AVXMODEF2P
12030           [(match_operand:AVXMODEF2P 1 "memory_operand" "m")
12031            (match_operand:AVXMODEF2P 2 "register_operand" "x")
12032            (match_dup 0)]
12033           UNSPEC_MASKLOAD))]
12034   "TARGET_AVX"
12035   "vmaskmov<ssemodesuffix>\t{%1, %2, %0|%0, %2, %1}"
12036   [(set_attr "type" "sselog1")
12037    (set_attr "prefix_extra" "1")
12038    (set_attr "prefix" "vex")
12039    (set_attr "mode" "<MODE>")])
12040
12041 (define_insn "avx_maskstore<ssemodesuffix><avxmodesuffix>"
12042   [(set (match_operand:AVXMODEF2P 0 "memory_operand" "=m")
12043         (unspec:AVXMODEF2P
12044           [(match_operand:AVXMODEF2P 1 "register_operand" "x")
12045            (match_operand:AVXMODEF2P 2 "register_operand" "x")
12046            (match_dup 0)]
12047           UNSPEC_MASKSTORE))]
12048   "TARGET_AVX"
12049   "vmaskmov<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
12050   [(set_attr "type" "sselog1")
12051    (set_attr "prefix_extra" "1")
12052    (set_attr "prefix" "vex")
12053    (set_attr "mode" "<MODE>")])
12054
12055 (define_insn_and_split "avx_<avxmodesuffixp><avxmodesuffix>_<avxmodesuffixp>"
12056   [(set (match_operand:AVX256MODE2P 0 "nonimmediate_operand" "=x,m")
12057         (unspec:AVX256MODE2P
12058           [(match_operand:<avxhalfvecmode> 1 "nonimmediate_operand" "xm,x")]
12059           UNSPEC_CAST))]
12060   "TARGET_AVX"
12061   "#"
12062   "&& reload_completed"
12063   [(const_int 0)]
12064 {
12065   rtx op1 = operands[1];
12066   if (REG_P (op1))
12067     op1 = gen_rtx_REG (<MODE>mode, REGNO (op1));
12068   else
12069     op1 = gen_lowpart (<MODE>mode, op1);
12070   emit_move_insn (operands[0], op1);
12071   DONE;
12072 })
12073
12074 (define_expand "vec_init<mode>"
12075   [(match_operand:AVX256MODE 0 "register_operand" "")
12076    (match_operand 1 "" "")]
12077   "TARGET_AVX"
12078 {
12079   ix86_expand_vector_init (false, operands[0], operands[1]);
12080   DONE;
12081 })
12082
12083 (define_insn "*vec_concat<mode>_avx"
12084   [(set (match_operand:AVX256MODE 0 "register_operand"   "=x,x")
12085         (vec_concat:AVX256MODE
12086           (match_operand:<avxhalfvecmode> 1 "register_operand" "x,x")
12087           (match_operand:<avxhalfvecmode> 2 "vector_move_operand" "xm,C")))]
12088   "TARGET_AVX"
12089 {
12090   switch (which_alternative)
12091     {
12092     case 0:
12093       return "vinsertf128\t{$0x1, %2, %t1, %0|%0, %t1, %2, 0x1}";
12094     case 1:
12095       switch (get_attr_mode (insn))
12096         {
12097         case MODE_V8SF:
12098           return "vmovaps\t{%1, %x0|%x0, %1}";
12099         case MODE_V4DF:
12100           return "vmovapd\t{%1, %x0|%x0, %1}";
12101         default:
12102           return "vmovdqa\t{%1, %x0|%x0, %1}";
12103         }
12104     default:
12105       gcc_unreachable ();
12106     }
12107 }
12108   [(set_attr "type" "sselog,ssemov")
12109    (set_attr "prefix_extra" "1,*")
12110    (set_attr "length_immediate" "1,*")
12111    (set_attr "prefix" "vex")
12112    (set_attr "mode" "<avxvecmode>")])
12113
12114 (define_insn "vcvtph2ps"
12115   [(set (match_operand:V4SF 0 "register_operand" "=x")
12116         (vec_select:V4SF
12117           (unspec:V8SF [(match_operand:V8HI 1 "register_operand" "x")]
12118                        UNSPEC_VCVTPH2PS)
12119           (parallel [(const_int 0) (const_int 1)
12120                      (const_int 1) (const_int 2)])))]
12121   "TARGET_F16C"
12122   "vcvtph2ps\t{%1, %0|%0, %1}"
12123   [(set_attr "type" "ssecvt")
12124    (set_attr "prefix" "vex")
12125    (set_attr "mode" "V4SF")])
12126
12127 (define_insn "*vcvtph2ps_load"
12128   [(set (match_operand:V4SF 0 "register_operand" "=x")
12129         (unspec:V4SF [(match_operand:V4HI 1 "memory_operand" "m")]
12130                      UNSPEC_VCVTPH2PS))]
12131   "TARGET_F16C"
12132   "vcvtph2ps\t{%1, %0|%0, %1}"
12133   [(set_attr "type" "ssecvt")
12134    (set_attr "prefix" "vex")
12135    (set_attr "mode" "V8SF")])
12136
12137 (define_insn "vcvtph2ps256"
12138   [(set (match_operand:V8SF 0 "register_operand" "=x")
12139         (unspec:V8SF [(match_operand:V8HI 1 "nonimmediate_operand" "xm")]
12140                      UNSPEC_VCVTPH2PS))]
12141   "TARGET_F16C"
12142   "vcvtph2ps\t{%1, %0|%0, %1}"
12143   [(set_attr "type" "ssecvt")
12144    (set_attr "prefix" "vex")
12145    (set_attr "mode" "V8SF")])
12146
12147 (define_expand "vcvtps2ph"
12148   [(set (match_operand:V8HI 0 "register_operand" "")
12149         (vec_concat:V8HI
12150           (unspec:V4HI [(match_operand:V4SF 1 "register_operand" "")
12151                         (match_operand:SI 2 "immediate_operand" "")]
12152                        UNSPEC_VCVTPS2PH)
12153           (match_dup 3)))]
12154   "TARGET_F16C"
12155   "operands[3] = CONST0_RTX (V4HImode);")
12156
12157 (define_insn "*vcvtps2ph"
12158   [(set (match_operand:V8HI 0 "register_operand" "=x")
12159         (vec_concat:V8HI
12160           (unspec:V4HI [(match_operand:V4SF 1 "register_operand" "x")
12161                         (match_operand:SI 2 "immediate_operand" "N")]
12162                        UNSPEC_VCVTPS2PH)
12163           (match_operand:V4HI 3 "const0_operand" "")))]
12164   "TARGET_F16C"
12165   "vcvtps2ph\t{%2, %1, %0|%0, %1, %2}"
12166   [(set_attr "type" "ssecvt")
12167    (set_attr "prefix" "vex")
12168    (set_attr "mode" "V4SF")])
12169
12170 (define_insn "*vcvtps2ph_store"
12171   [(set (match_operand:V4HI 0 "memory_operand" "=m")
12172         (unspec:V4HI [(match_operand:V4SF 1 "register_operand" "x")
12173                       (match_operand:SI 2 "immediate_operand" "N")]
12174                      UNSPEC_VCVTPS2PH))]
12175   "TARGET_F16C"
12176   "vcvtps2ph\t{%2, %1, %0|%0, %1, %2}"
12177   [(set_attr "type" "ssecvt")
12178    (set_attr "prefix" "vex")
12179    (set_attr "mode" "V4SF")])
12180
12181 (define_insn "vcvtps2ph256"
12182   [(set (match_operand:V8HI 0 "nonimmediate_operand" "=xm")
12183         (unspec:V8HI [(match_operand:V8SF 1 "register_operand" "x")
12184                       (match_operand:SI 2 "immediate_operand" "N")]
12185                      UNSPEC_VCVTPS2PH))]
12186   "TARGET_F16C"
12187   "vcvtps2ph\t{%2, %1, %0|%0, %1, %2}"
12188   [(set_attr "type" "ssecvt")
12189    (set_attr "prefix" "vex")
12190    (set_attr "mode" "V8SF")])