OSDN Git Service

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