OSDN Git Service

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