Merge branch 'vendor/GCC44'
[dragonfly.git] / contrib / gcc-4.4 / gcc / config / i386 / mmx.md
1 ;; GCC machine description for MMX and 3dNOW! instructions
2 ;; Copyright (C) 2005, 2007, 2008
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 (define_mode_iterator MMXMODEI8 [V8QI V4HI V2SI V1DI])
36
37 ;; All 8-byte vector modes handled by MMX
38 (define_mode_iterator MMXMODE [V8QI V4HI V2SI V1DI V2SF])
39
40 ;; Mix-n-match
41 (define_mode_iterator MMXMODE12 [V8QI V4HI])
42 (define_mode_iterator MMXMODE24 [V4HI V2SI])
43 (define_mode_iterator MMXMODE248 [V4HI V2SI V1DI])
44
45 ;; Mapping from integer vector mode to mnemonic suffix
46 (define_mode_attr mmxvecsize [(V8QI "b") (V4HI "w") (V2SI "d") (V1DI "q")])
47
48 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
49 ;;
50 ;; Move patterns
51 ;;
52 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
53
54 ;; All of these patterns are enabled for MMX as well as 3dNOW.
55 ;; This is essential for maintaining stable calling conventions.
56
57 (define_expand "mov<mode>"
58   [(set (match_operand:MMXMODEI8 0 "nonimmediate_operand" "")
59         (match_operand:MMXMODEI8 1 "nonimmediate_operand" ""))]
60   "TARGET_MMX"
61 {
62   ix86_expand_vector_move (<MODE>mode, operands);
63   DONE;
64 })
65
66 (define_insn "*mov<mode>_internal_rex64"
67   [(set (match_operand:MMXMODEI8 0 "nonimmediate_operand"
68                                 "=rm,r,!?y,!?y ,m  ,!y,*Y2,x,x ,m,r,Yi")
69         (match_operand:MMXMODEI8 1 "vector_move_operand"
70                                 "Cr ,m,C  ,!?ym,!?y,*Y2,!y,C,xm,x,Yi,r"))]
71   "TARGET_64BIT && TARGET_MMX
72    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
73   "@
74     mov{q}\t{%1, %0|%0, %1}
75     mov{q}\t{%1, %0|%0, %1}
76     pxor\t%0, %0
77     movq\t{%1, %0|%0, %1}
78     movq\t{%1, %0|%0, %1}
79     movdq2q\t{%1, %0|%0, %1}
80     movq2dq\t{%1, %0|%0, %1}
81     %vpxor\t%0, %d0
82     %vmovq\t{%1, %0|%0, %1}
83     %vmovq\t{%1, %0|%0, %1}
84     %vmovq\t{%1, %0|%0, %1}
85     %vmovq\t{%1, %0|%0, %1}"
86   [(set_attr "type" "imov,imov,mmx,mmxmov,mmxmov,ssecvt,ssecvt,sselog1,ssemov,ssemov,ssemov,ssemov")
87    (set_attr "unit" "*,*,*,*,*,mmx,mmx,*,*,*,*,*")
88    (set (attr "prefix")
89      (if_then_else (eq_attr "alternative" "7,8,9,10,11")
90        (const_string "maybe_vex")
91        (const_string "orig")))
92    (set_attr "mode" "DI")])
93
94 (define_insn "*mov<mode>_internal_avx"
95   [(set (match_operand:MMXMODEI8 0 "nonimmediate_operand"
96                         "=!?y,!?y,m  ,!y ,*Y2,*Y2,*Y2 ,m  ,r  ,m")
97         (match_operand:MMXMODEI8 1 "vector_move_operand"
98                         "C   ,!ym,!?y,*Y2,!y ,C  ,*Y2m,*Y2,irm,r"))]
99   "TARGET_AVX
100    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
101   "@
102     pxor\t%0, %0
103     movq\t{%1, %0|%0, %1}
104     movq\t{%1, %0|%0, %1}
105     movdq2q\t{%1, %0|%0, %1}
106     movq2dq\t{%1, %0|%0, %1}
107     vpxor\t%0, %0, %0
108     vmovq\t{%1, %0|%0, %1}
109     vmovq\t{%1, %0|%0, %1}
110     #
111     #"
112   [(set_attr "type" "mmx,mmxmov,mmxmov,ssecvt,ssecvt,sselog1,ssemov,ssemov,*,*")
113    (set_attr "unit" "*,*,*,mmx,mmx,*,*,*,*,*")
114    (set (attr "prefix")
115      (if_then_else (eq_attr "alternative" "5,6,7")
116        (const_string "vex")
117        (const_string "orig")))
118    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,DI,DI,DI")])
119
120 (define_insn "*mov<mode>_internal"
121   [(set (match_operand:MMXMODEI8 0 "nonimmediate_operand"
122                         "=!?y,!?y,m  ,!y ,*Y2,*Y2,*Y2 ,m  ,*x,*x,*x,m ,r  ,m")
123         (match_operand:MMXMODEI8 1 "vector_move_operand"
124                         "C   ,!ym,!?y,*Y2,!y ,C  ,*Y2m,*Y2,C ,*x,m ,*x,irm,r"))]
125   "TARGET_MMX
126    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
127   "@
128     pxor\t%0, %0
129     movq\t{%1, %0|%0, %1}
130     movq\t{%1, %0|%0, %1}
131     movdq2q\t{%1, %0|%0, %1}
132     movq2dq\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     xorps\t%0, %0
137     movaps\t{%1, %0|%0, %1}
138     movlps\t{%1, %0|%0, %1}
139     movlps\t{%1, %0|%0, %1}
140     #
141     #"
142   [(set_attr "type" "mmx,mmxmov,mmxmov,ssecvt,ssecvt,sselog1,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov,*,*")
143    (set_attr "unit" "*,*,*,mmx,mmx,*,*,*,*,*,*,*,*,*")
144    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,DI,V4SF,V4SF,V2SF,V2SF,DI,DI")])
145
146 (define_expand "movv2sf"
147   [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
148         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
149   "TARGET_MMX"
150 {
151   ix86_expand_vector_move (V2SFmode, operands);
152   DONE;
153 })
154
155 (define_insn "*movv2sf_internal_rex64_avx"
156   [(set (match_operand:V2SF 0 "nonimmediate_operand"
157                                 "=rm,r ,!?y,!?y ,m ,!y,Y2,x,x,x,m,r,x")
158         (match_operand:V2SF 1 "vector_move_operand"
159                                 "Cr ,m ,C  ,!?ym,!y,Y2,!y,C,x,m,x,x,r"))]
160   "TARGET_64BIT && TARGET_AVX
161    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
162   "@
163     mov{q}\t{%1, %0|%0, %1}
164     mov{q}\t{%1, %0|%0, %1}
165     pxor\t%0, %0
166     movq\t{%1, %0|%0, %1}
167     movq\t{%1, %0|%0, %1}
168     movdq2q\t{%1, %0|%0, %1}
169     movq2dq\t{%1, %0|%0, %1}
170     vxorps\t%0, %0, %0
171     vmovaps\t{%1, %0|%0, %1}
172     vmovlps\t{%1, %0, %0|%0, %0, %1}
173     vmovlps\t{%1, %0|%0, %1}
174     vmovq\t{%1, %0|%0, %1}
175     vmovq\t{%1, %0|%0, %1}"
176   [(set_attr "type" "imov,imov,mmx,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,sselog1,ssemov,ssemov,ssemov,ssemov")
177    (set_attr "unit" "*,*,*,*,*,mmx,mmx,*,*,*,*,*,*")
178    (set (attr "prefix")
179      (if_then_else (eq_attr "alternative" "7,8,9,10,11,12")
180        (const_string "vex")
181        (const_string "orig")))
182    (set_attr "mode" "DI,DI,DI,DI,DI,DI,DI,V4SF,V4SF,V2SF,V2SF,DI,DI")])
183
184 (define_insn "*movv2sf_internal_rex64"
185   [(set (match_operand:V2SF 0 "nonimmediate_operand"
186                                 "=rm,r ,!?y,!?y ,m ,!y,*Y2,x,x,x,m,r,Yi")
187         (match_operand:V2SF 1 "vector_move_operand"
188                                 "Cr ,m ,C  ,!?ym,!y,*Y2,!y,C,x,m,x,Yi,r"))]
189   "TARGET_64BIT && TARGET_MMX
190    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
191   "@
192     mov{q}\t{%1, %0|%0, %1}
193     mov{q}\t{%1, %0|%0, %1}
194     pxor\t%0, %0
195     movq\t{%1, %0|%0, %1}
196     movq\t{%1, %0|%0, %1}
197     movdq2q\t{%1, %0|%0, %1}
198     movq2dq\t{%1, %0|%0, %1}
199     xorps\t%0, %0
200     movaps\t{%1, %0|%0, %1}
201     movlps\t{%1, %0|%0, %1}
202     movlps\t{%1, %0|%0, %1}
203     movd\t{%1, %0|%0, %1}
204     movd\t{%1, %0|%0, %1}"
205   [(set_attr "type" "imov,imov,mmx,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,sselog1,ssemov,ssemov,ssemov,ssemov")
206    (set_attr "unit" "*,*,*,*,*,mmx,mmx,*,*,*,*,*,*")
207    (set_attr "mode" "DI,DI,DI,DI,DI,DI,DI,V4SF,V4SF,V2SF,V2SF,DI,DI")])
208
209 (define_insn "*movv2sf_internal_avx"
210   [(set (match_operand:V2SF 0 "nonimmediate_operand"
211                         "=!?y,!?y ,m  ,!y ,*Y2,*x,*x,*x,m ,r  ,m")
212         (match_operand:V2SF 1 "vector_move_operand"
213                         "C   ,!?ym,!?y,*Y2,!y ,C ,*x,m ,*x,irm,r"))]
214   "TARGET_AVX
215    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
216   "@
217     pxor\t%0, %0
218     movq\t{%1, %0|%0, %1}
219     movq\t{%1, %0|%0, %1}
220     movdq2q\t{%1, %0|%0, %1}
221     movq2dq\t{%1, %0|%0, %1}
222     vxorps\t%0, %0, %0
223     vmovaps\t{%1, %0|%0, %1}
224     vmovlps\t{%1, %0, %0|%0, %0, %1}
225     vmovlps\t{%1, %0|%0, %1}
226     #
227     #"
228   [(set_attr "type" "mmx,mmxmov,mmxmov,ssecvt,ssecvt,sselog1,ssemov,ssemov,ssemov,*,*")
229    (set_attr "unit" "*,*,*,mmx,mmx,*,*,*,*,*,*")
230    (set (attr "prefix")
231      (if_then_else (eq_attr "alternative" "5,6,7,8")
232        (const_string "vex")
233        (const_string "orig")))
234    (set_attr "mode" "DI,DI,DI,DI,DI,V4SF,V4SF,V2SF,V2SF,DI,DI")])
235
236 (define_insn "*movv2sf_internal"
237   [(set (match_operand:V2SF 0 "nonimmediate_operand"
238                         "=!?y,!?y ,m  ,!y ,*Y2,*x,*x,*x,m ,r  ,m")
239         (match_operand:V2SF 1 "vector_move_operand"
240                         "C   ,!?ym,!?y,*Y2,!y ,C ,*x,m ,*x,irm,r"))]
241   "TARGET_MMX
242    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
243   "@
244     pxor\t%0, %0
245     movq\t{%1, %0|%0, %1}
246     movq\t{%1, %0|%0, %1}
247     movdq2q\t{%1, %0|%0, %1}
248     movq2dq\t{%1, %0|%0, %1}
249     xorps\t%0, %0
250     movaps\t{%1, %0|%0, %1}
251     movlps\t{%1, %0|%0, %1}
252     movlps\t{%1, %0|%0, %1}
253     #
254     #"
255   [(set_attr "type" "mmx,mmxmov,mmxmov,ssecvt,ssecvt,sselog1,ssemov,ssemov,ssemov,*,*")
256    (set_attr "unit" "*,*,*,mmx,mmx,*,*,*,*,*,*")
257    (set_attr "mode" "DI,DI,DI,DI,DI,V4SF,V4SF,V2SF,V2SF,DI,DI")])
258
259 ;; %%% This multiword shite has got to go.
260 (define_split
261   [(set (match_operand:MMXMODE 0 "nonimmediate_operand" "")
262         (match_operand:MMXMODE 1 "general_operand" ""))]
263   "!TARGET_64BIT && reload_completed
264    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
265    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
266   [(const_int 0)]
267   "ix86_split_long_move (operands); DONE;")
268
269 (define_expand "push<mode>1"
270   [(match_operand:MMXMODE 0 "register_operand" "")]
271   "TARGET_MMX"
272 {
273   ix86_expand_push (<MODE>mode, operands[0]);
274   DONE;
275 })
276
277 (define_expand "movmisalign<mode>"
278   [(set (match_operand:MMXMODE 0 "nonimmediate_operand" "")
279         (match_operand:MMXMODE 1 "nonimmediate_operand" ""))]
280   "TARGET_MMX"
281 {
282   ix86_expand_vector_move (<MODE>mode, operands);
283   DONE;
284 })
285
286 (define_insn "sse_movntdi"
287   [(set (match_operand:DI 0 "memory_operand" "=m")
288         (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
289                    UNSPEC_MOVNT))]
290   "TARGET_SSE || TARGET_3DNOW_A"
291   "movntq\t{%1, %0|%0, %1}"
292   [(set_attr "type" "mmxmov")
293    (set_attr "mode" "DI")])
294
295 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
296 ;;
297 ;; Parallel single-precision floating point arithmetic
298 ;;
299 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
300
301 (define_expand "mmx_addv2sf3"
302   [(set (match_operand:V2SF 0 "register_operand" "")
303         (plus:V2SF
304           (match_operand:V2SF 1 "nonimmediate_operand" "")
305           (match_operand:V2SF 2 "nonimmediate_operand" "")))]
306   "TARGET_3DNOW"
307   "ix86_fixup_binary_operands_no_copy (PLUS, V2SFmode, operands);")
308
309 (define_insn "*mmx_addv2sf3"
310   [(set (match_operand:V2SF 0 "register_operand" "=y")
311         (plus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
312                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
313   "TARGET_3DNOW && ix86_binary_operator_ok (PLUS, V2SFmode, operands)"
314   "pfadd\t{%2, %0|%0, %2}"
315   [(set_attr "type" "mmxadd")
316    (set_attr "mode" "V2SF")])
317
318 (define_expand "mmx_subv2sf3"
319   [(set (match_operand:V2SF 0 "register_operand" "")
320         (minus:V2SF (match_operand:V2SF 1 "register_operand" "")
321                     (match_operand:V2SF 2 "nonimmediate_operand" "")))]
322   "TARGET_3DNOW"
323   "")
324
325 (define_expand "mmx_subrv2sf3"
326   [(set (match_operand:V2SF 0 "register_operand" "")
327         (minus:V2SF (match_operand:V2SF 2 "register_operand" "")
328                     (match_operand:V2SF 1 "nonimmediate_operand" "")))]
329   "TARGET_3DNOW"
330   "")
331
332 (define_insn "*mmx_subv2sf3"
333   [(set (match_operand:V2SF 0 "register_operand" "=y,y")
334         (minus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "0,ym")
335                     (match_operand:V2SF 2 "nonimmediate_operand" "ym,0")))]
336   "TARGET_3DNOW && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
337   "@
338    pfsub\t{%2, %0|%0, %2}
339    pfsubr\t{%1, %0|%0, %1}"
340   [(set_attr "type" "mmxadd")
341    (set_attr "mode" "V2SF")])
342
343 (define_expand "mmx_mulv2sf3"
344   [(set (match_operand:V2SF 0 "register_operand" "")
345         (mult:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "")
346                    (match_operand:V2SF 2 "nonimmediate_operand" "")))]
347   "TARGET_3DNOW"
348   "ix86_fixup_binary_operands_no_copy (MULT, V2SFmode, operands);")
349
350 (define_insn "*mmx_mulv2sf3"
351   [(set (match_operand:V2SF 0 "register_operand" "=y")
352         (mult:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
353                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
354   "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V2SFmode, operands)"
355   "pfmul\t{%2, %0|%0, %2}"
356   [(set_attr "type" "mmxmul")
357    (set_attr "mode" "V2SF")])
358
359 ;; ??? For !flag_finite_math_only, the representation with SMIN/SMAX
360 ;; isn't really correct, as those rtl operators aren't defined when
361 ;; applied to NaNs.  Hopefully the optimizers won't get too smart on us.
362
363 (define_expand "mmx_<code>v2sf3"
364   [(set (match_operand:V2SF 0 "register_operand" "")
365         (smaxmin:V2SF
366           (match_operand:V2SF 1 "nonimmediate_operand" "")
367           (match_operand:V2SF 2 "nonimmediate_operand" "")))]
368   "TARGET_3DNOW"
369 {
370   if (!flag_finite_math_only)
371     operands[1] = force_reg (V2SFmode, operands[1]);
372   ix86_fixup_binary_operands_no_copy (<CODE>, V2SFmode, operands);
373 })
374
375 (define_insn "*mmx_<code>v2sf3_finite"
376   [(set (match_operand:V2SF 0 "register_operand" "=y")
377         (smaxmin:V2SF
378           (match_operand:V2SF 1 "nonimmediate_operand" "%0")
379           (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
380   "TARGET_3DNOW && flag_finite_math_only
381    && ix86_binary_operator_ok (<CODE>, V2SFmode, operands)"
382   "pf<maxminfprefix>\t{%2, %0|%0, %2}"
383   [(set_attr "type" "mmxadd")
384    (set_attr "mode" "V2SF")])
385
386 (define_insn "*mmx_<code>v2sf3"
387   [(set (match_operand:V2SF 0 "register_operand" "=y")
388         (smaxmin:V2SF
389           (match_operand:V2SF 1 "register_operand" "0")
390           (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
391   "TARGET_3DNOW"
392   "pf<maxminfprefix>\t{%2, %0|%0, %2}"
393   [(set_attr "type" "mmxadd")
394    (set_attr "mode" "V2SF")])
395
396 (define_insn "mmx_rcpv2sf2"
397   [(set (match_operand:V2SF 0 "register_operand" "=y")
398         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
399                      UNSPEC_PFRCP))]
400   "TARGET_3DNOW"
401   "pfrcp\t{%1, %0|%0, %1}"
402   [(set_attr "type" "mmx")
403    (set_attr "mode" "V2SF")])
404
405 (define_insn "mmx_rcpit1v2sf3"
406   [(set (match_operand:V2SF 0 "register_operand" "=y")
407         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
408                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
409                      UNSPEC_PFRCPIT1))]
410   "TARGET_3DNOW"
411   "pfrcpit1\t{%2, %0|%0, %2}"
412   [(set_attr "type" "mmx")
413    (set_attr "mode" "V2SF")])
414
415 (define_insn "mmx_rcpit2v2sf3"
416   [(set (match_operand:V2SF 0 "register_operand" "=y")
417         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
418                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
419                      UNSPEC_PFRCPIT2))]
420   "TARGET_3DNOW"
421   "pfrcpit2\t{%2, %0|%0, %2}"
422   [(set_attr "type" "mmx")
423    (set_attr "mode" "V2SF")])
424
425 (define_insn "mmx_rsqrtv2sf2"
426   [(set (match_operand:V2SF 0 "register_operand" "=y")
427         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
428                      UNSPEC_PFRSQRT))]
429   "TARGET_3DNOW"
430   "pfrsqrt\t{%1, %0|%0, %1}"
431   [(set_attr "type" "mmx")
432    (set_attr "mode" "V2SF")])
433
434 (define_insn "mmx_rsqit1v2sf3"
435   [(set (match_operand:V2SF 0 "register_operand" "=y")
436         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
437                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
438                      UNSPEC_PFRSQIT1))]
439   "TARGET_3DNOW"
440   "pfrsqit1\t{%2, %0|%0, %2}"
441   [(set_attr "type" "mmx")
442    (set_attr "mode" "V2SF")])
443
444 (define_insn "mmx_haddv2sf3"
445   [(set (match_operand:V2SF 0 "register_operand" "=y")
446         (vec_concat:V2SF
447           (plus:SF
448             (vec_select:SF
449               (match_operand:V2SF 1 "register_operand" "0")
450               (parallel [(const_int  0)]))
451             (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
452           (plus:SF
453             (vec_select:SF
454               (match_operand:V2SF 2 "nonimmediate_operand" "ym")
455               (parallel [(const_int  0)]))
456             (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
457   "TARGET_3DNOW"
458   "pfacc\t{%2, %0|%0, %2}"
459   [(set_attr "type" "mmxadd")
460    (set_attr "mode" "V2SF")])
461
462 (define_insn "mmx_hsubv2sf3"
463   [(set (match_operand:V2SF 0 "register_operand" "=y")
464         (vec_concat:V2SF
465           (minus:SF
466             (vec_select:SF
467               (match_operand:V2SF 1 "register_operand" "0")
468               (parallel [(const_int  0)]))
469             (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
470           (minus:SF
471             (vec_select:SF
472               (match_operand:V2SF 2 "nonimmediate_operand" "ym")
473               (parallel [(const_int  0)]))
474             (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
475   "TARGET_3DNOW_A"
476   "pfnacc\t{%2, %0|%0, %2}"
477   [(set_attr "type" "mmxadd")
478    (set_attr "mode" "V2SF")])
479
480 (define_insn "mmx_addsubv2sf3"
481   [(set (match_operand:V2SF 0 "register_operand" "=y")
482         (vec_merge:V2SF
483           (plus:V2SF
484             (match_operand:V2SF 1 "register_operand" "0")
485             (match_operand:V2SF 2 "nonimmediate_operand" "ym"))
486           (minus:V2SF (match_dup 1) (match_dup 2))
487           (const_int 1)))]
488   "TARGET_3DNOW_A"
489   "pfpnacc\t{%2, %0|%0, %2}"
490   [(set_attr "type" "mmxadd")
491    (set_attr "mode" "V2SF")])
492
493 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
494 ;;
495 ;; Parallel single-precision floating point comparisons
496 ;;
497 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
498
499 (define_expand "mmx_eqv2sf3"
500   [(set (match_operand:V2SI 0 "register_operand" "")
501         (eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "")
502                  (match_operand:V2SF 2 "nonimmediate_operand" "")))]
503   "TARGET_3DNOW"
504   "ix86_fixup_binary_operands_no_copy (EQ, V2SFmode, operands);")
505
506 (define_insn "*mmx_eqv2sf3"
507   [(set (match_operand:V2SI 0 "register_operand" "=y")
508         (eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "%0")
509                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
510   "TARGET_3DNOW && ix86_binary_operator_ok (EQ, V2SFmode, operands)"
511   "pfcmpeq\t{%2, %0|%0, %2}"
512   [(set_attr "type" "mmxcmp")
513    (set_attr "mode" "V2SF")])
514
515 (define_insn "mmx_gtv2sf3"
516   [(set (match_operand:V2SI 0 "register_operand" "=y")
517         (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
518                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
519   "TARGET_3DNOW"
520   "pfcmpgt\t{%2, %0|%0, %2}"
521   [(set_attr "type" "mmxcmp")
522    (set_attr "mode" "V2SF")])
523
524 (define_insn "mmx_gev2sf3"
525   [(set (match_operand:V2SI 0 "register_operand" "=y")
526         (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
527                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
528   "TARGET_3DNOW"
529   "pfcmpge\t{%2, %0|%0, %2}"
530   [(set_attr "type" "mmxcmp")
531    (set_attr "mode" "V2SF")])
532
533 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
534 ;;
535 ;; Parallel single-precision floating point conversion operations
536 ;;
537 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
538
539 (define_insn "mmx_pf2id"
540   [(set (match_operand:V2SI 0 "register_operand" "=y")
541         (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
542   "TARGET_3DNOW"
543   "pf2id\t{%1, %0|%0, %1}"
544   [(set_attr "type" "mmxcvt")
545    (set_attr "mode" "V2SF")])
546
547 (define_insn "mmx_pf2iw"
548   [(set (match_operand:V2SI 0 "register_operand" "=y")
549         (sign_extend:V2SI
550           (ss_truncate:V2HI
551             (fix:V2SI
552               (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
553   "TARGET_3DNOW_A"
554   "pf2iw\t{%1, %0|%0, %1}"
555   [(set_attr "type" "mmxcvt")
556    (set_attr "mode" "V2SF")])
557
558 (define_insn "mmx_pi2fw"
559   [(set (match_operand:V2SF 0 "register_operand" "=y")
560         (float:V2SF
561           (sign_extend:V2SI
562             (truncate:V2HI
563               (match_operand:V2SI 1 "nonimmediate_operand" "ym")))))]
564   "TARGET_3DNOW_A"
565   "pi2fw\t{%1, %0|%0, %1}"
566   [(set_attr "type" "mmxcvt")
567    (set_attr "mode" "V2SF")])
568
569 (define_insn "mmx_floatv2si2"
570   [(set (match_operand:V2SF 0 "register_operand" "=y")
571         (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
572   "TARGET_3DNOW"
573   "pi2fd\t{%1, %0|%0, %1}"
574   [(set_attr "type" "mmxcvt")
575    (set_attr "mode" "V2SF")])
576
577 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
578 ;;
579 ;; Parallel single-precision floating point element swizzling
580 ;;
581 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
582
583 (define_insn "mmx_pswapdv2sf2"
584   [(set (match_operand:V2SF 0 "register_operand" "=y")
585         (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
586                          (parallel [(const_int 1) (const_int 0)])))]
587   "TARGET_3DNOW_A"
588   "pswapd\t{%1, %0|%0, %1}"
589   [(set_attr "type" "mmxcvt")
590    (set_attr "mode" "V2SF")])
591
592 (define_insn "*vec_dupv2sf"
593   [(set (match_operand:V2SF 0 "register_operand" "=y")
594         (vec_duplicate:V2SF
595           (match_operand:SF 1 "register_operand" "0")))]
596   "TARGET_MMX"
597   "punpckldq\t%0, %0"
598   [(set_attr "type" "mmxcvt")
599    (set_attr "mode" "DI")])
600
601 (define_insn "*mmx_concatv2sf"
602   [(set (match_operand:V2SF 0 "register_operand"     "=y,y")
603         (vec_concat:V2SF
604           (match_operand:SF 1 "nonimmediate_operand" " 0,rm")
605           (match_operand:SF 2 "vector_move_operand"  "ym,C")))]
606   "TARGET_MMX && !TARGET_SSE"
607   "@
608    punpckldq\t{%2, %0|%0, %2}
609    movd\t{%1, %0|%0, %1}"
610   [(set_attr "type" "mmxcvt,mmxmov")
611    (set_attr "mode" "DI")])
612
613 (define_expand "vec_setv2sf"
614   [(match_operand:V2SF 0 "register_operand" "")
615    (match_operand:SF 1 "register_operand" "")
616    (match_operand 2 "const_int_operand" "")]
617   "TARGET_MMX"
618 {
619   ix86_expand_vector_set (false, operands[0], operands[1],
620                           INTVAL (operands[2]));
621   DONE;
622 })
623
624 ;; Avoid combining registers from different units in a single alternative,
625 ;; see comment above inline_secondary_memory_needed function in i386.c
626 (define_insn_and_split "*vec_extractv2sf_0"
627   [(set (match_operand:SF 0 "nonimmediate_operand"     "=x, m,y ,m,f,r")
628         (vec_select:SF
629           (match_operand:V2SF 1 "nonimmediate_operand" " xm,x,ym,y,m,m")
630           (parallel [(const_int 0)])))]
631   "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
632   "#"
633   "&& reload_completed"
634   [(const_int 0)]
635 {
636   rtx op1 = operands[1];
637   if (REG_P (op1))
638     op1 = gen_rtx_REG (SFmode, REGNO (op1));
639   else
640     op1 = gen_lowpart (SFmode, op1);
641   emit_move_insn (operands[0], op1);
642   DONE;
643 })
644
645 ;; Avoid combining registers from different units in a single alternative,
646 ;; see comment above inline_secondary_memory_needed function in i386.c
647 (define_insn "*vec_extractv2sf_1"
648   [(set (match_operand:SF 0 "nonimmediate_operand"     "=y,x,y,x,f,r")
649         (vec_select:SF
650           (match_operand:V2SF 1 "nonimmediate_operand" " 0,0,o,o,o,o")
651           (parallel [(const_int 1)])))]
652   "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
653   "@
654    punpckhdq\t%0, %0
655    unpckhps\t%0, %0
656    #
657    #
658    #
659    #"
660   [(set_attr "type" "mmxcvt,sselog1,mmxmov,ssemov,fmov,imov")
661    (set_attr "mode" "DI,V4SF,SF,SF,SF,SF")])
662
663 (define_split
664   [(set (match_operand:SF 0 "register_operand" "")
665         (vec_select:SF
666           (match_operand:V2SF 1 "memory_operand" "")
667           (parallel [(const_int 1)])))]
668   "TARGET_MMX && reload_completed"
669   [(const_int 0)]
670 {
671   operands[1] = adjust_address (operands[1], SFmode, 4);
672   emit_move_insn (operands[0], operands[1]);
673   DONE;
674 })
675
676 (define_expand "vec_extractv2sf"
677   [(match_operand:SF 0 "register_operand" "")
678    (match_operand:V2SF 1 "register_operand" "")
679    (match_operand 2 "const_int_operand" "")]
680   "TARGET_MMX"
681 {
682   ix86_expand_vector_extract (false, operands[0], operands[1],
683                               INTVAL (operands[2]));
684   DONE;
685 })
686
687 (define_expand "vec_initv2sf"
688   [(match_operand:V2SF 0 "register_operand" "")
689    (match_operand 1 "" "")]
690   "TARGET_SSE"
691 {
692   ix86_expand_vector_init (false, operands[0], operands[1]);
693   DONE;
694 })
695
696 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
697 ;;
698 ;; Parallel integral arithmetic
699 ;;
700 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
701
702 (define_expand "mmx_<plusminus_insn><mode>3"
703   [(set (match_operand:MMXMODEI8 0 "register_operand" "")
704         (plusminus:MMXMODEI8
705           (match_operand:MMXMODEI8 1 "nonimmediate_operand" "")
706           (match_operand:MMXMODEI8 2 "nonimmediate_operand" "")))]
707   "TARGET_MMX || (TARGET_SSE2 && <MODE>mode == V1DImode)"
708   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
709
710 (define_insn "*mmx_<plusminus_insn><mode>3"
711   [(set (match_operand:MMXMODEI8 0 "register_operand" "=y")
712         (plusminus:MMXMODEI8
713           (match_operand:MMXMODEI8 1 "nonimmediate_operand" "<comm>0")
714           (match_operand:MMXMODEI8 2 "nonimmediate_operand" "ym")))]
715   "(TARGET_MMX || (TARGET_SSE2 && <MODE>mode == V1DImode))
716    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
717   "p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}"
718   [(set_attr "type" "mmxadd")
719    (set_attr "mode" "DI")])
720
721 (define_expand "mmx_<plusminus_insn><mode>3"
722   [(set (match_operand:MMXMODE12 0 "register_operand" "")
723         (sat_plusminus:MMXMODE12
724           (match_operand:MMXMODE12 1 "nonimmediate_operand" "")
725           (match_operand:MMXMODE12 2 "nonimmediate_operand" "")))]
726   "TARGET_MMX"
727   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
728
729 (define_insn "*mmx_<plusminus_insn><mode>3"
730   [(set (match_operand:MMXMODE12 0 "register_operand" "=y")
731         (sat_plusminus:MMXMODE12
732           (match_operand:MMXMODE12 1 "nonimmediate_operand" "<comm>0")
733           (match_operand:MMXMODE12 2 "nonimmediate_operand" "ym")))]
734   "TARGET_MMX && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
735   "p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}"
736   [(set_attr "type" "mmxadd")
737    (set_attr "mode" "DI")])
738
739 (define_expand "mmx_mulv4hi3"
740   [(set (match_operand:V4HI 0 "register_operand" "")
741         (mult:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "")
742                    (match_operand:V4HI 2 "nonimmediate_operand" "")))]
743   "TARGET_MMX"
744   "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
745
746 (define_insn "*mmx_mulv4hi3"
747   [(set (match_operand:V4HI 0 "register_operand" "=y")
748         (mult:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "%0")
749                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
750   "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
751   "pmullw\t{%2, %0|%0, %2}"
752   [(set_attr "type" "mmxmul")
753    (set_attr "mode" "DI")])
754
755 (define_expand "mmx_smulv4hi3_highpart"
756   [(set (match_operand:V4HI 0 "register_operand" "")
757         (truncate:V4HI
758           (lshiftrt:V4SI
759             (mult:V4SI
760               (sign_extend:V4SI
761                 (match_operand:V4HI 1 "nonimmediate_operand" ""))
762               (sign_extend:V4SI
763                 (match_operand:V4HI 2 "nonimmediate_operand" "")))
764             (const_int 16))))]
765   "TARGET_MMX"
766   "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
767
768 (define_insn "*mmx_smulv4hi3_highpart"
769   [(set (match_operand:V4HI 0 "register_operand" "=y")
770         (truncate:V4HI
771           (lshiftrt:V4SI
772             (mult:V4SI
773               (sign_extend:V4SI
774                 (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
775               (sign_extend:V4SI
776                 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
777             (const_int 16))))]
778   "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
779   "pmulhw\t{%2, %0|%0, %2}"
780   [(set_attr "type" "mmxmul")
781    (set_attr "mode" "DI")])
782
783 (define_expand "mmx_umulv4hi3_highpart"
784   [(set (match_operand:V4HI 0 "register_operand" "")
785         (truncate:V4HI
786           (lshiftrt:V4SI
787             (mult:V4SI
788               (zero_extend:V4SI
789                 (match_operand:V4HI 1 "nonimmediate_operand" ""))
790               (zero_extend:V4SI
791                 (match_operand:V4HI 2 "nonimmediate_operand" "")))
792             (const_int 16))))]
793   "TARGET_SSE || TARGET_3DNOW_A"
794   "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
795
796 (define_insn "*mmx_umulv4hi3_highpart"
797   [(set (match_operand:V4HI 0 "register_operand" "=y")
798         (truncate:V4HI
799           (lshiftrt:V4SI
800             (mult:V4SI
801               (zero_extend:V4SI
802                 (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
803               (zero_extend:V4SI
804                 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
805           (const_int 16))))]
806   "(TARGET_SSE || TARGET_3DNOW_A)
807    && ix86_binary_operator_ok (MULT, V4HImode, operands)"
808   "pmulhuw\t{%2, %0|%0, %2}"
809   [(set_attr "type" "mmxmul")
810    (set_attr "mode" "DI")])
811
812 (define_expand "mmx_pmaddwd"
813   [(set (match_operand:V2SI 0 "register_operand" "")
814         (plus:V2SI
815           (mult:V2SI
816             (sign_extend:V2SI
817               (vec_select:V2HI
818                 (match_operand:V4HI 1 "nonimmediate_operand" "")
819                 (parallel [(const_int 0) (const_int 2)])))
820             (sign_extend:V2SI
821               (vec_select:V2HI
822                 (match_operand:V4HI 2 "nonimmediate_operand" "")
823                 (parallel [(const_int 0) (const_int 2)]))))
824           (mult:V2SI
825             (sign_extend:V2SI
826               (vec_select:V2HI (match_dup 1)
827                 (parallel [(const_int 1) (const_int 3)])))
828             (sign_extend:V2SI
829               (vec_select:V2HI (match_dup 2)
830                 (parallel [(const_int 1) (const_int 3)]))))))]
831   "TARGET_MMX"
832   "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
833
834 (define_insn "*mmx_pmaddwd"
835   [(set (match_operand:V2SI 0 "register_operand" "=y")
836         (plus:V2SI
837           (mult:V2SI
838             (sign_extend:V2SI
839               (vec_select:V2HI
840                 (match_operand:V4HI 1 "nonimmediate_operand" "%0")
841                 (parallel [(const_int 0) (const_int 2)])))
842             (sign_extend:V2SI
843               (vec_select:V2HI
844                 (match_operand:V4HI 2 "nonimmediate_operand" "ym")
845                 (parallel [(const_int 0) (const_int 2)]))))
846           (mult:V2SI
847             (sign_extend:V2SI
848               (vec_select:V2HI (match_dup 1)
849                 (parallel [(const_int 1) (const_int 3)])))
850             (sign_extend:V2SI
851               (vec_select:V2HI (match_dup 2)
852                 (parallel [(const_int 1) (const_int 3)]))))))]
853   "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
854   "pmaddwd\t{%2, %0|%0, %2}"
855   [(set_attr "type" "mmxmul")
856    (set_attr "mode" "DI")])
857
858 (define_expand "mmx_pmulhrwv4hi3"
859   [(set (match_operand:V4HI 0 "register_operand" "")
860         (truncate:V4HI
861           (lshiftrt:V4SI
862             (plus:V4SI
863               (mult:V4SI
864                 (sign_extend:V4SI
865                   (match_operand:V4HI 1 "nonimmediate_operand" ""))
866                 (sign_extend:V4SI
867                   (match_operand:V4HI 2 "nonimmediate_operand" "")))
868               (const_vector:V4SI [(const_int 32768) (const_int 32768)
869                                   (const_int 32768) (const_int 32768)]))
870             (const_int 16))))]
871   "TARGET_3DNOW"
872   "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
873
874 (define_insn "*mmx_pmulhrwv4hi3"
875   [(set (match_operand:V4HI 0 "register_operand" "=y")
876         (truncate:V4HI
877           (lshiftrt:V4SI
878             (plus:V4SI
879               (mult:V4SI
880                 (sign_extend:V4SI
881                   (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
882                 (sign_extend:V4SI
883                   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
884               (const_vector:V4SI [(const_int 32768) (const_int 32768)
885                                   (const_int 32768) (const_int 32768)]))
886             (const_int 16))))]
887   "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V4HImode, operands)"
888   "pmulhrw\t{%2, %0|%0, %2}"
889   [(set_attr "type" "mmxmul")
890    (set_attr "mode" "DI")])
891
892 (define_expand "sse2_umulv1siv1di3"
893   [(set (match_operand:V1DI 0 "register_operand" "")
894         (mult:V1DI
895           (zero_extend:V1DI
896             (vec_select:V1SI
897               (match_operand:V2SI 1 "nonimmediate_operand" "")
898               (parallel [(const_int 0)])))
899           (zero_extend:V1DI
900             (vec_select:V1SI
901               (match_operand:V2SI 2 "nonimmediate_operand" "")
902               (parallel [(const_int 0)])))))]
903   "TARGET_SSE2"
904   "ix86_fixup_binary_operands_no_copy (MULT, V2SImode, operands);")
905
906 (define_insn "*sse2_umulv1siv1di3"
907   [(set (match_operand:V1DI 0 "register_operand" "=y")
908         (mult:V1DI
909           (zero_extend:V1DI
910             (vec_select:V1SI
911               (match_operand:V2SI 1 "nonimmediate_operand" "%0")
912               (parallel [(const_int 0)])))
913           (zero_extend:V1DI
914             (vec_select:V1SI
915               (match_operand:V2SI 2 "nonimmediate_operand" "ym")
916               (parallel [(const_int 0)])))))]
917   "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V2SImode, operands)"
918   "pmuludq\t{%2, %0|%0, %2}"
919   [(set_attr "type" "mmxmul")
920    (set_attr "mode" "DI")])
921
922 (define_expand "mmx_<code>v4hi3"
923   [(set (match_operand:V4HI 0 "register_operand" "")
924         (smaxmin:V4HI
925           (match_operand:V4HI 1 "nonimmediate_operand" "")
926           (match_operand:V4HI 2 "nonimmediate_operand" "")))]
927   "TARGET_SSE || TARGET_3DNOW_A"
928   "ix86_fixup_binary_operands_no_copy (<CODE>, V4HImode, operands);")
929
930 (define_insn "*mmx_<code>v4hi3"
931   [(set (match_operand:V4HI 0 "register_operand" "=y")
932         (smaxmin:V4HI
933           (match_operand:V4HI 1 "nonimmediate_operand" "%0")
934           (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
935   "(TARGET_SSE || TARGET_3DNOW_A)
936    && ix86_binary_operator_ok (<CODE>, V4HImode, operands)"
937   "p<maxminiprefix>w\t{%2, %0|%0, %2}"
938   [(set_attr "type" "mmxadd")
939    (set_attr "mode" "DI")])
940
941 (define_expand "mmx_<code>v8qi3"
942   [(set (match_operand:V8QI 0 "register_operand" "")
943         (umaxmin:V8QI
944           (match_operand:V8QI 1 "nonimmediate_operand" "")
945           (match_operand:V8QI 2 "nonimmediate_operand" "")))]
946   "TARGET_SSE || TARGET_3DNOW_A"
947   "ix86_fixup_binary_operands_no_copy (<CODE>, V8QImode, operands);")
948
949 (define_insn "*mmx_<code>v8qi3"
950   [(set (match_operand:V8QI 0 "register_operand" "=y")
951         (umaxmin:V8QI
952           (match_operand:V8QI 1 "nonimmediate_operand" "%0")
953           (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
954   "(TARGET_SSE || TARGET_3DNOW_A)
955    && ix86_binary_operator_ok (<CODE>, V8QImode, operands)"
956   "p<maxminiprefix>b\t{%2, %0|%0, %2}"
957   [(set_attr "type" "mmxadd")
958    (set_attr "mode" "DI")])
959
960 (define_insn "mmx_ashr<mode>3"
961   [(set (match_operand:MMXMODE24 0 "register_operand" "=y")
962         (ashiftrt:MMXMODE24
963           (match_operand:MMXMODE24 1 "register_operand" "0")
964           (match_operand:SI 2 "nonmemory_operand" "yN")))]
965   "TARGET_MMX"
966   "psra<mmxvecsize>\t{%2, %0|%0, %2}"
967   [(set_attr "type" "mmxshft")
968    (set_attr "mode" "DI")])
969
970 (define_insn "mmx_lshr<mode>3"
971   [(set (match_operand:MMXMODE248 0 "register_operand" "=y")
972         (lshiftrt:MMXMODE248
973           (match_operand:MMXMODE248 1 "register_operand" "0")
974           (match_operand:SI 2 "nonmemory_operand" "yN")))]
975   "TARGET_MMX"
976   "psrl<mmxvecsize>\t{%2, %0|%0, %2}"
977   [(set_attr "type" "mmxshft")
978    (set_attr "mode" "DI")])
979
980 (define_insn "mmx_ashl<mode>3"
981   [(set (match_operand:MMXMODE248 0 "register_operand" "=y")
982         (ashift:MMXMODE248
983           (match_operand:MMXMODE248 1 "register_operand" "0")
984           (match_operand:SI 2 "nonmemory_operand" "yN")))]
985   "TARGET_MMX"
986   "psll<mmxvecsize>\t{%2, %0|%0, %2}"
987   [(set_attr "type" "mmxshft")
988    (set_attr "mode" "DI")])
989
990 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
991 ;;
992 ;; Parallel integral comparisons
993 ;;
994 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
995
996 (define_expand "mmx_eq<mode>3"
997   [(set (match_operand:MMXMODEI 0 "register_operand" "")
998         (eq:MMXMODEI
999           (match_operand:MMXMODEI 1 "nonimmediate_operand" "")
1000           (match_operand:MMXMODEI 2 "nonimmediate_operand" "")))]
1001   "TARGET_MMX"
1002   "ix86_fixup_binary_operands_no_copy (EQ, <MODE>mode, operands);")
1003
1004 (define_insn "*mmx_eq<mode>3"
1005   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
1006         (eq:MMXMODEI
1007           (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
1008           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
1009   "TARGET_MMX && ix86_binary_operator_ok (EQ, <MODE>mode, operands)"
1010   "pcmpeq<mmxvecsize>\t{%2, %0|%0, %2}"
1011   [(set_attr "type" "mmxcmp")
1012    (set_attr "mode" "DI")])
1013
1014 (define_insn "mmx_gt<mode>3"
1015   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
1016         (gt:MMXMODEI
1017           (match_operand:MMXMODEI 1 "register_operand" "0")
1018           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
1019   "TARGET_MMX"
1020   "pcmpgt<mmxvecsize>\t{%2, %0|%0, %2}"
1021   [(set_attr "type" "mmxcmp")
1022    (set_attr "mode" "DI")])
1023
1024 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1025 ;;
1026 ;; Parallel integral logical operations
1027 ;;
1028 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1029
1030 (define_insn "mmx_andnot<mode>3"
1031   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
1032         (and:MMXMODEI
1033           (not:MMXMODEI (match_operand:MMXMODEI 1 "register_operand" "0"))
1034           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
1035   "TARGET_MMX"
1036   "pandn\t{%2, %0|%0, %2}"
1037   [(set_attr "type" "mmxadd")
1038    (set_attr "mode" "DI")])
1039
1040 (define_expand "mmx_<code><mode>3"
1041   [(set (match_operand:MMXMODEI 0 "register_operand" "")
1042         (plogic:MMXMODEI
1043           (match_operand:MMXMODEI 1 "nonimmediate_operand" "")
1044           (match_operand:MMXMODEI 2 "nonimmediate_operand" "")))]
1045   "TARGET_MMX"
1046   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
1047
1048 (define_insn "*mmx_<code><mode>3"
1049   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
1050         (plogic:MMXMODEI
1051           (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
1052           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
1053   "TARGET_MMX && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
1054   "p<plogicprefix>\t{%2, %0|%0, %2}"
1055   [(set_attr "type" "mmxadd")
1056    (set_attr "mode" "DI")])
1057
1058 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1059 ;;
1060 ;; Parallel integral element swizzling
1061 ;;
1062 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1063
1064 (define_insn "mmx_packsswb"
1065   [(set (match_operand:V8QI 0 "register_operand" "=y")
1066         (vec_concat:V8QI
1067           (ss_truncate:V4QI
1068             (match_operand:V4HI 1 "register_operand" "0"))
1069           (ss_truncate:V4QI
1070             (match_operand:V4HI 2 "nonimmediate_operand" "ym"))))]
1071   "TARGET_MMX"
1072   "packsswb\t{%2, %0|%0, %2}"
1073   [(set_attr "type" "mmxshft")
1074    (set_attr "mode" "DI")])
1075
1076 (define_insn "mmx_packssdw"
1077   [(set (match_operand:V4HI 0 "register_operand" "=y")
1078         (vec_concat:V4HI
1079           (ss_truncate:V2HI
1080             (match_operand:V2SI 1 "register_operand" "0"))
1081           (ss_truncate:V2HI
1082             (match_operand:V2SI 2 "nonimmediate_operand" "ym"))))]
1083   "TARGET_MMX"
1084   "packssdw\t{%2, %0|%0, %2}"
1085   [(set_attr "type" "mmxshft")
1086    (set_attr "mode" "DI")])
1087
1088 (define_insn "mmx_packuswb"
1089   [(set (match_operand:V8QI 0 "register_operand" "=y")
1090         (vec_concat:V8QI
1091           (us_truncate:V4QI
1092             (match_operand:V4HI 1 "register_operand" "0"))
1093           (us_truncate:V4QI
1094             (match_operand:V4HI 2 "nonimmediate_operand" "ym"))))]
1095   "TARGET_MMX"
1096   "packuswb\t{%2, %0|%0, %2}"
1097   [(set_attr "type" "mmxshft")
1098    (set_attr "mode" "DI")])
1099
1100 (define_insn "mmx_punpckhbw"
1101   [(set (match_operand:V8QI 0 "register_operand" "=y")
1102         (vec_select:V8QI
1103           (vec_concat:V16QI
1104             (match_operand:V8QI 1 "register_operand" "0")
1105             (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
1106           (parallel [(const_int 4) (const_int 12)
1107                      (const_int 5) (const_int 13)
1108                      (const_int 6) (const_int 14)
1109                      (const_int 7) (const_int 15)])))]
1110   "TARGET_MMX"
1111   "punpckhbw\t{%2, %0|%0, %2}"
1112   [(set_attr "type" "mmxcvt")
1113    (set_attr "mode" "DI")])
1114
1115 (define_insn "mmx_punpcklbw"
1116   [(set (match_operand:V8QI 0 "register_operand" "=y")
1117         (vec_select:V8QI
1118           (vec_concat:V16QI
1119             (match_operand:V8QI 1 "register_operand" "0")
1120             (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
1121           (parallel [(const_int 0) (const_int 8)
1122                      (const_int 1) (const_int 9)
1123                      (const_int 2) (const_int 10)
1124                      (const_int 3) (const_int 11)])))]
1125   "TARGET_MMX"
1126   "punpcklbw\t{%2, %0|%0, %2}"
1127   [(set_attr "type" "mmxcvt")
1128    (set_attr "mode" "DI")])
1129
1130 (define_insn "mmx_punpckhwd"
1131   [(set (match_operand:V4HI 0 "register_operand" "=y")
1132         (vec_select:V4HI
1133           (vec_concat:V8HI
1134             (match_operand:V4HI 1 "register_operand" "0")
1135             (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
1136           (parallel [(const_int 2) (const_int 6)
1137                      (const_int 3) (const_int 7)])))]
1138   "TARGET_MMX"
1139   "punpckhwd\t{%2, %0|%0, %2}"
1140   [(set_attr "type" "mmxcvt")
1141    (set_attr "mode" "DI")])
1142
1143 (define_insn "mmx_punpcklwd"
1144   [(set (match_operand:V4HI 0 "register_operand" "=y")
1145         (vec_select:V4HI
1146           (vec_concat:V8HI
1147             (match_operand:V4HI 1 "register_operand" "0")
1148             (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
1149           (parallel [(const_int 0) (const_int 4)
1150                      (const_int 1) (const_int 5)])))]
1151   "TARGET_MMX"
1152   "punpcklwd\t{%2, %0|%0, %2}"
1153   [(set_attr "type" "mmxcvt")
1154    (set_attr "mode" "DI")])
1155
1156 (define_insn "mmx_punpckhdq"
1157   [(set (match_operand:V2SI 0 "register_operand" "=y")
1158         (vec_select:V2SI
1159           (vec_concat:V4SI
1160             (match_operand:V2SI 1 "register_operand" "0")
1161             (match_operand:V2SI 2 "nonimmediate_operand" "ym"))
1162           (parallel [(const_int 1)
1163                      (const_int 3)])))]
1164   "TARGET_MMX"
1165   "punpckhdq\t{%2, %0|%0, %2}"
1166   [(set_attr "type" "mmxcvt")
1167    (set_attr "mode" "DI")])
1168
1169 (define_insn "mmx_punpckldq"
1170   [(set (match_operand:V2SI 0 "register_operand" "=y")
1171         (vec_select:V2SI
1172           (vec_concat:V4SI
1173             (match_operand:V2SI 1 "register_operand" "0")
1174             (match_operand:V2SI 2 "nonimmediate_operand" "ym"))
1175           (parallel [(const_int 0)
1176                      (const_int 2)])))]
1177   "TARGET_MMX"
1178   "punpckldq\t{%2, %0|%0, %2}"
1179   [(set_attr "type" "mmxcvt")
1180    (set_attr "mode" "DI")])
1181
1182 (define_expand "mmx_pinsrw"
1183   [(set (match_operand:V4HI 0 "register_operand" "")
1184         (vec_merge:V4HI
1185           (vec_duplicate:V4HI
1186             (match_operand:SI 2 "nonimmediate_operand" ""))
1187           (match_operand:V4HI 1 "register_operand" "")
1188           (match_operand:SI 3 "const_0_to_3_operand" "")))]
1189   "TARGET_SSE || TARGET_3DNOW_A"
1190 {
1191   operands[2] = gen_lowpart (HImode, operands[2]);
1192   operands[3] = GEN_INT (1 << INTVAL (operands[3]));
1193 })
1194
1195 (define_insn "*mmx_pinsrw"
1196   [(set (match_operand:V4HI 0 "register_operand" "=y")
1197         (vec_merge:V4HI
1198           (vec_duplicate:V4HI
1199             (match_operand:HI 2 "nonimmediate_operand" "rm"))
1200           (match_operand:V4HI 1 "register_operand" "0")
1201           (match_operand:SI 3 "const_pow2_1_to_8_operand" "n")))]
1202   "TARGET_SSE || TARGET_3DNOW_A"
1203 {
1204   operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
1205   if (MEM_P (operands[2]))
1206     return "pinsrw\t{%3, %2, %0|%0, %2, %3}";
1207   else
1208     return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}";
1209 }
1210   [(set_attr "type" "mmxcvt")
1211    (set_attr "mode" "DI")])
1212
1213 (define_insn "mmx_pextrw"
1214   [(set (match_operand:SI 0 "register_operand" "=r")
1215         (zero_extend:SI
1216           (vec_select:HI
1217             (match_operand:V4HI 1 "register_operand" "y")
1218             (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n")]))))]
1219   "TARGET_SSE || TARGET_3DNOW_A"
1220   "pextrw\t{%2, %1, %0|%0, %1, %2}"
1221   [(set_attr "type" "mmxcvt")
1222    (set_attr "mode" "DI")])
1223
1224 (define_expand "mmx_pshufw"
1225   [(match_operand:V4HI 0 "register_operand" "")
1226    (match_operand:V4HI 1 "nonimmediate_operand" "")
1227    (match_operand:SI 2 "const_int_operand" "")]
1228   "TARGET_SSE || TARGET_3DNOW_A"
1229 {
1230   int mask = INTVAL (operands[2]);
1231   emit_insn (gen_mmx_pshufw_1 (operands[0], operands[1],
1232                                GEN_INT ((mask >> 0) & 3),
1233                                GEN_INT ((mask >> 2) & 3),
1234                                GEN_INT ((mask >> 4) & 3),
1235                                GEN_INT ((mask >> 6) & 3)));
1236   DONE;
1237 })
1238
1239 (define_insn "mmx_pshufw_1"
1240   [(set (match_operand:V4HI 0 "register_operand" "=y")
1241         (vec_select:V4HI
1242           (match_operand:V4HI 1 "nonimmediate_operand" "ym")
1243           (parallel [(match_operand 2 "const_0_to_3_operand" "")
1244                      (match_operand 3 "const_0_to_3_operand" "")
1245                      (match_operand 4 "const_0_to_3_operand" "")
1246                      (match_operand 5 "const_0_to_3_operand" "")])))]
1247   "TARGET_SSE || TARGET_3DNOW_A"
1248 {
1249   int mask = 0;
1250   mask |= INTVAL (operands[2]) << 0;
1251   mask |= INTVAL (operands[3]) << 2;
1252   mask |= INTVAL (operands[4]) << 4;
1253   mask |= INTVAL (operands[5]) << 6;
1254   operands[2] = GEN_INT (mask);
1255
1256   return "pshufw\t{%2, %1, %0|%0, %1, %2}";
1257 }
1258   [(set_attr "type" "mmxcvt")
1259    (set_attr "mode" "DI")])
1260
1261 (define_insn "mmx_pswapdv2si2"
1262   [(set (match_operand:V2SI 0 "register_operand" "=y")
1263         (vec_select:V2SI
1264           (match_operand:V2SI 1 "nonimmediate_operand" "ym")
1265           (parallel [(const_int 1) (const_int 0)])))]
1266   "TARGET_3DNOW_A"
1267   "pswapd\t{%1, %0|%0, %1}"
1268   [(set_attr "type" "mmxcvt")
1269    (set_attr "mode" "DI")])
1270
1271 (define_insn "*vec_dupv4hi"
1272   [(set (match_operand:V4HI 0 "register_operand" "=y")
1273         (vec_duplicate:V4HI
1274           (truncate:HI
1275             (match_operand:SI 1 "register_operand" "0"))))]
1276   "TARGET_SSE || TARGET_3DNOW_A"
1277   "pshufw\t{$0, %0, %0|%0, %0, 0}"
1278   [(set_attr "type" "mmxcvt")
1279    (set_attr "mode" "DI")])
1280
1281 (define_insn "*vec_dupv2si"
1282   [(set (match_operand:V2SI 0 "register_operand" "=y")
1283         (vec_duplicate:V2SI
1284           (match_operand:SI 1 "register_operand" "0")))]
1285   "TARGET_MMX"
1286   "punpckldq\t%0, %0"
1287   [(set_attr "type" "mmxcvt")
1288    (set_attr "mode" "DI")])
1289
1290 (define_insn "*mmx_concatv2si"
1291   [(set (match_operand:V2SI 0 "register_operand"     "=y,y")
1292         (vec_concat:V2SI
1293           (match_operand:SI 1 "nonimmediate_operand" " 0,rm")
1294           (match_operand:SI 2 "vector_move_operand"  "ym,C")))]
1295   "TARGET_MMX && !TARGET_SSE"
1296   "@
1297    punpckldq\t{%2, %0|%0, %2}
1298    movd\t{%1, %0|%0, %1}"
1299   [(set_attr "type" "mmxcvt,mmxmov")
1300    (set_attr "mode" "DI")])
1301
1302 (define_expand "vec_setv2si"
1303   [(match_operand:V2SI 0 "register_operand" "")
1304    (match_operand:SI 1 "register_operand" "")
1305    (match_operand 2 "const_int_operand" "")]
1306   "TARGET_MMX"
1307 {
1308   ix86_expand_vector_set (false, operands[0], operands[1],
1309                           INTVAL (operands[2]));
1310   DONE;
1311 })
1312
1313 ;; Avoid combining registers from different units in a single alternative,
1314 ;; see comment above inline_secondary_memory_needed function in i386.c
1315 (define_insn_and_split "*vec_extractv2si_0"
1316   [(set (match_operand:SI 0 "nonimmediate_operand"     "=x,m,y, m,r")
1317         (vec_select:SI
1318           (match_operand:V2SI 1 "nonimmediate_operand" "xm,x,ym,y,m")
1319           (parallel [(const_int 0)])))]
1320   "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1321   "#"
1322   "&& reload_completed"
1323   [(const_int 0)]
1324 {
1325   rtx op1 = operands[1];
1326   if (REG_P (op1))
1327     op1 = gen_rtx_REG (SImode, REGNO (op1));
1328   else
1329     op1 = gen_lowpart (SImode, op1);
1330   emit_move_insn (operands[0], op1);
1331   DONE;
1332 })
1333
1334 ;; Avoid combining registers from different units in a single alternative,
1335 ;; see comment above inline_secondary_memory_needed function in i386.c
1336 (define_insn "*vec_extractv2si_1"
1337   [(set (match_operand:SI 0 "nonimmediate_operand"     "=y,Y2,Y2,x,y,x,r")
1338         (vec_select:SI
1339           (match_operand:V2SI 1 "nonimmediate_operand" " 0,0 ,Y2,0,o,o,o")
1340           (parallel [(const_int 1)])))]
1341   "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1342   "@
1343    punpckhdq\t%0, %0
1344    punpckhdq\t%0, %0
1345    pshufd\t{$85, %1, %0|%0, %1, 85}
1346    unpckhps\t%0, %0
1347    #
1348    #
1349    #"
1350   [(set_attr "type" "mmxcvt,sselog1,sselog1,sselog1,mmxmov,ssemov,imov")
1351    (set_attr "mode" "DI,TI,TI,V4SF,SI,SI,SI")])
1352
1353 (define_split
1354   [(set (match_operand:SI 0 "register_operand" "")
1355         (vec_select:SI
1356           (match_operand:V2SI 1 "memory_operand" "")
1357           (parallel [(const_int 1)])))]
1358   "TARGET_MMX && reload_completed"
1359   [(const_int 0)]
1360 {
1361   operands[1] = adjust_address (operands[1], SImode, 4);
1362   emit_move_insn (operands[0], operands[1]);
1363   DONE;
1364 })
1365
1366 (define_expand "vec_extractv2si"
1367   [(match_operand:SI 0 "register_operand" "")
1368    (match_operand:V2SI 1 "register_operand" "")
1369    (match_operand 2 "const_int_operand" "")]
1370   "TARGET_MMX"
1371 {
1372   ix86_expand_vector_extract (false, operands[0], operands[1],
1373                               INTVAL (operands[2]));
1374   DONE;
1375 })
1376
1377 (define_expand "vec_initv2si"
1378   [(match_operand:V2SI 0 "register_operand" "")
1379    (match_operand 1 "" "")]
1380   "TARGET_SSE"
1381 {
1382   ix86_expand_vector_init (false, operands[0], operands[1]);
1383   DONE;
1384 })
1385
1386 (define_expand "vec_setv4hi"
1387   [(match_operand:V4HI 0 "register_operand" "")
1388    (match_operand:HI 1 "register_operand" "")
1389    (match_operand 2 "const_int_operand" "")]
1390   "TARGET_MMX"
1391 {
1392   ix86_expand_vector_set (false, operands[0], operands[1],
1393                           INTVAL (operands[2]));
1394   DONE;
1395 })
1396
1397 (define_expand "vec_extractv4hi"
1398   [(match_operand:HI 0 "register_operand" "")
1399    (match_operand:V4HI 1 "register_operand" "")
1400    (match_operand 2 "const_int_operand" "")]
1401   "TARGET_MMX"
1402 {
1403   ix86_expand_vector_extract (false, operands[0], operands[1],
1404                               INTVAL (operands[2]));
1405   DONE;
1406 })
1407
1408 (define_expand "vec_initv4hi"
1409   [(match_operand:V4HI 0 "register_operand" "")
1410    (match_operand 1 "" "")]
1411   "TARGET_SSE"
1412 {
1413   ix86_expand_vector_init (false, operands[0], operands[1]);
1414   DONE;
1415 })
1416
1417 (define_expand "vec_setv8qi"
1418   [(match_operand:V8QI 0 "register_operand" "")
1419    (match_operand:QI 1 "register_operand" "")
1420    (match_operand 2 "const_int_operand" "")]
1421   "TARGET_MMX"
1422 {
1423   ix86_expand_vector_set (false, operands[0], operands[1],
1424                           INTVAL (operands[2]));
1425   DONE;
1426 })
1427
1428 (define_expand "vec_extractv8qi"
1429   [(match_operand:QI 0 "register_operand" "")
1430    (match_operand:V8QI 1 "register_operand" "")
1431    (match_operand 2 "const_int_operand" "")]
1432   "TARGET_MMX"
1433 {
1434   ix86_expand_vector_extract (false, operands[0], operands[1],
1435                               INTVAL (operands[2]));
1436   DONE;
1437 })
1438
1439 (define_expand "vec_initv8qi"
1440   [(match_operand:V8QI 0 "register_operand" "")
1441    (match_operand 1 "" "")]
1442   "TARGET_SSE"
1443 {
1444   ix86_expand_vector_init (false, operands[0], operands[1]);
1445   DONE;
1446 })
1447
1448 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1449 ;;
1450 ;; Miscellaneous
1451 ;;
1452 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1453
1454 (define_expand "mmx_uavgv8qi3"
1455   [(set (match_operand:V8QI 0 "register_operand" "")
1456         (truncate:V8QI
1457           (lshiftrt:V8HI
1458             (plus:V8HI
1459               (plus:V8HI
1460                 (zero_extend:V8HI
1461                   (match_operand:V8QI 1 "nonimmediate_operand" ""))
1462                 (zero_extend:V8HI
1463                   (match_operand:V8QI 2 "nonimmediate_operand" "")))
1464               (const_vector:V8HI [(const_int 1) (const_int 1)
1465                                   (const_int 1) (const_int 1)
1466                                   (const_int 1) (const_int 1)
1467                                   (const_int 1) (const_int 1)]))
1468             (const_int 1))))]
1469   "TARGET_SSE || TARGET_3DNOW"
1470   "ix86_fixup_binary_operands_no_copy (PLUS, V8QImode, operands);")
1471
1472 (define_insn "*mmx_uavgv8qi3"
1473   [(set (match_operand:V8QI 0 "register_operand" "=y")
1474         (truncate:V8QI
1475           (lshiftrt:V8HI
1476             (plus:V8HI
1477               (plus:V8HI
1478                 (zero_extend:V8HI
1479                   (match_operand:V8QI 1 "nonimmediate_operand" "%0"))
1480                 (zero_extend:V8HI
1481                   (match_operand:V8QI 2 "nonimmediate_operand" "ym")))
1482               (const_vector:V8HI [(const_int 1) (const_int 1)
1483                                   (const_int 1) (const_int 1)
1484                                   (const_int 1) (const_int 1)
1485                                   (const_int 1) (const_int 1)]))
1486             (const_int 1))))]
1487   "(TARGET_SSE || TARGET_3DNOW)
1488    && ix86_binary_operator_ok (PLUS, V8QImode, operands)"
1489 {
1490   /* These two instructions have the same operation, but their encoding
1491      is different.  Prefer the one that is de facto standard.  */
1492   if (TARGET_SSE || TARGET_3DNOW_A)
1493     return "pavgb\t{%2, %0|%0, %2}";
1494   else
1495     return "pavgusb\t{%2, %0|%0, %2}";
1496 }
1497   [(set_attr "type" "mmxshft")
1498    (set_attr "mode" "DI")])
1499
1500 (define_expand "mmx_uavgv4hi3"
1501   [(set (match_operand:V4HI 0 "register_operand" "")
1502         (truncate:V4HI
1503           (lshiftrt:V4SI
1504             (plus:V4SI
1505               (plus:V4SI
1506                 (zero_extend:V4SI
1507                   (match_operand:V4HI 1 "nonimmediate_operand" ""))
1508                 (zero_extend:V4SI
1509                   (match_operand:V4HI 2 "nonimmediate_operand" "")))
1510               (const_vector:V4SI [(const_int 1) (const_int 1)
1511                                   (const_int 1) (const_int 1)]))
1512             (const_int 1))))]
1513   "TARGET_SSE || TARGET_3DNOW_A"
1514   "ix86_fixup_binary_operands_no_copy (PLUS, V4HImode, operands);")
1515
1516 (define_insn "*mmx_uavgv4hi3"
1517   [(set (match_operand:V4HI 0 "register_operand" "=y")
1518         (truncate:V4HI
1519           (lshiftrt:V4SI
1520             (plus:V4SI
1521               (plus:V4SI
1522                 (zero_extend:V4SI
1523                   (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
1524                 (zero_extend:V4SI
1525                   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
1526               (const_vector:V4SI [(const_int 1) (const_int 1)
1527                                   (const_int 1) (const_int 1)]))
1528             (const_int 1))))]
1529   "(TARGET_SSE || TARGET_3DNOW_A)
1530    && ix86_binary_operator_ok (PLUS, V4HImode, operands)"
1531   "pavgw\t{%2, %0|%0, %2}"
1532   [(set_attr "type" "mmxshft")
1533    (set_attr "mode" "DI")])
1534
1535 (define_insn "mmx_psadbw"
1536   [(set (match_operand:V1DI 0 "register_operand" "=y")
1537         (unspec:V1DI [(match_operand:V8QI 1 "register_operand" "0")
1538                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
1539                      UNSPEC_PSADBW))]
1540   "TARGET_SSE || TARGET_3DNOW_A"
1541   "psadbw\t{%2, %0|%0, %2}"
1542   [(set_attr "type" "mmxshft")
1543    (set_attr "mode" "DI")])
1544
1545 (define_insn "mmx_pmovmskb"
1546   [(set (match_operand:SI 0 "register_operand" "=r")
1547         (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
1548                    UNSPEC_MOVMSK))]
1549   "TARGET_SSE || TARGET_3DNOW_A"
1550   "pmovmskb\t{%1, %0|%0, %1}"
1551   [(set_attr "type" "mmxcvt")
1552    (set_attr "mode" "DI")])
1553
1554 (define_expand "mmx_maskmovq"
1555   [(set (match_operand:V8QI 0 "memory_operand" "")
1556         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "")
1557                       (match_operand:V8QI 2 "register_operand" "")
1558                       (match_dup 0)]
1559                      UNSPEC_MASKMOV))]
1560   "TARGET_SSE || TARGET_3DNOW_A"
1561   "")
1562
1563 (define_insn "*mmx_maskmovq"
1564   [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
1565         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
1566                       (match_operand:V8QI 2 "register_operand" "y")
1567                       (mem:V8QI (match_dup 0))]
1568                      UNSPEC_MASKMOV))]
1569   "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
1570   ;; @@@ check ordering of operands in intel/nonintel syntax
1571   "maskmovq\t{%2, %1|%1, %2}"
1572   [(set_attr "type" "mmxcvt")
1573    (set_attr "mode" "DI")])
1574
1575 (define_insn "*mmx_maskmovq_rex"
1576   [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
1577         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
1578                       (match_operand:V8QI 2 "register_operand" "y")
1579                       (mem:V8QI (match_dup 0))]
1580                      UNSPEC_MASKMOV))]
1581   "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
1582   ;; @@@ check ordering of operands in intel/nonintel syntax
1583   "maskmovq\t{%2, %1|%1, %2}"
1584   [(set_attr "type" "mmxcvt")
1585    (set_attr "mode" "DI")])
1586
1587 (define_insn "mmx_emms"
1588   [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
1589    (clobber (reg:XF ST0_REG))
1590    (clobber (reg:XF ST1_REG))
1591    (clobber (reg:XF ST2_REG))
1592    (clobber (reg:XF ST3_REG))
1593    (clobber (reg:XF ST4_REG))
1594    (clobber (reg:XF ST5_REG))
1595    (clobber (reg:XF ST6_REG))
1596    (clobber (reg:XF ST7_REG))
1597    (clobber (reg:DI MM0_REG))
1598    (clobber (reg:DI MM1_REG))
1599    (clobber (reg:DI MM2_REG))
1600    (clobber (reg:DI MM3_REG))
1601    (clobber (reg:DI MM4_REG))
1602    (clobber (reg:DI MM5_REG))
1603    (clobber (reg:DI MM6_REG))
1604    (clobber (reg:DI MM7_REG))]
1605   "TARGET_MMX"
1606   "emms"
1607   [(set_attr "type" "mmx")
1608    (set_attr "memory" "unknown")])
1609
1610 (define_insn "mmx_femms"
1611   [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
1612    (clobber (reg:XF ST0_REG))
1613    (clobber (reg:XF ST1_REG))
1614    (clobber (reg:XF ST2_REG))
1615    (clobber (reg:XF ST3_REG))
1616    (clobber (reg:XF ST4_REG))
1617    (clobber (reg:XF ST5_REG))
1618    (clobber (reg:XF ST6_REG))
1619    (clobber (reg:XF ST7_REG))
1620    (clobber (reg:DI MM0_REG))
1621    (clobber (reg:DI MM1_REG))
1622    (clobber (reg:DI MM2_REG))
1623    (clobber (reg:DI MM3_REG))
1624    (clobber (reg:DI MM4_REG))
1625    (clobber (reg:DI MM5_REG))
1626    (clobber (reg:DI MM6_REG))
1627    (clobber (reg:DI MM7_REG))]
1628   "TARGET_3DNOW"
1629   "femms"
1630   [(set_attr "type" "mmx")
1631    (set_attr "memory" "none")])