OSDN Git Service

2009-05-06 H.J. Lu <hongjiu.lu@intel.com>
[pf3gnuchains/gcc-fork.git] / 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 ;; Mapping from float mode to required SSE level
68 (define_mode_attr sse [(SF "sse") (DF "sse2") (V4SF "sse") (V2DF "sse2")])
69
70 ;; Mapping from integer vector mode to mnemonic suffix
71 (define_mode_attr ssevecsize [(V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")])
72
73 ;; Mapping of the sse5 suffix
74 (define_mode_attr ssemodesuffixf4 [(SF "ss") (DF "sd")
75                                    (V4SF "ps") (V2DF "pd")])
76 (define_mode_attr ssemodesuffixf2s [(SF "ss") (DF "sd")
77                                     (V4SF "ss") (V2DF "sd")])
78 (define_mode_attr ssemodesuffixf2c [(V4SF "s") (V2DF "d")])
79
80 ;; Mapping of the max integer size for sse5 rotate immediate constraint
81 (define_mode_attr sserotatemax [(V16QI "7") (V8HI "15") (V4SI "31") (V2DI "63")])
82
83 ;; Mapping of vector modes back to the scalar modes
84 (define_mode_attr ssescalarmode [(V4SF "SF") (V2DF "DF")
85                                  (V16QI "QI") (V8HI "HI")
86                                  (V4SI "SI") (V2DI "DI")])
87
88 ;; Mapping of vector modes to a vector mode of double size
89 (define_mode_attr ssedoublesizemode [(V2DF "V4DF") (V2DI "V4DI")
90                                      (V4SF "V8SF") (V4SI "V8SI")])
91
92 ;; Number of scalar elements in each vector type
93 (define_mode_attr ssescalarnum [(V4SF "4") (V2DF "2")
94                                 (V16QI "16") (V8HI "8")
95                                 (V4SI "4") (V2DI "2")])
96
97 ;; Mapping for AVX
98 (define_mode_attr avxvecmode
99   [(V16QI "TI") (V8HI "TI") (V4SI "TI") (V2DI "TI") (V4SF "V4SF")
100    (V2DF "V2DF") (V32QI "OI") (V16HI "OI") (V8SI "OI") (V4DI "OI")
101    (V8SF "V8SF") (V4DF "V4DF")])
102 (define_mode_attr avxvecpsmode
103   [(V16QI "V4SF") (V8HI "V4SF") (V4SI "V4SF") (V2DI "V4SF")
104    (V32QI "V8SF") (V16HI "V8SF") (V8SI "V8SF") (V4DI "V8SF")])
105 (define_mode_attr avxhalfvecmode
106   [(V4SF "V2SF") (V32QI "V16QI")  (V16HI "V8HI") (V8SI "V4SI")
107    (V4DI "V2DI") (V8SF "V4SF") (V4DF "V2DF")])
108 (define_mode_attr avxscalarmode
109   [(V16QI "QI") (V8HI "HI") (V4SI "SI") (V4SF "SF") (V2DF "DF")
110    (V8SF "SF") (V4DF "DF")])
111 (define_mode_attr avxcvtvecmode
112   [(V4SF "V4SI") (V8SF "V8SI") (V4SI "V4SF") (V8SI "V8SF")])
113 (define_mode_attr avxpermvecmode
114   [(V2DF "V2DI") (V4SF "V4SI") (V4DF "V4DI") (V8SF "V8SI")])
115 (define_mode_attr avxmodesuffixf2c
116   [(V4SF "s") (V2DF "d") (V8SF "s") (V4DF "d")])
117 (define_mode_attr avxmodesuffixp
118  [(V2DF "pd") (V4SI "si") (V4SF "ps") (V8SF "ps") (V8SI "si")
119   (V4DF "pd")])
120 (define_mode_attr avxmodesuffix
121   [(V16QI "") (V32QI "256") (V4SI "") (V4SF "") (V2DF "")
122    (V8SI "256") (V8SF "256") (V4DF "256")])
123
124 ;; Mapping of immediate bits for blend instructions
125 (define_mode_attr blendbits
126   [(V8SF "255") (V4SF "15") (V4DF "15") (V2DF "3")])
127
128 ;; Mapping of immediate bits for vpermil instructions
129 (define_mode_attr vpermilbits
130   [(V8SF "255") (V4SF "255") (V4DF "15") (V2DF "3")])
131
132 ;; Mapping of immediate bits for pinsr instructions
133 (define_mode_attr pinsrbits [(V16QI "32768") (V8HI "128") (V4SI "8")])
134
135 ;; Patterns whose name begins with "sse{,2,3}_" are invoked by intrinsics.
136
137 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
138 ;;
139 ;; Move patterns
140 ;;
141 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
142
143 (define_expand "mov<mode>"
144   [(set (match_operand:AVX256MODE 0 "nonimmediate_operand" "")
145         (match_operand:AVX256MODE 1 "nonimmediate_operand" ""))]
146   "TARGET_AVX"
147 {
148   ix86_expand_vector_move (<MODE>mode, operands);
149   DONE;
150 })
151
152 (define_insn "*avx_mov<mode>_internal"
153   [(set (match_operand:AVXMODE 0 "nonimmediate_operand" "=x,x ,m")
154         (match_operand:AVXMODE 1 "nonimmediate_or_sse_const_operand"  "C ,xm,x"))]
155   "TARGET_AVX
156    && (register_operand (operands[0], <MODE>mode)
157        || register_operand (operands[1], <MODE>mode))"
158 {
159   switch (which_alternative)
160     {
161     case 0:
162       return standard_sse_constant_opcode (insn, operands[1]);
163     case 1:
164     case 2:
165       switch (get_attr_mode (insn))
166         {
167         case MODE_V8SF:
168         case MODE_V4SF:
169           return "vmovaps\t{%1, %0|%0, %1}";
170         case MODE_V4DF:
171         case MODE_V2DF:
172           return "vmovapd\t{%1, %0|%0, %1}";
173         default:
174           return "vmovdqa\t{%1, %0|%0, %1}";
175         }
176     default:
177       gcc_unreachable ();
178     }
179 }
180   [(set_attr "type" "sselog1,ssemov,ssemov")
181    (set_attr "prefix" "vex")
182    (set_attr "mode" "<avxvecmode>")])
183
184 ;; All of these patterns are enabled for SSE1 as well as SSE2.
185 ;; This is essential for maintaining stable calling conventions.
186
187 (define_expand "mov<mode>"
188   [(set (match_operand:SSEMODE 0 "nonimmediate_operand" "")
189         (match_operand:SSEMODE 1 "nonimmediate_operand" ""))]
190   "TARGET_SSE"
191 {
192   ix86_expand_vector_move (<MODE>mode, operands);
193   DONE;
194 })
195
196 (define_insn "*mov<mode>_internal"
197   [(set (match_operand:SSEMODE 0 "nonimmediate_operand" "=x,x ,m")
198         (match_operand:SSEMODE 1 "nonimmediate_or_sse_const_operand"  "C ,xm,x"))]
199   "TARGET_SSE
200    && (register_operand (operands[0], <MODE>mode)
201        || register_operand (operands[1], <MODE>mode))"
202 {
203   switch (which_alternative)
204     {
205     case 0:
206       return standard_sse_constant_opcode (insn, operands[1]);
207     case 1:
208     case 2:
209       switch (get_attr_mode (insn))
210         {
211         case MODE_V4SF:
212           return "movaps\t{%1, %0|%0, %1}";
213         case MODE_V2DF:
214           return "movapd\t{%1, %0|%0, %1}";
215         default:
216           return "movdqa\t{%1, %0|%0, %1}";
217         }
218     default:
219       gcc_unreachable ();
220     }
221 }
222   [(set_attr "type" "sselog1,ssemov,ssemov")
223    (set (attr "mode")
224         (cond [(ior (ior (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
225                          (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
226                     (and (eq_attr "alternative" "2")
227                          (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
228                              (const_int 0))))
229                  (const_string "V4SF")
230                (eq (const_string "<MODE>mode") (const_string "V4SFmode"))
231                  (const_string "V4SF")
232                (eq (const_string "<MODE>mode") (const_string "V2DFmode"))
233                  (const_string "V2DF")
234               ]
235           (const_string "TI")))])
236
237 ;; Move a DI from a 32-bit register pair (e.g. %edx:%eax) to an xmm.
238 ;; We'd rather avoid this entirely; if the 32-bit reg pair was loaded
239 ;; from memory, we'd prefer to load the memory directly into the %xmm
240 ;; register.  To facilitate this happy circumstance, this pattern won't
241 ;; split until after register allocation.  If the 64-bit value didn't
242 ;; come from memory, this is the best we can do.  This is much better
243 ;; than storing %edx:%eax into a stack temporary and loading an %xmm
244 ;; from there.
245
246 (define_insn_and_split "movdi_to_sse"
247   [(parallel
248     [(set (match_operand:V4SI 0 "register_operand" "=?x,x")
249           (subreg:V4SI (match_operand:DI 1 "nonimmediate_operand" "r,m") 0))
250      (clobber (match_scratch:V4SI 2 "=&x,X"))])]
251   "!TARGET_64BIT && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES"
252   "#"
253   "&& reload_completed"
254   [(const_int 0)]
255 {
256  if (register_operand (operands[1], DImode))
257    {
258       /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
259          Assemble the 64-bit DImode value in an xmm register.  */
260       emit_insn (gen_sse2_loadld (operands[0], CONST0_RTX (V4SImode),
261                                   gen_rtx_SUBREG (SImode, operands[1], 0)));
262       emit_insn (gen_sse2_loadld (operands[2], CONST0_RTX (V4SImode),
263                                   gen_rtx_SUBREG (SImode, operands[1], 4)));
264       emit_insn (gen_sse2_punpckldq (operands[0], operands[0], operands[2]));
265     }
266  else if (memory_operand (operands[1], DImode))
267       emit_insn (gen_vec_concatv2di (gen_lowpart (V2DImode, operands[0]), operands[1], const0_rtx));
268  else
269       gcc_unreachable ();
270 })
271
272 (define_split
273   [(set (match_operand:V4SF 0 "register_operand" "")
274         (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
275   "TARGET_SSE && reload_completed"
276   [(set (match_dup 0)
277         (vec_merge:V4SF
278           (vec_duplicate:V4SF (match_dup 1))
279           (match_dup 2)
280           (const_int 1)))]
281 {
282   operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
283   operands[2] = CONST0_RTX (V4SFmode);
284 })
285
286 (define_split
287   [(set (match_operand:V2DF 0 "register_operand" "")
288         (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
289   "TARGET_SSE2 && reload_completed"
290   [(set (match_dup 0) (vec_concat:V2DF (match_dup 1) (match_dup 2)))]
291 {
292   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
293   operands[2] = CONST0_RTX (DFmode);
294 })
295
296 (define_expand "push<mode>1"
297   [(match_operand:AVX256MODE 0 "register_operand" "")]
298   "TARGET_AVX"
299 {
300   ix86_expand_push (<MODE>mode, operands[0]);
301   DONE;
302 })
303
304 (define_expand "push<mode>1"
305   [(match_operand:SSEMODE 0 "register_operand" "")]
306   "TARGET_SSE"
307 {
308   ix86_expand_push (<MODE>mode, operands[0]);
309   DONE;
310 })
311
312 (define_expand "movmisalign<mode>"
313   [(set (match_operand:AVX256MODE 0 "nonimmediate_operand" "")
314         (match_operand:AVX256MODE 1 "nonimmediate_operand" ""))]
315   "TARGET_AVX"
316 {
317   ix86_expand_vector_move_misalign (<MODE>mode, operands);
318   DONE;
319 })
320
321 (define_expand "movmisalign<mode>"
322   [(set (match_operand:SSEMODE 0 "nonimmediate_operand" "")
323         (match_operand:SSEMODE 1 "nonimmediate_operand" ""))]
324   "TARGET_SSE"
325 {
326   ix86_expand_vector_move_misalign (<MODE>mode, operands);
327   DONE;
328 })
329
330 (define_insn "avx_movup<avxmodesuffixf2c><avxmodesuffix>"
331   [(set (match_operand:AVXMODEF2P 0 "nonimmediate_operand" "=x,m")
332         (unspec:AVXMODEF2P
333           [(match_operand:AVXMODEF2P 1 "nonimmediate_operand" "xm,x")]
334           UNSPEC_MOVU))]
335   "AVX_VEC_FLOAT_MODE_P (<MODE>mode)
336    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
337   "vmovup<avxmodesuffixf2c>\t{%1, %0|%0, %1}"
338   [(set_attr "type" "ssemov")
339    (set_attr "movu" "1")
340    (set_attr "prefix" "vex")
341    (set_attr "mode" "<MODE>")])
342
343 (define_insn "sse2_movq128"
344   [(set (match_operand:V2DI 0 "register_operand" "=x")
345         (vec_concat:V2DI
346           (vec_select:DI
347             (match_operand:V2DI 1 "nonimmediate_operand" "xm")
348             (parallel [(const_int 0)]))
349           (const_int 0)))]
350   "TARGET_SSE2"
351   "%vmovq\t{%1, %0|%0, %1}"
352   [(set_attr "type" "ssemov")
353    (set_attr "prefix" "maybe_vex")
354    (set_attr "mode" "TI")])
355
356 (define_insn "<sse>_movup<ssemodesuffixf2c>"
357   [(set (match_operand:SSEMODEF2P 0 "nonimmediate_operand" "=x,m")
358         (unspec:SSEMODEF2P
359           [(match_operand:SSEMODEF2P 1 "nonimmediate_operand" "xm,x")]
360           UNSPEC_MOVU))]
361   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)
362    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
363   "movup<ssemodesuffixf2c>\t{%1, %0|%0, %1}"
364   [(set_attr "type" "ssemov")
365    (set_attr "movu" "1")
366    (set_attr "mode" "<MODE>")])
367
368 (define_insn "avx_movdqu<avxmodesuffix>"
369   [(set (match_operand:AVXMODEQI 0 "nonimmediate_operand" "=x,m")
370         (unspec:AVXMODEQI
371           [(match_operand:AVXMODEQI 1 "nonimmediate_operand" "xm,x")]
372           UNSPEC_MOVU))]
373   "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
374   "vmovdqu\t{%1, %0|%0, %1}"
375   [(set_attr "type" "ssemov")
376    (set_attr "movu" "1")
377    (set_attr "prefix" "vex")
378    (set_attr "mode" "<avxvecmode>")])
379
380 (define_insn "sse2_movdqu"
381   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
382         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
383                       UNSPEC_MOVU))]
384   "TARGET_SSE2 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
385   "movdqu\t{%1, %0|%0, %1}"
386   [(set_attr "type" "ssemov")
387    (set_attr "movu" "1")
388    (set_attr "prefix_data16" "1")
389    (set_attr "mode" "TI")])
390
391 (define_insn "avx_movnt<mode>"
392   [(set (match_operand:AVXMODEF2P 0 "memory_operand" "=m")
393         (unspec:AVXMODEF2P
394           [(match_operand:AVXMODEF2P 1 "register_operand" "x")]
395           UNSPEC_MOVNT))]
396   "AVX_VEC_FLOAT_MODE_P (<MODE>mode)"
397   "vmovntp<avxmodesuffixf2c>\t{%1, %0|%0, %1}"
398   [(set_attr "type" "ssemov")
399    (set_attr "prefix" "vex")
400    (set_attr "mode" "<MODE>")])
401
402 (define_insn "<sse>_movnt<mode>"
403   [(set (match_operand:SSEMODEF2P 0 "memory_operand" "=m")
404         (unspec:SSEMODEF2P
405           [(match_operand:SSEMODEF2P 1 "register_operand" "x")]
406           UNSPEC_MOVNT))]
407   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
408   "movntp<ssemodesuffixf2c>\t{%1, %0|%0, %1}"
409   [(set_attr "type" "ssemov")
410    (set_attr "mode" "<MODE>")])
411
412 (define_insn "avx_movnt<mode>"
413   [(set (match_operand:AVXMODEDI 0 "memory_operand" "=m")
414         (unspec:AVXMODEDI
415           [(match_operand:AVXMODEDI 1 "register_operand" "x")]
416           UNSPEC_MOVNT))]
417   "TARGET_AVX"
418   "vmovntdq\t{%1, %0|%0, %1}"
419   [(set_attr "type" "ssecvt")
420    (set_attr "prefix" "vex")
421    (set_attr "mode" "<avxvecmode>")])
422
423 (define_insn "sse2_movntv2di"
424   [(set (match_operand:V2DI 0 "memory_operand" "=m")
425         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
426                      UNSPEC_MOVNT))]
427   "TARGET_SSE2"
428   "movntdq\t{%1, %0|%0, %1}"
429   [(set_attr "type" "ssemov")
430    (set_attr "prefix_data16" "1")
431    (set_attr "mode" "TI")])
432
433 (define_insn "sse2_movntsi"
434   [(set (match_operand:SI 0 "memory_operand" "=m")
435         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
436                    UNSPEC_MOVNT))]
437   "TARGET_SSE2"
438   "movnti\t{%1, %0|%0, %1}"
439   [(set_attr "type" "ssemov")
440    (set_attr "mode" "V2DF")])
441
442 (define_insn "avx_lddqu<avxmodesuffix>"
443   [(set (match_operand:AVXMODEQI 0 "register_operand" "=x")
444         (unspec:AVXMODEQI
445           [(match_operand:AVXMODEQI 1 "memory_operand" "m")]
446           UNSPEC_LDDQU))]
447   "TARGET_AVX"
448   "vlddqu\t{%1, %0|%0, %1}"
449   [(set_attr "type" "ssecvt")
450    (set_attr "movu" "1")
451    (set_attr "prefix" "vex")
452    (set_attr "mode" "<avxvecmode>")])
453
454 (define_insn "sse3_lddqu"
455   [(set (match_operand:V16QI 0 "register_operand" "=x")
456         (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
457                       UNSPEC_LDDQU))]
458   "TARGET_SSE3"
459   "lddqu\t{%1, %0|%0, %1}"
460   [(set_attr "type" "ssemov")
461    (set_attr "movu" "1")
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 "atom_sse_attr" "rcp")
769    (set_attr "prefix" "maybe_vex")
770    (set_attr "mode" "V4SF")])
771
772 (define_insn "*avx_vmrcpv4sf2"
773   [(set (match_operand:V4SF 0 "register_operand" "=x")
774         (vec_merge:V4SF
775           (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
776                        UNSPEC_RCP)
777           (match_operand:V4SF 2 "register_operand" "x")
778           (const_int 1)))]
779   "TARGET_AVX"
780   "vrcpss\t{%1, %2, %0|%0, %2, %1}"
781   [(set_attr "type" "sse")
782    (set_attr "prefix" "vex")
783    (set_attr "mode" "SF")])
784
785 (define_insn "sse_vmrcpv4sf2"
786   [(set (match_operand:V4SF 0 "register_operand" "=x")
787         (vec_merge:V4SF
788           (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
789                        UNSPEC_RCP)
790           (match_operand:V4SF 2 "register_operand" "0")
791           (const_int 1)))]
792   "TARGET_SSE"
793   "rcpss\t{%1, %0|%0, %1}"
794   [(set_attr "type" "sse")
795    (set_attr "atom_sse_attr" "rcp")
796    (set_attr "mode" "SF")])
797
798 (define_expand "sqrtv8sf2"
799   [(set (match_operand:V8SF 0 "register_operand" "")
800         (sqrt:V8SF (match_operand:V8SF 1 "nonimmediate_operand" "")))]
801   "TARGET_AVX"
802 {
803   if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
804       && flag_finite_math_only && !flag_trapping_math
805       && flag_unsafe_math_optimizations)
806     {
807       ix86_emit_swsqrtsf (operands[0], operands[1], V8SFmode, 0);
808       DONE;
809     }
810 })
811
812 (define_insn "avx_sqrtv8sf2"
813   [(set (match_operand:V8SF 0 "register_operand" "=x")
814         (sqrt:V8SF (match_operand:V8SF 1 "nonimmediate_operand" "xm")))]
815   "TARGET_AVX"
816   "vsqrtps\t{%1, %0|%0, %1}"
817   [(set_attr "type" "sse")
818    (set_attr "prefix" "vex")
819    (set_attr "mode" "V8SF")])
820
821 (define_expand "sqrtv4sf2"
822   [(set (match_operand:V4SF 0 "register_operand" "")
823         (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "")))]
824   "TARGET_SSE"
825 {
826   if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
827       && flag_finite_math_only && !flag_trapping_math
828       && flag_unsafe_math_optimizations)
829     {
830       ix86_emit_swsqrtsf (operands[0], operands[1], V4SFmode, 0);
831       DONE;
832     }
833 })
834
835 (define_insn "sse_sqrtv4sf2"
836   [(set (match_operand:V4SF 0 "register_operand" "=x")
837         (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
838   "TARGET_SSE"
839   "%vsqrtps\t{%1, %0|%0, %1}"
840   [(set_attr "type" "sse")
841    (set_attr "atom_sse_attr" "sqrt")
842    (set_attr "prefix" "maybe_vex")
843    (set_attr "mode" "V4SF")])
844
845 (define_insn "sqrtv4df2"
846   [(set (match_operand:V4DF 0 "register_operand" "=x")
847         (sqrt:V4DF (match_operand:V4DF 1 "nonimmediate_operand" "xm")))]
848   "TARGET_AVX"
849   "vsqrtpd\t{%1, %0|%0, %1}"
850   [(set_attr "type" "sse")
851    (set_attr "prefix" "vex")
852    (set_attr "mode" "V4DF")])
853
854 (define_insn "sqrtv2df2"
855   [(set (match_operand:V2DF 0 "register_operand" "=x")
856         (sqrt:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
857   "TARGET_SSE2"
858   "%vsqrtpd\t{%1, %0|%0, %1}"
859   [(set_attr "type" "sse")
860    (set_attr "prefix" "maybe_vex")
861    (set_attr "mode" "V2DF")])
862
863 (define_insn "*avx_vmsqrt<mode>2"
864   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
865         (vec_merge:SSEMODEF2P
866           (sqrt:SSEMODEF2P
867             (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "xm"))
868           (match_operand:SSEMODEF2P 2 "register_operand" "x")
869           (const_int 1)))]
870   "AVX_VEC_FLOAT_MODE_P (<MODE>mode)"
871   "vsqrts<ssemodesuffixf2c>\t{%1, %2, %0|%0, %2, %1}"
872   [(set_attr "type" "sse")
873    (set_attr "prefix" "vex")
874    (set_attr "mode" "<ssescalarmode>")])
875
876 (define_insn "<sse>_vmsqrt<mode>2"
877   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
878         (vec_merge:SSEMODEF2P
879           (sqrt:SSEMODEF2P
880             (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "xm"))
881           (match_operand:SSEMODEF2P 2 "register_operand" "0")
882           (const_int 1)))]
883   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
884   "sqrts<ssemodesuffixf2c>\t{%1, %0|%0, %1}"
885   [(set_attr "type" "sse")
886    (set_attr "atom_sse_attr" "sqrt")
887    (set_attr "mode" "<ssescalarmode>")])
888
889 (define_expand "rsqrtv8sf2"
890   [(set (match_operand:V8SF 0 "register_operand" "")
891         (unspec:V8SF
892           [(match_operand:V8SF 1 "nonimmediate_operand" "")] UNSPEC_RSQRT))]
893   "TARGET_AVX && TARGET_SSE_MATH"
894 {
895   ix86_emit_swsqrtsf (operands[0], operands[1], V8SFmode, 1);
896   DONE;
897 })
898
899 (define_insn "avx_rsqrtv8sf2"
900   [(set (match_operand:V8SF 0 "register_operand" "=x")
901         (unspec:V8SF
902           [(match_operand:V8SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
903   "TARGET_AVX"
904   "vrsqrtps\t{%1, %0|%0, %1}"
905   [(set_attr "type" "sse")
906    (set_attr "prefix" "vex")
907    (set_attr "mode" "V8SF")])
908
909 (define_expand "rsqrtv4sf2"
910   [(set (match_operand:V4SF 0 "register_operand" "")
911         (unspec:V4SF
912           [(match_operand:V4SF 1 "nonimmediate_operand" "")] UNSPEC_RSQRT))]
913   "TARGET_SSE_MATH"
914 {
915   ix86_emit_swsqrtsf (operands[0], operands[1], V4SFmode, 1);
916   DONE;
917 })
918
919 (define_insn "sse_rsqrtv4sf2"
920   [(set (match_operand:V4SF 0 "register_operand" "=x")
921         (unspec:V4SF
922           [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
923   "TARGET_SSE"
924   "%vrsqrtps\t{%1, %0|%0, %1}"
925   [(set_attr "type" "sse")
926    (set_attr "prefix" "maybe_vex")
927    (set_attr "mode" "V4SF")])
928
929 (define_insn "*avx_vmrsqrtv4sf2"
930   [(set (match_operand:V4SF 0 "register_operand" "=x")
931         (vec_merge:V4SF
932           (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
933                        UNSPEC_RSQRT)
934           (match_operand:V4SF 2 "register_operand" "x")
935           (const_int 1)))]
936   "TARGET_AVX"
937   "vrsqrtss\t{%1, %2, %0|%0, %2, %1}"
938   [(set_attr "type" "sse")
939    (set_attr "prefix" "vex")
940    (set_attr "mode" "SF")])
941
942 (define_insn "sse_vmrsqrtv4sf2"
943   [(set (match_operand:V4SF 0 "register_operand" "=x")
944         (vec_merge:V4SF
945           (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
946                        UNSPEC_RSQRT)
947           (match_operand:V4SF 2 "register_operand" "0")
948           (const_int 1)))]
949   "TARGET_SSE"
950   "rsqrtss\t{%1, %0|%0, %1}"
951   [(set_attr "type" "sse")
952    (set_attr "mode" "SF")])
953
954 ;; ??? For !flag_finite_math_only, the representation with SMIN/SMAX
955 ;; isn't really correct, as those rtl operators aren't defined when
956 ;; applied to NaNs.  Hopefully the optimizers won't get too smart on us.
957
958 (define_expand "<code><mode>3"
959   [(set (match_operand:AVX256MODEF2P 0 "register_operand" "")
960         (smaxmin:AVX256MODEF2P
961           (match_operand:AVX256MODEF2P 1 "nonimmediate_operand" "")
962           (match_operand:AVX256MODEF2P 2 "nonimmediate_operand" "")))]
963   "AVX256_VEC_FLOAT_MODE_P (<MODE>mode)"
964 {
965   if (!flag_finite_math_only)
966     operands[1] = force_reg (<MODE>mode, operands[1]);
967   ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);
968 })
969
970 (define_expand "<code><mode>3"
971   [(set (match_operand:SSEMODEF2P 0 "register_operand" "")
972         (smaxmin:SSEMODEF2P
973           (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "")
974           (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "")))]
975   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
976 {
977   if (!flag_finite_math_only)
978     operands[1] = force_reg (<MODE>mode, operands[1]);
979   ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);
980 })
981
982 (define_insn "*avx_<code><mode>3_finite"
983   [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x")
984         (smaxmin:AVXMODEF2P
985           (match_operand:AVXMODEF2P 1 "nonimmediate_operand" "%x")
986           (match_operand:AVXMODEF2P 2 "nonimmediate_operand" "xm")))]
987   "AVX_VEC_FLOAT_MODE_P (<MODE>mode) && flag_finite_math_only
988    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
989   "v<maxminfprefix>p<avxmodesuffixf2c>\t{%2, %1, %0|%0, %1, %2}"
990   [(set_attr "type" "sseadd")
991    (set_attr "prefix" "vex")
992    (set_attr "mode" "<MODE>")])
993
994 (define_insn "*<code><mode>3_finite"
995   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
996         (smaxmin:SSEMODEF2P
997           (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "%0")
998           (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")))]
999   "SSE_VEC_FLOAT_MODE_P (<MODE>mode) && flag_finite_math_only
1000    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
1001   "<maxminfprefix>p<ssemodesuffixf2c>\t{%2, %0|%0, %2}"
1002   [(set_attr "type" "sseadd")
1003    (set_attr "mode" "<MODE>")])
1004
1005 (define_insn "*avx_<code><mode>3"
1006   [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x")
1007         (smaxmin:AVXMODEF2P
1008           (match_operand:AVXMODEF2P 1 "nonimmediate_operand" "%x")
1009           (match_operand:AVXMODEF2P 2 "nonimmediate_operand" "xm")))]
1010   "AVX_VEC_FLOAT_MODE_P (<MODE>mode)"
1011   "v<maxminfprefix>p<avxmodesuffixf2c>\t{%2, %1, %0|%0, %1, %2}"
1012   [(set_attr "type" "sseadd")
1013    (set_attr "prefix" "vex")
1014    (set_attr "mode" "<avxvecmode>")])
1015
1016 (define_insn "*<code><mode>3"
1017   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
1018         (smaxmin:SSEMODEF2P
1019           (match_operand:SSEMODEF2P 1 "register_operand" "0")
1020           (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")))]
1021   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
1022   "<maxminfprefix>p<ssemodesuffixf2c>\t{%2, %0|%0, %2}"
1023   [(set_attr "type" "sseadd")
1024    (set_attr "mode" "<MODE>")])
1025
1026 (define_insn "*avx_vm<code><mode>3"
1027   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
1028         (vec_merge:SSEMODEF2P
1029           (smaxmin:SSEMODEF2P
1030             (match_operand:SSEMODEF2P 1 "register_operand" "x")
1031             (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm"))
1032          (match_dup 1)
1033          (const_int 1)))]
1034   "AVX128_VEC_FLOAT_MODE_P (<MODE>mode)"
1035   "v<maxminfprefix>s<ssemodesuffixf2c>\t{%2, %1, %0|%0, %1, %2}"
1036   [(set_attr "type" "sse")
1037    (set_attr "prefix" "vex")
1038    (set_attr "mode" "<ssescalarmode>")])
1039
1040 (define_insn "<sse>_vm<code><mode>3"
1041   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
1042         (vec_merge:SSEMODEF2P
1043           (smaxmin:SSEMODEF2P
1044             (match_operand:SSEMODEF2P 1 "register_operand" "0")
1045             (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm"))
1046          (match_dup 1)
1047          (const_int 1)))]
1048   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
1049   "<maxminfprefix>s<ssemodesuffixf2c>\t{%2, %0|%0, %2}"
1050   [(set_attr "type" "sseadd")
1051    (set_attr "mode" "<ssescalarmode>")])
1052
1053 ;; These versions of the min/max patterns implement exactly the operations
1054 ;;   min = (op1 < op2 ? op1 : op2)
1055 ;;   max = (!(op1 < op2) ? op1 : op2)
1056 ;; Their operands are not commutative, and thus they may be used in the
1057 ;; presence of -0.0 and NaN.
1058
1059 (define_insn "*avx_ieee_smin<mode>3"
1060   [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x")
1061         (unspec:AVXMODEF2P
1062           [(match_operand:AVXMODEF2P 1 "register_operand" "x")
1063            (match_operand:AVXMODEF2P 2 "nonimmediate_operand" "xm")]
1064          UNSPEC_IEEE_MIN))]
1065   "AVX_VEC_FLOAT_MODE_P (<MODE>mode)"
1066   "vminp<avxmodesuffixf2c>\t{%2, %1, %0|%0, %1, %2}"
1067   [(set_attr "type" "sseadd")
1068    (set_attr "prefix" "vex")
1069    (set_attr "mode" "<avxvecmode>")])
1070
1071 (define_insn "*avx_ieee_smax<mode>3"
1072   [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x")
1073         (unspec:AVXMODEF2P
1074           [(match_operand:AVXMODEF2P 1 "register_operand" "x")
1075            (match_operand:AVXMODEF2P 2 "nonimmediate_operand" "xm")]
1076          UNSPEC_IEEE_MAX))]
1077   "AVX_VEC_FLOAT_MODE_P (<MODE>mode)"
1078   "vmaxp<avxmodesuffixf2c>\t{%2, %1, %0|%0, %1, %2}"
1079   [(set_attr "type" "sseadd")
1080    (set_attr "prefix" "vex")
1081    (set_attr "mode" "<avxvecmode>")])
1082
1083 (define_insn "*ieee_smin<mode>3"
1084   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
1085         (unspec:SSEMODEF2P
1086           [(match_operand:SSEMODEF2P 1 "register_operand" "0")
1087            (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")]
1088          UNSPEC_IEEE_MIN))]
1089   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
1090   "minp<ssemodesuffixf2c>\t{%2, %0|%0, %2}"
1091   [(set_attr "type" "sseadd")
1092    (set_attr "mode" "<MODE>")])
1093
1094 (define_insn "*ieee_smax<mode>3"
1095   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
1096         (unspec:SSEMODEF2P
1097           [(match_operand:SSEMODEF2P 1 "register_operand" "0")
1098            (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")]
1099          UNSPEC_IEEE_MAX))]
1100   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
1101   "maxp<ssemodesuffixf2c>\t{%2, %0|%0, %2}"
1102   [(set_attr "type" "sseadd")
1103    (set_attr "mode" "<MODE>")])
1104
1105 (define_insn "avx_addsubv8sf3"
1106   [(set (match_operand:V8SF 0 "register_operand" "=x")
1107         (vec_merge:V8SF
1108           (plus:V8SF
1109             (match_operand:V8SF 1 "register_operand" "x")
1110             (match_operand:V8SF 2 "nonimmediate_operand" "xm"))
1111           (minus:V8SF (match_dup 1) (match_dup 2))
1112           (const_int 170)))]
1113   "TARGET_AVX"
1114   "vaddsubps\t{%2, %1, %0|%0, %1, %2}"
1115   [(set_attr "type" "sseadd")
1116    (set_attr "prefix" "vex")
1117    (set_attr "mode" "V8SF")])
1118
1119 (define_insn "avx_addsubv4df3"
1120   [(set (match_operand:V4DF 0 "register_operand" "=x")
1121         (vec_merge:V4DF
1122           (plus:V4DF
1123             (match_operand:V4DF 1 "register_operand" "x")
1124             (match_operand:V4DF 2 "nonimmediate_operand" "xm"))
1125           (minus:V4DF (match_dup 1) (match_dup 2))
1126           (const_int 10)))]
1127   "TARGET_AVX"
1128   "vaddsubpd\t{%2, %1, %0|%0, %1, %2}"
1129   [(set_attr "type" "sseadd")
1130    (set_attr "prefix" "vex")
1131    (set_attr "mode" "V4DF")])
1132
1133 (define_insn "*avx_addsubv4sf3"
1134   [(set (match_operand:V4SF 0 "register_operand" "=x")
1135         (vec_merge:V4SF
1136           (plus:V4SF
1137             (match_operand:V4SF 1 "register_operand" "x")
1138             (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
1139           (minus:V4SF (match_dup 1) (match_dup 2))
1140           (const_int 10)))]
1141   "TARGET_AVX"
1142   "vaddsubps\t{%2, %1, %0|%0, %1, %2}"
1143   [(set_attr "type" "sseadd")
1144    (set_attr "prefix" "vex")
1145    (set_attr "mode" "V4SF")])
1146
1147 (define_insn "sse3_addsubv4sf3"
1148   [(set (match_operand:V4SF 0 "register_operand" "=x")
1149         (vec_merge:V4SF
1150           (plus:V4SF
1151             (match_operand:V4SF 1 "register_operand" "0")
1152             (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
1153           (minus:V4SF (match_dup 1) (match_dup 2))
1154           (const_int 10)))]
1155   "TARGET_SSE3"
1156   "addsubps\t{%2, %0|%0, %2}"
1157   [(set_attr "type" "sseadd")
1158    (set_attr "prefix_rep" "1")
1159    (set_attr "mode" "V4SF")])
1160
1161 (define_insn "*avx_addsubv2df3"
1162   [(set (match_operand:V2DF 0 "register_operand" "=x")
1163         (vec_merge:V2DF
1164           (plus:V2DF
1165             (match_operand:V2DF 1 "register_operand" "x")
1166             (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
1167           (minus:V2DF (match_dup 1) (match_dup 2))
1168           (const_int 2)))]
1169   "TARGET_AVX"
1170   "vaddsubpd\t{%2, %1, %0|%0, %1, %2}"
1171   [(set_attr "type" "sseadd")
1172    (set_attr "prefix" "vex")
1173    (set_attr "mode" "V2DF")])
1174
1175 (define_insn "sse3_addsubv2df3"
1176   [(set (match_operand:V2DF 0 "register_operand" "=x")
1177         (vec_merge:V2DF
1178           (plus:V2DF
1179             (match_operand:V2DF 1 "register_operand" "0")
1180             (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
1181           (minus:V2DF (match_dup 1) (match_dup 2))
1182           (const_int 2)))]
1183   "TARGET_SSE3"
1184   "addsubpd\t{%2, %0|%0, %2}"
1185   [(set_attr "type" "sseadd")
1186    (set_attr "atom_unit" "complex")
1187    (set_attr "mode" "V2DF")])
1188
1189 (define_insn "avx_h<plusminus_insn>v4df3"
1190   [(set (match_operand:V4DF 0 "register_operand" "=x")
1191         (vec_concat:V4DF
1192           (vec_concat:V2DF
1193             (plusminus:DF
1194               (vec_select:DF
1195                 (match_operand:V4DF 1 "register_operand" "x")
1196                 (parallel [(const_int 0)]))
1197               (vec_select:DF (match_dup 1) (parallel [(const_int 1)])))
1198             (plusminus:DF
1199               (vec_select:DF (match_dup 1) (parallel [(const_int 2)]))
1200               (vec_select:DF (match_dup 1) (parallel [(const_int 3)]))))
1201           (vec_concat:V2DF
1202             (plusminus:DF
1203               (vec_select:DF
1204                 (match_operand:V4DF 2 "nonimmediate_operand" "xm")
1205                 (parallel [(const_int 0)]))
1206               (vec_select:DF (match_dup 2) (parallel [(const_int 1)])))
1207             (plusminus:DF
1208               (vec_select:DF (match_dup 2) (parallel [(const_int 2)]))
1209               (vec_select:DF (match_dup 2) (parallel [(const_int 3)]))))))]
1210   "TARGET_AVX"
1211   "vh<plusminus_mnemonic>pd\t{%2, %1, %0|%0, %1, %2}"
1212   [(set_attr "type" "sseadd")
1213    (set_attr "prefix" "vex")
1214    (set_attr "mode" "V4DF")])
1215
1216 (define_insn "avx_h<plusminus_insn>v8sf3"
1217   [(set (match_operand:V8SF 0 "register_operand" "=x")
1218         (vec_concat:V8SF
1219           (vec_concat:V4SF
1220             (vec_concat:V2SF
1221               (plusminus:SF
1222                 (vec_select:SF
1223                   (match_operand:V8SF 1 "register_operand" "x")
1224                   (parallel [(const_int 0)]))
1225                 (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
1226               (plusminus:SF
1227                 (vec_select:SF (match_dup 1) (parallel [(const_int 2)]))
1228                 (vec_select:SF (match_dup 1) (parallel [(const_int 3)]))))
1229             (vec_concat:V2SF
1230               (plusminus:SF
1231                 (vec_select:SF
1232                   (match_operand:V8SF 2 "nonimmediate_operand" "xm")
1233                   (parallel [(const_int 0)]))
1234                 (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))
1235               (plusminus:SF
1236                 (vec_select:SF (match_dup 2) (parallel [(const_int 2)]))
1237                 (vec_select:SF (match_dup 2) (parallel [(const_int 3)])))))
1238           (vec_concat:V4SF
1239             (vec_concat:V2SF
1240               (plusminus:SF
1241                 (vec_select:SF (match_dup 1) (parallel [(const_int 4)]))
1242                 (vec_select:SF (match_dup 1) (parallel [(const_int 5)])))
1243               (plusminus:SF
1244                 (vec_select:SF (match_dup 1) (parallel [(const_int 6)]))
1245                 (vec_select:SF (match_dup 1) (parallel [(const_int 7)]))))
1246             (vec_concat:V2SF
1247               (plusminus:SF
1248                 (vec_select:SF (match_dup 2) (parallel [(const_int 4)]))
1249                 (vec_select:SF (match_dup 2) (parallel [(const_int 5)])))
1250               (plusminus:SF
1251                 (vec_select:SF (match_dup 2) (parallel [(const_int 6)]))
1252                 (vec_select:SF (match_dup 2) (parallel [(const_int 7)])))))))]
1253   "TARGET_AVX"
1254   "vh<plusminus_mnemonic>ps\t{%2, %1, %0|%0, %1, %2}"
1255   [(set_attr "type" "sseadd")
1256    (set_attr "prefix" "vex")
1257    (set_attr "mode" "V8SF")])
1258
1259 (define_insn "*avx_h<plusminus_insn>v4sf3"
1260   [(set (match_operand:V4SF 0 "register_operand" "=x")
1261         (vec_concat:V4SF
1262           (vec_concat:V2SF
1263             (plusminus:SF
1264               (vec_select:SF
1265                 (match_operand:V4SF 1 "register_operand" "x")
1266                 (parallel [(const_int 0)]))
1267               (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
1268             (plusminus:SF
1269               (vec_select:SF (match_dup 1) (parallel [(const_int 2)]))
1270               (vec_select:SF (match_dup 1) (parallel [(const_int 3)]))))
1271           (vec_concat:V2SF
1272             (plusminus:SF
1273               (vec_select:SF
1274                 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
1275                 (parallel [(const_int 0)]))
1276               (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))
1277             (plusminus:SF
1278               (vec_select:SF (match_dup 2) (parallel [(const_int 2)]))
1279               (vec_select:SF (match_dup 2) (parallel [(const_int 3)]))))))]
1280   "TARGET_AVX"
1281   "vh<plusminus_mnemonic>ps\t{%2, %1, %0|%0, %1, %2}"
1282   [(set_attr "type" "sseadd")
1283    (set_attr "prefix" "vex")
1284    (set_attr "mode" "V4SF")])
1285
1286 (define_insn "sse3_h<plusminus_insn>v4sf3"
1287   [(set (match_operand:V4SF 0 "register_operand" "=x")
1288         (vec_concat:V4SF
1289           (vec_concat:V2SF
1290             (plusminus:SF
1291               (vec_select:SF
1292                 (match_operand:V4SF 1 "register_operand" "0")
1293                 (parallel [(const_int 0)]))
1294               (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
1295             (plusminus:SF
1296               (vec_select:SF (match_dup 1) (parallel [(const_int 2)]))
1297               (vec_select:SF (match_dup 1) (parallel [(const_int 3)]))))
1298           (vec_concat:V2SF
1299             (plusminus:SF
1300               (vec_select:SF
1301                 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
1302                 (parallel [(const_int 0)]))
1303               (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))
1304             (plusminus:SF
1305               (vec_select:SF (match_dup 2) (parallel [(const_int 2)]))
1306               (vec_select:SF (match_dup 2) (parallel [(const_int 3)]))))))]
1307   "TARGET_SSE3"
1308   "h<plusminus_mnemonic>ps\t{%2, %0|%0, %2}"
1309   [(set_attr "type" "sseadd")
1310    (set_attr "atom_unit" "complex")
1311    (set_attr "prefix_rep" "1")
1312    (set_attr "mode" "V4SF")])
1313
1314 (define_insn "*avx_h<plusminus_insn>v2df3"
1315   [(set (match_operand:V2DF 0 "register_operand" "=x")
1316         (vec_concat:V2DF
1317           (plusminus:DF
1318             (vec_select:DF
1319               (match_operand:V2DF 1 "register_operand" "x")
1320               (parallel [(const_int 0)]))
1321             (vec_select:DF (match_dup 1) (parallel [(const_int 1)])))
1322           (plusminus:DF
1323             (vec_select:DF
1324               (match_operand:V2DF 2 "nonimmediate_operand" "xm")
1325               (parallel [(const_int 0)]))
1326             (vec_select:DF (match_dup 2) (parallel [(const_int 1)])))))]
1327   "TARGET_AVX"
1328   "vh<plusminus_mnemonic>pd\t{%2, %1, %0|%0, %1, %2}"
1329   [(set_attr "type" "sseadd")
1330    (set_attr "prefix" "vex")
1331    (set_attr "mode" "V2DF")])
1332
1333 (define_insn "sse3_h<plusminus_insn>v2df3"
1334   [(set (match_operand:V2DF 0 "register_operand" "=x")
1335         (vec_concat:V2DF
1336           (plusminus:DF
1337             (vec_select:DF
1338               (match_operand:V2DF 1 "register_operand" "0")
1339               (parallel [(const_int 0)]))
1340             (vec_select:DF (match_dup 1) (parallel [(const_int 1)])))
1341           (plusminus:DF
1342             (vec_select:DF
1343               (match_operand:V2DF 2 "nonimmediate_operand" "xm")
1344               (parallel [(const_int 0)]))
1345             (vec_select:DF (match_dup 2) (parallel [(const_int 1)])))))]
1346   "TARGET_SSE3"
1347   "h<plusminus_mnemonic>pd\t{%2, %0|%0, %2}"
1348   [(set_attr "type" "sseadd")
1349    (set_attr "mode" "V2DF")])
1350
1351 (define_expand "reduc_splus_v4sf"
1352   [(match_operand:V4SF 0 "register_operand" "")
1353    (match_operand:V4SF 1 "register_operand" "")]
1354   "TARGET_SSE"
1355 {
1356   if (TARGET_SSE3)
1357     {
1358       rtx tmp = gen_reg_rtx (V4SFmode);
1359       emit_insn (gen_sse3_haddv4sf3 (tmp, operands[1], operands[1]));
1360       emit_insn (gen_sse3_haddv4sf3 (operands[0], tmp, tmp));
1361     }
1362   else
1363     ix86_expand_reduc_v4sf (gen_addv4sf3, operands[0], operands[1]);
1364   DONE;
1365 })
1366
1367 (define_expand "reduc_splus_v2df"
1368   [(match_operand:V2DF 0 "register_operand" "")
1369    (match_operand:V2DF 1 "register_operand" "")]
1370   "TARGET_SSE3"
1371 {
1372   emit_insn (gen_sse3_haddv2df3 (operands[0], operands[1], operands[1]));
1373   DONE;
1374 })
1375
1376 (define_expand "reduc_smax_v4sf"
1377   [(match_operand:V4SF 0 "register_operand" "")
1378    (match_operand:V4SF 1 "register_operand" "")]
1379   "TARGET_SSE"
1380 {
1381   ix86_expand_reduc_v4sf (gen_smaxv4sf3, operands[0], operands[1]);
1382   DONE;
1383 })
1384
1385 (define_expand "reduc_smin_v4sf"
1386   [(match_operand:V4SF 0 "register_operand" "")
1387    (match_operand:V4SF 1 "register_operand" "")]
1388   "TARGET_SSE"
1389 {
1390   ix86_expand_reduc_v4sf (gen_sminv4sf3, operands[0], operands[1]);
1391   DONE;
1392 })
1393
1394 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1395 ;;
1396 ;; Parallel floating point comparisons
1397 ;;
1398 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1399
1400 (define_insn "avx_cmpp<avxmodesuffixf2c><mode>3"
1401   [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x")
1402         (unspec:AVXMODEF2P
1403           [(match_operand:AVXMODEF2P 1 "register_operand" "x")
1404            (match_operand:AVXMODEF2P 2 "nonimmediate_operand" "xm")
1405            (match_operand:SI 3 "const_0_to_31_operand" "n")]
1406           UNSPEC_PCMP))]
1407   "TARGET_AVX"
1408   "vcmpp<avxmodesuffixf2c>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1409   [(set_attr "type" "ssecmp")
1410    (set_attr "prefix" "vex")
1411    (set_attr "mode" "<MODE>")])
1412
1413 (define_insn "avx_cmps<ssemodesuffixf2c><mode>3"
1414   [(set (match_operand:SSEMODEF2P 0 "register_operand" "")
1415         (vec_merge:SSEMODEF2P
1416           (unspec:SSEMODEF2P
1417             [(match_operand:SSEMODEF2P 1 "register_operand" "x")
1418              (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")
1419              (match_operand:SI 3 "const_0_to_31_operand" "n")]
1420             UNSPEC_PCMP)
1421          (match_dup 1)
1422          (const_int 1)))]
1423   "TARGET_AVX"
1424   "vcmps<ssemodesuffixf2c>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1425   [(set_attr "type" "ssecmp")
1426    (set_attr "prefix" "vex")
1427    (set_attr "mode" "<ssescalarmode>")])
1428
1429 ;; We don't promote 128bit vector compare intrinsics. But vectorizer
1430 ;; may generate 256bit vector compare instructions.
1431 (define_insn "*avx_maskcmp<mode>3"
1432   [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x")
1433         (match_operator:AVXMODEF2P 3 "avx_comparison_float_operator"
1434                 [(match_operand:AVXMODEF2P 1 "register_operand" "x")
1435                  (match_operand:AVXMODEF2P 2 "nonimmediate_operand" "xm")]))]
1436   "AVX_VEC_FLOAT_MODE_P (<MODE>mode)"
1437   "vcmp%D3p<avxmodesuffixf2c>\t{%2, %1, %0|%0, %1, %2}"
1438   [(set_attr "type" "ssecmp")
1439    (set_attr "prefix" "vex")
1440    (set_attr "mode" "<avxvecmode>")])
1441
1442 (define_insn "<sse>_maskcmp<mode>3"
1443   [(set (match_operand:SSEMODEF4 0 "register_operand" "=x")
1444         (match_operator:SSEMODEF4 3 "sse_comparison_operator"
1445                 [(match_operand:SSEMODEF4 1 "register_operand" "0")
1446                  (match_operand:SSEMODEF4 2 "nonimmediate_operand" "xm")]))]
1447   "(SSE_FLOAT_MODE_P (<MODE>mode) || SSE_VEC_FLOAT_MODE_P (<MODE>mode))
1448    && !TARGET_SSE5"
1449   "cmp%D3<ssemodesuffixf4>\t{%2, %0|%0, %2}"
1450   [(set_attr "type" "ssecmp")
1451    (set_attr "mode" "<MODE>")])
1452
1453 (define_insn "<sse>_vmmaskcmp<mode>3"
1454   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
1455         (vec_merge:SSEMODEF2P
1456          (match_operator:SSEMODEF2P 3 "sse_comparison_operator"
1457                 [(match_operand:SSEMODEF2P 1 "register_operand" "0")
1458                  (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")])
1459          (match_dup 1)
1460          (const_int 1)))]
1461   "SSE_VEC_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
1462   "cmp%D3s<ssemodesuffixf2c>\t{%2, %0|%0, %2}"
1463   [(set_attr "type" "ssecmp")
1464    (set_attr "mode" "<ssescalarmode>")])
1465
1466 (define_insn "<sse>_comi"
1467   [(set (reg:CCFP FLAGS_REG)
1468         (compare:CCFP
1469           (vec_select:MODEF
1470             (match_operand:<ssevecmode> 0 "register_operand" "x")
1471             (parallel [(const_int 0)]))
1472           (vec_select:MODEF
1473             (match_operand:<ssevecmode> 1 "nonimmediate_operand" "xm")
1474             (parallel [(const_int 0)]))))]
1475   "SSE_FLOAT_MODE_P (<MODE>mode)"
1476   "%vcomis<ssemodefsuffix>\t{%1, %0|%0, %1}"
1477   [(set_attr "type" "ssecomi")
1478    (set_attr "prefix" "maybe_vex")
1479    (set_attr "mode" "<MODE>")])
1480
1481 (define_insn "<sse>_ucomi"
1482   [(set (reg:CCFPU FLAGS_REG)
1483         (compare:CCFPU
1484           (vec_select:MODEF
1485             (match_operand:<ssevecmode> 0 "register_operand" "x")
1486             (parallel [(const_int 0)]))
1487           (vec_select:MODEF
1488             (match_operand:<ssevecmode> 1 "nonimmediate_operand" "xm")
1489             (parallel [(const_int 0)]))))]
1490   "SSE_FLOAT_MODE_P (<MODE>mode)"
1491   "%vucomis<ssemodefsuffix>\t{%1, %0|%0, %1}"
1492   [(set_attr "type" "ssecomi")
1493    (set_attr "prefix" "maybe_vex")
1494    (set_attr "mode" "<MODE>")])
1495
1496 (define_expand "vcond<mode>"
1497   [(set (match_operand:SSEMODEF2P 0 "register_operand" "")
1498         (if_then_else:SSEMODEF2P
1499           (match_operator 3 ""
1500             [(match_operand:SSEMODEF2P 4 "nonimmediate_operand" "")
1501              (match_operand:SSEMODEF2P 5 "nonimmediate_operand" "")])
1502           (match_operand:SSEMODEF2P 1 "general_operand" "")
1503           (match_operand:SSEMODEF2P 2 "general_operand" "")))]
1504   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
1505 {
1506   if (ix86_expand_fp_vcond (operands))
1507     DONE;
1508   else
1509     FAIL;
1510 })
1511
1512 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1513 ;;
1514 ;; Parallel floating point logical operations
1515 ;;
1516 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1517
1518 (define_insn "avx_andnot<mode>3"
1519   [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x")
1520         (and:AVXMODEF2P
1521           (not:AVXMODEF2P
1522             (match_operand:AVXMODEF2P 1 "register_operand" "x"))
1523           (match_operand:AVXMODEF2P 2 "nonimmediate_operand" "xm")))]
1524   "AVX_VEC_FLOAT_MODE_P (<MODE>mode)"
1525   "vandnp<avxmodesuffixf2c>\t{%2, %1, %0|%0, %1, %2}"
1526   [(set_attr "type" "sselog")
1527    (set_attr "prefix" "vex")
1528    (set_attr "mode" "<avxvecmode>")])
1529
1530 (define_insn "<sse>_andnot<mode>3"
1531   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
1532         (and:SSEMODEF2P
1533           (not:SSEMODEF2P
1534             (match_operand:SSEMODEF2P 1 "register_operand" "0"))
1535           (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")))]
1536   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
1537   "andnp<ssemodesuffixf2c>\t{%2, %0|%0, %2}"
1538   [(set_attr "type" "sselog")
1539    (set_attr "mode" "<MODE>")])
1540
1541 (define_expand "<code><mode>3"
1542   [(set (match_operand:AVX256MODEF2P 0 "register_operand" "")
1543         (plogic:AVX256MODEF2P
1544           (match_operand:AVX256MODEF2P 1 "nonimmediate_operand" "")
1545           (match_operand:AVX256MODEF2P 2 "nonimmediate_operand" "")))]
1546   "AVX256_VEC_FLOAT_MODE_P (<MODE>mode)"
1547   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
1548
1549 (define_insn "*avx_<code><mode>3"
1550   [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x")
1551         (plogic:AVXMODEF2P
1552           (match_operand:AVXMODEF2P 1 "nonimmediate_operand" "%x")
1553           (match_operand:AVXMODEF2P 2 "nonimmediate_operand" "xm")))]
1554   "AVX_VEC_FLOAT_MODE_P (<MODE>mode)
1555    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
1556   "v<plogicprefix>p<avxmodesuffixf2c>\t{%2, %1, %0|%0, %1, %2}"
1557   [(set_attr "type" "sselog")
1558    (set_attr "prefix" "vex")
1559    (set_attr "mode" "<avxvecmode>")])
1560
1561 (define_expand "<code><mode>3"
1562   [(set (match_operand:SSEMODEF2P 0 "register_operand" "")
1563         (plogic:SSEMODEF2P
1564           (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "")
1565           (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "")))]
1566   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
1567   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
1568
1569 (define_insn "*<code><mode>3"
1570   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x")
1571         (plogic:SSEMODEF2P
1572           (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "%0")
1573           (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")))]
1574   "SSE_VEC_FLOAT_MODE_P (<MODE>mode)
1575    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
1576   "<plogicprefix>p<ssemodesuffixf2c>\t{%2, %0|%0, %2}"
1577   [(set_attr "type" "sselog")
1578    (set_attr "mode" "<MODE>")])
1579
1580 ;; Also define scalar versions.  These are used for abs, neg, and
1581 ;; conditional move.  Using subregs into vector modes causes register
1582 ;; allocation lossage.  These patterns do not allow memory operands
1583 ;; because the native instructions read the full 128-bits.
1584
1585 (define_insn "*avx_andnot<mode>3"
1586   [(set (match_operand:MODEF 0 "register_operand" "=x")
1587         (and:MODEF
1588           (not:MODEF
1589             (match_operand:MODEF 1 "register_operand" "x"))
1590             (match_operand:MODEF 2 "register_operand" "x")))]
1591   "AVX_FLOAT_MODE_P (<MODE>mode)"
1592   "vandnp<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
1593   [(set_attr "type" "sselog")
1594    (set_attr "prefix" "vex")
1595    (set_attr "mode" "<ssevecmode>")])
1596
1597 (define_insn "*andnot<mode>3"
1598   [(set (match_operand:MODEF 0 "register_operand" "=x")
1599         (and:MODEF
1600           (not:MODEF
1601             (match_operand:MODEF 1 "register_operand" "0"))
1602             (match_operand:MODEF 2 "register_operand" "x")))]
1603   "SSE_FLOAT_MODE_P (<MODE>mode)"
1604   "andnp<ssemodefsuffix>\t{%2, %0|%0, %2}"
1605   [(set_attr "type" "sselog")
1606    (set_attr "mode" "<ssevecmode>")])
1607
1608 (define_insn "*avx_<code><mode>3"
1609   [(set (match_operand:MODEF 0 "register_operand" "=x")
1610         (plogic:MODEF
1611           (match_operand:MODEF 1 "register_operand" "x")
1612           (match_operand:MODEF 2 "register_operand" "x")))]
1613   "AVX_FLOAT_MODE_P (<MODE>mode)"
1614   "v<plogicprefix>p<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
1615   [(set_attr "type" "sselog")
1616    (set_attr "prefix" "vex")
1617    (set_attr "mode" "<ssevecmode>")])
1618
1619 (define_insn "*<code><mode>3"
1620   [(set (match_operand:MODEF 0 "register_operand" "=x")
1621         (plogic:MODEF
1622           (match_operand:MODEF 1 "register_operand" "0")
1623           (match_operand:MODEF 2 "register_operand" "x")))]
1624   "SSE_FLOAT_MODE_P (<MODE>mode)"
1625   "<plogicprefix>p<ssemodefsuffix>\t{%2, %0|%0, %2}"
1626   [(set_attr "type" "sselog")
1627    (set_attr "mode" "<ssevecmode>")])
1628
1629 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1630 ;;
1631 ;; SSE5 floating point multiply/accumulate instructions This includes the
1632 ;; scalar version of the instructions as well as the vector
1633 ;;
1634 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1635
1636 ;; In order to match (*a * *b) + *c, particularly when vectorizing, allow
1637 ;; combine to generate a multiply/add with two memory references.  We then
1638 ;; split this insn, into loading up the destination register with one of the
1639 ;; memory operations.  If we don't manage to split the insn, reload will
1640 ;; generate the appropriate moves.  The reason this is needed, is that combine
1641 ;; has already folded one of the memory references into both the multiply and
1642 ;; add insns, and it can't generate a new pseudo.  I.e.:
1643 ;;      (set (reg1) (mem (addr1)))
1644 ;;      (set (reg2) (mult (reg1) (mem (addr2))))
1645 ;;      (set (reg3) (plus (reg2) (mem (addr3))))
1646
1647 (define_insn "sse5_fmadd<mode>4"
1648   [(set (match_operand:SSEMODEF4 0 "register_operand" "=x,x,x,x")
1649         (plus:SSEMODEF4
1650          (mult:SSEMODEF4
1651           (match_operand:SSEMODEF4 1 "nonimmediate_operand" "%0,0,x,xm")
1652           (match_operand:SSEMODEF4 2 "nonimmediate_operand" "x,xm,xm,x"))
1653          (match_operand:SSEMODEF4 3 "nonimmediate_operand" "xm,x,0,0")))]
1654   "TARGET_SSE5 && TARGET_FUSED_MADD
1655    && ix86_sse5_valid_op_p (operands, insn, 4, true, 2, true)"
1656   "fmadd<ssemodesuffixf4>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1657   [(set_attr "type" "ssemuladd")
1658    (set_attr "mode" "<MODE>")])
1659
1660 ;; Split fmadd with two memory operands into a load and the fmadd.
1661 (define_split
1662   [(set (match_operand:SSEMODEF4 0 "register_operand" "")
1663         (plus:SSEMODEF4
1664          (mult:SSEMODEF4
1665           (match_operand:SSEMODEF4 1 "nonimmediate_operand" "")
1666           (match_operand:SSEMODEF4 2 "nonimmediate_operand" ""))
1667          (match_operand:SSEMODEF4 3 "nonimmediate_operand" "")))]
1668   "TARGET_SSE5
1669    && !ix86_sse5_valid_op_p (operands, insn, 4, true, 1, true)
1670    && ix86_sse5_valid_op_p (operands, insn, 4, true, 2, true)
1671    && !reg_mentioned_p (operands[0], operands[1])
1672    && !reg_mentioned_p (operands[0], operands[2])
1673    && !reg_mentioned_p (operands[0], operands[3])"
1674   [(const_int 0)]
1675 {
1676   ix86_expand_sse5_multiple_memory (operands, 4, <MODE>mode);
1677   emit_insn (gen_sse5_fmadd<mode>4 (operands[0], operands[1],
1678                                     operands[2], operands[3]));
1679   DONE;
1680 })
1681
1682 ;; For the scalar operations, use operand1 for the upper words that aren't
1683 ;; modified, so restrict the forms that are generated.
1684 ;; Scalar version of fmadd
1685 (define_insn "sse5_vmfmadd<mode>4"
1686   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x")
1687         (vec_merge:SSEMODEF2P
1688          (plus:SSEMODEF2P
1689           (mult:SSEMODEF2P
1690            (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "0,0")
1691            (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm"))
1692           (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x"))
1693          (match_dup 1)
1694          (const_int 1)))]
1695   "TARGET_SSE5 && TARGET_FUSED_MADD
1696    && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, true)"
1697   "fmadd<ssemodesuffixf2s>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1698   [(set_attr "type" "ssemuladd")
1699    (set_attr "mode" "<MODE>")])
1700
1701 ;; Floating multiply and subtract
1702 ;; Allow two memory operands the same as fmadd
1703 (define_insn "sse5_fmsub<mode>4"
1704   [(set (match_operand:SSEMODEF4 0 "register_operand" "=x,x,x,x")
1705         (minus:SSEMODEF4
1706          (mult:SSEMODEF4
1707           (match_operand:SSEMODEF4 1 "nonimmediate_operand" "%0,0,x,xm")
1708           (match_operand:SSEMODEF4 2 "nonimmediate_operand" "x,xm,xm,x"))
1709          (match_operand:SSEMODEF4 3 "nonimmediate_operand" "xm,x,0,0")))]
1710   "TARGET_SSE5 && TARGET_FUSED_MADD
1711    && ix86_sse5_valid_op_p (operands, insn, 4, true, 2, true)"
1712   "fmsub<ssemodesuffixf4>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1713   [(set_attr "type" "ssemuladd")
1714    (set_attr "mode" "<MODE>")])
1715
1716 ;; Split fmsub with two memory operands into a load and the fmsub.
1717 (define_split
1718   [(set (match_operand:SSEMODEF4 0 "register_operand" "")
1719         (minus:SSEMODEF4
1720          (mult:SSEMODEF4
1721           (match_operand:SSEMODEF4 1 "nonimmediate_operand" "")
1722           (match_operand:SSEMODEF4 2 "nonimmediate_operand" ""))
1723          (match_operand:SSEMODEF4 3 "nonimmediate_operand" "")))]
1724   "TARGET_SSE5
1725    && !ix86_sse5_valid_op_p (operands, insn, 4, true, 1, true)
1726    && ix86_sse5_valid_op_p (operands, insn, 4, true, 2, true)
1727    && !reg_mentioned_p (operands[0], operands[1])
1728    && !reg_mentioned_p (operands[0], operands[2])
1729    && !reg_mentioned_p (operands[0], operands[3])"
1730   [(const_int 0)]
1731 {
1732   ix86_expand_sse5_multiple_memory (operands, 4, <MODE>mode);
1733   emit_insn (gen_sse5_fmsub<mode>4 (operands[0], operands[1],
1734                                     operands[2], operands[3]));
1735   DONE;
1736 })
1737
1738 ;; For the scalar operations, use operand1 for the upper words that aren't
1739 ;; modified, so restrict the forms that are generated.
1740 ;; Scalar version of fmsub
1741 (define_insn "sse5_vmfmsub<mode>4"
1742   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x")
1743         (vec_merge:SSEMODEF2P
1744          (minus:SSEMODEF2P
1745           (mult:SSEMODEF2P
1746            (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "0,0")
1747            (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm"))
1748           (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x"))
1749          (match_dup 1)
1750          (const_int 1)))]
1751   "TARGET_SSE5 && TARGET_FUSED_MADD
1752    && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
1753   "fmsub<ssemodesuffixf2s>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1754   [(set_attr "type" "ssemuladd")
1755    (set_attr "mode" "<MODE>")])
1756
1757 ;; Floating point negative multiply and add
1758 ;; Rewrite (- (a * b) + c) into the canonical form: c - (a * b)
1759 ;; Note operands are out of order to simplify call to ix86_sse5_valid_p
1760 ;; Allow two memory operands to help in optimizing.
1761 (define_insn "sse5_fnmadd<mode>4"
1762   [(set (match_operand:SSEMODEF4 0 "register_operand" "=x,x,x,x")
1763         (minus:SSEMODEF4
1764          (match_operand:SSEMODEF4 3 "nonimmediate_operand" "xm,x,0,0")
1765          (mult:SSEMODEF4
1766           (match_operand:SSEMODEF4 1 "nonimmediate_operand" "%0,0,x,xm")
1767           (match_operand:SSEMODEF4 2 "nonimmediate_operand" "x,xm,xm,x"))))]
1768   "TARGET_SSE5 && TARGET_FUSED_MADD
1769    && ix86_sse5_valid_op_p (operands, insn, 4, true, 2, true)"
1770   "fnmadd<ssemodesuffixf4>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1771   [(set_attr "type" "ssemuladd")
1772    (set_attr "mode" "<MODE>")])
1773
1774 ;; Split fnmadd with two memory operands into a load and the fnmadd.
1775 (define_split
1776   [(set (match_operand:SSEMODEF4 0 "register_operand" "")
1777         (minus:SSEMODEF4
1778          (match_operand:SSEMODEF4 3 "nonimmediate_operand" "")
1779          (mult:SSEMODEF4
1780           (match_operand:SSEMODEF4 1 "nonimmediate_operand" "")
1781           (match_operand:SSEMODEF4 2 "nonimmediate_operand" ""))))]
1782   "TARGET_SSE5
1783    && !ix86_sse5_valid_op_p (operands, insn, 4, true, 1, true)
1784    && ix86_sse5_valid_op_p (operands, insn, 4, true, 2, true)
1785    && !reg_mentioned_p (operands[0], operands[1])
1786    && !reg_mentioned_p (operands[0], operands[2])
1787    && !reg_mentioned_p (operands[0], operands[3])"
1788   [(const_int 0)]
1789 {
1790   ix86_expand_sse5_multiple_memory (operands, 4, <MODE>mode);
1791   emit_insn (gen_sse5_fnmadd<mode>4 (operands[0], operands[1],
1792                                      operands[2], operands[3]));
1793   DONE;
1794 })
1795
1796 ;; For the scalar operations, use operand1 for the upper words that aren't
1797 ;; modified, so restrict the forms that are generated.
1798 ;; Scalar version of fnmadd
1799 (define_insn "sse5_vmfnmadd<mode>4"
1800   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x")
1801         (vec_merge:SSEMODEF2P
1802          (minus:SSEMODEF2P
1803           (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x")
1804           (mult:SSEMODEF2P
1805            (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "0,0")
1806            (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm")))
1807          (match_dup 1)
1808          (const_int 1)))]
1809   "TARGET_SSE5 && TARGET_FUSED_MADD
1810    && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, true)"
1811   "fnmadd<ssemodesuffixf2s>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1812   [(set_attr "type" "ssemuladd")
1813    (set_attr "mode" "<MODE>")])
1814
1815 ;; Floating point negative multiply and subtract
1816 ;; Rewrite (- (a * b) - c) into the canonical form: ((-a) * b) - c
1817 ;; Allow 2 memory operands to help with optimization
1818 (define_insn "sse5_fnmsub<mode>4"
1819   [(set (match_operand:SSEMODEF4 0 "register_operand" "=x,x")
1820         (minus:SSEMODEF4
1821          (mult:SSEMODEF4
1822           (neg:SSEMODEF4
1823            (match_operand:SSEMODEF4 1 "nonimmediate_operand" "0,0"))
1824           (match_operand:SSEMODEF4 2 "nonimmediate_operand" "x,xm"))
1825          (match_operand:SSEMODEF4 3 "nonimmediate_operand" "xm,x")))]
1826   "TARGET_SSE5 && TARGET_FUSED_MADD
1827    && ix86_sse5_valid_op_p (operands, insn, 4, true, 2, false)"
1828   "fnmsub<ssemodesuffixf4>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1829   [(set_attr "type" "ssemuladd")
1830    (set_attr "mode" "<MODE>")])
1831
1832 ;; Split fnmsub with two memory operands into a load and the fmsub.
1833 (define_split
1834   [(set (match_operand:SSEMODEF4 0 "register_operand" "")
1835         (minus:SSEMODEF4
1836          (mult:SSEMODEF4
1837           (neg:SSEMODEF4
1838            (match_operand:SSEMODEF4 1 "nonimmediate_operand" ""))
1839           (match_operand:SSEMODEF4 2 "nonimmediate_operand" ""))
1840          (match_operand:SSEMODEF4 3 "nonimmediate_operand" "")))]
1841   "TARGET_SSE5
1842    && !ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)
1843    && ix86_sse5_valid_op_p (operands, insn, 4, true, 2, false)
1844    && !reg_mentioned_p (operands[0], operands[1])
1845    && !reg_mentioned_p (operands[0], operands[2])
1846    && !reg_mentioned_p (operands[0], operands[3])"
1847   [(const_int 0)]
1848 {
1849   ix86_expand_sse5_multiple_memory (operands, 4, <MODE>mode);
1850   emit_insn (gen_sse5_fnmsub<mode>4 (operands[0], operands[1],
1851                                      operands[2], operands[3]));
1852   DONE;
1853 })
1854
1855 ;; For the scalar operations, use operand1 for the upper words that aren't
1856 ;; modified, so restrict the forms that are generated.
1857 ;; Scalar version of fnmsub
1858 (define_insn "sse5_vmfnmsub<mode>4"
1859   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x")
1860         (vec_merge:SSEMODEF2P
1861          (minus:SSEMODEF2P
1862           (mult:SSEMODEF2P
1863            (neg:SSEMODEF2P
1864             (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "0,0"))
1865            (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm"))
1866           (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x"))
1867          (match_dup 1)
1868          (const_int 1)))]
1869   "TARGET_SSE5 && TARGET_FUSED_MADD
1870    && ix86_sse5_valid_op_p (operands, insn, 4, true, 2, false)"
1871   "fnmsub<ssemodesuffixf2s>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1872   [(set_attr "type" "ssemuladd")
1873    (set_attr "mode" "<MODE>")])
1874
1875 ;; The same instructions using an UNSPEC to allow the intrinsic to be used
1876 ;; even if the user used -mno-fused-madd
1877 ;; Parallel instructions.  During instruction generation, just default
1878 ;; to registers, and let combine later build the appropriate instruction.
1879 (define_expand "sse5i_fmadd<mode>4"
1880   [(set (match_operand:SSEMODEF2P 0 "register_operand" "")
1881         (unspec:SSEMODEF2P
1882          [(plus:SSEMODEF2P
1883            (mult:SSEMODEF2P
1884             (match_operand:SSEMODEF2P 1 "register_operand" "")
1885             (match_operand:SSEMODEF2P 2 "register_operand" ""))
1886            (match_operand:SSEMODEF2P 3 "register_operand" ""))]
1887          UNSPEC_SSE5_INTRINSIC))]
1888   "TARGET_SSE5"
1889 {
1890   /* If we have -mfused-madd, emit the normal insn rather than the UNSPEC */
1891   if (TARGET_FUSED_MADD)
1892     {
1893       emit_insn (gen_sse5_fmadd<mode>4 (operands[0], operands[1],
1894                                         operands[2], operands[3]));
1895       DONE;
1896     }
1897 })
1898
1899 (define_insn "*sse5i_fmadd<mode>4"
1900   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x,x,x")
1901         (unspec:SSEMODEF2P
1902          [(plus:SSEMODEF2P
1903            (mult:SSEMODEF2P
1904             (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "%0,0,x,xm")
1905             (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm,xm,x"))
1906            (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x,0,0"))]
1907          UNSPEC_SSE5_INTRINSIC))]
1908   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, true)"
1909   "fmadd<ssemodesuffixf4>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1910   [(set_attr "type" "ssemuladd")
1911    (set_attr "mode" "<MODE>")])
1912
1913 (define_expand "sse5i_fmsub<mode>4"
1914   [(set (match_operand:SSEMODEF2P 0 "register_operand" "")
1915         (unspec:SSEMODEF2P
1916          [(minus:SSEMODEF2P
1917            (mult:SSEMODEF2P
1918             (match_operand:SSEMODEF2P 1 "register_operand" "")
1919             (match_operand:SSEMODEF2P 2 "register_operand" ""))
1920            (match_operand:SSEMODEF2P 3 "register_operand" ""))]
1921          UNSPEC_SSE5_INTRINSIC))]
1922   "TARGET_SSE5"
1923 {
1924   /* If we have -mfused-madd, emit the normal insn rather than the UNSPEC */
1925   if (TARGET_FUSED_MADD)
1926     {
1927       emit_insn (gen_sse5_fmsub<mode>4 (operands[0], operands[1],
1928                                         operands[2], operands[3]));
1929       DONE;
1930     }
1931 })
1932
1933 (define_insn "*sse5i_fmsub<mode>4"
1934   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x,x,x")
1935         (unspec:SSEMODEF2P
1936          [(minus:SSEMODEF2P
1937            (mult:SSEMODEF2P
1938             (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "%0,0,x,xm")
1939             (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm,xm,x"))
1940            (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x,0,0"))]
1941          UNSPEC_SSE5_INTRINSIC))]
1942   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, true)"
1943   "fmsub<ssemodesuffixf4>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1944   [(set_attr "type" "ssemuladd")
1945    (set_attr "mode" "<MODE>")])
1946
1947 ;; Rewrite (- (a * b) + c) into the canonical form: c - (a * b)
1948 ;; Note operands are out of order to simplify call to ix86_sse5_valid_p
1949 (define_expand "sse5i_fnmadd<mode>4"
1950   [(set (match_operand:SSEMODEF2P 0 "register_operand" "")
1951         (unspec:SSEMODEF2P
1952          [(minus:SSEMODEF2P
1953            (match_operand:SSEMODEF2P 3 "register_operand" "")
1954            (mult:SSEMODEF2P
1955             (match_operand:SSEMODEF2P 1 "register_operand" "")
1956             (match_operand:SSEMODEF2P 2 "register_operand" "")))]
1957          UNSPEC_SSE5_INTRINSIC))]
1958   "TARGET_SSE5"
1959 {
1960   /* If we have -mfused-madd, emit the normal insn rather than the UNSPEC */
1961   if (TARGET_FUSED_MADD)
1962     {
1963       emit_insn (gen_sse5_fnmadd<mode>4 (operands[0], operands[1],
1964                                          operands[2], operands[3]));
1965       DONE;
1966     }
1967 })
1968
1969 (define_insn "*sse5i_fnmadd<mode>4"
1970   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x,x,x")
1971         (unspec:SSEMODEF2P
1972          [(minus:SSEMODEF2P
1973            (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x,0,0")
1974            (mult:SSEMODEF2P
1975             (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "%0,0,x,xm")
1976             (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm,xm,x")))]
1977          UNSPEC_SSE5_INTRINSIC))]
1978   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, true)"
1979   "fnmadd<ssemodesuffixf4>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1980   [(set_attr "type" "ssemuladd")
1981    (set_attr "mode" "<MODE>")])
1982
1983 ;; Rewrite (- (a * b) - c) into the canonical form: ((-a) * b) - c
1984 (define_expand "sse5i_fnmsub<mode>4"
1985   [(set (match_operand:SSEMODEF2P 0 "register_operand" "")
1986         (unspec:SSEMODEF2P
1987          [(minus:SSEMODEF2P
1988            (mult:SSEMODEF2P
1989             (neg:SSEMODEF2P
1990              (match_operand:SSEMODEF2P 1 "register_operand" ""))
1991             (match_operand:SSEMODEF2P 2 "register_operand" ""))
1992            (match_operand:SSEMODEF2P 3 "register_operand" ""))]
1993          UNSPEC_SSE5_INTRINSIC))]
1994   "TARGET_SSE5"
1995 {
1996   /* If we have -mfused-madd, emit the normal insn rather than the UNSPEC */
1997   if (TARGET_FUSED_MADD)
1998     {
1999       emit_insn (gen_sse5_fnmsub<mode>4 (operands[0], operands[1],
2000                                          operands[2], operands[3]));
2001       DONE;
2002     }
2003 })
2004
2005 (define_insn "*sse5i_fnmsub<mode>4"
2006   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x,x,x")
2007         (unspec:SSEMODEF2P
2008          [(minus:SSEMODEF2P
2009            (mult:SSEMODEF2P
2010             (neg:SSEMODEF2P
2011              (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "0,0,x,xm"))
2012             (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm,xm,x"))
2013            (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x,0,0"))]
2014          UNSPEC_SSE5_INTRINSIC))]
2015   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
2016   "fnmsub<ssemodesuffixf4>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
2017   [(set_attr "type" "ssemuladd")
2018    (set_attr "mode" "<MODE>")])
2019
2020 ;; Scalar instructions
2021 (define_expand "sse5i_vmfmadd<mode>4"
2022   [(set (match_operand:SSEMODEF2P 0 "register_operand" "")
2023         (unspec:SSEMODEF2P
2024          [(vec_merge:SSEMODEF2P
2025            (plus:SSEMODEF2P
2026             (mult:SSEMODEF2P
2027              (match_operand:SSEMODEF2P 1 "register_operand" "")
2028              (match_operand:SSEMODEF2P 2 "register_operand" ""))
2029             (match_operand:SSEMODEF2P 3 "register_operand" ""))
2030            (match_dup 1)
2031            (const_int 0))]
2032          UNSPEC_SSE5_INTRINSIC))]
2033   "TARGET_SSE5"
2034 {
2035   /* If we have -mfused-madd, emit the normal insn rather than the UNSPEC */
2036   if (TARGET_FUSED_MADD)
2037     {
2038       emit_insn (gen_sse5_vmfmadd<mode>4 (operands[0], operands[1],
2039                                           operands[2], operands[3]));
2040       DONE;
2041     }
2042 })
2043
2044 ;; For the scalar operations, use operand1 for the upper words that aren't
2045 ;; modified, so restrict the forms that are accepted.
2046 (define_insn "*sse5i_vmfmadd<mode>4"
2047   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x")
2048         (unspec:SSEMODEF2P
2049          [(vec_merge:SSEMODEF2P
2050            (plus:SSEMODEF2P
2051             (mult:SSEMODEF2P
2052              (match_operand:SSEMODEF2P 1 "register_operand" "0,0")
2053              (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm"))
2054             (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x"))
2055            (match_dup 0)
2056            (const_int 0))]
2057          UNSPEC_SSE5_INTRINSIC))]
2058   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
2059   "fmadd<ssemodesuffixf2s>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
2060   [(set_attr "type" "ssemuladd")
2061    (set_attr "mode" "<ssescalarmode>")])
2062
2063 (define_expand "sse5i_vmfmsub<mode>4"
2064   [(set (match_operand:SSEMODEF2P 0 "register_operand" "")
2065         (unspec:SSEMODEF2P
2066          [(vec_merge:SSEMODEF2P
2067            (minus:SSEMODEF2P
2068             (mult:SSEMODEF2P
2069              (match_operand:SSEMODEF2P 1 "register_operand" "")
2070              (match_operand:SSEMODEF2P 2 "register_operand" ""))
2071             (match_operand:SSEMODEF2P 3 "register_operand" ""))
2072            (match_dup 0)
2073            (const_int 1))]
2074          UNSPEC_SSE5_INTRINSIC))]
2075   "TARGET_SSE5"
2076 {
2077   /* If we have -mfused-madd, emit the normal insn rather than the UNSPEC */
2078   if (TARGET_FUSED_MADD)
2079     {
2080       emit_insn (gen_sse5_vmfmsub<mode>4 (operands[0], operands[1],
2081                                           operands[2], operands[3]));
2082       DONE;
2083     }
2084 })
2085
2086 (define_insn "*sse5i_vmfmsub<mode>4"
2087   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x")
2088         (unspec:SSEMODEF2P
2089          [(vec_merge:SSEMODEF2P
2090            (minus:SSEMODEF2P
2091             (mult:SSEMODEF2P
2092              (match_operand:SSEMODEF2P 1 "register_operand" "0,0")
2093              (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm"))
2094             (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x"))
2095            (match_dup 1)
2096            (const_int 1))]
2097          UNSPEC_SSE5_INTRINSIC))]
2098   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
2099   "fmsub<ssemodesuffixf2s>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
2100   [(set_attr "type" "ssemuladd")
2101    (set_attr "mode" "<ssescalarmode>")])
2102
2103 ;; Note operands are out of order to simplify call to ix86_sse5_valid_p
2104 (define_expand "sse5i_vmfnmadd<mode>4"
2105   [(set (match_operand:SSEMODEF2P 0 "register_operand" "")
2106         (unspec:SSEMODEF2P
2107          [(vec_merge:SSEMODEF2P
2108            (minus:SSEMODEF2P
2109             (match_operand:SSEMODEF2P 3 "register_operand" "")
2110             (mult:SSEMODEF2P
2111              (match_operand:SSEMODEF2P 1 "register_operand" "")
2112              (match_operand:SSEMODEF2P 2 "register_operand" "")))
2113            (match_dup 1)
2114            (const_int 1))]
2115          UNSPEC_SSE5_INTRINSIC))]
2116   "TARGET_SSE5"
2117 {
2118   /* If we have -mfused-madd, emit the normal insn rather than the UNSPEC */
2119   if (TARGET_FUSED_MADD)
2120     {
2121       emit_insn (gen_sse5_vmfnmadd<mode>4 (operands[0], operands[1],
2122                                            operands[2], operands[3]));
2123       DONE;
2124     }
2125 })
2126
2127 (define_insn "*sse5i_vmfnmadd<mode>4"
2128   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x")
2129         (unspec:SSEMODEF2P
2130          [(vec_merge:SSEMODEF2P
2131            (minus:SSEMODEF2P
2132             (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x")
2133             (mult:SSEMODEF2P
2134              (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "%0,0")
2135              (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm")))
2136            (match_dup 1)
2137            (const_int 1))]
2138          UNSPEC_SSE5_INTRINSIC))]
2139   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, true)"
2140   "fnmadd<ssemodesuffixf2s>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
2141   [(set_attr "type" "ssemuladd")
2142    (set_attr "mode" "<ssescalarmode>")])
2143
2144 (define_expand "sse5i_vmfnmsub<mode>4"
2145   [(set (match_operand:SSEMODEF2P 0 "register_operand" "")
2146         (unspec:SSEMODEF2P
2147          [(vec_merge:SSEMODEF2P
2148            (minus:SSEMODEF2P
2149             (mult:SSEMODEF2P
2150              (neg:SSEMODEF2P
2151               (match_operand:SSEMODEF2P 1 "register_operand" ""))
2152              (match_operand:SSEMODEF2P 2 "register_operand" ""))
2153             (match_operand:SSEMODEF2P 3 "register_operand" ""))
2154            (match_dup 1)
2155            (const_int 1))]
2156          UNSPEC_SSE5_INTRINSIC))]
2157   "TARGET_SSE5"
2158 {
2159   /* If we have -mfused-madd, emit the normal insn rather than the UNSPEC */
2160   if (TARGET_FUSED_MADD)
2161     {
2162       emit_insn (gen_sse5_vmfnmsub<mode>4 (operands[0], operands[1],
2163                                            operands[2], operands[3]));
2164       DONE;
2165     }
2166 })
2167
2168 (define_insn "*sse5i_vmfnmsub<mode>4"
2169   [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x")
2170         (unspec:SSEMODEF2P
2171          [(vec_merge:SSEMODEF2P
2172            (minus:SSEMODEF2P
2173             (mult:SSEMODEF2P
2174              (neg:SSEMODEF2P
2175               (match_operand:SSEMODEF2P 1 "register_operand" "0,0"))
2176              (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm"))
2177             (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x"))
2178            (match_dup 1)
2179            (const_int 1))]
2180          UNSPEC_SSE5_INTRINSIC))]
2181   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
2182   "fnmsub<ssemodesuffixf2s>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
2183   [(set_attr "type" "ssemuladd")
2184    (set_attr "mode" "<ssescalarmode>")])
2185
2186 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2187 ;;
2188 ;; Parallel single-precision floating point conversion operations
2189 ;;
2190 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2191
2192 (define_insn "sse_cvtpi2ps"
2193   [(set (match_operand:V4SF 0 "register_operand" "=x")
2194         (vec_merge:V4SF
2195           (vec_duplicate:V4SF
2196             (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
2197           (match_operand:V4SF 1 "register_operand" "0")
2198           (const_int 3)))]
2199   "TARGET_SSE"
2200   "cvtpi2ps\t{%2, %0|%0, %2}"
2201   [(set_attr "type" "ssecvt")
2202    (set_attr "mode" "V4SF")])
2203
2204 (define_insn "sse_cvtps2pi"
2205   [(set (match_operand:V2SI 0 "register_operand" "=y")
2206         (vec_select:V2SI
2207           (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
2208                        UNSPEC_FIX_NOTRUNC)
2209           (parallel [(const_int 0) (const_int 1)])))]
2210   "TARGET_SSE"
2211   "cvtps2pi\t{%1, %0|%0, %1}"
2212   [(set_attr "type" "ssecvt")
2213    (set_attr "unit" "mmx")
2214    (set_attr "mode" "DI")])
2215
2216 (define_insn "sse_cvttps2pi"
2217   [(set (match_operand:V2SI 0 "register_operand" "=y")
2218         (vec_select:V2SI
2219           (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
2220           (parallel [(const_int 0) (const_int 1)])))]
2221   "TARGET_SSE"
2222   "cvttps2pi\t{%1, %0|%0, %1}"
2223   [(set_attr "type" "ssecvt")
2224    (set_attr "unit" "mmx")
2225    (set_attr "mode" "SF")])
2226
2227 (define_insn "*avx_cvtsi2ss"
2228   [(set (match_operand:V4SF 0 "register_operand" "=x")
2229         (vec_merge:V4SF
2230           (vec_duplicate:V4SF
2231             (float:SF (match_operand:SI 2 "nonimmediate_operand" "rm")))
2232           (match_operand:V4SF 1 "register_operand" "x")
2233           (const_int 1)))]
2234   "TARGET_AVX"
2235   "vcvtsi2ss\t{%2, %1, %0|%0, %1, %2}"
2236   [(set_attr "type" "sseicvt")
2237    (set_attr "prefix" "vex")
2238    (set_attr "mode" "SF")])
2239
2240 (define_insn "sse_cvtsi2ss"
2241   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
2242         (vec_merge:V4SF
2243           (vec_duplicate:V4SF
2244             (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,m")))
2245           (match_operand:V4SF 1 "register_operand" "0,0")
2246           (const_int 1)))]
2247   "TARGET_SSE"
2248   "cvtsi2ss\t{%2, %0|%0, %2}"
2249   [(set_attr "type" "sseicvt")
2250    (set_attr "athlon_decode" "vector,double")
2251    (set_attr "amdfam10_decode" "vector,double")
2252    (set_attr "mode" "SF")])
2253
2254 (define_insn "*avx_cvtsi2ssq"
2255   [(set (match_operand:V4SF 0 "register_operand" "=x")
2256         (vec_merge:V4SF
2257           (vec_duplicate:V4SF
2258             (float:SF (match_operand:DI 2 "nonimmediate_operand" "rm")))
2259           (match_operand:V4SF 1 "register_operand" "x")
2260           (const_int 1)))]
2261   "TARGET_AVX && TARGET_64BIT"
2262   "vcvtsi2ssq\t{%2, %1, %0|%0, %1, %2}"
2263   [(set_attr "type" "sseicvt")
2264    (set_attr "prefix" "vex")
2265    (set_attr "mode" "SF")])
2266
2267 (define_insn "sse_cvtsi2ssq"
2268   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
2269         (vec_merge:V4SF
2270           (vec_duplicate:V4SF
2271             (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
2272           (match_operand:V4SF 1 "register_operand" "0,0")
2273           (const_int 1)))]
2274   "TARGET_SSE && TARGET_64BIT"
2275   "cvtsi2ssq\t{%2, %0|%0, %2}"
2276   [(set_attr "type" "sseicvt")
2277    (set_attr "athlon_decode" "vector,double")
2278    (set_attr "amdfam10_decode" "vector,double")
2279    (set_attr "mode" "SF")])
2280
2281 (define_insn "sse_cvtss2si"
2282   [(set (match_operand:SI 0 "register_operand" "=r,r")
2283         (unspec:SI
2284           [(vec_select:SF
2285              (match_operand:V4SF 1 "nonimmediate_operand" "x,m")
2286              (parallel [(const_int 0)]))]
2287           UNSPEC_FIX_NOTRUNC))]
2288   "TARGET_SSE"
2289   "%vcvtss2si\t{%1, %0|%0, %1}"
2290   [(set_attr "type" "sseicvt")
2291    (set_attr "athlon_decode" "double,vector")
2292    (set_attr "prefix_rep" "1")
2293    (set_attr "prefix" "maybe_vex")
2294    (set_attr "mode" "SI")])
2295
2296 (define_insn "sse_cvtss2si_2"
2297   [(set (match_operand:SI 0 "register_operand" "=r,r")
2298         (unspec:SI [(match_operand:SF 1 "nonimmediate_operand" "x,m")]
2299                    UNSPEC_FIX_NOTRUNC))]
2300   "TARGET_SSE"
2301   "%vcvtss2si\t{%1, %0|%0, %1}"
2302   [(set_attr "type" "sseicvt")
2303    (set_attr "athlon_decode" "double,vector")
2304    (set_attr "amdfam10_decode" "double,double")
2305    (set_attr "prefix_rep" "1")
2306    (set_attr "prefix" "maybe_vex")
2307    (set_attr "mode" "SI")])
2308
2309 (define_insn "sse_cvtss2siq"
2310   [(set (match_operand:DI 0 "register_operand" "=r,r")
2311         (unspec:DI
2312           [(vec_select:SF
2313              (match_operand:V4SF 1 "nonimmediate_operand" "x,m")
2314              (parallel [(const_int 0)]))]
2315           UNSPEC_FIX_NOTRUNC))]
2316   "TARGET_SSE && TARGET_64BIT"
2317   "%vcvtss2siq\t{%1, %0|%0, %1}"
2318   [(set_attr "type" "sseicvt")
2319    (set_attr "athlon_decode" "double,vector")
2320    (set_attr "prefix_rep" "1")
2321    (set_attr "prefix" "maybe_vex")
2322    (set_attr "mode" "DI")])
2323
2324 (define_insn "sse_cvtss2siq_2"
2325   [(set (match_operand:DI 0 "register_operand" "=r,r")
2326         (unspec:DI [(match_operand:SF 1 "nonimmediate_operand" "x,m")]
2327                    UNSPEC_FIX_NOTRUNC))]
2328   "TARGET_SSE && TARGET_64BIT"
2329   "%vcvtss2siq\t{%1, %0|%0, %1}"
2330   [(set_attr "type" "sseicvt")
2331    (set_attr "athlon_decode" "double,vector")
2332    (set_attr "amdfam10_decode" "double,double")
2333    (set_attr "prefix_rep" "1")
2334    (set_attr "prefix" "maybe_vex")
2335    (set_attr "mode" "DI")])
2336
2337 (define_insn "sse_cvttss2si"
2338   [(set (match_operand:SI 0 "register_operand" "=r,r")
2339         (fix:SI
2340           (vec_select:SF
2341             (match_operand:V4SF 1 "nonimmediate_operand" "x,m")
2342             (parallel [(const_int 0)]))))]
2343   "TARGET_SSE"
2344   "%vcvttss2si\t{%1, %0|%0, %1}"
2345   [(set_attr "type" "sseicvt")
2346    (set_attr "athlon_decode" "double,vector")
2347    (set_attr "amdfam10_decode" "double,double")
2348    (set_attr "prefix_rep" "1")
2349    (set_attr "prefix" "maybe_vex")
2350    (set_attr "mode" "SI")])
2351
2352 (define_insn "sse_cvttss2siq"
2353   [(set (match_operand:DI 0 "register_operand" "=r,r")
2354         (fix:DI
2355           (vec_select:SF
2356             (match_operand:V4SF 1 "nonimmediate_operand" "x,m")
2357             (parallel [(const_int 0)]))))]
2358   "TARGET_SSE && TARGET_64BIT"
2359   "%vcvttss2siq\t{%1, %0|%0, %1}"
2360   [(set_attr "type" "sseicvt")
2361    (set_attr "athlon_decode" "double,vector")
2362    (set_attr "amdfam10_decode" "double,double")
2363    (set_attr "prefix_rep" "1")
2364    (set_attr "prefix" "maybe_vex")
2365    (set_attr "mode" "DI")])
2366
2367 (define_insn "avx_cvtdq2ps<avxmodesuffix>"
2368   [(set (match_operand:AVXMODEDCVTDQ2PS 0 "register_operand" "=x")
2369         (float:AVXMODEDCVTDQ2PS
2370           (match_operand:<avxcvtvecmode> 1 "nonimmediate_operand" "xm")))]
2371   "TARGET_AVX"
2372   "vcvtdq2ps\t{%1, %0|%0, %1}"
2373   [(set_attr "type" "ssecvt")
2374    (set_attr "prefix" "vex")
2375    (set_attr "mode" "<avxvecmode>")])
2376
2377 (define_insn "sse2_cvtdq2ps"
2378   [(set (match_operand:V4SF 0 "register_operand" "=x")
2379         (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
2380   "TARGET_SSE2"
2381   "cvtdq2ps\t{%1, %0|%0, %1}"
2382   [(set_attr "type" "ssecvt")
2383    (set_attr "mode" "V4SF")])
2384
2385 (define_insn "avx_cvtps2dq<avxmodesuffix>"
2386   [(set (match_operand:AVXMODEDCVTPS2DQ 0 "register_operand" "=x")
2387         (unspec:AVXMODEDCVTPS2DQ
2388           [(match_operand:<avxcvtvecmode> 1 "nonimmediate_operand" "xm")]
2389           UNSPEC_FIX_NOTRUNC))]
2390   "TARGET_AVX"
2391   "vcvtps2dq\t{%1, %0|%0, %1}"
2392   [(set_attr "type" "ssecvt")
2393    (set_attr "prefix" "vex")
2394    (set_attr "mode" "<avxvecmode>")])
2395
2396 (define_insn "sse2_cvtps2dq"
2397   [(set (match_operand:V4SI 0 "register_operand" "=x")
2398         (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
2399                      UNSPEC_FIX_NOTRUNC))]
2400   "TARGET_SSE2"
2401   "cvtps2dq\t{%1, %0|%0, %1}"
2402   [(set_attr "type" "ssecvt")
2403    (set_attr "prefix_data16" "1")
2404    (set_attr "mode" "TI")])
2405
2406 (define_insn "avx_cvttps2dq<avxmodesuffix>"
2407   [(set (match_operand:AVXMODEDCVTPS2DQ 0 "register_operand" "=x")
2408         (fix:AVXMODEDCVTPS2DQ
2409           (match_operand:<avxcvtvecmode> 1 "nonimmediate_operand" "xm")))]
2410   "TARGET_AVX"
2411   "vcvttps2dq\t{%1, %0|%0, %1}"
2412   [(set_attr "type" "ssecvt")
2413    (set_attr "prefix" "vex")
2414    (set_attr "mode" "<avxvecmode>")])
2415
2416 (define_insn "sse2_cvttps2dq"
2417   [(set (match_operand:V4SI 0 "register_operand" "=x")
2418         (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
2419   "TARGET_SSE2"
2420   "cvttps2dq\t{%1, %0|%0, %1}"
2421   [(set_attr "type" "ssecvt")
2422    (set_attr "prefix_rep" "1")
2423    (set_attr "mode" "TI")])
2424
2425 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2426 ;;
2427 ;; Parallel double-precision floating point conversion operations
2428 ;;
2429 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2430
2431 (define_insn "sse2_cvtpi2pd"
2432   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
2433         (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "y,m")))]
2434   "TARGET_SSE2"
2435   "cvtpi2pd\t{%1, %0|%0, %1}"
2436   [(set_attr "type" "ssecvt")
2437    (set_attr "unit" "mmx,*")
2438    (set_attr "mode" "V2DF")])
2439
2440 (define_insn "sse2_cvtpd2pi"
2441   [(set (match_operand:V2SI 0 "register_operand" "=y")
2442         (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
2443                      UNSPEC_FIX_NOTRUNC))]
2444   "TARGET_SSE2"
2445   "cvtpd2pi\t{%1, %0|%0, %1}"
2446   [(set_attr "type" "ssecvt")
2447    (set_attr "unit" "mmx")
2448    (set_attr "prefix_data16" "1")
2449    (set_attr "mode" "DI")])
2450
2451 (define_insn "sse2_cvttpd2pi"
2452   [(set (match_operand:V2SI 0 "register_operand" "=y")
2453         (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
2454   "TARGET_SSE2"
2455   "cvttpd2pi\t{%1, %0|%0, %1}"
2456   [(set_attr "type" "ssecvt")
2457    (set_attr "unit" "mmx")
2458    (set_attr "prefix_data16" "1")
2459    (set_attr "mode" "TI")])
2460
2461 (define_insn "*avx_cvtsi2sd"
2462   [(set (match_operand:V2DF 0 "register_operand" "=x")
2463         (vec_merge:V2DF
2464           (vec_duplicate:V2DF
2465             (float:DF (match_operand:SI 2 "nonimmediate_operand" "rm")))
2466           (match_operand:V2DF 1 "register_operand" "x")
2467           (const_int 1)))]
2468   "TARGET_AVX"
2469   "vcvtsi2sd\t{%2, %1, %0|%0, %1, %2}"
2470   [(set_attr "type" "sseicvt")
2471    (set_attr "prefix" "vex")
2472    (set_attr "mode" "DF")])
2473
2474 (define_insn "sse2_cvtsi2sd"
2475   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
2476         (vec_merge:V2DF
2477           (vec_duplicate:V2DF
2478             (float:DF (match_operand:SI 2 "nonimmediate_operand" "r,m")))
2479           (match_operand:V2DF 1 "register_operand" "0,0")
2480           (const_int 1)))]
2481   "TARGET_SSE2"
2482   "cvtsi2sd\t{%2, %0|%0, %2}"
2483   [(set_attr "type" "sseicvt")
2484    (set_attr "mode" "DF")
2485    (set_attr "athlon_decode" "double,direct")
2486    (set_attr "amdfam10_decode" "vector,double")])
2487
2488 (define_insn "*avx_cvtsi2sdq"
2489   [(set (match_operand:V2DF 0 "register_operand" "=x")
2490         (vec_merge:V2DF
2491           (vec_duplicate:V2DF
2492             (float:DF (match_operand:DI 2 "nonimmediate_operand" "rm")))
2493           (match_operand:V2DF 1 "register_operand" "x")
2494           (const_int 1)))]
2495   "TARGET_AVX && TARGET_64BIT"
2496   "vcvtsi2sdq\t{%2, %1, %0|%0, %1, %2}"
2497   [(set_attr "type" "sseicvt")
2498    (set_attr "prefix" "vex")
2499    (set_attr "mode" "DF")])
2500
2501 (define_insn "sse2_cvtsi2sdq"
2502   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
2503         (vec_merge:V2DF
2504           (vec_duplicate:V2DF
2505             (float:DF (match_operand:DI 2 "nonimmediate_operand" "r,m")))
2506           (match_operand:V2DF 1 "register_operand" "0,0")
2507           (const_int 1)))]
2508   "TARGET_SSE2 && TARGET_64BIT"
2509   "cvtsi2sdq\t{%2, %0|%0, %2}"
2510   [(set_attr "type" "sseicvt")
2511    (set_attr "mode" "DF")
2512    (set_attr "athlon_decode" "double,direct")
2513    (set_attr "amdfam10_decode" "vector,double")])
2514
2515 (define_insn "sse2_cvtsd2si"
2516   [(set (match_operand:SI 0 "register_operand" "=r,r")
2517         (unspec:SI
2518           [(vec_select:DF
2519              (match_operand:V2DF 1 "nonimmediate_operand" "x,m")
2520              (parallel [(const_int 0)]))]
2521           UNSPEC_FIX_NOTRUNC))]
2522   "TARGET_SSE2"
2523   "%vcvtsd2si\t{%1, %0|%0, %1}"
2524   [(set_attr "type" "sseicvt")
2525    (set_attr "athlon_decode" "double,vector")
2526    (set_attr "prefix_rep" "1")
2527    (set_attr "prefix" "maybe_vex")
2528    (set_attr "mode" "SI")])
2529
2530 (define_insn "sse2_cvtsd2si_2"
2531   [(set (match_operand:SI 0 "register_operand" "=r,r")
2532         (unspec:SI [(match_operand:DF 1 "nonimmediate_operand" "x,m")]
2533                    UNSPEC_FIX_NOTRUNC))]
2534   "TARGET_SSE2"
2535   "%vcvtsd2si\t{%1, %0|%0, %1}"
2536   [(set_attr "type" "sseicvt")
2537    (set_attr "athlon_decode" "double,vector")
2538    (set_attr "amdfam10_decode" "double,double")
2539    (set_attr "prefix_rep" "1")
2540    (set_attr "prefix" "maybe_vex")
2541    (set_attr "mode" "SI")])
2542
2543 (define_insn "sse2_cvtsd2siq"
2544   [(set (match_operand:DI 0 "register_operand" "=r,r")
2545         (unspec:DI
2546           [(vec_select:DF
2547              (match_operand:V2DF 1 "nonimmediate_operand" "x,m")
2548              (parallel [(const_int 0)]))]
2549           UNSPEC_FIX_NOTRUNC))]
2550   "TARGET_SSE2 && TARGET_64BIT"
2551   "%vcvtsd2siq\t{%1, %0|%0, %1}"
2552   [(set_attr "type" "sseicvt")
2553    (set_attr "athlon_decode" "double,vector")
2554    (set_attr "prefix_rep" "1")
2555    (set_attr "prefix" "maybe_vex")
2556    (set_attr "mode" "DI")])
2557
2558 (define_insn "sse2_cvtsd2siq_2"
2559   [(set (match_operand:DI 0 "register_operand" "=r,r")
2560         (unspec:DI [(match_operand:DF 1 "nonimmediate_operand" "x,m")]
2561                    UNSPEC_FIX_NOTRUNC))]
2562   "TARGET_SSE2 && TARGET_64BIT"
2563   "%vcvtsd2siq\t{%1, %0|%0, %1}"
2564   [(set_attr "type" "sseicvt")
2565    (set_attr "athlon_decode" "double,vector")
2566    (set_attr "amdfam10_decode" "double,double")
2567    (set_attr "prefix_rep" "1")
2568    (set_attr "prefix" "maybe_vex")
2569    (set_attr "mode" "DI")])
2570
2571 (define_insn "sse2_cvttsd2si"
2572   [(set (match_operand:SI 0 "register_operand" "=r,r")
2573         (fix:SI
2574           (vec_select:DF
2575             (match_operand:V2DF 1 "nonimmediate_operand" "x,m")
2576             (parallel [(const_int 0)]))))]
2577   "TARGET_SSE2"
2578   "%vcvttsd2si\t{%1, %0|%0, %1}"
2579   [(set_attr "type" "sseicvt")
2580    (set_attr "prefix_rep" "1")
2581    (set_attr "prefix" "maybe_vex")
2582    (set_attr "mode" "SI")
2583    (set_attr "athlon_decode" "double,vector")
2584    (set_attr "amdfam10_decode" "double,double")])
2585
2586 (define_insn "sse2_cvttsd2siq"
2587   [(set (match_operand:DI 0 "register_operand" "=r,r")
2588         (fix:DI
2589           (vec_select:DF
2590             (match_operand:V2DF 1 "nonimmediate_operand" "x,m")
2591             (parallel [(const_int 0)]))))]
2592   "TARGET_SSE2 && TARGET_64BIT"
2593   "%vcvttsd2siq\t{%1, %0|%0, %1}"
2594   [(set_attr "type" "sseicvt")
2595    (set_attr "prefix_rep" "1")
2596    (set_attr "prefix" "maybe_vex")
2597    (set_attr "mode" "DI")
2598    (set_attr "athlon_decode" "double,vector")
2599    (set_attr "amdfam10_decode" "double,double")])
2600
2601 (define_insn "avx_cvtdq2pd256"
2602   [(set (match_operand:V4DF 0 "register_operand" "=x")
2603         (float:V4DF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
2604   "TARGET_AVX"
2605   "vcvtdq2pd\t{%1, %0|%0, %1}"
2606   [(set_attr "type" "ssecvt")
2607    (set_attr "prefix" "vex")
2608    (set_attr "mode" "V4DF")])
2609
2610 (define_insn "sse2_cvtdq2pd"
2611   [(set (match_operand:V2DF 0 "register_operand" "=x")
2612         (float:V2DF
2613           (vec_select:V2SI
2614             (match_operand:V4SI 1 "nonimmediate_operand" "xm")
2615             (parallel [(const_int 0) (const_int 1)]))))]
2616   "TARGET_SSE2"
2617   "%vcvtdq2pd\t{%1, %0|%0, %1}"
2618   [(set_attr "type" "ssecvt")
2619    (set_attr "prefix" "maybe_vex")
2620    (set_attr "mode" "V2DF")])
2621
2622 (define_insn "avx_cvtpd2dq256"
2623   [(set (match_operand:V4SI 0 "register_operand" "=x")
2624         (unspec:V4SI [(match_operand:V4DF 1 "nonimmediate_operand" "xm")]
2625                      UNSPEC_FIX_NOTRUNC))]
2626   "TARGET_AVX"
2627   "vcvtpd2dq{y}\t{%1, %0|%0, %1}"
2628   [(set_attr "type" "ssecvt")
2629    (set_attr "prefix" "vex")
2630    (set_attr "mode" "OI")])
2631
2632 (define_expand "sse2_cvtpd2dq"
2633   [(set (match_operand:V4SI 0 "register_operand" "")
2634         (vec_concat:V4SI
2635           (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "")]
2636                        UNSPEC_FIX_NOTRUNC)
2637           (match_dup 2)))]
2638   "TARGET_SSE2"
2639   "operands[2] = CONST0_RTX (V2SImode);")
2640
2641 (define_insn "*sse2_cvtpd2dq"
2642   [(set (match_operand:V4SI 0 "register_operand" "=x")
2643         (vec_concat:V4SI
2644           (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
2645                        UNSPEC_FIX_NOTRUNC)
2646           (match_operand:V2SI 2 "const0_operand" "")))]
2647   "TARGET_SSE2"
2648   "* return TARGET_AVX ? \"vcvtpd2dq{x}\t{%1, %0|%0, %1}\"
2649                        : \"cvtpd2dq\t{%1, %0|%0, %1}\";"
2650   [(set_attr "type" "ssecvt")
2651    (set_attr "prefix_rep" "1")
2652    (set_attr "prefix" "maybe_vex")
2653    (set_attr "mode" "TI")
2654    (set_attr "amdfam10_decode" "double")])
2655
2656 (define_insn "avx_cvttpd2dq256"
2657   [(set (match_operand:V4SI 0 "register_operand" "=x")
2658         (fix:V4SI (match_operand:V4DF 1 "nonimmediate_operand" "xm")))]
2659   "TARGET_AVX"
2660   "vcvttpd2dq{y}\t{%1, %0|%0, %1}"
2661   [(set_attr "type" "ssecvt")
2662    (set_attr "prefix" "vex")
2663    (set_attr "mode" "OI")])
2664
2665 (define_expand "sse2_cvttpd2dq"
2666   [(set (match_operand:V4SI 0 "register_operand" "")
2667         (vec_concat:V4SI
2668           (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" ""))
2669           (match_dup 2)))]
2670   "TARGET_SSE2"
2671   "operands[2] = CONST0_RTX (V2SImode);")
2672
2673 (define_insn "*sse2_cvttpd2dq"
2674   [(set (match_operand:V4SI 0 "register_operand" "=x")
2675         (vec_concat:V4SI
2676           (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
2677           (match_operand:V2SI 2 "const0_operand" "")))]
2678   "TARGET_SSE2"
2679   "* return TARGET_AVX ? \"vcvttpd2dq{x}\t{%1, %0|%0, %1}\"
2680                        : \"cvttpd2dq\t{%1, %0|%0, %1}\";"
2681   [(set_attr "type" "ssecvt")
2682    (set_attr "prefix_rep" "1")
2683    (set_attr "prefix" "maybe_vex")
2684    (set_attr "mode" "TI")
2685    (set_attr "amdfam10_decode" "double")])
2686
2687 (define_insn "*avx_cvtsd2ss"
2688   [(set (match_operand:V4SF 0 "register_operand" "=x")
2689         (vec_merge:V4SF
2690           (vec_duplicate:V4SF
2691             (float_truncate:V2SF
2692               (match_operand:V2DF 2 "nonimmediate_operand" "xm")))
2693           (match_operand:V4SF 1 "register_operand" "x")
2694           (const_int 1)))]
2695   "TARGET_AVX"
2696   "vcvtsd2ss\t{%2, %1, %0|%0, %1, %2}"
2697   [(set_attr "type" "ssecvt")
2698    (set_attr "prefix" "vex")
2699    (set_attr "mode" "SF")])
2700
2701 (define_insn "sse2_cvtsd2ss"
2702   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
2703         (vec_merge:V4SF
2704           (vec_duplicate:V4SF
2705             (float_truncate:V2SF
2706               (match_operand:V2DF 2 "nonimmediate_operand" "x,m")))
2707           (match_operand:V4SF 1 "register_operand" "0,0")
2708           (const_int 1)))]
2709   "TARGET_SSE2"
2710   "cvtsd2ss\t{%2, %0|%0, %2}"
2711   [(set_attr "type" "ssecvt")
2712    (set_attr "athlon_decode" "vector,double")
2713    (set_attr "amdfam10_decode" "vector,double")
2714    (set_attr "mode" "SF")])
2715
2716 (define_insn "*avx_cvtss2sd"
2717   [(set (match_operand:V2DF 0 "register_operand" "=x")
2718         (vec_merge:V2DF
2719           (float_extend:V2DF
2720             (vec_select:V2SF
2721               (match_operand:V4SF 2 "nonimmediate_operand" "xm")
2722               (parallel [(const_int 0) (const_int 1)])))
2723           (match_operand:V2DF 1 "register_operand" "x")
2724           (const_int 1)))]
2725   "TARGET_AVX"
2726   "vcvtss2sd\t{%2, %1, %0|%0, %1, %2}"
2727   [(set_attr "type" "ssecvt")
2728    (set_attr "prefix" "vex")
2729    (set_attr "mode" "DF")])
2730
2731 (define_insn "sse2_cvtss2sd"
2732   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
2733         (vec_merge:V2DF
2734           (float_extend:V2DF
2735             (vec_select:V2SF
2736               (match_operand:V4SF 2 "nonimmediate_operand" "x,m")
2737               (parallel [(const_int 0) (const_int 1)])))
2738           (match_operand:V2DF 1 "register_operand" "0,0")
2739           (const_int 1)))]
2740   "TARGET_SSE2"
2741   "cvtss2sd\t{%2, %0|%0, %2}"
2742   [(set_attr "type" "ssecvt")
2743    (set_attr "amdfam10_decode" "vector,double")
2744    (set_attr "mode" "DF")])
2745
2746 (define_insn "avx_cvtpd2ps256"
2747   [(set (match_operand:V4SF 0 "register_operand" "=x")
2748         (float_truncate:V4SF
2749           (match_operand:V4DF 1 "nonimmediate_operand" "xm")))]
2750   "TARGET_AVX"
2751   "vcvtpd2ps{y}\t{%1, %0|%0, %1}"
2752   [(set_attr "type" "ssecvt")
2753    (set_attr "prefix" "vex")
2754    (set_attr "mode" "V4SF")])
2755
2756 (define_expand "sse2_cvtpd2ps"
2757   [(set (match_operand:V4SF 0 "register_operand" "")
2758         (vec_concat:V4SF
2759           (float_truncate:V2SF
2760             (match_operand:V2DF 1 "nonimmediate_operand" ""))
2761           (match_dup 2)))]
2762   "TARGET_SSE2"
2763   "operands[2] = CONST0_RTX (V2SFmode);")
2764
2765 (define_insn "*sse2_cvtpd2ps"
2766   [(set (match_operand:V4SF 0 "register_operand" "=x")
2767         (vec_concat:V4SF
2768           (float_truncate:V2SF
2769             (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
2770           (match_operand:V2SF 2 "const0_operand" "")))]
2771   "TARGET_SSE2"
2772   "* return TARGET_AVX ? \"vcvtpd2ps{x}\t{%1, %0|%0, %1}\"
2773                        : \"cvtpd2ps\t{%1, %0|%0, %1}\";"
2774   [(set_attr "type" "ssecvt")
2775    (set_attr "prefix_data16" "1")
2776    (set_attr "prefix" "maybe_vex")
2777    (set_attr "mode" "V4SF")
2778    (set_attr "amdfam10_decode" "double")])
2779
2780 (define_insn "avx_cvtps2pd256"
2781   [(set (match_operand:V4DF 0 "register_operand" "=x")
2782         (float_extend:V4DF
2783           (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
2784   "TARGET_AVX"
2785   "vcvtps2pd\t{%1, %0|%0, %1}"
2786   [(set_attr "type" "ssecvt")
2787    (set_attr "prefix" "vex")
2788    (set_attr "mode" "V4DF")])
2789
2790 (define_insn "sse2_cvtps2pd"
2791   [(set (match_operand:V2DF 0 "register_operand" "=x")
2792         (float_extend:V2DF
2793           (vec_select:V2SF
2794             (match_operand:V4SF 1 "nonimmediate_operand" "xm")
2795             (parallel [(const_int 0) (const_int 1)]))))]
2796   "TARGET_SSE2"
2797   "%vcvtps2pd\t{%1, %0|%0, %1}"
2798   [(set_attr "type" "ssecvt")
2799    (set_attr "prefix" "maybe_vex")
2800    (set_attr "mode" "V2DF")
2801    (set_attr "amdfam10_decode" "direct")])
2802
2803 (define_expand "vec_unpacks_hi_v4sf"
2804   [(set (match_dup 2)
2805    (vec_select:V4SF
2806      (vec_concat:V8SF
2807        (match_dup 2)
2808        (match_operand:V4SF 1 "nonimmediate_operand" ""))
2809      (parallel [(const_int 6)
2810                 (const_int 7)
2811                 (const_int 2)
2812                 (const_int 3)])))
2813   (set (match_operand:V2DF 0 "register_operand" "")
2814    (float_extend:V2DF
2815      (vec_select:V2SF
2816        (match_dup 2)
2817        (parallel [(const_int 0) (const_int 1)]))))]
2818  "TARGET_SSE2"
2819 {
2820  operands[2] = gen_reg_rtx (V4SFmode);
2821 })
2822
2823 (define_expand "vec_unpacks_lo_v4sf"
2824   [(set (match_operand:V2DF 0 "register_operand" "")
2825         (float_extend:V2DF
2826           (vec_select:V2SF
2827             (match_operand:V4SF 1 "nonimmediate_operand" "")
2828             (parallel [(const_int 0) (const_int 1)]))))]
2829   "TARGET_SSE2")
2830
2831 (define_expand "vec_unpacks_float_hi_v8hi"
2832   [(match_operand:V4SF 0 "register_operand" "")
2833    (match_operand:V8HI 1 "register_operand" "")]
2834   "TARGET_SSE2"
2835 {
2836   rtx tmp = gen_reg_rtx (V4SImode);
2837
2838   emit_insn (gen_vec_unpacks_hi_v8hi (tmp, operands[1]));
2839   emit_insn (gen_sse2_cvtdq2ps (operands[0], tmp));
2840   DONE;
2841 })
2842
2843 (define_expand "vec_unpacks_float_lo_v8hi"
2844   [(match_operand:V4SF 0 "register_operand" "")
2845    (match_operand:V8HI 1 "register_operand" "")]
2846   "TARGET_SSE2"
2847 {
2848   rtx tmp = gen_reg_rtx (V4SImode);
2849
2850   emit_insn (gen_vec_unpacks_lo_v8hi (tmp, operands[1]));
2851   emit_insn (gen_sse2_cvtdq2ps (operands[0], tmp));
2852   DONE;
2853 })
2854
2855 (define_expand "vec_unpacku_float_hi_v8hi"
2856   [(match_operand:V4SF 0 "register_operand" "")
2857    (match_operand:V8HI 1 "register_operand" "")]
2858   "TARGET_SSE2"
2859 {
2860   rtx tmp = gen_reg_rtx (V4SImode);
2861
2862   emit_insn (gen_vec_unpacku_hi_v8hi (tmp, operands[1]));
2863   emit_insn (gen_sse2_cvtdq2ps (operands[0], tmp));
2864   DONE;
2865 })
2866
2867 (define_expand "vec_unpacku_float_lo_v8hi"
2868   [(match_operand:V4SF 0 "register_operand" "")
2869    (match_operand:V8HI 1 "register_operand" "")]
2870   "TARGET_SSE2"
2871 {
2872   rtx tmp = gen_reg_rtx (V4SImode);
2873
2874   emit_insn (gen_vec_unpacku_lo_v8hi (tmp, operands[1]));
2875   emit_insn (gen_sse2_cvtdq2ps (operands[0], tmp));
2876   DONE;
2877 })
2878
2879 (define_expand "vec_unpacks_float_hi_v4si"
2880   [(set (match_dup 2)
2881         (vec_select:V4SI
2882           (match_operand:V4SI 1 "nonimmediate_operand" "")
2883           (parallel [(const_int 2)
2884                      (const_int 3)
2885                      (const_int 2)
2886                      (const_int 3)])))
2887    (set (match_operand:V2DF 0 "register_operand" "")
2888         (float:V2DF
2889           (vec_select:V2SI
2890           (match_dup 2)
2891             (parallel [(const_int 0) (const_int 1)]))))]
2892  "TARGET_SSE2"
2893 {
2894  operands[2] = gen_reg_rtx (V4SImode);
2895 })
2896
2897 (define_expand "vec_unpacks_float_lo_v4si"
2898   [(set (match_operand:V2DF 0 "register_operand" "")
2899         (float:V2DF
2900           (vec_select:V2SI
2901             (match_operand:V4SI 1 "nonimmediate_operand" "")
2902             (parallel [(const_int 0) (const_int 1)]))))]
2903   "TARGET_SSE2")
2904
2905 (define_expand "vec_pack_trunc_v2df"
2906   [(match_operand:V4SF 0 "register_operand" "")
2907    (match_operand:V2DF 1 "nonimmediate_operand" "")
2908    (match_operand:V2DF 2 "nonimmediate_operand" "")]
2909   "TARGET_SSE2"
2910 {
2911   rtx r1, r2;
2912
2913   r1 = gen_reg_rtx (V4SFmode);
2914   r2 = gen_reg_rtx (V4SFmode);
2915
2916   emit_insn (gen_sse2_cvtpd2ps (r1, operands[1]));
2917   emit_insn (gen_sse2_cvtpd2ps (r2, operands[2]));
2918   emit_insn (gen_sse_movlhps (operands[0], r1, r2));
2919   DONE;
2920 })
2921
2922 (define_expand "vec_pack_sfix_trunc_v2df"
2923   [(match_operand:V4SI 0 "register_operand" "")
2924    (match_operand:V2DF 1 "nonimmediate_operand" "")
2925    (match_operand:V2DF 2 "nonimmediate_operand" "")]
2926   "TARGET_SSE2"
2927 {
2928   rtx r1, r2;
2929
2930   r1 = gen_reg_rtx (V4SImode);
2931   r2 = gen_reg_rtx (V4SImode);
2932
2933   emit_insn (gen_sse2_cvttpd2dq (r1, operands[1]));
2934   emit_insn (gen_sse2_cvttpd2dq (r2, operands[2]));
2935   emit_insn (gen_sse2_punpcklqdq (gen_lowpart (V2DImode, operands[0]),
2936                                   gen_lowpart (V2DImode, r1),
2937                                   gen_lowpart (V2DImode, r2)));
2938   DONE;
2939 })
2940
2941 (define_expand "vec_pack_sfix_v2df"
2942   [(match_operand:V4SI 0 "register_operand" "")
2943    (match_operand:V2DF 1 "nonimmediate_operand" "")
2944    (match_operand:V2DF 2 "nonimmediate_operand" "")]
2945   "TARGET_SSE2"
2946 {
2947   rtx r1, r2;
2948
2949   r1 = gen_reg_rtx (V4SImode);
2950   r2 = gen_reg_rtx (V4SImode);
2951
2952   emit_insn (gen_sse2_cvtpd2dq (r1, operands[1]));
2953   emit_insn (gen_sse2_cvtpd2dq (r2, operands[2]));
2954   emit_insn (gen_sse2_punpcklqdq (gen_lowpart (V2DImode, operands[0]),
2955                                   gen_lowpart (V2DImode, r1),
2956                                   gen_lowpart (V2DImode, r2)));
2957   DONE;
2958 })
2959
2960 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2961 ;;
2962 ;; Parallel single-precision floating point element swizzling
2963 ;;
2964 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2965
2966 (define_expand "sse_movhlps_exp"
2967   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
2968         (vec_select:V4SF
2969           (vec_concat:V8SF
2970             (match_operand:V4SF 1 "nonimmediate_operand" "")
2971             (match_operand:V4SF 2 "nonimmediate_operand" ""))
2972           (parallel [(const_int 6)
2973                      (const_int 7)
2974                      (const_int 2)
2975                      (const_int 3)])))]
2976   "TARGET_SSE"
2977   "ix86_fixup_binary_operands (UNKNOWN, V4SFmode, operands);")
2978
2979 (define_insn "*avx_movhlps"
2980   [(set (match_operand:V4SF 0 "nonimmediate_operand"     "=x,x,m")
2981         (vec_select:V4SF
2982           (vec_concat:V8SF
2983             (match_operand:V4SF 1 "nonimmediate_operand" " x,x,0")
2984             (match_operand:V4SF 2 "nonimmediate_operand" " x,o,x"))
2985           (parallel [(const_int 6)
2986                      (const_int 7)
2987                      (const_int 2)
2988                      (const_int 3)])))]
2989   "TARGET_AVX && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
2990   "@
2991    vmovhlps\t{%2, %1, %0|%0, %1, %2}
2992    vmovlps\t{%H2, %1, %0|%0, %1, %H2}
2993    vmovhps\t{%2, %0|%0, %2}"
2994   [(set_attr "type" "ssemov")
2995    (set_attr "prefix" "vex")
2996    (set_attr "mode" "V4SF,V2SF,V2SF")])
2997
2998 (define_insn "sse_movhlps"
2999   [(set (match_operand:V4SF 0 "nonimmediate_operand"     "=x,x,m")
3000         (vec_select:V4SF
3001           (vec_concat:V8SF
3002             (match_operand:V4SF 1 "nonimmediate_operand" " 0,0,0")
3003             (match_operand:V4SF 2 "nonimmediate_operand" " x,o,x"))
3004           (parallel [(const_int 6)
3005                      (const_int 7)
3006                      (const_int 2)
3007                      (const_int 3)])))]
3008   "TARGET_SSE && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
3009   "@
3010    movhlps\t{%2, %0|%0, %2}
3011    movlps\t{%H2, %0|%0, %H2}
3012    movhps\t{%2, %0|%0, %2}"
3013   [(set_attr "type" "ssemov")
3014    (set_attr "mode" "V4SF,V2SF,V2SF")])
3015
3016 (define_expand "sse_movlhps_exp"
3017   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
3018         (vec_select:V4SF
3019           (vec_concat:V8SF
3020             (match_operand:V4SF 1 "nonimmediate_operand" "")
3021             (match_operand:V4SF 2 "nonimmediate_operand" ""))
3022           (parallel [(const_int 0)
3023                      (const_int 1)
3024                      (const_int 4)
3025                      (const_int 5)])))]
3026   "TARGET_SSE"
3027   "ix86_fixup_binary_operands (UNKNOWN, V4SFmode, operands);")
3028
3029 (define_insn "*avx_movlhps"
3030   [(set (match_operand:V4SF 0 "nonimmediate_operand"     "=x,x,o")
3031         (vec_select:V4SF
3032           (vec_concat:V8SF
3033             (match_operand:V4SF 1 "nonimmediate_operand" " x,x,0")
3034             (match_operand:V4SF 2 "nonimmediate_operand" " x,m,x"))
3035           (parallel [(const_int 0)
3036                      (const_int 1)
3037                      (const_int 4)
3038                      (const_int 5)])))]
3039   "TARGET_AVX && ix86_binary_operator_ok (UNKNOWN, V4SFmode, operands)"
3040   "@
3041    vmovlhps\t{%2, %1, %0|%0, %1, %2}
3042    vmovhps\t{%2, %1, %0|%0, %1, %2}
3043    vmovlps\t{%2, %H0|%H0, %2}"
3044   [(set_attr "type" "ssemov")
3045    (set_attr "prefix" "vex")
3046    (set_attr "mode" "V4SF,V2SF,V2SF")])
3047
3048 (define_insn "sse_movlhps"
3049   [(set (match_operand:V4SF 0 "nonimmediate_operand"     "=x,x,o")
3050         (vec_select:V4SF
3051           (vec_concat:V8SF
3052             (match_operand:V4SF 1 "nonimmediate_operand" " 0,0,0")
3053             (match_operand:V4SF 2 "nonimmediate_operand" " x,m,x"))
3054           (parallel [(const_int 0)
3055                      (const_int 1)
3056                      (const_int 4)
3057                      (const_int 5)])))]
3058   "TARGET_SSE && ix86_binary_operator_ok (UNKNOWN, V4SFmode, operands)"
3059   "@
3060    movlhps\t{%2, %0|%0, %2}
3061    movhps\t{%2, %0|%0, %2}
3062    movlps\t{%2, %H0|%H0, %2}"
3063   [(set_attr "type" "ssemov")
3064    (set_attr "mode" "V4SF,V2SF,V2SF")])
3065
3066 (define_insn "avx_unpckhps256"
3067   [(set (match_operand:V8SF 0 "register_operand" "=x")
3068         (vec_select:V8SF
3069           (vec_concat:V16SF
3070             (match_operand:V8SF 1 "register_operand" "x")
3071             (match_operand:V8SF 2 "nonimmediate_operand" "xm"))
3072           (parallel [(const_int 2) (const_int 10)
3073                      (const_int 3) (const_int 11)
3074                      (const_int 6) (const_int 14)
3075                      (const_int 7) (const_int 15)])))]
3076   "TARGET_AVX"
3077   "vunpckhps\t{%2, %1, %0|%0, %1, %2}"
3078   [(set_attr "type" "sselog")
3079    (set_attr "prefix" "vex")
3080    (set_attr "mode" "V8SF")])
3081
3082 (define_insn "*avx_unpckhps"
3083   [(set (match_operand:V4SF 0 "register_operand" "=x")
3084         (vec_select:V4SF
3085           (vec_concat:V8SF
3086             (match_operand:V4SF 1 "register_operand" "x")
3087             (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
3088           (parallel [(const_int 2) (const_int 6)
3089                      (const_int 3) (const_int 7)])))]
3090   "TARGET_AVX"
3091   "vunpckhps\t{%2, %1, %0|%0, %1, %2}"
3092   [(set_attr "type" "sselog")
3093    (set_attr "prefix" "vex")
3094    (set_attr "mode" "V4SF")])
3095
3096 (define_insn "sse_unpckhps"
3097   [(set (match_operand:V4SF 0 "register_operand" "=x")
3098         (vec_select:V4SF
3099           (vec_concat:V8SF
3100             (match_operand:V4SF 1 "register_operand" "0")
3101             (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
3102           (parallel [(const_int 2) (const_int 6)
3103                      (const_int 3) (const_int 7)])))]
3104   "TARGET_SSE"
3105   "unpckhps\t{%2, %0|%0, %2}"
3106   [(set_attr "type" "sselog")
3107    (set_attr "mode" "V4SF")])
3108
3109 (define_insn "avx_unpcklps256"
3110   [(set (match_operand:V8SF 0 "register_operand" "=x")
3111         (vec_select:V8SF
3112           (vec_concat:V16SF
3113             (match_operand:V8SF 1 "register_operand" "x")
3114             (match_operand:V8SF 2 "nonimmediate_operand" "xm"))
3115           (parallel [(const_int 0) (const_int 8)
3116                      (const_int 1) (const_int 9)
3117                      (const_int 4) (const_int 12)
3118                      (const_int 5) (const_int 13)])))]
3119   "TARGET_AVX"
3120   "vunpcklps\t{%2, %1, %0|%0, %1, %2}"
3121   [(set_attr "type" "sselog")
3122    (set_attr "prefix" "vex")
3123    (set_attr "mode" "V8SF")])
3124
3125 (define_insn "*avx_unpcklps"
3126   [(set (match_operand:V4SF 0 "register_operand" "=x")
3127         (vec_select:V4SF
3128           (vec_concat:V8SF
3129             (match_operand:V4SF 1 "register_operand" "x")
3130             (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
3131           (parallel [(const_int 0) (const_int 4)
3132                      (const_int 1) (const_int 5)])))]
3133   "TARGET_AVX"
3134   "vunpcklps\t{%2, %1, %0|%0, %1, %2}"
3135   [(set_attr "type" "sselog")
3136    (set_attr "prefix" "vex")
3137    (set_attr "mode" "V4SF")])
3138
3139 (define_insn "sse_unpcklps"
3140   [(set (match_operand:V4SF 0 "register_operand" "=x")
3141         (vec_select:V4SF
3142           (vec_concat:V8SF
3143             (match_operand:V4SF 1 "register_operand" "0")
3144             (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
3145           (parallel [(const_int 0) (const_int 4)
3146                      (const_int 1) (const_int 5)])))]
3147   "TARGET_SSE"
3148   "unpcklps\t{%2, %0|%0, %2}"
3149   [(set_attr "type" "sselog")
3150    (set_attr "mode" "V4SF")])
3151
3152 ;; These are modeled with the same vec_concat as the others so that we
3153 ;; capture users of shufps that can use the new instructions
3154 (define_insn "avx_movshdup256"
3155   [(set (match_operand:V8SF 0 "register_operand" "=x")
3156         (vec_select:V8SF
3157           (vec_concat:V16SF
3158             (match_operand:V8SF 1 "nonimmediate_operand" "xm")
3159             (match_dup 1))
3160           (parallel [(const_int 1) (const_int 1)
3161                      (const_int 3) (const_int 3)
3162                      (const_int 5) (const_int 5)
3163                      (const_int 7) (const_int 7)])))]
3164   "TARGET_AVX"
3165   "vmovshdup\t{%1, %0|%0, %1}"
3166   [(set_attr "type" "sse")
3167    (set_attr "prefix" "vex")
3168    (set_attr "mode" "V8SF")])
3169
3170 (define_insn "sse3_movshdup"
3171   [(set (match_operand:V4SF 0 "register_operand" "=x")
3172         (vec_select:V4SF
3173           (vec_concat:V8SF
3174             (match_operand:V4SF 1 "nonimmediate_operand" "xm")
3175             (match_dup 1))
3176           (parallel [(const_int 1)
3177                      (const_int 1)
3178                      (const_int 7)
3179                      (const_int 7)])))]
3180   "TARGET_SSE3"
3181   "%vmovshdup\t{%1, %0|%0, %1}"
3182   [(set_attr "type" "sse")
3183    (set_attr "prefix_rep" "1")
3184    (set_attr "prefix" "maybe_vex")
3185    (set_attr "mode" "V4SF")])
3186
3187 (define_insn "avx_movsldup256"
3188   [(set (match_operand:V8SF 0 "register_operand" "=x")
3189         (vec_select:V8SF
3190           (vec_concat:V16SF
3191             (match_operand:V8SF 1 "nonimmediate_operand" "xm")
3192             (match_dup 1))
3193           (parallel [(const_int 0) (const_int 0)
3194                      (const_int 2) (const_int 2)
3195                      (const_int 4) (const_int 4)
3196                      (const_int 6) (const_int 6)])))]
3197   "TARGET_AVX"
3198   "vmovsldup\t{%1, %0|%0, %1}"
3199   [(set_attr "type" "sse")
3200    (set_attr "prefix" "vex")
3201    (set_attr "mode" "V8SF")])
3202
3203 (define_insn "sse3_movsldup"
3204   [(set (match_operand:V4SF 0 "register_operand" "=x")
3205         (vec_select:V4SF
3206           (vec_concat:V8SF
3207             (match_operand:V4SF 1 "nonimmediate_operand" "xm")
3208             (match_dup 1))
3209           (parallel [(const_int 0)
3210                      (const_int 0)
3211                      (const_int 6)
3212                      (const_int 6)])))]
3213   "TARGET_SSE3"
3214   "%vmovsldup\t{%1, %0|%0, %1}"
3215   [(set_attr "type" "sse")
3216    (set_attr "prefix_rep" "1")
3217    (set_attr "prefix" "maybe_vex")
3218    (set_attr "mode" "V4SF")])
3219
3220 (define_expand "avx_shufps256"
3221   [(match_operand:V8SF 0 "register_operand" "")
3222    (match_operand:V8SF 1 "register_operand" "")
3223    (match_operand:V8SF 2 "nonimmediate_operand" "")
3224    (match_operand:SI 3 "const_int_operand" "")]
3225   "TARGET_AVX"
3226 {
3227   int mask = INTVAL (operands[3]);
3228   emit_insn (gen_avx_shufps256_1 (operands[0], operands[1], operands[2],
3229                                   GEN_INT ((mask >> 0) & 3),
3230                                   GEN_INT ((mask >> 2) & 3),
3231                                   GEN_INT (((mask >> 4) & 3) + 8),
3232                                   GEN_INT (((mask >> 6) & 3) + 8),
3233                                   GEN_INT (((mask >> 0) & 3) + 4),
3234                                   GEN_INT (((mask >> 2) & 3) + 4),
3235                                   GEN_INT (((mask >> 4) & 3) + 12),
3236                                   GEN_INT (((mask >> 6) & 3) + 12)));
3237   DONE;
3238 })
3239
3240 ;; One bit in mask selects 2 elements.
3241 (define_insn "avx_shufps256_1"
3242   [(set (match_operand:V8SF 0 "register_operand" "=x")
3243         (vec_select:V8SF
3244           (vec_concat:V16SF
3245             (match_operand:V8SF 1 "register_operand" "x")
3246             (match_operand:V8SF 2 "nonimmediate_operand" "xm"))
3247           (parallel [(match_operand 3  "const_0_to_3_operand"   "")
3248                      (match_operand 4  "const_0_to_3_operand"   "")
3249                      (match_operand 5  "const_8_to_11_operand"  "")
3250                      (match_operand 6  "const_8_to_11_operand"  "")
3251                      (match_operand 7  "const_4_to_7_operand"   "")
3252                      (match_operand 8  "const_4_to_7_operand"   "")
3253                      (match_operand 9  "const_12_to_15_operand" "")
3254                      (match_operand 10 "const_12_to_15_operand" "")])))]
3255   "TARGET_AVX
3256    && (INTVAL (operands[3]) == (INTVAL (operands[7]) - 4)
3257        && INTVAL (operands[4]) == (INTVAL (operands[8]) - 4)
3258        && INTVAL (operands[5]) == (INTVAL (operands[9]) - 4)
3259        && INTVAL (operands[6]) == (INTVAL (operands[10]) - 4))"
3260 {
3261   int mask;
3262   mask = INTVAL (operands[3]);
3263   mask |= INTVAL (operands[4]) << 2;
3264   mask |= (INTVAL (operands[5]) - 8) << 4;
3265   mask |= (INTVAL (operands[6]) - 8) << 6;
3266   operands[3] = GEN_INT (mask);
3267
3268   return "vshufps\t{%3, %2, %1, %0|%0, %1, %2, %3}";
3269 }
3270   [(set_attr "type" "sselog")
3271    (set_attr "prefix" "vex")
3272    (set_attr "mode" "V8SF")])
3273
3274 (define_expand "sse_shufps"
3275   [(match_operand:V4SF 0 "register_operand" "")
3276    (match_operand:V4SF 1 "register_operand" "")
3277    (match_operand:V4SF 2 "nonimmediate_operand" "")
3278    (match_operand:SI 3 "const_int_operand" "")]
3279   "TARGET_SSE"
3280 {
3281   int mask = INTVAL (operands[3]);
3282   emit_insn (gen_sse_shufps_v4sf (operands[0], operands[1], operands[2],
3283                                GEN_INT ((mask >> 0) & 3),
3284                                GEN_INT ((mask >> 2) & 3),
3285                                GEN_INT (((mask >> 4) & 3) + 4),
3286                                GEN_INT (((mask >> 6) & 3) + 4)));
3287   DONE;
3288 })
3289
3290 (define_insn "*avx_shufps_<mode>"
3291   [(set (match_operand:SSEMODE4S 0 "register_operand" "=x")
3292         (vec_select:SSEMODE4S
3293           (vec_concat:<ssedoublesizemode>
3294             (match_operand:SSEMODE4S 1 "register_operand" "x")
3295             (match_operand:SSEMODE4S 2 "nonimmediate_operand" "xm"))
3296           (parallel [(match_operand 3 "const_0_to_3_operand" "")
3297                      (match_operand 4 "const_0_to_3_operand" "")
3298                      (match_operand 5 "const_4_to_7_operand" "")
3299                      (match_operand 6 "const_4_to_7_operand" "")])))]
3300   "TARGET_AVX"
3301 {
3302   int mask = 0;
3303   mask |= INTVAL (operands[3]) << 0;
3304   mask |= INTVAL (operands[4]) << 2;
3305   mask |= (INTVAL (operands[5]) - 4) << 4;
3306   mask |= (INTVAL (operands[6]) - 4) << 6;
3307   operands[3] = GEN_INT (mask);
3308
3309   return "vshufps\t{%3, %2, %1, %0|%0, %1, %2, %3}";
3310 }
3311   [(set_attr "type" "sselog")
3312    (set_attr "prefix" "vex")
3313    (set_attr "mode" "V4SF")])
3314
3315 (define_insn "sse_shufps_<mode>"
3316   [(set (match_operand:SSEMODE4S 0 "register_operand" "=x")
3317         (vec_select:SSEMODE4S
3318           (vec_concat:<ssedoublesizemode>
3319             (match_operand:SSEMODE4S 1 "register_operand" "0")
3320             (match_operand:SSEMODE4S 2 "nonimmediate_operand" "xm"))
3321           (parallel [(match_operand 3 "const_0_to_3_operand" "")
3322                      (match_operand 4 "const_0_to_3_operand" "")
3323                      (match_operand 5 "const_4_to_7_operand" "")
3324                      (match_operand 6 "const_4_to_7_operand" "")])))]
3325   "TARGET_SSE"
3326 {
3327   int mask = 0;
3328   mask |= INTVAL (operands[3]) << 0;
3329   mask |= INTVAL (operands[4]) << 2;
3330   mask |= (INTVAL (operands[5]) - 4) << 4;
3331   mask |= (INTVAL (operands[6]) - 4) << 6;
3332   operands[3] = GEN_INT (mask);
3333
3334   return "shufps\t{%3, %2, %0|%0, %2, %3}";
3335 }
3336   [(set_attr "type" "sselog")
3337    (set_attr "mode" "V4SF")])
3338
3339 (define_insn "sse_storehps"
3340   [(set (match_operand:V2SF 0 "nonimmediate_operand" "=m,x,x")
3341         (vec_select:V2SF
3342           (match_operand:V4SF 1 "nonimmediate_operand" "x,x,o")
3343           (parallel [(const_int 2) (const_int 3)])))]
3344   "TARGET_SSE"
3345   "@
3346    %vmovhps\t{%1, %0|%0, %1}
3347    %vmovhlps\t{%1, %d0|%d0, %1}
3348    %vmovlps\t{%H1, %d0|%d0, %H1}"
3349   [(set_attr "type" "ssemov")
3350    (set_attr "prefix" "maybe_vex")
3351    (set_attr "mode" "V2SF,V4SF,V2SF")])
3352
3353 (define_expand "sse_loadhps_exp"
3354   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
3355         (vec_concat:V4SF
3356           (vec_select:V2SF
3357             (match_operand:V4SF 1 "nonimmediate_operand" "")
3358             (parallel [(const_int 0) (const_int 1)]))
3359           (match_operand:V2SF 2 "nonimmediate_operand" "")))]
3360   "TARGET_SSE"
3361   "ix86_fixup_binary_operands (UNKNOWN, V4SFmode, operands);")
3362
3363 (define_insn "*avx_loadhps"
3364   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,o")
3365         (vec_concat:V4SF
3366           (vec_select:V2SF
3367             (match_operand:V4SF 1 "nonimmediate_operand" "x,x,0")
3368             (parallel [(const_int 0) (const_int 1)]))
3369           (match_operand:V2SF 2 "nonimmediate_operand" "m,x,x")))]
3370   "TARGET_AVX"
3371   "@
3372    vmovhps\t{%2, %1, %0|%0, %1, %2}
3373    vmovlhps\t{%2, %1, %0|%0, %1, %2}
3374    vmovlps\t{%2, %H0|%H0, %2}"