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