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