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