comparison gcc/config/i386/mmx.md @ 0:a06113de4d67

first commit
author kent <kent@cr.ie.u-ryukyu.ac.jp>
date Fri, 17 Jul 2009 14:47:48 +0900
parents
children 3bfb6c00c1e0
comparison
equal deleted inserted replaced
-1:000000000000 0:a06113de4d67
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}
339 pfsubr\t{%2, %0|%0, %2}"
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])));
1205 return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}";
1206 }
1207 [(set_attr "type" "mmxcvt")
1208 (set_attr "mode" "DI")])
1209
1210 (define_insn "mmx_pextrw"
1211 [(set (match_operand:SI 0 "register_operand" "=r")
1212 (zero_extend:SI
1213 (vec_select:HI
1214 (match_operand:V4HI 1 "register_operand" "y")
1215 (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n")]))))]
1216 "TARGET_SSE || TARGET_3DNOW_A"
1217 "pextrw\t{%2, %1, %0|%0, %1, %2}"
1218 [(set_attr "type" "mmxcvt")
1219 (set_attr "mode" "DI")])
1220
1221 (define_expand "mmx_pshufw"
1222 [(match_operand:V4HI 0 "register_operand" "")
1223 (match_operand:V4HI 1 "nonimmediate_operand" "")
1224 (match_operand:SI 2 "const_int_operand" "")]
1225 "TARGET_SSE || TARGET_3DNOW_A"
1226 {
1227 int mask = INTVAL (operands[2]);
1228 emit_insn (gen_mmx_pshufw_1 (operands[0], operands[1],
1229 GEN_INT ((mask >> 0) & 3),
1230 GEN_INT ((mask >> 2) & 3),
1231 GEN_INT ((mask >> 4) & 3),
1232 GEN_INT ((mask >> 6) & 3)));
1233 DONE;
1234 })
1235
1236 (define_insn "mmx_pshufw_1"
1237 [(set (match_operand:V4HI 0 "register_operand" "=y")
1238 (vec_select:V4HI
1239 (match_operand:V4HI 1 "nonimmediate_operand" "ym")
1240 (parallel [(match_operand 2 "const_0_to_3_operand" "")
1241 (match_operand 3 "const_0_to_3_operand" "")
1242 (match_operand 4 "const_0_to_3_operand" "")
1243 (match_operand 5 "const_0_to_3_operand" "")])))]
1244 "TARGET_SSE || TARGET_3DNOW_A"
1245 {
1246 int mask = 0;
1247 mask |= INTVAL (operands[2]) << 0;
1248 mask |= INTVAL (operands[3]) << 2;
1249 mask |= INTVAL (operands[4]) << 4;
1250 mask |= INTVAL (operands[5]) << 6;
1251 operands[2] = GEN_INT (mask);
1252
1253 return "pshufw\t{%2, %1, %0|%0, %1, %2}";
1254 }
1255 [(set_attr "type" "mmxcvt")
1256 (set_attr "mode" "DI")])
1257
1258 (define_insn "mmx_pswapdv2si2"
1259 [(set (match_operand:V2SI 0 "register_operand" "=y")
1260 (vec_select:V2SI
1261 (match_operand:V2SI 1 "nonimmediate_operand" "ym")
1262 (parallel [(const_int 1) (const_int 0)])))]
1263 "TARGET_3DNOW_A"
1264 "pswapd\t{%1, %0|%0, %1}"
1265 [(set_attr "type" "mmxcvt")
1266 (set_attr "mode" "DI")])
1267
1268 (define_insn "*vec_dupv4hi"
1269 [(set (match_operand:V4HI 0 "register_operand" "=y")
1270 (vec_duplicate:V4HI
1271 (truncate:HI
1272 (match_operand:SI 1 "register_operand" "0"))))]
1273 "TARGET_SSE || TARGET_3DNOW_A"
1274 "pshufw\t{$0, %0, %0|%0, %0, 0}"
1275 [(set_attr "type" "mmxcvt")
1276 (set_attr "mode" "DI")])
1277
1278 (define_insn "*vec_dupv2si"
1279 [(set (match_operand:V2SI 0 "register_operand" "=y")
1280 (vec_duplicate:V2SI
1281 (match_operand:SI 1 "register_operand" "0")))]
1282 "TARGET_MMX"
1283 "punpckldq\t%0, %0"
1284 [(set_attr "type" "mmxcvt")
1285 (set_attr "mode" "DI")])
1286
1287 (define_insn "*mmx_concatv2si"
1288 [(set (match_operand:V2SI 0 "register_operand" "=y,y")
1289 (vec_concat:V2SI
1290 (match_operand:SI 1 "nonimmediate_operand" " 0,rm")
1291 (match_operand:SI 2 "vector_move_operand" "ym,C")))]
1292 "TARGET_MMX && !TARGET_SSE"
1293 "@
1294 punpckldq\t{%2, %0|%0, %2}
1295 movd\t{%1, %0|%0, %1}"
1296 [(set_attr "type" "mmxcvt,mmxmov")
1297 (set_attr "mode" "DI")])
1298
1299 (define_expand "vec_setv2si"
1300 [(match_operand:V2SI 0 "register_operand" "")
1301 (match_operand:SI 1 "register_operand" "")
1302 (match_operand 2 "const_int_operand" "")]
1303 "TARGET_MMX"
1304 {
1305 ix86_expand_vector_set (false, operands[0], operands[1],
1306 INTVAL (operands[2]));
1307 DONE;
1308 })
1309
1310 ;; Avoid combining registers from different units in a single alternative,
1311 ;; see comment above inline_secondary_memory_needed function in i386.c
1312 (define_insn_and_split "*vec_extractv2si_0"
1313 [(set (match_operand:SI 0 "nonimmediate_operand" "=x,m,y, m,r")
1314 (vec_select:SI
1315 (match_operand:V2SI 1 "nonimmediate_operand" "xm,x,ym,y,m")
1316 (parallel [(const_int 0)])))]
1317 "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1318 "#"
1319 "&& reload_completed"
1320 [(const_int 0)]
1321 {
1322 rtx op1 = operands[1];
1323 if (REG_P (op1))
1324 op1 = gen_rtx_REG (SImode, REGNO (op1));
1325 else
1326 op1 = gen_lowpart (SImode, op1);
1327 emit_move_insn (operands[0], op1);
1328 DONE;
1329 })
1330
1331 ;; Avoid combining registers from different units in a single alternative,
1332 ;; see comment above inline_secondary_memory_needed function in i386.c
1333 (define_insn "*vec_extractv2si_1"
1334 [(set (match_operand:SI 0 "nonimmediate_operand" "=y,Y2,Y2,x,y,x,r")
1335 (vec_select:SI
1336 (match_operand:V2SI 1 "nonimmediate_operand" " 0,0 ,Y2,0,o,o,o")
1337 (parallel [(const_int 1)])))]
1338 "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1339 "@
1340 punpckhdq\t%0, %0
1341 punpckhdq\t%0, %0
1342 pshufd\t{$85, %1, %0|%0, %1, 85}
1343 unpckhps\t%0, %0
1344 #
1345 #
1346 #"
1347 [(set_attr "type" "mmxcvt,sselog1,sselog1,sselog1,mmxmov,ssemov,imov")
1348 (set_attr "mode" "DI,TI,TI,V4SF,SI,SI,SI")])
1349
1350 (define_split
1351 [(set (match_operand:SI 0 "register_operand" "")
1352 (vec_select:SI
1353 (match_operand:V2SI 1 "memory_operand" "")
1354 (parallel [(const_int 1)])))]
1355 "TARGET_MMX && reload_completed"
1356 [(const_int 0)]
1357 {
1358 operands[1] = adjust_address (operands[1], SImode, 4);
1359 emit_move_insn (operands[0], operands[1]);
1360 DONE;
1361 })
1362
1363 (define_expand "vec_extractv2si"
1364 [(match_operand:SI 0 "register_operand" "")
1365 (match_operand:V2SI 1 "register_operand" "")
1366 (match_operand 2 "const_int_operand" "")]
1367 "TARGET_MMX"
1368 {
1369 ix86_expand_vector_extract (false, operands[0], operands[1],
1370 INTVAL (operands[2]));
1371 DONE;
1372 })
1373
1374 (define_expand "vec_initv2si"
1375 [(match_operand:V2SI 0 "register_operand" "")
1376 (match_operand 1 "" "")]
1377 "TARGET_SSE"
1378 {
1379 ix86_expand_vector_init (false, operands[0], operands[1]);
1380 DONE;
1381 })
1382
1383 (define_expand "vec_setv4hi"
1384 [(match_operand:V4HI 0 "register_operand" "")
1385 (match_operand:HI 1 "register_operand" "")
1386 (match_operand 2 "const_int_operand" "")]
1387 "TARGET_MMX"
1388 {
1389 ix86_expand_vector_set (false, operands[0], operands[1],
1390 INTVAL (operands[2]));
1391 DONE;
1392 })
1393
1394 (define_expand "vec_extractv4hi"
1395 [(match_operand:HI 0 "register_operand" "")
1396 (match_operand:V4HI 1 "register_operand" "")
1397 (match_operand 2 "const_int_operand" "")]
1398 "TARGET_MMX"
1399 {
1400 ix86_expand_vector_extract (false, operands[0], operands[1],
1401 INTVAL (operands[2]));
1402 DONE;
1403 })
1404
1405 (define_expand "vec_initv4hi"
1406 [(match_operand:V4HI 0 "register_operand" "")
1407 (match_operand 1 "" "")]
1408 "TARGET_SSE"
1409 {
1410 ix86_expand_vector_init (false, operands[0], operands[1]);
1411 DONE;
1412 })
1413
1414 (define_expand "vec_setv8qi"
1415 [(match_operand:V8QI 0 "register_operand" "")
1416 (match_operand:QI 1 "register_operand" "")
1417 (match_operand 2 "const_int_operand" "")]
1418 "TARGET_MMX"
1419 {
1420 ix86_expand_vector_set (false, operands[0], operands[1],
1421 INTVAL (operands[2]));
1422 DONE;
1423 })
1424
1425 (define_expand "vec_extractv8qi"
1426 [(match_operand:QI 0 "register_operand" "")
1427 (match_operand:V8QI 1 "register_operand" "")
1428 (match_operand 2 "const_int_operand" "")]
1429 "TARGET_MMX"
1430 {
1431 ix86_expand_vector_extract (false, operands[0], operands[1],
1432 INTVAL (operands[2]));
1433 DONE;
1434 })
1435
1436 (define_expand "vec_initv8qi"
1437 [(match_operand:V8QI 0 "register_operand" "")
1438 (match_operand 1 "" "")]
1439 "TARGET_SSE"
1440 {
1441 ix86_expand_vector_init (false, operands[0], operands[1]);
1442 DONE;
1443 })
1444
1445 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1446 ;;
1447 ;; Miscellaneous
1448 ;;
1449 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1450
1451 (define_expand "mmx_uavgv8qi3"
1452 [(set (match_operand:V8QI 0 "register_operand" "")
1453 (truncate:V8QI
1454 (lshiftrt:V8HI
1455 (plus:V8HI
1456 (plus:V8HI
1457 (zero_extend:V8HI
1458 (match_operand:V8QI 1 "nonimmediate_operand" ""))
1459 (zero_extend:V8HI
1460 (match_operand:V8QI 2 "nonimmediate_operand" "")))
1461 (const_vector:V8HI [(const_int 1) (const_int 1)
1462 (const_int 1) (const_int 1)
1463 (const_int 1) (const_int 1)
1464 (const_int 1) (const_int 1)]))
1465 (const_int 1))))]
1466 "TARGET_SSE || TARGET_3DNOW"
1467 "ix86_fixup_binary_operands_no_copy (PLUS, V8QImode, operands);")
1468
1469 (define_insn "*mmx_uavgv8qi3"
1470 [(set (match_operand:V8QI 0 "register_operand" "=y")
1471 (truncate:V8QI
1472 (lshiftrt:V8HI
1473 (plus:V8HI
1474 (plus:V8HI
1475 (zero_extend:V8HI
1476 (match_operand:V8QI 1 "nonimmediate_operand" "%0"))
1477 (zero_extend:V8HI
1478 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))
1479 (const_vector:V8HI [(const_int 1) (const_int 1)
1480 (const_int 1) (const_int 1)
1481 (const_int 1) (const_int 1)
1482 (const_int 1) (const_int 1)]))
1483 (const_int 1))))]
1484 "(TARGET_SSE || TARGET_3DNOW)
1485 && ix86_binary_operator_ok (PLUS, V8QImode, operands)"
1486 {
1487 /* These two instructions have the same operation, but their encoding
1488 is different. Prefer the one that is de facto standard. */
1489 if (TARGET_SSE || TARGET_3DNOW_A)
1490 return "pavgb\t{%2, %0|%0, %2}";
1491 else
1492 return "pavgusb\t{%2, %0|%0, %2}";
1493 }
1494 [(set_attr "type" "mmxshft")
1495 (set_attr "mode" "DI")])
1496
1497 (define_expand "mmx_uavgv4hi3"
1498 [(set (match_operand:V4HI 0 "register_operand" "")
1499 (truncate:V4HI
1500 (lshiftrt:V4SI
1501 (plus:V4SI
1502 (plus:V4SI
1503 (zero_extend:V4SI
1504 (match_operand:V4HI 1 "nonimmediate_operand" ""))
1505 (zero_extend:V4SI
1506 (match_operand:V4HI 2 "nonimmediate_operand" "")))
1507 (const_vector:V4SI [(const_int 1) (const_int 1)
1508 (const_int 1) (const_int 1)]))
1509 (const_int 1))))]
1510 "TARGET_SSE || TARGET_3DNOW_A"
1511 "ix86_fixup_binary_operands_no_copy (PLUS, V4HImode, operands);")
1512
1513 (define_insn "*mmx_uavgv4hi3"
1514 [(set (match_operand:V4HI 0 "register_operand" "=y")
1515 (truncate:V4HI
1516 (lshiftrt:V4SI
1517 (plus:V4SI
1518 (plus:V4SI
1519 (zero_extend:V4SI
1520 (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
1521 (zero_extend:V4SI
1522 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
1523 (const_vector:V4SI [(const_int 1) (const_int 1)
1524 (const_int 1) (const_int 1)]))
1525 (const_int 1))))]
1526 "(TARGET_SSE || TARGET_3DNOW_A)
1527 && ix86_binary_operator_ok (PLUS, V4HImode, operands)"
1528 "pavgw\t{%2, %0|%0, %2}"
1529 [(set_attr "type" "mmxshft")
1530 (set_attr "mode" "DI")])
1531
1532 (define_insn "mmx_psadbw"
1533 [(set (match_operand:V1DI 0 "register_operand" "=y")
1534 (unspec:V1DI [(match_operand:V8QI 1 "register_operand" "0")
1535 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
1536 UNSPEC_PSADBW))]
1537 "TARGET_SSE || TARGET_3DNOW_A"
1538 "psadbw\t{%2, %0|%0, %2}"
1539 [(set_attr "type" "mmxshft")
1540 (set_attr "mode" "DI")])
1541
1542 (define_insn "mmx_pmovmskb"
1543 [(set (match_operand:SI 0 "register_operand" "=r")
1544 (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
1545 UNSPEC_MOVMSK))]
1546 "TARGET_SSE || TARGET_3DNOW_A"
1547 "pmovmskb\t{%1, %0|%0, %1}"
1548 [(set_attr "type" "mmxcvt")
1549 (set_attr "mode" "DI")])
1550
1551 (define_expand "mmx_maskmovq"
1552 [(set (match_operand:V8QI 0 "memory_operand" "")
1553 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "")
1554 (match_operand:V8QI 2 "register_operand" "")
1555 (match_dup 0)]
1556 UNSPEC_MASKMOV))]
1557 "TARGET_SSE || TARGET_3DNOW_A"
1558 "")
1559
1560 (define_insn "*mmx_maskmovq"
1561 [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
1562 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
1563 (match_operand:V8QI 2 "register_operand" "y")
1564 (mem:V8QI (match_dup 0))]
1565 UNSPEC_MASKMOV))]
1566 "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
1567 ;; @@@ check ordering of operands in intel/nonintel syntax
1568 "maskmovq\t{%2, %1|%1, %2}"
1569 [(set_attr "type" "mmxcvt")
1570 (set_attr "mode" "DI")])
1571
1572 (define_insn "*mmx_maskmovq_rex"
1573 [(set (mem:V8QI (match_operand:DI 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_emms"
1585 [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
1586 (clobber (reg:XF ST0_REG))
1587 (clobber (reg:XF ST1_REG))
1588 (clobber (reg:XF ST2_REG))
1589 (clobber (reg:XF ST3_REG))
1590 (clobber (reg:XF ST4_REG))
1591 (clobber (reg:XF ST5_REG))
1592 (clobber (reg:XF ST6_REG))
1593 (clobber (reg:XF ST7_REG))
1594 (clobber (reg:DI MM0_REG))
1595 (clobber (reg:DI MM1_REG))
1596 (clobber (reg:DI MM2_REG))
1597 (clobber (reg:DI MM3_REG))
1598 (clobber (reg:DI MM4_REG))
1599 (clobber (reg:DI MM5_REG))
1600 (clobber (reg:DI MM6_REG))
1601 (clobber (reg:DI MM7_REG))]
1602 "TARGET_MMX"
1603 "emms"
1604 [(set_attr "type" "mmx")
1605 (set_attr "memory" "unknown")])
1606
1607 (define_insn "mmx_femms"
1608 [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
1609 (clobber (reg:XF ST0_REG))
1610 (clobber (reg:XF ST1_REG))
1611 (clobber (reg:XF ST2_REG))
1612 (clobber (reg:XF ST3_REG))
1613 (clobber (reg:XF ST4_REG))
1614 (clobber (reg:XF ST5_REG))
1615 (clobber (reg:XF ST6_REG))
1616 (clobber (reg:XF ST7_REG))
1617 (clobber (reg:DI MM0_REG))
1618 (clobber (reg:DI MM1_REG))
1619 (clobber (reg:DI MM2_REG))
1620 (clobber (reg:DI MM3_REG))
1621 (clobber (reg:DI MM4_REG))
1622 (clobber (reg:DI MM5_REG))
1623 (clobber (reg:DI MM6_REG))
1624 (clobber (reg:DI MM7_REG))]
1625 "TARGET_3DNOW"
1626 "femms"
1627 [(set_attr "type" "mmx")
1628 (set_attr "memory" "none")])