1 ;; GCC machine description for MMX and 3dNOW! instructions
2 ;; Copyright (C) 2005-2019 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 "TARGET_SSE2")])
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:MMXMODE 0 "nonimmediate_operand")
72 (match_operand:MMXMODE 1 "nonimmediate_operand"))]
73 "TARGET_MMX || TARGET_MMX_WITH_SSE"
75 ix86_expand_vector_move (<MODE>mode, operands);
79 (define_insn "*mov<mode>_internal"
80 [(set (match_operand:MMXMODE 0 "nonimmediate_operand"
81 "=r ,o ,r,r ,m ,?!y,!y,?!y,m ,r ,?!y,v,v,v,m,r,v,!y,*x")
82 (match_operand:MMXMODE 1 "nonimm_or_0_operand"
83 "rCo,rC,C,rm,rC,C ,!y,m ,?!y,?!y,r ,C,v,m,v,v,r,*x,!y"))]
84 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
85 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
87 switch (get_attr_type (insn))
93 if (get_attr_mode (insn) == MODE_SI)
94 return "mov{l}\t{%1, %k0|%k0, %1}";
96 return "mov{q}\t{%1, %0|%0, %1}";
99 return "pxor\t%0, %0";
102 /* Handle broken assemblers that require movd instead of movq. */
103 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
104 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
105 return "movd\t{%1, %0|%0, %1}";
106 return "movq\t{%1, %0|%0, %1}";
109 if (SSE_REG_P (operands[0]))
110 return "movq2dq\t{%1, %0|%0, %1}";
112 return "movdq2q\t{%1, %0|%0, %1}";
115 return standard_sse_constant_opcode (insn, operands);
118 switch (get_attr_mode (insn))
121 /* Handle broken assemblers that require movd instead of movq. */
122 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
123 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
124 return "%vmovd\t{%1, %0|%0, %1}";
125 return "%vmovq\t{%1, %0|%0, %1}";
127 return "%vmovdqa\t{%1, %0|%0, %1}";
129 return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
132 if (TARGET_AVX && REG_P (operands[0]))
133 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
134 return "%vmovlps\t{%1, %0|%0, %1}";
136 return "%vmovaps\t{%1, %0|%0, %1}";
147 (cond [(eq_attr "alternative" "0,1")
148 (const_string "nox64")
149 (eq_attr "alternative" "2,3,4,9,10")
151 (eq_attr "alternative" "15,16")
152 (const_string "x64_sse2")
153 (eq_attr "alternative" "17,18")
154 (const_string "sse2")
158 (cond [(eq_attr "alternative" "0,1")
159 (const_string "multi")
160 (eq_attr "alternative" "2,3,4")
161 (const_string "imov")
162 (eq_attr "alternative" "5")
164 (eq_attr "alternative" "6,7,8,9,10")
165 (const_string "mmxmov")
166 (eq_attr "alternative" "11")
167 (const_string "sselog1")
168 (eq_attr "alternative" "17,18")
169 (const_string "ssecvt")
171 (const_string "ssemov")))
172 (set (attr "prefix_rex")
173 (if_then_else (eq_attr "alternative" "9,10,15,16")
177 (if_then_else (eq_attr "type" "sselog1,ssemov")
178 (const_string "maybe_vex")
179 (const_string "orig")))
180 (set (attr "prefix_data16")
182 (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
186 (cond [(eq_attr "alternative" "2")
188 (eq_attr "alternative" "11,12")
189 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
190 (match_operand 1 "ext_sse_reg_operand"))
192 (match_test "<MODE>mode == V2SFmode")
193 (const_string "V4SF")
194 (ior (not (match_test "TARGET_SSE2"))
195 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
196 (const_string "V4SF")
197 (match_test "TARGET_AVX")
199 (match_test "optimize_function_for_size_p (cfun)")
200 (const_string "V4SF")
204 (and (eq_attr "alternative" "13,14")
205 (ior (match_test "<MODE>mode == V2SFmode")
206 (not (match_test "TARGET_SSE2"))))
207 (const_string "V2SF")
209 (const_string "DI")))
210 (set (attr "preferred_for_speed")
211 (cond [(eq_attr "alternative" "9,15")
212 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
213 (eq_attr "alternative" "10,16")
214 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
216 (symbol_ref "true")))])
219 [(set (match_operand:MMXMODE 0 "nonimmediate_gr_operand")
220 (match_operand:MMXMODE 1 "nonimmediate_gr_operand"))]
221 "!TARGET_64BIT && reload_completed"
223 "ix86_split_long_move (operands); DONE;")
226 [(set (match_operand:MMXMODE 0 "nonimmediate_gr_operand")
227 (match_operand:MMXMODE 1 "const0_operand"))]
228 "!TARGET_64BIT && reload_completed"
230 "ix86_split_long_move (operands); DONE;")
232 (define_expand "movmisalign<mode>"
233 [(set (match_operand:MMXMODE 0 "nonimmediate_operand")
234 (match_operand:MMXMODE 1 "nonimmediate_operand"))]
235 "TARGET_MMX || TARGET_MMX_WITH_SSE"
237 ix86_expand_vector_move (<MODE>mode, operands);
241 (define_insn "sse_movntq"
242 [(set (match_operand:DI 0 "memory_operand" "=m,m")
243 (unspec:DI [(match_operand:DI 1 "register_operand" "y,r")]
245 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
246 && (TARGET_SSE || TARGET_3DNOW_A)"
248 movntq\t{%1, %0|%0, %1}
249 movnti\t{%1, %0|%0, %1}"
250 [(set_attr "isa" "*,x64")
251 (set_attr "mmx_isa" "native,*")
252 (set_attr "type" "mmxmov,ssemov")
253 (set_attr "mode" "DI")])
255 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
257 ;; Parallel single-precision floating point arithmetic
259 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
261 (define_expand "mmx_addv2sf3"
262 [(set (match_operand:V2SF 0 "register_operand")
264 (match_operand:V2SF 1 "nonimmediate_operand")
265 (match_operand:V2SF 2 "nonimmediate_operand")))]
267 "ix86_fixup_binary_operands_no_copy (PLUS, V2SFmode, operands);")
269 (define_insn "*mmx_addv2sf3"
270 [(set (match_operand:V2SF 0 "register_operand" "=y")
271 (plus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
272 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
273 "TARGET_3DNOW && ix86_binary_operator_ok (PLUS, V2SFmode, operands)"
274 "pfadd\t{%2, %0|%0, %2}"
275 [(set_attr "type" "mmxadd")
276 (set_attr "prefix_extra" "1")
277 (set_attr "mode" "V2SF")])
279 (define_expand "mmx_subv2sf3"
280 [(set (match_operand:V2SF 0 "register_operand")
281 (minus:V2SF (match_operand:V2SF 1 "register_operand")
282 (match_operand:V2SF 2 "nonimmediate_operand")))]
285 (define_expand "mmx_subrv2sf3"
286 [(set (match_operand:V2SF 0 "register_operand")
287 (minus:V2SF (match_operand:V2SF 2 "register_operand")
288 (match_operand:V2SF 1 "nonimmediate_operand")))]
291 (define_insn "*mmx_subv2sf3"
292 [(set (match_operand:V2SF 0 "register_operand" "=y,y")
293 (minus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "0,ym")
294 (match_operand:V2SF 2 "nonimmediate_operand" "ym,0")))]
295 "TARGET_3DNOW && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
297 pfsub\t{%2, %0|%0, %2}
298 pfsubr\t{%1, %0|%0, %1}"
299 [(set_attr "type" "mmxadd")
300 (set_attr "prefix_extra" "1")
301 (set_attr "mode" "V2SF")])
303 (define_expand "mmx_mulv2sf3"
304 [(set (match_operand:V2SF 0 "register_operand")
305 (mult:V2SF (match_operand:V2SF 1 "nonimmediate_operand")
306 (match_operand:V2SF 2 "nonimmediate_operand")))]
308 "ix86_fixup_binary_operands_no_copy (MULT, V2SFmode, operands);")
310 (define_insn "*mmx_mulv2sf3"
311 [(set (match_operand:V2SF 0 "register_operand" "=y")
312 (mult:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
313 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
314 "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V2SFmode, operands)"
315 "pfmul\t{%2, %0|%0, %2}"
316 [(set_attr "type" "mmxmul")
317 (set_attr "prefix_extra" "1")
318 (set_attr "mode" "V2SF")])
320 (define_expand "mmx_<code>v2sf3"
321 [(set (match_operand:V2SF 0 "register_operand")
323 (match_operand:V2SF 1 "nonimmediate_operand")
324 (match_operand:V2SF 2 "nonimmediate_operand")))]
327 if (!flag_finite_math_only || flag_signed_zeros)
329 operands[1] = force_reg (V2SFmode, operands[1]);
330 emit_insn (gen_mmx_ieee_<maxmin_float>v2sf3
331 (operands[0], operands[1], operands[2]));
335 ix86_fixup_binary_operands_no_copy (<CODE>, V2SFmode, operands);
338 ;; These versions of the min/max patterns are intentionally ignorant of
339 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
340 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
341 ;; are undefined in this condition, we're certain this is correct.
343 (define_insn "*mmx_<code>v2sf3"
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 && ix86_binary_operator_ok (<CODE>, V2SFmode, operands)"
349 "pf<maxmin_float>\t{%2, %0|%0, %2}"
350 [(set_attr "type" "mmxadd")
351 (set_attr "prefix_extra" "1")
352 (set_attr "mode" "V2SF")])
354 ;; These versions of the min/max patterns implement exactly the operations
355 ;; min = (op1 < op2 ? op1 : op2)
356 ;; max = (!(op1 < op2) ? op1 : op2)
357 ;; Their operands are not commutative, and thus they may be used in the
358 ;; presence of -0.0 and NaN.
360 (define_insn "mmx_ieee_<ieee_maxmin>v2sf3"
361 [(set (match_operand:V2SF 0 "register_operand" "=y")
363 [(match_operand:V2SF 1 "register_operand" "0")
364 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
367 "pf<ieee_maxmin>\t{%2, %0|%0, %2}"
368 [(set_attr "type" "mmxadd")
369 (set_attr "prefix_extra" "1")
370 (set_attr "mode" "V2SF")])
372 (define_insn "mmx_rcpv2sf2"
373 [(set (match_operand:V2SF 0 "register_operand" "=y")
374 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
377 "pfrcp\t{%1, %0|%0, %1}"
378 [(set_attr "type" "mmx")
379 (set_attr "prefix_extra" "1")
380 (set_attr "mode" "V2SF")])
382 (define_insn "mmx_rcpit1v2sf3"
383 [(set (match_operand:V2SF 0 "register_operand" "=y")
384 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
385 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
388 "pfrcpit1\t{%2, %0|%0, %2}"
389 [(set_attr "type" "mmx")
390 (set_attr "prefix_extra" "1")
391 (set_attr "mode" "V2SF")])
393 (define_insn "mmx_rcpit2v2sf3"
394 [(set (match_operand:V2SF 0 "register_operand" "=y")
395 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
396 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
399 "pfrcpit2\t{%2, %0|%0, %2}"
400 [(set_attr "type" "mmx")
401 (set_attr "prefix_extra" "1")
402 (set_attr "mode" "V2SF")])
404 (define_insn "mmx_rsqrtv2sf2"
405 [(set (match_operand:V2SF 0 "register_operand" "=y")
406 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
409 "pfrsqrt\t{%1, %0|%0, %1}"
410 [(set_attr "type" "mmx")
411 (set_attr "prefix_extra" "1")
412 (set_attr "mode" "V2SF")])
414 (define_insn "mmx_rsqit1v2sf3"
415 [(set (match_operand:V2SF 0 "register_operand" "=y")
416 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
417 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
420 "pfrsqit1\t{%2, %0|%0, %2}"
421 [(set_attr "type" "mmx")
422 (set_attr "prefix_extra" "1")
423 (set_attr "mode" "V2SF")])
425 (define_insn "mmx_haddv2sf3"
426 [(set (match_operand:V2SF 0 "register_operand" "=y")
430 (match_operand:V2SF 1 "register_operand" "0")
431 (parallel [(const_int 0)]))
432 (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
435 (match_operand:V2SF 2 "nonimmediate_operand" "ym")
436 (parallel [(const_int 0)]))
437 (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
439 "pfacc\t{%2, %0|%0, %2}"
440 [(set_attr "type" "mmxadd")
441 (set_attr "prefix_extra" "1")
442 (set_attr "mode" "V2SF")])
444 (define_insn "mmx_hsubv2sf3"
445 [(set (match_operand:V2SF 0 "register_operand" "=y")
449 (match_operand:V2SF 1 "register_operand" "0")
450 (parallel [(const_int 0)]))
451 (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
454 (match_operand:V2SF 2 "nonimmediate_operand" "ym")
455 (parallel [(const_int 0)]))
456 (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
458 "pfnacc\t{%2, %0|%0, %2}"
459 [(set_attr "type" "mmxadd")
460 (set_attr "prefix_extra" "1")
461 (set_attr "mode" "V2SF")])
463 (define_insn "mmx_addsubv2sf3"
464 [(set (match_operand:V2SF 0 "register_operand" "=y")
467 (match_operand:V2SF 1 "register_operand" "0")
468 (match_operand:V2SF 2 "nonimmediate_operand" "ym"))
469 (minus:V2SF (match_dup 1) (match_dup 2))
472 "pfpnacc\t{%2, %0|%0, %2}"
473 [(set_attr "type" "mmxadd")
474 (set_attr "prefix_extra" "1")
475 (set_attr "mode" "V2SF")])
477 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
479 ;; Parallel single-precision floating point comparisons
481 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
483 (define_expand "mmx_eqv2sf3"
484 [(set (match_operand:V2SI 0 "register_operand")
485 (eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand")
486 (match_operand:V2SF 2 "nonimmediate_operand")))]
488 "ix86_fixup_binary_operands_no_copy (EQ, V2SFmode, operands);")
490 (define_insn "*mmx_eqv2sf3"
491 [(set (match_operand:V2SI 0 "register_operand" "=y")
492 (eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "%0")
493 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
494 "TARGET_3DNOW && ix86_binary_operator_ok (EQ, V2SFmode, operands)"
495 "pfcmpeq\t{%2, %0|%0, %2}"
496 [(set_attr "type" "mmxcmp")
497 (set_attr "prefix_extra" "1")
498 (set_attr "mode" "V2SF")])
500 (define_insn "mmx_gtv2sf3"
501 [(set (match_operand:V2SI 0 "register_operand" "=y")
502 (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
503 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
505 "pfcmpgt\t{%2, %0|%0, %2}"
506 [(set_attr "type" "mmxcmp")
507 (set_attr "prefix_extra" "1")
508 (set_attr "mode" "V2SF")])
510 (define_insn "mmx_gev2sf3"
511 [(set (match_operand:V2SI 0 "register_operand" "=y")
512 (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
513 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
515 "pfcmpge\t{%2, %0|%0, %2}"
516 [(set_attr "type" "mmxcmp")
517 (set_attr "prefix_extra" "1")
518 (set_attr "mode" "V2SF")])
520 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
522 ;; Parallel single-precision floating point conversion operations
524 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
526 (define_insn "mmx_pf2id"
527 [(set (match_operand:V2SI 0 "register_operand" "=y")
528 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
530 "pf2id\t{%1, %0|%0, %1}"
531 [(set_attr "type" "mmxcvt")
532 (set_attr "prefix_extra" "1")
533 (set_attr "mode" "V2SF")])
535 (define_insn "mmx_pf2iw"
536 [(set (match_operand:V2SI 0 "register_operand" "=y")
540 (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
542 "pf2iw\t{%1, %0|%0, %1}"
543 [(set_attr "type" "mmxcvt")
544 (set_attr "prefix_extra" "1")
545 (set_attr "mode" "V2SF")])
547 (define_insn "mmx_pi2fw"
548 [(set (match_operand:V2SF 0 "register_operand" "=y")
552 (match_operand:V2SI 1 "nonimmediate_operand" "ym")))))]
554 "pi2fw\t{%1, %0|%0, %1}"
555 [(set_attr "type" "mmxcvt")
556 (set_attr "prefix_extra" "1")
557 (set_attr "mode" "V2SF")])
559 (define_insn "mmx_floatv2si2"
560 [(set (match_operand:V2SF 0 "register_operand" "=y")
561 (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
563 "pi2fd\t{%1, %0|%0, %1}"
564 [(set_attr "type" "mmxcvt")
565 (set_attr "prefix_extra" "1")
566 (set_attr "mode" "V2SF")])
568 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
570 ;; Parallel single-precision floating point element swizzling
572 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
574 (define_insn "mmx_pswapdv2sf2"
575 [(set (match_operand:V2SF 0 "register_operand" "=y")
576 (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
577 (parallel [(const_int 1) (const_int 0)])))]
579 "pswapd\t{%1, %0|%0, %1}"
580 [(set_attr "type" "mmxcvt")
581 (set_attr "prefix_extra" "1")
582 (set_attr "mode" "V2SF")])
584 (define_insn_and_split "*vec_dupv2sf"
585 [(set (match_operand:V2SF 0 "register_operand" "=y,x,Yv")
587 (match_operand:SF 1 "register_operand" "0,0,Yv")))]
588 "TARGET_MMX || TARGET_MMX_WITH_SSE"
593 "TARGET_MMX_WITH_SSE && reload_completed"
595 (vec_duplicate:V4SF (match_dup 1)))]
596 "operands[0] = lowpart_subreg (V4SFmode, operands[0],
597 GET_MODE (operands[0]));"
598 [(set_attr "mmx_isa" "native,sse_noavx,avx")
599 (set_attr "type" "mmxcvt,ssemov,ssemov")
600 (set_attr "mode" "DI,TI,TI")])
602 (define_insn "*mmx_concatv2sf"
603 [(set (match_operand:V2SF 0 "register_operand" "=y,y")
605 (match_operand:SF 1 "nonimmediate_operand" " 0,rm")
606 (match_operand:SF 2 "nonimm_or_0_operand" "ym,C")))]
607 "TARGET_MMX && !TARGET_SSE"
609 punpckldq\t{%2, %0|%0, %2}
610 movd\t{%1, %0|%0, %1}"
611 [(set_attr "type" "mmxcvt,mmxmov")
612 (set_attr "mode" "DI")])
614 (define_expand "vec_setv2sf"
615 [(match_operand:V2SF 0 "register_operand")
616 (match_operand:SF 1 "register_operand")
617 (match_operand 2 "const_int_operand")]
618 "TARGET_MMX || TARGET_MMX_WITH_SSE"
620 ix86_expand_vector_set (TARGET_MMX_WITH_SSE, operands[0], operands[1],
621 INTVAL (operands[2]));
625 ;; Avoid combining registers from different units in a single alternative,
626 ;; see comment above inline_secondary_memory_needed function in i386.c
627 (define_insn_and_split "*vec_extractv2sf_0"
628 [(set (match_operand:SF 0 "nonimmediate_operand" "=x, m,y ,m,f,r")
630 (match_operand:V2SF 1 "nonimmediate_operand" " xm,x,ym,y,m,m")
631 (parallel [(const_int 0)])))]
632 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
633 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
635 "&& reload_completed"
636 [(set (match_dup 0) (match_dup 1))]
637 "operands[1] = gen_lowpart (SFmode, operands[1]);"
638 [(set_attr "mmx_isa" "*,*,native,native,*,*")])
640 ;; Avoid combining registers from different units in a single alternative,
641 ;; see comment above inline_secondary_memory_needed function in i386.c
642 (define_insn "*vec_extractv2sf_1"
643 [(set (match_operand:SF 0 "nonimmediate_operand" "=y,x,x,y,x,f,r")
645 (match_operand:V2SF 1 "nonimmediate_operand" " 0,x,x,o,o,o,o")
646 (parallel [(const_int 1)])))]
647 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
648 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
651 %vmovshdup\t{%1, %0|%0, %1}
652 shufps\t{$0xe5, %1, %0|%0, %1, 0xe5}
657 [(set_attr "isa" "*,sse3,noavx,*,*,*,*")
658 (set_attr "mmx_isa" "native,*,*,native,*,*,*")
659 (set_attr "type" "mmxcvt,sse,sseshuf1,mmxmov,ssemov,fmov,imov")
660 (set (attr "length_immediate")
661 (if_then_else (eq_attr "alternative" "2")
664 (set (attr "prefix_rep")
665 (if_then_else (eq_attr "alternative" "1")
668 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig,orig,orig")
669 (set_attr "mode" "DI,V4SF,V4SF,SF,SF,SF,SF")])
672 [(set (match_operand:SF 0 "register_operand")
674 (match_operand:V2SF 1 "memory_operand")
675 (parallel [(const_int 1)])))]
676 "(TARGET_MMX || TARGET_MMX_WITH_SSE) && reload_completed"
677 [(set (match_dup 0) (match_dup 1))]
678 "operands[1] = adjust_address (operands[1], SFmode, 4);")
680 (define_expand "vec_extractv2sfsf"
681 [(match_operand:SF 0 "register_operand")
682 (match_operand:V2SF 1 "register_operand")
683 (match_operand 2 "const_int_operand")]
684 "TARGET_MMX || TARGET_MMX_WITH_SSE"
686 ix86_expand_vector_extract (TARGET_MMX_WITH_SSE, operands[0],
687 operands[1], INTVAL (operands[2]));
691 (define_expand "vec_initv2sfsf"
692 [(match_operand:V2SF 0 "register_operand")
694 "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_SSE"
696 ix86_expand_vector_init (TARGET_MMX_WITH_SSE, operands[0],
701 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
703 ;; Parallel integral arithmetic
705 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
707 (define_expand "mmx_<plusminus_insn><mode>3"
708 [(set (match_operand:MMXMODEI8 0 "register_operand")
710 (match_operand:MMXMODEI8 1 "register_mmxmem_operand")
711 (match_operand:MMXMODEI8 2 "register_mmxmem_operand")))]
712 "TARGET_MMX || TARGET_MMX_WITH_SSE"
713 "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
715 (define_expand "<plusminus_insn><mode>3"
716 [(set (match_operand:MMXMODEI 0 "register_operand")
718 (match_operand:MMXMODEI 1 "register_operand")
719 (match_operand:MMXMODEI 2 "register_operand")))]
720 "TARGET_MMX_WITH_SSE"
721 "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
723 (define_insn "*mmx_<plusminus_insn><mode>3"
724 [(set (match_operand:MMXMODEI8 0 "register_operand" "=y,x,Yv")
726 (match_operand:MMXMODEI8 1 "register_mmxmem_operand" "<comm>0,0,Yv")
727 (match_operand:MMXMODEI8 2 "register_mmxmem_operand" "ym,x,Yv")))]
728 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
729 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
731 p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}
732 p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}
733 vp<plusminus_mnemonic><mmxvecsize>\t{%2, %1, %0|%0, %1, %2}"
734 [(set_attr "isa" "*,sse2_noavx,avx")
735 (set_attr "mmx_isa" "native,*,*")
736 (set_attr "type" "mmxadd,sseadd,sseadd")
737 (set_attr "mode" "DI,TI,TI")])
739 (define_expand "mmx_<plusminus_insn><mode>3"
740 [(set (match_operand:MMXMODE12 0 "register_operand")
741 (sat_plusminus:MMXMODE12
742 (match_operand:MMXMODE12 1 "register_mmxmem_operand")
743 (match_operand:MMXMODE12 2 "register_mmxmem_operand")))]
744 "TARGET_MMX || TARGET_MMX_WITH_SSE"
745 "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
747 (define_insn "*mmx_<plusminus_insn><mode>3"
748 [(set (match_operand:MMXMODE12 0 "register_operand" "=y,x,Yv")
749 (sat_plusminus:MMXMODE12
750 (match_operand:MMXMODE12 1 "register_mmxmem_operand" "<comm>0,0,Yv")
751 (match_operand:MMXMODE12 2 "register_mmxmem_operand" "ym,x,Yv")))]
752 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
753 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
755 p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}
756 p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}
757 vp<plusminus_mnemonic><mmxvecsize>\t{%2, %1, %0|%0, %1, %2}"
758 [(set_attr "isa" "*,sse2_noavx,avx")
759 (set_attr "mmx_isa" "native,*,*")
760 (set_attr "type" "mmxadd,sseadd,sseadd")
761 (set_attr "mode" "DI,TI,TI")])
763 (define_expand "mmx_mulv4hi3"
764 [(set (match_operand:V4HI 0 "register_operand")
765 (mult:V4HI (match_operand:V4HI 1 "register_mmxmem_operand")
766 (match_operand:V4HI 2 "register_mmxmem_operand")))]
767 "TARGET_MMX || TARGET_MMX_WITH_SSE"
768 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
770 (define_expand "mulv4hi3"
771 [(set (match_operand:V4HI 0 "register_operand")
772 (mult:V4HI (match_operand:V4HI 1 "register_operand")
773 (match_operand:V4HI 2 "register_operand")))]
774 "TARGET_MMX_WITH_SSE"
775 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
777 (define_insn "*mmx_mulv4hi3"
778 [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
779 (mult:V4HI (match_operand:V4HI 1 "register_mmxmem_operand" "%0,0,Yv")
780 (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv")))]
781 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
782 && ix86_binary_operator_ok (MULT, V4HImode, operands)"
784 pmullw\t{%2, %0|%0, %2}
785 pmullw\t{%2, %0|%0, %2}
786 vpmullw\t{%2, %1, %0|%0, %1, %2}"
787 [(set_attr "isa" "*,sse2_noavx,avx")
788 (set_attr "mmx_isa" "native,*,*")
789 (set_attr "type" "mmxmul,ssemul,ssemul")
790 (set_attr "mode" "DI,TI,TI")])
792 (define_expand "mmx_smulv4hi3_highpart"
793 [(set (match_operand:V4HI 0 "register_operand")
798 (match_operand:V4HI 1 "register_mmxmem_operand"))
800 (match_operand:V4HI 2 "register_mmxmem_operand")))
802 "TARGET_MMX || TARGET_MMX_WITH_SSE"
803 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
805 (define_insn "*mmx_smulv4hi3_highpart"
806 [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
811 (match_operand:V4HI 1 "register_mmxmem_operand" "%0,0,Yv"))
813 (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv")))
815 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
816 && ix86_binary_operator_ok (MULT, V4HImode, operands)"
818 pmulhw\t{%2, %0|%0, %2}
819 pmulhw\t{%2, %0|%0, %2}
820 vpmulhw\t{%2, %1, %0|%0, %1, %2}"
821 [(set_attr "isa" "*,sse2_noavx,avx")
822 (set_attr "mmx_isa" "native,*,*")
823 (set_attr "type" "mmxmul,ssemul,ssemul")
824 (set_attr "mode" "DI,TI,TI")])
826 (define_expand "mmx_umulv4hi3_highpart"
827 [(set (match_operand:V4HI 0 "register_operand")
832 (match_operand:V4HI 1 "register_mmxmem_operand"))
834 (match_operand:V4HI 2 "register_mmxmem_operand")))
836 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
837 && (TARGET_SSE || TARGET_3DNOW_A)"
838 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
840 (define_insn "*mmx_umulv4hi3_highpart"
841 [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
846 (match_operand:V4HI 1 "register_mmxmem_operand" "%0,0,Yv"))
848 (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv")))
850 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
851 && (TARGET_SSE || TARGET_3DNOW_A)
852 && ix86_binary_operator_ok (MULT, V4HImode, operands)"
854 pmulhuw\t{%2, %0|%0, %2}
855 pmulhuw\t{%2, %0|%0, %2}
856 vpmulhuw\t{%2, %1, %0|%0, %1, %2}"
857 [(set_attr "isa" "*,sse2_noavx,avx")
858 (set_attr "mmx_isa" "native,*,*")
859 (set_attr "type" "mmxmul,ssemul,ssemul")
860 (set_attr "mode" "DI,TI,TI")])
862 (define_expand "mmx_pmaddwd"
863 [(set (match_operand:V2SI 0 "register_operand")
868 (match_operand:V4HI 1 "register_mmxmem_operand")
869 (parallel [(const_int 0) (const_int 2)])))
872 (match_operand:V4HI 2 "register_mmxmem_operand")
873 (parallel [(const_int 0) (const_int 2)]))))
876 (vec_select:V2HI (match_dup 1)
877 (parallel [(const_int 1) (const_int 3)])))
879 (vec_select:V2HI (match_dup 2)
880 (parallel [(const_int 1) (const_int 3)]))))))]
881 "TARGET_MMX || TARGET_MMX_WITH_SSE"
882 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
884 (define_insn "*mmx_pmaddwd"
885 [(set (match_operand:V2SI 0 "register_operand" "=y,x,Yv")
890 (match_operand:V4HI 1 "register_mmxmem_operand" "%0,0,Yv")
891 (parallel [(const_int 0) (const_int 2)])))
894 (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv")
895 (parallel [(const_int 0) (const_int 2)]))))
898 (vec_select:V2HI (match_dup 1)
899 (parallel [(const_int 1) (const_int 3)])))
901 (vec_select:V2HI (match_dup 2)
902 (parallel [(const_int 1) (const_int 3)]))))))]
903 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
904 && ix86_binary_operator_ok (MULT, V4HImode, operands)"
906 pmaddwd\t{%2, %0|%0, %2}
907 pmaddwd\t{%2, %0|%0, %2}
908 vpmaddwd\t{%2, %1, %0|%0, %1, %2}"
909 [(set_attr "isa" "*,sse2_noavx,avx")
910 (set_attr "mmx_isa" "native,*,*")
911 (set_attr "type" "mmxmul,sseiadd,sseiadd")
912 (set_attr "mode" "DI,TI,TI")])
914 (define_expand "mmx_pmulhrwv4hi3"
915 [(set (match_operand:V4HI 0 "register_operand")
921 (match_operand:V4HI 1 "nonimmediate_operand"))
923 (match_operand:V4HI 2 "nonimmediate_operand")))
924 (const_vector:V4SI [(const_int 32768) (const_int 32768)
925 (const_int 32768) (const_int 32768)]))
928 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
930 (define_insn "*mmx_pmulhrwv4hi3"
931 [(set (match_operand:V4HI 0 "register_operand" "=y")
937 (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
939 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
940 (const_vector:V4SI [(const_int 32768) (const_int 32768)
941 (const_int 32768) (const_int 32768)]))
943 "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V4HImode, operands)"
944 "pmulhrw\t{%2, %0|%0, %2}"
945 [(set_attr "type" "mmxmul")
946 (set_attr "prefix_extra" "1")
947 (set_attr "mode" "DI")])
949 (define_expand "sse2_umulv1siv1di3"
950 [(set (match_operand:V1DI 0 "register_operand")
954 (match_operand:V2SI 1 "register_mmxmem_operand")
955 (parallel [(const_int 0)])))
958 (match_operand:V2SI 2 "register_mmxmem_operand")
959 (parallel [(const_int 0)])))))]
960 "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_SSE2"
961 "ix86_fixup_binary_operands_no_copy (MULT, V2SImode, operands);")
963 (define_insn "*sse2_umulv1siv1di3"
964 [(set (match_operand:V1DI 0 "register_operand" "=y,x,Yv")
968 (match_operand:V2SI 1 "register_mmxmem_operand" "%0,0,Yv")
969 (parallel [(const_int 0)])))
972 (match_operand:V2SI 2 "register_mmxmem_operand" "ym,x,Yv")
973 (parallel [(const_int 0)])))))]
974 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
976 && ix86_binary_operator_ok (MULT, V2SImode, operands)"
978 pmuludq\t{%2, %0|%0, %2}
979 pmuludq\t{%2, %0|%0, %2}
980 vpmuludq\t{%2, %1, %0|%0, %1, %2}"
981 [(set_attr "isa" "*,sse2_noavx,avx")
982 (set_attr "mmx_isa" "native,*,*")
983 (set_attr "type" "mmxmul,ssemul,ssemul")
984 (set_attr "mode" "DI,TI,TI")])
986 (define_expand "mmx_<code>v4hi3"
987 [(set (match_operand:V4HI 0 "register_operand")
989 (match_operand:V4HI 1 "register_mmxmem_operand")
990 (match_operand:V4HI 2 "register_mmxmem_operand")))]
991 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
992 && (TARGET_SSE || TARGET_3DNOW_A)"
993 "ix86_fixup_binary_operands_no_copy (<CODE>, V4HImode, operands);")
995 (define_expand "<code>v4hi3"
996 [(set (match_operand:V4HI 0 "register_operand")
998 (match_operand:V4HI 1 "register_operand")
999 (match_operand:V4HI 2 "register_operand")))]
1000 "TARGET_MMX_WITH_SSE"
1001 "ix86_fixup_binary_operands_no_copy (<CODE>, V4HImode, operands);")
1003 (define_insn "*mmx_<code>v4hi3"
1004 [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
1006 (match_operand:V4HI 1 "register_mmxmem_operand" "%0,0,Yv")
1007 (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv")))]
1008 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1009 && (TARGET_SSE || TARGET_3DNOW_A)
1010 && ix86_binary_operator_ok (<CODE>, V4HImode, operands)"
1012 p<maxmin_int>w\t{%2, %0|%0, %2}
1013 p<maxmin_int>w\t{%2, %0|%0, %2}
1014 vp<maxmin_int>w\t{%2, %1, %0|%0, %1, %2}"
1015 [(set_attr "isa" "*,sse2_noavx,avx")
1016 (set_attr "mmx_isa" "native,*,*")
1017 (set_attr "type" "mmxadd,sseiadd,sseiadd")
1018 (set_attr "mode" "DI,TI,TI")])
1020 (define_expand "mmx_<code>v8qi3"
1021 [(set (match_operand:V8QI 0 "register_operand")
1023 (match_operand:V8QI 1 "register_mmxmem_operand")
1024 (match_operand:V8QI 2 "register_mmxmem_operand")))]
1025 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1026 && (TARGET_SSE || TARGET_3DNOW_A)"
1027 "ix86_fixup_binary_operands_no_copy (<CODE>, V8QImode, operands);")
1029 (define_expand "<code>v8qi3"
1030 [(set (match_operand:V8QI 0 "register_operand")
1032 (match_operand:V8QI 1 "register_operand")
1033 (match_operand:V8QI 2 "register_operand")))]
1034 "TARGET_MMX_WITH_SSE"
1035 "ix86_fixup_binary_operands_no_copy (<CODE>, V8QImode, operands);")
1037 (define_insn "*mmx_<code>v8qi3"
1038 [(set (match_operand:V8QI 0 "register_operand" "=y,x,Yv")
1040 (match_operand:V8QI 1 "register_mmxmem_operand" "%0,0,Yv")
1041 (match_operand:V8QI 2 "register_mmxmem_operand" "ym,x,Yv")))]
1042 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1043 && (TARGET_SSE || TARGET_3DNOW_A)
1044 && ix86_binary_operator_ok (<CODE>, V8QImode, operands)"
1046 p<maxmin_int>b\t{%2, %0|%0, %2}
1047 p<maxmin_int>b\t{%2, %0|%0, %2}
1048 vp<maxmin_int>b\t{%2, %1, %0|%0, %1, %2}"
1049 [(set_attr "isa" "*,sse2_noavx,avx")
1050 (set_attr "mmx_isa" "native,*,*")
1051 (set_attr "type" "mmxadd,sseiadd,sseiadd")
1052 (set_attr "mode" "DI,TI,TI")])
1054 (define_insn "mmx_ashr<mode>3"
1055 [(set (match_operand:MMXMODE24 0 "register_operand" "=y,x,Yv")
1057 (match_operand:MMXMODE24 1 "register_operand" "0,0,Yv")
1058 (match_operand:DI 2 "nonmemory_operand" "yN,xN,YvN")))]
1059 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1061 psra<mmxvecsize>\t{%2, %0|%0, %2}
1062 psra<mmxvecsize>\t{%2, %0|%0, %2}
1063 vpsra<mmxvecsize>\t{%2, %1, %0|%0, %1, %2}"
1064 [(set_attr "isa" "*,sse2_noavx,avx")
1065 (set_attr "mmx_isa" "native,*,*")
1066 (set_attr "type" "mmxshft,sseishft,sseishft")
1067 (set (attr "length_immediate")
1068 (if_then_else (match_operand 2 "const_int_operand")
1070 (const_string "0")))
1071 (set_attr "mode" "DI,TI,TI")])
1073 (define_expand "ashr<mode>3"
1074 [(set (match_operand:MMXMODE24 0 "register_operand")
1076 (match_operand:MMXMODE24 1 "register_operand")
1077 (match_operand:DI 2 "nonmemory_operand")))]
1078 "TARGET_MMX_WITH_SSE")
1080 (define_insn "mmx_<shift_insn><mode>3"
1081 [(set (match_operand:MMXMODE248 0 "register_operand" "=y,x,Yv")
1082 (any_lshift:MMXMODE248
1083 (match_operand:MMXMODE248 1 "register_operand" "0,0,Yv")
1084 (match_operand:DI 2 "nonmemory_operand" "yN,xN,YvN")))]
1085 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1087 p<vshift><mmxvecsize>\t{%2, %0|%0, %2}
1088 p<vshift><mmxvecsize>\t{%2, %0|%0, %2}
1089 vp<vshift><mmxvecsize>\t{%2, %1, %0|%0, %1, %2}"
1090 [(set_attr "isa" "*,sse2_noavx,avx")
1091 (set_attr "mmx_isa" "native,*,*")
1092 (set_attr "type" "mmxshft,sseishft,sseishft")
1093 (set (attr "length_immediate")
1094 (if_then_else (match_operand 2 "const_int_operand")
1096 (const_string "0")))
1097 (set_attr "mode" "DI,TI,TI")])
1099 (define_expand "<shift_insn><mode>3"
1100 [(set (match_operand:MMXMODE248 0 "register_operand")
1101 (any_lshift:MMXMODE248
1102 (match_operand:MMXMODE248 1 "register_operand")
1103 (match_operand:DI 2 "nonmemory_operand")))]
1104 "TARGET_MMX_WITH_SSE")
1106 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1108 ;; Parallel integral comparisons
1110 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1112 (define_expand "mmx_eq<mode>3"
1113 [(set (match_operand:MMXMODEI 0 "register_operand")
1115 (match_operand:MMXMODEI 1 "register_mmxmem_operand")
1116 (match_operand:MMXMODEI 2 "register_mmxmem_operand")))]
1117 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1118 "ix86_fixup_binary_operands_no_copy (EQ, <MODE>mode, operands);")
1120 (define_insn "*mmx_eq<mode>3"
1121 [(set (match_operand:MMXMODEI 0 "register_operand" "=y,x,Yv")
1123 (match_operand:MMXMODEI 1 "register_mmxmem_operand" "%0,0,Yv")
1124 (match_operand:MMXMODEI 2 "register_mmxmem_operand" "ym,x,Yv")))]
1125 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1126 && ix86_binary_operator_ok (EQ, <MODE>mode, operands)"
1128 pcmpeq<mmxvecsize>\t{%2, %0|%0, %2}
1129 pcmpeq<mmxvecsize>\t{%2, %0|%0, %2}
1130 vpcmpeq<mmxvecsize>\t{%2, %1, %0|%0, %1, %2}"
1131 [(set_attr "isa" "*,sse2_noavx,avx")
1132 (set_attr "mmx_isa" "native,*,*")
1133 (set_attr "type" "mmxcmp,ssecmp,ssecmp")
1134 (set_attr "mode" "DI,TI,TI")])
1136 (define_insn "mmx_gt<mode>3"
1137 [(set (match_operand:MMXMODEI 0 "register_operand" "=y,x,Yv")
1139 (match_operand:MMXMODEI 1 "register_operand" "0,0,Yv")
1140 (match_operand:MMXMODEI 2 "register_mmxmem_operand" "ym,x,Yv")))]
1141 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1143 pcmpgt<mmxvecsize>\t{%2, %0|%0, %2}
1144 pcmpgt<mmxvecsize>\t{%2, %0|%0, %2}
1145 vpcmpgt<mmxvecsize>\t{%2, %1, %0|%0, %1, %2}"
1146 [(set_attr "isa" "*,sse2_noavx,avx")
1147 (set_attr "mmx_isa" "native,*,*")
1148 (set_attr "type" "mmxcmp,ssecmp,ssecmp")
1149 (set_attr "mode" "DI,TI,TI")])
1151 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1153 ;; Parallel integral logical operations
1155 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1157 (define_insn "mmx_andnot<mode>3"
1158 [(set (match_operand:MMXMODEI 0 "register_operand" "=y,x,Yv")
1160 (not:MMXMODEI (match_operand:MMXMODEI 1 "register_operand" "0,0,Yv"))
1161 (match_operand:MMXMODEI 2 "register_mmxmem_operand" "ym,x,Yv")))]
1162 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1164 pandn\t{%2, %0|%0, %2}
1165 pandn\t{%2, %0|%0, %2}
1166 vpandn\t{%2, %1, %0|%0, %1, %2}"
1167 [(set_attr "isa" "*,sse2_noavx,avx")
1168 (set_attr "mmx_isa" "native,*,*")
1169 (set_attr "type" "mmxadd,sselog,sselog")
1170 (set_attr "mode" "DI,TI,TI")])
1172 (define_expand "mmx_<code><mode>3"
1173 [(set (match_operand:MMXMODEI 0 "register_operand")
1175 (match_operand:MMXMODEI 1 "register_mmxmem_operand")
1176 (match_operand:MMXMODEI 2 "register_mmxmem_operand")))]
1177 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1178 "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
1180 (define_expand "<code><mode>3"
1181 [(set (match_operand:MMXMODEI 0 "register_operand")
1183 (match_operand:MMXMODEI 1 "register_operand")
1184 (match_operand:MMXMODEI 2 "register_operand")))]
1185 "TARGET_MMX_WITH_SSE"
1186 "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
1188 (define_insn "*mmx_<code><mode>3"
1189 [(set (match_operand:MMXMODEI 0 "register_operand" "=y,x,Yv")
1191 (match_operand:MMXMODEI 1 "register_mmxmem_operand" "%0,0,Yv")
1192 (match_operand:MMXMODEI 2 "register_mmxmem_operand" "ym,x,Yv")))]
1193 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1194 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
1196 p<logic>\t{%2, %0|%0, %2}
1197 p<logic>\t{%2, %0|%0, %2}
1198 vp<logic>\t{%2, %1, %0|%0, %1, %2}"
1199 [(set_attr "isa" "*,sse2_noavx,avx")
1200 (set_attr "mmx_isa" "native,*,*")
1201 (set_attr "type" "mmxadd,sselog,sselog")
1202 (set_attr "mode" "DI,TI,TI")])
1204 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1206 ;; Parallel integral element swizzling
1208 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1210 ;; Used in signed and unsigned truncations with saturation.
1211 (define_code_iterator any_s_truncate [ss_truncate us_truncate])
1212 ;; Instruction suffix for truncations with saturation.
1213 (define_code_attr s_trunsuffix [(ss_truncate "s") (us_truncate "u")])
1215 (define_insn_and_split "mmx_pack<s_trunsuffix>swb"
1216 [(set (match_operand:V8QI 0 "register_operand" "=y,x,Yv")
1218 (any_s_truncate:V4QI
1219 (match_operand:V4HI 1 "register_operand" "0,0,Yv"))
1220 (any_s_truncate:V4QI
1221 (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv"))))]
1222 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1224 pack<s_trunsuffix>swb\t{%2, %0|%0, %2}
1227 "TARGET_MMX_WITH_SSE && reload_completed"
1229 "ix86_split_mmx_pack (operands, <any_s_truncate:CODE>); DONE;"
1230 [(set_attr "mmx_isa" "native,sse_noavx,avx")
1231 (set_attr "type" "mmxshft,sselog,sselog")
1232 (set_attr "mode" "DI,TI,TI")])
1234 (define_insn_and_split "mmx_packssdw"
1235 [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
1238 (match_operand:V2SI 1 "register_operand" "0,0,Yv"))
1240 (match_operand:V2SI 2 "register_mmxmem_operand" "ym,x,Yv"))))]
1241 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1243 packssdw\t{%2, %0|%0, %2}
1246 "TARGET_MMX_WITH_SSE && reload_completed"
1248 "ix86_split_mmx_pack (operands, SS_TRUNCATE); DONE;"
1249 [(set_attr "mmx_isa" "native,sse_noavx,avx")
1250 (set_attr "type" "mmxshft,sselog,sselog")
1251 (set_attr "mode" "DI,TI,TI")])
1253 (define_insn_and_split "mmx_punpckhbw"
1254 [(set (match_operand:V8QI 0 "register_operand" "=y,x,Yv")
1257 (match_operand:V8QI 1 "register_operand" "0,0,Yv")
1258 (match_operand:V8QI 2 "register_mmxmem_operand" "ym,x,Yv"))
1259 (parallel [(const_int 4) (const_int 12)
1260 (const_int 5) (const_int 13)
1261 (const_int 6) (const_int 14)
1262 (const_int 7) (const_int 15)])))]
1263 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1265 punpckhbw\t{%2, %0|%0, %2}
1268 "TARGET_MMX_WITH_SSE && reload_completed"
1270 "ix86_split_mmx_punpck (operands, true); DONE;"
1271 [(set_attr "mmx_isa" "native,sse_noavx,avx")
1272 (set_attr "type" "mmxcvt,sselog,sselog")
1273 (set_attr "mode" "DI,TI,TI")])
1275 (define_insn_and_split "mmx_punpcklbw"
1276 [(set (match_operand:V8QI 0 "register_operand" "=y,x,Yv")
1279 (match_operand:V8QI 1 "register_operand" "0,0,Yv")
1280 (match_operand:V8QI 2 "register_mmxmem_operand" "ym,x,Yv"))
1281 (parallel [(const_int 0) (const_int 8)
1282 (const_int 1) (const_int 9)
1283 (const_int 2) (const_int 10)
1284 (const_int 3) (const_int 11)])))]
1285 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1287 punpcklbw\t{%2, %0|%0, %k2}
1290 "TARGET_MMX_WITH_SSE && reload_completed"
1292 "ix86_split_mmx_punpck (operands, false); DONE;"
1293 [(set_attr "mmx_isa" "native,sse_noavx,avx")
1294 (set_attr "type" "mmxcvt,sselog,sselog")
1295 (set_attr "mode" "DI,TI,TI")])
1297 (define_insn_and_split "mmx_punpckhwd"
1298 [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
1301 (match_operand:V4HI 1 "register_operand" "0,0,Yv")
1302 (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv"))
1303 (parallel [(const_int 2) (const_int 6)
1304 (const_int 3) (const_int 7)])))]
1305 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1307 punpckhwd\t{%2, %0|%0, %2}
1310 "TARGET_MMX_WITH_SSE && reload_completed"
1312 "ix86_split_mmx_punpck (operands, true); DONE;"
1313 [(set_attr "mmx_isa" "native,sse_noavx,avx")
1314 (set_attr "type" "mmxcvt,sselog,sselog")
1315 (set_attr "mode" "DI,TI,TI")])
1317 (define_insn_and_split "mmx_punpcklwd"
1318 [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
1321 (match_operand:V4HI 1 "register_operand" "0,0,Yv")
1322 (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv"))
1323 (parallel [(const_int 0) (const_int 4)
1324 (const_int 1) (const_int 5)])))]
1325 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1327 punpcklwd\t{%2, %0|%0, %k2}
1330 "TARGET_MMX_WITH_SSE && reload_completed"
1332 "ix86_split_mmx_punpck (operands, false); DONE;"
1333 [(set_attr "mmx_isa" "native,sse_noavx,avx")
1334 (set_attr "type" "mmxcvt,sselog,sselog")
1335 (set_attr "mode" "DI,TI,TI")])
1337 (define_insn_and_split "mmx_punpckhdq"
1338 [(set (match_operand:V2SI 0 "register_operand" "=y,x,Yv")
1341 (match_operand:V2SI 1 "register_operand" "0,0,Yv")
1342 (match_operand:V2SI 2 "register_mmxmem_operand" "ym,x,Yv"))
1343 (parallel [(const_int 1)
1345 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1347 punpckhdq\t{%2, %0|%0, %2}
1350 "TARGET_MMX_WITH_SSE && reload_completed"
1352 "ix86_split_mmx_punpck (operands, true); DONE;"
1353 [(set_attr "mmx_isa" "native,sse_noavx,avx")
1354 (set_attr "type" "mmxcvt,sselog,sselog")
1355 (set_attr "mode" "DI,TI,TI")])
1357 (define_insn_and_split "mmx_punpckldq"
1358 [(set (match_operand:V2SI 0 "register_operand" "=y,x,Yv")
1361 (match_operand:V2SI 1 "register_operand" "0,0,Yv")
1362 (match_operand:V2SI 2 "register_mmxmem_operand" "ym,x,Yv"))
1363 (parallel [(const_int 0)
1365 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1367 punpckldq\t{%2, %0|%0, %k2}
1370 "TARGET_MMX_WITH_SSE && reload_completed"
1372 "ix86_split_mmx_punpck (operands, false); DONE;"
1373 [(set_attr "mmx_isa" "native,sse_noavx,avx")
1374 (set_attr "type" "mmxcvt,sselog,sselog")
1375 (set_attr "mode" "DI,TI,TI")])
1377 (define_expand "mmx_pinsrw"
1378 [(set (match_operand:V4HI 0 "register_operand")
1381 (match_operand:SI 2 "nonimmediate_operand"))
1382 (match_operand:V4HI 1 "register_operand")
1383 (match_operand:SI 3 "const_0_to_3_operand")))]
1384 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1385 && (TARGET_SSE || TARGET_3DNOW_A)"
1387 operands[2] = gen_lowpart (HImode, operands[2]);
1388 operands[3] = GEN_INT (1 << INTVAL (operands[3]));
1391 (define_insn "*mmx_pinsrw"
1392 [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
1395 (match_operand:HI 2 "nonimmediate_operand" "rm,rm,rm"))
1396 (match_operand:V4HI 1 "register_operand" "0,0,Yv")
1397 (match_operand:SI 3 "const_int_operand")))]
1398 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1399 && (TARGET_SSE || TARGET_3DNOW_A)
1400 && ((unsigned) exact_log2 (INTVAL (operands[3]))
1401 < GET_MODE_NUNITS (V4HImode))"
1403 operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
1404 switch (which_alternative)
1407 if (MEM_P (operands[2]))
1408 return "vpinsrw\t{%3, %2, %1, %0|%0, %1, %2, %3}";
1410 return "vpinsrw\t{%3, %k2, %1, %0|%0, %1, %k2, %3}";
1413 if (MEM_P (operands[2]))
1414 return "pinsrw\t{%3, %2, %0|%0, %2, %3}";
1416 return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}";
1421 [(set_attr "isa" "*,sse2_noavx,avx")
1422 (set_attr "mmx_isa" "native,*,*")
1423 (set_attr "type" "mmxcvt,sselog,sselog")
1424 (set_attr "length_immediate" "1")
1425 (set_attr "mode" "DI,TI,TI")])
1427 (define_insn "mmx_pextrw"
1428 [(set (match_operand:SI 0 "register_operand" "=r,r")
1431 (match_operand:V4HI 1 "register_operand" "y,Yv")
1432 (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n,n")]))))]
1433 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1434 && (TARGET_SSE || TARGET_3DNOW_A)"
1436 pextrw\t{%2, %1, %0|%0, %1, %2}
1437 %vpextrw\t{%2, %1, %0|%0, %1, %2}"
1438 [(set_attr "isa" "*,sse2")
1439 (set_attr "mmx_isa" "native,*")
1440 (set_attr "type" "mmxcvt,sselog1")
1441 (set_attr "length_immediate" "1")
1442 (set_attr "mode" "DI,TI")])
1444 (define_expand "mmx_pshufw"
1445 [(match_operand:V4HI 0 "register_operand")
1446 (match_operand:V4HI 1 "register_mmxmem_operand")
1447 (match_operand:SI 2 "const_int_operand")]
1448 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1449 && (TARGET_SSE || TARGET_3DNOW_A)"
1451 int mask = INTVAL (operands[2]);
1452 emit_insn (gen_mmx_pshufw_1 (operands[0], operands[1],
1453 GEN_INT ((mask >> 0) & 3),
1454 GEN_INT ((mask >> 2) & 3),
1455 GEN_INT ((mask >> 4) & 3),
1456 GEN_INT ((mask >> 6) & 3)));
1460 (define_insn "mmx_pshufw_1"
1461 [(set (match_operand:V4HI 0 "register_operand" "=y,Yv")
1463 (match_operand:V4HI 1 "register_mmxmem_operand" "ym,Yv")
1464 (parallel [(match_operand 2 "const_0_to_3_operand")
1465 (match_operand 3 "const_0_to_3_operand")
1466 (match_operand 4 "const_0_to_3_operand")
1467 (match_operand 5 "const_0_to_3_operand")])))]
1468 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1469 && (TARGET_SSE || TARGET_3DNOW_A)"
1472 mask |= INTVAL (operands[2]) << 0;
1473 mask |= INTVAL (operands[3]) << 2;
1474 mask |= INTVAL (operands[4]) << 4;
1475 mask |= INTVAL (operands[5]) << 6;
1476 operands[2] = GEN_INT (mask);
1478 switch (which_alternative)
1481 return "pshufw\t{%2, %1, %0|%0, %1, %2}";
1483 return "%vpshuflw\t{%2, %1, %0|%0, %1, %2}";
1488 [(set_attr "isa" "*,sse2")
1489 (set_attr "mmx_isa" "native,*")
1490 (set_attr "type" "mmxcvt,sselog")
1491 (set_attr "length_immediate" "1")
1492 (set_attr "mode" "DI,TI")])
1494 (define_insn "mmx_pswapdv2si2"
1495 [(set (match_operand:V2SI 0 "register_operand" "=y")
1497 (match_operand:V2SI 1 "nonimmediate_operand" "ym")
1498 (parallel [(const_int 1) (const_int 0)])))]
1500 "pswapd\t{%1, %0|%0, %1}"
1501 [(set_attr "type" "mmxcvt")
1502 (set_attr "prefix_extra" "1")
1503 (set_attr "mode" "DI")])
1505 (define_insn_and_split "*vec_dupv4hi"
1506 [(set (match_operand:V4HI 0 "register_operand" "=y,Yv,Yw")
1509 (match_operand:SI 1 "register_operand" "0,Yv,r"))))]
1510 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1511 && (TARGET_SSE || TARGET_3DNOW_A)"
1513 pshufw\t{$0, %0, %0|%0, %0, 0}
1516 "TARGET_MMX_WITH_SSE && reload_completed"
1520 operands[0] = lowpart_subreg (V8HImode, operands[0],
1521 GET_MODE (operands[0]));
1524 operands[1] = lowpart_subreg (HImode, operands[1],
1525 GET_MODE (operands[1]));
1526 op = gen_rtx_VEC_DUPLICATE (V8HImode, operands[1]);
1530 operands[1] = lowpart_subreg (V8HImode, operands[1],
1531 GET_MODE (operands[1]));
1532 rtx mask = gen_rtx_PARALLEL (VOIDmode,
1543 op = gen_rtx_VEC_SELECT (V8HImode, operands[1], mask);
1545 emit_insn (gen_rtx_SET (operands[0], op));
1548 [(set_attr "mmx_isa" "native,sse,avx")
1549 (set_attr "type" "mmxcvt,sselog1,ssemov")
1550 (set_attr "length_immediate" "1,1,0")
1551 (set_attr "mode" "DI,TI,TI")])
1553 (define_insn_and_split "*vec_dupv2si"
1554 [(set (match_operand:V2SI 0 "register_operand" "=y,x,Yv,Yw")
1556 (match_operand:SI 1 "register_operand" "0,0,Yv,r")))]
1557 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1563 "TARGET_MMX_WITH_SSE && reload_completed"
1565 (vec_duplicate:V4SI (match_dup 1)))]
1566 "operands[0] = lowpart_subreg (V4SImode, operands[0],
1567 GET_MODE (operands[0]));"
1568 [(set_attr "mmx_isa" "native,sse_noavx,avx,avx")
1569 (set_attr "type" "mmxcvt,ssemov,ssemov,ssemov")
1570 (set_attr "mode" "DI,TI,TI,TI")])
1572 (define_insn "*mmx_concatv2si"
1573 [(set (match_operand:V2SI 0 "register_operand" "=y,y")
1575 (match_operand:SI 1 "nonimmediate_operand" " 0,rm")
1576 (match_operand:SI 2 "nonimm_or_0_operand" "ym,C")))]
1577 "TARGET_MMX && !TARGET_SSE"
1579 punpckldq\t{%2, %0|%0, %2}
1580 movd\t{%1, %0|%0, %1}"
1581 [(set_attr "type" "mmxcvt,mmxmov")
1582 (set_attr "mode" "DI")])
1584 (define_expand "vec_setv2si"
1585 [(match_operand:V2SI 0 "register_operand")
1586 (match_operand:SI 1 "register_operand")
1587 (match_operand 2 "const_int_operand")]
1588 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1590 ix86_expand_vector_set (TARGET_MMX_WITH_SSE, operands[0], operands[1],
1591 INTVAL (operands[2]));
1595 ;; Avoid combining registers from different units in a single alternative,
1596 ;; see comment above inline_secondary_memory_needed function in i386.c
1597 (define_insn_and_split "*vec_extractv2si_0"
1598 [(set (match_operand:SI 0 "nonimmediate_operand" "=x,m,y, m,r")
1600 (match_operand:V2SI 1 "nonimmediate_operand" "xm,x,ym,y,m")
1601 (parallel [(const_int 0)])))]
1602 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1603 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1605 "&& reload_completed"
1606 [(set (match_dup 0) (match_dup 1))]
1607 "operands[1] = gen_lowpart (SImode, operands[1]);"
1608 [(set_attr "mmx_isa" "*,*,native,native,*")])
1610 ;; Avoid combining registers from different units in a single alternative,
1611 ;; see comment above inline_secondary_memory_needed function in i386.c
1612 (define_insn "*vec_extractv2si_1"
1613 [(set (match_operand:SI 0 "nonimmediate_operand" "=y,x,x,y,x,r")
1615 (match_operand:V2SI 1 "nonimmediate_operand" " 0,x,x,o,o,o")
1616 (parallel [(const_int 1)])))]
1617 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1618 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1621 %vpshufd\t{$0xe5, %1, %0|%0, %1, 0xe5}
1622 shufps\t{$0xe5, %1, %0|%0, %1, 0xe5}
1626 [(set_attr "isa" "*,sse2,noavx,*,*,*")
1627 (set_attr "mmx_isa" "native,*,*,native,*,*")
1628 (set_attr "type" "mmxcvt,sseshuf1,sseshuf1,mmxmov,ssemov,imov")
1629 (set (attr "length_immediate")
1630 (if_then_else (eq_attr "alternative" "1,2")
1632 (const_string "*")))
1633 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig,orig")
1634 (set_attr "mode" "DI,TI,V4SF,SI,SI,SI")])
1637 [(set (match_operand:SI 0 "register_operand")
1639 (match_operand:V2SI 1 "memory_operand")
1640 (parallel [(const_int 1)])))]
1641 "(TARGET_MMX || TARGET_MMX_WITH_SSE) && reload_completed"
1642 [(set (match_dup 0) (match_dup 1))]
1643 "operands[1] = adjust_address (operands[1], SImode, 4);")
1645 (define_insn_and_split "*vec_extractv2si_zext_mem"
1646 [(set (match_operand:DI 0 "register_operand" "=y,x,r")
1649 (match_operand:V2SI 1 "memory_operand" "o,o,o")
1650 (parallel [(match_operand:SI 2 "const_0_to_1_operand")]))))]
1653 "&& reload_completed"
1654 [(set (match_dup 0) (zero_extend:DI (match_dup 1)))]
1656 operands[1] = adjust_address (operands[1], SImode, INTVAL (operands[2]) * 4);
1658 [(set_attr "isa" "*,sse2,*")
1659 (set_attr "mmx_isa" "native,*,*")])
1661 (define_expand "vec_extractv2sisi"
1662 [(match_operand:SI 0 "register_operand")
1663 (match_operand:V2SI 1 "register_operand")
1664 (match_operand 2 "const_int_operand")]
1665 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1667 ix86_expand_vector_extract (TARGET_MMX_WITH_SSE, operands[0],
1668 operands[1], INTVAL (operands[2]));
1672 (define_expand "vec_initv2sisi"
1673 [(match_operand:V2SI 0 "register_operand")
1675 "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_SSE"
1677 ix86_expand_vector_init (TARGET_MMX_WITH_SSE, operands[0],
1682 (define_expand "vec_setv4hi"
1683 [(match_operand:V4HI 0 "register_operand")
1684 (match_operand:HI 1 "register_operand")
1685 (match_operand 2 "const_int_operand")]
1686 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1688 ix86_expand_vector_set (TARGET_MMX_WITH_SSE, operands[0], operands[1],
1689 INTVAL (operands[2]));
1693 (define_expand "vec_extractv4hihi"
1694 [(match_operand:HI 0 "register_operand")
1695 (match_operand:V4HI 1 "register_operand")
1696 (match_operand 2 "const_int_operand")]
1697 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1699 ix86_expand_vector_extract (TARGET_MMX_WITH_SSE, operands[0],
1700 operands[1], INTVAL (operands[2]));
1704 (define_expand "vec_initv4hihi"
1705 [(match_operand:V4HI 0 "register_operand")
1707 "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_SSE"
1709 ix86_expand_vector_init (TARGET_MMX_WITH_SSE, operands[0],
1714 (define_expand "vec_setv8qi"
1715 [(match_operand:V8QI 0 "register_operand")
1716 (match_operand:QI 1 "register_operand")
1717 (match_operand 2 "const_int_operand")]
1718 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1720 ix86_expand_vector_set (TARGET_MMX_WITH_SSE, operands[0], operands[1],
1721 INTVAL (operands[2]));
1725 (define_expand "vec_extractv8qiqi"
1726 [(match_operand:QI 0 "register_operand")
1727 (match_operand:V8QI 1 "register_operand")
1728 (match_operand 2 "const_int_operand")]
1729 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1731 ix86_expand_vector_extract (TARGET_MMX_WITH_SSE, operands[0],
1732 operands[1], INTVAL (operands[2]));
1736 (define_expand "vec_initv8qiqi"
1737 [(match_operand:V8QI 0 "register_operand")
1739 "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_SSE"
1741 ix86_expand_vector_init (TARGET_MMX_WITH_SSE, operands[0],
1746 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1750 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1752 (define_expand "mmx_uavgv8qi3"
1753 [(set (match_operand:V8QI 0 "register_operand")
1759 (match_operand:V8QI 1 "register_mmxmem_operand"))
1761 (match_operand:V8QI 2 "register_mmxmem_operand")))
1762 (const_vector:V8HI [(const_int 1) (const_int 1)
1763 (const_int 1) (const_int 1)
1764 (const_int 1) (const_int 1)
1765 (const_int 1) (const_int 1)]))
1767 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1768 && (TARGET_SSE || TARGET_3DNOW)"
1769 "ix86_fixup_binary_operands_no_copy (PLUS, V8QImode, operands);")
1771 (define_insn "*mmx_uavgv8qi3"
1772 [(set (match_operand:V8QI 0 "register_operand" "=y,x,Yv")
1778 (match_operand:V8QI 1 "register_mmxmem_operand" "%0,0,Yv"))
1780 (match_operand:V8QI 2 "register_mmxmem_operand" "ym,x,Yv")))
1781 (const_vector:V8HI [(const_int 1) (const_int 1)
1782 (const_int 1) (const_int 1)
1783 (const_int 1) (const_int 1)
1784 (const_int 1) (const_int 1)]))
1786 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1787 && (TARGET_SSE || TARGET_3DNOW)
1788 && ix86_binary_operator_ok (PLUS, V8QImode, operands)"
1790 switch (which_alternative)
1793 return "vpavgb\t{%2, %1, %0|%0, %1, %2}";
1796 /* These two instructions have the same operation, but their encoding
1797 is different. Prefer the one that is de facto standard. */
1798 if (TARGET_SSE || TARGET_3DNOW_A)
1799 return "pavgb\t{%2, %0|%0, %2}";
1801 return "pavgusb\t{%2, %0|%0, %2}";
1806 [(set_attr "isa" "*,sse2_noavx,avx")
1807 (set_attr "mmx_isa" "native,*,*")
1808 (set_attr "type" "mmxshft,sseiadd,sseiadd")
1809 (set (attr "prefix_extra")
1811 (not (ior (match_test "TARGET_SSE")
1812 (match_test "TARGET_3DNOW_A")))
1814 (const_string "*")))
1815 (set_attr "mode" "DI,TI,TI")])
1817 (define_expand "mmx_uavgv4hi3"
1818 [(set (match_operand:V4HI 0 "register_operand")
1824 (match_operand:V4HI 1 "register_mmxmem_operand"))
1826 (match_operand:V4HI 2 "register_mmxmem_operand")))
1827 (const_vector:V4SI [(const_int 1) (const_int 1)
1828 (const_int 1) (const_int 1)]))
1830 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1831 && (TARGET_SSE || TARGET_3DNOW_A)"
1832 "ix86_fixup_binary_operands_no_copy (PLUS, V4HImode, operands);")
1834 (define_insn "*mmx_uavgv4hi3"
1835 [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
1841 (match_operand:V4HI 1 "register_mmxmem_operand" "%0,0,Yv"))
1843 (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv")))
1844 (const_vector:V4SI [(const_int 1) (const_int 1)
1845 (const_int 1) (const_int 1)]))
1847 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1848 && (TARGET_SSE || TARGET_3DNOW_A)
1849 && ix86_binary_operator_ok (PLUS, V4HImode, operands)"
1851 pavgw\t{%2, %0|%0, %2}
1852 pavgw\t{%2, %0|%0, %2}
1853 vpavgw\t{%2, %1, %0|%0, %1, %2}"
1854 [(set_attr "isa" "*,sse2_noavx,avx")
1855 (set_attr "mmx_isa" "native,*,*")
1856 (set_attr "type" "mmxshft,sseiadd,sseiadd")
1857 (set_attr "mode" "DI,TI,TI")])
1859 (define_insn "mmx_psadbw"
1860 [(set (match_operand:V1DI 0 "register_operand" "=y,x,Yv")
1861 (unspec:V1DI [(match_operand:V8QI 1 "register_operand" "0,0,Yv")
1862 (match_operand:V8QI 2 "register_mmxmem_operand" "ym,x,Yv")]
1864 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1865 && (TARGET_SSE || TARGET_3DNOW_A)"
1867 psadbw\t{%2, %0|%0, %2}
1868 psadbw\t{%2, %0|%0, %2}
1869 vpsadbw\t{%2, %1, %0|%0, %1, %2}"
1870 [(set_attr "isa" "*,sse2_noavx,avx")
1871 (set_attr "mmx_isa" "native,*,*")
1872 (set_attr "type" "mmxshft,sseiadd,sseiadd")
1873 (set_attr "mode" "DI,TI,TI")])
1875 (define_insn_and_split "mmx_pmovmskb"
1876 [(set (match_operand:SI 0 "register_operand" "=r,r")
1877 (unspec:SI [(match_operand:V8QI 1 "register_operand" "y,x")]
1879 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1880 && (TARGET_SSE || TARGET_3DNOW_A)"
1882 pmovmskb\t{%1, %0|%0, %1}
1884 "TARGET_MMX_WITH_SSE && reload_completed"
1886 (unspec:SI [(match_dup 1)] UNSPEC_MOVMSK))
1888 (zero_extend:SI (match_dup 2)))]
1890 /* Generate SSE pmovmskb and zero-extend from QImode to SImode. */
1891 operands[1] = lowpart_subreg (V16QImode, operands[1],
1892 GET_MODE (operands[1]));
1893 operands[2] = lowpart_subreg (QImode, operands[0],
1894 GET_MODE (operands[0]));
1896 [(set_attr "mmx_isa" "native,sse")
1897 (set_attr "type" "mmxcvt,ssemov")
1898 (set_attr "mode" "DI,TI")])
1900 (define_expand "mmx_maskmovq"
1901 [(set (match_operand:V8QI 0 "memory_operand")
1902 (unspec:V8QI [(match_operand:V8QI 1 "register_operand")
1903 (match_operand:V8QI 2 "register_operand")
1906 "TARGET_SSE || TARGET_3DNOW_A")
1908 (define_insn "*mmx_maskmovq"
1909 [(set (mem:V8QI (match_operand:P 0 "register_operand" "D"))
1910 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
1911 (match_operand:V8QI 2 "register_operand" "y")
1912 (mem:V8QI (match_dup 0))]
1914 "TARGET_SSE || TARGET_3DNOW_A"
1915 ;; @@@ check ordering of operands in intel/nonintel syntax
1916 "maskmovq\t{%2, %1|%1, %2}"
1917 [(set_attr "type" "mmxcvt")
1918 (set_attr "znver1_decode" "vector")
1919 (set_attr "mode" "DI")])
1921 (define_int_iterator EMMS
1922 [(UNSPECV_EMMS "TARGET_MMX")
1923 (UNSPECV_FEMMS "TARGET_3DNOW")])
1925 (define_int_attr emms
1926 [(UNSPECV_EMMS "emms")
1927 (UNSPECV_FEMMS "femms")])
1929 (define_expand "mmx_<emms>"
1931 [(unspec_volatile [(const_int 0)] EMMS)
1932 (clobber (reg:XF ST0_REG))
1933 (clobber (reg:XF ST1_REG))
1934 (clobber (reg:XF ST2_REG))
1935 (clobber (reg:XF ST3_REG))
1936 (clobber (reg:XF ST4_REG))
1937 (clobber (reg:XF ST5_REG))
1938 (clobber (reg:XF ST6_REG))
1939 (clobber (reg:XF ST7_REG))
1940 (clobber (reg:DI MM0_REG))
1941 (clobber (reg:DI MM1_REG))
1942 (clobber (reg:DI MM2_REG))
1943 (clobber (reg:DI MM3_REG))
1944 (clobber (reg:DI MM4_REG))
1945 (clobber (reg:DI MM5_REG))
1946 (clobber (reg:DI MM6_REG))
1947 (clobber (reg:DI MM7_REG))])]
1948 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1952 emit_insn (gen_nop ());
1957 (define_insn "*mmx_<emms>"
1958 [(unspec_volatile [(const_int 0)] EMMS)
1959 (clobber (reg:XF ST0_REG))
1960 (clobber (reg:XF ST1_REG))
1961 (clobber (reg:XF ST2_REG))
1962 (clobber (reg:XF ST3_REG))
1963 (clobber (reg:XF ST4_REG))
1964 (clobber (reg:XF ST5_REG))
1965 (clobber (reg:XF ST6_REG))
1966 (clobber (reg:XF ST7_REG))
1967 (clobber (reg:DI MM0_REG))
1968 (clobber (reg:DI MM1_REG))
1969 (clobber (reg:DI MM2_REG))
1970 (clobber (reg:DI MM3_REG))
1971 (clobber (reg:DI MM4_REG))
1972 (clobber (reg:DI MM5_REG))
1973 (clobber (reg:DI MM6_REG))
1974 (clobber (reg:DI MM7_REG))]
1977 [(set_attr "type" "mmx")
1978 (set_attr "modrm" "0")
1979 (set_attr "memory" "none")])