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