OSDN Git Service

PR target/19424
[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 "movmisalign<mode>"
179   [(set (match_operand:MMXMODE 0 "nonimmediate_operand" "")
180         (match_operand:MMXMODE 1 "nonimmediate_operand" ""))]
181   "TARGET_MMX"
182 {
183   ix86_expand_vector_move (<MODE>mode, operands);
184   DONE;
185 })
186
187 (define_insn "sse_movntdi"
188   [(set (match_operand:DI 0 "memory_operand" "=m")
189         (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
190                    UNSPEC_MOVNT))]
191   "TARGET_SSE || TARGET_3DNOW_A"
192   "movntq\t{%1, %0|%0, %1}"
193   [(set_attr "type" "mmxmov")
194    (set_attr "mode" "DI")])
195
196 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
197 ;;
198 ;; Parallel single-precision floating point arithmetic
199 ;;
200 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
201
202 (define_insn "mmx_addv2sf3"
203   [(set (match_operand:V2SF 0 "register_operand" "=y")
204         (plus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
205                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
206   "TARGET_3DNOW && ix86_binary_operator_ok (PLUS, V2SFmode, operands)"
207   "pfadd\\t{%2, %0|%0, %2}"
208   [(set_attr "type" "mmxadd")
209    (set_attr "mode" "V2SF")])
210
211 (define_insn "mmx_subv2sf3"
212   [(set (match_operand:V2SF 0 "register_operand" "=y,y")
213         (minus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "0,ym")
214                     (match_operand:V2SF 2 "nonimmediate_operand" "ym,0")))]
215   "TARGET_3DNOW && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
216   "@
217    pfsub\\t{%2, %0|%0, %2}
218    pfsubr\\t{%2, %0|%0, %2}"
219   [(set_attr "type" "mmxadd")
220    (set_attr "mode" "V2SF")])
221
222 (define_expand "mmx_subrv2sf3"
223   [(set (match_operand:V2SF 0 "register_operand" "")
224         (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "")
225                     (match_operand:V2SF 1 "nonimmediate_operand" "")))]
226   "TARGET_3DNOW && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
227   "")
228
229 (define_insn "mmx_mulv2sf3"
230   [(set (match_operand:V2SF 0 "register_operand" "=y")
231         (mult:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
232                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
233   "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V2SFmode, operands)"
234   "pfmul\\t{%2, %0|%0, %2}"
235   [(set_attr "type" "mmxmul")
236    (set_attr "mode" "V2SF")])
237
238 (define_insn "mmx_smaxv2sf3"
239   [(set (match_operand:V2SF 0 "register_operand" "=y")
240         (smax:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
241                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
242   "TARGET_3DNOW && ix86_binary_operator_ok (SMAX, V2SFmode, operands)"
243   "pfmax\\t{%2, %0|%0, %2}"
244   [(set_attr "type" "mmxadd")
245    (set_attr "mode" "V2SF")])
246
247 (define_insn "mmx_sminv2sf3"
248   [(set (match_operand:V2SF 0 "register_operand" "=y")
249         (smin:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
250                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
251   "TARGET_3DNOW && ix86_binary_operator_ok (SMIN, V2SFmode, operands)"
252   "pfmin\\t{%2, %0|%0, %2}"
253   [(set_attr "type" "mmxadd")
254    (set_attr "mode" "V2SF")])
255
256 (define_insn "mmx_rcpv2sf2"
257   [(set (match_operand:V2SF 0 "register_operand" "=y")
258         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
259                      UNSPEC_PFRCP))]
260   "TARGET_3DNOW"
261   "pfrcp\\t{%1, %0|%0, %1}"
262   [(set_attr "type" "mmx")
263    (set_attr "mode" "V2SF")])
264
265 (define_insn "mmx_rcpit1v2sf3"
266   [(set (match_operand:V2SF 0 "register_operand" "=y")
267         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
268                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
269                      UNSPEC_PFRCPIT1))]
270   "TARGET_3DNOW"
271   "pfrcpit1\\t{%2, %0|%0, %2}"
272   [(set_attr "type" "mmx")
273    (set_attr "mode" "V2SF")])
274
275 (define_insn "mmx_rcpit2v2sf3"
276   [(set (match_operand:V2SF 0 "register_operand" "=y")
277         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
278                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
279                      UNSPEC_PFRCPIT2))]
280   "TARGET_3DNOW"
281   "pfrcpit2\\t{%2, %0|%0, %2}"
282   [(set_attr "type" "mmx")
283    (set_attr "mode" "V2SF")])
284
285 (define_insn "mmx_rsqrtv2sf2"
286   [(set (match_operand:V2SF 0 "register_operand" "=y")
287         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
288                      UNSPEC_PFRSQRT))]
289   "TARGET_3DNOW"
290   "pfrsqrt\\t{%1, %0|%0, %1}"
291   [(set_attr "type" "mmx")
292    (set_attr "mode" "V2SF")])
293                 
294 (define_insn "mmx_rsqit1v2sf3"
295   [(set (match_operand:V2SF 0 "register_operand" "=y")
296         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
297                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
298                      UNSPEC_PFRSQIT1))]
299   "TARGET_3DNOW"
300   "pfrsqit1\\t{%2, %0|%0, %2}"
301   [(set_attr "type" "mmx")
302    (set_attr "mode" "V2SF")])
303
304 (define_insn "mmx_haddv2sf3"
305   [(set (match_operand:V2SF 0 "register_operand" "=y")
306         (vec_concat:V2SF
307           (plus:SF
308             (vec_select:SF
309               (match_operand:V2SF 1 "register_operand" "0")
310               (parallel [(const_int  0)]))
311             (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
312           (plus:SF
313             (vec_select:SF
314               (match_operand:V2SF 2 "nonimmediate_operand" "ym")
315               (parallel [(const_int  0)]))
316             (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
317   "TARGET_3DNOW"
318   "pfacc\\t{%2, %0|%0, %2}"
319   [(set_attr "type" "mmxadd")
320    (set_attr "mode" "V2SF")])
321
322 (define_insn "mmx_hsubv2sf3"
323   [(set (match_operand:V2SF 0 "register_operand" "=y")
324         (vec_concat:V2SF
325           (minus:SF
326             (vec_select:SF
327               (match_operand:V2SF 1 "register_operand" "0")
328               (parallel [(const_int  0)]))
329             (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
330           (minus:SF
331             (vec_select:SF
332               (match_operand:V2SF 2 "nonimmediate_operand" "ym")
333               (parallel [(const_int  0)]))
334             (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
335   "TARGET_3DNOW_A"
336   "pfnacc\\t{%2, %0|%0, %2}"
337   [(set_attr "type" "mmxadd")
338    (set_attr "mode" "V2SF")])
339
340 (define_insn "mmx_addsubv2sf3"
341   [(set (match_operand:V2SF 0 "register_operand" "=y")
342         (vec_merge:V2SF
343           (plus:V2SF
344             (match_operand:V2SF 1 "register_operand" "0")
345             (match_operand:V2SF 2 "nonimmediate_operand" "ym"))
346           (minus:V2SF (match_dup 1) (match_dup 2))
347           (const_int 1)))]
348   "TARGET_3DNOW_A"
349   "pfpnacc\\t{%2, %0|%0, %2}"
350   [(set_attr "type" "mmxadd")
351    (set_attr "mode" "V2SF")])
352
353 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
354 ;;
355 ;; Parallel single-precision floating point comparisons
356 ;;
357 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
358
359 (define_insn "mmx_gtv2sf3"
360   [(set (match_operand:V2SI 0 "register_operand" "=y")
361         (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
362                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
363   "TARGET_3DNOW"
364   "pfcmpgt\\t{%2, %0|%0, %2}"
365   [(set_attr "type" "mmxcmp")
366    (set_attr "mode" "V2SF")])
367
368 (define_insn "mmx_gev2sf3"
369   [(set (match_operand:V2SI 0 "register_operand" "=y")
370         (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
371                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
372   "TARGET_3DNOW"
373   "pfcmpge\\t{%2, %0|%0, %2}"
374   [(set_attr "type" "mmxcmp")
375    (set_attr "mode" "V2SF")])
376
377 (define_insn "mmx_eqv2sf3"
378   [(set (match_operand:V2SI 0 "register_operand" "=y")
379         (eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "%0")
380                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
381   "TARGET_3DNOW && ix86_binary_operator_ok (EQ, V2SFmode, operands)"
382   "pfcmpeq\\t{%2, %0|%0, %2}"
383   [(set_attr "type" "mmxcmp")
384    (set_attr "mode" "V2SF")])
385
386 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
387 ;;
388 ;; Parallel single-precision floating point conversion operations
389 ;;
390 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
391
392 (define_insn "mmx_pf2id"
393   [(set (match_operand:V2SI 0 "register_operand" "=y")
394         (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
395   "TARGET_3DNOW"
396   "pf2id\\t{%1, %0|%0, %1}"
397   [(set_attr "type" "mmxcvt")
398    (set_attr "mode" "V2SF")])
399
400 (define_insn "mmx_pf2iw"
401   [(set (match_operand:V2SI 0 "register_operand" "=y")
402         (sign_extend:V2SI
403           (ss_truncate:V2HI
404             (fix:V2SI
405               (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
406   "TARGET_3DNOW_A"
407   "pf2iw\\t{%1, %0|%0, %1}"
408   [(set_attr "type" "mmxcvt")
409    (set_attr "mode" "V2SF")])
410
411 (define_insn "mmx_pi2fw"
412   [(set (match_operand:V2SF 0 "register_operand" "=y")
413         (float:V2SF
414           (sign_extend:V2SI
415             (truncate:V2HI
416               (match_operand:V2SI 1 "nonimmediate_operand" "ym")))))]
417   "TARGET_3DNOW_A"
418   "pi2fw\\t{%1, %0|%0, %1}"
419   [(set_attr "type" "mmxcvt")
420    (set_attr "mode" "V2SF")])
421
422 (define_insn "mmx_floatv2si2"
423   [(set (match_operand:V2SF 0 "register_operand" "=y")
424         (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
425   "TARGET_3DNOW"
426   "pi2fd\\t{%1, %0|%0, %1}"
427   [(set_attr "type" "mmxcvt")
428    (set_attr "mode" "V2SF")])
429
430 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
431 ;;
432 ;; Parallel single-precision floating point element swizzling
433 ;;
434 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
435
436 (define_insn "mmx_pswapdv2sf2"
437   [(set (match_operand:V2SF 0 "register_operand" "=y")
438         (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
439                          (parallel [(const_int 1) (const_int 0)])))]
440   "TARGET_3DNOW_A"
441   "pswapd\\t{%1, %0|%0, %1}"
442   [(set_attr "type" "mmxcvt")
443    (set_attr "mode" "V2SF")])
444
445 (define_insn "*vec_dupv2sf"
446   [(set (match_operand:V2SF 0 "register_operand" "=y")
447         (vec_duplicate:V2SF
448           (match_operand:SF 1 "register_operand" "0")))]
449   "TARGET_MMX"
450   "punpckldq\t%0, %0"
451   [(set_attr "type" "mmxcvt")
452    (set_attr "mode" "DI")])
453
454 (define_insn "*mmx_concatv2sf"
455   [(set (match_operand:V2SF 0 "register_operand"     "=y,y")
456         (vec_concat:V2SF
457           (match_operand:SF 1 "nonimmediate_operand" " 0,rm")
458           (match_operand:SF 2 "vector_move_operand"  "ym,C")))]
459   "TARGET_MMX && !TARGET_SSE"
460   "@
461    punpckldq\t{%2, %0|%0, %2}
462    movd\t{%1, %0|%0, %1}"
463   [(set_attr "type" "mmxcvt,mmxmov")
464    (set_attr "mode" "DI")])
465
466 (define_expand "vec_setv2sf"
467   [(match_operand:V2SF 0 "register_operand" "")
468    (match_operand:SF 1 "register_operand" "")
469    (match_operand 2 "const_int_operand" "")]
470   "TARGET_MMX"
471 {
472   ix86_expand_vector_set (false, operands[0], operands[1],
473                           INTVAL (operands[2]));
474   DONE;
475 })
476
477 (define_expand "vec_extractv2sf"
478   [(match_operand:SF 0 "register_operand" "")
479    (match_operand:V2SF 1 "register_operand" "")
480    (match_operand 2 "const_int_operand" "")]
481   "TARGET_MMX"
482 {
483   ix86_expand_vector_extract (false, operands[0], operands[1],
484                               INTVAL (operands[2]));
485   DONE;
486 })
487
488 (define_expand "vec_initv2sf"
489   [(match_operand:V2SF 0 "register_operand" "")
490    (match_operand 1 "" "")]
491   "TARGET_SSE"
492 {
493   ix86_expand_vector_init (false, operands[0], operands[1]);
494   DONE;
495 })
496
497 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
498 ;;
499 ;; Parallel integral arithmetic
500 ;;
501 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
502
503 (define_insn "mmx_add<mode>3"
504   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
505         (plus:MMXMODEI
506           (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
507           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
508   "TARGET_MMX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
509   "padd<mmxvecsize>\t{%2, %0|%0, %2}"
510   [(set_attr "type" "mmxadd")
511    (set_attr "mode" "DI")])
512
513 (define_insn "mmx_adddi3"
514   [(set (match_operand:DI 0 "register_operand" "=y")
515         (unspec:DI
516          [(plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
517                    (match_operand:DI 2 "nonimmediate_operand" "ym"))]
518          UNSPEC_NOP))]
519   "TARGET_MMX && ix86_binary_operator_ok (PLUS, DImode, operands)"
520   "paddq\t{%2, %0|%0, %2}"
521   [(set_attr "type" "mmxadd")
522    (set_attr "mode" "DI")])
523
524 (define_insn "mmx_ssadd<mode>3"
525   [(set (match_operand:MMXMODE12 0 "register_operand" "=y")
526         (ss_plus:MMXMODE12
527           (match_operand:MMXMODE12 1 "nonimmediate_operand" "%0")
528           (match_operand:MMXMODE12 2 "nonimmediate_operand" "ym")))]
529   "TARGET_MMX"
530   "padds<mmxvecsize>\t{%2, %0|%0, %2}"
531   [(set_attr "type" "mmxadd")
532    (set_attr "mode" "DI")])
533
534 (define_insn "mmx_usadd<mode>3"
535   [(set (match_operand:MMXMODE12 0 "register_operand" "=y")
536         (us_plus:MMXMODE12
537           (match_operand:MMXMODE12 1 "nonimmediate_operand" "%0")
538           (match_operand:MMXMODE12 2 "nonimmediate_operand" "ym")))]
539   "TARGET_MMX"
540   "paddus<mmxvecsize>\t{%2, %0|%0, %2}"
541   [(set_attr "type" "mmxadd")
542    (set_attr "mode" "DI")])
543
544 (define_insn "mmx_sub<mode>3"
545   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
546         (minus:MMXMODEI
547           (match_operand:MMXMODEI 1 "register_operand" "0")
548           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
549   "TARGET_MMX"
550   "psub<mmxvecsize>\t{%2, %0|%0, %2}"
551   [(set_attr "type" "mmxadd")
552    (set_attr "mode" "DI")])
553
554 (define_insn "mmx_subdi3"
555   [(set (match_operand:DI 0 "register_operand" "=y")
556         (unspec:DI
557          [(minus:DI (match_operand:DI 1 "register_operand" "0")
558                     (match_operand:DI 2 "nonimmediate_operand" "ym"))]
559          UNSPEC_NOP))]
560   "TARGET_MMX"
561   "psubq\t{%2, %0|%0, %2}"
562   [(set_attr "type" "mmxadd")
563    (set_attr "mode" "DI")])
564
565 (define_insn "mmx_sssub<mode>3"
566   [(set (match_operand:MMXMODE12 0 "register_operand" "=y")
567         (ss_minus:MMXMODE12
568           (match_operand:MMXMODE12 1 "register_operand" "0")
569           (match_operand:MMXMODE12 2 "nonimmediate_operand" "ym")))]
570   "TARGET_MMX"
571   "psubs<mmxvecsize>\t{%2, %0|%0, %2}"
572   [(set_attr "type" "mmxadd")
573    (set_attr "mode" "DI")])
574
575 (define_insn "mmx_ussub<mode>3"
576   [(set (match_operand:MMXMODE12 0 "register_operand" "=y")
577         (us_minus:MMXMODE12
578           (match_operand:MMXMODE12 1 "register_operand" "0")
579           (match_operand:MMXMODE12 2 "nonimmediate_operand" "ym")))]
580   "TARGET_MMX"
581   "psubus<mmxvecsize>\t{%2, %0|%0, %2}"
582   [(set_attr "type" "mmxadd")
583    (set_attr "mode" "DI")])
584
585 (define_insn "mmx_mulv4hi3"
586   [(set (match_operand:V4HI 0 "register_operand" "=y")
587         (mult:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "%0")
588                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
589   "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
590   "pmullw\t{%2, %0|%0, %2}"
591   [(set_attr "type" "mmxmul")
592    (set_attr "mode" "DI")])
593
594 (define_insn "mmx_smulv4hi3_highpart"
595   [(set (match_operand:V4HI 0 "register_operand" "=y")
596         (truncate:V4HI
597          (lshiftrt:V4SI
598           (mult:V4SI (sign_extend:V4SI
599                       (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
600                      (sign_extend:V4SI
601                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
602           (const_int 16))))]
603   "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
604   "pmulhw\t{%2, %0|%0, %2}"
605   [(set_attr "type" "mmxmul")
606    (set_attr "mode" "DI")])
607
608 (define_insn "mmx_umulv4hi3_highpart"
609   [(set (match_operand:V4HI 0 "register_operand" "=y")
610         (truncate:V4HI
611          (lshiftrt:V4SI
612           (mult:V4SI (zero_extend:V4SI
613                       (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
614                      (zero_extend:V4SI
615                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
616           (const_int 16))))]
617   "(TARGET_SSE || TARGET_3DNOW_A)
618    && ix86_binary_operator_ok (MULT, V4HImode, operands)"
619   "pmulhuw\t{%2, %0|%0, %2}"
620   [(set_attr "type" "mmxmul")
621    (set_attr "mode" "DI")])
622
623 (define_insn "mmx_pmaddwd"
624   [(set (match_operand:V2SI 0 "register_operand" "=y")
625         (plus:V2SI
626           (mult:V2SI
627             (sign_extend:V2SI
628               (vec_select:V2HI
629                 (match_operand:V4HI 1 "nonimmediate_operand" "%0")
630                 (parallel [(const_int 0) (const_int 2)])))
631             (sign_extend:V2SI
632               (vec_select:V2HI
633                 (match_operand:V4HI 2 "nonimmediate_operand" "ym")
634                 (parallel [(const_int 0) (const_int 2)]))))
635           (mult:V2SI
636             (sign_extend:V2SI
637               (vec_select:V2HI (match_dup 1)
638                 (parallel [(const_int 1) (const_int 3)])))
639             (sign_extend:V2SI
640               (vec_select:V2HI (match_dup 2)
641                 (parallel [(const_int 1) (const_int 3)]))))))]
642   "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
643   "pmaddwd\t{%2, %0|%0, %2}"
644   [(set_attr "type" "mmxmul")
645    (set_attr "mode" "DI")])
646
647 (define_insn "mmx_pmulhrwv4hi3"
648   [(set (match_operand:V4HI 0 "register_operand" "=y")
649         (truncate:V4HI
650           (lshiftrt:V4SI
651             (plus:V4SI
652               (mult:V4SI
653                 (sign_extend:V4SI
654                   (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
655                 (sign_extend:V4SI
656                   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
657               (const_vector:V4SI [(const_int 32768) (const_int 32768)
658                                   (const_int 32768) (const_int 32768)]))
659             (const_int 16))))]
660   "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V4HImode, operands)"
661   "pmulhrw\\t{%2, %0|%0, %2}"
662   [(set_attr "type" "mmxmul")
663    (set_attr "mode" "DI")])
664
665 (define_insn "sse2_umulsidi3"
666   [(set (match_operand:DI 0 "register_operand" "=y")
667         (mult:DI
668           (zero_extend:DI
669             (vec_select:SI
670               (match_operand:V2SI 1 "nonimmediate_operand" "%0")
671               (parallel [(const_int 0)])))
672           (zero_extend:DI
673             (vec_select:SI
674               (match_operand:V2SI 2 "nonimmediate_operand" "ym")
675               (parallel [(const_int 0)])))))]
676   "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V2SImode, operands)"
677   "pmuludq\t{%2, %0|%0, %2}"
678   [(set_attr "type" "mmxmul")
679    (set_attr "mode" "DI")])
680
681 (define_insn "mmx_umaxv8qi3"
682   [(set (match_operand:V8QI 0 "register_operand" "=y")
683         (umax:V8QI (match_operand:V8QI 1 "nonimmediate_operand" "%0")
684                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
685   "(TARGET_SSE || TARGET_3DNOW_A)
686    && ix86_binary_operator_ok (UMAX, V8QImode, operands)"
687   "pmaxub\t{%2, %0|%0, %2}"
688   [(set_attr "type" "mmxadd")
689    (set_attr "mode" "DI")])
690
691 (define_insn "mmx_smaxv4hi3"
692   [(set (match_operand:V4HI 0 "register_operand" "=y")
693         (smax:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "%0")
694                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
695   "(TARGET_SSE || TARGET_3DNOW_A)
696    && ix86_binary_operator_ok (SMAX, V4HImode, operands)"
697   "pmaxsw\t{%2, %0|%0, %2}"
698   [(set_attr "type" "mmxadd")
699    (set_attr "mode" "DI")])
700
701 (define_insn "mmx_uminv8qi3"
702   [(set (match_operand:V8QI 0 "register_operand" "=y")
703         (umin:V8QI (match_operand:V8QI 1 "nonimmediate_operand" "%0")
704                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
705   "(TARGET_SSE || TARGET_3DNOW_A)
706    && ix86_binary_operator_ok (UMIN, V8QImode, operands)"
707   "pminub\t{%2, %0|%0, %2}"
708   [(set_attr "type" "mmxadd")
709    (set_attr "mode" "DI")])
710
711 (define_insn "mmx_sminv4hi3"
712   [(set (match_operand:V4HI 0 "register_operand" "=y")
713         (smin:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "%0")
714                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
715   "(TARGET_SSE || TARGET_3DNOW_A)
716    && ix86_binary_operator_ok (SMIN, V4HImode, operands)"
717   "pminsw\t{%2, %0|%0, %2}"
718   [(set_attr "type" "mmxadd")
719    (set_attr "mode" "DI")])
720
721 (define_insn "mmx_ashr<mode>3"
722   [(set (match_operand:MMXMODE24 0 "register_operand" "=y")
723         (ashiftrt:MMXMODE24
724           (match_operand:MMXMODE24 1 "register_operand" "0")
725           (match_operand:DI 2 "nonmemory_operand" "yi")))]
726   "TARGET_MMX"
727   "psra<mmxvecsize>\t{%2, %0|%0, %2}"
728   [(set_attr "type" "mmxshft")
729    (set_attr "mode" "DI")])
730
731 (define_insn "mmx_lshr<mode>3"
732   [(set (match_operand:MMXMODE24 0 "register_operand" "=y")
733         (lshiftrt:MMXMODE24
734           (match_operand:MMXMODE24 1 "register_operand" "0")
735           (match_operand:DI 2 "nonmemory_operand" "yi")))]
736   "TARGET_MMX"
737   "psrl<mmxvecsize>\t{%2, %0|%0, %2}"
738   [(set_attr "type" "mmxshft")
739    (set_attr "mode" "DI")])
740
741 (define_insn "mmx_lshrdi3"
742   [(set (match_operand:DI 0 "register_operand" "=y")
743         (unspec:DI
744           [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
745                        (match_operand:DI 2 "nonmemory_operand" "yi"))]
746           UNSPEC_NOP))]
747   "TARGET_MMX"
748   "psrlq\t{%2, %0|%0, %2}"
749   [(set_attr "type" "mmxshft")
750    (set_attr "mode" "DI")])
751
752 (define_insn "mmx_ashl<mode>3"
753   [(set (match_operand:MMXMODE24 0 "register_operand" "=y")
754         (ashift:MMXMODE24
755           (match_operand:MMXMODE24 1 "register_operand" "0")
756           (match_operand:DI 2 "nonmemory_operand" "yi")))]
757   "TARGET_MMX"
758   "psll<mmxvecsize>\t{%2, %0|%0, %2}"
759   [(set_attr "type" "mmxshft")
760    (set_attr "mode" "DI")])
761
762 (define_insn "mmx_ashldi3"
763   [(set (match_operand:DI 0 "register_operand" "=y")
764         (unspec:DI
765          [(ashift:DI (match_operand:DI 1 "register_operand" "0")
766                      (match_operand:DI 2 "nonmemory_operand" "yi"))]
767          UNSPEC_NOP))]
768   "TARGET_MMX"
769   "psllq\t{%2, %0|%0, %2}"
770   [(set_attr "type" "mmxshft")
771    (set_attr "mode" "DI")])
772
773 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
774 ;;
775 ;; Parallel integral comparisons
776 ;;
777 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
778
779 (define_insn "mmx_eq<mode>3"
780   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
781         (eq:MMXMODEI
782           (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
783           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
784   "TARGET_MMX && ix86_binary_operator_ok (EQ, <MODE>mode, operands)"
785   "pcmpeq<mmxvecsize>\t{%2, %0|%0, %2}"
786   [(set_attr "type" "mmxcmp")
787    (set_attr "mode" "DI")])
788
789 (define_insn "mmx_gt<mode>3"
790   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
791         (gt:MMXMODEI
792           (match_operand:MMXMODEI 1 "register_operand" "0")
793           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
794   "TARGET_MMX"
795   "pcmpgt<mmxvecsize>\t{%2, %0|%0, %2}"
796   [(set_attr "type" "mmxcmp")
797    (set_attr "mode" "DI")])
798
799 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
800 ;;
801 ;; Parallel integral logical operations
802 ;;
803 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
804
805 (define_insn "mmx_and<mode>3"
806   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
807         (and:MMXMODEI
808           (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
809           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
810   "TARGET_MMX && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
811   "pand\t{%2, %0|%0, %2}"
812   [(set_attr "type" "mmxadd")
813    (set_attr "mode" "DI")])
814
815 (define_insn "mmx_nand<mode>3"
816   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
817         (and:MMXMODEI
818           (not:MMXMODEI (match_operand:MMXMODEI 1 "register_operand" "0"))
819           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
820   "TARGET_MMX"
821   "pandn\t{%2, %0|%0, %2}"
822   [(set_attr "type" "mmxadd")
823    (set_attr "mode" "DI")])
824
825 (define_insn "mmx_ior<mode>3"
826   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
827         (ior:MMXMODEI
828           (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
829           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
830   "TARGET_MMX && ix86_binary_operator_ok (IOR, <MODE>mode, operands)"
831   "por\t{%2, %0|%0, %2}"
832   [(set_attr "type" "mmxadd")
833    (set_attr "mode" "DI")])
834
835 (define_insn "mmx_xor<mode>3"
836   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
837         (xor:MMXMODEI
838           (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
839           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
840   "TARGET_MMX && ix86_binary_operator_ok (XOR, <MODE>mode, operands)"
841   "pxor\t{%2, %0|%0, %2}"
842   [(set_attr "type" "mmxadd")
843    (set_attr "mode" "DI")
844    (set_attr "memory" "none")])
845
846 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
847 ;;
848 ;; Parallel integral element swizzling
849 ;;
850 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
851
852 (define_insn "mmx_packsswb"
853   [(set (match_operand:V8QI 0 "register_operand" "=y")
854         (vec_concat:V8QI
855           (ss_truncate:V4QI
856             (match_operand:V4HI 1 "register_operand" "0"))
857           (ss_truncate:V4QI
858             (match_operand:V4HI 2 "nonimmediate_operand" "ym"))))]
859   "TARGET_MMX"
860   "packsswb\t{%2, %0|%0, %2}"
861   [(set_attr "type" "mmxshft")
862    (set_attr "mode" "DI")])
863
864 (define_insn "mmx_packssdw"
865   [(set (match_operand:V4HI 0 "register_operand" "=y")
866         (vec_concat:V4HI
867           (ss_truncate:V2HI
868             (match_operand:V2SI 1 "register_operand" "0"))
869           (ss_truncate:V2HI
870             (match_operand:V2SI 2 "nonimmediate_operand" "ym"))))]
871   "TARGET_MMX"
872   "packssdw\t{%2, %0|%0, %2}"
873   [(set_attr "type" "mmxshft")
874    (set_attr "mode" "DI")])
875
876 (define_insn "mmx_packuswb"
877   [(set (match_operand:V8QI 0 "register_operand" "=y")
878         (vec_concat:V8QI
879           (us_truncate:V4QI
880             (match_operand:V4HI 1 "register_operand" "0"))
881           (us_truncate:V4QI
882             (match_operand:V4HI 2 "nonimmediate_operand" "ym"))))]
883   "TARGET_MMX"
884   "packuswb\t{%2, %0|%0, %2}"
885   [(set_attr "type" "mmxshft")
886    (set_attr "mode" "DI")])
887
888 (define_insn "mmx_punpckhbw"
889   [(set (match_operand:V8QI 0 "register_operand" "=y")
890         (vec_select:V8QI
891           (vec_concat:V16QI
892             (match_operand:V8QI 1 "register_operand" "0")
893             (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
894           (parallel [(const_int 4) (const_int 12)
895                      (const_int 5) (const_int 13)
896                      (const_int 6) (const_int 14)
897                      (const_int 7) (const_int 15)])))]
898   "TARGET_MMX"
899   "punpckhbw\t{%2, %0|%0, %2}"
900   [(set_attr "type" "mmxcvt")
901    (set_attr "mode" "DI")])
902
903 (define_insn "mmx_punpcklbw"
904   [(set (match_operand:V8QI 0 "register_operand" "=y")
905         (vec_select:V8QI
906           (vec_concat:V16QI
907             (match_operand:V8QI 1 "register_operand" "0")
908             (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
909           (parallel [(const_int 0) (const_int 8)
910                      (const_int 1) (const_int 9)
911                      (const_int 2) (const_int 10)
912                      (const_int 3) (const_int 11)])))]
913   "TARGET_MMX"
914   "punpcklbw\t{%2, %0|%0, %2}"
915   [(set_attr "type" "mmxcvt")
916    (set_attr "mode" "DI")])
917
918 (define_insn "mmx_punpckhwd"
919   [(set (match_operand:V4HI 0 "register_operand" "=y")
920         (vec_select:V4HI
921           (vec_concat:V8HI
922             (match_operand:V4HI 1 "register_operand" "0")
923             (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
924           (parallel [(const_int 2) (const_int 6)
925                      (const_int 3) (const_int 7)])))]
926   "TARGET_MMX"
927   "punpckhwd\t{%2, %0|%0, %2}"
928   [(set_attr "type" "mmxcvt")
929    (set_attr "mode" "DI")])
930
931 (define_insn "mmx_punpcklwd"
932   [(set (match_operand:V4HI 0 "register_operand" "=y")
933         (vec_select:V4HI
934           (vec_concat:V8HI
935             (match_operand:V4HI 1 "register_operand" "0")
936             (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
937           (parallel [(const_int 0) (const_int 4)
938                      (const_int 1) (const_int 5)])))]
939   "TARGET_MMX"
940   "punpcklwd\t{%2, %0|%0, %2}"
941   [(set_attr "type" "mmxcvt")
942    (set_attr "mode" "DI")])
943
944 (define_insn "mmx_punpckhdq"
945   [(set (match_operand:V2SI 0 "register_operand" "=y")
946         (vec_select:V2SI
947           (vec_concat:V4SI
948             (match_operand:V2SI 1 "register_operand" "0")
949             (match_operand:V2SI 2 "nonimmediate_operand" "ym"))
950           (parallel [(const_int 1)
951                      (const_int 3)])))]
952   "TARGET_MMX"
953   "punpckhdq\t{%2, %0|%0, %2}"
954   [(set_attr "type" "mmxcvt")
955    (set_attr "mode" "DI")])
956
957 (define_insn "mmx_punpckldq"
958   [(set (match_operand:V2SI 0 "register_operand" "=y")
959         (vec_select:V2SI
960           (vec_concat:V4SI
961             (match_operand:V2SI 1 "register_operand" "0")
962             (match_operand:V2SI 2 "nonimmediate_operand" "ym"))
963           (parallel [(const_int 0)
964                      (const_int 2)])))]
965   "TARGET_MMX"
966   "punpckldq\t{%2, %0|%0, %2}"
967   [(set_attr "type" "mmxcvt")
968    (set_attr "mode" "DI")])
969
970 (define_expand "mmx_pinsrw"
971   [(set (match_operand:V4HI 0 "register_operand" "")
972         (vec_merge:V4HI
973           (vec_duplicate:V4HI
974             (match_operand:SI 2 "nonimmediate_operand" ""))
975           (match_operand:V4HI 1 "register_operand" "")
976           (match_operand:SI 3 "const_0_to_3_operand" "")))]
977   "TARGET_SSE || TARGET_3DNOW_A"
978 {
979   operands[2] = gen_lowpart (HImode, operands[2]);
980   operands[3] = GEN_INT (1 << INTVAL (operands[3]));
981 })
982
983 (define_insn "*mmx_pinsrw"
984   [(set (match_operand:V4HI 0 "register_operand" "=y")
985         (vec_merge:V4HI
986           (vec_duplicate:V4HI
987             (match_operand:HI 2 "nonimmediate_operand" "rm"))
988           (match_operand:V4HI 1 "register_operand" "0")
989           (match_operand:SI 3 "const_pow2_1_to_8_operand" "n")))]
990   "TARGET_SSE || TARGET_3DNOW_A"
991 {
992   operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
993   return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}";
994 }
995   [(set_attr "type" "mmxcvt")
996    (set_attr "mode" "DI")])
997
998 (define_insn "mmx_pextrw"
999   [(set (match_operand:SI 0 "register_operand" "=r")
1000         (zero_extend:SI
1001           (vec_select:HI
1002             (match_operand:V4HI 1 "register_operand" "y")
1003             (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n")]))))]
1004   "TARGET_SSE || TARGET_3DNOW_A"
1005   "pextrw\t{%2, %1, %0|%0, %1, %2}"
1006   [(set_attr "type" "mmxcvt")
1007    (set_attr "mode" "DI")])
1008
1009 (define_expand "mmx_pshufw"
1010   [(match_operand:V4HI 0 "register_operand" "")
1011    (match_operand:V4HI 1 "nonimmediate_operand" "")
1012    (match_operand:SI 2 "const_int_operand" "")]
1013   "TARGET_SSE || TARGET_3DNOW_A"
1014 {
1015   int mask = INTVAL (operands[2]);
1016   emit_insn (gen_mmx_pshufw_1 (operands[0], operands[1],
1017                                GEN_INT ((mask >> 0) & 3),
1018                                GEN_INT ((mask >> 2) & 3),
1019                                GEN_INT ((mask >> 4) & 3),
1020                                GEN_INT ((mask >> 6) & 3)));
1021   DONE;
1022 })
1023
1024 (define_insn "mmx_pshufw_1"
1025   [(set (match_operand:V4HI 0 "register_operand" "=y")
1026         (vec_select:V4HI
1027           (match_operand:V4HI 1 "nonimmediate_operand" "ym")
1028           (parallel [(match_operand 2 "const_0_to_3_operand" "")
1029                      (match_operand 3 "const_0_to_3_operand" "")
1030                      (match_operand 4 "const_0_to_3_operand" "")
1031                      (match_operand 5 "const_0_to_3_operand" "")])))]
1032   "TARGET_SSE || TARGET_3DNOW_A"
1033 {
1034   int mask = 0;
1035   mask |= INTVAL (operands[2]) << 0;
1036   mask |= INTVAL (operands[3]) << 2;
1037   mask |= INTVAL (operands[4]) << 4;
1038   mask |= INTVAL (operands[5]) << 6;
1039   operands[2] = GEN_INT (mask);
1040
1041   return "pshufw\t{%2, %1, %0|%0, %1, %2}";
1042 }
1043   [(set_attr "type" "mmxcvt")
1044    (set_attr "mode" "DI")])
1045
1046 (define_insn "mmx_pswapdv2si2"
1047   [(set (match_operand:V2SI 0 "register_operand" "=y")
1048         (vec_select:V2SI
1049           (match_operand:V2SI 1 "nonimmediate_operand" "ym")
1050           (parallel [(const_int 1) (const_int 0)])))]
1051   "TARGET_3DNOW_A"
1052   "pswapd\\t{%1, %0|%0, %1}"
1053   [(set_attr "type" "mmxcvt")
1054    (set_attr "mode" "DI")])
1055
1056 (define_insn "*vec_dupv4hi"
1057   [(set (match_operand:V4HI 0 "register_operand" "=y")
1058         (vec_duplicate:V4HI
1059           (truncate:HI
1060             (match_operand:SI 1 "register_operand" "0"))))]
1061   "TARGET_MMX"
1062   "pshufw\t{$0, %0, %0|%0, %0, 0}"
1063   [(set_attr "type" "mmxcvt")
1064    (set_attr "mode" "DI")])
1065
1066 (define_insn "*vec_dupv2si"
1067   [(set (match_operand:V2SI 0 "register_operand" "=y")
1068         (vec_duplicate:V2SI
1069           (match_operand:SI 1 "register_operand" "0")))]
1070   "TARGET_MMX"
1071   "punpckldq\t%0, %0"
1072   [(set_attr "type" "mmxcvt")
1073    (set_attr "mode" "DI")])
1074
1075 (define_insn "*mmx_concatv2si"
1076   [(set (match_operand:V2SI 0 "register_operand"     "=y,y")
1077         (vec_concat:V2SI
1078           (match_operand:SI 1 "nonimmediate_operand" " 0,rm")
1079           (match_operand:SI 2 "vector_move_operand"  "ym,C")))]
1080   "TARGET_MMX && !TARGET_SSE"
1081   "@
1082    punpckldq\t{%2, %0|%0, %2}
1083    movd\t{%1, %0|%0, %1}"
1084   [(set_attr "type" "mmxcvt,mmxmov")
1085    (set_attr "mode" "DI")])
1086
1087 (define_expand "vec_setv2si"
1088   [(match_operand:V2SI 0 "register_operand" "")
1089    (match_operand:SI 1 "register_operand" "")
1090    (match_operand 2 "const_int_operand" "")]
1091   "TARGET_MMX"
1092 {
1093   ix86_expand_vector_set (false, operands[0], operands[1],
1094                           INTVAL (operands[2]));
1095   DONE;
1096 })
1097
1098 (define_expand "vec_extractv2si"
1099   [(match_operand:SI 0 "register_operand" "")
1100    (match_operand:V2SI 1 "register_operand" "")
1101    (match_operand 2 "const_int_operand" "")]
1102   "TARGET_MMX"
1103 {
1104   ix86_expand_vector_extract (false, operands[0], operands[1],
1105                               INTVAL (operands[2]));
1106   DONE;
1107 })
1108
1109 (define_expand "vec_initv2si"
1110   [(match_operand:V2SI 0 "register_operand" "")
1111    (match_operand 1 "" "")]
1112   "TARGET_SSE"
1113 {
1114   ix86_expand_vector_init (false, operands[0], operands[1]);
1115   DONE;
1116 })
1117
1118 (define_expand "vec_setv4hi"
1119   [(match_operand:V4HI 0 "register_operand" "")
1120    (match_operand:HI 1 "register_operand" "")
1121    (match_operand 2 "const_int_operand" "")]
1122   "TARGET_MMX"
1123 {
1124   ix86_expand_vector_set (false, operands[0], operands[1],
1125                           INTVAL (operands[2]));
1126   DONE;
1127 })
1128
1129 (define_expand "vec_extractv4hi"
1130   [(match_operand:HI 0 "register_operand" "")
1131    (match_operand:V4HI 1 "register_operand" "")
1132    (match_operand 2 "const_int_operand" "")]
1133   "TARGET_MMX"
1134 {
1135   ix86_expand_vector_extract (false, operands[0], operands[1],
1136                               INTVAL (operands[2]));
1137   DONE;
1138 })
1139
1140 (define_expand "vec_initv4hi"
1141   [(match_operand:V4HI 0 "register_operand" "")
1142    (match_operand 1 "" "")]
1143   "TARGET_SSE"
1144 {
1145   ix86_expand_vector_init (false, operands[0], operands[1]);
1146   DONE;
1147 })
1148
1149 (define_expand "vec_setv8qi"
1150   [(match_operand:V8QI 0 "register_operand" "")
1151    (match_operand:QI 1 "register_operand" "")
1152    (match_operand 2 "const_int_operand" "")]
1153   "TARGET_MMX"
1154 {
1155   ix86_expand_vector_set (false, operands[0], operands[1],
1156                           INTVAL (operands[2]));
1157   DONE;
1158 })
1159
1160 (define_expand "vec_extractv8qi"
1161   [(match_operand:QI 0 "register_operand" "")
1162    (match_operand:V8QI 1 "register_operand" "")
1163    (match_operand 2 "const_int_operand" "")]
1164   "TARGET_MMX"
1165 {
1166   ix86_expand_vector_extract (false, operands[0], operands[1],
1167                               INTVAL (operands[2]));
1168   DONE;
1169 })
1170
1171 (define_expand "vec_initv8qi"
1172   [(match_operand:V8QI 0 "register_operand" "")
1173    (match_operand 1 "" "")]
1174   "TARGET_SSE"
1175 {
1176   ix86_expand_vector_init (false, operands[0], operands[1]);
1177   DONE;
1178 })
1179
1180 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1181 ;;
1182 ;; Miscellaneous
1183 ;;
1184 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1185
1186 (define_insn "mmx_uavgv8qi3"
1187   [(set (match_operand:V8QI 0 "register_operand" "=y")
1188         (truncate:V8QI
1189           (lshiftrt:V8HI
1190             (plus:V8HI
1191               (plus:V8HI
1192                 (zero_extend:V8HI
1193                   (match_operand:V8QI 1 "nonimmediate_operand" "%0"))
1194                 (zero_extend:V8HI
1195                   (match_operand:V8QI 2 "nonimmediate_operand" "ym")))
1196               (const_vector:V8HI [(const_int 1) (const_int 1)
1197                                   (const_int 1) (const_int 1)
1198                                   (const_int 1) (const_int 1)
1199                                   (const_int 1) (const_int 1)]))
1200             (const_int 1))))]
1201   "(TARGET_SSE || TARGET_3DNOW)
1202    && ix86_binary_operator_ok (PLUS, V8QImode, operands)"
1203 {
1204   /* These two instructions have the same operation, but their encoding
1205      is different.  Prefer the one that is de facto standard.  */
1206   if (TARGET_SSE || TARGET_3DNOW_A)
1207     return "pavgb\t{%2, %0|%0, %2}";
1208   else
1209     return "pavgusb\\t{%2, %0|%0, %2}";
1210 }
1211   [(set_attr "type" "mmxshft")
1212    (set_attr "mode" "DI")])
1213
1214 (define_insn "mmx_uavgv4hi3"
1215   [(set (match_operand:V4HI 0 "register_operand" "=y")
1216         (truncate:V4HI
1217           (lshiftrt:V4SI
1218             (plus:V4SI
1219               (plus:V4SI
1220                 (zero_extend:V4SI
1221                   (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
1222                 (zero_extend:V4SI
1223                   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
1224               (const_vector:V4SI [(const_int 1) (const_int 1)
1225                                   (const_int 1) (const_int 1)]))
1226             (const_int 1))))]
1227   "(TARGET_SSE || TARGET_3DNOW_A)
1228    && ix86_binary_operator_ok (PLUS, V4HImode, operands)"
1229   "pavgw\t{%2, %0|%0, %2}"
1230   [(set_attr "type" "mmxshft")
1231    (set_attr "mode" "DI")])
1232
1233 (define_insn "mmx_psadbw"
1234   [(set (match_operand:DI 0 "register_operand" "=y")
1235         (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
1236                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
1237                    UNSPEC_PSADBW))]
1238   "TARGET_SSE || TARGET_3DNOW_A"
1239   "psadbw\t{%2, %0|%0, %2}"
1240   [(set_attr "type" "mmxshft")
1241    (set_attr "mode" "DI")])
1242
1243 (define_insn "mmx_pmovmskb"
1244   [(set (match_operand:SI 0 "register_operand" "=r")
1245         (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
1246                    UNSPEC_MOVMSK))]
1247   "TARGET_SSE || TARGET_3DNOW_A"
1248   "pmovmskb\t{%1, %0|%0, %1}"
1249   [(set_attr "type" "ssecvt")
1250    (set_attr "mode" "V4SF")])
1251
1252 (define_expand "mmx_maskmovq"
1253   [(set (match_operand:V8QI 0 "memory_operand" "")
1254         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
1255                       (match_operand:V8QI 2 "register_operand" "y")
1256                       (match_dup 0)]
1257                      UNSPEC_MASKMOV))]
1258   "TARGET_SSE || TARGET_3DNOW_A"
1259   "")
1260
1261 (define_insn "*mmx_maskmovq"
1262   [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
1263         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
1264                       (match_operand:V8QI 2 "register_operand" "y")
1265                       (mem:V8QI (match_dup 0))]
1266                      UNSPEC_MASKMOV))]
1267   "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
1268   ;; @@@ check ordering of operands in intel/nonintel syntax
1269   "maskmovq\t{%2, %1|%1, %2}"
1270   [(set_attr "type" "mmxcvt")
1271    (set_attr "mode" "DI")])
1272
1273 (define_insn "*mmx_maskmovq_rex"
1274   [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
1275         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
1276                       (match_operand:V8QI 2 "register_operand" "y")
1277                       (mem:V8QI (match_dup 0))]
1278                      UNSPEC_MASKMOV))]
1279   "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
1280   ;; @@@ check ordering of operands in intel/nonintel syntax
1281   "maskmovq\t{%2, %1|%1, %2}"
1282   [(set_attr "type" "mmxcvt")
1283    (set_attr "mode" "DI")])
1284
1285 (define_insn "mmx_emms"
1286   [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
1287    (clobber (reg:XF 8))
1288    (clobber (reg:XF 9))
1289    (clobber (reg:XF 10))
1290    (clobber (reg:XF 11))
1291    (clobber (reg:XF 12))
1292    (clobber (reg:XF 13))
1293    (clobber (reg:XF 14))
1294    (clobber (reg:XF 15))
1295    (clobber (reg:DI 29))
1296    (clobber (reg:DI 30))
1297    (clobber (reg:DI 31))
1298    (clobber (reg:DI 32))
1299    (clobber (reg:DI 33))
1300    (clobber (reg:DI 34))
1301    (clobber (reg:DI 35))
1302    (clobber (reg:DI 36))]
1303   "TARGET_MMX"
1304   "emms"
1305   [(set_attr "type" "mmx")
1306    (set_attr "memory" "unknown")])
1307
1308 (define_insn "mmx_femms"
1309   [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
1310    (clobber (reg:XF 8))
1311    (clobber (reg:XF 9))
1312    (clobber (reg:XF 10))
1313    (clobber (reg:XF 11))
1314    (clobber (reg:XF 12))
1315    (clobber (reg:XF 13))
1316    (clobber (reg:XF 14))
1317    (clobber (reg:XF 15))
1318    (clobber (reg:DI 29))
1319    (clobber (reg:DI 30))
1320    (clobber (reg:DI 31))
1321    (clobber (reg:DI 32))
1322    (clobber (reg:DI 33))
1323    (clobber (reg:DI 34))
1324    (clobber (reg:DI 35))
1325    (clobber (reg:DI 36))]
1326   "TARGET_3DNOW"
1327   "femms"
1328   [(set_attr "type" "mmx")
1329    (set_attr "memory" "none")])