OSDN Git Service

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