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