OSDN Git Service

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