OSDN Git Service

* config/i386/i386.c (ix86_expand_push): New.
[pf3gnuchains/gcc-fork.git] / 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_expand "vec_extractv2sf"
486   [(match_operand:SF 0 "register_operand" "")
487    (match_operand:V2SF 1 "register_operand" "")
488    (match_operand 2 "const_int_operand" "")]
489   "TARGET_MMX"
490 {
491   ix86_expand_vector_extract (false, operands[0], operands[1],
492                               INTVAL (operands[2]));
493   DONE;
494 })
495
496 (define_expand "vec_initv2sf"
497   [(match_operand:V2SF 0 "register_operand" "")
498    (match_operand 1 "" "")]
499   "TARGET_SSE"
500 {
501   ix86_expand_vector_init (false, operands[0], operands[1]);
502   DONE;
503 })
504
505 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
506 ;;
507 ;; Parallel integral arithmetic
508 ;;
509 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
510
511 (define_insn "mmx_add<mode>3"
512   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
513         (plus:MMXMODEI
514           (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
515           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
516   "TARGET_MMX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
517   "padd<mmxvecsize>\t{%2, %0|%0, %2}"
518   [(set_attr "type" "mmxadd")
519    (set_attr "mode" "DI")])
520
521 (define_insn "mmx_adddi3"
522   [(set (match_operand:DI 0 "register_operand" "=y")
523         (unspec:DI
524          [(plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
525                    (match_operand:DI 2 "nonimmediate_operand" "ym"))]
526          UNSPEC_NOP))]
527   "TARGET_MMX && ix86_binary_operator_ok (PLUS, DImode, operands)"
528   "paddq\t{%2, %0|%0, %2}"
529   [(set_attr "type" "mmxadd")
530    (set_attr "mode" "DI")])
531
532 (define_insn "mmx_ssadd<mode>3"
533   [(set (match_operand:MMXMODE12 0 "register_operand" "=y")
534         (ss_plus:MMXMODE12
535           (match_operand:MMXMODE12 1 "nonimmediate_operand" "%0")
536           (match_operand:MMXMODE12 2 "nonimmediate_operand" "ym")))]
537   "TARGET_MMX"
538   "padds<mmxvecsize>\t{%2, %0|%0, %2}"
539   [(set_attr "type" "mmxadd")
540    (set_attr "mode" "DI")])
541
542 (define_insn "mmx_usadd<mode>3"
543   [(set (match_operand:MMXMODE12 0 "register_operand" "=y")
544         (us_plus:MMXMODE12
545           (match_operand:MMXMODE12 1 "nonimmediate_operand" "%0")
546           (match_operand:MMXMODE12 2 "nonimmediate_operand" "ym")))]
547   "TARGET_MMX"
548   "paddus<mmxvecsize>\t{%2, %0|%0, %2}"
549   [(set_attr "type" "mmxadd")
550    (set_attr "mode" "DI")])
551
552 (define_insn "mmx_sub<mode>3"
553   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
554         (minus:MMXMODEI
555           (match_operand:MMXMODEI 1 "register_operand" "0")
556           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
557   "TARGET_MMX"
558   "psub<mmxvecsize>\t{%2, %0|%0, %2}"
559   [(set_attr "type" "mmxadd")
560    (set_attr "mode" "DI")])
561
562 (define_insn "mmx_subdi3"
563   [(set (match_operand:DI 0 "register_operand" "=y")
564         (unspec:DI
565          [(minus:DI (match_operand:DI 1 "register_operand" "0")
566                     (match_operand:DI 2 "nonimmediate_operand" "ym"))]
567          UNSPEC_NOP))]
568   "TARGET_MMX"
569   "psubq\t{%2, %0|%0, %2}"
570   [(set_attr "type" "mmxadd")
571    (set_attr "mode" "DI")])
572
573 (define_insn "mmx_sssub<mode>3"
574   [(set (match_operand:MMXMODE12 0 "register_operand" "=y")
575         (ss_minus:MMXMODE12
576           (match_operand:MMXMODE12 1 "register_operand" "0")
577           (match_operand:MMXMODE12 2 "nonimmediate_operand" "ym")))]
578   "TARGET_MMX"
579   "psubs<mmxvecsize>\t{%2, %0|%0, %2}"
580   [(set_attr "type" "mmxadd")
581    (set_attr "mode" "DI")])
582
583 (define_insn "mmx_ussub<mode>3"
584   [(set (match_operand:MMXMODE12 0 "register_operand" "=y")
585         (us_minus:MMXMODE12
586           (match_operand:MMXMODE12 1 "register_operand" "0")
587           (match_operand:MMXMODE12 2 "nonimmediate_operand" "ym")))]
588   "TARGET_MMX"
589   "psubus<mmxvecsize>\t{%2, %0|%0, %2}"
590   [(set_attr "type" "mmxadd")
591    (set_attr "mode" "DI")])
592
593 (define_insn "mmx_mulv4hi3"
594   [(set (match_operand:V4HI 0 "register_operand" "=y")
595         (mult:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "%0")
596                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
597   "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
598   "pmullw\t{%2, %0|%0, %2}"
599   [(set_attr "type" "mmxmul")
600    (set_attr "mode" "DI")])
601
602 (define_insn "mmx_smulv4hi3_highpart"
603   [(set (match_operand:V4HI 0 "register_operand" "=y")
604         (truncate:V4HI
605          (lshiftrt:V4SI
606           (mult:V4SI (sign_extend:V4SI
607                       (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
608                      (sign_extend:V4SI
609                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
610           (const_int 16))))]
611   "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
612   "pmulhw\t{%2, %0|%0, %2}"
613   [(set_attr "type" "mmxmul")
614    (set_attr "mode" "DI")])
615
616 (define_insn "mmx_umulv4hi3_highpart"
617   [(set (match_operand:V4HI 0 "register_operand" "=y")
618         (truncate:V4HI
619          (lshiftrt:V4SI
620           (mult:V4SI (zero_extend:V4SI
621                       (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
622                      (zero_extend:V4SI
623                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
624           (const_int 16))))]
625   "(TARGET_SSE || TARGET_3DNOW_A)
626    && ix86_binary_operator_ok (MULT, V4HImode, operands)"
627   "pmulhuw\t{%2, %0|%0, %2}"
628   [(set_attr "type" "mmxmul")
629    (set_attr "mode" "DI")])
630
631 (define_insn "mmx_pmaddwd"
632   [(set (match_operand:V2SI 0 "register_operand" "=y")
633         (plus:V2SI
634           (mult:V2SI
635             (sign_extend:V2SI
636               (vec_select:V2HI
637                 (match_operand:V4HI 1 "nonimmediate_operand" "%0")
638                 (parallel [(const_int 0) (const_int 2)])))
639             (sign_extend:V2SI
640               (vec_select:V2HI
641                 (match_operand:V4HI 2 "nonimmediate_operand" "ym")
642                 (parallel [(const_int 0) (const_int 2)]))))
643           (mult:V2SI
644             (sign_extend:V2SI
645               (vec_select:V2HI (match_dup 1)
646                 (parallel [(const_int 1) (const_int 3)])))
647             (sign_extend:V2SI
648               (vec_select:V2HI (match_dup 2)
649                 (parallel [(const_int 1) (const_int 3)]))))))]
650   "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
651   "pmaddwd\t{%2, %0|%0, %2}"
652   [(set_attr "type" "mmxmul")
653    (set_attr "mode" "DI")])
654
655 (define_insn "mmx_pmulhrwv4hi3"
656   [(set (match_operand:V4HI 0 "register_operand" "=y")
657         (truncate:V4HI
658           (lshiftrt:V4SI
659             (plus:V4SI
660               (mult:V4SI
661                 (sign_extend:V4SI
662                   (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
663                 (sign_extend:V4SI
664                   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
665               (const_vector:V4SI [(const_int 32768) (const_int 32768)
666                                   (const_int 32768) (const_int 32768)]))
667             (const_int 16))))]
668   "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V4HImode, operands)"
669   "pmulhrw\\t{%2, %0|%0, %2}"
670   [(set_attr "type" "mmxmul")
671    (set_attr "mode" "DI")])
672
673 (define_insn "sse2_umulsidi3"
674   [(set (match_operand:DI 0 "register_operand" "=y")
675         (mult:DI
676           (zero_extend:DI
677             (vec_select:SI
678               (match_operand:V2SI 1 "nonimmediate_operand" "%0")
679               (parallel [(const_int 0)])))
680           (zero_extend:DI
681             (vec_select:SI
682               (match_operand:V2SI 2 "nonimmediate_operand" "ym")
683               (parallel [(const_int 0)])))))]
684   "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V2SImode, operands)"
685   "pmuludq\t{%2, %0|%0, %2}"
686   [(set_attr "type" "mmxmul")
687    (set_attr "mode" "DI")])
688
689 (define_insn "mmx_umaxv8qi3"
690   [(set (match_operand:V8QI 0 "register_operand" "=y")
691         (umax:V8QI (match_operand:V8QI 1 "nonimmediate_operand" "%0")
692                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
693   "(TARGET_SSE || TARGET_3DNOW_A)
694    && ix86_binary_operator_ok (UMAX, V8QImode, operands)"
695   "pmaxub\t{%2, %0|%0, %2}"
696   [(set_attr "type" "mmxadd")
697    (set_attr "mode" "DI")])
698
699 (define_insn "mmx_smaxv4hi3"
700   [(set (match_operand:V4HI 0 "register_operand" "=y")
701         (smax:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "%0")
702                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
703   "(TARGET_SSE || TARGET_3DNOW_A)
704    && ix86_binary_operator_ok (SMAX, V4HImode, operands)"
705   "pmaxsw\t{%2, %0|%0, %2}"
706   [(set_attr "type" "mmxadd")
707    (set_attr "mode" "DI")])
708
709 (define_insn "mmx_uminv8qi3"
710   [(set (match_operand:V8QI 0 "register_operand" "=y")
711         (umin:V8QI (match_operand:V8QI 1 "nonimmediate_operand" "%0")
712                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
713   "(TARGET_SSE || TARGET_3DNOW_A)
714    && ix86_binary_operator_ok (UMIN, V8QImode, operands)"
715   "pminub\t{%2, %0|%0, %2}"
716   [(set_attr "type" "mmxadd")
717    (set_attr "mode" "DI")])
718
719 (define_insn "mmx_sminv4hi3"
720   [(set (match_operand:V4HI 0 "register_operand" "=y")
721         (smin:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "%0")
722                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
723   "(TARGET_SSE || TARGET_3DNOW_A)
724    && ix86_binary_operator_ok (SMIN, V4HImode, operands)"
725   "pminsw\t{%2, %0|%0, %2}"
726   [(set_attr "type" "mmxadd")
727    (set_attr "mode" "DI")])
728
729 (define_insn "mmx_ashr<mode>3"
730   [(set (match_operand:MMXMODE24 0 "register_operand" "=y")
731         (ashiftrt:MMXMODE24
732           (match_operand:MMXMODE24 1 "register_operand" "0")
733           (match_operand:DI 2 "nonmemory_operand" "yi")))]
734   "TARGET_MMX"
735   "psra<mmxvecsize>\t{%2, %0|%0, %2}"
736   [(set_attr "type" "mmxshft")
737    (set_attr "mode" "DI")])
738
739 (define_insn "mmx_lshr<mode>3"
740   [(set (match_operand:MMXMODE24 0 "register_operand" "=y")
741         (lshiftrt:MMXMODE24
742           (match_operand:MMXMODE24 1 "register_operand" "0")
743           (match_operand:DI 2 "nonmemory_operand" "yi")))]
744   "TARGET_MMX"
745   "psrl<mmxvecsize>\t{%2, %0|%0, %2}"
746   [(set_attr "type" "mmxshft")
747    (set_attr "mode" "DI")])
748
749 (define_insn "mmx_lshrdi3"
750   [(set (match_operand:DI 0 "register_operand" "=y")
751         (unspec:DI
752           [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
753                        (match_operand:DI 2 "nonmemory_operand" "yi"))]
754           UNSPEC_NOP))]
755   "TARGET_MMX"
756   "psrlq\t{%2, %0|%0, %2}"
757   [(set_attr "type" "mmxshft")
758    (set_attr "mode" "DI")])
759
760 (define_insn "mmx_ashl<mode>3"
761   [(set (match_operand:MMXMODE24 0 "register_operand" "=y")
762         (ashift:MMXMODE24
763           (match_operand:MMXMODE24 1 "register_operand" "0")
764           (match_operand:DI 2 "nonmemory_operand" "yi")))]
765   "TARGET_MMX"
766   "psll<mmxvecsize>\t{%2, %0|%0, %2}"
767   [(set_attr "type" "mmxshft")
768    (set_attr "mode" "DI")])
769
770 (define_insn "mmx_ashldi3"
771   [(set (match_operand:DI 0 "register_operand" "=y")
772         (unspec:DI
773          [(ashift:DI (match_operand:DI 1 "register_operand" "0")
774                      (match_operand:DI 2 "nonmemory_operand" "yi"))]
775          UNSPEC_NOP))]
776   "TARGET_MMX"
777   "psllq\t{%2, %0|%0, %2}"
778   [(set_attr "type" "mmxshft")
779    (set_attr "mode" "DI")])
780
781 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
782 ;;
783 ;; Parallel integral comparisons
784 ;;
785 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
786
787 (define_insn "mmx_eq<mode>3"
788   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
789         (eq:MMXMODEI
790           (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
791           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
792   "TARGET_MMX && ix86_binary_operator_ok (EQ, <MODE>mode, operands)"
793   "pcmpeq<mmxvecsize>\t{%2, %0|%0, %2}"
794   [(set_attr "type" "mmxcmp")
795    (set_attr "mode" "DI")])
796
797 (define_insn "mmx_gt<mode>3"
798   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
799         (gt:MMXMODEI
800           (match_operand:MMXMODEI 1 "register_operand" "0")
801           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
802   "TARGET_MMX"
803   "pcmpgt<mmxvecsize>\t{%2, %0|%0, %2}"
804   [(set_attr "type" "mmxcmp")
805    (set_attr "mode" "DI")])
806
807 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
808 ;;
809 ;; Parallel integral logical operations
810 ;;
811 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
812
813 (define_insn "mmx_and<mode>3"
814   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
815         (and:MMXMODEI
816           (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
817           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
818   "TARGET_MMX && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
819   "pand\t{%2, %0|%0, %2}"
820   [(set_attr "type" "mmxadd")
821    (set_attr "mode" "DI")])
822
823 (define_insn "mmx_nand<mode>3"
824   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
825         (and:MMXMODEI
826           (not:MMXMODEI (match_operand:MMXMODEI 1 "register_operand" "0"))
827           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
828   "TARGET_MMX"
829   "pandn\t{%2, %0|%0, %2}"
830   [(set_attr "type" "mmxadd")
831    (set_attr "mode" "DI")])
832
833 (define_insn "mmx_ior<mode>3"
834   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
835         (ior:MMXMODEI
836           (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
837           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
838   "TARGET_MMX && ix86_binary_operator_ok (IOR, <MODE>mode, operands)"
839   "por\t{%2, %0|%0, %2}"
840   [(set_attr "type" "mmxadd")
841    (set_attr "mode" "DI")])
842
843 (define_insn "mmx_xor<mode>3"
844   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
845         (xor:MMXMODEI
846           (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
847           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
848   "TARGET_MMX && ix86_binary_operator_ok (XOR, <MODE>mode, operands)"
849   "pxor\t{%2, %0|%0, %2}"
850   [(set_attr "type" "mmxadd")
851    (set_attr "mode" "DI")
852    (set_attr "memory" "none")])
853
854 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
855 ;;
856 ;; Parallel integral element swizzling
857 ;;
858 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
859
860 (define_insn "mmx_packsswb"
861   [(set (match_operand:V8QI 0 "register_operand" "=y")
862         (vec_concat:V8QI
863           (ss_truncate:V4QI
864             (match_operand:V4HI 1 "register_operand" "0"))
865           (ss_truncate:V4QI
866             (match_operand:V4HI 2 "nonimmediate_operand" "ym"))))]
867   "TARGET_MMX"
868   "packsswb\t{%2, %0|%0, %2}"
869   [(set_attr "type" "mmxshft")
870    (set_attr "mode" "DI")])
871
872 (define_insn "mmx_packssdw"
873   [(set (match_operand:V4HI 0 "register_operand" "=y")
874         (vec_concat:V4HI
875           (ss_truncate:V2HI
876             (match_operand:V2SI 1 "register_operand" "0"))
877           (ss_truncate:V2HI
878             (match_operand:V2SI 2 "nonimmediate_operand" "ym"))))]
879   "TARGET_MMX"
880   "packssdw\t{%2, %0|%0, %2}"
881   [(set_attr "type" "mmxshft")
882    (set_attr "mode" "DI")])
883
884 (define_insn "mmx_packuswb"
885   [(set (match_operand:V8QI 0 "register_operand" "=y")
886         (vec_concat:V8QI
887           (us_truncate:V4QI
888             (match_operand:V4HI 1 "register_operand" "0"))
889           (us_truncate:V4QI
890             (match_operand:V4HI 2 "nonimmediate_operand" "ym"))))]
891   "TARGET_MMX"
892   "packuswb\t{%2, %0|%0, %2}"
893   [(set_attr "type" "mmxshft")
894    (set_attr "mode" "DI")])
895
896 (define_insn "mmx_punpckhbw"
897   [(set (match_operand:V8QI 0 "register_operand" "=y")
898         (vec_select:V8QI
899           (vec_concat:V16QI
900             (match_operand:V8QI 1 "register_operand" "0")
901             (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
902           (parallel [(const_int 4) (const_int 12)
903                      (const_int 5) (const_int 13)
904                      (const_int 6) (const_int 14)
905                      (const_int 7) (const_int 15)])))]
906   "TARGET_MMX"
907   "punpckhbw\t{%2, %0|%0, %2}"
908   [(set_attr "type" "mmxcvt")
909    (set_attr "mode" "DI")])
910
911 (define_insn "mmx_punpcklbw"
912   [(set (match_operand:V8QI 0 "register_operand" "=y")
913         (vec_select:V8QI
914           (vec_concat:V16QI
915             (match_operand:V8QI 1 "register_operand" "0")
916             (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
917           (parallel [(const_int 0) (const_int 8)
918                      (const_int 1) (const_int 9)
919                      (const_int 2) (const_int 10)
920                      (const_int 3) (const_int 11)])))]
921   "TARGET_MMX"
922   "punpcklbw\t{%2, %0|%0, %2}"
923   [(set_attr "type" "mmxcvt")
924    (set_attr "mode" "DI")])
925
926 (define_insn "mmx_punpckhwd"
927   [(set (match_operand:V4HI 0 "register_operand" "=y")
928         (vec_select:V4HI
929           (vec_concat:V8HI
930             (match_operand:V4HI 1 "register_operand" "0")
931             (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
932           (parallel [(const_int 2) (const_int 6)
933                      (const_int 3) (const_int 7)])))]
934   "TARGET_MMX"
935   "punpckhwd\t{%2, %0|%0, %2}"
936   [(set_attr "type" "mmxcvt")
937    (set_attr "mode" "DI")])
938
939 (define_insn "mmx_punpcklwd"
940   [(set (match_operand:V4HI 0 "register_operand" "=y")
941         (vec_select:V4HI
942           (vec_concat:V8HI
943             (match_operand:V4HI 1 "register_operand" "0")
944             (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
945           (parallel [(const_int 0) (const_int 4)
946                      (const_int 1) (const_int 5)])))]
947   "TARGET_MMX"
948   "punpcklwd\t{%2, %0|%0, %2}"
949   [(set_attr "type" "mmxcvt")
950    (set_attr "mode" "DI")])
951
952 (define_insn "mmx_punpckhdq"
953   [(set (match_operand:V2SI 0 "register_operand" "=y")
954         (vec_select:V2SI
955           (vec_concat:V4SI
956             (match_operand:V2SI 1 "register_operand" "0")
957             (match_operand:V2SI 2 "nonimmediate_operand" "ym"))
958           (parallel [(const_int 1)
959                      (const_int 3)])))]
960   "TARGET_MMX"
961   "punpckhdq\t{%2, %0|%0, %2}"
962   [(set_attr "type" "mmxcvt")
963    (set_attr "mode" "DI")])
964
965 (define_insn "mmx_punpckldq"
966   [(set (match_operand:V2SI 0 "register_operand" "=y")
967         (vec_select:V2SI
968           (vec_concat:V4SI
969             (match_operand:V2SI 1 "register_operand" "0")
970             (match_operand:V2SI 2 "nonimmediate_operand" "ym"))
971           (parallel [(const_int 0)
972                      (const_int 2)])))]
973   "TARGET_MMX"
974   "punpckldq\t{%2, %0|%0, %2}"
975   [(set_attr "type" "mmxcvt")
976    (set_attr "mode" "DI")])
977
978 (define_expand "mmx_pinsrw"
979   [(set (match_operand:V4HI 0 "register_operand" "")
980         (vec_merge:V4HI
981           (vec_duplicate:V4HI
982             (match_operand:SI 2 "nonimmediate_operand" ""))
983           (match_operand:V4HI 1 "register_operand" "")
984           (match_operand:SI 3 "const_0_to_3_operand" "")))]
985   "TARGET_SSE || TARGET_3DNOW_A"
986 {
987   operands[2] = gen_lowpart (HImode, operands[2]);
988   operands[3] = GEN_INT (1 << INTVAL (operands[3]));
989 })
990
991 (define_insn "*mmx_pinsrw"
992   [(set (match_operand:V4HI 0 "register_operand" "=y")
993         (vec_merge:V4HI
994           (vec_duplicate:V4HI
995             (match_operand:HI 2 "nonimmediate_operand" "rm"))
996           (match_operand:V4HI 1 "register_operand" "0")
997           (match_operand:SI 3 "const_pow2_1_to_8_operand" "n")))]
998   "TARGET_SSE || TARGET_3DNOW_A"
999 {
1000   operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
1001   return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}";
1002 }
1003   [(set_attr "type" "mmxcvt")
1004    (set_attr "mode" "DI")])
1005
1006 (define_insn "mmx_pextrw"
1007   [(set (match_operand:SI 0 "register_operand" "=r")
1008         (zero_extend:SI
1009           (vec_select:HI
1010             (match_operand:V4HI 1 "register_operand" "y")
1011             (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n")]))))]
1012   "TARGET_SSE || TARGET_3DNOW_A"
1013   "pextrw\t{%2, %1, %0|%0, %1, %2}"
1014   [(set_attr "type" "mmxcvt")
1015    (set_attr "mode" "DI")])
1016
1017 (define_expand "mmx_pshufw"
1018   [(match_operand:V4HI 0 "register_operand" "")
1019    (match_operand:V4HI 1 "nonimmediate_operand" "")
1020    (match_operand:SI 2 "const_int_operand" "")]
1021   "TARGET_SSE || TARGET_3DNOW_A"
1022 {
1023   int mask = INTVAL (operands[2]);
1024   emit_insn (gen_mmx_pshufw_1 (operands[0], operands[1],
1025                                GEN_INT ((mask >> 0) & 3),
1026                                GEN_INT ((mask >> 2) & 3),
1027                                GEN_INT ((mask >> 4) & 3),
1028                                GEN_INT ((mask >> 6) & 3)));
1029   DONE;
1030 })
1031
1032 (define_insn "mmx_pshufw_1"
1033   [(set (match_operand:V4HI 0 "register_operand" "=y")
1034         (vec_select:V4HI
1035           (match_operand:V4HI 1 "nonimmediate_operand" "ym")
1036           (parallel [(match_operand 2 "const_0_to_3_operand" "")
1037                      (match_operand 3 "const_0_to_3_operand" "")
1038                      (match_operand 4 "const_0_to_3_operand" "")
1039                      (match_operand 5 "const_0_to_3_operand" "")])))]
1040   "TARGET_SSE || TARGET_3DNOW_A"
1041 {
1042   int mask = 0;
1043   mask |= INTVAL (operands[2]) << 0;
1044   mask |= INTVAL (operands[3]) << 2;
1045   mask |= INTVAL (operands[4]) << 4;
1046   mask |= INTVAL (operands[5]) << 6;
1047   operands[2] = GEN_INT (mask);
1048
1049   return "pshufw\t{%2, %1, %0|%0, %1, %2}";
1050 }
1051   [(set_attr "type" "mmxcvt")
1052    (set_attr "mode" "DI")])
1053
1054 (define_insn "mmx_pswapdv2si2"
1055   [(set (match_operand:V2SI 0 "register_operand" "=y")
1056         (vec_select:V2SI
1057           (match_operand:V2SI 1 "nonimmediate_operand" "ym")
1058           (parallel [(const_int 1) (const_int 0)])))]
1059   "TARGET_3DNOW_A"
1060   "pswapd\\t{%1, %0|%0, %1}"
1061   [(set_attr "type" "mmxcvt")
1062    (set_attr "mode" "DI")])
1063
1064 (define_insn "*vec_dupv4hi"
1065   [(set (match_operand:V4HI 0 "register_operand" "=y")
1066         (vec_duplicate:V4HI
1067           (truncate:HI
1068             (match_operand:SI 1 "register_operand" "0"))))]
1069   "TARGET_MMX"
1070   "pshufw\t{$0, %0, %0|%0, %0, 0}"
1071   [(set_attr "type" "mmxcvt")
1072    (set_attr "mode" "DI")])
1073
1074 (define_insn "*vec_dupv2si"
1075   [(set (match_operand:V2SI 0 "register_operand" "=y")
1076         (vec_duplicate:V2SI
1077           (match_operand:SI 1 "register_operand" "0")))]
1078   "TARGET_MMX"
1079   "punpckldq\t%0, %0"
1080   [(set_attr "type" "mmxcvt")
1081    (set_attr "mode" "DI")])
1082
1083 (define_insn "*mmx_concatv2si"
1084   [(set (match_operand:V2SI 0 "register_operand"     "=y,y")
1085         (vec_concat:V2SI
1086           (match_operand:SI 1 "nonimmediate_operand" " 0,rm")
1087           (match_operand:SI 2 "vector_move_operand"  "ym,C")))]
1088   "TARGET_MMX && !TARGET_SSE"
1089   "@
1090    punpckldq\t{%2, %0|%0, %2}
1091    movd\t{%1, %0|%0, %1}"
1092   [(set_attr "type" "mmxcvt,mmxmov")
1093    (set_attr "mode" "DI")])
1094
1095 (define_expand "vec_setv2si"
1096   [(match_operand:V2SI 0 "register_operand" "")
1097    (match_operand:SI 1 "register_operand" "")
1098    (match_operand 2 "const_int_operand" "")]
1099   "TARGET_MMX"
1100 {
1101   ix86_expand_vector_set (false, operands[0], operands[1],
1102                           INTVAL (operands[2]));
1103   DONE;
1104 })
1105
1106 (define_expand "vec_extractv2si"
1107   [(match_operand:SI 0 "register_operand" "")
1108    (match_operand:V2SI 1 "register_operand" "")
1109    (match_operand 2 "const_int_operand" "")]
1110   "TARGET_MMX"
1111 {
1112   ix86_expand_vector_extract (false, operands[0], operands[1],
1113                               INTVAL (operands[2]));
1114   DONE;
1115 })
1116
1117 (define_expand "vec_initv2si"
1118   [(match_operand:V2SI 0 "register_operand" "")
1119    (match_operand 1 "" "")]
1120   "TARGET_SSE"
1121 {
1122   ix86_expand_vector_init (false, operands[0], operands[1]);
1123   DONE;
1124 })
1125
1126 (define_expand "vec_setv4hi"
1127   [(match_operand:V4HI 0 "register_operand" "")
1128    (match_operand:HI 1 "register_operand" "")
1129    (match_operand 2 "const_int_operand" "")]
1130   "TARGET_MMX"
1131 {
1132   ix86_expand_vector_set (false, operands[0], operands[1],
1133                           INTVAL (operands[2]));
1134   DONE;
1135 })
1136
1137 (define_expand "vec_extractv4hi"
1138   [(match_operand:HI 0 "register_operand" "")
1139    (match_operand:V4HI 1 "register_operand" "")
1140    (match_operand 2 "const_int_operand" "")]
1141   "TARGET_MMX"
1142 {
1143   ix86_expand_vector_extract (false, operands[0], operands[1],
1144                               INTVAL (operands[2]));
1145   DONE;
1146 })
1147
1148 (define_expand "vec_initv4hi"
1149   [(match_operand:V4HI 0 "register_operand" "")
1150    (match_operand 1 "" "")]
1151   "TARGET_SSE"
1152 {
1153   ix86_expand_vector_init (false, operands[0], operands[1]);
1154   DONE;
1155 })
1156
1157 (define_expand "vec_setv8qi"
1158   [(match_operand:V8QI 0 "register_operand" "")
1159    (match_operand:QI 1 "register_operand" "")
1160    (match_operand 2 "const_int_operand" "")]
1161   "TARGET_MMX"
1162 {
1163   ix86_expand_vector_set (false, operands[0], operands[1],
1164                           INTVAL (operands[2]));
1165   DONE;
1166 })
1167
1168 (define_expand "vec_extractv8qi"
1169   [(match_operand:QI 0 "register_operand" "")
1170    (match_operand:V8QI 1 "register_operand" "")
1171    (match_operand 2 "const_int_operand" "")]
1172   "TARGET_MMX"
1173 {
1174   ix86_expand_vector_extract (false, operands[0], operands[1],
1175                               INTVAL (operands[2]));
1176   DONE;
1177 })
1178
1179 (define_expand "vec_initv8qi"
1180   [(match_operand:V8QI 0 "register_operand" "")
1181    (match_operand 1 "" "")]
1182   "TARGET_SSE"
1183 {
1184   ix86_expand_vector_init (false, operands[0], operands[1]);
1185   DONE;
1186 })
1187
1188 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1189 ;;
1190 ;; Miscellaneous
1191 ;;
1192 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1193
1194 (define_insn "mmx_uavgv8qi3"
1195   [(set (match_operand:V8QI 0 "register_operand" "=y")
1196         (truncate:V8QI
1197           (lshiftrt:V8HI
1198             (plus:V8HI
1199               (plus:V8HI
1200                 (zero_extend:V8HI
1201                   (match_operand:V8QI 1 "nonimmediate_operand" "%0"))
1202                 (zero_extend:V8HI
1203                   (match_operand:V8QI 2 "nonimmediate_operand" "ym")))
1204               (const_vector:V8HI [(const_int 1) (const_int 1)
1205                                   (const_int 1) (const_int 1)
1206                                   (const_int 1) (const_int 1)
1207                                   (const_int 1) (const_int 1)]))
1208             (const_int 1))))]
1209   "(TARGET_SSE || TARGET_3DNOW)
1210    && ix86_binary_operator_ok (PLUS, V8QImode, operands)"
1211 {
1212   /* These two instructions have the same operation, but their encoding
1213      is different.  Prefer the one that is de facto standard.  */
1214   if (TARGET_SSE || TARGET_3DNOW_A)
1215     return "pavgb\t{%2, %0|%0, %2}";
1216   else
1217     return "pavgusb\\t{%2, %0|%0, %2}";
1218 }
1219   [(set_attr "type" "mmxshft")
1220    (set_attr "mode" "DI")])
1221
1222 (define_insn "mmx_uavgv4hi3"
1223   [(set (match_operand:V4HI 0 "register_operand" "=y")
1224         (truncate:V4HI
1225           (lshiftrt:V4SI
1226             (plus:V4SI
1227               (plus:V4SI
1228                 (zero_extend:V4SI
1229                   (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
1230                 (zero_extend:V4SI
1231                   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
1232               (const_vector:V4SI [(const_int 1) (const_int 1)
1233                                   (const_int 1) (const_int 1)]))
1234             (const_int 1))))]
1235   "(TARGET_SSE || TARGET_3DNOW_A)
1236    && ix86_binary_operator_ok (PLUS, V4HImode, operands)"
1237   "pavgw\t{%2, %0|%0, %2}"
1238   [(set_attr "type" "mmxshft")
1239    (set_attr "mode" "DI")])
1240
1241 (define_insn "mmx_psadbw"
1242   [(set (match_operand:DI 0 "register_operand" "=y")
1243         (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
1244                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
1245                    UNSPEC_PSADBW))]
1246   "TARGET_SSE || TARGET_3DNOW_A"
1247   "psadbw\t{%2, %0|%0, %2}"
1248   [(set_attr "type" "mmxshft")
1249    (set_attr "mode" "DI")])
1250
1251 (define_insn "mmx_pmovmskb"
1252   [(set (match_operand:SI 0 "register_operand" "=r")
1253         (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
1254                    UNSPEC_MOVMSK))]
1255   "TARGET_SSE || TARGET_3DNOW_A"
1256   "pmovmskb\t{%1, %0|%0, %1}"
1257   [(set_attr "type" "ssecvt")
1258    (set_attr "mode" "V4SF")])
1259
1260 (define_expand "mmx_maskmovq"
1261   [(set (match_operand:V8QI 0 "memory_operand" "")
1262         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
1263                       (match_operand:V8QI 2 "register_operand" "y")
1264                       (match_dup 0)]
1265                      UNSPEC_MASKMOV))]
1266   "TARGET_SSE || TARGET_3DNOW_A"
1267   "")
1268
1269 (define_insn "*mmx_maskmovq"
1270   [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
1271         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
1272                       (match_operand:V8QI 2 "register_operand" "y")
1273                       (mem:V8QI (match_dup 0))]
1274                      UNSPEC_MASKMOV))]
1275   "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
1276   ;; @@@ check ordering of operands in intel/nonintel syntax
1277   "maskmovq\t{%2, %1|%1, %2}"
1278   [(set_attr "type" "mmxcvt")
1279    (set_attr "mode" "DI")])
1280
1281 (define_insn "*mmx_maskmovq_rex"
1282   [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
1283         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
1284                       (match_operand:V8QI 2 "register_operand" "y")
1285                       (mem:V8QI (match_dup 0))]
1286                      UNSPEC_MASKMOV))]
1287   "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
1288   ;; @@@ check ordering of operands in intel/nonintel syntax
1289   "maskmovq\t{%2, %1|%1, %2}"
1290   [(set_attr "type" "mmxcvt")
1291    (set_attr "mode" "DI")])
1292
1293 (define_insn "mmx_emms"
1294   [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
1295    (clobber (reg:XF 8))
1296    (clobber (reg:XF 9))
1297    (clobber (reg:XF 10))
1298    (clobber (reg:XF 11))
1299    (clobber (reg:XF 12))
1300    (clobber (reg:XF 13))
1301    (clobber (reg:XF 14))
1302    (clobber (reg:XF 15))
1303    (clobber (reg:DI 29))
1304    (clobber (reg:DI 30))
1305    (clobber (reg:DI 31))
1306    (clobber (reg:DI 32))
1307    (clobber (reg:DI 33))
1308    (clobber (reg:DI 34))
1309    (clobber (reg:DI 35))
1310    (clobber (reg:DI 36))]
1311   "TARGET_MMX"
1312   "emms"
1313   [(set_attr "type" "mmx")
1314    (set_attr "memory" "unknown")])
1315
1316 (define_insn "mmx_femms"
1317   [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
1318    (clobber (reg:XF 8))
1319    (clobber (reg:XF 9))
1320    (clobber (reg:XF 10))
1321    (clobber (reg:XF 11))
1322    (clobber (reg:XF 12))
1323    (clobber (reg:XF 13))
1324    (clobber (reg:XF 14))
1325    (clobber (reg:XF 15))
1326    (clobber (reg:DI 29))
1327    (clobber (reg:DI 30))
1328    (clobber (reg:DI 31))
1329    (clobber (reg:DI 32))
1330    (clobber (reg:DI 33))
1331    (clobber (reg:DI 34))
1332    (clobber (reg:DI 35))
1333    (clobber (reg:DI 36))]
1334   "TARGET_3DNOW"
1335   "femms"
1336   [(set_attr "type" "mmx")
1337    (set_attr "memory" "none")])