OSDN Git Service

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