i386: Emulate MMX mmx_pmaddwd with SSE
[gcc.git] / gcc / config / i386 / mmx.md
1 ;; GCC machine description for MMX and 3dNOW! instructions
2 ;; Copyright (C) 2005-2019 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 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
62 ;;
63 ;; Move patterns
64 ;;
65 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
66
67 ;; All of these patterns are enabled for MMX as well as 3dNOW.
68 ;; This is essential for maintaining stable calling conventions.
69
70 (define_expand "mov<mode>"
71 [(set (match_operand:MMXMODE 0 "nonimmediate_operand")
72 (match_operand:MMXMODE 1 "nonimmediate_operand"))]
73 "TARGET_MMX"
74 {
75 ix86_expand_vector_move (<MODE>mode, operands);
76 DONE;
77 })
78
79 (define_insn "*mov<mode>_internal"
80 [(set (match_operand:MMXMODE 0 "nonimmediate_operand"
81 "=r ,o ,r,r ,m ,?!y,!y,?!y,m ,r ,?!y,v,v,v,m,r,v,!y,*x")
82 (match_operand:MMXMODE 1 "nonimm_or_0_operand"
83 "rCo,rC,C,rm,rC,C ,!y,m ,?!y,?!y,r ,C,v,m,v,v,r,*x,!y"))]
84 "TARGET_MMX
85 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
86 {
87 switch (get_attr_type (insn))
88 {
89 case TYPE_MULTI:
90 return "#";
91
92 case TYPE_IMOV:
93 if (get_attr_mode (insn) == MODE_SI)
94 return "mov{l}\t{%1, %k0|%k0, %1}";
95 else
96 return "mov{q}\t{%1, %0|%0, %1}";
97
98 case TYPE_MMX:
99 return "pxor\t%0, %0";
100
101 case TYPE_MMXMOV:
102 /* Handle broken assemblers that require movd instead of movq. */
103 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
104 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
105 return "movd\t{%1, %0|%0, %1}";
106 return "movq\t{%1, %0|%0, %1}";
107
108 case TYPE_SSECVT:
109 if (SSE_REG_P (operands[0]))
110 return "movq2dq\t{%1, %0|%0, %1}";
111 else
112 return "movdq2q\t{%1, %0|%0, %1}";
113
114 case TYPE_SSELOG1:
115 return standard_sse_constant_opcode (insn, operands);
116
117 case TYPE_SSEMOV:
118 switch (get_attr_mode (insn))
119 {
120 case MODE_DI:
121 /* Handle broken assemblers that require movd instead of movq. */
122 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
123 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
124 return "%vmovd\t{%1, %0|%0, %1}";
125 return "%vmovq\t{%1, %0|%0, %1}";
126 case MODE_TI:
127 return "%vmovdqa\t{%1, %0|%0, %1}";
128 case MODE_XI:
129 return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
130
131 case MODE_V2SF:
132 if (TARGET_AVX && REG_P (operands[0]))
133 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
134 return "%vmovlps\t{%1, %0|%0, %1}";
135 case MODE_V4SF:
136 return "%vmovaps\t{%1, %0|%0, %1}";
137
138 default:
139 gcc_unreachable ();
140 }
141
142 default:
143 gcc_unreachable ();
144 }
145 }
146 [(set (attr "isa")
147 (cond [(eq_attr "alternative" "0,1")
148 (const_string "nox64")
149 (eq_attr "alternative" "2,3,4,9,10")
150 (const_string "x64")
151 (eq_attr "alternative" "15,16")
152 (const_string "x64_sse2")
153 (eq_attr "alternative" "17,18")
154 (const_string "sse2")
155 ]
156 (const_string "*")))
157 (set (attr "type")
158 (cond [(eq_attr "alternative" "0,1")
159 (const_string "multi")
160 (eq_attr "alternative" "2,3,4")
161 (const_string "imov")
162 (eq_attr "alternative" "5")
163 (const_string "mmx")
164 (eq_attr "alternative" "6,7,8,9,10")
165 (const_string "mmxmov")
166 (eq_attr "alternative" "11")
167 (const_string "sselog1")
168 (eq_attr "alternative" "17,18")
169 (const_string "ssecvt")
170 ]
171 (const_string "ssemov")))
172 (set (attr "prefix_rex")
173 (if_then_else (eq_attr "alternative" "9,10,15,16")
174 (const_string "1")
175 (const_string "*")))
176 (set (attr "prefix")
177 (if_then_else (eq_attr "type" "sselog1,ssemov")
178 (const_string "maybe_vex")
179 (const_string "orig")))
180 (set (attr "prefix_data16")
181 (if_then_else
182 (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
183 (const_string "1")
184 (const_string "*")))
185 (set (attr "mode")
186 (cond [(eq_attr "alternative" "2")
187 (const_string "SI")
188 (eq_attr "alternative" "11,12")
189 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
190 (match_operand 1 "ext_sse_reg_operand"))
191 (const_string "XI")
192 (match_test "<MODE>mode == V2SFmode")
193 (const_string "V4SF")
194 (ior (not (match_test "TARGET_SSE2"))
195 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
196 (const_string "V4SF")
197 (match_test "TARGET_AVX")
198 (const_string "TI")
199 (match_test "optimize_function_for_size_p (cfun)")
200 (const_string "V4SF")
201 ]
202 (const_string "TI"))
203
204 (and (eq_attr "alternative" "13,14")
205 (ior (match_test "<MODE>mode == V2SFmode")
206 (not (match_test "TARGET_SSE2"))))
207 (const_string "V2SF")
208 ]
209 (const_string "DI")))
210 (set (attr "preferred_for_speed")
211 (cond [(eq_attr "alternative" "9,15")
212 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
213 (eq_attr "alternative" "10,16")
214 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
215 ]
216 (symbol_ref "true")))])
217
218 (define_split
219 [(set (match_operand:MMXMODE 0 "nonimmediate_gr_operand")
220 (match_operand:MMXMODE 1 "nonimmediate_gr_operand"))]
221 "!TARGET_64BIT && reload_completed"
222 [(const_int 0)]
223 "ix86_split_long_move (operands); DONE;")
224
225 (define_split
226 [(set (match_operand:MMXMODE 0 "nonimmediate_gr_operand")
227 (match_operand:MMXMODE 1 "const0_operand"))]
228 "!TARGET_64BIT && reload_completed"
229 [(const_int 0)]
230 "ix86_split_long_move (operands); DONE;")
231
232 (define_expand "movmisalign<mode>"
233 [(set (match_operand:MMXMODE 0 "nonimmediate_operand")
234 (match_operand:MMXMODE 1 "nonimmediate_operand"))]
235 "TARGET_MMX"
236 {
237 ix86_expand_vector_move (<MODE>mode, operands);
238 DONE;
239 })
240
241 (define_insn "sse_movntq"
242 [(set (match_operand:DI 0 "memory_operand" "=m")
243 (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
244 UNSPEC_MOVNTQ))]
245 "TARGET_SSE || TARGET_3DNOW_A"
246 "movntq\t{%1, %0|%0, %1}"
247 [(set_attr "type" "mmxmov")
248 (set_attr "mode" "DI")])
249
250 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
251 ;;
252 ;; Parallel single-precision floating point arithmetic
253 ;;
254 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
255
256 (define_expand "mmx_addv2sf3"
257 [(set (match_operand:V2SF 0 "register_operand")
258 (plus:V2SF
259 (match_operand:V2SF 1 "nonimmediate_operand")
260 (match_operand:V2SF 2 "nonimmediate_operand")))]
261 "TARGET_3DNOW"
262 "ix86_fixup_binary_operands_no_copy (PLUS, V2SFmode, operands);")
263
264 (define_insn "*mmx_addv2sf3"
265 [(set (match_operand:V2SF 0 "register_operand" "=y")
266 (plus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
267 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
268 "TARGET_3DNOW && ix86_binary_operator_ok (PLUS, V2SFmode, operands)"
269 "pfadd\t{%2, %0|%0, %2}"
270 [(set_attr "type" "mmxadd")
271 (set_attr "prefix_extra" "1")
272 (set_attr "mode" "V2SF")])
273
274 (define_expand "mmx_subv2sf3"
275 [(set (match_operand:V2SF 0 "register_operand")
276 (minus:V2SF (match_operand:V2SF 1 "register_operand")
277 (match_operand:V2SF 2 "nonimmediate_operand")))]
278 "TARGET_3DNOW")
279
280 (define_expand "mmx_subrv2sf3"
281 [(set (match_operand:V2SF 0 "register_operand")
282 (minus:V2SF (match_operand:V2SF 2 "register_operand")
283 (match_operand:V2SF 1 "nonimmediate_operand")))]
284 "TARGET_3DNOW")
285
286 (define_insn "*mmx_subv2sf3"
287 [(set (match_operand:V2SF 0 "register_operand" "=y,y")
288 (minus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "0,ym")
289 (match_operand:V2SF 2 "nonimmediate_operand" "ym,0")))]
290 "TARGET_3DNOW && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
291 "@
292 pfsub\t{%2, %0|%0, %2}
293 pfsubr\t{%1, %0|%0, %1}"
294 [(set_attr "type" "mmxadd")
295 (set_attr "prefix_extra" "1")
296 (set_attr "mode" "V2SF")])
297
298 (define_expand "mmx_mulv2sf3"
299 [(set (match_operand:V2SF 0 "register_operand")
300 (mult:V2SF (match_operand:V2SF 1 "nonimmediate_operand")
301 (match_operand:V2SF 2 "nonimmediate_operand")))]
302 "TARGET_3DNOW"
303 "ix86_fixup_binary_operands_no_copy (MULT, V2SFmode, operands);")
304
305 (define_insn "*mmx_mulv2sf3"
306 [(set (match_operand:V2SF 0 "register_operand" "=y")
307 (mult:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
308 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
309 "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V2SFmode, operands)"
310 "pfmul\t{%2, %0|%0, %2}"
311 [(set_attr "type" "mmxmul")
312 (set_attr "prefix_extra" "1")
313 (set_attr "mode" "V2SF")])
314
315 (define_expand "mmx_<code>v2sf3"
316 [(set (match_operand:V2SF 0 "register_operand")
317 (smaxmin:V2SF
318 (match_operand:V2SF 1 "nonimmediate_operand")
319 (match_operand:V2SF 2 "nonimmediate_operand")))]
320 "TARGET_3DNOW"
321 {
322 if (!flag_finite_math_only || flag_signed_zeros)
323 {
324 operands[1] = force_reg (V2SFmode, operands[1]);
325 emit_insn (gen_mmx_ieee_<maxmin_float>v2sf3
326 (operands[0], operands[1], operands[2]));
327 DONE;
328 }
329 else
330 ix86_fixup_binary_operands_no_copy (<CODE>, V2SFmode, operands);
331 })
332
333 ;; These versions of the min/max patterns are intentionally ignorant of
334 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
335 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
336 ;; are undefined in this condition, we're certain this is correct.
337
338 (define_insn "*mmx_<code>v2sf3"
339 [(set (match_operand:V2SF 0 "register_operand" "=y")
340 (smaxmin:V2SF
341 (match_operand:V2SF 1 "nonimmediate_operand" "%0")
342 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
343 "TARGET_3DNOW && ix86_binary_operator_ok (<CODE>, V2SFmode, operands)"
344 "pf<maxmin_float>\t{%2, %0|%0, %2}"
345 [(set_attr "type" "mmxadd")
346 (set_attr "prefix_extra" "1")
347 (set_attr "mode" "V2SF")])
348
349 ;; These versions of the min/max patterns implement exactly the operations
350 ;; min = (op1 < op2 ? op1 : op2)
351 ;; max = (!(op1 < op2) ? op1 : op2)
352 ;; Their operands are not commutative, and thus they may be used in the
353 ;; presence of -0.0 and NaN.
354
355 (define_insn "mmx_ieee_<ieee_maxmin>v2sf3"
356 [(set (match_operand:V2SF 0 "register_operand" "=y")
357 (unspec:V2SF
358 [(match_operand:V2SF 1 "register_operand" "0")
359 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
360 IEEE_MAXMIN))]
361 "TARGET_3DNOW"
362 "pf<ieee_maxmin>\t{%2, %0|%0, %2}"
363 [(set_attr "type" "mmxadd")
364 (set_attr "prefix_extra" "1")
365 (set_attr "mode" "V2SF")])
366
367 (define_insn "mmx_rcpv2sf2"
368 [(set (match_operand:V2SF 0 "register_operand" "=y")
369 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
370 UNSPEC_PFRCP))]
371 "TARGET_3DNOW"
372 "pfrcp\t{%1, %0|%0, %1}"
373 [(set_attr "type" "mmx")
374 (set_attr "prefix_extra" "1")
375 (set_attr "mode" "V2SF")])
376
377 (define_insn "mmx_rcpit1v2sf3"
378 [(set (match_operand:V2SF 0 "register_operand" "=y")
379 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
380 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
381 UNSPEC_PFRCPIT1))]
382 "TARGET_3DNOW"
383 "pfrcpit1\t{%2, %0|%0, %2}"
384 [(set_attr "type" "mmx")
385 (set_attr "prefix_extra" "1")
386 (set_attr "mode" "V2SF")])
387
388 (define_insn "mmx_rcpit2v2sf3"
389 [(set (match_operand:V2SF 0 "register_operand" "=y")
390 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
391 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
392 UNSPEC_PFRCPIT2))]
393 "TARGET_3DNOW"
394 "pfrcpit2\t{%2, %0|%0, %2}"
395 [(set_attr "type" "mmx")
396 (set_attr "prefix_extra" "1")
397 (set_attr "mode" "V2SF")])
398
399 (define_insn "mmx_rsqrtv2sf2"
400 [(set (match_operand:V2SF 0 "register_operand" "=y")
401 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
402 UNSPEC_PFRSQRT))]
403 "TARGET_3DNOW"
404 "pfrsqrt\t{%1, %0|%0, %1}"
405 [(set_attr "type" "mmx")
406 (set_attr "prefix_extra" "1")
407 (set_attr "mode" "V2SF")])
408
409 (define_insn "mmx_rsqit1v2sf3"
410 [(set (match_operand:V2SF 0 "register_operand" "=y")
411 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
412 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
413 UNSPEC_PFRSQIT1))]
414 "TARGET_3DNOW"
415 "pfrsqit1\t{%2, %0|%0, %2}"
416 [(set_attr "type" "mmx")
417 (set_attr "prefix_extra" "1")
418 (set_attr "mode" "V2SF")])
419
420 (define_insn "mmx_haddv2sf3"
421 [(set (match_operand:V2SF 0 "register_operand" "=y")
422 (vec_concat:V2SF
423 (plus:SF
424 (vec_select:SF
425 (match_operand:V2SF 1 "register_operand" "0")
426 (parallel [(const_int 0)]))
427 (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
428 (plus:SF
429 (vec_select:SF
430 (match_operand:V2SF 2 "nonimmediate_operand" "ym")
431 (parallel [(const_int 0)]))
432 (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
433 "TARGET_3DNOW"
434 "pfacc\t{%2, %0|%0, %2}"
435 [(set_attr "type" "mmxadd")
436 (set_attr "prefix_extra" "1")
437 (set_attr "mode" "V2SF")])
438
439 (define_insn "mmx_hsubv2sf3"
440 [(set (match_operand:V2SF 0 "register_operand" "=y")
441 (vec_concat:V2SF
442 (minus:SF
443 (vec_select:SF
444 (match_operand:V2SF 1 "register_operand" "0")
445 (parallel [(const_int 0)]))
446 (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
447 (minus:SF
448 (vec_select:SF
449 (match_operand:V2SF 2 "nonimmediate_operand" "ym")
450 (parallel [(const_int 0)]))
451 (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
452 "TARGET_3DNOW_A"
453 "pfnacc\t{%2, %0|%0, %2}"
454 [(set_attr "type" "mmxadd")
455 (set_attr "prefix_extra" "1")
456 (set_attr "mode" "V2SF")])
457
458 (define_insn "mmx_addsubv2sf3"
459 [(set (match_operand:V2SF 0 "register_operand" "=y")
460 (vec_merge:V2SF
461 (plus:V2SF
462 (match_operand:V2SF 1 "register_operand" "0")
463 (match_operand:V2SF 2 "nonimmediate_operand" "ym"))
464 (minus:V2SF (match_dup 1) (match_dup 2))
465 (const_int 1)))]
466 "TARGET_3DNOW_A"
467 "pfpnacc\t{%2, %0|%0, %2}"
468 [(set_attr "type" "mmxadd")
469 (set_attr "prefix_extra" "1")
470 (set_attr "mode" "V2SF")])
471
472 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
473 ;;
474 ;; Parallel single-precision floating point comparisons
475 ;;
476 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
477
478 (define_expand "mmx_eqv2sf3"
479 [(set (match_operand:V2SI 0 "register_operand")
480 (eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand")
481 (match_operand:V2SF 2 "nonimmediate_operand")))]
482 "TARGET_3DNOW"
483 "ix86_fixup_binary_operands_no_copy (EQ, V2SFmode, operands);")
484
485 (define_insn "*mmx_eqv2sf3"
486 [(set (match_operand:V2SI 0 "register_operand" "=y")
487 (eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "%0")
488 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
489 "TARGET_3DNOW && ix86_binary_operator_ok (EQ, V2SFmode, operands)"
490 "pfcmpeq\t{%2, %0|%0, %2}"
491 [(set_attr "type" "mmxcmp")
492 (set_attr "prefix_extra" "1")
493 (set_attr "mode" "V2SF")])
494
495 (define_insn "mmx_gtv2sf3"
496 [(set (match_operand:V2SI 0 "register_operand" "=y")
497 (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
498 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
499 "TARGET_3DNOW"
500 "pfcmpgt\t{%2, %0|%0, %2}"
501 [(set_attr "type" "mmxcmp")
502 (set_attr "prefix_extra" "1")
503 (set_attr "mode" "V2SF")])
504
505 (define_insn "mmx_gev2sf3"
506 [(set (match_operand:V2SI 0 "register_operand" "=y")
507 (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
508 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
509 "TARGET_3DNOW"
510 "pfcmpge\t{%2, %0|%0, %2}"
511 [(set_attr "type" "mmxcmp")
512 (set_attr "prefix_extra" "1")
513 (set_attr "mode" "V2SF")])
514
515 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
516 ;;
517 ;; Parallel single-precision floating point conversion operations
518 ;;
519 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
520
521 (define_insn "mmx_pf2id"
522 [(set (match_operand:V2SI 0 "register_operand" "=y")
523 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
524 "TARGET_3DNOW"
525 "pf2id\t{%1, %0|%0, %1}"
526 [(set_attr "type" "mmxcvt")
527 (set_attr "prefix_extra" "1")
528 (set_attr "mode" "V2SF")])
529
530 (define_insn "mmx_pf2iw"
531 [(set (match_operand:V2SI 0 "register_operand" "=y")
532 (sign_extend:V2SI
533 (ss_truncate:V2HI
534 (fix:V2SI
535 (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
536 "TARGET_3DNOW_A"
537 "pf2iw\t{%1, %0|%0, %1}"
538 [(set_attr "type" "mmxcvt")
539 (set_attr "prefix_extra" "1")
540 (set_attr "mode" "V2SF")])
541
542 (define_insn "mmx_pi2fw"
543 [(set (match_operand:V2SF 0 "register_operand" "=y")
544 (float:V2SF
545 (sign_extend:V2SI
546 (truncate:V2HI
547 (match_operand:V2SI 1 "nonimmediate_operand" "ym")))))]
548 "TARGET_3DNOW_A"
549 "pi2fw\t{%1, %0|%0, %1}"
550 [(set_attr "type" "mmxcvt")
551 (set_attr "prefix_extra" "1")
552 (set_attr "mode" "V2SF")])
553
554 (define_insn "mmx_floatv2si2"
555 [(set (match_operand:V2SF 0 "register_operand" "=y")
556 (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
557 "TARGET_3DNOW"
558 "pi2fd\t{%1, %0|%0, %1}"
559 [(set_attr "type" "mmxcvt")
560 (set_attr "prefix_extra" "1")
561 (set_attr "mode" "V2SF")])
562
563 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
564 ;;
565 ;; Parallel single-precision floating point element swizzling
566 ;;
567 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
568
569 (define_insn "mmx_pswapdv2sf2"
570 [(set (match_operand:V2SF 0 "register_operand" "=y")
571 (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
572 (parallel [(const_int 1) (const_int 0)])))]
573 "TARGET_3DNOW_A"
574 "pswapd\t{%1, %0|%0, %1}"
575 [(set_attr "type" "mmxcvt")
576 (set_attr "prefix_extra" "1")
577 (set_attr "mode" "V2SF")])
578
579 (define_insn "*vec_dupv2sf"
580 [(set (match_operand:V2SF 0 "register_operand" "=y")
581 (vec_duplicate:V2SF
582 (match_operand:SF 1 "register_operand" "0")))]
583 "TARGET_MMX"
584 "punpckldq\t%0, %0"
585 [(set_attr "type" "mmxcvt")
586 (set_attr "mode" "DI")])
587
588 (define_insn "*mmx_concatv2sf"
589 [(set (match_operand:V2SF 0 "register_operand" "=y,y")
590 (vec_concat:V2SF
591 (match_operand:SF 1 "nonimmediate_operand" " 0,rm")
592 (match_operand:SF 2 "nonimm_or_0_operand" "ym,C")))]
593 "TARGET_MMX && !TARGET_SSE"
594 "@
595 punpckldq\t{%2, %0|%0, %2}
596 movd\t{%1, %0|%0, %1}"
597 [(set_attr "type" "mmxcvt,mmxmov")
598 (set_attr "mode" "DI")])
599
600 (define_expand "vec_setv2sf"
601 [(match_operand:V2SF 0 "register_operand")
602 (match_operand:SF 1 "register_operand")
603 (match_operand 2 "const_int_operand")]
604 "TARGET_MMX"
605 {
606 ix86_expand_vector_set (false, operands[0], operands[1],
607 INTVAL (operands[2]));
608 DONE;
609 })
610
611 ;; Avoid combining registers from different units in a single alternative,
612 ;; see comment above inline_secondary_memory_needed function in i386.c
613 (define_insn_and_split "*vec_extractv2sf_0"
614 [(set (match_operand:SF 0 "nonimmediate_operand" "=x, m,y ,m,f,r")
615 (vec_select:SF
616 (match_operand:V2SF 1 "nonimmediate_operand" " xm,x,ym,y,m,m")
617 (parallel [(const_int 0)])))]
618 "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
619 "#"
620 "&& reload_completed"
621 [(set (match_dup 0) (match_dup 1))]
622 "operands[1] = gen_lowpart (SFmode, operands[1]);")
623
624 ;; Avoid combining registers from different units in a single alternative,
625 ;; see comment above inline_secondary_memory_needed function in i386.c
626 (define_insn "*vec_extractv2sf_1"
627 [(set (match_operand:SF 0 "nonimmediate_operand" "=y,x,x,y,x,f,r")
628 (vec_select:SF
629 (match_operand:V2SF 1 "nonimmediate_operand" " 0,x,x,o,o,o,o")
630 (parallel [(const_int 1)])))]
631 "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
632 "@
633 punpckhdq\t%0, %0
634 %vmovshdup\t{%1, %0|%0, %1}
635 shufps\t{$0xe5, %1, %0|%0, %1, 0xe5}
636 #
637 #
638 #
639 #"
640 [(set_attr "isa" "*,sse3,noavx,*,*,*,*")
641 (set_attr "type" "mmxcvt,sse,sseshuf1,mmxmov,ssemov,fmov,imov")
642 (set (attr "length_immediate")
643 (if_then_else (eq_attr "alternative" "2")
644 (const_string "1")
645 (const_string "*")))
646 (set (attr "prefix_rep")
647 (if_then_else (eq_attr "alternative" "1")
648 (const_string "1")
649 (const_string "*")))
650 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig,orig,orig")
651 (set_attr "mode" "DI,V4SF,V4SF,SF,SF,SF,SF")])
652
653 (define_split
654 [(set (match_operand:SF 0 "register_operand")
655 (vec_select:SF
656 (match_operand:V2SF 1 "memory_operand")
657 (parallel [(const_int 1)])))]
658 "TARGET_MMX && reload_completed"
659 [(set (match_dup 0) (match_dup 1))]
660 "operands[1] = adjust_address (operands[1], SFmode, 4);")
661
662 (define_expand "vec_extractv2sfsf"
663 [(match_operand:SF 0 "register_operand")
664 (match_operand:V2SF 1 "register_operand")
665 (match_operand 2 "const_int_operand")]
666 "TARGET_MMX"
667 {
668 ix86_expand_vector_extract (false, operands[0], operands[1],
669 INTVAL (operands[2]));
670 DONE;
671 })
672
673 (define_expand "vec_initv2sfsf"
674 [(match_operand:V2SF 0 "register_operand")
675 (match_operand 1)]
676 "TARGET_SSE"
677 {
678 ix86_expand_vector_init (false, operands[0], operands[1]);
679 DONE;
680 })
681
682 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
683 ;;
684 ;; Parallel integral arithmetic
685 ;;
686 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
687
688 (define_expand "mmx_<plusminus_insn><mode>3"
689 [(set (match_operand:MMXMODEI8 0 "register_operand")
690 (plusminus:MMXMODEI8
691 (match_operand:MMXMODEI8 1 "register_mmxmem_operand")
692 (match_operand:MMXMODEI8 2 "register_mmxmem_operand")))]
693 "TARGET_MMX || TARGET_MMX_WITH_SSE"
694 "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
695
696 (define_expand "<plusminus_insn><mode>3"
697 [(set (match_operand:MMXMODEI 0 "register_operand")
698 (plusminus:MMXMODEI
699 (match_operand:MMXMODEI 1 "register_operand")
700 (match_operand:MMXMODEI 2 "register_operand")))]
701 "TARGET_MMX_WITH_SSE"
702 "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
703
704 (define_insn "*mmx_<plusminus_insn><mode>3"
705 [(set (match_operand:MMXMODEI8 0 "register_operand" "=y,x,Yv")
706 (plusminus:MMXMODEI8
707 (match_operand:MMXMODEI8 1 "register_mmxmem_operand" "<comm>0,0,Yv")
708 (match_operand:MMXMODEI8 2 "register_mmxmem_operand" "ym,x,Yv")))]
709 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
710 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
711 "@
712 p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}
713 p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}
714 vp<plusminus_mnemonic><mmxvecsize>\t{%2, %1, %0|%0, %1, %2}"
715 [(set_attr "mmx_isa" "native,x64_noavx,x64_avx")
716 (set_attr "type" "mmxadd,sseadd,sseadd")
717 (set_attr "mode" "DI,TI,TI")])
718
719 (define_expand "mmx_<plusminus_insn><mode>3"
720 [(set (match_operand:MMXMODE12 0 "register_operand")
721 (sat_plusminus:MMXMODE12
722 (match_operand:MMXMODE12 1 "register_mmxmem_operand")
723 (match_operand:MMXMODE12 2 "register_mmxmem_operand")))]
724 "TARGET_MMX || TARGET_MMX_WITH_SSE"
725 "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
726
727 (define_insn "*mmx_<plusminus_insn><mode>3"
728 [(set (match_operand:MMXMODE12 0 "register_operand" "=y,x,Yv")
729 (sat_plusminus:MMXMODE12
730 (match_operand:MMXMODE12 1 "register_mmxmem_operand" "<comm>0,0,Yv")
731 (match_operand:MMXMODE12 2 "register_mmxmem_operand" "ym,x,Yv")))]
732 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
733 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
734 "@
735 p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}
736 p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}
737 vp<plusminus_mnemonic><mmxvecsize>\t{%2, %1, %0|%0, %1, %2}"
738 [(set_attr "mmx_isa" "native,x64_noavx,x64_avx")
739 (set_attr "type" "mmxadd,sseadd,sseadd")
740 (set_attr "mode" "DI,TI,TI")])
741
742 (define_expand "mmx_mulv4hi3"
743 [(set (match_operand:V4HI 0 "register_operand")
744 (mult:V4HI (match_operand:V4HI 1 "register_mmxmem_operand")
745 (match_operand:V4HI 2 "register_mmxmem_operand")))]
746 "TARGET_MMX || TARGET_MMX_WITH_SSE"
747 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
748
749 (define_expand "mulv4hi3"
750 [(set (match_operand:V4HI 0 "register_operand")
751 (mult:V4HI (match_operand:V4HI 1 "register_operand")
752 (match_operand:V4HI 2 "register_operand")))]
753 "TARGET_MMX_WITH_SSE"
754 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
755
756 (define_insn "*mmx_mulv4hi3"
757 [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
758 (mult:V4HI (match_operand:V4HI 1 "register_mmxmem_operand" "%0,0,Yv")
759 (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv")))]
760 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
761 && ix86_binary_operator_ok (MULT, V4HImode, operands)"
762 "@
763 pmullw\t{%2, %0|%0, %2}
764 pmullw\t{%2, %0|%0, %2}
765 vpmullw\t{%2, %1, %0|%0, %1, %2}"
766 [(set_attr "mmx_isa" "native,x64_noavx,x64_avx")
767 (set_attr "type" "mmxmul,ssemul,ssemul")
768 (set_attr "mode" "DI,TI,TI")])
769
770 (define_expand "mmx_smulv4hi3_highpart"
771 [(set (match_operand:V4HI 0 "register_operand")
772 (truncate:V4HI
773 (lshiftrt:V4SI
774 (mult:V4SI
775 (sign_extend:V4SI
776 (match_operand:V4HI 1 "register_mmxmem_operand"))
777 (sign_extend:V4SI
778 (match_operand:V4HI 2 "register_mmxmem_operand")))
779 (const_int 16))))]
780 "TARGET_MMX || TARGET_MMX_WITH_SSE"
781 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
782
783 (define_insn "*mmx_smulv4hi3_highpart"
784 [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
785 (truncate:V4HI
786 (lshiftrt:V4SI
787 (mult:V4SI
788 (sign_extend:V4SI
789 (match_operand:V4HI 1 "register_mmxmem_operand" "%0,0,Yv"))
790 (sign_extend:V4SI
791 (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv")))
792 (const_int 16))))]
793 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
794 && ix86_binary_operator_ok (MULT, V4HImode, operands)"
795 "@
796 pmulhw\t{%2, %0|%0, %2}
797 pmulhw\t{%2, %0|%0, %2}
798 vpmulhw\t{%2, %1, %0|%0, %1, %2}"
799 [(set_attr "mmx_isa" "native,x64_noavx,x64_avx")
800 (set_attr "type" "mmxmul,ssemul,ssemul")
801 (set_attr "mode" "DI,TI,TI")])
802
803 (define_expand "mmx_umulv4hi3_highpart"
804 [(set (match_operand:V4HI 0 "register_operand")
805 (truncate:V4HI
806 (lshiftrt:V4SI
807 (mult:V4SI
808 (zero_extend:V4SI
809 (match_operand:V4HI 1 "nonimmediate_operand"))
810 (zero_extend:V4SI
811 (match_operand:V4HI 2 "nonimmediate_operand")))
812 (const_int 16))))]
813 "TARGET_SSE || TARGET_3DNOW_A"
814 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
815
816 (define_insn "*mmx_umulv4hi3_highpart"
817 [(set (match_operand:V4HI 0 "register_operand" "=y")
818 (truncate:V4HI
819 (lshiftrt:V4SI
820 (mult:V4SI
821 (zero_extend:V4SI
822 (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
823 (zero_extend:V4SI
824 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
825 (const_int 16))))]
826 "(TARGET_SSE || TARGET_3DNOW_A)
827 && ix86_binary_operator_ok (MULT, V4HImode, operands)"
828 "pmulhuw\t{%2, %0|%0, %2}"
829 [(set_attr "type" "mmxmul")
830 (set_attr "mode" "DI")])
831
832 (define_expand "mmx_pmaddwd"
833 [(set (match_operand:V2SI 0 "register_operand")
834 (plus:V2SI
835 (mult:V2SI
836 (sign_extend:V2SI
837 (vec_select:V2HI
838 (match_operand:V4HI 1 "register_mmxmem_operand")
839 (parallel [(const_int 0) (const_int 2)])))
840 (sign_extend:V2SI
841 (vec_select:V2HI
842 (match_operand:V4HI 2 "register_mmxmem_operand")
843 (parallel [(const_int 0) (const_int 2)]))))
844 (mult:V2SI
845 (sign_extend:V2SI
846 (vec_select:V2HI (match_dup 1)
847 (parallel [(const_int 1) (const_int 3)])))
848 (sign_extend:V2SI
849 (vec_select:V2HI (match_dup 2)
850 (parallel [(const_int 1) (const_int 3)]))))))]
851 "TARGET_MMX || TARGET_MMX_WITH_SSE"
852 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
853
854 (define_insn "*mmx_pmaddwd"
855 [(set (match_operand:V2SI 0 "register_operand" "=y,x,Yv")
856 (plus:V2SI
857 (mult:V2SI
858 (sign_extend:V2SI
859 (vec_select:V2HI
860 (match_operand:V4HI 1 "register_mmxmem_operand" "%0,0,Yv")
861 (parallel [(const_int 0) (const_int 2)])))
862 (sign_extend:V2SI
863 (vec_select:V2HI
864 (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv")
865 (parallel [(const_int 0) (const_int 2)]))))
866 (mult:V2SI
867 (sign_extend:V2SI
868 (vec_select:V2HI (match_dup 1)
869 (parallel [(const_int 1) (const_int 3)])))
870 (sign_extend:V2SI
871 (vec_select:V2HI (match_dup 2)
872 (parallel [(const_int 1) (const_int 3)]))))))]
873 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
874 && ix86_binary_operator_ok (MULT, V4HImode, operands)"
875 "@
876 pmaddwd\t{%2, %0|%0, %2}
877 pmaddwd\t{%2, %0|%0, %2}
878 vpmaddwd\t{%2, %1, %0|%0, %1, %2}"
879 [(set_attr "mmx_isa" "native,x64_noavx,x64_avx")
880 (set_attr "type" "mmxmul,sseiadd,sseiadd")
881 (set_attr "mode" "DI,TI,TI")])
882
883 (define_expand "mmx_pmulhrwv4hi3"
884 [(set (match_operand:V4HI 0 "register_operand")
885 (truncate:V4HI
886 (lshiftrt:V4SI
887 (plus:V4SI
888 (mult:V4SI
889 (sign_extend:V4SI
890 (match_operand:V4HI 1 "nonimmediate_operand"))
891 (sign_extend:V4SI
892 (match_operand:V4HI 2 "nonimmediate_operand")))
893 (const_vector:V4SI [(const_int 32768) (const_int 32768)
894 (const_int 32768) (const_int 32768)]))
895 (const_int 16))))]
896 "TARGET_3DNOW"
897 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
898
899 (define_insn "*mmx_pmulhrwv4hi3"
900 [(set (match_operand:V4HI 0 "register_operand" "=y")
901 (truncate:V4HI
902 (lshiftrt:V4SI
903 (plus:V4SI
904 (mult:V4SI
905 (sign_extend:V4SI
906 (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
907 (sign_extend:V4SI
908 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
909 (const_vector:V4SI [(const_int 32768) (const_int 32768)
910 (const_int 32768) (const_int 32768)]))
911 (const_int 16))))]
912 "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V4HImode, operands)"
913 "pmulhrw\t{%2, %0|%0, %2}"
914 [(set_attr "type" "mmxmul")
915 (set_attr "prefix_extra" "1")
916 (set_attr "mode" "DI")])
917
918 (define_expand "sse2_umulv1siv1di3"
919 [(set (match_operand:V1DI 0 "register_operand")
920 (mult:V1DI
921 (zero_extend:V1DI
922 (vec_select:V1SI
923 (match_operand:V2SI 1 "nonimmediate_operand")
924 (parallel [(const_int 0)])))
925 (zero_extend:V1DI
926 (vec_select:V1SI
927 (match_operand:V2SI 2 "nonimmediate_operand")
928 (parallel [(const_int 0)])))))]
929 "TARGET_SSE2"
930 "ix86_fixup_binary_operands_no_copy (MULT, V2SImode, operands);")
931
932 (define_insn "*sse2_umulv1siv1di3"
933 [(set (match_operand:V1DI 0 "register_operand" "=y")
934 (mult:V1DI
935 (zero_extend:V1DI
936 (vec_select:V1SI
937 (match_operand:V2SI 1 "nonimmediate_operand" "%0")
938 (parallel [(const_int 0)])))
939 (zero_extend:V1DI
940 (vec_select:V1SI
941 (match_operand:V2SI 2 "nonimmediate_operand" "ym")
942 (parallel [(const_int 0)])))))]
943 "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V2SImode, operands)"
944 "pmuludq\t{%2, %0|%0, %2}"
945 [(set_attr "type" "mmxmul")
946 (set_attr "mode" "DI")])
947
948 (define_expand "mmx_<code>v4hi3"
949 [(set (match_operand:V4HI 0 "register_operand")
950 (smaxmin:V4HI
951 (match_operand:V4HI 1 "nonimmediate_operand")
952 (match_operand:V4HI 2 "nonimmediate_operand")))]
953 "TARGET_SSE || TARGET_3DNOW_A"
954 "ix86_fixup_binary_operands_no_copy (<CODE>, V4HImode, operands);")
955
956 (define_insn "*mmx_<code>v4hi3"
957 [(set (match_operand:V4HI 0 "register_operand" "=y")
958 (smaxmin:V4HI
959 (match_operand:V4HI 1 "nonimmediate_operand" "%0")
960 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
961 "(TARGET_SSE || TARGET_3DNOW_A)
962 && ix86_binary_operator_ok (<CODE>, V4HImode, operands)"
963 "p<maxmin_int>w\t{%2, %0|%0, %2}"
964 [(set_attr "type" "mmxadd")
965 (set_attr "mode" "DI")])
966
967 (define_expand "mmx_<code>v8qi3"
968 [(set (match_operand:V8QI 0 "register_operand")
969 (umaxmin:V8QI
970 (match_operand:V8QI 1 "nonimmediate_operand")
971 (match_operand:V8QI 2 "nonimmediate_operand")))]
972 "TARGET_SSE || TARGET_3DNOW_A"
973 "ix86_fixup_binary_operands_no_copy (<CODE>, V8QImode, operands);")
974
975 (define_insn "*mmx_<code>v8qi3"
976 [(set (match_operand:V8QI 0 "register_operand" "=y")
977 (umaxmin:V8QI
978 (match_operand:V8QI 1 "nonimmediate_operand" "%0")
979 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
980 "(TARGET_SSE || TARGET_3DNOW_A)
981 && ix86_binary_operator_ok (<CODE>, V8QImode, operands)"
982 "p<maxmin_int>b\t{%2, %0|%0, %2}"
983 [(set_attr "type" "mmxadd")
984 (set_attr "mode" "DI")])
985
986 (define_insn "mmx_ashr<mode>3"
987 [(set (match_operand:MMXMODE24 0 "register_operand" "=y")
988 (ashiftrt:MMXMODE24
989 (match_operand:MMXMODE24 1 "register_operand" "0")
990 (match_operand:DI 2 "nonmemory_operand" "yN")))]
991 "TARGET_MMX"
992 "psra<mmxvecsize>\t{%2, %0|%0, %2}"
993 [(set_attr "type" "mmxshft")
994 (set (attr "length_immediate")
995 (if_then_else (match_operand 2 "const_int_operand")
996 (const_string "1")
997 (const_string "0")))
998 (set_attr "mode" "DI")])
999
1000 (define_insn "mmx_<shift_insn><mode>3"
1001 [(set (match_operand:MMXMODE248 0 "register_operand" "=y")
1002 (any_lshift:MMXMODE248
1003 (match_operand:MMXMODE248 1 "register_operand" "0")
1004 (match_operand:DI 2 "nonmemory_operand" "yN")))]
1005 "TARGET_MMX"
1006 "p<vshift><mmxvecsize>\t{%2, %0|%0, %2}"
1007 [(set_attr "type" "mmxshft")
1008 (set (attr "length_immediate")
1009 (if_then_else (match_operand 2 "const_int_operand")
1010 (const_string "1")
1011 (const_string "0")))
1012 (set_attr "mode" "DI")])
1013
1014 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1015 ;;
1016 ;; Parallel integral comparisons
1017 ;;
1018 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1019
1020 (define_expand "mmx_eq<mode>3"
1021 [(set (match_operand:MMXMODEI 0 "register_operand")
1022 (eq:MMXMODEI
1023 (match_operand:MMXMODEI 1 "nonimmediate_operand")
1024 (match_operand:MMXMODEI 2 "nonimmediate_operand")))]
1025 "TARGET_MMX"
1026 "ix86_fixup_binary_operands_no_copy (EQ, <MODE>mode, operands);")
1027
1028 (define_insn "*mmx_eq<mode>3"
1029 [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
1030 (eq:MMXMODEI
1031 (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
1032 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
1033 "TARGET_MMX && ix86_binary_operator_ok (EQ, <MODE>mode, operands)"
1034 "pcmpeq<mmxvecsize>\t{%2, %0|%0, %2}"
1035 [(set_attr "type" "mmxcmp")
1036 (set_attr "mode" "DI")])
1037
1038 (define_insn "mmx_gt<mode>3"
1039 [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
1040 (gt:MMXMODEI
1041 (match_operand:MMXMODEI 1 "register_operand" "0")
1042 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
1043 "TARGET_MMX"
1044 "pcmpgt<mmxvecsize>\t{%2, %0|%0, %2}"
1045 [(set_attr "type" "mmxcmp")
1046 (set_attr "mode" "DI")])
1047
1048 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1049 ;;
1050 ;; Parallel integral logical operations
1051 ;;
1052 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1053
1054 (define_insn "mmx_andnot<mode>3"
1055 [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
1056 (and:MMXMODEI
1057 (not:MMXMODEI (match_operand:MMXMODEI 1 "register_operand" "0"))
1058 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
1059 "TARGET_MMX"
1060 "pandn\t{%2, %0|%0, %2}"
1061 [(set_attr "type" "mmxadd")
1062 (set_attr "mode" "DI")])
1063
1064 (define_expand "mmx_<code><mode>3"
1065 [(set (match_operand:MMXMODEI 0 "register_operand")
1066 (any_logic:MMXMODEI
1067 (match_operand:MMXMODEI 1 "nonimmediate_operand")
1068 (match_operand:MMXMODEI 2 "nonimmediate_operand")))]
1069 "TARGET_MMX"
1070 "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
1071
1072 (define_insn "*mmx_<code><mode>3"
1073 [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
1074 (any_logic:MMXMODEI
1075 (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
1076 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
1077 "TARGET_MMX && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
1078 "p<logic>\t{%2, %0|%0, %2}"
1079 [(set_attr "type" "mmxadd")
1080 (set_attr "mode" "DI")])
1081
1082 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1083 ;;
1084 ;; Parallel integral element swizzling
1085 ;;
1086 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1087
1088 ;; Used in signed and unsigned truncations with saturation.
1089 (define_code_iterator any_s_truncate [ss_truncate us_truncate])
1090 ;; Instruction suffix for truncations with saturation.
1091 (define_code_attr s_trunsuffix [(ss_truncate "s") (us_truncate "u")])
1092
1093 (define_insn_and_split "mmx_pack<s_trunsuffix>swb"
1094 [(set (match_operand:V8QI 0 "register_operand" "=y,x,Yv")
1095 (vec_concat:V8QI
1096 (any_s_truncate:V4QI
1097 (match_operand:V4HI 1 "register_operand" "0,0,Yv"))
1098 (any_s_truncate:V4QI
1099 (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv"))))]
1100 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1101 "@
1102 pack<s_trunsuffix>swb\t{%2, %0|%0, %2}
1103 #
1104 #"
1105 "TARGET_MMX_WITH_SSE && reload_completed"
1106 [(const_int 0)]
1107 "ix86_split_mmx_pack (operands, <any_s_truncate:CODE>); DONE;"
1108 [(set_attr "mmx_isa" "native,x64_noavx,x64_avx")
1109 (set_attr "type" "mmxshft,sselog,sselog")
1110 (set_attr "mode" "DI,TI,TI")])
1111
1112 (define_insn_and_split "mmx_packssdw"
1113 [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
1114 (vec_concat:V4HI
1115 (ss_truncate:V2HI
1116 (match_operand:V2SI 1 "register_operand" "0,0,Yv"))
1117 (ss_truncate:V2HI
1118 (match_operand:V2SI 2 "register_mmxmem_operand" "ym,x,Yv"))))]
1119 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1120 "@
1121 packssdw\t{%2, %0|%0, %2}
1122 #
1123 #"
1124 "TARGET_MMX_WITH_SSE && reload_completed"
1125 [(const_int 0)]
1126 "ix86_split_mmx_pack (operands, SS_TRUNCATE); DONE;"
1127 [(set_attr "mmx_isa" "native,x64_noavx,x64_avx")
1128 (set_attr "type" "mmxshft,sselog,sselog")
1129 (set_attr "mode" "DI,TI,TI")])
1130
1131 (define_insn_and_split "mmx_punpckhbw"
1132 [(set (match_operand:V8QI 0 "register_operand" "=y,x,Yv")
1133 (vec_select:V8QI
1134 (vec_concat:V16QI
1135 (match_operand:V8QI 1 "register_operand" "0,0,Yv")
1136 (match_operand:V8QI 2 "register_mmxmem_operand" "ym,x,Yv"))
1137 (parallel [(const_int 4) (const_int 12)
1138 (const_int 5) (const_int 13)
1139 (const_int 6) (const_int 14)
1140 (const_int 7) (const_int 15)])))]
1141 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1142 "@
1143 punpckhbw\t{%2, %0|%0, %2}
1144 #
1145 #"
1146 "TARGET_MMX_WITH_SSE && reload_completed"
1147 [(const_int 0)]
1148 "ix86_split_mmx_punpck (operands, true); DONE;"
1149 [(set_attr "mmx_isa" "native,x64_noavx,x64_avx")
1150 (set_attr "type" "mmxcvt,sselog,sselog")
1151 (set_attr "mode" "DI,TI,TI")])
1152
1153 (define_insn_and_split "mmx_punpcklbw"
1154 [(set (match_operand:V8QI 0 "register_operand" "=y,x,Yv")
1155 (vec_select:V8QI
1156 (vec_concat:V16QI
1157 (match_operand:V8QI 1 "register_operand" "0,0,Yv")
1158 (match_operand:V8QI 2 "register_mmxmem_operand" "ym,x,Yv"))
1159 (parallel [(const_int 0) (const_int 8)
1160 (const_int 1) (const_int 9)
1161 (const_int 2) (const_int 10)
1162 (const_int 3) (const_int 11)])))]
1163 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1164 "@
1165 punpcklbw\t{%2, %0|%0, %k2}
1166 #
1167 #"
1168 "TARGET_MMX_WITH_SSE && reload_completed"
1169 [(const_int 0)]
1170 "ix86_split_mmx_punpck (operands, false); DONE;"
1171 [(set_attr "mmx_isa" "native,x64_noavx,x64_avx")
1172 (set_attr "type" "mmxcvt,sselog,sselog")
1173 (set_attr "mode" "DI,TI,TI")])
1174
1175 (define_insn_and_split "mmx_punpckhwd"
1176 [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
1177 (vec_select:V4HI
1178 (vec_concat:V8HI
1179 (match_operand:V4HI 1 "register_operand" "0,0,Yv")
1180 (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv"))
1181 (parallel [(const_int 2) (const_int 6)
1182 (const_int 3) (const_int 7)])))]
1183 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1184 "@
1185 punpckhwd\t{%2, %0|%0, %2}
1186 #
1187 #"
1188 "TARGET_MMX_WITH_SSE && reload_completed"
1189 [(const_int 0)]
1190 "ix86_split_mmx_punpck (operands, true); DONE;"
1191 [(set_attr "mmx_isa" "native,x64_noavx,x64_avx")
1192 (set_attr "type" "mmxcvt,sselog,sselog")
1193 (set_attr "mode" "DI,TI,TI")])
1194
1195 (define_insn_and_split "mmx_punpcklwd"
1196 [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
1197 (vec_select:V4HI
1198 (vec_concat:V8HI
1199 (match_operand:V4HI 1 "register_operand" "0,0,Yv")
1200 (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv"))
1201 (parallel [(const_int 0) (const_int 4)
1202 (const_int 1) (const_int 5)])))]
1203 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1204 "@
1205 punpcklwd\t{%2, %0|%0, %k2}
1206 #
1207 #"
1208 "TARGET_MMX_WITH_SSE && reload_completed"
1209 [(const_int 0)]
1210 "ix86_split_mmx_punpck (operands, false); DONE;"
1211 [(set_attr "mmx_isa" "native,x64_noavx,x64_avx")
1212 (set_attr "type" "mmxcvt,sselog,sselog")
1213 (set_attr "mode" "DI,TI,TI")])
1214
1215 (define_insn_and_split "mmx_punpckhdq"
1216 [(set (match_operand:V2SI 0 "register_operand" "=y,x,Yv")
1217 (vec_select:V2SI
1218 (vec_concat:V4SI
1219 (match_operand:V2SI 1 "register_operand" "0,0,Yv")
1220 (match_operand:V2SI 2 "register_mmxmem_operand" "ym,x,Yv"))
1221 (parallel [(const_int 1)
1222 (const_int 3)])))]
1223 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1224 "@
1225 punpckhdq\t{%2, %0|%0, %2}
1226 #
1227 #"
1228 "TARGET_MMX_WITH_SSE && reload_completed"
1229 [(const_int 0)]
1230 "ix86_split_mmx_punpck (operands, true); DONE;"
1231 [(set_attr "mmx_isa" "native,x64_noavx,x64_avx")
1232 (set_attr "type" "mmxcvt,sselog,sselog")
1233 (set_attr "mode" "DI,TI,TI")])
1234
1235 (define_insn_and_split "mmx_punpckldq"
1236 [(set (match_operand:V2SI 0 "register_operand" "=y,x,Yv")
1237 (vec_select:V2SI
1238 (vec_concat:V4SI
1239 (match_operand:V2SI 1 "register_operand" "0,0,Yv")
1240 (match_operand:V2SI 2 "register_mmxmem_operand" "ym,x,Yv"))
1241 (parallel [(const_int 0)
1242 (const_int 2)])))]
1243 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1244 "@
1245 punpckldq\t{%2, %0|%0, %k2}
1246 #
1247 #"
1248 "TARGET_MMX_WITH_SSE && reload_completed"
1249 [(const_int 0)]
1250 "ix86_split_mmx_punpck (operands, false); DONE;"
1251 [(set_attr "mmx_isa" "native,x64_noavx,x64_avx")
1252 (set_attr "type" "mmxcvt,sselog,sselog")
1253 (set_attr "mode" "DI,TI,TI")])
1254
1255 (define_expand "mmx_pinsrw"
1256 [(set (match_operand:V4HI 0 "register_operand")
1257 (vec_merge:V4HI
1258 (vec_duplicate:V4HI
1259 (match_operand:SI 2 "nonimmediate_operand"))
1260 (match_operand:V4HI 1 "register_operand")
1261 (match_operand:SI 3 "const_0_to_3_operand")))]
1262 "TARGET_SSE || TARGET_3DNOW_A"
1263 {
1264 operands[2] = gen_lowpart (HImode, operands[2]);
1265 operands[3] = GEN_INT (1 << INTVAL (operands[3]));
1266 })
1267
1268 (define_insn "*mmx_pinsrw"
1269 [(set (match_operand:V4HI 0 "register_operand" "=y")
1270 (vec_merge:V4HI
1271 (vec_duplicate:V4HI
1272 (match_operand:HI 2 "nonimmediate_operand" "rm"))
1273 (match_operand:V4HI 1 "register_operand" "0")
1274 (match_operand:SI 3 "const_int_operand")))]
1275 "(TARGET_SSE || TARGET_3DNOW_A)
1276 && ((unsigned) exact_log2 (INTVAL (operands[3]))
1277 < GET_MODE_NUNITS (V4HImode))"
1278 {
1279 operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
1280 if (MEM_P (operands[2]))
1281 return "pinsrw\t{%3, %2, %0|%0, %2, %3}";
1282 else
1283 return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}";
1284 }
1285 [(set_attr "type" "mmxcvt")
1286 (set_attr "length_immediate" "1")
1287 (set_attr "mode" "DI")])
1288
1289 (define_insn "mmx_pextrw"
1290 [(set (match_operand:SI 0 "register_operand" "=r")
1291 (zero_extend:SI
1292 (vec_select:HI
1293 (match_operand:V4HI 1 "register_operand" "y")
1294 (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n")]))))]
1295 "TARGET_SSE || TARGET_3DNOW_A"
1296 "pextrw\t{%2, %1, %0|%0, %1, %2}"
1297 [(set_attr "type" "mmxcvt")
1298 (set_attr "length_immediate" "1")
1299 (set_attr "mode" "DI")])
1300
1301 (define_expand "mmx_pshufw"
1302 [(match_operand:V4HI 0 "register_operand")
1303 (match_operand:V4HI 1 "nonimmediate_operand")
1304 (match_operand:SI 2 "const_int_operand")]
1305 "TARGET_SSE || TARGET_3DNOW_A"
1306 {
1307 int mask = INTVAL (operands[2]);
1308 emit_insn (gen_mmx_pshufw_1 (operands[0], operands[1],
1309 GEN_INT ((mask >> 0) & 3),
1310 GEN_INT ((mask >> 2) & 3),
1311 GEN_INT ((mask >> 4) & 3),
1312 GEN_INT ((mask >> 6) & 3)));
1313 DONE;
1314 })
1315
1316 (define_insn "mmx_pshufw_1"
1317 [(set (match_operand:V4HI 0 "register_operand" "=y")
1318 (vec_select:V4HI
1319 (match_operand:V4HI 1 "nonimmediate_operand" "ym")
1320 (parallel [(match_operand 2 "const_0_to_3_operand")
1321 (match_operand 3 "const_0_to_3_operand")
1322 (match_operand 4 "const_0_to_3_operand")
1323 (match_operand 5 "const_0_to_3_operand")])))]
1324 "TARGET_SSE || TARGET_3DNOW_A"
1325 {
1326 int mask = 0;
1327 mask |= INTVAL (operands[2]) << 0;
1328 mask |= INTVAL (operands[3]) << 2;
1329 mask |= INTVAL (operands[4]) << 4;
1330 mask |= INTVAL (operands[5]) << 6;
1331 operands[2] = GEN_INT (mask);
1332
1333 return "pshufw\t{%2, %1, %0|%0, %1, %2}";
1334 }
1335 [(set_attr "type" "mmxcvt")
1336 (set_attr "length_immediate" "1")
1337 (set_attr "mode" "DI")])
1338
1339 (define_insn "mmx_pswapdv2si2"
1340 [(set (match_operand:V2SI 0 "register_operand" "=y")
1341 (vec_select:V2SI
1342 (match_operand:V2SI 1 "nonimmediate_operand" "ym")
1343 (parallel [(const_int 1) (const_int 0)])))]
1344 "TARGET_3DNOW_A"
1345 "pswapd\t{%1, %0|%0, %1}"
1346 [(set_attr "type" "mmxcvt")
1347 (set_attr "prefix_extra" "1")
1348 (set_attr "mode" "DI")])
1349
1350 (define_insn "*vec_dupv4hi"
1351 [(set (match_operand:V4HI 0 "register_operand" "=y")
1352 (vec_duplicate:V4HI
1353 (truncate:HI
1354 (match_operand:SI 1 "register_operand" "0"))))]
1355 "TARGET_SSE || TARGET_3DNOW_A"
1356 "pshufw\t{$0, %0, %0|%0, %0, 0}"
1357 [(set_attr "type" "mmxcvt")
1358 (set_attr "length_immediate" "1")
1359 (set_attr "mode" "DI")])
1360
1361 (define_insn "*vec_dupv2si"
1362 [(set (match_operand:V2SI 0 "register_operand" "=y")
1363 (vec_duplicate:V2SI
1364 (match_operand:SI 1 "register_operand" "0")))]
1365 "TARGET_MMX"
1366 "punpckldq\t%0, %0"
1367 [(set_attr "type" "mmxcvt")
1368 (set_attr "mode" "DI")])
1369
1370 (define_insn "*mmx_concatv2si"
1371 [(set (match_operand:V2SI 0 "register_operand" "=y,y")
1372 (vec_concat:V2SI
1373 (match_operand:SI 1 "nonimmediate_operand" " 0,rm")
1374 (match_operand:SI 2 "nonimm_or_0_operand" "ym,C")))]
1375 "TARGET_MMX && !TARGET_SSE"
1376 "@
1377 punpckldq\t{%2, %0|%0, %2}
1378 movd\t{%1, %0|%0, %1}"
1379 [(set_attr "type" "mmxcvt,mmxmov")
1380 (set_attr "mode" "DI")])
1381
1382 (define_expand "vec_setv2si"
1383 [(match_operand:V2SI 0 "register_operand")
1384 (match_operand:SI 1 "register_operand")
1385 (match_operand 2 "const_int_operand")]
1386 "TARGET_MMX"
1387 {
1388 ix86_expand_vector_set (false, operands[0], operands[1],
1389 INTVAL (operands[2]));
1390 DONE;
1391 })
1392
1393 ;; Avoid combining registers from different units in a single alternative,
1394 ;; see comment above inline_secondary_memory_needed function in i386.c
1395 (define_insn_and_split "*vec_extractv2si_0"
1396 [(set (match_operand:SI 0 "nonimmediate_operand" "=x,m,y, m,r")
1397 (vec_select:SI
1398 (match_operand:V2SI 1 "nonimmediate_operand" "xm,x,ym,y,m")
1399 (parallel [(const_int 0)])))]
1400 "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1401 "#"
1402 "&& reload_completed"
1403 [(set (match_dup 0) (match_dup 1))]
1404 "operands[1] = gen_lowpart (SImode, operands[1]);")
1405
1406 ;; Avoid combining registers from different units in a single alternative,
1407 ;; see comment above inline_secondary_memory_needed function in i386.c
1408 (define_insn "*vec_extractv2si_1"
1409 [(set (match_operand:SI 0 "nonimmediate_operand" "=y,x,x,y,x,r")
1410 (vec_select:SI
1411 (match_operand:V2SI 1 "nonimmediate_operand" " 0,x,x,o,o,o")
1412 (parallel [(const_int 1)])))]
1413 "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1414 "@
1415 punpckhdq\t%0, %0
1416 %vpshufd\t{$0xe5, %1, %0|%0, %1, 0xe5}
1417 shufps\t{$0xe5, %1, %0|%0, %1, 0xe5}
1418 #
1419 #
1420 #"
1421 [(set_attr "isa" "*,sse2,noavx,*,*,*")
1422 (set_attr "type" "mmxcvt,sseshuf1,sseshuf1,mmxmov,ssemov,imov")
1423 (set (attr "length_immediate")
1424 (if_then_else (eq_attr "alternative" "1,2")
1425 (const_string "1")
1426 (const_string "*")))
1427 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig,orig")
1428 (set_attr "mode" "DI,TI,V4SF,SI,SI,SI")])
1429
1430 (define_split
1431 [(set (match_operand:SI 0 "register_operand")
1432 (vec_select:SI
1433 (match_operand:V2SI 1 "memory_operand")
1434 (parallel [(const_int 1)])))]
1435 "TARGET_MMX && reload_completed"
1436 [(set (match_dup 0) (match_dup 1))]
1437 "operands[1] = adjust_address (operands[1], SImode, 4);")
1438
1439 (define_insn_and_split "*vec_extractv2si_zext_mem"
1440 [(set (match_operand:DI 0 "register_operand" "=y,x,r")
1441 (zero_extend:DI
1442 (vec_select:SI
1443 (match_operand:V2SI 1 "memory_operand" "o,o,o")
1444 (parallel [(match_operand:SI 2 "const_0_to_1_operand")]))))]
1445 "TARGET_64BIT"
1446 "#"
1447 "&& reload_completed"
1448 [(set (match_dup 0) (zero_extend:DI (match_dup 1)))]
1449 {
1450 operands[1] = adjust_address (operands[1], SImode, INTVAL (operands[2]) * 4);
1451 }
1452 [(set_attr "isa" "*,sse2,*")])
1453
1454 (define_expand "vec_extractv2sisi"
1455 [(match_operand:SI 0 "register_operand")
1456 (match_operand:V2SI 1 "register_operand")
1457 (match_operand 2 "const_int_operand")]
1458 "TARGET_MMX"
1459 {
1460 ix86_expand_vector_extract (false, operands[0], operands[1],
1461 INTVAL (operands[2]));
1462 DONE;
1463 })
1464
1465 (define_expand "vec_initv2sisi"
1466 [(match_operand:V2SI 0 "register_operand")
1467 (match_operand 1)]
1468 "TARGET_SSE"
1469 {
1470 ix86_expand_vector_init (false, operands[0], operands[1]);
1471 DONE;
1472 })
1473
1474 (define_expand "vec_setv4hi"
1475 [(match_operand:V4HI 0 "register_operand")
1476 (match_operand:HI 1 "register_operand")
1477 (match_operand 2 "const_int_operand")]
1478 "TARGET_MMX"
1479 {
1480 ix86_expand_vector_set (false, operands[0], operands[1],
1481 INTVAL (operands[2]));
1482 DONE;
1483 })
1484
1485 (define_expand "vec_extractv4hihi"
1486 [(match_operand:HI 0 "register_operand")
1487 (match_operand:V4HI 1 "register_operand")
1488 (match_operand 2 "const_int_operand")]
1489 "TARGET_MMX"
1490 {
1491 ix86_expand_vector_extract (false, operands[0], operands[1],
1492 INTVAL (operands[2]));
1493 DONE;
1494 })
1495
1496 (define_expand "vec_initv4hihi"
1497 [(match_operand:V4HI 0 "register_operand")
1498 (match_operand 1)]
1499 "TARGET_SSE"
1500 {
1501 ix86_expand_vector_init (false, operands[0], operands[1]);
1502 DONE;
1503 })
1504
1505 (define_expand "vec_setv8qi"
1506 [(match_operand:V8QI 0 "register_operand")
1507 (match_operand:QI 1 "register_operand")
1508 (match_operand 2 "const_int_operand")]
1509 "TARGET_MMX"
1510 {
1511 ix86_expand_vector_set (false, operands[0], operands[1],
1512 INTVAL (operands[2]));
1513 DONE;
1514 })
1515
1516 (define_expand "vec_extractv8qiqi"
1517 [(match_operand:QI 0 "register_operand")
1518 (match_operand:V8QI 1 "register_operand")
1519 (match_operand 2 "const_int_operand")]
1520 "TARGET_MMX"
1521 {
1522 ix86_expand_vector_extract (false, operands[0], operands[1],
1523 INTVAL (operands[2]));
1524 DONE;
1525 })
1526
1527 (define_expand "vec_initv8qiqi"
1528 [(match_operand:V8QI 0 "register_operand")
1529 (match_operand 1)]
1530 "TARGET_SSE"
1531 {
1532 ix86_expand_vector_init (false, operands[0], operands[1]);
1533 DONE;
1534 })
1535
1536 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1537 ;;
1538 ;; Miscellaneous
1539 ;;
1540 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1541
1542 (define_expand "mmx_uavgv8qi3"
1543 [(set (match_operand:V8QI 0 "register_operand")
1544 (truncate:V8QI
1545 (lshiftrt:V8HI
1546 (plus:V8HI
1547 (plus:V8HI
1548 (zero_extend:V8HI
1549 (match_operand:V8QI 1 "nonimmediate_operand"))
1550 (zero_extend:V8HI
1551 (match_operand:V8QI 2 "nonimmediate_operand")))
1552 (const_vector:V8HI [(const_int 1) (const_int 1)
1553 (const_int 1) (const_int 1)
1554 (const_int 1) (const_int 1)
1555 (const_int 1) (const_int 1)]))
1556 (const_int 1))))]
1557 "TARGET_SSE || TARGET_3DNOW"
1558 "ix86_fixup_binary_operands_no_copy (PLUS, V8QImode, operands);")
1559
1560 (define_insn "*mmx_uavgv8qi3"
1561 [(set (match_operand:V8QI 0 "register_operand" "=y")
1562 (truncate:V8QI
1563 (lshiftrt:V8HI
1564 (plus:V8HI
1565 (plus:V8HI
1566 (zero_extend:V8HI
1567 (match_operand:V8QI 1 "nonimmediate_operand" "%0"))
1568 (zero_extend:V8HI
1569 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))
1570 (const_vector:V8HI [(const_int 1) (const_int 1)
1571 (const_int 1) (const_int 1)
1572 (const_int 1) (const_int 1)
1573 (const_int 1) (const_int 1)]))
1574 (const_int 1))))]
1575 "(TARGET_SSE || TARGET_3DNOW)
1576 && ix86_binary_operator_ok (PLUS, V8QImode, operands)"
1577 {
1578 /* These two instructions have the same operation, but their encoding
1579 is different. Prefer the one that is de facto standard. */
1580 if (TARGET_SSE || TARGET_3DNOW_A)
1581 return "pavgb\t{%2, %0|%0, %2}";
1582 else
1583 return "pavgusb\t{%2, %0|%0, %2}";
1584 }
1585 [(set_attr "type" "mmxshft")
1586 (set (attr "prefix_extra")
1587 (if_then_else
1588 (not (ior (match_test "TARGET_SSE")
1589 (match_test "TARGET_3DNOW_A")))
1590 (const_string "1")
1591 (const_string "*")))
1592 (set_attr "mode" "DI")])
1593
1594 (define_expand "mmx_uavgv4hi3"
1595 [(set (match_operand:V4HI 0 "register_operand")
1596 (truncate:V4HI
1597 (lshiftrt:V4SI
1598 (plus:V4SI
1599 (plus:V4SI
1600 (zero_extend:V4SI
1601 (match_operand:V4HI 1 "nonimmediate_operand"))
1602 (zero_extend:V4SI
1603 (match_operand:V4HI 2 "nonimmediate_operand")))
1604 (const_vector:V4SI [(const_int 1) (const_int 1)
1605 (const_int 1) (const_int 1)]))
1606 (const_int 1))))]
1607 "TARGET_SSE || TARGET_3DNOW_A"
1608 "ix86_fixup_binary_operands_no_copy (PLUS, V4HImode, operands);")
1609
1610 (define_insn "*mmx_uavgv4hi3"
1611 [(set (match_operand:V4HI 0 "register_operand" "=y")
1612 (truncate:V4HI
1613 (lshiftrt:V4SI
1614 (plus:V4SI
1615 (plus:V4SI
1616 (zero_extend:V4SI
1617 (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
1618 (zero_extend:V4SI
1619 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
1620 (const_vector:V4SI [(const_int 1) (const_int 1)
1621 (const_int 1) (const_int 1)]))
1622 (const_int 1))))]
1623 "(TARGET_SSE || TARGET_3DNOW_A)
1624 && ix86_binary_operator_ok (PLUS, V4HImode, operands)"
1625 "pavgw\t{%2, %0|%0, %2}"
1626 [(set_attr "type" "mmxshft")
1627 (set_attr "mode" "DI")])
1628
1629 (define_insn "mmx_psadbw"
1630 [(set (match_operand:V1DI 0 "register_operand" "=y")
1631 (unspec:V1DI [(match_operand:V8QI 1 "register_operand" "0")
1632 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
1633 UNSPEC_PSADBW))]
1634 "TARGET_SSE || TARGET_3DNOW_A"
1635 "psadbw\t{%2, %0|%0, %2}"
1636 [(set_attr "type" "mmxshft")
1637 (set_attr "mode" "DI")])
1638
1639 (define_insn "mmx_pmovmskb"
1640 [(set (match_operand:SI 0 "register_operand" "=r")
1641 (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
1642 UNSPEC_MOVMSK))]
1643 "TARGET_SSE || TARGET_3DNOW_A"
1644 "pmovmskb\t{%1, %0|%0, %1}"
1645 [(set_attr "type" "mmxcvt")
1646 (set_attr "mode" "DI")])
1647
1648 (define_expand "mmx_maskmovq"
1649 [(set (match_operand:V8QI 0 "memory_operand")
1650 (unspec:V8QI [(match_operand:V8QI 1 "register_operand")
1651 (match_operand:V8QI 2 "register_operand")
1652 (match_dup 0)]
1653 UNSPEC_MASKMOV))]
1654 "TARGET_SSE || TARGET_3DNOW_A")
1655
1656 (define_insn "*mmx_maskmovq"
1657 [(set (mem:V8QI (match_operand:P 0 "register_operand" "D"))
1658 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
1659 (match_operand:V8QI 2 "register_operand" "y")
1660 (mem:V8QI (match_dup 0))]
1661 UNSPEC_MASKMOV))]
1662 "TARGET_SSE || TARGET_3DNOW_A"
1663 ;; @@@ check ordering of operands in intel/nonintel syntax
1664 "maskmovq\t{%2, %1|%1, %2}"
1665 [(set_attr "type" "mmxcvt")
1666 (set_attr "znver1_decode" "vector")
1667 (set_attr "mode" "DI")])
1668
1669 (define_int_iterator EMMS
1670 [(UNSPECV_EMMS "TARGET_MMX")
1671 (UNSPECV_FEMMS "TARGET_3DNOW")])
1672
1673 (define_int_attr emms
1674 [(UNSPECV_EMMS "emms")
1675 (UNSPECV_FEMMS "femms")])
1676
1677 (define_insn "mmx_<emms>"
1678 [(unspec_volatile [(const_int 0)] EMMS)
1679 (clobber (reg:XF ST0_REG))
1680 (clobber (reg:XF ST1_REG))
1681 (clobber (reg:XF ST2_REG))
1682 (clobber (reg:XF ST3_REG))
1683 (clobber (reg:XF ST4_REG))
1684 (clobber (reg:XF ST5_REG))
1685 (clobber (reg:XF ST6_REG))
1686 (clobber (reg:XF ST7_REG))
1687 (clobber (reg:DI MM0_REG))
1688 (clobber (reg:DI MM1_REG))
1689 (clobber (reg:DI MM2_REG))
1690 (clobber (reg:DI MM3_REG))
1691 (clobber (reg:DI MM4_REG))
1692 (clobber (reg:DI MM5_REG))
1693 (clobber (reg:DI MM6_REG))
1694 (clobber (reg:DI MM7_REG))]
1695 ""
1696 "<emms>"
1697 [(set_attr "type" "mmx")
1698 (set_attr "modrm" "0")
1699 (set_attr "memory" "none")])