OSDN Git Service

* config/i386/mmx.md ("sse2_umulv1siv2di3"): Rename from
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / mmx.md
1 ;; GCC machine description for MMX and 3dNOW! instructions
2 ;; Copyright (C) 2005, 2007
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,x")
69         (match_operand:MMXMODEI8 1 "vector_move_operand"
70                                 "Cr ,m,C ,!ym,!y,Y2,!y,C,xm,x,x,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     pxor\t%0, %0
82     movq\t{%1, %0|%0, %1}
83     movq\t{%1, %0|%0, %1}
84     movd\t{%1, %0|%0, %1}
85     movd\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 "mode" "DI")])
89
90 (define_insn "*mov<mode>_internal"
91   [(set (match_operand:MMXMODEI8 0 "nonimmediate_operand"
92                         "=!y,!y ,m ,!y ,*Y2,*Y2,*Y2 ,m  ,*x,*x,*x,m ,?r ,?m")
93         (match_operand:MMXMODEI8 1 "vector_move_operand"
94                         "C  ,!ym,!y,*Y2,!y ,C  ,*Y2m,*Y2,C ,*x,m ,*x,irm,r"))]
95   "TARGET_MMX
96    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
97   "@
98     pxor\t%0, %0
99     movq\t{%1, %0|%0, %1}
100     movq\t{%1, %0|%0, %1}
101     movdq2q\t{%1, %0|%0, %1}
102     movq2dq\t{%1, %0|%0, %1}
103     pxor\t%0, %0
104     movq\t{%1, %0|%0, %1}
105     movq\t{%1, %0|%0, %1}
106     xorps\t%0, %0
107     movaps\t{%1, %0|%0, %1}
108     movlps\t{%1, %0|%0, %1}
109     movlps\t{%1, %0|%0, %1}
110     #
111     #"
112   [(set_attr "type" "mmx,mmxmov,mmxmov,ssecvt,ssecvt,sselog1,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov,*,*")
113    (set_attr "unit" "*,*,*,mmx,mmx,*,*,*,*,*,*,*,*,*")
114    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,DI,V4SF,V4SF,V2SF,V2SF,DI,DI")])
115
116 (define_expand "movv2sf"
117   [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
118         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
119   "TARGET_MMX"
120 {
121   ix86_expand_vector_move (V2SFmode, operands);
122   DONE;
123 })
124
125 (define_insn "*movv2sf_internal_rex64"
126   [(set (match_operand:V2SF 0 "nonimmediate_operand"
127                                 "=rm,r,!y ,!y ,m ,!y,Y2,x,x,x,m,r,x")
128         (match_operand:V2SF 1 "vector_move_operand"
129                                 "Cr ,m ,C ,!ym,!y,Y2,!y,C,x,m,x,x,r"))]
130   "TARGET_64BIT && TARGET_MMX
131    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
132   "@
133     mov{q}\t{%1, %0|%0, %1}
134     mov{q}\t{%1, %0|%0, %1}
135     pxor\t%0, %0
136     movq\t{%1, %0|%0, %1}
137     movq\t{%1, %0|%0, %1}
138     movdq2q\t{%1, %0|%0, %1}
139     movq2dq\t{%1, %0|%0, %1}
140     xorps\t%0, %0
141     movaps\t{%1, %0|%0, %1}
142     movlps\t{%1, %0|%0, %1}
143     movlps\t{%1, %0|%0, %1}
144     movd\t{%1, %0|%0, %1}
145     movd\t{%1, %0|%0, %1}"
146   [(set_attr "type" "imov,imov,mmx,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,sselog1,ssemov,ssemov,ssemov,ssemov")
147    (set_attr "unit" "*,*,*,*,*,mmx,mmx,*,*,*,*,*,*")
148    (set_attr "mode" "DI,DI,DI,DI,DI,DI,DI,V4SF,V4SF,V2SF,V2SF,DI,DI")])
149
150 (define_insn "*movv2sf_internal"
151   [(set (match_operand:V2SF 0 "nonimmediate_operand"
152                         "=!y,!y ,m,!y ,*Y2,*x,*x,*x,m ,?r ,?m")
153         (match_operand:V2SF 1 "vector_move_operand"
154                         "C ,!ym,!y,*Y2,!y ,C ,*x,m ,*x,irm,r"))]
155   "TARGET_MMX
156    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
157   "@
158     pxor\t%0, %0
159     movq\t{%1, %0|%0, %1}
160     movq\t{%1, %0|%0, %1}
161     movdq2q\t{%1, %0|%0, %1}
162     movq2dq\t{%1, %0|%0, %1}
163     xorps\t%0, %0
164     movaps\t{%1, %0|%0, %1}
165     movlps\t{%1, %0|%0, %1}
166     movlps\t{%1, %0|%0, %1}
167     #
168     #"
169   [(set_attr "type" "mmx,mmxmov,mmxmov,ssecvt,ssecvt,sselog1,ssemov,ssemov,ssemov,*,*")
170    (set_attr "unit" "*,*,*,mmx,mmx,*,*,*,*,*,*")
171    (set_attr "mode" "DI,DI,DI,DI,DI,V4SF,V4SF,V2SF,V2SF,DI,DI")])
172
173 ;; %%% This multiword shite has got to go.
174 (define_split
175   [(set (match_operand:MMXMODE 0 "nonimmediate_operand" "")
176         (match_operand:MMXMODE 1 "general_operand" ""))]
177   "!TARGET_64BIT && reload_completed
178    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
179    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
180   [(const_int 0)]
181   "ix86_split_long_move (operands); DONE;")
182
183 (define_expand "push<mode>1"
184   [(match_operand:MMXMODE 0 "register_operand" "")]
185   "TARGET_MMX"
186 {
187   ix86_expand_push (<MODE>mode, operands[0]);
188   DONE;
189 })
190
191 (define_expand "movmisalign<mode>"
192   [(set (match_operand:MMXMODE 0 "nonimmediate_operand" "")
193         (match_operand:MMXMODE 1 "nonimmediate_operand" ""))]
194   "TARGET_MMX"
195 {
196   ix86_expand_vector_move (<MODE>mode, operands);
197   DONE;
198 })
199
200 (define_insn "sse_movntdi"
201   [(set (match_operand:DI 0 "memory_operand" "=m")
202         (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
203                    UNSPEC_MOVNT))]
204   "TARGET_SSE || TARGET_3DNOW_A"
205   "movntq\t{%1, %0|%0, %1}"
206   [(set_attr "type" "mmxmov")
207    (set_attr "mode" "DI")])
208
209 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
210 ;;
211 ;; Parallel single-precision floating point arithmetic
212 ;;
213 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
214
215 (define_insn "mmx_addv2sf3"
216   [(set (match_operand:V2SF 0 "register_operand" "=y")
217         (plus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
218                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
219   "TARGET_3DNOW && ix86_binary_operator_ok (PLUS, V2SFmode, operands)"
220   "pfadd\\t{%2, %0|%0, %2}"
221   [(set_attr "type" "mmxadd")
222    (set_attr "mode" "V2SF")])
223
224 (define_insn "mmx_subv2sf3"
225   [(set (match_operand:V2SF 0 "register_operand" "=y,y")
226         (minus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "0,ym")
227                     (match_operand:V2SF 2 "nonimmediate_operand" "ym,0")))]
228   "TARGET_3DNOW && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
229   "@
230    pfsub\\t{%2, %0|%0, %2}
231    pfsubr\\t{%2, %0|%0, %2}"
232   [(set_attr "type" "mmxadd")
233    (set_attr "mode" "V2SF")])
234
235 (define_expand "mmx_subrv2sf3"
236   [(set (match_operand:V2SF 0 "register_operand" "")
237         (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "")
238                     (match_operand:V2SF 1 "nonimmediate_operand" "")))]
239   "TARGET_3DNOW && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
240   "")
241
242 (define_insn "mmx_mulv2sf3"
243   [(set (match_operand:V2SF 0 "register_operand" "=y")
244         (mult:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
245                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
246   "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V2SFmode, operands)"
247   "pfmul\\t{%2, %0|%0, %2}"
248   [(set_attr "type" "mmxmul")
249    (set_attr "mode" "V2SF")])
250
251 (define_insn "mmx_smaxv2sf3"
252   [(set (match_operand:V2SF 0 "register_operand" "=y")
253         (smax:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
254                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
255   "TARGET_3DNOW && ix86_binary_operator_ok (SMAX, V2SFmode, operands)"
256   "pfmax\\t{%2, %0|%0, %2}"
257   [(set_attr "type" "mmxadd")
258    (set_attr "mode" "V2SF")])
259
260 (define_insn "mmx_sminv2sf3"
261   [(set (match_operand:V2SF 0 "register_operand" "=y")
262         (smin:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
263                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
264   "TARGET_3DNOW && ix86_binary_operator_ok (SMIN, V2SFmode, operands)"
265   "pfmin\\t{%2, %0|%0, %2}"
266   [(set_attr "type" "mmxadd")
267    (set_attr "mode" "V2SF")])
268
269 (define_insn "mmx_rcpv2sf2"
270   [(set (match_operand:V2SF 0 "register_operand" "=y")
271         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
272                      UNSPEC_PFRCP))]
273   "TARGET_3DNOW"
274   "pfrcp\\t{%1, %0|%0, %1}"
275   [(set_attr "type" "mmx")
276    (set_attr "mode" "V2SF")])
277
278 (define_insn "mmx_rcpit1v2sf3"
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_PFRCPIT1))]
283   "TARGET_3DNOW"
284   "pfrcpit1\\t{%2, %0|%0, %2}"
285   [(set_attr "type" "mmx")
286    (set_attr "mode" "V2SF")])
287
288 (define_insn "mmx_rcpit2v2sf3"
289   [(set (match_operand:V2SF 0 "register_operand" "=y")
290         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
291                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
292                      UNSPEC_PFRCPIT2))]
293   "TARGET_3DNOW"
294   "pfrcpit2\\t{%2, %0|%0, %2}"
295   [(set_attr "type" "mmx")
296    (set_attr "mode" "V2SF")])
297
298 (define_insn "mmx_rsqrtv2sf2"
299   [(set (match_operand:V2SF 0 "register_operand" "=y")
300         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
301                      UNSPEC_PFRSQRT))]
302   "TARGET_3DNOW"
303   "pfrsqrt\\t{%1, %0|%0, %1}"
304   [(set_attr "type" "mmx")
305    (set_attr "mode" "V2SF")])
306
307 (define_insn "mmx_rsqit1v2sf3"
308   [(set (match_operand:V2SF 0 "register_operand" "=y")
309         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
310                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
311                      UNSPEC_PFRSQIT1))]
312   "TARGET_3DNOW"
313   "pfrsqit1\\t{%2, %0|%0, %2}"
314   [(set_attr "type" "mmx")
315    (set_attr "mode" "V2SF")])
316
317 (define_insn "mmx_haddv2sf3"
318   [(set (match_operand:V2SF 0 "register_operand" "=y")
319         (vec_concat:V2SF
320           (plus:SF
321             (vec_select:SF
322               (match_operand:V2SF 1 "register_operand" "0")
323               (parallel [(const_int  0)]))
324             (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
325           (plus:SF
326             (vec_select:SF
327               (match_operand:V2SF 2 "nonimmediate_operand" "ym")
328               (parallel [(const_int  0)]))
329             (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
330   "TARGET_3DNOW"
331   "pfacc\\t{%2, %0|%0, %2}"
332   [(set_attr "type" "mmxadd")
333    (set_attr "mode" "V2SF")])
334
335 (define_insn "mmx_hsubv2sf3"
336   [(set (match_operand:V2SF 0 "register_operand" "=y")
337         (vec_concat:V2SF
338           (minus:SF
339             (vec_select:SF
340               (match_operand:V2SF 1 "register_operand" "0")
341               (parallel [(const_int  0)]))
342             (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
343           (minus:SF
344             (vec_select:SF
345               (match_operand:V2SF 2 "nonimmediate_operand" "ym")
346               (parallel [(const_int  0)]))
347             (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
348   "TARGET_3DNOW_A"
349   "pfnacc\\t{%2, %0|%0, %2}"
350   [(set_attr "type" "mmxadd")
351    (set_attr "mode" "V2SF")])
352
353 (define_insn "mmx_addsubv2sf3"
354   [(set (match_operand:V2SF 0 "register_operand" "=y")
355         (vec_merge:V2SF
356           (plus:V2SF
357             (match_operand:V2SF 1 "register_operand" "0")
358             (match_operand:V2SF 2 "nonimmediate_operand" "ym"))
359           (minus:V2SF (match_dup 1) (match_dup 2))
360           (const_int 1)))]
361   "TARGET_3DNOW_A"
362   "pfpnacc\\t{%2, %0|%0, %2}"
363   [(set_attr "type" "mmxadd")
364    (set_attr "mode" "V2SF")])
365
366 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
367 ;;
368 ;; Parallel single-precision floating point comparisons
369 ;;
370 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
371
372 (define_insn "mmx_gtv2sf3"
373   [(set (match_operand:V2SI 0 "register_operand" "=y")
374         (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
375                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
376   "TARGET_3DNOW"
377   "pfcmpgt\\t{%2, %0|%0, %2}"
378   [(set_attr "type" "mmxcmp")
379    (set_attr "mode" "V2SF")])
380
381 (define_insn "mmx_gev2sf3"
382   [(set (match_operand:V2SI 0 "register_operand" "=y")
383         (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
384                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
385   "TARGET_3DNOW"
386   "pfcmpge\\t{%2, %0|%0, %2}"
387   [(set_attr "type" "mmxcmp")
388    (set_attr "mode" "V2SF")])
389
390 (define_insn "mmx_eqv2sf3"
391   [(set (match_operand:V2SI 0 "register_operand" "=y")
392         (eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "%0")
393                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
394   "TARGET_3DNOW && ix86_binary_operator_ok (EQ, V2SFmode, operands)"
395   "pfcmpeq\\t{%2, %0|%0, %2}"
396   [(set_attr "type" "mmxcmp")
397    (set_attr "mode" "V2SF")])
398
399 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
400 ;;
401 ;; Parallel single-precision floating point conversion operations
402 ;;
403 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
404
405 (define_insn "mmx_pf2id"
406   [(set (match_operand:V2SI 0 "register_operand" "=y")
407         (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
408   "TARGET_3DNOW"
409   "pf2id\\t{%1, %0|%0, %1}"
410   [(set_attr "type" "mmxcvt")
411    (set_attr "mode" "V2SF")])
412
413 (define_insn "mmx_pf2iw"
414   [(set (match_operand:V2SI 0 "register_operand" "=y")
415         (sign_extend:V2SI
416           (ss_truncate:V2HI
417             (fix:V2SI
418               (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
419   "TARGET_3DNOW_A"
420   "pf2iw\\t{%1, %0|%0, %1}"
421   [(set_attr "type" "mmxcvt")
422    (set_attr "mode" "V2SF")])
423
424 (define_insn "mmx_pi2fw"
425   [(set (match_operand:V2SF 0 "register_operand" "=y")
426         (float:V2SF
427           (sign_extend:V2SI
428             (truncate:V2HI
429               (match_operand:V2SI 1 "nonimmediate_operand" "ym")))))]
430   "TARGET_3DNOW_A"
431   "pi2fw\\t{%1, %0|%0, %1}"
432   [(set_attr "type" "mmxcvt")
433    (set_attr "mode" "V2SF")])
434
435 (define_insn "mmx_floatv2si2"
436   [(set (match_operand:V2SF 0 "register_operand" "=y")
437         (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
438   "TARGET_3DNOW"
439   "pi2fd\\t{%1, %0|%0, %1}"
440   [(set_attr "type" "mmxcvt")
441    (set_attr "mode" "V2SF")])
442
443 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
444 ;;
445 ;; Parallel single-precision floating point element swizzling
446 ;;
447 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
448
449 (define_insn "mmx_pswapdv2sf2"
450   [(set (match_operand:V2SF 0 "register_operand" "=y")
451         (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
452                          (parallel [(const_int 1) (const_int 0)])))]
453   "TARGET_3DNOW_A"
454   "pswapd\\t{%1, %0|%0, %1}"
455   [(set_attr "type" "mmxcvt")
456    (set_attr "mode" "V2SF")])
457
458 (define_insn "*vec_dupv2sf"
459   [(set (match_operand:V2SF 0 "register_operand" "=y")
460         (vec_duplicate:V2SF
461           (match_operand:SF 1 "register_operand" "0")))]
462   "TARGET_MMX"
463   "punpckldq\t%0, %0"
464   [(set_attr "type" "mmxcvt")
465    (set_attr "mode" "DI")])
466
467 (define_insn "*mmx_concatv2sf"
468   [(set (match_operand:V2SF 0 "register_operand"     "=y,y")
469         (vec_concat:V2SF
470           (match_operand:SF 1 "nonimmediate_operand" " 0,rm")
471           (match_operand:SF 2 "vector_move_operand"  "ym,C")))]
472   "TARGET_MMX && !TARGET_SSE"
473   "@
474    punpckldq\t{%2, %0|%0, %2}
475    movd\t{%1, %0|%0, %1}"
476   [(set_attr "type" "mmxcvt,mmxmov")
477    (set_attr "mode" "DI")])
478
479 (define_expand "vec_setv2sf"
480   [(match_operand:V2SF 0 "register_operand" "")
481    (match_operand:SF 1 "register_operand" "")
482    (match_operand 2 "const_int_operand" "")]
483   "TARGET_MMX"
484 {
485   ix86_expand_vector_set (false, operands[0], operands[1],
486                           INTVAL (operands[2]));
487   DONE;
488 })
489
490 (define_insn_and_split "*vec_extractv2sf_0"
491   [(set (match_operand:SF 0 "nonimmediate_operand"     "=x,y,m,m,frxy")
492         (vec_select:SF
493           (match_operand:V2SF 1 "nonimmediate_operand" " x,y,x,y,m")
494           (parallel [(const_int 0)])))]
495   "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
496   "#"
497   "&& reload_completed"
498   [(const_int 0)]
499 {
500   rtx op1 = operands[1];
501   if (REG_P (op1))
502     op1 = gen_rtx_REG (SFmode, REGNO (op1));
503   else
504     op1 = gen_lowpart (SFmode, op1);
505   emit_move_insn (operands[0], op1);
506   DONE;
507 })
508
509 (define_insn "*vec_extractv2sf_1"
510   [(set (match_operand:SF 0 "nonimmediate_operand"     "=y,x,frxy")
511         (vec_select:SF
512           (match_operand:V2SF 1 "nonimmediate_operand" " 0,0,o")
513           (parallel [(const_int 1)])))]
514   "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
515   "@
516    punpckhdq\t%0, %0
517    unpckhps\t%0, %0
518    #"
519   [(set_attr "type" "mmxcvt,sselog1,*")
520    (set_attr "mode" "DI,V4SF,SI")])
521
522 (define_split
523   [(set (match_operand:SF 0 "register_operand" "")
524         (vec_select:SF
525           (match_operand:V2SF 1 "memory_operand" "")
526           (parallel [(const_int 1)])))]
527   "TARGET_MMX && reload_completed"
528   [(const_int 0)]
529 {
530   operands[1] = adjust_address (operands[1], SFmode, 4);
531   emit_move_insn (operands[0], operands[1]);
532   DONE;
533 })
534
535 (define_expand "vec_extractv2sf"
536   [(match_operand:SF 0 "register_operand" "")
537    (match_operand:V2SF 1 "register_operand" "")
538    (match_operand 2 "const_int_operand" "")]
539   "TARGET_MMX"
540 {
541   ix86_expand_vector_extract (false, operands[0], operands[1],
542                               INTVAL (operands[2]));
543   DONE;
544 })
545
546 (define_expand "vec_initv2sf"
547   [(match_operand:V2SF 0 "register_operand" "")
548    (match_operand 1 "" "")]
549   "TARGET_SSE"
550 {
551   ix86_expand_vector_init (false, operands[0], operands[1]);
552   DONE;
553 })
554
555 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
556 ;;
557 ;; Parallel integral arithmetic
558 ;;
559 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
560
561 (define_insn "mmx_add<mode>3"
562   [(set (match_operand:MMXMODEI8 0 "register_operand" "=y")
563         (plus:MMXMODEI8
564           (match_operand:MMXMODEI8 1 "nonimmediate_operand" "%0")
565           (match_operand:MMXMODEI8 2 "nonimmediate_operand" "ym")))]
566   "(TARGET_MMX || (TARGET_SSE2 && <MODE>mode == V1DImode))
567    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
568   "padd<mmxvecsize>\t{%2, %0|%0, %2}"
569   [(set_attr "type" "mmxadd")
570    (set_attr "mode" "DI")])
571
572 (define_insn "mmx_ssadd<mode>3"
573   [(set (match_operand:MMXMODE12 0 "register_operand" "=y")
574         (ss_plus:MMXMODE12
575           (match_operand:MMXMODE12 1 "nonimmediate_operand" "%0")
576           (match_operand:MMXMODE12 2 "nonimmediate_operand" "ym")))]
577   "TARGET_MMX"
578   "padds<mmxvecsize>\t{%2, %0|%0, %2}"
579   [(set_attr "type" "mmxadd")
580    (set_attr "mode" "DI")])
581
582 (define_insn "mmx_usadd<mode>3"
583   [(set (match_operand:MMXMODE12 0 "register_operand" "=y")
584         (us_plus:MMXMODE12
585           (match_operand:MMXMODE12 1 "nonimmediate_operand" "%0")
586           (match_operand:MMXMODE12 2 "nonimmediate_operand" "ym")))]
587   "TARGET_MMX"
588   "paddus<mmxvecsize>\t{%2, %0|%0, %2}"
589   [(set_attr "type" "mmxadd")
590    (set_attr "mode" "DI")])
591
592 (define_insn "mmx_sub<mode>3"
593   [(set (match_operand:MMXMODEI8 0 "register_operand" "=y")
594         (minus:MMXMODEI8
595           (match_operand:MMXMODEI8 1 "register_operand" "0")
596           (match_operand:MMXMODEI8 2 "nonimmediate_operand" "ym")))]
597   "(TARGET_MMX || (TARGET_SSE2 && <MODE>mode == V1DImode))"
598   "psub<mmxvecsize>\t{%2, %0|%0, %2}"
599   [(set_attr "type" "mmxadd")
600    (set_attr "mode" "DI")])
601
602 (define_insn "mmx_sssub<mode>3"
603   [(set (match_operand:MMXMODE12 0 "register_operand" "=y")
604         (ss_minus:MMXMODE12
605           (match_operand:MMXMODE12 1 "register_operand" "0")
606           (match_operand:MMXMODE12 2 "nonimmediate_operand" "ym")))]
607   "TARGET_MMX"
608   "psubs<mmxvecsize>\t{%2, %0|%0, %2}"
609   [(set_attr "type" "mmxadd")
610    (set_attr "mode" "DI")])
611
612 (define_insn "mmx_ussub<mode>3"
613   [(set (match_operand:MMXMODE12 0 "register_operand" "=y")
614         (us_minus:MMXMODE12
615           (match_operand:MMXMODE12 1 "register_operand" "0")
616           (match_operand:MMXMODE12 2 "nonimmediate_operand" "ym")))]
617   "TARGET_MMX"
618   "psubus<mmxvecsize>\t{%2, %0|%0, %2}"
619   [(set_attr "type" "mmxadd")
620    (set_attr "mode" "DI")])
621
622 (define_insn "mmx_mulv4hi3"
623   [(set (match_operand:V4HI 0 "register_operand" "=y")
624         (mult:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "%0")
625                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
626   "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
627   "pmullw\t{%2, %0|%0, %2}"
628   [(set_attr "type" "mmxmul")
629    (set_attr "mode" "DI")])
630
631 (define_insn "mmx_smulv4hi3_highpart"
632   [(set (match_operand:V4HI 0 "register_operand" "=y")
633         (truncate:V4HI
634          (lshiftrt:V4SI
635           (mult:V4SI (sign_extend:V4SI
636                       (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
637                      (sign_extend:V4SI
638                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
639           (const_int 16))))]
640   "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
641   "pmulhw\t{%2, %0|%0, %2}"
642   [(set_attr "type" "mmxmul")
643    (set_attr "mode" "DI")])
644
645 (define_insn "mmx_umulv4hi3_highpart"
646   [(set (match_operand:V4HI 0 "register_operand" "=y")
647         (truncate:V4HI
648          (lshiftrt:V4SI
649           (mult:V4SI (zero_extend:V4SI
650                       (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
651                      (zero_extend:V4SI
652                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
653           (const_int 16))))]
654   "(TARGET_SSE || TARGET_3DNOW_A)
655    && ix86_binary_operator_ok (MULT, V4HImode, operands)"
656   "pmulhuw\t{%2, %0|%0, %2}"
657   [(set_attr "type" "mmxmul")
658    (set_attr "mode" "DI")])
659
660 (define_insn "mmx_pmaddwd"
661   [(set (match_operand:V2SI 0 "register_operand" "=y")
662         (plus:V2SI
663           (mult:V2SI
664             (sign_extend:V2SI
665               (vec_select:V2HI
666                 (match_operand:V4HI 1 "nonimmediate_operand" "%0")
667                 (parallel [(const_int 0) (const_int 2)])))
668             (sign_extend:V2SI
669               (vec_select:V2HI
670                 (match_operand:V4HI 2 "nonimmediate_operand" "ym")
671                 (parallel [(const_int 0) (const_int 2)]))))
672           (mult:V2SI
673             (sign_extend:V2SI
674               (vec_select:V2HI (match_dup 1)
675                 (parallel [(const_int 1) (const_int 3)])))
676             (sign_extend:V2SI
677               (vec_select:V2HI (match_dup 2)
678                 (parallel [(const_int 1) (const_int 3)]))))))]
679   "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
680   "pmaddwd\t{%2, %0|%0, %2}"
681   [(set_attr "type" "mmxmul")
682    (set_attr "mode" "DI")])
683
684 (define_insn "mmx_pmulhrwv4hi3"
685   [(set (match_operand:V4HI 0 "register_operand" "=y")
686         (truncate:V4HI
687           (lshiftrt:V4SI
688             (plus:V4SI
689               (mult:V4SI
690                 (sign_extend:V4SI
691                   (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
692                 (sign_extend:V4SI
693                   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
694               (const_vector:V4SI [(const_int 32768) (const_int 32768)
695                                   (const_int 32768) (const_int 32768)]))
696             (const_int 16))))]
697   "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V4HImode, operands)"
698   "pmulhrw\\t{%2, %0|%0, %2}"
699   [(set_attr "type" "mmxmul")
700    (set_attr "mode" "DI")])
701
702 (define_insn "sse2_umulv1siv1di3"
703   [(set (match_operand:V1DI 0 "register_operand" "=y")
704         (mult:V1DI
705           (zero_extend:V1DI
706             (vec_select:V1SI
707               (match_operand:V2SI 1 "nonimmediate_operand" "%0")
708               (parallel [(const_int 0)])))
709           (zero_extend:V1DI
710             (vec_select:V1SI
711               (match_operand:V2SI 2 "nonimmediate_operand" "ym")
712               (parallel [(const_int 0)])))))]
713   "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V2SImode, operands)"
714   "pmuludq\t{%2, %0|%0, %2}"
715   [(set_attr "type" "mmxmul")
716    (set_attr "mode" "DI")])
717
718 (define_insn "mmx_umaxv8qi3"
719   [(set (match_operand:V8QI 0 "register_operand" "=y")
720         (umax:V8QI (match_operand:V8QI 1 "nonimmediate_operand" "%0")
721                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
722   "(TARGET_SSE || TARGET_3DNOW_A)
723    && ix86_binary_operator_ok (UMAX, V8QImode, operands)"
724   "pmaxub\t{%2, %0|%0, %2}"
725   [(set_attr "type" "mmxadd")
726    (set_attr "mode" "DI")])
727
728 (define_insn "mmx_smaxv4hi3"
729   [(set (match_operand:V4HI 0 "register_operand" "=y")
730         (smax:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "%0")
731                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
732   "(TARGET_SSE || TARGET_3DNOW_A)
733    && ix86_binary_operator_ok (SMAX, V4HImode, operands)"
734   "pmaxsw\t{%2, %0|%0, %2}"
735   [(set_attr "type" "mmxadd")
736    (set_attr "mode" "DI")])
737
738 (define_insn "mmx_uminv8qi3"
739   [(set (match_operand:V8QI 0 "register_operand" "=y")
740         (umin:V8QI (match_operand:V8QI 1 "nonimmediate_operand" "%0")
741                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
742   "(TARGET_SSE || TARGET_3DNOW_A)
743    && ix86_binary_operator_ok (UMIN, V8QImode, operands)"
744   "pminub\t{%2, %0|%0, %2}"
745   [(set_attr "type" "mmxadd")
746    (set_attr "mode" "DI")])
747
748 (define_insn "mmx_sminv4hi3"
749   [(set (match_operand:V4HI 0 "register_operand" "=y")
750         (smin:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "%0")
751                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
752   "(TARGET_SSE || TARGET_3DNOW_A)
753    && ix86_binary_operator_ok (SMIN, V4HImode, operands)"
754   "pminsw\t{%2, %0|%0, %2}"
755   [(set_attr "type" "mmxadd")
756    (set_attr "mode" "DI")])
757
758 (define_insn "mmx_ashr<mode>3"
759   [(set (match_operand:MMXMODE24 0 "register_operand" "=y")
760         (ashiftrt:MMXMODE24
761           (match_operand:MMXMODE24 1 "register_operand" "0")
762           (match_operand:SI 2 "nonmemory_operand" "yN")))]
763   "TARGET_MMX"
764   "psra<mmxvecsize>\t{%2, %0|%0, %2}"
765   [(set_attr "type" "mmxshft")
766    (set_attr "mode" "DI")])
767
768 (define_insn "mmx_lshr<mode>3"
769   [(set (match_operand:MMXMODE248 0 "register_operand" "=y")
770         (lshiftrt:MMXMODE248
771           (match_operand:MMXMODE248 1 "register_operand" "0")
772           (match_operand:SI 2 "nonmemory_operand" "yN")))]
773   "TARGET_MMX"
774   "psrl<mmxvecsize>\t{%2, %0|%0, %2}"
775   [(set_attr "type" "mmxshft")
776    (set_attr "mode" "DI")])
777
778 (define_insn "mmx_ashl<mode>3"
779   [(set (match_operand:MMXMODE248 0 "register_operand" "=y")
780         (ashift:MMXMODE248
781           (match_operand:MMXMODE248 1 "register_operand" "0")
782           (match_operand:SI 2 "nonmemory_operand" "yN")))]
783   "TARGET_MMX"
784   "psll<mmxvecsize>\t{%2, %0|%0, %2}"
785   [(set_attr "type" "mmxshft")
786    (set_attr "mode" "DI")])
787
788 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
789 ;;
790 ;; Parallel integral comparisons
791 ;;
792 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
793
794 (define_insn "mmx_eq<mode>3"
795   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
796         (eq:MMXMODEI
797           (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
798           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
799   "TARGET_MMX && ix86_binary_operator_ok (EQ, <MODE>mode, operands)"
800   "pcmpeq<mmxvecsize>\t{%2, %0|%0, %2}"
801   [(set_attr "type" "mmxcmp")
802    (set_attr "mode" "DI")])
803
804 (define_insn "mmx_gt<mode>3"
805   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
806         (gt:MMXMODEI
807           (match_operand:MMXMODEI 1 "register_operand" "0")
808           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
809   "TARGET_MMX"
810   "pcmpgt<mmxvecsize>\t{%2, %0|%0, %2}"
811   [(set_attr "type" "mmxcmp")
812    (set_attr "mode" "DI")])
813
814 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
815 ;;
816 ;; Parallel integral logical operations
817 ;;
818 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
819
820 (define_insn "mmx_and<mode>3"
821   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
822         (and:MMXMODEI
823           (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
824           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
825   "TARGET_MMX && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
826   "pand\t{%2, %0|%0, %2}"
827   [(set_attr "type" "mmxadd")
828    (set_attr "mode" "DI")])
829
830 (define_insn "mmx_nand<mode>3"
831   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
832         (and:MMXMODEI
833           (not:MMXMODEI (match_operand:MMXMODEI 1 "register_operand" "0"))
834           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
835   "TARGET_MMX"
836   "pandn\t{%2, %0|%0, %2}"
837   [(set_attr "type" "mmxadd")
838    (set_attr "mode" "DI")])
839
840 (define_insn "mmx_ior<mode>3"
841   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
842         (ior:MMXMODEI
843           (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
844           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
845   "TARGET_MMX && ix86_binary_operator_ok (IOR, <MODE>mode, operands)"
846   "por\t{%2, %0|%0, %2}"
847   [(set_attr "type" "mmxadd")
848    (set_attr "mode" "DI")])
849
850 (define_insn "mmx_xor<mode>3"
851   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
852         (xor:MMXMODEI
853           (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
854           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
855   "TARGET_MMX && ix86_binary_operator_ok (XOR, <MODE>mode, operands)"
856   "pxor\t{%2, %0|%0, %2}"
857   [(set_attr "type" "mmxadd")
858    (set_attr "mode" "DI")
859    (set_attr "memory" "none")])
860
861 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
862 ;;
863 ;; Parallel integral element swizzling
864 ;;
865 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
866
867 (define_insn "mmx_packsswb"
868   [(set (match_operand:V8QI 0 "register_operand" "=y")
869         (vec_concat:V8QI
870           (ss_truncate:V4QI
871             (match_operand:V4HI 1 "register_operand" "0"))
872           (ss_truncate:V4QI
873             (match_operand:V4HI 2 "nonimmediate_operand" "ym"))))]
874   "TARGET_MMX"
875   "packsswb\t{%2, %0|%0, %2}"
876   [(set_attr "type" "mmxshft")
877    (set_attr "mode" "DI")])
878
879 (define_insn "mmx_packssdw"
880   [(set (match_operand:V4HI 0 "register_operand" "=y")
881         (vec_concat:V4HI
882           (ss_truncate:V2HI
883             (match_operand:V2SI 1 "register_operand" "0"))
884           (ss_truncate:V2HI
885             (match_operand:V2SI 2 "nonimmediate_operand" "ym"))))]
886   "TARGET_MMX"
887   "packssdw\t{%2, %0|%0, %2}"
888   [(set_attr "type" "mmxshft")
889    (set_attr "mode" "DI")])
890
891 (define_insn "mmx_packuswb"
892   [(set (match_operand:V8QI 0 "register_operand" "=y")
893         (vec_concat:V8QI
894           (us_truncate:V4QI
895             (match_operand:V4HI 1 "register_operand" "0"))
896           (us_truncate:V4QI
897             (match_operand:V4HI 2 "nonimmediate_operand" "ym"))))]
898   "TARGET_MMX"
899   "packuswb\t{%2, %0|%0, %2}"
900   [(set_attr "type" "mmxshft")
901    (set_attr "mode" "DI")])
902
903 (define_insn "mmx_punpckhbw"
904   [(set (match_operand:V8QI 0 "register_operand" "=y")
905         (vec_select:V8QI
906           (vec_concat:V16QI
907             (match_operand:V8QI 1 "register_operand" "0")
908             (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
909           (parallel [(const_int 4) (const_int 12)
910                      (const_int 5) (const_int 13)
911                      (const_int 6) (const_int 14)
912                      (const_int 7) (const_int 15)])))]
913   "TARGET_MMX"
914   "punpckhbw\t{%2, %0|%0, %2}"
915   [(set_attr "type" "mmxcvt")
916    (set_attr "mode" "DI")])
917
918 (define_insn "mmx_punpcklbw"
919   [(set (match_operand:V8QI 0 "register_operand" "=y")
920         (vec_select:V8QI
921           (vec_concat:V16QI
922             (match_operand:V8QI 1 "register_operand" "0")
923             (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
924           (parallel [(const_int 0) (const_int 8)
925                      (const_int 1) (const_int 9)
926                      (const_int 2) (const_int 10)
927                      (const_int 3) (const_int 11)])))]
928   "TARGET_MMX"
929   "punpcklbw\t{%2, %0|%0, %2}"
930   [(set_attr "type" "mmxcvt")
931    (set_attr "mode" "DI")])
932
933 (define_insn "mmx_punpckhwd"
934   [(set (match_operand:V4HI 0 "register_operand" "=y")
935         (vec_select:V4HI
936           (vec_concat:V8HI
937             (match_operand:V4HI 1 "register_operand" "0")
938             (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
939           (parallel [(const_int 2) (const_int 6)
940                      (const_int 3) (const_int 7)])))]
941   "TARGET_MMX"
942   "punpckhwd\t{%2, %0|%0, %2}"
943   [(set_attr "type" "mmxcvt")
944    (set_attr "mode" "DI")])
945
946 (define_insn "mmx_punpcklwd"
947   [(set (match_operand:V4HI 0 "register_operand" "=y")
948         (vec_select:V4HI
949           (vec_concat:V8HI
950             (match_operand:V4HI 1 "register_operand" "0")
951             (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
952           (parallel [(const_int 0) (const_int 4)
953                      (const_int 1) (const_int 5)])))]
954   "TARGET_MMX"
955   "punpcklwd\t{%2, %0|%0, %2}"
956   [(set_attr "type" "mmxcvt")
957    (set_attr "mode" "DI")])
958
959 (define_insn "mmx_punpckhdq"
960   [(set (match_operand:V2SI 0 "register_operand" "=y")
961         (vec_select:V2SI
962           (vec_concat:V4SI
963             (match_operand:V2SI 1 "register_operand" "0")
964             (match_operand:V2SI 2 "nonimmediate_operand" "ym"))
965           (parallel [(const_int 1)
966                      (const_int 3)])))]
967   "TARGET_MMX"
968   "punpckhdq\t{%2, %0|%0, %2}"
969   [(set_attr "type" "mmxcvt")
970    (set_attr "mode" "DI")])
971
972 (define_insn "mmx_punpckldq"
973   [(set (match_operand:V2SI 0 "register_operand" "=y")
974         (vec_select:V2SI
975           (vec_concat:V4SI
976             (match_operand:V2SI 1 "register_operand" "0")
977             (match_operand:V2SI 2 "nonimmediate_operand" "ym"))
978           (parallel [(const_int 0)
979                      (const_int 2)])))]
980   "TARGET_MMX"
981   "punpckldq\t{%2, %0|%0, %2}"
982   [(set_attr "type" "mmxcvt")
983    (set_attr "mode" "DI")])
984
985 (define_expand "mmx_pinsrw"
986   [(set (match_operand:V4HI 0 "register_operand" "")
987         (vec_merge:V4HI
988           (vec_duplicate:V4HI
989             (match_operand:SI 2 "nonimmediate_operand" ""))
990           (match_operand:V4HI 1 "register_operand" "")
991           (match_operand:SI 3 "const_0_to_3_operand" "")))]
992   "TARGET_SSE || TARGET_3DNOW_A"
993 {
994   operands[2] = gen_lowpart (HImode, operands[2]);
995   operands[3] = GEN_INT (1 << INTVAL (operands[3]));
996 })
997
998 (define_insn "*mmx_pinsrw"
999   [(set (match_operand:V4HI 0 "register_operand" "=y")
1000         (vec_merge:V4HI
1001           (vec_duplicate:V4HI
1002             (match_operand:HI 2 "nonimmediate_operand" "rm"))
1003           (match_operand:V4HI 1 "register_operand" "0")
1004           (match_operand:SI 3 "const_pow2_1_to_8_operand" "n")))]
1005   "TARGET_SSE || TARGET_3DNOW_A"
1006 {
1007   operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
1008   return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}";
1009 }
1010   [(set_attr "type" "mmxcvt")
1011    (set_attr "mode" "DI")])
1012
1013 (define_insn "mmx_pextrw"
1014   [(set (match_operand:SI 0 "register_operand" "=r")
1015         (zero_extend:SI
1016           (vec_select:HI
1017             (match_operand:V4HI 1 "register_operand" "y")
1018             (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n")]))))]
1019   "TARGET_SSE || TARGET_3DNOW_A"
1020   "pextrw\t{%2, %1, %0|%0, %1, %2}"
1021   [(set_attr "type" "mmxcvt")
1022    (set_attr "mode" "DI")])
1023
1024 (define_expand "mmx_pshufw"
1025   [(match_operand:V4HI 0 "register_operand" "")
1026    (match_operand:V4HI 1 "nonimmediate_operand" "")
1027    (match_operand:SI 2 "const_int_operand" "")]
1028   "TARGET_SSE || TARGET_3DNOW_A"
1029 {
1030   int mask = INTVAL (operands[2]);
1031   emit_insn (gen_mmx_pshufw_1 (operands[0], operands[1],
1032                                GEN_INT ((mask >> 0) & 3),
1033                                GEN_INT ((mask >> 2) & 3),
1034                                GEN_INT ((mask >> 4) & 3),
1035                                GEN_INT ((mask >> 6) & 3)));
1036   DONE;
1037 })
1038
1039 (define_insn "mmx_pshufw_1"
1040   [(set (match_operand:V4HI 0 "register_operand" "=y")
1041         (vec_select:V4HI
1042           (match_operand:V4HI 1 "nonimmediate_operand" "ym")
1043           (parallel [(match_operand 2 "const_0_to_3_operand" "")
1044                      (match_operand 3 "const_0_to_3_operand" "")
1045                      (match_operand 4 "const_0_to_3_operand" "")
1046                      (match_operand 5 "const_0_to_3_operand" "")])))]
1047   "TARGET_SSE || TARGET_3DNOW_A"
1048 {
1049   int mask = 0;
1050   mask |= INTVAL (operands[2]) << 0;
1051   mask |= INTVAL (operands[3]) << 2;
1052   mask |= INTVAL (operands[4]) << 4;
1053   mask |= INTVAL (operands[5]) << 6;
1054   operands[2] = GEN_INT (mask);
1055
1056   return "pshufw\t{%2, %1, %0|%0, %1, %2}";
1057 }
1058   [(set_attr "type" "mmxcvt")
1059    (set_attr "mode" "DI")])
1060
1061 (define_insn "mmx_pswapdv2si2"
1062   [(set (match_operand:V2SI 0 "register_operand" "=y")
1063         (vec_select:V2SI
1064           (match_operand:V2SI 1 "nonimmediate_operand" "ym")
1065           (parallel [(const_int 1) (const_int 0)])))]
1066   "TARGET_3DNOW_A"
1067   "pswapd\\t{%1, %0|%0, %1}"
1068   [(set_attr "type" "mmxcvt")
1069    (set_attr "mode" "DI")])
1070
1071 (define_insn "*vec_dupv4hi"
1072   [(set (match_operand:V4HI 0 "register_operand" "=y")
1073         (vec_duplicate:V4HI
1074           (truncate:HI
1075             (match_operand:SI 1 "register_operand" "0"))))]
1076   "TARGET_SSE || TARGET_3DNOW_A"
1077   "pshufw\t{$0, %0, %0|%0, %0, 0}"
1078   [(set_attr "type" "mmxcvt")
1079    (set_attr "mode" "DI")])
1080
1081 (define_insn "*vec_dupv2si"
1082   [(set (match_operand:V2SI 0 "register_operand" "=y")
1083         (vec_duplicate:V2SI
1084           (match_operand:SI 1 "register_operand" "0")))]
1085   "TARGET_MMX"
1086   "punpckldq\t%0, %0"
1087   [(set_attr "type" "mmxcvt")
1088    (set_attr "mode" "DI")])
1089
1090 (define_insn "*mmx_concatv2si"
1091   [(set (match_operand:V2SI 0 "register_operand"     "=y,y")
1092         (vec_concat:V2SI
1093           (match_operand:SI 1 "nonimmediate_operand" " 0,rm")
1094           (match_operand:SI 2 "vector_move_operand"  "ym,C")))]
1095   "TARGET_MMX && !TARGET_SSE"
1096   "@
1097    punpckldq\t{%2, %0|%0, %2}
1098    movd\t{%1, %0|%0, %1}"
1099   [(set_attr "type" "mmxcvt,mmxmov")
1100    (set_attr "mode" "DI")])
1101
1102 (define_expand "vec_setv2si"
1103   [(match_operand:V2SI 0 "register_operand" "")
1104    (match_operand:SI 1 "register_operand" "")
1105    (match_operand 2 "const_int_operand" "")]
1106   "TARGET_MMX"
1107 {
1108   ix86_expand_vector_set (false, operands[0], operands[1],
1109                           INTVAL (operands[2]));
1110   DONE;
1111 })
1112
1113 (define_insn_and_split "*vec_extractv2si_0"
1114   [(set (match_operand:SI 0 "nonimmediate_operand"     "=x,y,m,m,frxy")
1115         (vec_select:SI
1116           (match_operand:V2SI 1 "nonimmediate_operand" " x,y,x,y,m")
1117           (parallel [(const_int 0)])))]
1118   "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1119   "#"
1120   "&& reload_completed"
1121   [(const_int 0)]
1122 {
1123   rtx op1 = operands[1];
1124   if (REG_P (op1))
1125     op1 = gen_rtx_REG (SImode, REGNO (op1));
1126   else
1127     op1 = gen_lowpart (SImode, op1);
1128   emit_move_insn (operands[0], op1);
1129   DONE;
1130 })
1131
1132 (define_insn "*vec_extractv2si_1"
1133   [(set (match_operand:SI 0 "nonimmediate_operand"     "=y,Y2,Y2,x,frxy")
1134         (vec_select:SI
1135           (match_operand:V2SI 1 "nonimmediate_operand" " 0,0 ,Y2,0,o")
1136           (parallel [(const_int 1)])))]
1137   "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1138   "@
1139    punpckhdq\t%0, %0
1140    punpckhdq\t%0, %0
1141    pshufd\t{$85, %1, %0|%0, %1, 85}
1142    unpckhps\t%0, %0
1143    #"
1144   [(set_attr "type" "mmxcvt,sselog1,sselog1,sselog1,*")
1145    (set_attr "mode" "DI,TI,TI,V4SF,SI")])
1146
1147 (define_split
1148   [(set (match_operand:SI 0 "register_operand" "")
1149         (vec_select:SI
1150           (match_operand:V2SI 1 "memory_operand" "")
1151           (parallel [(const_int 1)])))]
1152   "TARGET_MMX && reload_completed"
1153   [(const_int 0)]
1154 {
1155   operands[1] = adjust_address (operands[1], SImode, 4);
1156   emit_move_insn (operands[0], operands[1]);
1157   DONE;
1158 })
1159
1160 (define_expand "vec_extractv2si"
1161   [(match_operand:SI 0 "register_operand" "")
1162    (match_operand:V2SI 1 "register_operand" "")
1163    (match_operand 2 "const_int_operand" "")]
1164   "TARGET_MMX"
1165 {
1166   ix86_expand_vector_extract (false, operands[0], operands[1],
1167                               INTVAL (operands[2]));
1168   DONE;
1169 })
1170
1171 (define_expand "vec_initv2si"
1172   [(match_operand:V2SI 0 "register_operand" "")
1173    (match_operand 1 "" "")]
1174   "TARGET_SSE"
1175 {
1176   ix86_expand_vector_init (false, operands[0], operands[1]);
1177   DONE;
1178 })
1179
1180 (define_expand "vec_setv4hi"
1181   [(match_operand:V4HI 0 "register_operand" "")
1182    (match_operand:HI 1 "register_operand" "")
1183    (match_operand 2 "const_int_operand" "")]
1184   "TARGET_MMX"
1185 {
1186   ix86_expand_vector_set (false, operands[0], operands[1],
1187                           INTVAL (operands[2]));
1188   DONE;
1189 })
1190
1191 (define_expand "vec_extractv4hi"
1192   [(match_operand:HI 0 "register_operand" "")
1193    (match_operand:V4HI 1 "register_operand" "")
1194    (match_operand 2 "const_int_operand" "")]
1195   "TARGET_MMX"
1196 {
1197   ix86_expand_vector_extract (false, operands[0], operands[1],
1198                               INTVAL (operands[2]));
1199   DONE;
1200 })
1201
1202 (define_expand "vec_initv4hi"
1203   [(match_operand:V4HI 0 "register_operand" "")
1204    (match_operand 1 "" "")]
1205   "TARGET_SSE"
1206 {
1207   ix86_expand_vector_init (false, operands[0], operands[1]);
1208   DONE;
1209 })
1210
1211 (define_expand "vec_setv8qi"
1212   [(match_operand:V8QI 0 "register_operand" "")
1213    (match_operand:QI 1 "register_operand" "")
1214    (match_operand 2 "const_int_operand" "")]
1215   "TARGET_MMX"
1216 {
1217   ix86_expand_vector_set (false, operands[0], operands[1],
1218                           INTVAL (operands[2]));
1219   DONE;
1220 })
1221
1222 (define_expand "vec_extractv8qi"
1223   [(match_operand:QI 0 "register_operand" "")
1224    (match_operand:V8QI 1 "register_operand" "")
1225    (match_operand 2 "const_int_operand" "")]
1226   "TARGET_MMX"
1227 {
1228   ix86_expand_vector_extract (false, operands[0], operands[1],
1229                               INTVAL (operands[2]));
1230   DONE;
1231 })
1232
1233 (define_expand "vec_initv8qi"
1234   [(match_operand:V8QI 0 "register_operand" "")
1235    (match_operand 1 "" "")]
1236   "TARGET_SSE"
1237 {
1238   ix86_expand_vector_init (false, operands[0], operands[1]);
1239   DONE;
1240 })
1241
1242 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1243 ;;
1244 ;; Miscellaneous
1245 ;;
1246 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1247
1248 (define_insn "mmx_uavgv8qi3"
1249   [(set (match_operand:V8QI 0 "register_operand" "=y")
1250         (truncate:V8QI
1251           (lshiftrt:V8HI
1252             (plus:V8HI
1253               (plus:V8HI
1254                 (zero_extend:V8HI
1255                   (match_operand:V8QI 1 "nonimmediate_operand" "%0"))
1256                 (zero_extend:V8HI
1257                   (match_operand:V8QI 2 "nonimmediate_operand" "ym")))
1258               (const_vector:V8HI [(const_int 1) (const_int 1)
1259                                   (const_int 1) (const_int 1)
1260                                   (const_int 1) (const_int 1)
1261                                   (const_int 1) (const_int 1)]))
1262             (const_int 1))))]
1263   "(TARGET_SSE || TARGET_3DNOW)
1264    && ix86_binary_operator_ok (PLUS, V8QImode, operands)"
1265 {
1266   /* These two instructions have the same operation, but their encoding
1267      is different.  Prefer the one that is de facto standard.  */
1268   if (TARGET_SSE || TARGET_3DNOW_A)
1269     return "pavgb\t{%2, %0|%0, %2}";
1270   else
1271     return "pavgusb\\t{%2, %0|%0, %2}";
1272 }
1273   [(set_attr "type" "mmxshft")
1274    (set_attr "mode" "DI")])
1275
1276 (define_insn "mmx_uavgv4hi3"
1277   [(set (match_operand:V4HI 0 "register_operand" "=y")
1278         (truncate:V4HI
1279           (lshiftrt:V4SI
1280             (plus:V4SI
1281               (plus:V4SI
1282                 (zero_extend:V4SI
1283                   (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
1284                 (zero_extend:V4SI
1285                   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
1286               (const_vector:V4SI [(const_int 1) (const_int 1)
1287                                   (const_int 1) (const_int 1)]))
1288             (const_int 1))))]
1289   "(TARGET_SSE || TARGET_3DNOW_A)
1290    && ix86_binary_operator_ok (PLUS, V4HImode, operands)"
1291   "pavgw\t{%2, %0|%0, %2}"
1292   [(set_attr "type" "mmxshft")
1293    (set_attr "mode" "DI")])
1294
1295 (define_insn "mmx_psadbw"
1296   [(set (match_operand:V1DI 0 "register_operand" "=y")
1297         (unspec:V1DI [(match_operand:V8QI 1 "register_operand" "0")
1298                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
1299                      UNSPEC_PSADBW))]
1300   "TARGET_SSE || TARGET_3DNOW_A"
1301   "psadbw\t{%2, %0|%0, %2}"
1302   [(set_attr "type" "mmxshft")
1303    (set_attr "mode" "DI")])
1304
1305 (define_insn "mmx_pmovmskb"
1306   [(set (match_operand:SI 0 "register_operand" "=r")
1307         (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
1308                    UNSPEC_MOVMSK))]
1309   "TARGET_SSE || TARGET_3DNOW_A"
1310   "pmovmskb\t{%1, %0|%0, %1}"
1311   [(set_attr "type" "mmxcvt")
1312    (set_attr "mode" "DI")])
1313
1314 (define_expand "mmx_maskmovq"
1315   [(set (match_operand:V8QI 0 "memory_operand" "")
1316         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "")
1317                       (match_operand:V8QI 2 "register_operand" "")
1318                       (match_dup 0)]
1319                      UNSPEC_MASKMOV))]
1320   "TARGET_SSE || TARGET_3DNOW_A"
1321   "")
1322
1323 (define_insn "*mmx_maskmovq"
1324   [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
1325         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
1326                       (match_operand:V8QI 2 "register_operand" "y")
1327                       (mem:V8QI (match_dup 0))]
1328                      UNSPEC_MASKMOV))]
1329   "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
1330   ;; @@@ check ordering of operands in intel/nonintel syntax
1331   "maskmovq\t{%2, %1|%1, %2}"
1332   [(set_attr "type" "mmxcvt")
1333    (set_attr "mode" "DI")])
1334
1335 (define_insn "*mmx_maskmovq_rex"
1336   [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
1337         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
1338                       (match_operand:V8QI 2 "register_operand" "y")
1339                       (mem:V8QI (match_dup 0))]
1340                      UNSPEC_MASKMOV))]
1341   "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
1342   ;; @@@ check ordering of operands in intel/nonintel syntax
1343   "maskmovq\t{%2, %1|%1, %2}"
1344   [(set_attr "type" "mmxcvt")
1345    (set_attr "mode" "DI")])
1346
1347 (define_insn "mmx_emms"
1348   [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
1349    (clobber (reg:XF 8))
1350    (clobber (reg:XF 9))
1351    (clobber (reg:XF 10))
1352    (clobber (reg:XF 11))
1353    (clobber (reg:XF 12))
1354    (clobber (reg:XF 13))
1355    (clobber (reg:XF 14))
1356    (clobber (reg:XF 15))
1357    (clobber (reg:DI 29))
1358    (clobber (reg:DI 30))
1359    (clobber (reg:DI 31))
1360    (clobber (reg:DI 32))
1361    (clobber (reg:DI 33))
1362    (clobber (reg:DI 34))
1363    (clobber (reg:DI 35))
1364    (clobber (reg:DI 36))]
1365   "TARGET_MMX"
1366   "emms"
1367   [(set_attr "type" "mmx")
1368    (set_attr "memory" "unknown")])
1369
1370 (define_insn "mmx_femms"
1371   [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
1372    (clobber (reg:XF 8))
1373    (clobber (reg:XF 9))
1374    (clobber (reg:XF 10))
1375    (clobber (reg:XF 11))
1376    (clobber (reg:XF 12))
1377    (clobber (reg:XF 13))
1378    (clobber (reg:XF 14))
1379    (clobber (reg:XF 15))
1380    (clobber (reg:DI 29))
1381    (clobber (reg:DI 30))
1382    (clobber (reg:DI 31))
1383    (clobber (reg:DI 32))
1384    (clobber (reg:DI 33))
1385    (clobber (reg:DI 34))
1386    (clobber (reg:DI 35))
1387    (clobber (reg:DI 36))]
1388   "TARGET_3DNOW"
1389   "femms"
1390   [(set_attr "type" "mmx")
1391    (set_attr "memory" "none")])