OSDN Git Service

5311402031163f247beeb8d8cbb4a625538c0dca
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / sse.md
1 ;; GCC machine description for SSE instructions
2 ;; Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011
3 ;; Free Software Foundation, Inc.
4 ;;
5 ;; This file is part of GCC.
6 ;;
7 ;; GCC is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 3, or (at your option)
10 ;; any later version.
11 ;;
12 ;; GCC is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 ;; GNU General Public License for more details.
16 ;;
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3.  If not see
19 ;; <http://www.gnu.org/licenses/>.
20
21 ;; All vector modes including V?TImode, used in move patterns.
22 (define_mode_iterator V16
23   [(V32QI "TARGET_AVX") V16QI
24    (V16HI "TARGET_AVX") V8HI
25    (V8SI "TARGET_AVX") V4SI
26    (V4DI "TARGET_AVX") V2DI
27    (V2TI "TARGET_AVX") V1TI
28    (V8SF "TARGET_AVX") V4SF
29    (V4DF "TARGET_AVX") V2DF])
30
31 ;; All vector modes
32 (define_mode_iterator V
33   [(V32QI "TARGET_AVX") V16QI
34    (V16HI "TARGET_AVX") V8HI
35    (V8SI "TARGET_AVX") V4SI
36    (V4DI "TARGET_AVX") V2DI
37    (V8SF "TARGET_AVX") V4SF
38    (V4DF "TARGET_AVX") (V2DF "TARGET_SSE2")])
39
40 ;; All 128bit vector modes
41 (define_mode_iterator V_128
42   [V16QI V8HI V4SI V2DI V4SF (V2DF "TARGET_SSE2")])
43
44 ;; All 256bit vector modes
45 (define_mode_iterator V_256
46   [V32QI V16HI V8SI V4DI V8SF V4DF])
47
48 ;; All vector float modes
49 (define_mode_iterator VF
50   [(V8SF "TARGET_AVX") V4SF
51    (V4DF "TARGET_AVX") (V2DF "TARGET_SSE2")])
52
53 ;; All SFmode vector float modes
54 (define_mode_iterator VF1
55   [(V8SF "TARGET_AVX") V4SF])
56
57 ;; All DFmode vector float modes
58 (define_mode_iterator VF2
59   [(V4DF "TARGET_AVX") V2DF])
60
61 ;; All 128bit vector float modes
62 (define_mode_iterator VF_128
63   [V4SF (V2DF "TARGET_SSE2")])
64
65 ;; All 256bit vector float modes
66 (define_mode_iterator VF_256
67   [V8SF V4DF])
68
69 ;; All vector integer modes
70 (define_mode_iterator VI
71   [(V32QI "TARGET_AVX") V16QI
72    (V16HI "TARGET_AVX") V8HI
73    (V8SI "TARGET_AVX") V4SI
74    (V4DI "TARGET_AVX") V2DI])
75
76 (define_mode_iterator VI_AVX2
77   [(V32QI "TARGET_AVX2") V16QI
78    (V16HI "TARGET_AVX2") V8HI
79    (V8SI "TARGET_AVX2") V4SI
80    (V4DI "TARGET_AVX2") V2DI])
81
82 ;; All QImode vector integer modes
83 (define_mode_iterator VI1
84   [(V32QI "TARGET_AVX") V16QI])
85
86 ;; All DImode vector integer modes
87 (define_mode_iterator VI8
88   [(V4DI "TARGET_AVX") V2DI])
89
90 (define_mode_iterator VI1_AVX2
91   [(V32QI "TARGET_AVX2") V16QI])
92
93 (define_mode_iterator VI2_AVX2
94   [(V16HI "TARGET_AVX2") V8HI])
95
96 (define_mode_iterator VI4_AVX2
97   [(V8SI "TARGET_AVX2") V4SI])
98
99 (define_mode_iterator VI8_AVX2
100   [(V4DI "TARGET_AVX2") V2DI])
101
102 ;; ??? We should probably use TImode instead.
103 (define_mode_iterator VIMAX_AVX2
104   [(V2TI "TARGET_AVX2") V1TI])
105
106 ;; ??? This should probably be dropped in favor of VIMAX_AVX2.
107 (define_mode_iterator SSESCALARMODE
108   [(V2TI "TARGET_AVX2") TI])
109
110 (define_mode_iterator VI12_AVX2
111   [(V32QI "TARGET_AVX2") V16QI
112    (V16HI "TARGET_AVX2") V8HI])
113
114 (define_mode_iterator VI24_AVX2
115   [(V16HI "TARGET_AVX2") V8HI
116    (V8SI "TARGET_AVX2") V4SI])
117
118 (define_mode_iterator VI124_AVX2
119   [(V32QI "TARGET_AVX2") V16QI
120    (V16HI "TARGET_AVX2") V8HI
121    (V8SI "TARGET_AVX2") V4SI])
122
123 (define_mode_iterator VI248_AVX2
124   [(V16HI "TARGET_AVX2") V8HI
125    (V8SI "TARGET_AVX2") V4SI
126    (V4DI "TARGET_AVX2") V2DI])
127
128 (define_mode_iterator VI48_AVX2
129   [(V8SI "TARGET_AVX2") V4SI
130    (V4DI "TARGET_AVX2") V2DI])
131
132 (define_mode_iterator V48_AVX2
133   [V4SF V2DF
134    V8SF V4DF
135    (V4SI "TARGET_AVX2") (V2DI "TARGET_AVX2")
136    (V8SI "TARGET_AVX2") (V4DI "TARGET_AVX2")])
137
138 (define_mode_attr sse2_avx2
139   [(V16QI "sse2") (V32QI "avx2")
140    (V8HI "sse2") (V16HI "avx2")
141    (V4SI "sse2") (V8SI "avx2")
142    (V2DI "sse2") (V4DI "avx2")
143    (V1TI "sse2") (V2TI "avx2")])
144
145 (define_mode_attr ssse3_avx2
146    [(V16QI "ssse3") (V32QI "avx2")
147     (V8HI "ssse3") (V16HI "avx2")
148     (V4SI "ssse3") (V8SI "avx2")
149     (V2DI "ssse3") (V4DI "avx2")
150     (TI "ssse3") (V2TI "avx2")])
151
152 (define_mode_attr sse4_1_avx2
153    [(V16QI "sse4_1") (V32QI "avx2")
154     (V8HI "sse4_1") (V16HI "avx2")
155     (V4SI "sse4_1") (V8SI "avx2")
156     (V2DI "sse4_1") (V4DI "avx2")])
157
158 (define_mode_attr avx_avx2
159   [(V4SF "avx") (V2DF "avx")
160    (V8SF "avx") (V4DF "avx")
161    (V4SI "avx2") (V2DI "avx2")
162    (V8SI "avx2") (V4DI "avx2")])
163
164 (define_mode_attr vec_avx2
165   [(V16QI "vec") (V32QI "avx2")
166    (V8HI "vec") (V16HI "avx2")
167    (V4SI "vec") (V8SI "avx2")
168    (V2DI "vec") (V4DI "avx2")])
169
170 (define_mode_attr ssedoublemode
171   [(V16HI "V16SI") (V8HI "V8SI")])
172
173 (define_mode_attr ssebytemode
174   [(V4DI "V32QI") (V2DI "V16QI")])
175
176 ;; All 128bit vector integer modes
177 (define_mode_iterator VI_128 [V16QI V8HI V4SI V2DI])
178
179 ;; All 256bit vector integer modes
180 (define_mode_iterator VI_256 [V32QI V16HI V8SI V4DI])
181
182 ;; Random 128bit vector integer mode combinations
183 (define_mode_iterator VI12_128 [V16QI V8HI])
184 (define_mode_iterator VI14_128 [V16QI V4SI])
185 (define_mode_iterator VI124_128 [V16QI V8HI V4SI])
186 (define_mode_iterator VI128_128 [V16QI V8HI V2DI])
187 (define_mode_iterator VI24_128 [V8HI V4SI])
188 (define_mode_iterator VI248_128 [V8HI V4SI V2DI])
189 (define_mode_iterator VI48_128 [V4SI V2DI])
190
191 ;; Random 256bit vector integer mode combinations
192 (define_mode_iterator VI124_256 [V32QI V16HI V8SI])
193 (define_mode_iterator VI48_256 [V8SI V4DI])
194
195 ;; Int-float size matches
196 (define_mode_iterator VI4F_128 [V4SI V4SF])
197 (define_mode_iterator VI8F_128 [V2DI V2DF])
198 (define_mode_iterator VI4F_256 [V8SI V8SF])
199 (define_mode_iterator VI8F_256 [V4DI V4DF])
200
201 ;; Mapping from float mode to required SSE level
202 (define_mode_attr sse
203   [(SF "sse") (DF "sse2")
204    (V4SF "sse") (V2DF "sse2")
205    (V8SF "avx") (V4DF "avx")])
206
207 (define_mode_attr sse2
208   [(V16QI "sse2") (V32QI "avx")
209    (V2DI "sse2") (V4DI "avx")])
210
211 (define_mode_attr sse3
212   [(V16QI "sse3") (V32QI "avx")])
213
214 (define_mode_attr sse4_1
215   [(V4SF "sse4_1") (V2DF "sse4_1")
216    (V8SF "avx") (V4DF "avx")])
217
218 (define_mode_attr avxsizesuffix
219   [(V32QI "256") (V16HI "256") (V8SI "256") (V4DI "256")
220    (V16QI "") (V8HI "") (V4SI "") (V2DI "")
221    (V8SF "256") (V4DF "256")
222    (V4SF "") (V2DF "")])
223
224 ;; SSE instruction mode
225 (define_mode_attr sseinsnmode
226   [(V32QI "OI") (V16HI "OI") (V8SI "OI") (V4DI "OI") (V2TI "OI")
227    (V16QI "TI") (V8HI "TI") (V4SI "TI") (V2DI "TI") (V1TI "TI")
228    (V8SF "V8SF") (V4DF "V4DF")
229    (V4SF "V4SF") (V2DF "V2DF")
230    (TI "TI")])
231
232 ;; Mapping of vector float modes to an integer mode of the same size
233 (define_mode_attr sseintvecmode
234   [(V8SF "V8SI") (V4DF "V4DI")
235    (V4SF "V4SI") (V2DF "V2DI")
236    (V4DF "V4DI") (V8SF "V8SI")
237    (V8SI "V8SI") (V4DI "V4DI")
238    (V4SI "V4SI") (V2DI "V2DI")
239    (V16HI "V16HI") (V8HI "V8HI")
240    (V32QI "V32QI") (V16QI "V16QI")])
241
242 ;; Mapping of vector modes to a vector mode of double size
243 (define_mode_attr ssedoublevecmode
244   [(V32QI "V64QI") (V16HI "V32HI") (V8SI "V16SI") (V4DI "V8DI")
245    (V16QI "V32QI") (V8HI "V16HI") (V4SI "V8SI") (V2DI "V4DI")
246    (V8SF "V16SF") (V4DF "V8DF")
247    (V4SF "V8SF") (V2DF "V4DF")])
248
249 ;; Mapping of vector modes to a vector mode of half size
250 (define_mode_attr ssehalfvecmode
251   [(V32QI "V16QI") (V16HI "V8HI") (V8SI "V4SI") (V4DI "V2DI")
252    (V16QI  "V8QI") (V8HI  "V4HI") (V4SI "V2SI")
253    (V8SF "V4SF") (V4DF "V2DF")
254    (V4SF "V2SF")])
255
256 ;; Mapping of vector modes back to the scalar modes
257 (define_mode_attr ssescalarmode
258   [(V32QI "QI") (V16HI "HI") (V8SI "SI") (V4DI "DI")
259    (V16QI "QI") (V8HI "HI") (V4SI "SI") (V2DI "DI")
260    (V8SF "SF") (V4DF "DF")
261    (V4SF "SF") (V2DF "DF")])
262
263 ;; Number of scalar elements in each vector type
264 (define_mode_attr ssescalarnum
265   [(V32QI "32") (V16HI "16") (V8SI "8") (V4DI "4")
266    (V16QI "16") (V8HI "8") (V4SI "4") (V2DI "2")
267    (V8SF "8") (V4DF "4")
268    (V4SF "4") (V2DF "2")])
269
270 ;; SSE prefix for integer vector modes
271 (define_mode_attr sseintprefix
272   [(V2DI "p") (V2DF "")
273    (V4DI "p") (V4DF "")
274    (V4SI "p") (V4SF "")
275    (V8SI "p") (V8SF "")])
276
277 ;; SSE scalar suffix for vector modes
278 (define_mode_attr ssescalarmodesuffix
279   [(SF "ss") (DF "sd")
280    (V8SF "ss") (V4DF "sd")
281    (V4SF "ss") (V2DF "sd")
282    (V8SI "ss") (V4DI "sd")
283    (V4SI "d")])
284
285 ;; Pack/unpack vector modes
286 (define_mode_attr sseunpackmode
287   [(V16QI "V8HI") (V8HI "V4SI") (V4SI "V2DI")
288    (V32QI "V16HI") (V16HI "V8SI") (V8SI "V4DI")])
289
290 (define_mode_attr ssepackmode
291   [(V8HI "V16QI") (V4SI "V8HI") (V2DI "V4SI")
292    (V16HI "V32QI") (V8SI "V16HI") (V4DI "V8SI")])
293
294 ;; Mapping of the max integer size for xop rotate immediate constraint
295 (define_mode_attr sserotatemax
296   [(V16QI "7") (V8HI "15") (V4SI "31") (V2DI "63")])
297
298 ;; Mapping of mode to cast intrinsic name
299 (define_mode_attr castmode [(V8SI "si") (V8SF "ps") (V4DF "pd")])
300
301 ;; Instruction suffix for sign and zero extensions.
302 (define_code_attr extsuffix [(sign_extend "sx") (zero_extend "zx")])
303
304 ;; i128 for integer vectors and TARGET_AVX2, f128 otherwise.
305 (define_mode_attr i128
306   [(V8SF "f128") (V4DF "f128") (V32QI "%~128") (V16HI "%~128")
307    (V8SI "%~128") (V4DI "%~128")])
308
309 ;; Mix-n-match
310 (define_mode_iterator AVX256MODE2P [V8SI V8SF V4DF])
311
312 (define_mode_iterator AVXMODE48P_DI
313                       [V2DI V2DF V4DI V4DF V4SF V4SI])
314 (define_mode_attr AVXMODE48P_DI
315                       [(V2DI "V2DI") (V2DF "V2DI")
316                        (V4DI "V4DI") (V4DF "V4DI")
317                        (V4SI "V2DI") (V4SF "V2DI")
318                        (V8SI "V4DI") (V8SF "V4DI")])
319
320 (define_mode_iterator FMAMODE [SF DF V4SF V2DF V8SF V4DF])
321
322 ;; Mapping of immediate bits for blend instructions
323 (define_mode_attr blendbits
324   [(V8SF "255") (V4SF "15") (V4DF "15") (V2DF "3")])
325
326 ;; Patterns whose name begins with "sse{,2,3}_" are invoked by intrinsics.
327
328 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
329 ;;
330 ;; Move patterns
331 ;;
332 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
333
334 ;; All of these patterns are enabled for SSE1 as well as SSE2.
335 ;; This is essential for maintaining stable calling conventions.
336
337 (define_expand "mov<mode>"
338   [(set (match_operand:V16 0 "nonimmediate_operand" "")
339         (match_operand:V16 1 "nonimmediate_operand" ""))]
340   "TARGET_SSE"
341 {
342   ix86_expand_vector_move (<MODE>mode, operands);
343   DONE;
344 })
345
346 (define_insn "*mov<mode>_internal"
347   [(set (match_operand:V16 0 "nonimmediate_operand" "=x,x ,m")
348         (match_operand:V16 1 "nonimmediate_or_sse_const_operand"  "C ,xm,x"))]
349   "TARGET_SSE
350    && (register_operand (operands[0], <MODE>mode)
351        || register_operand (operands[1], <MODE>mode))"
352 {
353   switch (which_alternative)
354     {
355     case 0:
356       return standard_sse_constant_opcode (insn, operands[1]);
357     case 1:
358     case 2:
359       switch (get_attr_mode (insn))
360         {
361         case MODE_V8SF:
362         case MODE_V4SF:
363           if (TARGET_AVX
364               && (misaligned_operand (operands[0], <MODE>mode)
365                   || misaligned_operand (operands[1], <MODE>mode)))
366             return "vmovups\t{%1, %0|%0, %1}";
367           else
368             return "%vmovaps\t{%1, %0|%0, %1}";
369
370         case MODE_V4DF:
371         case MODE_V2DF:
372           if (TARGET_AVX
373               && (misaligned_operand (operands[0], <MODE>mode)
374                   || misaligned_operand (operands[1], <MODE>mode)))
375             return "vmovupd\t{%1, %0|%0, %1}";
376           else if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
377             return "%vmovaps\t{%1, %0|%0, %1}";
378           else
379             return "%vmovapd\t{%1, %0|%0, %1}";
380
381         case MODE_OI:
382         case MODE_TI:
383           if (TARGET_AVX
384               && (misaligned_operand (operands[0], <MODE>mode)
385                   || misaligned_operand (operands[1], <MODE>mode)))
386             return "vmovdqu\t{%1, %0|%0, %1}";
387           else if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
388             return "%vmovaps\t{%1, %0|%0, %1}";
389           else
390             return "%vmovdqa\t{%1, %0|%0, %1}";
391
392         default:
393           gcc_unreachable ();
394         }
395     default:
396       gcc_unreachable ();
397     }
398 }
399   [(set_attr "type" "sselog1,ssemov,ssemov")
400    (set_attr "prefix" "maybe_vex")
401    (set (attr "mode")
402         (cond [(match_test "TARGET_AVX")
403                  (const_string "<sseinsnmode>")
404                (ior (ior (match_test "optimize_function_for_size_p (cfun)")
405                          (not (match_test "TARGET_SSE2")))
406                     (and (eq_attr "alternative" "2")
407                          (match_test "TARGET_SSE_TYPELESS_STORES")))
408                  (const_string "V4SF")
409                (eq (const_string "<MODE>mode") (const_string "V4SFmode"))
410                  (const_string "V4SF")
411                (eq (const_string "<MODE>mode") (const_string "V2DFmode"))
412                  (const_string "V2DF")
413               ]
414           (const_string "TI")))])
415
416 (define_insn "sse2_movq128"
417   [(set (match_operand:V2DI 0 "register_operand" "=x")
418         (vec_concat:V2DI
419           (vec_select:DI
420             (match_operand:V2DI 1 "nonimmediate_operand" "xm")
421             (parallel [(const_int 0)]))
422           (const_int 0)))]
423   "TARGET_SSE2"
424   "%vmovq\t{%1, %0|%0, %1}"
425   [(set_attr "type" "ssemov")
426    (set_attr "prefix" "maybe_vex")
427    (set_attr "mode" "TI")])
428
429 ;; Move a DI from a 32-bit register pair (e.g. %edx:%eax) to an xmm.
430 ;; We'd rather avoid this entirely; if the 32-bit reg pair was loaded
431 ;; from memory, we'd prefer to load the memory directly into the %xmm
432 ;; register.  To facilitate this happy circumstance, this pattern won't
433 ;; split until after register allocation.  If the 64-bit value didn't
434 ;; come from memory, this is the best we can do.  This is much better
435 ;; than storing %edx:%eax into a stack temporary and loading an %xmm
436 ;; from there.
437
438 (define_insn_and_split "movdi_to_sse"
439   [(parallel
440     [(set (match_operand:V4SI 0 "register_operand" "=?x,x")
441           (subreg:V4SI (match_operand:DI 1 "nonimmediate_operand" "r,m") 0))
442      (clobber (match_scratch:V4SI 2 "=&x,X"))])]
443   "!TARGET_64BIT && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES"
444   "#"
445   "&& reload_completed"
446   [(const_int 0)]
447 {
448  if (register_operand (operands[1], DImode))
449    {
450       /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
451          Assemble the 64-bit DImode value in an xmm register.  */
452       emit_insn (gen_sse2_loadld (operands[0], CONST0_RTX (V4SImode),
453                                   gen_rtx_SUBREG (SImode, operands[1], 0)));
454       emit_insn (gen_sse2_loadld (operands[2], CONST0_RTX (V4SImode),
455                                   gen_rtx_SUBREG (SImode, operands[1], 4)));
456       emit_insn (gen_vec_interleave_lowv4si (operands[0], operands[0],
457                                              operands[2]));
458     }
459  else if (memory_operand (operands[1], DImode))
460    emit_insn (gen_vec_concatv2di (gen_lowpart (V2DImode, operands[0]),
461                                   operands[1], const0_rtx));
462  else
463    gcc_unreachable ();
464 })
465
466 (define_split
467   [(set (match_operand:V4SF 0 "register_operand" "")
468         (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
469   "TARGET_SSE && reload_completed"
470   [(set (match_dup 0)
471         (vec_merge:V4SF
472           (vec_duplicate:V4SF (match_dup 1))
473           (match_dup 2)
474           (const_int 1)))]
475 {
476   operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
477   operands[2] = CONST0_RTX (V4SFmode);
478 })
479
480 (define_split
481   [(set (match_operand:V2DF 0 "register_operand" "")
482         (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
483   "TARGET_SSE2 && reload_completed"
484   [(set (match_dup 0) (vec_concat:V2DF (match_dup 1) (match_dup 2)))]
485 {
486   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
487   operands[2] = CONST0_RTX (DFmode);
488 })
489
490 (define_expand "push<mode>1"
491   [(match_operand:V16 0 "register_operand" "")]
492   "TARGET_SSE"
493 {
494   ix86_expand_push (<MODE>mode, operands[0]);
495   DONE;
496 })
497
498 (define_expand "movmisalign<mode>"
499   [(set (match_operand:V16 0 "nonimmediate_operand" "")
500         (match_operand:V16 1 "nonimmediate_operand" ""))]
501   "TARGET_SSE"
502 {
503   ix86_expand_vector_move_misalign (<MODE>mode, operands);
504   DONE;
505 })
506
507 (define_expand "<sse>_movu<ssemodesuffix><avxsizesuffix>"
508   [(set (match_operand:VF 0 "nonimmediate_operand" "")
509         (unspec:VF
510           [(match_operand:VF 1 "nonimmediate_operand" "")]
511           UNSPEC_MOVU))]
512   "TARGET_SSE"
513 {
514   if (MEM_P (operands[0]) && MEM_P (operands[1]))
515     operands[1] = force_reg (<MODE>mode, operands[1]);
516 })
517
518 (define_insn "*<sse>_movu<ssemodesuffix><avxsizesuffix>"
519   [(set (match_operand:VF 0 "nonimmediate_operand" "=x,m")
520         (unspec:VF
521           [(match_operand:VF 1 "nonimmediate_operand" "xm,x")]
522           UNSPEC_MOVU))]
523   "TARGET_SSE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
524   "%vmovu<ssemodesuffix>\t{%1, %0|%0, %1}"
525   [(set_attr "type" "ssemov")
526    (set_attr "movu" "1")
527    (set_attr "prefix" "maybe_vex")
528    (set_attr "mode" "<MODE>")])
529
530 (define_expand "<sse2>_movdqu<avxsizesuffix>"
531   [(set (match_operand:VI1 0 "nonimmediate_operand" "")
532         (unspec:VI1 [(match_operand:VI1 1 "nonimmediate_operand" "")]
533                     UNSPEC_MOVU))]
534   "TARGET_SSE2"
535 {
536   if (MEM_P (operands[0]) && MEM_P (operands[1]))
537     operands[1] = force_reg (<MODE>mode, operands[1]);
538 })
539
540 (define_insn "*<sse2>_movdqu<avxsizesuffix>"
541   [(set (match_operand:VI1 0 "nonimmediate_operand" "=x,m")
542         (unspec:VI1 [(match_operand:VI1 1 "nonimmediate_operand" "xm,x")]
543                     UNSPEC_MOVU))]
544   "TARGET_SSE2 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
545   "%vmovdqu\t{%1, %0|%0, %1}"
546   [(set_attr "type" "ssemov")
547    (set_attr "movu" "1")
548    (set (attr "prefix_data16")
549      (if_then_else
550        (match_test "TARGET_AVX")
551      (const_string "*")
552      (const_string "1")))
553    (set_attr "prefix" "maybe_vex")
554    (set_attr "mode" "<sseinsnmode>")])
555
556 (define_insn "<sse3>_lddqu<avxsizesuffix>"
557   [(set (match_operand:VI1 0 "register_operand" "=x")
558         (unspec:VI1 [(match_operand:VI1 1 "memory_operand" "m")]
559                     UNSPEC_LDDQU))]
560   "TARGET_SSE3"
561   "%vlddqu\t{%1, %0|%0, %1}"
562   [(set_attr "type" "ssemov")
563    (set_attr "movu" "1")
564    (set (attr "prefix_data16")
565      (if_then_else
566        (match_test "TARGET_AVX")
567      (const_string "*")
568      (const_string "0")))
569    (set (attr "prefix_rep")
570      (if_then_else
571        (match_test "TARGET_AVX")
572      (const_string "*")
573      (const_string "1")))
574    (set_attr "prefix" "maybe_vex")
575    (set_attr "mode" "<sseinsnmode>")])
576
577 (define_insn "sse2_movntsi"
578   [(set (match_operand:SI 0 "memory_operand" "=m")
579         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
580                    UNSPEC_MOVNT))]
581   "TARGET_SSE2"
582   "movnti\t{%1, %0|%0, %1}"
583   [(set_attr "type" "ssemov")
584    (set_attr "prefix_data16" "0")
585    (set_attr "mode" "V2DF")])
586
587 (define_insn "<sse>_movnt<mode>"
588   [(set (match_operand:VF 0 "memory_operand" "=m")
589         (unspec:VF [(match_operand:VF 1 "register_operand" "x")]
590                    UNSPEC_MOVNT))]
591   "TARGET_SSE"
592   "%vmovnt<ssemodesuffix>\t{%1, %0|%0, %1}"
593   [(set_attr "type" "ssemov")
594    (set_attr "prefix" "maybe_vex")
595    (set_attr "mode" "<MODE>")])
596
597 (define_insn "<sse2>_movnt<mode>"
598   [(set (match_operand:VI8 0 "memory_operand" "=m")
599         (unspec:VI8 [(match_operand:VI8 1 "register_operand" "x")]
600                     UNSPEC_MOVNT))]
601   "TARGET_SSE2"
602   "%vmovntdq\t{%1, %0|%0, %1}"
603   [(set_attr "type" "ssecvt")
604    (set (attr "prefix_data16")
605      (if_then_else
606        (match_test "TARGET_AVX")
607      (const_string "*")
608      (const_string "1")))
609    (set_attr "prefix" "maybe_vex")
610    (set_attr "mode" "<sseinsnmode>")])
611
612 ; Expand patterns for non-temporal stores.  At the moment, only those
613 ; that directly map to insns are defined; it would be possible to
614 ; define patterns for other modes that would expand to several insns.
615
616 ;; Modes handled by storent patterns.
617 (define_mode_iterator STORENT_MODE
618   [(SI "TARGET_SSE2") (SF "TARGET_SSE4A") (DF "TARGET_SSE4A")
619    (V2DI "TARGET_SSE2")
620    (V8SF "TARGET_AVX") V4SF
621    (V4DF "TARGET_AVX") (V2DF "TARGET_SSE2")])
622
623 (define_expand "storent<mode>"
624   [(set (match_operand:STORENT_MODE 0 "memory_operand" "")
625         (unspec:STORENT_MODE
626           [(match_operand:STORENT_MODE 1 "register_operand" "")]
627           UNSPEC_MOVNT))]
628   "TARGET_SSE")
629
630 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
631 ;;
632 ;; Parallel floating point arithmetic
633 ;;
634 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
635
636 (define_expand "<code><mode>2"
637   [(set (match_operand:VF 0 "register_operand" "")
638         (absneg:VF
639           (match_operand:VF 1 "register_operand" "")))]
640   "TARGET_SSE"
641   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
642
643 (define_insn_and_split "*absneg<mode>2"
644   [(set (match_operand:VF 0 "register_operand" "=x,x,x,x")
645         (match_operator:VF 3 "absneg_operator"
646           [(match_operand:VF 1 "nonimmediate_operand" "0, xm,x, m")]))
647    (use (match_operand:VF 2 "nonimmediate_operand"    "xm,0, xm,x"))]
648   "TARGET_SSE"
649   "#"
650   "&& reload_completed"
651   [(const_int 0)]
652 {
653   enum rtx_code absneg_op;
654   rtx op1, op2;
655   rtx t;
656
657   if (TARGET_AVX)
658     {
659       if (MEM_P (operands[1]))
660         op1 = operands[2], op2 = operands[1];
661       else
662         op1 = operands[1], op2 = operands[2];
663     }
664   else
665     {
666       op1 = operands[0];
667       if (rtx_equal_p (operands[0], operands[1]))
668         op2 = operands[2];
669       else
670         op2 = operands[1];
671     }
672
673   absneg_op = GET_CODE (operands[3]) == NEG ? XOR : AND;
674   t = gen_rtx_fmt_ee (absneg_op, <MODE>mode, op1, op2);
675   t = gen_rtx_SET (VOIDmode, operands[0], t);
676   emit_insn (t);
677   DONE;
678 }
679   [(set_attr "isa" "noavx,noavx,avx,avx")])
680
681 (define_expand "<plusminus_insn><mode>3"
682   [(set (match_operand:VF 0 "register_operand" "")
683         (plusminus:VF
684           (match_operand:VF 1 "nonimmediate_operand" "")
685           (match_operand:VF 2 "nonimmediate_operand" "")))]
686   "TARGET_SSE"
687   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
688
689 (define_insn "*<plusminus_insn><mode>3"
690   [(set (match_operand:VF 0 "register_operand" "=x,x")
691         (plusminus:VF
692           (match_operand:VF 1 "nonimmediate_operand" "<comm>0,x")
693           (match_operand:VF 2 "nonimmediate_operand" "xm,xm")))]
694   "TARGET_SSE && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
695   "@
696    <plusminus_mnemonic><ssemodesuffix>\t{%2, %0|%0, %2}
697    v<plusminus_mnemonic><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
698   [(set_attr "isa" "noavx,avx")
699    (set_attr "type" "sseadd")
700    (set_attr "prefix" "orig,vex")
701    (set_attr "mode" "<MODE>")])
702
703 (define_insn "<sse>_vm<plusminus_insn><mode>3"
704   [(set (match_operand:VF_128 0 "register_operand" "=x,x")
705         (vec_merge:VF_128
706           (plusminus:VF_128
707             (match_operand:VF_128 1 "register_operand" "0,x")
708             (match_operand:VF_128 2 "nonimmediate_operand" "xm,xm"))
709           (match_dup 1)
710           (const_int 1)))]
711   "TARGET_SSE"
712   "@
713    <plusminus_mnemonic><ssescalarmodesuffix>\t{%2, %0|%0, %2}
714    v<plusminus_mnemonic><ssescalarmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
715   [(set_attr "isa" "noavx,avx")
716    (set_attr "type" "sseadd")
717    (set_attr "prefix" "orig,vex")
718    (set_attr "mode" "<ssescalarmode>")])
719
720 (define_expand "mul<mode>3"
721   [(set (match_operand:VF 0 "register_operand" "")
722         (mult:VF
723           (match_operand:VF 1 "nonimmediate_operand" "")
724           (match_operand:VF 2 "nonimmediate_operand" "")))]
725   "TARGET_SSE"
726   "ix86_fixup_binary_operands_no_copy (MULT, <MODE>mode, operands);")
727
728 (define_insn "*mul<mode>3"
729   [(set (match_operand:VF 0 "register_operand" "=x,x")
730         (mult:VF
731           (match_operand:VF 1 "nonimmediate_operand" "%0,x")
732           (match_operand:VF 2 "nonimmediate_operand" "xm,xm")))]
733   "TARGET_SSE && ix86_binary_operator_ok (MULT, <MODE>mode, operands)"
734   "@
735    mul<ssemodesuffix>\t{%2, %0|%0, %2}
736    vmul<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
737   [(set_attr "isa" "noavx,avx")
738    (set_attr "type" "ssemul")
739    (set_attr "prefix" "orig,vex")
740    (set_attr "mode" "<MODE>")])
741
742 (define_insn "<sse>_vmmul<mode>3"
743   [(set (match_operand:VF_128 0 "register_operand" "=x,x")
744         (vec_merge:VF_128
745           (mult:VF_128
746             (match_operand:VF_128 1 "register_operand" "0,x")
747             (match_operand:VF_128 2 "nonimmediate_operand" "xm,xm"))
748           (match_dup 1)
749           (const_int 1)))]
750   "TARGET_SSE"
751   "@
752    mul<ssescalarmodesuffix>\t{%2, %0|%0, %2}
753    vmul<ssescalarmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
754   [(set_attr "isa" "noavx,avx")
755    (set_attr "type" "ssemul")
756    (set_attr "prefix" "orig,vex")
757    (set_attr "mode" "<ssescalarmode>")])
758
759 (define_expand "div<mode>3"
760   [(set (match_operand:VF2 0 "register_operand" "")
761         (div:VF2 (match_operand:VF2 1 "register_operand" "")
762                  (match_operand:VF2 2 "nonimmediate_operand" "")))]
763   "TARGET_SSE2"
764   "ix86_fixup_binary_operands_no_copy (DIV, <MODE>mode, operands);")
765
766 (define_expand "div<mode>3"
767   [(set (match_operand:VF1 0 "register_operand" "")
768         (div:VF1 (match_operand:VF1 1 "register_operand" "")
769                  (match_operand:VF1 2 "nonimmediate_operand" "")))]
770   "TARGET_SSE"
771 {
772   ix86_fixup_binary_operands_no_copy (DIV, <MODE>mode, operands);
773
774   if (TARGET_SSE_MATH
775       && TARGET_RECIP_VEC_DIV
776       && !optimize_insn_for_size_p ()
777       && flag_finite_math_only && !flag_trapping_math
778       && flag_unsafe_math_optimizations)
779     {
780       ix86_emit_swdivsf (operands[0], operands[1], operands[2], <MODE>mode);
781       DONE;
782     }
783 })
784
785 (define_insn "<sse>_div<mode>3"
786   [(set (match_operand:VF 0 "register_operand" "=x,x")
787         (div:VF
788           (match_operand:VF 1 "register_operand" "0,x")
789           (match_operand:VF 2 "nonimmediate_operand" "xm,xm")))]
790   "TARGET_SSE"
791   "@
792    div<ssemodesuffix>\t{%2, %0|%0, %2}
793    vdiv<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
794   [(set_attr "isa" "noavx,avx")
795    (set_attr "type" "ssediv")
796    (set_attr "prefix" "orig,vex")
797    (set_attr "mode" "<MODE>")])
798
799 (define_insn "<sse>_vmdiv<mode>3"
800   [(set (match_operand:VF_128 0 "register_operand" "=x,x")
801         (vec_merge:VF_128
802           (div:VF_128
803             (match_operand:VF_128 1 "register_operand" "0,x")
804             (match_operand:VF_128 2 "nonimmediate_operand" "xm,xm"))
805           (match_dup 1)
806           (const_int 1)))]
807   "TARGET_SSE"
808   "@
809    div<ssescalarmodesuffix>\t{%2, %0|%0, %2}
810    vdiv<ssescalarmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
811   [(set_attr "isa" "noavx,avx")
812    (set_attr "type" "ssediv")
813    (set_attr "prefix" "orig,vex")
814    (set_attr "mode" "<ssescalarmode>")])
815
816 (define_insn "<sse>_rcp<mode>2"
817   [(set (match_operand:VF1 0 "register_operand" "=x")
818         (unspec:VF1
819           [(match_operand:VF1 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
820   "TARGET_SSE"
821   "%vrcpps\t{%1, %0|%0, %1}"
822   [(set_attr "type" "sse")
823    (set_attr "atom_sse_attr" "rcp")
824    (set_attr "prefix" "maybe_vex")
825    (set_attr "mode" "<MODE>")])
826
827 (define_insn "sse_vmrcpv4sf2"
828   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
829         (vec_merge:V4SF
830           (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,xm")]
831                        UNSPEC_RCP)
832           (match_operand:V4SF 2 "register_operand" "0,x")
833           (const_int 1)))]
834   "TARGET_SSE"
835   "@
836    rcpss\t{%1, %0|%0, %1}
837    vrcpss\t{%1, %2, %0|%0, %2, %1}"
838   [(set_attr "isa" "noavx,avx")
839    (set_attr "type" "sse")
840    (set_attr "atom_sse_attr" "rcp")
841    (set_attr "prefix" "orig,vex")
842    (set_attr "mode" "SF")])
843
844 (define_expand "sqrt<mode>2"
845   [(set (match_operand:VF2 0 "register_operand" "")
846         (sqrt:VF2 (match_operand:VF2 1 "nonimmediate_operand" "")))]
847   "TARGET_SSE2")
848
849 (define_expand "sqrt<mode>2"
850   [(set (match_operand:VF1 0 "register_operand" "")
851         (sqrt:VF1 (match_operand:VF1 1 "nonimmediate_operand" "")))]
852   "TARGET_SSE"
853 {
854   if (TARGET_SSE_MATH
855       && TARGET_RECIP_VEC_SQRT
856       && !optimize_insn_for_size_p ()
857       && flag_finite_math_only && !flag_trapping_math
858       && flag_unsafe_math_optimizations)
859     {
860       ix86_emit_swsqrtsf (operands[0], operands[1], <MODE>mode, false);
861       DONE;
862     }
863 })
864
865 (define_insn "<sse>_sqrt<mode>2"
866   [(set (match_operand:VF 0 "register_operand" "=x")
867         (sqrt:VF (match_operand:VF 1 "nonimmediate_operand" "xm")))]
868   "TARGET_SSE"
869   "%vsqrt<ssemodesuffix>\t{%1, %0|%0, %1}"
870   [(set_attr "type" "sse")
871    (set_attr "atom_sse_attr" "sqrt")
872    (set_attr "prefix" "maybe_vex")
873    (set_attr "mode" "<MODE>")])
874
875 (define_insn "<sse>_vmsqrt<mode>2"
876   [(set (match_operand:VF_128 0 "register_operand" "=x,x")
877         (vec_merge:VF_128
878           (sqrt:VF_128
879             (match_operand:VF_128 1 "nonimmediate_operand" "xm,xm"))
880           (match_operand:VF_128 2 "register_operand" "0,x")
881           (const_int 1)))]
882   "TARGET_SSE"
883   "@
884    sqrt<ssescalarmodesuffix>\t{%1, %0|%0, %1}
885    vsqrt<ssescalarmodesuffix>\t{%1, %2, %0|%0, %2, %1}"
886   [(set_attr "isa" "noavx,avx")
887    (set_attr "type" "sse")
888    (set_attr "atom_sse_attr" "sqrt")
889    (set_attr "prefix" "orig,vex")
890    (set_attr "mode" "<ssescalarmode>")])
891
892 (define_expand "rsqrt<mode>2"
893   [(set (match_operand:VF1 0 "register_operand" "")
894         (unspec:VF1
895           [(match_operand:VF1 1 "nonimmediate_operand" "")] UNSPEC_RSQRT))]
896   "TARGET_SSE_MATH"
897 {
898   ix86_emit_swsqrtsf (operands[0], operands[1], <MODE>mode, true);
899   DONE;
900 })
901
902 (define_insn "<sse>_rsqrt<mode>2"
903   [(set (match_operand:VF1 0 "register_operand" "=x")
904         (unspec:VF1
905           [(match_operand:VF1 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
906   "TARGET_SSE"
907   "%vrsqrtps\t{%1, %0|%0, %1}"
908   [(set_attr "type" "sse")
909    (set_attr "prefix" "maybe_vex")
910    (set_attr "mode" "<MODE>")])
911
912 (define_insn "sse_vmrsqrtv4sf2"
913   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
914         (vec_merge:V4SF
915           (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,xm")]
916                        UNSPEC_RSQRT)
917           (match_operand:V4SF 2 "register_operand" "0,x")
918           (const_int 1)))]
919   "TARGET_SSE"
920   "@
921    rsqrtss\t{%1, %0|%0, %1}
922    vrsqrtss\t{%1, %2, %0|%0, %2, %1}"
923   [(set_attr "isa" "noavx,avx")
924    (set_attr "type" "sse")
925    (set_attr "prefix" "orig,vex")
926    (set_attr "mode" "SF")])
927
928 ;; ??? For !flag_finite_math_only, the representation with SMIN/SMAX
929 ;; isn't really correct, as those rtl operators aren't defined when
930 ;; applied to NaNs.  Hopefully the optimizers won't get too smart on us.
931
932 (define_expand "<code><mode>3"
933   [(set (match_operand:VF 0 "register_operand" "")
934         (smaxmin:VF
935           (match_operand:VF 1 "nonimmediate_operand" "")
936           (match_operand:VF 2 "nonimmediate_operand" "")))]
937   "TARGET_SSE"
938 {
939   if (!flag_finite_math_only)
940     operands[1] = force_reg (<MODE>mode, operands[1]);
941   ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);
942 })
943
944 (define_insn "*<code><mode>3_finite"
945   [(set (match_operand:VF 0 "register_operand" "=x,x")
946         (smaxmin:VF
947           (match_operand:VF 1 "nonimmediate_operand" "%0,x")
948           (match_operand:VF 2 "nonimmediate_operand" "xm,xm")))]
949   "TARGET_SSE && flag_finite_math_only
950    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
951   "@
952    <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
953    v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
954   [(set_attr "isa" "noavx,avx")
955    (set_attr "type" "sseadd")
956    (set_attr "prefix" "orig,vex")
957    (set_attr "mode" "<MODE>")])
958
959 (define_insn "*<code><mode>3"
960   [(set (match_operand:VF 0 "register_operand" "=x,x")
961         (smaxmin:VF
962           (match_operand:VF 1 "register_operand" "0,x")
963           (match_operand:VF 2 "nonimmediate_operand" "xm,xm")))]
964   "TARGET_SSE && !flag_finite_math_only"
965   "@
966    <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
967    v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
968   [(set_attr "isa" "noavx,avx")
969    (set_attr "type" "sseadd")
970    (set_attr "prefix" "orig,vex")
971    (set_attr "mode" "<MODE>")])
972
973 (define_insn "<sse>_vm<code><mode>3"
974   [(set (match_operand:VF_128 0 "register_operand" "=x,x")
975         (vec_merge:VF_128
976           (smaxmin:VF_128
977             (match_operand:VF_128 1 "register_operand" "0,x")
978             (match_operand:VF_128 2 "nonimmediate_operand" "xm,xm"))
979          (match_dup 1)
980          (const_int 1)))]
981   "TARGET_SSE"
982   "@
983    <maxmin_float><ssescalarmodesuffix>\t{%2, %0|%0, %2}
984    v<maxmin_float><ssescalarmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
985   [(set_attr "isa" "noavx,avx")
986    (set_attr "type" "sse")
987    (set_attr "prefix" "orig,vex")
988    (set_attr "mode" "<ssescalarmode>")])
989
990 ;; These versions of the min/max patterns implement exactly the operations
991 ;;   min = (op1 < op2 ? op1 : op2)
992 ;;   max = (!(op1 < op2) ? op1 : op2)
993 ;; Their operands are not commutative, and thus they may be used in the
994 ;; presence of -0.0 and NaN.
995
996 (define_insn "*ieee_smin<mode>3"
997   [(set (match_operand:VF 0 "register_operand" "=x,x")
998         (unspec:VF
999           [(match_operand:VF 1 "register_operand" "0,x")
1000            (match_operand:VF 2 "nonimmediate_operand" "xm,xm")]
1001          UNSPEC_IEEE_MIN))]
1002   "TARGET_SSE"
1003   "@
1004    min<ssemodesuffix>\t{%2, %0|%0, %2}
1005    vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
1006   [(set_attr "isa" "noavx,avx")
1007    (set_attr "type" "sseadd")
1008    (set_attr "prefix" "orig,vex")
1009    (set_attr "mode" "<MODE>")])
1010
1011 (define_insn "*ieee_smax<mode>3"
1012   [(set (match_operand:VF 0 "register_operand" "=x,x")
1013         (unspec:VF
1014           [(match_operand:VF 1 "register_operand" "0,x")
1015            (match_operand:VF 2 "nonimmediate_operand" "xm,xm")]
1016          UNSPEC_IEEE_MAX))]
1017   "TARGET_SSE"
1018   "@
1019    max<ssemodesuffix>\t{%2, %0|%0, %2}
1020    vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
1021   [(set_attr "isa" "noavx,avx")
1022    (set_attr "type" "sseadd")
1023    (set_attr "prefix" "orig,vex")
1024    (set_attr "mode" "<MODE>")])
1025
1026 (define_insn "avx_addsubv4df3"
1027   [(set (match_operand:V4DF 0 "register_operand" "=x")
1028         (vec_merge:V4DF
1029           (plus:V4DF
1030             (match_operand:V4DF 1 "register_operand" "x")
1031             (match_operand:V4DF 2 "nonimmediate_operand" "xm"))
1032           (minus:V4DF (match_dup 1) (match_dup 2))
1033           (const_int 10)))]
1034   "TARGET_AVX"
1035   "vaddsubpd\t{%2, %1, %0|%0, %1, %2}"
1036   [(set_attr "type" "sseadd")
1037    (set_attr "prefix" "vex")
1038    (set_attr "mode" "V4DF")])
1039
1040 (define_insn "sse3_addsubv2df3"
1041   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
1042         (vec_merge:V2DF
1043           (plus:V2DF
1044             (match_operand:V2DF 1 "register_operand" "0,x")
1045             (match_operand:V2DF 2 "nonimmediate_operand" "xm,xm"))
1046           (minus:V2DF (match_dup 1) (match_dup 2))
1047           (const_int 2)))]
1048   "TARGET_SSE3"
1049   "@
1050    addsubpd\t{%2, %0|%0, %2}
1051    vaddsubpd\t{%2, %1, %0|%0, %1, %2}"
1052   [(set_attr "isa" "noavx,avx")
1053    (set_attr "type" "sseadd")
1054    (set_attr "atom_unit" "complex")
1055    (set_attr "prefix" "orig,vex")
1056    (set_attr "mode" "V2DF")])
1057
1058 (define_insn "avx_addsubv8sf3"
1059   [(set (match_operand:V8SF 0 "register_operand" "=x")
1060         (vec_merge:V8SF
1061           (plus:V8SF
1062             (match_operand:V8SF 1 "register_operand" "x")
1063             (match_operand:V8SF 2 "nonimmediate_operand" "xm"))
1064           (minus:V8SF (match_dup 1) (match_dup 2))
1065           (const_int 170)))]
1066   "TARGET_AVX"
1067   "vaddsubps\t{%2, %1, %0|%0, %1, %2}"
1068   [(set_attr "type" "sseadd")
1069    (set_attr "prefix" "vex")
1070    (set_attr "mode" "V8SF")])
1071
1072 (define_insn "sse3_addsubv4sf3"
1073   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
1074         (vec_merge:V4SF
1075           (plus:V4SF
1076             (match_operand:V4SF 1 "register_operand" "0,x")
1077             (match_operand:V4SF 2 "nonimmediate_operand" "xm,xm"))
1078           (minus:V4SF (match_dup 1) (match_dup 2))
1079           (const_int 10)))]
1080   "TARGET_SSE3"
1081   "@
1082    addsubps\t{%2, %0|%0, %2}
1083    vaddsubps\t{%2, %1, %0|%0, %1, %2}"
1084   [(set_attr "isa" "noavx,avx")
1085    (set_attr "type" "sseadd")
1086    (set_attr "prefix" "orig,vex")
1087    (set_attr "prefix_rep" "1,*")
1088    (set_attr "mode" "V4SF")])
1089
1090 (define_insn "avx_h<plusminus_insn>v4df3"
1091   [(set (match_operand:V4DF 0 "register_operand" "=x")
1092         (vec_concat:V4DF
1093           (vec_concat:V2DF
1094             (plusminus:DF
1095               (vec_select:DF
1096                 (match_operand:V4DF 1 "register_operand" "x")
1097                 (parallel [(const_int 0)]))
1098               (vec_select:DF (match_dup 1) (parallel [(const_int 1)])))
1099             (plusminus:DF
1100               (vec_select:DF (match_dup 1) (parallel [(const_int 2)]))
1101               (vec_select:DF (match_dup 1) (parallel [(const_int 3)]))))
1102           (vec_concat:V2DF
1103             (plusminus:DF
1104               (vec_select:DF
1105                 (match_operand:V4DF 2 "nonimmediate_operand" "xm")
1106                 (parallel [(const_int 0)]))
1107               (vec_select:DF (match_dup 2) (parallel [(const_int 1)])))
1108             (plusminus:DF
1109               (vec_select:DF (match_dup 2) (parallel [(const_int 2)]))
1110               (vec_select:DF (match_dup 2) (parallel [(const_int 3)]))))))]
1111   "TARGET_AVX"
1112   "vh<plusminus_mnemonic>pd\t{%2, %1, %0|%0, %1, %2}"
1113   [(set_attr "type" "sseadd")
1114    (set_attr "prefix" "vex")
1115    (set_attr "mode" "V4DF")])
1116
1117 (define_insn "sse3_h<plusminus_insn>v2df3"
1118   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
1119         (vec_concat:V2DF
1120           (plusminus:DF
1121             (vec_select:DF
1122               (match_operand:V2DF 1 "register_operand" "0,x")
1123               (parallel [(const_int 0)]))
1124             (vec_select:DF (match_dup 1) (parallel [(const_int 1)])))
1125           (plusminus:DF
1126             (vec_select:DF
1127               (match_operand:V2DF 2 "nonimmediate_operand" "xm,xm")
1128               (parallel [(const_int 0)]))
1129             (vec_select:DF (match_dup 2) (parallel [(const_int 1)])))))]
1130   "TARGET_SSE3"
1131   "@
1132    h<plusminus_mnemonic>pd\t{%2, %0|%0, %2}
1133    vh<plusminus_mnemonic>pd\t{%2, %1, %0|%0, %1, %2}"
1134   [(set_attr "isa" "noavx,avx")
1135    (set_attr "type" "sseadd")
1136    (set_attr "prefix" "orig,vex")
1137    (set_attr "mode" "V2DF")])
1138
1139 (define_insn "avx_h<plusminus_insn>v8sf3"
1140   [(set (match_operand:V8SF 0 "register_operand" "=x")
1141         (vec_concat:V8SF
1142           (vec_concat:V4SF
1143             (vec_concat:V2SF
1144               (plusminus:SF
1145                 (vec_select:SF
1146                   (match_operand:V8SF 1 "register_operand" "x")
1147                   (parallel [(const_int 0)]))
1148                 (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
1149               (plusminus:SF
1150                 (vec_select:SF (match_dup 1) (parallel [(const_int 2)]))
1151                 (vec_select:SF (match_dup 1) (parallel [(const_int 3)]))))
1152             (vec_concat:V2SF
1153               (plusminus:SF
1154                 (vec_select:SF
1155                   (match_operand:V8SF 2 "nonimmediate_operand" "xm")
1156                   (parallel [(const_int 0)]))
1157                 (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))
1158               (plusminus:SF
1159                 (vec_select:SF (match_dup 2) (parallel [(const_int 2)]))
1160                 (vec_select:SF (match_dup 2) (parallel [(const_int 3)])))))
1161           (vec_concat:V4SF
1162             (vec_concat:V2SF
1163               (plusminus:SF
1164                 (vec_select:SF (match_dup 1) (parallel [(const_int 4)]))
1165                 (vec_select:SF (match_dup 1) (parallel [(const_int 5)])))
1166               (plusminus:SF
1167                 (vec_select:SF (match_dup 1) (parallel [(const_int 6)]))
1168                 (vec_select:SF (match_dup 1) (parallel [(const_int 7)]))))
1169             (vec_concat:V2SF
1170               (plusminus:SF
1171                 (vec_select:SF (match_dup 2) (parallel [(const_int 4)]))
1172                 (vec_select:SF (match_dup 2) (parallel [(const_int 5)])))
1173               (plusminus:SF
1174                 (vec_select:SF (match_dup 2) (parallel [(const_int 6)]))
1175                 (vec_select:SF (match_dup 2) (parallel [(const_int 7)])))))))]
1176   "TARGET_AVX"
1177   "vh<plusminus_mnemonic>ps\t{%2, %1, %0|%0, %1, %2}"
1178   [(set_attr "type" "sseadd")
1179    (set_attr "prefix" "vex")
1180    (set_attr "mode" "V8SF")])
1181
1182 (define_insn "sse3_h<plusminus_insn>v4sf3"
1183   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
1184         (vec_concat:V4SF
1185           (vec_concat:V2SF
1186             (plusminus:SF
1187               (vec_select:SF
1188                 (match_operand:V4SF 1 "register_operand" "0,x")
1189                 (parallel [(const_int 0)]))
1190               (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
1191             (plusminus:SF
1192               (vec_select:SF (match_dup 1) (parallel [(const_int 2)]))
1193               (vec_select:SF (match_dup 1) (parallel [(const_int 3)]))))
1194           (vec_concat:V2SF
1195             (plusminus:SF
1196               (vec_select:SF
1197                 (match_operand:V4SF 2 "nonimmediate_operand" "xm,xm")
1198                 (parallel [(const_int 0)]))
1199               (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))
1200             (plusminus:SF
1201               (vec_select:SF (match_dup 2) (parallel [(const_int 2)]))
1202               (vec_select:SF (match_dup 2) (parallel [(const_int 3)]))))))]
1203   "TARGET_SSE3"
1204   "@
1205    h<plusminus_mnemonic>ps\t{%2, %0|%0, %2}
1206    vh<plusminus_mnemonic>ps\t{%2, %1, %0|%0, %1, %2}"
1207   [(set_attr "isa" "noavx,avx")
1208    (set_attr "type" "sseadd")
1209    (set_attr "atom_unit" "complex")
1210    (set_attr "prefix" "orig,vex")
1211    (set_attr "prefix_rep" "1,*")
1212    (set_attr "mode" "V4SF")])
1213
1214 (define_expand "reduc_splus_v4df"
1215   [(match_operand:V4DF 0 "register_operand" "")
1216    (match_operand:V4DF 1 "register_operand" "")]
1217   "TARGET_AVX"
1218 {
1219   rtx tmp = gen_reg_rtx (V4DFmode);
1220   rtx tmp2 = gen_reg_rtx (V4DFmode);
1221   emit_insn (gen_avx_haddv4df3 (tmp, operands[1], operands[1]));
1222   emit_insn (gen_avx_vperm2f128v4df3 (tmp2, tmp, tmp, GEN_INT (1)));
1223   emit_insn (gen_addv4df3 (operands[0], tmp, tmp2));
1224   DONE;
1225 })
1226
1227 (define_expand "reduc_splus_v2df"
1228   [(match_operand:V2DF 0 "register_operand" "")
1229    (match_operand:V2DF 1 "register_operand" "")]
1230   "TARGET_SSE3"
1231 {
1232   emit_insn (gen_sse3_haddv2df3 (operands[0], operands[1], operands[1]));
1233   DONE;
1234 })
1235
1236 (define_expand "reduc_splus_v8sf"
1237   [(match_operand:V8SF 0 "register_operand" "")
1238    (match_operand:V8SF 1 "register_operand" "")]
1239   "TARGET_AVX"
1240 {
1241   rtx tmp = gen_reg_rtx (V8SFmode);
1242   rtx tmp2 = gen_reg_rtx (V8SFmode);
1243   emit_insn (gen_avx_haddv8sf3 (tmp, operands[1], operands[1]));
1244   emit_insn (gen_avx_haddv8sf3 (tmp2, tmp, tmp));
1245   emit_insn (gen_avx_vperm2f128v8sf3 (tmp, tmp2, tmp2, GEN_INT (1)));
1246   emit_insn (gen_addv8sf3 (operands[0], tmp, tmp2));
1247   DONE;
1248 })
1249
1250 (define_expand "reduc_splus_v4sf"
1251   [(match_operand:V4SF 0 "register_operand" "")
1252    (match_operand:V4SF 1 "register_operand" "")]
1253   "TARGET_SSE"
1254 {
1255   if (TARGET_SSE3)
1256     {
1257       rtx tmp = gen_reg_rtx (V4SFmode);
1258       emit_insn (gen_sse3_haddv4sf3 (tmp, operands[1], operands[1]));
1259       emit_insn (gen_sse3_haddv4sf3 (operands[0], tmp, tmp));
1260     }
1261   else
1262     ix86_expand_reduc (gen_addv4sf3, operands[0], operands[1]);
1263   DONE;
1264 })
1265
1266 ;; Modes handled by reduc_sm{in,ax}* patterns.
1267 (define_mode_iterator REDUC_SMINMAX_MODE
1268   [(V32QI "TARGET_AVX2") (V16HI "TARGET_AVX2")
1269    (V8SI "TARGET_AVX2") (V4DI "TARGET_AVX2")
1270    (V8SF "TARGET_AVX") (V4DF "TARGET_AVX")
1271    (V4SF "TARGET_SSE")])
1272
1273 (define_expand "reduc_<code>_<mode>"
1274   [(smaxmin:REDUC_SMINMAX_MODE
1275      (match_operand:REDUC_SMINMAX_MODE 0 "register_operand" "")
1276      (match_operand:REDUC_SMINMAX_MODE 1 "register_operand" ""))]
1277   ""
1278 {
1279   ix86_expand_reduc (gen_<code><mode>3, operands[0], operands[1]);
1280   DONE;
1281 })
1282
1283 (define_expand "reduc_<code>_<mode>"
1284   [(umaxmin:VI_256
1285      (match_operand:VI_256 0 "register_operand" "")
1286      (match_operand:VI_256 1 "register_operand" ""))]
1287   "TARGET_AVX2"
1288 {
1289   ix86_expand_reduc (gen_<code><mode>3, operands[0], operands[1]);
1290   DONE;
1291 })
1292
1293 (define_expand "reduc_umin_v8hi"
1294   [(umin:V8HI
1295      (match_operand:V8HI 0 "register_operand" "")
1296      (match_operand:V8HI 1 "register_operand" ""))]
1297   "TARGET_SSE4_1"
1298 {
1299   ix86_expand_reduc (gen_uminv8hi3, operands[0], operands[1]);
1300   DONE;
1301 })
1302
1303 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1304 ;;
1305 ;; Parallel floating point comparisons
1306 ;;
1307 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1308
1309 (define_insn "avx_cmp<mode>3"
1310   [(set (match_operand:VF 0 "register_operand" "=x")
1311         (unspec:VF
1312           [(match_operand:VF 1 "register_operand" "x")
1313            (match_operand:VF 2 "nonimmediate_operand" "xm")
1314            (match_operand:SI 3 "const_0_to_31_operand" "n")]
1315           UNSPEC_PCMP))]
1316   "TARGET_AVX"
1317   "vcmp<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1318   [(set_attr "type" "ssecmp")
1319    (set_attr "length_immediate" "1")
1320    (set_attr "prefix" "vex")
1321    (set_attr "mode" "<MODE>")])
1322
1323 (define_insn "avx_vmcmp<mode>3"
1324   [(set (match_operand:VF_128 0 "register_operand" "=x")
1325         (vec_merge:VF_128
1326           (unspec:VF_128
1327             [(match_operand:VF_128 1 "register_operand" "x")
1328              (match_operand:VF_128 2 "nonimmediate_operand" "xm")
1329              (match_operand:SI 3 "const_0_to_31_operand" "n")]
1330             UNSPEC_PCMP)
1331          (match_dup 1)
1332          (const_int 1)))]
1333   "TARGET_AVX"
1334   "vcmp<ssescalarmodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1335   [(set_attr "type" "ssecmp")
1336    (set_attr "length_immediate" "1")
1337    (set_attr "prefix" "vex")
1338    (set_attr "mode" "<ssescalarmode>")])
1339
1340 (define_insn "*<sse>_maskcmp<mode>3_comm"
1341   [(set (match_operand:VF 0 "register_operand" "=x,x")
1342         (match_operator:VF 3 "sse_comparison_operator"
1343           [(match_operand:VF 1 "register_operand" "%0,x")
1344            (match_operand:VF 2 "nonimmediate_operand" "xm,xm")]))]
1345   "TARGET_SSE
1346    && GET_RTX_CLASS (GET_CODE (operands[3])) == RTX_COMM_COMPARE"
1347   "@
1348    cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
1349    vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
1350   [(set_attr "isa" "noavx,avx")
1351    (set_attr "type" "ssecmp")
1352    (set_attr "length_immediate" "1")
1353    (set_attr "prefix" "orig,vex")
1354    (set_attr "mode" "<MODE>")])
1355
1356 (define_insn "<sse>_maskcmp<mode>3"
1357   [(set (match_operand:VF 0 "register_operand" "=x,x")
1358         (match_operator:VF 3 "sse_comparison_operator"
1359           [(match_operand:VF 1 "register_operand" "0,x")
1360            (match_operand:VF 2 "nonimmediate_operand" "xm,xm")]))]
1361   "TARGET_SSE"
1362   "@
1363    cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
1364    vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
1365   [(set_attr "isa" "noavx,avx")
1366    (set_attr "type" "ssecmp")
1367    (set_attr "length_immediate" "1")
1368    (set_attr "prefix" "orig,vex")
1369    (set_attr "mode" "<MODE>")])
1370
1371 (define_insn "<sse>_vmmaskcmp<mode>3"
1372   [(set (match_operand:VF_128 0 "register_operand" "=x,x")
1373         (vec_merge:VF_128
1374          (match_operator:VF_128 3 "sse_comparison_operator"
1375            [(match_operand:VF_128 1 "register_operand" "0,x")
1376             (match_operand:VF_128 2 "nonimmediate_operand" "xm,xm")])
1377          (match_dup 1)
1378          (const_int 1)))]
1379   "TARGET_SSE"
1380   "@
1381    cmp%D3<ssescalarmodesuffix>\t{%2, %0|%0, %2}
1382    vcmp%D3<ssescalarmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
1383   [(set_attr "isa" "noavx,avx")
1384    (set_attr "type" "ssecmp")
1385    (set_attr "length_immediate" "1,*")
1386    (set_attr "prefix" "orig,vex")
1387    (set_attr "mode" "<ssescalarmode>")])
1388
1389 (define_insn "<sse>_comi"
1390   [(set (reg:CCFP FLAGS_REG)
1391         (compare:CCFP
1392           (vec_select:MODEF
1393             (match_operand:<ssevecmode> 0 "register_operand" "x")
1394             (parallel [(const_int 0)]))
1395           (vec_select:MODEF
1396             (match_operand:<ssevecmode> 1 "nonimmediate_operand" "xm")
1397             (parallel [(const_int 0)]))))]
1398   "SSE_FLOAT_MODE_P (<MODE>mode)"
1399   "%vcomi<ssemodesuffix>\t{%1, %0|%0, %1}"
1400   [(set_attr "type" "ssecomi")
1401    (set_attr "prefix" "maybe_vex")
1402    (set_attr "prefix_rep" "0")
1403    (set (attr "prefix_data16")
1404         (if_then_else (eq_attr "mode" "DF")
1405                       (const_string "1")
1406                       (const_string "0")))
1407    (set_attr "mode" "<MODE>")])
1408
1409 (define_insn "<sse>_ucomi"
1410   [(set (reg:CCFPU FLAGS_REG)
1411         (compare:CCFPU
1412           (vec_select:MODEF
1413             (match_operand:<ssevecmode> 0 "register_operand" "x")
1414             (parallel [(const_int 0)]))
1415           (vec_select:MODEF
1416             (match_operand:<ssevecmode> 1 "nonimmediate_operand" "xm")
1417             (parallel [(const_int 0)]))))]
1418   "SSE_FLOAT_MODE_P (<MODE>mode)"
1419   "%vucomi<ssemodesuffix>\t{%1, %0|%0, %1}"
1420   [(set_attr "type" "ssecomi")
1421    (set_attr "prefix" "maybe_vex")
1422    (set_attr "prefix_rep" "0")
1423    (set (attr "prefix_data16")
1424         (if_then_else (eq_attr "mode" "DF")
1425                       (const_string "1")
1426                       (const_string "0")))
1427    (set_attr "mode" "<MODE>")])
1428
1429 (define_expand "vcond<V_256:mode><VF_256:mode>"
1430   [(set (match_operand:V_256 0 "register_operand" "")
1431         (if_then_else:V_256
1432           (match_operator 3 ""
1433             [(match_operand:VF_256 4 "nonimmediate_operand" "")
1434              (match_operand:VF_256 5 "nonimmediate_operand" "")])
1435           (match_operand:V_256 1 "general_operand" "")
1436           (match_operand:V_256 2 "general_operand" "")))]
1437   "TARGET_AVX
1438    && (GET_MODE_NUNITS (<V_256:MODE>mode)
1439        == GET_MODE_NUNITS (<VF_256:MODE>mode))"
1440 {
1441   bool ok = ix86_expand_fp_vcond (operands);
1442   gcc_assert (ok);
1443   DONE;
1444 })
1445
1446 (define_expand "vcond<V_128:mode><VF_128:mode>"
1447   [(set (match_operand:V_128 0 "register_operand" "")
1448         (if_then_else:V_128
1449           (match_operator 3 ""
1450             [(match_operand:VF_128 4 "nonimmediate_operand" "")
1451              (match_operand:VF_128 5 "nonimmediate_operand" "")])
1452           (match_operand:V_128 1 "general_operand" "")
1453           (match_operand:V_128 2 "general_operand" "")))]
1454   "TARGET_SSE
1455    && (GET_MODE_NUNITS (<V_128:MODE>mode)
1456        == GET_MODE_NUNITS (<VF_128:MODE>mode))"
1457 {
1458   bool ok = ix86_expand_fp_vcond (operands);
1459   gcc_assert (ok);
1460   DONE;
1461 })
1462
1463 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1464 ;;
1465 ;; Parallel floating point logical operations
1466 ;;
1467 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1468
1469 (define_insn "<sse>_andnot<mode>3"
1470   [(set (match_operand:VF 0 "register_operand" "=x,x")
1471         (and:VF
1472           (not:VF
1473             (match_operand:VF 1 "register_operand" "0,x"))
1474           (match_operand:VF 2 "nonimmediate_operand" "xm,xm")))]
1475   "TARGET_SSE"
1476 {
1477   static char buf[32];
1478   const char *insn;
1479   const char *suffix
1480     = TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL ? "ps" : "<ssemodesuffix>";
1481
1482   switch (which_alternative)
1483     {
1484     case 0:
1485       insn = "andn%s\t{%%2, %%0|%%0, %%2}";
1486       break;
1487     case 1:
1488       insn = "vandn%s\t{%%2, %%1, %%0|%%0, %%1, %%2}";
1489       break;
1490     default:
1491       gcc_unreachable ();
1492     }
1493
1494   snprintf (buf, sizeof (buf), insn, suffix);
1495   return buf;
1496 }
1497   [(set_attr "isa" "noavx,avx")
1498    (set_attr "type" "sselog")
1499    (set_attr "prefix" "orig,vex")
1500    (set_attr "mode" "<MODE>")])
1501
1502 (define_expand "<code><mode>3"
1503   [(set (match_operand:VF 0 "register_operand" "")
1504         (any_logic:VF
1505           (match_operand:VF 1 "nonimmediate_operand" "")
1506           (match_operand:VF 2 "nonimmediate_operand" "")))]
1507   "TARGET_SSE"
1508   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
1509
1510 (define_insn "*<code><mode>3"
1511   [(set (match_operand:VF 0 "register_operand" "=x,x")
1512         (any_logic:VF
1513           (match_operand:VF 1 "nonimmediate_operand" "%0,x")
1514           (match_operand:VF 2 "nonimmediate_operand" "xm,xm")))]
1515   "TARGET_SSE && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
1516 {
1517   static char buf[32];
1518   const char *insn;
1519   const char *suffix
1520     = TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL ? "ps" : "<ssemodesuffix>";
1521
1522   switch (which_alternative)
1523     {
1524     case 0:
1525       insn = "<logic>%s\t{%%2, %%0|%%0, %%2}";
1526       break;
1527     case 1:
1528       insn = "v<logic>%s\t{%%2, %%1, %%0|%%0, %%1, %%2}";
1529       break;
1530     default:
1531       gcc_unreachable ();
1532     }
1533
1534   snprintf (buf, sizeof (buf), insn, suffix);
1535   return buf;
1536 }
1537   [(set_attr "isa" "noavx,avx")
1538    (set_attr "type" "sselog")
1539    (set_attr "prefix" "orig,vex")
1540    (set_attr "mode" "<MODE>")])
1541
1542 (define_expand "copysign<mode>3"
1543   [(set (match_dup 4)
1544         (and:VF
1545           (not:VF (match_dup 3))
1546           (match_operand:VF 1 "nonimmediate_operand" "")))
1547    (set (match_dup 5)
1548         (and:VF (match_dup 3)
1549                 (match_operand:VF 2 "nonimmediate_operand" "")))
1550    (set (match_operand:VF 0 "register_operand" "")
1551         (ior:VF (match_dup 4) (match_dup 5)))]
1552   "TARGET_SSE"
1553 {
1554   operands[3] = ix86_build_signbit_mask (<MODE>mode, 1, 0);
1555
1556   operands[4] = gen_reg_rtx (<MODE>mode);
1557   operands[5] = gen_reg_rtx (<MODE>mode);
1558 })
1559
1560 ;; Also define scalar versions.  These are used for abs, neg, and
1561 ;; conditional move.  Using subregs into vector modes causes register
1562 ;; allocation lossage.  These patterns do not allow memory operands
1563 ;; because the native instructions read the full 128-bits.
1564
1565 (define_insn "*andnot<mode>3"
1566   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
1567         (and:MODEF
1568           (not:MODEF
1569             (match_operand:MODEF 1 "register_operand" "0,x"))
1570             (match_operand:MODEF 2 "register_operand" "x,x")))]
1571   "SSE_FLOAT_MODE_P (<MODE>mode)"
1572 {
1573   static char buf[32];
1574   const char *insn;
1575   const char *suffix
1576     = TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL ? "ps" : "<ssevecmodesuffix>";
1577
1578   switch (which_alternative)
1579     {
1580     case 0:
1581       insn = "andn%s\t{%%2, %%0|%%0, %%2}";
1582       break;
1583     case 1:
1584       insn = "vandn%s\t{%%2, %%1, %%0|%%0, %%1, %%2}";
1585       break;
1586     default:
1587       gcc_unreachable ();
1588     }
1589
1590   snprintf (buf, sizeof (buf), insn, suffix);
1591   return buf;
1592 }
1593   [(set_attr "isa" "noavx,avx")
1594    (set_attr "type" "sselog")
1595    (set_attr "prefix" "orig,vex")
1596    (set_attr "mode" "<ssevecmode>")])
1597
1598 (define_insn "*<code><mode>3"
1599   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
1600         (any_logic:MODEF
1601           (match_operand:MODEF 1 "register_operand" "%0,x")
1602           (match_operand:MODEF 2 "register_operand" "x,x")))]
1603   "SSE_FLOAT_MODE_P (<MODE>mode)"
1604 {
1605   static char buf[32];
1606   const char *insn;
1607   const char *suffix
1608     = TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL ? "ps" : "<ssevecmodesuffix>";
1609
1610   switch (which_alternative)
1611     {
1612     case 0:
1613       insn = "<logic>%s\t{%%2, %%0|%%0, %%2}";
1614       break;
1615     case 1:
1616       insn = "v<logic>%s\t{%%2, %%1, %%0|%%0, %%1, %%2}";
1617       break;
1618     default:
1619       gcc_unreachable ();
1620     }
1621
1622   snprintf (buf, sizeof (buf), insn, suffix);
1623   return buf;
1624 }
1625   [(set_attr "isa" "noavx,avx")
1626    (set_attr "type" "sselog")
1627    (set_attr "prefix" "orig,vex")
1628    (set_attr "mode" "<ssevecmode>")])
1629
1630 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1631 ;;
1632 ;; FMA4 floating point multiply/accumulate instructions.  This
1633 ;; includes the scalar version of the instructions as well as the
1634 ;; vector.
1635 ;;
1636 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1637
1638 ;; In order to match (*a * *b) + *c, particularly when vectorizing, allow
1639 ;; combine to generate a multiply/add with two memory references.  We then
1640 ;; split this insn, into loading up the destination register with one of the
1641 ;; memory operations.  If we don't manage to split the insn, reload will
1642 ;; generate the appropriate moves.  The reason this is needed, is that combine
1643 ;; has already folded one of the memory references into both the multiply and
1644 ;; add insns, and it can't generate a new pseudo.  I.e.:
1645 ;;      (set (reg1) (mem (addr1)))
1646 ;;      (set (reg2) (mult (reg1) (mem (addr2))))
1647 ;;      (set (reg3) (plus (reg2) (mem (addr3))))
1648 ;;
1649 ;; ??? This is historic, pre-dating the gimple fma transformation.
1650 ;; We could now properly represent that only one memory operand is
1651 ;; allowed and not be penalized during optimization.
1652
1653 ;; Intrinsic FMA operations.
1654
1655 ;; The standard names for fma is only available with SSE math enabled.
1656 (define_expand "fma<mode>4"
1657   [(set (match_operand:FMAMODE 0 "register_operand")
1658         (fma:FMAMODE
1659           (match_operand:FMAMODE 1 "nonimmediate_operand")
1660           (match_operand:FMAMODE 2 "nonimmediate_operand")
1661           (match_operand:FMAMODE 3 "nonimmediate_operand")))]
1662   "(TARGET_FMA || TARGET_FMA4) && TARGET_SSE_MATH")
1663
1664 (define_expand "fms<mode>4"
1665   [(set (match_operand:FMAMODE 0 "register_operand")
1666         (fma:FMAMODE
1667           (match_operand:FMAMODE 1 "nonimmediate_operand")
1668           (match_operand:FMAMODE 2 "nonimmediate_operand")
1669           (neg:FMAMODE (match_operand:FMAMODE 3 "nonimmediate_operand"))))]
1670   "(TARGET_FMA || TARGET_FMA4) && TARGET_SSE_MATH")
1671
1672 (define_expand "fnma<mode>4"
1673   [(set (match_operand:FMAMODE 0 "register_operand")
1674         (fma:FMAMODE
1675           (neg:FMAMODE (match_operand:FMAMODE 1 "nonimmediate_operand"))
1676           (match_operand:FMAMODE 2 "nonimmediate_operand")
1677           (match_operand:FMAMODE 3 "nonimmediate_operand")))]
1678   "(TARGET_FMA || TARGET_FMA4) && TARGET_SSE_MATH")
1679
1680 (define_expand "fnms<mode>4"
1681   [(set (match_operand:FMAMODE 0 "register_operand")
1682         (fma:FMAMODE
1683           (neg:FMAMODE (match_operand:FMAMODE 1 "nonimmediate_operand"))
1684           (match_operand:FMAMODE 2 "nonimmediate_operand")
1685           (neg:FMAMODE (match_operand:FMAMODE 3 "nonimmediate_operand"))))]
1686   "(TARGET_FMA || TARGET_FMA4) && TARGET_SSE_MATH")
1687
1688 ;; The builtin for fma4intrin.h is not constrained by SSE math enabled.
1689 (define_expand "fma4i_fmadd_<mode>"
1690   [(set (match_operand:FMAMODE 0 "register_operand")
1691         (fma:FMAMODE
1692           (match_operand:FMAMODE 1 "nonimmediate_operand")
1693           (match_operand:FMAMODE 2 "nonimmediate_operand")
1694           (match_operand:FMAMODE 3 "nonimmediate_operand")))]
1695   "TARGET_FMA || TARGET_FMA4")
1696
1697 (define_insn "*fma4i_fmadd_<mode>"
1698   [(set (match_operand:FMAMODE 0 "register_operand" "=x,x")
1699         (fma:FMAMODE
1700           (match_operand:FMAMODE 1 "nonimmediate_operand" "%x,x")
1701           (match_operand:FMAMODE 2 "nonimmediate_operand" " x,m")
1702           (match_operand:FMAMODE 3 "nonimmediate_operand" "xm,x")))]
1703   "TARGET_FMA4"
1704   "vfmadd<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1705   [(set_attr "type" "ssemuladd")
1706    (set_attr "mode" "<MODE>")])
1707
1708 (define_insn "*fma4i_fmsub_<mode>"
1709   [(set (match_operand:FMAMODE 0 "register_operand" "=x,x")
1710         (fma:FMAMODE
1711           (match_operand:FMAMODE 1 "nonimmediate_operand" "%x,x")
1712           (match_operand:FMAMODE 2 "nonimmediate_operand" " x,m")
1713           (neg:FMAMODE
1714             (match_operand:FMAMODE 3 "nonimmediate_operand" "xm,x"))))]
1715   "TARGET_FMA4"
1716   "vfmsub<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1717   [(set_attr "type" "ssemuladd")
1718    (set_attr "mode" "<MODE>")])
1719
1720 (define_insn "*fma4i_fnmadd_<mode>"
1721   [(set (match_operand:FMAMODE 0 "register_operand" "=x,x")
1722         (fma:FMAMODE
1723           (neg:FMAMODE
1724             (match_operand:FMAMODE 1 "nonimmediate_operand" "%x,x"))
1725           (match_operand:FMAMODE   2 "nonimmediate_operand" " x,m")
1726           (match_operand:FMAMODE   3 "nonimmediate_operand" "xm,x")))]
1727   "TARGET_FMA4"
1728   "vfnmadd<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1729   [(set_attr "type" "ssemuladd")
1730    (set_attr "mode" "<MODE>")])
1731
1732 (define_insn "*fma4i_fnmsub_<mode>"
1733   [(set (match_operand:FMAMODE 0 "register_operand" "=x,x")
1734         (fma:FMAMODE
1735           (neg:FMAMODE
1736             (match_operand:FMAMODE 1 "nonimmediate_operand" "%x,x"))
1737           (match_operand:FMAMODE   2 "nonimmediate_operand" " x,m")
1738           (neg:FMAMODE
1739             (match_operand:FMAMODE 3 "nonimmediate_operand" "xm,x"))))]
1740   "TARGET_FMA4"
1741   "vfnmsub<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1742   [(set_attr "type" "ssemuladd")
1743    (set_attr "mode" "<MODE>")])
1744
1745 ;; Scalar versions of the above.  Unlike ADDSS et al, these write the
1746 ;; entire destination register, with the high-order elements zeroed.
1747
1748 (define_expand "fma4i_vmfmadd_<mode>"
1749   [(set (match_operand:VF_128 0 "register_operand")
1750         (vec_merge:VF_128
1751           (fma:VF_128
1752             (match_operand:VF_128 1 "nonimmediate_operand")
1753             (match_operand:VF_128 2 "nonimmediate_operand")
1754             (match_operand:VF_128 3 "nonimmediate_operand"))
1755           (match_dup 4)
1756           (const_int 1)))]
1757   "TARGET_FMA4"
1758 {
1759   operands[4] = CONST0_RTX (<MODE>mode);
1760 })
1761
1762 (define_expand "fmai_vmfmadd_<mode>"
1763   [(set (match_operand:VF_128 0 "register_operand")
1764         (vec_merge:VF_128
1765           (fma:VF_128
1766             (match_operand:VF_128 1 "nonimmediate_operand")
1767             (match_operand:VF_128 2 "nonimmediate_operand")
1768             (match_operand:VF_128 3 "nonimmediate_operand"))
1769           (match_dup 0)
1770           (const_int 1)))]
1771   "TARGET_FMA")
1772
1773 (define_insn "*fmai_fmadd_<mode>"
1774   [(set (match_operand:VF_128 0 "register_operand" "=x,x,x")
1775         (vec_merge:VF_128
1776           (fma:VF_128
1777             (match_operand:VF_128 1 "nonimmediate_operand" "%0, 0,x")
1778             (match_operand:VF_128 2 "nonimmediate_operand" "xm, x,xm")
1779             (match_operand:VF_128 3 "nonimmediate_operand" " x,xm,0"))
1780           (match_dup 0)
1781           (const_int 1)))]
1782   "TARGET_FMA"
1783   "@
1784    vfmadd132<ssescalarmodesuffix>\t{%2, %3, %0|%0, %3, %2}
1785    vfmadd213<ssescalarmodesuffix>\t{%3, %2, %0|%0, %2, %3}
1786    vfmadd231<ssescalarmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
1787   [(set_attr "type" "ssemuladd")
1788    (set_attr "mode" "<MODE>")])
1789
1790 (define_insn "*fmai_fmsub_<mode>"
1791   [(set (match_operand:VF_128 0 "register_operand" "=x,x,x")
1792         (vec_merge:VF_128
1793           (fma:VF_128
1794             (match_operand:VF_128   1 "nonimmediate_operand" "%0, 0,x")
1795             (match_operand:VF_128   2 "nonimmediate_operand" "xm, x,xm")
1796             (neg:VF_128
1797               (match_operand:VF_128 3 "nonimmediate_operand" " x,xm,0")))
1798           (match_dup 0)
1799           (const_int 1)))]
1800   "TARGET_FMA"
1801   "@
1802    vfmsub132<ssescalarmodesuffix>\t{%2, %3, %0|%0, %3, %2}
1803    vfmsub213<ssescalarmodesuffix>\t{%3, %2, %0|%0, %2, %3}
1804    vfmsub231<ssescalarmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
1805   [(set_attr "type" "ssemuladd")
1806    (set_attr "mode" "<MODE>")])
1807
1808 (define_insn "*fmai_fnmadd_<mode>"
1809   [(set (match_operand:VF_128 0 "register_operand" "=x,x,x")
1810         (vec_merge:VF_128
1811           (fma:VF_128
1812             (neg:VF_128
1813               (match_operand:VF_128 1 "nonimmediate_operand" "%0, 0,x"))
1814             (match_operand:VF_128   2 "nonimmediate_operand" "xm, x,xm")
1815             (match_operand:VF_128   3 "nonimmediate_operand" " x,xm,0"))
1816           (match_dup 0)
1817           (const_int 1)))]
1818   "TARGET_FMA"
1819   "@
1820    vfnmadd132<ssescalarmodesuffix>\t{%2, %3, %0|%0, %3, %2}
1821    vfnmadd213<ssescalarmodesuffix>\t{%3, %2, %0|%0, %2, %3}
1822    vfnmadd231<ssescalarmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
1823   [(set_attr "type" "ssemuladd")
1824    (set_attr "mode" "<MODE>")])
1825
1826 (define_insn "*fmai_fnmsub_<mode>"
1827   [(set (match_operand:VF_128 0 "register_operand" "=x,x,x")
1828         (vec_merge:VF_128
1829           (fma:VF_128
1830             (neg:VF_128
1831               (match_operand:VF_128 1 "nonimmediate_operand" "%0, 0,x"))
1832             (match_operand:VF_128   2 "nonimmediate_operand" "xm, x,xm")
1833             (neg:VF_128
1834               (match_operand:VF_128 3 "nonimmediate_operand" " x,xm,0")))
1835           (match_dup 0)
1836           (const_int 1)))]
1837   "TARGET_FMA"
1838   "@
1839    vfnmsub132<ssescalarmodesuffix>\t{%2, %3, %0|%0, %3, %2}
1840    vfnmsub213<ssescalarmodesuffix>\t{%3, %2, %0|%0, %2, %3}
1841    vfnmsub231<ssescalarmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
1842   [(set_attr "type" "ssemuladd")
1843    (set_attr "mode" "<MODE>")])
1844
1845 (define_insn "*fma4i_vmfmadd_<mode>"
1846   [(set (match_operand:VF_128 0 "register_operand" "=x,x")
1847         (vec_merge:VF_128
1848           (fma:VF_128
1849             (match_operand:VF_128 1 "nonimmediate_operand" "%x,x")
1850             (match_operand:VF_128 2 "nonimmediate_operand" " x,m")
1851             (match_operand:VF_128 3 "nonimmediate_operand" "xm,x"))
1852           (match_operand:VF_128 4 "const0_operand" "")
1853           (const_int 1)))]
1854   "TARGET_FMA4"
1855   "vfmadd<ssescalarmodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1856   [(set_attr "type" "ssemuladd")
1857    (set_attr "mode" "<MODE>")])
1858
1859 (define_insn "*fma4i_vmfmsub_<mode>"
1860   [(set (match_operand:VF_128 0 "register_operand" "=x,x")
1861         (vec_merge:VF_128
1862           (fma:VF_128
1863             (match_operand:VF_128 1 "nonimmediate_operand" "%x,x")
1864             (match_operand:VF_128 2 "nonimmediate_operand" " x,m")
1865             (neg:VF_128
1866               (match_operand:VF_128 3 "nonimmediate_operand" "xm,x")))
1867           (match_operand:VF_128 4 "const0_operand" "")
1868           (const_int 1)))]
1869   "TARGET_FMA4"
1870   "vfmsub<ssescalarmodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1871   [(set_attr "type" "ssemuladd")
1872    (set_attr "mode" "<MODE>")])
1873
1874 (define_insn "*fma4i_vmfnmadd_<mode>"
1875   [(set (match_operand:VF_128 0 "register_operand" "=x,x")
1876         (vec_merge:VF_128
1877           (fma:VF_128
1878             (neg:VF_128
1879               (match_operand:VF_128 1 "nonimmediate_operand" "%x,x"))
1880             (match_operand:VF_128   2 "nonimmediate_operand" " x,m")
1881             (match_operand:VF_128   3 "nonimmediate_operand" "xm,x"))
1882           (match_operand:VF_128 4 "const0_operand" "")
1883           (const_int 1)))]
1884   "TARGET_FMA4"
1885   "vfnmadd<ssescalarmodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1886   [(set_attr "type" "ssemuladd")
1887    (set_attr "mode" "<MODE>")])
1888
1889 (define_insn "*fma4i_vmfnmsub_<mode>"
1890   [(set (match_operand:VF_128 0 "register_operand" "=x,x")
1891         (vec_merge:VF_128
1892           (fma:VF_128
1893             (neg:VF_128
1894               (match_operand:VF_128 1 "nonimmediate_operand" "%x,x"))
1895             (match_operand:VF_128   2 "nonimmediate_operand" " x,m")
1896             (neg:VF_128
1897               (match_operand:VF_128   3 "nonimmediate_operand" "xm,x")))
1898           (match_operand:VF_128 4 "const0_operand" "")
1899           (const_int 1)))]
1900   "TARGET_FMA4"
1901   "vfnmsub<ssescalarmodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1902   [(set_attr "type" "ssemuladd")
1903    (set_attr "mode" "<MODE>")])
1904
1905 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1906 ;;
1907 ;; FMA4 Parallel floating point multiply addsub and subadd operations.
1908 ;;
1909 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1910
1911 ;; It would be possible to represent these without the UNSPEC as
1912 ;;
1913 ;; (vec_merge
1914 ;;   (fma op1 op2 op3)
1915 ;;   (fma op1 op2 (neg op3))
1916 ;;   (merge-const))
1917 ;;
1918 ;; But this doesn't seem useful in practice.
1919
1920 (define_expand "fmaddsub_<mode>"
1921   [(set (match_operand:VF 0 "register_operand")
1922         (unspec:VF
1923           [(match_operand:VF 1 "nonimmediate_operand")
1924            (match_operand:VF 2 "nonimmediate_operand")
1925            (match_operand:VF 3 "nonimmediate_operand")]
1926           UNSPEC_FMADDSUB))]
1927   "TARGET_FMA || TARGET_FMA4")
1928
1929 (define_insn "*fma4_fmaddsub_<mode>"
1930   [(set (match_operand:VF 0 "register_operand" "=x,x")
1931         (unspec:VF
1932           [(match_operand:VF 1 "nonimmediate_operand" "%x,x")
1933            (match_operand:VF 2 "nonimmediate_operand" " x,m")
1934            (match_operand:VF 3 "nonimmediate_operand" "xm,x")]
1935           UNSPEC_FMADDSUB))]
1936   "TARGET_FMA4"
1937   "vfmaddsub<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1938   [(set_attr "type" "ssemuladd")
1939    (set_attr "mode" "<MODE>")])
1940
1941 (define_insn "*fma4_fmsubadd_<mode>"
1942   [(set (match_operand:VF 0 "register_operand" "=x,x")
1943         (unspec:VF
1944           [(match_operand:VF 1 "nonimmediate_operand" "%x,x")
1945            (match_operand:VF 2 "nonimmediate_operand" " x,m")
1946            (neg:VF
1947              (match_operand:VF 3 "nonimmediate_operand" "xm,x"))]
1948           UNSPEC_FMADDSUB))]
1949   "TARGET_FMA4"
1950   "vfmsubadd<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1951   [(set_attr "type" "ssemuladd")
1952    (set_attr "mode" "<MODE>")])
1953
1954 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1955 ;;
1956 ;; FMA3 floating point multiply/accumulate instructions.
1957 ;;
1958 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1959
1960 (define_insn "*fma_fmadd_<mode>"
1961   [(set (match_operand:FMAMODE 0 "register_operand" "=x,x,x")
1962         (fma:FMAMODE
1963           (match_operand:FMAMODE 1 "nonimmediate_operand" "%0, 0,x")
1964           (match_operand:FMAMODE 2 "nonimmediate_operand" "xm, x,xm")
1965           (match_operand:FMAMODE 3 "nonimmediate_operand" " x,xm,0")))]
1966   "TARGET_FMA"
1967   "@
1968    vfmadd132<ssemodesuffix>\t{%2, %3, %0|%0, %3, %2}
1969    vfmadd213<ssemodesuffix>\t{%3, %2, %0|%0, %2, %3}
1970    vfmadd231<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
1971   [(set_attr "type" "ssemuladd")
1972    (set_attr "mode" "<MODE>")])
1973
1974 (define_insn "*fma_fmsub_<mode>"
1975   [(set (match_operand:FMAMODE 0 "register_operand" "=x,x,x")
1976         (fma:FMAMODE
1977           (match_operand:FMAMODE   1 "nonimmediate_operand" "%0, 0,x")
1978           (match_operand:FMAMODE   2 "nonimmediate_operand" "xm, x,xm")
1979           (neg:FMAMODE
1980             (match_operand:FMAMODE 3 "nonimmediate_operand" " x,xm,0"))))]
1981   "TARGET_FMA"
1982   "@
1983    vfmsub132<ssemodesuffix>\t{%2, %3, %0|%0, %3, %2}
1984    vfmsub213<ssemodesuffix>\t{%3, %2, %0|%0, %2, %3}
1985    vfmsub231<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
1986   [(set_attr "type" "ssemuladd")
1987    (set_attr "mode" "<MODE>")])
1988
1989 (define_insn "*fma_fnmadd_<mode>"
1990   [(set (match_operand:FMAMODE 0 "register_operand" "=x,x,x")
1991         (fma:FMAMODE
1992           (neg:FMAMODE
1993             (match_operand:FMAMODE 1 "nonimmediate_operand" "%0, 0,x"))
1994           (match_operand:FMAMODE   2 "nonimmediate_operand" "xm, x,xm")
1995           (match_operand:FMAMODE   3 "nonimmediate_operand" " x,xm,0")))]
1996   "TARGET_FMA"
1997   "@
1998    vfnmadd132<ssemodesuffix>\t{%2, %3, %0|%0, %3, %2}
1999    vfnmadd213<ssemodesuffix>\t{%3, %2, %0|%0, %2, %3}
2000    vfnmadd231<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
2001   [(set_attr "type" "ssemuladd")
2002    (set_attr "mode" "<MODE>")])
2003
2004 (define_insn "*fma_fnmsub_<mode>"
2005   [(set (match_operand:FMAMODE 0 "register_operand" "=x,x,x")
2006         (fma:FMAMODE
2007           (neg:FMAMODE
2008             (match_operand:FMAMODE 1 "nonimmediate_operand" "%0, 0,x"))
2009           (match_operand:FMAMODE   2 "nonimmediate_operand" "xm, x,xm")
2010           (neg:FMAMODE
2011             (match_operand:FMAMODE 3 "nonimmediate_operand" " x,xm,0"))))]
2012   "TARGET_FMA"
2013   "@
2014    vfnmsub132<ssemodesuffix>\t{%2, %3, %0|%0, %3, %2}
2015    vfnmsub213<ssemodesuffix>\t{%3, %2, %0|%0, %2, %3}
2016    vfnmsub231<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
2017   [(set_attr "type" "ssemuladd")
2018    (set_attr "mode" "<MODE>")])
2019
2020 (define_insn "*fma_fmaddsub_<mode>"
2021   [(set (match_operand:VF 0 "register_operand" "=x,x,x")
2022         (unspec:VF
2023           [(match_operand:VF 1 "nonimmediate_operand" "%0, 0,x")
2024            (match_operand:VF 2 "nonimmediate_operand" "xm, x,xm")
2025            (match_operand:VF 3 "nonimmediate_operand" " x,xm,0")]
2026           UNSPEC_FMADDSUB))]
2027   "TARGET_FMA"
2028   "@
2029    vfmaddsub132<ssemodesuffix>\t{%2, %3, %0|%0, %3, %2}
2030    vfmaddsub213<ssemodesuffix>\t{%3, %2, %0|%0, %2, %3}
2031    vfmaddsub231<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
2032   [(set_attr "type" "ssemuladd")
2033    (set_attr "mode" "<MODE>")])
2034
2035 (define_insn "*fma_fmsubadd_<mode>"
2036   [(set (match_operand:VF 0 "register_operand" "=x,x,x")
2037         (unspec:VF
2038           [(match_operand:VF   1 "nonimmediate_operand" "%0, 0,x")
2039            (match_operand:VF   2 "nonimmediate_operand" "xm, x,xm")
2040            (neg:VF
2041              (match_operand:VF 3 "nonimmediate_operand" " x,xm,0"))]
2042           UNSPEC_FMADDSUB))]
2043   "TARGET_FMA"
2044   "@
2045    vfmsubadd132<ssemodesuffix>\t{%2, %3, %0|%0, %3, %2}
2046    vfmsubadd213<ssemodesuffix>\t{%3, %2, %0|%0, %2, %3}
2047    vfmsubadd231<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
2048   [(set_attr "type" "ssemuladd")
2049    (set_attr "mode" "<MODE>")])
2050
2051 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2052 ;;
2053 ;; Parallel single-precision floating point conversion operations
2054 ;;
2055 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2056
2057 (define_insn "sse_cvtpi2ps"
2058   [(set (match_operand:V4SF 0 "register_operand" "=x")
2059         (vec_merge:V4SF
2060           (vec_duplicate:V4SF
2061             (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
2062           (match_operand:V4SF 1 "register_operand" "0")
2063           (const_int 3)))]
2064   "TARGET_SSE"
2065   "cvtpi2ps\t{%2, %0|%0, %2}"
2066   [(set_attr "type" "ssecvt")
2067    (set_attr "mode" "V4SF")])
2068
2069 (define_insn "sse_cvtps2pi"
2070   [(set (match_operand:V2SI 0 "register_operand" "=y")
2071         (vec_select:V2SI
2072           (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
2073                        UNSPEC_FIX_NOTRUNC)
2074           (parallel [(const_int 0) (const_int 1)])))]
2075   "TARGET_SSE"
2076   "cvtps2pi\t{%1, %0|%0, %1}"
2077   [(set_attr "type" "ssecvt")
2078    (set_attr "unit" "mmx")
2079    (set_attr "mode" "DI")])
2080
2081 (define_insn "sse_cvttps2pi"
2082   [(set (match_operand:V2SI 0 "register_operand" "=y")
2083         (vec_select:V2SI
2084           (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
2085           (parallel [(const_int 0) (const_int 1)])))]
2086   "TARGET_SSE"
2087   "cvttps2pi\t{%1, %0|%0, %1}"
2088   [(set_attr "type" "ssecvt")
2089    (set_attr "unit" "mmx")
2090    (set_attr "prefix_rep" "0")
2091    (set_attr "mode" "SF")])
2092
2093 (define_insn "sse_cvtsi2ss"
2094   [(set (match_operand:V4SF 0 "register_operand" "=x,x,x")
2095         (vec_merge:V4SF
2096           (vec_duplicate:V4SF
2097             (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,m,rm")))
2098           (match_operand:V4SF 1 "register_operand" "0,0,x")
2099           (const_int 1)))]
2100   "TARGET_SSE"
2101   "@
2102    cvtsi2ss\t{%2, %0|%0, %2}
2103    cvtsi2ss\t{%2, %0|%0, %2}
2104    vcvtsi2ss\t{%2, %1, %0|%0, %1, %2}"
2105   [(set_attr "isa" "noavx,noavx,avx")
2106    (set_attr "type" "sseicvt")
2107    (set_attr "athlon_decode" "vector,double,*")
2108    (set_attr "amdfam10_decode" "vector,double,*")
2109    (set_attr "bdver1_decode" "double,direct,*")
2110    (set_attr "prefix" "orig,orig,vex")
2111    (set_attr "mode" "SF")])
2112
2113 (define_insn "sse_cvtsi2ssq"
2114   [(set (match_operand:V4SF 0 "register_operand" "=x,x,x")
2115         (vec_merge:V4SF
2116           (vec_duplicate:V4SF
2117             (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,m,rm")))
2118           (match_operand:V4SF 1 "register_operand" "0,0,x")
2119           (const_int 1)))]
2120   "TARGET_SSE && TARGET_64BIT"
2121   "@
2122    cvtsi2ssq\t{%2, %0|%0, %2}
2123    cvtsi2ssq\t{%2, %0|%0, %2}
2124    vcvtsi2ssq\t{%2, %1, %0|%0, %1, %2}"
2125   [(set_attr "isa" "noavx,noavx,avx")
2126    (set_attr "type" "sseicvt")
2127    (set_attr "athlon_decode" "vector,double,*")
2128    (set_attr "amdfam10_decode" "vector,double,*")
2129    (set_attr "bdver1_decode" "double,direct,*")
2130    (set_attr "length_vex" "*,*,4")
2131    (set_attr "prefix_rex" "1,1,*")
2132    (set_attr "prefix" "orig,orig,vex")
2133    (set_attr "mode" "SF")])
2134
2135 (define_insn "sse_cvtss2si"
2136   [(set (match_operand:SI 0 "register_operand" "=r,r")
2137         (unspec:SI
2138           [(vec_select:SF
2139              (match_operand:V4SF 1 "nonimmediate_operand" "x,m")
2140              (parallel [(const_int 0)]))]
2141           UNSPEC_FIX_NOTRUNC))]
2142   "TARGET_SSE"
2143   "%vcvtss2si\t{%1, %0|%0, %1}"
2144   [(set_attr "type" "sseicvt")
2145    (set_attr "athlon_decode" "double,vector")
2146    (set_attr "bdver1_decode" "double,double")
2147    (set_attr "prefix_rep" "1")
2148    (set_attr "prefix" "maybe_vex")
2149    (set_attr "mode" "SI")])
2150
2151 (define_insn "sse_cvtss2si_2"
2152   [(set (match_operand:SI 0 "register_operand" "=r,r")
2153         (unspec:SI [(match_operand:SF 1 "nonimmediate_operand" "x,m")]
2154                    UNSPEC_FIX_NOTRUNC))]
2155   "TARGET_SSE"
2156   "%vcvtss2si\t{%1, %0|%0, %1}"
2157   [(set_attr "type" "sseicvt")
2158    (set_attr "athlon_decode" "double,vector")
2159    (set_attr "amdfam10_decode" "double,double")
2160    (set_attr "bdver1_decode" "double,double")
2161    (set_attr "prefix_rep" "1")
2162    (set_attr "prefix" "maybe_vex")
2163    (set_attr "mode" "SI")])
2164
2165 (define_insn "sse_cvtss2siq"
2166   [(set (match_operand:DI 0 "register_operand" "=r,r")
2167         (unspec:DI
2168           [(vec_select:SF
2169              (match_operand:V4SF 1 "nonimmediate_operand" "x,m")
2170              (parallel [(const_int 0)]))]
2171           UNSPEC_FIX_NOTRUNC))]
2172   "TARGET_SSE && TARGET_64BIT"
2173   "%vcvtss2si{q}\t{%1, %0|%0, %1}"
2174   [(set_attr "type" "sseicvt")
2175    (set_attr "athlon_decode" "double,vector")
2176    (set_attr "bdver1_decode" "double,double")
2177    (set_attr "prefix_rep" "1")
2178    (set_attr "prefix" "maybe_vex")
2179    (set_attr "mode" "DI")])
2180
2181 (define_insn "sse_cvtss2siq_2"
2182   [(set (match_operand:DI 0 "register_operand" "=r,r")
2183         (unspec:DI [(match_operand:SF 1 "nonimmediate_operand" "x,m")]
2184                    UNSPEC_FIX_NOTRUNC))]
2185   "TARGET_SSE && TARGET_64BIT"
2186   "%vcvtss2si{q}\t{%1, %0|%0, %1}"
2187   [(set_attr "type" "sseicvt")
2188    (set_attr "athlon_decode" "double,vector")
2189    (set_attr "amdfam10_decode" "double,double")
2190    (set_attr "bdver1_decode" "double,double")
2191    (set_attr "prefix_rep" "1")
2192    (set_attr "prefix" "maybe_vex")
2193    (set_attr "mode" "DI")])
2194
2195 (define_insn "sse_cvttss2si"
2196   [(set (match_operand:SI 0 "register_operand" "=r,r")
2197         (fix:SI
2198           (vec_select:SF
2199             (match_operand:V4SF 1 "nonimmediate_operand" "x,m")
2200             (parallel [(const_int 0)]))))]
2201   "TARGET_SSE"
2202   "%vcvttss2si\t{%1, %0|%0, %1}"
2203   [(set_attr "type" "sseicvt")
2204    (set_attr "athlon_decode" "double,vector")
2205    (set_attr "amdfam10_decode" "double,double")
2206    (set_attr "bdver1_decode" "double,double")
2207    (set_attr "prefix_rep" "1")
2208    (set_attr "prefix" "maybe_vex")
2209    (set_attr "mode" "SI")])
2210
2211 (define_insn "sse_cvttss2siq"
2212   [(set (match_operand:DI 0 "register_operand" "=r,r")
2213         (fix:DI
2214           (vec_select:SF
2215             (match_operand:V4SF 1 "nonimmediate_operand" "x,m")
2216             (parallel [(const_int 0)]))))]
2217   "TARGET_SSE && TARGET_64BIT"
2218   "%vcvttss2si{q}\t{%1, %0|%0, %1}"
2219   [(set_attr "type" "sseicvt")
2220    (set_attr "athlon_decode" "double,vector")
2221    (set_attr "amdfam10_decode" "double,double")
2222    (set_attr "bdver1_decode" "double,double")
2223    (set_attr "prefix_rep" "1")
2224    (set_attr "prefix" "maybe_vex")
2225    (set_attr "mode" "DI")])
2226
2227 (define_insn "avx_cvtdq2ps256"
2228   [(set (match_operand:V8SF 0 "register_operand" "=x")
2229         (float:V8SF (match_operand:V8SI 1 "nonimmediate_operand" "xm")))]
2230   "TARGET_AVX"
2231   "vcvtdq2ps\t{%1, %0|%0, %1}"
2232   [(set_attr "type" "ssecvt")
2233    (set_attr "prefix" "vex")
2234    (set_attr "mode" "V8SF")])
2235
2236 (define_insn "sse2_cvtdq2ps"
2237   [(set (match_operand:V4SF 0 "register_operand" "=x")
2238         (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
2239   "TARGET_SSE2"
2240   "%vcvtdq2ps\t{%1, %0|%0, %1}"
2241   [(set_attr "type" "ssecvt")
2242    (set_attr "prefix" "maybe_vex")
2243    (set_attr "mode" "V4SF")])
2244
2245 (define_expand "sse2_cvtudq2ps"
2246   [(set (match_dup 5)
2247         (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "")))
2248    (set (match_dup 6)
2249         (lt:V4SF (match_dup 5) (match_dup 3)))
2250    (set (match_dup 7)
2251         (and:V4SF (match_dup 6) (match_dup 4)))
2252    (set (match_operand:V4SF 0 "register_operand" "")
2253         (plus:V4SF (match_dup 5) (match_dup 7)))]
2254   "TARGET_SSE2"
2255 {
2256   REAL_VALUE_TYPE TWO32r;
2257   rtx x;
2258   int i;
2259
2260   real_ldexp (&TWO32r, &dconst1, 32);
2261   x = const_double_from_real_value (TWO32r, SFmode);
2262
2263   operands[3] = force_reg (V4SFmode, CONST0_RTX (V4SFmode));
2264   operands[4] = force_reg (V4SFmode,
2265                            ix86_build_const_vector (V4SFmode, 1, x));
2266
2267   for (i = 5; i < 8; i++)
2268     operands[i] = gen_reg_rtx (V4SFmode);
2269 })
2270
2271 (define_insn "avx_cvtps2dq256"
2272   [(set (match_operand:V8SI 0 "register_operand" "=x")
2273         (unspec:V8SI [(match_operand:V8SF 1 "nonimmediate_operand" "xm")]
2274                      UNSPEC_FIX_NOTRUNC))]
2275   "TARGET_AVX"
2276   "vcvtps2dq\t{%1, %0|%0, %1}"
2277   [(set_attr "type" "ssecvt")
2278    (set_attr "prefix" "vex")
2279    (set_attr "mode" "OI")])
2280
2281 (define_insn "sse2_cvtps2dq"
2282   [(set (match_operand:V4SI 0 "register_operand" "=x")
2283         (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
2284                      UNSPEC_FIX_NOTRUNC))]
2285   "TARGET_SSE2"
2286   "%vcvtps2dq\t{%1, %0|%0, %1}"
2287   [(set_attr "type" "ssecvt")
2288    (set (attr "prefix_data16")
2289      (if_then_else
2290        (match_test "TARGET_AVX")
2291      (const_string "*")
2292      (const_string "1")))
2293    (set_attr "prefix" "maybe_vex")
2294    (set_attr "mode" "TI")])
2295
2296 (define_insn "avx_cvttps2dq256"
2297   [(set (match_operand:V8SI 0 "register_operand" "=x")
2298         (fix:V8SI (match_operand:V8SF 1 "nonimmediate_operand" "xm")))]
2299   "TARGET_AVX"
2300   "vcvttps2dq\t{%1, %0|%0, %1}"
2301   [(set_attr "type" "ssecvt")
2302    (set_attr "prefix" "vex")
2303    (set_attr "mode" "OI")])
2304
2305 (define_insn "sse2_cvttps2dq"
2306   [(set (match_operand:V4SI 0 "register_operand" "=x")
2307         (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
2308   "TARGET_SSE2"
2309   "%vcvttps2dq\t{%1, %0|%0, %1}"
2310   [(set_attr "type" "ssecvt")
2311    (set (attr "prefix_rep")
2312      (if_then_else
2313        (match_test "TARGET_AVX")
2314      (const_string "*")
2315      (const_string "1")))
2316    (set (attr "prefix_data16")
2317      (if_then_else
2318        (match_test "TARGET_AVX")
2319      (const_string "*")
2320      (const_string "0")))
2321    (set_attr "prefix_data16" "0")
2322    (set_attr "prefix" "maybe_vex")
2323    (set_attr "mode" "TI")])
2324
2325 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2326 ;;
2327 ;; Parallel double-precision floating point conversion operations
2328 ;;
2329 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2330
2331 (define_insn "sse2_cvtpi2pd"
2332   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
2333         (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "y,m")))]
2334   "TARGET_SSE2"
2335   "cvtpi2pd\t{%1, %0|%0, %1}"
2336   [(set_attr "type" "ssecvt")
2337    (set_attr "unit" "mmx,*")
2338    (set_attr "prefix_data16" "1,*")
2339    (set_attr "mode" "V2DF")])
2340
2341 (define_insn "sse2_cvtpd2pi"
2342   [(set (match_operand:V2SI 0 "register_operand" "=y")
2343         (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
2344                      UNSPEC_FIX_NOTRUNC))]
2345   "TARGET_SSE2"
2346   "cvtpd2pi\t{%1, %0|%0, %1}"
2347   [(set_attr "type" "ssecvt")
2348    (set_attr "unit" "mmx")
2349    (set_attr "bdver1_decode" "double")
2350    (set_attr "prefix_data16" "1")
2351    (set_attr "mode" "DI")])
2352
2353 (define_insn "sse2_cvttpd2pi"
2354   [(set (match_operand:V2SI 0 "register_operand" "=y")
2355         (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
2356   "TARGET_SSE2"
2357   "cvttpd2pi\t{%1, %0|%0, %1}"
2358   [(set_attr "type" "ssecvt")
2359    (set_attr "unit" "mmx")
2360    (set_attr "bdver1_decode" "double")
2361    (set_attr "prefix_data16" "1")
2362    (set_attr "mode" "TI")])
2363
2364 (define_insn "sse2_cvtsi2sd"
2365   [(set (match_operand:V2DF 0 "register_operand" "=x,x,x")
2366         (vec_merge:V2DF
2367           (vec_duplicate:V2DF
2368             (float:DF (match_operand:SI 2 "nonimmediate_operand" "r,m,rm")))
2369           (match_operand:V2DF 1 "register_operand" "0,0,x")
2370           (const_int 1)))]
2371   "TARGET_SSE2"
2372   "@
2373    cvtsi2sd\t{%2, %0|%0, %2}
2374    cvtsi2sd\t{%2, %0|%0, %2}
2375    vcvtsi2sd\t{%2, %1, %0|%0, %1, %2}"
2376   [(set_attr "isa" "noavx,noavx,avx")
2377    (set_attr "type" "sseicvt")
2378    (set_attr "athlon_decode" "double,direct,*")
2379    (set_attr "amdfam10_decode" "vector,double,*")
2380    (set_attr "bdver1_decode" "double,direct,*")
2381    (set_attr "prefix" "orig,orig,vex")
2382    (set_attr "mode" "DF")])
2383
2384 (define_insn "sse2_cvtsi2sdq"
2385   [(set (match_operand:V2DF 0 "register_operand" "=x,x,x")
2386         (vec_merge:V2DF
2387           (vec_duplicate:V2DF
2388             (float:DF (match_operand:DI 2 "nonimmediate_operand" "r,m,rm")))
2389           (match_operand:V2DF 1 "register_operand" "0,0,x")
2390           (const_int 1)))]
2391   "TARGET_SSE2 && TARGET_64BIT"
2392   "@
2393    cvtsi2sdq\t{%2, %0|%0, %2}
2394    cvtsi2sdq\t{%2, %0|%0, %2}
2395    vcvtsi2sdq\t{%2, %1, %0|%0, %1, %2}"
2396   [(set_attr "isa" "noavx,noavx,avx")
2397    (set_attr "type" "sseicvt")
2398    (set_attr "athlon_decode" "double,direct,*")
2399    (set_attr "amdfam10_decode" "vector,double,*")
2400    (set_attr "bdver1_decode" "double,direct,*")
2401    (set_attr "length_vex" "*,*,4")
2402    (set_attr "prefix_rex" "1,1,*")
2403    (set_attr "prefix" "orig,orig,vex")
2404    (set_attr "mode" "DF")])
2405
2406 (define_insn "sse2_cvtsd2si"
2407   [(set (match_operand:SI 0 "register_operand" "=r,r")
2408         (unspec:SI
2409           [(vec_select:DF
2410              (match_operand:V2DF 1 "nonimmediate_operand" "x,m")
2411              (parallel [(const_int 0)]))]
2412           UNSPEC_FIX_NOTRUNC))]
2413   "TARGET_SSE2"
2414   "%vcvtsd2si\t{%1, %0|%0, %1}"
2415   [(set_attr "type" "sseicvt")
2416    (set_attr "athlon_decode" "double,vector")
2417    (set_attr "bdver1_decode" "double,double")
2418    (set_attr "prefix_rep" "1")
2419    (set_attr "prefix" "maybe_vex")
2420    (set_attr "mode" "SI")])
2421
2422 (define_insn "sse2_cvtsd2si_2"
2423   [(set (match_operand:SI 0 "register_operand" "=r,r")
2424         (unspec:SI [(match_operand:DF 1 "nonimmediate_operand" "x,m")]
2425                    UNSPEC_FIX_NOTRUNC))]
2426   "TARGET_SSE2"
2427   "%vcvtsd2si\t{%1, %0|%0, %1}"
2428   [(set_attr "type" "sseicvt")
2429    (set_attr "athlon_decode" "double,vector")
2430    (set_attr "amdfam10_decode" "double,double")
2431    (set_attr "bdver1_decode" "double,double")
2432    (set_attr "prefix_rep" "1")
2433    (set_attr "prefix" "maybe_vex")
2434    (set_attr "mode" "SI")])
2435
2436 (define_insn "sse2_cvtsd2siq"
2437   [(set (match_operand:DI 0 "register_operand" "=r,r")
2438         (unspec:DI
2439           [(vec_select:DF
2440              (match_operand:V2DF 1 "nonimmediate_operand" "x,m")
2441              (parallel [(const_int 0)]))]
2442           UNSPEC_FIX_NOTRUNC))]
2443   "TARGET_SSE2 && TARGET_64BIT"
2444   "%vcvtsd2si{q}\t{%1, %0|%0, %1}"
2445   [(set_attr "type" "sseicvt")
2446    (set_attr "athlon_decode" "double,vector")
2447    (set_attr "bdver1_decode" "double,double")
2448    (set_attr "prefix_rep" "1")
2449    (set_attr "prefix" "maybe_vex")
2450    (set_attr "mode" "DI")])
2451
2452 (define_insn "sse2_cvtsd2siq_2"
2453   [(set (match_operand:DI 0 "register_operand" "=r,r")
2454         (unspec:DI [(match_operand:DF 1 "nonimmediate_operand" "x,m")]
2455                    UNSPEC_FIX_NOTRUNC))]
2456   "TARGET_SSE2 && TARGET_64BIT"
2457   "%vcvtsd2si{q}\t{%1, %0|%0, %1}"
2458   [(set_attr "type" "sseicvt")
2459    (set_attr "athlon_decode" "double,vector")
2460    (set_attr "amdfam10_decode" "double,double")
2461    (set_attr "bdver1_decode" "double,double")
2462    (set_attr "prefix_rep" "1")
2463    (set_attr "prefix" "maybe_vex")
2464    (set_attr "mode" "DI")])
2465
2466 (define_insn "sse2_cvttsd2si"
2467   [(set (match_operand:SI 0 "register_operand" "=r,r")
2468         (fix:SI
2469           (vec_select:DF
2470             (match_operand:V2DF 1 "nonimmediate_operand" "x,m")
2471             (parallel [(const_int 0)]))))]
2472   "TARGET_SSE2"
2473   "%vcvttsd2si\t{%1, %0|%0, %1}"
2474   [(set_attr "type" "sseicvt")
2475    (set_attr "athlon_decode" "double,vector")
2476    (set_attr "amdfam10_decode" "double,double")
2477    (set_attr "bdver1_decode" "double,double")
2478    (set_attr "prefix_rep" "1")
2479    (set_attr "prefix" "maybe_vex")
2480    (set_attr "mode" "SI")])
2481
2482 (define_insn "sse2_cvttsd2siq"
2483   [(set (match_operand:DI 0 "register_operand" "=r,r")
2484         (fix:DI
2485           (vec_select:DF
2486             (match_operand:V2DF 1 "nonimmediate_operand" "x,m")
2487             (parallel [(const_int 0)]))))]
2488   "TARGET_SSE2 && TARGET_64BIT"
2489   "%vcvttsd2si{q}\t{%1, %0|%0, %1}"
2490   [(set_attr "type" "sseicvt")
2491    (set_attr "athlon_decode" "double,vector")
2492    (set_attr "amdfam10_decode" "double,double")
2493    (set_attr "bdver1_decode" "double,double")
2494    (set_attr "prefix_rep" "1")
2495    (set_attr "prefix" "maybe_vex")
2496    (set_attr "mode" "DI")])
2497
2498 (define_insn "avx_cvtdq2pd256"
2499   [(set (match_operand:V4DF 0 "register_operand" "=x")
2500         (float:V4DF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
2501   "TARGET_AVX"
2502   "vcvtdq2pd\t{%1, %0|%0, %1}"
2503   [(set_attr "type" "ssecvt")
2504    (set_attr "prefix" "vex")
2505    (set_attr "mode" "V4DF")])
2506
2507 (define_insn "avx_cvtdq2pd256_2"
2508   [(set (match_operand:V4DF 0 "register_operand" "=x")
2509         (float:V4DF
2510           (vec_select:V4SI
2511             (match_operand:V8SI 1 "nonimmediate_operand" "xm")
2512             (parallel [(const_int 0) (const_int 1)
2513                        (const_int 2) (const_int 3)]))))]
2514   "TARGET_AVX"
2515   "vcvtdq2pd\t{%x1, %0|%0, %x1}"
2516   [(set_attr "type" "ssecvt")
2517    (set_attr "prefix" "vex")
2518    (set_attr "mode" "V4DF")])
2519
2520 (define_insn "sse2_cvtdq2pd"
2521   [(set (match_operand:V2DF 0 "register_operand" "=x")
2522         (float:V2DF
2523           (vec_select:V2SI
2524             (match_operand:V4SI 1 "nonimmediate_operand" "xm")
2525             (parallel [(const_int 0) (const_int 1)]))))]
2526   "TARGET_SSE2"
2527   "%vcvtdq2pd\t{%1, %0|%0, %q1}"
2528   [(set_attr "type" "ssecvt")
2529    (set_attr "prefix" "maybe_vex")
2530    (set_attr "mode" "V2DF")])
2531
2532 (define_insn "avx_cvtpd2dq256"
2533   [(set (match_operand:V4SI 0 "register_operand" "=x")
2534         (unspec:V4SI [(match_operand:V4DF 1 "nonimmediate_operand" "xm")]
2535                      UNSPEC_FIX_NOTRUNC))]
2536   "TARGET_AVX"
2537   "vcvtpd2dq{y}\t{%1, %0|%0, %1}"
2538   [(set_attr "type" "ssecvt")
2539    (set_attr "prefix" "vex")
2540    (set_attr "mode" "OI")])
2541
2542 (define_expand "avx_cvtpd2dq256_2"
2543   [(set (match_operand:V8SI 0 "register_operand" "")
2544         (vec_concat:V8SI
2545           (unspec:V4SI [(match_operand:V4DF 1 "nonimmediate_operand" "")]
2546                        UNSPEC_FIX_NOTRUNC)
2547           (match_dup 2)))]
2548   "TARGET_AVX"
2549   "operands[2] = CONST0_RTX (V4SImode);")
2550
2551 (define_insn "*avx_cvtpd2dq256_2"
2552   [(set (match_operand:V8SI 0 "register_operand" "=x")
2553         (vec_concat:V8SI
2554           (unspec:V4SI [(match_operand:V4DF 1 "nonimmediate_operand" "xm")]
2555                        UNSPEC_FIX_NOTRUNC)
2556           (match_operand:V4SI 2 "const0_operand" "")))]
2557   "TARGET_AVX"
2558   "vcvtpd2dq{y}\t{%1, %x0|%x0, %1}"
2559   [(set_attr "type" "ssecvt")
2560    (set_attr "prefix" "vex")
2561    (set_attr "mode" "OI")])
2562
2563 (define_expand "sse2_cvtpd2dq"
2564   [(set (match_operand:V4SI 0 "register_operand" "")
2565         (vec_concat:V4SI
2566           (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "")]
2567                        UNSPEC_FIX_NOTRUNC)
2568           (match_dup 2)))]
2569   "TARGET_SSE2"
2570   "operands[2] = CONST0_RTX (V2SImode);")
2571
2572 (define_insn "*sse2_cvtpd2dq"
2573   [(set (match_operand:V4SI 0 "register_operand" "=x")
2574         (vec_concat:V4SI
2575           (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
2576                        UNSPEC_FIX_NOTRUNC)
2577           (match_operand:V2SI 2 "const0_operand" "")))]
2578   "TARGET_SSE2"
2579 {
2580   if (TARGET_AVX)
2581     return "vcvtpd2dq{x}\t{%1, %0|%0, %1}";
2582   else
2583     return "cvtpd2dq\t{%1, %0|%0, %1}";
2584 }
2585   [(set_attr "type" "ssecvt")
2586    (set_attr "prefix_rep" "1")
2587    (set_attr "prefix_data16" "0")
2588    (set_attr "prefix" "maybe_vex")
2589    (set_attr "mode" "TI")
2590    (set_attr "amdfam10_decode" "double")
2591    (set_attr "athlon_decode" "vector")
2592    (set_attr "bdver1_decode" "double")])
2593
2594 (define_insn "avx_cvttpd2dq256"
2595   [(set (match_operand:V4SI 0 "register_operand" "=x")
2596         (fix:V4SI (match_operand:V4DF 1 "nonimmediate_operand" "xm")))]
2597   "TARGET_AVX"
2598   "vcvttpd2dq{y}\t{%1, %0|%0, %1}"
2599   [(set_attr "type" "ssecvt")
2600    (set_attr "prefix" "vex")
2601    (set_attr "mode" "OI")])
2602
2603 (define_expand "avx_cvttpd2dq256_2"
2604   [(set (match_operand:V8SI 0 "register_operand" "")
2605         (vec_concat:V8SI
2606           (fix:V4SI (match_operand:V4DF 1 "nonimmediate_operand" ""))
2607           (match_dup 2)))]
2608   "TARGET_AVX"
2609   "operands[2] = CONST0_RTX (V4SImode);")
2610
2611 (define_insn "*avx_cvttpd2dq256_2"
2612   [(set (match_operand:V8SI 0 "register_operand" "=x")
2613         (vec_concat:V8SI
2614           (fix:V4SI (match_operand:V4DF 1 "nonimmediate_operand" "xm"))
2615           (match_operand:V4SI 2 "const0_operand" "")))]
2616   "TARGET_AVX"
2617   "vcvttpd2dq{y}\t{%1, %x0|%x0, %1}"
2618   [(set_attr "type" "ssecvt")
2619    (set_attr "prefix" "vex")
2620    (set_attr "mode" "OI")])
2621
2622 (define_expand "sse2_cvttpd2dq"
2623   [(set (match_operand:V4SI 0 "register_operand" "")
2624         (vec_concat:V4SI
2625           (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" ""))
2626           (match_dup 2)))]
2627   "TARGET_SSE2"
2628   "operands[2] = CONST0_RTX (V2SImode);")
2629
2630 (define_insn "*sse2_cvttpd2dq"
2631   [(set (match_operand:V4SI 0 "register_operand" "=x")
2632         (vec_concat:V4SI
2633           (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
2634           (match_operand:V2SI 2 "const0_operand" "")))]
2635   "TARGET_SSE2"
2636 {
2637   if (TARGET_AVX)
2638     return "vcvttpd2dq{x}\t{%1, %0|%0, %1}";
2639   else
2640     return "cvttpd2dq\t{%1, %0|%0, %1}";
2641 }
2642   [(set_attr "type" "ssecvt")
2643    (set_attr "amdfam10_decode" "double")
2644    (set_attr "athlon_decode" "vector")
2645    (set_attr "bdver1_decode" "double")
2646    (set_attr "prefix" "maybe_vex")
2647    (set_attr "mode" "TI")])
2648
2649 (define_insn "sse2_cvtsd2ss"
2650   [(set (match_operand:V4SF 0 "register_operand" "=x,x,x")
2651         (vec_merge:V4SF
2652           (vec_duplicate:V4SF
2653             (float_truncate:V2SF
2654               (match_operand:V2DF 2 "nonimmediate_operand" "x,m,xm")))
2655           (match_operand:V4SF 1 "register_operand" "0,0,x")
2656           (const_int 1)))]
2657   "TARGET_SSE2"
2658   "@
2659    cvtsd2ss\t{%2, %0|%0, %2}
2660    cvtsd2ss\t{%2, %0|%0, %2}
2661    vcvtsd2ss\t{%2, %1, %0|%0, %1, %2}"
2662   [(set_attr "isa" "noavx,noavx,avx")
2663    (set_attr "type" "ssecvt")
2664    (set_attr "athlon_decode" "vector,double,*")
2665    (set_attr "amdfam10_decode" "vector,double,*")
2666    (set_attr "bdver1_decode" "direct,direct,*")
2667    (set_attr "prefix" "orig,orig,vex")
2668    (set_attr "mode" "SF")])
2669
2670 (define_insn "sse2_cvtss2sd"
2671   [(set (match_operand:V2DF 0 "register_operand" "=x,x,x")
2672         (vec_merge:V2DF
2673           (float_extend:V2DF
2674             (vec_select:V2SF
2675               (match_operand:V4SF 2 "nonimmediate_operand" "x,m,xm")
2676               (parallel [(const_int 0) (const_int 1)])))
2677           (match_operand:V2DF 1 "register_operand" "0,0,x")
2678           (const_int 1)))]
2679   "TARGET_SSE2"
2680   "@
2681    cvtss2sd\t{%2, %0|%0, %2}
2682    cvtss2sd\t{%2, %0|%0, %2}
2683    vcvtss2sd\t{%2, %1, %0|%0, %1, %2}"
2684   [(set_attr "isa" "noavx,noavx,avx")
2685    (set_attr "type" "ssecvt")
2686    (set_attr "amdfam10_decode" "vector,double,*")
2687    (set_attr "athlon_decode" "direct,direct,*")
2688    (set_attr "bdver1_decode" "direct,direct,*")
2689    (set_attr "prefix" "orig,orig,vex")
2690    (set_attr "mode" "DF")])
2691
2692 (define_insn "avx_cvtpd2ps256"
2693   [(set (match_operand:V4SF 0 "register_operand" "=x")
2694         (float_truncate:V4SF
2695           (match_operand:V4DF 1 "nonimmediate_operand" "xm")))]
2696   "TARGET_AVX"
2697   "vcvtpd2ps{y}\t{%1, %0|%0, %1}"
2698   [(set_attr "type" "ssecvt")
2699    (set_attr "prefix" "vex")
2700    (set_attr "mode" "V4SF")])
2701
2702 (define_expand "sse2_cvtpd2ps"
2703   [(set (match_operand:V4SF 0 "register_operand" "")
2704         (vec_concat:V4SF
2705           (float_truncate:V2SF
2706             (match_operand:V2DF 1 "nonimmediate_operand" ""))
2707           (match_dup 2)))]
2708   "TARGET_SSE2"
2709   "operands[2] = CONST0_RTX (V2SFmode);")
2710
2711 (define_insn "*sse2_cvtpd2ps"
2712   [(set (match_operand:V4SF 0 "register_operand" "=x")
2713         (vec_concat:V4SF
2714           (float_truncate:V2SF
2715             (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
2716           (match_operand:V2SF 2 "const0_operand" "")))]
2717   "TARGET_SSE2"
2718 {
2719   if (TARGET_AVX)
2720     return "vcvtpd2ps{x}\t{%1, %0|%0, %1}";
2721   else
2722     return "cvtpd2ps\t{%1, %0|%0, %1}";
2723 }
2724   [(set_attr "type" "ssecvt")
2725    (set_attr "amdfam10_decode" "double")
2726    (set_attr "athlon_decode" "vector")
2727    (set_attr "bdver1_decode" "double")
2728    (set_attr "prefix_data16" "1")
2729    (set_attr "prefix" "maybe_vex")
2730    (set_attr "mode" "V4SF")])
2731
2732 (define_insn "avx_cvtps2pd256"
2733   [(set (match_operand:V4DF 0 "register_operand" "=x")
2734         (float_extend:V4DF
2735           (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
2736   "TARGET_AVX"
2737   "vcvtps2pd\t{%1, %0|%0, %1}"
2738   [(set_attr "type" "ssecvt")
2739    (set_attr "prefix" "vex")
2740    (set_attr "mode" "V4DF")])
2741
2742 (define_insn "*avx_cvtps2pd256_2"
2743   [(set (match_operand:V4DF 0 "register_operand" "=x")
2744         (float_extend:V4DF
2745           (vec_select:V4SF
2746             (match_operand:V8SF 1 "nonimmediate_operand" "xm")
2747             (parallel [(const_int 0) (const_int 1)
2748                        (const_int 2) (const_int 3)]))))]
2749   "TARGET_AVX"
2750   "vcvtps2pd\t{%x1, %0|%0, %x1}"
2751   [(set_attr "type" "ssecvt")
2752    (set_attr "prefix" "vex")
2753    (set_attr "mode" "V4DF")])
2754
2755 (define_insn "sse2_cvtps2pd"
2756   [(set (match_operand:V2DF 0 "register_operand" "=x")
2757         (float_extend:V2DF
2758           (vec_select:V2SF
2759             (match_operand:V4SF 1 "nonimmediate_operand" "xm")
2760             (parallel [(const_int 0) (const_int 1)]))))]
2761   "TARGET_SSE2"
2762   "%vcvtps2pd\t{%1, %0|%0, %q1}"
2763   [(set_attr "type" "ssecvt")
2764    (set_attr "amdfam10_decode" "direct")
2765    (set_attr "athlon_decode" "double")
2766    (set_attr "bdver1_decode" "double")
2767    (set_attr "prefix_data16" "0")
2768    (set_attr "prefix" "maybe_vex")
2769    (set_attr "mode" "V2DF")])
2770
2771 (define_expand "vec_unpacks_hi_v4sf"
2772   [(set (match_dup 2)
2773    (vec_select:V4SF
2774      (vec_concat:V8SF
2775        (match_dup 2)
2776        (match_operand:V4SF 1 "nonimmediate_operand" ""))
2777      (parallel [(const_int 6) (const_int 7)
2778                 (const_int 2) (const_int 3)])))
2779   (set (match_operand:V2DF 0 "register_operand" "")
2780    (float_extend:V2DF
2781      (vec_select:V2SF
2782        (match_dup 2)
2783        (parallel [(const_int 0) (const_int 1)]))))]
2784   "TARGET_SSE2"
2785   "operands[2] = gen_reg_rtx (V4SFmode);")
2786
2787 (define_expand "vec_unpacks_hi_v8sf"
2788   [(set (match_dup 2)
2789         (vec_select:V4SF
2790           (match_operand:V8SF 1 "nonimmediate_operand" "")
2791           (parallel [(const_int 4) (const_int 5)
2792                      (const_int 6) (const_int 7)])))
2793    (set (match_operand:V4DF 0 "register_operand" "")
2794         (float_extend:V4DF
2795           (match_dup 2)))]
2796   "TARGET_AVX"
2797   "operands[2] = gen_reg_rtx (V4SFmode);")
2798
2799 (define_expand "vec_unpacks_lo_v4sf"
2800   [(set (match_operand:V2DF 0 "register_operand" "")
2801         (float_extend:V2DF
2802           (vec_select:V2SF
2803             (match_operand:V4SF 1 "nonimmediate_operand" "")
2804             (parallel [(const_int 0) (const_int 1)]))))]
2805   "TARGET_SSE2")
2806
2807 (define_expand "vec_unpacks_lo_v8sf"
2808   [(set (match_operand:V4DF 0 "register_operand" "")
2809         (float_extend:V4DF
2810           (vec_select:V4SF
2811             (match_operand:V8SF 1 "nonimmediate_operand" "")
2812             (parallel [(const_int 0) (const_int 1)
2813                        (const_int 2) (const_int 3)]))))]
2814   "TARGET_AVX")
2815
2816 (define_mode_attr sseunpackfltmode
2817   [(V8HI "V4SF") (V4SI "V2DF") (V16HI "V8SF") (V8SI "V4DF")])
2818
2819 (define_expand "vec_unpacks_float_hi_<mode>"
2820   [(match_operand:<sseunpackfltmode> 0 "register_operand" "")
2821    (match_operand:VI2_AVX2 1 "register_operand" "")]
2822   "TARGET_SSE2"
2823 {
2824   rtx tmp = gen_reg_rtx (<sseunpackmode>mode);
2825
2826   emit_insn (gen_vec_unpacks_hi_<mode> (tmp, operands[1]));
2827   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2828                           gen_rtx_FLOAT (<sseunpackfltmode>mode, tmp)));
2829   DONE;
2830 })
2831
2832 (define_expand "vec_unpacks_float_lo_<mode>"
2833   [(match_operand:<sseunpackfltmode> 0 "register_operand" "")
2834    (match_operand:VI2_AVX2 1 "register_operand" "")]
2835   "TARGET_SSE2"
2836 {
2837   rtx tmp = gen_reg_rtx (<sseunpackmode>mode);
2838
2839   emit_insn (gen_vec_unpacks_lo_<mode> (tmp, operands[1]));
2840   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2841                           gen_rtx_FLOAT (<sseunpackfltmode>mode, tmp)));
2842   DONE;
2843 })
2844
2845 (define_expand "vec_unpacku_float_hi_<mode>"
2846   [(match_operand:<sseunpackfltmode> 0 "register_operand" "")
2847    (match_operand:VI2_AVX2 1 "register_operand" "")]
2848   "TARGET_SSE2"
2849 {
2850   rtx tmp = gen_reg_rtx (<sseunpackmode>mode);
2851
2852   emit_insn (gen_vec_unpacku_hi_<mode> (tmp, operands[1]));
2853   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2854                           gen_rtx_FLOAT (<sseunpackfltmode>mode, tmp)));
2855   DONE;
2856 })
2857
2858 (define_expand "vec_unpacku_float_lo_<mode>"
2859   [(match_operand:<sseunpackfltmode> 0 "register_operand" "")
2860    (match_operand:VI2_AVX2 1 "register_operand" "")]
2861   "TARGET_SSE2"
2862 {
2863   rtx tmp = gen_reg_rtx (<sseunpackmode>mode);
2864
2865   emit_insn (gen_vec_unpacku_lo_<mode> (tmp, operands[1]));
2866   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2867                           gen_rtx_FLOAT (<sseunpackfltmode>mode, tmp)));
2868   DONE;
2869 })
2870
2871 (define_expand "vec_unpacks_float_hi_v4si"
2872   [(set (match_dup 2)
2873         (vec_select:V4SI
2874           (match_operand:V4SI 1 "nonimmediate_operand" "")
2875           (parallel [(const_int 2) (const_int 3)
2876                      (const_int 2) (const_int 3)])))
2877    (set (match_operand:V2DF 0 "register_operand" "")
2878         (float:V2DF
2879           (vec_select:V2SI
2880           (match_dup 2)
2881             (parallel [(const_int 0) (const_int 1)]))))]
2882   "TARGET_SSE2"
2883   "operands[2] = gen_reg_rtx (V4SImode);")
2884
2885 (define_expand "vec_unpacks_float_lo_v4si"
2886   [(set (match_operand:V2DF 0 "register_operand" "")
2887         (float:V2DF
2888           (vec_select:V2SI
2889             (match_operand:V4SI 1 "nonimmediate_operand" "")
2890             (parallel [(const_int 0) (const_int 1)]))))]
2891   "TARGET_SSE2")
2892
2893 (define_expand "vec_unpacks_float_hi_v8si"
2894   [(set (match_dup 2)
2895         (vec_select:V4SI
2896           (match_operand:V8SI 1 "nonimmediate_operand" "")
2897           (parallel [(const_int 4) (const_int 5)
2898                      (const_int 6) (const_int 7)])))
2899    (set (match_operand:V4DF 0 "register_operand" "")
2900         (float:V4DF
2901           (match_dup 2)))]
2902   "TARGET_AVX"
2903   "operands[2] = gen_reg_rtx (V4SImode);")
2904
2905 (define_expand "vec_unpacks_float_lo_v8si"
2906   [(set (match_operand:V4DF 0 "register_operand" "")
2907         (float:V4DF
2908           (vec_select:V4SI
2909             (match_operand:V8SI 1 "nonimmediate_operand" "")
2910             (parallel [(const_int 0) (const_int 1)
2911                        (const_int 2) (const_int 3)]))))]
2912   "TARGET_AVX")
2913
2914 (define_expand "vec_unpacku_float_hi_v4si"
2915   [(set (match_dup 5)
2916         (vec_select:V4SI
2917           (match_operand:V4SI 1 "nonimmediate_operand" "")
2918           (parallel [(const_int 2) (const_int 3)
2919                      (const_int 2) (const_int 3)])))
2920    (set (match_dup 6)
2921         (float:V2DF
2922           (vec_select:V2SI
2923           (match_dup 5)
2924             (parallel [(const_int 0) (const_int 1)]))))
2925    (set (match_dup 7)
2926         (lt:V2DF (match_dup 6) (match_dup 3)))
2927    (set (match_dup 8)
2928         (and:V2DF (match_dup 7) (match_dup 4)))
2929    (set (match_operand:V2DF 0 "register_operand" "")
2930         (plus:V2DF (match_dup 6) (match_dup 8)))]
2931   "TARGET_SSE2"
2932 {
2933   REAL_VALUE_TYPE TWO32r;
2934   rtx x;
2935   int i;
2936
2937   real_ldexp (&TWO32r, &dconst1, 32);
2938   x = const_double_from_real_value (TWO32r, DFmode);
2939
2940   operands[3] = force_reg (V2DFmode, CONST0_RTX (V2DFmode));
2941   operands[4] = force_reg (V2DFmode,
2942                            ix86_build_const_vector (V2DFmode, 1, x));
2943
2944   operands[5] = gen_reg_rtx (V4SImode);
2945
2946   for (i = 6; i < 9; i++)
2947     operands[i] = gen_reg_rtx (V2DFmode);
2948 })
2949
2950 (define_expand "vec_unpacku_float_lo_v4si"
2951   [(set (match_dup 5)
2952         (float:V2DF
2953           (vec_select:V2SI
2954             (match_operand:V4SI 1 "nonimmediate_operand" "")
2955             (parallel [(const_int 0) (const_int 1)]))))
2956    (set (match_dup 6)
2957         (lt:V2DF (match_dup 5) (match_dup 3)))
2958    (set (match_dup 7)
2959         (and:V2DF (match_dup 6) (match_dup 4)))
2960    (set (match_operand:V2DF 0 "register_operand" "")
2961         (plus:V2DF (match_dup 5) (match_dup 7)))]
2962   "TARGET_SSE2"
2963 {
2964   REAL_VALUE_TYPE TWO32r;
2965   rtx x;
2966   int i;
2967
2968   real_ldexp (&TWO32r, &dconst1, 32);
2969   x = const_double_from_real_value (TWO32r, DFmode);
2970
2971   operands[3] = force_reg (V2DFmode, CONST0_RTX (V2DFmode));
2972   operands[4] = force_reg (V2DFmode,
2973                            ix86_build_const_vector (V2DFmode, 1, x));
2974
2975   for (i = 5; i < 8; i++)
2976     operands[i] = gen_reg_rtx (V2DFmode);
2977 })
2978
2979 (define_expand "vec_unpacku_float_hi_v8si"
2980   [(match_operand:V4DF 0 "register_operand" "")
2981    (match_operand:V8SI 1 "register_operand" "")]
2982   "TARGET_AVX"
2983 {
2984   REAL_VALUE_TYPE TWO32r;
2985   rtx x, tmp[6];
2986   int i;
2987
2988   real_ldexp (&TWO32r, &dconst1, 32);
2989   x = const_double_from_real_value (TWO32r, DFmode);
2990
2991   tmp[0] = force_reg (V4DFmode, CONST0_RTX (V4DFmode));
2992   tmp[1] = force_reg (V4DFmode, ix86_build_const_vector (V4DFmode, 1, x));
2993   tmp[5] = gen_reg_rtx (V4SImode);
2994
2995   for (i = 2; i < 5; i++)
2996     tmp[i] = gen_reg_rtx (V4DFmode);
2997   emit_insn (gen_vec_extract_hi_v8si (tmp[5], operands[1]));
2998   emit_insn (gen_avx_cvtdq2pd256 (tmp[2], tmp[5]));
2999   emit_insn (gen_rtx_SET (VOIDmode, tmp[3],
3000                           gen_rtx_LT (V4DFmode, tmp[2], tmp[0])));
3001   emit_insn (gen_andv4df3 (tmp[4], tmp[3], tmp[1]));
3002   emit_insn (gen_addv4df3 (operands[0], tmp[2], tmp[4]));
3003   DONE;
3004 })
3005
3006 (define_expand "vec_unpacku_float_lo_v8si"
3007   [(match_operand:V4DF 0 "register_operand" "")
3008    (match_operand:V8SI 1 "nonimmediate_operand" "")]
3009   "TARGET_AVX"
3010 {
3011   REAL_VALUE_TYPE TWO32r;
3012   rtx x, tmp[5];
3013   int i;
3014
3015   real_ldexp (&TWO32r, &dconst1, 32);
3016   x = const_double_from_real_value (TWO32r, DFmode);
3017
3018   tmp[0] = force_reg (V4DFmode, CONST0_RTX (V4DFmode));
3019   tmp[1] = force_reg (V4DFmode, ix86_build_const_vector (V4DFmode, 1, x));
3020
3021   for (i = 2; i < 5; i++)
3022     tmp[i] = gen_reg_rtx (V4DFmode);
3023   emit_insn (gen_avx_cvtdq2pd256_2 (tmp[2], operands[1]));
3024   emit_insn (gen_rtx_SET (VOIDmode, tmp[3],
3025                           gen_rtx_LT (V4DFmode, tmp[2], tmp[0])));
3026   emit_insn (gen_andv4df3 (tmp[4], tmp[3], tmp[1]));
3027   emit_insn (gen_addv4df3 (operands[0], tmp[2], tmp[4]));
3028   DONE;
3029 })
3030
3031 (define_expand "vec_pack_trunc_v4df"
3032   [(set (match_dup 3)
3033         (float_truncate:V4SF
3034           (match_operand:V4DF 1 "nonimmediate_operand" "")))
3035    (set (match_dup 4)
3036         (float_truncate:V4SF
3037           (match_operand:V4DF 2 "nonimmediate_operand" "")))
3038    (set (match_operand:V8SF 0 "register_operand" "")
3039         (vec_concat:V8SF
3040           (match_dup 3)
3041           (match_dup 4)))]
3042   "TARGET_AVX"
3043 {
3044   operands[3] = gen_reg_rtx (V4SFmode);
3045   operands[4] = gen_reg_rtx (V4SFmode);
3046 })
3047
3048 (define_expand "vec_pack_trunc_v2df"
3049   [(match_operand:V4SF 0 "register_operand" "")
3050    (match_operand:V2DF 1 "nonimmediate_operand" "")
3051    (match_operand:V2DF 2 "nonimmediate_operand" "")]
3052   "TARGET_SSE2"
3053 {
3054   rtx r1, r2;
3055
3056   r1 = gen_reg_rtx (V4SFmode);
3057   r2 = gen_reg_rtx (V4SFmode);
3058
3059   emit_insn (gen_sse2_cvtpd2ps (r1, operands[1]));
3060   emit_insn (gen_sse2_cvtpd2ps (r2, operands[2]));
3061   emit_insn (gen_sse_movlhps (operands[0], r1, r2));
3062   DONE;
3063 })
3064
3065 (define_expand "vec_pack_sfix_trunc_v4df"
3066   [(match_operand:V8SI 0 "register_operand" "")
3067    (match_operand:V4DF 1 "nonimmediate_operand" "")
3068    (match_operand:V4DF 2 "nonimmediate_operand" "")]
3069   "TARGET_AVX"
3070 {
3071   rtx r1, r2;
3072
3073   r1 = gen_reg_rtx (V8SImode);
3074   r2 = gen_reg_rtx (V8SImode);
3075
3076   emit_insn (gen_avx_cvttpd2dq256_2 (r1, operands[1]));
3077   emit_insn (gen_avx_cvttpd2dq256_2 (r2, operands[2]));
3078   emit_insn (gen_avx_vperm2f128v8si3 (operands[0], r1, r2, GEN_INT (0x20)));
3079   DONE;
3080 })
3081
3082 (define_expand "vec_pack_sfix_trunc_v2df"
3083   [(match_operand:V4SI 0 "register_operand" "")
3084    (match_operand:V2DF 1 "nonimmediate_operand" "")
3085    (match_operand:V2DF 2 "nonimmediate_operand" "")]
3086   "TARGET_SSE2"
3087 {
3088   rtx r1, r2;
3089
3090   r1 = gen_reg_rtx (V4SImode);
3091   r2 = gen_reg_rtx (V4SImode);
3092
3093   emit_insn (gen_sse2_cvttpd2dq (r1, operands[1]));
3094   emit_insn (gen_sse2_cvttpd2dq (r2, operands[2]));
3095   emit_insn (gen_vec_interleave_lowv2di (gen_lowpart (V2DImode, operands[0]),
3096                                          gen_lowpart (V2DImode, r1),
3097                                          gen_lowpart (V2DImode, r2)));
3098   DONE;
3099 })
3100
3101 (define_expand "vec_pack_sfix_v4df"
3102   [(match_operand:V8SI 0 "register_operand" "")
3103    (match_operand:V4DF 1 "nonimmediate_operand" "")
3104    (match_operand:V4DF 2 "nonimmediate_operand" "")]
3105   "TARGET_AVX"
3106 {
3107   rtx r1, r2;
3108
3109   r1 = gen_reg_rtx (V8SImode);
3110   r2 = gen_reg_rtx (V8SImode);
3111
3112   emit_insn (gen_avx_cvtpd2dq256_2 (r1, operands[1]));
3113   emit_insn (gen_avx_cvtpd2dq256_2 (r2, operands[2]));
3114   emit_insn (gen_avx_vperm2f128v8si3 (operands[0], r1, r2, GEN_INT (0x20)));
3115   DONE;
3116 })
3117
3118 (define_expand "vec_pack_sfix_v2df"
3119   [(match_operand:V4SI 0 "register_operand" "")
3120    (match_operand:V2DF 1 "nonimmediate_operand" "")
3121    (match_operand:V2DF 2 "nonimmediate_operand" "")]
3122   "TARGET_SSE2"
3123 {
3124   rtx r1, r2;
3125
3126   r1 = gen_reg_rtx (V4SImode);
3127   r2 = gen_reg_rtx (V4SImode);
3128
3129   emit_insn (gen_sse2_cvtpd2dq (r1, operands[1]));
3130   emit_insn (gen_sse2_cvtpd2dq (r2, operands[2]));
3131   emit_insn (gen_vec_interleave_lowv2di (gen_lowpart (V2DImode, operands[0]),
3132                                          gen_lowpart (V2DImode, r1),
3133                                          gen_lowpart (V2DImode, r2)));
3134   DONE;
3135 })
3136
3137 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3138 ;;
3139 ;; Parallel single-precision floating point element swizzling
3140 ;;
3141 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3142
3143 (define_expand "sse_movhlps_exp"
3144   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
3145         (vec_select:V4SF
3146           (vec_concat:V8SF
3147             (match_operand:V4SF 1 "nonimmediate_operand" "")
3148             (match_operand:V4SF 2 "nonimmediate_operand" ""))
3149           (parallel [(const_int 6)
3150                      (const_int 7)
3151                      (const_int 2)
3152                      (const_int 3)])))]
3153   "TARGET_SSE"
3154 {
3155   rtx dst = ix86_fixup_binary_operands (UNKNOWN, V4SFmode, operands);
3156
3157   emit_insn (gen_sse_movhlps (dst, operands[1], operands[2]));
3158
3159   /* Fix up the destination if needed.  */
3160   if (dst != operands[0])
3161     emit_move_insn (operands[0], dst);
3162
3163   DONE;
3164 })
3165
3166 (define_insn "sse_movhlps"
3167   [(set (match_operand:V4SF 0 "nonimmediate_operand"     "=x,x,x,x,m")
3168         (vec_select:V4SF
3169           (vec_concat:V8SF
3170             (match_operand:V4SF 1 "nonimmediate_operand" " 0,x,0,x,0")
3171             (match_operand:V4SF 2 "nonimmediate_operand" " x,x,o,o,x"))
3172           (parallel [(const_int 6)
3173                      (const_int 7)
3174                      (const_int 2)
3175                      (const_int 3)])))]
3176   "TARGET_SSE && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
3177   "@
3178    movhlps\t{%2, %0|%0, %2}
3179    vmovhlps\t{%2, %1, %0|%0, %1, %2}
3180    movlps\t{%H2, %0|%0, %H2}
3181    vmovlps\t{%H2, %1, %0|%0, %1, %H2}
3182    %vmovhps\t{%2, %0|%0, %2}"
3183   [(set_attr "isa" "noavx,avx,noavx,avx,*")
3184    (set_attr "type" "ssemov")
3185    (set_attr "prefix" "orig,vex,orig,vex,maybe_vex")
3186    (set_attr "mode" "V4SF,V4SF,V2SF,V2SF,V2SF")])
3187
3188 (define_expand "sse_movlhps_exp"
3189   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
3190         (vec_select:V4SF
3191           (vec_concat:V8SF
3192             (match_operand:V4SF 1 "nonimmediate_operand" "")
3193             (match_operand:V4SF 2 "nonimmediate_operand" ""))
3194           (parallel [(const_int 0)
3195                      (const_int 1)
3196                      (const_int 4)
3197                      (const_int 5)])))]
3198   "TARGET_SSE"
3199 {
3200   rtx dst = ix86_fixup_binary_operands (UNKNOWN, V4SFmode, operands);
3201
3202   emit_insn (gen_sse_movlhps (dst, operands[1], operands[2]));
3203
3204   /* Fix up the destination if needed.  */
3205   if (dst != operands[0])
3206     emit_move_insn (operands[0], dst);
3207
3208   DONE;
3209 })
3210
3211 (define_insn "sse_movlhps"
3212   [(set (match_operand:V4SF 0 "nonimmediate_operand"     "=x,x,x,x,o")
3213         (vec_select:V4SF
3214           (vec_concat:V8SF
3215             (match_operand:V4SF 1 "nonimmediate_operand" " 0,x,0,x,0")
3216             (match_operand:V4SF 2 "nonimmediate_operand" " x,x,m,x,x"))
3217           (parallel [(const_int 0)
3218                      (const_int 1)
3219                      (const_int 4)
3220                      (const_int 5)])))]
3221   "TARGET_SSE && ix86_binary_operator_ok (UNKNOWN, V4SFmode, operands)"
3222   "@
3223    movlhps\t{%2, %0|%0, %2}
3224    vmovlhps\t{%2, %1, %0|%0, %1, %2}
3225    movhps\t{%2, %0|%0, %2}
3226    vmovhps\t{%2, %1, %0|%0, %1, %2}
3227    %vmovlps\t{%2, %H0|%H0, %2}"
3228   [(set_attr "isa" "noavx,avx,noavx,avx,*")
3229    (set_attr "type" "ssemov")
3230    (set_attr "prefix" "orig,vex,orig,vex,maybe_vex")
3231    (set_attr "mode" "V4SF,V4SF,V2SF,V2SF,V2SF")])
3232
3233 ;; Recall that the 256-bit unpck insns only shuffle within their lanes.
3234 (define_insn "avx_unpckhps256"
3235   [(set (match_operand:V8SF 0 "register_operand" "=x")
3236         (vec_select:V8SF
3237           (vec_concat:V16SF
3238             (match_operand:V8SF 1 "register_operand" "x")
3239             (match_operand:V8SF 2 "nonimmediate_operand" "xm"))
3240           (parallel [(const_int 2) (const_int 10)
3241                      (const_int 3) (const_int 11)
3242                      (const_int 6) (const_int 14)
3243                      (const_int 7) (const_int 15)])))]
3244   "TARGET_AVX"
3245   "vunpckhps\t{%2, %1, %0|%0, %1, %2}"
3246   [(set_attr "type" "sselog")
3247    (set_attr "prefix" "vex")
3248    (set_attr "mode" "V8SF")])
3249
3250 (define_expand "vec_interleave_highv8sf"
3251   [(set (match_dup 3)
3252         (vec_select:V8SF
3253           (vec_concat:V16SF
3254             (match_operand:V8SF 1 "register_operand" "x")
3255             (match_operand:V8SF 2 "nonimmediate_operand" "xm"))
3256           (parallel [(const_int 0) (const_int 8)
3257                      (const_int 1) (const_int 9)
3258                      (const_int 4) (const_int 12)
3259                      (const_int 5) (const_int 13)])))
3260    (set (match_dup 4)
3261         (vec_select:V8SF
3262           (vec_concat:V16SF
3263             (match_dup 1)
3264             (match_dup 2))
3265           (parallel [(const_int 2) (const_int 10)
3266                      (const_int 3) (const_int 11)
3267                      (const_int 6) (const_int 14)
3268                      (const_int 7) (const_int 15)])))
3269    (set (match_operand:V8SF 0 "register_operand" "")
3270         (vec_select:V8SF
3271           (vec_concat:V16SF
3272             (match_dup 3)
3273             (match_dup 4))
3274           (parallel [(const_int 4) (const_int 5)
3275                      (const_int 6) (const_int 7)
3276                      (const_int 12) (const_int 13)
3277                      (const_int 14) (const_int 15)])))]
3278  "TARGET_AVX"
3279 {
3280   operands[3] = gen_reg_rtx (V8SFmode);
3281   operands[4] = gen_reg_rtx (V8SFmode);
3282 })
3283
3284 (define_insn "vec_interleave_highv4sf"
3285   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
3286         (vec_select:V4SF
3287           (vec_concat:V8SF
3288             (match_operand:V4SF 1 "register_operand" "0,x")
3289             (match_operand:V4SF 2 "nonimmediate_operand" "xm,xm"))
3290           (parallel [(const_int 2) (const_int 6)
3291                      (const_int 3) (const_int 7)])))]
3292   "TARGET_SSE"
3293   "@
3294    unpckhps\t{%2, %0|%0, %2}
3295    vunpckhps\t{%2, %1, %0|%0, %1, %2}"
3296   [(set_attr "isa" "noavx,avx")
3297    (set_attr "type" "sselog")
3298    (set_attr "prefix" "orig,vex")
3299    (set_attr "mode" "V4SF")])
3300
3301 ;; Recall that the 256-bit unpck insns only shuffle within their lanes.
3302 (define_insn "avx_unpcklps256"
3303   [(set (match_operand:V8SF 0 "register_operand" "=x")
3304         (vec_select:V8SF
3305           (vec_concat:V16SF
3306             (match_operand:V8SF 1 "register_operand" "x")
3307             (match_operand:V8SF 2 "nonimmediate_operand" "xm"))
3308           (parallel [(const_int 0) (const_int 8)
3309                      (const_int 1) (const_int 9)
3310                      (const_int 4) (const_int 12)
3311                      (const_int 5) (const_int 13)])))]
3312   "TARGET_AVX"
3313   "vunpcklps\t{%2, %1, %0|%0, %1, %2}"
3314   [(set_attr "type" "sselog")
3315    (set_attr "prefix" "vex")
3316    (set_attr "mode" "V8SF")])
3317
3318 (define_expand "vec_interleave_lowv8sf"
3319   [(set (match_dup 3)
3320         (vec_select:V8SF
3321           (vec_concat:V16SF
3322             (match_operand:V8SF 1 "register_operand" "x")
3323             (match_operand:V8SF 2 "nonimmediate_operand" "xm"))
3324           (parallel [(const_int 0) (const_int 8)
3325                      (const_int 1) (const_int 9)
3326                      (const_int 4) (const_int 12)
3327                      (const_int 5) (const_int 13)])))
3328    (set (match_dup 4)
3329         (vec_select:V8SF
3330           (vec_concat:V16SF
3331             (match_dup 1)
3332             (match_dup 2))
3333           (parallel [(const_int 2) (const_int 10)
3334                      (const_int 3) (const_int 11)
3335                      (const_int 6) (const_int 14)
3336                      (const_int 7) (const_int 15)])))
3337    (set (match_operand:V8SF 0 "register_operand" "")
3338         (vec_select:V8SF
3339           (vec_concat:V16SF
3340             (match_dup 3)
3341             (match_dup 4))
3342           (parallel [(const_int 0) (const_int 1)
3343                      (const_int 2) (const_int 3)
3344                      (const_int 8) (const_int 9)
3345                      (const_int 10) (const_int 11)])))]
3346  "TARGET_AVX"
3347 {
3348   operands[3] = gen_reg_rtx (V8SFmode);
3349   operands[4] = gen_reg_rtx (V8SFmode);
3350 })
3351
3352 (define_insn "vec_interleave_lowv4sf"
3353   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
3354         (vec_select:V4SF
3355           (vec_concat:V8SF
3356             (match_operand:V4SF 1 "register_operand" "0,x")
3357             (match_operand:V4SF 2 "nonimmediate_operand" "xm,xm"))
3358           (parallel [(const_int 0) (const_int 4)
3359                      (const_int 1) (const_int 5)])))]
3360   "TARGET_SSE"
3361   "@
3362    unpcklps\t{%2, %0|%0, %2}
3363    vunpcklps\t{%2, %1, %0|%0, %1, %2}"
3364   [(set_attr "isa" "noavx,avx")
3365    (set_attr "type" "sselog")
3366    (set_attr "prefix" "orig,vex")
3367    (set_attr "mode" "V4SF")])
3368
3369 ;; These are modeled with the same vec_concat as the others so that we
3370 ;; capture users of shufps that can use the new instructions
3371 (define_insn "avx_movshdup256"
3372   [(set (match_operand:V8SF 0 "register_operand" "=x")
3373         (vec_select:V8SF
3374           (vec_concat:V16SF
3375             (match_operand:V8SF 1 "nonimmediate_operand" "xm")
3376             (match_dup 1))
3377           (parallel [(const_int 1) (const_int 1)
3378                      (const_int 3) (const_int 3)
3379                      (const_int 5) (const_int 5)
3380                      (const_int 7) (const_int 7)])))]
3381   "TARGET_AVX"
3382   "vmovshdup\t{%1, %0|%0, %1}"
3383   [(set_attr "type" "sse")
3384    (set_attr "prefix" "vex")
3385    (set_attr "mode" "V8SF")])
3386
3387 (define_insn "sse3_movshdup"
3388   [(set (match_operand:V4SF 0 "register_operand" "=x")
3389         (vec_select:V4SF
3390           (vec_concat:V8SF
3391             (match_operand:V4SF 1 "nonimmediate_operand" "xm")
3392             (match_dup 1))
3393           (parallel [(const_int 1)
3394                      (const_int 1)
3395                      (const_int 7)
3396                      (const_int 7)])))]
3397   "TARGET_SSE3"
3398   "%vmovshdup\t{%1, %0|%0, %1}"
3399   [(set_attr "type" "sse")
3400    (set_attr "prefix_rep" "1")
3401    (set_attr "prefix" "maybe_vex")
3402    (set_attr "mode" "V4SF")])
3403
3404 (define_insn "avx_movsldup256"
3405   [(set (match_operand:V8SF 0 "register_operand" "=x")
3406         (vec_select:V8SF
3407           (vec_concat:V16SF
3408             (match_operand:V8SF 1 "nonimmediate_operand" "xm")
3409             (match_dup 1))
3410           (parallel [(const_int 0) (const_int 0)
3411                      (const_int 2) (const_int 2)
3412                      (const_int 4) (const_int 4)
3413                      (const_int 6) (const_int 6)])))]
3414   "TARGET_AVX"
3415   "vmovsldup\t{%1, %0|%0, %1}"
3416   [(set_attr "type" "sse")
3417    (set_attr "prefix" "vex")
3418    (set_attr "mode" "V8SF")])
3419
3420 (define_insn "sse3_movsldup"
3421   [(set (match_operand:V4SF 0 "register_operand" "=x")
3422         (vec_select:V4SF
3423           (vec_concat:V8SF
3424             (match_operand:V4SF 1 "nonimmediate_operand" "xm")
3425             (match_dup 1))
3426           (parallel [(const_int 0)
3427                      (const_int 0)
3428                      (const_int 6)
3429                      (const_int 6)])))]
3430   "TARGET_SSE3"
3431   "%vmovsldup\t{%1, %0|%0, %1}"
3432   [(set_attr "type" "sse")
3433    (set_attr "prefix_rep" "1")
3434    (set_attr "prefix" "maybe_vex")
3435    (set_attr "mode" "V4SF")])
3436
3437 (define_expand "avx_shufps256"
3438   [(match_operand:V8SF 0 "register_operand" "")
3439    (match_operand:V8SF 1 "register_operand" "")
3440    (match_operand:V8SF 2 "nonimmediate_operand" "")
3441    (match_operand:SI 3 "const_int_operand" "")]
3442   "TARGET_AVX"
3443 {
3444   int mask = INTVAL (operands[3]);
3445   emit_insn (gen_avx_shufps256_1 (operands[0], operands[1], operands[2],
3446                                   GEN_INT ((mask >> 0) & 3),
3447                                   GEN_INT ((mask >> 2) & 3),
3448                                   GEN_INT (((mask >> 4) & 3) + 8),
3449                                   GEN_INT (((mask >> 6) & 3) + 8),
3450                                   GEN_INT (((mask >> 0) & 3) + 4),
3451                                   GEN_INT (((mask >> 2) & 3) + 4),
3452                                   GEN_INT (((mask >> 4) & 3) + 12),
3453                                   GEN_INT (((mask >> 6) & 3) + 12)));
3454   DONE;
3455 })
3456
3457 ;; One bit in mask selects 2 elements.
3458 (define_insn "avx_shufps256_1"
3459   [(set (match_operand:V8SF 0 "register_operand" "=x")
3460         (vec_select:V8SF
3461           (vec_concat:V16SF
3462             (match_operand:V8SF 1 "register_operand" "x")
3463             (match_operand:V8SF 2 "nonimmediate_operand" "xm"))
3464           (parallel [(match_operand 3  "const_0_to_3_operand"   "")
3465                      (match_operand 4  "const_0_to_3_operand"   "")
3466                      (match_operand 5  "const_8_to_11_operand"  "")
3467                      (match_operand 6  "const_8_to_11_operand"  "")
3468                      (match_operand 7  "const_4_to_7_operand"   "")
3469                      (match_operand 8  "const_4_to_7_operand"   "")
3470                      (match_operand 9  "const_12_to_15_operand" "")
3471                      (match_operand 10 "const_12_to_15_operand" "")])))]
3472   "TARGET_AVX
3473    && (INTVAL (operands[3]) == (INTVAL (operands[7]) - 4)
3474        && INTVAL (operands[4]) == (INTVAL (operands[8]) - 4)
3475        && INTVAL (operands[5]) == (INTVAL (operands[9]) - 4)
3476        && INTVAL (operands[6]) == (INTVAL (operands[10]) - 4))"
3477 {
3478   int mask;
3479   mask = INTVAL (operands[3]);
3480   mask |= INTVAL (operands[4]) << 2;
3481   mask |= (INTVAL (operands[5]) - 8) << 4;
3482   mask |= (INTVAL (operands[6]) - 8) << 6;
3483   operands[3] = GEN_INT (mask);
3484
3485   return "vshufps\t{%3, %2, %1, %0|%0, %1, %2, %3}";
3486 }
3487   [(set_attr "type" "sselog")
3488    (set_attr "length_immediate" "1")
3489    (set_attr "prefix" "vex")
3490    (set_attr "mode" "V8SF")])
3491
3492 (define_expand "sse_shufps"
3493   [(match_operand:V4SF 0 "register_operand" "")
3494    (match_operand:V4SF 1 "register_operand" "")
3495    (match_operand:V4SF 2 "nonimmediate_operand" "")
3496    (match_operand:SI 3 "const_int_operand" "")]
3497   "TARGET_SSE"
3498 {
3499   int mask = INTVAL (operands[3]);
3500   emit_insn (gen_sse_shufps_v4sf (operands[0], operands[1], operands[2],
3501                                GEN_INT ((mask >> 0) & 3),
3502                                GEN_INT ((mask >> 2) & 3),
3503                                GEN_INT (((mask >> 4) & 3) + 4),
3504                                GEN_INT (((mask >> 6) & 3) + 4)));
3505   DONE;
3506 })
3507
3508 (define_insn "sse_shufps_<mode>"
3509   [(set (match_operand:VI4F_128 0 "register_operand" "=x,x")
3510         (vec_select:VI4F_128
3511           (vec_concat:<ssedoublevecmode>
3512             (match_operand:VI4F_128 1 "register_operand" "0,x")
3513             (match_operand:VI4F_128 2 "nonimmediate_operand" "xm,xm"))
3514           (parallel [(match_operand 3 "const_0_to_3_operand" "")
3515                      (match_operand 4 "const_0_to_3_operand" "")
3516                      (match_operand 5 "const_4_to_7_operand" "")
3517                      (match_operand 6 "const_4_to_7_operand" "")])))]
3518   "TARGET_SSE"
3519 {
3520   int mask = 0;
3521   mask |= INTVAL (operands[3]) << 0;
3522   mask |= INTVAL (operands[4]) << 2;
3523   mask |= (INTVAL (operands[5]) - 4) << 4;
3524   mask |= (INTVAL (operands[6]) - 4) << 6;
3525   operands[3] = GEN_INT (mask);
3526
3527   switch (which_alternative)
3528     {
3529     case 0:
3530       return "shufps\t{%3, %2, %0|%0, %2, %3}";
3531     case 1:
3532       return "vshufps\t{%3, %2, %1, %0|%0, %1, %2, %3}";
3533     default:
3534       gcc_unreachable ();
3535     }
3536 }
3537   [(set_attr "isa" "noavx,avx")
3538    (set_attr "type" "sselog")
3539    (set_attr "length_immediate" "1")
3540    (set_attr "prefix" "orig,vex")
3541    (set_attr "mode" "V4SF")])
3542
3543 (define_insn "sse_storehps"
3544   [(set (match_operand:V2SF 0 "nonimmediate_operand" "=m,x,x")
3545         (vec_select:V2SF
3546           (match_operand:V4SF 1 "nonimmediate_operand" "x,x,o")
3547           (parallel [(const_int 2) (const_int 3)])))]
3548   "TARGET_SSE"
3549   "@
3550    %vmovhps\t{%1, %0|%0, %1}
3551    %vmovhlps\t{%1, %d0|%d0, %1}
3552    %vmovlps\t{%H1, %d0|%d0, %H1}"
3553   [(set_attr "type" "ssemov")
3554    (set_attr "prefix" "maybe_vex")
3555    (set_attr "mode" "V2SF,V4SF,V2SF")])
3556
3557 (define_expand "sse_loadhps_exp"
3558   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
3559         (vec_concat:V4SF
3560           (vec_select:V2SF
3561             (match_operand:V4SF 1 "nonimmediate_operand" "")
3562             (parallel [(const_int 0) (const_int 1)]))
3563           (match_operand:V2SF 2 "nonimmediate_operand" "")))]
3564   "TARGET_SSE"
3565 {
3566   rtx dst = ix86_fixup_binary_operands (UNKNOWN, V4SFmode, operands);
3567
3568   emit_insn (gen_sse_loadhps (dst, operands[1], operands[2]));
3569
3570   /* Fix up the destination if needed.  */
3571   if (dst != operands[0])
3572     emit_move_insn (operands[0], dst);
3573
3574   DONE;
3575 })
3576
3577 (define_insn "sse_loadhps"
3578   [(set (match_operand:V4SF 0 "nonimmediate_operand"     "=x,x,x,x,o")
3579         (vec_concat:V4SF
3580           (vec_select:V2SF
3581             (match_operand:V4SF 1 "nonimmediate_operand" " 0,x,0,x,0")
3582             (parallel [(const_int 0) (const_int 1)]))
3583           (match_operand:V2SF 2 "nonimmediate_operand"   " m,m,x,x,x")))]
3584   "TARGET_SSE"
3585   "@
3586    movhps\t{%2, %0|%0, %2}
3587    vmovhps\t{%2, %1, %0|%0, %1, %2}
3588    movlhps\t{%2, %0|%0, %2}
3589    vmovlhps\t{%2, %1, %0|%0, %1, %2}
3590    %vmovlps\t{%2, %H0|%H0, %2}"
3591   [(set_attr "isa" "noavx,avx,noavx,avx,*")
3592    (set_attr "type" "ssemov")
3593    (set_attr "prefix" "orig,vex,orig,vex,maybe_vex")
3594    (set_attr "mode" "V2SF,V2SF,V4SF,V4SF,V2SF")])
3595
3596 (define_insn "sse_storelps"
3597   [(set (match_operand:V2SF 0 "nonimmediate_operand"   "=m,x,x")
3598         (vec_select:V2SF
3599           (match_operand:V4SF 1 "nonimmediate_operand" " x,x,m")
3600           (parallel [(const_int 0) (const_int 1)])))]
3601   "TARGET_SSE"
3602   "@
3603    %vmovlps\t{%1, %0|%0, %1}
3604    %vmovaps\t{%1, %0|%0, %1}
3605    %vmovlps\t{%1, %d0|%d0, %1}"
3606   [(set_attr "type" "ssemov")
3607    (set_attr "prefix" "maybe_vex")
3608    (set_attr "mode" "V2SF,V4SF,V2SF")])
3609
3610 (define_expand "sse_loadlps_exp"
3611   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
3612         (vec_concat:V4SF
3613           (match_operand:V2SF 2 "nonimmediate_operand" "")
3614           (vec_select:V2SF
3615             (match_operand:V4SF 1 "nonimmediate_operand" "")
3616             (parallel [(const_int 2) (const_int 3)]))))]
3617   "TARGET_SSE"
3618 {
3619   rtx dst = ix86_fixup_binary_operands (UNKNOWN, V4SFmode, operands);
3620
3621   emit_insn (gen_sse_loadlps (dst, operands[1], operands[2]));
3622
3623   /* Fix up the destination if needed.  */
3624   if (dst != operands[0])
3625     emit_move_insn (operands[0], dst);
3626
3627   DONE;
3628 })
3629
3630 (define_insn "sse_loadlps"
3631   [(set (match_operand:V4SF 0 "nonimmediate_operand"     "=x,x,x,x,m")
3632         (vec_concat:V4SF
3633           (match_operand:V2SF 2 "nonimmediate_operand"   " 0,x,m,x,x")
3634           (vec_select:V2SF
3635             (match_operand:V4SF 1 "nonimmediate_operand" " x,x,0,x,0")
3636             (parallel [(const_int 2) (const_int 3)]))))]
3637   "TARGET_SSE"
3638   "@
3639    shufps\t{$0xe4, %1, %0|%0, %1, 0xe4}
3640    vshufps\t{$0xe4, %1, %2, %0|%0, %2, %1, 0xe4}
3641    movlps\t{%2, %0|%0, %2}
3642    vmovlps\t{%2, %1, %0|%0, %1, %2}
3643    %vmovlps\t{%2, %0|%0, %2}"
3644   [(set_attr "isa" "noavx,avx,noavx,avx,*")
3645    (set_attr "type" "sselog,sselog,ssemov,ssemov,ssemov")
3646    (set_attr "length_immediate" "1,1,*,*,*")
3647    (set_attr "prefix" "orig,vex,orig,vex,maybe_vex")
3648    (set_attr "mode" "V4SF,V4SF,V2SF,V2SF,V2SF")])
3649
3650 (define_insn "sse_movss"
3651   [(set (match_operand:V4SF 0 "register_operand"   "=x,x")
3652         (vec_merge:V4SF
3653           (match_operand:V4SF 2 "register_operand" " x,x")
3654           (match_operand:V4SF 1 "register_operand" " 0,x")
3655           (const_int 1)))]
3656   "TARGET_SSE"
3657   "@
3658    movss\t{%2, %0|%0, %2}
3659    vmovss\t{%2, %1, %0|%0, %1, %2}"
3660   [(set_attr "isa" "noavx,avx")
3661    (set_attr "type" "ssemov")
3662    (set_attr "prefix" "orig,vex")
3663    (set_attr "mode" "SF")])
3664
3665 (define_expand "vec_dupv4sf"
3666   [(set (match_operand:V4SF 0 "register_operand" "")
3667         (vec_duplicate:V4SF
3668           (match_operand:SF 1 "nonimmediate_operand" "")))]
3669   "TARGET_SSE"
3670 {
3671   if (!TARGET_AVX)
3672     operands[1] = force_reg (SFmode, operands[1]);
3673 })
3674
3675 (define_insn "avx2_vec_dupv4sf"
3676   [(set (match_operand:V4SF 0 "register_operand" "=x")
3677         (vec_duplicate:V4SF
3678           (vec_select:SF
3679             (match_operand:V4SF 1 "register_operand" "x")
3680             (parallel [(const_int 0)]))))]
3681   "TARGET_AVX2"
3682   "vbroadcastss\t{%1, %0|%0, %1}"
3683   [(set_attr "type" "sselog1")
3684     (set_attr "prefix" "vex")
3685     (set_attr "mode" "V4SF")])
3686
3687 (define_insn "*vec_dupv4sf_avx"
3688   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
3689         (vec_duplicate:V4SF
3690           (match_operand:SF 1 "nonimmediate_operand" "x,m")))]
3691   "TARGET_AVX"
3692   "@
3693    vshufps\t{$0, %1, %1, %0|%0, %1, %1, 0}
3694    vbroadcastss\t{%1, %0|%0, %1}"
3695   [(set_attr "type" "sselog1,ssemov")
3696    (set_attr "length_immediate" "1,0")
3697    (set_attr "prefix_extra" "0,1")
3698    (set_attr "prefix" "vex")
3699    (set_attr "mode" "V4SF")])
3700
3701 (define_insn "avx2_vec_dupv8sf"
3702   [(set (match_operand:V8SF 0 "register_operand" "=x")
3703         (vec_duplicate:V8SF
3704           (vec_select:SF
3705             (match_operand:V4SF 1 "register_operand" "x")
3706             (parallel [(const_int 0)]))))]
3707   "TARGET_AVX2"
3708   "vbroadcastss\t{%1, %0|%0, %1}"
3709   [(set_attr "type" "sselog1")
3710    (set_attr "prefix" "vex")
3711    (set_attr "mode" "V8SF")])
3712
3713 (define_insn "*vec_dupv4sf"
3714   [(set (match_operand:V4SF 0 "register_operand" "=x")
3715         (vec_duplicate:V4SF
3716           (match_operand:SF 1 "register_operand" "0")))]
3717   "TARGET_SSE"
3718   "shufps\t{$0, %0, %0|%0, %0, 0}"
3719   [(set_attr "type" "sselog1")
3720    (set_attr "length_immediate" "1")
3721    (set_attr "mode" "V4SF")])
3722
3723 ;; Although insertps takes register source, we prefer
3724 ;; unpcklps with register source since it is shorter.
3725 (define_insn "*vec_concatv2sf_sse4_1"
3726   [(set (match_operand:V2SF 0 "register_operand"     "=x,x,x,x,x,*y ,*y")
3727         (vec_concat:V2SF
3728           (match_operand:SF 1 "nonimmediate_operand" " 0,x,0,x,m, 0 , m")
3729           (match_operand:SF 2 "vector_move_operand"  " x,x,m,m,C,*ym, C")))]
3730   "TARGET_SSE4_1"
3731   "@
3732    unpcklps\t{%2, %0|%0, %2}
3733    vunpcklps\t{%2, %1, %0|%0, %1, %2}
3734    insertps\t{$0x10, %2, %0|%0, %2, 0x10}
3735    vinsertps\t{$0x10, %2, %1, %0|%0, %1, %2, 0x10}
3736    %vmovss\t{%1, %0|%0, %1}
3737    punpckldq\t{%2, %0|%0, %2}
3738    movd\t{%1, %0|%0, %1}"
3739   [(set_attr "isa" "noavx,avx,noavx,avx,*,*,*")
3740    (set_attr "type" "sselog,sselog,sselog,sselog,ssemov,mmxcvt,mmxmov")
3741    (set_attr "prefix_data16" "*,*,1,*,*,*,*")
3742    (set_attr "prefix_extra" "*,*,1,1,*,*,*")
3743    (set_attr "length_immediate" "*,*,1,1,*,*,*")
3744    (set_attr "prefix" "orig,vex,orig,vex,maybe_vex,orig,orig")
3745    (set_attr "mode" "V4SF,V4SF,V4SF,V4SF,SF,DI,DI")])
3746
3747 ;; ??? In theory we can match memory for the MMX alternative, but allowing
3748 ;; nonimmediate_operand for operand 2 and *not* allowing memory for the SSE
3749 ;; alternatives pretty much forces the MMX alternative to be chosen.
3750 (define_insn "*vec_concatv2sf_sse"
3751   [(set (match_operand:V2SF 0 "register_operand"     "=x,x,*y,*y")
3752         (vec_concat:V2SF
3753           (match_operand:SF 1 "nonimmediate_operand" " 0,m, 0, m")
3754           (match_operand:SF 2 "reg_or_0_operand"     " x,C,*y, C")))]
3755   "TARGET_SSE"
3756   "@
3757    unpcklps\t{%2, %0|%0, %2}
3758    movss\t{%1, %0|%0, %1}
3759    punpckldq\t{%2, %0|%0, %2}
3760    movd\t{%1, %0|%0, %1}"
3761   [(set_attr "type" "sselog,ssemov,mmxcvt,mmxmov")
3762    (set_attr "mode" "V4SF,SF,DI,DI")])
3763
3764 (define_insn "*vec_concatv4sf"
3765   [(set (match_operand:V4SF 0 "register_operand"       "=x,x,x,x")
3766         (vec_concat:V4SF
3767           (match_operand:V2SF 1 "register_operand"     " 0,x,0,x")
3768           (match_operand:V2SF 2 "nonimmediate_operand" " x,x,m,m")))]
3769   "TARGET_SSE"
3770   "@
3771    movlhps\t{%2, %0|%0, %2}
3772    vmovlhps\t{%2, %1, %0|%0, %1, %2}
3773    movhps\t{%2, %0|%0, %2}
3774    vmovhps\t{%2, %1, %0|%0, %1, %2}"
3775   [(set_attr "isa" "noavx,avx,noavx,avx")
3776    (set_attr "type" "ssemov")
3777    (set_attr "prefix" "orig,vex,orig,vex")
3778    (set_attr "mode" "V4SF,V4SF,V2SF,V2SF")])
3779
3780 (define_expand "vec_init<mode>"
3781   [(match_operand:V_128 0 "register_operand" "")
3782    (match_operand 1 "" "")]
3783   "TARGET_SSE"
3784 {
3785   ix86_expand_vector_init (false, operands[0], operands[1]);
3786   DONE;
3787 })
3788
3789 ;; Avoid combining registers from different units in a single alternative,
3790 ;; see comment above inline_secondary_memory_needed function in i386.c
3791 (define_insn "vec_set<mode>_0"
3792   [(set (match_operand:VI4F_128 0 "nonimmediate_operand"
3793           "=x,x,x ,x,x,x,x  ,x  ,m,m ,m")
3794         (vec_merge:VI4F_128
3795           (vec_duplicate:VI4F_128
3796             (match_operand:<ssescalarmode> 2 "general_operand"
3797           " x,m,*r,m,x,x,*rm,*rm,x,fF,*r"))
3798           (match_operand:VI4F_128 1 "vector_move_operand"
3799           " C,C,C ,C,0,x,0  ,x  ,0,0 ,0")
3800           (const_int 1)))]
3801   "TARGET_SSE"
3802   "@
3803    %vinsertps\t{$0xe, %d2, %0|%0, %d2, 0xe}
3804    %vmov<ssescalarmodesuffix>\t{%2, %0|%0, %2}
3805    %vmovd\t{%2, %0|%0, %2}
3806    movss\t{%2, %0|%0, %2}
3807    movss\t{%2, %0|%0, %2}
3808    vmovss\t{%2, %1, %0|%0, %1, %2}
3809    pinsrd\t{$0, %2, %0|%0, %2, 0}
3810    vpinsrd\t{$0, %2, %1, %0|%0, %1, %2, 0}
3811    #
3812    #
3813    #"
3814   [(set_attr "isa" "sse4,sse2,sse2,noavx,noavx,avx,sse4_noavx,avx,*,*,*")
3815    (set (attr "type")
3816      (cond [(eq_attr "alternative" "0,6,7")
3817               (const_string "sselog")
3818             (eq_attr "alternative" "9")
3819               (const_string "fmov")
3820             (eq_attr "alternative" "10")
3821               (const_string "imov")
3822            ]
3823            (const_string "ssemov")))
3824    (set_attr "prefix_extra" "*,*,*,*,*,*,1,1,*,*,*")
3825    (set_attr "length_immediate" "*,*,*,*,*,*,1,1,*,*,*")
3826    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,orig,orig,vex,orig,vex,*,*,*")
3827    (set_attr "mode" "SF,<ssescalarmode>,SI,SF,SF,SF,TI,TI,*,*,*")])
3828
3829 ;; A subset is vec_setv4sf.
3830 (define_insn "*vec_setv4sf_sse4_1"
3831   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
3832         (vec_merge:V4SF
3833           (vec_duplicate:V4SF
3834             (match_operand:SF 2 "nonimmediate_operand" "xm,xm"))
3835           (match_operand:V4SF 1 "register_operand" "0,x")
3836           (match_operand:SI 3 "const_int_operand" "")))]
3837   "TARGET_SSE4_1
3838    && ((unsigned) exact_log2 (INTVAL (operands[3]))
3839        < GET_MODE_NUNITS (V4SFmode))"
3840 {
3841   operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])) << 4);
3842   switch (which_alternative)
3843     {
3844     case 0:
3845       return "insertps\t{%3, %2, %0|%0, %2, %3}";
3846     case 1:
3847       return "vinsertps\t{%3, %2, %1, %0|%0, %1, %2, %3}";
3848     default:
3849       gcc_unreachable ();
3850     }
3851 }
3852   [(set_attr "isa" "noavx,avx")
3853    (set_attr "type" "sselog")
3854    (set_attr "prefix_data16" "1,*")
3855    (set_attr "prefix_extra" "1")
3856    (set_attr "length_immediate" "1")
3857    (set_attr "prefix" "orig,vex")
3858    (set_attr "mode" "V4SF")])
3859
3860 (define_insn "sse4_1_insertps"
3861   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
3862         (unspec:V4SF [(match_operand:V4SF 2 "nonimmediate_operand" "xm,xm")
3863                       (match_operand:V4SF 1 "register_operand" "0,x")
3864                       (match_operand:SI 3 "const_0_to_255_operand" "n,n")]
3865                      UNSPEC_INSERTPS))]
3866   "TARGET_SSE4_1"
3867 {
3868   if (MEM_P (operands[2]))
3869     {
3870       unsigned count_s = INTVAL (operands[3]) >> 6;
3871       if (count_s)
3872         operands[3] = GEN_INT (INTVAL (operands[3]) & 0x3f);
3873       operands[2] = adjust_address_nv (operands[2], SFmode, count_s * 4);
3874     }
3875   switch (which_alternative)
3876     {
3877     case 0:
3878       return "insertps\t{%3, %2, %0|%0, %2, %3}";
3879     case 1:
3880       return "vinsertps\t{%3, %2, %1, %0|%0, %1, %2, %3}";
3881     default:
3882       gcc_unreachable ();
3883     }
3884 }
3885   [(set_attr "isa" "noavx,avx")
3886    (set_attr "type" "sselog")
3887    (set_attr "prefix_data16" "1,*")
3888    (set_attr "prefix_extra" "1")
3889    (set_attr "length_immediate" "1")
3890    (set_attr "prefix" "orig,vex")
3891    (set_attr "mode" "V4SF")])
3892
3893 (define_split
3894   [(set (match_operand:VI4F_128 0 "memory_operand" "")
3895         (vec_merge:VI4F_128
3896           (vec_duplicate:VI4F_128
3897             (match_operand:<ssescalarmode> 1 "nonmemory_operand" ""))
3898           (match_dup 0)
3899           (const_int 1)))]
3900   "TARGET_SSE && reload_completed"
3901   [(const_int 0)]
3902 {
3903   emit_move_insn (adjust_address (operands[0], <ssescalarmode>mode, 0),
3904                   operands[1]);
3905   DONE;
3906 })
3907
3908 (define_expand "vec_set<mode>"
3909   [(match_operand:V 0 "register_operand" "")
3910    (match_operand:<ssescalarmode> 1 "register_operand" "")
3911    (match_operand 2 "const_int_operand" "")]
3912   "TARGET_SSE"
3913 {
3914   ix86_expand_vector_set (false, operands[0], operands[1],
3915                           INTVAL (operands[2]));
3916   DONE;
3917 })
3918
3919 (define_insn_and_split "*vec_extractv4sf_0"
3920   [(set (match_operand:SF 0 "nonimmediate_operand" "=x,m,f,r")
3921         (vec_select:SF
3922           (match_operand:V4SF 1 "nonimmediate_operand" "xm,x,m,m")
3923           (parallel [(const_int 0)])))]
3924   "TARGET_SSE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3925   "#"
3926   "&& reload_completed"
3927   [(const_int 0)]
3928 {
3929   rtx op1 = operands[1];
3930   if (REG_P (op1))
3931     op1 = gen_rtx_REG (SFmode, REGNO (op1));
3932   else
3933     op1 = gen_lowpart (SFmode, op1);
3934   emit_move_insn (operands[0], op1);
3935   DONE;
3936 })
3937
3938 (define_insn_and_split "*sse4_1_extractps"
3939   [(set (match_operand:SF 0 "nonimmediate_operand" "=rm,x,x")
3940         (vec_select:SF
3941           (match_operand:V4SF 1 "register_operand" "x,0,x")
3942           (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n,n,n")])))]
3943   "TARGET_SSE4_1"
3944   "@
3945    %vextractps\t{%2, %1, %0|%0, %1, %2}
3946    #
3947    #"
3948   "&& reload_completed && SSE_REG_P (operands[0])"
3949   [(const_int 0)]
3950 {
3951   rtx dest = gen_rtx_REG (V4SFmode, REGNO (operands[0]));
3952   switch (INTVAL (operands[2]))
3953     {
3954     case 1:
3955     case 3:
3956       emit_insn (gen_sse_shufps_v4sf (dest, operands[1], operands[1],
3957                                       operands[2], operands[2],
3958                                       GEN_INT (INTVAL (operands[2]) + 4),
3959                                       GEN_INT (INTVAL (operands[2]) + 4)));
3960       break;
3961     case 2:
3962       emit_insn (gen_vec_interleave_highv4sf (dest, operands[1], operands[1]));
3963       break;
3964     default:
3965       /* 0 should be handled by the *vec_extractv4sf_0 pattern above.  */
3966       gcc_unreachable ();
3967     }
3968   DONE;
3969 }
3970   [(set_attr "isa" "*,noavx,avx")
3971    (set_attr "type" "sselog,*,*")
3972    (set_attr "prefix_data16" "1,*,*")
3973    (set_attr "prefix_extra" "1,*,*")
3974    (set_attr "length_immediate" "1,*,*")
3975    (set_attr "prefix" "maybe_vex,*,*")
3976    (set_attr "mode" "V4SF,*,*")])
3977
3978 (define_insn_and_split "*vec_extract_v4sf_mem"
3979   [(set (match_operand:SF 0 "register_operand" "=x,*r,f")
3980        (vec_select:SF
3981          (match_operand:V4SF 1 "memory_operand" "o,o,o")
3982          (parallel [(match_operand 2 "const_0_to_3_operand" "n,n,n")])))]
3983   "TARGET_SSE"
3984   "#"
3985   "&& reload_completed"
3986   [(const_int 0)]
3987 {
3988   int i = INTVAL (operands[2]);
3989
3990   emit_move_insn (operands[0], adjust_address (operands[1], SFmode, i*4));
3991   DONE;
3992 })
3993
3994 (define_expand "avx_vextractf128<mode>"
3995   [(match_operand:<ssehalfvecmode> 0 "nonimmediate_operand" "")
3996    (match_operand:V_256 1 "register_operand" "")
3997    (match_operand:SI 2 "const_0_to_1_operand" "")]
3998   "TARGET_AVX"
3999 {
4000   rtx (*insn)(rtx, rtx);
4001
4002   switch (INTVAL (operands[2]))
4003     {
4004     case 0:
4005       insn = gen_vec_extract_lo_<mode>;
4006       break;
4007     case 1:
4008       insn = gen_vec_extract_hi_<mode>;
4009       break;
4010     default:
4011       gcc_unreachable ();
4012     }
4013
4014   emit_insn (insn (operands[0], operands[1]));
4015   DONE;
4016 })
4017
4018 (define_insn_and_split "vec_extract_lo_<mode>"
4019   [(set (match_operand:<ssehalfvecmode> 0 "nonimmediate_operand" "=x,m")
4020         (vec_select:<ssehalfvecmode>
4021           (match_operand:VI8F_256 1 "nonimmediate_operand" "xm,x")
4022           (parallel [(const_int 0) (const_int 1)])))]
4023   "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
4024   "#"
4025   "&& reload_completed"
4026   [(const_int 0)]
4027 {
4028   rtx op1 = operands[1];
4029   if (REG_P (op1))
4030     op1 = gen_rtx_REG (<ssehalfvecmode>mode, REGNO (op1));
4031   else
4032     op1 = gen_lowpart (<ssehalfvecmode>mode, op1);
4033   emit_move_insn (operands[0], op1);
4034   DONE;
4035 })
4036
4037 (define_insn "vec_extract_hi_<mode>"
4038   [(set (match_operand:<ssehalfvecmode> 0 "nonimmediate_operand" "=x,m")
4039         (vec_select:<ssehalfvecmode>
4040           (match_operand:VI8F_256 1 "register_operand" "x,x")
4041           (parallel [(const_int 2) (const_int 3)])))]
4042   "TARGET_AVX"
4043   "vextract<i128>\t{$0x1, %1, %0|%0, %1, 0x1}"
4044   [(set_attr "type" "sselog")
4045    (set_attr "prefix_extra" "1")