OSDN Git Service

b8e821de90e86cbc9078e9b744a631536656d67a
[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 tmp0, tmp1;
3042
3043   if (TARGET_AVX && !TARGET_PREFER_AVX128)
3044     {
3045       tmp0 = gen_reg_rtx (V4DFmode);
3046       tmp1 = force_reg (V2DFmode, operands[1]);
3047
3048       emit_insn (gen_avx_vec_concatv4df (tmp0, tmp1, operands[2]));
3049       emit_insn (gen_avx_cvtpd2ps256 (operands[0], tmp0));
3050     }
3051   else
3052     {
3053       tmp0 = gen_reg_rtx (V4SFmode);
3054       tmp1 = gen_reg_rtx (V4SFmode);
3055
3056       emit_insn (gen_sse2_cvtpd2ps (tmp0, operands[1]));
3057       emit_insn (gen_sse2_cvtpd2ps (tmp1, operands[2]));
3058       emit_insn (gen_sse_movlhps (operands[0], tmp0, tmp1));
3059     }
3060   DONE;
3061 })
3062
3063 (define_expand "vec_pack_sfix_trunc_v4df"
3064   [(match_operand:V8SI 0 "register_operand" "")
3065    (match_operand:V4DF 1 "nonimmediate_operand" "")
3066    (match_operand:V4DF 2 "nonimmediate_operand" "")]
3067   "TARGET_AVX"
3068 {
3069   rtx r1, r2;
3070
3071   r1 = gen_reg_rtx (V4SImode);
3072   r2 = gen_reg_rtx (V4SImode);
3073
3074   emit_insn (gen_fix_truncv4dfv4si2 (r1, operands[1]));
3075   emit_insn (gen_fix_truncv4dfv4si2 (r2, operands[2]));
3076   emit_insn (gen_avx_vec_concatv8si (operands[0], r1, r2));
3077   DONE;
3078 })
3079
3080 (define_expand "vec_pack_sfix_trunc_v2df"
3081   [(match_operand:V4SI 0 "register_operand" "")
3082    (match_operand:V2DF 1 "nonimmediate_operand" "")
3083    (match_operand:V2DF 2 "nonimmediate_operand" "")]
3084   "TARGET_SSE2"
3085 {
3086   rtx tmp0, tmp1;
3087
3088   if (TARGET_AVX && !TARGET_PREFER_AVX128)
3089     {
3090       tmp0 = gen_reg_rtx (V4DFmode);
3091       tmp1 = force_reg (V2DFmode, operands[1]);
3092
3093       emit_insn (gen_avx_vec_concatv4df (tmp0, tmp1, operands[2]));
3094       emit_insn (gen_fix_truncv4dfv4si2 (operands[0], tmp0));
3095     }
3096   else
3097     {
3098       tmp0 = gen_reg_rtx (V4SImode);
3099       tmp1 = gen_reg_rtx (V4SImode);
3100
3101       emit_insn (gen_sse2_cvttpd2dq (tmp0, operands[1]));
3102       emit_insn (gen_sse2_cvttpd2dq (tmp1, operands[2]));
3103       emit_insn
3104        (gen_vec_interleave_lowv2di (gen_lowpart (V2DImode, operands[0]),
3105                                     gen_lowpart (V2DImode, tmp0),
3106                                     gen_lowpart (V2DImode, tmp1)));
3107     }
3108   DONE;
3109 })
3110
3111 (define_mode_attr ssepackfltmode
3112   [(V4DF "V8SI") (V2DF "V4SI")])
3113
3114 (define_expand "vec_pack_ufix_trunc_<mode>"
3115   [(match_operand:<ssepackfltmode> 0 "register_operand" "")
3116    (match_operand:VF2 1 "register_operand" "")
3117    (match_operand:VF2 2 "register_operand" "")]
3118   "TARGET_SSE2"
3119 {
3120   rtx tmp[7];
3121   tmp[0] = ix86_expand_adjust_ufix_to_sfix_si (operands[1], &tmp[2]);
3122   tmp[1] = ix86_expand_adjust_ufix_to_sfix_si (operands[2], &tmp[3]);
3123   tmp[4] = gen_reg_rtx (<ssepackfltmode>mode);
3124   emit_insn (gen_vec_pack_sfix_trunc_<mode> (tmp[4], tmp[0], tmp[1]));
3125   if (<ssepackfltmode>mode == V4SImode || TARGET_AVX2)
3126     {
3127       tmp[5] = gen_reg_rtx (<ssepackfltmode>mode);
3128       ix86_expand_vec_extract_even_odd (tmp[5], tmp[2], tmp[3], 0);
3129     }
3130   else
3131     {
3132       tmp[5] = gen_reg_rtx (V8SFmode);
3133       ix86_expand_vec_extract_even_odd (tmp[5], gen_lowpart (V8SFmode, tmp[2]),
3134                                         gen_lowpart (V8SFmode, tmp[3]), 0);
3135       tmp[5] = gen_lowpart (V8SImode, tmp[5]);
3136     }
3137   tmp[6] = expand_simple_binop (<ssepackfltmode>mode, XOR, tmp[4], tmp[5],
3138                                 operands[0], 0, OPTAB_DIRECT);
3139   if (tmp[6] != operands[0])
3140     emit_move_insn (operands[0], tmp[6]);
3141   DONE;
3142 })
3143
3144 (define_expand "vec_pack_sfix_v4df"
3145   [(match_operand:V8SI 0 "register_operand" "")
3146    (match_operand:V4DF 1 "nonimmediate_operand" "")
3147    (match_operand:V4DF 2 "nonimmediate_operand" "")]
3148   "TARGET_AVX"
3149 {
3150   rtx r1, r2;
3151
3152   r1 = gen_reg_rtx (V4SImode);
3153   r2 = gen_reg_rtx (V4SImode);
3154
3155   emit_insn (gen_avx_cvtpd2dq256 (r1, operands[1]));
3156   emit_insn (gen_avx_cvtpd2dq256 (r2, operands[2]));
3157   emit_insn (gen_avx_vec_concatv8si (operands[0], r1, r2));
3158   DONE;
3159 })
3160
3161 (define_expand "vec_pack_sfix_v2df"
3162   [(match_operand:V4SI 0 "register_operand" "")
3163    (match_operand:V2DF 1 "nonimmediate_operand" "")
3164    (match_operand:V2DF 2 "nonimmediate_operand" "")]
3165   "TARGET_SSE2"
3166 {
3167   rtx tmp0, tmp1;
3168
3169   if (TARGET_AVX && !TARGET_PREFER_AVX128)
3170     {
3171       tmp0 = gen_reg_rtx (V4DFmode);
3172       tmp1 = force_reg (V2DFmode, operands[1]);
3173
3174       emit_insn (gen_avx_vec_concatv4df (tmp0, tmp1, operands[2]));
3175       emit_insn (gen_avx_cvtpd2dq256 (operands[0], tmp0));
3176     }
3177   else
3178     {
3179       tmp0 = gen_reg_rtx (V4SImode);
3180       tmp1 = gen_reg_rtx (V4SImode);
3181
3182       emit_insn (gen_sse2_cvtpd2dq (tmp0, operands[1]));
3183       emit_insn (gen_sse2_cvtpd2dq (tmp1, operands[2]));
3184       emit_insn
3185        (gen_vec_interleave_lowv2di (gen_lowpart (V2DImode, operands[0]),
3186                                     gen_lowpart (V2DImode, tmp0),
3187                                     gen_lowpart (V2DImode, tmp1)));
3188     }
3189   DONE;
3190 })
3191
3192 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3193 ;;
3194 ;; Parallel single-precision floating point element swizzling
3195 ;;
3196 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3197
3198 (define_expand "sse_movhlps_exp"
3199   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
3200         (vec_select:V4SF
3201           (vec_concat:V8SF
3202             (match_operand:V4SF 1 "nonimmediate_operand" "")
3203             (match_operand:V4SF 2 "nonimmediate_operand" ""))
3204           (parallel [(const_int 6)
3205                      (const_int 7)
3206                      (const_int 2)
3207                      (const_int 3)])))]
3208   "TARGET_SSE"
3209 {
3210   rtx dst = ix86_fixup_binary_operands (UNKNOWN, V4SFmode, operands);
3211
3212   emit_insn (gen_sse_movhlps (dst, operands[1], operands[2]));
3213
3214   /* Fix up the destination if needed.  */
3215   if (dst != operands[0])
3216     emit_move_insn (operands[0], dst);
3217
3218   DONE;
3219 })
3220
3221 (define_insn "sse_movhlps"
3222   [(set (match_operand:V4SF 0 "nonimmediate_operand"     "=x,x,x,x,m")
3223         (vec_select:V4SF
3224           (vec_concat:V8SF
3225             (match_operand:V4SF 1 "nonimmediate_operand" " 0,x,0,x,0")
3226             (match_operand:V4SF 2 "nonimmediate_operand" " x,x,o,o,x"))
3227           (parallel [(const_int 6)
3228                      (const_int 7)
3229                      (const_int 2)
3230                      (const_int 3)])))]
3231   "TARGET_SSE && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
3232   "@
3233    movhlps\t{%2, %0|%0, %2}
3234    vmovhlps\t{%2, %1, %0|%0, %1, %2}
3235    movlps\t{%H2, %0|%0, %H2}
3236    vmovlps\t{%H2, %1, %0|%0, %1, %H2}
3237    %vmovhps\t{%2, %0|%0, %2}"
3238   [(set_attr "isa" "noavx,avx,noavx,avx,*")
3239    (set_attr "type" "ssemov")
3240    (set_attr "prefix" "orig,vex,orig,vex,maybe_vex")
3241    (set_attr "mode" "V4SF,V4SF,V2SF,V2SF,V2SF")])
3242
3243 (define_expand "sse_movlhps_exp"
3244   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
3245         (vec_select:V4SF
3246           (vec_concat:V8SF
3247             (match_operand:V4SF 1 "nonimmediate_operand" "")
3248             (match_operand:V4SF 2 "nonimmediate_operand" ""))
3249           (parallel [(const_int 0)
3250                      (const_int 1)
3251                      (const_int 4)
3252                      (const_int 5)])))]
3253   "TARGET_SSE"
3254 {
3255   rtx dst = ix86_fixup_binary_operands (UNKNOWN, V4SFmode, operands);
3256
3257   emit_insn (gen_sse_movlhps (dst, operands[1], operands[2]));
3258
3259   /* Fix up the destination if needed.  */
3260   if (dst != operands[0])
3261     emit_move_insn (operands[0], dst);
3262
3263   DONE;
3264 })
3265
3266 (define_insn "sse_movlhps"
3267   [(set (match_operand:V4SF 0 "nonimmediate_operand"     "=x,x,x,x,o")
3268         (vec_select:V4SF
3269           (vec_concat:V8SF
3270             (match_operand:V4SF 1 "nonimmediate_operand" " 0,x,0,x,0")
3271             (match_operand:V4SF 2 "nonimmediate_operand" " x,x,m,x,x"))
3272           (parallel [(const_int 0)
3273                      (const_int 1)
3274                      (const_int 4)
3275                      (const_int 5)])))]
3276   "TARGET_SSE && ix86_binary_operator_ok (UNKNOWN, V4SFmode, operands)"
3277   "@
3278    movlhps\t{%2, %0|%0, %2}
3279    vmovlhps\t{%2, %1, %0|%0, %1, %2}
3280    movhps\t{%2, %0|%0, %2}
3281    vmovhps\t{%2, %1, %0|%0, %1, %2}
3282    %vmovlps\t{%2, %H0|%H0, %2}"
3283   [(set_attr "isa" "noavx,avx,noavx,avx,*")
3284    (set_attr "type" "ssemov")
3285    (set_attr "prefix" "orig,vex,orig,vex,maybe_vex")
3286    (set_attr "mode" "V4SF,V4SF,V2SF,V2SF,V2SF")])
3287
3288 ;; Recall that the 256-bit unpck insns only shuffle within their lanes.
3289 (define_insn "avx_unpckhps256"
3290   [(set (match_operand:V8SF 0 "register_operand" "=x")
3291         (vec_select:V8SF
3292           (vec_concat:V16SF
3293             (match_operand:V8SF 1 "register_operand" "x")
3294             (match_operand:V8SF 2 "nonimmediate_operand" "xm"))
3295           (parallel [(const_int 2) (const_int 10)
3296                      (const_int 3) (const_int 11)
3297                      (const_int 6) (const_int 14)
3298                      (const_int 7) (const_int 15)])))]
3299   "TARGET_AVX"
3300   "vunpckhps\t{%2, %1, %0|%0, %1, %2}"
3301   [(set_attr "type" "sselog")
3302    (set_attr "prefix" "vex")
3303    (set_attr "mode" "V8SF")])
3304
3305 (define_expand "vec_interleave_highv8sf"
3306   [(set (match_dup 3)
3307         (vec_select:V8SF
3308           (vec_concat:V16SF
3309             (match_operand:V8SF 1 "register_operand" "x")
3310             (match_operand:V8SF 2 "nonimmediate_operand" "xm"))
3311           (parallel [(const_int 0) (const_int 8)
3312                      (const_int 1) (const_int 9)
3313                      (const_int 4) (const_int 12)
3314                      (const_int 5) (const_int 13)])))
3315    (set (match_dup 4)
3316         (vec_select:V8SF
3317           (vec_concat:V16SF
3318             (match_dup 1)
3319             (match_dup 2))
3320           (parallel [(const_int 2) (const_int 10)
3321                      (const_int 3) (const_int 11)
3322                      (const_int 6) (const_int 14)
3323                      (const_int 7) (const_int 15)])))
3324    (set (match_operand:V8SF 0 "register_operand" "")
3325         (vec_select:V8SF
3326           (vec_concat:V16SF
3327             (match_dup 3)
3328             (match_dup 4))
3329           (parallel [(const_int 4) (const_int 5)
3330                      (const_int 6) (const_int 7)
3331                      (const_int 12) (const_int 13)
3332                      (const_int 14) (const_int 15)])))]
3333  "TARGET_AVX"
3334 {
3335   operands[3] = gen_reg_rtx (V8SFmode);
3336   operands[4] = gen_reg_rtx (V8SFmode);
3337 })
3338
3339 (define_insn "vec_interleave_highv4sf"
3340   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
3341         (vec_select:V4SF
3342           (vec_concat:V8SF
3343             (match_operand:V4SF 1 "register_operand" "0,x")
3344             (match_operand:V4SF 2 "nonimmediate_operand" "xm,xm"))
3345           (parallel [(const_int 2) (const_int 6)
3346                      (const_int 3) (const_int 7)])))]
3347   "TARGET_SSE"
3348   "@
3349    unpckhps\t{%2, %0|%0, %2}
3350    vunpckhps\t{%2, %1, %0|%0, %1, %2}"
3351   [(set_attr "isa" "noavx,avx")
3352    (set_attr "type" "sselog")
3353    (set_attr "prefix" "orig,vex")
3354    (set_attr "mode" "V4SF")])
3355
3356 ;; Recall that the 256-bit unpck insns only shuffle within their lanes.
3357 (define_insn "avx_unpcklps256"
3358   [(set (match_operand:V8SF 0 "register_operand" "=x")
3359         (vec_select:V8SF
3360           (vec_concat:V16SF
3361             (match_operand:V8SF 1 "register_operand" "x")
3362             (match_operand:V8SF 2 "nonimmediate_operand" "xm"))
3363           (parallel [(const_int 0) (const_int 8)
3364                      (const_int 1) (const_int 9)
3365                      (const_int 4) (const_int 12)
3366                      (const_int 5) (const_int 13)])))]
3367   "TARGET_AVX"
3368   "vunpcklps\t{%2, %1, %0|%0, %1, %2}"
3369   [(set_attr "type" "sselog")
3370    (set_attr "prefix" "vex")
3371    (set_attr "mode" "V8SF")])
3372
3373 (define_expand "vec_interleave_lowv8sf"
3374   [(set (match_dup 3)
3375         (vec_select:V8SF
3376           (vec_concat:V16SF
3377             (match_operand:V8SF 1 "register_operand" "x")
3378             (match_operand:V8SF 2 "nonimmediate_operand" "xm"))
3379           (parallel [(const_int 0) (const_int 8)
3380                      (const_int 1) (const_int 9)
3381                      (const_int 4) (const_int 12)
3382                      (const_int 5) (const_int 13)])))
3383    (set (match_dup 4)
3384         (vec_select:V8SF
3385           (vec_concat:V16SF
3386             (match_dup 1)
3387             (match_dup 2))
3388           (parallel [(const_int 2) (const_int 10)
3389                      (const_int 3) (const_int 11)
3390                      (const_int 6) (const_int 14)
3391                      (const_int 7) (const_int 15)])))
3392    (set (match_operand:V8SF 0 "register_operand" "")
3393         (vec_select:V8SF
3394           (vec_concat:V16SF
3395             (match_dup 3)
3396             (match_dup 4))
3397           (parallel [(const_int 0) (const_int 1)
3398                      (const_int 2) (const_int 3)
3399                      (const_int 8) (const_int 9)
3400                      (const_int 10) (const_int 11)])))]
3401  "TARGET_AVX"
3402 {
3403   operands[3] = gen_reg_rtx (V8SFmode);
3404   operands[4] = gen_reg_rtx (V8SFmode);
3405 })
3406
3407 (define_insn "vec_interleave_lowv4sf"
3408   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
3409         (vec_select:V4SF
3410           (vec_concat:V8SF
3411             (match_operand:V4SF 1 "register_operand" "0,x")
3412             (match_operand:V4SF 2 "nonimmediate_operand" "xm,xm"))
3413           (parallel [(const_int 0) (const_int 4)
3414                      (const_int 1) (const_int 5)])))]
3415   "TARGET_SSE"
3416   "@
3417    unpcklps\t{%2, %0|%0, %2}
3418    vunpcklps\t{%2, %1, %0|%0, %1, %2}"
3419   [(set_attr "isa" "noavx,avx")
3420    (set_attr "type" "sselog")
3421    (set_attr "prefix" "orig,vex")
3422    (set_attr "mode" "V4SF")])
3423
3424 ;; These are modeled with the same vec_concat as the others so that we
3425 ;; capture users of shufps that can use the new instructions
3426 (define_insn "avx_movshdup256"
3427   [(set (match_operand:V8SF 0 "register_operand" "=x")
3428         (vec_select:V8SF
3429           (vec_concat:V16SF
3430             (match_operand:V8SF 1 "nonimmediate_operand" "xm")
3431             (match_dup 1))
3432           (parallel [(const_int 1) (const_int 1)
3433                      (const_int 3) (const_int 3)
3434                      (const_int 5) (const_int 5)
3435                      (const_int 7) (const_int 7)])))]
3436   "TARGET_AVX"
3437   "vmovshdup\t{%1, %0|%0, %1}"
3438   [(set_attr "type" "sse")
3439    (set_attr "prefix" "vex")
3440    (set_attr "mode" "V8SF")])
3441
3442 (define_insn "sse3_movshdup"
3443   [(set (match_operand:V4SF 0 "register_operand" "=x")
3444         (vec_select:V4SF
3445           (vec_concat:V8SF
3446             (match_operand:V4SF 1 "nonimmediate_operand" "xm")
3447             (match_dup 1))
3448           (parallel [(const_int 1)
3449                      (const_int 1)
3450                      (const_int 7)
3451                      (const_int 7)])))]
3452   "TARGET_SSE3"
3453   "%vmovshdup\t{%1, %0|%0, %1}"
3454   [(set_attr "type" "sse")
3455    (set_attr "prefix_rep" "1")
3456    (set_attr "prefix" "maybe_vex")
3457    (set_attr "mode" "V4SF")])
3458
3459 (define_insn "avx_movsldup256"
3460   [(set (match_operand:V8SF 0 "register_operand" "=x")
3461         (vec_select:V8SF
3462           (vec_concat:V16SF
3463             (match_operand:V8SF 1 "nonimmediate_operand" "xm")
3464             (match_dup 1))
3465           (parallel [(const_int 0) (const_int 0)
3466                      (const_int 2) (const_int 2)
3467                      (const_int 4) (const_int 4)
3468                      (const_int 6) (const_int 6)])))]
3469   "TARGET_AVX"
3470   "vmovsldup\t{%1, %0|%0, %1}"
3471   [(set_attr "type" "sse")
3472    (set_attr "prefix" "vex")
3473    (set_attr "mode" "V8SF")])
3474
3475 (define_insn "sse3_movsldup"
3476   [(set (match_operand:V4SF 0 "register_operand" "=x")
3477         (vec_select:V4SF
3478           (vec_concat:V8SF
3479             (match_operand:V4SF 1 "nonimmediate_operand" "xm")
3480             (match_dup 1))
3481           (parallel [(const_int 0)
3482                      (const_int 0)
3483                      (const_int 6)
3484                      (const_int 6)])))]
3485   "TARGET_SSE3"
3486   "%vmovsldup\t{%1, %0|%0, %1}"
3487   [(set_attr "type" "sse")
3488    (set_attr "prefix_rep" "1")
3489    (set_attr "prefix" "maybe_vex")
3490    (set_attr "mode" "V4SF")])
3491
3492 (define_expand "avx_shufps256"
3493   [(match_operand:V8SF 0 "register_operand" "")
3494    (match_operand:V8SF 1 "register_operand" "")
3495    (match_operand:V8SF 2 "nonimmediate_operand" "")
3496    (match_operand:SI 3 "const_int_operand" "")]
3497   "TARGET_AVX"
3498 {
3499   int mask = INTVAL (operands[3]);
3500   emit_insn (gen_avx_shufps256_1 (operands[0], operands[1], operands[2],
3501                                   GEN_INT ((mask >> 0) & 3),
3502                                   GEN_INT ((mask >> 2) & 3),
3503                                   GEN_INT (((mask >> 4) & 3) + 8),
3504                                   GEN_INT (((mask >> 6) & 3) + 8),
3505                                   GEN_INT (((mask >> 0) & 3) + 4),
3506                                   GEN_INT (((mask >> 2) & 3) + 4),
3507                                   GEN_INT (((mask >> 4) & 3) + 12),
3508                                   GEN_INT (((mask >> 6) & 3) + 12)));
3509   DONE;
3510 })
3511
3512 ;; One bit in mask selects 2 elements.
3513 (define_insn "avx_shufps256_1"
3514   [(set (match_operand:V8SF 0 "register_operand" "=x")
3515         (vec_select:V8SF
3516           (vec_concat:V16SF
3517             (match_operand:V8SF 1 "register_operand" "x")
3518             (match_operand:V8SF 2 "nonimmediate_operand" "xm"))
3519           (parallel [(match_operand 3  "const_0_to_3_operand"   "")
3520                      (match_operand 4  "const_0_to_3_operand"   "")
3521                      (match_operand 5  "const_8_to_11_operand"  "")
3522                      (match_operand 6  "const_8_to_11_operand"  "")
3523                      (match_operand 7  "const_4_to_7_operand"   "")
3524                      (match_operand 8  "const_4_to_7_operand"   "")
3525                      (match_operand 9  "const_12_to_15_operand" "")
3526                      (match_operand 10 "const_12_to_15_operand" "")])))]
3527   "TARGET_AVX
3528    && (INTVAL (operands[3]) == (INTVAL (operands[7]) - 4)
3529        && INTVAL (operands[4]) == (INTVAL (operands[8]) - 4)
3530        && INTVAL (operands[5]) == (INTVAL (operands[9]) - 4)
3531        && INTVAL (operands[6]) == (INTVAL (operands[10]) - 4))"
3532 {
3533   int mask;
3534   mask = INTVAL (operands[3]);
3535   mask |= INTVAL (operands[4]) << 2;
3536   mask |= (INTVAL (operands[5]) - 8) << 4;
3537   mask |= (INTVAL (operands[6]) - 8) << 6;
3538   operands[3] = GEN_INT (mask);
3539
3540   return "vshufps\t{%3, %2, %1, %0|%0, %1, %2, %3}";
3541 }
3542   [(set_attr "type" "sselog")
3543    (set_attr "length_immediate" "1")
3544    (set_attr "prefix" "vex")
3545    (set_attr "mode" "V8SF")])
3546
3547 (define_expand "sse_shufps"
3548   [(match_operand:V4SF 0 "register_operand" "")
3549    (match_operand:V4SF 1 "register_operand" "")
3550    (match_operand:V4SF 2 "nonimmediate_operand" "")
3551    (match_operand:SI 3 "const_int_operand" "")]
3552   "TARGET_SSE"
3553 {
3554   int mask = INTVAL (operands[3]);
3555   emit_insn (gen_sse_shufps_v4sf (operands[0], operands[1], operands[2],
3556                                GEN_INT ((mask >> 0) & 3),
3557                                GEN_INT ((mask >> 2) & 3),
3558                                GEN_INT (((mask >> 4) & 3) + 4),
3559                                GEN_INT (((mask >> 6) & 3) + 4)));
3560   DONE;
3561 })
3562
3563 (define_insn "sse_shufps_<mode>"
3564   [(set (match_operand:VI4F_128 0 "register_operand" "=x,x")
3565         (vec_select:VI4F_128
3566           (vec_concat:<ssedoublevecmode>
3567             (match_operand:VI4F_128 1 "register_operand" "0,x")
3568             (match_operand:VI4F_128 2 "nonimmediate_operand" "xm,xm"))
3569           (parallel [(match_operand 3 "const_0_to_3_operand" "")
3570                      (match_operand 4 "const_0_to_3_operand" "")
3571                      (match_operand 5 "const_4_to_7_operand" "")
3572                      (match_operand 6 "const_4_to_7_operand" "")])))]
3573   "TARGET_SSE"
3574 {
3575   int mask = 0;
3576   mask |= INTVAL (operands[3]) << 0;
3577   mask |= INTVAL (operands[4]) << 2;
3578   mask |= (INTVAL (operands[5]) - 4) << 4;
3579   mask |= (INTVAL (operands[6]) - 4) << 6;
3580   operands[3] = GEN_INT (mask);
3581
3582   switch (which_alternative)
3583     {
3584     case 0:
3585       return "shufps\t{%3, %2, %0|%0, %2, %3}";
3586     case 1:
3587       return "vshufps\t{%3, %2, %1, %0|%0, %1, %2, %3}";
3588     default:
3589       gcc_unreachable ();
3590     }
3591 }
3592   [(set_attr "isa" "noavx,avx")
3593    (set_attr "type" "sselog")
3594    (set_attr "length_immediate" "1")
3595    (set_attr "prefix" "orig,vex")
3596    (set_attr "mode" "V4SF")])
3597
3598 (define_insn "sse_storehps"
3599   [(set (match_operand:V2SF 0 "nonimmediate_operand" "=m,x,x")
3600         (vec_select:V2SF
3601           (match_operand:V4SF 1 "nonimmediate_operand" "x,x,o")
3602           (parallel [(const_int 2) (const_int 3)])))]
3603   "TARGET_SSE"
3604   "@
3605    %vmovhps\t{%1, %0|%0, %1}
3606    %vmovhlps\t{%1, %d0|%d0, %1}
3607    %vmovlps\t{%H1, %d0|%d0, %H1}"
3608   [(set_attr "type" "ssemov")
3609    (set_attr "prefix" "maybe_vex")
3610    (set_attr "mode" "V2SF,V4SF,V2SF")])
3611
3612 (define_expand "sse_loadhps_exp"
3613   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
3614         (vec_concat:V4SF
3615           (vec_select:V2SF
3616             (match_operand:V4SF 1 "nonimmediate_operand" "")
3617             (parallel [(const_int 0) (const_int 1)]))
3618           (match_operand:V2SF 2 "nonimmediate_operand" "")))]
3619   "TARGET_SSE"
3620 {
3621   rtx dst = ix86_fixup_binary_operands (UNKNOWN, V4SFmode, operands);
3622
3623   emit_insn (gen_sse_loadhps (dst, operands[1], operands[2]));
3624
3625   /* Fix up the destination if needed.  */
3626   if (dst != operands[0])
3627     emit_move_insn (operands[0], dst);
3628
3629   DONE;
3630 })
3631
3632 (define_insn "sse_loadhps"
3633   [(set (match_operand:V4SF 0 "nonimmediate_operand"     "=x,x,x,x,o")
3634         (vec_concat:V4SF
3635           (vec_select:V2SF
3636             (match_operand:V4SF 1 "nonimmediate_operand" " 0,x,0,x,0")
3637             (parallel [(const_int 0) (const_int 1)]))
3638           (match_operand:V2SF 2 "nonimmediate_operand"   " m,m,x,x,x")))]
3639   "TARGET_SSE"
3640   "@
3641    movhps\t{%2, %0|%0, %2}
3642    vmovhps\t{%2, %1, %0|%0, %1, %2}
3643    movlhps\t{%2, %0|%0, %2}
3644    vmovlhps\t{%2, %1, %0|%0, %1, %2}
3645    %vmovlps\t{%2, %H0|%H0, %2}"
3646   [(set_attr "isa" "noavx,avx,noavx,avx,*")
3647    (set_attr "type" "ssemov")
3648    (set_attr "prefix" "orig,vex,orig,vex,maybe_vex")
3649    (set_attr "mode" "V2SF,V2SF,V4SF,V4SF,V2SF")])
3650
3651 (define_insn "sse_storelps"
3652   [(set (match_operand:V2SF 0 "nonimmediate_operand"   "=m,x,x")
3653         (vec_select:V2SF
3654           (match_operand:V4SF 1 "nonimmediate_operand" " x,x,m")
3655           (parallel [(const_int 0) (const_int 1)])))]
3656   "TARGET_SSE"
3657   "@
3658    %vmovlps\t{%1, %0|%0, %1}
3659    %vmovaps\t{%1, %0|%0, %1}
3660    %vmovlps\t{%1, %d0|%d0, %1}"
3661   [(set_attr "type" "ssemov")
3662    (set_attr "prefix" "maybe_vex")
3663    (set_attr "mode" "V2SF,V4SF,V2SF")])
3664
3665 (define_expand "sse_loadlps_exp"
3666   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
3667         (vec_concat:V4SF
3668           (match_operand:V2SF 2 "nonimmediate_operand" "")
3669           (vec_select:V2SF
3670             (match_operand:V4SF 1 "nonimmediate_operand" "")
3671             (parallel [(const_int 2) (const_int 3)]))))]
3672   "TARGET_SSE"
3673 {
3674   rtx dst = ix86_fixup_binary_operands (UNKNOWN, V4SFmode, operands);
3675
3676   emit_insn (gen_sse_loadlps (dst, operands[1], operands[2]));
3677
3678   /* Fix up the destination if needed.  */
3679   if (dst != operands[0])
3680     emit_move_insn (operands[0], dst);
3681
3682   DONE;
3683 })
3684
3685 (define_insn "sse_loadlps"
3686   [(set (match_operand:V4SF 0 "nonimmediate_operand"     "=x,x,x,x,m")
3687         (vec_concat:V4SF
3688           (match_operand:V2SF 2 "nonimmediate_operand"   " 0,x,m,x,x")
3689           (vec_select:V2SF
3690             (match_operand:V4SF 1 "nonimmediate_operand" " x,x,0,x,0")
3691             (parallel [(const_int 2) (const_int 3)]))))]
3692   "TARGET_SSE"
3693   "@
3694    shufps\t{$0xe4, %1, %0|%0, %1, 0xe4}
3695    vshufps\t{$0xe4, %1, %2, %0|%0, %2, %1, 0xe4}
3696    movlps\t{%2, %0|%0, %2}
3697    vmovlps\t{%2, %1, %0|%0, %1, %2}
3698    %vmovlps\t{%2, %0|%0, %2}"
3699   [(set_attr "isa" "noavx,avx,noavx,avx,*")
3700    (set_attr "type" "sselog,sselog,ssemov,ssemov,ssemov")
3701    (set_attr "length_immediate" "1,1,*,*,*")
3702    (set_attr "prefix" "orig,vex,orig,vex,maybe_vex")
3703    (set_attr "mode" "V4SF,V4SF,V2SF,V2SF,V2SF")])
3704
3705 (define_insn "sse_movss"
3706   [(set (match_operand:V4SF 0 "register_operand"   "=x,x")
3707         (vec_merge:V4SF
3708           (match_operand:V4SF 2 "register_operand" " x,x")
3709           (match_operand:V4SF 1 "register_operand" " 0,x")
3710           (const_int 1)))]
3711   "TARGET_SSE"
3712   "@
3713    movss\t{%2, %0|%0, %2}
3714    vmovss\t{%2, %1, %0|%0, %1, %2}"
3715   [(set_attr "isa" "noavx,avx")
3716    (set_attr "type" "ssemov")
3717    (set_attr "prefix" "orig,vex")
3718    (set_attr "mode" "SF")])
3719
3720 (define_insn "avx2_vec_dup<mode>"
3721   [(set (match_operand:VF1 0 "register_operand" "=x")
3722         (vec_duplicate:VF1
3723           (vec_select:SF
3724             (match_operand:V4SF 1 "register_operand" "x")
3725             (parallel [(const_int 0)]))))]
3726   "TARGET_AVX2"
3727   "vbroadcastss\t{%1, %0|%0, %1}"
3728   [(set_attr "type" "sselog1")
3729     (set_attr "prefix" "vex")
3730     (set_attr "mode" "<MODE>")])
3731
3732 (define_insn "vec_dupv4sf"
3733   [(set (match_operand:V4SF 0 "register_operand" "=x,x,x")
3734         (vec_duplicate:V4SF
3735           (match_operand:SF 1 "nonimmediate_operand" "x,m,0")))]
3736   "TARGET_SSE"
3737   "@
3738    vshufps\t{$0, %1, %1, %0|%0, %1, %1, 0}
3739    vbroadcastss\t{%1, %0|%0, %1}
3740    shufps\t{$0, %0, %0|%0, %0, 0}"
3741   [(set_attr "isa" "avx,avx,noavx")
3742    (set_attr "type" "sselog1,ssemov,sselog1")
3743    (set_attr "length_immediate" "1,0,1")
3744    (set_attr "prefix_extra" "0,1,*")
3745    (set_attr "prefix" "vex,vex,orig")
3746    (set_attr "mode" "V4SF")])
3747
3748 ;; Although insertps takes register source, we prefer
3749 ;; unpcklps with register source since it is shorter.
3750 (define_insn "*vec_concatv2sf_sse4_1"
3751   [(set (match_operand:V2SF 0 "register_operand"     "=x,x,x,x,x,*y ,*y")
3752         (vec_concat:V2SF
3753           (match_operand:SF 1 "nonimmediate_operand" " 0,x,0,x,m, 0 , m")
3754           (match_operand:SF 2 "vector_move_operand"  " x,x,m,m,C,*ym, C")))]
3755   "TARGET_SSE4_1"
3756   "@
3757    unpcklps\t{%2, %0|%0, %2}
3758    vunpcklps\t{%2, %1, %0|%0, %1, %2}
3759    insertps\t{$0x10, %2, %0|%0, %2, 0x10}
3760    vinsertps\t{$0x10, %2, %1, %0|%0, %1, %2, 0x10}
3761    %vmovss\t{%1, %0|%0, %1}
3762    punpckldq\t{%2, %0|%0, %2}
3763    movd\t{%1, %0|%0, %1}"
3764   [(set_attr "isa" "noavx,avx,noavx,avx,*,*,*")
3765    (set_attr "type" "sselog,sselog,sselog,sselog,ssemov,mmxcvt,mmxmov")
3766    (set_attr "prefix_data16" "*,*,1,*,*,*,*")
3767    (set_attr "prefix_extra" "*,*,1,1,*,*,*")
3768    (set_attr "length_immediate" "*,*,1,1,*,*,*")
3769    (set_attr "prefix" "orig,vex,orig,vex,maybe_vex,orig,orig")
3770    (set_attr "mode" "V4SF,V4SF,V4SF,V4SF,SF,DI,DI")])
3771
3772 ;; ??? In theory we can match memory for the MMX alternative, but allowing
3773 ;; nonimmediate_operand for operand 2 and *not* allowing memory for the SSE
3774 ;; alternatives pretty much forces the MMX alternative to be chosen.
3775 (define_insn "*vec_concatv2sf_sse"
3776   [(set (match_operand:V2SF 0 "register_operand"     "=x,x,*y,*y")
3777         (vec_concat:V2SF
3778           (match_operand:SF 1 "nonimmediate_operand" " 0,m, 0, m")
3779           (match_operand:SF 2 "reg_or_0_operand"     " x,C,*y, C")))]
3780   "TARGET_SSE"
3781   "@
3782    unpcklps\t{%2, %0|%0, %2}
3783    movss\t{%1, %0|%0, %1}
3784    punpckldq\t{%2, %0|%0, %2}
3785    movd\t{%1, %0|%0, %1}"
3786   [(set_attr "type" "sselog,ssemov,mmxcvt,mmxmov")
3787    (set_attr "mode" "V4SF,SF,DI,DI")])
3788
3789 (define_insn "*vec_concatv4sf"
3790   [(set (match_operand:V4SF 0 "register_operand"       "=x,x,x,x")
3791         (vec_concat:V4SF
3792           (match_operand:V2SF 1 "register_operand"     " 0,x,0,x")
3793           (match_operand:V2SF 2 "nonimmediate_operand" " x,x,m,m")))]
3794   "TARGET_SSE"
3795   "@
3796    movlhps\t{%2, %0|%0, %2}
3797    vmovlhps\t{%2, %1, %0|%0, %1, %2}
3798    movhps\t{%2, %0|%0, %2}
3799    vmovhps\t{%2, %1, %0|%0, %1, %2}"
3800   [(set_attr "isa" "noavx,avx,noavx,avx")
3801    (set_attr "type" "ssemov")
3802    (set_attr "prefix" "orig,vex,orig,vex")
3803    (set_attr "mode" "V4SF,V4SF,V2SF,V2SF")])
3804
3805 (define_expand "vec_init<mode>"
3806   [(match_operand:V_128 0 "register_operand" "")
3807    (match_operand 1 "" "")]
3808   "TARGET_SSE"
3809 {
3810   ix86_expand_vector_init (false, operands[0], operands[1]);
3811   DONE;
3812 })
3813
3814 ;; Avoid combining registers from different units in a single alternative,
3815 ;; see comment above inline_secondary_memory_needed function in i386.c
3816 (define_insn "vec_set<mode>_0"
3817   [(set (match_operand:VI4F_128 0 "nonimmediate_operand"
3818           "=x,x,x ,x,x,x,x  ,x  ,m,m ,m")
3819         (vec_merge:VI4F_128
3820           (vec_duplicate:VI4F_128
3821             (match_operand:<ssescalarmode> 2 "general_operand"
3822           " x,m,*r,m,x,x,*rm,*rm,x,fF,*r"))
3823           (match_operand:VI4F_128 1 "vector_move_operand"
3824           " C,C,C ,C,0,x,0  ,x  ,0,0 ,0")
3825           (const_int 1)))]
3826   "TARGET_SSE"
3827   "@
3828    %vinsertps\t{$0xe, %d2, %0|%0, %d2, 0xe}
3829    %vmov<ssescalarmodesuffix>\t{%2, %0|%0, %2}
3830    %vmovd\t{%2, %0|%0, %2}
3831    movss\t{%2, %0|%0, %2}
3832    movss\t{%2, %0|%0, %2}
3833    vmovss\t{%2, %1, %0|%0, %1, %2}
3834    pinsrd\t{$0, %2, %0|%0, %2, 0}
3835    vpinsrd\t{$0, %2, %1, %0|%0, %1, %2, 0}
3836    #
3837    #
3838    #"
3839   [(set_attr "isa" "sse4,sse2,sse2,noavx,noavx,avx,sse4_noavx,avx,*,*,*")
3840    (set (attr "type")
3841      (cond [(eq_attr "alternative" "0,6,7")
3842               (const_string "sselog")
3843             (eq_attr "alternative" "9")
3844               (const_string "fmov")
3845             (eq_attr "alternative" "10")
3846               (const_string "imov")
3847            ]
3848            (const_string "ssemov")))
3849    (set_attr "prefix_extra" "*,*,*,*,*,*,1,1,*,*,*")
3850    (set_attr "length_immediate" "*,*,*,*,*,*,1,1,*,*,*")
3851    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,orig,orig,vex,orig,vex,*,*,*")
3852    (set_attr "mode" "SF,<ssescalarmode>,SI,SF,SF,SF,TI,TI,*,*,*")])
3853
3854 ;; A subset is vec_setv4sf.
3855 (define_insn "*vec_setv4sf_sse4_1"
3856   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
3857         (vec_merge:V4SF
3858           (vec_duplicate:V4SF
3859             (match_operand:SF 2 "nonimmediate_operand" "xm,xm"))
3860           (match_operand:V4SF 1 "register_operand" "0,x")
3861           (match_operand:SI 3 "const_int_operand" "")))]
3862   "TARGET_SSE4_1
3863    && ((unsigned) exact_log2 (INTVAL (operands[3]))
3864        < GET_MODE_NUNITS (V4SFmode))"
3865 {
3866   operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])) << 4);
3867   switch (which_alternative)
3868     {
3869     case 0:
3870       return "insertps\t{%3, %2, %0|%0, %2, %3}";
3871     case 1:
3872       return "vinsertps\t{%3, %2, %1, %0|%0, %1, %2, %3}";
3873     default:
3874       gcc_unreachable ();
3875     }
3876 }
3877   [(set_attr "isa" "noavx,avx")
3878    (set_attr "type" "sselog")
3879    (set_attr "prefix_data16" "1,*")
3880    (set_attr "prefix_extra" "1")
3881    (set_attr "length_immediate" "1")
3882    (set_attr "prefix" "orig,vex")
3883    (set_attr "mode" "V4SF")])
3884
3885 (define_insn "sse4_1_insertps"
3886   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
3887         (unspec:V4SF [(match_operand:V4SF 2 "nonimmediate_operand" "xm,xm")
3888                       (match_operand:V4SF 1 "register_operand" "0,x")
3889                       (match_operand:SI 3 "const_0_to_255_operand" "n,n")]
3890                      UNSPEC_INSERTPS))]
3891   "TARGET_SSE4_1"
3892 {
3893   if (MEM_P (operands[2]))
3894     {
3895       unsigned count_s = INTVAL (operands[3]) >> 6;
3896       if (count_s)
3897         operands[3] = GEN_INT (INTVAL (operands[3]) & 0x3f);
3898       operands[2] = adjust_address_nv (operands[2], SFmode, count_s * 4);
3899     }
3900   switch (which_alternative)
3901     {
3902     case 0:
3903       return "insertps\t{%3, %2, %0|%0, %2, %3}";
3904     case 1:
3905       return "vinsertps\t{%3, %2, %1, %0|%0, %1, %2, %3}";
3906     default:
3907       gcc_unreachable ();
3908     }
3909 }
3910   [(set_attr "isa" "noavx,avx")
3911    (set_attr "type" "sselog")
3912    (set_attr "prefix_data16" "1,*")
3913    (set_attr "prefix_extra" "1")
3914    (set_attr "length_immediate" "1")
3915    (set_attr "prefix" "orig,vex")
3916    (set_attr "mode" "V4SF")])
3917
3918 (define_split
3919   [(set (match_operand:VI4F_128 0 "memory_operand" "")
3920         (vec_merge:VI4F_128
3921           (vec_duplicate:VI4F_128
3922             (match_operand:<ssescalarmode> 1 "nonmemory_operand" ""))
3923           (match_dup 0)
3924           (const_int 1)))]
3925   "TARGET_SSE && reload_completed"
3926   [(const_int 0)]
3927 {
3928   emit_move_insn (adjust_address (operands[0], <ssescalarmode>mode, 0),
3929                   operands[1]);
3930   DONE;
3931 })
3932
3933 (define_expand "vec_set<mode>"
3934   [(match_operand:V 0 "register_operand" "")
3935    (match_operand:<ssescalarmode> 1 "register_operand" "")
3936    (match_operand 2 "const_int_operand" "")]
3937   "TARGET_SSE"
3938 {
3939   ix86_expand_vector_set (false, operands[0], operands[1],
3940                           INTVAL (operands[2]));
3941   DONE;
3942 })
3943
3944 (define_insn_and_split "*vec_extractv4sf_0"
3945   [(set (match_operand:SF 0 "nonimmediate_operand" "=x,m,f,r")
3946         (vec_select:SF
3947           (match_operand:V4SF 1 "nonimmediate_operand" "xm,x,m,m")
3948           (parallel [(const_int 0)])))]
3949   "TARGET_SSE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3950   "#"
3951   "&& reload_completed"
3952   [(const_int 0)]
3953 {
3954   rtx op1 = operands[1];
3955   if (REG_P (op1))
3956     op1 = gen_rtx_REG (SFmode, REGNO (op1));
3957   else
3958     op1 = gen_lowpart (SFmode, op1);
3959   emit_move_insn (operands[0], op1);
3960   DONE;
3961 })
3962
3963 (define_insn_and_split "*sse4_1_extractps"
3964   [(set (match_operand:SF 0 "nonimmediate_operand" "=rm,x,x")
3965         (vec_select:SF
3966           (match_operand:V4SF 1 "register_operand" "x,0,x")
3967           (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n,n,n")])))]
3968   "TARGET_SSE4_1"
3969   "@
3970    %vextractps\t{%2, %1, %0|%0, %1, %2}
3971    #
3972    #"
3973   "&& reload_completed && SSE_REG_P (operands[0])"
3974   [(const_int 0)]
3975 {
3976   rtx dest = gen_rtx_REG (V4SFmode, REGNO (operands[0]));
3977   switch (INTVAL (operands[2]))
3978     {
3979     case 1:
3980     case 3:
3981       emit_insn (gen_sse_shufps_v4sf (dest, operands[1], operands[1],
3982                                       operands[2], operands[2],
3983                                       GEN_INT (INTVAL (operands[2]) + 4),
3984                                       GEN_INT (INTVAL (operands[2]) + 4)));
3985       break;
3986     case 2:
3987       emit_insn (gen_vec_interleave_highv4sf (dest, operands[1], operands[1]));
3988       break;
3989     default:
3990       /* 0 should be handled by the *vec_extractv4sf_0 pattern above.  */
3991       gcc_unreachable ();
3992     }
3993   DONE;
3994 }
3995   [(set_attr "isa" "*,noavx,avx")
3996    (set_attr "type" "sselog,*,*")
3997    (set_attr "prefix_data16" "1,*,*")
3998    (set_attr "prefix_extra" "1,*,*")
3999    (set_attr "length_immediate" "1,*,*")
4000    (set_attr "prefix" "maybe_vex,*,*")
4001    (set_attr "mode" "V4SF,*,*")])
4002
4003 (define_insn_and_split "*vec_extract_v4sf_mem"
4004   [(set (match_operand:SF 0 "register_operand" "=x,*r,f")
4005        (vec_select:SF
4006          (match_operand:V4SF 1 "memory_operand" "o,o,o")
4007          (parallel [(match_operand 2 "const_0_to_3_operand" "n,n,n")])))]
4008   "TARGET_SSE"
4009   "#"
4010   "&& reload_completed"
4011   [(const_int 0)]
4012 {
4013   int i = INTVAL (operands[2]);
4014
4015   emit_move_insn (operands[0], adjust_address (operands[1], SFmode, i*4));
4016   DONE;
4017 })
4018
4019 (define_expand "avx_vextractf128<mode>"
4020   [(match_operand:<ssehalfvecmode> 0 "nonimmediate_operand" "")
4021    (match_operand:V_256 1 "register_operand" "")
4022    (match_operand:SI 2 "const_0_to_1_operand" "")]
4023   "TARGET_AVX"
4024 {
4025   rtx (*insn)(rtx, rtx);
4026
4027   switch (INTVAL (operands[2]))
4028     {
4029     case 0:
4030       insn = gen_vec_extract_lo_<mode>;
4031       break;
4032     case 1:
4033       insn = gen_vec_extract_hi_<mode>;
4034       break;
4035     default:
4036       gcc_unreachable ();
4037     }
4038
4039   emit_insn (insn (operands[0], operands[1]));
4040   DONE;
4041 })
4042
4043 (define_insn_and_split "vec_extract_lo_<mode>"
4044   [(set (match_operand:<ssehalfvecmode> 0 "nonimmediate_operand" "=x,m")
4045         (vec_select:<ssehalfvecmode>
4046           (match_operand:VI8F_256 1 "nonimmediate_operand" "xm,x")
4047           (parallel [(const_int 0) (const_int