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