1 ;; GCC machine description for MMX and 3dNOW! instructions
2 ;; Copyright (C) 2005-2013 Free Software Foundation, Inc.
4 ;; This file is part of GCC.
6 ;; GCC is free software; you can redistribute it and/or modify
7 ;; it under the terms of the GNU General Public License as published by
8 ;; the Free Software Foundation; either version 3, or (at your option)
11 ;; GCC is distributed in the hope that it will be useful,
12 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ;; GNU General Public License for more details.
16 ;; You should have received a copy of the GNU General Public License
17 ;; along with GCC; see the file COPYING3. If not see
18 ;; <http://www.gnu.org/licenses/>.
20 ;; The MMX and 3dNOW! patterns are in the same file because they use
21 ;; the same register file, and 3dNOW! adds a number of extensions to
22 ;; the base integer MMX isa.
24 ;; Note! Except for the basic move instructions, *all* of these
25 ;; patterns are outside the normal optabs namespace. This is because
26 ;; use of these registers requires the insertion of emms or femms
27 ;; instructions to return to normal fpu mode. The compiler doesn't
28 ;; know how to do that itself, which means it's up to the user. Which
29 ;; means that we should never use any of these patterns except at the
30 ;; direction of the user via a builtin.
32 (define_c_enum "unspec" [
41 (define_c_enum "unspecv" [
46 ;; 8 byte integral modes handled by MMX (and by extension, SSE)
47 (define_mode_iterator MMXMODEI [V8QI V4HI V2SI])
48 (define_mode_iterator MMXMODEI8 [V8QI V4HI V2SI V1DI])
50 ;; All 8-byte vector modes handled by MMX
51 (define_mode_iterator MMXMODE [V8QI V4HI V2SI V1DI V2SF])
54 (define_mode_iterator MMXMODE12 [V8QI V4HI])
55 (define_mode_iterator MMXMODE24 [V4HI V2SI])
56 (define_mode_iterator MMXMODE248 [V4HI V2SI V1DI])
58 ;; Mapping from integer vector mode to mnemonic suffix
59 (define_mode_attr mmxvecsize [(V8QI "b") (V4HI "w") (V2SI "d") (V1DI "q")])
61 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
65 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
67 ;; All of these patterns are enabled for MMX as well as 3dNOW.
68 ;; This is essential for maintaining stable calling conventions.
70 (define_expand "mov<mode>"
71 [(set (match_operand:MMXMODEI8 0 "nonimmediate_operand")
72 (match_operand:MMXMODEI8 1 "nonimmediate_operand"))]
75 ix86_expand_vector_move (<MODE>mode, operands);
79 ;; movd instead of movq is required to handle broken assemblers.
80 (define_insn "*mov<mode>_internal_rex64"
81 [(set (match_operand:MMXMODEI8 0 "nonimmediate_operand"
82 "=rm,r,!?y,!y,!?y,m ,!y ,*x,x,x ,m,r ,Yi")
83 (match_operand:MMXMODEI8 1 "vector_move_operand"
84 "Cr ,m,C ,!y,m ,!?y,*x,!y ,C,xm,x,Yi,r"))]
85 "TARGET_64BIT && TARGET_MMX
86 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
88 mov{q}\t{%1, %0|%0, %1}
89 mov{q}\t{%1, %0|%0, %1}
94 movdq2q\t{%1, %0|%0, %1}
95 movq2dq\t{%1, %0|%0, %1}
97 %vmovq\t{%1, %0|%0, %1}
98 %vmovq\t{%1, %0|%0, %1}
99 %vmovd\t{%1, %0|%0, %1}
100 %vmovd\t{%1, %0|%0, %1}"
102 (cond [(eq_attr "alternative" "0,1")
103 (const_string "imov")
104 (eq_attr "alternative" "2")
106 (eq_attr "alternative" "3,4,5")
107 (const_string "mmxmov")
108 (eq_attr "alternative" "6,7")
109 (const_string "ssecvt")
110 (eq_attr "alternative" "8")
111 (const_string "sselog1")
113 (const_string "ssemov")))
115 (if_then_else (eq_attr "alternative" "6,7")
118 (set (attr "prefix_rep")
119 (if_then_else (eq_attr "alternative" "6,7,9")
122 (set (attr "prefix_data16")
123 (if_then_else (eq_attr "alternative" "10,11,12")
126 (set (attr "prefix_rex")
127 (if_then_else (eq_attr "alternative" "9,10")
128 (symbol_ref "x86_extended_reg_mentioned_p (insn)")
131 (if_then_else (eq_attr "alternative" "8,9,10,11,12")
132 (const_string "maybe_vex")
133 (const_string "orig")))
134 (set_attr "mode" "DI")])
136 (define_insn "*mov<mode>_internal"
137 [(set (match_operand:MMXMODEI8 0 "nonimmediate_operand"
138 "=!?y,!y,!?y,m ,!y,*x,*x,*x ,m ,*x,*x,*x,m ,r ,m")
139 (match_operand:MMXMODEI8 1 "vector_move_operand"
140 "C ,!y,m ,!?y,*x,!y,C ,*xm,*x,C ,*x,m ,*x,irm,r"))]
141 "!TARGET_64BIT && TARGET_MMX
142 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
145 movq\t{%1, %0|%0, %1}
146 movq\t{%1, %0|%0, %1}
147 movq\t{%1, %0|%0, %1}
148 movdq2q\t{%1, %0|%0, %1}
149 movq2dq\t{%1, %0|%0, %1}
151 %vmovq\t{%1, %0|%0, %1}
152 %vmovq\t{%1, %0|%0, %1}
154 movaps\t{%1, %0|%0, %1}
155 movlps\t{%1, %0|%0, %1}
156 movlps\t{%1, %0|%0, %1}
160 (cond [(eq_attr "alternative" "4,5,6,7,8")
161 (const_string "sse2")
162 (eq_attr "alternative" "9,10,11,12")
163 (const_string "noavx")
167 (cond [(eq_attr "alternative" "0")
169 (eq_attr "alternative" "1,2,3")
170 (const_string "mmxmov")
171 (eq_attr "alternative" "4,5")
172 (const_string "ssecvt")
173 (eq_attr "alternative" "6,9")
174 (const_string "sselog1")
175 (eq_attr "alternative" "13,14")
176 (const_string "multi")
178 (const_string "ssemov")))
180 (if_then_else (eq_attr "alternative" "4,5")
183 (set (attr "prefix_rep")
185 (ior (eq_attr "alternative" "4,5")
186 (and (eq_attr "alternative" "7")
187 (not (match_test "TARGET_AVX"))))
190 (set (attr "prefix_data16")
192 (and (eq_attr "alternative" "8")
193 (not (match_test "TARGET_AVX")))
197 (if_then_else (eq_attr "alternative" "6,7,8")
198 (const_string "maybe_vex")
199 (const_string "orig")))
200 (set_attr "mode" "DI,DI,DI,DI,DI,DI,TI,DI,DI,V4SF,V4SF,V2SF,V2SF,DI,DI")])
202 (define_expand "movv2sf"
203 [(set (match_operand:V2SF 0 "nonimmediate_operand")
204 (match_operand:V2SF 1 "nonimmediate_operand"))]
207 ix86_expand_vector_move (V2SFmode, operands);
211 ;; movd instead of movq is required to handle broken assemblers.
212 (define_insn "*movv2sf_internal_rex64"
213 [(set (match_operand:V2SF 0 "nonimmediate_operand"
214 "=rm,r,!?y,!y,!?y,m ,!y,*x,x,x,x,m,r ,Yi")
215 (match_operand:V2SF 1 "vector_move_operand"
216 "Cr ,m,C ,!y,m ,!?y,*x,!y,C,x,m,x,Yi,r"))]
217 "TARGET_64BIT && TARGET_MMX
218 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
220 mov{q}\t{%1, %0|%0, %1}
221 mov{q}\t{%1, %0|%0, %1}
223 movq\t{%1, %0|%0, %1}
224 movq\t{%1, %0|%0, %1}
225 movq\t{%1, %0|%0, %1}
226 movdq2q\t{%1, %0|%0, %1}
227 movq2dq\t{%1, %0|%0, %1}
229 %vmovaps\t{%1, %0|%0, %1}
230 %vmovlps\t{%1, %d0|%d0, %1}
231 %vmovlps\t{%1, %0|%0, %1}
232 %vmovd\t{%1, %0|%0, %1}
233 %vmovd\t{%1, %0|%0, %1}"
235 (cond [(eq_attr "alternative" "0,1")
236 (const_string "imov")
237 (eq_attr "alternative" "2")
239 (eq_attr "alternative" "3,4,5")
240 (const_string "mmxmov")
241 (eq_attr "alternative" "6,7")
242 (const_string "ssecvt")
243 (eq_attr "alternative" "9")
244 (const_string "sselog1")
246 (const_string "ssemov")))
248 (if_then_else (eq_attr "alternative" "6,7")
251 (set (attr "prefix_rep")
252 (if_then_else (eq_attr "alternative" "6,7")
255 (set (attr "length_vex")
257 (and (eq_attr "alternative" "12,13")
258 (match_test "TARGET_AVX"))
262 (if_then_else (eq_attr "alternative" "8,9,10,11,12,13")
263 (const_string "maybe_vex")
264 (const_string "orig")))
265 (set_attr "mode" "DI,DI,DI,DI,DI,DI,DI,DI,V4SF,V4SF,V2SF,V2SF,DI,DI")])
267 (define_insn "*movv2sf_internal"
268 [(set (match_operand:V2SF 0 "nonimmediate_operand"
269 "=!?y,!y,!?y,m ,!y,*x,*x,*x,*x,m ,r ,m")
270 (match_operand:V2SF 1 "vector_move_operand"
271 "C ,!y,m ,!?y,*x,!y,C ,*x,m ,*x,irm,r"))]
272 "!TARGET_64BIT && TARGET_MMX
273 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
276 movq\t{%1, %0|%0, %1}
277 movq\t{%1, %0|%0, %1}
278 movq\t{%1, %0|%0, %1}
279 movdq2q\t{%1, %0|%0, %1}
280 movq2dq\t{%1, %0|%0, %1}
282 %vmovaps\t{%1, %0|%0, %1}
283 %vmovlps\t{%1, %d0|%d0, %1}
284 %vmovlps\t{%1, %0|%0, %1}
288 (if_then_else (eq_attr "alternative" "4,5")
289 (const_string "sse2")
292 (cond [(eq_attr "alternative" "0")
294 (eq_attr "alternative" "1,2,3")
295 (const_string "mmxmov")
296 (eq_attr "alternative" "4,5")
297 (const_string "ssecvt")
298 (eq_attr "alternative" "6")
299 (const_string "sselog1")
300 (eq_attr "alternative" "10,11")
301 (const_string "multi")
303 (const_string "ssemov")))
305 (if_then_else (eq_attr "alternative" "4,5")
308 (set (attr "prefix_rep")
309 (if_then_else (eq_attr "alternative" "4,5")
313 (if_then_else (eq_attr "alternative" "6,7,8,9")
314 (const_string "maybe_vex")
315 (const_string "orig")))
316 (set_attr "mode" "DI,DI,DI,DI,DI,DI,V4SF,V4SF,V2SF,V2SF,DI,DI")])
318 ;; %%% This multiword shite has got to go.
320 [(set (match_operand:MMXMODE 0 "nonimmediate_operand")
321 (match_operand:MMXMODE 1 "general_operand"))]
322 "!TARGET_64BIT && reload_completed
323 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0])
324 || MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
326 "ix86_split_long_move (operands); DONE;")
328 (define_expand "push<mode>1"
329 [(match_operand:MMXMODE 0 "register_operand")]
332 ix86_expand_push (<MODE>mode, operands[0]);
336 (define_expand "movmisalign<mode>"
337 [(set (match_operand:MMXMODE 0 "nonimmediate_operand")
338 (match_operand:MMXMODE 1 "nonimmediate_operand"))]
341 ix86_expand_vector_move (<MODE>mode, operands);
345 (define_insn "sse_movntq"
346 [(set (match_operand:DI 0 "memory_operand" "=m")
347 (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
349 "TARGET_SSE || TARGET_3DNOW_A"
350 "movntq\t{%1, %0|%0, %1}"
351 [(set_attr "type" "mmxmov")
352 (set_attr "mode" "DI")])
354 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
356 ;; Parallel single-precision floating point arithmetic
358 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
360 (define_expand "mmx_addv2sf3"
361 [(set (match_operand:V2SF 0 "register_operand")
363 (match_operand:V2SF 1 "nonimmediate_operand")
364 (match_operand:V2SF 2 "nonimmediate_operand")))]
366 "ix86_fixup_binary_operands_no_copy (PLUS, V2SFmode, operands);")
368 (define_insn "*mmx_addv2sf3"
369 [(set (match_operand:V2SF 0 "register_operand" "=y")
370 (plus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
371 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
372 "TARGET_3DNOW && ix86_binary_operator_ok (PLUS, V2SFmode, operands)"
373 "pfadd\t{%2, %0|%0, %2}"
374 [(set_attr "type" "mmxadd")
375 (set_attr "prefix_extra" "1")
376 (set_attr "mode" "V2SF")])
378 (define_expand "mmx_subv2sf3"
379 [(set (match_operand:V2SF 0 "register_operand")
380 (minus:V2SF (match_operand:V2SF 1 "register_operand")
381 (match_operand:V2SF 2 "nonimmediate_operand")))]
384 (define_expand "mmx_subrv2sf3"
385 [(set (match_operand:V2SF 0 "register_operand")
386 (minus:V2SF (match_operand:V2SF 2 "register_operand")
387 (match_operand:V2SF 1 "nonimmediate_operand")))]
390 (define_insn "*mmx_subv2sf3"
391 [(set (match_operand:V2SF 0 "register_operand" "=y,y")
392 (minus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "0,ym")
393 (match_operand:V2SF 2 "nonimmediate_operand" "ym,0")))]
394 "TARGET_3DNOW && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
396 pfsub\t{%2, %0|%0, %2}
397 pfsubr\t{%1, %0|%0, %1}"
398 [(set_attr "type" "mmxadd")
399 (set_attr "prefix_extra" "1")
400 (set_attr "mode" "V2SF")])
402 (define_expand "mmx_mulv2sf3"
403 [(set (match_operand:V2SF 0 "register_operand")
404 (mult:V2SF (match_operand:V2SF 1 "nonimmediate_operand")
405 (match_operand:V2SF 2 "nonimmediate_operand")))]
407 "ix86_fixup_binary_operands_no_copy (MULT, V2SFmode, operands);")
409 (define_insn "*mmx_mulv2sf3"
410 [(set (match_operand:V2SF 0 "register_operand" "=y")
411 (mult:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
412 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
413 "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V2SFmode, operands)"
414 "pfmul\t{%2, %0|%0, %2}"
415 [(set_attr "type" "mmxmul")
416 (set_attr "prefix_extra" "1")
417 (set_attr "mode" "V2SF")])
419 ;; ??? For !flag_finite_math_only, the representation with SMIN/SMAX
420 ;; isn't really correct, as those rtl operators aren't defined when
421 ;; applied to NaNs. Hopefully the optimizers won't get too smart on us.
423 (define_expand "mmx_<code>v2sf3"
424 [(set (match_operand:V2SF 0 "register_operand")
426 (match_operand:V2SF 1 "nonimmediate_operand")
427 (match_operand:V2SF 2 "nonimmediate_operand")))]
430 if (!flag_finite_math_only)
431 operands[1] = force_reg (V2SFmode, operands[1]);
432 ix86_fixup_binary_operands_no_copy (<CODE>, V2SFmode, operands);
435 (define_insn "*mmx_<code>v2sf3_finite"
436 [(set (match_operand:V2SF 0 "register_operand" "=y")
438 (match_operand:V2SF 1 "nonimmediate_operand" "%0")
439 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
440 "TARGET_3DNOW && flag_finite_math_only
441 && ix86_binary_operator_ok (<CODE>, V2SFmode, operands)"
442 "pf<maxmin_float>\t{%2, %0|%0, %2}"
443 [(set_attr "type" "mmxadd")
444 (set_attr "prefix_extra" "1")
445 (set_attr "mode" "V2SF")])
447 (define_insn "*mmx_<code>v2sf3"
448 [(set (match_operand:V2SF 0 "register_operand" "=y")
450 (match_operand:V2SF 1 "register_operand" "0")
451 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
453 "pf<maxmin_float>\t{%2, %0|%0, %2}"
454 [(set_attr "type" "mmxadd")
455 (set_attr "prefix_extra" "1")
456 (set_attr "mode" "V2SF")])
458 (define_insn "mmx_rcpv2sf2"
459 [(set (match_operand:V2SF 0 "register_operand" "=y")
460 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
463 "pfrcp\t{%1, %0|%0, %1}"
464 [(set_attr "type" "mmx")
465 (set_attr "prefix_extra" "1")
466 (set_attr "mode" "V2SF")])
468 (define_insn "mmx_rcpit1v2sf3"
469 [(set (match_operand:V2SF 0 "register_operand" "=y")
470 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
471 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
474 "pfrcpit1\t{%2, %0|%0, %2}"
475 [(set_attr "type" "mmx")
476 (set_attr "prefix_extra" "1")
477 (set_attr "mode" "V2SF")])
479 (define_insn "mmx_rcpit2v2sf3"
480 [(set (match_operand:V2SF 0 "register_operand" "=y")
481 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
482 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
485 "pfrcpit2\t{%2, %0|%0, %2}"
486 [(set_attr "type" "mmx")
487 (set_attr "prefix_extra" "1")
488 (set_attr "mode" "V2SF")])
490 (define_insn "mmx_rsqrtv2sf2"
491 [(set (match_operand:V2SF 0 "register_operand" "=y")
492 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
495 "pfrsqrt\t{%1, %0|%0, %1}"
496 [(set_attr "type" "mmx")
497 (set_attr "prefix_extra" "1")
498 (set_attr "mode" "V2SF")])
500 (define_insn "mmx_rsqit1v2sf3"
501 [(set (match_operand:V2SF 0 "register_operand" "=y")
502 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
503 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
506 "pfrsqit1\t{%2, %0|%0, %2}"
507 [(set_attr "type" "mmx")
508 (set_attr "prefix_extra" "1")
509 (set_attr "mode" "V2SF")])
511 (define_insn "mmx_haddv2sf3"
512 [(set (match_operand:V2SF 0 "register_operand" "=y")
516 (match_operand:V2SF 1 "register_operand" "0")
517 (parallel [(const_int 0)]))
518 (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
521 (match_operand:V2SF 2 "nonimmediate_operand" "ym")
522 (parallel [(const_int 0)]))
523 (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
525 "pfacc\t{%2, %0|%0, %2}"
526 [(set_attr "type" "mmxadd")
527 (set_attr "prefix_extra" "1")
528 (set_attr "mode" "V2SF")])
530 (define_insn "mmx_hsubv2sf3"
531 [(set (match_operand:V2SF 0 "register_operand" "=y")
535 (match_operand:V2SF 1 "register_operand" "0")
536 (parallel [(const_int 0)]))
537 (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
540 (match_operand:V2SF 2 "nonimmediate_operand" "ym")
541 (parallel [(const_int 0)]))
542 (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
544 "pfnacc\t{%2, %0|%0, %2}"
545 [(set_attr "type" "mmxadd")
546 (set_attr "prefix_extra" "1")
547 (set_attr "mode" "V2SF")])
549 (define_insn "mmx_addsubv2sf3"
550 [(set (match_operand:V2SF 0 "register_operand" "=y")
553 (match_operand:V2SF 1 "register_operand" "0")
554 (match_operand:V2SF 2 "nonimmediate_operand" "ym"))
555 (minus:V2SF (match_dup 1) (match_dup 2))
558 "pfpnacc\t{%2, %0|%0, %2}"
559 [(set_attr "type" "mmxadd")
560 (set_attr "prefix_extra" "1")
561 (set_attr "mode" "V2SF")])
563 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
565 ;; Parallel single-precision floating point comparisons
567 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
569 (define_expand "mmx_eqv2sf3"
570 [(set (match_operand:V2SI 0 "register_operand")
571 (eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand")
572 (match_operand:V2SF 2 "nonimmediate_operand")))]
574 "ix86_fixup_binary_operands_no_copy (EQ, V2SFmode, operands);")
576 (define_insn "*mmx_eqv2sf3"
577 [(set (match_operand:V2SI 0 "register_operand" "=y")
578 (eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "%0")
579 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
580 "TARGET_3DNOW && ix86_binary_operator_ok (EQ, V2SFmode, operands)"
581 "pfcmpeq\t{%2, %0|%0, %2}"
582 [(set_attr "type" "mmxcmp")
583 (set_attr "prefix_extra" "1")
584 (set_attr "mode" "V2SF")])
586 (define_insn "mmx_gtv2sf3"
587 [(set (match_operand:V2SI 0 "register_operand" "=y")
588 (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
589 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
591 "pfcmpgt\t{%2, %0|%0, %2}"
592 [(set_attr "type" "mmxcmp")
593 (set_attr "prefix_extra" "1")
594 (set_attr "mode" "V2SF")])
596 (define_insn "mmx_gev2sf3"
597 [(set (match_operand:V2SI 0 "register_operand" "=y")
598 (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
599 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
601 "pfcmpge\t{%2, %0|%0, %2}"
602 [(set_attr "type" "mmxcmp")
603 (set_attr "prefix_extra" "1")
604 (set_attr "mode" "V2SF")])
606 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
608 ;; Parallel single-precision floating point conversion operations
610 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
612 (define_insn "mmx_pf2id"
613 [(set (match_operand:V2SI 0 "register_operand" "=y")
614 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
616 "pf2id\t{%1, %0|%0, %1}"
617 [(set_attr "type" "mmxcvt")
618 (set_attr "prefix_extra" "1")
619 (set_attr "mode" "V2SF")])
621 (define_insn "mmx_pf2iw"
622 [(set (match_operand:V2SI 0 "register_operand" "=y")
626 (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
628 "pf2iw\t{%1, %0|%0, %1}"
629 [(set_attr "type" "mmxcvt")
630 (set_attr "prefix_extra" "1")
631 (set_attr "mode" "V2SF")])
633 (define_insn "mmx_pi2fw"
634 [(set (match_operand:V2SF 0 "register_operand" "=y")
638 (match_operand:V2SI 1 "nonimmediate_operand" "ym")))))]
640 "pi2fw\t{%1, %0|%0, %1}"
641 [(set_attr "type" "mmxcvt")
642 (set_attr "prefix_extra" "1")
643 (set_attr "mode" "V2SF")])
645 (define_insn "mmx_floatv2si2"
646 [(set (match_operand:V2SF 0 "register_operand" "=y")
647 (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
649 "pi2fd\t{%1, %0|%0, %1}"
650 [(set_attr "type" "mmxcvt")
651 (set_attr "prefix_extra" "1")
652 (set_attr "mode" "V2SF")])
654 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
656 ;; Parallel single-precision floating point element swizzling
658 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
660 (define_insn "mmx_pswapdv2sf2"
661 [(set (match_operand:V2SF 0 "register_operand" "=y")
662 (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
663 (parallel [(const_int 1) (const_int 0)])))]
665 "pswapd\t{%1, %0|%0, %1}"
666 [(set_attr "type" "mmxcvt")
667 (set_attr "prefix_extra" "1")
668 (set_attr "mode" "V2SF")])
670 (define_insn "*vec_dupv2sf"
671 [(set (match_operand:V2SF 0 "register_operand" "=y")
673 (match_operand:SF 1 "register_operand" "0")))]
676 [(set_attr "type" "mmxcvt")
677 (set_attr "mode" "DI")])
679 (define_insn "*mmx_concatv2sf"
680 [(set (match_operand:V2SF 0 "register_operand" "=y,y")
682 (match_operand:SF 1 "nonimmediate_operand" " 0,rm")
683 (match_operand:SF 2 "vector_move_operand" "ym,C")))]
684 "TARGET_MMX && !TARGET_SSE"
686 punpckldq\t{%2, %0|%0, %2}
687 movd\t{%1, %0|%0, %1}"
688 [(set_attr "type" "mmxcvt,mmxmov")
689 (set_attr "mode" "DI")])
691 (define_expand "vec_setv2sf"
692 [(match_operand:V2SF 0 "register_operand")
693 (match_operand:SF 1 "register_operand")
694 (match_operand 2 "const_int_operand")]
697 ix86_expand_vector_set (false, operands[0], operands[1],
698 INTVAL (operands[2]));
702 ;; Avoid combining registers from different units in a single alternative,
703 ;; see comment above inline_secondary_memory_needed function in i386.c
704 (define_insn_and_split "*vec_extractv2sf_0"
705 [(set (match_operand:SF 0 "nonimmediate_operand" "=x, m,y ,m,f,r")
707 (match_operand:V2SF 1 "nonimmediate_operand" " xm,x,ym,y,m,m")
708 (parallel [(const_int 0)])))]
709 "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
711 "&& reload_completed"
714 rtx op1 = operands[1];
716 op1 = gen_rtx_REG (SFmode, REGNO (op1));
718 op1 = gen_lowpart (SFmode, op1);
719 emit_move_insn (operands[0], op1);
723 ;; Avoid combining registers from different units in a single alternative,
724 ;; see comment above inline_secondary_memory_needed function in i386.c
725 (define_insn "*vec_extractv2sf_1"
726 [(set (match_operand:SF 0 "nonimmediate_operand" "=y,x,y,x,f,r")
728 (match_operand:V2SF 1 "nonimmediate_operand" " 0,0,o,o,o,o")
729 (parallel [(const_int 1)])))]
730 "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
738 [(set_attr "type" "mmxcvt,sselog1,mmxmov,ssemov,fmov,imov")
739 (set_attr "mode" "DI,V4SF,SF,SF,SF,SF")])
742 [(set (match_operand:SF 0 "register_operand")
744 (match_operand:V2SF 1 "memory_operand")
745 (parallel [(const_int 1)])))]
746 "TARGET_MMX && reload_completed"
749 operands[1] = adjust_address (operands[1], SFmode, 4);
750 emit_move_insn (operands[0], operands[1]);
754 (define_expand "vec_extractv2sf"
755 [(match_operand:SF 0 "register_operand")
756 (match_operand:V2SF 1 "register_operand")
757 (match_operand 2 "const_int_operand")]
760 ix86_expand_vector_extract (false, operands[0], operands[1],
761 INTVAL (operands[2]));
765 (define_expand "vec_initv2sf"
766 [(match_operand:V2SF 0 "register_operand")
770 ix86_expand_vector_init (false, operands[0], operands[1]);
774 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
776 ;; Parallel integral arithmetic
778 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
780 (define_expand "mmx_<plusminus_insn><mode>3"
781 [(set (match_operand:MMXMODEI8 0 "register_operand")
783 (match_operand:MMXMODEI8 1 "nonimmediate_operand")
784 (match_operand:MMXMODEI8 2 "nonimmediate_operand")))]
785 "TARGET_MMX || (TARGET_SSE2 && <MODE>mode == V1DImode)"
786 "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
788 (define_insn "*mmx_<plusminus_insn><mode>3"
789 [(set (match_operand:MMXMODEI8 0 "register_operand" "=y")
791 (match_operand:MMXMODEI8 1 "nonimmediate_operand" "<comm>0")
792 (match_operand:MMXMODEI8 2 "nonimmediate_operand" "ym")))]
793 "(TARGET_MMX || (TARGET_SSE2 && <MODE>mode == V1DImode))
794 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
795 "p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}"
796 [(set_attr "type" "mmxadd")
797 (set_attr "mode" "DI")])
799 (define_expand "mmx_<plusminus_insn><mode>3"
800 [(set (match_operand:MMXMODE12 0 "register_operand")
801 (sat_plusminus:MMXMODE12
802 (match_operand:MMXMODE12 1 "nonimmediate_operand")
803 (match_operand:MMXMODE12 2 "nonimmediate_operand")))]
805 "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
807 (define_insn "*mmx_<plusminus_insn><mode>3"
808 [(set (match_operand:MMXMODE12 0 "register_operand" "=y")
809 (sat_plusminus:MMXMODE12
810 (match_operand:MMXMODE12 1 "nonimmediate_operand" "<comm>0")
811 (match_operand:MMXMODE12 2 "nonimmediate_operand" "ym")))]
812 "TARGET_MMX && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
813 "p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}"
814 [(set_attr "type" "mmxadd")
815 (set_attr "mode" "DI")])
817 (define_expand "mmx_mulv4hi3"
818 [(set (match_operand:V4HI 0 "register_operand")
819 (mult:V4HI (match_operand:V4HI 1 "nonimmediate_operand")
820 (match_operand:V4HI 2 "nonimmediate_operand")))]
822 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
824 (define_insn "*mmx_mulv4hi3"
825 [(set (match_operand:V4HI 0 "register_operand" "=y")
826 (mult:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "%0")
827 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
828 "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
829 "pmullw\t{%2, %0|%0, %2}"
830 [(set_attr "type" "mmxmul")
831 (set_attr "mode" "DI")])
833 (define_expand "mmx_smulv4hi3_highpart"
834 [(set (match_operand:V4HI 0 "register_operand")
839 (match_operand:V4HI 1 "nonimmediate_operand"))
841 (match_operand:V4HI 2 "nonimmediate_operand")))
844 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
846 (define_insn "*mmx_smulv4hi3_highpart"
847 [(set (match_operand:V4HI 0 "register_operand" "=y")
852 (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
854 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
856 "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
857 "pmulhw\t{%2, %0|%0, %2}"
858 [(set_attr "type" "mmxmul")
859 (set_attr "mode" "DI")])
861 (define_expand "mmx_umulv4hi3_highpart"
862 [(set (match_operand:V4HI 0 "register_operand")
867 (match_operand:V4HI 1 "nonimmediate_operand"))
869 (match_operand:V4HI 2 "nonimmediate_operand")))
871 "TARGET_SSE || TARGET_3DNOW_A"
872 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
874 (define_insn "*mmx_umulv4hi3_highpart"
875 [(set (match_operand:V4HI 0 "register_operand" "=y")
880 (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
882 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
884 "(TARGET_SSE || TARGET_3DNOW_A)
885 && ix86_binary_operator_ok (MULT, V4HImode, operands)"
886 "pmulhuw\t{%2, %0|%0, %2}"
887 [(set_attr "type" "mmxmul")
888 (set_attr "mode" "DI")])
890 (define_expand "mmx_pmaddwd"
891 [(set (match_operand:V2SI 0 "register_operand")
896 (match_operand:V4HI 1 "nonimmediate_operand")
897 (parallel [(const_int 0) (const_int 2)])))
900 (match_operand:V4HI 2 "nonimmediate_operand")
901 (parallel [(const_int 0) (const_int 2)]))))
904 (vec_select:V2HI (match_dup 1)
905 (parallel [(const_int 1) (const_int 3)])))
907 (vec_select:V2HI (match_dup 2)
908 (parallel [(const_int 1) (const_int 3)]))))))]
910 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
912 (define_insn "*mmx_pmaddwd"
913 [(set (match_operand:V2SI 0 "register_operand" "=y")
918 (match_operand:V4HI 1 "nonimmediate_operand" "%0")
919 (parallel [(const_int 0) (const_int 2)])))
922 (match_operand:V4HI 2 "nonimmediate_operand" "ym")
923 (parallel [(const_int 0) (const_int 2)]))))
926 (vec_select:V2HI (match_dup 1)
927 (parallel [(const_int 1) (const_int 3)])))
929 (vec_select:V2HI (match_dup 2)
930 (parallel [(const_int 1) (const_int 3)]))))))]
931 "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
932 "pmaddwd\t{%2, %0|%0, %2}"
933 [(set_attr "type" "mmxmul")
934 (set_attr "mode" "DI")])
936 (define_expand "mmx_pmulhrwv4hi3"
937 [(set (match_operand:V4HI 0 "register_operand")
943 (match_operand:V4HI 1 "nonimmediate_operand"))
945 (match_operand:V4HI 2 "nonimmediate_operand")))
946 (const_vector:V4SI [(const_int 32768) (const_int 32768)
947 (const_int 32768) (const_int 32768)]))
950 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
952 (define_insn "*mmx_pmulhrwv4hi3"
953 [(set (match_operand:V4HI 0 "register_operand" "=y")
959 (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
961 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
962 (const_vector:V4SI [(const_int 32768) (const_int 32768)
963 (const_int 32768) (const_int 32768)]))
965 "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V4HImode, operands)"
966 "pmulhrw\t{%2, %0|%0, %2}"
967 [(set_attr "type" "mmxmul")
968 (set_attr "prefix_extra" "1")
969 (set_attr "mode" "DI")])
971 (define_expand "sse2_umulv1siv1di3"
972 [(set (match_operand:V1DI 0 "register_operand")
976 (match_operand:V2SI 1 "nonimmediate_operand")
977 (parallel [(const_int 0)])))
980 (match_operand:V2SI 2 "nonimmediate_operand")
981 (parallel [(const_int 0)])))))]
983 "ix86_fixup_binary_operands_no_copy (MULT, V2SImode, operands);")
985 (define_insn "*sse2_umulv1siv1di3"
986 [(set (match_operand:V1DI 0 "register_operand" "=y")
990 (match_operand:V2SI 1 "nonimmediate_operand" "%0")
991 (parallel [(const_int 0)])))
994 (match_operand:V2SI 2 "nonimmediate_operand" "ym")
995 (parallel [(const_int 0)])))))]
996 "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V2SImode, operands)"
997 "pmuludq\t{%2, %0|%0, %2}"
998 [(set_attr "type" "mmxmul")
999 (set_attr "mode" "DI")])
1001 (define_expand "mmx_<code>v4hi3"
1002 [(set (match_operand:V4HI 0 "register_operand")
1004 (match_operand:V4HI 1 "nonimmediate_operand")
1005 (match_operand:V4HI 2 "nonimmediate_operand")))]
1006 "TARGET_SSE || TARGET_3DNOW_A"
1007 "ix86_fixup_binary_operands_no_copy (<CODE>, V4HImode, operands);")
1009 (define_insn "*mmx_<code>v4hi3"
1010 [(set (match_operand:V4HI 0 "register_operand" "=y")
1012 (match_operand:V4HI 1 "nonimmediate_operand" "%0")
1013 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
1014 "(TARGET_SSE || TARGET_3DNOW_A)
1015 && ix86_binary_operator_ok (<CODE>, V4HImode, operands)"
1016 "p<maxmin_int>w\t{%2, %0|%0, %2}"
1017 [(set_attr "type" "mmxadd")
1018 (set_attr "mode" "DI")])
1020 (define_expand "mmx_<code>v8qi3"
1021 [(set (match_operand:V8QI 0 "register_operand")
1023 (match_operand:V8QI 1 "nonimmediate_operand")
1024 (match_operand:V8QI 2 "nonimmediate_operand")))]
1025 "TARGET_SSE || TARGET_3DNOW_A"
1026 "ix86_fixup_binary_operands_no_copy (<CODE>, V8QImode, operands);")
1028 (define_insn "*mmx_<code>v8qi3"
1029 [(set (match_operand:V8QI 0 "register_operand" "=y")
1031 (match_operand:V8QI 1 "nonimmediate_operand" "%0")
1032 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
1033 "(TARGET_SSE || TARGET_3DNOW_A)
1034 && ix86_binary_operator_ok (<CODE>, V8QImode, operands)"
1035 "p<maxmin_int>b\t{%2, %0|%0, %2}"
1036 [(set_attr "type" "mmxadd")
1037 (set_attr "mode" "DI")])
1039 (define_insn "mmx_ashr<mode>3"
1040 [(set (match_operand:MMXMODE24 0 "register_operand" "=y")
1042 (match_operand:MMXMODE24 1 "register_operand" "0")
1043 (match_operand:SI 2 "nonmemory_operand" "yN")))]
1045 "psra<mmxvecsize>\t{%2, %0|%0, %2}"
1046 [(set_attr "type" "mmxshft")
1047 (set (attr "length_immediate")
1048 (if_then_else (match_operand 2 "const_int_operand")
1050 (const_string "0")))
1051 (set_attr "mode" "DI")])
1053 (define_insn "mmx_<shift_insn><mode>3"
1054 [(set (match_operand:MMXMODE248 0 "register_operand" "=y")
1055 (any_lshift:MMXMODE248
1056 (match_operand:MMXMODE248 1 "register_operand" "0")
1057 (match_operand:SI 2 "nonmemory_operand" "yN")))]
1059 "p<vshift><mmxvecsize>\t{%2, %0|%0, %2}"
1060 [(set_attr "type" "mmxshft")
1061 (set (attr "length_immediate")
1062 (if_then_else (match_operand 2 "const_int_operand")
1064 (const_string "0")))
1065 (set_attr "mode" "DI")])
1067 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1069 ;; Parallel integral comparisons
1071 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1073 (define_expand "mmx_eq<mode>3"
1074 [(set (match_operand:MMXMODEI 0 "register_operand")
1076 (match_operand:MMXMODEI 1 "nonimmediate_operand")
1077 (match_operand:MMXMODEI 2 "nonimmediate_operand")))]
1079 "ix86_fixup_binary_operands_no_copy (EQ, <MODE>mode, operands);")
1081 (define_insn "*mmx_eq<mode>3"
1082 [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
1084 (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
1085 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
1086 "TARGET_MMX && ix86_binary_operator_ok (EQ, <MODE>mode, operands)"
1087 "pcmpeq<mmxvecsize>\t{%2, %0|%0, %2}"
1088 [(set_attr "type" "mmxcmp")
1089 (set_attr "mode" "DI")])
1091 (define_insn "mmx_gt<mode>3"
1092 [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
1094 (match_operand:MMXMODEI 1 "register_operand" "0")
1095 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
1097 "pcmpgt<mmxvecsize>\t{%2, %0|%0, %2}"
1098 [(set_attr "type" "mmxcmp")
1099 (set_attr "mode" "DI")])
1101 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1103 ;; Parallel integral logical operations
1105 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1107 (define_insn "mmx_andnot<mode>3"
1108 [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
1110 (not:MMXMODEI (match_operand:MMXMODEI 1 "register_operand" "0"))
1111 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
1113 "pandn\t{%2, %0|%0, %2}"
1114 [(set_attr "type" "mmxadd")
1115 (set_attr "mode" "DI")])
1117 (define_expand "mmx_<code><mode>3"
1118 [(set (match_operand:MMXMODEI 0 "register_operand")
1120 (match_operand:MMXMODEI 1 "nonimmediate_operand")
1121 (match_operand:MMXMODEI 2 "nonimmediate_operand")))]
1123 "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
1125 (define_insn "*mmx_<code><mode>3"
1126 [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
1128 (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
1129 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
1130 "TARGET_MMX && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
1131 "p<logic>\t{%2, %0|%0, %2}"
1132 [(set_attr "type" "mmxadd")
1133 (set_attr "mode" "DI")])
1135 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1137 ;; Parallel integral element swizzling
1139 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1141 (define_insn "mmx_packsswb"
1142 [(set (match_operand:V8QI 0 "register_operand" "=y")
1145 (match_operand:V4HI 1 "register_operand" "0"))
1147 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))))]
1149 "packsswb\t{%2, %0|%0, %2}"
1150 [(set_attr "type" "mmxshft")
1151 (set_attr "mode" "DI")])
1153 (define_insn "mmx_packssdw"
1154 [(set (match_operand:V4HI 0 "register_operand" "=y")
1157 (match_operand:V2SI 1 "register_operand" "0"))
1159 (match_operand:V2SI 2 "nonimmediate_operand" "ym"))))]
1161 "packssdw\t{%2, %0|%0, %2}"
1162 [(set_attr "type" "mmxshft")
1163 (set_attr "mode" "DI")])
1165 (define_insn "mmx_packuswb"
1166 [(set (match_operand:V8QI 0 "register_operand" "=y")
1169 (match_operand:V4HI 1 "register_operand" "0"))
1171 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))))]
1173 "packuswb\t{%2, %0|%0, %2}"
1174 [(set_attr "type" "mmxshft")
1175 (set_attr "mode" "DI")])
1177 (define_insn "mmx_punpckhbw"
1178 [(set (match_operand:V8QI 0 "register_operand" "=y")
1181 (match_operand:V8QI 1 "register_operand" "0")
1182 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
1183 (parallel [(const_int 4) (const_int 12)
1184 (const_int 5) (const_int 13)
1185 (const_int 6) (const_int 14)
1186 (const_int 7) (const_int 15)])))]
1188 "punpckhbw\t{%2, %0|%0, %2}"
1189 [(set_attr "type" "mmxcvt")
1190 (set_attr "mode" "DI")])
1192 (define_insn "mmx_punpcklbw"
1193 [(set (match_operand:V8QI 0 "register_operand" "=y")
1196 (match_operand:V8QI 1 "register_operand" "0")
1197 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
1198 (parallel [(const_int 0) (const_int 8)
1199 (const_int 1) (const_int 9)
1200 (const_int 2) (const_int 10)
1201 (const_int 3) (const_int 11)])))]
1203 "punpcklbw\t{%2, %0|%0, %2}"
1204 [(set_attr "type" "mmxcvt")
1205 (set_attr "mode" "DI")])
1207 (define_insn "mmx_punpckhwd"
1208 [(set (match_operand:V4HI 0 "register_operand" "=y")
1211 (match_operand:V4HI 1 "register_operand" "0")
1212 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
1213 (parallel [(const_int 2) (const_int 6)
1214 (const_int 3) (const_int 7)])))]
1216 "punpckhwd\t{%2, %0|%0, %2}"
1217 [(set_attr "type" "mmxcvt")
1218 (set_attr "mode" "DI")])
1220 (define_insn "mmx_punpcklwd"
1221 [(set (match_operand:V4HI 0 "register_operand" "=y")
1224 (match_operand:V4HI 1 "register_operand" "0")
1225 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
1226 (parallel [(const_int 0) (const_int 4)
1227 (const_int 1) (const_int 5)])))]
1229 "punpcklwd\t{%2, %0|%0, %2}"
1230 [(set_attr "type" "mmxcvt")
1231 (set_attr "mode" "DI")])
1233 (define_insn "mmx_punpckhdq"
1234 [(set (match_operand:V2SI 0 "register_operand" "=y")
1237 (match_operand:V2SI 1 "register_operand" "0")
1238 (match_operand:V2SI 2 "nonimmediate_operand" "ym"))
1239 (parallel [(const_int 1)
1242 "punpckhdq\t{%2, %0|%0, %2}"
1243 [(set_attr "type" "mmxcvt")
1244 (set_attr "mode" "DI")])
1246 (define_insn "mmx_punpckldq"
1247 [(set (match_operand:V2SI 0 "register_operand" "=y")
1250 (match_operand:V2SI 1 "register_operand" "0")
1251 (match_operand:V2SI 2 "nonimmediate_operand" "ym"))
1252 (parallel [(const_int 0)
1255 "punpckldq\t{%2, %0|%0, %2}"
1256 [(set_attr "type" "mmxcvt")
1257 (set_attr "mode" "DI")])
1259 (define_expand "mmx_pinsrw"
1260 [(set (match_operand:V4HI 0 "register_operand")
1263 (match_operand:SI 2 "nonimmediate_operand"))
1264 (match_operand:V4HI 1 "register_operand")
1265 (match_operand:SI 3 "const_0_to_3_operand")))]
1266 "TARGET_SSE || TARGET_3DNOW_A"
1268 operands[2] = gen_lowpart (HImode, operands[2]);
1269 operands[3] = GEN_INT (1 << INTVAL (operands[3]));
1272 (define_insn "*mmx_pinsrw"
1273 [(set (match_operand:V4HI 0 "register_operand" "=y")
1276 (match_operand:HI 2 "nonimmediate_operand" "rm"))
1277 (match_operand:V4HI 1 "register_operand" "0")
1278 (match_operand:SI 3 "const_int_operand")))]
1279 "(TARGET_SSE || TARGET_3DNOW_A)
1280 && ((unsigned) exact_log2 (INTVAL (operands[3]))
1281 < GET_MODE_NUNITS (V4HImode))"
1283 operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
1284 if (MEM_P (operands[2]))
1285 return "pinsrw\t{%3, %2, %0|%0, %2, %3}";
1287 return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}";
1289 [(set_attr "type" "mmxcvt")
1290 (set_attr "length_immediate" "1")
1291 (set_attr "mode" "DI")])
1293 (define_insn "mmx_pextrw"
1294 [(set (match_operand:SI 0 "register_operand" "=r")
1297 (match_operand:V4HI 1 "register_operand" "y")
1298 (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n")]))))]
1299 "TARGET_SSE || TARGET_3DNOW_A"
1300 "pextrw\t{%2, %1, %0|%0, %1, %2}"
1301 [(set_attr "type" "mmxcvt")
1302 (set_attr "length_immediate" "1")
1303 (set_attr "mode" "DI")])
1305 (define_expand "mmx_pshufw"
1306 [(match_operand:V4HI 0 "register_operand")
1307 (match_operand:V4HI 1 "nonimmediate_operand")
1308 (match_operand:SI 2 "const_int_operand")]
1309 "TARGET_SSE || TARGET_3DNOW_A"
1311 int mask = INTVAL (operands[2]);
1312 emit_insn (gen_mmx_pshufw_1 (operands[0], operands[1],
1313 GEN_INT ((mask >> 0) & 3),
1314 GEN_INT ((mask >> 2) & 3),
1315 GEN_INT ((mask >> 4) & 3),
1316 GEN_INT ((mask >> 6) & 3)));
1320 (define_insn "mmx_pshufw_1"
1321 [(set (match_operand:V4HI 0 "register_operand" "=y")
1323 (match_operand:V4HI 1 "nonimmediate_operand" "ym")
1324 (parallel [(match_operand 2 "const_0_to_3_operand")
1325 (match_operand 3 "const_0_to_3_operand")
1326 (match_operand 4 "const_0_to_3_operand")
1327 (match_operand 5 "const_0_to_3_operand")])))]
1328 "TARGET_SSE || TARGET_3DNOW_A"
1331 mask |= INTVAL (operands[2]) << 0;
1332 mask |= INTVAL (operands[3]) << 2;
1333 mask |= INTVAL (operands[4]) << 4;
1334 mask |= INTVAL (operands[5]) << 6;
1335 operands[2] = GEN_INT (mask);
1337 return "pshufw\t{%2, %1, %0|%0, %1, %2}";
1339 [(set_attr "type" "mmxcvt")
1340 (set_attr "length_immediate" "1")
1341 (set_attr "mode" "DI")])
1343 (define_insn "mmx_pswapdv2si2"
1344 [(set (match_operand:V2SI 0 "register_operand" "=y")
1346 (match_operand:V2SI 1 "nonimmediate_operand" "ym")
1347 (parallel [(const_int 1) (const_int 0)])))]
1349 "pswapd\t{%1, %0|%0, %1}"
1350 [(set_attr "type" "mmxcvt")
1351 (set_attr "prefix_extra" "1")
1352 (set_attr "mode" "DI")])
1354 (define_insn "*vec_dupv4hi"
1355 [(set (match_operand:V4HI 0 "register_operand" "=y")
1358 (match_operand:SI 1 "register_operand" "0"))))]
1359 "TARGET_SSE || TARGET_3DNOW_A"
1360 "pshufw\t{$0, %0, %0|%0, %0, 0}"
1361 [(set_attr "type" "mmxcvt")
1362 (set_attr "length_immediate" "1")
1363 (set_attr "mode" "DI")])
1365 (define_insn "*vec_dupv2si"
1366 [(set (match_operand:V2SI 0 "register_operand" "=y")
1368 (match_operand:SI 1 "register_operand" "0")))]
1371 [(set_attr "type" "mmxcvt")
1372 (set_attr "mode" "DI")])
1374 (define_insn "*mmx_concatv2si"
1375 [(set (match_operand:V2SI 0 "register_operand" "=y,y")
1377 (match_operand:SI 1 "nonimmediate_operand" " 0,rm")
1378 (match_operand:SI 2 "vector_move_operand" "ym,C")))]
1379 "TARGET_MMX && !TARGET_SSE"
1381 punpckldq\t{%2, %0|%0, %2}
1382 movd\t{%1, %0|%0, %1}"
1383 [(set_attr "type" "mmxcvt,mmxmov")
1384 (set_attr "mode" "DI")])
1386 (define_expand "vec_setv2si"
1387 [(match_operand:V2SI 0 "register_operand")
1388 (match_operand:SI 1 "register_operand")
1389 (match_operand 2 "const_int_operand")]
1392 ix86_expand_vector_set (false, operands[0], operands[1],
1393 INTVAL (operands[2]));
1397 ;; Avoid combining registers from different units in a single alternative,
1398 ;; see comment above inline_secondary_memory_needed function in i386.c
1399 (define_insn_and_split "*vec_extractv2si_0"
1400 [(set (match_operand:SI 0 "nonimmediate_operand" "=x,m,y, m,r")
1402 (match_operand:V2SI 1 "nonimmediate_operand" "xm,x,ym,y,m")
1403 (parallel [(const_int 0)])))]
1404 "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1406 "&& reload_completed"
1409 rtx op1 = operands[1];
1411 op1 = gen_rtx_REG (SImode, REGNO (op1));
1413 op1 = gen_lowpart (SImode, op1);
1414 emit_move_insn (operands[0], op1);
1418 ;; Avoid combining registers from different units in a single alternative,
1419 ;; see comment above inline_secondary_memory_needed function in i386.c
1420 (define_insn "*vec_extractv2si_1"
1421 [(set (match_operand:SI 0 "nonimmediate_operand" "=y,x,x,x,y,x,r")
1423 (match_operand:V2SI 1 "nonimmediate_operand" " 0,0,x,0,o,o,o")
1424 (parallel [(const_int 1)])))]
1425 "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1429 pshufd\t{$85, %1, %0|%0, %1, 85}
1435 (if_then_else (eq_attr "alternative" "1,2")
1436 (const_string "sse2")
1437 (const_string "*")))
1438 (set_attr "type" "mmxcvt,sselog1,sselog1,sselog1,mmxmov,ssemov,imov")
1439 (set_attr "length_immediate" "*,*,1,*,*,*,*")
1440 (set_attr "mode" "DI,TI,TI,V4SF,SI,SI,SI")])
1443 [(set (match_operand:SI 0 "register_operand")
1445 (match_operand:V2SI 1 "memory_operand")
1446 (parallel [(const_int 1)])))]
1447 "TARGET_MMX && reload_completed"
1450 operands[1] = adjust_address (operands[1], SImode, 4);
1451 emit_move_insn (operands[0], operands[1]);
1455 (define_expand "vec_extractv2si"
1456 [(match_operand:SI 0 "register_operand")
1457 (match_operand:V2SI 1 "register_operand")
1458 (match_operand 2 "const_int_operand")]
1461 ix86_expand_vector_extract (false, operands[0], operands[1],
1462 INTVAL (operands[2]));
1466 (define_expand "vec_initv2si"
1467 [(match_operand:V2SI 0 "register_operand")
1471 ix86_expand_vector_init (false, operands[0], operands[1]);
1475 (define_expand "vec_setv4hi"
1476 [(match_operand:V4HI 0 "register_operand")
1477 (match_operand:HI 1 "register_operand")
1478 (match_operand 2 "const_int_operand")]
1481 ix86_expand_vector_set (false, operands[0], operands[1],
1482 INTVAL (operands[2]));
1486 (define_expand "vec_extractv4hi"
1487 [(match_operand:HI 0 "register_operand")
1488 (match_operand:V4HI 1 "register_operand")
1489 (match_operand 2 "const_int_operand")]
1492 ix86_expand_vector_extract (false, operands[0], operands[1],
1493 INTVAL (operands[2]));
1497 (define_expand "vec_initv4hi"
1498 [(match_operand:V4HI 0 "register_operand")
1502 ix86_expand_vector_init (false, operands[0], operands[1]);
1506 (define_expand "vec_setv8qi"
1507 [(match_operand:V8QI 0 "register_operand")
1508 (match_operand:QI 1 "register_operand")
1509 (match_operand 2 "const_int_operand")]
1512 ix86_expand_vector_set (false, operands[0], operands[1],
1513 INTVAL (operands[2]));
1517 (define_expand "vec_extractv8qi"
1518 [(match_operand:QI 0 "register_operand")
1519 (match_operand:V8QI 1 "register_operand")
1520 (match_operand 2 "const_int_operand")]
1523 ix86_expand_vector_extract (false, operands[0], operands[1],
1524 INTVAL (operands[2]));
1528 (define_expand "vec_initv8qi"
1529 [(match_operand:V8QI 0 "register_operand")
1533 ix86_expand_vector_init (false, operands[0], operands[1]);
1537 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1541 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1543 (define_expand "mmx_uavgv8qi3"
1544 [(set (match_operand:V8QI 0 "register_operand")
1550 (match_operand:V8QI 1 "nonimmediate_operand"))
1552 (match_operand:V8QI 2 "nonimmediate_operand")))
1553 (const_vector:V8HI [(const_int 1) (const_int 1)
1554 (const_int 1) (const_int 1)
1555 (const_int 1) (const_int 1)
1556 (const_int 1) (const_int 1)]))
1558 "TARGET_SSE || TARGET_3DNOW"
1559 "ix86_fixup_binary_operands_no_copy (PLUS, V8QImode, operands);")
1561 (define_insn "*mmx_uavgv8qi3"
1562 [(set (match_operand:V8QI 0 "register_operand" "=y")
1568 (match_operand:V8QI 1 "nonimmediate_operand" "%0"))
1570 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))
1571 (const_vector:V8HI [(const_int 1) (const_int 1)
1572 (const_int 1) (const_int 1)
1573 (const_int 1) (const_int 1)
1574 (const_int 1) (const_int 1)]))
1576 "(TARGET_SSE || TARGET_3DNOW)
1577 && ix86_binary_operator_ok (PLUS, V8QImode, operands)"
1579 /* These two instructions have the same operation, but their encoding
1580 is different. Prefer the one that is de facto standard. */
1581 if (TARGET_SSE || TARGET_3DNOW_A)
1582 return "pavgb\t{%2, %0|%0, %2}";
1584 return "pavgusb\t{%2, %0|%0, %2}";
1586 [(set_attr "type" "mmxshft")
1587 (set (attr "prefix_extra")
1589 (not (ior (match_test "TARGET_SSE")
1590 (match_test "TARGET_3DNOW_A")))
1592 (const_string "*")))
1593 (set_attr "mode" "DI")])
1595 (define_expand "mmx_uavgv4hi3"
1596 [(set (match_operand:V4HI 0 "register_operand")
1602 (match_operand:V4HI 1 "nonimmediate_operand"))
1604 (match_operand:V4HI 2 "nonimmediate_operand")))
1605 (const_vector:V4SI [(const_int 1) (const_int 1)
1606 (const_int 1) (const_int 1)]))
1608 "TARGET_SSE || TARGET_3DNOW_A"
1609 "ix86_fixup_binary_operands_no_copy (PLUS, V4HImode, operands);")
1611 (define_insn "*mmx_uavgv4hi3"
1612 [(set (match_operand:V4HI 0 "register_operand" "=y")
1618 (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
1620 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
1621 (const_vector:V4SI [(const_int 1) (const_int 1)
1622 (const_int 1) (const_int 1)]))
1624 "(TARGET_SSE || TARGET_3DNOW_A)
1625 && ix86_binary_operator_ok (PLUS, V4HImode, operands)"
1626 "pavgw\t{%2, %0|%0, %2}"
1627 [(set_attr "type" "mmxshft")
1628 (set_attr "mode" "DI")])
1630 (define_insn "mmx_psadbw"
1631 [(set (match_operand:V1DI 0 "register_operand" "=y")
1632 (unspec:V1DI [(match_operand:V8QI 1 "register_operand" "0")
1633 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
1635 "TARGET_SSE || TARGET_3DNOW_A"
1636 "psadbw\t{%2, %0|%0, %2}"
1637 [(set_attr "type" "mmxshft")
1638 (set_attr "mode" "DI")])
1640 (define_insn "mmx_pmovmskb"
1641 [(set (match_operand:SI 0 "register_operand" "=r")
1642 (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
1644 "TARGET_SSE || TARGET_3DNOW_A"
1645 "pmovmskb\t{%1, %0|%0, %1}"
1646 [(set_attr "type" "mmxcvt")
1647 (set_attr "mode" "DI")])
1649 (define_expand "mmx_maskmovq"
1650 [(set (match_operand:V8QI 0 "memory_operand")
1651 (unspec:V8QI [(match_operand:V8QI 1 "register_operand")
1652 (match_operand:V8QI 2 "register_operand")
1655 "TARGET_SSE || TARGET_3DNOW_A")
1657 (define_insn "*mmx_maskmovq"
1658 [(set (mem:V8QI (match_operand:P 0 "register_operand" "D"))
1659 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
1660 (match_operand:V8QI 2 "register_operand" "y")
1661 (mem:V8QI (match_dup 0))]
1663 "TARGET_SSE || TARGET_3DNOW_A"
1664 ;; @@@ check ordering of operands in intel/nonintel syntax
1665 "maskmovq\t{%2, %1|%1, %2}"
1666 [(set_attr "type" "mmxcvt")
1667 (set_attr "mode" "DI")])
1669 (define_expand "mmx_emms"
1670 [(match_par_dup 0 [(const_int 0)])]
1675 operands[0] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (17));
1677 XVECEXP (operands[0], 0, 0)
1678 = gen_rtx_UNSPEC_VOLATILE (VOIDmode, gen_rtvec (1, const0_rtx),
1681 for (regno = 0; regno < 8; regno++)
1683 XVECEXP (operands[0], 0, regno + 1)
1684 = gen_rtx_CLOBBER (VOIDmode,
1685 gen_rtx_REG (XFmode, FIRST_STACK_REG + regno));
1687 XVECEXP (operands[0], 0, regno + 9)
1688 = gen_rtx_CLOBBER (VOIDmode,
1689 gen_rtx_REG (DImode, FIRST_MMX_REG + regno));
1693 (define_insn "*mmx_emms"
1694 [(match_parallel 0 "emms_operation"
1695 [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)])]
1698 [(set_attr "type" "mmx")
1699 (set_attr "modrm" "0")
1700 (set_attr "memory" "none")])
1702 (define_expand "mmx_femms"
1703 [(match_par_dup 0 [(const_int 0)])]
1708 operands[0] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (17));
1710 XVECEXP (operands[0], 0, 0)
1711 = gen_rtx_UNSPEC_VOLATILE (VOIDmode, gen_rtvec (1, const0_rtx),
1714 for (regno = 0; regno < 8; regno++)
1716 XVECEXP (operands[0], 0, regno + 1)
1717 = gen_rtx_CLOBBER (VOIDmode,
1718 gen_rtx_REG (XFmode, FIRST_STACK_REG + regno));
1720 XVECEXP (operands[0], 0, regno + 9)
1721 = gen_rtx_CLOBBER (VOIDmode,
1722 gen_rtx_REG (DImode, FIRST_MMX_REG + regno));
1726 (define_insn "*mmx_femms"
1727 [(match_parallel 0 "emms_operation"
1728 [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)])]
1731 [(set_attr "type" "mmx")
1732 (set_attr "modrm" "0")
1733 (set_attr "memory" "none")])