]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/i386/mmx.md
Fix TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL handling.
[thirdparty/gcc.git] / gcc / config / i386 / mmx.md
1 ;; GCC machine description for MMX and 3dNOW! instructions
2 ;; Copyright (C) 2005-2020 Free Software Foundation, Inc.
3 ;;
4 ;; This file is part of GCC.
5 ;;
6 ;; GCC is free software; you can redistribute it and/or modify
7 ;; it under the terms of the GNU General Public License as published by
8 ;; the Free Software Foundation; either version 3, or (at your option)
9 ;; any later version.
10 ;;
11 ;; GCC is distributed in the hope that it will be useful,
12 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ;; GNU General Public License for more details.
15 ;;
16 ;; You should have received a copy of the GNU General Public License
17 ;; along with GCC; see the file COPYING3. If not see
18 ;; <http://www.gnu.org/licenses/>.
19
20 ;; The MMX and 3dNOW! patterns are in the same file because they use
21 ;; the same register file, and 3dNOW! adds a number of extensions to
22 ;; the base integer MMX isa.
23
24 ;; Note! Except for the basic move instructions, *all* of these
25 ;; patterns are outside the normal optabs namespace. This is because
26 ;; use of these registers requires the insertion of emms or femms
27 ;; instructions to return to normal fpu mode. The compiler doesn't
28 ;; know how to do that itself, which means it's up to the user. Which
29 ;; means that we should never use any of these patterns except at the
30 ;; direction of the user via a builtin.
31
32 (define_c_enum "unspec" [
33 UNSPEC_MOVNTQ
34 UNSPEC_PFRCP
35 UNSPEC_PFRCPIT1
36 UNSPEC_PFRCPIT2
37 UNSPEC_PFRSQRT
38 UNSPEC_PFRSQIT1
39 ])
40
41 (define_c_enum "unspecv" [
42 UNSPECV_EMMS
43 UNSPECV_FEMMS
44 ])
45
46 ;; 8 byte integral modes handled by MMX (and by extension, SSE)
47 (define_mode_iterator MMXMODEI [V8QI V4HI V2SI])
48 (define_mode_iterator MMXMODEI8 [V8QI V4HI V2SI (V1DI "TARGET_SSE2")])
49
50 ;; All 8-byte vector modes handled by MMX
51 (define_mode_iterator MMXMODE [V8QI V4HI V2SI V1DI V2SF])
52
53 ;; Mix-n-match
54 (define_mode_iterator MMXMODE12 [V8QI V4HI])
55 (define_mode_iterator MMXMODE24 [V4HI V2SI])
56 (define_mode_iterator MMXMODE248 [V4HI V2SI V1DI])
57
58 ;; Mapping from integer vector mode to mnemonic suffix
59 (define_mode_attr mmxvecsize [(V8QI "b") (V4HI "w") (V2SI "d") (V1DI "q")])
60
61 (define_mode_attr mmxdoublemode
62 [(V8QI "V8HI") (V4HI "V4SI")])
63
64 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
65 ;;
66 ;; Move patterns
67 ;;
68 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
69
70 ;; All of these patterns are enabled for MMX as well as 3dNOW.
71 ;; This is essential for maintaining stable calling conventions.
72
73 (define_expand "mov<mode>"
74 [(set (match_operand:MMXMODE 0 "nonimmediate_operand")
75 (match_operand:MMXMODE 1 "nonimmediate_operand"))]
76 "TARGET_MMX || TARGET_MMX_WITH_SSE"
77 {
78 ix86_expand_vector_move (<MODE>mode, operands);
79 DONE;
80 })
81
82 (define_insn "*mov<mode>_internal"
83 [(set (match_operand:MMXMODE 0 "nonimmediate_operand"
84 "=r ,o ,r,r ,m ,?!y,!y,?!y,m ,r ,?!y,v,v,v,m,r,v,!y,*x")
85 (match_operand:MMXMODE 1 "nonimm_or_0_operand"
86 "rCo,rC,C,rm,rC,C ,!y,m ,?!y,?!y,r ,C,v,m,v,v,r,*x,!y"))]
87 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
88 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
89 {
90 switch (get_attr_type (insn))
91 {
92 case TYPE_MULTI:
93 return "#";
94
95 case TYPE_IMOV:
96 if (get_attr_mode (insn) == MODE_SI)
97 return "mov{l}\t{%1, %k0|%k0, %1}";
98 else
99 return "mov{q}\t{%1, %0|%0, %1}";
100
101 case TYPE_MMX:
102 return "pxor\t%0, %0";
103
104 case TYPE_MMXMOV:
105 /* Handle broken assemblers that require movd instead of movq. */
106 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
107 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
108 return "movd\t{%1, %0|%0, %1}";
109 return "movq\t{%1, %0|%0, %1}";
110
111 case TYPE_SSECVT:
112 if (SSE_REG_P (operands[0]))
113 return "movq2dq\t{%1, %0|%0, %1}";
114 else
115 return "movdq2q\t{%1, %0|%0, %1}";
116
117 case TYPE_SSELOG1:
118 return standard_sse_constant_opcode (insn, operands);
119
120 case TYPE_SSEMOV:
121 switch (get_attr_mode (insn))
122 {
123 case MODE_DI:
124 /* Handle broken assemblers that require movd instead of movq. */
125 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
126 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
127 return "%vmovd\t{%1, %0|%0, %1}";
128 return "%vmovq\t{%1, %0|%0, %1}";
129 case MODE_TI:
130 return "%vmovdqa\t{%1, %0|%0, %1}";
131 case MODE_XI:
132 return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
133
134 case MODE_V2SF:
135 if (TARGET_AVX && REG_P (operands[0]))
136 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
137 return "%vmovlps\t{%1, %0|%0, %1}";
138 case MODE_V4SF:
139 return "%vmovaps\t{%1, %0|%0, %1}";
140
141 default:
142 gcc_unreachable ();
143 }
144
145 default:
146 gcc_unreachable ();
147 }
148 }
149 [(set (attr "isa")
150 (cond [(eq_attr "alternative" "0,1")
151 (const_string "nox64")
152 (eq_attr "alternative" "2,3,4,9,10")
153 (const_string "x64")
154 (eq_attr "alternative" "15,16")
155 (const_string "x64_sse2")
156 (eq_attr "alternative" "17,18")
157 (const_string "sse2")
158 ]
159 (const_string "*")))
160 (set (attr "type")
161 (cond [(eq_attr "alternative" "0,1")
162 (const_string "multi")
163 (eq_attr "alternative" "2,3,4")
164 (const_string "imov")
165 (eq_attr "alternative" "5")
166 (const_string "mmx")
167 (eq_attr "alternative" "6,7,8,9,10")
168 (const_string "mmxmov")
169 (eq_attr "alternative" "11")
170 (const_string "sselog1")
171 (eq_attr "alternative" "17,18")
172 (const_string "ssecvt")
173 ]
174 (const_string "ssemov")))
175 (set (attr "prefix_rex")
176 (if_then_else (eq_attr "alternative" "9,10,15,16")
177 (const_string "1")
178 (const_string "*")))
179 (set (attr "prefix")
180 (if_then_else (eq_attr "type" "sselog1,ssemov")
181 (const_string "maybe_vex")
182 (const_string "orig")))
183 (set (attr "prefix_data16")
184 (if_then_else
185 (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
186 (const_string "1")
187 (const_string "*")))
188 (set (attr "mode")
189 (cond [(eq_attr "alternative" "2")
190 (const_string "SI")
191 (eq_attr "alternative" "11,12")
192 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
193 (match_operand 1 "ext_sse_reg_operand"))
194 (const_string "XI")
195 (match_test "<MODE>mode == V2SFmode")
196 (const_string "V4SF")
197 (ior (not (match_test "TARGET_SSE2"))
198 (match_test "optimize_function_for_size_p (cfun)"))
199 (const_string "V4SF")
200 ]
201 (const_string "TI"))
202
203 (and (eq_attr "alternative" "13,14")
204 (ior (match_test "<MODE>mode == V2SFmode")
205 (not (match_test "TARGET_SSE2"))))
206 (const_string "V2SF")
207 ]
208 (const_string "DI")))
209 (set (attr "preferred_for_speed")
210 (cond [(eq_attr "alternative" "9,15")
211 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
212 (eq_attr "alternative" "10,16")
213 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
214 ]
215 (symbol_ref "true")))])
216
217 (define_split
218 [(set (match_operand:MMXMODE 0 "nonimmediate_gr_operand")
219 (match_operand:MMXMODE 1 "nonimmediate_gr_operand"))]
220 "!TARGET_64BIT && reload_completed"
221 [(const_int 0)]
222 "ix86_split_long_move (operands); DONE;")
223
224 (define_split
225 [(set (match_operand:MMXMODE 0 "nonimmediate_gr_operand")
226 (match_operand:MMXMODE 1 "const0_operand"))]
227 "!TARGET_64BIT && reload_completed"
228 [(const_int 0)]
229 "ix86_split_long_move (operands); DONE;")
230
231 (define_expand "movmisalign<mode>"
232 [(set (match_operand:MMXMODE 0 "nonimmediate_operand")
233 (match_operand:MMXMODE 1 "nonimmediate_operand"))]
234 "TARGET_MMX || TARGET_MMX_WITH_SSE"
235 {
236 ix86_expand_vector_move (<MODE>mode, operands);
237 DONE;
238 })
239
240 (define_insn "sse_movntq"
241 [(set (match_operand:DI 0 "memory_operand" "=m,m")
242 (unspec:DI [(match_operand:DI 1 "register_operand" "y,r")]
243 UNSPEC_MOVNTQ))]
244 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
245 && (TARGET_SSE || TARGET_3DNOW_A)"
246 "@
247 movntq\t{%1, %0|%0, %1}
248 movnti\t{%1, %0|%0, %1}"
249 [(set_attr "isa" "*,x64")
250 (set_attr "mmx_isa" "native,*")
251 (set_attr "type" "mmxmov,ssemov")
252 (set_attr "mode" "DI")])
253
254 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
255 ;;
256 ;; Parallel single-precision floating point arithmetic
257 ;;
258 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
259
260 (define_expand "mmx_addv2sf3"
261 [(set (match_operand:V2SF 0 "register_operand")
262 (plus:V2SF
263 (match_operand:V2SF 1 "nonimmediate_operand")
264 (match_operand:V2SF 2 "nonimmediate_operand")))]
265 "TARGET_3DNOW"
266 "ix86_fixup_binary_operands_no_copy (PLUS, V2SFmode, operands);")
267
268 (define_insn "*mmx_addv2sf3"
269 [(set (match_operand:V2SF 0 "register_operand" "=y")
270 (plus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
271 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
272 "TARGET_3DNOW && ix86_binary_operator_ok (PLUS, V2SFmode, operands)"
273 "pfadd\t{%2, %0|%0, %2}"
274 [(set_attr "type" "mmxadd")
275 (set_attr "prefix_extra" "1")
276 (set_attr "mode" "V2SF")])
277
278 (define_expand "mmx_subv2sf3"
279 [(set (match_operand:V2SF 0 "register_operand")
280 (minus:V2SF (match_operand:V2SF 1 "register_operand")
281 (match_operand:V2SF 2 "nonimmediate_operand")))]
282 "TARGET_3DNOW")
283
284 (define_expand "mmx_subrv2sf3"
285 [(set (match_operand:V2SF 0 "register_operand")
286 (minus:V2SF (match_operand:V2SF 2 "register_operand")
287 (match_operand:V2SF 1 "nonimmediate_operand")))]
288 "TARGET_3DNOW")
289
290 (define_insn "*mmx_subv2sf3"
291 [(set (match_operand:V2SF 0 "register_operand" "=y,y")
292 (minus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "0,ym")
293 (match_operand:V2SF 2 "nonimmediate_operand" "ym,0")))]
294 "TARGET_3DNOW && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
295 "@
296 pfsub\t{%2, %0|%0, %2}
297 pfsubr\t{%1, %0|%0, %1}"
298 [(set_attr "type" "mmxadd")
299 (set_attr "prefix_extra" "1")
300 (set_attr "mode" "V2SF")])
301
302 (define_expand "mmx_mulv2sf3"
303 [(set (match_operand:V2SF 0 "register_operand")
304 (mult:V2SF (match_operand:V2SF 1 "nonimmediate_operand")
305 (match_operand:V2SF 2 "nonimmediate_operand")))]
306 "TARGET_3DNOW"
307 "ix86_fixup_binary_operands_no_copy (MULT, V2SFmode, operands);")
308
309 (define_insn "*mmx_mulv2sf3"
310 [(set (match_operand:V2SF 0 "register_operand" "=y")
311 (mult:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
312 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
313 "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V2SFmode, operands)"
314 "pfmul\t{%2, %0|%0, %2}"
315 [(set_attr "type" "mmxmul")
316 (set_attr "prefix_extra" "1")
317 (set_attr "mode" "V2SF")])
318
319 (define_expand "mmx_<code>v2sf3"
320 [(set (match_operand:V2SF 0 "register_operand")
321 (smaxmin:V2SF
322 (match_operand:V2SF 1 "nonimmediate_operand")
323 (match_operand:V2SF 2 "nonimmediate_operand")))]
324 "TARGET_3DNOW"
325 {
326 if (!flag_finite_math_only || flag_signed_zeros)
327 {
328 operands[1] = force_reg (V2SFmode, operands[1]);
329 emit_insn (gen_mmx_ieee_<maxmin_float>v2sf3
330 (operands[0], operands[1], operands[2]));
331 DONE;
332 }
333 else
334 ix86_fixup_binary_operands_no_copy (<CODE>, V2SFmode, operands);
335 })
336
337 ;; These versions of the min/max patterns are intentionally ignorant of
338 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
339 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
340 ;; are undefined in this condition, we're certain this is correct.
341
342 (define_insn "*mmx_<code>v2sf3"
343 [(set (match_operand:V2SF 0 "register_operand" "=y")
344 (smaxmin:V2SF
345 (match_operand:V2SF 1 "nonimmediate_operand" "%0")
346 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
347 "TARGET_3DNOW && ix86_binary_operator_ok (<CODE>, V2SFmode, operands)"
348 "pf<maxmin_float>\t{%2, %0|%0, %2}"
349 [(set_attr "type" "mmxadd")
350 (set_attr "prefix_extra" "1")
351 (set_attr "mode" "V2SF")])
352
353 ;; These versions of the min/max patterns implement exactly the operations
354 ;; min = (op1 < op2 ? op1 : op2)
355 ;; max = (!(op1 < op2) ? op1 : op2)
356 ;; Their operands are not commutative, and thus they may be used in the
357 ;; presence of -0.0 and NaN.
358
359 (define_insn "mmx_ieee_<ieee_maxmin>v2sf3"
360 [(set (match_operand:V2SF 0 "register_operand" "=y")
361 (unspec:V2SF
362 [(match_operand:V2SF 1 "register_operand" "0")
363 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
364 IEEE_MAXMIN))]
365 "TARGET_3DNOW"
366 "pf<ieee_maxmin>\t{%2, %0|%0, %2}"
367 [(set_attr "type" "mmxadd")
368 (set_attr "prefix_extra" "1")
369 (set_attr "mode" "V2SF")])
370
371 (define_insn "mmx_rcpv2sf2"
372 [(set (match_operand:V2SF 0 "register_operand" "=y")
373 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
374 UNSPEC_PFRCP))]
375 "TARGET_3DNOW"
376 "pfrcp\t{%1, %0|%0, %1}"
377 [(set_attr "type" "mmx")
378 (set_attr "prefix_extra" "1")
379 (set_attr "mode" "V2SF")])
380
381 (define_insn "mmx_rcpit1v2sf3"
382 [(set (match_operand:V2SF 0 "register_operand" "=y")
383 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
384 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
385 UNSPEC_PFRCPIT1))]
386 "TARGET_3DNOW"
387 "pfrcpit1\t{%2, %0|%0, %2}"
388 [(set_attr "type" "mmx")
389 (set_attr "prefix_extra" "1")
390 (set_attr "mode" "V2SF")])
391
392 (define_insn "mmx_rcpit2v2sf3"
393 [(set (match_operand:V2SF 0 "register_operand" "=y")
394 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
395 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
396 UNSPEC_PFRCPIT2))]
397 "TARGET_3DNOW"
398 "pfrcpit2\t{%2, %0|%0, %2}"
399 [(set_attr "type" "mmx")
400 (set_attr "prefix_extra" "1")
401 (set_attr "mode" "V2SF")])
402
403 (define_insn "mmx_rsqrtv2sf2"
404 [(set (match_operand:V2SF 0 "register_operand" "=y")
405 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
406 UNSPEC_PFRSQRT))]
407 "TARGET_3DNOW"
408 "pfrsqrt\t{%1, %0|%0, %1}"
409 [(set_attr "type" "mmx")
410 (set_attr "prefix_extra" "1")
411 (set_attr "mode" "V2SF")])
412
413 (define_insn "mmx_rsqit1v2sf3"
414 [(set (match_operand:V2SF 0 "register_operand" "=y")
415 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
416 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
417 UNSPEC_PFRSQIT1))]
418 "TARGET_3DNOW"
419 "pfrsqit1\t{%2, %0|%0, %2}"
420 [(set_attr "type" "mmx")
421 (set_attr "prefix_extra" "1")
422 (set_attr "mode" "V2SF")])
423
424 (define_insn "mmx_haddv2sf3"
425 [(set (match_operand:V2SF 0 "register_operand" "=y")
426 (vec_concat:V2SF
427 (plus:SF
428 (vec_select:SF
429 (match_operand:V2SF 1 "register_operand" "0")
430 (parallel [(const_int 0)]))
431 (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
432 (plus:SF
433 (vec_select:SF
434 (match_operand:V2SF 2 "nonimmediate_operand" "ym")
435 (parallel [(const_int 0)]))
436 (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
437 "TARGET_3DNOW"
438 "pfacc\t{%2, %0|%0, %2}"
439 [(set_attr "type" "mmxadd")
440 (set_attr "prefix_extra" "1")
441 (set_attr "mode" "V2SF")])
442
443 (define_insn "mmx_hsubv2sf3"
444 [(set (match_operand:V2SF 0 "register_operand" "=y")
445 (vec_concat:V2SF
446 (minus:SF
447 (vec_select:SF
448 (match_operand:V2SF 1 "register_operand" "0")
449 (parallel [(const_int 0)]))
450 (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
451 (minus:SF
452 (vec_select:SF
453 (match_operand:V2SF 2 "nonimmediate_operand" "ym")
454 (parallel [(const_int 0)]))
455 (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
456 "TARGET_3DNOW_A"
457 "pfnacc\t{%2, %0|%0, %2}"
458 [(set_attr "type" "mmxadd")
459 (set_attr "prefix_extra" "1")
460 (set_attr "mode" "V2SF")])
461
462 (define_insn "mmx_addsubv2sf3"
463 [(set (match_operand:V2SF 0 "register_operand" "=y")
464 (vec_merge:V2SF
465 (plus:V2SF
466 (match_operand:V2SF 1 "register_operand" "0")
467 (match_operand:V2SF 2 "nonimmediate_operand" "ym"))
468 (minus:V2SF (match_dup 1) (match_dup 2))
469 (const_int 1)))]
470 "TARGET_3DNOW_A"
471 "pfpnacc\t{%2, %0|%0, %2}"
472 [(set_attr "type" "mmxadd")
473 (set_attr "prefix_extra" "1")
474 (set_attr "mode" "V2SF")])
475
476 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
477 ;;
478 ;; Parallel single-precision floating point comparisons
479 ;;
480 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
481
482 (define_expand "mmx_eqv2sf3"
483 [(set (match_operand:V2SI 0 "register_operand")
484 (eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand")
485 (match_operand:V2SF 2 "nonimmediate_operand")))]
486 "TARGET_3DNOW"
487 "ix86_fixup_binary_operands_no_copy (EQ, V2SFmode, operands);")
488
489 (define_insn "*mmx_eqv2sf3"
490 [(set (match_operand:V2SI 0 "register_operand" "=y")
491 (eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "%0")
492 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
493 "TARGET_3DNOW && ix86_binary_operator_ok (EQ, V2SFmode, operands)"
494 "pfcmpeq\t{%2, %0|%0, %2}"
495 [(set_attr "type" "mmxcmp")
496 (set_attr "prefix_extra" "1")
497 (set_attr "mode" "V2SF")])
498
499 (define_insn "mmx_gtv2sf3"
500 [(set (match_operand:V2SI 0 "register_operand" "=y")
501 (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
502 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
503 "TARGET_3DNOW"
504 "pfcmpgt\t{%2, %0|%0, %2}"
505 [(set_attr "type" "mmxcmp")
506 (set_attr "prefix_extra" "1")
507 (set_attr "mode" "V2SF")])
508
509 (define_insn "mmx_gev2sf3"
510 [(set (match_operand:V2SI 0 "register_operand" "=y")
511 (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
512 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
513 "TARGET_3DNOW"
514 "pfcmpge\t{%2, %0|%0, %2}"
515 [(set_attr "type" "mmxcmp")
516 (set_attr "prefix_extra" "1")
517 (set_attr "mode" "V2SF")])
518
519 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
520 ;;
521 ;; Parallel single-precision floating point conversion operations
522 ;;
523 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
524
525 (define_insn "mmx_pf2id"
526 [(set (match_operand:V2SI 0 "register_operand" "=y")
527 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
528 "TARGET_3DNOW"
529 "pf2id\t{%1, %0|%0, %1}"
530 [(set_attr "type" "mmxcvt")
531 (set_attr "prefix_extra" "1")
532 (set_attr "mode" "V2SF")])
533
534 (define_insn "mmx_pf2iw"
535 [(set (match_operand:V2SI 0 "register_operand" "=y")
536 (sign_extend:V2SI
537 (ss_truncate:V2HI
538 (fix:V2SI
539 (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
540 "TARGET_3DNOW_A"
541 "pf2iw\t{%1, %0|%0, %1}"
542 [(set_attr "type" "mmxcvt")
543 (set_attr "prefix_extra" "1")
544 (set_attr "mode" "V2SF")])
545
546 (define_insn "mmx_pi2fw"
547 [(set (match_operand:V2SF 0 "register_operand" "=y")
548 (float:V2SF
549 (sign_extend:V2SI
550 (truncate:V2HI
551 (match_operand:V2SI 1 "nonimmediate_operand" "ym")))))]
552 "TARGET_3DNOW_A"
553 "pi2fw\t{%1, %0|%0, %1}"
554 [(set_attr "type" "mmxcvt")
555 (set_attr "prefix_extra" "1")
556 (set_attr "mode" "V2SF")])
557
558 (define_insn "mmx_floatv2si2"
559 [(set (match_operand:V2SF 0 "register_operand" "=y")
560 (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
561 "TARGET_3DNOW"
562 "pi2fd\t{%1, %0|%0, %1}"
563 [(set_attr "type" "mmxcvt")
564 (set_attr "prefix_extra" "1")
565 (set_attr "mode" "V2SF")])
566
567 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
568 ;;
569 ;; Parallel single-precision floating point element swizzling
570 ;;
571 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
572
573 (define_insn "mmx_pswapdv2sf2"
574 [(set (match_operand:V2SF 0 "register_operand" "=y")
575 (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
576 (parallel [(const_int 1) (const_int 0)])))]
577 "TARGET_3DNOW_A"
578 "pswapd\t{%1, %0|%0, %1}"
579 [(set_attr "type" "mmxcvt")
580 (set_attr "prefix_extra" "1")
581 (set_attr "mode" "V2SF")])
582
583 (define_insn_and_split "*vec_dupv2sf"
584 [(set (match_operand:V2SF 0 "register_operand" "=y,x,Yv")
585 (vec_duplicate:V2SF
586 (match_operand:SF 1 "register_operand" "0,0,Yv")))]
587 "TARGET_MMX || TARGET_MMX_WITH_SSE"
588 "@
589 punpckldq\t%0, %0
590 #
591 #"
592 "TARGET_SSE && reload_completed
593 && SSE_REGNO_P (REGNO (operands[0]))"
594 [(set (match_dup 0)
595 (vec_duplicate:V4SF (match_dup 1)))]
596 {
597 operands[0] = lowpart_subreg (V4SFmode, operands[0],
598 GET_MODE (operands[0]));
599 }
600 [(set_attr "isa" "*,sse_noavx,avx")
601 (set_attr "mmx_isa" "native,*,*")
602 (set_attr "type" "mmxcvt,ssemov,ssemov")
603 (set_attr "mode" "DI,TI,TI")])
604
605 (define_insn "*mmx_concatv2sf"
606 [(set (match_operand:V2SF 0 "register_operand" "=y,y")
607 (vec_concat:V2SF
608 (match_operand:SF 1 "nonimmediate_operand" " 0,rm")
609 (match_operand:SF 2 "nonimm_or_0_operand" "ym,C")))]
610 "TARGET_MMX && !TARGET_SSE"
611 "@
612 punpckldq\t{%2, %0|%0, %2}
613 movd\t{%1, %0|%0, %1}"
614 [(set_attr "type" "mmxcvt,mmxmov")
615 (set_attr "mode" "DI")])
616
617 (define_expand "vec_setv2sf"
618 [(match_operand:V2SF 0 "register_operand")
619 (match_operand:SF 1 "register_operand")
620 (match_operand 2 "const_int_operand")]
621 "TARGET_MMX || TARGET_MMX_WITH_SSE"
622 {
623 ix86_expand_vector_set (TARGET_MMX_WITH_SSE, operands[0], operands[1],
624 INTVAL (operands[2]));
625 DONE;
626 })
627
628 ;; Avoid combining registers from different units in a single alternative,
629 ;; see comment above inline_secondary_memory_needed function in i386.c
630 (define_insn_and_split "*vec_extractv2sf_0"
631 [(set (match_operand:SF 0 "nonimmediate_operand" "=x, m,y ,m,f,r")
632 (vec_select:SF
633 (match_operand:V2SF 1 "nonimmediate_operand" " xm,x,ym,y,m,m")
634 (parallel [(const_int 0)])))]
635 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
636 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
637 "#"
638 "&& reload_completed"
639 [(set (match_dup 0) (match_dup 1))]
640 "operands[1] = gen_lowpart (SFmode, operands[1]);"
641 [(set_attr "mmx_isa" "*,*,native,native,*,*")])
642
643 ;; Avoid combining registers from different units in a single alternative,
644 ;; see comment above inline_secondary_memory_needed function in i386.c
645 (define_insn "*vec_extractv2sf_1"
646 [(set (match_operand:SF 0 "nonimmediate_operand" "=y,x,x,y,x,f,r")
647 (vec_select:SF
648 (match_operand:V2SF 1 "nonimmediate_operand" " 0,x,x,o,o,o,o")
649 (parallel [(const_int 1)])))]
650 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
651 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
652 "@
653 punpckhdq\t%0, %0
654 %vmovshdup\t{%1, %0|%0, %1}
655 shufps\t{$0xe5, %1, %0|%0, %1, 0xe5}
656 #
657 #
658 #
659 #"
660 [(set_attr "isa" "*,sse3,noavx,*,*,*,*")
661 (set_attr "mmx_isa" "native,*,*,native,*,*,*")
662 (set_attr "type" "mmxcvt,sse,sseshuf1,mmxmov,ssemov,fmov,imov")
663 (set (attr "length_immediate")
664 (if_then_else (eq_attr "alternative" "2")
665 (const_string "1")
666 (const_string "*")))
667 (set (attr "prefix_rep")
668 (if_then_else (eq_attr "alternative" "1")
669 (const_string "1")
670 (const_string "*")))
671 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig,orig,orig")
672 (set_attr "mode" "DI,V4SF,V4SF,SF,SF,SF,SF")])
673
674 (define_split
675 [(set (match_operand:SF 0 "register_operand")
676 (vec_select:SF
677 (match_operand:V2SF 1 "memory_operand")
678 (parallel [(const_int 1)])))]
679 "(TARGET_MMX || TARGET_MMX_WITH_SSE) && reload_completed"
680 [(set (match_dup 0) (match_dup 1))]
681 "operands[1] = adjust_address (operands[1], SFmode, 4);")
682
683 (define_expand "vec_extractv2sfsf"
684 [(match_operand:SF 0 "register_operand")
685 (match_operand:V2SF 1 "register_operand")
686 (match_operand 2 "const_int_operand")]
687 "TARGET_MMX || TARGET_MMX_WITH_SSE"
688 {
689 ix86_expand_vector_extract (TARGET_MMX_WITH_SSE, operands[0],
690 operands[1], INTVAL (operands[2]));
691 DONE;
692 })
693
694 (define_expand "vec_initv2sfsf"
695 [(match_operand:V2SF 0 "register_operand")
696 (match_operand 1)]
697 "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_SSE"
698 {
699 ix86_expand_vector_init (TARGET_MMX_WITH_SSE, operands[0],
700 operands[1]);
701 DONE;
702 })
703
704 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
705 ;;
706 ;; Parallel integral arithmetic
707 ;;
708 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
709
710 (define_expand "mmx_<plusminus_insn><mode>3"
711 [(set (match_operand:MMXMODEI8 0 "register_operand")
712 (plusminus:MMXMODEI8
713 (match_operand:MMXMODEI8 1 "register_mmxmem_operand")
714 (match_operand:MMXMODEI8 2 "register_mmxmem_operand")))]
715 "TARGET_MMX || TARGET_MMX_WITH_SSE"
716 "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
717
718 (define_expand "<plusminus_insn><mode>3"
719 [(set (match_operand:MMXMODEI 0 "register_operand")
720 (plusminus:MMXMODEI
721 (match_operand:MMXMODEI 1 "register_operand")
722 (match_operand:MMXMODEI 2 "register_operand")))]
723 "TARGET_MMX_WITH_SSE"
724 "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
725
726 (define_insn "*mmx_<plusminus_insn><mode>3"
727 [(set (match_operand:MMXMODEI8 0 "register_operand" "=y,x,Yv")
728 (plusminus:MMXMODEI8
729 (match_operand:MMXMODEI8 1 "register_mmxmem_operand" "<comm>0,0,Yv")
730 (match_operand:MMXMODEI8 2 "register_mmxmem_operand" "ym,x,Yv")))]
731 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
732 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
733 "@
734 p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}
735 p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}
736 vp<plusminus_mnemonic><mmxvecsize>\t{%2, %1, %0|%0, %1, %2}"
737 [(set_attr "isa" "*,sse2_noavx,avx")
738 (set_attr "mmx_isa" "native,*,*")
739 (set_attr "type" "mmxadd,sseadd,sseadd")
740 (set_attr "mode" "DI,TI,TI")])
741
742 (define_expand "mmx_<plusminus_insn><mode>3"
743 [(set (match_operand:MMXMODE12 0 "register_operand")
744 (sat_plusminus:MMXMODE12
745 (match_operand:MMXMODE12 1 "register_mmxmem_operand")
746 (match_operand:MMXMODE12 2 "register_mmxmem_operand")))]
747 "TARGET_MMX || TARGET_MMX_WITH_SSE"
748 "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
749
750 (define_insn "*mmx_<plusminus_insn><mode>3"
751 [(set (match_operand:MMXMODE12 0 "register_operand" "=y,x,Yv")
752 (sat_plusminus:MMXMODE12
753 (match_operand:MMXMODE12 1 "register_mmxmem_operand" "<comm>0,0,Yv")
754 (match_operand:MMXMODE12 2 "register_mmxmem_operand" "ym,x,Yv")))]
755 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
756 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
757 "@
758 p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}
759 p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}
760 vp<plusminus_mnemonic><mmxvecsize>\t{%2, %1, %0|%0, %1, %2}"
761 [(set_attr "isa" "*,sse2_noavx,avx")
762 (set_attr "mmx_isa" "native,*,*")
763 (set_attr "type" "mmxadd,sseadd,sseadd")
764 (set_attr "mode" "DI,TI,TI")])
765
766 (define_expand "mmx_mulv4hi3"
767 [(set (match_operand:V4HI 0 "register_operand")
768 (mult:V4HI (match_operand:V4HI 1 "register_mmxmem_operand")
769 (match_operand:V4HI 2 "register_mmxmem_operand")))]
770 "TARGET_MMX || TARGET_MMX_WITH_SSE"
771 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
772
773 (define_expand "mulv4hi3"
774 [(set (match_operand:V4HI 0 "register_operand")
775 (mult:V4HI (match_operand:V4HI 1 "register_operand")
776 (match_operand:V4HI 2 "register_operand")))]
777 "TARGET_MMX_WITH_SSE"
778 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
779
780 (define_insn "*mmx_mulv4hi3"
781 [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
782 (mult:V4HI (match_operand:V4HI 1 "register_mmxmem_operand" "%0,0,Yv")
783 (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv")))]
784 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
785 && ix86_binary_operator_ok (MULT, V4HImode, operands)"
786 "@
787 pmullw\t{%2, %0|%0, %2}
788 pmullw\t{%2, %0|%0, %2}
789 vpmullw\t{%2, %1, %0|%0, %1, %2}"
790 [(set_attr "isa" "*,sse2_noavx,avx")
791 (set_attr "mmx_isa" "native,*,*")
792 (set_attr "type" "mmxmul,ssemul,ssemul")
793 (set_attr "mode" "DI,TI,TI")])
794
795 (define_expand "mmx_smulv4hi3_highpart"
796 [(set (match_operand:V4HI 0 "register_operand")
797 (truncate:V4HI
798 (lshiftrt:V4SI
799 (mult:V4SI
800 (sign_extend:V4SI
801 (match_operand:V4HI 1 "register_mmxmem_operand"))
802 (sign_extend:V4SI
803 (match_operand:V4HI 2 "register_mmxmem_operand")))
804 (const_int 16))))]
805 "TARGET_MMX || TARGET_MMX_WITH_SSE"
806 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
807
808 (define_insn "*mmx_smulv4hi3_highpart"
809 [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
810 (truncate:V4HI
811 (lshiftrt:V4SI
812 (mult:V4SI
813 (sign_extend:V4SI
814 (match_operand:V4HI 1 "register_mmxmem_operand" "%0,0,Yv"))
815 (sign_extend:V4SI
816 (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv")))
817 (const_int 16))))]
818 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
819 && ix86_binary_operator_ok (MULT, V4HImode, operands)"
820 "@
821 pmulhw\t{%2, %0|%0, %2}
822 pmulhw\t{%2, %0|%0, %2}
823 vpmulhw\t{%2, %1, %0|%0, %1, %2}"
824 [(set_attr "isa" "*,sse2_noavx,avx")
825 (set_attr "mmx_isa" "native,*,*")
826 (set_attr "type" "mmxmul,ssemul,ssemul")
827 (set_attr "mode" "DI,TI,TI")])
828
829 (define_expand "mmx_umulv4hi3_highpart"
830 [(set (match_operand:V4HI 0 "register_operand")
831 (truncate:V4HI
832 (lshiftrt:V4SI
833 (mult:V4SI
834 (zero_extend:V4SI
835 (match_operand:V4HI 1 "register_mmxmem_operand"))
836 (zero_extend:V4SI
837 (match_operand:V4HI 2 "register_mmxmem_operand")))
838 (const_int 16))))]
839 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
840 && (TARGET_SSE || TARGET_3DNOW_A)"
841 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
842
843 (define_insn "*mmx_umulv4hi3_highpart"
844 [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
845 (truncate:V4HI
846 (lshiftrt:V4SI
847 (mult:V4SI
848 (zero_extend:V4SI
849 (match_operand:V4HI 1 "register_mmxmem_operand" "%0,0,Yv"))
850 (zero_extend:V4SI
851 (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv")))
852 (const_int 16))))]
853 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
854 && (TARGET_SSE || TARGET_3DNOW_A)
855 && ix86_binary_operator_ok (MULT, V4HImode, operands)"
856 "@
857 pmulhuw\t{%2, %0|%0, %2}
858 pmulhuw\t{%2, %0|%0, %2}
859 vpmulhuw\t{%2, %1, %0|%0, %1, %2}"
860 [(set_attr "isa" "*,sse2_noavx,avx")
861 (set_attr "mmx_isa" "native,*,*")
862 (set_attr "type" "mmxmul,ssemul,ssemul")
863 (set_attr "mode" "DI,TI,TI")])
864
865 (define_expand "mmx_pmaddwd"
866 [(set (match_operand:V2SI 0 "register_operand")
867 (plus:V2SI
868 (mult:V2SI
869 (sign_extend:V2SI
870 (vec_select:V2HI
871 (match_operand:V4HI 1 "register_mmxmem_operand")
872 (parallel [(const_int 0) (const_int 2)])))
873 (sign_extend:V2SI
874 (vec_select:V2HI
875 (match_operand:V4HI 2 "register_mmxmem_operand")
876 (parallel [(const_int 0) (const_int 2)]))))
877 (mult:V2SI
878 (sign_extend:V2SI
879 (vec_select:V2HI (match_dup 1)
880 (parallel [(const_int 1) (const_int 3)])))
881 (sign_extend:V2SI
882 (vec_select:V2HI (match_dup 2)
883 (parallel [(const_int 1) (const_int 3)]))))))]
884 "TARGET_MMX || TARGET_MMX_WITH_SSE"
885 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
886
887 (define_insn "*mmx_pmaddwd"
888 [(set (match_operand:V2SI 0 "register_operand" "=y,x,Yv")
889 (plus:V2SI
890 (mult:V2SI
891 (sign_extend:V2SI
892 (vec_select:V2HI
893 (match_operand:V4HI 1 "register_mmxmem_operand" "%0,0,Yv")
894 (parallel [(const_int 0) (const_int 2)])))
895 (sign_extend:V2SI
896 (vec_select:V2HI
897 (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv")
898 (parallel [(const_int 0) (const_int 2)]))))
899 (mult:V2SI
900 (sign_extend:V2SI
901 (vec_select:V2HI (match_dup 1)
902 (parallel [(const_int 1) (const_int 3)])))
903 (sign_extend:V2SI
904 (vec_select:V2HI (match_dup 2)
905 (parallel [(const_int 1) (const_int 3)]))))))]
906 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
907 && ix86_binary_operator_ok (MULT, V4HImode, operands)"
908 "@
909 pmaddwd\t{%2, %0|%0, %2}
910 pmaddwd\t{%2, %0|%0, %2}
911 vpmaddwd\t{%2, %1, %0|%0, %1, %2}"
912 [(set_attr "isa" "*,sse2_noavx,avx")
913 (set_attr "mmx_isa" "native,*,*")
914 (set_attr "type" "mmxmul,sseiadd,sseiadd")
915 (set_attr "mode" "DI,TI,TI")])
916
917 (define_expand "mmx_pmulhrwv4hi3"
918 [(set (match_operand:V4HI 0 "register_operand")
919 (truncate:V4HI
920 (lshiftrt:V4SI
921 (plus:V4SI
922 (mult:V4SI
923 (sign_extend:V4SI
924 (match_operand:V4HI 1 "nonimmediate_operand"))
925 (sign_extend:V4SI
926 (match_operand:V4HI 2 "nonimmediate_operand")))
927 (const_vector:V4SI [(const_int 32768) (const_int 32768)
928 (const_int 32768) (const_int 32768)]))
929 (const_int 16))))]
930 "TARGET_3DNOW"
931 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
932
933 (define_insn "*mmx_pmulhrwv4hi3"
934 [(set (match_operand:V4HI 0 "register_operand" "=y")
935 (truncate:V4HI
936 (lshiftrt:V4SI
937 (plus:V4SI
938 (mult:V4SI
939 (sign_extend:V4SI
940 (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
941 (sign_extend:V4SI
942 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
943 (const_vector:V4SI [(const_int 32768) (const_int 32768)
944 (const_int 32768) (const_int 32768)]))
945 (const_int 16))))]
946 "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V4HImode, operands)"
947 "pmulhrw\t{%2, %0|%0, %2}"
948 [(set_attr "type" "mmxmul")
949 (set_attr "prefix_extra" "1")
950 (set_attr "mode" "DI")])
951
952 (define_expand "sse2_umulv1siv1di3"
953 [(set (match_operand:V1DI 0 "register_operand")
954 (mult:V1DI
955 (zero_extend:V1DI
956 (vec_select:V1SI
957 (match_operand:V2SI 1 "register_mmxmem_operand")
958 (parallel [(const_int 0)])))
959 (zero_extend:V1DI
960 (vec_select:V1SI
961 (match_operand:V2SI 2 "register_mmxmem_operand")
962 (parallel [(const_int 0)])))))]
963 "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_SSE2"
964 "ix86_fixup_binary_operands_no_copy (MULT, V2SImode, operands);")
965
966 (define_insn "*sse2_umulv1siv1di3"
967 [(set (match_operand:V1DI 0 "register_operand" "=y,x,Yv")
968 (mult:V1DI
969 (zero_extend:V1DI
970 (vec_select:V1SI
971 (match_operand:V2SI 1 "register_mmxmem_operand" "%0,0,Yv")
972 (parallel [(const_int 0)])))
973 (zero_extend:V1DI
974 (vec_select:V1SI
975 (match_operand:V2SI 2 "register_mmxmem_operand" "ym,x,Yv")
976 (parallel [(const_int 0)])))))]
977 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
978 && TARGET_SSE2
979 && ix86_binary_operator_ok (MULT, V2SImode, operands)"
980 "@
981 pmuludq\t{%2, %0|%0, %2}
982 pmuludq\t{%2, %0|%0, %2}
983 vpmuludq\t{%2, %1, %0|%0, %1, %2}"
984 [(set_attr "isa" "*,sse2_noavx,avx")
985 (set_attr "mmx_isa" "native,*,*")
986 (set_attr "type" "mmxmul,ssemul,ssemul")
987 (set_attr "mode" "DI,TI,TI")])
988
989 (define_expand "mmx_<code>v4hi3"
990 [(set (match_operand:V4HI 0 "register_operand")
991 (smaxmin:V4HI
992 (match_operand:V4HI 1 "register_mmxmem_operand")
993 (match_operand:V4HI 2 "register_mmxmem_operand")))]
994 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
995 && (TARGET_SSE || TARGET_3DNOW_A)"
996 "ix86_fixup_binary_operands_no_copy (<CODE>, V4HImode, operands);")
997
998 (define_expand "<code>v4hi3"
999 [(set (match_operand:V4HI 0 "register_operand")
1000 (smaxmin:V4HI
1001 (match_operand:V4HI 1 "register_operand")
1002 (match_operand:V4HI 2 "register_operand")))]
1003 "TARGET_MMX_WITH_SSE"
1004 "ix86_fixup_binary_operands_no_copy (<CODE>, V4HImode, operands);")
1005
1006 (define_insn "*mmx_<code>v4hi3"
1007 [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
1008 (smaxmin:V4HI
1009 (match_operand:V4HI 1 "register_mmxmem_operand" "%0,0,Yv")
1010 (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv")))]
1011 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1012 && (TARGET_SSE || TARGET_3DNOW_A)
1013 && ix86_binary_operator_ok (<CODE>, V4HImode, operands)"
1014 "@
1015 p<maxmin_int>w\t{%2, %0|%0, %2}
1016 p<maxmin_int>w\t{%2, %0|%0, %2}
1017 vp<maxmin_int>w\t{%2, %1, %0|%0, %1, %2}"
1018 [(set_attr "isa" "*,sse2_noavx,avx")
1019 (set_attr "mmx_isa" "native,*,*")
1020 (set_attr "type" "mmxadd,sseiadd,sseiadd")
1021 (set_attr "mode" "DI,TI,TI")])
1022
1023 (define_expand "mmx_<code>v8qi3"
1024 [(set (match_operand:V8QI 0 "register_operand")
1025 (umaxmin:V8QI
1026 (match_operand:V8QI 1 "register_mmxmem_operand")
1027 (match_operand:V8QI 2 "register_mmxmem_operand")))]
1028 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1029 && (TARGET_SSE || TARGET_3DNOW_A)"
1030 "ix86_fixup_binary_operands_no_copy (<CODE>, V8QImode, operands);")
1031
1032 (define_expand "<code>v8qi3"
1033 [(set (match_operand:V8QI 0 "register_operand")
1034 (umaxmin:V8QI
1035 (match_operand:V8QI 1 "register_operand")
1036 (match_operand:V8QI 2 "register_operand")))]
1037 "TARGET_MMX_WITH_SSE"
1038 "ix86_fixup_binary_operands_no_copy (<CODE>, V8QImode, operands);")
1039
1040 (define_insn "*mmx_<code>v8qi3"
1041 [(set (match_operand:V8QI 0 "register_operand" "=y,x,Yv")
1042 (umaxmin:V8QI
1043 (match_operand:V8QI 1 "register_mmxmem_operand" "%0,0,Yv")
1044 (match_operand:V8QI 2 "register_mmxmem_operand" "ym,x,Yv")))]
1045 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1046 && (TARGET_SSE || TARGET_3DNOW_A)
1047 && ix86_binary_operator_ok (<CODE>, V8QImode, operands)"
1048 "@
1049 p<maxmin_int>b\t{%2, %0|%0, %2}
1050 p<maxmin_int>b\t{%2, %0|%0, %2}
1051 vp<maxmin_int>b\t{%2, %1, %0|%0, %1, %2}"
1052 [(set_attr "isa" "*,sse2_noavx,avx")
1053 (set_attr "mmx_isa" "native,*,*")
1054 (set_attr "type" "mmxadd,sseiadd,sseiadd")
1055 (set_attr "mode" "DI,TI,TI")])
1056
1057 (define_insn "mmx_ashr<mode>3"
1058 [(set (match_operand:MMXMODE24 0 "register_operand" "=y,x,Yv")
1059 (ashiftrt:MMXMODE24
1060 (match_operand:MMXMODE24 1 "register_operand" "0,0,Yv")
1061 (match_operand:DI 2 "nonmemory_operand" "yN,xN,YvN")))]
1062 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1063 "@
1064 psra<mmxvecsize>\t{%2, %0|%0, %2}
1065 psra<mmxvecsize>\t{%2, %0|%0, %2}
1066 vpsra<mmxvecsize>\t{%2, %1, %0|%0, %1, %2}"
1067 [(set_attr "isa" "*,sse2_noavx,avx")
1068 (set_attr "mmx_isa" "native,*,*")
1069 (set_attr "type" "mmxshft,sseishft,sseishft")
1070 (set (attr "length_immediate")
1071 (if_then_else (match_operand 2 "const_int_operand")
1072 (const_string "1")
1073 (const_string "0")))
1074 (set_attr "mode" "DI,TI,TI")])
1075
1076 (define_expand "ashr<mode>3"
1077 [(set (match_operand:MMXMODE24 0 "register_operand")
1078 (ashiftrt:MMXMODE24
1079 (match_operand:MMXMODE24 1 "register_operand")
1080 (match_operand:DI 2 "nonmemory_operand")))]
1081 "TARGET_MMX_WITH_SSE")
1082
1083 (define_insn "mmx_<shift_insn><mode>3"
1084 [(set (match_operand:MMXMODE248 0 "register_operand" "=y,x,Yv")
1085 (any_lshift:MMXMODE248
1086 (match_operand:MMXMODE248 1 "register_operand" "0,0,Yv")
1087 (match_operand:DI 2 "nonmemory_operand" "yN,xN,YvN")))]
1088 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1089 "@
1090 p<vshift><mmxvecsize>\t{%2, %0|%0, %2}
1091 p<vshift><mmxvecsize>\t{%2, %0|%0, %2}
1092 vp<vshift><mmxvecsize>\t{%2, %1, %0|%0, %1, %2}"
1093 [(set_attr "isa" "*,sse2_noavx,avx")
1094 (set_attr "mmx_isa" "native,*,*")
1095 (set_attr "type" "mmxshft,sseishft,sseishft")
1096 (set (attr "length_immediate")
1097 (if_then_else (match_operand 2 "const_int_operand")
1098 (const_string "1")
1099 (const_string "0")))
1100 (set_attr "mode" "DI,TI,TI")])
1101
1102 (define_expand "<shift_insn><mode>3"
1103 [(set (match_operand:MMXMODE248 0 "register_operand")
1104 (any_lshift:MMXMODE248
1105 (match_operand:MMXMODE248 1 "register_operand")
1106 (match_operand:DI 2 "nonmemory_operand")))]
1107 "TARGET_MMX_WITH_SSE")
1108
1109 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1110 ;;
1111 ;; Parallel integral comparisons
1112 ;;
1113 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1114
1115 (define_expand "mmx_eq<mode>3"
1116 [(set (match_operand:MMXMODEI 0 "register_operand")
1117 (eq:MMXMODEI
1118 (match_operand:MMXMODEI 1 "register_mmxmem_operand")
1119 (match_operand:MMXMODEI 2 "register_mmxmem_operand")))]
1120 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1121 "ix86_fixup_binary_operands_no_copy (EQ, <MODE>mode, operands);")
1122
1123 (define_insn "*mmx_eq<mode>3"
1124 [(set (match_operand:MMXMODEI 0 "register_operand" "=y,x,Yv")
1125 (eq:MMXMODEI
1126 (match_operand:MMXMODEI 1 "register_mmxmem_operand" "%0,0,Yv")
1127 (match_operand:MMXMODEI 2 "register_mmxmem_operand" "ym,x,Yv")))]
1128 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1129 && ix86_binary_operator_ok (EQ, <MODE>mode, operands)"
1130 "@
1131 pcmpeq<mmxvecsize>\t{%2, %0|%0, %2}
1132 pcmpeq<mmxvecsize>\t{%2, %0|%0, %2}
1133 vpcmpeq<mmxvecsize>\t{%2, %1, %0|%0, %1, %2}"
1134 [(set_attr "isa" "*,sse2_noavx,avx")
1135 (set_attr "mmx_isa" "native,*,*")
1136 (set_attr "type" "mmxcmp,ssecmp,ssecmp")
1137 (set_attr "mode" "DI,TI,TI")])
1138
1139 (define_insn "mmx_gt<mode>3"
1140 [(set (match_operand:MMXMODEI 0 "register_operand" "=y,x,Yv")
1141 (gt:MMXMODEI
1142 (match_operand:MMXMODEI 1 "register_operand" "0,0,Yv")
1143 (match_operand:MMXMODEI 2 "register_mmxmem_operand" "ym,x,Yv")))]
1144 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1145 "@
1146 pcmpgt<mmxvecsize>\t{%2, %0|%0, %2}
1147 pcmpgt<mmxvecsize>\t{%2, %0|%0, %2}
1148 vpcmpgt<mmxvecsize>\t{%2, %1, %0|%0, %1, %2}"
1149 [(set_attr "isa" "*,sse2_noavx,avx")
1150 (set_attr "mmx_isa" "native,*,*")
1151 (set_attr "type" "mmxcmp,ssecmp,ssecmp")
1152 (set_attr "mode" "DI,TI,TI")])
1153
1154 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1155 ;;
1156 ;; Parallel integral logical operations
1157 ;;
1158 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1159
1160 (define_expand "one_cmpl<mode>2"
1161 [(set (match_operand:MMXMODEI 0 "register_operand")
1162 (xor:MMXMODEI
1163 (match_operand:MMXMODEI 1 "register_operand")
1164 (match_dup 2)))]
1165 "TARGET_MMX_WITH_SSE"
1166 "operands[2] = force_reg (<MODE>mode, CONSTM1_RTX (<MODE>mode));")
1167
1168 (define_insn "mmx_andnot<mode>3"
1169 [(set (match_operand:MMXMODEI 0 "register_operand" "=y,x,Yv")
1170 (and:MMXMODEI
1171 (not:MMXMODEI (match_operand:MMXMODEI 1 "register_operand" "0,0,Yv"))
1172 (match_operand:MMXMODEI 2 "register_mmxmem_operand" "ym,x,Yv")))]
1173 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1174 "@
1175 pandn\t{%2, %0|%0, %2}
1176 pandn\t{%2, %0|%0, %2}
1177 vpandn\t{%2, %1, %0|%0, %1, %2}"
1178 [(set_attr "isa" "*,sse2_noavx,avx")
1179 (set_attr "mmx_isa" "native,*,*")
1180 (set_attr "type" "mmxadd,sselog,sselog")
1181 (set_attr "mode" "DI,TI,TI")])
1182
1183 (define_expand "mmx_<code><mode>3"
1184 [(set (match_operand:MMXMODEI 0 "register_operand")
1185 (any_logic:MMXMODEI
1186 (match_operand:MMXMODEI 1 "register_mmxmem_operand")
1187 (match_operand:MMXMODEI 2 "register_mmxmem_operand")))]
1188 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1189 "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
1190
1191 (define_expand "<code><mode>3"
1192 [(set (match_operand:MMXMODEI 0 "register_operand")
1193 (any_logic:MMXMODEI
1194 (match_operand:MMXMODEI 1 "register_operand")
1195 (match_operand:MMXMODEI 2 "register_operand")))]
1196 "TARGET_MMX_WITH_SSE"
1197 "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
1198
1199 (define_insn "*mmx_<code><mode>3"
1200 [(set (match_operand:MMXMODEI 0 "register_operand" "=y,x,Yv")
1201 (any_logic:MMXMODEI
1202 (match_operand:MMXMODEI 1 "register_mmxmem_operand" "%0,0,Yv")
1203 (match_operand:MMXMODEI 2 "register_mmxmem_operand" "ym,x,Yv")))]
1204 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1205 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
1206 "@
1207 p<logic>\t{%2, %0|%0, %2}
1208 p<logic>\t{%2, %0|%0, %2}
1209 vp<logic>\t{%2, %1, %0|%0, %1, %2}"
1210 [(set_attr "isa" "*,sse2_noavx,avx")
1211 (set_attr "mmx_isa" "native,*,*")
1212 (set_attr "type" "mmxadd,sselog,sselog")
1213 (set_attr "mode" "DI,TI,TI")])
1214
1215 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1216 ;;
1217 ;; Parallel integral element swizzling
1218 ;;
1219 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1220
1221 ;; Used in signed and unsigned truncations with saturation.
1222 (define_code_iterator any_s_truncate [ss_truncate us_truncate])
1223 ;; Instruction suffix for truncations with saturation.
1224 (define_code_attr s_trunsuffix [(ss_truncate "s") (us_truncate "u")])
1225
1226 (define_insn_and_split "mmx_pack<s_trunsuffix>swb"
1227 [(set (match_operand:V8QI 0 "register_operand" "=y,x,Yv")
1228 (vec_concat:V8QI
1229 (any_s_truncate:V4QI
1230 (match_operand:V4HI 1 "register_operand" "0,0,Yv"))
1231 (any_s_truncate:V4QI
1232 (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv"))))]
1233 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1234 "@
1235 pack<s_trunsuffix>swb\t{%2, %0|%0, %2}
1236 #
1237 #"
1238 "TARGET_SSE2 && reload_completed
1239 && SSE_REGNO_P (REGNO (operands[0]))"
1240 [(const_int 0)]
1241 "ix86_split_mmx_pack (operands, <any_s_truncate:CODE>); DONE;"
1242 [(set_attr "mmx_isa" "native,sse_noavx,avx")
1243 (set_attr "type" "mmxshft,sselog,sselog")
1244 (set_attr "mode" "DI,TI,TI")])
1245
1246 (define_insn_and_split "mmx_packssdw"
1247 [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
1248 (vec_concat:V4HI
1249 (ss_truncate:V2HI
1250 (match_operand:V2SI 1 "register_operand" "0,0,Yv"))
1251 (ss_truncate:V2HI
1252 (match_operand:V2SI 2 "register_mmxmem_operand" "ym,x,Yv"))))]
1253 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1254 "@
1255 packssdw\t{%2, %0|%0, %2}
1256 #
1257 #"
1258 "TARGET_SSE2 && reload_completed
1259 && SSE_REGNO_P (REGNO (operands[0]))"
1260 [(const_int 0)]
1261 "ix86_split_mmx_pack (operands, SS_TRUNCATE); DONE;"
1262 [(set_attr "mmx_isa" "native,sse_noavx,avx")
1263 (set_attr "type" "mmxshft,sselog,sselog")
1264 (set_attr "mode" "DI,TI,TI")])
1265
1266 (define_insn_and_split "mmx_punpckhbw"
1267 [(set (match_operand:V8QI 0 "register_operand" "=y,x,Yv")
1268 (vec_select:V8QI
1269 (vec_concat:V16QI
1270 (match_operand:V8QI 1 "register_operand" "0,0,Yv")
1271 (match_operand:V8QI 2 "register_mmxmem_operand" "ym,x,Yv"))
1272 (parallel [(const_int 4) (const_int 12)
1273 (const_int 5) (const_int 13)
1274 (const_int 6) (const_int 14)
1275 (const_int 7) (const_int 15)])))]
1276 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1277 "@
1278 punpckhbw\t{%2, %0|%0, %2}
1279 #
1280 #"
1281 "TARGET_SSE2 && reload_completed
1282 && SSE_REGNO_P (REGNO (operands[0]))"
1283 [(const_int 0)]
1284 "ix86_split_mmx_punpck (operands, true); DONE;"
1285 [(set_attr "mmx_isa" "native,sse_noavx,avx")
1286 (set_attr "type" "mmxcvt,sselog,sselog")
1287 (set_attr "mode" "DI,TI,TI")])
1288
1289 (define_insn_and_split "mmx_punpcklbw"
1290 [(set (match_operand:V8QI 0 "register_operand" "=y,x,Yv")
1291 (vec_select:V8QI
1292 (vec_concat:V16QI
1293 (match_operand:V8QI 1 "register_operand" "0,0,Yv")
1294 (match_operand:V8QI 2 "register_mmxmem_operand" "ym,x,Yv"))
1295 (parallel [(const_int 0) (const_int 8)
1296 (const_int 1) (const_int 9)
1297 (const_int 2) (const_int 10)
1298 (const_int 3) (const_int 11)])))]
1299 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1300 "@
1301 punpcklbw\t{%2, %0|%0, %k2}
1302 #
1303 #"
1304 "TARGET_SSE2 && reload_completed
1305 && SSE_REGNO_P (REGNO (operands[0]))"
1306 [(const_int 0)]
1307 "ix86_split_mmx_punpck (operands, false); DONE;"
1308 [(set_attr "mmx_isa" "native,sse_noavx,avx")
1309 (set_attr "type" "mmxcvt,sselog,sselog")
1310 (set_attr "mode" "DI,TI,TI")])
1311
1312 (define_insn_and_split "mmx_punpckhwd"
1313 [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
1314 (vec_select:V4HI
1315 (vec_concat:V8HI
1316 (match_operand:V4HI 1 "register_operand" "0,0,Yv")
1317 (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv"))
1318 (parallel [(const_int 2) (const_int 6)
1319 (const_int 3) (const_int 7)])))]
1320 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1321 "@
1322 punpckhwd\t{%2, %0|%0, %2}
1323 #
1324 #"
1325 "TARGET_SSE2 && reload_completed
1326 && SSE_REGNO_P (REGNO (operands[0]))"
1327 [(const_int 0)]
1328 "ix86_split_mmx_punpck (operands, true); DONE;"
1329 [(set_attr "mmx_isa" "native,sse_noavx,avx")
1330 (set_attr "type" "mmxcvt,sselog,sselog")
1331 (set_attr "mode" "DI,TI,TI")])
1332
1333 (define_insn_and_split "mmx_punpcklwd"
1334 [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
1335 (vec_select:V4HI
1336 (vec_concat:V8HI
1337 (match_operand:V4HI 1 "register_operand" "0,0,Yv")
1338 (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv"))
1339 (parallel [(const_int 0) (const_int 4)
1340 (const_int 1) (const_int 5)])))]
1341 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1342 "@
1343 punpcklwd\t{%2, %0|%0, %k2}
1344 #
1345 #"
1346 "TARGET_SSE2 && reload_completed
1347 && SSE_REGNO_P (REGNO (operands[0]))"
1348 [(const_int 0)]
1349 "ix86_split_mmx_punpck (operands, false); DONE;"
1350 [(set_attr "mmx_isa" "native,sse_noavx,avx")
1351 (set_attr "type" "mmxcvt,sselog,sselog")
1352 (set_attr "mode" "DI,TI,TI")])
1353
1354 (define_insn_and_split "mmx_punpckhdq"
1355 [(set (match_operand:V2SI 0 "register_operand" "=y,x,Yv")
1356 (vec_select:V2SI
1357 (vec_concat:V4SI
1358 (match_operand:V2SI 1 "register_operand" "0,0,Yv")
1359 (match_operand:V2SI 2 "register_mmxmem_operand" "ym,x,Yv"))
1360 (parallel [(const_int 1)
1361 (const_int 3)])))]
1362 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1363 "@
1364 punpckhdq\t{%2, %0|%0, %2}
1365 #
1366 #"
1367 "TARGET_SSE2 && reload_completed
1368 && SSE_REGNO_P (REGNO (operands[0]))"
1369 [(const_int 0)]
1370 "ix86_split_mmx_punpck (operands, true); DONE;"
1371 [(set_attr "mmx_isa" "native,sse_noavx,avx")
1372 (set_attr "type" "mmxcvt,sselog,sselog")
1373 (set_attr "mode" "DI,TI,TI")])
1374
1375 (define_insn_and_split "mmx_punpckldq"
1376 [(set (match_operand:V2SI 0 "register_operand" "=y,x,Yv")
1377 (vec_select:V2SI
1378 (vec_concat:V4SI
1379 (match_operand:V2SI 1 "register_operand" "0,0,Yv")
1380 (match_operand:V2SI 2 "register_mmxmem_operand" "ym,x,Yv"))
1381 (parallel [(const_int 0)
1382 (const_int 2)])))]
1383 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1384 "@
1385 punpckldq\t{%2, %0|%0, %k2}
1386 #
1387 #"
1388 "TARGET_SSE2 && reload_completed
1389 && SSE_REGNO_P (REGNO (operands[0]))"
1390 [(const_int 0)]
1391 "ix86_split_mmx_punpck (operands, false); DONE;"
1392 [(set_attr "mmx_isa" "native,sse_noavx,avx")
1393 (set_attr "type" "mmxcvt,sselog,sselog")
1394 (set_attr "mode" "DI,TI,TI")])
1395
1396 (define_insn "*mmx_pinsrd"
1397 [(set (match_operand:V2SI 0 "register_operand" "=x,Yv")
1398 (vec_merge:V2SI
1399 (vec_duplicate:V2SI
1400 (match_operand:SI 2 "nonimmediate_operand" "rm,rm"))
1401 (match_operand:V2SI 1 "register_operand" "0,Yv")
1402 (match_operand:SI 3 "const_int_operand")))]
1403 "TARGET_MMX_WITH_SSE && TARGET_SSE4_1
1404 && ((unsigned) exact_log2 (INTVAL (operands[3]))
1405 < GET_MODE_NUNITS (V2SImode))"
1406 {
1407 operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
1408 switch (which_alternative)
1409 {
1410 case 1:
1411 return "vpinsrd\t{%3, %2, %1, %0|%0, %1, %2, %3}";
1412 case 0:
1413 return "pinsrd\t{%3, %2, %0|%0, %2, %3}";
1414 default:
1415 gcc_unreachable ();
1416 }
1417 }
1418 [(set_attr "isa" "noavx,avx")
1419 (set_attr "prefix_data16" "1")
1420 (set_attr "prefix_extra" "1")
1421 (set_attr "type" "sselog")
1422 (set_attr "length_immediate" "1")
1423 (set_attr "prefix" "orig,vex")
1424 (set_attr "mode" "TI")])
1425
1426 (define_expand "mmx_pinsrw"
1427 [(set (match_operand:V4HI 0 "register_operand")
1428 (vec_merge:V4HI
1429 (vec_duplicate:V4HI
1430 (match_operand:SI 2 "nonimmediate_operand"))
1431 (match_operand:V4HI 1 "register_operand")
1432 (match_operand:SI 3 "const_0_to_3_operand")))]
1433 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1434 && (TARGET_SSE || TARGET_3DNOW_A)"
1435 {
1436 operands[2] = gen_lowpart (HImode, operands[2]);
1437 operands[3] = GEN_INT (1 << INTVAL (operands[3]));
1438 })
1439
1440 (define_insn "*mmx_pinsrw"
1441 [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
1442 (vec_merge:V4HI
1443 (vec_duplicate:V4HI
1444 (match_operand:HI 2 "nonimmediate_operand" "rm,rm,rm"))
1445 (match_operand:V4HI 1 "register_operand" "0,0,Yv")
1446 (match_operand:SI 3 "const_int_operand")))]
1447 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1448 && (TARGET_SSE || TARGET_3DNOW_A)
1449 && ((unsigned) exact_log2 (INTVAL (operands[3]))
1450 < GET_MODE_NUNITS (V4HImode))"
1451 {
1452 operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
1453 switch (which_alternative)
1454 {
1455 case 2:
1456 if (MEM_P (operands[2]))
1457 return "vpinsrw\t{%3, %2, %1, %0|%0, %1, %2, %3}";
1458 else
1459 return "vpinsrw\t{%3, %k2, %1, %0|%0, %1, %k2, %3}";
1460 case 1:
1461 case 0:
1462 if (MEM_P (operands[2]))
1463 return "pinsrw\t{%3, %2, %0|%0, %2, %3}";
1464 else
1465 return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}";
1466 default:
1467 gcc_unreachable ();
1468 }
1469 }
1470 [(set_attr "isa" "*,sse2_noavx,avx")
1471 (set_attr "mmx_isa" "native,*,*")
1472 (set_attr "type" "mmxcvt,sselog,sselog")
1473 (set_attr "length_immediate" "1")
1474 (set_attr "mode" "DI,TI,TI")])
1475
1476 (define_insn "*mmx_pinsrb"
1477 [(set (match_operand:V8QI 0 "register_operand" "=x,Yv")
1478 (vec_merge:V8QI
1479 (vec_duplicate:V8QI
1480 (match_operand:QI 2 "nonimmediate_operand" "rm,rm"))
1481 (match_operand:V8QI 1 "register_operand" "0,Yv")
1482 (match_operand:SI 3 "const_int_operand")))]
1483 "TARGET_MMX_WITH_SSE && TARGET_SSE4_1
1484 && ((unsigned) exact_log2 (INTVAL (operands[3]))
1485 < GET_MODE_NUNITS (V8QImode))"
1486 {
1487 operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
1488 switch (which_alternative)
1489 {
1490 case 1:
1491 if (MEM_P (operands[2]))
1492 return "vpinsrb\t{%3, %2, %1, %0|%0, %1, %2, %3}";
1493 else
1494 return "vpinsrb\t{%3, %k2, %1, %0|%0, %1, %k2, %3}";
1495 case 0:
1496 if (MEM_P (operands[2]))
1497 return "pinsrb\t{%3, %2, %0|%0, %2, %3}";
1498 else
1499 return "pinsrb\t{%3, %k2, %0|%0, %k2, %3}";
1500 default:
1501 gcc_unreachable ();
1502 }
1503 }
1504 [(set_attr "isa" "noavx,avx")
1505 (set_attr "type" "sselog")
1506 (set_attr "prefix_data16" "1")
1507 (set_attr "prefix_extra" "1")
1508 (set_attr "length_immediate" "1")
1509 (set_attr "prefix" "orig,vex")
1510 (set_attr "mode" "TI")])
1511
1512 (define_insn "*mmx_pextrw"
1513 [(set (match_operand:HI 0 "register_sse4nonimm_operand" "=r,r,m")
1514 (vec_select:HI
1515 (match_operand:V4HI 1 "register_operand" "y,Yv,Yv")
1516 (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n,n,n")])))]
1517 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1518 && (TARGET_SSE || TARGET_3DNOW_A)"
1519 "@
1520 pextrw\t{%2, %1, %k0|%k0, %1, %2}
1521 %vpextrw\t{%2, %1, %k0|%k0, %1, %2}
1522 %vpextrw\t{%2, %1, %0|%0, %1, %2}"
1523 [(set_attr "isa" "*,sse2,sse4")
1524 (set_attr "mmx_isa" "native,*,*")
1525 (set_attr "type" "mmxcvt,sselog1,sselog1")
1526 (set_attr "length_immediate" "1")
1527 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
1528 (set_attr "mode" "DI,TI,TI")])
1529
1530 (define_insn "*mmx_pextrw_zext"
1531 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
1532 (zero_extend:SWI48
1533 (vec_select:HI
1534 (match_operand:V4HI 1 "register_operand" "y,Yv")
1535 (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n,n")]))))]
1536 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1537 && (TARGET_SSE || TARGET_3DNOW_A)"
1538 "@
1539 pextrw\t{%2, %1, %k0|%k0, %1, %2}
1540 %vpextrw\t{%2, %1, %k0|%k0, %1, %2}"
1541 [(set_attr "isa" "*,sse2")
1542 (set_attr "mmx_isa" "native,*")
1543 (set_attr "type" "mmxcvt,sselog1")
1544 (set_attr "length_immediate" "1")
1545 (set_attr "prefix" "orig,maybe_vex")
1546 (set_attr "mode" "DI,TI")])
1547
1548 (define_insn "*mmx_pextrb"
1549 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,m")
1550 (vec_select:QI
1551 (match_operand:V8QI 1 "register_operand" "Yv,Yv")
1552 (parallel [(match_operand:SI 2 "const_0_to_7_operand" "n,n")])))]
1553 "TARGET_MMX_WITH_SSE && TARGET_SSE4_1"
1554 "@
1555 %vpextrb\t{%2, %1, %k0|%k0, %1, %2}
1556 %vpextrb\t{%2, %1, %0|%0, %1, %2}"
1557 [(set_attr "type" "sselog1")
1558 (set_attr "prefix_data16" "1")
1559 (set_attr "prefix_extra" "1")
1560 (set_attr "length_immediate" "1")
1561 (set_attr "prefix" "maybe_vex")
1562 (set_attr "mode" "TI")])
1563
1564 (define_insn "*mmx_pextrb_zext"
1565 [(set (match_operand:SWI248 0 "register_operand" "=r")
1566 (zero_extend:SWI248
1567 (vec_select:QI
1568 (match_operand:V8QI 1 "register_operand" "Yv")
1569 (parallel [(match_operand:SI 2 "const_0_to_7_operand" "n")]))))]
1570 "TARGET_MMX_WITH_SSE && TARGET_SSE4_1"
1571 "%vpextrb\t{%2, %1, %k0|%k0, %1, %2}"
1572 [(set_attr "type" "sselog1")
1573 (set_attr "prefix_data16" "1")
1574 (set_attr "prefix_extra" "1")
1575 (set_attr "length_immediate" "1")
1576 (set_attr "prefix" "maybe_vex")
1577 (set_attr "mode" "TI")])
1578
1579 (define_expand "mmx_pshufw"
1580 [(match_operand:V4HI 0 "register_operand")
1581 (match_operand:V4HI 1 "register_mmxmem_operand")
1582 (match_operand:SI 2 "const_int_operand")]
1583 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1584 && (TARGET_SSE || TARGET_3DNOW_A)"
1585 {
1586 int mask = INTVAL (operands[2]);
1587 emit_insn (gen_mmx_pshufw_1 (operands[0], operands[1],
1588 GEN_INT ((mask >> 0) & 3),
1589 GEN_INT ((mask >> 2) & 3),
1590 GEN_INT ((mask >> 4) & 3),
1591 GEN_INT ((mask >> 6) & 3)));
1592 DONE;
1593 })
1594
1595 (define_insn "mmx_pshufw_1"
1596 [(set (match_operand:V4HI 0 "register_operand" "=y,Yv")
1597 (vec_select:V4HI
1598 (match_operand:V4HI 1 "register_mmxmem_operand" "ym,Yv")
1599 (parallel [(match_operand 2 "const_0_to_3_operand")
1600 (match_operand 3 "const_0_to_3_operand")
1601 (match_operand 4 "const_0_to_3_operand")
1602 (match_operand 5 "const_0_to_3_operand")])))]
1603 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1604 && (TARGET_SSE || TARGET_3DNOW_A)"
1605 {
1606 int mask = 0;
1607 mask |= INTVAL (operands[2]) << 0;
1608 mask |= INTVAL (operands[3]) << 2;
1609 mask |= INTVAL (operands[4]) << 4;
1610 mask |= INTVAL (operands[5]) << 6;
1611 operands[2] = GEN_INT (mask);
1612
1613 switch (which_alternative)
1614 {
1615 case 0:
1616 return "pshufw\t{%2, %1, %0|%0, %1, %2}";
1617 case 1:
1618 return "%vpshuflw\t{%2, %1, %0|%0, %1, %2}";
1619 default:
1620 gcc_unreachable ();
1621 }
1622 }
1623 [(set_attr "isa" "*,sse2")
1624 (set_attr "mmx_isa" "native,*")
1625 (set_attr "type" "mmxcvt,sselog")
1626 (set_attr "length_immediate" "1")
1627 (set_attr "mode" "DI,TI")])
1628
1629 (define_insn "mmx_pswapdv2si2"
1630 [(set (match_operand:V2SI 0 "register_operand" "=y")
1631 (vec_select:V2SI
1632 (match_operand:V2SI 1 "nonimmediate_operand" "ym")
1633 (parallel [(const_int 1) (const_int 0)])))]
1634 "TARGET_3DNOW_A"
1635 "pswapd\t{%1, %0|%0, %1}"
1636 [(set_attr "type" "mmxcvt")
1637 (set_attr "prefix_extra" "1")
1638 (set_attr "mode" "DI")])
1639
1640 (define_insn_and_split "*vec_dupv4hi"
1641 [(set (match_operand:V4HI 0 "register_operand" "=y,Yv,Yw")
1642 (vec_duplicate:V4HI
1643 (truncate:HI
1644 (match_operand:SI 1 "register_operand" "0,Yv,r"))))]
1645 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1646 && (TARGET_SSE || TARGET_3DNOW_A)"
1647 "@
1648 pshufw\t{$0, %0, %0|%0, %0, 0}
1649 #
1650 #"
1651 "TARGET_SSE2 && reload_completed
1652 && SSE_REGNO_P (REGNO (operands[0]))"
1653 [(const_int 0)]
1654 {
1655 rtx op;
1656 operands[0] = lowpart_subreg (V8HImode, operands[0],
1657 GET_MODE (operands[0]));
1658 if (TARGET_AVX2)
1659 {
1660 operands[1] = lowpart_subreg (HImode, operands[1],
1661 GET_MODE (operands[1]));
1662 op = gen_rtx_VEC_DUPLICATE (V8HImode, operands[1]);
1663 }
1664 else
1665 {
1666 operands[1] = lowpart_subreg (V8HImode, operands[1],
1667 GET_MODE (operands[1]));
1668 rtx mask = gen_rtx_PARALLEL (VOIDmode,
1669 gen_rtvec (8,
1670 GEN_INT (0),
1671 GEN_INT (0),
1672 GEN_INT (0),
1673 GEN_INT (0),
1674 GEN_INT (4),
1675 GEN_INT (5),
1676 GEN_INT (6),
1677 GEN_INT (7)));
1678
1679 op = gen_rtx_VEC_SELECT (V8HImode, operands[1], mask);
1680 }
1681 emit_insn (gen_rtx_SET (operands[0], op));
1682 DONE;
1683 }
1684 [(set_attr "mmx_isa" "native,sse,avx")
1685 (set_attr "type" "mmxcvt,sselog1,ssemov")
1686 (set_attr "length_immediate" "1,1,0")
1687 (set_attr "mode" "DI,TI,TI")])
1688
1689 (define_insn_and_split "*vec_dupv2si"
1690 [(set (match_operand:V2SI 0 "register_operand" "=y,x,Yv,Yw")
1691 (vec_duplicate:V2SI
1692 (match_operand:SI 1 "register_operand" "0,0,Yv,r")))]
1693 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1694 "@
1695 punpckldq\t%0, %0
1696 #
1697 #
1698 #"
1699 "TARGET_SSE && reload_completed
1700 && SSE_REGNO_P (REGNO (operands[0]))"
1701 [(set (match_dup 0)
1702 (vec_duplicate:V4SI (match_dup 1)))]
1703 {
1704 operands[0] = lowpart_subreg (V4SImode, operands[0],
1705 GET_MODE (operands[0]));
1706 }
1707 [(set_attr "isa" "*,sse_noavx,avx,avx")
1708 (set_attr "mmx_isa" "native,*,*,*")
1709 (set_attr "type" "mmxcvt,ssemov,ssemov,ssemov")
1710 (set_attr "mode" "DI,TI,TI,TI")])
1711
1712 (define_insn "*mmx_concatv2si"
1713 [(set (match_operand:V2SI 0 "register_operand" "=y,y")
1714 (vec_concat:V2SI
1715 (match_operand:SI 1 "nonimmediate_operand" " 0,rm")
1716 (match_operand:SI 2 "nonimm_or_0_operand" "ym,C")))]
1717 "TARGET_MMX && !TARGET_SSE"
1718 "@
1719 punpckldq\t{%2, %0|%0, %2}
1720 movd\t{%1, %0|%0, %1}"
1721 [(set_attr "type" "mmxcvt,mmxmov")
1722 (set_attr "mode" "DI")])
1723
1724 (define_expand "vec_setv2si"
1725 [(match_operand:V2SI 0 "register_operand")
1726 (match_operand:SI 1 "register_operand")
1727 (match_operand 2 "const_int_operand")]
1728 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1729 {
1730 ix86_expand_vector_set (TARGET_MMX_WITH_SSE, operands[0], operands[1],
1731 INTVAL (operands[2]));
1732 DONE;
1733 })
1734
1735 ;; Avoid combining registers from different units in a single alternative,
1736 ;; see comment above inline_secondary_memory_needed function in i386.c
1737 (define_insn_and_split "*vec_extractv2si_0"
1738 [(set (match_operand:SI 0 "nonimmediate_operand" "=x,m,y, m,r,r")
1739 (vec_select:SI
1740 (match_operand:V2SI 1 "nonimmediate_operand" "xm,x,ym,y,m,x")
1741 (parallel [(const_int 0)])))]
1742 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1743 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1744 "#"
1745 "&& reload_completed"
1746 [(set (match_dup 0) (match_dup 1))]
1747 "operands[1] = gen_lowpart (SImode, operands[1]);"
1748 [(set_attr "isa" "*,*,*,*,*,sse2")
1749 (set_attr "mmx_isa" "*,*,native,native,*,*")
1750 (set (attr "preferred_for_speed")
1751 (cond [(eq_attr "alternative" "5")
1752 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
1753 ]
1754 (symbol_ref "true")))])
1755
1756 (define_insn "*vec_extractv2si_0_zext_sse4"
1757 [(set (match_operand:DI 0 "register_operand" "=r,x")
1758 (zero_extend:DI
1759 (vec_select:SI
1760 (match_operand:V2SI 1 "register_operand" "x,x")
1761 (parallel [(const_int 0)]))))]
1762 "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_SSE4_1"
1763 "#"
1764 [(set_attr "isa" "x64,*")
1765 (set (attr "preferred_for_speed")
1766 (cond [(eq_attr "alternative" "0")
1767 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
1768 ]
1769 (symbol_ref "true")))])
1770
1771 (define_insn "*vec_extractv2si_0_zext"
1772 [(set (match_operand:DI 0 "register_operand" "=r")
1773 (zero_extend:DI
1774 (vec_select:SI
1775 (match_operand:V2SI 1 "register_operand" "x")
1776 (parallel [(const_int 0)]))))]
1777 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1778 && TARGET_64BIT && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_FROM_VEC"
1779 "#")
1780
1781 (define_split
1782 [(set (match_operand:DI 0 "register_operand")
1783 (zero_extend:DI
1784 (vec_select:SI
1785 (match_operand:V2SI 1 "register_operand")
1786 (parallel [(const_int 0)]))))]
1787 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1788 && TARGET_SSE2 && reload_completed"
1789 [(set (match_dup 0) (zero_extend:DI (match_dup 1)))]
1790 "operands[1] = gen_lowpart (SImode, operands[1]);")
1791
1792 ;; Avoid combining registers from different units in a single alternative,
1793 ;; see comment above inline_secondary_memory_needed function in i386.c
1794 (define_insn "*vec_extractv2si_1"
1795 [(set (match_operand:SI 0 "nonimmediate_operand" "=y,rm,x,x,y,x,r")
1796 (vec_select:SI
1797 (match_operand:V2SI 1 "nonimmediate_operand" " 0,x ,x,x,o,o,o")
1798 (parallel [(const_int 1)])))]
1799 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1800 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1801 "@
1802 punpckhdq\t%0, %0
1803 %vpextrd\t{$1, %1, %0|%0, %1, 1}
1804 %vpshufd\t{$0xe5, %1, %0|%0, %1, 0xe5}
1805 shufps\t{$0xe5, %1, %0|%0, %1, 0xe5}
1806 #
1807 #
1808 #"
1809 [(set_attr "isa" "*,sse4,sse2,noavx,*,*,*")
1810 (set_attr "mmx_isa" "native,*,*,*,native,*,*")
1811 (set_attr "type" "mmxcvt,ssemov,sseshuf1,sseshuf1,mmxmov,ssemov,imov")
1812 (set (attr "length_immediate")
1813 (if_then_else (eq_attr "alternative" "1,2,3")
1814 (const_string "1")
1815 (const_string "*")))
1816 (set_attr "prefix" "orig,maybe_vex,maybe_vex,orig,orig,orig,orig")
1817 (set_attr "mode" "DI,TI,TI,V4SF,SI,SI,SI")])
1818
1819 (define_split
1820 [(set (match_operand:SI 0 "register_operand")
1821 (vec_select:SI
1822 (match_operand:V2SI 1 "memory_operand")
1823 (parallel [(const_int 1)])))]
1824 "(TARGET_MMX || TARGET_MMX_WITH_SSE) && reload_completed"
1825 [(set (match_dup 0) (match_dup 1))]
1826 "operands[1] = adjust_address (operands[1], SImode, 4);")
1827
1828 (define_insn "*vec_extractv2si_1_zext"
1829 [(set (match_operand:DI 0 "register_operand" "=r")
1830 (zero_extend:DI
1831 (vec_select:SI
1832 (match_operand:V2SI 1 "register_operand" "x")
1833 (parallel [(const_int 1)]))))]
1834 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1835 && TARGET_64BIT && TARGET_SSE4_1"
1836 "%vpextrd\t{$1, %1, %k0|%k0, %1, 1}"
1837 [(set_attr "type" "sselog1")
1838 (set_attr "prefix_extra" "1")
1839 (set_attr "length_immediate" "1")
1840 (set_attr "prefix" "maybe_vex")
1841 (set_attr "mode" "TI")])
1842
1843 (define_insn_and_split "*vec_extractv2si_zext_mem"
1844 [(set (match_operand:DI 0 "register_operand" "=y,x,r")
1845 (zero_extend:DI
1846 (vec_select:SI
1847 (match_operand:V2SI 1 "memory_operand" "o,o,o")
1848 (parallel [(match_operand:SI 2 "const_0_to_1_operand")]))))]
1849 "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_64BIT"
1850 "#"
1851 "&& reload_completed"
1852 [(set (match_dup 0) (zero_extend:DI (match_dup 1)))]
1853 {
1854 operands[1] = adjust_address (operands[1], SImode, INTVAL (operands[2]) * 4);
1855 }
1856 [(set_attr "isa" "*,sse2,*")
1857 (set_attr "mmx_isa" "native,*,*")])
1858
1859 (define_expand "vec_extractv2sisi"
1860 [(match_operand:SI 0 "register_operand")
1861 (match_operand:V2SI 1 "register_operand")
1862 (match_operand 2 "const_int_operand")]
1863 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1864 {
1865 ix86_expand_vector_extract (TARGET_MMX_WITH_SSE, operands[0],
1866 operands[1], INTVAL (operands[2]));
1867 DONE;
1868 })
1869
1870 (define_expand "vec_initv2sisi"
1871 [(match_operand:V2SI 0 "register_operand")
1872 (match_operand 1)]
1873 "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_SSE"
1874 {
1875 ix86_expand_vector_init (TARGET_MMX_WITH_SSE, operands[0],
1876 operands[1]);
1877 DONE;
1878 })
1879
1880 (define_expand "vec_setv4hi"
1881 [(match_operand:V4HI 0 "register_operand")
1882 (match_operand:HI 1 "register_operand")
1883 (match_operand 2 "const_int_operand")]
1884 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1885 {
1886 ix86_expand_vector_set (TARGET_MMX_WITH_SSE, operands[0], operands[1],
1887 INTVAL (operands[2]));
1888 DONE;
1889 })
1890
1891 (define_expand "vec_extractv4hihi"
1892 [(match_operand:HI 0 "register_operand")
1893 (match_operand:V4HI 1 "register_operand")
1894 (match_operand 2 "const_int_operand")]
1895 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1896 {
1897 ix86_expand_vector_extract (TARGET_MMX_WITH_SSE, operands[0],
1898 operands[1], INTVAL (operands[2]));
1899 DONE;
1900 })
1901
1902 (define_expand "vec_initv4hihi"
1903 [(match_operand:V4HI 0 "register_operand")
1904 (match_operand 1)]
1905 "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_SSE"
1906 {
1907 ix86_expand_vector_init (TARGET_MMX_WITH_SSE, operands[0],
1908 operands[1]);
1909 DONE;
1910 })
1911
1912 (define_expand "vec_setv8qi"
1913 [(match_operand:V8QI 0 "register_operand")
1914 (match_operand:QI 1 "register_operand")
1915 (match_operand 2 "const_int_operand")]
1916 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1917 {
1918 ix86_expand_vector_set (TARGET_MMX_WITH_SSE, operands[0], operands[1],
1919 INTVAL (operands[2]));
1920 DONE;
1921 })
1922
1923 (define_expand "vec_extractv8qiqi"
1924 [(match_operand:QI 0 "register_operand")
1925 (match_operand:V8QI 1 "register_operand")
1926 (match_operand 2 "const_int_operand")]
1927 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1928 {
1929 ix86_expand_vector_extract (TARGET_MMX_WITH_SSE, operands[0],
1930 operands[1], INTVAL (operands[2]));
1931 DONE;
1932 })
1933
1934 (define_expand "vec_initv8qiqi"
1935 [(match_operand:V8QI 0 "register_operand")
1936 (match_operand 1)]
1937 "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_SSE"
1938 {
1939 ix86_expand_vector_init (TARGET_MMX_WITH_SSE, operands[0],
1940 operands[1]);
1941 DONE;
1942 })
1943
1944 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1945 ;;
1946 ;; Miscellaneous
1947 ;;
1948 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1949
1950 (define_expand "mmx_uavg<mode>3"
1951 [(set (match_operand:MMXMODE12 0 "register_operand")
1952 (truncate:MMXMODE12
1953 (lshiftrt:<mmxdoublemode>
1954 (plus:<mmxdoublemode>
1955 (plus:<mmxdoublemode>
1956 (zero_extend:<mmxdoublemode>
1957 (match_operand:MMXMODE12 1 "register_mmxmem_operand"))
1958 (zero_extend:<mmxdoublemode>
1959 (match_operand:MMXMODE12 2 "register_mmxmem_operand")))
1960 (match_dup 3))
1961 (const_int 1))))]
1962 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1963 && (TARGET_SSE || TARGET_3DNOW)"
1964 {
1965 operands[3] = CONST1_RTX(<mmxdoublemode>mode);
1966 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
1967 })
1968
1969 (define_insn "*mmx_uavgv8qi3"
1970 [(set (match_operand:V8QI 0 "register_operand" "=y,x,Yv")
1971 (truncate:V8QI
1972 (lshiftrt:V8HI
1973 (plus:V8HI
1974 (plus:V8HI
1975 (zero_extend:V8HI
1976 (match_operand:V8QI 1 "register_mmxmem_operand" "%0,0,Yv"))
1977 (zero_extend:V8HI
1978 (match_operand:V8QI 2 "register_mmxmem_operand" "ym,x,Yv")))
1979 (const_vector:V8HI [(const_int 1) (const_int 1)
1980 (const_int 1) (const_int 1)
1981 (const_int 1) (const_int 1)
1982 (const_int 1) (const_int 1)]))
1983 (const_int 1))))]
1984 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1985 && (TARGET_SSE || TARGET_3DNOW)
1986 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
1987 {
1988 switch (which_alternative)
1989 {
1990 case 2:
1991 return "vpavgb\t{%2, %1, %0|%0, %1, %2}";
1992 case 1:
1993 case 0:
1994 /* These two instructions have the same operation, but their encoding
1995 is different. Prefer the one that is de facto standard. */
1996 if (TARGET_SSE || TARGET_3DNOW_A)
1997 return "pavgb\t{%2, %0|%0, %2}";
1998 else
1999 return "pavgusb\t{%2, %0|%0, %2}";
2000 default:
2001 gcc_unreachable ();
2002 }
2003 }
2004 [(set_attr "isa" "*,sse2_noavx,avx")
2005 (set_attr "mmx_isa" "native,*,*")
2006 (set_attr "type" "mmxshft,sseiadd,sseiadd")
2007 (set (attr "prefix_extra")
2008 (if_then_else
2009 (not (ior (match_test "TARGET_SSE")
2010 (match_test "TARGET_3DNOW_A")))
2011 (const_string "1")
2012 (const_string "*")))
2013 (set_attr "mode" "DI,TI,TI")])
2014
2015 (define_insn "*mmx_uavgv4hi3"
2016 [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
2017 (truncate:V4HI
2018 (lshiftrt:V4SI
2019 (plus:V4SI
2020 (plus:V4SI
2021 (zero_extend:V4SI
2022 (match_operand:V4HI 1 "register_mmxmem_operand" "%0,0,Yv"))
2023 (zero_extend:V4SI
2024 (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv")))
2025 (const_vector:V4SI [(const_int 1) (const_int 1)
2026 (const_int 1) (const_int 1)]))
2027 (const_int 1))))]
2028 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
2029 && (TARGET_SSE || TARGET_3DNOW_A)
2030 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
2031 "@
2032 pavgw\t{%2, %0|%0, %2}
2033 pavgw\t{%2, %0|%0, %2}
2034 vpavgw\t{%2, %1, %0|%0, %1, %2}"
2035 [(set_attr "isa" "*,sse2_noavx,avx")
2036 (set_attr "mmx_isa" "native,*,*")
2037 (set_attr "type" "mmxshft,sseiadd,sseiadd")
2038 (set_attr "mode" "DI,TI,TI")])
2039
2040 (define_expand "uavg<mode>3_ceil"
2041 [(set (match_operand:MMXMODE12 0 "register_operand")
2042 (truncate:MMXMODE12
2043 (lshiftrt:<mmxdoublemode>
2044 (plus:<mmxdoublemode>
2045 (plus:<mmxdoublemode>
2046 (zero_extend:<mmxdoublemode>
2047 (match_operand:MMXMODE12 1 "register_operand"))
2048 (zero_extend:<mmxdoublemode>
2049 (match_operand:MMXMODE12 2 "register_operand")))
2050 (match_dup 3))
2051 (const_int 1))))]
2052 "TARGET_MMX_WITH_SSE"
2053 {
2054 operands[3] = CONST1_RTX(<mmxdoublemode>mode);
2055 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
2056 })
2057
2058 (define_insn "mmx_psadbw"
2059 [(set (match_operand:V1DI 0 "register_operand" "=y,x,Yv")
2060 (unspec:V1DI [(match_operand:V8QI 1 "register_operand" "0,0,Yv")
2061 (match_operand:V8QI 2 "register_mmxmem_operand" "ym,x,Yv")]
2062 UNSPEC_PSADBW))]
2063 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
2064 && (TARGET_SSE || TARGET_3DNOW_A)"
2065 "@
2066 psadbw\t{%2, %0|%0, %2}
2067 psadbw\t{%2, %0|%0, %2}
2068 vpsadbw\t{%2, %1, %0|%0, %1, %2}"
2069 [(set_attr "isa" "*,sse2_noavx,avx")
2070 (set_attr "mmx_isa" "native,*,*")
2071 (set_attr "type" "mmxshft,sseiadd,sseiadd")
2072 (set_attr "mode" "DI,TI,TI")])
2073
2074 (define_expand "reduc_plus_scal_v8qi"
2075 [(plus:V8QI
2076 (match_operand:QI 0 "register_operand")
2077 (match_operand:V8QI 1 "register_operand"))]
2078 "TARGET_MMX_WITH_SSE"
2079 {
2080 rtx tmp = gen_reg_rtx (V8QImode);
2081 emit_move_insn (tmp, CONST0_RTX (V8QImode));
2082 rtx tmp2 = gen_reg_rtx (V1DImode);
2083 emit_insn (gen_mmx_psadbw (tmp2, operands[1], tmp));
2084 tmp2 = gen_lowpart (V8QImode, tmp2);
2085 emit_insn (gen_vec_extractv8qiqi (operands[0], tmp2, const0_rtx));
2086 DONE;
2087 })
2088
2089 (define_expand "usadv8qi"
2090 [(match_operand:V2SI 0 "register_operand")
2091 (match_operand:V8QI 1 "register_operand")
2092 (match_operand:V8QI 2 "register_operand")
2093 (match_operand:V2SI 3 "register_operand")]
2094 "TARGET_MMX_WITH_SSE"
2095 {
2096 rtx t1 = gen_reg_rtx (V1DImode);
2097 rtx t2 = gen_reg_rtx (V2SImode);
2098 emit_insn (gen_mmx_psadbw (t1, operands[1], operands[2]));
2099 convert_move (t2, t1, 0);
2100 emit_insn (gen_addv2si3 (operands[0], t2, operands[3]));
2101 DONE;
2102 })
2103
2104 (define_insn_and_split "mmx_pmovmskb"
2105 [(set (match_operand:SI 0 "register_operand" "=r,r")
2106 (unspec:SI [(match_operand:V8QI 1 "register_operand" "y,x")]
2107 UNSPEC_MOVMSK))]
2108 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
2109 && (TARGET_SSE || TARGET_3DNOW_A)"
2110 "@
2111 pmovmskb\t{%1, %0|%0, %1}
2112 #"
2113 "TARGET_SSE2 && reload_completed
2114 && SSE_REGNO_P (REGNO (operands[1]))"
2115 [(set (match_dup 0)
2116 (unspec:SI [(match_dup 1)] UNSPEC_MOVMSK))
2117 (set (match_dup 0)
2118 (zero_extend:SI (match_dup 2)))]
2119 {
2120 /* Generate SSE pmovmskb and zero-extend from QImode to SImode. */
2121 operands[1] = lowpart_subreg (V16QImode, operands[1],
2122 GET_MODE (operands[1]));
2123 operands[2] = lowpart_subreg (QImode, operands[0],
2124 GET_MODE (operands[0]));
2125 }
2126 [(set_attr "mmx_isa" "native,sse")
2127 (set_attr "type" "mmxcvt,ssemov")
2128 (set_attr "mode" "DI,TI")])
2129
2130 (define_expand "mmx_maskmovq"
2131 [(set (match_operand:V8QI 0 "memory_operand")
2132 (unspec:V8QI [(match_operand:V8QI 1 "register_operand")
2133 (match_operand:V8QI 2 "register_operand")
2134 (match_dup 0)]
2135 UNSPEC_MASKMOV))]
2136 "TARGET_SSE || TARGET_3DNOW_A")
2137
2138 (define_insn "*mmx_maskmovq"
2139 [(set (mem:V8QI (match_operand:P 0 "register_operand" "D"))
2140 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
2141 (match_operand:V8QI 2 "register_operand" "y")
2142 (mem:V8QI (match_dup 0))]
2143 UNSPEC_MASKMOV))]
2144 "TARGET_SSE || TARGET_3DNOW_A"
2145 ;; @@@ check ordering of operands in intel/nonintel syntax
2146 "maskmovq\t{%2, %1|%1, %2}"
2147 [(set_attr "type" "mmxcvt")
2148 (set_attr "znver1_decode" "vector")
2149 (set_attr "mode" "DI")])
2150
2151 (define_int_iterator EMMS
2152 [(UNSPECV_EMMS "TARGET_MMX")
2153 (UNSPECV_FEMMS "TARGET_3DNOW")])
2154
2155 (define_int_attr emms
2156 [(UNSPECV_EMMS "emms")
2157 (UNSPECV_FEMMS "femms")])
2158
2159 (define_expand "mmx_<emms>"
2160 [(parallel
2161 [(unspec_volatile [(const_int 0)] EMMS)
2162 (clobber (reg:XF ST0_REG))
2163 (clobber (reg:XF ST1_REG))
2164 (clobber (reg:XF ST2_REG))
2165 (clobber (reg:XF ST3_REG))
2166 (clobber (reg:XF ST4_REG))
2167 (clobber (reg:XF ST5_REG))
2168 (clobber (reg:XF ST6_REG))
2169 (clobber (reg:XF ST7_REG))
2170 (clobber (reg:DI MM0_REG))
2171 (clobber (reg:DI MM1_REG))
2172 (clobber (reg:DI MM2_REG))
2173 (clobber (reg:DI MM3_REG))
2174 (clobber (reg:DI MM4_REG))
2175 (clobber (reg:DI MM5_REG))
2176 (clobber (reg:DI MM6_REG))
2177 (clobber (reg:DI MM7_REG))])]
2178 "TARGET_MMX || TARGET_MMX_WITH_SSE"
2179 {
2180 if (!TARGET_MMX)
2181 {
2182 emit_insn (gen_nop ());
2183 DONE;
2184 }
2185 })
2186
2187 (define_insn "*mmx_<emms>"
2188 [(unspec_volatile [(const_int 0)] EMMS)
2189 (clobber (reg:XF ST0_REG))
2190 (clobber (reg:XF ST1_REG))
2191 (clobber (reg:XF ST2_REG))
2192 (clobber (reg:XF ST3_REG))
2193 (clobber (reg:XF ST4_REG))
2194 (clobber (reg:XF ST5_REG))
2195 (clobber (reg:XF ST6_REG))
2196 (clobber (reg:XF ST7_REG))
2197 (clobber (reg:DI MM0_REG))
2198 (clobber (reg:DI MM1_REG))
2199 (clobber (reg:DI MM2_REG))
2200 (clobber (reg:DI MM3_REG))
2201 (clobber (reg:DI MM4_REG))
2202 (clobber (reg:DI MM5_REG))
2203 (clobber (reg:DI MM6_REG))
2204 (clobber (reg:DI MM7_REG))]
2205 ""
2206 "<emms>"
2207 [(set_attr "type" "mmx")
2208 (set_attr "modrm" "0")
2209 (set_attr "memory" "none")])