OSDN Git Service

* config/i386/mmx.md: Rename "*..." insn patterns from my
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / mmx.md
1 ;; GCC machine description for MMX and 3dNOW! instructions
2 ;; Copyright (C) 2005, 2007, 2008
3 ;; Free Software Foundation, Inc.
4 ;;
5 ;; This file is part of GCC.
6 ;;
7 ;; GCC is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 3, or (at your option)
10 ;; any later version.
11 ;;
12 ;; GCC is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 ;; GNU General Public License for more details.
16 ;;
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3.  If not see
19 ;; <http://www.gnu.org/licenses/>.
20
21 ;; The MMX and 3dNOW! patterns are in the same file because they use
22 ;; the same register file, and 3dNOW! adds a number of extensions to
23 ;; the base integer MMX isa.
24
25 ;; Note!  Except for the basic move instructions, *all* of these
26 ;; patterns are outside the normal optabs namespace.  This is because
27 ;; use of these registers requires the insertion of emms or femms
28 ;; instructions to return to normal fpu mode.  The compiler doesn't
29 ;; know how to do that itself, which means it's up to the user.  Which
30 ;; means that we should never use any of these patterns except at the
31 ;; direction of the user via a builtin.
32
33 ;; 8 byte integral modes handled by MMX (and by extension, SSE)
34 (define_mode_iterator MMXMODEI [V8QI V4HI V2SI])
35 (define_mode_iterator MMXMODEI8 [V8QI V4HI V2SI V1DI])
36
37 ;; All 8-byte vector modes handled by MMX
38 (define_mode_iterator MMXMODE [V8QI V4HI V2SI V1DI V2SF])
39
40 ;; Mix-n-match
41 (define_mode_iterator MMXMODE12 [V8QI V4HI])
42 (define_mode_iterator MMXMODE24 [V4HI V2SI])
43 (define_mode_iterator MMXMODE248 [V4HI V2SI V1DI])
44
45 ;; Mapping from integer vector mode to mnemonic suffix
46 (define_mode_attr mmxvecsize [(V8QI "b") (V4HI "w") (V2SI "d") (V1DI "q")])
47
48 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
49 ;;
50 ;; Move patterns
51 ;;
52 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
53
54 ;; All of these patterns are enabled for MMX as well as 3dNOW.
55 ;; This is essential for maintaining stable calling conventions.
56
57 (define_expand "mov<mode>"
58   [(set (match_operand:MMXMODEI8 0 "nonimmediate_operand" "")
59         (match_operand:MMXMODEI8 1 "nonimmediate_operand" ""))]
60   "TARGET_MMX"
61 {
62   ix86_expand_vector_move (<MODE>mode, operands);
63   DONE;
64 })
65
66 (define_insn "*mov<mode>_internal_rex64"
67   [(set (match_operand:MMXMODEI8 0 "nonimmediate_operand"
68                                 "=rm,r,!?y,!?y ,m  ,!y,Y2,x,x ,m,r,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_expand "mmx_addv2sf3"
216   [(set (match_operand:V2SF 0 "register_operand" "")
217         (plus:V2SF
218           (match_operand:V2SF 1 "nonimmediate_operand" "")
219           (match_operand:V2SF 2 "nonimmediate_operand" "")))]
220   "TARGET_3DNOW"
221   "ix86_fixup_binary_operands_no_copy (PLUS, V2SFmode, operands);")
222
223 (define_insn "*mmx_addv2sf3"
224   [(set (match_operand:V2SF 0 "register_operand" "=y")
225         (plus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
226                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
227   "TARGET_3DNOW && ix86_binary_operator_ok (PLUS, V2SFmode, operands)"
228   "pfadd\t{%2, %0|%0, %2}"
229   [(set_attr "type" "mmxadd")
230    (set_attr "mode" "V2SF")])
231
232 (define_insn "mmx_subv2sf3"
233   [(set (match_operand:V2SF 0 "register_operand" "=y,y")
234         (minus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "0,ym")
235                     (match_operand:V2SF 2 "nonimmediate_operand" "ym,0")))]
236   "TARGET_3DNOW && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
237   "@
238    pfsub\t{%2, %0|%0, %2}
239    pfsubr\t{%2, %0|%0, %2}"
240   [(set_attr "type" "mmxadd")
241    (set_attr "mode" "V2SF")])
242
243 (define_expand "mmx_subrv2sf3"
244   [(set (match_operand:V2SF 0 "register_operand" "")
245         (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "")
246                     (match_operand:V2SF 1 "nonimmediate_operand" "")))]
247   "TARGET_3DNOW && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
248   "")
249
250 (define_expand "mmx_mulv2sf3"
251   [(set (match_operand:V2SF 0 "register_operand" "")
252         (mult:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "")
253                    (match_operand:V2SF 2 "nonimmediate_operand" "")))]
254   "TARGET_3DNOW"
255   "ix86_fixup_binary_operands_no_copy (MULT, V2SFmode, operands);")
256
257 (define_insn "*mmx_mulv2sf3"
258   [(set (match_operand:V2SF 0 "register_operand" "=y")
259         (mult:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
260                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
261   "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V2SFmode, operands)"
262   "pfmul\t{%2, %0|%0, %2}"
263   [(set_attr "type" "mmxmul")
264    (set_attr "mode" "V2SF")])
265
266 ;; ??? For !flag_finite_math_only, the representation with SMIN/SMAX
267 ;; isn't really correct, as those rtl operators aren't defined when
268 ;; applied to NaNs.  Hopefully the optimizers won't get too smart on us.
269
270 (define_expand "mmx_<code>v2sf3"
271   [(set (match_operand:V2SF 0 "register_operand" "")
272         (smaxmin:V2SF
273           (match_operand:V2SF 1 "nonimmediate_operand" "")
274           (match_operand:V2SF 2 "nonimmediate_operand" "")))]
275   "TARGET_3DNOW"
276 {
277   if (!flag_finite_math_only)
278     operands[1] = force_reg (V2SFmode, operands[1]);
279   ix86_fixup_binary_operands_no_copy (<CODE>, V2SFmode, operands);
280 })
281
282 (define_insn "*mmx_<code>v2sf3_finite"
283   [(set (match_operand:V2SF 0 "register_operand" "=y")
284         (smaxmin:V2SF
285           (match_operand:V2SF 1 "nonimmediate_operand" "%0")
286           (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
287   "TARGET_3DNOW && flag_finite_math_only
288    && ix86_binary_operator_ok (<CODE>, V2SFmode, operands)"
289   "pf<maxminfprefix>\t{%2, %0|%0, %2}"
290   [(set_attr "type" "mmxadd")
291    (set_attr "mode" "V2SF")])
292
293 (define_insn "*mmx_<code>v2sf3"
294   [(set (match_operand:V2SF 0 "register_operand" "=y")
295         (smaxmin:V2SF
296           (match_operand:V2SF 1 "register_operand" "0")
297           (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
298   "TARGET_3DNOW"
299   "pf<maxminfprefix>\t{%2, %0|%0, %2}"
300   [(set_attr "type" "mmxadd")
301    (set_attr "mode" "V2SF")])
302
303 (define_insn "mmx_rcpv2sf2"
304   [(set (match_operand:V2SF 0 "register_operand" "=y")
305         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
306                      UNSPEC_PFRCP))]
307   "TARGET_3DNOW"
308   "pfrcp\t{%1, %0|%0, %1}"
309   [(set_attr "type" "mmx")
310    (set_attr "mode" "V2SF")])
311
312 (define_insn "mmx_rcpit1v2sf3"
313   [(set (match_operand:V2SF 0 "register_operand" "=y")
314         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
315                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
316                      UNSPEC_PFRCPIT1))]
317   "TARGET_3DNOW"
318   "pfrcpit1\t{%2, %0|%0, %2}"
319   [(set_attr "type" "mmx")
320    (set_attr "mode" "V2SF")])
321
322 (define_insn "mmx_rcpit2v2sf3"
323   [(set (match_operand:V2SF 0 "register_operand" "=y")
324         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
325                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
326                      UNSPEC_PFRCPIT2))]
327   "TARGET_3DNOW"
328   "pfrcpit2\t{%2, %0|%0, %2}"
329   [(set_attr "type" "mmx")
330    (set_attr "mode" "V2SF")])
331
332 (define_insn "mmx_rsqrtv2sf2"
333   [(set (match_operand:V2SF 0 "register_operand" "=y")
334         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
335                      UNSPEC_PFRSQRT))]
336   "TARGET_3DNOW"
337   "pfrsqrt\t{%1, %0|%0, %1}"
338   [(set_attr "type" "mmx")
339    (set_attr "mode" "V2SF")])
340
341 (define_insn "mmx_rsqit1v2sf3"
342   [(set (match_operand:V2SF 0 "register_operand" "=y")
343         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
344                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
345                      UNSPEC_PFRSQIT1))]
346   "TARGET_3DNOW"
347   "pfrsqit1\t{%2, %0|%0, %2}"
348   [(set_attr "type" "mmx")
349    (set_attr "mode" "V2SF")])
350
351 (define_insn "mmx_haddv2sf3"
352   [(set (match_operand:V2SF 0 "register_operand" "=y")
353         (vec_concat:V2SF
354           (plus:SF
355             (vec_select:SF
356               (match_operand:V2SF 1 "register_operand" "0")
357               (parallel [(const_int  0)]))
358             (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
359           (plus:SF
360             (vec_select:SF
361               (match_operand:V2SF 2 "nonimmediate_operand" "ym")
362               (parallel [(const_int  0)]))
363             (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
364   "TARGET_3DNOW"
365   "pfacc\t{%2, %0|%0, %2}"
366   [(set_attr "type" "mmxadd")
367    (set_attr "mode" "V2SF")])
368
369 (define_insn "mmx_hsubv2sf3"
370   [(set (match_operand:V2SF 0 "register_operand" "=y")
371         (vec_concat:V2SF
372           (minus:SF
373             (vec_select:SF
374               (match_operand:V2SF 1 "register_operand" "0")
375               (parallel [(const_int  0)]))
376             (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
377           (minus:SF
378             (vec_select:SF
379               (match_operand:V2SF 2 "nonimmediate_operand" "ym")
380               (parallel [(const_int  0)]))
381             (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
382   "TARGET_3DNOW_A"
383   "pfnacc\t{%2, %0|%0, %2}"
384   [(set_attr "type" "mmxadd")
385    (set_attr "mode" "V2SF")])
386
387 (define_insn "mmx_addsubv2sf3"
388   [(set (match_operand:V2SF 0 "register_operand" "=y")
389         (vec_merge:V2SF
390           (plus:V2SF
391             (match_operand:V2SF 1 "register_operand" "0")
392             (match_operand:V2SF 2 "nonimmediate_operand" "ym"))
393           (minus:V2SF (match_dup 1) (match_dup 2))
394           (const_int 1)))]
395   "TARGET_3DNOW_A"
396   "pfpnacc\t{%2, %0|%0, %2}"
397   [(set_attr "type" "mmxadd")
398    (set_attr "mode" "V2SF")])
399
400 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
401 ;;
402 ;; Parallel single-precision floating point comparisons
403 ;;
404 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
405
406 (define_insn "mmx_gtv2sf3"
407   [(set (match_operand:V2SI 0 "register_operand" "=y")
408         (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
409                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
410   "TARGET_3DNOW"
411   "pfcmpgt\t{%2, %0|%0, %2}"
412   [(set_attr "type" "mmxcmp")
413    (set_attr "mode" "V2SF")])
414
415 (define_insn "mmx_gev2sf3"
416   [(set (match_operand:V2SI 0 "register_operand" "=y")
417         (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
418                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
419   "TARGET_3DNOW"
420   "pfcmpge\t{%2, %0|%0, %2}"
421   [(set_attr "type" "mmxcmp")
422    (set_attr "mode" "V2SF")])
423
424 (define_insn "mmx_eqv2sf3"
425   [(set (match_operand:V2SI 0 "register_operand" "=y")
426         (eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "%0")
427                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
428   "TARGET_3DNOW && ix86_binary_operator_ok (EQ, V2SFmode, operands)"
429   "pfcmpeq\t{%2, %0|%0, %2}"
430   [(set_attr "type" "mmxcmp")
431    (set_attr "mode" "V2SF")])
432
433 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
434 ;;
435 ;; Parallel single-precision floating point conversion operations
436 ;;
437 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
438
439 (define_insn "mmx_pf2id"
440   [(set (match_operand:V2SI 0 "register_operand" "=y")
441         (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
442   "TARGET_3DNOW"
443   "pf2id\t{%1, %0|%0, %1}"
444   [(set_attr "type" "mmxcvt")
445    (set_attr "mode" "V2SF")])
446
447 (define_insn "mmx_pf2iw"
448   [(set (match_operand:V2SI 0 "register_operand" "=y")
449         (sign_extend:V2SI
450           (ss_truncate:V2HI
451             (fix:V2SI
452               (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
453   "TARGET_3DNOW_A"
454   "pf2iw\t{%1, %0|%0, %1}"
455   [(set_attr "type" "mmxcvt")
456    (set_attr "mode" "V2SF")])
457
458 (define_insn "mmx_pi2fw"
459   [(set (match_operand:V2SF 0 "register_operand" "=y")
460         (float:V2SF
461           (sign_extend:V2SI
462             (truncate:V2HI
463               (match_operand:V2SI 1 "nonimmediate_operand" "ym")))))]
464   "TARGET_3DNOW_A"
465   "pi2fw\t{%1, %0|%0, %1}"
466   [(set_attr "type" "mmxcvt")
467    (set_attr "mode" "V2SF")])
468
469 (define_insn "mmx_floatv2si2"
470   [(set (match_operand:V2SF 0 "register_operand" "=y")
471         (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
472   "TARGET_3DNOW"
473   "pi2fd\t{%1, %0|%0, %1}"
474   [(set_attr "type" "mmxcvt")
475    (set_attr "mode" "V2SF")])
476
477 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
478 ;;
479 ;; Parallel single-precision floating point element swizzling
480 ;;
481 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
482
483 (define_insn "mmx_pswapdv2sf2"
484   [(set (match_operand:V2SF 0 "register_operand" "=y")
485         (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
486                          (parallel [(const_int 1) (const_int 0)])))]
487   "TARGET_3DNOW_A"
488   "pswapd\t{%1, %0|%0, %1}"
489   [(set_attr "type" "mmxcvt")
490    (set_attr "mode" "V2SF")])
491
492 (define_insn "*vec_dupv2sf"
493   [(set (match_operand:V2SF 0 "register_operand" "=y")
494         (vec_duplicate:V2SF
495           (match_operand:SF 1 "register_operand" "0")))]
496   "TARGET_MMX"
497   "punpckldq\t%0, %0"
498   [(set_attr "type" "mmxcvt")
499    (set_attr "mode" "DI")])
500
501 (define_insn "*mmx_concatv2sf"
502   [(set (match_operand:V2SF 0 "register_operand"     "=y,y")
503         (vec_concat:V2SF
504           (match_operand:SF 1 "nonimmediate_operand" " 0,rm")
505           (match_operand:SF 2 "vector_move_operand"  "ym,C")))]
506   "TARGET_MMX && !TARGET_SSE"
507   "@
508    punpckldq\t{%2, %0|%0, %2}
509    movd\t{%1, %0|%0, %1}"
510   [(set_attr "type" "mmxcvt,mmxmov")
511    (set_attr "mode" "DI")])
512
513 (define_expand "vec_setv2sf"
514   [(match_operand:V2SF 0 "register_operand" "")
515    (match_operand:SF 1 "register_operand" "")
516    (match_operand 2 "const_int_operand" "")]
517   "TARGET_MMX"
518 {
519   ix86_expand_vector_set (false, operands[0], operands[1],
520                           INTVAL (operands[2]));
521   DONE;
522 })
523
524 (define_insn_and_split "*vec_extractv2sf_0"
525   [(set (match_operand:SF 0 "nonimmediate_operand"     "=x,y,m,m,frxy")
526         (vec_select:SF
527           (match_operand:V2SF 1 "nonimmediate_operand" " x,y,x,y,m")
528           (parallel [(const_int 0)])))]
529   "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
530   "#"
531   "&& reload_completed"
532   [(const_int 0)]
533 {
534   rtx op1 = operands[1];
535   if (REG_P (op1))
536     op1 = gen_rtx_REG (SFmode, REGNO (op1));
537   else
538     op1 = gen_lowpart (SFmode, op1);
539   emit_move_insn (operands[0], op1);
540   DONE;
541 })
542
543 (define_insn "*vec_extractv2sf_1"
544   [(set (match_operand:SF 0 "nonimmediate_operand"     "=y,x,frxy")
545         (vec_select:SF
546           (match_operand:V2SF 1 "nonimmediate_operand" " 0,0,o")
547           (parallel [(const_int 1)])))]
548   "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
549   "@
550    punpckhdq\t%0, %0
551    unpckhps\t%0, %0
552    #"
553   [(set_attr "type" "mmxcvt,sselog1,*")
554    (set_attr "mode" "DI,V4SF,SI")])
555
556 (define_split
557   [(set (match_operand:SF 0 "register_operand" "")
558         (vec_select:SF
559           (match_operand:V2SF 1 "memory_operand" "")
560           (parallel [(const_int 1)])))]
561   "TARGET_MMX && reload_completed"
562   [(const_int 0)]
563 {
564   operands[1] = adjust_address (operands[1], SFmode, 4);
565   emit_move_insn (operands[0], operands[1]);
566   DONE;
567 })
568
569 (define_expand "vec_extractv2sf"
570   [(match_operand:SF 0 "register_operand" "")
571    (match_operand:V2SF 1 "register_operand" "")
572    (match_operand 2 "const_int_operand" "")]
573   "TARGET_MMX"
574 {
575   ix86_expand_vector_extract (false, operands[0], operands[1],
576                               INTVAL (operands[2]));
577   DONE;
578 })
579
580 (define_expand "vec_initv2sf"
581   [(match_operand:V2SF 0 "register_operand" "")
582    (match_operand 1 "" "")]
583   "TARGET_SSE"
584 {
585   ix86_expand_vector_init (false, operands[0], operands[1]);
586   DONE;
587 })
588
589 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
590 ;;
591 ;; Parallel integral arithmetic
592 ;;
593 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
594
595 (define_expand "mmx_<plusminus_insn><mode>3"
596   [(set (match_operand:MMXMODEI8 0 "register_operand" "")
597         (plusminus:MMXMODEI8
598           (match_operand:MMXMODEI8 1 "nonimmediate_operand" "")
599           (match_operand:MMXMODEI8 2 "nonimmediate_operand" "")))]
600   "TARGET_MMX || (TARGET_SSE2 && <MODE>mode == V1DImode)"
601   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
602
603 (define_insn "*mmx_<plusminus_insn><mode>3"
604   [(set (match_operand:MMXMODEI8 0 "register_operand" "=y")
605         (plusminus:MMXMODEI8
606           (match_operand:MMXMODEI8 1 "nonimmediate_operand" "<comm>0")
607           (match_operand:MMXMODEI8 2 "nonimmediate_operand" "ym")))]
608   "(TARGET_MMX || (TARGET_SSE2 && <MODE>mode == V1DImode))
609    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
610   "p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}"
611   [(set_attr "type" "mmxadd")
612    (set_attr "mode" "DI")])
613
614 (define_expand "mmx_<plusminus_insn><mode>3"
615   [(set (match_operand:MMXMODE12 0 "register_operand" "")
616         (sat_plusminus:MMXMODE12
617           (match_operand:MMXMODE12 1 "nonimmediate_operand" "")
618           (match_operand:MMXMODE12 2 "nonimmediate_operand" "")))]
619   "TARGET_MMX"
620   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
621
622 (define_insn "*mmx_<plusminus_insn><mode>3"
623   [(set (match_operand:MMXMODE12 0 "register_operand" "=y")
624         (sat_plusminus:MMXMODE12
625           (match_operand:MMXMODE12 1 "nonimmediate_operand" "<comm>0")
626           (match_operand:MMXMODE12 2 "nonimmediate_operand" "ym")))]
627   "TARGET_MMX && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
628   "p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}"
629   [(set_attr "type" "mmxadd")
630    (set_attr "mode" "DI")])
631
632 (define_expand "mmx_mulv4hi3"
633   [(set (match_operand:V4HI 0 "register_operand" "")
634         (mult:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "")
635                    (match_operand:V4HI 2 "nonimmediate_operand" "")))]
636   "TARGET_MMX"
637   "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
638
639 (define_insn "*mmx_mulv4hi3"
640   [(set (match_operand:V4HI 0 "register_operand" "=y")
641         (mult:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "%0")
642                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
643   "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
644   "pmullw\t{%2, %0|%0, %2}"
645   [(set_attr "type" "mmxmul")
646    (set_attr "mode" "DI")])
647
648 (define_expand "mmx_smulv4hi3_highpart"
649   [(set (match_operand:V4HI 0 "register_operand" "")
650         (truncate:V4HI
651           (lshiftrt:V4SI
652             (mult:V4SI
653               (sign_extend:V4SI
654                 (match_operand:V4HI 1 "nonimmediate_operand" ""))
655               (sign_extend:V4SI
656                 (match_operand:V4HI 2 "nonimmediate_operand" "")))
657             (const_int 16))))]
658   "TARGET_MMX"
659   "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
660
661 (define_insn "*mmx_smulv4hi3_highpart"
662   [(set (match_operand:V4HI 0 "register_operand" "=y")
663         (truncate:V4HI
664           (lshiftrt:V4SI
665             (mult:V4SI
666               (sign_extend:V4SI
667                 (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
668               (sign_extend:V4SI
669                 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
670             (const_int 16))))]
671   "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
672   "pmulhw\t{%2, %0|%0, %2}"
673   [(set_attr "type" "mmxmul")
674    (set_attr "mode" "DI")])
675
676 (define_expand "mmx_umulv4hi3_highpart"
677   [(set (match_operand:V4HI 0 "register_operand" "")
678         (truncate:V4HI
679           (lshiftrt:V4SI
680             (mult:V4SI
681               (zero_extend:V4SI
682                 (match_operand:V4HI 1 "nonimmediate_operand" ""))
683               (zero_extend:V4SI
684                 (match_operand:V4HI 2 "nonimmediate_operand" "")))
685             (const_int 16))))]
686   "TARGET_SSE || TARGET_3DNOW_A"
687   "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
688
689 (define_insn "*mmx_umulv4hi3_highpart"
690   [(set (match_operand:V4HI 0 "register_operand" "=y")
691         (truncate:V4HI
692           (lshiftrt:V4SI
693             (mult:V4SI
694               (zero_extend:V4SI
695                 (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
696               (zero_extend:V4SI
697                 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
698           (const_int 16))))]
699   "(TARGET_SSE || TARGET_3DNOW_A)
700    && ix86_binary_operator_ok (MULT, V4HImode, operands)"
701   "pmulhuw\t{%2, %0|%0, %2}"
702   [(set_attr "type" "mmxmul")
703    (set_attr "mode" "DI")])
704
705 (define_insn "mmx_pmaddwd"
706   [(set (match_operand:V2SI 0 "register_operand" "=y")
707         (plus:V2SI
708           (mult:V2SI
709             (sign_extend:V2SI
710               (vec_select:V2HI
711                 (match_operand:V4HI 1 "nonimmediate_operand" "%0")
712                 (parallel [(const_int 0) (const_int 2)])))
713             (sign_extend:V2SI
714               (vec_select:V2HI
715                 (match_operand:V4HI 2 "nonimmediate_operand" "ym")
716                 (parallel [(const_int 0) (const_int 2)]))))
717           (mult:V2SI
718             (sign_extend:V2SI
719               (vec_select:V2HI (match_dup 1)
720                 (parallel [(const_int 1) (const_int 3)])))
721             (sign_extend:V2SI
722               (vec_select:V2HI (match_dup 2)
723                 (parallel [(const_int 1) (const_int 3)]))))))]
724   "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
725   "pmaddwd\t{%2, %0|%0, %2}"
726   [(set_attr "type" "mmxmul")
727    (set_attr "mode" "DI")])
728
729 (define_insn "mmx_pmulhrwv4hi3"
730   [(set (match_operand:V4HI 0 "register_operand" "=y")
731         (truncate:V4HI
732           (lshiftrt:V4SI
733             (plus:V4SI
734               (mult:V4SI
735                 (sign_extend:V4SI
736                   (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
737                 (sign_extend:V4SI
738                   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
739               (const_vector:V4SI [(const_int 32768) (const_int 32768)
740                                   (const_int 32768) (const_int 32768)]))
741             (const_int 16))))]
742   "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V4HImode, operands)"
743   "pmulhrw\t{%2, %0|%0, %2}"
744   [(set_attr "type" "mmxmul")
745    (set_attr "mode" "DI")])
746
747 (define_insn "sse2_umulv1siv1di3"
748   [(set (match_operand:V1DI 0 "register_operand" "=y")
749         (mult:V1DI
750           (zero_extend:V1DI
751             (vec_select:V1SI
752               (match_operand:V2SI 1 "nonimmediate_operand" "%0")
753               (parallel [(const_int 0)])))
754           (zero_extend:V1DI
755             (vec_select:V1SI
756               (match_operand:V2SI 2 "nonimmediate_operand" "ym")
757               (parallel [(const_int 0)])))))]
758   "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V2SImode, operands)"
759   "pmuludq\t{%2, %0|%0, %2}"
760   [(set_attr "type" "mmxmul")
761    (set_attr "mode" "DI")])
762
763 (define_expand "mmx_<code>v4hi3"
764   [(set (match_operand:V4HI 0 "register_operand" "")
765         (smaxmin:V4HI
766           (match_operand:V4HI 1 "nonimmediate_operand" "")
767           (match_operand:V4HI 2 "nonimmediate_operand" "")))]
768   "TARGET_SSE || TARGET_3DNOW_A"
769   "ix86_fixup_binary_operands_no_copy (<CODE>, V4HImode, operands);")
770
771 (define_insn "*mmx_<code>v4hi3"
772   [(set (match_operand:V4HI 0 "register_operand" "=y")
773         (smaxmin:V4HI
774           (match_operand:V4HI 1 "nonimmediate_operand" "%0")
775           (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
776   "(TARGET_SSE || TARGET_3DNOW_A)
777    && ix86_binary_operator_ok (<CODE>, V4HImode, operands)"
778   "p<maxminiprefix>w\t{%2, %0|%0, %2}"
779   [(set_attr "type" "mmxadd")
780    (set_attr "mode" "DI")])
781
782 (define_expand "mmx_<code>v8qi3"
783   [(set (match_operand:V8QI 0 "register_operand" "")
784         (umaxmin:V8QI
785           (match_operand:V8QI 1 "nonimmediate_operand" "")
786           (match_operand:V8QI 2 "nonimmediate_operand" "")))]
787   "TARGET_SSE || TARGET_3DNOW_A"
788   "ix86_fixup_binary_operands_no_copy (<CODE>, V8QImode, operands);")
789
790 (define_insn "*mmx_<code>v8qi3"
791   [(set (match_operand:V8QI 0 "register_operand" "=y")
792         (umaxmin:V8QI
793           (match_operand:V8QI 1 "nonimmediate_operand" "%0")
794           (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
795   "(TARGET_SSE || TARGET_3DNOW_A)
796    && ix86_binary_operator_ok (<CODE>, V8QImode, operands)"
797   "p<maxminiprefix>b\t{%2, %0|%0, %2}"
798   [(set_attr "type" "mmxadd")
799    (set_attr "mode" "DI")])
800
801 (define_insn "mmx_ashr<mode>3"
802   [(set (match_operand:MMXMODE24 0 "register_operand" "=y")
803         (ashiftrt:MMXMODE24
804           (match_operand:MMXMODE24 1 "register_operand" "0")
805           (match_operand:SI 2 "nonmemory_operand" "yN")))]
806   "TARGET_MMX"
807   "psra<mmxvecsize>\t{%2, %0|%0, %2}"
808   [(set_attr "type" "mmxshft")
809    (set_attr "mode" "DI")])
810
811 (define_insn "mmx_lshr<mode>3"
812   [(set (match_operand:MMXMODE248 0 "register_operand" "=y")
813         (lshiftrt:MMXMODE248
814           (match_operand:MMXMODE248 1 "register_operand" "0")
815           (match_operand:SI 2 "nonmemory_operand" "yN")))]
816   "TARGET_MMX"
817   "psrl<mmxvecsize>\t{%2, %0|%0, %2}"
818   [(set_attr "type" "mmxshft")
819    (set_attr "mode" "DI")])
820
821 (define_insn "mmx_ashl<mode>3"
822   [(set (match_operand:MMXMODE248 0 "register_operand" "=y")
823         (ashift:MMXMODE248
824           (match_operand:MMXMODE248 1 "register_operand" "0")
825           (match_operand:SI 2 "nonmemory_operand" "yN")))]
826   "TARGET_MMX"
827   "psll<mmxvecsize>\t{%2, %0|%0, %2}"
828   [(set_attr "type" "mmxshft")
829    (set_attr "mode" "DI")])
830
831 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
832 ;;
833 ;; Parallel integral comparisons
834 ;;
835 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
836
837 (define_insn "mmx_eq<mode>3"
838   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
839         (eq:MMXMODEI
840           (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
841           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
842   "TARGET_MMX && ix86_binary_operator_ok (EQ, <MODE>mode, operands)"
843   "pcmpeq<mmxvecsize>\t{%2, %0|%0, %2}"
844   [(set_attr "type" "mmxcmp")
845    (set_attr "mode" "DI")])
846
847 (define_insn "mmx_gt<mode>3"
848   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
849         (gt:MMXMODEI
850           (match_operand:MMXMODEI 1 "register_operand" "0")
851           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
852   "TARGET_MMX"
853   "pcmpgt<mmxvecsize>\t{%2, %0|%0, %2}"
854   [(set_attr "type" "mmxcmp")
855    (set_attr "mode" "DI")])
856
857 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
858 ;;
859 ;; Parallel integral logical operations
860 ;;
861 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
862
863 (define_insn "mmx_nand<mode>3"
864   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
865         (and:MMXMODEI
866           (not:MMXMODEI (match_operand:MMXMODEI 1 "register_operand" "0"))
867           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
868   "TARGET_MMX"
869   "pandn\t{%2, %0|%0, %2}"
870   [(set_attr "type" "mmxadd")
871    (set_attr "mode" "DI")])
872
873 (define_expand "mmx_<code><mode>3"
874   [(set (match_operand:MMXMODEI 0 "register_operand" "")
875         (plogic:MMXMODEI
876           (match_operand:MMXMODEI 1 "nonimmediate_operand" "")
877           (match_operand:MMXMODEI 2 "nonimmediate_operand" "")))]
878   "TARGET_MMX"
879   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
880
881 (define_insn "*mmx_<code><mode>3"
882   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
883         (plogic:MMXMODEI
884           (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
885           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
886   "TARGET_MMX && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
887   "p<plogicprefix>\t{%2, %0|%0, %2}"
888   [(set_attr "type" "mmxadd")
889    (set_attr "mode" "DI")])
890
891 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
892 ;;
893 ;; Parallel integral element swizzling
894 ;;
895 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
896
897 (define_insn "mmx_packsswb"
898   [(set (match_operand:V8QI 0 "register_operand" "=y")
899         (vec_concat:V8QI
900           (ss_truncate:V4QI
901             (match_operand:V4HI 1 "register_operand" "0"))
902           (ss_truncate:V4QI
903             (match_operand:V4HI 2 "nonimmediate_operand" "ym"))))]
904   "TARGET_MMX"
905   "packsswb\t{%2, %0|%0, %2}"
906   [(set_attr "type" "mmxshft")
907    (set_attr "mode" "DI")])
908
909 (define_insn "mmx_packssdw"
910   [(set (match_operand:V4HI 0 "register_operand" "=y")
911         (vec_concat:V4HI
912           (ss_truncate:V2HI
913             (match_operand:V2SI 1 "register_operand" "0"))
914           (ss_truncate:V2HI
915             (match_operand:V2SI 2 "nonimmediate_operand" "ym"))))]
916   "TARGET_MMX"
917   "packssdw\t{%2, %0|%0, %2}"
918   [(set_attr "type" "mmxshft")
919    (set_attr "mode" "DI")])
920
921 (define_insn "mmx_packuswb"
922   [(set (match_operand:V8QI 0 "register_operand" "=y")
923         (vec_concat:V8QI
924           (us_truncate:V4QI
925             (match_operand:V4HI 1 "register_operand" "0"))
926           (us_truncate:V4QI
927             (match_operand:V4HI 2 "nonimmediate_operand" "ym"))))]
928   "TARGET_MMX"
929   "packuswb\t{%2, %0|%0, %2}"
930   [(set_attr "type" "mmxshft")
931    (set_attr "mode" "DI")])
932
933 (define_insn "mmx_punpckhbw"
934   [(set (match_operand:V8QI 0 "register_operand" "=y")
935         (vec_select:V8QI
936           (vec_concat:V16QI
937             (match_operand:V8QI 1 "register_operand" "0")
938             (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
939           (parallel [(const_int 4) (const_int 12)
940                      (const_int 5) (const_int 13)
941                      (const_int 6) (const_int 14)
942                      (const_int 7) (const_int 15)])))]
943   "TARGET_MMX"
944   "punpckhbw\t{%2, %0|%0, %2}"
945   [(set_attr "type" "mmxcvt")
946    (set_attr "mode" "DI")])
947
948 (define_insn "mmx_punpcklbw"
949   [(set (match_operand:V8QI 0 "register_operand" "=y")
950         (vec_select:V8QI
951           (vec_concat:V16QI
952             (match_operand:V8QI 1 "register_operand" "0")
953             (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
954           (parallel [(const_int 0) (const_int 8)
955                      (const_int 1) (const_int 9)
956                      (const_int 2) (const_int 10)
957                      (const_int 3) (const_int 11)])))]
958   "TARGET_MMX"
959   "punpcklbw\t{%2, %0|%0, %2}"
960   [(set_attr "type" "mmxcvt")
961    (set_attr "mode" "DI")])
962
963 (define_insn "mmx_punpckhwd"
964   [(set (match_operand:V4HI 0 "register_operand" "=y")
965         (vec_select:V4HI
966           (vec_concat:V8HI
967             (match_operand:V4HI 1 "register_operand" "0")
968             (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
969           (parallel [(const_int 2) (const_int 6)
970                      (const_int 3) (const_int 7)])))]
971   "TARGET_MMX"
972   "punpckhwd\t{%2, %0|%0, %2}"
973   [(set_attr "type" "mmxcvt")
974    (set_attr "mode" "DI")])
975
976 (define_insn "mmx_punpcklwd"
977   [(set (match_operand:V4HI 0 "register_operand" "=y")
978         (vec_select:V4HI
979           (vec_concat:V8HI
980             (match_operand:V4HI 1 "register_operand" "0")
981             (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
982           (parallel [(const_int 0) (const_int 4)
983                      (const_int 1) (const_int 5)])))]
984   "TARGET_MMX"
985   "punpcklwd\t{%2, %0|%0, %2}"
986   [(set_attr "type" "mmxcvt")
987    (set_attr "mode" "DI")])
988
989 (define_insn "mmx_punpckhdq"
990   [(set (match_operand:V2SI 0 "register_operand" "=y")
991         (vec_select:V2SI
992           (vec_concat:V4SI
993             (match_operand:V2SI 1 "register_operand" "0")
994             (match_operand:V2SI 2 "nonimmediate_operand" "ym"))
995           (parallel [(const_int 1)
996                      (const_int 3)])))]
997   "TARGET_MMX"
998   "punpckhdq\t{%2, %0|%0, %2}"
999   [(set_attr "type" "mmxcvt")
1000    (set_attr "mode" "DI")])
1001
1002 (define_insn "mmx_punpckldq"
1003   [(set (match_operand:V2SI 0 "register_operand" "=y")
1004         (vec_select:V2SI
1005           (vec_concat:V4SI
1006             (match_operand:V2SI 1 "register_operand" "0")
1007             (match_operand:V2SI 2 "nonimmediate_operand" "ym"))
1008           (parallel [(const_int 0)
1009                      (const_int 2)])))]
1010   "TARGET_MMX"
1011   "punpckldq\t{%2, %0|%0, %2}"
1012   [(set_attr "type" "mmxcvt")
1013    (set_attr "mode" "DI")])
1014
1015 (define_expand "mmx_pinsrw"
1016   [(set (match_operand:V4HI 0 "register_operand" "")
1017         (vec_merge:V4HI
1018           (vec_duplicate:V4HI
1019             (match_operand:SI 2 "nonimmediate_operand" ""))
1020           (match_operand:V4HI 1 "register_operand" "")
1021           (match_operand:SI 3 "const_0_to_3_operand" "")))]
1022   "TARGET_SSE || TARGET_3DNOW_A"
1023 {
1024   operands[2] = gen_lowpart (HImode, operands[2]);
1025   operands[3] = GEN_INT (1 << INTVAL (operands[3]));
1026 })
1027
1028 (define_insn "*mmx_pinsrw"
1029   [(set (match_operand:V4HI 0 "register_operand" "=y")
1030         (vec_merge:V4HI
1031           (vec_duplicate:V4HI
1032             (match_operand:HI 2 "nonimmediate_operand" "rm"))
1033           (match_operand:V4HI 1 "register_operand" "0")
1034           (match_operand:SI 3 "const_pow2_1_to_8_operand" "n")))]
1035   "TARGET_SSE || TARGET_3DNOW_A"
1036 {
1037   operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
1038   return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}";
1039 }
1040   [(set_attr "type" "mmxcvt")
1041    (set_attr "mode" "DI")])
1042
1043 (define_insn "mmx_pextrw"
1044   [(set (match_operand:SI 0 "register_operand" "=r")
1045         (zero_extend:SI
1046           (vec_select:HI
1047             (match_operand:V4HI 1 "register_operand" "y")
1048             (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n")]))))]
1049   "TARGET_SSE || TARGET_3DNOW_A"
1050   "pextrw\t{%2, %1, %0|%0, %1, %2}"
1051   [(set_attr "type" "mmxcvt")
1052    (set_attr "mode" "DI")])
1053
1054 (define_expand "mmx_pshufw"
1055   [(match_operand:V4HI 0 "register_operand" "")
1056    (match_operand:V4HI 1 "nonimmediate_operand" "")
1057    (match_operand:SI 2 "const_int_operand" "")]
1058   "TARGET_SSE || TARGET_3DNOW_A"
1059 {
1060   int mask = INTVAL (operands[2]);
1061   emit_insn (gen_mmx_pshufw_1 (operands[0], operands[1],
1062                                GEN_INT ((mask >> 0) & 3),
1063                                GEN_INT ((mask >> 2) & 3),
1064                                GEN_INT ((mask >> 4) & 3),
1065                                GEN_INT ((mask >> 6) & 3)));
1066   DONE;
1067 })
1068
1069 (define_insn "mmx_pshufw_1"
1070   [(set (match_operand:V4HI 0 "register_operand" "=y")
1071         (vec_select:V4HI
1072           (match_operand:V4HI 1 "nonimmediate_operand" "ym")
1073           (parallel [(match_operand 2 "const_0_to_3_operand" "")
1074                      (match_operand 3 "const_0_to_3_operand" "")
1075                      (match_operand 4 "const_0_to_3_operand" "")
1076                      (match_operand 5 "const_0_to_3_operand" "")])))]
1077   "TARGET_SSE || TARGET_3DNOW_A"
1078 {
1079   int mask = 0;
1080   mask |= INTVAL (operands[2]) << 0;
1081   mask |= INTVAL (operands[3]) << 2;
1082   mask |= INTVAL (operands[4]) << 4;
1083   mask |= INTVAL (operands[5]) << 6;
1084   operands[2] = GEN_INT (mask);
1085
1086   return "pshufw\t{%2, %1, %0|%0, %1, %2}";
1087 }
1088   [(set_attr "type" "mmxcvt")
1089    (set_attr "mode" "DI")])
1090
1091 (define_insn "mmx_pswapdv2si2"
1092   [(set (match_operand:V2SI 0 "register_operand" "=y")
1093         (vec_select:V2SI
1094           (match_operand:V2SI 1 "nonimmediate_operand" "ym")
1095           (parallel [(const_int 1) (const_int 0)])))]
1096   "TARGET_3DNOW_A"
1097   "pswapd\t{%1, %0|%0, %1}"
1098   [(set_attr "type" "mmxcvt")
1099    (set_attr "mode" "DI")])
1100
1101 (define_insn "*vec_dupv4hi"
1102   [(set (match_operand:V4HI 0 "register_operand" "=y")
1103         (vec_duplicate:V4HI
1104           (truncate:HI
1105             (match_operand:SI 1 "register_operand" "0"))))]
1106   "TARGET_SSE || TARGET_3DNOW_A"
1107   "pshufw\t{$0, %0, %0|%0, %0, 0}"
1108   [(set_attr "type" "mmxcvt")
1109    (set_attr "mode" "DI")])
1110
1111 (define_insn "*vec_dupv2si"
1112   [(set (match_operand:V2SI 0 "register_operand" "=y")
1113         (vec_duplicate:V2SI
1114           (match_operand:SI 1 "register_operand" "0")))]
1115   "TARGET_MMX"
1116   "punpckldq\t%0, %0"
1117   [(set_attr "type" "mmxcvt")
1118    (set_attr "mode" "DI")])
1119
1120 (define_insn "*mmx_concatv2si"
1121   [(set (match_operand:V2SI 0 "register_operand"     "=y,y")
1122         (vec_concat:V2SI
1123           (match_operand:SI 1 "nonimmediate_operand" " 0,rm")
1124           (match_operand:SI 2 "vector_move_operand"  "ym,C")))]
1125   "TARGET_MMX && !TARGET_SSE"
1126   "@
1127    punpckldq\t{%2, %0|%0, %2}
1128    movd\t{%1, %0|%0, %1}"
1129   [(set_attr "type" "mmxcvt,mmxmov")
1130    (set_attr "mode" "DI")])
1131
1132 (define_expand "vec_setv2si"
1133   [(match_operand:V2SI 0 "register_operand" "")
1134    (match_operand:SI 1 "register_operand" "")
1135    (match_operand 2 "const_int_operand" "")]
1136   "TARGET_MMX"
1137 {
1138   ix86_expand_vector_set (false, operands[0], operands[1],
1139                           INTVAL (operands[2]));
1140   DONE;
1141 })
1142
1143 (define_insn_and_split "*vec_extractv2si_0"
1144   [(set (match_operand:SI 0 "nonimmediate_operand"     "=x,y,m,m,frxy")
1145         (vec_select:SI
1146           (match_operand:V2SI 1 "nonimmediate_operand" " x,y,x,y,m")
1147           (parallel [(const_int 0)])))]
1148   "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1149   "#"
1150   "&& reload_completed"
1151   [(const_int 0)]
1152 {
1153   rtx op1 = operands[1];
1154   if (REG_P (op1))
1155     op1 = gen_rtx_REG (SImode, REGNO (op1));
1156   else
1157     op1 = gen_lowpart (SImode, op1);
1158   emit_move_insn (operands[0], op1);
1159   DONE;
1160 })
1161
1162 (define_insn "*vec_extractv2si_1"
1163   [(set (match_operand:SI 0 "nonimmediate_operand"     "=y,Y2,Y2,x,frxy")
1164         (vec_select:SI
1165           (match_operand:V2SI 1 "nonimmediate_operand" " 0,0 ,Y2,0,o")
1166           (parallel [(const_int 1)])))]
1167   "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1168   "@
1169    punpckhdq\t%0, %0
1170    punpckhdq\t%0, %0
1171    pshufd\t{$85, %1, %0|%0, %1, 85}
1172    unpckhps\t%0, %0
1173    #"
1174   [(set_attr "type" "mmxcvt,sselog1,sselog1,sselog1,*")
1175    (set_attr "mode" "DI,TI,TI,V4SF,SI")])
1176
1177 (define_split
1178   [(set (match_operand:SI 0 "register_operand" "")
1179         (vec_select:SI
1180           (match_operand:V2SI 1 "memory_operand" "")
1181           (parallel [(const_int 1)])))]
1182   "TARGET_MMX && reload_completed"
1183   [(const_int 0)]
1184 {
1185   operands[1] = adjust_address (operands[1], SImode, 4);
1186   emit_move_insn (operands[0], operands[1]);
1187   DONE;
1188 })
1189
1190 (define_expand "vec_extractv2si"
1191   [(match_operand:SI 0 "register_operand" "")
1192    (match_operand:V2SI 1 "register_operand" "")
1193    (match_operand 2 "const_int_operand" "")]
1194   "TARGET_MMX"
1195 {
1196   ix86_expand_vector_extract (false, operands[0], operands[1],
1197                               INTVAL (operands[2]));
1198   DONE;
1199 })
1200
1201 (define_expand "vec_initv2si"
1202   [(match_operand:V2SI 0 "register_operand" "")
1203    (match_operand 1 "" "")]
1204   "TARGET_SSE"
1205 {
1206   ix86_expand_vector_init (false, operands[0], operands[1]);
1207   DONE;
1208 })
1209
1210 (define_expand "vec_setv4hi"
1211   [(match_operand:V4HI 0 "register_operand" "")
1212    (match_operand:HI 1 "register_operand" "")
1213    (match_operand 2 "const_int_operand" "")]
1214   "TARGET_MMX"
1215 {
1216   ix86_expand_vector_set (false, operands[0], operands[1],
1217                           INTVAL (operands[2]));
1218   DONE;
1219 })
1220
1221 (define_expand "vec_extractv4hi"
1222   [(match_operand:HI 0 "register_operand" "")
1223    (match_operand:V4HI 1 "register_operand" "")
1224    (match_operand 2 "const_int_operand" "")]
1225   "TARGET_MMX"
1226 {
1227   ix86_expand_vector_extract (false, operands[0], operands[1],
1228                               INTVAL (operands[2]));
1229   DONE;
1230 })
1231
1232 (define_expand "vec_initv4hi"
1233   [(match_operand:V4HI 0 "register_operand" "")
1234    (match_operand 1 "" "")]
1235   "TARGET_SSE"
1236 {
1237   ix86_expand_vector_init (false, operands[0], operands[1]);
1238   DONE;
1239 })
1240
1241 (define_expand "vec_setv8qi"
1242   [(match_operand:V8QI 0 "register_operand" "")
1243    (match_operand:QI 1 "register_operand" "")
1244    (match_operand 2 "const_int_operand" "")]
1245   "TARGET_MMX"
1246 {
1247   ix86_expand_vector_set (false, operands[0], operands[1],
1248                           INTVAL (operands[2]));
1249   DONE;
1250 })
1251
1252 (define_expand "vec_extractv8qi"
1253   [(match_operand:QI 0 "register_operand" "")
1254    (match_operand:V8QI 1 "register_operand" "")
1255    (match_operand 2 "const_int_operand" "")]
1256   "TARGET_MMX"
1257 {
1258   ix86_expand_vector_extract (false, operands[0], operands[1],
1259                               INTVAL (operands[2]));
1260   DONE;
1261 })
1262
1263 (define_expand "vec_initv8qi"
1264   [(match_operand:V8QI 0 "register_operand" "")
1265    (match_operand 1 "" "")]
1266   "TARGET_SSE"
1267 {
1268   ix86_expand_vector_init (false, operands[0], operands[1]);
1269   DONE;
1270 })
1271
1272 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1273 ;;
1274 ;; Miscellaneous
1275 ;;
1276 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1277
1278 (define_insn "mmx_uavgv8qi3"
1279   [(set (match_operand:V8QI 0 "register_operand" "=y")
1280         (truncate:V8QI
1281           (lshiftrt:V8HI
1282             (plus:V8HI
1283               (plus:V8HI
1284                 (zero_extend:V8HI
1285                   (match_operand:V8QI 1 "nonimmediate_operand" "%0"))
1286                 (zero_extend:V8HI
1287                   (match_operand:V8QI 2 "nonimmediate_operand" "ym")))
1288               (const_vector:V8HI [(const_int 1) (const_int 1)
1289                                   (const_int 1) (const_int 1)
1290                                   (const_int 1) (const_int 1)
1291                                   (const_int 1) (const_int 1)]))
1292             (const_int 1))))]
1293   "(TARGET_SSE || TARGET_3DNOW)
1294    && ix86_binary_operator_ok (PLUS, V8QImode, operands)"
1295 {
1296   /* These two instructions have the same operation, but their encoding
1297      is different.  Prefer the one that is de facto standard.  */
1298   if (TARGET_SSE || TARGET_3DNOW_A)
1299     return "pavgb\t{%2, %0|%0, %2}";
1300   else
1301     return "pavgusb\t{%2, %0|%0, %2}";
1302 }
1303   [(set_attr "type" "mmxshft")
1304    (set_attr "mode" "DI")])
1305
1306 (define_insn "mmx_uavgv4hi3"
1307   [(set (match_operand:V4HI 0 "register_operand" "=y")
1308         (truncate:V4HI
1309           (lshiftrt:V4SI
1310             (plus:V4SI
1311               (plus:V4SI
1312                 (zero_extend:V4SI
1313                   (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
1314                 (zero_extend:V4SI
1315                   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
1316               (const_vector:V4SI [(const_int 1) (const_int 1)
1317                                   (const_int 1) (const_int 1)]))
1318             (const_int 1))))]
1319   "(TARGET_SSE || TARGET_3DNOW_A)
1320    && ix86_binary_operator_ok (PLUS, V4HImode, operands)"
1321   "pavgw\t{%2, %0|%0, %2}"
1322   [(set_attr "type" "mmxshft")
1323    (set_attr "mode" "DI")])
1324
1325 (define_insn "mmx_psadbw"
1326   [(set (match_operand:V1DI 0 "register_operand" "=y")
1327         (unspec:V1DI [(match_operand:V8QI 1 "register_operand" "0")
1328                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
1329                      UNSPEC_PSADBW))]
1330   "TARGET_SSE || TARGET_3DNOW_A"
1331   "psadbw\t{%2, %0|%0, %2}"
1332   [(set_attr "type" "mmxshft")
1333    (set_attr "mode" "DI")])
1334
1335 (define_insn "mmx_pmovmskb"
1336   [(set (match_operand:SI 0 "register_operand" "=r")
1337         (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
1338                    UNSPEC_MOVMSK))]
1339   "TARGET_SSE || TARGET_3DNOW_A"
1340   "pmovmskb\t{%1, %0|%0, %1}"
1341   [(set_attr "type" "mmxcvt")
1342    (set_attr "mode" "DI")])
1343
1344 (define_expand "mmx_maskmovq"
1345   [(set (match_operand:V8QI 0 "memory_operand" "")
1346         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "")
1347                       (match_operand:V8QI 2 "register_operand" "")
1348                       (match_dup 0)]
1349                      UNSPEC_MASKMOV))]
1350   "TARGET_SSE || TARGET_3DNOW_A"
1351   "")
1352
1353 (define_insn "*mmx_maskmovq"
1354   [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
1355         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
1356                       (match_operand:V8QI 2 "register_operand" "y")
1357                       (mem:V8QI (match_dup 0))]
1358                      UNSPEC_MASKMOV))]
1359   "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
1360   ;; @@@ check ordering of operands in intel/nonintel syntax
1361   "maskmovq\t{%2, %1|%1, %2}"
1362   [(set_attr "type" "mmxcvt")
1363    (set_attr "mode" "DI")])
1364
1365 (define_insn "*mmx_maskmovq_rex"
1366   [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
1367         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
1368                       (match_operand:V8QI 2 "register_operand" "y")
1369                       (mem:V8QI (match_dup 0))]
1370                      UNSPEC_MASKMOV))]
1371   "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
1372   ;; @@@ check ordering of operands in intel/nonintel syntax
1373   "maskmovq\t{%2, %1|%1, %2}"
1374   [(set_attr "type" "mmxcvt")
1375    (set_attr "mode" "DI")])
1376
1377 (define_insn "mmx_emms"
1378   [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
1379    (clobber (reg:XF 8))
1380    (clobber (reg:XF 9))
1381    (clobber (reg:XF 10))
1382    (clobber (reg:XF 11))
1383    (clobber (reg:XF 12))
1384    (clobber (reg:XF 13))
1385    (clobber (reg:XF 14))
1386    (clobber (reg:XF 15))
1387    (clobber (reg:DI 29))
1388    (clobber (reg:DI 30))
1389    (clobber (reg:DI 31))
1390    (clobber (reg:DI 32))
1391    (clobber (reg:DI 33))
1392    (clobber (reg:DI 34))
1393    (clobber (reg:DI 35))
1394    (clobber (reg:DI 36))]
1395   "TARGET_MMX"
1396   "emms"
1397   [(set_attr "type" "mmx")
1398    (set_attr "memory" "unknown")])
1399
1400 (define_insn "mmx_femms"
1401   [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
1402    (clobber (reg:XF 8))
1403    (clobber (reg:XF 9))
1404    (clobber (reg:XF 10))
1405    (clobber (reg:XF 11))
1406    (clobber (reg:XF 12))
1407    (clobber (reg:XF 13))
1408    (clobber (reg:XF 14))
1409    (clobber (reg:XF 15))
1410    (clobber (reg:DI 29))
1411    (clobber (reg:DI 30))
1412    (clobber (reg:DI 31))
1413    (clobber (reg:DI 32))
1414    (clobber (reg:DI 33))
1415    (clobber (reg:DI 34))
1416    (clobber (reg:DI 35))
1417    (clobber (reg:DI 36))]
1418   "TARGET_3DNOW"
1419   "femms"
1420   [(set_attr "type" "mmx")
1421    (set_attr "memory" "none")])