OSDN Git Service

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