1 ;; GCC machine description for MMX and 3dNOW! instructions
2 ;; Copyright (C) 2005, 2007, 2008, 2009, 2010, 2011
3 ;; Free Software Foundation, Inc.
5 ;; This file is part of GCC.
7 ;; GCC is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 3, or (at your option)
12 ;; GCC is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ;; GNU General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3. If not see
19 ;; <http://www.gnu.org/licenses/>.
21 ;; The MMX and 3dNOW! patterns are in the same file because they use
22 ;; the same register file, and 3dNOW! adds a number of extensions to
23 ;; the base integer MMX isa.
25 ;; Note! Except for the basic move instructions, *all* of these
26 ;; patterns are outside the normal optabs namespace. This is because
27 ;; use of these registers requires the insertion of emms or femms
28 ;; instructions to return to normal fpu mode. The compiler doesn't
29 ;; know how to do that itself, which means it's up to the user. Which
30 ;; means that we should never use any of these patterns except at the
31 ;; direction of the user via a builtin.
33 (define_c_enum "unspec" [
42 (define_c_enum "unspecv" [
47 ;; 8 byte integral modes handled by MMX (and by extension, SSE)
48 (define_mode_iterator MMXMODEI [V8QI V4HI V2SI])
49 (define_mode_iterator MMXMODEI8 [V8QI V4HI V2SI V1DI])
51 ;; All 8-byte vector modes handled by MMX
52 (define_mode_iterator MMXMODE [V8QI V4HI V2SI V1DI V2SF])
55 (define_mode_iterator MMXMODE12 [V8QI V4HI])
56 (define_mode_iterator MMXMODE24 [V4HI V2SI])
57 (define_mode_iterator MMXMODE248 [V4HI V2SI V1DI])
59 ;; Mapping from integer vector mode to mnemonic suffix
60 (define_mode_attr mmxvecsize [(V8QI "b") (V4HI "w") (V2SI "d") (V1DI "q")])
62 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
66 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
68 ;; All of these patterns are enabled for MMX as well as 3dNOW.
69 ;; This is essential for maintaining stable calling conventions.
71 (define_expand "mov<mode>"
72 [(set (match_operand:MMXMODEI8 0 "nonimmediate_operand" "")
73 (match_operand:MMXMODEI8 1 "nonimmediate_operand" ""))]
76 ix86_expand_vector_move (<MODE>mode, operands);
80 ;; movd instead of movq is required to handle broken assemblers.
81 (define_insn "*mov<mode>_internal_rex64"
82 [(set (match_operand:MMXMODEI8 0 "nonimmediate_operand"
83 "=rm,r,!?y,!y,!?y,m ,!y ,*x,x,x ,m,r ,Yi")
84 (match_operand:MMXMODEI8 1 "vector_move_operand"
85 "Cr ,m,C ,!y,m ,!?y,*x,!y ,C,xm,x,Yi,r"))]
86 "TARGET_64BIT && TARGET_MMX
87 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
89 mov{q}\t{%1, %0|%0, %1}
90 mov{q}\t{%1, %0|%0, %1}
95 movdq2q\t{%1, %0|%0, %1}
96 movq2dq\t{%1, %0|%0, %1}
98 %vmovq\t{%1, %0|%0, %1}
99 %vmovq\t{%1, %0|%0, %1}
100 %vmovd\t{%1, %0|%0, %1}
101 %vmovd\t{%1, %0|%0, %1}"
103 (cond [(eq_attr "alternative" "0,1")
104 (const_string "imov")
105 (eq_attr "alternative" "2")
107 (eq_attr "alternative" "3,4,5")
108 (const_string "mmxmov")
109 (eq_attr "alternative" "6,7")
110 (const_string "ssecvt")
111 (eq_attr "alternative" "8")
112 (const_string "sselog1")
114 (const_string "ssemov")))
116 (if_then_else (eq_attr "alternative" "6,7")
119 (set (attr "prefix_rep")
120 (if_then_else (eq_attr "alternative" "6,7,9")
123 (set (attr "prefix_data16")
124 (if_then_else (eq_attr "alternative" "10,11,12")
127 (set (attr "prefix_rex")
128 (if_then_else (eq_attr "alternative" "9,10")
129 (symbol_ref "x86_extended_reg_mentioned_p (insn)")
132 (if_then_else (eq_attr "alternative" "8,9,10,11,12")
133 (const_string "maybe_vex")
134 (const_string "orig")))
135 (set_attr "mode" "DI")])
137 (define_insn "*mov<mode>_internal"
138 [(set (match_operand:MMXMODEI8 0 "nonimmediate_operand"
139 "=!?y,!y,!?y,m ,!y,*x,*x,*x ,m ,*x,*x,*x,m ,r ,m")
140 (match_operand:MMXMODEI8 1 "vector_move_operand"
141 "C ,!y,m ,!?y,*x,!y,C ,*xm,*x,C ,*x,m ,*x,irm,r"))]
142 "!TARGET_64BIT && TARGET_MMX
143 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
146 movq\t{%1, %0|%0, %1}
147 movq\t{%1, %0|%0, %1}
148 movq\t{%1, %0|%0, %1}
149 movdq2q\t{%1, %0|%0, %1}
150 movq2dq\t{%1, %0|%0, %1}
152 %vmovq\t{%1, %0|%0, %1}
153 %vmovq\t{%1, %0|%0, %1}
155 movaps\t{%1, %0|%0, %1}
156 movlps\t{%1, %0|%0, %1}
157 movlps\t{%1, %0|%0, %1}
161 (cond [(eq_attr "alternative" "4,5,6,7,8")
162 (const_string "sse2")
163 (eq_attr "alternative" "9,10,11,12")
164 (const_string "noavx")
168 (cond [(eq_attr "alternative" "0")
170 (eq_attr "alternative" "1,2,3")
171 (const_string "mmxmov")
172 (eq_attr "alternative" "4,5")
173 (const_string "ssecvt")
174 (eq_attr "alternative" "6,9")
175 (const_string "sselog1")
176 (eq_attr "alternative" "13,14")
177 (const_string "multi")
179 (const_string "ssemov")))
181 (if_then_else (eq_attr "alternative" "4,5")
184 (set (attr "prefix_rep")
186 (ior (eq_attr "alternative" "4,5")
187 (and (eq_attr "alternative" "7")
188 (not (match_test "TARGET_AVX"))))
191 (set (attr "prefix_data16")
193 (and (eq_attr "alternative" "8")
194 (not (match_test "TARGET_AVX")))
198 (if_then_else (eq_attr "alternative" "6,7,8")
199 (const_string "maybe_vex")
200 (const_string "orig")))
201 (set_attr "mode" "DI,DI,DI,DI,DI,DI,TI,DI,DI,V4SF,V4SF,V2SF,V2SF,DI,DI")])
203 (define_expand "movv2sf"
204 [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
205 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
208 ix86_expand_vector_move (V2SFmode, operands);
212 ;; movd instead of movq is required to handle broken assemblers.
213 (define_insn "*movv2sf_internal_rex64"
214 [(set (match_operand:V2SF 0 "nonimmediate_operand"
215 "=rm,r,!?y,!y,!?y,m ,!y,*x,x,x,x,m,r ,Yi")
216 (match_operand:V2SF 1 "vector_move_operand"
217 "Cr ,m,C ,!y,m ,!?y,*x,!y,C,x,m,x,Yi,r"))]
218 "TARGET_64BIT && TARGET_MMX
219 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
221 mov{q}\t{%1, %0|%0, %1}
222 mov{q}\t{%1, %0|%0, %1}
224 movq\t{%1, %0|%0, %1}
225 movq\t{%1, %0|%0, %1}
226 movq\t{%1, %0|%0, %1}
227 movdq2q\t{%1, %0|%0, %1}
228 movq2dq\t{%1, %0|%0, %1}
230 %vmovaps\t{%1, %0|%0, %1}
231 %vmovlps\t{%1, %d0|%d0, %1}
232 %vmovlps\t{%1, %0|%0, %1}
233 %vmovd\t{%1, %0|%0, %1}
234 %vmovd\t{%1, %0|%0, %1}"
236 (cond [(eq_attr "alternative" "0,1")
237 (const_string "imov")
238 (eq_attr "alternative" "2")
240 (eq_attr "alternative" "3,4,5")
241 (const_string "mmxmov")
242 (eq_attr "alternative" "6,7")
243 (const_string "ssecvt")
244 (eq_attr "alternative" "9")
245 (const_string "sselog1")
247 (const_string "ssemov")))
249 (if_then_else (eq_attr "alternative" "6,7")
252 (set (attr "prefix_rep")
253 (if_then_else (eq_attr "alternative" "6,7")
256 (set (attr "length_vex")
258 (and (eq_attr "alternative" "12,13")
259 (match_test "TARGET_AVX"))
263 (if_then_else (eq_attr "alternative" "8,9,10,11,12,13")
264 (const_string "maybe_vex")
265 (const_string "orig")))
266 (set_attr "mode" "DI,DI,DI,DI,DI,DI,DI,DI,V4SF,V4SF,V2SF,V2SF,DI,DI")])
268 (define_insn "*movv2sf_internal"
269 [(set (match_operand:V2SF 0 "nonimmediate_operand"
270 "=!?y,!y,!?y,m ,!y,*x,*x,*x,*x,m ,r ,m")
271 (match_operand:V2SF 1 "vector_move_operand"
272 "C ,!y,m ,!?y,*x,!y,C ,*x,m ,*x,irm,r"))]
273 "!TARGET_64BIT && TARGET_MMX
274 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
277 movq\t{%1, %0|%0, %1}
278 movq\t{%1, %0|%0, %1}
279 movq\t{%1, %0|%0, %1}
280 movdq2q\t{%1, %0|%0, %1}
281 movq2dq\t{%1, %0|%0, %1}
283 %vmovaps\t{%1, %0|%0, %1}
284 %vmovlps\t{%1, %d0|%d0, %1}
285 %vmovlps\t{%1, %0|%0, %1}
289 (if_then_else (eq_attr "alternative" "4,5")
290 (const_string "sse2")
293 (cond [(eq_attr "alternative" "0")
295 (eq_attr "alternative" "1,2,3")
296 (const_string "mmxmov")
297 (eq_attr "alternative" "4,5")
298 (const_string "ssecvt")
299 (eq_attr "alternative" "6")
300 (const_string "sselog1")
301 (eq_attr "alternative" "10,11")
302 (const_string "multi")
304 (const_string "ssemov")))
306 (if_then_else (eq_attr "alternative" "4,5")
309 (set (attr "prefix_rep")
310 (if_then_else (eq_attr "alternative" "4,5")
314 (if_then_else (eq_attr "alternative" "6,7,8,9")
315 (const_string "maybe_vex")
316 (const_string "orig")))
317 (set_attr "mode" "DI,DI,DI,DI,DI,DI,V4SF,V4SF,V2SF,V2SF,DI,DI")])
319 ;; %%% This multiword shite has got to go.
321 [(set (match_operand:MMXMODE 0 "nonimmediate_operand" "")
322 (match_operand:MMXMODE 1 "general_operand" ""))]
323 "!TARGET_64BIT && reload_completed
324 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0])
325 || MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
327 "ix86_split_long_move (operands); DONE;")
329 (define_expand "push<mode>1"
330 [(match_operand:MMXMODE 0 "register_operand" "")]
333 ix86_expand_push (<MODE>mode, operands[0]);
337 (define_expand "movmisalign<mode>"
338 [(set (match_operand:MMXMODE 0 "nonimmediate_operand" "")
339 (match_operand:MMXMODE 1 "nonimmediate_operand" ""))]
342 ix86_expand_vector_move (<MODE>mode, operands);
346 (define_insn "sse_movntq"
347 [(set (match_operand:DI 0 "memory_operand" "=m")
348 (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
350 "TARGET_SSE || TARGET_3DNOW_A"
351 "movntq\t{%1, %0|%0, %1}"
352 [(set_attr "type" "mmxmov")
353 (set_attr "mode" "DI")])
355 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
357 ;; Parallel single-precision floating point arithmetic
359 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
361 (define_expand "mmx_addv2sf3"
362 [(set (match_operand:V2SF 0 "register_operand" "")
364 (match_operand:V2SF 1 "nonimmediate_operand" "")
365 (match_operand:V2SF 2 "nonimmediate_operand" "")))]
367 "ix86_fixup_binary_operands_no_copy (PLUS, V2SFmode, operands);")
369 (define_insn "*mmx_addv2sf3"
370 [(set (match_operand:V2SF 0 "register_operand" "=y")
371 (plus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
372 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
373 "TARGET_3DNOW && ix86_binary_operator_ok (PLUS, V2SFmode, operands)"
374 "pfadd\t{%2, %0|%0, %2}"
375 [(set_attr "type" "mmxadd")
376 (set_attr "prefix_extra" "1")
377 (set_attr "mode" "V2SF")])
379 (define_expand "mmx_subv2sf3"
380 [(set (match_operand:V2SF 0 "register_operand" "")
381 (minus:V2SF (match_operand:V2SF 1 "register_operand" "")
382 (match_operand:V2SF 2 "nonimmediate_operand" "")))]
385 (define_expand "mmx_subrv2sf3"
386 [(set (match_operand:V2SF 0 "register_operand" "")
387 (minus:V2SF (match_operand:V2SF 2 "register_operand" "")
388 (match_operand:V2SF 1 "nonimmediate_operand" "")))]
391 (define_insn "*mmx_subv2sf3"
392 [(set (match_operand:V2SF 0 "register_operand" "=y,y")
393 (minus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "0,ym")
394 (match_operand:V2SF 2 "nonimmediate_operand" "ym,0")))]
395 "TARGET_3DNOW && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
397 pfsub\t{%2, %0|%0, %2}
398 pfsubr\t{%1, %0|%0, %1}"
399 [(set_attr "type" "mmxadd")
400 (set_attr "prefix_extra" "1")
401 (set_attr "mode" "V2SF")])
403 (define_expand "mmx_mulv2sf3"
404 [(set (match_operand:V2SF 0 "register_operand" "")
405 (mult:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "")
406 (match_operand:V2SF 2 "nonimmediate_operand" "")))]
408 "ix86_fixup_binary_operands_no_copy (MULT, V2SFmode, operands);")
410 (define_insn "*mmx_mulv2sf3"
411 [(set (match_operand:V2SF 0 "register_operand" "=y")
412 (mult:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
413 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
414 "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V2SFmode, operands)"
415 "pfmul\t{%2, %0|%0, %2}"
416 [(set_attr "type" "mmxmul")
417 (set_attr "prefix_extra" "1")
418 (set_attr "mode" "V2SF")])
420 ;; ??? For !flag_finite_math_only, the representation with SMIN/SMAX
421 ;; isn't really correct, as those rtl operators aren't defined when
422 ;; applied to NaNs. Hopefully the optimizers won't get too smart on us.
424 (define_expand "mmx_<code>v2sf3"
425 [(set (match_operand:V2SF 0 "register_operand" "")
427 (match_operand:V2SF 1 "nonimmediate_operand" "")
428 (match_operand:V2SF 2 "nonimmediate_operand" "")))]
431 if (!flag_finite_math_only)
432 operands[1] = force_reg (V2SFmode, operands[1]);
433 ix86_fixup_binary_operands_no_copy (<CODE>, V2SFmode, operands);
436 (define_insn "*mmx_<code>v2sf3_finite"
437 [(set (match_operand:V2SF 0 "register_operand" "=y")
439 (match_operand:V2SF 1 "nonimmediate_operand" "%0")
440 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
441 "TARGET_3DNOW && flag_finite_math_only
442 && ix86_binary_operator_ok (<CODE>, V2SFmode, operands)"
443 "pf<maxmin_float>\t{%2, %0|%0, %2}"
444 [(set_attr "type" "mmxadd")
445 (set_attr "prefix_extra" "1")
446 (set_attr "mode" "V2SF")])
448 (define_insn "*mmx_<code>v2sf3"
449 [(set (match_operand:V2SF 0 "register_operand" "=y")
451 (match_operand:V2SF 1 "register_operand" "0")
452 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
454 "pf<maxmin_float>\t{%2, %0|%0, %2}"
455 [(set_attr "type" "mmxadd")
456 (set_attr "prefix_extra" "1")
457 (set_attr "mode" "V2SF")])
459 (define_insn "mmx_rcpv2sf2"
460 [(set (match_operand:V2SF 0 "register_operand" "=y")
461 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
464 "pfrcp\t{%1, %0|%0, %1}"
465 [(set_attr "type" "mmx")
466 (set_attr "prefix_extra" "1")
467 (set_attr "mode" "V2SF")])
469 (define_insn "mmx_rcpit1v2sf3"
470 [(set (match_operand:V2SF 0 "register_operand" "=y")
471 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
472 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
475 "pfrcpit1\t{%2, %0|%0, %2}"
476 [(set_attr "type" "mmx")
477 (set_attr "prefix_extra" "1")
478 (set_attr "mode" "V2SF")])
480 (define_insn "mmx_rcpit2v2sf3"
481 [(set (match_operand:V2SF 0 "register_operand" "=y")
482 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
483 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
486 "pfrcpit2\t{%2, %0|%0, %2}"
487 [(set_attr "type" "mmx")
488 (set_attr "prefix_extra" "1")
489 (set_attr "mode" "V2SF")])
491 (define_insn "mmx_rsqrtv2sf2"
492 [(set (match_operand:V2SF 0 "register_operand" "=y")
493 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
496 "pfrsqrt\t{%1, %0|%0, %1}"
497 [(set_attr "type" "mmx")
498 (set_attr "prefix_extra" "1")
499 (set_attr "mode" "V2SF")])
501 (define_insn "mmx_rsqit1v2sf3"
502 [(set (match_operand:V2SF 0 "register_operand" "=y")
503 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
504 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
507 "pfrsqit1\t{%2, %0|%0, %2}"
508 [(set_attr "type" "mmx")
509 (set_attr "prefix_extra" "1")
510 (set_attr "mode" "V2SF")])
512 (define_insn "mmx_haddv2sf3"
513 [(set (match_operand:V2SF 0 "register_operand" "=y")
517 (match_operand:V2SF 1 "register_operand" "0")
518 (parallel [(const_int 0)]))
519 (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
522 (match_operand:V2SF 2 "nonimmediate_operand" "ym")
523 (parallel [(const_int 0)]))
524 (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
526 "pfacc\t{%2, %0|%0, %2}"
527 [(set_attr "type" "mmxadd")
528 (set_attr "prefix_extra" "1")
529 (set_attr "mode" "V2SF")])
531 (define_insn "mmx_hsubv2sf3"
532 [(set (match_operand:V2SF 0 "register_operand" "=y")
536 (match_operand:V2SF 1 "register_operand" "0")
537 (parallel [(const_int 0)]))
538 (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
541 (match_operand:V2SF 2 "nonimmediate_operand" "ym")
542 (parallel [(const_int 0)]))
543 (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
545 "pfnacc\t{%2, %0|%0, %2}"
546 [(set_attr "type" "mmxadd")
547 (set_attr "prefix_extra" "1")
548 (set_attr "mode" "V2SF")])
550 (define_insn "mmx_addsubv2sf3"
551 [(set (match_operand:V2SF 0 "register_operand" "=y")
554 (match_operand:V2SF 1 "register_operand" "0")
555 (match_operand:V2SF 2 "nonimmediate_operand" "ym"))
556 (minus:V2SF (match_dup 1) (match_dup 2))
559 "pfpnacc\t{%2, %0|%0, %2}"
560 [(set_attr "type" "mmxadd")
561 (set_attr "prefix_extra" "1")
562 (set_attr "mode" "V2SF")])
564 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
566 ;; Parallel single-precision floating point comparisons
568 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
570 (define_expand "mmx_eqv2sf3"
571 [(set (match_operand:V2SI 0 "register_operand" "")
572 (eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "")
573 (match_operand:V2SF 2 "nonimmediate_operand" "")))]
575 "ix86_fixup_binary_operands_no_copy (EQ, V2SFmode, operands);")
577 (define_insn "*mmx_eqv2sf3"
578 [(set (match_operand:V2SI 0 "register_operand" "=y")
579 (eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "%0")
580 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
581 "TARGET_3DNOW && ix86_binary_operator_ok (EQ, V2SFmode, operands)"
582 "pfcmpeq\t{%2, %0|%0, %2}"
583 [(set_attr "type" "mmxcmp")
584 (set_attr "prefix_extra" "1")
585 (set_attr "mode" "V2SF")])
587 (define_insn "mmx_gtv2sf3"
588 [(set (match_operand:V2SI 0 "register_operand" "=y")
589 (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
590 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
592 "pfcmpgt\t{%2, %0|%0, %2}"
593 [(set_attr "type" "mmxcmp")
594 (set_attr "prefix_extra" "1")
595 (set_attr "mode" "V2SF")])
597 (define_insn "mmx_gev2sf3"
598 [(set (match_operand:V2SI 0 "register_operand" "=y")
599 (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
600 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
602 "pfcmpge\t{%2, %0|%0, %2}"
603 [(set_attr "type" "mmxcmp")
604 (set_attr "prefix_extra" "1")
605 (set_attr "mode" "V2SF")])
607 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
609 ;; Parallel single-precision floating point conversion operations
611 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
613 (define_insn "mmx_pf2id"
614 [(set (match_operand:V2SI 0 "register_operand" "=y")
615 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
617 "pf2id\t{%1, %0|%0, %1}"
618 [(set_attr "type" "mmxcvt")
619 (set_attr "prefix_extra" "1")
620 (set_attr "mode" "V2SF")])
622 (define_insn "mmx_pf2iw"
623 [(set (match_operand:V2SI 0 "register_operand" "=y")
627 (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
629 "pf2iw\t{%1, %0|%0, %1}"
630 [(set_attr "type" "mmxcvt")
631 (set_attr "prefix_extra" "1")
632 (set_attr "mode" "V2SF")])
634 (define_insn "mmx_pi2fw"
635 [(set (match_operand:V2SF 0 "register_operand" "=y")
639 (match_operand:V2SI 1 "nonimmediate_operand" "ym")))))]
641 "pi2fw\t{%1, %0|%0, %1}"
642 [(set_attr "type" "mmxcvt")
643 (set_attr "prefix_extra" "1")
644 (set_attr "mode" "V2SF")])
646 (define_insn "mmx_floatv2si2"
647 [(set (match_operand:V2SF 0 "register_operand" "=y")
648 (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
650 "pi2fd\t{%1, %0|%0, %1}"
651 [(set_attr "type" "mmxcvt")
652 (set_attr "prefix_extra" "1")
653 (set_attr "mode" "V2SF")])
655 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
657 ;; Parallel single-precision floating point element swizzling
659 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
661 (define_insn "mmx_pswapdv2sf2"
662 [(set (match_operand:V2SF 0 "register_operand" "=y")
663 (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
664 (parallel [(const_int 1) (const_int 0)])))]
666 "pswapd\t{%1, %0|%0, %1}"
667 [(set_attr "type" "mmxcvt")
668 (set_attr "prefix_extra" "1")
669 (set_attr "mode" "V2SF")])
671 (define_insn "*vec_dupv2sf"
672 [(set (match_operand:V2SF 0 "register_operand" "=y")
674 (match_operand:SF 1 "register_operand" "0")))]
677 [(set_attr "type" "mmxcvt")
678 (set_attr "mode" "DI")])
680 (define_insn "*mmx_concatv2sf"
681 [(set (match_operand:V2SF 0 "register_operand" "=y,y")
683 (match_operand:SF 1 "nonimmediate_operand" " 0,rm")
684 (match_operand:SF 2 "vector_move_operand" "ym,C")))]
685 "TARGET_MMX && !TARGET_SSE"
687 punpckldq\t{%2, %0|%0, %2}
688 movd\t{%1, %0|%0, %1}"
689 [(set_attr "type" "mmxcvt,mmxmov")
690 (set_attr "mode" "DI")])
692 (define_expand "vec_setv2sf"
693 [(match_operand:V2SF 0 "register_operand" "")
694 (match_operand:SF 1 "register_operand" "")
695 (match_operand 2 "const_int_operand" "")]
698 ix86_expand_vector_set (false, operands[0], operands[1],
699 INTVAL (operands[2]));
703 ;; Avoid combining registers from different units in a single alternative,
704 ;; see comment above inline_secondary_memory_needed function in i386.c
705 (define_insn_and_split "*vec_extractv2sf_0"
706 [(set (match_operand:SF 0 "nonimmediate_operand" "=x, m,y ,m,f,r")
708 (match_operand:V2SF 1 "nonimmediate_operand" " xm,x,ym,y,m,m")
709 (parallel [(const_int 0)])))]
710 "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
712 "&& reload_completed"
715 rtx op1 = operands[1];
717 op1 = gen_rtx_REG (SFmode, REGNO (op1));
719 op1 = gen_lowpart (SFmode, op1);
720 emit_move_insn (operands[0], op1);
724 ;; Avoid combining registers from different units in a single alternative,
725 ;; see comment above inline_secondary_memory_needed function in i386.c
726 (define_insn "*vec_extractv2sf_1"
727 [(set (match_operand:SF 0 "nonimmediate_operand" "=y,x,y,x,f,r")
729 (match_operand:V2SF 1 "nonimmediate_operand" " 0,0,o,o,o,o")
730 (parallel [(const_int 1)])))]
731 "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
739 [(set_attr "type" "mmxcvt,sselog1,mmxmov,ssemov,fmov,imov")
740 (set_attr "mode" "DI,V4SF,SF,SF,SF,SF")])
743 [(set (match_operand:SF 0 "register_operand" "")
745 (match_operand:V2SF 1 "memory_operand" "")
746 (parallel [(const_int 1)])))]
747 "TARGET_MMX && reload_completed"
750 operands[1] = adjust_address (operands[1], SFmode, 4);
751 emit_move_insn (operands[0], operands[1]);
755 (define_expand "vec_extractv2sf"
756 [(match_operand:SF 0 "register_operand" "")
757 (match_operand:V2SF 1 "register_operand" "")
758 (match_operand 2 "const_int_operand" "")]
761 ix86_expand_vector_extract (false, operands[0], operands[1],
762 INTVAL (operands[2]));
766 (define_expand "vec_initv2sf"
767 [(match_operand:V2SF 0 "register_operand" "")
768 (match_operand 1 "" "")]
771 ix86_expand_vector_init (false, operands[0], operands[1]);
775 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
777 ;; Parallel integral arithmetic
779 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
781 (define_expand "mmx_<plusminus_insn><mode>3"
782 [(set (match_operand:MMXMODEI8 0 "register_operand" "")
784 (match_operand:MMXMODEI8 1 "nonimmediate_operand" "")
785 (match_operand:MMXMODEI8 2 "nonimmediate_operand" "")))]
786 "TARGET_MMX || (TARGET_SSE2 && <MODE>mode == V1DImode)"
787 "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
789 (define_insn "*mmx_<plusminus_insn><mode>3"
790 [(set (match_operand:MMXMODEI8 0 "register_operand" "=y")
792 (match_operand:MMXMODEI8 1 "nonimmediate_operand" "<comm>0")
793 (match_operand:MMXMODEI8 2 "nonimmediate_operand" "ym")))]
794 "(TARGET_MMX || (TARGET_SSE2 && <MODE>mode == V1DImode))
795 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
796 "p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}"
797 [(set_attr "type" "mmxadd")
798 (set_attr "mode" "DI")])
800 (define_expand "mmx_<plusminus_insn><mode>3"
801 [(set (match_operand:MMXMODE12 0 "register_operand" "")
802 (sat_plusminus:MMXMODE12
803 (match_operand:MMXMODE12 1 "nonimmediate_operand" "")
804 (match_operand:MMXMODE12 2 "nonimmediate_operand" "")))]
806 "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
808 (define_insn "*mmx_<plusminus_insn><mode>3"
809 [(set (match_operand:MMXMODE12 0 "register_operand" "=y")
810 (sat_plusminus:MMXMODE12
811 (match_operand:MMXMODE12 1 "nonimmediate_operand" "<comm>0")
812 (match_operand:MMXMODE12 2 "nonimmediate_operand" "ym")))]
813 "TARGET_MMX && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
814 "p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}"
815 [(set_attr "type" "mmxadd")
816 (set_attr "mode" "DI")])
818 (define_expand "mmx_mulv4hi3"
819 [(set (match_operand:V4HI 0 "register_operand" "")
820 (mult:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "")
821 (match_operand:V4HI 2 "nonimmediate_operand" "")))]
823 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
825 (define_insn "*mmx_mulv4hi3"
826 [(set (match_operand:V4HI 0 "register_operand" "=y")
827 (mult:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "%0")
828 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
829 "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
830 "pmullw\t{%2, %0|%0, %2}"
831 [(set_attr "type" "mmxmul")
832 (set_attr "mode" "DI")])
834 (define_expand "mmx_smulv4hi3_highpart"
835 [(set (match_operand:V4HI 0 "register_operand" "")
840 (match_operand:V4HI 1 "nonimmediate_operand" ""))
842 (match_operand:V4HI 2 "nonimmediate_operand" "")))
845 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
847 (define_insn "*mmx_smulv4hi3_highpart"
848 [(set (match_operand:V4HI 0 "register_operand" "=y")
853 (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
855 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
857 "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
858 "pmulhw\t{%2, %0|%0, %2}"
859 [(set_attr "type" "mmxmul")
860 (set_attr "mode" "DI")])
862 (define_expand "mmx_umulv4hi3_highpart"
863 [(set (match_operand:V4HI 0 "register_operand" "")
868 (match_operand:V4HI 1 "nonimmediate_operand" ""))
870 (match_operand:V4HI 2 "nonimmediate_operand" "")))
872 "TARGET_SSE || TARGET_3DNOW_A"
873 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
875 (define_insn "*mmx_umulv4hi3_highpart"
876 [(set (match_operand:V4HI 0 "register_operand" "=y")
881 (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
883 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
885 "(TARGET_SSE || TARGET_3DNOW_A)
886 && ix86_binary_operator_ok (MULT, V4HImode, operands)"
887 "pmulhuw\t{%2, %0|%0, %2}"
888 [(set_attr "type" "mmxmul")
889 (set_attr "mode" "DI")])
891 (define_expand "mmx_pmaddwd"
892 [(set (match_operand:V2SI 0 "register_operand" "")
897 (match_operand:V4HI 1 "nonimmediate_operand" "")
898 (parallel [(const_int 0) (const_int 2)])))
901 (match_operand:V4HI 2 "nonimmediate_operand" "")
902 (parallel [(const_int 0) (const_int 2)]))))
905 (vec_select:V2HI (match_dup 1)
906 (parallel [(const_int 1) (const_int 3)])))
908 (vec_select:V2HI (match_dup 2)
909 (parallel [(const_int 1) (const_int 3)]))))))]
911 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
913 (define_insn "*mmx_pmaddwd"
914 [(set (match_operand:V2SI 0 "register_operand" "=y")
919 (match_operand:V4HI 1 "nonimmediate_operand" "%0")
920 (parallel [(const_int 0) (const_int 2)])))
923 (match_operand:V4HI 2 "nonimmediate_operand" "ym")
924 (parallel [(const_int 0) (const_int 2)]))))
927 (vec_select:V2HI (match_dup 1)
928 (parallel [(const_int 1) (const_int 3)])))
930 (vec_select:V2HI (match_dup 2)
931 (parallel [(const_int 1) (const_int 3)]))))))]
932 "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
933 "pmaddwd\t{%2, %0|%0, %2}"
934 [(set_attr "type" "mmxmul")
935 (set_attr "mode" "DI")])
937 (define_expand "mmx_pmulhrwv4hi3"
938 [(set (match_operand:V4HI 0 "register_operand" "")
944 (match_operand:V4HI 1 "nonimmediate_operand" ""))
946 (match_operand:V4HI 2 "nonimmediate_operand" "")))
947 (const_vector:V4SI [(const_int 32768) (const_int 32768)
948 (const_int 32768) (const_int 32768)]))
951 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
953 (define_insn "*mmx_pmulhrwv4hi3"
954 [(set (match_operand:V4HI 0 "register_operand" "=y")
960 (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
962 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
963 (const_vector:V4SI [(const_int 32768) (const_int 32768)
964 (const_int 32768) (const_int 32768)]))
966 "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V4HImode, operands)"
967 "pmulhrw\t{%2, %0|%0, %2}"
968 [(set_attr "type" "mmxmul")
969 (set_attr "prefix_extra" "1")
970 (set_attr "mode" "DI")])
972 (define_expand "sse2_umulv1siv1di3"
973 [(set (match_operand:V1DI 0 "register_operand" "")
977 (match_operand:V2SI 1 "nonimmediate_operand" "")
978 (parallel [(const_int 0)])))
981 (match_operand:V2SI 2 "nonimmediate_operand" "")
982 (parallel [(const_int 0)])))))]
984 "ix86_fixup_binary_operands_no_copy (MULT, V2SImode, operands);")
986 (define_insn "*sse2_umulv1siv1di3"
987 [(set (match_operand:V1DI 0 "register_operand" "=y")
991 (match_operand:V2SI 1 "nonimmediate_operand" "%0")
992 (parallel [(const_int 0)])))
995 (match_operand:V2SI 2 "nonimmediate_operand" "ym")
996 (parallel [(const_int 0)])))))]
997 "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V2SImode, operands)"
998 "pmuludq\t{%2, %0|%0, %2}"
999 [(set_attr "type" "mmxmul")
1000 (set_attr "mode" "DI")])
1002 (define_expand "mmx_<code>v4hi3"
1003 [(set (match_operand:V4HI 0 "register_operand" "")
1005 (match_operand:V4HI 1 "nonimmediate_operand" "")
1006 (match_operand:V4HI 2 "nonimmediate_operand" "")))]
1007 "TARGET_SSE || TARGET_3DNOW_A"
1008 "ix86_fixup_binary_operands_no_copy (<CODE>, V4HImode, operands);")
1010 (define_insn "*mmx_<code>v4hi3"
1011 [(set (match_operand:V4HI 0 "register_operand" "=y")
1013 (match_operand:V4HI 1 "nonimmediate_operand" "%0")
1014 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
1015 "(TARGET_SSE || TARGET_3DNOW_A)
1016 && ix86_binary_operator_ok (<CODE>, V4HImode, operands)"
1017 "p<maxmin_int>w\t{%2, %0|%0, %2}"
1018 [(set_attr "type" "mmxadd")
1019 (set_attr "mode" "DI")])
1021 (define_expand "mmx_<code>v8qi3"
1022 [(set (match_operand:V8QI 0 "register_operand" "")
1024 (match_operand:V8QI 1 "nonimmediate_operand" "")
1025 (match_operand:V8QI 2 "nonimmediate_operand" "")))]
1026 "TARGET_SSE || TARGET_3DNOW_A"
1027 "ix86_fixup_binary_operands_no_copy (<CODE>, V8QImode, operands);")
1029 (define_insn "*mmx_<code>v8qi3"
1030 [(set (match_operand:V8QI 0 "register_operand" "=y")
1032 (match_operand:V8QI 1 "nonimmediate_operand" "%0")
1033 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
1034 "(TARGET_SSE || TARGET_3DNOW_A)
1035 && ix86_binary_operator_ok (<CODE>, V8QImode, operands)"
1036 "p<maxmin_int>b\t{%2, %0|%0, %2}"
1037 [(set_attr "type" "mmxadd")
1038 (set_attr "mode" "DI")])
1040 (define_insn "mmx_ashr<mode>3"
1041 [(set (match_operand:MMXMODE24 0 "register_operand" "=y")
1043 (match_operand:MMXMODE24 1 "register_operand" "0")
1044 (match_operand:SI 2 "nonmemory_operand" "yN")))]
1046 "psra<mmxvecsize>\t{%2, %0|%0, %2}"
1047 [(set_attr "type" "mmxshft")
1048 (set (attr "length_immediate")
1049 (if_then_else (match_operand 2 "const_int_operand" "")
1051 (const_string "0")))
1052 (set_attr "mode" "DI")])
1054 (define_insn "mmx_<shift_insn><mode>3"
1055 [(set (match_operand:MMXMODE248 0 "register_operand" "=y")
1056 (any_lshift:MMXMODE248
1057 (match_operand:MMXMODE248 1 "register_operand" "0")
1058 (match_operand:SI 2 "nonmemory_operand" "yN")))]
1060 "p<vshift><mmxvecsize>\t{%2, %0|%0, %2}"
1061 [(set_attr "type" "mmxshft")
1062 (set (attr "length_immediate")
1063 (if_then_else (match_operand 2 "const_int_operand" "")
1065 (const_string "0")))
1066 (set_attr "mode" "DI")])
1068 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1070 ;; Parallel integral comparisons
1072 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1074 (define_expand "mmx_eq<mode>3"
1075 [(set (match_operand:MMXMODEI 0 "register_operand" "")
1077 (match_operand:MMXMODEI 1 "nonimmediate_operand" "")
1078 (match_operand:MMXMODEI 2 "nonimmediate_operand" "")))]
1080 "ix86_fixup_binary_operands_no_copy (EQ, <MODE>mode, operands);")
1082 (define_insn "*mmx_eq<mode>3"
1083 [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
1085 (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
1086 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
1087 "TARGET_MMX && ix86_binary_operator_ok (EQ, <MODE>mode, operands)"
1088 "pcmpeq<mmxvecsize>\t{%2, %0|%0, %2}"
1089 [(set_attr "type" "mmxcmp")
1090 (set_attr "mode" "DI")])
1092 (define_insn "mmx_gt<mode>3"
1093 [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
1095 (match_operand:MMXMODEI 1 "register_operand" "0")
1096 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
1098 "pcmpgt<mmxvecsize>\t{%2, %0|%0, %2}"
1099 [(set_attr "type" "mmxcmp")
1100 (set_attr "mode" "DI")])
1102 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1104 ;; Parallel integral logical operations
1106 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1108 (define_insn "mmx_andnot<mode>3"
1109 [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
1111 (not:MMXMODEI (match_operand:MMXMODEI 1 "register_operand" "0"))
1112 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
1114 "pandn\t{%2, %0|%0, %2}"
1115 [(set_attr "type" "mmxadd")
1116 (set_attr "mode" "DI")])
1118 (define_expand "mmx_<code><mode>3"
1119 [(set (match_operand:MMXMODEI 0 "register_operand" "")
1121 (match_operand:MMXMODEI 1 "nonimmediate_operand" "")
1122 (match_operand:MMXMODEI 2 "nonimmediate_operand" "")))]
1124 "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
1126 (define_insn "*mmx_<code><mode>3"
1127 [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
1129 (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
1130 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
1131 "TARGET_MMX && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
1132 "p<logic>\t{%2, %0|%0, %2}"
1133 [(set_attr "type" "mmxadd")
1134 (set_attr "mode" "DI")])
1136 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1138 ;; Parallel integral element swizzling
1140 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1142 (define_insn "mmx_packsswb"
1143 [(set (match_operand:V8QI 0 "register_operand" "=y")
1146 (match_operand:V4HI 1 "register_operand" "0"))
1148 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))))]
1150 "packsswb\t{%2, %0|%0, %2}"
1151 [(set_attr "type" "mmxshft")
1152 (set_attr "mode" "DI")])
1154 (define_insn "mmx_packssdw"
1155 [(set (match_operand:V4HI 0 "register_operand" "=y")
1158 (match_operand:V2SI 1 "register_operand" "0"))
1160 (match_operand:V2SI 2 "nonimmediate_operand" "ym"))))]
1162 "packssdw\t{%2, %0|%0, %2}"
1163 [(set_attr "type" "mmxshft")
1164 (set_attr "mode" "DI")])
1166 (define_insn "mmx_packuswb"
1167 [(set (match_operand:V8QI 0 "register_operand" "=y")
1170 (match_operand:V4HI 1 "register_operand" "0"))
1172 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))))]
1174 "packuswb\t{%2, %0|%0, %2}"
1175 [(set_attr "type" "mmxshft")
1176 (set_attr "mode" "DI")])
1178 (define_insn "mmx_punpckhbw"
1179 [(set (match_operand:V8QI 0 "register_operand" "=y")
1182 (match_operand:V8QI 1 "register_operand" "0")
1183 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
1184 (parallel [(const_int 4) (const_int 12)
1185 (const_int 5) (const_int 13)
1186 (const_int 6) (const_int 14)
1187 (const_int 7) (const_int 15)])))]
1189 "punpckhbw\t{%2, %0|%0, %2}"
1190 [(set_attr "type" "mmxcvt")
1191 (set_attr "mode" "DI")])
1193 (define_insn "mmx_punpcklbw"
1194 [(set (match_operand:V8QI 0 "register_operand" "=y")
1197 (match_operand:V8QI 1 "register_operand" "0")
1198 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
1199 (parallel [(const_int 0) (const_int 8)
1200 (const_int 1) (const_int 9)
1201 (const_int 2) (const_int 10)
1202 (const_int 3) (const_int 11)])))]
1204 "punpcklbw\t{%2, %0|%0, %2}"
1205 [(set_attr "type" "mmxcvt")
1206 (set_attr "mode" "DI")])
1208 (define_insn "mmx_punpckhwd"
1209 [(set (match_operand:V4HI 0 "register_operand" "=y")
1212 (match_operand:V4HI 1 "register_operand" "0")
1213 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
1214 (parallel [(const_int 2) (const_int 6)
1215 (const_int 3) (const_int 7)])))]
1217 "punpckhwd\t{%2, %0|%0, %2}"
1218 [(set_attr "type" "mmxcvt")
1219 (set_attr "mode" "DI")])
1221 (define_insn "mmx_punpcklwd"
1222 [(set (match_operand:V4HI 0 "register_operand" "=y")
1225 (match_operand:V4HI 1 "register_operand" "0")
1226 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
1227 (parallel [(const_int 0) (const_int 4)
1228 (const_int 1) (const_int 5)])))]
1230 "punpcklwd\t{%2, %0|%0, %2}"
1231 [(set_attr "type" "mmxcvt")
1232 (set_attr "mode" "DI")])
1234 (define_insn "mmx_punpckhdq"
1235 [(set (match_operand:V2SI 0 "register_operand" "=y")
1238 (match_operand:V2SI 1 "register_operand" "0")
1239 (match_operand:V2SI 2 "nonimmediate_operand" "ym"))
1240 (parallel [(const_int 1)
1243 "punpckhdq\t{%2, %0|%0, %2}"
1244 [(set_attr "type" "mmxcvt")
1245 (set_attr "mode" "DI")])
1247 (define_insn "mmx_punpckldq"
1248 [(set (match_operand:V2SI 0 "register_operand" "=y")
1251 (match_operand:V2SI 1 "register_operand" "0")
1252 (match_operand:V2SI 2 "nonimmediate_operand" "ym"))
1253 (parallel [(const_int 0)
1256 "punpckldq\t{%2, %0|%0, %2}"
1257 [(set_attr "type" "mmxcvt")
1258 (set_attr "mode" "DI")])
1260 (define_expand "mmx_pinsrw"
1261 [(set (match_operand:V4HI 0 "register_operand" "")
1264 (match_operand:SI 2 "nonimmediate_operand" ""))
1265 (match_operand:V4HI 1 "register_operand" "")
1266 (match_operand:SI 3 "const_0_to_3_operand" "")))]
1267 "TARGET_SSE || TARGET_3DNOW_A"
1269 operands[2] = gen_lowpart (HImode, operands[2]);
1270 operands[3] = GEN_INT (1 << INTVAL (operands[3]));
1273 (define_insn "*mmx_pinsrw"
1274 [(set (match_operand:V4HI 0 "register_operand" "=y")
1277 (match_operand:HI 2 "nonimmediate_operand" "rm"))
1278 (match_operand:V4HI 1 "register_operand" "0")
1279 (match_operand:SI 3 "const_int_operand" "")))]
1280 "(TARGET_SSE || TARGET_3DNOW_A)
1281 && ((unsigned) exact_log2 (INTVAL (operands[3]))
1282 < GET_MODE_NUNITS (V4HImode))"
1284 operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
1285 if (MEM_P (operands[2]))
1286 return "pinsrw\t{%3, %2, %0|%0, %2, %3}";
1288 return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}";
1290 [(set_attr "type" "mmxcvt")
1291 (set_attr "length_immediate" "1")
1292 (set_attr "mode" "DI")])
1294 (define_insn "mmx_pextrw"
1295 [(set (match_operand:SI 0 "register_operand" "=r")
1298 (match_operand:V4HI 1 "register_operand" "y")
1299 (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n")]))))]
1300 "TARGET_SSE || TARGET_3DNOW_A"
1301 "pextrw\t{%2, %1, %0|%0, %1, %2}"
1302 [(set_attr "type" "mmxcvt")
1303 (set_attr "length_immediate" "1")
1304 (set_attr "mode" "DI")])
1306 (define_expand "mmx_pshufw"
1307 [(match_operand:V4HI 0 "register_operand" "")
1308 (match_operand:V4HI 1 "nonimmediate_operand" "")
1309 (match_operand:SI 2 "const_int_operand" "")]
1310 "TARGET_SSE || TARGET_3DNOW_A"
1312 int mask = INTVAL (operands[2]);
1313 emit_insn (gen_mmx_pshufw_1 (operands[0], operands[1],
1314 GEN_INT ((mask >> 0) & 3),
1315 GEN_INT ((mask >> 2) & 3),
1316 GEN_INT ((mask >> 4) & 3),
1317 GEN_INT ((mask >> 6) & 3)));
1321 (define_insn "mmx_pshufw_1"
1322 [(set (match_operand:V4HI 0 "register_operand" "=y")
1324 (match_operand:V4HI 1 "nonimmediate_operand" "ym")
1325 (parallel [(match_operand 2 "const_0_to_3_operand" "")
1326 (match_operand 3 "const_0_to_3_operand" "")
1327 (match_operand 4 "const_0_to_3_operand" "")
1328 (match_operand 5 "const_0_to_3_operand" "")])))]
1329 "TARGET_SSE || TARGET_3DNOW_A"
1332 mask |= INTVAL (operands[2]) << 0;
1333 mask |= INTVAL (operands[3]) << 2;
1334 mask |= INTVAL (operands[4]) << 4;
1335 mask |= INTVAL (operands[5]) << 6;
1336 operands[2] = GEN_INT (mask);
1338 return "pshufw\t{%2, %1, %0|%0, %1, %2}";
1340 [(set_attr "type" "mmxcvt")
1341 (set_attr "length_immediate" "1")
1342 (set_attr "mode" "DI")])
1344 (define_insn "mmx_pswapdv2si2"
1345 [(set (match_operand:V2SI 0 "register_operand" "=y")
1347 (match_operand:V2SI 1 "nonimmediate_operand" "ym")
1348 (parallel [(const_int 1) (const_int 0)])))]
1350 "pswapd\t{%1, %0|%0, %1}"
1351 [(set_attr "type" "mmxcvt")
1352 (set_attr "prefix_extra" "1")
1353 (set_attr "mode" "DI")])
1355 (define_insn "*vec_dupv4hi"
1356 [(set (match_operand:V4HI 0 "register_operand" "=y")
1359 (match_operand:SI 1 "register_operand" "0"))))]
1360 "TARGET_SSE || TARGET_3DNOW_A"
1361 "pshufw\t{$0, %0, %0|%0, %0, 0}"
1362 [(set_attr "type" "mmxcvt")
1363 (set_attr "length_immediate" "1")
1364 (set_attr "mode" "DI")])
1366 (define_insn "*vec_dupv2si"
1367 [(set (match_operand:V2SI 0 "register_operand" "=y")
1369 (match_operand:SI 1 "register_operand" "0")))]
1372 [(set_attr "type" "mmxcvt")
1373 (set_attr "mode" "DI")])
1375 (define_insn "*mmx_concatv2si"
1376 [(set (match_operand:V2SI 0 "register_operand" "=y,y")
1378 (match_operand:SI 1 "nonimmediate_operand" " 0,rm")
1379 (match_operand:SI 2 "vector_move_operand" "ym,C")))]
1380 "TARGET_MMX && !TARGET_SSE"
1382 punpckldq\t{%2, %0|%0, %2}
1383 movd\t{%1, %0|%0, %1}"
1384 [(set_attr "type" "mmxcvt,mmxmov")
1385 (set_attr "mode" "DI")])
1387 (define_expand "vec_setv2si"
1388 [(match_operand:V2SI 0 "register_operand" "")
1389 (match_operand:SI 1 "register_operand" "")
1390 (match_operand 2 "const_int_operand" "")]
1393 ix86_expand_vector_set (false, operands[0], operands[1],
1394 INTVAL (operands[2]));
1398 ;; Avoid combining registers from different units in a single alternative,
1399 ;; see comment above inline_secondary_memory_needed function in i386.c
1400 (define_insn_and_split "*vec_extractv2si_0"
1401 [(set (match_operand:SI 0 "nonimmediate_operand" "=x,m,y, m,r")
1403 (match_operand:V2SI 1 "nonimmediate_operand" "xm,x,ym,y,m")
1404 (parallel [(const_int 0)])))]
1405 "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1407 "&& reload_completed"
1410 rtx op1 = operands[1];
1412 op1 = gen_rtx_REG (SImode, REGNO (op1));
1414 op1 = gen_lowpart (SImode, op1);
1415 emit_move_insn (operands[0], op1);
1419 ;; Avoid combining registers from different units in a single alternative,
1420 ;; see comment above inline_secondary_memory_needed function in i386.c
1421 (define_insn "*vec_extractv2si_1"
1422 [(set (match_operand:SI 0 "nonimmediate_operand" "=y,x,x,x,y,x,r")
1424 (match_operand:V2SI 1 "nonimmediate_operand" " 0,0,x,0,o,o,o")
1425 (parallel [(const_int 1)])))]
1426 "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1430 pshufd\t{$85, %1, %0|%0, %1, 85}
1436 (if_then_else (eq_attr "alternative" "1,2")
1437 (const_string "sse2")
1438 (const_string "*")))
1439 (set_attr "type" "mmxcvt,sselog1,sselog1,sselog1,mmxmov,ssemov,imov")
1440 (set_attr "length_immediate" "*,*,1,*,*,*,*")
1441 (set_attr "mode" "DI,TI,TI,V4SF,SI,SI,SI")])
1444 [(set (match_operand:SI 0 "register_operand" "")
1446 (match_operand:V2SI 1 "memory_operand" "")
1447 (parallel [(const_int 1)])))]
1448 "TARGET_MMX && reload_completed"
1451 operands[1] = adjust_address (operands[1], SImode, 4);
1452 emit_move_insn (operands[0], operands[1]);
1456 (define_expand "vec_extractv2si"
1457 [(match_operand:SI 0 "register_operand" "")
1458 (match_operand:V2SI 1 "register_operand" "")
1459 (match_operand 2 "const_int_operand" "")]
1462 ix86_expand_vector_extract (false, operands[0], operands[1],
1463 INTVAL (operands[2]));
1467 (define_expand "vec_initv2si"
1468 [(match_operand:V2SI 0 "register_operand" "")
1469 (match_operand 1 "" "")]
1472 ix86_expand_vector_init (false, operands[0], operands[1]);
1476 (define_expand "vec_setv4hi"
1477 [(match_operand:V4HI 0 "register_operand" "")
1478 (match_operand:HI 1 "register_operand" "")
1479 (match_operand 2 "const_int_operand" "")]
1482 ix86_expand_vector_set (false, operands[0], operands[1],
1483 INTVAL (operands[2]));
1487 (define_expand "vec_extractv4hi"
1488 [(match_operand:HI 0 "register_operand" "")
1489 (match_operand:V4HI 1 "register_operand" "")
1490 (match_operand 2 "const_int_operand" "")]
1493 ix86_expand_vector_extract (false, operands[0], operands[1],
1494 INTVAL (operands[2]));
1498 (define_expand "vec_initv4hi"
1499 [(match_operand:V4HI 0 "register_operand" "")
1500 (match_operand 1 "" "")]
1503 ix86_expand_vector_init (false, operands[0], operands[1]);
1507 (define_expand "vec_setv8qi"
1508 [(match_operand:V8QI 0 "register_operand" "")
1509 (match_operand:QI 1 "register_operand" "")
1510 (match_operand 2 "const_int_operand" "")]
1513 ix86_expand_vector_set (false, operands[0], operands[1],
1514 INTVAL (operands[2]));
1518 (define_expand "vec_extractv8qi"
1519 [(match_operand:QI 0 "register_operand" "")
1520 (match_operand:V8QI 1 "register_operand" "")
1521 (match_operand 2 "const_int_operand" "")]
1524 ix86_expand_vector_extract (false, operands[0], operands[1],
1525 INTVAL (operands[2]));
1529 (define_expand "vec_initv8qi"
1530 [(match_operand:V8QI 0 "register_operand" "")
1531 (match_operand 1 "" "")]
1534 ix86_expand_vector_init (false, operands[0], operands[1]);
1538 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1542 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1544 (define_expand "mmx_uavgv8qi3"
1545 [(set (match_operand:V8QI 0 "register_operand" "")
1551 (match_operand:V8QI 1 "nonimmediate_operand" ""))
1553 (match_operand:V8QI 2 "nonimmediate_operand" "")))
1554 (const_vector:V8HI [(const_int 1) (const_int 1)
1555 (const_int 1) (const_int 1)
1556 (const_int 1) (const_int 1)
1557 (const_int 1) (const_int 1)]))
1559 "TARGET_SSE || TARGET_3DNOW"
1560 "ix86_fixup_binary_operands_no_copy (PLUS, V8QImode, operands);")
1562 (define_insn "*mmx_uavgv8qi3"
1563 [(set (match_operand:V8QI 0 "register_operand" "=y")
1569 (match_operand:V8QI 1 "nonimmediate_operand" "%0"))
1571 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))
1572 (const_vector:V8HI [(const_int 1) (const_int 1)
1573 (const_int 1) (const_int 1)
1574 (const_int 1) (const_int 1)
1575 (const_int 1) (const_int 1)]))
1577 "(TARGET_SSE || TARGET_3DNOW)
1578 && ix86_binary_operator_ok (PLUS, V8QImode, operands)"
1580 /* These two instructions have the same operation, but their encoding
1581 is different. Prefer the one that is de facto standard. */
1582 if (TARGET_SSE || TARGET_3DNOW_A)
1583 return "pavgb\t{%2, %0|%0, %2}";
1585 return "pavgusb\t{%2, %0|%0, %2}";
1587 [(set_attr "type" "mmxshft")
1588 (set (attr "prefix_extra")
1590 (not (ior (match_test "TARGET_SSE")
1591 (match_test "TARGET_3DNOW_A")))
1593 (const_string "*")))
1594 (set_attr "mode" "DI")])
1596 (define_expand "mmx_uavgv4hi3"
1597 [(set (match_operand:V4HI 0 "register_operand" "")
1603 (match_operand:V4HI 1 "nonimmediate_operand" ""))
1605 (match_operand:V4HI 2 "nonimmediate_operand" "")))
1606 (const_vector:V4SI [(const_int 1) (const_int 1)
1607 (const_int 1) (const_int 1)]))
1609 "TARGET_SSE || TARGET_3DNOW_A"
1610 "ix86_fixup_binary_operands_no_copy (PLUS, V4HImode, operands);")
1612 (define_insn "*mmx_uavgv4hi3"
1613 [(set (match_operand:V4HI 0 "register_operand" "=y")
1619 (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
1621 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
1622 (const_vector:V4SI [(const_int 1) (const_int 1)
1623 (const_int 1) (const_int 1)]))
1625 "(TARGET_SSE || TARGET_3DNOW_A)
1626 && ix86_binary_operator_ok (PLUS, V4HImode, operands)"
1627 "pavgw\t{%2, %0|%0, %2}"
1628 [(set_attr "type" "mmxshft")
1629 (set_attr "mode" "DI")])
1631 (define_insn "mmx_psadbw"
1632 [(set (match_operand:V1DI 0 "register_operand" "=y")
1633 (unspec:V1DI [(match_operand:V8QI 1 "register_operand" "0")
1634 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
1636 "TARGET_SSE || TARGET_3DNOW_A"
1637 "psadbw\t{%2, %0|%0, %2}"
1638 [(set_attr "type" "mmxshft")
1639 (set_attr "mode" "DI")])
1641 (define_insn "mmx_pmovmskb"
1642 [(set (match_operand:SI 0 "register_operand" "=r")
1643 (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
1645 "TARGET_SSE || TARGET_3DNOW_A"
1646 "pmovmskb\t{%1, %0|%0, %1}"
1647 [(set_attr "type" "mmxcvt")
1648 (set_attr "mode" "DI")])
1650 (define_expand "mmx_maskmovq"
1651 [(set (match_operand:V8QI 0 "memory_operand" "")
1652 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "")
1653 (match_operand:V8QI 2 "register_operand" "")
1656 "TARGET_SSE || TARGET_3DNOW_A")
1658 (define_insn "*mmx_maskmovq"
1659 [(set (mem:V8QI (match_operand:P 0 "register_operand" "D"))
1660 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
1661 (match_operand:V8QI 2 "register_operand" "y")
1662 (mem:V8QI (match_dup 0))]
1664 "TARGET_SSE || TARGET_3DNOW_A"
1665 ;; @@@ check ordering of operands in intel/nonintel syntax
1666 "maskmovq\t{%2, %1|%1, %2}"
1667 [(set_attr "type" "mmxcvt")
1668 (set_attr "mode" "DI")])
1670 (define_expand "mmx_emms"
1671 [(match_par_dup 0 [(const_int 0)])]
1676 operands[0] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (17));
1678 XVECEXP (operands[0], 0, 0)
1679 = gen_rtx_UNSPEC_VOLATILE (VOIDmode, gen_rtvec (1, const0_rtx),
1682 for (regno = 0; regno < 8; regno++)
1684 XVECEXP (operands[0], 0, regno + 1)
1685 = gen_rtx_CLOBBER (VOIDmode,
1686 gen_rtx_REG (XFmode, FIRST_STACK_REG + regno));
1688 XVECEXP (operands[0], 0, regno + 9)
1689 = gen_rtx_CLOBBER (VOIDmode,
1690 gen_rtx_REG (DImode, FIRST_MMX_REG + regno));
1694 (define_insn "*mmx_emms"
1695 [(match_parallel 0 "emms_operation"
1696 [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)])]
1699 [(set_attr "type" "mmx")
1700 (set_attr "modrm" "0")
1701 (set_attr "memory" "none")])
1703 (define_expand "mmx_femms"
1704 [(match_par_dup 0 [(const_int 0)])]
1709 operands[0] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (17));
1711 XVECEXP (operands[0], 0, 0)
1712 = gen_rtx_UNSPEC_VOLATILE (VOIDmode, gen_rtvec (1, const0_rtx),
1715 for (regno = 0; regno < 8; regno++)
1717 XVECEXP (operands[0], 0, regno + 1)
1718 = gen_rtx_CLOBBER (VOIDmode,
1719 gen_rtx_REG (XFmode, FIRST_STACK_REG + regno));
1721 XVECEXP (operands[0], 0, regno + 9)
1722 = gen_rtx_CLOBBER (VOIDmode,
1723 gen_rtx_REG (DImode, FIRST_MMX_REG + regno));
1727 (define_insn "*mmx_femms"
1728 [(match_parallel 0 "emms_operation"
1729 [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)])]
1732 [(set_attr "type" "mmx")
1733 (set_attr "modrm" "0")
1734 (set_attr "memory" "none")])