1 ;; GCC machine description for MMX and 3dNOW! instructions
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 2, 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 COPYING. If not, write to
19 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
20 ;; Boston, MA 02110-1301, USA.
22 ;; The MMX and 3dNOW! patterns are in the same file because they use
23 ;; the same register file, and 3dNOW! adds a number of extensions to
24 ;; the base integer MMX isa.
26 ;; Note! Except for the basic move instructions, *all* of these
27 ;; patterns are outside the normal optabs namespace. This is because
28 ;; use of these registers requires the insertion of emms or femms
29 ;; instructions to return to normal fpu mode. The compiler doesn't
30 ;; know how to do that itself, which means it's up to the user. Which
31 ;; means that we should never use any of these patterns except at the
32 ;; direction of the user via a builtin.
34 ;; 8 byte integral modes handled by MMX (and by extension, SSE)
35 (define_mode_macro MMXMODEI [V8QI V4HI V2SI])
37 ;; All 8-byte vector modes handled by MMX
38 (define_mode_macro MMXMODE [V8QI V4HI V2SI V2SF])
41 (define_mode_macro MMXMODE12 [V8QI V4HI])
42 (define_mode_macro MMXMODE24 [V4HI V2SI])
44 ;; Mapping from integer vector mode to mnemonic suffix
45 (define_mode_attr mmxvecsize [(V8QI "b") (V4HI "w") (V2SI "d") (DI "q")])
47 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
51 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
53 ;; All of these patterns are enabled for MMX as well as 3dNOW.
54 ;; This is essential for maintaining stable calling conventions.
56 (define_expand "mov<mode>"
57 [(set (match_operand:MMXMODEI 0 "nonimmediate_operand" "")
58 (match_operand:MMXMODEI 1 "nonimmediate_operand" ""))]
61 ix86_expand_vector_move (<MODE>mode, operands);
65 (define_insn "*mov<mode>_internal_rex64"
66 [(set (match_operand:MMXMODEI 0 "nonimmediate_operand"
67 "=rm,r,*y,*y ,m ,*y,Y ,x,x ,m,r,x")
68 (match_operand:MMXMODEI 1 "vector_move_operand"
69 "Cr ,m,C ,*ym,*y,Y ,*y,C,xm,x,x,r"))]
70 "TARGET_64BIT && TARGET_MMX
71 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
78 movdq2q\t{%1, %0|%0, %1}
79 movq2dq\t{%1, %0|%0, %1}
84 movd\t{%1, %0|%0, %1}"
85 [(set_attr "type" "imov,imov,mmx,mmxmov,mmxmov,ssecvt,ssecvt,sselog1,ssemov,ssemov,ssemov,ssemov")
86 (set_attr "unit" "*,*,*,*,*,mmx,mmx,*,*,*,*,*")
87 (set_attr "mode" "DI")])
89 (define_insn "*mov<mode>_internal"
90 [(set (match_operand:MMXMODEI 0 "nonimmediate_operand"
91 "=*y,*y ,m ,*y,*Y,*Y,*Y ,m ,*x,*x,*x,m ,?r ,?m")
92 (match_operand:MMXMODEI 1 "vector_move_operand"
93 "C ,*ym,*y,*Y,*y,C ,*Ym,*Y,C ,*x,m ,*x,irm,r"))]
95 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
100 movdq2q\t{%1, %0|%0, %1}
101 movq2dq\t{%1, %0|%0, %1}
103 movq\t{%1, %0|%0, %1}
104 movq\t{%1, %0|%0, %1}
106 movaps\t{%1, %0|%0, %1}
107 movlps\t{%1, %0|%0, %1}
108 movlps\t{%1, %0|%0, %1}
111 [(set_attr "type" "mmx,mmxmov,mmxmov,ssecvt,ssecvt,sselog1,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov,*,*")
112 (set_attr "unit" "*,*,*,mmx,mmx,*,*,*,*,*,*,*,*,*")
113 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,DI,V4SF,V4SF,V2SF,V2SF,DI,DI")])
115 (define_expand "movv2sf"
116 [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
117 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
120 ix86_expand_vector_move (V2SFmode, operands);
124 (define_insn "*movv2sf_internal_rex64"
125 [(set (match_operand:V2SF 0 "nonimmediate_operand"
126 "=rm,r,*y ,*y ,m ,*y,Y ,x,x,x,m,r,x")
127 (match_operand:V2SF 1 "vector_move_operand"
128 "Cr ,m ,C ,*ym,*y,Y ,*y,C,x,m,x,x,r"))]
129 "TARGET_64BIT && TARGET_MMX
130 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
132 movq\t{%1, %0|%0, %1}
133 movq\t{%1, %0|%0, %1}
135 movq\t{%1, %0|%0, %1}
136 movq\t{%1, %0|%0, %1}
137 movdq2q\t{%1, %0|%0, %1}
138 movq2dq\t{%1, %0|%0, %1}
140 movaps\t{%1, %0|%0, %1}
141 movlps\t{%1, %0|%0, %1}
142 movlps\t{%1, %0|%0, %1}
143 movd\t{%1, %0|%0, %1}
144 movd\t{%1, %0|%0, %1}"
145 [(set_attr "type" "imov,imov,mmx,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,sselog1,ssemov,ssemov,ssemov,ssemov")
146 (set_attr "unit" "*,*,*,*,*,mmx,mmx,*,*,*,*,*,*")
147 (set_attr "mode" "DI,DI,DI,DI,DI,DI,DI,V4SF,V4SF,V2SF,V2SF,DI,DI")])
149 (define_insn "*movv2sf_internal"
150 [(set (match_operand:V2SF 0 "nonimmediate_operand"
151 "=*y,*y ,m,*y,*Y,*x,*x,*x,m ,?r ,?m")
152 (match_operand:V2SF 1 "vector_move_operand"
153 "C ,*ym,*y,*Y,*y,C ,*x,m ,*x,irm,r"))]
155 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
158 movq\t{%1, %0|%0, %1}
159 movq\t{%1, %0|%0, %1}
160 movdq2q\t{%1, %0|%0, %1}
161 movq2dq\t{%1, %0|%0, %1}
163 movaps\t{%1, %0|%0, %1}
164 movlps\t{%1, %0|%0, %1}
165 movlps\t{%1, %0|%0, %1}
168 [(set_attr "type" "mmx,mmxmov,mmxmov,ssecvt,ssecvt,sselog1,ssemov,ssemov,ssemov,*,*")
169 (set_attr "unit" "*,*,*,mmx,mmx,*,*,*,*,*,*")
170 (set_attr "mode" "DI,DI,DI,DI,DI,V4SF,V4SF,V2SF,V2SF,DI,DI")])
172 ;; %%% This multiword shite has got to go.
174 [(set (match_operand:MMXMODE 0 "nonimmediate_operand" "")
175 (match_operand:MMXMODE 1 "general_operand" ""))]
176 "!TARGET_64BIT && reload_completed
177 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
178 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
180 "ix86_split_long_move (operands); DONE;")
182 (define_expand "push<mode>1"
183 [(match_operand:MMXMODE 0 "register_operand" "")]
186 ix86_expand_push (<MODE>mode, operands[0]);
190 (define_expand "movmisalign<mode>"
191 [(set (match_operand:MMXMODE 0 "nonimmediate_operand" "")
192 (match_operand:MMXMODE 1 "nonimmediate_operand" ""))]
195 ix86_expand_vector_move (<MODE>mode, operands);
199 (define_insn "sse_movntdi"
200 [(set (match_operand:DI 0 "memory_operand" "=m")
201 (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
203 "TARGET_SSE || TARGET_3DNOW_A"
204 "movntq\t{%1, %0|%0, %1}"
205 [(set_attr "type" "mmxmov")
206 (set_attr "mode" "DI")])
208 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
210 ;; Parallel single-precision floating point arithmetic
212 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
214 (define_insn "mmx_addv2sf3"
215 [(set (match_operand:V2SF 0 "register_operand" "=y")
216 (plus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
217 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
218 "TARGET_3DNOW && ix86_binary_operator_ok (PLUS, V2SFmode, operands)"
219 "pfadd\\t{%2, %0|%0, %2}"
220 [(set_attr "type" "mmxadd")
221 (set_attr "mode" "V2SF")])
223 (define_insn "mmx_subv2sf3"
224 [(set (match_operand:V2SF 0 "register_operand" "=y,y")
225 (minus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "0,ym")
226 (match_operand:V2SF 2 "nonimmediate_operand" "ym,0")))]
227 "TARGET_3DNOW && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
229 pfsub\\t{%2, %0|%0, %2}
230 pfsubr\\t{%2, %0|%0, %2}"
231 [(set_attr "type" "mmxadd")
232 (set_attr "mode" "V2SF")])
234 (define_expand "mmx_subrv2sf3"
235 [(set (match_operand:V2SF 0 "register_operand" "")
236 (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "")
237 (match_operand:V2SF 1 "nonimmediate_operand" "")))]
238 "TARGET_3DNOW && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
241 (define_insn "mmx_mulv2sf3"
242 [(set (match_operand:V2SF 0 "register_operand" "=y")
243 (mult:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
244 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
245 "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V2SFmode, operands)"
246 "pfmul\\t{%2, %0|%0, %2}"
247 [(set_attr "type" "mmxmul")
248 (set_attr "mode" "V2SF")])
250 (define_insn "mmx_smaxv2sf3"
251 [(set (match_operand:V2SF 0 "register_operand" "=y")
252 (smax:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
253 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
254 "TARGET_3DNOW && ix86_binary_operator_ok (SMAX, V2SFmode, operands)"
255 "pfmax\\t{%2, %0|%0, %2}"
256 [(set_attr "type" "mmxadd")
257 (set_attr "mode" "V2SF")])
259 (define_insn "mmx_sminv2sf3"
260 [(set (match_operand:V2SF 0 "register_operand" "=y")
261 (smin:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
262 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
263 "TARGET_3DNOW && ix86_binary_operator_ok (SMIN, V2SFmode, operands)"
264 "pfmin\\t{%2, %0|%0, %2}"
265 [(set_attr "type" "mmxadd")
266 (set_attr "mode" "V2SF")])
268 (define_insn "mmx_rcpv2sf2"
269 [(set (match_operand:V2SF 0 "register_operand" "=y")
270 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
273 "pfrcp\\t{%1, %0|%0, %1}"
274 [(set_attr "type" "mmx")
275 (set_attr "mode" "V2SF")])
277 (define_insn "mmx_rcpit1v2sf3"
278 [(set (match_operand:V2SF 0 "register_operand" "=y")
279 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
280 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
283 "pfrcpit1\\t{%2, %0|%0, %2}"
284 [(set_attr "type" "mmx")
285 (set_attr "mode" "V2SF")])
287 (define_insn "mmx_rcpit2v2sf3"
288 [(set (match_operand:V2SF 0 "register_operand" "=y")
289 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
290 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
293 "pfrcpit2\\t{%2, %0|%0, %2}"
294 [(set_attr "type" "mmx")
295 (set_attr "mode" "V2SF")])
297 (define_insn "mmx_rsqrtv2sf2"
298 [(set (match_operand:V2SF 0 "register_operand" "=y")
299 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
302 "pfrsqrt\\t{%1, %0|%0, %1}"
303 [(set_attr "type" "mmx")
304 (set_attr "mode" "V2SF")])
306 (define_insn "mmx_rsqit1v2sf3"
307 [(set (match_operand:V2SF 0 "register_operand" "=y")
308 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
309 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
312 "pfrsqit1\\t{%2, %0|%0, %2}"
313 [(set_attr "type" "mmx")
314 (set_attr "mode" "V2SF")])
316 (define_insn "mmx_haddv2sf3"
317 [(set (match_operand:V2SF 0 "register_operand" "=y")
321 (match_operand:V2SF 1 "register_operand" "0")
322 (parallel [(const_int 0)]))
323 (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
326 (match_operand:V2SF 2 "nonimmediate_operand" "ym")
327 (parallel [(const_int 0)]))
328 (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
330 "pfacc\\t{%2, %0|%0, %2}"
331 [(set_attr "type" "mmxadd")
332 (set_attr "mode" "V2SF")])
334 (define_insn "mmx_hsubv2sf3"
335 [(set (match_operand:V2SF 0 "register_operand" "=y")
339 (match_operand:V2SF 1 "register_operand" "0")
340 (parallel [(const_int 0)]))
341 (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
344 (match_operand:V2SF 2 "nonimmediate_operand" "ym")
345 (parallel [(const_int 0)]))
346 (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
348 "pfnacc\\t{%2, %0|%0, %2}"
349 [(set_attr "type" "mmxadd")
350 (set_attr "mode" "V2SF")])
352 (define_insn "mmx_addsubv2sf3"
353 [(set (match_operand:V2SF 0 "register_operand" "=y")
356 (match_operand:V2SF 1 "register_operand" "0")
357 (match_operand:V2SF 2 "nonimmediate_operand" "ym"))
358 (minus:V2SF (match_dup 1) (match_dup 2))
361 "pfpnacc\\t{%2, %0|%0, %2}"
362 [(set_attr "type" "mmxadd")
363 (set_attr "mode" "V2SF")])
365 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
367 ;; Parallel single-precision floating point comparisons
369 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
371 (define_insn "mmx_gtv2sf3"
372 [(set (match_operand:V2SI 0 "register_operand" "=y")
373 (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
374 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
376 "pfcmpgt\\t{%2, %0|%0, %2}"
377 [(set_attr "type" "mmxcmp")
378 (set_attr "mode" "V2SF")])
380 (define_insn "mmx_gev2sf3"
381 [(set (match_operand:V2SI 0 "register_operand" "=y")
382 (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
383 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
385 "pfcmpge\\t{%2, %0|%0, %2}"
386 [(set_attr "type" "mmxcmp")
387 (set_attr "mode" "V2SF")])
389 (define_insn "mmx_eqv2sf3"
390 [(set (match_operand:V2SI 0 "register_operand" "=y")
391 (eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "%0")
392 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
393 "TARGET_3DNOW && ix86_binary_operator_ok (EQ, V2SFmode, operands)"
394 "pfcmpeq\\t{%2, %0|%0, %2}"
395 [(set_attr "type" "mmxcmp")
396 (set_attr "mode" "V2SF")])
398 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
400 ;; Parallel single-precision floating point conversion operations
402 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
404 (define_insn "mmx_pf2id"
405 [(set (match_operand:V2SI 0 "register_operand" "=y")
406 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
408 "pf2id\\t{%1, %0|%0, %1}"
409 [(set_attr "type" "mmxcvt")
410 (set_attr "mode" "V2SF")])
412 (define_insn "mmx_pf2iw"
413 [(set (match_operand:V2SI 0 "register_operand" "=y")
417 (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
419 "pf2iw\\t{%1, %0|%0, %1}"
420 [(set_attr "type" "mmxcvt")
421 (set_attr "mode" "V2SF")])
423 (define_insn "mmx_pi2fw"
424 [(set (match_operand:V2SF 0 "register_operand" "=y")
428 (match_operand:V2SI 1 "nonimmediate_operand" "ym")))))]
430 "pi2fw\\t{%1, %0|%0, %1}"
431 [(set_attr "type" "mmxcvt")
432 (set_attr "mode" "V2SF")])
434 (define_insn "mmx_floatv2si2"
435 [(set (match_operand:V2SF 0 "register_operand" "=y")
436 (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
438 "pi2fd\\t{%1, %0|%0, %1}"
439 [(set_attr "type" "mmxcvt")
440 (set_attr "mode" "V2SF")])
442 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
444 ;; Parallel single-precision floating point element swizzling
446 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
448 (define_insn "mmx_pswapdv2sf2"
449 [(set (match_operand:V2SF 0 "register_operand" "=y")
450 (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
451 (parallel [(const_int 1) (const_int 0)])))]
453 "pswapd\\t{%1, %0|%0, %1}"
454 [(set_attr "type" "mmxcvt")
455 (set_attr "mode" "V2SF")])
457 (define_insn "*vec_dupv2sf"
458 [(set (match_operand:V2SF 0 "register_operand" "=y")
460 (match_operand:SF 1 "register_operand" "0")))]
463 [(set_attr "type" "mmxcvt")
464 (set_attr "mode" "DI")])
466 (define_insn "*mmx_concatv2sf"
467 [(set (match_operand:V2SF 0 "register_operand" "=y,y")
469 (match_operand:SF 1 "nonimmediate_operand" " 0,rm")
470 (match_operand:SF 2 "vector_move_operand" "ym,C")))]
471 "TARGET_MMX && !TARGET_SSE"
473 punpckldq\t{%2, %0|%0, %2}
474 movd\t{%1, %0|%0, %1}"
475 [(set_attr "type" "mmxcvt,mmxmov")
476 (set_attr "mode" "DI")])
478 (define_expand "vec_setv2sf"
479 [(match_operand:V2SF 0 "register_operand" "")
480 (match_operand:SF 1 "register_operand" "")
481 (match_operand 2 "const_int_operand" "")]
484 ix86_expand_vector_set (false, operands[0], operands[1],
485 INTVAL (operands[2]));
489 (define_insn_and_split "*vec_extractv2sf_0"
490 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,y,m,m,frxy")
492 (match_operand:V2SF 1 "nonimmediate_operand" " x,y,x,y,m")
493 (parallel [(const_int 0)])))]
494 "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
496 "&& reload_completed"
499 rtx op1 = operands[1];
501 op1 = gen_rtx_REG (SFmode, REGNO (op1));
503 op1 = gen_lowpart (SFmode, op1);
504 emit_move_insn (operands[0], op1);
508 (define_insn "*vec_extractv2sf_1"
509 [(set (match_operand:SF 0 "nonimmediate_operand" "=y,x,frxy")
511 (match_operand:V2SF 1 "nonimmediate_operand" " 0,0,o")
512 (parallel [(const_int 1)])))]
513 "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
518 [(set_attr "type" "mmxcvt,sselog1,*")
519 (set_attr "mode" "DI,V4SF,SI")])
522 [(set (match_operand:SF 0 "register_operand" "")
524 (match_operand:V2SF 1 "memory_operand" "")
525 (parallel [(const_int 1)])))]
526 "TARGET_MMX && reload_completed"
529 operands[1] = adjust_address (operands[1], SFmode, 4);
530 emit_move_insn (operands[0], operands[1]);
534 (define_expand "vec_extractv2sf"
535 [(match_operand:SF 0 "register_operand" "")
536 (match_operand:V2SF 1 "register_operand" "")
537 (match_operand 2 "const_int_operand" "")]
540 ix86_expand_vector_extract (false, operands[0], operands[1],
541 INTVAL (operands[2]));
545 (define_expand "vec_initv2sf"
546 [(match_operand:V2SF 0 "register_operand" "")
547 (match_operand 1 "" "")]
550 ix86_expand_vector_init (false, operands[0], operands[1]);
554 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
556 ;; Parallel integral arithmetic
558 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
560 (define_insn "mmx_add<mode>3"
561 [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
563 (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
564 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
565 "TARGET_MMX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
566 "padd<mmxvecsize>\t{%2, %0|%0, %2}"
567 [(set_attr "type" "mmxadd")
568 (set_attr "mode" "DI")])
570 (define_insn "mmx_adddi3"
571 [(set (match_operand:DI 0 "register_operand" "=y")
573 [(plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
574 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
576 "TARGET_SSE2 && ix86_binary_operator_ok (PLUS, DImode, operands)"
577 "paddq\t{%2, %0|%0, %2}"
578 [(set_attr "type" "mmxadd")
579 (set_attr "mode" "DI")])
581 (define_insn "mmx_ssadd<mode>3"
582 [(set (match_operand:MMXMODE12 0 "register_operand" "=y")
584 (match_operand:MMXMODE12 1 "nonimmediate_operand" "%0")
585 (match_operand:MMXMODE12 2 "nonimmediate_operand" "ym")))]
587 "padds<mmxvecsize>\t{%2, %0|%0, %2}"
588 [(set_attr "type" "mmxadd")
589 (set_attr "mode" "DI")])
591 (define_insn "mmx_usadd<mode>3"
592 [(set (match_operand:MMXMODE12 0 "register_operand" "=y")
594 (match_operand:MMXMODE12 1 "nonimmediate_operand" "%0")
595 (match_operand:MMXMODE12 2 "nonimmediate_operand" "ym")))]
597 "paddus<mmxvecsize>\t{%2, %0|%0, %2}"
598 [(set_attr "type" "mmxadd")
599 (set_attr "mode" "DI")])
601 (define_insn "mmx_sub<mode>3"
602 [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
604 (match_operand:MMXMODEI 1 "register_operand" "0")
605 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
607 "psub<mmxvecsize>\t{%2, %0|%0, %2}"
608 [(set_attr "type" "mmxadd")
609 (set_attr "mode" "DI")])
611 (define_insn "mmx_subdi3"
612 [(set (match_operand:DI 0 "register_operand" "=y")
614 [(minus:DI (match_operand:DI 1 "register_operand" "0")
615 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
618 "psubq\t{%2, %0|%0, %2}"
619 [(set_attr "type" "mmxadd")
620 (set_attr "mode" "DI")])
622 (define_insn "mmx_sssub<mode>3"
623 [(set (match_operand:MMXMODE12 0 "register_operand" "=y")
625 (match_operand:MMXMODE12 1 "register_operand" "0")
626 (match_operand:MMXMODE12 2 "nonimmediate_operand" "ym")))]
628 "psubs<mmxvecsize>\t{%2, %0|%0, %2}"
629 [(set_attr "type" "mmxadd")
630 (set_attr "mode" "DI")])
632 (define_insn "mmx_ussub<mode>3"
633 [(set (match_operand:MMXMODE12 0 "register_operand" "=y")
635 (match_operand:MMXMODE12 1 "register_operand" "0")
636 (match_operand:MMXMODE12 2 "nonimmediate_operand" "ym")))]
638 "psubus<mmxvecsize>\t{%2, %0|%0, %2}"
639 [(set_attr "type" "mmxadd")
640 (set_attr "mode" "DI")])
642 (define_insn "mmx_mulv4hi3"
643 [(set (match_operand:V4HI 0 "register_operand" "=y")
644 (mult:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "%0")
645 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
646 "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
647 "pmullw\t{%2, %0|%0, %2}"
648 [(set_attr "type" "mmxmul")
649 (set_attr "mode" "DI")])
651 (define_insn "mmx_smulv4hi3_highpart"
652 [(set (match_operand:V4HI 0 "register_operand" "=y")
655 (mult:V4SI (sign_extend:V4SI
656 (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
658 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
660 "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
661 "pmulhw\t{%2, %0|%0, %2}"
662 [(set_attr "type" "mmxmul")
663 (set_attr "mode" "DI")])
665 (define_insn "mmx_umulv4hi3_highpart"
666 [(set (match_operand:V4HI 0 "register_operand" "=y")
669 (mult:V4SI (zero_extend:V4SI
670 (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
672 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
674 "(TARGET_SSE || TARGET_3DNOW_A)
675 && ix86_binary_operator_ok (MULT, V4HImode, operands)"
676 "pmulhuw\t{%2, %0|%0, %2}"
677 [(set_attr "type" "mmxmul")
678 (set_attr "mode" "DI")])
680 (define_insn "mmx_pmaddwd"
681 [(set (match_operand:V2SI 0 "register_operand" "=y")
686 (match_operand:V4HI 1 "nonimmediate_operand" "%0")
687 (parallel [(const_int 0) (const_int 2)])))
690 (match_operand:V4HI 2 "nonimmediate_operand" "ym")
691 (parallel [(const_int 0) (const_int 2)]))))
694 (vec_select:V2HI (match_dup 1)
695 (parallel [(const_int 1) (const_int 3)])))
697 (vec_select:V2HI (match_dup 2)
698 (parallel [(const_int 1) (const_int 3)]))))))]
699 "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
700 "pmaddwd\t{%2, %0|%0, %2}"
701 [(set_attr "type" "mmxmul")
702 (set_attr "mode" "DI")])
704 (define_insn "mmx_pmulhrwv4hi3"
705 [(set (match_operand:V4HI 0 "register_operand" "=y")
711 (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
713 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
714 (const_vector:V4SI [(const_int 32768) (const_int 32768)
715 (const_int 32768) (const_int 32768)]))
717 "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V4HImode, operands)"
718 "pmulhrw\\t{%2, %0|%0, %2}"
719 [(set_attr "type" "mmxmul")
720 (set_attr "mode" "DI")])
722 (define_insn "sse2_umulsidi3"
723 [(set (match_operand:DI 0 "register_operand" "=y")
727 (match_operand:V2SI 1 "nonimmediate_operand" "%0")
728 (parallel [(const_int 0)])))
731 (match_operand:V2SI 2 "nonimmediate_operand" "ym")
732 (parallel [(const_int 0)])))))]
733 "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V2SImode, operands)"
734 "pmuludq\t{%2, %0|%0, %2}"
735 [(set_attr "type" "mmxmul")
736 (set_attr "mode" "DI")])
738 (define_insn "mmx_umaxv8qi3"
739 [(set (match_operand:V8QI 0 "register_operand" "=y")
740 (umax:V8QI (match_operand:V8QI 1 "nonimmediate_operand" "%0")
741 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
742 "(TARGET_SSE || TARGET_3DNOW_A)
743 && ix86_binary_operator_ok (UMAX, V8QImode, operands)"
744 "pmaxub\t{%2, %0|%0, %2}"
745 [(set_attr "type" "mmxadd")
746 (set_attr "mode" "DI")])
748 (define_insn "mmx_smaxv4hi3"
749 [(set (match_operand:V4HI 0 "register_operand" "=y")
750 (smax:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "%0")
751 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
752 "(TARGET_SSE || TARGET_3DNOW_A)
753 && ix86_binary_operator_ok (SMAX, V4HImode, operands)"
754 "pmaxsw\t{%2, %0|%0, %2}"
755 [(set_attr "type" "mmxadd")
756 (set_attr "mode" "DI")])
758 (define_insn "mmx_uminv8qi3"
759 [(set (match_operand:V8QI 0 "register_operand" "=y")
760 (umin:V8QI (match_operand:V8QI 1 "nonimmediate_operand" "%0")
761 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
762 "(TARGET_SSE || TARGET_3DNOW_A)
763 && ix86_binary_operator_ok (UMIN, V8QImode, operands)"
764 "pminub\t{%2, %0|%0, %2}"
765 [(set_attr "type" "mmxadd")
766 (set_attr "mode" "DI")])
768 (define_insn "mmx_sminv4hi3"
769 [(set (match_operand:V4HI 0 "register_operand" "=y")
770 (smin:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "%0")
771 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
772 "(TARGET_SSE || TARGET_3DNOW_A)
773 && ix86_binary_operator_ok (SMIN, V4HImode, operands)"
774 "pminsw\t{%2, %0|%0, %2}"
775 [(set_attr "type" "mmxadd")
776 (set_attr "mode" "DI")])
778 (define_insn "mmx_ashr<mode>3"
779 [(set (match_operand:MMXMODE24 0 "register_operand" "=y")
781 (match_operand:MMXMODE24 1 "register_operand" "0")
782 (match_operand:DI 2 "nonmemory_operand" "yi")))]
784 "psra<mmxvecsize>\t{%2, %0|%0, %2}"
785 [(set_attr "type" "mmxshft")
786 (set_attr "mode" "DI")])
788 (define_insn "mmx_lshr<mode>3"
789 [(set (match_operand:MMXMODE24 0 "register_operand" "=y")
791 (match_operand:MMXMODE24 1 "register_operand" "0")
792 (match_operand:DI 2 "nonmemory_operand" "yi")))]
794 "psrl<mmxvecsize>\t{%2, %0|%0, %2}"
795 [(set_attr "type" "mmxshft")
796 (set_attr "mode" "DI")])
798 (define_insn "mmx_lshrdi3"
799 [(set (match_operand:DI 0 "register_operand" "=y")
801 [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
802 (match_operand:DI 2 "nonmemory_operand" "yi"))]
805 "psrlq\t{%2, %0|%0, %2}"
806 [(set_attr "type" "mmxshft")
807 (set_attr "mode" "DI")])
809 (define_insn "mmx_ashl<mode>3"
810 [(set (match_operand:MMXMODE24 0 "register_operand" "=y")
812 (match_operand:MMXMODE24 1 "register_operand" "0")
813 (match_operand:DI 2 "nonmemory_operand" "yi")))]
815 "psll<mmxvecsize>\t{%2, %0|%0, %2}"
816 [(set_attr "type" "mmxshft")
817 (set_attr "mode" "DI")])
819 (define_insn "mmx_ashldi3"
820 [(set (match_operand:DI 0 "register_operand" "=y")
822 [(ashift:DI (match_operand:DI 1 "register_operand" "0")
823 (match_operand:DI 2 "nonmemory_operand" "yi"))]
826 "psllq\t{%2, %0|%0, %2}"
827 [(set_attr "type" "mmxshft")
828 (set_attr "mode" "DI")])
830 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
832 ;; Parallel integral comparisons
834 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
836 (define_insn "mmx_eq<mode>3"
837 [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
839 (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
840 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
841 "TARGET_MMX && ix86_binary_operator_ok (EQ, <MODE>mode, operands)"
842 "pcmpeq<mmxvecsize>\t{%2, %0|%0, %2}"
843 [(set_attr "type" "mmxcmp")
844 (set_attr "mode" "DI")])
846 (define_insn "mmx_gt<mode>3"
847 [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
849 (match_operand:MMXMODEI 1 "register_operand" "0")
850 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
852 "pcmpgt<mmxvecsize>\t{%2, %0|%0, %2}"
853 [(set_attr "type" "mmxcmp")
854 (set_attr "mode" "DI")])
856 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
858 ;; Parallel integral logical operations
860 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
862 (define_insn "mmx_and<mode>3"
863 [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
865 (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
866 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
867 "TARGET_MMX && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
868 "pand\t{%2, %0|%0, %2}"
869 [(set_attr "type" "mmxadd")
870 (set_attr "mode" "DI")])
872 (define_insn "mmx_nand<mode>3"
873 [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
875 (not:MMXMODEI (match_operand:MMXMODEI 1 "register_operand" "0"))
876 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
878 "pandn\t{%2, %0|%0, %2}"
879 [(set_attr "type" "mmxadd")
880 (set_attr "mode" "DI")])
882 (define_insn "mmx_ior<mode>3"
883 [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
885 (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
886 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
887 "TARGET_MMX && ix86_binary_operator_ok (IOR, <MODE>mode, operands)"
888 "por\t{%2, %0|%0, %2}"
889 [(set_attr "type" "mmxadd")
890 (set_attr "mode" "DI")])
892 (define_insn "mmx_xor<mode>3"
893 [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
895 (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
896 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
897 "TARGET_MMX && ix86_binary_operator_ok (XOR, <MODE>mode, operands)"
898 "pxor\t{%2, %0|%0, %2}"
899 [(set_attr "type" "mmxadd")
900 (set_attr "mode" "DI")
901 (set_attr "memory" "none")])
903 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
905 ;; Parallel integral element swizzling
907 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
909 (define_insn "mmx_packsswb"
910 [(set (match_operand:V8QI 0 "register_operand" "=y")
913 (match_operand:V4HI 1 "register_operand" "0"))
915 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))))]
917 "packsswb\t{%2, %0|%0, %2}"
918 [(set_attr "type" "mmxshft")
919 (set_attr "mode" "DI")])
921 (define_insn "mmx_packssdw"
922 [(set (match_operand:V4HI 0 "register_operand" "=y")
925 (match_operand:V2SI 1 "register_operand" "0"))
927 (match_operand:V2SI 2 "nonimmediate_operand" "ym"))))]
929 "packssdw\t{%2, %0|%0, %2}"
930 [(set_attr "type" "mmxshft")
931 (set_attr "mode" "DI")])
933 (define_insn "mmx_packuswb"
934 [(set (match_operand:V8QI 0 "register_operand" "=y")
937 (match_operand:V4HI 1 "register_operand" "0"))
939 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))))]
941 "packuswb\t{%2, %0|%0, %2}"
942 [(set_attr "type" "mmxshft")
943 (set_attr "mode" "DI")])
945 (define_insn "mmx_punpckhbw"
946 [(set (match_operand:V8QI 0 "register_operand" "=y")
949 (match_operand:V8QI 1 "register_operand" "0")
950 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
951 (parallel [(const_int 4) (const_int 12)
952 (const_int 5) (const_int 13)
953 (const_int 6) (const_int 14)
954 (const_int 7) (const_int 15)])))]
956 "punpckhbw\t{%2, %0|%0, %2}"
957 [(set_attr "type" "mmxcvt")
958 (set_attr "mode" "DI")])
960 (define_insn "mmx_punpcklbw"
961 [(set (match_operand:V8QI 0 "register_operand" "=y")
964 (match_operand:V8QI 1 "register_operand" "0")
965 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
966 (parallel [(const_int 0) (const_int 8)
967 (const_int 1) (const_int 9)
968 (const_int 2) (const_int 10)
969 (const_int 3) (const_int 11)])))]
971 "punpcklbw\t{%2, %0|%0, %2}"
972 [(set_attr "type" "mmxcvt")
973 (set_attr "mode" "DI")])
975 (define_insn "mmx_punpckhwd"
976 [(set (match_operand:V4HI 0 "register_operand" "=y")
979 (match_operand:V4HI 1 "register_operand" "0")
980 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
981 (parallel [(const_int 2) (const_int 6)
982 (const_int 3) (const_int 7)])))]
984 "punpckhwd\t{%2, %0|%0, %2}"
985 [(set_attr "type" "mmxcvt")
986 (set_attr "mode" "DI")])
988 (define_insn "mmx_punpcklwd"
989 [(set (match_operand:V4HI 0 "register_operand" "=y")
992 (match_operand:V4HI 1 "register_operand" "0")
993 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
994 (parallel [(const_int 0) (const_int 4)
995 (const_int 1) (const_int 5)])))]
997 "punpcklwd\t{%2, %0|%0, %2}"
998 [(set_attr "type" "mmxcvt")
999 (set_attr "mode" "DI")])
1001 (define_insn "mmx_punpckhdq"
1002 [(set (match_operand:V2SI 0 "register_operand" "=y")
1005 (match_operand:V2SI 1 "register_operand" "0")
1006 (match_operand:V2SI 2 "nonimmediate_operand" "ym"))
1007 (parallel [(const_int 1)
1010 "punpckhdq\t{%2, %0|%0, %2}"
1011 [(set_attr "type" "mmxcvt")
1012 (set_attr "mode" "DI")])
1014 (define_insn "mmx_punpckldq"
1015 [(set (match_operand:V2SI 0 "register_operand" "=y")
1018 (match_operand:V2SI 1 "register_operand" "0")
1019 (match_operand:V2SI 2 "nonimmediate_operand" "ym"))
1020 (parallel [(const_int 0)
1023 "punpckldq\t{%2, %0|%0, %2}"
1024 [(set_attr "type" "mmxcvt")
1025 (set_attr "mode" "DI")])
1027 (define_expand "mmx_pinsrw"
1028 [(set (match_operand:V4HI 0 "register_operand" "")
1031 (match_operand:SI 2 "nonimmediate_operand" ""))
1032 (match_operand:V4HI 1 "register_operand" "")
1033 (match_operand:SI 3 "const_0_to_3_operand" "")))]
1034 "TARGET_SSE || TARGET_3DNOW_A"
1036 operands[2] = gen_lowpart (HImode, operands[2]);
1037 operands[3] = GEN_INT (1 << INTVAL (operands[3]));
1040 (define_insn "*mmx_pinsrw"
1041 [(set (match_operand:V4HI 0 "register_operand" "=y")
1044 (match_operand:HI 2 "nonimmediate_operand" "rm"))
1045 (match_operand:V4HI 1 "register_operand" "0")
1046 (match_operand:SI 3 "const_pow2_1_to_8_operand" "n")))]
1047 "TARGET_SSE || TARGET_3DNOW_A"
1049 operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
1050 return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}";
1052 [(set_attr "type" "mmxcvt")
1053 (set_attr "mode" "DI")])
1055 (define_insn "mmx_pextrw"
1056 [(set (match_operand:SI 0 "register_operand" "=r")
1059 (match_operand:V4HI 1 "register_operand" "y")
1060 (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n")]))))]
1061 "TARGET_SSE || TARGET_3DNOW_A"
1062 "pextrw\t{%2, %1, %0|%0, %1, %2}"
1063 [(set_attr "type" "mmxcvt")
1064 (set_attr "mode" "DI")])
1066 (define_expand "mmx_pshufw"
1067 [(match_operand:V4HI 0 "register_operand" "")
1068 (match_operand:V4HI 1 "nonimmediate_operand" "")
1069 (match_operand:SI 2 "const_int_operand" "")]
1070 "TARGET_SSE || TARGET_3DNOW_A"
1072 int mask = INTVAL (operands[2]);
1073 emit_insn (gen_mmx_pshufw_1 (operands[0], operands[1],
1074 GEN_INT ((mask >> 0) & 3),
1075 GEN_INT ((mask >> 2) & 3),
1076 GEN_INT ((mask >> 4) & 3),
1077 GEN_INT ((mask >> 6) & 3)));
1081 (define_insn "mmx_pshufw_1"
1082 [(set (match_operand:V4HI 0 "register_operand" "=y")
1084 (match_operand:V4HI 1 "nonimmediate_operand" "ym")
1085 (parallel [(match_operand 2 "const_0_to_3_operand" "")
1086 (match_operand 3 "const_0_to_3_operand" "")
1087 (match_operand 4 "const_0_to_3_operand" "")
1088 (match_operand 5 "const_0_to_3_operand" "")])))]
1089 "TARGET_SSE || TARGET_3DNOW_A"
1092 mask |= INTVAL (operands[2]) << 0;
1093 mask |= INTVAL (operands[3]) << 2;
1094 mask |= INTVAL (operands[4]) << 4;
1095 mask |= INTVAL (operands[5]) << 6;
1096 operands[2] = GEN_INT (mask);
1098 return "pshufw\t{%2, %1, %0|%0, %1, %2}";
1100 [(set_attr "type" "mmxcvt")
1101 (set_attr "mode" "DI")])
1103 (define_insn "mmx_pswapdv2si2"
1104 [(set (match_operand:V2SI 0 "register_operand" "=y")
1106 (match_operand:V2SI 1 "nonimmediate_operand" "ym")
1107 (parallel [(const_int 1) (const_int 0)])))]
1109 "pswapd\\t{%1, %0|%0, %1}"
1110 [(set_attr "type" "mmxcvt")
1111 (set_attr "mode" "DI")])
1113 (define_insn "*vec_dupv4hi"
1114 [(set (match_operand:V4HI 0 "register_operand" "=y")
1117 (match_operand:SI 1 "register_operand" "0"))))]
1118 "TARGET_SSE || TARGET_3DNOW_A"
1119 "pshufw\t{$0, %0, %0|%0, %0, 0}"
1120 [(set_attr "type" "mmxcvt")
1121 (set_attr "mode" "DI")])
1123 (define_insn "*vec_dupv2si"
1124 [(set (match_operand:V2SI 0 "register_operand" "=y")
1126 (match_operand:SI 1 "register_operand" "0")))]
1129 [(set_attr "type" "mmxcvt")
1130 (set_attr "mode" "DI")])
1132 (define_insn "*mmx_concatv2si"
1133 [(set (match_operand:V2SI 0 "register_operand" "=y,y")
1135 (match_operand:SI 1 "nonimmediate_operand" " 0,rm")
1136 (match_operand:SI 2 "vector_move_operand" "ym,C")))]
1137 "TARGET_MMX && !TARGET_SSE"
1139 punpckldq\t{%2, %0|%0, %2}
1140 movd\t{%1, %0|%0, %1}"
1141 [(set_attr "type" "mmxcvt,mmxmov")
1142 (set_attr "mode" "DI")])
1144 (define_expand "vec_setv2si"
1145 [(match_operand:V2SI 0 "register_operand" "")
1146 (match_operand:SI 1 "register_operand" "")
1147 (match_operand 2 "const_int_operand" "")]
1150 ix86_expand_vector_set (false, operands[0], operands[1],
1151 INTVAL (operands[2]));
1155 (define_insn_and_split "*vec_extractv2si_0"
1156 [(set (match_operand:SI 0 "nonimmediate_operand" "=x,y,m,m,frxy")
1158 (match_operand:V2SI 1 "nonimmediate_operand" " x,y,x,y,m")
1159 (parallel [(const_int 0)])))]
1160 "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1162 "&& reload_completed"
1165 rtx op1 = operands[1];
1167 op1 = gen_rtx_REG (SImode, REGNO (op1));
1169 op1 = gen_lowpart (SImode, op1);
1170 emit_move_insn (operands[0], op1);
1174 (define_insn "*vec_extractv2si_1"
1175 [(set (match_operand:SI 0 "nonimmediate_operand" "=y,Y,Y,x,frxy")
1177 (match_operand:V2SI 1 "nonimmediate_operand" " 0,0,Y,0,o")
1178 (parallel [(const_int 1)])))]
1179 "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1183 pshufd\t{$85, %1, %0|%0, %1, 85}
1186 [(set_attr "type" "mmxcvt,sselog1,sselog1,sselog1,*")
1187 (set_attr "mode" "DI,TI,TI,V4SF,SI")])
1190 [(set (match_operand:SI 0 "register_operand" "")
1192 (match_operand:V2SI 1 "memory_operand" "")
1193 (parallel [(const_int 1)])))]
1194 "TARGET_MMX && reload_completed"
1197 operands[1] = adjust_address (operands[1], SImode, 4);
1198 emit_move_insn (operands[0], operands[1]);
1202 (define_expand "vec_extractv2si"
1203 [(match_operand:SI 0 "register_operand" "")
1204 (match_operand:V2SI 1 "register_operand" "")
1205 (match_operand 2 "const_int_operand" "")]
1208 ix86_expand_vector_extract (false, operands[0], operands[1],
1209 INTVAL (operands[2]));
1213 (define_expand "vec_initv2si"
1214 [(match_operand:V2SI 0 "register_operand" "")
1215 (match_operand 1 "" "")]
1218 ix86_expand_vector_init (false, operands[0], operands[1]);
1222 (define_expand "vec_setv4hi"
1223 [(match_operand:V4HI 0 "register_operand" "")
1224 (match_operand:HI 1 "register_operand" "")
1225 (match_operand 2 "const_int_operand" "")]
1228 ix86_expand_vector_set (false, operands[0], operands[1],
1229 INTVAL (operands[2]));
1233 (define_expand "vec_extractv4hi"
1234 [(match_operand:HI 0 "register_operand" "")
1235 (match_operand:V4HI 1 "register_operand" "")
1236 (match_operand 2 "const_int_operand" "")]
1239 ix86_expand_vector_extract (false, operands[0], operands[1],
1240 INTVAL (operands[2]));
1244 (define_expand "vec_initv4hi"
1245 [(match_operand:V4HI 0 "register_operand" "")
1246 (match_operand 1 "" "")]
1249 ix86_expand_vector_init (false, operands[0], operands[1]);
1253 (define_expand "vec_setv8qi"
1254 [(match_operand:V8QI 0 "register_operand" "")
1255 (match_operand:QI 1 "register_operand" "")
1256 (match_operand 2 "const_int_operand" "")]
1259 ix86_expand_vector_set (false, operands[0], operands[1],
1260 INTVAL (operands[2]));
1264 (define_expand "vec_extractv8qi"
1265 [(match_operand:QI 0 "register_operand" "")
1266 (match_operand:V8QI 1 "register_operand" "")
1267 (match_operand 2 "const_int_operand" "")]
1270 ix86_expand_vector_extract (false, operands[0], operands[1],
1271 INTVAL (operands[2]));
1275 (define_expand "vec_initv8qi"
1276 [(match_operand:V8QI 0 "register_operand" "")
1277 (match_operand 1 "" "")]
1280 ix86_expand_vector_init (false, operands[0], operands[1]);
1284 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1288 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1290 (define_insn "mmx_uavgv8qi3"
1291 [(set (match_operand:V8QI 0 "register_operand" "=y")
1297 (match_operand:V8QI 1 "nonimmediate_operand" "%0"))
1299 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))
1300 (const_vector:V8HI [(const_int 1) (const_int 1)
1301 (const_int 1) (const_int 1)
1302 (const_int 1) (const_int 1)
1303 (const_int 1) (const_int 1)]))
1305 "(TARGET_SSE || TARGET_3DNOW)
1306 && ix86_binary_operator_ok (PLUS, V8QImode, operands)"
1308 /* These two instructions have the same operation, but their encoding
1309 is different. Prefer the one that is de facto standard. */
1310 if (TARGET_SSE || TARGET_3DNOW_A)
1311 return "pavgb\t{%2, %0|%0, %2}";
1313 return "pavgusb\\t{%2, %0|%0, %2}";
1315 [(set_attr "type" "mmxshft")
1316 (set_attr "mode" "DI")])
1318 (define_insn "mmx_uavgv4hi3"
1319 [(set (match_operand:V4HI 0 "register_operand" "=y")
1325 (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
1327 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
1328 (const_vector:V4SI [(const_int 1) (const_int 1)
1329 (const_int 1) (const_int 1)]))
1331 "(TARGET_SSE || TARGET_3DNOW_A)
1332 && ix86_binary_operator_ok (PLUS, V4HImode, operands)"
1333 "pavgw\t{%2, %0|%0, %2}"
1334 [(set_attr "type" "mmxshft")
1335 (set_attr "mode" "DI")])
1337 (define_insn "mmx_psadbw"
1338 [(set (match_operand:DI 0 "register_operand" "=y")
1339 (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
1340 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
1342 "TARGET_SSE || TARGET_3DNOW_A"
1343 "psadbw\t{%2, %0|%0, %2}"
1344 [(set_attr "type" "mmxshft")
1345 (set_attr "mode" "DI")])
1347 (define_insn "mmx_pmovmskb"
1348 [(set (match_operand:SI 0 "register_operand" "=r")
1349 (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
1351 "TARGET_SSE || TARGET_3DNOW_A"
1352 "pmovmskb\t{%1, %0|%0, %1}"
1353 [(set_attr "type" "mmxcvt")
1354 (set_attr "mode" "DI")])
1356 (define_expand "mmx_maskmovq"
1357 [(set (match_operand:V8QI 0 "memory_operand" "")
1358 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
1359 (match_operand:V8QI 2 "register_operand" "y")
1362 "TARGET_SSE || TARGET_3DNOW_A"
1365 (define_insn "*mmx_maskmovq"
1366 [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
1367 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
1368 (match_operand:V8QI 2 "register_operand" "y")
1369 (mem:V8QI (match_dup 0))]
1371 "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
1372 ;; @@@ check ordering of operands in intel/nonintel syntax
1373 "maskmovq\t{%2, %1|%1, %2}"
1374 [(set_attr "type" "mmxcvt")
1375 (set_attr "mode" "DI")])
1377 (define_insn "*mmx_maskmovq_rex"
1378 [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
1379 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
1380 (match_operand:V8QI 2 "register_operand" "y")
1381 (mem:V8QI (match_dup 0))]
1383 "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
1384 ;; @@@ check ordering of operands in intel/nonintel syntax
1385 "maskmovq\t{%2, %1|%1, %2}"
1386 [(set_attr "type" "mmxcvt")
1387 (set_attr "mode" "DI")])
1389 (define_insn "mmx_emms"
1390 [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
1391 (clobber (reg:XF 8))
1392 (clobber (reg:XF 9))
1393 (clobber (reg:XF 10))
1394 (clobber (reg:XF 11))
1395 (clobber (reg:XF 12))
1396 (clobber (reg:XF 13))
1397 (clobber (reg:XF 14))
1398 (clobber (reg:XF 15))
1399 (clobber (reg:DI 29))
1400 (clobber (reg:DI 30))
1401 (clobber (reg:DI 31))
1402 (clobber (reg:DI 32))
1403 (clobber (reg:DI 33))
1404 (clobber (reg:DI 34))
1405 (clobber (reg:DI 35))
1406 (clobber (reg:DI 36))]
1409 [(set_attr "type" "mmx")
1410 (set_attr "memory" "unknown")])
1412 (define_insn "mmx_femms"
1413 [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
1414 (clobber (reg:XF 8))
1415 (clobber (reg:XF 9))
1416 (clobber (reg:XF 10))
1417 (clobber (reg:XF 11))
1418 (clobber (reg:XF 12))
1419 (clobber (reg:XF 13))
1420 (clobber (reg:XF 14))
1421 (clobber (reg:XF 15))
1422 (clobber (reg:DI 29))
1423 (clobber (reg:DI 30))
1424 (clobber (reg:DI 31))
1425 (clobber (reg:DI 32))
1426 (clobber (reg:DI 33))
1427 (clobber (reg:DI 34))
1428 (clobber (reg:DI 35))
1429 (clobber (reg:DI 36))]
1432 [(set_attr "type" "mmx")
1433 (set_attr "memory" "none")])