1 ;; GCC machine description for MMX and 3dNOW! instructions
2 ;; Copyright (C) 2005, 2007
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 ;; 8 byte integral modes handled by MMX (and by extension, SSE)
34 (define_mode_iterator MMXMODEI [V8QI V4HI V2SI])
36 ;; All 8-byte vector modes handled by MMX
37 (define_mode_iterator MMXMODE [V8QI V4HI V2SI V2SF])
40 (define_mode_iterator MMXMODE12 [V8QI V4HI])
41 (define_mode_iterator MMXMODE24 [V4HI V2SI])
43 ;; Mapping from integer vector mode to mnemonic suffix
44 (define_mode_attr mmxvecsize [(V8QI "b") (V4HI "w") (V2SI "d") (DI "q")])
46 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
50 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
52 ;; All of these patterns are enabled for MMX as well as 3dNOW.
53 ;; This is essential for maintaining stable calling conventions.
55 (define_expand "mov<mode>"
56 [(set (match_operand:MMXMODEI 0 "nonimmediate_operand" "")
57 (match_operand:MMXMODEI 1 "nonimmediate_operand" ""))]
60 ix86_expand_vector_move (<MODE>mode, operands);
64 (define_insn "*mov<mode>_internal_rex64"
65 [(set (match_operand:MMXMODEI 0 "nonimmediate_operand"
66 "=rm,r,*y,*y ,m ,*y,Yt,x,x ,m,r,x")
67 (match_operand:MMXMODEI 1 "vector_move_operand"
68 "Cr ,m,C ,*ym,*y,Yt,*y,C,xm,x,x,r"))]
69 "TARGET_64BIT && TARGET_MMX
70 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
77 movdq2q\t{%1, %0|%0, %1}
78 movq2dq\t{%1, %0|%0, %1}
83 movd\t{%1, %0|%0, %1}"
84 [(set_attr "type" "imov,imov,mmx,mmxmov,mmxmov,ssecvt,ssecvt,sselog1,ssemov,ssemov,ssemov,ssemov")
85 (set_attr "unit" "*,*,*,*,*,mmx,mmx,*,*,*,*,*")
86 (set_attr "mode" "DI")])
88 (define_insn "*mov<mode>_internal"
89 [(set (match_operand:MMXMODEI 0 "nonimmediate_operand"
90 "=*y,*y ,m ,*y ,*Yt,*Yt,*Yt ,m ,*x,*x,*x,m ,?r ,?m")
91 (match_operand:MMXMODEI 1 "vector_move_operand"
92 "C ,*ym,*y,*Yt,*y ,C ,*Ytm,*Yt,C ,*x,m ,*x,irm,r"))]
94 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
99 movdq2q\t{%1, %0|%0, %1}
100 movq2dq\t{%1, %0|%0, %1}
102 movq\t{%1, %0|%0, %1}
103 movq\t{%1, %0|%0, %1}
105 movaps\t{%1, %0|%0, %1}
106 movlps\t{%1, %0|%0, %1}
107 movlps\t{%1, %0|%0, %1}
110 [(set_attr "type" "mmx,mmxmov,mmxmov,ssecvt,ssecvt,sselog1,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov,*,*")
111 (set_attr "unit" "*,*,*,mmx,mmx,*,*,*,*,*,*,*,*,*")
112 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,DI,V4SF,V4SF,V2SF,V2SF,DI,DI")])
114 (define_expand "movv2sf"
115 [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
116 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
119 ix86_expand_vector_move (V2SFmode, operands);
123 (define_insn "*movv2sf_internal_rex64"
124 [(set (match_operand:V2SF 0 "nonimmediate_operand"
125 "=rm,r,*y ,*y ,m ,*y,Yt,x,x,x,m,r,x")
126 (match_operand:V2SF 1 "vector_move_operand"
127 "Cr ,m ,C ,*ym,*y,Yt,*y,C,x,m,x,x,r"))]
128 "TARGET_64BIT && TARGET_MMX
129 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
131 movq\t{%1, %0|%0, %1}
132 movq\t{%1, %0|%0, %1}
134 movq\t{%1, %0|%0, %1}
135 movq\t{%1, %0|%0, %1}
136 movdq2q\t{%1, %0|%0, %1}
137 movq2dq\t{%1, %0|%0, %1}
139 movaps\t{%1, %0|%0, %1}
140 movlps\t{%1, %0|%0, %1}
141 movlps\t{%1, %0|%0, %1}
142 movd\t{%1, %0|%0, %1}
143 movd\t{%1, %0|%0, %1}"
144 [(set_attr "type" "imov,imov,mmx,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,sselog1,ssemov,ssemov,ssemov,ssemov")
145 (set_attr "unit" "*,*,*,*,*,mmx,mmx,*,*,*,*,*,*")
146 (set_attr "mode" "DI,DI,DI,DI,DI,DI,DI,V4SF,V4SF,V2SF,V2SF,DI,DI")])
148 (define_insn "*movv2sf_internal"
149 [(set (match_operand:V2SF 0 "nonimmediate_operand"
150 "=*y,*y ,m,*y ,*Yt,*x,*x,*x,m ,?r ,?m")
151 (match_operand:V2SF 1 "vector_move_operand"
152 "C ,*ym,*y,*Yt,*y ,C ,*x,m ,*x,irm,r"))]
154 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
157 movq\t{%1, %0|%0, %1}
158 movq\t{%1, %0|%0, %1}
159 movdq2q\t{%1, %0|%0, %1}
160 movq2dq\t{%1, %0|%0, %1}
162 movaps\t{%1, %0|%0, %1}
163 movlps\t{%1, %0|%0, %1}
164 movlps\t{%1, %0|%0, %1}
167 [(set_attr "type" "mmx,mmxmov,mmxmov,ssecvt,ssecvt,sselog1,ssemov,ssemov,ssemov,*,*")
168 (set_attr "unit" "*,*,*,mmx,mmx,*,*,*,*,*,*")
169 (set_attr "mode" "DI,DI,DI,DI,DI,V4SF,V4SF,V2SF,V2SF,DI,DI")])
171 ;; %%% This multiword shite has got to go.
173 [(set (match_operand:MMXMODE 0 "nonimmediate_operand" "")
174 (match_operand:MMXMODE 1 "general_operand" ""))]
175 "!TARGET_64BIT && reload_completed
176 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
177 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
179 "ix86_split_long_move (operands); DONE;")
181 (define_expand "push<mode>1"
182 [(match_operand:MMXMODE 0 "register_operand" "")]
185 ix86_expand_push (<MODE>mode, operands[0]);
189 (define_expand "movmisalign<mode>"
190 [(set (match_operand:MMXMODE 0 "nonimmediate_operand" "")
191 (match_operand:MMXMODE 1 "nonimmediate_operand" ""))]
194 ix86_expand_vector_move (<MODE>mode, operands);
198 (define_insn "sse_movntdi"
199 [(set (match_operand:DI 0 "memory_operand" "=m")
200 (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
202 "TARGET_SSE || TARGET_3DNOW_A"
203 "movntq\t{%1, %0|%0, %1}"
204 [(set_attr "type" "mmxmov")
205 (set_attr "mode" "DI")])
207 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
209 ;; Parallel single-precision floating point arithmetic
211 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
213 (define_insn "mmx_addv2sf3"
214 [(set (match_operand:V2SF 0 "register_operand" "=y")
215 (plus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
216 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
217 "TARGET_3DNOW && ix86_binary_operator_ok (PLUS, V2SFmode, operands)"
218 "pfadd\\t{%2, %0|%0, %2}"
219 [(set_attr "type" "mmxadd")
220 (set_attr "mode" "V2SF")])
222 (define_insn "mmx_subv2sf3"
223 [(set (match_operand:V2SF 0 "register_operand" "=y,y")
224 (minus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "0,ym")
225 (match_operand:V2SF 2 "nonimmediate_operand" "ym,0")))]
226 "TARGET_3DNOW && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
228 pfsub\\t{%2, %0|%0, %2}
229 pfsubr\\t{%2, %0|%0, %2}"
230 [(set_attr "type" "mmxadd")
231 (set_attr "mode" "V2SF")])
233 (define_expand "mmx_subrv2sf3"
234 [(set (match_operand:V2SF 0 "register_operand" "")
235 (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "")
236 (match_operand:V2SF 1 "nonimmediate_operand" "")))]
237 "TARGET_3DNOW && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
240 (define_insn "mmx_mulv2sf3"
241 [(set (match_operand:V2SF 0 "register_operand" "=y")
242 (mult:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
243 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
244 "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V2SFmode, operands)"
245 "pfmul\\t{%2, %0|%0, %2}"
246 [(set_attr "type" "mmxmul")
247 (set_attr "mode" "V2SF")])
249 (define_insn "mmx_smaxv2sf3"
250 [(set (match_operand:V2SF 0 "register_operand" "=y")
251 (smax:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
252 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
253 "TARGET_3DNOW && ix86_binary_operator_ok (SMAX, V2SFmode, operands)"
254 "pfmax\\t{%2, %0|%0, %2}"
255 [(set_attr "type" "mmxadd")
256 (set_attr "mode" "V2SF")])
258 (define_insn "mmx_sminv2sf3"
259 [(set (match_operand:V2SF 0 "register_operand" "=y")
260 (smin:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
261 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
262 "TARGET_3DNOW && ix86_binary_operator_ok (SMIN, V2SFmode, operands)"
263 "pfmin\\t{%2, %0|%0, %2}"
264 [(set_attr "type" "mmxadd")
265 (set_attr "mode" "V2SF")])
267 (define_insn "mmx_rcpv2sf2"
268 [(set (match_operand:V2SF 0 "register_operand" "=y")
269 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
272 "pfrcp\\t{%1, %0|%0, %1}"
273 [(set_attr "type" "mmx")
274 (set_attr "mode" "V2SF")])
276 (define_insn "mmx_rcpit1v2sf3"
277 [(set (match_operand:V2SF 0 "register_operand" "=y")
278 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
279 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
282 "pfrcpit1\\t{%2, %0|%0, %2}"
283 [(set_attr "type" "mmx")
284 (set_attr "mode" "V2SF")])
286 (define_insn "mmx_rcpit2v2sf3"
287 [(set (match_operand:V2SF 0 "register_operand" "=y")
288 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
289 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
292 "pfrcpit2\\t{%2, %0|%0, %2}"
293 [(set_attr "type" "mmx")
294 (set_attr "mode" "V2SF")])
296 (define_insn "mmx_rsqrtv2sf2"
297 [(set (match_operand:V2SF 0 "register_operand" "=y")
298 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
301 "pfrsqrt\\t{%1, %0|%0, %1}"
302 [(set_attr "type" "mmx")
303 (set_attr "mode" "V2SF")])
305 (define_insn "mmx_rsqit1v2sf3"
306 [(set (match_operand:V2SF 0 "register_operand" "=y")
307 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
308 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
311 "pfrsqit1\\t{%2, %0|%0, %2}"
312 [(set_attr "type" "mmx")
313 (set_attr "mode" "V2SF")])
315 (define_insn "mmx_haddv2sf3"
316 [(set (match_operand:V2SF 0 "register_operand" "=y")
320 (match_operand:V2SF 1 "register_operand" "0")
321 (parallel [(const_int 0)]))
322 (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
325 (match_operand:V2SF 2 "nonimmediate_operand" "ym")
326 (parallel [(const_int 0)]))
327 (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
329 "pfacc\\t{%2, %0|%0, %2}"
330 [(set_attr "type" "mmxadd")
331 (set_attr "mode" "V2SF")])
333 (define_insn "mmx_hsubv2sf3"
334 [(set (match_operand:V2SF 0 "register_operand" "=y")
338 (match_operand:V2SF 1 "register_operand" "0")
339 (parallel [(const_int 0)]))
340 (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
343 (match_operand:V2SF 2 "nonimmediate_operand" "ym")
344 (parallel [(const_int 0)]))
345 (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
347 "pfnacc\\t{%2, %0|%0, %2}"
348 [(set_attr "type" "mmxadd")
349 (set_attr "mode" "V2SF")])
351 (define_insn "mmx_addsubv2sf3"
352 [(set (match_operand:V2SF 0 "register_operand" "=y")
355 (match_operand:V2SF 1 "register_operand" "0")
356 (match_operand:V2SF 2 "nonimmediate_operand" "ym"))
357 (minus:V2SF (match_dup 1) (match_dup 2))
360 "pfpnacc\\t{%2, %0|%0, %2}"
361 [(set_attr "type" "mmxadd")
362 (set_attr "mode" "V2SF")])
364 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
366 ;; Parallel single-precision floating point comparisons
368 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
370 (define_insn "mmx_gtv2sf3"
371 [(set (match_operand:V2SI 0 "register_operand" "=y")
372 (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
373 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
375 "pfcmpgt\\t{%2, %0|%0, %2}"
376 [(set_attr "type" "mmxcmp")
377 (set_attr "mode" "V2SF")])
379 (define_insn "mmx_gev2sf3"
380 [(set (match_operand:V2SI 0 "register_operand" "=y")
381 (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
382 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
384 "pfcmpge\\t{%2, %0|%0, %2}"
385 [(set_attr "type" "mmxcmp")
386 (set_attr "mode" "V2SF")])
388 (define_insn "mmx_eqv2sf3"
389 [(set (match_operand:V2SI 0 "register_operand" "=y")
390 (eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "%0")
391 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
392 "TARGET_3DNOW && ix86_binary_operator_ok (EQ, V2SFmode, operands)"
393 "pfcmpeq\\t{%2, %0|%0, %2}"
394 [(set_attr "type" "mmxcmp")
395 (set_attr "mode" "V2SF")])
397 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
399 ;; Parallel single-precision floating point conversion operations
401 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
403 (define_insn "mmx_pf2id"
404 [(set (match_operand:V2SI 0 "register_operand" "=y")
405 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
407 "pf2id\\t{%1, %0|%0, %1}"
408 [(set_attr "type" "mmxcvt")
409 (set_attr "mode" "V2SF")])
411 (define_insn "mmx_pf2iw"
412 [(set (match_operand:V2SI 0 "register_operand" "=y")
416 (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
418 "pf2iw\\t{%1, %0|%0, %1}"
419 [(set_attr "type" "mmxcvt")
420 (set_attr "mode" "V2SF")])
422 (define_insn "mmx_pi2fw"
423 [(set (match_operand:V2SF 0 "register_operand" "=y")
427 (match_operand:V2SI 1 "nonimmediate_operand" "ym")))))]
429 "pi2fw\\t{%1, %0|%0, %1}"
430 [(set_attr "type" "mmxcvt")
431 (set_attr "mode" "V2SF")])
433 (define_insn "mmx_floatv2si2"
434 [(set (match_operand:V2SF 0 "register_operand" "=y")
435 (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
437 "pi2fd\\t{%1, %0|%0, %1}"
438 [(set_attr "type" "mmxcvt")
439 (set_attr "mode" "V2SF")])
441 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
443 ;; Parallel single-precision floating point element swizzling
445 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
447 (define_insn "mmx_pswapdv2sf2"
448 [(set (match_operand:V2SF 0 "register_operand" "=y")
449 (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
450 (parallel [(const_int 1) (const_int 0)])))]
452 "pswapd\\t{%1, %0|%0, %1}"
453 [(set_attr "type" "mmxcvt")
454 (set_attr "mode" "V2SF")])
456 (define_insn "*vec_dupv2sf"
457 [(set (match_operand:V2SF 0 "register_operand" "=y")
459 (match_operand:SF 1 "register_operand" "0")))]
462 [(set_attr "type" "mmxcvt")
463 (set_attr "mode" "DI")])
465 (define_insn "*mmx_concatv2sf"
466 [(set (match_operand:V2SF 0 "register_operand" "=y,y")
468 (match_operand:SF 1 "nonimmediate_operand" " 0,rm")
469 (match_operand:SF 2 "vector_move_operand" "ym,C")))]
470 "TARGET_MMX && !TARGET_SSE"
472 punpckldq\t{%2, %0|%0, %2}
473 movd\t{%1, %0|%0, %1}"
474 [(set_attr "type" "mmxcvt,mmxmov")
475 (set_attr "mode" "DI")])
477 (define_expand "vec_setv2sf"
478 [(match_operand:V2SF 0 "register_operand" "")
479 (match_operand:SF 1 "register_operand" "")
480 (match_operand 2 "const_int_operand" "")]
483 ix86_expand_vector_set (false, operands[0], operands[1],
484 INTVAL (operands[2]));
488 (define_insn_and_split "*vec_extractv2sf_0"
489 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,y,m,m,frxy")
491 (match_operand:V2SF 1 "nonimmediate_operand" " x,y,x,y,m")
492 (parallel [(const_int 0)])))]
493 "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
495 "&& reload_completed"
498 rtx op1 = operands[1];
500 op1 = gen_rtx_REG (SFmode, REGNO (op1));
502 op1 = gen_lowpart (SFmode, op1);
503 emit_move_insn (operands[0], op1);
507 (define_insn "*vec_extractv2sf_1"
508 [(set (match_operand:SF 0 "nonimmediate_operand" "=y,x,frxy")
510 (match_operand:V2SF 1 "nonimmediate_operand" " 0,0,o")
511 (parallel [(const_int 1)])))]
512 "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
517 [(set_attr "type" "mmxcvt,sselog1,*")
518 (set_attr "mode" "DI,V4SF,SI")])
521 [(set (match_operand:SF 0 "register_operand" "")
523 (match_operand:V2SF 1 "memory_operand" "")
524 (parallel [(const_int 1)])))]
525 "TARGET_MMX && reload_completed"
528 operands[1] = adjust_address (operands[1], SFmode, 4);
529 emit_move_insn (operands[0], operands[1]);
533 (define_expand "vec_extractv2sf"
534 [(match_operand:SF 0 "register_operand" "")
535 (match_operand:V2SF 1 "register_operand" "")
536 (match_operand 2 "const_int_operand" "")]
539 ix86_expand_vector_extract (false, operands[0], operands[1],
540 INTVAL (operands[2]));
544 (define_expand "vec_initv2sf"
545 [(match_operand:V2SF 0 "register_operand" "")
546 (match_operand 1 "" "")]
549 ix86_expand_vector_init (false, operands[0], operands[1]);
553 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
555 ;; Parallel integral arithmetic
557 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
559 (define_insn "mmx_add<mode>3"
560 [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
562 (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
563 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
564 "TARGET_MMX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
565 "padd<mmxvecsize>\t{%2, %0|%0, %2}"
566 [(set_attr "type" "mmxadd")
567 (set_attr "mode" "DI")])
569 (define_insn "mmx_adddi3"
570 [(set (match_operand:DI 0 "register_operand" "=y")
572 [(plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
573 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
575 "TARGET_SSE2 && ix86_binary_operator_ok (PLUS, DImode, operands)"
576 "paddq\t{%2, %0|%0, %2}"
577 [(set_attr "type" "mmxadd")
578 (set_attr "mode" "DI")])
580 (define_insn "mmx_ssadd<mode>3"
581 [(set (match_operand:MMXMODE12 0 "register_operand" "=y")
583 (match_operand:MMXMODE12 1 "nonimmediate_operand" "%0")
584 (match_operand:MMXMODE12 2 "nonimmediate_operand" "ym")))]
586 "padds<mmxvecsize>\t{%2, %0|%0, %2}"
587 [(set_attr "type" "mmxadd")
588 (set_attr "mode" "DI")])
590 (define_insn "mmx_usadd<mode>3"
591 [(set (match_operand:MMXMODE12 0 "register_operand" "=y")
593 (match_operand:MMXMODE12 1 "nonimmediate_operand" "%0")
594 (match_operand:MMXMODE12 2 "nonimmediate_operand" "ym")))]
596 "paddus<mmxvecsize>\t{%2, %0|%0, %2}"
597 [(set_attr "type" "mmxadd")
598 (set_attr "mode" "DI")])
600 (define_insn "mmx_sub<mode>3"
601 [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
603 (match_operand:MMXMODEI 1 "register_operand" "0")
604 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
606 "psub<mmxvecsize>\t{%2, %0|%0, %2}"
607 [(set_attr "type" "mmxadd")
608 (set_attr "mode" "DI")])
610 (define_insn "mmx_subdi3"
611 [(set (match_operand:DI 0 "register_operand" "=y")
613 [(minus:DI (match_operand:DI 1 "register_operand" "0")
614 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
617 "psubq\t{%2, %0|%0, %2}"
618 [(set_attr "type" "mmxadd")
619 (set_attr "mode" "DI")])
621 (define_insn "mmx_sssub<mode>3"
622 [(set (match_operand:MMXMODE12 0 "register_operand" "=y")
624 (match_operand:MMXMODE12 1 "register_operand" "0")
625 (match_operand:MMXMODE12 2 "nonimmediate_operand" "ym")))]
627 "psubs<mmxvecsize>\t{%2, %0|%0, %2}"
628 [(set_attr "type" "mmxadd")
629 (set_attr "mode" "DI")])
631 (define_insn "mmx_ussub<mode>3"
632 [(set (match_operand:MMXMODE12 0 "register_operand" "=y")
634 (match_operand:MMXMODE12 1 "register_operand" "0")
635 (match_operand:MMXMODE12 2 "nonimmediate_operand" "ym")))]
637 "psubus<mmxvecsize>\t{%2, %0|%0, %2}"
638 [(set_attr "type" "mmxadd")
639 (set_attr "mode" "DI")])
641 (define_insn "mmx_mulv4hi3"
642 [(set (match_operand:V4HI 0 "register_operand" "=y")
643 (mult:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "%0")
644 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
645 "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
646 "pmullw\t{%2, %0|%0, %2}"
647 [(set_attr "type" "mmxmul")
648 (set_attr "mode" "DI")])
650 (define_insn "mmx_smulv4hi3_highpart"
651 [(set (match_operand:V4HI 0 "register_operand" "=y")
654 (mult:V4SI (sign_extend:V4SI
655 (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
657 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
659 "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
660 "pmulhw\t{%2, %0|%0, %2}"
661 [(set_attr "type" "mmxmul")
662 (set_attr "mode" "DI")])
664 (define_insn "mmx_umulv4hi3_highpart"
665 [(set (match_operand:V4HI 0 "register_operand" "=y")
668 (mult:V4SI (zero_extend:V4SI
669 (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
671 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
673 "(TARGET_SSE || TARGET_3DNOW_A)
674 && ix86_binary_operator_ok (MULT, V4HImode, operands)"
675 "pmulhuw\t{%2, %0|%0, %2}"
676 [(set_attr "type" "mmxmul")
677 (set_attr "mode" "DI")])
679 (define_insn "mmx_pmaddwd"
680 [(set (match_operand:V2SI 0 "register_operand" "=y")
685 (match_operand:V4HI 1 "nonimmediate_operand" "%0")
686 (parallel [(const_int 0) (const_int 2)])))
689 (match_operand:V4HI 2 "nonimmediate_operand" "ym")
690 (parallel [(const_int 0) (const_int 2)]))))
693 (vec_select:V2HI (match_dup 1)
694 (parallel [(const_int 1) (const_int 3)])))
696 (vec_select:V2HI (match_dup 2)
697 (parallel [(const_int 1) (const_int 3)]))))))]
698 "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
699 "pmaddwd\t{%2, %0|%0, %2}"
700 [(set_attr "type" "mmxmul")
701 (set_attr "mode" "DI")])
703 (define_insn "mmx_pmulhrwv4hi3"
704 [(set (match_operand:V4HI 0 "register_operand" "=y")
710 (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
712 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
713 (const_vector:V4SI [(const_int 32768) (const_int 32768)
714 (const_int 32768) (const_int 32768)]))
716 "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V4HImode, operands)"
717 "pmulhrw\\t{%2, %0|%0, %2}"
718 [(set_attr "type" "mmxmul")
719 (set_attr "mode" "DI")])
721 (define_insn "sse2_umulsidi3"
722 [(set (match_operand:DI 0 "register_operand" "=y")
726 (match_operand:V2SI 1 "nonimmediate_operand" "%0")
727 (parallel [(const_int 0)])))
730 (match_operand:V2SI 2 "nonimmediate_operand" "ym")
731 (parallel [(const_int 0)])))))]
732 "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V2SImode, operands)"
733 "pmuludq\t{%2, %0|%0, %2}"
734 [(set_attr "type" "mmxmul")
735 (set_attr "mode" "DI")])
737 (define_insn "mmx_umaxv8qi3"
738 [(set (match_operand:V8QI 0 "register_operand" "=y")
739 (umax:V8QI (match_operand:V8QI 1 "nonimmediate_operand" "%0")
740 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
741 "(TARGET_SSE || TARGET_3DNOW_A)
742 && ix86_binary_operator_ok (UMAX, V8QImode, operands)"
743 "pmaxub\t{%2, %0|%0, %2}"
744 [(set_attr "type" "mmxadd")
745 (set_attr "mode" "DI")])
747 (define_insn "mmx_smaxv4hi3"
748 [(set (match_operand:V4HI 0 "register_operand" "=y")
749 (smax:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "%0")
750 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
751 "(TARGET_SSE || TARGET_3DNOW_A)
752 && ix86_binary_operator_ok (SMAX, V4HImode, operands)"
753 "pmaxsw\t{%2, %0|%0, %2}"
754 [(set_attr "type" "mmxadd")
755 (set_attr "mode" "DI")])
757 (define_insn "mmx_uminv8qi3"
758 [(set (match_operand:V8QI 0 "register_operand" "=y")
759 (umin:V8QI (match_operand:V8QI 1 "nonimmediate_operand" "%0")
760 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
761 "(TARGET_SSE || TARGET_3DNOW_A)
762 && ix86_binary_operator_ok (UMIN, V8QImode, operands)"
763 "pminub\t{%2, %0|%0, %2}"
764 [(set_attr "type" "mmxadd")
765 (set_attr "mode" "DI")])
767 (define_insn "mmx_sminv4hi3"
768 [(set (match_operand:V4HI 0 "register_operand" "=y")
769 (smin:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "%0")
770 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
771 "(TARGET_SSE || TARGET_3DNOW_A)
772 && ix86_binary_operator_ok (SMIN, V4HImode, operands)"
773 "pminsw\t{%2, %0|%0, %2}"
774 [(set_attr "type" "mmxadd")
775 (set_attr "mode" "DI")])
777 (define_insn "mmx_ashr<mode>3"
778 [(set (match_operand:MMXMODE24 0 "register_operand" "=y")
780 (match_operand:MMXMODE24 1 "register_operand" "0")
781 (match_operand:DI 2 "nonmemory_operand" "yi")))]
783 "psra<mmxvecsize>\t{%2, %0|%0, %2}"
784 [(set_attr "type" "mmxshft")
785 (set_attr "mode" "DI")])
787 (define_insn "mmx_lshr<mode>3"
788 [(set (match_operand:MMXMODE24 0 "register_operand" "=y")
790 (match_operand:MMXMODE24 1 "register_operand" "0")
791 (match_operand:DI 2 "nonmemory_operand" "yi")))]
793 "psrl<mmxvecsize>\t{%2, %0|%0, %2}"
794 [(set_attr "type" "mmxshft")
795 (set_attr "mode" "DI")])
797 (define_insn "mmx_lshrdi3"
798 [(set (match_operand:DI 0 "register_operand" "=y")
800 [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
801 (match_operand:DI 2 "nonmemory_operand" "yi"))]
804 "psrlq\t{%2, %0|%0, %2}"
805 [(set_attr "type" "mmxshft")
806 (set_attr "mode" "DI")])
808 (define_insn "mmx_ashl<mode>3"
809 [(set (match_operand:MMXMODE24 0 "register_operand" "=y")
811 (match_operand:MMXMODE24 1 "register_operand" "0")
812 (match_operand:DI 2 "nonmemory_operand" "yi")))]
814 "psll<mmxvecsize>\t{%2, %0|%0, %2}"
815 [(set_attr "type" "mmxshft")
816 (set_attr "mode" "DI")])
818 (define_insn "mmx_ashldi3"
819 [(set (match_operand:DI 0 "register_operand" "=y")
821 [(ashift:DI (match_operand:DI 1 "register_operand" "0")
822 (match_operand:DI 2 "nonmemory_operand" "yi"))]
825 "psllq\t{%2, %0|%0, %2}"
826 [(set_attr "type" "mmxshft")
827 (set_attr "mode" "DI")])
829 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
831 ;; Parallel integral comparisons
833 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
835 (define_insn "mmx_eq<mode>3"
836 [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
838 (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
839 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
840 "TARGET_MMX && ix86_binary_operator_ok (EQ, <MODE>mode, operands)"
841 "pcmpeq<mmxvecsize>\t{%2, %0|%0, %2}"
842 [(set_attr "type" "mmxcmp")
843 (set_attr "mode" "DI")])
845 (define_insn "mmx_gt<mode>3"
846 [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
848 (match_operand:MMXMODEI 1 "register_operand" "0")
849 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
851 "pcmpgt<mmxvecsize>\t{%2, %0|%0, %2}"
852 [(set_attr "type" "mmxcmp")
853 (set_attr "mode" "DI")])
855 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
857 ;; Parallel integral logical operations
859 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
861 (define_insn "mmx_and<mode>3"
862 [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
864 (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
865 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
866 "TARGET_MMX && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
867 "pand\t{%2, %0|%0, %2}"
868 [(set_attr "type" "mmxadd")
869 (set_attr "mode" "DI")])
871 (define_insn "mmx_nand<mode>3"
872 [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
874 (not:MMXMODEI (match_operand:MMXMODEI 1 "register_operand" "0"))
875 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
877 "pandn\t{%2, %0|%0, %2}"
878 [(set_attr "type" "mmxadd")
879 (set_attr "mode" "DI")])
881 (define_insn "mmx_ior<mode>3"
882 [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
884 (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
885 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
886 "TARGET_MMX && ix86_binary_operator_ok (IOR, <MODE>mode, operands)"
887 "por\t{%2, %0|%0, %2}"
888 [(set_attr "type" "mmxadd")
889 (set_attr "mode" "DI")])
891 (define_insn "mmx_xor<mode>3"
892 [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
894 (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
895 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
896 "TARGET_MMX && ix86_binary_operator_ok (XOR, <MODE>mode, operands)"
897 "pxor\t{%2, %0|%0, %2}"
898 [(set_attr "type" "mmxadd")
899 (set_attr "mode" "DI")
900 (set_attr "memory" "none")])
902 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
904 ;; Parallel integral element swizzling
906 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
908 (define_insn "mmx_packsswb"
909 [(set (match_operand:V8QI 0 "register_operand" "=y")
912 (match_operand:V4HI 1 "register_operand" "0"))
914 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))))]
916 "packsswb\t{%2, %0|%0, %2}"
917 [(set_attr "type" "mmxshft")
918 (set_attr "mode" "DI")])
920 (define_insn "mmx_packssdw"
921 [(set (match_operand:V4HI 0 "register_operand" "=y")
924 (match_operand:V2SI 1 "register_operand" "0"))
926 (match_operand:V2SI 2 "nonimmediate_operand" "ym"))))]
928 "packssdw\t{%2, %0|%0, %2}"
929 [(set_attr "type" "mmxshft")
930 (set_attr "mode" "DI")])
932 (define_insn "mmx_packuswb"
933 [(set (match_operand:V8QI 0 "register_operand" "=y")
936 (match_operand:V4HI 1 "register_operand" "0"))
938 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))))]
940 "packuswb\t{%2, %0|%0, %2}"
941 [(set_attr "type" "mmxshft")
942 (set_attr "mode" "DI")])
944 (define_insn "mmx_punpckhbw"
945 [(set (match_operand:V8QI 0 "register_operand" "=y")
948 (match_operand:V8QI 1 "register_operand" "0")
949 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
950 (parallel [(const_int 4) (const_int 12)
951 (const_int 5) (const_int 13)
952 (const_int 6) (const_int 14)
953 (const_int 7) (const_int 15)])))]
955 "punpckhbw\t{%2, %0|%0, %2}"
956 [(set_attr "type" "mmxcvt")
957 (set_attr "mode" "DI")])
959 (define_insn "mmx_punpcklbw"
960 [(set (match_operand:V8QI 0 "register_operand" "=y")
963 (match_operand:V8QI 1 "register_operand" "0")
964 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
965 (parallel [(const_int 0) (const_int 8)
966 (const_int 1) (const_int 9)
967 (const_int 2) (const_int 10)
968 (const_int 3) (const_int 11)])))]
970 "punpcklbw\t{%2, %0|%0, %2}"
971 [(set_attr "type" "mmxcvt")
972 (set_attr "mode" "DI")])
974 (define_insn "mmx_punpckhwd"
975 [(set (match_operand:V4HI 0 "register_operand" "=y")
978 (match_operand:V4HI 1 "register_operand" "0")
979 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
980 (parallel [(const_int 2) (const_int 6)
981 (const_int 3) (const_int 7)])))]
983 "punpckhwd\t{%2, %0|%0, %2}"
984 [(set_attr "type" "mmxcvt")
985 (set_attr "mode" "DI")])
987 (define_insn "mmx_punpcklwd"
988 [(set (match_operand:V4HI 0 "register_operand" "=y")
991 (match_operand:V4HI 1 "register_operand" "0")
992 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
993 (parallel [(const_int 0) (const_int 4)
994 (const_int 1) (const_int 5)])))]
996 "punpcklwd\t{%2, %0|%0, %2}"
997 [(set_attr "type" "mmxcvt")
998 (set_attr "mode" "DI")])
1000 (define_insn "mmx_punpckhdq"
1001 [(set (match_operand:V2SI 0 "register_operand" "=y")
1004 (match_operand:V2SI 1 "register_operand" "0")
1005 (match_operand:V2SI 2 "nonimmediate_operand" "ym"))
1006 (parallel [(const_int 1)
1009 "punpckhdq\t{%2, %0|%0, %2}"
1010 [(set_attr "type" "mmxcvt")
1011 (set_attr "mode" "DI")])
1013 (define_insn "mmx_punpckldq"
1014 [(set (match_operand:V2SI 0 "register_operand" "=y")
1017 (match_operand:V2SI 1 "register_operand" "0")
1018 (match_operand:V2SI 2 "nonimmediate_operand" "ym"))
1019 (parallel [(const_int 0)
1022 "punpckldq\t{%2, %0|%0, %2}"
1023 [(set_attr "type" "mmxcvt")
1024 (set_attr "mode" "DI")])
1026 (define_expand "mmx_pinsrw"
1027 [(set (match_operand:V4HI 0 "register_operand" "")
1030 (match_operand:SI 2 "nonimmediate_operand" ""))
1031 (match_operand:V4HI 1 "register_operand" "")
1032 (match_operand:SI 3 "const_0_to_3_operand" "")))]
1033 "TARGET_SSE || TARGET_3DNOW_A"
1035 operands[2] = gen_lowpart (HImode, operands[2]);
1036 operands[3] = GEN_INT (1 << INTVAL (operands[3]));
1039 (define_insn "*mmx_pinsrw"
1040 [(set (match_operand:V4HI 0 "register_operand" "=y")
1043 (match_operand:HI 2 "nonimmediate_operand" "rm"))
1044 (match_operand:V4HI 1 "register_operand" "0")
1045 (match_operand:SI 3 "const_pow2_1_to_8_operand" "n")))]
1046 "TARGET_SSE || TARGET_3DNOW_A"
1048 operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
1049 return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}";
1051 [(set_attr "type" "mmxcvt")
1052 (set_attr "mode" "DI")])
1054 (define_insn "mmx_pextrw"
1055 [(set (match_operand:SI 0 "register_operand" "=r")
1058 (match_operand:V4HI 1 "register_operand" "y")
1059 (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n")]))))]
1060 "TARGET_SSE || TARGET_3DNOW_A"
1061 "pextrw\t{%2, %1, %0|%0, %1, %2}"
1062 [(set_attr "type" "mmxcvt")
1063 (set_attr "mode" "DI")])
1065 (define_expand "mmx_pshufw"
1066 [(match_operand:V4HI 0 "register_operand" "")
1067 (match_operand:V4HI 1 "nonimmediate_operand" "")
1068 (match_operand:SI 2 "const_int_operand" "")]
1069 "TARGET_SSE || TARGET_3DNOW_A"
1071 int mask = INTVAL (operands[2]);
1072 emit_insn (gen_mmx_pshufw_1 (operands[0], operands[1],
1073 GEN_INT ((mask >> 0) & 3),
1074 GEN_INT ((mask >> 2) & 3),
1075 GEN_INT ((mask >> 4) & 3),
1076 GEN_INT ((mask >> 6) & 3)));
1080 (define_insn "mmx_pshufw_1"
1081 [(set (match_operand:V4HI 0 "register_operand" "=y")
1083 (match_operand:V4HI 1 "nonimmediate_operand" "ym")
1084 (parallel [(match_operand 2 "const_0_to_3_operand" "")
1085 (match_operand 3 "const_0_to_3_operand" "")
1086 (match_operand 4 "const_0_to_3_operand" "")
1087 (match_operand 5 "const_0_to_3_operand" "")])))]
1088 "TARGET_SSE || TARGET_3DNOW_A"
1091 mask |= INTVAL (operands[2]) << 0;
1092 mask |= INTVAL (operands[3]) << 2;
1093 mask |= INTVAL (operands[4]) << 4;
1094 mask |= INTVAL (operands[5]) << 6;
1095 operands[2] = GEN_INT (mask);
1097 return "pshufw\t{%2, %1, %0|%0, %1, %2}";
1099 [(set_attr "type" "mmxcvt")
1100 (set_attr "mode" "DI")])
1102 (define_insn "mmx_pswapdv2si2"
1103 [(set (match_operand:V2SI 0 "register_operand" "=y")
1105 (match_operand:V2SI 1 "nonimmediate_operand" "ym")
1106 (parallel [(const_int 1) (const_int 0)])))]
1108 "pswapd\\t{%1, %0|%0, %1}"
1109 [(set_attr "type" "mmxcvt")
1110 (set_attr "mode" "DI")])
1112 (define_insn "*vec_dupv4hi"
1113 [(set (match_operand:V4HI 0 "register_operand" "=y")
1116 (match_operand:SI 1 "register_operand" "0"))))]
1117 "TARGET_SSE || TARGET_3DNOW_A"
1118 "pshufw\t{$0, %0, %0|%0, %0, 0}"
1119 [(set_attr "type" "mmxcvt")
1120 (set_attr "mode" "DI")])
1122 (define_insn "*vec_dupv2si"
1123 [(set (match_operand:V2SI 0 "register_operand" "=y")
1125 (match_operand:SI 1 "register_operand" "0")))]
1128 [(set_attr "type" "mmxcvt")
1129 (set_attr "mode" "DI")])
1131 (define_insn "*mmx_concatv2si"
1132 [(set (match_operand:V2SI 0 "register_operand" "=y,y")
1134 (match_operand:SI 1 "nonimmediate_operand" " 0,rm")
1135 (match_operand:SI 2 "vector_move_operand" "ym,C")))]
1136 "TARGET_MMX && !TARGET_SSE"
1138 punpckldq\t{%2, %0|%0, %2}
1139 movd\t{%1, %0|%0, %1}"
1140 [(set_attr "type" "mmxcvt,mmxmov")
1141 (set_attr "mode" "DI")])
1143 (define_expand "vec_setv2si"
1144 [(match_operand:V2SI 0 "register_operand" "")
1145 (match_operand:SI 1 "register_operand" "")
1146 (match_operand 2 "const_int_operand" "")]
1149 ix86_expand_vector_set (false, operands[0], operands[1],
1150 INTVAL (operands[2]));
1154 (define_insn_and_split "*vec_extractv2si_0"
1155 [(set (match_operand:SI 0 "nonimmediate_operand" "=x,y,m,m,frxy")
1157 (match_operand:V2SI 1 "nonimmediate_operand" " x,y,x,y,m")
1158 (parallel [(const_int 0)])))]
1159 "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1161 "&& reload_completed"
1164 rtx op1 = operands[1];
1166 op1 = gen_rtx_REG (SImode, REGNO (op1));
1168 op1 = gen_lowpart (SImode, op1);
1169 emit_move_insn (operands[0], op1);
1173 (define_insn "*vec_extractv2si_1"
1174 [(set (match_operand:SI 0 "nonimmediate_operand" "=y,Yt,Yt,x,frxy")
1176 (match_operand:V2SI 1 "nonimmediate_operand" " 0,0 ,Yt,0,o")
1177 (parallel [(const_int 1)])))]
1178 "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1182 pshufd\t{$85, %1, %0|%0, %1, 85}
1185 [(set_attr "type" "mmxcvt,sselog1,sselog1,sselog1,*")
1186 (set_attr "mode" "DI,TI,TI,V4SF,SI")])
1189 [(set (match_operand:SI 0 "register_operand" "")
1191 (match_operand:V2SI 1 "memory_operand" "")
1192 (parallel [(const_int 1)])))]
1193 "TARGET_MMX && reload_completed"
1196 operands[1] = adjust_address (operands[1], SImode, 4);
1197 emit_move_insn (operands[0], operands[1]);
1201 (define_expand "vec_extractv2si"
1202 [(match_operand:SI 0 "register_operand" "")
1203 (match_operand:V2SI 1 "register_operand" "")
1204 (match_operand 2 "const_int_operand" "")]
1207 ix86_expand_vector_extract (false, operands[0], operands[1],
1208 INTVAL (operands[2]));
1212 (define_expand "vec_initv2si"
1213 [(match_operand:V2SI 0 "register_operand" "")
1214 (match_operand 1 "" "")]
1217 ix86_expand_vector_init (false, operands[0], operands[1]);
1221 (define_expand "vec_setv4hi"
1222 [(match_operand:V4HI 0 "register_operand" "")
1223 (match_operand:HI 1 "register_operand" "")
1224 (match_operand 2 "const_int_operand" "")]
1227 ix86_expand_vector_set (false, operands[0], operands[1],
1228 INTVAL (operands[2]));
1232 (define_expand "vec_extractv4hi"
1233 [(match_operand:HI 0 "register_operand" "")
1234 (match_operand:V4HI 1 "register_operand" "")
1235 (match_operand 2 "const_int_operand" "")]
1238 ix86_expand_vector_extract (false, operands[0], operands[1],
1239 INTVAL (operands[2]));
1243 (define_expand "vec_initv4hi"
1244 [(match_operand:V4HI 0 "register_operand" "")
1245 (match_operand 1 "" "")]
1248 ix86_expand_vector_init (false, operands[0], operands[1]);
1252 (define_expand "vec_setv8qi"
1253 [(match_operand:V8QI 0 "register_operand" "")
1254 (match_operand:QI 1 "register_operand" "")
1255 (match_operand 2 "const_int_operand" "")]
1258 ix86_expand_vector_set (false, operands[0], operands[1],
1259 INTVAL (operands[2]));
1263 (define_expand "vec_extractv8qi"
1264 [(match_operand:QI 0 "register_operand" "")
1265 (match_operand:V8QI 1 "register_operand" "")
1266 (match_operand 2 "const_int_operand" "")]
1269 ix86_expand_vector_extract (false, operands[0], operands[1],
1270 INTVAL (operands[2]));
1274 (define_expand "vec_initv8qi"
1275 [(match_operand:V8QI 0 "register_operand" "")
1276 (match_operand 1 "" "")]
1279 ix86_expand_vector_init (false, operands[0], operands[1]);
1283 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1287 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1289 (define_insn "mmx_uavgv8qi3"
1290 [(set (match_operand:V8QI 0 "register_operand" "=y")
1296 (match_operand:V8QI 1 "nonimmediate_operand" "%0"))
1298 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))
1299 (const_vector:V8HI [(const_int 1) (const_int 1)
1300 (const_int 1) (const_int 1)
1301 (const_int 1) (const_int 1)
1302 (const_int 1) (const_int 1)]))
1304 "(TARGET_SSE || TARGET_3DNOW)
1305 && ix86_binary_operator_ok (PLUS, V8QImode, operands)"
1307 /* These two instructions have the same operation, but their encoding
1308 is different. Prefer the one that is de facto standard. */
1309 if (TARGET_SSE || TARGET_3DNOW_A)
1310 return "pavgb\t{%2, %0|%0, %2}";
1312 return "pavgusb\\t{%2, %0|%0, %2}";
1314 [(set_attr "type" "mmxshft")
1315 (set_attr "mode" "DI")])
1317 (define_insn "mmx_uavgv4hi3"
1318 [(set (match_operand:V4HI 0 "register_operand" "=y")
1324 (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
1326 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
1327 (const_vector:V4SI [(const_int 1) (const_int 1)
1328 (const_int 1) (const_int 1)]))
1330 "(TARGET_SSE || TARGET_3DNOW_A)
1331 && ix86_binary_operator_ok (PLUS, V4HImode, operands)"
1332 "pavgw\t{%2, %0|%0, %2}"
1333 [(set_attr "type" "mmxshft")
1334 (set_attr "mode" "DI")])
1336 (define_insn "mmx_psadbw"
1337 [(set (match_operand:DI 0 "register_operand" "=y")
1338 (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
1339 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
1341 "TARGET_SSE || TARGET_3DNOW_A"
1342 "psadbw\t{%2, %0|%0, %2}"
1343 [(set_attr "type" "mmxshft")
1344 (set_attr "mode" "DI")])
1346 (define_insn "mmx_pmovmskb"
1347 [(set (match_operand:SI 0 "register_operand" "=r")
1348 (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
1350 "TARGET_SSE || TARGET_3DNOW_A"
1351 "pmovmskb\t{%1, %0|%0, %1}"
1352 [(set_attr "type" "mmxcvt")
1353 (set_attr "mode" "DI")])
1355 (define_expand "mmx_maskmovq"
1356 [(set (match_operand:V8QI 0 "memory_operand" "")
1357 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "")
1358 (match_operand:V8QI 2 "register_operand" "")
1361 "TARGET_SSE || TARGET_3DNOW_A"
1364 (define_insn "*mmx_maskmovq"
1365 [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
1366 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
1367 (match_operand:V8QI 2 "register_operand" "y")
1368 (mem:V8QI (match_dup 0))]
1370 "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
1371 ;; @@@ check ordering of operands in intel/nonintel syntax
1372 "maskmovq\t{%2, %1|%1, %2}"
1373 [(set_attr "type" "mmxcvt")
1374 (set_attr "mode" "DI")])
1376 (define_insn "*mmx_maskmovq_rex"
1377 [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
1378 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
1379 (match_operand:V8QI 2 "register_operand" "y")
1380 (mem:V8QI (match_dup 0))]
1382 "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
1383 ;; @@@ check ordering of operands in intel/nonintel syntax
1384 "maskmovq\t{%2, %1|%1, %2}"
1385 [(set_attr "type" "mmxcvt")
1386 (set_attr "mode" "DI")])
1388 (define_insn "mmx_emms"
1389 [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
1390 (clobber (reg:XF 8))
1391 (clobber (reg:XF 9))
1392 (clobber (reg:XF 10))
1393 (clobber (reg:XF 11))
1394 (clobber (reg:XF 12))
1395 (clobber (reg:XF 13))
1396 (clobber (reg:XF 14))
1397 (clobber (reg:XF 15))
1398 (clobber (reg:DI 29))
1399 (clobber (reg:DI 30))
1400 (clobber (reg:DI 31))
1401 (clobber (reg:DI 32))
1402 (clobber (reg:DI 33))
1403 (clobber (reg:DI 34))
1404 (clobber (reg:DI 35))
1405 (clobber (reg:DI 36))]
1408 [(set_attr "type" "mmx")
1409 (set_attr "memory" "unknown")])
1411 (define_insn "mmx_femms"
1412 [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
1413 (clobber (reg:XF 8))
1414 (clobber (reg:XF 9))
1415 (clobber (reg:XF 10))
1416 (clobber (reg:XF 11))
1417 (clobber (reg:XF 12))
1418 (clobber (reg:XF 13))
1419 (clobber (reg:XF 14))
1420 (clobber (reg:XF 15))
1421 (clobber (reg:DI 29))
1422 (clobber (reg:DI 30))
1423 (clobber (reg:DI 31))
1424 (clobber (reg:DI 32))
1425 (clobber (reg:DI 33))
1426 (clobber (reg:DI 34))
1427 (clobber (reg:DI 35))
1428 (clobber (reg:DI 36))]
1431 [(set_attr "type" "mmx")
1432 (set_attr "memory" "none")])