Merge branch 'master' into kiconv2
[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{%2, %0|%0, %2}"
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   return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}";
1206 }
1207   [(set_attr "type" "mmxcvt")
1208    (set_attr "mode" "DI")])
1209
1210 (define_insn "mmx_pextrw"
1211   [(set (match_operand:SI 0 "register_operand" "=r")
1212         (zero_extend:SI
1213           (vec_select:HI
1214             (match_operand:V4HI 1 "register_operand" "y")
1215             (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n")]))))]
1216   "TARGET_SSE || TARGET_3DNOW_A"
1217   "pextrw\t{%2, %1, %0|%0, %1, %2}"
1218   [(set_attr "type" "mmxcvt")
1219    (set_attr "mode" "DI")])
1220
1221 (define_expand "mmx_pshufw"
1222   [(match_operand:V4HI 0 "register_operand" "")
1223    (match_operand:V4HI 1 "nonimmediate_operand" "")
1224    (match_operand:SI 2 "const_int_operand" "")]
1225   "TARGET_SSE || TARGET_3DNOW_A"
1226 {
1227   int mask = INTVAL (operands[2]);
1228   emit_insn (gen_mmx_pshufw_1 (operands[0], operands[1],
1229                                GEN_INT ((mask >> 0) & 3),
1230                                GEN_INT ((mask >> 2) & 3),
1231                                GEN_INT ((mask >> 4) & 3),
1232                                GEN_INT ((mask >> 6) & 3)));
1233   DONE;
1234 })
1235
1236 (define_insn "mmx_pshufw_1"
1237   [(set (match_operand:V4HI 0 "register_operand" "=y")
1238         (vec_select:V4HI
1239           (match_operand:V4HI 1 "nonimmediate_operand" "ym")
1240           (parallel [(match_operand 2 "const_0_to_3_operand" "")
1241                      (match_operand 3 "const_0_to_3_operand" "")
1242                      (match_operand 4 "const_0_to_3_operand" "")
1243                      (match_operand 5 "const_0_to_3_operand" "")])))]
1244   "TARGET_SSE || TARGET_3DNOW_A"
1245 {
1246   int mask = 0;
1247   mask |= INTVAL (operands[2]) << 0;
1248   mask |= INTVAL (operands[3]) << 2;
1249   mask |= INTVAL (operands[4]) << 4;
1250   mask |= INTVAL (operands[5]) << 6;
1251   operands[2] = GEN_INT (mask);
1252
1253   return "pshufw\t{%2, %1, %0|%0, %1, %2}";
1254 }
1255   [(set_attr "type" "mmxcvt")
1256    (set_attr "mode" "DI")])
1257
1258 (define_insn "mmx_pswapdv2si2"
1259   [(set (match_operand:V2SI 0 "register_operand" "=y")
1260         (vec_select:V2SI
1261           (match_operand:V2SI 1 "nonimmediate_operand" "ym")
1262           (parallel [(const_int 1) (const_int 0)])))]
1263   "TARGET_3DNOW_A"
1264   "pswapd\t{%1, %0|%0, %1}"
1265   [(set_attr "type" "mmxcvt")
1266    (set_attr "mode" "DI")])
1267
1268 (define_insn "*vec_dupv4hi"
1269   [(set (match_operand:V4HI 0 "register_operand" "=y")
1270         (vec_duplicate:V4HI
1271           (truncate:HI
1272             (match_operand:SI 1 "register_operand" "0"))))]
1273   "TARGET_SSE || TARGET_3DNOW_A"
1274   "pshufw\t{$0, %0, %0|%0, %0, 0}"
1275   [(set_attr "type" "mmxcvt")
1276    (set_attr "mode" "DI")])
1277
1278 (define_insn "*vec_dupv2si"
1279   [(set (match_operand:V2SI 0 "register_operand" "=y")
1280         (vec_duplicate:V2SI
1281           (match_operand:SI 1 "register_operand" "0")))]
1282   "TARGET_MMX"
1283   "punpckldq\t%0, %0"
1284   [(set_attr "type" "mmxcvt")
1285    (set_attr "mode" "DI")])
1286
1287 (define_insn "*mmx_concatv2si"
1288   [(set (match_operand:V2SI 0 "register_operand"     "=y,y")
1289         (vec_concat:V2SI
1290           (match_operand:SI 1 "nonimmediate_operand" " 0,rm")
1291           (match_operand:SI 2 "vector_move_operand"  "ym,C")))]
1292   "TARGET_MMX && !TARGET_SSE"
1293   "@
1294    punpckldq\t{%2, %0|%0, %2}
1295    movd\t{%1, %0|%0, %1}"
1296   [(set_attr "type" "mmxcvt,mmxmov")
1297    (set_attr "mode" "DI")])
1298
1299 (define_expand "vec_setv2si"
1300   [(match_operand:V2SI 0 "register_operand" "")
1301    (match_operand:SI 1 "register_operand" "")
1302    (match_operand 2 "const_int_operand" "")]
1303   "TARGET_MMX"
1304 {
1305   ix86_expand_vector_set (false, operands[0], operands[1],
1306                           INTVAL (operands[2]));
1307   DONE;
1308 })
1309
1310 ;; Avoid combining registers from different units in a single alternative,
1311 ;; see comment above inline_secondary_memory_needed function in i386.c
1312 (define_insn_and_split "*vec_extractv2si_0"
1313   [(set (match_operand:SI 0 "nonimmediate_operand"     "=x,m,y, m,r")
1314         (vec_select:SI
1315           (match_operand:V2SI 1 "nonimmediate_operand" "xm,x,ym,y,m")
1316           (parallel [(const_int 0)])))]
1317   "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1318   "#"
1319   "&& reload_completed"
1320   [(const_int 0)]
1321 {
1322   rtx op1 = operands[1];
1323   if (REG_P (op1))
1324     op1 = gen_rtx_REG (SImode, REGNO (op1));
1325   else
1326     op1 = gen_lowpart (SImode, op1);
1327   emit_move_insn (operands[0], op1);
1328   DONE;
1329 })
1330
1331 ;; Avoid combining registers from different units in a single alternative,
1332 ;; see comment above inline_secondary_memory_needed function in i386.c
1333 (define_insn "*vec_extractv2si_1"
1334   [(set (match_operand:SI 0 "nonimmediate_operand"     "=y,Y2,Y2,x,y,x,r")
1335         (vec_select:SI
1336           (match_operand:V2SI 1 "nonimmediate_operand" " 0,0 ,Y2,0,o,o,o")
1337           (parallel [(const_int 1)])))]
1338   "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1339   "@
1340    punpckhdq\t%0, %0
1341    punpckhdq\t%0, %0
1342    pshufd\t{$85, %1, %0|%0, %1, 85}
1343    unpckhps\t%0, %0
1344    #
1345    #
1346    #"
1347   [(set_attr "type" "mmxcvt,sselog1,sselog1,sselog1,mmxmov,ssemov,imov")
1348    (set_attr "mode" "DI,TI,TI,V4SF,SI,SI,SI")])
1349
1350 (define_split
1351   [(set (match_operand:SI 0 "register_operand" "")
1352         (vec_select:SI
1353           (match_operand:V2SI 1 "memory_operand" "")
1354           (parallel [(const_int 1)])))]
1355   "TARGET_MMX && reload_completed"
1356   [(const_int 0)]
1357 {
1358   operands[1] = adjust_address (operands[1], SImode, 4);
1359   emit_move_insn (operands[0], operands[1]);
1360   DONE;
1361 })
1362
1363 (define_expand "vec_extractv2si"
1364   [(match_operand:SI 0 "register_operand" "")
1365    (match_operand:V2SI 1 "register_operand" "")
1366    (match_operand 2 "const_int_operand" "")]
1367   "TARGET_MMX"
1368 {
1369   ix86_expand_vector_extract (false, operands[0], operands[1],
1370                               INTVAL (operands[2]));
1371   DONE;
1372 })
1373
1374 (define_expand "vec_initv2si"
1375   [(match_operand:V2SI 0 "register_operand" "")
1376    (match_operand 1 "" "")]
1377   "TARGET_SSE"
1378 {
1379   ix86_expand_vector_init (false, operands[0], operands[1]);
1380   DONE;
1381 })
1382
1383 (define_expand "vec_setv4hi"
1384   [(match_operand:V4HI 0 "register_operand" "")
1385    (match_operand:HI 1 "register_operand" "")
1386    (match_operand 2 "const_int_operand" "")]
1387   "TARGET_MMX"
1388 {
1389   ix86_expand_vector_set (false, operands[0], operands[1],
1390                           INTVAL (operands[2]));
1391   DONE;
1392 })
1393
1394 (define_expand "vec_extractv4hi"
1395   [(match_operand:HI 0 "register_operand" "")
1396    (match_operand:V4HI 1 "register_operand" "")
1397    (match_operand 2 "const_int_operand" "")]
1398   "TARGET_MMX"
1399 {
1400   ix86_expand_vector_extract (false, operands[0], operands[1],
1401                               INTVAL (operands[2]));
1402   DONE;
1403 })
1404
1405 (define_expand "vec_initv4hi"
1406   [(match_operand:V4HI 0 "register_operand" "")
1407    (match_operand 1 "" "")]
1408   "TARGET_SSE"
1409 {
1410   ix86_expand_vector_init (false, operands[0], operands[1]);
1411   DONE;
1412 })
1413
1414 (define_expand "vec_setv8qi"
1415   [(match_operand:V8QI 0 "register_operand" "")
1416    (match_operand:QI 1 "register_operand" "")
1417    (match_operand 2 "const_int_operand" "")]
1418   "TARGET_MMX"
1419 {
1420   ix86_expand_vector_set (false, operands[0], operands[1],
1421                           INTVAL (operands[2]));
1422   DONE;
1423 })
1424
1425 (define_expand "vec_extractv8qi"
1426   [(match_operand:QI 0 "register_operand" "")
1427    (match_operand:V8QI 1 "register_operand" "")
1428    (match_operand 2 "const_int_operand" "")]
1429   "TARGET_MMX"
1430 {
1431   ix86_expand_vector_extract (false, operands[0], operands[1],
1432                               INTVAL (operands[2]));
1433   DONE;
1434 })
1435
1436 (define_expand "vec_initv8qi"
1437   [(match_operand:V8QI 0 "register_operand" "")
1438    (match_operand 1 "" "")]
1439   "TARGET_SSE"
1440 {
1441   ix86_expand_vector_init (false, operands[0], operands[1]);
1442   DONE;
1443 })
1444
1445 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1446 ;;
1447 ;; Miscellaneous
1448 ;;
1449 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1450
1451 (define_expand "mmx_uavgv8qi3"
1452   [(set (match_operand:V8QI 0 "register_operand" "")
1453         (truncate:V8QI
1454           (lshiftrt:V8HI
1455             (plus:V8HI
1456               (plus:V8HI
1457                 (zero_extend:V8HI
1458                   (match_operand:V8QI 1 "nonimmediate_operand" ""))
1459                 (zero_extend:V8HI
1460                   (match_operand:V8QI 2 "nonimmediate_operand" "")))
1461               (const_vector:V8HI [(const_int 1) (const_int 1)
1462                                   (const_int 1) (const_int 1)
1463                                   (const_int 1) (const_int 1)
1464                                   (const_int 1) (const_int 1)]))
1465             (const_int 1))))]
1466   "TARGET_SSE || TARGET_3DNOW"
1467   "ix86_fixup_binary_operands_no_copy (PLUS, V8QImode, operands);")
1468
1469 (define_insn "*mmx_uavgv8qi3"
1470   [(set (match_operand:V8QI 0 "register_operand" "=y")
1471         (truncate:V8QI
1472           (lshiftrt:V8HI
1473             (plus:V8HI
1474               (plus:V8HI
1475                 (zero_extend:V8HI
1476                   (match_operand:V8QI 1 "nonimmediate_operand" "%0"))
1477                 (zero_extend:V8HI
1478                   (match_operand:V8QI 2 "nonimmediate_operand" "ym")))
1479               (const_vector:V8HI [(const_int 1) (const_int 1)
1480                                   (const_int 1) (const_int 1)
1481                                   (const_int 1) (const_int 1)
1482                                   (const_int 1) (const_int 1)]))
1483             (const_int 1))))]
1484   "(TARGET_SSE || TARGET_3DNOW)
1485    && ix86_binary_operator_ok (PLUS, V8QImode, operands)"
1486 {
1487   /* These two instructions have the same operation, but their encoding
1488      is different.  Prefer the one that is de facto standard.  */
1489   if (TARGET_SSE || TARGET_3DNOW_A)
1490     return "pavgb\t{%2, %0|%0, %2}";
1491   else
1492     return "pavgusb\t{%2, %0|%0, %2}";
1493 }
1494   [(set_attr "type" "mmxshft")
1495    (set_attr "mode" "DI")])
1496
1497 (define_expand "mmx_uavgv4hi3"
1498   [(set (match_operand:V4HI 0 "register_operand" "")
1499         (truncate:V4HI
1500           (lshiftrt:V4SI
1501             (plus:V4SI
1502               (plus:V4SI
1503                 (zero_extend:V4SI
1504                   (match_operand:V4HI 1 "nonimmediate_operand" ""))
1505                 (zero_extend:V4SI
1506                   (match_operand:V4HI 2 "nonimmediate_operand" "")))
1507               (const_vector:V4SI [(const_int 1) (const_int 1)
1508                                   (const_int 1) (const_int 1)]))
1509             (const_int 1))))]
1510   "TARGET_SSE || TARGET_3DNOW_A"
1511   "ix86_fixup_binary_operands_no_copy (PLUS, V4HImode, operands);")
1512
1513 (define_insn "*mmx_uavgv4hi3"
1514   [(set (match_operand:V4HI 0 "register_operand" "=y")
1515         (truncate:V4HI
1516           (lshiftrt:V4SI
1517             (plus:V4SI
1518               (plus:V4SI
1519                 (zero_extend:V4SI
1520                   (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
1521                 (zero_extend:V4SI
1522                   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
1523               (const_vector:V4SI [(const_int 1) (const_int 1)
1524                                   (const_int 1) (const_int 1)]))
1525             (const_int 1))))]
1526   "(TARGET_SSE || TARGET_3DNOW_A)
1527    && ix86_binary_operator_ok (PLUS, V4HImode, operands)"
1528   "pavgw\t{%2, %0|%0, %2}"
1529   [(set_attr "type" "mmxshft")
1530    (set_attr "mode" "DI")])
1531
1532 (define_insn "mmx_psadbw"
1533   [(set (match_operand:V1DI 0 "register_operand" "=y")
1534         (unspec:V1DI [(match_operand:V8QI 1 "register_operand" "0")
1535                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
1536                      UNSPEC_PSADBW))]
1537   "TARGET_SSE || TARGET_3DNOW_A"
1538   "psadbw\t{%2, %0|%0, %2}"
1539   [(set_attr "type" "mmxshft")
1540    (set_attr "mode" "DI")])
1541
1542 (define_insn "mmx_pmovmskb"
1543   [(set (match_operand:SI 0 "register_operand" "=r")
1544         (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
1545                    UNSPEC_MOVMSK))]
1546   "TARGET_SSE || TARGET_3DNOW_A"
1547   "pmovmskb\t{%1, %0|%0, %1}"
1548   [(set_attr "type" "mmxcvt")
1549    (set_attr "mode" "DI")])
1550
1551 (define_expand "mmx_maskmovq"
1552   [(set (match_operand:V8QI 0 "memory_operand" "")
1553         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "")
1554                       (match_operand:V8QI 2 "register_operand" "")
1555                       (match_dup 0)]
1556                      UNSPEC_MASKMOV))]
1557   "TARGET_SSE || TARGET_3DNOW_A"
1558   "")
1559
1560 (define_insn "*mmx_maskmovq"
1561   [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
1562         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
1563                       (match_operand:V8QI 2 "register_operand" "y")
1564                       (mem:V8QI (match_dup 0))]
1565                      UNSPEC_MASKMOV))]
1566   "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
1567   ;; @@@ check ordering of operands in intel/nonintel syntax
1568   "maskmovq\t{%2, %1|%1, %2}"
1569   [(set_attr "type" "mmxcvt")
1570    (set_attr "mode" "DI")])
1571
1572 (define_insn "*mmx_maskmovq_rex"
1573   [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
1574         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
1575                       (match_operand:V8QI 2 "register_operand" "y")
1576                       (mem:V8QI (match_dup 0))]
1577                      UNSPEC_MASKMOV))]
1578   "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
1579   ;; @@@ check ordering of operands in intel/nonintel syntax
1580   "maskmovq\t{%2, %1|%1, %2}"
1581   [(set_attr "type" "mmxcvt")
1582    (set_attr "mode" "DI")])
1583
1584 (define_insn "mmx_emms"
1585   [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
1586    (clobber (reg:XF ST0_REG))
1587    (clobber (reg:XF ST1_REG))
1588    (clobber (reg:XF ST2_REG))
1589    (clobber (reg:XF ST3_REG))
1590    (clobber (reg:XF ST4_REG))
1591    (clobber (reg:XF ST5_REG))
1592    (clobber (reg:XF ST6_REG))
1593    (clobber (reg:XF ST7_REG))
1594    (clobber (reg:DI MM0_REG))
1595    (clobber (reg:DI MM1_REG))
1596    (clobber (reg:DI MM2_REG))
1597    (clobber (reg:DI MM3_REG))
1598    (clobber (reg:DI MM4_REG))
1599    (clobber (reg:DI MM5_REG))
1600    (clobber (reg:DI MM6_REG))
1601    (clobber (reg:DI MM7_REG))]
1602   "TARGET_MMX"
1603   "emms"
1604   [(set_attr "type" "mmx")
1605    (set_attr "memory" "unknown")])
1606
1607 (define_insn "mmx_femms"
1608   [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
1609    (clobber (reg:XF ST0_REG))
1610    (clobber (reg:XF ST1_REG))
1611    (clobber (reg:XF ST2_REG))
1612    (clobber (reg:XF ST3_REG))
1613    (clobber (reg:XF ST4_REG))
1614    (clobber (reg:XF ST5_REG))
1615    (clobber (reg:XF ST6_REG))
1616    (clobber (reg:XF ST7_REG))
1617    (clobber (reg:DI MM0_REG))
1618    (clobber (reg:DI MM1_REG))
1619    (clobber (reg:DI MM2_REG))
1620    (clobber (reg:DI MM3_REG))
1621    (clobber (reg:DI MM4_REG))
1622    (clobber (reg:DI MM5_REG))
1623    (clobber (reg:DI MM6_REG))
1624    (clobber (reg:DI MM7_REG))]
1625   "TARGET_3DNOW"
1626   "femms"
1627   [(set_attr "type" "mmx")
1628    (set_attr "memory" "none")])