OSDN Git Service

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