1 ;; GCC machine description for MMX and 3dNOW! instructions
2 ;; Copyright (C) 2005-2013 Free Software Foundation, Inc.
4 ;; This file is part of GCC.
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)
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.
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/>.
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.
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.
32 (define_c_enum "unspec" [
41 (define_c_enum "unspecv" [
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])
50 ;; All 8-byte vector modes handled by MMX
51 (define_mode_iterator MMXMODE [V8QI V4HI V2SI V1DI V2SF])
54 (define_mode_iterator MMXMODE12 [V8QI V4HI])
55 (define_mode_iterator MMXMODE24 [V4HI V2SI])
56 (define_mode_iterator MMXMODE248 [V4HI V2SI V1DI])
58 ;; Mapping from integer vector mode to mnemonic suffix
59 (define_mode_attr mmxvecsize [(V8QI "b") (V4HI "w") (V2SI "d") (V1DI "q")])
61 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
65 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
67 ;; All of these patterns are enabled for MMX as well as 3dNOW.
68 ;; This is essential for maintaining stable calling conventions.
70 (define_expand "mov<mode>"
71 [(set (match_operand:MMXMODE 0 "nonimmediate_operand")
72 (match_operand:MMXMODE 1 "nonimmediate_operand"))]
75 ix86_expand_vector_move (<MODE>mode, operands);
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 ,?!Ym,x,x,x,m,*x,*x,*x,m ,r ,Yi,!Ym,*Yi")
82 (match_operand:MMXMODE 1 "vector_move_operand"
83 "rCo,rC,C,rm,rC,C ,!y,m ,?!y,?!Yn,r ,C,x,m,x,C ,*x,m ,*x,Yj,r ,*Yj,!Yn"))]
85 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
87 switch (get_attr_type (insn))
93 if (get_attr_mode (insn) == MODE_SI)
94 return "mov{l}\t{%1, %k0|%k0, %1}";
96 return "mov{q}\t{%1, %0|%0, %1}";
99 return "pxor\t%0, %0";
102 #ifndef HAVE_AS_IX86_INTERUNIT_MOVQ
103 /* Handle broken assemblers that require movd instead of movq. */
104 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
105 return "movd\t{%1, %0|%0, %1}";
107 return "movq\t{%1, %0|%0, %1}";
110 if (SSE_REG_P (operands[0]))
111 return "movq2dq\t{%1, %0|%0, %1}";
113 return "movdq2q\t{%1, %0|%0, %1}";
116 return standard_sse_constant_opcode (insn, operands[1]);
119 switch (get_attr_mode (insn))
122 #ifndef HAVE_AS_IX86_INTERUNIT_MOVQ
123 /* Handle broken assemblers that require movd instead of movq. */
124 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
125 return "%vmovd\t{%1, %0|%0, %1}";
127 return "%vmovq\t{%1, %0|%0, %1}";
129 return "%vmovdqa\t{%1, %0|%0, %1}";
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}";
136 return "%vmovaps\t{%1, %0|%0, %1}";
147 (cond [(eq_attr "alternative" "0,1")
148 (const_string "nox64")
149 (eq_attr "alternative" "2,3,4,9,10,11,12,13,14,19,20")
154 (cond [(eq_attr "alternative" "0,1")
155 (const_string "multi")
156 (eq_attr "alternative" "2,3,4")
157 (const_string "imov")
158 (eq_attr "alternative" "5")
160 (eq_attr "alternative" "6,7,8,9,10")
161 (const_string "mmxmov")
162 (eq_attr "alternative" "11,15")
163 (const_string "sselog1")
164 (eq_attr "alternative" "21,22")
165 (const_string "ssecvt")
167 (const_string "ssemov")))
168 (set (attr "prefix_rex")
169 (if_then_else (eq_attr "alternative" "9,10,19,20")
173 (if_then_else (eq_attr "type" "sselog1,ssemov")
174 (const_string "maybe_vex")
175 (const_string "orig")))
176 (set (attr "prefix_data16")
178 (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
182 (cond [(eq_attr "alternative" "2")
184 (eq_attr "alternative" "11,12,15,16")
185 (cond [(match_test "<MODE>mode == V2SFmode")
186 (const_string "V4SF")
187 (ior (not (match_test "TARGET_SSE2"))
188 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
189 (const_string "V4SF")
190 (match_test "TARGET_AVX")
192 (match_test "optimize_function_for_size_p (cfun)")
193 (const_string "V4SF")
197 (and (eq_attr "alternative" "13,14,17,18")
198 (ior (match_test "<MODE>mode == V2SFmode")
199 (not (match_test "TARGET_SSE2"))))
200 (const_string "V2SF")
202 (const_string "DI")))])
205 [(set (match_operand:MMXMODE 0 "nonimmediate_operand")
206 (match_operand:MMXMODE 1 "general_operand"))]
207 "!TARGET_64BIT && reload_completed
208 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
209 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
211 "ix86_split_long_move (operands); DONE;")
213 (define_expand "push<mode>1"
214 [(match_operand:MMXMODE 0 "register_operand")]
217 ix86_expand_push (<MODE>mode, operands[0]);
221 (define_expand "movmisalign<mode>"
222 [(set (match_operand:MMXMODE 0 "nonimmediate_operand")
223 (match_operand:MMXMODE 1 "nonimmediate_operand"))]
226 ix86_expand_vector_move (<MODE>mode, operands);
230 (define_insn "sse_movntq"
231 [(set (match_operand:DI 0 "memory_operand" "=m")
232 (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
234 "TARGET_SSE || TARGET_3DNOW_A"
235 "movntq\t{%1, %0|%0, %1}"
236 [(set_attr "type" "mmxmov")
237 (set_attr "mode" "DI")])
239 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
241 ;; Parallel single-precision floating point arithmetic
243 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
245 (define_expand "mmx_addv2sf3"
246 [(set (match_operand:V2SF 0 "register_operand")
248 (match_operand:V2SF 1 "nonimmediate_operand")
249 (match_operand:V2SF 2 "nonimmediate_operand")))]
251 "ix86_fixup_binary_operands_no_copy (PLUS, V2SFmode, operands);")
253 (define_insn "*mmx_addv2sf3"
254 [(set (match_operand:V2SF 0 "register_operand" "=y")
255 (plus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
256 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
257 "TARGET_3DNOW && ix86_binary_operator_ok (PLUS, V2SFmode, operands)"
258 "pfadd\t{%2, %0|%0, %2}"
259 [(set_attr "type" "mmxadd")
260 (set_attr "prefix_extra" "1")
261 (set_attr "mode" "V2SF")])
263 (define_expand "mmx_subv2sf3"
264 [(set (match_operand:V2SF 0 "register_operand")
265 (minus:V2SF (match_operand:V2SF 1 "register_operand")
266 (match_operand:V2SF 2 "nonimmediate_operand")))]
269 (define_expand "mmx_subrv2sf3"
270 [(set (match_operand:V2SF 0 "register_operand")
271 (minus:V2SF (match_operand:V2SF 2 "register_operand")
272 (match_operand:V2SF 1 "nonimmediate_operand")))]
275 (define_insn "*mmx_subv2sf3"
276 [(set (match_operand:V2SF 0 "register_operand" "=y,y")
277 (minus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "0,ym")
278 (match_operand:V2SF 2 "nonimmediate_operand" "ym,0")))]
279 "TARGET_3DNOW && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
281 pfsub\t{%2, %0|%0, %2}
282 pfsubr\t{%1, %0|%0, %1}"
283 [(set_attr "type" "mmxadd")
284 (set_attr "prefix_extra" "1")
285 (set_attr "mode" "V2SF")])
287 (define_expand "mmx_mulv2sf3"
288 [(set (match_operand:V2SF 0 "register_operand")
289 (mult:V2SF (match_operand:V2SF 1 "nonimmediate_operand")
290 (match_operand:V2SF 2 "nonimmediate_operand")))]
292 "ix86_fixup_binary_operands_no_copy (MULT, V2SFmode, operands);")
294 (define_insn "*mmx_mulv2sf3"
295 [(set (match_operand:V2SF 0 "register_operand" "=y")
296 (mult:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
297 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
298 "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V2SFmode, operands)"
299 "pfmul\t{%2, %0|%0, %2}"
300 [(set_attr "type" "mmxmul")
301 (set_attr "prefix_extra" "1")
302 (set_attr "mode" "V2SF")])
304 ;; ??? For !flag_finite_math_only, the representation with SMIN/SMAX
305 ;; isn't really correct, as those rtl operators aren't defined when
306 ;; applied to NaNs. Hopefully the optimizers won't get too smart on us.
308 (define_expand "mmx_<code>v2sf3"
309 [(set (match_operand:V2SF 0 "register_operand")
311 (match_operand:V2SF 1 "nonimmediate_operand")
312 (match_operand:V2SF 2 "nonimmediate_operand")))]
315 if (!flag_finite_math_only)
316 operands[1] = force_reg (V2SFmode, operands[1]);
317 ix86_fixup_binary_operands_no_copy (<CODE>, V2SFmode, operands);
320 (define_insn "*mmx_<code>v2sf3_finite"
321 [(set (match_operand:V2SF 0 "register_operand" "=y")
323 (match_operand:V2SF 1 "nonimmediate_operand" "%0")
324 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
325 "TARGET_3DNOW && flag_finite_math_only
326 && ix86_binary_operator_ok (<CODE>, V2SFmode, operands)"
327 "pf<maxmin_float>\t{%2, %0|%0, %2}"
328 [(set_attr "type" "mmxadd")
329 (set_attr "prefix_extra" "1")
330 (set_attr "mode" "V2SF")])
332 (define_insn "*mmx_<code>v2sf3"
333 [(set (match_operand:V2SF 0 "register_operand" "=y")
335 (match_operand:V2SF 1 "register_operand" "0")
336 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
338 "pf<maxmin_float>\t{%2, %0|%0, %2}"
339 [(set_attr "type" "mmxadd")
340 (set_attr "prefix_extra" "1")
341 (set_attr "mode" "V2SF")])
343 (define_insn "mmx_rcpv2sf2"
344 [(set (match_operand:V2SF 0 "register_operand" "=y")
345 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
348 "pfrcp\t{%1, %0|%0, %1}"
349 [(set_attr "type" "mmx")
350 (set_attr "prefix_extra" "1")
351 (set_attr "mode" "V2SF")])
353 (define_insn "mmx_rcpit1v2sf3"
354 [(set (match_operand:V2SF 0 "register_operand" "=y")
355 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
356 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
359 "pfrcpit1\t{%2, %0|%0, %2}"
360 [(set_attr "type" "mmx")
361 (set_attr "prefix_extra" "1")
362 (set_attr "mode" "V2SF")])
364 (define_insn "mmx_rcpit2v2sf3"
365 [(set (match_operand:V2SF 0 "register_operand" "=y")
366 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
367 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
370 "pfrcpit2\t{%2, %0|%0, %2}"
371 [(set_attr "type" "mmx")
372 (set_attr "prefix_extra" "1")
373 (set_attr "mode" "V2SF")])
375 (define_insn "mmx_rsqrtv2sf2"
376 [(set (match_operand:V2SF 0 "register_operand" "=y")
377 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
380 "pfrsqrt\t{%1, %0|%0, %1}"
381 [(set_attr "type" "mmx")
382 (set_attr "prefix_extra" "1")
383 (set_attr "mode" "V2SF")])
385 (define_insn "mmx_rsqit1v2sf3"
386 [(set (match_operand:V2SF 0 "register_operand" "=y")
387 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
388 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
391 "pfrsqit1\t{%2, %0|%0, %2}"
392 [(set_attr "type" "mmx")
393 (set_attr "prefix_extra" "1")
394 (set_attr "mode" "V2SF")])
396 (define_insn "mmx_haddv2sf3"
397 [(set (match_operand:V2SF 0 "register_operand" "=y")
401 (match_operand:V2SF 1 "register_operand" "0")
402 (parallel [(const_int 0)]))
403 (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
406 (match_operand:V2SF 2 "nonimmediate_operand" "ym")
407 (parallel [(const_int 0)]))
408 (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
410 "pfacc\t{%2, %0|%0, %2}"
411 [(set_attr "type" "mmxadd")
412 (set_attr "prefix_extra" "1")
413 (set_attr "mode" "V2SF")])
415 (define_insn "mmx_hsubv2sf3"
416 [(set (match_operand:V2SF 0 "register_operand" "=y")
420 (match_operand:V2SF 1 "register_operand" "0")
421 (parallel [(const_int 0)]))
422 (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
425 (match_operand:V2SF 2 "nonimmediate_operand" "ym")
426 (parallel [(const_int 0)]))
427 (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
429 "pfnacc\t{%2, %0|%0, %2}"
430 [(set_attr "type" "mmxadd")
431 (set_attr "prefix_extra" "1")
432 (set_attr "mode" "V2SF")])
434 (define_insn "mmx_addsubv2sf3"
435 [(set (match_operand:V2SF 0 "register_operand" "=y")
438 (match_operand:V2SF 1 "register_operand" "0")
439 (match_operand:V2SF 2 "nonimmediate_operand" "ym"))
440 (minus:V2SF (match_dup 1) (match_dup 2))
443 "pfpnacc\t{%2, %0|%0, %2}"
444 [(set_attr "type" "mmxadd")
445 (set_attr "prefix_extra" "1")
446 (set_attr "mode" "V2SF")])
448 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
450 ;; Parallel single-precision floating point comparisons
452 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
454 (define_expand "mmx_eqv2sf3"
455 [(set (match_operand:V2SI 0 "register_operand")
456 (eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand")
457 (match_operand:V2SF 2 "nonimmediate_operand")))]
459 "ix86_fixup_binary_operands_no_copy (EQ, V2SFmode, operands);")
461 (define_insn "*mmx_eqv2sf3"
462 [(set (match_operand:V2SI 0 "register_operand" "=y")
463 (eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "%0")
464 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
465 "TARGET_3DNOW && ix86_binary_operator_ok (EQ, V2SFmode, operands)"
466 "pfcmpeq\t{%2, %0|%0, %2}"
467 [(set_attr "type" "mmxcmp")
468 (set_attr "prefix_extra" "1")
469 (set_attr "mode" "V2SF")])
471 (define_insn "mmx_gtv2sf3"
472 [(set (match_operand:V2SI 0 "register_operand" "=y")
473 (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
474 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
476 "pfcmpgt\t{%2, %0|%0, %2}"
477 [(set_attr "type" "mmxcmp")
478 (set_attr "prefix_extra" "1")
479 (set_attr "mode" "V2SF")])
481 (define_insn "mmx_gev2sf3"
482 [(set (match_operand:V2SI 0 "register_operand" "=y")
483 (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
484 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
486 "pfcmpge\t{%2, %0|%0, %2}"
487 [(set_attr "type" "mmxcmp")
488 (set_attr "prefix_extra" "1")
489 (set_attr "mode" "V2SF")])
491 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
493 ;; Parallel single-precision floating point conversion operations
495 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
497 (define_insn "mmx_pf2id"
498 [(set (match_operand:V2SI 0 "register_operand" "=y")
499 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
501 "pf2id\t{%1, %0|%0, %1}"
502 [(set_attr "type" "mmxcvt")
503 (set_attr "prefix_extra" "1")
504 (set_attr "mode" "V2SF")])
506 (define_insn "mmx_pf2iw"
507 [(set (match_operand:V2SI 0 "register_operand" "=y")
511 (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
513 "pf2iw\t{%1, %0|%0, %1}"
514 [(set_attr "type" "mmxcvt")
515 (set_attr "prefix_extra" "1")
516 (set_attr "mode" "V2SF")])
518 (define_insn "mmx_pi2fw"
519 [(set (match_operand:V2SF 0 "register_operand" "=y")
523 (match_operand:V2SI 1 "nonimmediate_operand" "ym")))))]
525 "pi2fw\t{%1, %0|%0, %1}"
526 [(set_attr "type" "mmxcvt")
527 (set_attr "prefix_extra" "1")
528 (set_attr "mode" "V2SF")])
530 (define_insn "mmx_floatv2si2"
531 [(set (match_operand:V2SF 0 "register_operand" "=y")
532 (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
534 "pi2fd\t{%1, %0|%0, %1}"
535 [(set_attr "type" "mmxcvt")
536 (set_attr "prefix_extra" "1")
537 (set_attr "mode" "V2SF")])
539 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
541 ;; Parallel single-precision floating point element swizzling
543 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
545 (define_insn "mmx_pswapdv2sf2"
546 [(set (match_operand:V2SF 0 "register_operand" "=y")
547 (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
548 (parallel [(const_int 1) (const_int 0)])))]
550 "pswapd\t{%1, %0|%0, %1}"
551 [(set_attr "type" "mmxcvt")
552 (set_attr "prefix_extra" "1")
553 (set_attr "mode" "V2SF")])
555 (define_insn "*vec_dupv2sf"
556 [(set (match_operand:V2SF 0 "register_operand" "=y")
558 (match_operand:SF 1 "register_operand" "0")))]
561 [(set_attr "type" "mmxcvt")
562 (set_attr "mode" "DI")])
564 (define_insn "*mmx_concatv2sf"
565 [(set (match_operand:V2SF 0 "register_operand" "=y,y")
567 (match_operand:SF 1 "nonimmediate_operand" " 0,rm")
568 (match_operand:SF 2 "vector_move_operand" "ym,C")))]
569 "TARGET_MMX && !TARGET_SSE"
571 punpckldq\t{%2, %0|%0, %2}
572 movd\t{%1, %0|%0, %1}"
573 [(set_attr "type" "mmxcvt,mmxmov")
574 (set_attr "mode" "DI")])
576 (define_expand "vec_setv2sf"
577 [(match_operand:V2SF 0 "register_operand")
578 (match_operand:SF 1 "register_operand")
579 (match_operand 2 "const_int_operand")]
582 ix86_expand_vector_set (false, operands[0], operands[1],
583 INTVAL (operands[2]));
587 ;; Avoid combining registers from different units in a single alternative,
588 ;; see comment above inline_secondary_memory_needed function in i386.c
589 (define_insn_and_split "*vec_extractv2sf_0"
590 [(set (match_operand:SF 0 "nonimmediate_operand" "=x, m,y ,m,f,r")
592 (match_operand:V2SF 1 "nonimmediate_operand" " xm,x,ym,y,m,m")
593 (parallel [(const_int 0)])))]
594 "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
596 "&& reload_completed"
599 rtx op1 = operands[1];
601 op1 = gen_rtx_REG (SFmode, REGNO (op1));
603 op1 = gen_lowpart (SFmode, op1);
604 emit_move_insn (operands[0], op1);
608 ;; Avoid combining registers from different units in a single alternative,
609 ;; see comment above inline_secondary_memory_needed function in i386.c
610 (define_insn "*vec_extractv2sf_1"
611 [(set (match_operand:SF 0 "nonimmediate_operand" "=y,x,y,x,f,r")
613 (match_operand:V2SF 1 "nonimmediate_operand" " 0,0,o,o,o,o")
614 (parallel [(const_int 1)])))]
615 "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
623 [(set_attr "type" "mmxcvt,sselog1,mmxmov,ssemov,fmov,imov")
624 (set_attr "mode" "DI,V4SF,SF,SF,SF,SF")])
627 [(set (match_operand:SF 0 "register_operand")
629 (match_operand:V2SF 1 "memory_operand")
630 (parallel [(const_int 1)])))]
631 "TARGET_MMX && reload_completed"
634 operands[1] = adjust_address (operands[1], SFmode, 4);
635 emit_move_insn (operands[0], operands[1]);
639 (define_expand "vec_extractv2sf"
640 [(match_operand:SF 0 "register_operand")
641 (match_operand:V2SF 1 "register_operand")
642 (match_operand 2 "const_int_operand")]
645 ix86_expand_vector_extract (false, operands[0], operands[1],
646 INTVAL (operands[2]));
650 (define_expand "vec_initv2sf"
651 [(match_operand:V2SF 0 "register_operand")
655 ix86_expand_vector_init (false, operands[0], operands[1]);
659 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
661 ;; Parallel integral arithmetic
663 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
665 (define_expand "mmx_<plusminus_insn><mode>3"
666 [(set (match_operand:MMXMODEI8 0 "register_operand")
668 (match_operand:MMXMODEI8 1 "nonimmediate_operand")
669 (match_operand:MMXMODEI8 2 "nonimmediate_operand")))]
670 "TARGET_MMX || (TARGET_SSE2 && <MODE>mode == V1DImode)"
671 "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
673 (define_insn "*mmx_<plusminus_insn><mode>3"
674 [(set (match_operand:MMXMODEI8 0 "register_operand" "=y")
676 (match_operand:MMXMODEI8 1 "nonimmediate_operand" "<comm>0")
677 (match_operand:MMXMODEI8 2 "nonimmediate_operand" "ym")))]
678 "(TARGET_MMX || (TARGET_SSE2 && <MODE>mode == V1DImode))
679 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
680 "p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}"
681 [(set_attr "type" "mmxadd")
682 (set_attr "mode" "DI")])
684 (define_expand "mmx_<plusminus_insn><mode>3"
685 [(set (match_operand:MMXMODE12 0 "register_operand")
686 (sat_plusminus:MMXMODE12
687 (match_operand:MMXMODE12 1 "nonimmediate_operand")
688 (match_operand:MMXMODE12 2 "nonimmediate_operand")))]
690 "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
692 (define_insn "*mmx_<plusminus_insn><mode>3"
693 [(set (match_operand:MMXMODE12 0 "register_operand" "=y")
694 (sat_plusminus:MMXMODE12
695 (match_operand:MMXMODE12 1 "nonimmediate_operand" "<comm>0")
696 (match_operand:MMXMODE12 2 "nonimmediate_operand" "ym")))]
697 "TARGET_MMX && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
698 "p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}"
699 [(set_attr "type" "mmxadd")
700 (set_attr "mode" "DI")])
702 (define_expand "mmx_mulv4hi3"
703 [(set (match_operand:V4HI 0 "register_operand")
704 (mult:V4HI (match_operand:V4HI 1 "nonimmediate_operand")
705 (match_operand:V4HI 2 "nonimmediate_operand")))]
707 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
709 (define_insn "*mmx_mulv4hi3"
710 [(set (match_operand:V4HI 0 "register_operand" "=y")
711 (mult:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "%0")
712 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
713 "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
714 "pmullw\t{%2, %0|%0, %2}"
715 [(set_attr "type" "mmxmul")
716 (set_attr "mode" "DI")])
718 (define_expand "mmx_smulv4hi3_highpart"
719 [(set (match_operand:V4HI 0 "register_operand")
724 (match_operand:V4HI 1 "nonimmediate_operand"))
726 (match_operand:V4HI 2 "nonimmediate_operand")))
729 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
731 (define_insn "*mmx_smulv4hi3_highpart"
732 [(set (match_operand:V4HI 0 "register_operand" "=y")
737 (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
739 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
741 "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
742 "pmulhw\t{%2, %0|%0, %2}"
743 [(set_attr "type" "mmxmul")
744 (set_attr "mode" "DI")])
746 (define_expand "mmx_umulv4hi3_highpart"
747 [(set (match_operand:V4HI 0 "register_operand")
752 (match_operand:V4HI 1 "nonimmediate_operand"))
754 (match_operand:V4HI 2 "nonimmediate_operand")))
756 "TARGET_SSE || TARGET_3DNOW_A"
757 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
759 (define_insn "*mmx_umulv4hi3_highpart"
760 [(set (match_operand:V4HI 0 "register_operand" "=y")
765 (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
767 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
769 "(TARGET_SSE || TARGET_3DNOW_A)
770 && ix86_binary_operator_ok (MULT, V4HImode, operands)"
771 "pmulhuw\t{%2, %0|%0, %2}"
772 [(set_attr "type" "mmxmul")
773 (set_attr "mode" "DI")])
775 (define_expand "mmx_pmaddwd"
776 [(set (match_operand:V2SI 0 "register_operand")
781 (match_operand:V4HI 1 "nonimmediate_operand")
782 (parallel [(const_int 0) (const_int 2)])))
785 (match_operand:V4HI 2 "nonimmediate_operand")
786 (parallel [(const_int 0) (const_int 2)]))))
789 (vec_select:V2HI (match_dup 1)
790 (parallel [(const_int 1) (const_int 3)])))
792 (vec_select:V2HI (match_dup 2)
793 (parallel [(const_int 1) (const_int 3)]))))))]
795 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
797 (define_insn "*mmx_pmaddwd"
798 [(set (match_operand:V2SI 0 "register_operand" "=y")
803 (match_operand:V4HI 1 "nonimmediate_operand" "%0")
804 (parallel [(const_int 0) (const_int 2)])))
807 (match_operand:V4HI 2 "nonimmediate_operand" "ym")
808 (parallel [(const_int 0) (const_int 2)]))))
811 (vec_select:V2HI (match_dup 1)
812 (parallel [(const_int 1) (const_int 3)])))
814 (vec_select:V2HI (match_dup 2)
815 (parallel [(const_int 1) (const_int 3)]))))))]
816 "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
817 "pmaddwd\t{%2, %0|%0, %2}"
818 [(set_attr "type" "mmxmul")
819 (set_attr "mode" "DI")])
821 (define_expand "mmx_pmulhrwv4hi3"
822 [(set (match_operand:V4HI 0 "register_operand")
828 (match_operand:V4HI 1 "nonimmediate_operand"))
830 (match_operand:V4HI 2 "nonimmediate_operand")))
831 (const_vector:V4SI [(const_int 32768) (const_int 32768)
832 (const_int 32768) (const_int 32768)]))
835 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
837 (define_insn "*mmx_pmulhrwv4hi3"
838 [(set (match_operand:V4HI 0 "register_operand" "=y")
844 (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
846 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
847 (const_vector:V4SI [(const_int 32768) (const_int 32768)
848 (const_int 32768) (const_int 32768)]))
850 "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V4HImode, operands)"
851 "pmulhrw\t{%2, %0|%0, %2}"
852 [(set_attr "type" "mmxmul")
853 (set_attr "prefix_extra" "1")
854 (set_attr "mode" "DI")])
856 (define_expand "sse2_umulv1siv1di3"
857 [(set (match_operand:V1DI 0 "register_operand")
861 (match_operand:V2SI 1 "nonimmediate_operand")
862 (parallel [(const_int 0)])))
865 (match_operand:V2SI 2 "nonimmediate_operand")
866 (parallel [(const_int 0)])))))]
868 "ix86_fixup_binary_operands_no_copy (MULT, V2SImode, operands);")
870 (define_insn "*sse2_umulv1siv1di3"
871 [(set (match_operand:V1DI 0 "register_operand" "=y")
875 (match_operand:V2SI 1 "nonimmediate_operand" "%0")
876 (parallel [(const_int 0)])))
879 (match_operand:V2SI 2 "nonimmediate_operand" "ym")
880 (parallel [(const_int 0)])))))]
881 "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V2SImode, operands)"
882 "pmuludq\t{%2, %0|%0, %2}"
883 [(set_attr "type" "mmxmul")
884 (set_attr "mode" "DI")])
886 (define_expand "mmx_<code>v4hi3"
887 [(set (match_operand:V4HI 0 "register_operand")
889 (match_operand:V4HI 1 "nonimmediate_operand")
890 (match_operand:V4HI 2 "nonimmediate_operand")))]
891 "TARGET_SSE || TARGET_3DNOW_A"
892 "ix86_fixup_binary_operands_no_copy (<CODE>, V4HImode, operands);")
894 (define_insn "*mmx_<code>v4hi3"
895 [(set (match_operand:V4HI 0 "register_operand" "=y")
897 (match_operand:V4HI 1 "nonimmediate_operand" "%0")
898 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
899 "(TARGET_SSE || TARGET_3DNOW_A)
900 && ix86_binary_operator_ok (<CODE>, V4HImode, operands)"
901 "p<maxmin_int>w\t{%2, %0|%0, %2}"
902 [(set_attr "type" "mmxadd")
903 (set_attr "mode" "DI")])
905 (define_expand "mmx_<code>v8qi3"
906 [(set (match_operand:V8QI 0 "register_operand")
908 (match_operand:V8QI 1 "nonimmediate_operand")
909 (match_operand:V8QI 2 "nonimmediate_operand")))]
910 "TARGET_SSE || TARGET_3DNOW_A"
911 "ix86_fixup_binary_operands_no_copy (<CODE>, V8QImode, operands);")
913 (define_insn "*mmx_<code>v8qi3"
914 [(set (match_operand:V8QI 0 "register_operand" "=y")
916 (match_operand:V8QI 1 "nonimmediate_operand" "%0")
917 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
918 "(TARGET_SSE || TARGET_3DNOW_A)
919 && ix86_binary_operator_ok (<CODE>, V8QImode, operands)"
920 "p<maxmin_int>b\t{%2, %0|%0, %2}"
921 [(set_attr "type" "mmxadd")
922 (set_attr "mode" "DI")])
924 (define_insn "mmx_ashr<mode>3"
925 [(set (match_operand:MMXMODE24 0 "register_operand" "=y")
927 (match_operand:MMXMODE24 1 "register_operand" "0")
928 (match_operand:SI 2 "nonmemory_operand" "yN")))]
930 "psra<mmxvecsize>\t{%2, %0|%0, %2}"
931 [(set_attr "type" "mmxshft")
932 (set (attr "length_immediate")
933 (if_then_else (match_operand 2 "const_int_operand")
936 (set_attr "mode" "DI")])
938 (define_insn "mmx_<shift_insn><mode>3"
939 [(set (match_operand:MMXMODE248 0 "register_operand" "=y")
940 (any_lshift:MMXMODE248
941 (match_operand:MMXMODE248 1 "register_operand" "0")
942 (match_operand:SI 2 "nonmemory_operand" "yN")))]
944 "p<vshift><mmxvecsize>\t{%2, %0|%0, %2}"
945 [(set_attr "type" "mmxshft")
946 (set (attr "length_immediate")
947 (if_then_else (match_operand 2 "const_int_operand")
950 (set_attr "mode" "DI")])
952 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
954 ;; Parallel integral comparisons
956 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
958 (define_expand "mmx_eq<mode>3"
959 [(set (match_operand:MMXMODEI 0 "register_operand")
961 (match_operand:MMXMODEI 1 "nonimmediate_operand")
962 (match_operand:MMXMODEI 2 "nonimmediate_operand")))]
964 "ix86_fixup_binary_operands_no_copy (EQ, <MODE>mode, operands);")
966 (define_insn "*mmx_eq<mode>3"
967 [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
969 (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
970 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
971 "TARGET_MMX && ix86_binary_operator_ok (EQ, <MODE>mode, operands)"
972 "pcmpeq<mmxvecsize>\t{%2, %0|%0, %2}"
973 [(set_attr "type" "mmxcmp")
974 (set_attr "mode" "DI")])
976 (define_insn "mmx_gt<mode>3"
977 [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
979 (match_operand:MMXMODEI 1 "register_operand" "0")
980 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
982 "pcmpgt<mmxvecsize>\t{%2, %0|%0, %2}"
983 [(set_attr "type" "mmxcmp")
984 (set_attr "mode" "DI")])
986 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
988 ;; Parallel integral logical operations
990 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
992 (define_insn "mmx_andnot<mode>3"
993 [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
995 (not:MMXMODEI (match_operand:MMXMODEI 1 "register_operand" "0"))
996 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
998 "pandn\t{%2, %0|%0, %2}"
999 [(set_attr "type" "mmxadd")
1000 (set_attr "mode" "DI")])
1002 (define_expand "mmx_<code><mode>3"
1003 [(set (match_operand:MMXMODEI 0 "register_operand")
1005 (match_operand:MMXMODEI 1 "nonimmediate_operand")
1006 (match_operand:MMXMODEI 2 "nonimmediate_operand")))]
1008 "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
1010 (define_insn "*mmx_<code><mode>3"
1011 [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
1013 (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
1014 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
1015 "TARGET_MMX && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
1016 "p<logic>\t{%2, %0|%0, %2}"
1017 [(set_attr "type" "mmxadd")
1018 (set_attr "mode" "DI")])
1020 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1022 ;; Parallel integral element swizzling
1024 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1026 (define_insn "mmx_packsswb"
1027 [(set (match_operand:V8QI 0 "register_operand" "=y")
1030 (match_operand:V4HI 1 "register_operand" "0"))
1032 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))))]
1034 "packsswb\t{%2, %0|%0, %2}"
1035 [(set_attr "type" "mmxshft")
1036 (set_attr "mode" "DI")])
1038 (define_insn "mmx_packssdw"
1039 [(set (match_operand:V4HI 0 "register_operand" "=y")
1042 (match_operand:V2SI 1 "register_operand" "0"))
1044 (match_operand:V2SI 2 "nonimmediate_operand" "ym"))))]
1046 "packssdw\t{%2, %0|%0, %2}"
1047 [(set_attr "type" "mmxshft")
1048 (set_attr "mode" "DI")])
1050 (define_insn "mmx_packuswb"
1051 [(set (match_operand:V8QI 0 "register_operand" "=y")
1054 (match_operand:V4HI 1 "register_operand" "0"))
1056 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))))]
1058 "packuswb\t{%2, %0|%0, %2}"
1059 [(set_attr "type" "mmxshft")
1060 (set_attr "mode" "DI")])
1062 (define_insn "mmx_punpckhbw"
1063 [(set (match_operand:V8QI 0 "register_operand" "=y")
1066 (match_operand:V8QI 1 "register_operand" "0")
1067 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
1068 (parallel [(const_int 4) (const_int 12)
1069 (const_int 5) (const_int 13)
1070 (const_int 6) (const_int 14)
1071 (const_int 7) (const_int 15)])))]
1073 "punpckhbw\t{%2, %0|%0, %2}"
1074 [(set_attr "type" "mmxcvt")
1075 (set_attr "mode" "DI")])
1077 (define_insn "mmx_punpcklbw"
1078 [(set (match_operand:V8QI 0 "register_operand" "=y")
1081 (match_operand:V8QI 1 "register_operand" "0")
1082 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
1083 (parallel [(const_int 0) (const_int 8)
1084 (const_int 1) (const_int 9)
1085 (const_int 2) (const_int 10)
1086 (const_int 3) (const_int 11)])))]
1088 "punpcklbw\t{%2, %0|%0, %2}"
1089 [(set_attr "type" "mmxcvt")
1090 (set_attr "mode" "DI")])
1092 (define_insn "mmx_punpckhwd"
1093 [(set (match_operand:V4HI 0 "register_operand" "=y")
1096 (match_operand:V4HI 1 "register_operand" "0")
1097 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
1098 (parallel [(const_int 2) (const_int 6)
1099 (const_int 3) (const_int 7)])))]
1101 "punpckhwd\t{%2, %0|%0, %2}"
1102 [(set_attr "type" "mmxcvt")
1103 (set_attr "mode" "DI")])
1105 (define_insn "mmx_punpcklwd"
1106 [(set (match_operand:V4HI 0 "register_operand" "=y")
1109 (match_operand:V4HI 1 "register_operand" "0")
1110 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
1111 (parallel [(const_int 0) (const_int 4)
1112 (const_int 1) (const_int 5)])))]
1114 "punpcklwd\t{%2, %0|%0, %2}"
1115 [(set_attr "type" "mmxcvt")
1116 (set_attr "mode" "DI")])
1118 (define_insn "mmx_punpckhdq"
1119 [(set (match_operand:V2SI 0 "register_operand" "=y")
1122 (match_operand:V2SI 1 "register_operand" "0")
1123 (match_operand:V2SI 2 "nonimmediate_operand" "ym"))
1124 (parallel [(const_int 1)
1127 "punpckhdq\t{%2, %0|%0, %2}"
1128 [(set_attr "type" "mmxcvt")
1129 (set_attr "mode" "DI")])
1131 (define_insn "mmx_punpckldq"
1132 [(set (match_operand:V2SI 0 "register_operand" "=y")
1135 (match_operand:V2SI 1 "register_operand" "0")
1136 (match_operand:V2SI 2 "nonimmediate_operand" "ym"))
1137 (parallel [(const_int 0)
1140 "punpckldq\t{%2, %0|%0, %2}"
1141 [(set_attr "type" "mmxcvt")
1142 (set_attr "mode" "DI")])
1144 (define_expand "mmx_pinsrw"
1145 [(set (match_operand:V4HI 0 "register_operand")
1148 (match_operand:SI 2 "nonimmediate_operand"))
1149 (match_operand:V4HI 1 "register_operand")
1150 (match_operand:SI 3 "const_0_to_3_operand")))]
1151 "TARGET_SSE || TARGET_3DNOW_A"
1153 operands[2] = gen_lowpart (HImode, operands[2]);
1154 operands[3] = GEN_INT (1 << INTVAL (operands[3]));
1157 (define_insn "*mmx_pinsrw"
1158 [(set (match_operand:V4HI 0 "register_operand" "=y")
1161 (match_operand:HI 2 "nonimmediate_operand" "rm"))
1162 (match_operand:V4HI 1 "register_operand" "0")
1163 (match_operand:SI 3 "const_int_operand")))]
1164 "(TARGET_SSE || TARGET_3DNOW_A)
1165 && ((unsigned) exact_log2 (INTVAL (operands[3]))
1166 < GET_MODE_NUNITS (V4HImode))"
1168 operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
1169 if (MEM_P (operands[2]))
1170 return "pinsrw\t{%3, %2, %0|%0, %2, %3}";
1172 return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}";
1174 [(set_attr "type" "mmxcvt")
1175 (set_attr "length_immediate" "1")
1176 (set_attr "mode" "DI")])
1178 (define_insn "mmx_pextrw"
1179 [(set (match_operand:SI 0 "register_operand" "=r")
1182 (match_operand:V4HI 1 "register_operand" "y")
1183 (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n")]))))]
1184 "TARGET_SSE || TARGET_3DNOW_A"
1185 "pextrw\t{%2, %1, %0|%0, %1, %2}"
1186 [(set_attr "type" "mmxcvt")
1187 (set_attr "length_immediate" "1")
1188 (set_attr "mode" "DI")])
1190 (define_expand "mmx_pshufw"
1191 [(match_operand:V4HI 0 "register_operand")
1192 (match_operand:V4HI 1 "nonimmediate_operand")
1193 (match_operand:SI 2 "const_int_operand")]
1194 "TARGET_SSE || TARGET_3DNOW_A"
1196 int mask = INTVAL (operands[2]);
1197 emit_insn (gen_mmx_pshufw_1 (operands[0], operands[1],
1198 GEN_INT ((mask >> 0) & 3),
1199 GEN_INT ((mask >> 2) & 3),
1200 GEN_INT ((mask >> 4) & 3),
1201 GEN_INT ((mask >> 6) & 3)));
1205 (define_insn "mmx_pshufw_1"
1206 [(set (match_operand:V4HI 0 "register_operand" "=y")
1208 (match_operand:V4HI 1 "nonimmediate_operand" "ym")
1209 (parallel [(match_operand 2 "const_0_to_3_operand")
1210 (match_operand 3 "const_0_to_3_operand")
1211 (match_operand 4 "const_0_to_3_operand")
1212 (match_operand 5 "const_0_to_3_operand")])))]
1213 "TARGET_SSE || TARGET_3DNOW_A"
1216 mask |= INTVAL (operands[2]) << 0;
1217 mask |= INTVAL (operands[3]) << 2;
1218 mask |= INTVAL (operands[4]) << 4;
1219 mask |= INTVAL (operands[5]) << 6;
1220 operands[2] = GEN_INT (mask);
1222 return "pshufw\t{%2, %1, %0|%0, %1, %2}";
1224 [(set_attr "type" "mmxcvt")
1225 (set_attr "length_immediate" "1")
1226 (set_attr "mode" "DI")])
1228 (define_insn "mmx_pswapdv2si2"
1229 [(set (match_operand:V2SI 0 "register_operand" "=y")
1231 (match_operand:V2SI 1 "nonimmediate_operand" "ym")
1232 (parallel [(const_int 1) (const_int 0)])))]
1234 "pswapd\t{%1, %0|%0, %1}"
1235 [(set_attr "type" "mmxcvt")
1236 (set_attr "prefix_extra" "1")
1237 (set_attr "mode" "DI")])
1239 (define_insn "*vec_dupv4hi"
1240 [(set (match_operand:V4HI 0 "register_operand" "=y")
1243 (match_operand:SI 1 "register_operand" "0"))))]
1244 "TARGET_SSE || TARGET_3DNOW_A"
1245 "pshufw\t{$0, %0, %0|%0, %0, 0}"
1246 [(set_attr "type" "mmxcvt")
1247 (set_attr "length_immediate" "1")
1248 (set_attr "mode" "DI")])
1250 (define_insn "*vec_dupv2si"
1251 [(set (match_operand:V2SI 0 "register_operand" "=y")
1253 (match_operand:SI 1 "register_operand" "0")))]
1256 [(set_attr "type" "mmxcvt")
1257 (set_attr "mode" "DI")])
1259 (define_insn "*mmx_concatv2si"
1260 [(set (match_operand:V2SI 0 "register_operand" "=y,y")
1262 (match_operand:SI 1 "nonimmediate_operand" " 0,rm")
1263 (match_operand:SI 2 "vector_move_operand" "ym,C")))]
1264 "TARGET_MMX && !TARGET_SSE"
1266 punpckldq\t{%2, %0|%0, %2}
1267 movd\t{%1, %0|%0, %1}"
1268 [(set_attr "type" "mmxcvt,mmxmov")
1269 (set_attr "mode" "DI")])
1271 (define_expand "vec_setv2si"
1272 [(match_operand:V2SI 0 "register_operand")
1273 (match_operand:SI 1 "register_operand")
1274 (match_operand 2 "const_int_operand")]
1277 ix86_expand_vector_set (false, operands[0], operands[1],
1278 INTVAL (operands[2]));
1282 ;; Avoid combining registers from different units in a single alternative,
1283 ;; see comment above inline_secondary_memory_needed function in i386.c
1284 (define_insn_and_split "*vec_extractv2si_0"
1285 [(set (match_operand:SI 0 "nonimmediate_operand" "=x,m,y, m,r")
1287 (match_operand:V2SI 1 "nonimmediate_operand" "xm,x,ym,y,m")
1288 (parallel [(const_int 0)])))]
1289 "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1291 "&& reload_completed"
1294 rtx op1 = operands[1];
1296 op1 = gen_rtx_REG (SImode, REGNO (op1));
1298 op1 = gen_lowpart (SImode, op1);
1299 emit_move_insn (operands[0], op1);
1303 ;; Avoid combining registers from different units in a single alternative,
1304 ;; see comment above inline_secondary_memory_needed function in i386.c
1305 (define_insn "*vec_extractv2si_1"
1306 [(set (match_operand:SI 0 "nonimmediate_operand" "=y,x,x,x,y,x,r")
1308 (match_operand:V2SI 1 "nonimmediate_operand" " 0,0,x,0,o,o,o")
1309 (parallel [(const_int 1)])))]
1310 "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1314 pshufd\t{$85, %1, %0|%0, %1, 85}
1320 (if_then_else (eq_attr "alternative" "1,2")
1321 (const_string "sse2")
1322 (const_string "*")))
1323 (set_attr "type" "mmxcvt,sselog1,sselog1,sselog1,mmxmov,ssemov,imov")
1324 (set_attr "length_immediate" "*,*,1,*,*,*,*")
1325 (set_attr "mode" "DI,TI,TI,V4SF,SI,SI,SI")])
1328 [(set (match_operand:SI 0 "register_operand")
1330 (match_operand:V2SI 1 "memory_operand")
1331 (parallel [(const_int 1)])))]
1332 "TARGET_MMX && reload_completed"
1335 operands[1] = adjust_address (operands[1], SImode, 4);
1336 emit_move_insn (operands[0], operands[1]);
1340 (define_expand "vec_extractv2si"
1341 [(match_operand:SI 0 "register_operand")
1342 (match_operand:V2SI 1 "register_operand")
1343 (match_operand 2 "const_int_operand")]
1346 ix86_expand_vector_extract (false, operands[0], operands[1],
1347 INTVAL (operands[2]));
1351 (define_expand "vec_initv2si"
1352 [(match_operand:V2SI 0 "register_operand")
1356 ix86_expand_vector_init (false, operands[0], operands[1]);
1360 (define_expand "vec_setv4hi"
1361 [(match_operand:V4HI 0 "register_operand")
1362 (match_operand:HI 1 "register_operand")
1363 (match_operand 2 "const_int_operand")]
1366 ix86_expand_vector_set (false, operands[0], operands[1],
1367 INTVAL (operands[2]));
1371 (define_expand "vec_extractv4hi"
1372 [(match_operand:HI 0 "register_operand")
1373 (match_operand:V4HI 1 "register_operand")
1374 (match_operand 2 "const_int_operand")]
1377 ix86_expand_vector_extract (false, operands[0], operands[1],
1378 INTVAL (operands[2]));
1382 (define_expand "vec_initv4hi"
1383 [(match_operand:V4HI 0 "register_operand")
1387 ix86_expand_vector_init (false, operands[0], operands[1]);
1391 (define_expand "vec_setv8qi"
1392 [(match_operand:V8QI 0 "register_operand")
1393 (match_operand:QI 1 "register_operand")
1394 (match_operand 2 "const_int_operand")]
1397 ix86_expand_vector_set (false, operands[0], operands[1],
1398 INTVAL (operands[2]));
1402 (define_expand "vec_extractv8qi"
1403 [(match_operand:QI 0 "register_operand")
1404 (match_operand:V8QI 1 "register_operand")
1405 (match_operand 2 "const_int_operand")]
1408 ix86_expand_vector_extract (false, operands[0], operands[1],
1409 INTVAL (operands[2]));
1413 (define_expand "vec_initv8qi"
1414 [(match_operand:V8QI 0 "register_operand")
1418 ix86_expand_vector_init (false, operands[0], operands[1]);
1422 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1426 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1428 (define_expand "mmx_uavgv8qi3"
1429 [(set (match_operand:V8QI 0 "register_operand")
1435 (match_operand:V8QI 1 "nonimmediate_operand"))
1437 (match_operand:V8QI 2 "nonimmediate_operand")))
1438 (const_vector:V8HI [(const_int 1) (const_int 1)
1439 (const_int 1) (const_int 1)
1440 (const_int 1) (const_int 1)
1441 (const_int 1) (const_int 1)]))
1443 "TARGET_SSE || TARGET_3DNOW"
1444 "ix86_fixup_binary_operands_no_copy (PLUS, V8QImode, operands);")
1446 (define_insn "*mmx_uavgv8qi3"
1447 [(set (match_operand:V8QI 0 "register_operand" "=y")
1453 (match_operand:V8QI 1 "nonimmediate_operand" "%0"))
1455 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))
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)]))
1461 "(TARGET_SSE || TARGET_3DNOW)
1462 && ix86_binary_operator_ok (PLUS, V8QImode, operands)"
1464 /* These two instructions have the same operation, but their encoding
1465 is different. Prefer the one that is de facto standard. */
1466 if (TARGET_SSE || TARGET_3DNOW_A)
1467 return "pavgb\t{%2, %0|%0, %2}";
1469 return "pavgusb\t{%2, %0|%0, %2}";
1471 [(set_attr "type" "mmxshft")
1472 (set (attr "prefix_extra")
1474 (not (ior (match_test "TARGET_SSE")
1475 (match_test "TARGET_3DNOW_A")))
1477 (const_string "*")))
1478 (set_attr "mode" "DI")])
1480 (define_expand "mmx_uavgv4hi3"
1481 [(set (match_operand:V4HI 0 "register_operand")
1487 (match_operand:V4HI 1 "nonimmediate_operand"))
1489 (match_operand:V4HI 2 "nonimmediate_operand")))
1490 (const_vector:V4SI [(const_int 1) (const_int 1)
1491 (const_int 1) (const_int 1)]))
1493 "TARGET_SSE || TARGET_3DNOW_A"
1494 "ix86_fixup_binary_operands_no_copy (PLUS, V4HImode, operands);")
1496 (define_insn "*mmx_uavgv4hi3"
1497 [(set (match_operand:V4HI 0 "register_operand" "=y")
1503 (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
1505 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
1506 (const_vector:V4SI [(const_int 1) (const_int 1)
1507 (const_int 1) (const_int 1)]))
1509 "(TARGET_SSE || TARGET_3DNOW_A)
1510 && ix86_binary_operator_ok (PLUS, V4HImode, operands)"
1511 "pavgw\t{%2, %0|%0, %2}"
1512 [(set_attr "type" "mmxshft")
1513 (set_attr "mode" "DI")])
1515 (define_insn "mmx_psadbw"
1516 [(set (match_operand:V1DI 0 "register_operand" "=y")
1517 (unspec:V1DI [(match_operand:V8QI 1 "register_operand" "0")
1518 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
1520 "TARGET_SSE || TARGET_3DNOW_A"
1521 "psadbw\t{%2, %0|%0, %2}"
1522 [(set_attr "type" "mmxshft")
1523 (set_attr "mode" "DI")])
1525 (define_insn "mmx_pmovmskb"
1526 [(set (match_operand:SI 0 "register_operand" "=r")
1527 (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
1529 "TARGET_SSE || TARGET_3DNOW_A"
1530 "pmovmskb\t{%1, %0|%0, %1}"
1531 [(set_attr "type" "mmxcvt")
1532 (set_attr "mode" "DI")])
1534 (define_expand "mmx_maskmovq"
1535 [(set (match_operand:V8QI 0 "memory_operand")
1536 (unspec:V8QI [(match_operand:V8QI 1 "register_operand")
1537 (match_operand:V8QI 2 "register_operand")
1540 "TARGET_SSE || TARGET_3DNOW_A")
1542 (define_insn "*mmx_maskmovq"
1543 [(set (mem:V8QI (match_operand:P 0 "register_operand" "D"))
1544 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
1545 (match_operand:V8QI 2 "register_operand" "y")
1546 (mem:V8QI (match_dup 0))]
1548 "TARGET_SSE || TARGET_3DNOW_A"
1549 ;; @@@ check ordering of operands in intel/nonintel syntax
1550 "maskmovq\t{%2, %1|%1, %2}"
1551 [(set_attr "type" "mmxcvt")
1552 (set_attr "mode" "DI")])
1554 (define_expand "mmx_emms"
1555 [(match_par_dup 0 [(const_int 0)])]
1560 operands[0] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (17));
1562 XVECEXP (operands[0], 0, 0)
1563 = gen_rtx_UNSPEC_VOLATILE (VOIDmode, gen_rtvec (1, const0_rtx),
1566 for (regno = 0; regno < 8; regno++)
1568 XVECEXP (operands[0], 0, regno + 1)
1569 = gen_rtx_CLOBBER (VOIDmode,
1570 gen_rtx_REG (XFmode, FIRST_STACK_REG + regno));
1572 XVECEXP (operands[0], 0, regno + 9)
1573 = gen_rtx_CLOBBER (VOIDmode,
1574 gen_rtx_REG (DImode, FIRST_MMX_REG + regno));
1578 (define_insn "*mmx_emms"
1579 [(match_parallel 0 "emms_operation"
1580 [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)])]
1583 [(set_attr "type" "mmx")
1584 (set_attr "modrm" "0")
1585 (set_attr "memory" "none")])
1587 (define_expand "mmx_femms"
1588 [(match_par_dup 0 [(const_int 0)])]
1593 operands[0] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (17));
1595 XVECEXP (operands[0], 0, 0)
1596 = gen_rtx_UNSPEC_VOLATILE (VOIDmode, gen_rtvec (1, const0_rtx),
1599 for (regno = 0; regno < 8; regno++)
1601 XVECEXP (operands[0], 0, regno + 1)
1602 = gen_rtx_CLOBBER (VOIDmode,
1603 gen_rtx_REG (XFmode, FIRST_STACK_REG + regno));
1605 XVECEXP (operands[0], 0, regno + 9)
1606 = gen_rtx_CLOBBER (VOIDmode,
1607 gen_rtx_REG (DImode, FIRST_MMX_REG + regno));
1611 (define_insn "*mmx_femms"
1612 [(match_parallel 0 "emms_operation"
1613 [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)])]
1616 [(set_attr "type" "mmx")
1617 (set_attr "modrm" "0")
1618 (set_attr "memory" "none")])