OSDN Git Service

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