OSDN Git Service

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