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