OSDN Git Service

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