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 ;; 8 byte integral modes handled by MMX (and by extension, SSE)
34 (define_mode_iterator MMXMODEI [V8QI V4HI V2SI])
35 (define_mode_iterator MMXMODEI8 [V8QI V4HI V2SI V1DI])
37 ;; All 8-byte vector modes handled by MMX
38 (define_mode_iterator MMXMODE [V8QI V4HI V2SI V1DI V2SF])
41 (define_mode_iterator MMXMODE12 [V8QI V4HI])
42 (define_mode_iterator MMXMODE24 [V4HI V2SI])
43 (define_mode_iterator MMXMODE248 [V4HI V2SI V1DI])
45 ;; Mapping from integer vector mode to mnemonic suffix
46 (define_mode_attr mmxvecsize [(V8QI "b") (V4HI "w") (V2SI "d") (V1DI "q")])
48 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
52 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
54 ;; All of these patterns are enabled for MMX as well as 3dNOW.
55 ;; This is essential for maintaining stable calling conventions.
57 (define_expand "mov<mode>"
58 [(set (match_operand:MMXMODEI8 0 "nonimmediate_operand" "")
59 (match_operand:MMXMODEI8 1 "nonimmediate_operand" ""))]
62 ix86_expand_vector_move (<MODE>mode, operands);
66 ;; movd instead of movq is required to handle broken assemblers.
67 (define_insn "*mov<mode>_internal_rex64"
68 [(set (match_operand:MMXMODEI8 0 "nonimmediate_operand"
69 "=rm,r,!?y,!y,!?y,m ,!y ,*Y2,x,x ,m,r ,Yi")
70 (match_operand:MMXMODEI8 1 "vector_move_operand"
71 "Cr ,m,C ,!y,m ,!?y,*Y2,!y ,C,xm,x,Yi,r"))]
72 "TARGET_64BIT && TARGET_MMX
73 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
75 mov{q}\t{%1, %0|%0, %1}
76 mov{q}\t{%1, %0|%0, %1}
81 movdq2q\t{%1, %0|%0, %1}
82 movq2dq\t{%1, %0|%0, %1}
84 %vmovq\t{%1, %0|%0, %1}
85 %vmovq\t{%1, %0|%0, %1}
86 %vmovd\t{%1, %0|%0, %1}
87 %vmovd\t{%1, %0|%0, %1}"
88 [(set_attr "type" "imov,imov,mmx,mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,sselog1,ssemov,ssemov,ssemov,ssemov")
89 (set_attr "unit" "*,*,*,*,*,*,mmx,mmx,*,*,*,*,*")
90 (set_attr "prefix_rep" "*,*,*,*,*,*,1,1,*,1,*,*,*")
91 (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,1,1,1")
92 (set (attr "prefix_rex")
93 (if_then_else (eq_attr "alternative" "9,10")
94 (symbol_ref "x86_extended_reg_mentioned_p (insn)")
97 (if_then_else (eq_attr "alternative" "8,9,10,11,12")
98 (const_string "maybe_vex")
99 (const_string "orig")))
100 (set_attr "mode" "DI")])
102 (define_insn "*mov<mode>_internal"
103 [(set (match_operand:MMXMODEI8 0 "nonimmediate_operand"
104 "=!?y,!y,!?y,m ,!y ,*Y2,*Y2,*Y2 ,m ,*x,*x,*x,m ,r ,m")
105 (match_operand:MMXMODEI8 1 "vector_move_operand"
106 "C ,!y,m ,!?y,*Y2,!y ,C ,*Y2m,*Y2,C ,*x,m ,*x,irm,r"))]
107 "!TARGET_64BIT && TARGET_MMX
108 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
111 movq\t{%1, %0|%0, %1}
112 movq\t{%1, %0|%0, %1}
113 movq\t{%1, %0|%0, %1}
114 movdq2q\t{%1, %0|%0, %1}
115 movq2dq\t{%1, %0|%0, %1}
117 %vmovq\t{%1, %0|%0, %1}
118 %vmovq\t{%1, %0|%0, %1}
120 movaps\t{%1, %0|%0, %1}
121 movlps\t{%1, %0|%0, %1}
122 movlps\t{%1, %0|%0, %1}
126 (if_then_else (eq_attr "alternative" "9,10,11,12")
127 (const_string "noavx")
128 (const_string "base")))
129 (set_attr "type" "mmx,mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,sselog1,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov,*,*")
130 (set_attr "unit" "*,*,*,*,mmx,mmx,*,*,*,*,*,*,*,*,*")
131 (set (attr "prefix_rep")
133 (ior (eq_attr "alternative" "4,5")
134 (and (eq_attr "alternative" "7")
135 (eq (symbol_ref "TARGET_AVX") (const_int 0))))
138 (set (attr "prefix_data16")
140 (and (eq_attr "alternative" "8")
141 (eq (symbol_ref "TARGET_AVX") (const_int 0)))
145 (if_then_else (eq_attr "alternative" "6,7,8")
146 (const_string "maybe_vex")
147 (const_string "orig")))
148 (set_attr "mode" "DI,DI,DI,DI,DI,DI,TI,DI,DI,V4SF,V4SF,V2SF,V2SF,DI,DI")])
150 (define_expand "movv2sf"
151 [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
152 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
155 ix86_expand_vector_move (V2SFmode, operands);
159 ;; movd instead of movq is required to handle broken assemblers.
160 (define_insn "*movv2sf_internal_rex64"
161 [(set (match_operand:V2SF 0 "nonimmediate_operand"
162 "=rm,r,!?y,!y,!?y,m ,!y ,*Y2,x,x,x,m,r ,Yi")
163 (match_operand:V2SF 1 "vector_move_operand"
164 "Cr ,m,C ,!y,m ,!?y,*Y2,!y ,C,x,m,x,Yi,r"))]
165 "TARGET_64BIT && TARGET_MMX
166 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
168 mov{q}\t{%1, %0|%0, %1}
169 mov{q}\t{%1, %0|%0, %1}
171 movq\t{%1, %0|%0, %1}
172 movq\t{%1, %0|%0, %1}
173 movq\t{%1, %0|%0, %1}
174 movdq2q\t{%1, %0|%0, %1}
175 movq2dq\t{%1, %0|%0, %1}
177 %vmovaps\t{%1, %0|%0, %1}
178 %vmovlps\t{%1, %d0|%d0, %1}
179 %vmovlps\t{%1, %0|%0, %1}
180 %vmovd\t{%1, %0|%0, %1}
181 %vmovd\t{%1, %0|%0, %1}"
182 [(set_attr "type" "imov,imov,mmx,mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,sselog1,ssemov,ssemov,ssemov,ssemov")
183 (set_attr "unit" "*,*,*,*,*,*,mmx,mmx,*,*,*,*,*,*")
184 (set_attr "prefix_rep" "*,*,*,*,*,*,1,1,*,*,*,*,*,*")
185 (set (attr "length_vex")
187 (and (eq_attr "alternative" "12,13")
188 (ne (symbol_ref "TARGET_AVX") (const_int 0)))
192 (if_then_else (eq_attr "alternative" "8,9,10,11,12,13")
193 (const_string "maybe_vex")
194 (const_string "orig")))
195 (set_attr "mode" "DI,DI,DI,DI,DI,DI,DI,DI,V4SF,V4SF,V2SF,V2SF,DI,DI")])
197 (define_insn "*movv2sf_internal"
198 [(set (match_operand:V2SF 0 "nonimmediate_operand"
199 "=!?y,!y,!?y,m ,!y ,*Y2,*x,*x,*x,m ,r ,m")
200 (match_operand:V2SF 1 "vector_move_operand"
201 "C ,!y,m ,!?y,*Y2,!y ,C ,*x,m ,*x,irm,r"))]
202 "!TARGET_64BIT && TARGET_MMX
203 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
206 movq\t{%1, %0|%0, %1}
207 movq\t{%1, %0|%0, %1}
208 movq\t{%1, %0|%0, %1}
209 movdq2q\t{%1, %0|%0, %1}
210 movq2dq\t{%1, %0|%0, %1}
212 %vmovaps\t{%1, %0|%0, %1}
213 %vmovlps\t{%1, %d0|%d0, %1}
214 %vmovlps\t{%1, %0|%0, %1}
217 [(set_attr "type" "mmx,mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,sselog1,ssemov,ssemov,ssemov,*,*")
218 (set_attr "unit" "*,*,*,*,mmx,mmx,*,*,*,*,*,*")
219 (set_attr "prefix_rep" "*,*,*,*,1,1,*,*,*,*,*,*")
221 (if_then_else (eq_attr "alternative" "6,7,8,9")
222 (const_string "maybe_vex")
223 (const_string "orig")))
224 (set_attr "mode" "DI,DI,DI,DI,DI,DI,V4SF,V4SF,V2SF,V2SF,DI,DI")])
226 ;; %%% This multiword shite has got to go.
228 [(set (match_operand:MMXMODE 0 "nonimmediate_operand" "")
229 (match_operand:MMXMODE 1 "general_operand" ""))]
230 "!TARGET_64BIT && reload_completed
231 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
232 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
234 "ix86_split_long_move (operands); DONE;")
236 (define_expand "push<mode>1"
237 [(match_operand:MMXMODE 0 "register_operand" "")]
240 ix86_expand_push (<MODE>mode, operands[0]);
244 (define_expand "movmisalign<mode>"
245 [(set (match_operand:MMXMODE 0 "nonimmediate_operand" "")
246 (match_operand:MMXMODE 1 "nonimmediate_operand" ""))]
249 ix86_expand_vector_move (<MODE>mode, operands);
253 (define_insn "sse_movntdi"
254 [(set (match_operand:DI 0 "memory_operand" "=m")
255 (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
257 "TARGET_SSE || TARGET_3DNOW_A"
258 "movntq\t{%1, %0|%0, %1}"
259 [(set_attr "type" "mmxmov")
260 (set_attr "mode" "DI")])
262 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
264 ;; Parallel single-precision floating point arithmetic
266 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
268 (define_expand "mmx_addv2sf3"
269 [(set (match_operand:V2SF 0 "register_operand" "")
271 (match_operand:V2SF 1 "nonimmediate_operand" "")
272 (match_operand:V2SF 2 "nonimmediate_operand" "")))]
274 "ix86_fixup_binary_operands_no_copy (PLUS, V2SFmode, operands);")
276 (define_insn "*mmx_addv2sf3"
277 [(set (match_operand:V2SF 0 "register_operand" "=y")
278 (plus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
279 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
280 "TARGET_3DNOW && ix86_binary_operator_ok (PLUS, V2SFmode, operands)"
281 "pfadd\t{%2, %0|%0, %2}"
282 [(set_attr "type" "mmxadd")
283 (set_attr "prefix_extra" "1")
284 (set_attr "mode" "V2SF")])
286 (define_expand "mmx_subv2sf3"
287 [(set (match_operand:V2SF 0 "register_operand" "")
288 (minus:V2SF (match_operand:V2SF 1 "register_operand" "")
289 (match_operand:V2SF 2 "nonimmediate_operand" "")))]
292 (define_expand "mmx_subrv2sf3"
293 [(set (match_operand:V2SF 0 "register_operand" "")
294 (minus:V2SF (match_operand:V2SF 2 "register_operand" "")
295 (match_operand:V2SF 1 "nonimmediate_operand" "")))]
298 (define_insn "*mmx_subv2sf3"
299 [(set (match_operand:V2SF 0 "register_operand" "=y,y")
300 (minus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "0,ym")
301 (match_operand:V2SF 2 "nonimmediate_operand" "ym,0")))]
302 "TARGET_3DNOW && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
304 pfsub\t{%2, %0|%0, %2}
305 pfsubr\t{%1, %0|%0, %1}"
306 [(set_attr "type" "mmxadd")
307 (set_attr "prefix_extra" "1")
308 (set_attr "mode" "V2SF")])
310 (define_expand "mmx_mulv2sf3"
311 [(set (match_operand:V2SF 0 "register_operand" "")
312 (mult:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "")
313 (match_operand:V2SF 2 "nonimmediate_operand" "")))]
315 "ix86_fixup_binary_operands_no_copy (MULT, V2SFmode, operands);")
317 (define_insn "*mmx_mulv2sf3"
318 [(set (match_operand:V2SF 0 "register_operand" "=y")
319 (mult:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
320 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
321 "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V2SFmode, operands)"
322 "pfmul\t{%2, %0|%0, %2}"
323 [(set_attr "type" "mmxmul")
324 (set_attr "prefix_extra" "1")
325 (set_attr "mode" "V2SF")])
327 ;; ??? For !flag_finite_math_only, the representation with SMIN/SMAX
328 ;; isn't really correct, as those rtl operators aren't defined when
329 ;; applied to NaNs. Hopefully the optimizers won't get too smart on us.
331 (define_expand "mmx_<code>v2sf3"
332 [(set (match_operand:V2SF 0 "register_operand" "")
334 (match_operand:V2SF 1 "nonimmediate_operand" "")
335 (match_operand:V2SF 2 "nonimmediate_operand" "")))]
338 if (!flag_finite_math_only)
339 operands[1] = force_reg (V2SFmode, operands[1]);
340 ix86_fixup_binary_operands_no_copy (<CODE>, V2SFmode, operands);
343 (define_insn "*mmx_<code>v2sf3_finite"
344 [(set (match_operand:V2SF 0 "register_operand" "=y")
346 (match_operand:V2SF 1 "nonimmediate_operand" "%0")
347 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
348 "TARGET_3DNOW && flag_finite_math_only
349 && ix86_binary_operator_ok (<CODE>, V2SFmode, operands)"
350 "pf<maxmin_float>\t{%2, %0|%0, %2}"
351 [(set_attr "type" "mmxadd")
352 (set_attr "prefix_extra" "1")
353 (set_attr "mode" "V2SF")])
355 (define_insn "*mmx_<code>v2sf3"
356 [(set (match_operand:V2SF 0 "register_operand" "=y")
358 (match_operand:V2SF 1 "register_operand" "0")
359 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
361 "pf<maxmin_float>\t{%2, %0|%0, %2}"
362 [(set_attr "type" "mmxadd")
363 (set_attr "prefix_extra" "1")
364 (set_attr "mode" "V2SF")])
366 (define_insn "mmx_rcpv2sf2"
367 [(set (match_operand:V2SF 0 "register_operand" "=y")
368 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
371 "pfrcp\t{%1, %0|%0, %1}"
372 [(set_attr "type" "mmx")
373 (set_attr "prefix_extra" "1")
374 (set_attr "mode" "V2SF")])
376 (define_insn "mmx_rcpit1v2sf3"
377 [(set (match_operand:V2SF 0 "register_operand" "=y")
378 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
379 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
382 "pfrcpit1\t{%2, %0|%0, %2}"
383 [(set_attr "type" "mmx")
384 (set_attr "prefix_extra" "1")
385 (set_attr "mode" "V2SF")])
387 (define_insn "mmx_rcpit2v2sf3"
388 [(set (match_operand:V2SF 0 "register_operand" "=y")
389 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
390 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
393 "pfrcpit2\t{%2, %0|%0, %2}"
394 [(set_attr "type" "mmx")
395 (set_attr "prefix_extra" "1")
396 (set_attr "mode" "V2SF")])
398 (define_insn "mmx_rsqrtv2sf2"
399 [(set (match_operand:V2SF 0 "register_operand" "=y")
400 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
403 "pfrsqrt\t{%1, %0|%0, %1}"
404 [(set_attr "type" "mmx")
405 (set_attr "prefix_extra" "1")
406 (set_attr "mode" "V2SF")])
408 (define_insn "mmx_rsqit1v2sf3"
409 [(set (match_operand:V2SF 0 "register_operand" "=y")
410 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
411 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
414 "pfrsqit1\t{%2, %0|%0, %2}"
415 [(set_attr "type" "mmx")
416 (set_attr "prefix_extra" "1")
417 (set_attr "mode" "V2SF")])
419 (define_insn "mmx_haddv2sf3"
420 [(set (match_operand:V2SF 0 "register_operand" "=y")
424 (match_operand:V2SF 1 "register_operand" "0")
425 (parallel [(const_int 0)]))
426 (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
429 (match_operand:V2SF 2 "nonimmediate_operand" "ym")
430 (parallel [(const_int 0)]))
431 (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
433 "pfacc\t{%2, %0|%0, %2}"
434 [(set_attr "type" "mmxadd")
435 (set_attr "prefix_extra" "1")
436 (set_attr "mode" "V2SF")])
438 (define_insn "mmx_hsubv2sf3"
439 [(set (match_operand:V2SF 0 "register_operand" "=y")
443 (match_operand:V2SF 1 "register_operand" "0")
444 (parallel [(const_int 0)]))
445 (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
448 (match_operand:V2SF 2 "nonimmediate_operand" "ym")
449 (parallel [(const_int 0)]))
450 (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
452 "pfnacc\t{%2, %0|%0, %2}"
453 [(set_attr "type" "mmxadd")
454 (set_attr "prefix_extra" "1")
455 (set_attr "mode" "V2SF")])
457 (define_insn "mmx_addsubv2sf3"
458 [(set (match_operand:V2SF 0 "register_operand" "=y")
461 (match_operand:V2SF 1 "register_operand" "0")
462 (match_operand:V2SF 2 "nonimmediate_operand" "ym"))
463 (minus:V2SF (match_dup 1) (match_dup 2))
466 "pfpnacc\t{%2, %0|%0, %2}"
467 [(set_attr "type" "mmxadd")
468 (set_attr "prefix_extra" "1")
469 (set_attr "mode" "V2SF")])
471 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
473 ;; Parallel single-precision floating point comparisons
475 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
477 (define_expand "mmx_eqv2sf3"
478 [(set (match_operand:V2SI 0 "register_operand" "")
479 (eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "")
480 (match_operand:V2SF 2 "nonimmediate_operand" "")))]
482 "ix86_fixup_binary_operands_no_copy (EQ, V2SFmode, operands);")
484 (define_insn "*mmx_eqv2sf3"
485 [(set (match_operand:V2SI 0 "register_operand" "=y")
486 (eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "%0")
487 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
488 "TARGET_3DNOW && ix86_binary_operator_ok (EQ, V2SFmode, operands)"
489 "pfcmpeq\t{%2, %0|%0, %2}"
490 [(set_attr "type" "mmxcmp")
491 (set_attr "prefix_extra" "1")
492 (set_attr "mode" "V2SF")])
494 (define_insn "mmx_gtv2sf3"
495 [(set (match_operand:V2SI 0 "register_operand" "=y")
496 (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
497 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
499 "pfcmpgt\t{%2, %0|%0, %2}"
500 [(set_attr "type" "mmxcmp")
501 (set_attr "prefix_extra" "1")
502 (set_attr "mode" "V2SF")])
504 (define_insn "mmx_gev2sf3"
505 [(set (match_operand:V2SI 0 "register_operand" "=y")
506 (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
507 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
509 "pfcmpge\t{%2, %0|%0, %2}"
510 [(set_attr "type" "mmxcmp")
511 (set_attr "prefix_extra" "1")
512 (set_attr "mode" "V2SF")])
514 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
516 ;; Parallel single-precision floating point conversion operations
518 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
520 (define_insn "mmx_pf2id"
521 [(set (match_operand:V2SI 0 "register_operand" "=y")
522 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
524 "pf2id\t{%1, %0|%0, %1}"
525 [(set_attr "type" "mmxcvt")
526 (set_attr "prefix_extra" "1")
527 (set_attr "mode" "V2SF")])
529 (define_insn "mmx_pf2iw"
530 [(set (match_operand:V2SI 0 "register_operand" "=y")
534 (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
536 "pf2iw\t{%1, %0|%0, %1}"
537 [(set_attr "type" "mmxcvt")
538 (set_attr "prefix_extra" "1")
539 (set_attr "mode" "V2SF")])
541 (define_insn "mmx_pi2fw"
542 [(set (match_operand:V2SF 0 "register_operand" "=y")
546 (match_operand:V2SI 1 "nonimmediate_operand" "ym")))))]
548 "pi2fw\t{%1, %0|%0, %1}"
549 [(set_attr "type" "mmxcvt")
550 (set_attr "prefix_extra" "1")
551 (set_attr "mode" "V2SF")])
553 (define_insn "mmx_floatv2si2"
554 [(set (match_operand:V2SF 0 "register_operand" "=y")
555 (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
557 "pi2fd\t{%1, %0|%0, %1}"
558 [(set_attr "type" "mmxcvt")
559 (set_attr "prefix_extra" "1")
560 (set_attr "mode" "V2SF")])
562 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
564 ;; Parallel single-precision floating point element swizzling
566 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
568 (define_insn "mmx_pswapdv2sf2"
569 [(set (match_operand:V2SF 0 "register_operand" "=y")
570 (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
571 (parallel [(const_int 1) (const_int 0)])))]
573 "pswapd\t{%1, %0|%0, %1}"
574 [(set_attr "type" "mmxcvt")
575 (set_attr "prefix_extra" "1")
576 (set_attr "mode" "V2SF")])
578 (define_insn "*vec_dupv2sf"
579 [(set (match_operand:V2SF 0 "register_operand" "=y")
581 (match_operand:SF 1 "register_operand" "0")))]
584 [(set_attr "type" "mmxcvt")
585 (set_attr "mode" "DI")])
587 (define_insn "*mmx_concatv2sf"
588 [(set (match_operand:V2SF 0 "register_operand" "=y,y")
590 (match_operand:SF 1 "nonimmediate_operand" " 0,rm")
591 (match_operand:SF 2 "vector_move_operand" "ym,C")))]
592 "TARGET_MMX && !TARGET_SSE"
594 punpckldq\t{%2, %0|%0, %2}
595 movd\t{%1, %0|%0, %1}"
596 [(set_attr "type" "mmxcvt,mmxmov")
597 (set_attr "mode" "DI")])
599 (define_expand "vec_setv2sf"
600 [(match_operand:V2SF 0 "register_operand" "")
601 (match_operand:SF 1 "register_operand" "")
602 (match_operand 2 "const_int_operand" "")]
605 ix86_expand_vector_set (false, operands[0], operands[1],
606 INTVAL (operands[2]));
610 ;; Avoid combining registers from different units in a single alternative,
611 ;; see comment above inline_secondary_memory_needed function in i386.c
612 (define_insn_and_split "*vec_extractv2sf_0"
613 [(set (match_operand:SF 0 "nonimmediate_operand" "=x, m,y ,m,f,r")
615 (match_operand:V2SF 1 "nonimmediate_operand" " xm,x,ym,y,m,m")
616 (parallel [(const_int 0)])))]
617 "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
619 "&& reload_completed"
622 rtx op1 = operands[1];
624 op1 = gen_rtx_REG (SFmode, REGNO (op1));
626 op1 = gen_lowpart (SFmode, op1);
627 emit_move_insn (operands[0], op1);
631 ;; Avoid combining registers from different units in a single alternative,
632 ;; see comment above inline_secondary_memory_needed function in i386.c
633 (define_insn "*vec_extractv2sf_1"
634 [(set (match_operand:SF 0 "nonimmediate_operand" "=y,x,y,x,f,r")
636 (match_operand:V2SF 1 "nonimmediate_operand" " 0,0,o,o,o,o")
637 (parallel [(const_int 1)])))]
638 "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
646 [(set_attr "type" "mmxcvt,sselog1,mmxmov,ssemov,fmov,imov")
647 (set_attr "mode" "DI,V4SF,SF,SF,SF,SF")])
650 [(set (match_operand:SF 0 "register_operand" "")
652 (match_operand:V2SF 1 "memory_operand" "")
653 (parallel [(const_int 1)])))]
654 "TARGET_MMX && reload_completed"
657 operands[1] = adjust_address (operands[1], SFmode, 4);
658 emit_move_insn (operands[0], operands[1]);
662 (define_expand "vec_extractv2sf"
663 [(match_operand:SF 0 "register_operand" "")
664 (match_operand:V2SF 1 "register_operand" "")
665 (match_operand 2 "const_int_operand" "")]
668 ix86_expand_vector_extract (false, operands[0], operands[1],
669 INTVAL (operands[2]));
673 (define_expand "vec_initv2sf"
674 [(match_operand:V2SF 0 "register_operand" "")
675 (match_operand 1 "" "")]
678 ix86_expand_vector_init (false, operands[0], operands[1]);
682 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
684 ;; Parallel integral arithmetic
686 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
688 (define_expand "mmx_<plusminus_insn><mode>3"
689 [(set (match_operand:MMXMODEI8 0 "register_operand" "")
691 (match_operand:MMXMODEI8 1 "nonimmediate_operand" "")
692 (match_operand:MMXMODEI8 2 "nonimmediate_operand" "")))]
693 "TARGET_MMX || (TARGET_SSE2 && <MODE>mode == V1DImode)"
694 "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
696 (define_insn "*mmx_<plusminus_insn><mode>3"
697 [(set (match_operand:MMXMODEI8 0 "register_operand" "=y")
699 (match_operand:MMXMODEI8 1 "nonimmediate_operand" "<comm>0")
700 (match_operand:MMXMODEI8 2 "nonimmediate_operand" "ym")))]
701 "(TARGET_MMX || (TARGET_SSE2 && <MODE>mode == V1DImode))
702 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
703 "p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}"
704 [(set_attr "type" "mmxadd")
705 (set_attr "mode" "DI")])
707 (define_expand "mmx_<plusminus_insn><mode>3"
708 [(set (match_operand:MMXMODE12 0 "register_operand" "")
709 (sat_plusminus:MMXMODE12
710 (match_operand:MMXMODE12 1 "nonimmediate_operand" "")
711 (match_operand:MMXMODE12 2 "nonimmediate_operand" "")))]
713 "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
715 (define_insn "*mmx_<plusminus_insn><mode>3"
716 [(set (match_operand:MMXMODE12 0 "register_operand" "=y")
717 (sat_plusminus:MMXMODE12
718 (match_operand:MMXMODE12 1 "nonimmediate_operand" "<comm>0")
719 (match_operand:MMXMODE12 2 "nonimmediate_operand" "ym")))]
720 "TARGET_MMX && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
721 "p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}"
722 [(set_attr "type" "mmxadd")
723 (set_attr "mode" "DI")])
725 (define_expand "mmx_mulv4hi3"
726 [(set (match_operand:V4HI 0 "register_operand" "")
727 (mult:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "")
728 (match_operand:V4HI 2 "nonimmediate_operand" "")))]
730 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
732 (define_insn "*mmx_mulv4hi3"
733 [(set (match_operand:V4HI 0 "register_operand" "=y")
734 (mult:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "%0")
735 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
736 "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
737 "pmullw\t{%2, %0|%0, %2}"
738 [(set_attr "type" "mmxmul")
739 (set_attr "mode" "DI")])
741 (define_expand "mmx_smulv4hi3_highpart"
742 [(set (match_operand:V4HI 0 "register_operand" "")
747 (match_operand:V4HI 1 "nonimmediate_operand" ""))
749 (match_operand:V4HI 2 "nonimmediate_operand" "")))
752 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
754 (define_insn "*mmx_smulv4hi3_highpart"
755 [(set (match_operand:V4HI 0 "register_operand" "=y")
760 (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
762 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
764 "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
765 "pmulhw\t{%2, %0|%0, %2}"
766 [(set_attr "type" "mmxmul")
767 (set_attr "mode" "DI")])
769 (define_expand "mmx_umulv4hi3_highpart"
770 [(set (match_operand:V4HI 0 "register_operand" "")
775 (match_operand:V4HI 1 "nonimmediate_operand" ""))
777 (match_operand:V4HI 2 "nonimmediate_operand" "")))
779 "TARGET_SSE || TARGET_3DNOW_A"
780 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
782 (define_insn "*mmx_umulv4hi3_highpart"
783 [(set (match_operand:V4HI 0 "register_operand" "=y")
788 (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
790 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
792 "(TARGET_SSE || TARGET_3DNOW_A)
793 && ix86_binary_operator_ok (MULT, V4HImode, operands)"
794 "pmulhuw\t{%2, %0|%0, %2}"
795 [(set_attr "type" "mmxmul")
796 (set_attr "mode" "DI")])
798 (define_expand "mmx_pmaddwd"
799 [(set (match_operand:V2SI 0 "register_operand" "")
804 (match_operand:V4HI 1 "nonimmediate_operand" "")
805 (parallel [(const_int 0) (const_int 2)])))
808 (match_operand:V4HI 2 "nonimmediate_operand" "")
809 (parallel [(const_int 0) (const_int 2)]))))
812 (vec_select:V2HI (match_dup 1)
813 (parallel [(const_int 1) (const_int 3)])))
815 (vec_select:V2HI (match_dup 2)
816 (parallel [(const_int 1) (const_int 3)]))))))]
818 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
820 (define_insn "*mmx_pmaddwd"
821 [(set (match_operand:V2SI 0 "register_operand" "=y")
826 (match_operand:V4HI 1 "nonimmediate_operand" "%0")
827 (parallel [(const_int 0) (const_int 2)])))
830 (match_operand:V4HI 2 "nonimmediate_operand" "ym")
831 (parallel [(const_int 0) (const_int 2)]))))
834 (vec_select:V2HI (match_dup 1)
835 (parallel [(const_int 1) (const_int 3)])))
837 (vec_select:V2HI (match_dup 2)
838 (parallel [(const_int 1) (const_int 3)]))))))]
839 "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
840 "pmaddwd\t{%2, %0|%0, %2}"
841 [(set_attr "type" "mmxmul")
842 (set_attr "mode" "DI")])
844 (define_expand "mmx_pmulhrwv4hi3"
845 [(set (match_operand:V4HI 0 "register_operand" "")
851 (match_operand:V4HI 1 "nonimmediate_operand" ""))
853 (match_operand:V4HI 2 "nonimmediate_operand" "")))
854 (const_vector:V4SI [(const_int 32768) (const_int 32768)
855 (const_int 32768) (const_int 32768)]))
858 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
860 (define_insn "*mmx_pmulhrwv4hi3"
861 [(set (match_operand:V4HI 0 "register_operand" "=y")
867 (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
869 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
870 (const_vector:V4SI [(const_int 32768) (const_int 32768)
871 (const_int 32768) (const_int 32768)]))
873 "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V4HImode, operands)"
874 "pmulhrw\t{%2, %0|%0, %2}"
875 [(set_attr "type" "mmxmul")
876 (set_attr "prefix_extra" "1")
877 (set_attr "mode" "DI")])
879 (define_expand "sse2_umulv1siv1di3"
880 [(set (match_operand:V1DI 0 "register_operand" "")
884 (match_operand:V2SI 1 "nonimmediate_operand" "")
885 (parallel [(const_int 0)])))
888 (match_operand:V2SI 2 "nonimmediate_operand" "")
889 (parallel [(const_int 0)])))))]
891 "ix86_fixup_binary_operands_no_copy (MULT, V2SImode, operands);")
893 (define_insn "*sse2_umulv1siv1di3"
894 [(set (match_operand:V1DI 0 "register_operand" "=y")
898 (match_operand:V2SI 1 "nonimmediate_operand" "%0")
899 (parallel [(const_int 0)])))
902 (match_operand:V2SI 2 "nonimmediate_operand" "ym")
903 (parallel [(const_int 0)])))))]
904 "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V2SImode, operands)"
905 "pmuludq\t{%2, %0|%0, %2}"
906 [(set_attr "type" "mmxmul")
907 (set_attr "mode" "DI")])
909 (define_expand "mmx_<code>v4hi3"
910 [(set (match_operand:V4HI 0 "register_operand" "")
912 (match_operand:V4HI 1 "nonimmediate_operand" "")
913 (match_operand:V4HI 2 "nonimmediate_operand" "")))]
914 "TARGET_SSE || TARGET_3DNOW_A"
915 "ix86_fixup_binary_operands_no_copy (<CODE>, V4HImode, operands);")
917 (define_insn "*mmx_<code>v4hi3"
918 [(set (match_operand:V4HI 0 "register_operand" "=y")
920 (match_operand:V4HI 1 "nonimmediate_operand" "%0")
921 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
922 "(TARGET_SSE || TARGET_3DNOW_A)
923 && ix86_binary_operator_ok (<CODE>, V4HImode, operands)"
924 "p<maxmin_int>w\t{%2, %0|%0, %2}"
925 [(set_attr "type" "mmxadd")
926 (set_attr "mode" "DI")])
928 (define_expand "mmx_<code>v8qi3"
929 [(set (match_operand:V8QI 0 "register_operand" "")
931 (match_operand:V8QI 1 "nonimmediate_operand" "")
932 (match_operand:V8QI 2 "nonimmediate_operand" "")))]
933 "TARGET_SSE || TARGET_3DNOW_A"
934 "ix86_fixup_binary_operands_no_copy (<CODE>, V8QImode, operands);")
936 (define_insn "*mmx_<code>v8qi3"
937 [(set (match_operand:V8QI 0 "register_operand" "=y")
939 (match_operand:V8QI 1 "nonimmediate_operand" "%0")
940 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
941 "(TARGET_SSE || TARGET_3DNOW_A)
942 && ix86_binary_operator_ok (<CODE>, V8QImode, operands)"
943 "p<maxmin_int>b\t{%2, %0|%0, %2}"
944 [(set_attr "type" "mmxadd")
945 (set_attr "mode" "DI")])
947 (define_insn "mmx_ashr<mode>3"
948 [(set (match_operand:MMXMODE24 0 "register_operand" "=y")
950 (match_operand:MMXMODE24 1 "register_operand" "0")
951 (match_operand:SI 2 "nonmemory_operand" "yN")))]
953 "psra<mmxvecsize>\t{%2, %0|%0, %2}"
954 [(set_attr "type" "mmxshft")
955 (set (attr "length_immediate")
956 (if_then_else (match_operand 2 "const_int_operand" "")
959 (set_attr "mode" "DI")])
961 (define_insn "mmx_lshr<mode>3"
962 [(set (match_operand:MMXMODE248 0 "register_operand" "=y")
964 (match_operand:MMXMODE248 1 "register_operand" "0")
965 (match_operand:SI 2 "nonmemory_operand" "yN")))]
967 "psrl<mmxvecsize>\t{%2, %0|%0, %2}"
968 [(set_attr "type" "mmxshft")
969 (set (attr "length_immediate")
970 (if_then_else (match_operand 2 "const_int_operand" "")
973 (set_attr "mode" "DI")])
975 (define_insn "mmx_ashl<mode>3"
976 [(set (match_operand:MMXMODE248 0 "register_operand" "=y")
978 (match_operand:MMXMODE248 1 "register_operand" "0")
979 (match_operand:SI 2 "nonmemory_operand" "yN")))]
981 "psll<mmxvecsize>\t{%2, %0|%0, %2}"
982 [(set_attr "type" "mmxshft")
983 (set (attr "length_immediate")
984 (if_then_else (match_operand 2 "const_int_operand" "")
987 (set_attr "mode" "DI")])
989 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
991 ;; Parallel integral comparisons
993 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
995 (define_expand "mmx_eq<mode>3"
996 [(set (match_operand:MMXMODEI 0 "register_operand" "")
998 (match_operand:MMXMODEI 1 "nonimmediate_operand" "")
999 (match_operand:MMXMODEI 2 "nonimmediate_operand" "")))]
1001 "ix86_fixup_binary_operands_no_copy (EQ, <MODE>mode, operands);")
1003 (define_insn "*mmx_eq<mode>3"
1004 [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
1006 (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
1007 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
1008 "TARGET_MMX && ix86_binary_operator_ok (EQ, <MODE>mode, operands)"
1009 "pcmpeq<mmxvecsize>\t{%2, %0|%0, %2}"
1010 [(set_attr "type" "mmxcmp")
1011 (set_attr "mode" "DI")])
1013 (define_insn "mmx_gt<mode>3"
1014 [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
1016 (match_operand:MMXMODEI 1 "register_operand" "0")
1017 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
1019 "pcmpgt<mmxvecsize>\t{%2, %0|%0, %2}"
1020 [(set_attr "type" "mmxcmp")
1021 (set_attr "mode" "DI")])
1023 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1025 ;; Parallel integral logical operations
1027 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1029 (define_insn "mmx_andnot<mode>3"
1030 [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
1032 (not:MMXMODEI (match_operand:MMXMODEI 1 "register_operand" "0"))
1033 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
1035 "pandn\t{%2, %0|%0, %2}"
1036 [(set_attr "type" "mmxadd")
1037 (set_attr "mode" "DI")])
1039 (define_expand "mmx_<code><mode>3"
1040 [(set (match_operand:MMXMODEI 0 "register_operand" "")
1042 (match_operand:MMXMODEI 1 "nonimmediate_operand" "")
1043 (match_operand:MMXMODEI 2 "nonimmediate_operand" "")))]
1045 "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
1047 (define_insn "*mmx_<code><mode>3"
1048 [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
1050 (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
1051 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
1052 "TARGET_MMX && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
1053 "p<logic>\t{%2, %0|%0, %2}"
1054 [(set_attr "type" "mmxadd")
1055 (set_attr "mode" "DI")])
1057 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1059 ;; Parallel integral element swizzling
1061 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1063 (define_insn "mmx_packsswb"
1064 [(set (match_operand:V8QI 0 "register_operand" "=y")
1067 (match_operand:V4HI 1 "register_operand" "0"))
1069 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))))]
1071 "packsswb\t{%2, %0|%0, %2}"
1072 [(set_attr "type" "mmxshft")
1073 (set_attr "mode" "DI")])
1075 (define_insn "mmx_packssdw"
1076 [(set (match_operand:V4HI 0 "register_operand" "=y")
1079 (match_operand:V2SI 1 "register_operand" "0"))
1081 (match_operand:V2SI 2 "nonimmediate_operand" "ym"))))]
1083 "packssdw\t{%2, %0|%0, %2}"
1084 [(set_attr "type" "mmxshft")
1085 (set_attr "mode" "DI")])
1087 (define_insn "mmx_packuswb"
1088 [(set (match_operand:V8QI 0 "register_operand" "=y")
1091 (match_operand:V4HI 1 "register_operand" "0"))
1093 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))))]
1095 "packuswb\t{%2, %0|%0, %2}"
1096 [(set_attr "type" "mmxshft")
1097 (set_attr "mode" "DI")])
1099 (define_insn "mmx_punpckhbw"
1100 [(set (match_operand:V8QI 0 "register_operand" "=y")
1103 (match_operand:V8QI 1 "register_operand" "0")
1104 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
1105 (parallel [(const_int 4) (const_int 12)
1106 (const_int 5) (const_int 13)
1107 (const_int 6) (const_int 14)
1108 (const_int 7) (const_int 15)])))]
1110 "punpckhbw\t{%2, %0|%0, %2}"
1111 [(set_attr "type" "mmxcvt")
1112 (set_attr "mode" "DI")])
1114 (define_insn "mmx_punpcklbw"
1115 [(set (match_operand:V8QI 0 "register_operand" "=y")
1118 (match_operand:V8QI 1 "register_operand" "0")
1119 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
1120 (parallel [(const_int 0) (const_int 8)
1121 (const_int 1) (const_int 9)
1122 (const_int 2) (const_int 10)
1123 (const_int 3) (const_int 11)])))]
1125 "punpcklbw\t{%2, %0|%0, %2}"
1126 [(set_attr "type" "mmxcvt")
1127 (set_attr "mode" "DI")])
1129 (define_insn "mmx_punpckhwd"
1130 [(set (match_operand:V4HI 0 "register_operand" "=y")
1133 (match_operand:V4HI 1 "register_operand" "0")
1134 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
1135 (parallel [(const_int 2) (const_int 6)
1136 (const_int 3) (const_int 7)])))]
1138 "punpckhwd\t{%2, %0|%0, %2}"
1139 [(set_attr "type" "mmxcvt")
1140 (set_attr "mode" "DI")])
1142 (define_insn "mmx_punpcklwd"
1143 [(set (match_operand:V4HI 0 "register_operand" "=y")
1146 (match_operand:V4HI 1 "register_operand" "0")
1147 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
1148 (parallel [(const_int 0) (const_int 4)
1149 (const_int 1) (const_int 5)])))]
1151 "punpcklwd\t{%2, %0|%0, %2}"
1152 [(set_attr "type" "mmxcvt")
1153 (set_attr "mode" "DI")])
1155 (define_insn "mmx_punpckhdq"
1156 [(set (match_operand:V2SI 0 "register_operand" "=y")
1159 (match_operand:V2SI 1 "register_operand" "0")
1160 (match_operand:V2SI 2 "nonimmediate_operand" "ym"))
1161 (parallel [(const_int 1)
1164 "punpckhdq\t{%2, %0|%0, %2}"
1165 [(set_attr "type" "mmxcvt")
1166 (set_attr "mode" "DI")])
1168 (define_insn "mmx_punpckldq"
1169 [(set (match_operand:V2SI 0 "register_operand" "=y")
1172 (match_operand:V2SI 1 "register_operand" "0")
1173 (match_operand:V2SI 2 "nonimmediate_operand" "ym"))
1174 (parallel [(const_int 0)
1177 "punpckldq\t{%2, %0|%0, %2}"
1178 [(set_attr "type" "mmxcvt")
1179 (set_attr "mode" "DI")])
1181 (define_expand "mmx_pinsrw"
1182 [(set (match_operand:V4HI 0 "register_operand" "")
1185 (match_operand:SI 2 "nonimmediate_operand" ""))
1186 (match_operand:V4HI 1 "register_operand" "")
1187 (match_operand:SI 3 "const_0_to_3_operand" "")))]
1188 "TARGET_SSE || TARGET_3DNOW_A"
1190 operands[2] = gen_lowpart (HImode, operands[2]);
1191 operands[3] = GEN_INT (1 << INTVAL (operands[3]));
1194 (define_insn "*mmx_pinsrw"
1195 [(set (match_operand:V4HI 0 "register_operand" "=y")
1198 (match_operand:HI 2 "nonimmediate_operand" "rm"))
1199 (match_operand:V4HI 1 "register_operand" "0")
1200 (match_operand:SI 3 "const_int_operand" "")))]
1201 "(TARGET_SSE || TARGET_3DNOW_A)
1202 && ((unsigned) exact_log2 (INTVAL (operands[3]))
1203 < GET_MODE_NUNITS (V4HImode))"
1205 operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
1206 if (MEM_P (operands[2]))
1207 return "pinsrw\t{%3, %2, %0|%0, %2, %3}";
1209 return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}";
1211 [(set_attr "type" "mmxcvt")
1212 (set_attr "length_immediate" "1")
1213 (set_attr "mode" "DI")])
1215 (define_insn "mmx_pextrw"
1216 [(set (match_operand:SI 0 "register_operand" "=r")
1219 (match_operand:V4HI 1 "register_operand" "y")
1220 (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n")]))))]
1221 "TARGET_SSE || TARGET_3DNOW_A"
1222 "pextrw\t{%2, %1, %0|%0, %1, %2}"
1223 [(set_attr "type" "mmxcvt")
1224 (set_attr "length_immediate" "1")
1225 (set_attr "mode" "DI")])
1227 (define_expand "mmx_pshufw"
1228 [(match_operand:V4HI 0 "register_operand" "")
1229 (match_operand:V4HI 1 "nonimmediate_operand" "")
1230 (match_operand:SI 2 "const_int_operand" "")]
1231 "TARGET_SSE || TARGET_3DNOW_A"
1233 int mask = INTVAL (operands[2]);
1234 emit_insn (gen_mmx_pshufw_1 (operands[0], operands[1],
1235 GEN_INT ((mask >> 0) & 3),
1236 GEN_INT ((mask >> 2) & 3),
1237 GEN_INT ((mask >> 4) & 3),
1238 GEN_INT ((mask >> 6) & 3)));
1242 (define_insn "mmx_pshufw_1"
1243 [(set (match_operand:V4HI 0 "register_operand" "=y")
1245 (match_operand:V4HI 1 "nonimmediate_operand" "ym")
1246 (parallel [(match_operand 2 "const_0_to_3_operand" "")
1247 (match_operand 3 "const_0_to_3_operand" "")
1248 (match_operand 4 "const_0_to_3_operand" "")
1249 (match_operand 5 "const_0_to_3_operand" "")])))]
1250 "TARGET_SSE || TARGET_3DNOW_A"
1253 mask |= INTVAL (operands[2]) << 0;
1254 mask |= INTVAL (operands[3]) << 2;
1255 mask |= INTVAL (operands[4]) << 4;
1256 mask |= INTVAL (operands[5]) << 6;
1257 operands[2] = GEN_INT (mask);
1259 return "pshufw\t{%2, %1, %0|%0, %1, %2}";
1261 [(set_attr "type" "mmxcvt")
1262 (set_attr "length_immediate" "1")
1263 (set_attr "mode" "DI")])
1265 (define_insn "mmx_pswapdv2si2"
1266 [(set (match_operand:V2SI 0 "register_operand" "=y")
1268 (match_operand:V2SI 1 "nonimmediate_operand" "ym")
1269 (parallel [(const_int 1) (const_int 0)])))]
1271 "pswapd\t{%1, %0|%0, %1}"
1272 [(set_attr "type" "mmxcvt")
1273 (set_attr "prefix_extra" "1")
1274 (set_attr "mode" "DI")])
1276 (define_insn "*vec_dupv4hi"
1277 [(set (match_operand:V4HI 0 "register_operand" "=y")
1280 (match_operand:SI 1 "register_operand" "0"))))]
1281 "TARGET_SSE || TARGET_3DNOW_A"
1282 "pshufw\t{$0, %0, %0|%0, %0, 0}"
1283 [(set_attr "type" "mmxcvt")
1284 (set_attr "length_immediate" "1")
1285 (set_attr "mode" "DI")])
1287 (define_insn "*vec_dupv2si"
1288 [(set (match_operand:V2SI 0 "register_operand" "=y")
1290 (match_operand:SI 1 "register_operand" "0")))]
1293 [(set_attr "type" "mmxcvt")
1294 (set_attr "mode" "DI")])
1296 (define_insn "*mmx_concatv2si"
1297 [(set (match_operand:V2SI 0 "register_operand" "=y,y")
1299 (match_operand:SI 1 "nonimmediate_operand" " 0,rm")
1300 (match_operand:SI 2 "vector_move_operand" "ym,C")))]
1301 "TARGET_MMX && !TARGET_SSE"
1303 punpckldq\t{%2, %0|%0, %2}
1304 movd\t{%1, %0|%0, %1}"
1305 [(set_attr "type" "mmxcvt,mmxmov")
1306 (set_attr "mode" "DI")])
1308 (define_expand "vec_setv2si"
1309 [(match_operand:V2SI 0 "register_operand" "")
1310 (match_operand:SI 1 "register_operand" "")
1311 (match_operand 2 "const_int_operand" "")]
1314 ix86_expand_vector_set (false, operands[0], operands[1],
1315 INTVAL (operands[2]));
1319 ;; Avoid combining registers from different units in a single alternative,
1320 ;; see comment above inline_secondary_memory_needed function in i386.c
1321 (define_insn_and_split "*vec_extractv2si_0"
1322 [(set (match_operand:SI 0 "nonimmediate_operand" "=x,m,y, m,r")
1324 (match_operand:V2SI 1 "nonimmediate_operand" "xm,x,ym,y,m")
1325 (parallel [(const_int 0)])))]
1326 "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1328 "&& reload_completed"
1331 rtx op1 = operands[1];
1333 op1 = gen_rtx_REG (SImode, REGNO (op1));
1335 op1 = gen_lowpart (SImode, op1);
1336 emit_move_insn (operands[0], op1);
1340 ;; Avoid combining registers from different units in a single alternative,
1341 ;; see comment above inline_secondary_memory_needed function in i386.c
1342 (define_insn "*vec_extractv2si_1"
1343 [(set (match_operand:SI 0 "nonimmediate_operand" "=y,Y2,Y2,x,y,x,r")
1345 (match_operand:V2SI 1 "nonimmediate_operand" " 0,0 ,Y2,0,o,o,o")
1346 (parallel [(const_int 1)])))]
1347 "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1351 pshufd\t{$85, %1, %0|%0, %1, 85}
1356 [(set_attr "type" "mmxcvt,sselog1,sselog1,sselog1,mmxmov,ssemov,imov")
1357 (set_attr "length_immediate" "*,*,1,*,*,*,*")
1358 (set_attr "mode" "DI,TI,TI,V4SF,SI,SI,SI")])
1361 [(set (match_operand:SI 0 "register_operand" "")
1363 (match_operand:V2SI 1 "memory_operand" "")
1364 (parallel [(const_int 1)])))]
1365 "TARGET_MMX && reload_completed"
1368 operands[1] = adjust_address (operands[1], SImode, 4);
1369 emit_move_insn (operands[0], operands[1]);
1373 (define_expand "vec_extractv2si"
1374 [(match_operand:SI 0 "register_operand" "")
1375 (match_operand:V2SI 1 "register_operand" "")
1376 (match_operand 2 "const_int_operand" "")]
1379 ix86_expand_vector_extract (false, operands[0], operands[1],
1380 INTVAL (operands[2]));
1384 (define_expand "vec_initv2si"
1385 [(match_operand:V2SI 0 "register_operand" "")
1386 (match_operand 1 "" "")]
1389 ix86_expand_vector_init (false, operands[0], operands[1]);
1393 (define_expand "vec_setv4hi"
1394 [(match_operand:V4HI 0 "register_operand" "")
1395 (match_operand:HI 1 "register_operand" "")
1396 (match_operand 2 "const_int_operand" "")]
1399 ix86_expand_vector_set (false, operands[0], operands[1],
1400 INTVAL (operands[2]));
1404 (define_expand "vec_extractv4hi"
1405 [(match_operand:HI 0 "register_operand" "")
1406 (match_operand:V4HI 1 "register_operand" "")
1407 (match_operand 2 "const_int_operand" "")]
1410 ix86_expand_vector_extract (false, operands[0], operands[1],
1411 INTVAL (operands[2]));
1415 (define_expand "vec_initv4hi"
1416 [(match_operand:V4HI 0 "register_operand" "")
1417 (match_operand 1 "" "")]
1420 ix86_expand_vector_init (false, operands[0], operands[1]);
1424 (define_expand "vec_setv8qi"
1425 [(match_operand:V8QI 0 "register_operand" "")
1426 (match_operand:QI 1 "register_operand" "")
1427 (match_operand 2 "const_int_operand" "")]
1430 ix86_expand_vector_set (false, operands[0], operands[1],
1431 INTVAL (operands[2]));
1435 (define_expand "vec_extractv8qi"
1436 [(match_operand:QI 0 "register_operand" "")
1437 (match_operand:V8QI 1 "register_operand" "")
1438 (match_operand 2 "const_int_operand" "")]
1441 ix86_expand_vector_extract (false, operands[0], operands[1],
1442 INTVAL (operands[2]));
1446 (define_expand "vec_initv8qi"
1447 [(match_operand:V8QI 0 "register_operand" "")
1448 (match_operand 1 "" "")]
1451 ix86_expand_vector_init (false, operands[0], operands[1]);
1455 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1459 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1461 (define_expand "mmx_uavgv8qi3"
1462 [(set (match_operand:V8QI 0 "register_operand" "")
1468 (match_operand:V8QI 1 "nonimmediate_operand" ""))
1470 (match_operand:V8QI 2 "nonimmediate_operand" "")))
1471 (const_vector:V8HI [(const_int 1) (const_int 1)
1472 (const_int 1) (const_int 1)
1473 (const_int 1) (const_int 1)
1474 (const_int 1) (const_int 1)]))
1476 "TARGET_SSE || TARGET_3DNOW"
1477 "ix86_fixup_binary_operands_no_copy (PLUS, V8QImode, operands);")
1479 (define_insn "*mmx_uavgv8qi3"
1480 [(set (match_operand:V8QI 0 "register_operand" "=y")
1486 (match_operand:V8QI 1 "nonimmediate_operand" "%0"))
1488 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))
1489 (const_vector:V8HI [(const_int 1) (const_int 1)
1490 (const_int 1) (const_int 1)
1491 (const_int 1) (const_int 1)
1492 (const_int 1) (const_int 1)]))
1494 "(TARGET_SSE || TARGET_3DNOW)
1495 && ix86_binary_operator_ok (PLUS, V8QImode, operands)"
1497 /* These two instructions have the same operation, but their encoding
1498 is different. Prefer the one that is de facto standard. */
1499 if (TARGET_SSE || TARGET_3DNOW_A)
1500 return "pavgb\t{%2, %0|%0, %2}";
1502 return "pavgusb\t{%2, %0|%0, %2}";
1504 [(set_attr "type" "mmxshft")
1505 (set (attr "prefix_extra")
1507 (eq (symbol_ref "(TARGET_SSE || TARGET_3DNOW_A)") (const_int 0))
1509 (const_string "*")))
1510 (set_attr "mode" "DI")])
1512 (define_expand "mmx_uavgv4hi3"
1513 [(set (match_operand:V4HI 0 "register_operand" "")
1519 (match_operand:V4HI 1 "nonimmediate_operand" ""))
1521 (match_operand:V4HI 2 "nonimmediate_operand" "")))
1522 (const_vector:V4SI [(const_int 1) (const_int 1)
1523 (const_int 1) (const_int 1)]))
1525 "TARGET_SSE || TARGET_3DNOW_A"
1526 "ix86_fixup_binary_operands_no_copy (PLUS, V4HImode, operands);")
1528 (define_insn "*mmx_uavgv4hi3"
1529 [(set (match_operand:V4HI 0 "register_operand" "=y")
1535 (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
1537 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
1538 (const_vector:V4SI [(const_int 1) (const_int 1)
1539 (const_int 1) (const_int 1)]))
1541 "(TARGET_SSE || TARGET_3DNOW_A)
1542 && ix86_binary_operator_ok (PLUS, V4HImode, operands)"
1543 "pavgw\t{%2, %0|%0, %2}"
1544 [(set_attr "type" "mmxshft")
1545 (set_attr "mode" "DI")])
1547 (define_insn "mmx_psadbw"
1548 [(set (match_operand:V1DI 0 "register_operand" "=y")
1549 (unspec:V1DI [(match_operand:V8QI 1 "register_operand" "0")
1550 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
1552 "TARGET_SSE || TARGET_3DNOW_A"
1553 "psadbw\t{%2, %0|%0, %2}"
1554 [(set_attr "type" "mmxshft")
1555 (set_attr "mode" "DI")])
1557 (define_insn "mmx_pmovmskb"
1558 [(set (match_operand:SI 0 "register_operand" "=r")
1559 (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
1561 "TARGET_SSE || TARGET_3DNOW_A"
1562 "pmovmskb\t{%1, %0|%0, %1}"
1563 [(set_attr "type" "mmxcvt")
1564 (set_attr "mode" "DI")])
1566 (define_expand "mmx_maskmovq"
1567 [(set (match_operand:V8QI 0 "memory_operand" "")
1568 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "")
1569 (match_operand:V8QI 2 "register_operand" "")
1572 "TARGET_SSE || TARGET_3DNOW_A")
1574 (define_insn "*mmx_maskmovq"
1575 [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
1576 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
1577 (match_operand:V8QI 2 "register_operand" "y")
1578 (mem:V8QI (match_dup 0))]
1580 "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
1581 ;; @@@ check ordering of operands in intel/nonintel syntax
1582 "maskmovq\t{%2, %1|%1, %2}"
1583 [(set_attr "type" "mmxcvt")
1584 (set_attr "mode" "DI")])
1586 (define_insn "*mmx_maskmovq_rex"
1587 [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
1588 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
1589 (match_operand:V8QI 2 "register_operand" "y")
1590 (mem:V8QI (match_dup 0))]
1592 "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
1593 ;; @@@ check ordering of operands in intel/nonintel syntax
1594 "maskmovq\t{%2, %1|%1, %2}"
1595 [(set_attr "type" "mmxcvt")
1596 (set_attr "mode" "DI")])
1598 (define_expand "mmx_emms"
1599 [(match_par_dup 0 [(const_int 0)])]
1604 operands[0] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (17));
1606 XVECEXP (operands[0], 0, 0)
1607 = gen_rtx_UNSPEC_VOLATILE (VOIDmode, gen_rtvec (1, const0_rtx),
1610 for (regno = 0; regno < 8; regno++)
1612 XVECEXP (operands[0], 0, regno + 1)
1613 = gen_rtx_CLOBBER (VOIDmode,
1614 gen_rtx_REG (XFmode, FIRST_STACK_REG + regno));
1616 XVECEXP (operands[0], 0, regno + 9)
1617 = gen_rtx_CLOBBER (VOIDmode,
1618 gen_rtx_REG (DImode, FIRST_MMX_REG + regno));
1622 (define_insn "*mmx_emms"
1623 [(match_parallel 0 "emms_operation"
1624 [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)])]
1627 [(set_attr "type" "mmx")
1628 (set_attr "modrm" "0")
1629 (set_attr "memory" "none")])
1631 (define_expand "mmx_femms"
1632 [(match_par_dup 0 [(const_int 0)])]
1637 operands[0] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (17));
1639 XVECEXP (operands[0], 0, 0)
1640 = gen_rtx_UNSPEC_VOLATILE (VOIDmode, gen_rtvec (1, const0_rtx),
1643 for (regno = 0; regno < 8; regno++)
1645 XVECEXP (operands[0], 0, regno + 1)
1646 = gen_rtx_CLOBBER (VOIDmode,
1647 gen_rtx_REG (XFmode, FIRST_STACK_REG + regno));
1649 XVECEXP (operands[0], 0, regno + 9)
1650 = gen_rtx_CLOBBER (VOIDmode,
1651 gen_rtx_REG (DImode, FIRST_MMX_REG + regno));
1655 (define_insn "*mmx_femms"
1656 [(match_parallel 0 "emms_operation"
1657 [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)])]
1660 [(set_attr "type" "mmx")
1661 (set_attr "modrm" "0")
1662 (set_attr "memory" "none")])