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