]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/i386/mmx.md
Update copyright years.
[thirdparty/gcc.git] / gcc / config / i386 / mmx.md
1 ;; GCC machine description for MMX and 3dNOW! instructions
2 ;; Copyright (C) 2005-2016 Free Software Foundation, Inc.
3 ;;
4 ;; This file is part of GCC.
5 ;;
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)
9 ;; any later version.
10 ;;
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.
15 ;;
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/>.
19
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.
23
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.
31
32 (define_c_enum "unspec" [
33 UNSPEC_MOVNTQ
34 UNSPEC_PFRCP
35 UNSPEC_PFRCPIT1
36 UNSPEC_PFRCPIT2
37 UNSPEC_PFRSQRT
38 UNSPEC_PFRSQIT1
39 ])
40
41 (define_c_enum "unspecv" [
42 UNSPECV_EMMS
43 UNSPECV_FEMMS
44 ])
45
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])
49
50 ;; All 8-byte vector modes handled by MMX
51 (define_mode_iterator MMXMODE [V8QI V4HI V2SI V1DI V2SF])
52
53 ;; Mix-n-match
54 (define_mode_iterator MMXMODE12 [V8QI V4HI])
55 (define_mode_iterator MMXMODE24 [V4HI V2SI])
56 (define_mode_iterator MMXMODE248 [V4HI V2SI V1DI])
57
58 ;; Mapping from integer vector mode to mnemonic suffix
59 (define_mode_attr mmxvecsize [(V8QI "b") (V4HI "w") (V2SI "d") (V1DI "q")])
60
61 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
62 ;;
63 ;; Move patterns
64 ;;
65 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
66
67 ;; All of these patterns are enabled for MMX as well as 3dNOW.
68 ;; This is essential for maintaining stable calling conventions.
69
70 (define_expand "mov<mode>"
71 [(set (match_operand:MMXMODE 0 "nonimmediate_operand")
72 (match_operand:MMXMODE 1 "nonimmediate_operand"))]
73 "TARGET_MMX"
74 {
75 ix86_expand_vector_move (<MODE>mode, operands);
76 DONE;
77 })
78
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 ,?!Ym,v,v,v,m,*x,*x,*x,m ,r ,Yi,!Ym,*Yi")
82 (match_operand:MMXMODE 1 "vector_move_operand"
83 "rCo,rC,C,rm,rC,C ,!y,m ,?!y,?!Yn,r ,C,v,m,v,C ,*x,m ,*x,Yj,r ,*Yj,!Yn"))]
84 "TARGET_MMX
85 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
86 {
87 switch (get_attr_type (insn))
88 {
89 case TYPE_MULTI:
90 return "#";
91
92 case TYPE_IMOV:
93 if (get_attr_mode (insn) == MODE_SI)
94 return "mov{l}\t{%1, %k0|%k0, %1}";
95 else
96 return "mov{q}\t{%1, %0|%0, %1}";
97
98 case TYPE_MMX:
99 return "pxor\t%0, %0";
100
101 case TYPE_MMXMOV:
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}";
107
108 case TYPE_SSECVT:
109 if (SSE_REG_P (operands[0]))
110 return "movq2dq\t{%1, %0|%0, %1}";
111 else
112 return "movdq2q\t{%1, %0|%0, %1}";
113
114 case TYPE_SSELOG1:
115 return standard_sse_constant_opcode (insn, operands[1]);
116
117 case TYPE_SSEMOV:
118 switch (get_attr_mode (insn))
119 {
120 case MODE_DI:
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}";
126 case MODE_TI:
127 return "%vmovdqa\t{%1, %0|%0, %1}";
128 case MODE_XI:
129 return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
130
131 case MODE_V2SF:
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}";
135 case MODE_V4SF:
136 return "%vmovaps\t{%1, %0|%0, %1}";
137
138 default:
139 gcc_unreachable ();
140 }
141
142 default:
143 gcc_unreachable ();
144 }
145 }
146 [(set (attr "isa")
147 (cond [(eq_attr "alternative" "0,1")
148 (const_string "nox64")
149 (eq_attr "alternative" "2,3,4,9,10,11,12,13,14,19,20")
150 (const_string "x64")
151 ]
152 (const_string "*")))
153 (set (attr "type")
154 (cond [(eq_attr "alternative" "0,1")
155 (const_string "multi")
156 (eq_attr "alternative" "2,3,4")
157 (const_string "imov")
158 (eq_attr "alternative" "5")
159 (const_string "mmx")
160 (eq_attr "alternative" "6,7,8,9,10")
161 (const_string "mmxmov")
162 (eq_attr "alternative" "11,15")
163 (const_string "sselog1")
164 (eq_attr "alternative" "21,22")
165 (const_string "ssecvt")
166 ]
167 (const_string "ssemov")))
168 (set (attr "prefix_rex")
169 (if_then_else (eq_attr "alternative" "9,10,19,20")
170 (const_string "1")
171 (const_string "*")))
172 (set (attr "prefix")
173 (if_then_else (eq_attr "type" "sselog1,ssemov")
174 (const_string "maybe_vex")
175 (const_string "orig")))
176 (set (attr "prefix_data16")
177 (if_then_else
178 (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
179 (const_string "1")
180 (const_string "*")))
181 (set (attr "mode")
182 (cond [(eq_attr "alternative" "2")
183 (const_string "SI")
184 (eq_attr "alternative" "11,12,15,16")
185 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
186 (match_operand 1 "ext_sse_reg_operand"))
187 (const_string "XI")
188 (match_test "<MODE>mode == V2SFmode")
189 (const_string "V4SF")
190 (ior (not (match_test "TARGET_SSE2"))
191 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
192 (const_string "V4SF")
193 (match_test "TARGET_AVX")
194 (const_string "TI")
195 (match_test "optimize_function_for_size_p (cfun)")
196 (const_string "V4SF")
197 ]
198 (const_string "TI"))
199
200 (and (eq_attr "alternative" "13,14,17,18")
201 (ior (match_test "<MODE>mode == V2SFmode")
202 (not (match_test "TARGET_SSE2"))))
203 (const_string "V2SF")
204 ]
205 (const_string "DI")))])
206
207 (define_split
208 [(set (match_operand:MMXMODE 0 "nonimmediate_operand")
209 (match_operand:MMXMODE 1 "general_operand"))]
210 "!TARGET_64BIT && reload_completed
211 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
212 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
213 [(const_int 0)]
214 "ix86_split_long_move (operands); DONE;")
215
216 (define_expand "movmisalign<mode>"
217 [(set (match_operand:MMXMODE 0 "nonimmediate_operand")
218 (match_operand:MMXMODE 1 "nonimmediate_operand"))]
219 "TARGET_MMX"
220 {
221 ix86_expand_vector_move (<MODE>mode, operands);
222 DONE;
223 })
224
225 (define_insn "sse_movntq"
226 [(set (match_operand:DI 0 "memory_operand" "=m")
227 (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
228 UNSPEC_MOVNTQ))]
229 "TARGET_SSE || TARGET_3DNOW_A"
230 "movntq\t{%1, %0|%0, %1}"
231 [(set_attr "type" "mmxmov")
232 (set_attr "mode" "DI")])
233
234 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
235 ;;
236 ;; Parallel single-precision floating point arithmetic
237 ;;
238 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
239
240 (define_expand "mmx_addv2sf3"
241 [(set (match_operand:V2SF 0 "register_operand")
242 (plus:V2SF
243 (match_operand:V2SF 1 "nonimmediate_operand")
244 (match_operand:V2SF 2 "nonimmediate_operand")))]
245 "TARGET_3DNOW"
246 "ix86_fixup_binary_operands_no_copy (PLUS, V2SFmode, operands);")
247
248 (define_insn "*mmx_addv2sf3"
249 [(set (match_operand:V2SF 0 "register_operand" "=y")
250 (plus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
251 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
252 "TARGET_3DNOW && ix86_binary_operator_ok (PLUS, V2SFmode, operands)"
253 "pfadd\t{%2, %0|%0, %2}"
254 [(set_attr "type" "mmxadd")
255 (set_attr "prefix_extra" "1")
256 (set_attr "mode" "V2SF")])
257
258 (define_expand "mmx_subv2sf3"
259 [(set (match_operand:V2SF 0 "register_operand")
260 (minus:V2SF (match_operand:V2SF 1 "register_operand")
261 (match_operand:V2SF 2 "nonimmediate_operand")))]
262 "TARGET_3DNOW")
263
264 (define_expand "mmx_subrv2sf3"
265 [(set (match_operand:V2SF 0 "register_operand")
266 (minus:V2SF (match_operand:V2SF 2 "register_operand")
267 (match_operand:V2SF 1 "nonimmediate_operand")))]
268 "TARGET_3DNOW")
269
270 (define_insn "*mmx_subv2sf3"
271 [(set (match_operand:V2SF 0 "register_operand" "=y,y")
272 (minus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "0,ym")
273 (match_operand:V2SF 2 "nonimmediate_operand" "ym,0")))]
274 "TARGET_3DNOW && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
275 "@
276 pfsub\t{%2, %0|%0, %2}
277 pfsubr\t{%1, %0|%0, %1}"
278 [(set_attr "type" "mmxadd")
279 (set_attr "prefix_extra" "1")
280 (set_attr "mode" "V2SF")])
281
282 (define_expand "mmx_mulv2sf3"
283 [(set (match_operand:V2SF 0 "register_operand")
284 (mult:V2SF (match_operand:V2SF 1 "nonimmediate_operand")
285 (match_operand:V2SF 2 "nonimmediate_operand")))]
286 "TARGET_3DNOW"
287 "ix86_fixup_binary_operands_no_copy (MULT, V2SFmode, operands);")
288
289 (define_insn "*mmx_mulv2sf3"
290 [(set (match_operand:V2SF 0 "register_operand" "=y")
291 (mult:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
292 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
293 "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V2SFmode, operands)"
294 "pfmul\t{%2, %0|%0, %2}"
295 [(set_attr "type" "mmxmul")
296 (set_attr "prefix_extra" "1")
297 (set_attr "mode" "V2SF")])
298
299 ;; ??? For !flag_finite_math_only, the representation with SMIN/SMAX
300 ;; isn't really correct, as those rtl operators aren't defined when
301 ;; applied to NaNs. Hopefully the optimizers won't get too smart on us.
302
303 (define_expand "mmx_<code>v2sf3"
304 [(set (match_operand:V2SF 0 "register_operand")
305 (smaxmin:V2SF
306 (match_operand:V2SF 1 "nonimmediate_operand")
307 (match_operand:V2SF 2 "nonimmediate_operand")))]
308 "TARGET_3DNOW"
309 {
310 if (!flag_finite_math_only)
311 operands[1] = force_reg (V2SFmode, operands[1]);
312 ix86_fixup_binary_operands_no_copy (<CODE>, V2SFmode, operands);
313 })
314
315 (define_insn "*mmx_<code>v2sf3_finite"
316 [(set (match_operand:V2SF 0 "register_operand" "=y")
317 (smaxmin:V2SF
318 (match_operand:V2SF 1 "nonimmediate_operand" "%0")
319 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
320 "TARGET_3DNOW && flag_finite_math_only
321 && ix86_binary_operator_ok (<CODE>, V2SFmode, operands)"
322 "pf<maxmin_float>\t{%2, %0|%0, %2}"
323 [(set_attr "type" "mmxadd")
324 (set_attr "prefix_extra" "1")
325 (set_attr "mode" "V2SF")])
326
327 (define_insn "*mmx_<code>v2sf3"
328 [(set (match_operand:V2SF 0 "register_operand" "=y")
329 (smaxmin:V2SF
330 (match_operand:V2SF 1 "register_operand" "0")
331 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
332 "TARGET_3DNOW"
333 "pf<maxmin_float>\t{%2, %0|%0, %2}"
334 [(set_attr "type" "mmxadd")
335 (set_attr "prefix_extra" "1")
336 (set_attr "mode" "V2SF")])
337
338 (define_insn "mmx_rcpv2sf2"
339 [(set (match_operand:V2SF 0 "register_operand" "=y")
340 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
341 UNSPEC_PFRCP))]
342 "TARGET_3DNOW"
343 "pfrcp\t{%1, %0|%0, %1}"
344 [(set_attr "type" "mmx")
345 (set_attr "prefix_extra" "1")
346 (set_attr "mode" "V2SF")])
347
348 (define_insn "mmx_rcpit1v2sf3"
349 [(set (match_operand:V2SF 0 "register_operand" "=y")
350 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
351 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
352 UNSPEC_PFRCPIT1))]
353 "TARGET_3DNOW"
354 "pfrcpit1\t{%2, %0|%0, %2}"
355 [(set_attr "type" "mmx")
356 (set_attr "prefix_extra" "1")
357 (set_attr "mode" "V2SF")])
358
359 (define_insn "mmx_rcpit2v2sf3"
360 [(set (match_operand:V2SF 0 "register_operand" "=y")
361 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
362 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
363 UNSPEC_PFRCPIT2))]
364 "TARGET_3DNOW"
365 "pfrcpit2\t{%2, %0|%0, %2}"
366 [(set_attr "type" "mmx")
367 (set_attr "prefix_extra" "1")
368 (set_attr "mode" "V2SF")])
369
370 (define_insn "mmx_rsqrtv2sf2"
371 [(set (match_operand:V2SF 0 "register_operand" "=y")
372 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
373 UNSPEC_PFRSQRT))]
374 "TARGET_3DNOW"
375 "pfrsqrt\t{%1, %0|%0, %1}"
376 [(set_attr "type" "mmx")
377 (set_attr "prefix_extra" "1")
378 (set_attr "mode" "V2SF")])
379
380 (define_insn "mmx_rsqit1v2sf3"
381 [(set (match_operand:V2SF 0 "register_operand" "=y")
382 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
383 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
384 UNSPEC_PFRSQIT1))]
385 "TARGET_3DNOW"
386 "pfrsqit1\t{%2, %0|%0, %2}"
387 [(set_attr "type" "mmx")
388 (set_attr "prefix_extra" "1")
389 (set_attr "mode" "V2SF")])
390
391 (define_insn "mmx_haddv2sf3"
392 [(set (match_operand:V2SF 0 "register_operand" "=y")
393 (vec_concat:V2SF
394 (plus:SF
395 (vec_select:SF
396 (match_operand:V2SF 1 "register_operand" "0")
397 (parallel [(const_int 0)]))
398 (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
399 (plus:SF
400 (vec_select:SF
401 (match_operand:V2SF 2 "nonimmediate_operand" "ym")
402 (parallel [(const_int 0)]))
403 (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
404 "TARGET_3DNOW"
405 "pfacc\t{%2, %0|%0, %2}"
406 [(set_attr "type" "mmxadd")
407 (set_attr "prefix_extra" "1")
408 (set_attr "mode" "V2SF")])
409
410 (define_insn "mmx_hsubv2sf3"
411 [(set (match_operand:V2SF 0 "register_operand" "=y")
412 (vec_concat:V2SF
413 (minus:SF
414 (vec_select:SF
415 (match_operand:V2SF 1 "register_operand" "0")
416 (parallel [(const_int 0)]))
417 (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
418 (minus:SF
419 (vec_select:SF
420 (match_operand:V2SF 2 "nonimmediate_operand" "ym")
421 (parallel [(const_int 0)]))
422 (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
423 "TARGET_3DNOW_A"
424 "pfnacc\t{%2, %0|%0, %2}"
425 [(set_attr "type" "mmxadd")
426 (set_attr "prefix_extra" "1")
427 (set_attr "mode" "V2SF")])
428
429 (define_insn "mmx_addsubv2sf3"
430 [(set (match_operand:V2SF 0 "register_operand" "=y")
431 (vec_merge:V2SF
432 (plus:V2SF
433 (match_operand:V2SF 1 "register_operand" "0")
434 (match_operand:V2SF 2 "nonimmediate_operand" "ym"))
435 (minus:V2SF (match_dup 1) (match_dup 2))
436 (const_int 1)))]
437 "TARGET_3DNOW_A"
438 "pfpnacc\t{%2, %0|%0, %2}"
439 [(set_attr "type" "mmxadd")
440 (set_attr "prefix_extra" "1")
441 (set_attr "mode" "V2SF")])
442
443 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
444 ;;
445 ;; Parallel single-precision floating point comparisons
446 ;;
447 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
448
449 (define_expand "mmx_eqv2sf3"
450 [(set (match_operand:V2SI 0 "register_operand")
451 (eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand")
452 (match_operand:V2SF 2 "nonimmediate_operand")))]
453 "TARGET_3DNOW"
454 "ix86_fixup_binary_operands_no_copy (EQ, V2SFmode, operands);")
455
456 (define_insn "*mmx_eqv2sf3"
457 [(set (match_operand:V2SI 0 "register_operand" "=y")
458 (eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "%0")
459 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
460 "TARGET_3DNOW && ix86_binary_operator_ok (EQ, V2SFmode, operands)"
461 "pfcmpeq\t{%2, %0|%0, %2}"
462 [(set_attr "type" "mmxcmp")
463 (set_attr "prefix_extra" "1")
464 (set_attr "mode" "V2SF")])
465
466 (define_insn "mmx_gtv2sf3"
467 [(set (match_operand:V2SI 0 "register_operand" "=y")
468 (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
469 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
470 "TARGET_3DNOW"
471 "pfcmpgt\t{%2, %0|%0, %2}"
472 [(set_attr "type" "mmxcmp")
473 (set_attr "prefix_extra" "1")
474 (set_attr "mode" "V2SF")])
475
476 (define_insn "mmx_gev2sf3"
477 [(set (match_operand:V2SI 0 "register_operand" "=y")
478 (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
479 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
480 "TARGET_3DNOW"
481 "pfcmpge\t{%2, %0|%0, %2}"
482 [(set_attr "type" "mmxcmp")
483 (set_attr "prefix_extra" "1")
484 (set_attr "mode" "V2SF")])
485
486 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
487 ;;
488 ;; Parallel single-precision floating point conversion operations
489 ;;
490 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
491
492 (define_insn "mmx_pf2id"
493 [(set (match_operand:V2SI 0 "register_operand" "=y")
494 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
495 "TARGET_3DNOW"
496 "pf2id\t{%1, %0|%0, %1}"
497 [(set_attr "type" "mmxcvt")
498 (set_attr "prefix_extra" "1")
499 (set_attr "mode" "V2SF")])
500
501 (define_insn "mmx_pf2iw"
502 [(set (match_operand:V2SI 0 "register_operand" "=y")
503 (sign_extend:V2SI
504 (ss_truncate:V2HI
505 (fix:V2SI
506 (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
507 "TARGET_3DNOW_A"
508 "pf2iw\t{%1, %0|%0, %1}"
509 [(set_attr "type" "mmxcvt")
510 (set_attr "prefix_extra" "1")
511 (set_attr "mode" "V2SF")])
512
513 (define_insn "mmx_pi2fw"
514 [(set (match_operand:V2SF 0 "register_operand" "=y")
515 (float:V2SF
516 (sign_extend:V2SI
517 (truncate:V2HI
518 (match_operand:V2SI 1 "nonimmediate_operand" "ym")))))]
519 "TARGET_3DNOW_A"
520 "pi2fw\t{%1, %0|%0, %1}"
521 [(set_attr "type" "mmxcvt")
522 (set_attr "prefix_extra" "1")
523 (set_attr "mode" "V2SF")])
524
525 (define_insn "mmx_floatv2si2"
526 [(set (match_operand:V2SF 0 "register_operand" "=y")
527 (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
528 "TARGET_3DNOW"
529 "pi2fd\t{%1, %0|%0, %1}"
530 [(set_attr "type" "mmxcvt")
531 (set_attr "prefix_extra" "1")
532 (set_attr "mode" "V2SF")])
533
534 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
535 ;;
536 ;; Parallel single-precision floating point element swizzling
537 ;;
538 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
539
540 (define_insn "mmx_pswapdv2sf2"
541 [(set (match_operand:V2SF 0 "register_operand" "=y")
542 (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
543 (parallel [(const_int 1) (const_int 0)])))]
544 "TARGET_3DNOW_A"
545 "pswapd\t{%1, %0|%0, %1}"
546 [(set_attr "type" "mmxcvt")
547 (set_attr "prefix_extra" "1")
548 (set_attr "mode" "V2SF")])
549
550 (define_insn "*vec_dupv2sf"
551 [(set (match_operand:V2SF 0 "register_operand" "=y")
552 (vec_duplicate:V2SF
553 (match_operand:SF 1 "register_operand" "0")))]
554 "TARGET_MMX"
555 "punpckldq\t%0, %0"
556 [(set_attr "type" "mmxcvt")
557 (set_attr "mode" "DI")])
558
559 (define_insn "*mmx_concatv2sf"
560 [(set (match_operand:V2SF 0 "register_operand" "=y,y")
561 (vec_concat:V2SF
562 (match_operand:SF 1 "nonimmediate_operand" " 0,rm")
563 (match_operand:SF 2 "vector_move_operand" "ym,C")))]
564 "TARGET_MMX && !TARGET_SSE"
565 "@
566 punpckldq\t{%2, %0|%0, %2}
567 movd\t{%1, %0|%0, %1}"
568 [(set_attr "type" "mmxcvt,mmxmov")
569 (set_attr "mode" "DI")])
570
571 (define_expand "vec_setv2sf"
572 [(match_operand:V2SF 0 "register_operand")
573 (match_operand:SF 1 "register_operand")
574 (match_operand 2 "const_int_operand")]
575 "TARGET_MMX"
576 {
577 ix86_expand_vector_set (false, operands[0], operands[1],
578 INTVAL (operands[2]));
579 DONE;
580 })
581
582 ;; Avoid combining registers from different units in a single alternative,
583 ;; see comment above inline_secondary_memory_needed function in i386.c
584 (define_insn_and_split "*vec_extractv2sf_0"
585 [(set (match_operand:SF 0 "nonimmediate_operand" "=x, m,y ,m,f,r")
586 (vec_select:SF
587 (match_operand:V2SF 1 "nonimmediate_operand" " xm,x,ym,y,m,m")
588 (parallel [(const_int 0)])))]
589 "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
590 "#"
591 "&& reload_completed"
592 [(set (match_dup 0) (match_dup 1))]
593 {
594 if (REG_P (operands[1]))
595 operands[1] = gen_rtx_REG (SFmode, REGNO (operands[1]));
596 else
597 operands[1] = adjust_address (operands[1], SFmode, 0);
598 })
599
600 ;; Avoid combining registers from different units in a single alternative,
601 ;; see comment above inline_secondary_memory_needed function in i386.c
602 (define_insn "*vec_extractv2sf_1"
603 [(set (match_operand:SF 0 "nonimmediate_operand" "=y,x,x,y,x,f,r")
604 (vec_select:SF
605 (match_operand:V2SF 1 "nonimmediate_operand" " 0,x,x,o,o,o,o")
606 (parallel [(const_int 1)])))]
607 "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
608 "@
609 punpckhdq\t%0, %0
610 %vmovshdup\t{%1, %0|%0, %1}
611 shufps\t{$0xe5, %1, %0|%0, %1, 0xe5}
612 #
613 #
614 #
615 #"
616 [(set_attr "isa" "*,sse3,noavx,*,*,*,*")
617 (set_attr "type" "mmxcvt,sse,sseshuf1,mmxmov,ssemov,fmov,imov")
618 (set_attr "length_immediate" "*,*,1,*,*,*,*")
619 (set_attr "prefix_rep" "*,1,*,*,*,*,*")
620 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig,orig,orig")
621 (set_attr "mode" "DI,V4SF,V4SF,SF,SF,SF,SF")])
622
623 (define_split
624 [(set (match_operand:SF 0 "register_operand")
625 (vec_select:SF
626 (match_operand:V2SF 1 "memory_operand")
627 (parallel [(const_int 1)])))]
628 "TARGET_MMX && reload_completed"
629 [(set (match_dup 0) (match_dup 1))]
630 "operands[1] = adjust_address (operands[1], SFmode, 4);")
631
632 (define_expand "vec_extractv2sf"
633 [(match_operand:SF 0 "register_operand")
634 (match_operand:V2SF 1 "register_operand")
635 (match_operand 2 "const_int_operand")]
636 "TARGET_MMX"
637 {
638 ix86_expand_vector_extract (false, operands[0], operands[1],
639 INTVAL (operands[2]));
640 DONE;
641 })
642
643 (define_expand "vec_initv2sf"
644 [(match_operand:V2SF 0 "register_operand")
645 (match_operand 1)]
646 "TARGET_SSE"
647 {
648 ix86_expand_vector_init (false, operands[0], operands[1]);
649 DONE;
650 })
651
652 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
653 ;;
654 ;; Parallel integral arithmetic
655 ;;
656 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
657
658 (define_expand "mmx_<plusminus_insn><mode>3"
659 [(set (match_operand:MMXMODEI8 0 "register_operand")
660 (plusminus:MMXMODEI8
661 (match_operand:MMXMODEI8 1 "nonimmediate_operand")
662 (match_operand:MMXMODEI8 2 "nonimmediate_operand")))]
663 "TARGET_MMX || (TARGET_SSE2 && <MODE>mode == V1DImode)"
664 "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
665
666 (define_insn "*mmx_<plusminus_insn><mode>3"
667 [(set (match_operand:MMXMODEI8 0 "register_operand" "=y")
668 (plusminus:MMXMODEI8
669 (match_operand:MMXMODEI8 1 "nonimmediate_operand" "<comm>0")
670 (match_operand:MMXMODEI8 2 "nonimmediate_operand" "ym")))]
671 "(TARGET_MMX || (TARGET_SSE2 && <MODE>mode == V1DImode))
672 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
673 "p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}"
674 [(set_attr "type" "mmxadd")
675 (set_attr "mode" "DI")])
676
677 (define_expand "mmx_<plusminus_insn><mode>3"
678 [(set (match_operand:MMXMODE12 0 "register_operand")
679 (sat_plusminus:MMXMODE12
680 (match_operand:MMXMODE12 1 "nonimmediate_operand")
681 (match_operand:MMXMODE12 2 "nonimmediate_operand")))]
682 "TARGET_MMX"
683 "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
684
685 (define_insn "*mmx_<plusminus_insn><mode>3"
686 [(set (match_operand:MMXMODE12 0 "register_operand" "=y")
687 (sat_plusminus:MMXMODE12
688 (match_operand:MMXMODE12 1 "nonimmediate_operand" "<comm>0")
689 (match_operand:MMXMODE12 2 "nonimmediate_operand" "ym")))]
690 "TARGET_MMX && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
691 "p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}"
692 [(set_attr "type" "mmxadd")
693 (set_attr "mode" "DI")])
694
695 (define_expand "mmx_mulv4hi3"
696 [(set (match_operand:V4HI 0 "register_operand")
697 (mult:V4HI (match_operand:V4HI 1 "nonimmediate_operand")
698 (match_operand:V4HI 2 "nonimmediate_operand")))]
699 "TARGET_MMX"
700 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
701
702 (define_insn "*mmx_mulv4hi3"
703 [(set (match_operand:V4HI 0 "register_operand" "=y")
704 (mult:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "%0")
705 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
706 "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
707 "pmullw\t{%2, %0|%0, %2}"
708 [(set_attr "type" "mmxmul")
709 (set_attr "mode" "DI")])
710
711 (define_expand "mmx_smulv4hi3_highpart"
712 [(set (match_operand:V4HI 0 "register_operand")
713 (truncate:V4HI
714 (lshiftrt:V4SI
715 (mult:V4SI
716 (sign_extend:V4SI
717 (match_operand:V4HI 1 "nonimmediate_operand"))
718 (sign_extend:V4SI
719 (match_operand:V4HI 2 "nonimmediate_operand")))
720 (const_int 16))))]
721 "TARGET_MMX"
722 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
723
724 (define_insn "*mmx_smulv4hi3_highpart"
725 [(set (match_operand:V4HI 0 "register_operand" "=y")
726 (truncate:V4HI
727 (lshiftrt:V4SI
728 (mult:V4SI
729 (sign_extend:V4SI
730 (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
731 (sign_extend:V4SI
732 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
733 (const_int 16))))]
734 "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
735 "pmulhw\t{%2, %0|%0, %2}"
736 [(set_attr "type" "mmxmul")
737 (set_attr "mode" "DI")])
738
739 (define_expand "mmx_umulv4hi3_highpart"
740 [(set (match_operand:V4HI 0 "register_operand")
741 (truncate:V4HI
742 (lshiftrt:V4SI
743 (mult:V4SI
744 (zero_extend:V4SI
745 (match_operand:V4HI 1 "nonimmediate_operand"))
746 (zero_extend:V4SI
747 (match_operand:V4HI 2 "nonimmediate_operand")))
748 (const_int 16))))]
749 "TARGET_SSE || TARGET_3DNOW_A"
750 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
751
752 (define_insn "*mmx_umulv4hi3_highpart"
753 [(set (match_operand:V4HI 0 "register_operand" "=y")
754 (truncate:V4HI
755 (lshiftrt:V4SI
756 (mult:V4SI
757 (zero_extend:V4SI
758 (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
759 (zero_extend:V4SI
760 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
761 (const_int 16))))]
762 "(TARGET_SSE || TARGET_3DNOW_A)
763 && ix86_binary_operator_ok (MULT, V4HImode, operands)"
764 "pmulhuw\t{%2, %0|%0, %2}"
765 [(set_attr "type" "mmxmul")
766 (set_attr "mode" "DI")])
767
768 (define_expand "mmx_pmaddwd"
769 [(set (match_operand:V2SI 0 "register_operand")
770 (plus:V2SI
771 (mult:V2SI
772 (sign_extend:V2SI
773 (vec_select:V2HI
774 (match_operand:V4HI 1 "nonimmediate_operand")
775 (parallel [(const_int 0) (const_int 2)])))
776 (sign_extend:V2SI
777 (vec_select:V2HI
778 (match_operand:V4HI 2 "nonimmediate_operand")
779 (parallel [(const_int 0) (const_int 2)]))))
780 (mult:V2SI
781 (sign_extend:V2SI
782 (vec_select:V2HI (match_dup 1)
783 (parallel [(const_int 1) (const_int 3)])))
784 (sign_extend:V2SI
785 (vec_select:V2HI (match_dup 2)
786 (parallel [(const_int 1) (const_int 3)]))))))]
787 "TARGET_MMX"
788 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
789
790 (define_insn "*mmx_pmaddwd"
791 [(set (match_operand:V2SI 0 "register_operand" "=y")
792 (plus:V2SI
793 (mult:V2SI
794 (sign_extend:V2SI
795 (vec_select:V2HI
796 (match_operand:V4HI 1 "nonimmediate_operand" "%0")
797 (parallel [(const_int 0) (const_int 2)])))
798 (sign_extend:V2SI
799 (vec_select:V2HI
800 (match_operand:V4HI 2 "nonimmediate_operand" "ym")
801 (parallel [(const_int 0) (const_int 2)]))))
802 (mult:V2SI
803 (sign_extend:V2SI
804 (vec_select:V2HI (match_dup 1)
805 (parallel [(const_int 1) (const_int 3)])))
806 (sign_extend:V2SI
807 (vec_select:V2HI (match_dup 2)
808 (parallel [(const_int 1) (const_int 3)]))))))]
809 "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
810 "pmaddwd\t{%2, %0|%0, %2}"
811 [(set_attr "type" "mmxmul")
812 (set_attr "mode" "DI")])
813
814 (define_expand "mmx_pmulhrwv4hi3"
815 [(set (match_operand:V4HI 0 "register_operand")
816 (truncate:V4HI
817 (lshiftrt:V4SI
818 (plus:V4SI
819 (mult:V4SI
820 (sign_extend:V4SI
821 (match_operand:V4HI 1 "nonimmediate_operand"))
822 (sign_extend:V4SI
823 (match_operand:V4HI 2 "nonimmediate_operand")))
824 (const_vector:V4SI [(const_int 32768) (const_int 32768)
825 (const_int 32768) (const_int 32768)]))
826 (const_int 16))))]
827 "TARGET_3DNOW"
828 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
829
830 (define_insn "*mmx_pmulhrwv4hi3"
831 [(set (match_operand:V4HI 0 "register_operand" "=y")
832 (truncate:V4HI
833 (lshiftrt:V4SI
834 (plus:V4SI
835 (mult:V4SI
836 (sign_extend:V4SI
837 (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
838 (sign_extend:V4SI
839 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
840 (const_vector:V4SI [(const_int 32768) (const_int 32768)
841 (const_int 32768) (const_int 32768)]))
842 (const_int 16))))]
843 "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V4HImode, operands)"
844 "pmulhrw\t{%2, %0|%0, %2}"
845 [(set_attr "type" "mmxmul")
846 (set_attr "prefix_extra" "1")
847 (set_attr "mode" "DI")])
848
849 (define_expand "sse2_umulv1siv1di3"
850 [(set (match_operand:V1DI 0 "register_operand")
851 (mult:V1DI
852 (zero_extend:V1DI
853 (vec_select:V1SI
854 (match_operand:V2SI 1 "nonimmediate_operand")
855 (parallel [(const_int 0)])))
856 (zero_extend:V1DI
857 (vec_select:V1SI
858 (match_operand:V2SI 2 "nonimmediate_operand")
859 (parallel [(const_int 0)])))))]
860 "TARGET_SSE2"
861 "ix86_fixup_binary_operands_no_copy (MULT, V2SImode, operands);")
862
863 (define_insn "*sse2_umulv1siv1di3"
864 [(set (match_operand:V1DI 0 "register_operand" "=y")
865 (mult:V1DI
866 (zero_extend:V1DI
867 (vec_select:V1SI
868 (match_operand:V2SI 1 "nonimmediate_operand" "%0")
869 (parallel [(const_int 0)])))
870 (zero_extend:V1DI
871 (vec_select:V1SI
872 (match_operand:V2SI 2 "nonimmediate_operand" "ym")
873 (parallel [(const_int 0)])))))]
874 "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V2SImode, operands)"
875 "pmuludq\t{%2, %0|%0, %2}"
876 [(set_attr "type" "mmxmul")
877 (set_attr "mode" "DI")])
878
879 (define_expand "mmx_<code>v4hi3"
880 [(set (match_operand:V4HI 0 "register_operand")
881 (smaxmin:V4HI
882 (match_operand:V4HI 1 "nonimmediate_operand")
883 (match_operand:V4HI 2 "nonimmediate_operand")))]
884 "TARGET_SSE || TARGET_3DNOW_A"
885 "ix86_fixup_binary_operands_no_copy (<CODE>, V4HImode, operands);")
886
887 (define_insn "*mmx_<code>v4hi3"
888 [(set (match_operand:V4HI 0 "register_operand" "=y")
889 (smaxmin:V4HI
890 (match_operand:V4HI 1 "nonimmediate_operand" "%0")
891 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
892 "(TARGET_SSE || TARGET_3DNOW_A)
893 && ix86_binary_operator_ok (<CODE>, V4HImode, operands)"
894 "p<maxmin_int>w\t{%2, %0|%0, %2}"
895 [(set_attr "type" "mmxadd")
896 (set_attr "mode" "DI")])
897
898 (define_expand "mmx_<code>v8qi3"
899 [(set (match_operand:V8QI 0 "register_operand")
900 (umaxmin:V8QI
901 (match_operand:V8QI 1 "nonimmediate_operand")
902 (match_operand:V8QI 2 "nonimmediate_operand")))]
903 "TARGET_SSE || TARGET_3DNOW_A"
904 "ix86_fixup_binary_operands_no_copy (<CODE>, V8QImode, operands);")
905
906 (define_insn "*mmx_<code>v8qi3"
907 [(set (match_operand:V8QI 0 "register_operand" "=y")
908 (umaxmin:V8QI
909 (match_operand:V8QI 1 "nonimmediate_operand" "%0")
910 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
911 "(TARGET_SSE || TARGET_3DNOW_A)
912 && ix86_binary_operator_ok (<CODE>, V8QImode, operands)"
913 "p<maxmin_int>b\t{%2, %0|%0, %2}"
914 [(set_attr "type" "mmxadd")
915 (set_attr "mode" "DI")])
916
917 (define_insn "mmx_ashr<mode>3"
918 [(set (match_operand:MMXMODE24 0 "register_operand" "=y")
919 (ashiftrt:MMXMODE24
920 (match_operand:MMXMODE24 1 "register_operand" "0")
921 (match_operand:SI 2 "nonmemory_operand" "yN")))]
922 "TARGET_MMX"
923 "psra<mmxvecsize>\t{%2, %0|%0, %2}"
924 [(set_attr "type" "mmxshft")
925 (set (attr "length_immediate")
926 (if_then_else (match_operand 2 "const_int_operand")
927 (const_string "1")
928 (const_string "0")))
929 (set_attr "mode" "DI")])
930
931 (define_insn "mmx_<shift_insn><mode>3"
932 [(set (match_operand:MMXMODE248 0 "register_operand" "=y")
933 (any_lshift:MMXMODE248
934 (match_operand:MMXMODE248 1 "register_operand" "0")
935 (match_operand:SI 2 "nonmemory_operand" "yN")))]
936 "TARGET_MMX"
937 "p<vshift><mmxvecsize>\t{%2, %0|%0, %2}"
938 [(set_attr "type" "mmxshft")
939 (set (attr "length_immediate")
940 (if_then_else (match_operand 2 "const_int_operand")
941 (const_string "1")
942 (const_string "0")))
943 (set_attr "mode" "DI")])
944
945 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
946 ;;
947 ;; Parallel integral comparisons
948 ;;
949 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
950
951 (define_expand "mmx_eq<mode>3"
952 [(set (match_operand:MMXMODEI 0 "register_operand")
953 (eq:MMXMODEI
954 (match_operand:MMXMODEI 1 "nonimmediate_operand")
955 (match_operand:MMXMODEI 2 "nonimmediate_operand")))]
956 "TARGET_MMX"
957 "ix86_fixup_binary_operands_no_copy (EQ, <MODE>mode, operands);")
958
959 (define_insn "*mmx_eq<mode>3"
960 [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
961 (eq:MMXMODEI
962 (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
963 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
964 "TARGET_MMX && ix86_binary_operator_ok (EQ, <MODE>mode, operands)"
965 "pcmpeq<mmxvecsize>\t{%2, %0|%0, %2}"
966 [(set_attr "type" "mmxcmp")
967 (set_attr "mode" "DI")])
968
969 (define_insn "mmx_gt<mode>3"
970 [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
971 (gt:MMXMODEI
972 (match_operand:MMXMODEI 1 "register_operand" "0")
973 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
974 "TARGET_MMX"
975 "pcmpgt<mmxvecsize>\t{%2, %0|%0, %2}"
976 [(set_attr "type" "mmxcmp")
977 (set_attr "mode" "DI")])
978
979 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
980 ;;
981 ;; Parallel integral logical operations
982 ;;
983 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
984
985 (define_insn "mmx_andnot<mode>3"
986 [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
987 (and:MMXMODEI
988 (not:MMXMODEI (match_operand:MMXMODEI 1 "register_operand" "0"))
989 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
990 "TARGET_MMX"
991 "pandn\t{%2, %0|%0, %2}"
992 [(set_attr "type" "mmxadd")
993 (set_attr "mode" "DI")])
994
995 (define_expand "mmx_<code><mode>3"
996 [(set (match_operand:MMXMODEI 0 "register_operand")
997 (any_logic:MMXMODEI
998 (match_operand:MMXMODEI 1 "nonimmediate_operand")
999 (match_operand:MMXMODEI 2 "nonimmediate_operand")))]
1000 "TARGET_MMX"
1001 "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
1002
1003 (define_insn "*mmx_<code><mode>3"
1004 [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
1005 (any_logic:MMXMODEI
1006 (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
1007 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
1008 "TARGET_MMX && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
1009 "p<logic>\t{%2, %0|%0, %2}"
1010 [(set_attr "type" "mmxadd")
1011 (set_attr "mode" "DI")])
1012
1013 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1014 ;;
1015 ;; Parallel integral element swizzling
1016 ;;
1017 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1018
1019 (define_insn "mmx_packsswb"
1020 [(set (match_operand:V8QI 0 "register_operand" "=y")
1021 (vec_concat:V8QI
1022 (ss_truncate:V4QI
1023 (match_operand:V4HI 1 "register_operand" "0"))
1024 (ss_truncate:V4QI
1025 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))))]
1026 "TARGET_MMX"
1027 "packsswb\t{%2, %0|%0, %2}"
1028 [(set_attr "type" "mmxshft")
1029 (set_attr "mode" "DI")])
1030
1031 (define_insn "mmx_packssdw"
1032 [(set (match_operand:V4HI 0 "register_operand" "=y")
1033 (vec_concat:V4HI
1034 (ss_truncate:V2HI
1035 (match_operand:V2SI 1 "register_operand" "0"))
1036 (ss_truncate:V2HI
1037 (match_operand:V2SI 2 "nonimmediate_operand" "ym"))))]
1038 "TARGET_MMX"
1039 "packssdw\t{%2, %0|%0, %2}"
1040 [(set_attr "type" "mmxshft")
1041 (set_attr "mode" "DI")])
1042
1043 (define_insn "mmx_packuswb"
1044 [(set (match_operand:V8QI 0 "register_operand" "=y")
1045 (vec_concat:V8QI
1046 (us_truncate:V4QI
1047 (match_operand:V4HI 1 "register_operand" "0"))
1048 (us_truncate:V4QI
1049 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))))]
1050 "TARGET_MMX"
1051 "packuswb\t{%2, %0|%0, %2}"
1052 [(set_attr "type" "mmxshft")
1053 (set_attr "mode" "DI")])
1054
1055 (define_insn "mmx_punpckhbw"
1056 [(set (match_operand:V8QI 0 "register_operand" "=y")
1057 (vec_select:V8QI
1058 (vec_concat:V16QI
1059 (match_operand:V8QI 1 "register_operand" "0")
1060 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
1061 (parallel [(const_int 4) (const_int 12)
1062 (const_int 5) (const_int 13)
1063 (const_int 6) (const_int 14)
1064 (const_int 7) (const_int 15)])))]
1065 "TARGET_MMX"
1066 "punpckhbw\t{%2, %0|%0, %2}"
1067 [(set_attr "type" "mmxcvt")
1068 (set_attr "mode" "DI")])
1069
1070 (define_insn "mmx_punpcklbw"
1071 [(set (match_operand:V8QI 0 "register_operand" "=y")
1072 (vec_select:V8QI
1073 (vec_concat:V16QI
1074 (match_operand:V8QI 1 "register_operand" "0")
1075 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
1076 (parallel [(const_int 0) (const_int 8)
1077 (const_int 1) (const_int 9)
1078 (const_int 2) (const_int 10)
1079 (const_int 3) (const_int 11)])))]
1080 "TARGET_MMX"
1081 "punpcklbw\t{%2, %0|%0, %k2}"
1082 [(set_attr "type" "mmxcvt")
1083 (set_attr "mode" "DI")])
1084
1085 (define_insn "mmx_punpckhwd"
1086 [(set (match_operand:V4HI 0 "register_operand" "=y")
1087 (vec_select:V4HI
1088 (vec_concat:V8HI
1089 (match_operand:V4HI 1 "register_operand" "0")
1090 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
1091 (parallel [(const_int 2) (const_int 6)
1092 (const_int 3) (const_int 7)])))]
1093 "TARGET_MMX"
1094 "punpckhwd\t{%2, %0|%0, %2}"
1095 [(set_attr "type" "mmxcvt")
1096 (set_attr "mode" "DI")])
1097
1098 (define_insn "mmx_punpcklwd"
1099 [(set (match_operand:V4HI 0 "register_operand" "=y")
1100 (vec_select:V4HI
1101 (vec_concat:V8HI
1102 (match_operand:V4HI 1 "register_operand" "0")
1103 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
1104 (parallel [(const_int 0) (const_int 4)
1105 (const_int 1) (const_int 5)])))]
1106 "TARGET_MMX"
1107 "punpcklwd\t{%2, %0|%0, %k2}"
1108 [(set_attr "type" "mmxcvt")
1109 (set_attr "mode" "DI")])
1110
1111 (define_insn "mmx_punpckhdq"
1112 [(set (match_operand:V2SI 0 "register_operand" "=y")
1113 (vec_select:V2SI
1114 (vec_concat:V4SI
1115 (match_operand:V2SI 1 "register_operand" "0")
1116 (match_operand:V2SI 2 "nonimmediate_operand" "ym"))
1117 (parallel [(const_int 1)
1118 (const_int 3)])))]
1119 "TARGET_MMX"
1120 "punpckhdq\t{%2, %0|%0, %2}"
1121 [(set_attr "type" "mmxcvt")
1122 (set_attr "mode" "DI")])
1123
1124 (define_insn "mmx_punpckldq"
1125 [(set (match_operand:V2SI 0 "register_operand" "=y")
1126 (vec_select:V2SI
1127 (vec_concat:V4SI
1128 (match_operand:V2SI 1 "register_operand" "0")
1129 (match_operand:V2SI 2 "nonimmediate_operand" "ym"))
1130 (parallel [(const_int 0)
1131 (const_int 2)])))]
1132 "TARGET_MMX"
1133 "punpckldq\t{%2, %0|%0, %k2}"
1134 [(set_attr "type" "mmxcvt")
1135 (set_attr "mode" "DI")])
1136
1137 (define_expand "mmx_pinsrw"
1138 [(set (match_operand:V4HI 0 "register_operand")
1139 (vec_merge:V4HI
1140 (vec_duplicate:V4HI
1141 (match_operand:SI 2 "nonimmediate_operand"))
1142 (match_operand:V4HI 1 "register_operand")
1143 (match_operand:SI 3 "const_0_to_3_operand")))]
1144 "TARGET_SSE || TARGET_3DNOW_A"
1145 {
1146 operands[2] = gen_lowpart (HImode, operands[2]);
1147 operands[3] = GEN_INT (1 << INTVAL (operands[3]));
1148 })
1149
1150 (define_insn "*mmx_pinsrw"
1151 [(set (match_operand:V4HI 0 "register_operand" "=y")
1152 (vec_merge:V4HI
1153 (vec_duplicate:V4HI
1154 (match_operand:HI 2 "nonimmediate_operand" "rm"))
1155 (match_operand:V4HI 1 "register_operand" "0")
1156 (match_operand:SI 3 "const_int_operand")))]
1157 "(TARGET_SSE || TARGET_3DNOW_A)
1158 && ((unsigned) exact_log2 (INTVAL (operands[3]))
1159 < GET_MODE_NUNITS (V4HImode))"
1160 {
1161 operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
1162 if (MEM_P (operands[2]))
1163 return "pinsrw\t{%3, %2, %0|%0, %2, %3}";
1164 else
1165 return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}";
1166 }
1167 [(set_attr "type" "mmxcvt")
1168 (set_attr "length_immediate" "1")
1169 (set_attr "mode" "DI")])
1170
1171 (define_insn "mmx_pextrw"
1172 [(set (match_operand:SI 0 "register_operand" "=r")
1173 (zero_extend:SI
1174 (vec_select:HI
1175 (match_operand:V4HI 1 "register_operand" "y")
1176 (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n")]))))]
1177 "TARGET_SSE || TARGET_3DNOW_A"
1178 "pextrw\t{%2, %1, %0|%0, %1, %2}"
1179 [(set_attr "type" "mmxcvt")
1180 (set_attr "length_immediate" "1")
1181 (set_attr "mode" "DI")])
1182
1183 (define_expand "mmx_pshufw"
1184 [(match_operand:V4HI 0 "register_operand")
1185 (match_operand:V4HI 1 "nonimmediate_operand")
1186 (match_operand:SI 2 "const_int_operand")]
1187 "TARGET_SSE || TARGET_3DNOW_A"
1188 {
1189 int mask = INTVAL (operands[2]);
1190 emit_insn (gen_mmx_pshufw_1 (operands[0], operands[1],
1191 GEN_INT ((mask >> 0) & 3),
1192 GEN_INT ((mask >> 2) & 3),
1193 GEN_INT ((mask >> 4) & 3),
1194 GEN_INT ((mask >> 6) & 3)));
1195 DONE;
1196 })
1197
1198 (define_insn "mmx_pshufw_1"
1199 [(set (match_operand:V4HI 0 "register_operand" "=y")
1200 (vec_select:V4HI
1201 (match_operand:V4HI 1 "nonimmediate_operand" "ym")
1202 (parallel [(match_operand 2 "const_0_to_3_operand")
1203 (match_operand 3 "const_0_to_3_operand")
1204 (match_operand 4 "const_0_to_3_operand")
1205 (match_operand 5 "const_0_to_3_operand")])))]
1206 "TARGET_SSE || TARGET_3DNOW_A"
1207 {
1208 int mask = 0;
1209 mask |= INTVAL (operands[2]) << 0;
1210 mask |= INTVAL (operands[3]) << 2;
1211 mask |= INTVAL (operands[4]) << 4;
1212 mask |= INTVAL (operands[5]) << 6;
1213 operands[2] = GEN_INT (mask);
1214
1215 return "pshufw\t{%2, %1, %0|%0, %1, %2}";
1216 }
1217 [(set_attr "type" "mmxcvt")
1218 (set_attr "length_immediate" "1")
1219 (set_attr "mode" "DI")])
1220
1221 (define_insn "mmx_pswapdv2si2"
1222 [(set (match_operand:V2SI 0 "register_operand" "=y")
1223 (vec_select:V2SI
1224 (match_operand:V2SI 1 "nonimmediate_operand" "ym")
1225 (parallel [(const_int 1) (const_int 0)])))]
1226 "TARGET_3DNOW_A"
1227 "pswapd\t{%1, %0|%0, %1}"
1228 [(set_attr "type" "mmxcvt")
1229 (set_attr "prefix_extra" "1")
1230 (set_attr "mode" "DI")])
1231
1232 (define_insn "*vec_dupv4hi"
1233 [(set (match_operand:V4HI 0 "register_operand" "=y")
1234 (vec_duplicate:V4HI
1235 (truncate:HI
1236 (match_operand:SI 1 "register_operand" "0"))))]
1237 "TARGET_SSE || TARGET_3DNOW_A"
1238 "pshufw\t{$0, %0, %0|%0, %0, 0}"
1239 [(set_attr "type" "mmxcvt")
1240 (set_attr "length_immediate" "1")
1241 (set_attr "mode" "DI")])
1242
1243 (define_insn "*vec_dupv2si"
1244 [(set (match_operand:V2SI 0 "register_operand" "=y")
1245 (vec_duplicate:V2SI
1246 (match_operand:SI 1 "register_operand" "0")))]
1247 "TARGET_MMX"
1248 "punpckldq\t%0, %0"
1249 [(set_attr "type" "mmxcvt")
1250 (set_attr "mode" "DI")])
1251
1252 (define_insn "*mmx_concatv2si"
1253 [(set (match_operand:V2SI 0 "register_operand" "=y,y")
1254 (vec_concat:V2SI
1255 (match_operand:SI 1 "nonimmediate_operand" " 0,rm")
1256 (match_operand:SI 2 "vector_move_operand" "ym,C")))]
1257 "TARGET_MMX && !TARGET_SSE"
1258 "@
1259 punpckldq\t{%2, %0|%0, %2}
1260 movd\t{%1, %0|%0, %1}"
1261 [(set_attr "type" "mmxcvt,mmxmov")
1262 (set_attr "mode" "DI")])
1263
1264 (define_expand "vec_setv2si"
1265 [(match_operand:V2SI 0 "register_operand")
1266 (match_operand:SI 1 "register_operand")
1267 (match_operand 2 "const_int_operand")]
1268 "TARGET_MMX"
1269 {
1270 ix86_expand_vector_set (false, operands[0], operands[1],
1271 INTVAL (operands[2]));
1272 DONE;
1273 })
1274
1275 ;; Avoid combining registers from different units in a single alternative,
1276 ;; see comment above inline_secondary_memory_needed function in i386.c
1277 (define_insn_and_split "*vec_extractv2si_0"
1278 [(set (match_operand:SI 0 "nonimmediate_operand" "=x,m,y, m,r")
1279 (vec_select:SI
1280 (match_operand:V2SI 1 "nonimmediate_operand" "xm,x,ym,y,m")
1281 (parallel [(const_int 0)])))]
1282 "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1283 "#"
1284 "&& reload_completed"
1285 [(set (match_dup 0) (match_dup 1))]
1286 {
1287 if (REG_P (operands[1]))
1288 operands[1] = gen_rtx_REG (SImode, REGNO (operands[1]));
1289 else
1290 operands[1] = adjust_address (operands[1], SImode, 0);
1291 })
1292
1293 ;; Avoid combining registers from different units in a single alternative,
1294 ;; see comment above inline_secondary_memory_needed function in i386.c
1295 (define_insn "*vec_extractv2si_1"
1296 [(set (match_operand:SI 0 "nonimmediate_operand" "=y,x,x,y,x,r")
1297 (vec_select:SI
1298 (match_operand:V2SI 1 "nonimmediate_operand" " 0,x,x,o,o,o")
1299 (parallel [(const_int 1)])))]
1300 "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1301 "@
1302 punpckhdq\t%0, %0
1303 %vpshufd\t{$0xe5, %1, %0|%0, %1, 0xe5}
1304 shufps\t{$0xe5, %1, %0|%0, %1, 0xe5}
1305 #
1306 #
1307 #"
1308 [(set_attr "isa" "*,sse2,noavx,*,*,*")
1309 (set_attr "type" "mmxcvt,sseshuf1,sseshuf1,mmxmov,ssemov,imov")
1310 (set_attr "length_immediate" "*,1,1,*,*,*")
1311 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig,orig")
1312 (set_attr "mode" "DI,TI,V4SF,SI,SI,SI")])
1313
1314 (define_split
1315 [(set (match_operand:SI 0 "register_operand")
1316 (vec_select:SI
1317 (match_operand:V2SI 1 "memory_operand")
1318 (parallel [(const_int 1)])))]
1319 "TARGET_MMX && reload_completed"
1320 [(set (match_dup 0) (match_dup 1))]
1321 "operands[1] = adjust_address (operands[1], SImode, 4);")
1322
1323 (define_insn_and_split "*vec_extractv2si_zext_mem"
1324 [(set (match_operand:DI 0 "register_operand" "=y,x,r")
1325 (zero_extend:DI
1326 (vec_select:SI
1327 (match_operand:V2SI 1 "memory_operand" "o,o,o")
1328 (parallel [(match_operand:SI 2 "const_0_to_1_operand")]))))]
1329 "TARGET_64BIT && TARGET_MMX"
1330 "#"
1331 "&& reload_completed"
1332 [(set (match_dup 0) (zero_extend:DI (match_dup 1)))]
1333 {
1334 operands[1] = adjust_address (operands[1], SImode, INTVAL (operands[2]) * 4);
1335 })
1336
1337 (define_expand "vec_extractv2si"
1338 [(match_operand:SI 0 "register_operand")
1339 (match_operand:V2SI 1 "register_operand")
1340 (match_operand 2 "const_int_operand")]
1341 "TARGET_MMX"
1342 {
1343 ix86_expand_vector_extract (false, operands[0], operands[1],
1344 INTVAL (operands[2]));
1345 DONE;
1346 })
1347
1348 (define_expand "vec_initv2si"
1349 [(match_operand:V2SI 0 "register_operand")
1350 (match_operand 1)]
1351 "TARGET_SSE"
1352 {
1353 ix86_expand_vector_init (false, operands[0], operands[1]);
1354 DONE;
1355 })
1356
1357 (define_expand "vec_setv4hi"
1358 [(match_operand:V4HI 0 "register_operand")
1359 (match_operand:HI 1 "register_operand")
1360 (match_operand 2 "const_int_operand")]
1361 "TARGET_MMX"
1362 {
1363 ix86_expand_vector_set (false, operands[0], operands[1],
1364 INTVAL (operands[2]));
1365 DONE;
1366 })
1367
1368 (define_expand "vec_extractv4hi"
1369 [(match_operand:HI 0 "register_operand")
1370 (match_operand:V4HI 1 "register_operand")
1371 (match_operand 2 "const_int_operand")]
1372 "TARGET_MMX"
1373 {
1374 ix86_expand_vector_extract (false, operands[0], operands[1],
1375 INTVAL (operands[2]));
1376 DONE;
1377 })
1378
1379 (define_expand "vec_initv4hi"
1380 [(match_operand:V4HI 0 "register_operand")
1381 (match_operand 1)]
1382 "TARGET_SSE"
1383 {
1384 ix86_expand_vector_init (false, operands[0], operands[1]);
1385 DONE;
1386 })
1387
1388 (define_expand "vec_setv8qi"
1389 [(match_operand:V8QI 0 "register_operand")
1390 (match_operand:QI 1 "register_operand")
1391 (match_operand 2 "const_int_operand")]
1392 "TARGET_MMX"
1393 {
1394 ix86_expand_vector_set (false, operands[0], operands[1],
1395 INTVAL (operands[2]));
1396 DONE;
1397 })
1398
1399 (define_expand "vec_extractv8qi"
1400 [(match_operand:QI 0 "register_operand")
1401 (match_operand:V8QI 1 "register_operand")
1402 (match_operand 2 "const_int_operand")]
1403 "TARGET_MMX"
1404 {
1405 ix86_expand_vector_extract (false, operands[0], operands[1],
1406 INTVAL (operands[2]));
1407 DONE;
1408 })
1409
1410 (define_expand "vec_initv8qi"
1411 [(match_operand:V8QI 0 "register_operand")
1412 (match_operand 1)]
1413 "TARGET_SSE"
1414 {
1415 ix86_expand_vector_init (false, operands[0], operands[1]);
1416 DONE;
1417 })
1418
1419 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1420 ;;
1421 ;; Miscellaneous
1422 ;;
1423 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1424
1425 (define_expand "mmx_uavgv8qi3"
1426 [(set (match_operand:V8QI 0 "register_operand")
1427 (truncate:V8QI
1428 (lshiftrt:V8HI
1429 (plus:V8HI
1430 (plus:V8HI
1431 (zero_extend:V8HI
1432 (match_operand:V8QI 1 "nonimmediate_operand"))
1433 (zero_extend:V8HI
1434 (match_operand:V8QI 2 "nonimmediate_operand")))
1435 (const_vector:V8HI [(const_int 1) (const_int 1)
1436 (const_int 1) (const_int 1)
1437 (const_int 1) (const_int 1)
1438 (const_int 1) (const_int 1)]))
1439 (const_int 1))))]
1440 "TARGET_SSE || TARGET_3DNOW"
1441 "ix86_fixup_binary_operands_no_copy (PLUS, V8QImode, operands);")
1442
1443 (define_insn "*mmx_uavgv8qi3"
1444 [(set (match_operand:V8QI 0 "register_operand" "=y")
1445 (truncate:V8QI
1446 (lshiftrt:V8HI
1447 (plus:V8HI
1448 (plus:V8HI
1449 (zero_extend:V8HI
1450 (match_operand:V8QI 1 "nonimmediate_operand" "%0"))
1451 (zero_extend:V8HI
1452 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))
1453 (const_vector:V8HI [(const_int 1) (const_int 1)
1454 (const_int 1) (const_int 1)
1455 (const_int 1) (const_int 1)
1456 (const_int 1) (const_int 1)]))
1457 (const_int 1))))]
1458 "(TARGET_SSE || TARGET_3DNOW)
1459 && ix86_binary_operator_ok (PLUS, V8QImode, operands)"
1460 {
1461 /* These two instructions have the same operation, but their encoding
1462 is different. Prefer the one that is de facto standard. */
1463 if (TARGET_SSE || TARGET_3DNOW_A)
1464 return "pavgb\t{%2, %0|%0, %2}";
1465 else
1466 return "pavgusb\t{%2, %0|%0, %2}";
1467 }
1468 [(set_attr "type" "mmxshft")
1469 (set (attr "prefix_extra")
1470 (if_then_else
1471 (not (ior (match_test "TARGET_SSE")
1472 (match_test "TARGET_3DNOW_A")))
1473 (const_string "1")
1474 (const_string "*")))
1475 (set_attr "mode" "DI")])
1476
1477 (define_expand "mmx_uavgv4hi3"
1478 [(set (match_operand:V4HI 0 "register_operand")
1479 (truncate:V4HI
1480 (lshiftrt:V4SI
1481 (plus:V4SI
1482 (plus:V4SI
1483 (zero_extend:V4SI
1484 (match_operand:V4HI 1 "nonimmediate_operand"))
1485 (zero_extend:V4SI
1486 (match_operand:V4HI 2 "nonimmediate_operand")))
1487 (const_vector:V4SI [(const_int 1) (const_int 1)
1488 (const_int 1) (const_int 1)]))
1489 (const_int 1))))]
1490 "TARGET_SSE || TARGET_3DNOW_A"
1491 "ix86_fixup_binary_operands_no_copy (PLUS, V4HImode, operands);")
1492
1493 (define_insn "*mmx_uavgv4hi3"
1494 [(set (match_operand:V4HI 0 "register_operand" "=y")
1495 (truncate:V4HI
1496 (lshiftrt:V4SI
1497 (plus:V4SI
1498 (plus:V4SI
1499 (zero_extend:V4SI
1500 (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
1501 (zero_extend:V4SI
1502 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
1503 (const_vector:V4SI [(const_int 1) (const_int 1)
1504 (const_int 1) (const_int 1)]))
1505 (const_int 1))))]
1506 "(TARGET_SSE || TARGET_3DNOW_A)
1507 && ix86_binary_operator_ok (PLUS, V4HImode, operands)"
1508 "pavgw\t{%2, %0|%0, %2}"
1509 [(set_attr "type" "mmxshft")
1510 (set_attr "mode" "DI")])
1511
1512 (define_insn "mmx_psadbw"
1513 [(set (match_operand:V1DI 0 "register_operand" "=y")
1514 (unspec:V1DI [(match_operand:V8QI 1 "register_operand" "0")
1515 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
1516 UNSPEC_PSADBW))]
1517 "TARGET_SSE || TARGET_3DNOW_A"
1518 "psadbw\t{%2, %0|%0, %2}"
1519 [(set_attr "type" "mmxshft")
1520 (set_attr "mode" "DI")])
1521
1522 (define_insn "mmx_pmovmskb"
1523 [(set (match_operand:SI 0 "register_operand" "=r")
1524 (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
1525 UNSPEC_MOVMSK))]
1526 "TARGET_SSE || TARGET_3DNOW_A"
1527 "pmovmskb\t{%1, %0|%0, %1}"
1528 [(set_attr "type" "mmxcvt")
1529 (set_attr "mode" "DI")])
1530
1531 (define_expand "mmx_maskmovq"
1532 [(set (match_operand:V8QI 0 "memory_operand")
1533 (unspec:V8QI [(match_operand:V8QI 1 "register_operand")
1534 (match_operand:V8QI 2 "register_operand")
1535 (match_dup 0)]
1536 UNSPEC_MASKMOV))]
1537 "TARGET_SSE || TARGET_3DNOW_A")
1538
1539 (define_insn "*mmx_maskmovq"
1540 [(set (mem:V8QI (match_operand:P 0 "register_operand" "D"))
1541 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
1542 (match_operand:V8QI 2 "register_operand" "y")
1543 (mem:V8QI (match_dup 0))]
1544 UNSPEC_MASKMOV))]
1545 "TARGET_SSE || TARGET_3DNOW_A"
1546 ;; @@@ check ordering of operands in intel/nonintel syntax
1547 "maskmovq\t{%2, %1|%1, %2}"
1548 [(set_attr "type" "mmxcvt")
1549 (set_attr "znver1_decode" "vector")
1550 (set_attr "mode" "DI")])
1551
1552 (define_expand "mmx_emms"
1553 [(match_par_dup 0 [(const_int 0)])]
1554 "TARGET_MMX"
1555 {
1556 int regno;
1557
1558 operands[0] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (17));
1559
1560 XVECEXP (operands[0], 0, 0)
1561 = gen_rtx_UNSPEC_VOLATILE (VOIDmode, gen_rtvec (1, const0_rtx),
1562 UNSPECV_EMMS);
1563
1564 for (regno = 0; regno < 8; regno++)
1565 {
1566 XVECEXP (operands[0], 0, regno + 1)
1567 = gen_rtx_CLOBBER (VOIDmode,
1568 gen_rtx_REG (XFmode, FIRST_STACK_REG + regno));
1569
1570 XVECEXP (operands[0], 0, regno + 9)
1571 = gen_rtx_CLOBBER (VOIDmode,
1572 gen_rtx_REG (DImode, FIRST_MMX_REG + regno));
1573 }
1574 })
1575
1576 (define_insn "*mmx_emms"
1577 [(match_parallel 0 "emms_operation"
1578 [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)])]
1579 "TARGET_MMX"
1580 "emms"
1581 [(set_attr "type" "mmx")
1582 (set_attr "modrm" "0")
1583 (set_attr "memory" "none")])
1584
1585 (define_expand "mmx_femms"
1586 [(match_par_dup 0 [(const_int 0)])]
1587 "TARGET_3DNOW"
1588 {
1589 int regno;
1590
1591 operands[0] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (17));
1592
1593 XVECEXP (operands[0], 0, 0)
1594 = gen_rtx_UNSPEC_VOLATILE (VOIDmode, gen_rtvec (1, const0_rtx),
1595 UNSPECV_FEMMS);
1596
1597 for (regno = 0; regno < 8; regno++)
1598 {
1599 XVECEXP (operands[0], 0, regno + 1)
1600 = gen_rtx_CLOBBER (VOIDmode,
1601 gen_rtx_REG (XFmode, FIRST_STACK_REG + regno));
1602
1603 XVECEXP (operands[0], 0, regno + 9)
1604 = gen_rtx_CLOBBER (VOIDmode,
1605 gen_rtx_REG (DImode, FIRST_MMX_REG + regno));
1606 }
1607 })
1608
1609 (define_insn "*mmx_femms"
1610 [(match_parallel 0 "emms_operation"
1611 [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)])]
1612 "TARGET_3DNOW"
1613 "femms"
1614 [(set_attr "type" "mmx")
1615 (set_attr "modrm" "0")
1616 (set_attr "memory" "none")])