OSDN Git Service

PR tree-optimization/36118
[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_nand<mode>3"
795   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
796         (and:MMXMODEI
797           (not:MMXMODEI (match_operand:MMXMODEI 1 "register_operand" "0"))
798           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
799   "TARGET_MMX"
800   "pandn\t{%2, %0|%0, %2}"
801   [(set_attr "type" "mmxadd")
802    (set_attr "mode" "DI")])
803
804 (define_insn "mmx_<code><mode>3"
805   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
806         (plogic:MMXMODEI
807           (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
808           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
809   "TARGET_MMX && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
810   "p<plogicprefix>\t{%2, %0|%0, %2}"
811   [(set_attr "type" "mmxadd")
812    (set_attr "mode" "DI")])
813
814 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
815 ;;
816 ;; Parallel integral element swizzling
817 ;;
818 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
819
820 (define_insn "mmx_packsswb"
821   [(set (match_operand:V8QI 0 "register_operand" "=y")
822         (vec_concat:V8QI
823           (ss_truncate:V4QI
824             (match_operand:V4HI 1 "register_operand" "0"))
825           (ss_truncate:V4QI
826             (match_operand:V4HI 2 "nonimmediate_operand" "ym"))))]
827   "TARGET_MMX"
828   "packsswb\t{%2, %0|%0, %2}"
829   [(set_attr "type" "mmxshft")
830    (set_attr "mode" "DI")])
831
832 (define_insn "mmx_packssdw"
833   [(set (match_operand:V4HI 0 "register_operand" "=y")
834         (vec_concat:V4HI
835           (ss_truncate:V2HI
836             (match_operand:V2SI 1 "register_operand" "0"))
837           (ss_truncate:V2HI
838             (match_operand:V2SI 2 "nonimmediate_operand" "ym"))))]
839   "TARGET_MMX"
840   "packssdw\t{%2, %0|%0, %2}"
841   [(set_attr "type" "mmxshft")
842    (set_attr "mode" "DI")])
843
844 (define_insn "mmx_packuswb"
845   [(set (match_operand:V8QI 0 "register_operand" "=y")
846         (vec_concat:V8QI
847           (us_truncate:V4QI
848             (match_operand:V4HI 1 "register_operand" "0"))
849           (us_truncate:V4QI
850             (match_operand:V4HI 2 "nonimmediate_operand" "ym"))))]
851   "TARGET_MMX"
852   "packuswb\t{%2, %0|%0, %2}"
853   [(set_attr "type" "mmxshft")
854    (set_attr "mode" "DI")])
855
856 (define_insn "mmx_punpckhbw"
857   [(set (match_operand:V8QI 0 "register_operand" "=y")
858         (vec_select:V8QI
859           (vec_concat:V16QI
860             (match_operand:V8QI 1 "register_operand" "0")
861             (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
862           (parallel [(const_int 4) (const_int 12)
863                      (const_int 5) (const_int 13)
864                      (const_int 6) (const_int 14)
865                      (const_int 7) (const_int 15)])))]
866   "TARGET_MMX"
867   "punpckhbw\t{%2, %0|%0, %2}"
868   [(set_attr "type" "mmxcvt")
869    (set_attr "mode" "DI")])
870
871 (define_insn "mmx_punpcklbw"
872   [(set (match_operand:V8QI 0 "register_operand" "=y")
873         (vec_select:V8QI
874           (vec_concat:V16QI
875             (match_operand:V8QI 1 "register_operand" "0")
876             (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
877           (parallel [(const_int 0) (const_int 8)
878                      (const_int 1) (const_int 9)
879                      (const_int 2) (const_int 10)
880                      (const_int 3) (const_int 11)])))]
881   "TARGET_MMX"
882   "punpcklbw\t{%2, %0|%0, %2}"
883   [(set_attr "type" "mmxcvt")
884    (set_attr "mode" "DI")])
885
886 (define_insn "mmx_punpckhwd"
887   [(set (match_operand:V4HI 0 "register_operand" "=y")
888         (vec_select:V4HI
889           (vec_concat:V8HI
890             (match_operand:V4HI 1 "register_operand" "0")
891             (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
892           (parallel [(const_int 2) (const_int 6)
893                      (const_int 3) (const_int 7)])))]
894   "TARGET_MMX"
895   "punpckhwd\t{%2, %0|%0, %2}"
896   [(set_attr "type" "mmxcvt")
897    (set_attr "mode" "DI")])
898
899 (define_insn "mmx_punpcklwd"
900   [(set (match_operand:V4HI 0 "register_operand" "=y")
901         (vec_select:V4HI
902           (vec_concat:V8HI
903             (match_operand:V4HI 1 "register_operand" "0")
904             (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
905           (parallel [(const_int 0) (const_int 4)
906                      (const_int 1) (const_int 5)])))]
907   "TARGET_MMX"
908   "punpcklwd\t{%2, %0|%0, %2}"
909   [(set_attr "type" "mmxcvt")
910    (set_attr "mode" "DI")])
911
912 (define_insn "mmx_punpckhdq"
913   [(set (match_operand:V2SI 0 "register_operand" "=y")
914         (vec_select:V2SI
915           (vec_concat:V4SI
916             (match_operand:V2SI 1 "register_operand" "0")
917             (match_operand:V2SI 2 "nonimmediate_operand" "ym"))
918           (parallel [(const_int 1)
919                      (const_int 3)])))]
920   "TARGET_MMX"
921   "punpckhdq\t{%2, %0|%0, %2}"
922   [(set_attr "type" "mmxcvt")
923    (set_attr "mode" "DI")])
924
925 (define_insn "mmx_punpckldq"
926   [(set (match_operand:V2SI 0 "register_operand" "=y")
927         (vec_select:V2SI
928           (vec_concat:V4SI
929             (match_operand:V2SI 1 "register_operand" "0")
930             (match_operand:V2SI 2 "nonimmediate_operand" "ym"))
931           (parallel [(const_int 0)
932                      (const_int 2)])))]
933   "TARGET_MMX"
934   "punpckldq\t{%2, %0|%0, %2}"
935   [(set_attr "type" "mmxcvt")
936    (set_attr "mode" "DI")])
937
938 (define_expand "mmx_pinsrw"
939   [(set (match_operand:V4HI 0 "register_operand" "")
940         (vec_merge:V4HI
941           (vec_duplicate:V4HI
942             (match_operand:SI 2 "nonimmediate_operand" ""))
943           (match_operand:V4HI 1 "register_operand" "")
944           (match_operand:SI 3 "const_0_to_3_operand" "")))]
945   "TARGET_SSE || TARGET_3DNOW_A"
946 {
947   operands[2] = gen_lowpart (HImode, operands[2]);
948   operands[3] = GEN_INT (1 << INTVAL (operands[3]));
949 })
950
951 (define_insn "*mmx_pinsrw"
952   [(set (match_operand:V4HI 0 "register_operand" "=y")
953         (vec_merge:V4HI
954           (vec_duplicate:V4HI
955             (match_operand:HI 2 "nonimmediate_operand" "rm"))
956           (match_operand:V4HI 1 "register_operand" "0")
957           (match_operand:SI 3 "const_pow2_1_to_8_operand" "n")))]
958   "TARGET_SSE || TARGET_3DNOW_A"
959 {
960   operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
961   return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}";
962 }
963   [(set_attr "type" "mmxcvt")
964    (set_attr "mode" "DI")])
965
966 (define_insn "mmx_pextrw"
967   [(set (match_operand:SI 0 "register_operand" "=r")
968         (zero_extend:SI
969           (vec_select:HI
970             (match_operand:V4HI 1 "register_operand" "y")
971             (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n")]))))]
972   "TARGET_SSE || TARGET_3DNOW_A"
973   "pextrw\t{%2, %1, %0|%0, %1, %2}"
974   [(set_attr "type" "mmxcvt")
975    (set_attr "mode" "DI")])
976
977 (define_expand "mmx_pshufw"
978   [(match_operand:V4HI 0 "register_operand" "")
979    (match_operand:V4HI 1 "nonimmediate_operand" "")
980    (match_operand:SI 2 "const_int_operand" "")]
981   "TARGET_SSE || TARGET_3DNOW_A"
982 {
983   int mask = INTVAL (operands[2]);
984   emit_insn (gen_mmx_pshufw_1 (operands[0], operands[1],
985                                GEN_INT ((mask >> 0) & 3),
986                                GEN_INT ((mask >> 2) & 3),
987                                GEN_INT ((mask >> 4) & 3),
988                                GEN_INT ((mask >> 6) & 3)));
989   DONE;
990 })
991
992 (define_insn "mmx_pshufw_1"
993   [(set (match_operand:V4HI 0 "register_operand" "=y")
994         (vec_select:V4HI
995           (match_operand:V4HI 1 "nonimmediate_operand" "ym")
996           (parallel [(match_operand 2 "const_0_to_3_operand" "")
997                      (match_operand 3 "const_0_to_3_operand" "")
998                      (match_operand 4 "const_0_to_3_operand" "")
999                      (match_operand 5 "const_0_to_3_operand" "")])))]
1000   "TARGET_SSE || TARGET_3DNOW_A"
1001 {
1002   int mask = 0;
1003   mask |= INTVAL (operands[2]) << 0;
1004   mask |= INTVAL (operands[3]) << 2;
1005   mask |= INTVAL (operands[4]) << 4;
1006   mask |= INTVAL (operands[5]) << 6;
1007   operands[2] = GEN_INT (mask);
1008
1009   return "pshufw\t{%2, %1, %0|%0, %1, %2}";
1010 }
1011   [(set_attr "type" "mmxcvt")
1012    (set_attr "mode" "DI")])
1013
1014 (define_insn "mmx_pswapdv2si2"
1015   [(set (match_operand:V2SI 0 "register_operand" "=y")
1016         (vec_select:V2SI
1017           (match_operand:V2SI 1 "nonimmediate_operand" "ym")
1018           (parallel [(const_int 1) (const_int 0)])))]
1019   "TARGET_3DNOW_A"
1020   "pswapd\\t{%1, %0|%0, %1}"
1021   [(set_attr "type" "mmxcvt")
1022    (set_attr "mode" "DI")])
1023
1024 (define_insn "*vec_dupv4hi"
1025   [(set (match_operand:V4HI 0 "register_operand" "=y")
1026         (vec_duplicate:V4HI
1027           (truncate:HI
1028             (match_operand:SI 1 "register_operand" "0"))))]
1029   "TARGET_SSE || TARGET_3DNOW_A"
1030   "pshufw\t{$0, %0, %0|%0, %0, 0}"
1031   [(set_attr "type" "mmxcvt")
1032    (set_attr "mode" "DI")])
1033
1034 (define_insn "*vec_dupv2si"
1035   [(set (match_operand:V2SI 0 "register_operand" "=y")
1036         (vec_duplicate:V2SI
1037           (match_operand:SI 1 "register_operand" "0")))]
1038   "TARGET_MMX"
1039   "punpckldq\t%0, %0"
1040   [(set_attr "type" "mmxcvt")
1041    (set_attr "mode" "DI")])
1042
1043 (define_insn "*mmx_concatv2si"
1044   [(set (match_operand:V2SI 0 "register_operand"     "=y,y")
1045         (vec_concat:V2SI
1046           (match_operand:SI 1 "nonimmediate_operand" " 0,rm")
1047           (match_operand:SI 2 "vector_move_operand"  "ym,C")))]
1048   "TARGET_MMX && !TARGET_SSE"
1049   "@
1050    punpckldq\t{%2, %0|%0, %2}
1051    movd\t{%1, %0|%0, %1}"
1052   [(set_attr "type" "mmxcvt,mmxmov")
1053    (set_attr "mode" "DI")])
1054
1055 (define_expand "vec_setv2si"
1056   [(match_operand:V2SI 0 "register_operand" "")
1057    (match_operand:SI 1 "register_operand" "")
1058    (match_operand 2 "const_int_operand" "")]
1059   "TARGET_MMX"
1060 {
1061   ix86_expand_vector_set (false, operands[0], operands[1],
1062                           INTVAL (operands[2]));
1063   DONE;
1064 })
1065
1066 (define_insn_and_split "*vec_extractv2si_0"
1067   [(set (match_operand:SI 0 "nonimmediate_operand"     "=x,y,m,m,frxy")
1068         (vec_select:SI
1069           (match_operand:V2SI 1 "nonimmediate_operand" " x,y,x,y,m")
1070           (parallel [(const_int 0)])))]
1071   "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1072   "#"
1073   "&& reload_completed"
1074   [(const_int 0)]
1075 {
1076   rtx op1 = operands[1];
1077   if (REG_P (op1))
1078     op1 = gen_rtx_REG (SImode, REGNO (op1));
1079   else
1080     op1 = gen_lowpart (SImode, op1);
1081   emit_move_insn (operands[0], op1);
1082   DONE;
1083 })
1084
1085 (define_insn "*vec_extractv2si_1"
1086   [(set (match_operand:SI 0 "nonimmediate_operand"     "=y,Y2,Y2,x,frxy")
1087         (vec_select:SI
1088           (match_operand:V2SI 1 "nonimmediate_operand" " 0,0 ,Y2,0,o")
1089           (parallel [(const_int 1)])))]
1090   "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1091   "@
1092    punpckhdq\t%0, %0
1093    punpckhdq\t%0, %0
1094    pshufd\t{$85, %1, %0|%0, %1, 85}
1095    unpckhps\t%0, %0
1096    #"
1097   [(set_attr "type" "mmxcvt,sselog1,sselog1,sselog1,*")
1098    (set_attr "mode" "DI,TI,TI,V4SF,SI")])
1099
1100 (define_split
1101   [(set (match_operand:SI 0 "register_operand" "")
1102         (vec_select:SI
1103           (match_operand:V2SI 1 "memory_operand" "")
1104           (parallel [(const_int 1)])))]
1105   "TARGET_MMX && reload_completed"
1106   [(const_int 0)]
1107 {
1108   operands[1] = adjust_address (operands[1], SImode, 4);
1109   emit_move_insn (operands[0], operands[1]);
1110   DONE;
1111 })
1112
1113 (define_expand "vec_extractv2si"
1114   [(match_operand:SI 0 "register_operand" "")
1115    (match_operand:V2SI 1 "register_operand" "")
1116    (match_operand 2 "const_int_operand" "")]
1117   "TARGET_MMX"
1118 {
1119   ix86_expand_vector_extract (false, operands[0], operands[1],
1120                               INTVAL (operands[2]));
1121   DONE;
1122 })
1123
1124 (define_expand "vec_initv2si"
1125   [(match_operand:V2SI 0 "register_operand" "")
1126    (match_operand 1 "" "")]
1127   "TARGET_SSE"
1128 {
1129   ix86_expand_vector_init (false, operands[0], operands[1]);
1130   DONE;
1131 })
1132
1133 (define_expand "vec_setv4hi"
1134   [(match_operand:V4HI 0 "register_operand" "")
1135    (match_operand:HI 1 "register_operand" "")
1136    (match_operand 2 "const_int_operand" "")]
1137   "TARGET_MMX"
1138 {
1139   ix86_expand_vector_set (false, operands[0], operands[1],
1140                           INTVAL (operands[2]));
1141   DONE;
1142 })
1143
1144 (define_expand "vec_extractv4hi"
1145   [(match_operand:HI 0 "register_operand" "")
1146    (match_operand:V4HI 1 "register_operand" "")
1147    (match_operand 2 "const_int_operand" "")]
1148   "TARGET_MMX"
1149 {
1150   ix86_expand_vector_extract (false, operands[0], operands[1],
1151                               INTVAL (operands[2]));
1152   DONE;
1153 })
1154
1155 (define_expand "vec_initv4hi"
1156   [(match_operand:V4HI 0 "register_operand" "")
1157    (match_operand 1 "" "")]
1158   "TARGET_SSE"
1159 {
1160   ix86_expand_vector_init (false, operands[0], operands[1]);
1161   DONE;
1162 })
1163
1164 (define_expand "vec_setv8qi"
1165   [(match_operand:V8QI 0 "register_operand" "")
1166    (match_operand:QI 1 "register_operand" "")
1167    (match_operand 2 "const_int_operand" "")]
1168   "TARGET_MMX"
1169 {
1170   ix86_expand_vector_set (false, operands[0], operands[1],
1171                           INTVAL (operands[2]));
1172   DONE;
1173 })
1174
1175 (define_expand "vec_extractv8qi"
1176   [(match_operand:QI 0 "register_operand" "")
1177    (match_operand:V8QI 1 "register_operand" "")
1178    (match_operand 2 "const_int_operand" "")]
1179   "TARGET_MMX"
1180 {
1181   ix86_expand_vector_extract (false, operands[0], operands[1],
1182                               INTVAL (operands[2]));
1183   DONE;
1184 })
1185
1186 (define_expand "vec_initv8qi"
1187   [(match_operand:V8QI 0 "register_operand" "")
1188    (match_operand 1 "" "")]
1189   "TARGET_SSE"
1190 {
1191   ix86_expand_vector_init (false, operands[0], operands[1]);
1192   DONE;
1193 })
1194
1195 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1196 ;;
1197 ;; Miscellaneous
1198 ;;
1199 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1200
1201 (define_insn "mmx_uavgv8qi3"
1202   [(set (match_operand:V8QI 0 "register_operand" "=y")
1203         (truncate:V8QI
1204           (lshiftrt:V8HI
1205             (plus:V8HI
1206               (plus:V8HI
1207                 (zero_extend:V8HI
1208                   (match_operand:V8QI 1 "nonimmediate_operand" "%0"))
1209                 (zero_extend:V8HI
1210                   (match_operand:V8QI 2 "nonimmediate_operand" "ym")))
1211               (const_vector:V8HI [(const_int 1) (const_int 1)
1212                                   (const_int 1) (const_int 1)
1213                                   (const_int 1) (const_int 1)
1214                                   (const_int 1) (const_int 1)]))
1215             (const_int 1))))]
1216   "(TARGET_SSE || TARGET_3DNOW)
1217    && ix86_binary_operator_ok (PLUS, V8QImode, operands)"
1218 {
1219   /* These two instructions have the same operation, but their encoding
1220      is different.  Prefer the one that is de facto standard.  */
1221   if (TARGET_SSE || TARGET_3DNOW_A)
1222     return "pavgb\t{%2, %0|%0, %2}";
1223   else
1224     return "pavgusb\\t{%2, %0|%0, %2}";
1225 }
1226   [(set_attr "type" "mmxshft")
1227    (set_attr "mode" "DI")])
1228
1229 (define_insn "mmx_uavgv4hi3"
1230   [(set (match_operand:V4HI 0 "register_operand" "=y")
1231         (truncate:V4HI
1232           (lshiftrt:V4SI
1233             (plus:V4SI
1234               (plus:V4SI
1235                 (zero_extend:V4SI
1236                   (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
1237                 (zero_extend:V4SI
1238                   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
1239               (const_vector:V4SI [(const_int 1) (const_int 1)
1240                                   (const_int 1) (const_int 1)]))
1241             (const_int 1))))]
1242   "(TARGET_SSE || TARGET_3DNOW_A)
1243    && ix86_binary_operator_ok (PLUS, V4HImode, operands)"
1244   "pavgw\t{%2, %0|%0, %2}"
1245   [(set_attr "type" "mmxshft")
1246    (set_attr "mode" "DI")])
1247
1248 (define_insn "mmx_psadbw"
1249   [(set (match_operand:V1DI 0 "register_operand" "=y")
1250         (unspec:V1DI [(match_operand:V8QI 1 "register_operand" "0")
1251                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
1252                      UNSPEC_PSADBW))]
1253   "TARGET_SSE || TARGET_3DNOW_A"
1254   "psadbw\t{%2, %0|%0, %2}"
1255   [(set_attr "type" "mmxshft")
1256    (set_attr "mode" "DI")])
1257
1258 (define_insn "mmx_pmovmskb"
1259   [(set (match_operand:SI 0 "register_operand" "=r")
1260         (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
1261                    UNSPEC_MOVMSK))]
1262   "TARGET_SSE || TARGET_3DNOW_A"
1263   "pmovmskb\t{%1, %0|%0, %1}"
1264   [(set_attr "type" "mmxcvt")
1265    (set_attr "mode" "DI")])
1266
1267 (define_expand "mmx_maskmovq"
1268   [(set (match_operand:V8QI 0 "memory_operand" "")
1269         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "")
1270                       (match_operand:V8QI 2 "register_operand" "")
1271                       (match_dup 0)]
1272                      UNSPEC_MASKMOV))]
1273   "TARGET_SSE || TARGET_3DNOW_A"
1274   "")
1275
1276 (define_insn "*mmx_maskmovq"
1277   [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
1278         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
1279                       (match_operand:V8QI 2 "register_operand" "y")
1280                       (mem:V8QI (match_dup 0))]
1281                      UNSPEC_MASKMOV))]
1282   "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
1283   ;; @@@ check ordering of operands in intel/nonintel syntax
1284   "maskmovq\t{%2, %1|%1, %2}"
1285   [(set_attr "type" "mmxcvt")
1286    (set_attr "mode" "DI")])
1287
1288 (define_insn "*mmx_maskmovq_rex"
1289   [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
1290         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
1291                       (match_operand:V8QI 2 "register_operand" "y")
1292                       (mem:V8QI (match_dup 0))]
1293                      UNSPEC_MASKMOV))]
1294   "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
1295   ;; @@@ check ordering of operands in intel/nonintel syntax
1296   "maskmovq\t{%2, %1|%1, %2}"
1297   [(set_attr "type" "mmxcvt")
1298    (set_attr "mode" "DI")])
1299
1300 (define_insn "mmx_emms"
1301   [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
1302    (clobber (reg:XF 8))
1303    (clobber (reg:XF 9))
1304    (clobber (reg:XF 10))
1305    (clobber (reg:XF 11))
1306    (clobber (reg:XF 12))
1307    (clobber (reg:XF 13))
1308    (clobber (reg:XF 14))
1309    (clobber (reg:XF 15))
1310    (clobber (reg:DI 29))
1311    (clobber (reg:DI 30))
1312    (clobber (reg:DI 31))
1313    (clobber (reg:DI 32))
1314    (clobber (reg:DI 33))
1315    (clobber (reg:DI 34))
1316    (clobber (reg:DI 35))
1317    (clobber (reg:DI 36))]
1318   "TARGET_MMX"
1319   "emms"
1320   [(set_attr "type" "mmx")
1321    (set_attr "memory" "unknown")])
1322
1323 (define_insn "mmx_femms"
1324   [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
1325    (clobber (reg:XF 8))
1326    (clobber (reg:XF 9))
1327    (clobber (reg:XF 10))
1328    (clobber (reg:XF 11))
1329    (clobber (reg:XF 12))
1330    (clobber (reg:XF 13))
1331    (clobber (reg:XF 14))
1332    (clobber (reg:XF 15))
1333    (clobber (reg:DI 29))
1334    (clobber (reg:DI 30))
1335    (clobber (reg:DI 31))
1336    (clobber (reg:DI 32))
1337    (clobber (reg:DI 33))
1338    (clobber (reg:DI 34))
1339    (clobber (reg:DI 35))
1340    (clobber (reg:DI 36))]
1341   "TARGET_3DNOW"
1342   "femms"
1343   [(set_attr "type" "mmx")
1344    (set_attr "memory" "none")])