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