OSDN Git Service

* config/i386/i386.c (bdesc_2arg): Update names for mmx_ prefixes.
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / mmx.md
1 ;; GCC machine description for MMX and 3dNOW! instructions
2 ;; Copyright (C) 2005
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 2, 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 COPYING.  If not, write to
19 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
20 ;; Boston, MA 02111-1307, USA.
21
22 ;; The MMX and 3dNOW! patterns are in the same file because they use
23 ;; the same register file, and 3dNOW! adds a number of extensions to
24 ;; the base integer MMX isa.
25
26 ;; Note!  Except for the basic move instructions, *all* of these 
27 ;; patterns are outside the normal optabs namespace.  This is because
28 ;; use of these registers requires the insertion of emms or femms
29 ;; instructions to return to normal fpu mode.  The compiler doesn't
30 ;; know how to do that itself, which means it's up to the user.  Which
31 ;; means that we should never use any of these patterns except at the
32 ;; direction of the user via a builtin.
33
34 ;; 8 byte integral modes handled by MMX (and by extension, SSE)
35 (define_mode_macro MMXMODEI [V8QI V4HI V2SI])
36
37 ;; All 8-byte vector modes handled by MMX
38 (define_mode_macro MMXMODE [V8QI V4HI V2SI V2SF])
39
40 ;; Mix-n-match
41 (define_mode_macro MMXMODE12 [V8QI V4HI])
42 (define_mode_macro MMXMODE24 [V4HI V2SI])
43
44 ;; Mapping from integer vector mode to mnemonic suffix
45 (define_mode_attr mmxvecsize [(V8QI "b") (V4HI "w") (V2SI "d") (DI "q")])
46
47 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
48 ;;
49 ;; Move patterns
50 ;;
51 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
52
53 ;; All of these patterns are enabled for MMX as well as 3dNOW.
54 ;; This is essential for maintaining stable calling conventions.
55
56 (define_expand "mov<mode>"
57   [(set (match_operand:MMXMODEI 0 "nonimmediate_operand" "")
58         (match_operand:MMXMODEI 1 "nonimmediate_operand" ""))]
59   "TARGET_MMX"
60 {
61   ix86_expand_vector_move (<MODE>mode, operands);
62   DONE;
63 })
64
65 (define_insn "*mov<mode>_internal_rex64"
66   [(set (match_operand:MMXMODEI 0 "nonimmediate_operand"
67                                 "=rm,r,*y,*y ,m ,*y,Y ,x,x ,m,r,x")
68         (match_operand:MMXMODEI 1 "vector_move_operand"
69                                 "Cr ,m,C ,*ym,*y,Y ,*y,C,xm,x,x,r"))]
70   "TARGET_64BIT && TARGET_MMX
71    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
72   "@
73     movq\t{%1, %0|%0, %1}
74     movq\t{%1, %0|%0, %1}
75     pxor\t%0, %0
76     movq\t{%1, %0|%0, %1}
77     movq\t{%1, %0|%0, %1}
78     movdq2q\t{%1, %0|%0, %1}
79     movq2dq\t{%1, %0|%0, %1}
80     pxor\t%0, %0
81     movq\t{%1, %0|%0, %1}
82     movq\t{%1, %0|%0, %1}
83     movd\t{%1, %0|%0, %1}
84     movd\t{%1, %0|%0, %1}"
85   [(set_attr "type" "imov,imov,mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov,ssemov,ssemov,ssemov")
86    (set_attr "mode" "DI")])
87
88 (define_insn "*mov<mode>_internal"
89   [(set (match_operand:MMXMODEI 0 "nonimmediate_operand"
90                                 "=*y,*y ,m ,*y,*Y,*Y,*Y ,m ,*x,*x,*x,m")
91         (match_operand:MMXMODEI 1 "vector_move_operand"
92                                 "C  ,*ym,*y,*Y,*y,C ,*Ym,*Y,C ,*x,m ,*x"))]
93   "TARGET_MMX
94    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
95   "@
96     pxor\t%0, %0
97     movq\t{%1, %0|%0, %1}
98     movq\t{%1, %0|%0, %1}
99     movdq2q\t{%1, %0|%0, %1}
100     movq2dq\t{%1, %0|%0, %1}
101     pxor\t%0, %0
102     movq\t{%1, %0|%0, %1}
103     movq\t{%1, %0|%0, %1}
104     xorps\t%0, %0
105     movaps\t{%1, %0|%0, %1}
106     movlps\t{%1, %0|%0, %1}
107     movlps\t{%1, %0|%0, %1}"
108   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov,ssemov,ssemov,ssemov,ssemov,ssemov")
109    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,DI,V4SF,V4SF,V2SF,V2SF")])
110
111 (define_expand "movv2sf"
112   [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
113         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
114   "TARGET_MMX"
115 {
116   ix86_expand_vector_move (V2SFmode, operands);
117   DONE;
118 })
119
120 (define_insn "*movv2sf_internal_rex64"
121   [(set (match_operand:V2SF 0 "nonimmediate_operand"
122                                 "=rm,r,*y ,*y ,m ,*y,Y ,x,x ,m,r,x")
123         (match_operand:V2SF 1 "vector_move_operand"
124                                 "Cr ,m ,C ,*ym,*y,Y ,*y,C,xm,x,x,r"))]
125   "TARGET_64BIT && TARGET_MMX
126    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
127   "@
128     movq\t{%1, %0|%0, %1}
129     movq\t{%1, %0|%0, %1}
130     pxor\t%0, %0
131     movq\t{%1, %0|%0, %1}
132     movq\t{%1, %0|%0, %1}
133     movdq2q\t{%1, %0|%0, %1}
134     movq2dq\t{%1, %0|%0, %1}
135     xorps\t%0, %0
136     movlps\t{%1, %0|%0, %1}
137     movlps\t{%1, %0|%0, %1}
138     movd\t{%1, %0|%0, %1}
139     movd\t{%1, %0|%0, %1}"
140   [(set_attr "type" "imov,imov,mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov,ssemov,ssemov,ssemov")
141    (set_attr "mode" "DI,DI,DI,DI,DI,DI,DI,V4SF,V2SF,V2SF,DI,DI")])
142
143 (define_insn "*movv2sf_internal"
144   [(set (match_operand:V2SF 0 "nonimmediate_operand"
145                                         "=*y,*y ,m,*y,*Y,*x,*x ,m")
146         (match_operand:V2SF 1 "vector_move_operand"
147                                         "C ,*ym,*y,*Y,*y,C ,*xm,*x"))]
148   "TARGET_MMX
149    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
150   "@
151     pxor\t%0, %0
152     movq\t{%1, %0|%0, %1}
153     movq\t{%1, %0|%0, %1}
154     movdq2q\t{%1, %0|%0, %1}
155     movq2dq\t{%1, %0|%0, %1}
156     xorps\t%0, %0
157     movlps\t{%1, %0|%0, %1}
158     movlps\t{%1, %0|%0, %1}"
159   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov,ssemov")
160    (set_attr "mode" "DI,DI,DI,DI,DI,V4SF,V2SF,V2SF")])
161
162 (define_expand "movmisalign<mode>"
163   [(set (match_operand:MMXMODE 0 "nonimmediate_operand" "")
164         (match_operand:MMXMODE 1 "nonimmediate_operand" ""))]
165   "TARGET_MMX"
166 {
167   ix86_expand_vector_move (<MODE>mode, operands);
168   DONE;
169 })
170
171 (define_insn "sse_movntdi"
172   [(set (match_operand:DI 0 "memory_operand" "=m")
173         (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
174                    UNSPEC_MOVNT))]
175   "TARGET_SSE || TARGET_3DNOW_A"
176   "movntq\t{%1, %0|%0, %1}"
177   [(set_attr "type" "mmxmov")
178    (set_attr "mode" "DI")])
179
180 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
181 ;;
182 ;; Parallel single-precision floating point arithmetic
183 ;;
184 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
185
186 (define_insn "mmx_addv2sf3"
187   [(set (match_operand:V2SF 0 "register_operand" "=y")
188         (plus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
189                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
190   "TARGET_3DNOW && ix86_binary_operator_ok (PLUS, V2SFmode, operands)"
191   "pfadd\\t{%2, %0|%0, %2}"
192   [(set_attr "type" "mmxadd")
193    (set_attr "mode" "V2SF")])
194
195 (define_insn "mmx_subv2sf3"
196   [(set (match_operand:V2SF 0 "register_operand" "=y,y")
197         (minus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "0,ym")
198                     (match_operand:V2SF 2 "nonimmediate_operand" "ym,0")))]
199   "TARGET_3DNOW && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
200   "@
201    pfsub\\t{%2, %0|%0, %2}
202    pfsubr\\t{%2, %0|%0, %2}"
203   [(set_attr "type" "mmxadd")
204    (set_attr "mode" "V2SF")])
205
206 (define_expand "mmx_subrv2sf3"
207   [(set (match_operand:V2SF 0 "register_operand" "")
208         (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "")
209                     (match_operand:V2SF 1 "nonimmediate_operand" "")))]
210   "TARGET_3DNOW && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
211   "")
212
213 (define_insn "mmx_mulv2sf3"
214   [(set (match_operand:V2SF 0 "register_operand" "=y")
215         (mult:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
216                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
217   "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V2SFmode, operands)"
218   "pfmul\\t{%2, %0|%0, %2}"
219   [(set_attr "type" "mmxmul")
220    (set_attr "mode" "V2SF")])
221
222 (define_insn "mmx_smaxv2sf3"
223   [(set (match_operand:V2SF 0 "register_operand" "=y")
224         (smax:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
225                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
226   "TARGET_3DNOW && ix86_binary_operator_ok (SMAX, V2SFmode, operands)"
227   "pfmax\\t{%2, %0|%0, %2}"
228   [(set_attr "type" "mmxadd")
229    (set_attr "mode" "V2SF")])
230
231 (define_insn "mmx_sminv2sf3"
232   [(set (match_operand:V2SF 0 "register_operand" "=y")
233         (smin:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
234                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
235   "TARGET_3DNOW && ix86_binary_operator_ok (SMIN, V2SFmode, operands)"
236   "pfmin\\t{%2, %0|%0, %2}"
237   [(set_attr "type" "mmxadd")
238    (set_attr "mode" "V2SF")])
239
240 (define_insn "mmx_rcpv2sf2"
241   [(set (match_operand:V2SF 0 "register_operand" "=y")
242         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
243                      UNSPEC_PFRCP))]
244   "TARGET_3DNOW"
245   "pfrcp\\t{%1, %0|%0, %1}"
246   [(set_attr "type" "mmx")
247    (set_attr "mode" "V2SF")])
248
249 (define_insn "mmx_rcpit1v2sf3"
250   [(set (match_operand:V2SF 0 "register_operand" "=y")
251         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
252                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
253                      UNSPEC_PFRCPIT1))]
254   "TARGET_3DNOW"
255   "pfrcpit1\\t{%2, %0|%0, %2}"
256   [(set_attr "type" "mmx")
257    (set_attr "mode" "V2SF")])
258
259 (define_insn "mmx_rcpit2v2sf3"
260   [(set (match_operand:V2SF 0 "register_operand" "=y")
261         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
262                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
263                      UNSPEC_PFRCPIT2))]
264   "TARGET_3DNOW"
265   "pfrcpit2\\t{%2, %0|%0, %2}"
266   [(set_attr "type" "mmx")
267    (set_attr "mode" "V2SF")])
268
269 (define_insn "mmx_rsqrtv2sf2"
270   [(set (match_operand:V2SF 0 "register_operand" "=y")
271         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
272                      UNSPEC_PFRSQRT))]
273   "TARGET_3DNOW"
274   "pfrsqrt\\t{%1, %0|%0, %1}"
275   [(set_attr "type" "mmx")
276    (set_attr "mode" "V2SF")])
277                 
278 (define_insn "mmx_rsqit1v2sf3"
279   [(set (match_operand:V2SF 0 "register_operand" "=y")
280         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
281                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
282                      UNSPEC_PFRSQIT1))]
283   "TARGET_3DNOW"
284   "pfrsqit1\\t{%2, %0|%0, %2}"
285   [(set_attr "type" "mmx")
286    (set_attr "mode" "V2SF")])
287
288 (define_insn "mmx_haddv2sf3"
289   [(set (match_operand:V2SF 0 "register_operand" "=y")
290         (vec_concat:V2SF
291           (plus:SF
292             (vec_select:SF
293               (match_operand:V2SF 1 "register_operand" "0")
294               (parallel [(const_int  0)]))
295             (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
296           (plus:SF
297             (vec_select:SF
298               (match_operand:V2SF 2 "nonimmediate_operand" "ym")
299               (parallel [(const_int  0)]))
300             (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
301   "TARGET_3DNOW"
302   "pfacc\\t{%2, %0|%0, %2}"
303   [(set_attr "type" "mmxadd")
304    (set_attr "mode" "V2SF")])
305
306 (define_insn "mmx_hsubv2sf3"
307   [(set (match_operand:V2SF 0 "register_operand" "=y")
308         (vec_concat:V2SF
309           (minus:SF
310             (vec_select:SF
311               (match_operand:V2SF 1 "register_operand" "0")
312               (parallel [(const_int  0)]))
313             (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
314           (minus:SF
315             (vec_select:SF
316               (match_operand:V2SF 2 "nonimmediate_operand" "ym")
317               (parallel [(const_int  0)]))
318             (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
319   "TARGET_3DNOW_A"
320   "pfnacc\\t{%2, %0|%0, %2}"
321   [(set_attr "type" "mmxadd")
322    (set_attr "mode" "V2SF")])
323
324 (define_insn "mmx_addsubv2sf3"
325   [(set (match_operand:V2SF 0 "register_operand" "=y")
326         (vec_merge:V2SF
327           (plus:V2SF
328             (match_operand:V2SF 1 "register_operand" "0")
329             (match_operand:V2SF 2 "nonimmediate_operand" "ym"))
330           (minus:V2SF (match_dup 1) (match_dup 2))
331           (const_int 1)))]
332   "TARGET_3DNOW_A"
333   "pfpnacc\\t{%2, %0|%0, %2}"
334   [(set_attr "type" "mmxadd")
335    (set_attr "mode" "V2SF")])
336
337 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
338 ;;
339 ;; Parallel single-precision floating point comparisons
340 ;;
341 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
342
343 (define_insn "mmx_gtv2sf3"
344   [(set (match_operand:V2SI 0 "register_operand" "=y")
345         (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
346                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
347   "TARGET_3DNOW"
348   "pfcmpgt\\t{%2, %0|%0, %2}"
349   [(set_attr "type" "mmxcmp")
350    (set_attr "mode" "V2SF")])
351
352 (define_insn "mmx_gev2sf3"
353   [(set (match_operand:V2SI 0 "register_operand" "=y")
354         (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
355                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
356   "TARGET_3DNOW"
357   "pfcmpge\\t{%2, %0|%0, %2}"
358   [(set_attr "type" "mmxcmp")
359    (set_attr "mode" "V2SF")])
360
361 (define_insn "mmx_eqv2sf3"
362   [(set (match_operand:V2SI 0 "register_operand" "=y")
363         (eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "%0")
364                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
365   "TARGET_3DNOW && ix86_binary_operator_ok (EQ, V2SFmode, operands)"
366   "pfcmpeq\\t{%2, %0|%0, %2}"
367   [(set_attr "type" "mmxcmp")
368    (set_attr "mode" "V2SF")])
369
370 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
371 ;;
372 ;; Parallel single-precision floating point conversion operations
373 ;;
374 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
375
376 (define_insn "mmx_pf2id"
377   [(set (match_operand:V2SI 0 "register_operand" "=y")
378         (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
379   "TARGET_3DNOW"
380   "pf2id\\t{%1, %0|%0, %1}"
381   [(set_attr "type" "mmxcvt")
382    (set_attr "mode" "V2SF")])
383
384 (define_insn "mmx_pf2iw"
385   [(set (match_operand:V2SI 0 "register_operand" "=y")
386         (sign_extend:V2SI
387           (ss_truncate:V2HI
388             (fix:V2SI
389               (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
390   "TARGET_3DNOW_A"
391   "pf2iw\\t{%1, %0|%0, %1}"
392   [(set_attr "type" "mmxcvt")
393    (set_attr "mode" "V2SF")])
394
395 (define_insn "mmx_pi2fw"
396   [(set (match_operand:V2SF 0 "register_operand" "=y")
397         (float:V2SF
398           (sign_extend:V2SI
399             (truncate:V2HI
400               (match_operand:V2SI 1 "nonimmediate_operand" "ym")))))]
401   "TARGET_3DNOW_A"
402   "pi2fw\\t{%1, %0|%0, %1}"
403   [(set_attr "type" "mmxcvt")
404    (set_attr "mode" "V2SF")])
405
406 (define_insn "mmx_floatv2si2"
407   [(set (match_operand:V2SF 0 "register_operand" "=y")
408         (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
409   "TARGET_3DNOW"
410   "pi2fd\\t{%1, %0|%0, %1}"
411   [(set_attr "type" "mmxcvt")
412    (set_attr "mode" "V2SF")])
413
414 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
415 ;;
416 ;; Parallel single-precision floating point element swizzling
417 ;;
418 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
419
420 (define_insn "mmx_pswapdv2sf2"
421   [(set (match_operand:V2SF 0 "register_operand" "=y")
422         (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
423                          (parallel [(const_int 1) (const_int 0)])))]
424   "TARGET_3DNOW_A"
425   "pswapd\\t{%1, %0|%0, %1}"
426   [(set_attr "type" "mmxcvt")
427    (set_attr "mode" "V2SF")])
428
429 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
430 ;;
431 ;; Parallel integral arithmetic
432 ;;
433 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
434
435 (define_insn "mmx_add<mode>3"
436   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
437         (plus:MMXMODEI
438           (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
439           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
440   "TARGET_MMX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
441   "padd<mmxvecsize>\t{%2, %0|%0, %2}"
442   [(set_attr "type" "mmxadd")
443    (set_attr "mode" "DI")])
444
445 (define_insn "mmx_adddi3"
446   [(set (match_operand:DI 0 "register_operand" "=y")
447         (unspec:DI
448          [(plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
449                    (match_operand:DI 2 "nonimmediate_operand" "ym"))]
450          UNSPEC_NOP))]
451   "TARGET_MMX && ix86_binary_operator_ok (PLUS, DImode, operands)"
452   "paddq\t{%2, %0|%0, %2}"
453   [(set_attr "type" "mmxadd")
454    (set_attr "mode" "DI")])
455
456 (define_insn "mmx_ssadd<mode>3"
457   [(set (match_operand:MMXMODE12 0 "register_operand" "=y")
458         (ss_plus:MMXMODE12
459           (match_operand:MMXMODE12 1 "nonimmediate_operand" "%0")
460           (match_operand:MMXMODE12 2 "nonimmediate_operand" "ym")))]
461   "TARGET_MMX"
462   "padds<mmxvecsize>\t{%2, %0|%0, %2}"
463   [(set_attr "type" "mmxadd")
464    (set_attr "mode" "DI")])
465
466 (define_insn "mmx_usadd<mode>3"
467   [(set (match_operand:MMXMODE12 0 "register_operand" "=y")
468         (us_plus:MMXMODE12
469           (match_operand:MMXMODE12 1 "nonimmediate_operand" "%0")
470           (match_operand:MMXMODE12 2 "nonimmediate_operand" "ym")))]
471   "TARGET_MMX"
472   "paddus<mmxvecsize>\t{%2, %0|%0, %2}"
473   [(set_attr "type" "mmxadd")
474    (set_attr "mode" "DI")])
475
476 (define_insn "mmx_sub<mode>3"
477   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
478         (minus:MMXMODEI
479           (match_operand:MMXMODEI 1 "register_operand" "0")
480           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
481   "TARGET_MMX"
482   "psub<mmxvecsize>\t{%2, %0|%0, %2}"
483   [(set_attr "type" "mmxadd")
484    (set_attr "mode" "DI")])
485
486 (define_insn "mmx_subdi3"
487   [(set (match_operand:DI 0 "register_operand" "=y")
488         (unspec:DI
489          [(minus:DI (match_operand:DI 1 "register_operand" "0")
490                     (match_operand:DI 2 "nonimmediate_operand" "ym"))]
491          UNSPEC_NOP))]
492   "TARGET_MMX"
493   "psubq\t{%2, %0|%0, %2}"
494   [(set_attr "type" "mmxadd")
495    (set_attr "mode" "DI")])
496
497 (define_insn "mmx_sssub<mode>3"
498   [(set (match_operand:MMXMODE12 0 "register_operand" "=y")
499         (ss_minus:MMXMODE12
500           (match_operand:MMXMODE12 1 "register_operand" "0")
501           (match_operand:MMXMODE12 2 "nonimmediate_operand" "ym")))]
502   "TARGET_MMX"
503   "psubs<mmxvecsize>\t{%2, %0|%0, %2}"
504   [(set_attr "type" "mmxadd")
505    (set_attr "mode" "DI")])
506
507 (define_insn "mmx_ussub<mode>3"
508   [(set (match_operand:MMXMODE12 0 "register_operand" "=y")
509         (us_minus:MMXMODE12
510           (match_operand:MMXMODE12 1 "register_operand" "0")
511           (match_operand:MMXMODE12 2 "nonimmediate_operand" "ym")))]
512   "TARGET_MMX"
513   "psubus<mmxvecsize>\t{%2, %0|%0, %2}"
514   [(set_attr "type" "mmxadd")
515    (set_attr "mode" "DI")])
516
517 (define_insn "mmx_mulv4hi3"
518   [(set (match_operand:V4HI 0 "register_operand" "=y")
519         (mult:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "%0")
520                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
521   "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
522   "pmullw\t{%2, %0|%0, %2}"
523   [(set_attr "type" "mmxmul")
524    (set_attr "mode" "DI")])
525
526 (define_insn "mmx_smulv4hi3_highpart"
527   [(set (match_operand:V4HI 0 "register_operand" "=y")
528         (truncate:V4HI
529          (lshiftrt:V4SI
530           (mult:V4SI (sign_extend:V4SI
531                       (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
532                      (sign_extend:V4SI
533                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
534           (const_int 16))))]
535   "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
536   "pmulhw\t{%2, %0|%0, %2}"
537   [(set_attr "type" "mmxmul")
538    (set_attr "mode" "DI")])
539
540 (define_insn "mmx_umulv4hi3_highpart"
541   [(set (match_operand:V4HI 0 "register_operand" "=y")
542         (truncate:V4HI
543          (lshiftrt:V4SI
544           (mult:V4SI (zero_extend:V4SI
545                       (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
546                      (zero_extend:V4SI
547                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
548           (const_int 16))))]
549   "(TARGET_SSE || TARGET_3DNOW_A)
550    && ix86_binary_operator_ok (MULT, V4HImode, operands)"
551   "pmulhuw\t{%2, %0|%0, %2}"
552   [(set_attr "type" "mmxmul")
553    (set_attr "mode" "DI")])
554
555 (define_insn "mmx_pmaddwd"
556   [(set (match_operand:V2SI 0 "register_operand" "=y")
557         (plus:V2SI
558           (mult:V2SI
559             (sign_extend:V2SI
560               (vec_select:V2HI
561                 (match_operand:V4HI 1 "nonimmediate_operand" "%0")
562                 (parallel [(const_int 0) (const_int 2)])))
563             (sign_extend:V2SI
564               (vec_select:V2HI
565                 (match_operand:V4HI 2 "nonimmediate_operand" "ym")
566                 (parallel [(const_int 0) (const_int 2)]))))
567           (mult:V2SI
568             (sign_extend:V2SI
569               (vec_select:V2HI (match_dup 1)
570                 (parallel [(const_int 1) (const_int 3)])))
571             (sign_extend:V2SI
572               (vec_select:V2HI (match_dup 2)
573                 (parallel [(const_int 1) (const_int 3)]))))))]
574   "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
575   "pmaddwd\t{%2, %0|%0, %2}"
576   [(set_attr "type" "mmxmul")
577    (set_attr "mode" "DI")])
578
579 (define_insn "mmx_pmulhrwv4hi3"
580   [(set (match_operand:V4HI 0 "register_operand" "=y")
581         (truncate:V4HI
582           (lshiftrt:V4SI
583             (plus:V4SI
584               (mult:V4SI
585                 (sign_extend:V4SI
586                   (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
587                 (sign_extend:V4SI
588                   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
589               (const_vector:V4SI [(const_int 32768) (const_int 32768)
590                                   (const_int 32768) (const_int 32768)]))
591             (const_int 16))))]
592   "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V4HImode, operands)"
593   "pmulhrw\\t{%2, %0|%0, %2}"
594   [(set_attr "type" "mmxmul")
595    (set_attr "mode" "DI")])
596
597 (define_insn "sse2_umulsidi3"
598   [(set (match_operand:DI 0 "register_operand" "=y")
599         (mult:DI
600           (zero_extend:DI
601             (vec_select:SI
602               (match_operand:V2SI 1 "nonimmediate_operand" "%0")
603               (parallel [(const_int 0)])))
604           (zero_extend:DI
605             (vec_select:SI
606               (match_operand:V2SI 2 "nonimmediate_operand" "ym")
607               (parallel [(const_int 0)])))))]
608   "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V2SImode, operands)"
609   "pmuludq\t{%2, %0|%0, %2}"
610   [(set_attr "type" "mmxmul")
611    (set_attr "mode" "DI")])
612
613 (define_insn "mmx_umaxv8qi3"
614   [(set (match_operand:V8QI 0 "register_operand" "=y")
615         (umax:V8QI (match_operand:V8QI 1 "nonimmediate_operand" "%0")
616                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
617   "(TARGET_SSE || TARGET_3DNOW_A)
618    && ix86_binary_operator_ok (UMAX, V8QImode, operands)"
619   "pmaxub\t{%2, %0|%0, %2}"
620   [(set_attr "type" "mmxadd")
621    (set_attr "mode" "DI")])
622
623 (define_insn "mmx_smaxv4hi3"
624   [(set (match_operand:V4HI 0 "register_operand" "=y")
625         (smax:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "%0")
626                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
627   "(TARGET_SSE || TARGET_3DNOW_A)
628    && ix86_binary_operator_ok (SMAX, V4HImode, operands)"
629   "pmaxsw\t{%2, %0|%0, %2}"
630   [(set_attr "type" "mmxadd")
631    (set_attr "mode" "DI")])
632
633 (define_insn "mmx_uminv8qi3"
634   [(set (match_operand:V8QI 0 "register_operand" "=y")
635         (umin:V8QI (match_operand:V8QI 1 "nonimmediate_operand" "%0")
636                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
637   "(TARGET_SSE || TARGET_3DNOW_A)
638    && ix86_binary_operator_ok (UMIN, V8QImode, operands)"
639   "pminub\t{%2, %0|%0, %2}"
640   [(set_attr "type" "mmxadd")
641    (set_attr "mode" "DI")])
642
643 (define_insn "mmx_sminv4hi3"
644   [(set (match_operand:V4HI 0 "register_operand" "=y")
645         (smin:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "%0")
646                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
647   "(TARGET_SSE || TARGET_3DNOW_A)
648    && ix86_binary_operator_ok (SMIN, V4HImode, operands)"
649   "pminsw\t{%2, %0|%0, %2}"
650   [(set_attr "type" "mmxadd")
651    (set_attr "mode" "DI")])
652
653 (define_insn "mmx_ashr<mode>3"
654   [(set (match_operand:MMXMODE24 0 "register_operand" "=y")
655         (ashiftrt:MMXMODE24
656           (match_operand:MMXMODE24 1 "register_operand" "0")
657           (match_operand:DI 2 "nonmemory_operand" "yi")))]
658   "TARGET_MMX"
659   "psra<mmxvecsize>\t{%2, %0|%0, %2}"
660   [(set_attr "type" "mmxshft")
661    (set_attr "mode" "DI")])
662
663 (define_insn "mmx_lshr<mode>3"
664   [(set (match_operand:MMXMODE24 0 "register_operand" "=y")
665         (lshiftrt:MMXMODE24
666           (match_operand:MMXMODE24 1 "register_operand" "0")
667           (match_operand:DI 2 "nonmemory_operand" "yi")))]
668   "TARGET_MMX"
669   "psrl<mmxvecsize>\t{%2, %0|%0, %2}"
670   [(set_attr "type" "mmxshft")
671    (set_attr "mode" "DI")])
672
673 (define_insn "mmx_lshrdi3"
674   [(set (match_operand:DI 0 "register_operand" "=y")
675         (unspec:DI
676           [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
677                        (match_operand:DI 2 "nonmemory_operand" "yi"))]
678           UNSPEC_NOP))]
679   "TARGET_MMX"
680   "psrlq\t{%2, %0|%0, %2}"
681   [(set_attr "type" "mmxshft")
682    (set_attr "mode" "DI")])
683
684 (define_insn "mmx_ashl<mode>3"
685   [(set (match_operand:MMXMODE24 0 "register_operand" "=y")
686         (ashift:MMXMODE24
687           (match_operand:MMXMODE24 1 "register_operand" "0")
688           (match_operand:DI 2 "nonmemory_operand" "yi")))]
689   "TARGET_MMX"
690   "psll<mmxvecsize>\t{%2, %0|%0, %2}"
691   [(set_attr "type" "mmxshft")
692    (set_attr "mode" "DI")])
693
694 (define_insn "mmx_ashldi3"
695   [(set (match_operand:DI 0 "register_operand" "=y")
696         (unspec:DI
697          [(ashift:DI (match_operand:DI 1 "register_operand" "0")
698                      (match_operand:DI 2 "nonmemory_operand" "yi"))]
699          UNSPEC_NOP))]
700   "TARGET_MMX"
701   "psllq\t{%2, %0|%0, %2}"
702   [(set_attr "type" "mmxshft")
703    (set_attr "mode" "DI")])
704
705 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
706 ;;
707 ;; Parallel integral comparisons
708 ;;
709 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
710
711 (define_insn "mmx_eq<mode>3"
712   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
713         (eq:MMXMODEI
714           (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
715           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
716   "TARGET_MMX && ix86_binary_operator_ok (EQ, <MODE>mode, operands)"
717   "pcmpeq<mmxvecsize>\t{%2, %0|%0, %2}"
718   [(set_attr "type" "mmxcmp")
719    (set_attr "mode" "DI")])
720
721 (define_insn "mmx_gt<mode>3"
722   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
723         (gt:MMXMODEI
724           (match_operand:MMXMODEI 1 "register_operand" "0")
725           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
726   "TARGET_MMX"
727   "pcmpgt<mmxvecsize>\t{%2, %0|%0, %2}"
728   [(set_attr "type" "mmxcmp")
729    (set_attr "mode" "DI")])
730
731 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
732 ;;
733 ;; Parallel integral logical operations
734 ;;
735 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
736
737 (define_insn "mmx_and<mode>3"
738   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
739         (and:MMXMODEI
740           (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
741           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
742   "TARGET_MMX && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
743   "pand\t{%2, %0|%0, %2}"
744   [(set_attr "type" "mmxadd")
745    (set_attr "mode" "DI")])
746
747 (define_insn "mmx_nand<mode>3"
748   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
749         (and:MMXMODEI
750           (not:MMXMODEI (match_operand:MMXMODEI 1 "register_operand" "0"))
751           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
752   "TARGET_MMX"
753   "pandn\t{%2, %0|%0, %2}"
754   [(set_attr "type" "mmxadd")
755    (set_attr "mode" "DI")])
756
757 (define_insn "mmx_ior<mode>3"
758   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
759         (ior:MMXMODEI
760           (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
761           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
762   "TARGET_MMX && ix86_binary_operator_ok (IOR, <MODE>mode, operands)"
763   "por\t{%2, %0|%0, %2}"
764   [(set_attr "type" "mmxadd")
765    (set_attr "mode" "DI")])
766
767 (define_insn "mmx_xor<mode>3"
768   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
769         (xor:MMXMODEI
770           (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
771           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
772   "TARGET_MMX && ix86_binary_operator_ok (XOR, <MODE>mode, operands)"
773   "pxor\t{%2, %0|%0, %2}"
774   [(set_attr "type" "mmxadd")
775    (set_attr "mode" "DI")
776    (set_attr "memory" "none")])
777
778 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
779 ;;
780 ;; Parallel integral element swizzling
781 ;;
782 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
783
784 (define_insn "mmx_packsswb"
785   [(set (match_operand:V8QI 0 "register_operand" "=y")
786         (vec_concat:V8QI
787           (ss_truncate:V4QI
788             (match_operand:V4HI 1 "register_operand" "0"))
789           (ss_truncate:V4QI
790             (match_operand:V4HI 2 "nonimmediate_operand" "ym"))))]
791   "TARGET_MMX"
792   "packsswb\t{%2, %0|%0, %2}"
793   [(set_attr "type" "mmxshft")
794    (set_attr "mode" "DI")])
795
796 (define_insn "mmx_packssdw"
797   [(set (match_operand:V4HI 0 "register_operand" "=y")
798         (vec_concat:V4HI
799           (ss_truncate:V2HI
800             (match_operand:V2SI 1 "register_operand" "0"))
801           (ss_truncate:V2HI
802             (match_operand:V2SI 2 "nonimmediate_operand" "ym"))))]
803   "TARGET_MMX"
804   "packssdw\t{%2, %0|%0, %2}"
805   [(set_attr "type" "mmxshft")
806    (set_attr "mode" "DI")])
807
808 (define_insn "mmx_packuswb"
809   [(set (match_operand:V8QI 0 "register_operand" "=y")
810         (vec_concat:V8QI
811           (us_truncate:V4QI
812             (match_operand:V4HI 1 "register_operand" "0"))
813           (us_truncate:V4QI
814             (match_operand:V4HI 2 "nonimmediate_operand" "ym"))))]
815   "TARGET_MMX"
816   "packuswb\t{%2, %0|%0, %2}"
817   [(set_attr "type" "mmxshft")
818    (set_attr "mode" "DI")])
819
820 (define_insn "mmx_punpckhbw"
821   [(set (match_operand:V8QI 0 "register_operand" "=y")
822         (vec_select:V8QI
823           (vec_concat:V16QI
824             (match_operand:V8QI 1 "register_operand" "0")
825             (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
826           (parallel [(const_int 4) (const_int 12)
827                      (const_int 5) (const_int 13)
828                      (const_int 6) (const_int 14)
829                      (const_int 7) (const_int 15)])))]
830   "TARGET_MMX"
831   "punpckhbw\t{%2, %0|%0, %2}"
832   [(set_attr "type" "mmxcvt")
833    (set_attr "mode" "DI")])
834
835 (define_insn "mmx_punpcklbw"
836   [(set (match_operand:V8QI 0 "register_operand" "=y")
837         (vec_select:V8QI
838           (vec_concat:V16QI
839             (match_operand:V8QI 1 "register_operand" "0")
840             (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
841           (parallel [(const_int 0) (const_int 8)
842                      (const_int 1) (const_int 9)
843                      (const_int 2) (const_int 10)
844                      (const_int 3) (const_int 11)])))]
845   "TARGET_MMX"
846   "punpcklbw\t{%2, %0|%0, %2}"
847   [(set_attr "type" "mmxcvt")
848    (set_attr "mode" "DI")])
849
850 (define_insn "mmx_punpckhwd"
851   [(set (match_operand:V4HI 0 "register_operand" "=y")
852         (vec_select:V4HI
853           (vec_concat:V8HI
854             (match_operand:V4HI 1 "register_operand" "0")
855             (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
856           (parallel [(const_int 2) (const_int 6)
857                      (const_int 3) (const_int 7)])))]
858   "TARGET_MMX"
859   "punpckhwd\t{%2, %0|%0, %2}"
860   [(set_attr "type" "mmxcvt")
861    (set_attr "mode" "DI")])
862
863 (define_insn "mmx_punpcklwd"
864   [(set (match_operand:V4HI 0 "register_operand" "=y")
865         (vec_select:V4HI
866           (vec_concat:V8HI
867             (match_operand:V4HI 1 "register_operand" "0")
868             (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
869           (parallel [(const_int 0) (const_int 4)
870                      (const_int 1) (const_int 5)])))]
871   "TARGET_MMX"
872   "punpcklwd\t{%2, %0|%0, %2}"
873   [(set_attr "type" "mmxcvt")
874    (set_attr "mode" "DI")])
875
876 (define_insn "mmx_punpckhdq"
877   [(set (match_operand:V2SI 0 "register_operand" "=y")
878         (vec_select:V2SI
879           (vec_concat:V4SI
880             (match_operand:V2SI 1 "register_operand" "0")
881             (match_operand:V2SI 2 "nonimmediate_operand" "ym"))
882           (parallel [(const_int 1)
883                      (const_int 3)])))]
884   "TARGET_MMX"
885   "punpckhdq\t{%2, %0|%0, %2}"
886   [(set_attr "type" "mmxcvt")
887    (set_attr "mode" "DI")])
888
889 (define_insn "mmx_punpckldq"
890   [(set (match_operand:V2SI 0 "register_operand" "=y")
891         (vec_select:V2SI
892           (vec_concat:V4SI
893             (match_operand:V2SI 1 "register_operand" "0")
894             (match_operand:V2SI 2 "nonimmediate_operand" "ym"))
895           (parallel [(const_int 0)
896                      (const_int 2)])))]
897   "TARGET_MMX"
898   "punpckldq\t{%2, %0|%0, %2}"
899   [(set_attr "type" "mmxcvt")
900    (set_attr "mode" "DI")])
901
902 (define_expand "mmx_pinsrw"
903   [(set (match_operand:V4HI 0 "register_operand" "")
904         (vec_merge:V4HI
905           (match_operand:V4HI 1 "register_operand" "")
906           (vec_duplicate:V4HI
907             (match_operand:SI 2 "nonimmediate_operand" ""))
908           (match_operand:SI 3 "const_0_to_3_operand" "")))]
909   "TARGET_SSE || TARGET_3DNOW_A"
910 {
911   operands[2] = gen_lowpart (HImode, operands[2]);
912   operands[3] = GEN_INT (1 << INTVAL (operands[3]));
913 })
914
915 (define_insn "*mmx_pinsrw"
916   [(set (match_operand:V4HI 0 "register_operand" "=y")
917         (vec_merge:V4HI
918           (match_operand:V4HI 1 "register_operand" "0")
919           (vec_duplicate:V4HI
920             (match_operand:HI 2 "nonimmediate_operand" "rm"))
921           (match_operand:SI 3 "const_pow2_1_to_8_operand" "n")))]
922   "TARGET_SSE || TARGET_3DNOW_A"
923 {
924   operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
925   return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}";
926 }
927   [(set_attr "type" "mmxcvt")
928    (set_attr "mode" "DI")])
929
930 (define_insn "mmx_pextrw"
931   [(set (match_operand:SI 0 "register_operand" "=r")
932         (zero_extend:SI
933           (vec_select:HI
934             (match_operand:V4HI 1 "register_operand" "y")
935             (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n")]))))]
936   "TARGET_SSE || TARGET_3DNOW_A"
937   "pextrw\t{%2, %1, %0|%0, %1, %2}"
938   [(set_attr "type" "mmxcvt")
939    (set_attr "mode" "DI")])
940
941
942 (define_expand "mmx_pshufw"
943   [(match_operand:V4HI 0 "register_operand" "")
944    (match_operand:V4HI 1 "nonimmediate_operand" "")
945    (match_operand:SI 2 "const_int_operand" "")]
946   "TARGET_SSE || TARGET_3DNOW_A"
947 {
948   int mask = INTVAL (operands[2]);
949   emit_insn (gen_mmx_pshufw_1 (operands[0], operands[1],
950                                GEN_INT ((mask >> 0) & 3),
951                                GEN_INT ((mask >> 2) & 3),
952                                GEN_INT ((mask >> 4) & 3),
953                                GEN_INT ((mask >> 6) & 3)));
954   DONE;
955 })
956
957 (define_insn "mmx_pshufw_1"
958   [(set (match_operand:V4HI 0 "register_operand" "=y")
959         (vec_select:V4HI
960           (match_operand:V4HI 1 "nonimmediate_operand" "ym")
961           (parallel [(match_operand 2 "const_0_to_3_operand" "")
962                      (match_operand 3 "const_0_to_3_operand" "")
963                      (match_operand 4 "const_0_to_3_operand" "")
964                      (match_operand 5 "const_0_to_3_operand" "")])))]
965   "TARGET_SSE || TARGET_3DNOW_A"
966 {
967   int mask = 0;
968   mask |= INTVAL (operands[2]) << 0;
969   mask |= INTVAL (operands[3]) << 2;
970   mask |= INTVAL (operands[4]) << 4;
971   mask |= INTVAL (operands[5]) << 6;
972   operands[2] = GEN_INT (mask);
973
974   return "pshufw\t{%2, %1, %0|%0, %1, %2}";
975 }
976   [(set_attr "type" "mmxcvt")
977    (set_attr "mode" "DI")])
978
979 (define_insn "mmx_pswapdv2si2"
980   [(set (match_operand:V2SI 0 "register_operand" "=y")
981         (vec_select:V2SI
982           (match_operand:V2SI 1 "nonimmediate_operand" "ym")
983           (parallel [(const_int 1) (const_int 0)])))]
984   "TARGET_3DNOW_A"
985   "pswapd\\t{%1, %0|%0, %1}"
986   [(set_attr "type" "mmxcvt")
987    (set_attr "mode" "DI")])
988
989 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
990 ;;
991 ;; Miscelaneous
992 ;;
993 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
994
995 (define_insn "mmx_uavgv8qi3"
996   [(set (match_operand:V8QI 0 "register_operand" "=y")
997         (truncate:V8QI
998           (lshiftrt:V8HI
999             (plus:V8HI
1000               (plus:V8HI
1001                 (zero_extend:V8HI
1002                   (match_operand:V8QI 1 "nonimmediate_operand" "%0"))
1003                 (zero_extend:V8HI
1004                   (match_operand:V8QI 2 "nonimmediate_operand" "ym")))
1005               (const_vector:V8HI [(const_int 1) (const_int 1)
1006                                   (const_int 1) (const_int 1)
1007                                   (const_int 1) (const_int 1)
1008                                   (const_int 1) (const_int 1)]))
1009             (const_int 1))))]
1010   "(TARGET_SSE || TARGET_3DNOW)
1011    && ix86_binary_operator_ok (PLUS, V8QImode, operands)"
1012 {
1013   /* These two instructions have the same operation, but their encoding
1014      is different.  Prefer the one that is defacto standard.  */
1015   if (TARGET_SSE || TARGET_3DNOW_A)
1016     return "pavgb\t{%2, %0|%0, %2}";
1017   else
1018     return "pavgusb\\t{%2, %0|%0, %2}";
1019 }
1020   [(set_attr "type" "mmxshft")
1021    (set_attr "mode" "DI")])
1022
1023 (define_insn "mmx_uavgv4hi3"
1024   [(set (match_operand:V4HI 0 "register_operand" "=y")
1025         (truncate:V4HI
1026           (lshiftrt:V4SI
1027             (plus:V4SI
1028               (plus:V4SI
1029                 (zero_extend:V4SI
1030                   (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
1031                 (zero_extend:V4SI
1032                   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
1033               (const_vector:V4SI [(const_int 1) (const_int 1)
1034                                   (const_int 1) (const_int 1)]))
1035             (const_int 1))))]
1036   "(TARGET_SSE || TARGET_3DNOW_A)
1037    && ix86_binary_operator_ok (PLUS, V4HImode, operands)"
1038   "pavgw\t{%2, %0|%0, %2}"
1039   [(set_attr "type" "mmxshft")
1040    (set_attr "mode" "DI")])
1041
1042 (define_insn "mmx_psadbw"
1043   [(set (match_operand:DI 0 "register_operand" "=y")
1044         (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
1045                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
1046                    UNSPEC_PSADBW))]
1047   "TARGET_SSE || TARGET_3DNOW_A"
1048   "psadbw\t{%2, %0|%0, %2}"
1049   [(set_attr "type" "mmxshft")
1050    (set_attr "mode" "DI")])
1051
1052 (define_insn "mmx_pmovmskb"
1053   [(set (match_operand:SI 0 "register_operand" "=r")
1054         (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
1055                    UNSPEC_MOVMSK))]
1056   "TARGET_SSE || TARGET_3DNOW_A"
1057   "pmovmskb\t{%1, %0|%0, %1}"
1058   [(set_attr "type" "ssecvt")
1059    (set_attr "mode" "V4SF")])
1060
1061 (define_expand "mmx_maskmovq"
1062   [(set (match_operand:V8QI 0 "memory_operand" "")
1063         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
1064                       (match_operand:V8QI 2 "register_operand" "y")
1065                       (match_dup 0)]
1066                      UNSPEC_MASKMOV))]
1067   "TARGET_SSE || TARGET_3DNOW_A"
1068   "")
1069
1070 (define_insn "*mmx_maskmovq"
1071   [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
1072         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
1073                       (match_operand:V8QI 2 "register_operand" "y")
1074                       (mem:V8QI (match_dup 0))]
1075                      UNSPEC_MASKMOV))]
1076   "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
1077   ;; @@@ check ordering of operands in intel/nonintel syntax
1078   "maskmovq\t{%2, %1|%1, %2}"
1079   [(set_attr "type" "mmxcvt")
1080    (set_attr "mode" "DI")])
1081
1082 (define_insn "*mmx_maskmovq_rex"
1083   [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
1084         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
1085                       (match_operand:V8QI 2 "register_operand" "y")
1086                       (mem:V8QI (match_dup 0))]
1087                      UNSPEC_MASKMOV))]
1088   "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
1089   ;; @@@ check ordering of operands in intel/nonintel syntax
1090   "maskmovq\t{%2, %1|%1, %2}"
1091   [(set_attr "type" "mmxcvt")
1092    (set_attr "mode" "DI")])
1093
1094 (define_insn "mmx_emms"
1095   [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
1096    (clobber (reg:XF 8))
1097    (clobber (reg:XF 9))
1098    (clobber (reg:XF 10))
1099    (clobber (reg:XF 11))
1100    (clobber (reg:XF 12))
1101    (clobber (reg:XF 13))
1102    (clobber (reg:XF 14))
1103    (clobber (reg:XF 15))
1104    (clobber (reg:DI 29))
1105    (clobber (reg:DI 30))
1106    (clobber (reg:DI 31))
1107    (clobber (reg:DI 32))
1108    (clobber (reg:DI 33))
1109    (clobber (reg:DI 34))
1110    (clobber (reg:DI 35))
1111    (clobber (reg:DI 36))]
1112   "TARGET_MMX"
1113   "emms"
1114   [(set_attr "type" "mmx")
1115    (set_attr "memory" "unknown")])
1116
1117 (define_insn "mmx_femms"
1118   [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
1119    (clobber (reg:XF 8))
1120    (clobber (reg:XF 9))
1121    (clobber (reg:XF 10))
1122    (clobber (reg:XF 11))
1123    (clobber (reg:XF 12))
1124    (clobber (reg:XF 13))
1125    (clobber (reg:XF 14))
1126    (clobber (reg:XF 15))
1127    (clobber (reg:DI 29))
1128    (clobber (reg:DI 30))
1129    (clobber (reg:DI 31))
1130    (clobber (reg:DI 32))
1131    (clobber (reg:DI 33))
1132    (clobber (reg:DI 34))
1133    (clobber (reg:DI 35))
1134    (clobber (reg:DI 36))]
1135   "TARGET_3DNOW"
1136   "femms"
1137   [(set_attr "type" "mmx")
1138    (set_attr "memory" "none")])