OSDN Git Service

04c5f9df9f82de85e295c06b6204026bb2330eb6
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / mmx.md
1 ;; GCC machine description for MMX and 3dNOW! instructions
2 ;; Copyright (C) 2005, 2007, 2008, 2009, 2010, 2011
3 ;; Free Software Foundation, Inc.
4 ;;
5 ;; This file is part of GCC.
6 ;;
7 ;; GCC is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 3, or (at your option)
10 ;; any later version.
11 ;;
12 ;; GCC is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 ;; GNU General Public License for more details.
16 ;;
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3.  If not see
19 ;; <http://www.gnu.org/licenses/>.
20
21 ;; The MMX and 3dNOW! patterns are in the same file because they use
22 ;; the same register file, and 3dNOW! adds a number of extensions to
23 ;; the base integer MMX isa.
24
25 ;; Note!  Except for the basic move instructions, *all* of these
26 ;; patterns are outside the normal optabs namespace.  This is because
27 ;; use of these registers requires the insertion of emms or femms
28 ;; instructions to return to normal fpu mode.  The compiler doesn't
29 ;; know how to do that itself, which means it's up to the user.  Which
30 ;; means that we should never use any of these patterns except at the
31 ;; direction of the user via a builtin.
32
33 ;; 8 byte integral modes handled by MMX (and by extension, SSE)
34 (define_mode_iterator MMXMODEI [V8QI V4HI V2SI])
35 (define_mode_iterator MMXMODEI8 [V8QI V4HI V2SI V1DI])
36
37 ;; All 8-byte vector modes handled by MMX
38 (define_mode_iterator MMXMODE [V8QI V4HI V2SI V1DI V2SF])
39
40 ;; Mix-n-match
41 (define_mode_iterator MMXMODE12 [V8QI V4HI])
42 (define_mode_iterator MMXMODE24 [V4HI V2SI])
43 (define_mode_iterator MMXMODE248 [V4HI V2SI V1DI])
44
45 ;; Mapping from integer vector mode to mnemonic suffix
46 (define_mode_attr mmxvecsize [(V8QI "b") (V4HI "w") (V2SI "d") (V1DI "q")])
47
48 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
49 ;;
50 ;; Move patterns
51 ;;
52 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
53
54 ;; All of these patterns are enabled for MMX as well as 3dNOW.
55 ;; This is essential for maintaining stable calling conventions.
56
57 (define_expand "mov<mode>"
58   [(set (match_operand:MMXMODEI8 0 "nonimmediate_operand" "")
59         (match_operand:MMXMODEI8 1 "nonimmediate_operand" ""))]
60   "TARGET_MMX"
61 {
62   ix86_expand_vector_move (<MODE>mode, operands);
63   DONE;
64 })
65
66 ;; movd instead of movq is required to handle broken assemblers.
67 (define_insn "*mov<mode>_internal_rex64"
68   [(set (match_operand:MMXMODEI8 0 "nonimmediate_operand"
69          "=rm,r,!?y,!y,!?y,m  ,!y ,*x,x,x ,m,r ,Yi")
70         (match_operand:MMXMODEI8 1 "vector_move_operand"
71          "Cr ,m,C  ,!y,m  ,!?y,*x,!y ,C,xm,x,Yi,r"))]
72   "TARGET_64BIT && TARGET_MMX
73    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
74   "@
75     mov{q}\t{%1, %0|%0, %1}
76     mov{q}\t{%1, %0|%0, %1}
77     pxor\t%0, %0
78     movq\t{%1, %0|%0, %1}
79     movq\t{%1, %0|%0, %1}
80     movq\t{%1, %0|%0, %1}
81     movdq2q\t{%1, %0|%0, %1}
82     movq2dq\t{%1, %0|%0, %1}
83     %vpxor\t%0, %d0
84     %vmovq\t{%1, %0|%0, %1}
85     %vmovq\t{%1, %0|%0, %1}
86     %vmovd\t{%1, %0|%0, %1}
87     %vmovd\t{%1, %0|%0, %1}"
88   [(set (attr "type")
89      (cond [(eq_attr "alternative" "0,1")
90               (const_string "imov")
91             (eq_attr "alternative" "2")
92               (const_string "mmx")
93             (eq_attr "alternative" "3,4,5")
94               (const_string "mmxmov")
95             (eq_attr "alternative" "6,7")
96               (const_string "ssecvt")
97             (eq_attr "alternative" "8")
98               (const_string "sselog1")
99            ]
100            (const_string "ssemov")))
101    (set (attr "unit")
102      (if_then_else (eq_attr "alternative" "6,7")
103        (const_string "mmx")
104        (const_string "*")))
105    (set (attr "prefix_rep")
106      (if_then_else (eq_attr "alternative" "6,7,9")
107        (const_string "1")
108        (const_string "*")))
109    (set (attr "prefix_data16")
110      (if_then_else (eq_attr "alternative" "10,11,12")
111        (const_string "1")
112        (const_string "*")))
113    (set (attr "prefix_rex")
114      (if_then_else (eq_attr "alternative" "9,10")
115        (symbol_ref "x86_extended_reg_mentioned_p (insn)")
116        (const_string "*")))
117    (set (attr "prefix")
118      (if_then_else (eq_attr "alternative" "8,9,10,11,12")
119        (const_string "maybe_vex")
120        (const_string "orig")))
121    (set_attr "mode" "DI")])
122
123 (define_insn "*mov<mode>_internal"
124   [(set (match_operand:MMXMODEI8 0 "nonimmediate_operand"
125          "=!?y,!y,!?y,m  ,!y,*x,*x,*x ,m ,*x,*x,*x,m ,r  ,m")
126         (match_operand:MMXMODEI8 1 "vector_move_operand"
127          "C   ,!y,m  ,!?y,*x,!y,C ,*xm,*x,C ,*x,m ,*x,irm,r"))]
128   "!TARGET_64BIT && TARGET_MMX
129    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
130   "@
131     pxor\t%0, %0
132     movq\t{%1, %0|%0, %1}
133     movq\t{%1, %0|%0, %1}
134     movq\t{%1, %0|%0, %1}
135     movdq2q\t{%1, %0|%0, %1}
136     movq2dq\t{%1, %0|%0, %1}
137     %vpxor\t%0, %d0
138     %vmovq\t{%1, %0|%0, %1}
139     %vmovq\t{%1, %0|%0, %1}
140     xorps\t%0, %0
141     movaps\t{%1, %0|%0, %1}
142     movlps\t{%1, %0|%0, %1}
143     movlps\t{%1, %0|%0, %1}
144     #
145     #"
146   [(set (attr "isa")
147      (cond [(eq_attr "alternative" "4,5,6,7,8")
148               (const_string "sse2")
149             (eq_attr "alternative" "9,10,11,12")
150               (const_string "noavx")
151            ]
152            (const_string "*")))
153    (set (attr "type")
154      (cond [(eq_attr "alternative" "0")
155               (const_string "mmx")
156             (eq_attr "alternative" "1,2,3")
157               (const_string "mmxmov")
158             (eq_attr "alternative" "4,5")
159               (const_string "ssecvt")
160             (eq_attr "alternative" "6,9")
161               (const_string "sselog1")
162             (eq_attr "alternative" "13,14")
163               (const_string "multi")
164            ]
165            (const_string "ssemov")))
166    (set (attr "unit")
167      (if_then_else (eq_attr "alternative" "4,5")
168        (const_string "mmx")
169        (const_string "*")))
170    (set (attr "prefix_rep")
171      (if_then_else
172        (ior (eq_attr "alternative" "4,5")
173             (and (eq_attr "alternative" "7")
174                  (not (match_test "TARGET_AVX"))))
175        (const_string "1")
176        (const_string "*")))
177    (set (attr "prefix_data16")
178      (if_then_else
179        (and (eq_attr "alternative" "8")
180             (not (match_test "TARGET_AVX")))
181        (const_string "1")
182        (const_string "*")))
183    (set (attr "prefix")
184      (if_then_else (eq_attr "alternative" "6,7,8")
185        (const_string "maybe_vex")
186        (const_string "orig")))
187    (set_attr "mode" "DI,DI,DI,DI,DI,DI,TI,DI,DI,V4SF,V4SF,V2SF,V2SF,DI,DI")])
188
189 (define_expand "movv2sf"
190   [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
191         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
192   "TARGET_MMX"
193 {
194   ix86_expand_vector_move (V2SFmode, operands);
195   DONE;
196 })
197
198 ;; movd instead of movq is required to handle broken assemblers.
199 (define_insn "*movv2sf_internal_rex64"
200   [(set (match_operand:V2SF 0 "nonimmediate_operand"
201          "=rm,r,!?y,!y,!?y,m  ,!y,*x,x,x,x,m,r ,Yi")
202         (match_operand:V2SF 1 "vector_move_operand"
203          "Cr ,m,C  ,!y,m  ,!?y,*x,!y,C,x,m,x,Yi,r"))]
204   "TARGET_64BIT && TARGET_MMX
205    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
206   "@
207     mov{q}\t{%1, %0|%0, %1}
208     mov{q}\t{%1, %0|%0, %1}
209     pxor\t%0, %0
210     movq\t{%1, %0|%0, %1}
211     movq\t{%1, %0|%0, %1}
212     movq\t{%1, %0|%0, %1}
213     movdq2q\t{%1, %0|%0, %1}
214     movq2dq\t{%1, %0|%0, %1}
215     %vxorps\t%0, %d0
216     %vmovaps\t{%1, %0|%0, %1}
217     %vmovlps\t{%1, %d0|%d0, %1}
218     %vmovlps\t{%1, %0|%0, %1}
219     %vmovd\t{%1, %0|%0, %1}
220     %vmovd\t{%1, %0|%0, %1}"
221   [(set (attr "type")
222      (cond [(eq_attr "alternative" "0,1")
223               (const_string "imov")
224             (eq_attr "alternative" "2")
225               (const_string "mmx")
226             (eq_attr "alternative" "3,4,5")
227               (const_string "mmxmov")
228             (eq_attr "alternative" "6,7")
229               (const_string "ssecvt")
230             (eq_attr "alternative" "9")
231               (const_string "sselog1")
232            ]
233            (const_string "ssemov")))
234    (set (attr "unit")
235      (if_then_else (eq_attr "alternative" "6,7")
236        (const_string "mmx")
237        (const_string "*")))
238    (set (attr "prefix_rep")
239      (if_then_else (eq_attr "alternative" "6,7")
240        (const_string "1")
241        (const_string "*")))
242    (set (attr "length_vex")
243      (if_then_else
244        (and (eq_attr "alternative" "12,13")
245             (match_test "TARGET_AVX"))
246        (const_string "4")
247        (const_string "*")))
248    (set (attr "prefix")
249      (if_then_else (eq_attr "alternative" "8,9,10,11,12,13")
250        (const_string "maybe_vex")
251        (const_string "orig")))
252    (set_attr "mode" "DI,DI,DI,DI,DI,DI,DI,DI,V4SF,V4SF,V2SF,V2SF,DI,DI")])
253
254 (define_insn "*movv2sf_internal"
255   [(set (match_operand:V2SF 0 "nonimmediate_operand"
256          "=!?y,!y,!?y,m  ,!y,*x,*x,*x,*x,m ,r  ,m")
257         (match_operand:V2SF 1 "vector_move_operand"
258          "C   ,!y,m  ,!?y,*x,!y,C ,*x,m ,*x,irm,r"))]
259   "!TARGET_64BIT && TARGET_MMX
260    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
261   "@
262     pxor\t%0, %0
263     movq\t{%1, %0|%0, %1}
264     movq\t{%1, %0|%0, %1}
265     movq\t{%1, %0|%0, %1}
266     movdq2q\t{%1, %0|%0, %1}
267     movq2dq\t{%1, %0|%0, %1}
268     %vxorps\t%0, %d0
269     %vmovaps\t{%1, %0|%0, %1}
270     %vmovlps\t{%1, %d0|%d0, %1}
271     %vmovlps\t{%1, %0|%0, %1}
272     #
273     #"
274   [(set (attr "isa")
275      (if_then_else (eq_attr "alternative" "4,5")
276        (const_string "sse2")
277        (const_string "*")))
278    (set (attr "type")
279      (cond [(eq_attr "alternative" "0")
280               (const_string "mmx")
281             (eq_attr "alternative" "1,2,3")
282               (const_string "mmxmov")
283             (eq_attr "alternative" "4,5")
284               (const_string "ssecvt")
285             (eq_attr "alternative" "6")
286               (const_string "sselog1")
287             (eq_attr "alternative" "10,11")
288               (const_string "multi")
289            ]
290            (const_string "ssemov")))
291    (set (attr "unit")
292      (if_then_else (eq_attr "alternative" "4,5")
293        (const_string "mmx")
294        (const_string "*")))
295    (set (attr "prefix_rep")
296      (if_then_else (eq_attr "alternative" "4,5")
297        (const_string "1")
298        (const_string "*")))
299    (set (attr "prefix")
300      (if_then_else (eq_attr "alternative" "6,7,8,9")
301        (const_string "maybe_vex")
302        (const_string "orig")))
303    (set_attr "mode" "DI,DI,DI,DI,DI,DI,V4SF,V4SF,V2SF,V2SF,DI,DI")])
304
305 ;; %%% This multiword shite has got to go.
306 (define_split
307   [(set (match_operand:MMXMODE 0 "nonimmediate_operand" "")
308         (match_operand:MMXMODE 1 "general_operand" ""))]
309   "!TARGET_64BIT && reload_completed
310    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0])
311         || MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
312   [(const_int 0)]
313   "ix86_split_long_move (operands); DONE;")
314
315 (define_expand "push<mode>1"
316   [(match_operand:MMXMODE 0 "register_operand" "")]
317   "TARGET_MMX"
318 {
319   ix86_expand_push (<MODE>mode, operands[0]);
320   DONE;
321 })
322
323 (define_expand "movmisalign<mode>"
324   [(set (match_operand:MMXMODE 0 "nonimmediate_operand" "")
325         (match_operand:MMXMODE 1 "nonimmediate_operand" ""))]
326   "TARGET_MMX"
327 {
328   ix86_expand_vector_move (<MODE>mode, operands);
329   DONE;
330 })
331
332 (define_insn "sse_movntdi"
333   [(set (match_operand:DI 0 "memory_operand" "=m")
334         (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
335                    UNSPEC_MOVNT))]
336   "TARGET_SSE || TARGET_3DNOW_A"
337   "movntq\t{%1, %0|%0, %1}"
338   [(set_attr "type" "mmxmov")
339    (set_attr "mode" "DI")])
340
341 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
342 ;;
343 ;; Parallel single-precision floating point arithmetic
344 ;;
345 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
346
347 (define_expand "mmx_addv2sf3"
348   [(set (match_operand:V2SF 0 "register_operand" "")
349         (plus:V2SF
350           (match_operand:V2SF 1 "nonimmediate_operand" "")
351           (match_operand:V2SF 2 "nonimmediate_operand" "")))]
352   "TARGET_3DNOW"
353   "ix86_fixup_binary_operands_no_copy (PLUS, V2SFmode, operands);")
354
355 (define_insn "*mmx_addv2sf3"
356   [(set (match_operand:V2SF 0 "register_operand" "=y")
357         (plus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
358                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
359   "TARGET_3DNOW && ix86_binary_operator_ok (PLUS, V2SFmode, operands)"
360   "pfadd\t{%2, %0|%0, %2}"
361   [(set_attr "type" "mmxadd")
362    (set_attr "prefix_extra" "1")
363    (set_attr "mode" "V2SF")])
364
365 (define_expand "mmx_subv2sf3"
366   [(set (match_operand:V2SF 0 "register_operand" "")
367         (minus:V2SF (match_operand:V2SF 1 "register_operand" "")
368                     (match_operand:V2SF 2 "nonimmediate_operand" "")))]
369   "TARGET_3DNOW")
370
371 (define_expand "mmx_subrv2sf3"
372   [(set (match_operand:V2SF 0 "register_operand" "")
373         (minus:V2SF (match_operand:V2SF 2 "register_operand" "")
374                     (match_operand:V2SF 1 "nonimmediate_operand" "")))]
375   "TARGET_3DNOW")
376
377 (define_insn "*mmx_subv2sf3"
378   [(set (match_operand:V2SF 0 "register_operand" "=y,y")
379         (minus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "0,ym")
380                     (match_operand:V2SF 2 "nonimmediate_operand" "ym,0")))]
381   "TARGET_3DNOW && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
382   "@
383    pfsub\t{%2, %0|%0, %2}
384    pfsubr\t{%1, %0|%0, %1}"
385   [(set_attr "type" "mmxadd")
386    (set_attr "prefix_extra" "1")
387    (set_attr "mode" "V2SF")])
388
389 (define_expand "mmx_mulv2sf3"
390   [(set (match_operand:V2SF 0 "register_operand" "")
391         (mult:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "")
392                    (match_operand:V2SF 2 "nonimmediate_operand" "")))]
393   "TARGET_3DNOW"
394   "ix86_fixup_binary_operands_no_copy (MULT, V2SFmode, operands);")
395
396 (define_insn "*mmx_mulv2sf3"
397   [(set (match_operand:V2SF 0 "register_operand" "=y")
398         (mult:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
399                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
400   "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V2SFmode, operands)"
401   "pfmul\t{%2, %0|%0, %2}"
402   [(set_attr "type" "mmxmul")
403    (set_attr "prefix_extra" "1")
404    (set_attr "mode" "V2SF")])
405
406 ;; ??? For !flag_finite_math_only, the representation with SMIN/SMAX
407 ;; isn't really correct, as those rtl operators aren't defined when
408 ;; applied to NaNs.  Hopefully the optimizers won't get too smart on us.
409
410 (define_expand "mmx_<code>v2sf3"
411   [(set (match_operand:V2SF 0 "register_operand" "")
412         (smaxmin:V2SF
413           (match_operand:V2SF 1 "nonimmediate_operand" "")
414           (match_operand:V2SF 2 "nonimmediate_operand" "")))]
415   "TARGET_3DNOW"
416 {
417   if (!flag_finite_math_only)
418     operands[1] = force_reg (V2SFmode, operands[1]);
419   ix86_fixup_binary_operands_no_copy (<CODE>, V2SFmode, operands);
420 })
421
422 (define_insn "*mmx_<code>v2sf3_finite"
423   [(set (match_operand:V2SF 0 "register_operand" "=y")
424         (smaxmin:V2SF
425           (match_operand:V2SF 1 "nonimmediate_operand" "%0")
426           (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
427   "TARGET_3DNOW && flag_finite_math_only
428    && ix86_binary_operator_ok (<CODE>, V2SFmode, operands)"
429   "pf<maxmin_float>\t{%2, %0|%0, %2}"
430   [(set_attr "type" "mmxadd")
431    (set_attr "prefix_extra" "1")
432    (set_attr "mode" "V2SF")])
433
434 (define_insn "*mmx_<code>v2sf3"
435   [(set (match_operand:V2SF 0 "register_operand" "=y")
436         (smaxmin:V2SF
437           (match_operand:V2SF 1 "register_operand" "0")
438           (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
439   "TARGET_3DNOW"
440   "pf<maxmin_float>\t{%2, %0|%0, %2}"
441   [(set_attr "type" "mmxadd")
442    (set_attr "prefix_extra" "1")
443    (set_attr "mode" "V2SF")])
444
445 (define_insn "mmx_rcpv2sf2"
446   [(set (match_operand:V2SF 0 "register_operand" "=y")
447         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
448                      UNSPEC_PFRCP))]
449   "TARGET_3DNOW"
450   "pfrcp\t{%1, %0|%0, %1}"
451   [(set_attr "type" "mmx")
452    (set_attr "prefix_extra" "1")
453    (set_attr "mode" "V2SF")])
454
455 (define_insn "mmx_rcpit1v2sf3"
456   [(set (match_operand:V2SF 0 "register_operand" "=y")
457         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
458                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
459                      UNSPEC_PFRCPIT1))]
460   "TARGET_3DNOW"
461   "pfrcpit1\t{%2, %0|%0, %2}"
462   [(set_attr "type" "mmx")
463    (set_attr "prefix_extra" "1")
464    (set_attr "mode" "V2SF")])
465
466 (define_insn "mmx_rcpit2v2sf3"
467   [(set (match_operand:V2SF 0 "register_operand" "=y")
468         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
469                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
470                      UNSPEC_PFRCPIT2))]
471   "TARGET_3DNOW"
472   "pfrcpit2\t{%2, %0|%0, %2}"
473   [(set_attr "type" "mmx")
474    (set_attr "prefix_extra" "1")
475    (set_attr "mode" "V2SF")])
476
477 (define_insn "mmx_rsqrtv2sf2"
478   [(set (match_operand:V2SF 0 "register_operand" "=y")
479         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
480                      UNSPEC_PFRSQRT))]
481   "TARGET_3DNOW"
482   "pfrsqrt\t{%1, %0|%0, %1}"
483   [(set_attr "type" "mmx")
484    (set_attr "prefix_extra" "1")
485    (set_attr "mode" "V2SF")])
486
487 (define_insn "mmx_rsqit1v2sf3"
488   [(set (match_operand:V2SF 0 "register_operand" "=y")
489         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
490                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
491                      UNSPEC_PFRSQIT1))]
492   "TARGET_3DNOW"
493   "pfrsqit1\t{%2, %0|%0, %2}"
494   [(set_attr "type" "mmx")
495    (set_attr "prefix_extra" "1")
496    (set_attr "mode" "V2SF")])
497
498 (define_insn "mmx_haddv2sf3"
499   [(set (match_operand:V2SF 0 "register_operand" "=y")
500         (vec_concat:V2SF
501           (plus:SF
502             (vec_select:SF
503               (match_operand:V2SF 1 "register_operand" "0")
504               (parallel [(const_int  0)]))
505             (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
506           (plus:SF
507             (vec_select:SF
508               (match_operand:V2SF 2 "nonimmediate_operand" "ym")
509               (parallel [(const_int  0)]))
510             (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
511   "TARGET_3DNOW"
512   "pfacc\t{%2, %0|%0, %2}"
513   [(set_attr "type" "mmxadd")
514    (set_attr "prefix_extra" "1")
515    (set_attr "mode" "V2SF")])
516
517 (define_insn "mmx_hsubv2sf3"
518   [(set (match_operand:V2SF 0 "register_operand" "=y")
519         (vec_concat:V2SF
520           (minus:SF
521             (vec_select:SF
522               (match_operand:V2SF 1 "register_operand" "0")
523               (parallel [(const_int  0)]))
524             (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
525           (minus:SF
526             (vec_select:SF
527               (match_operand:V2SF 2 "nonimmediate_operand" "ym")
528               (parallel [(const_int  0)]))
529             (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
530   "TARGET_3DNOW_A"
531   "pfnacc\t{%2, %0|%0, %2}"
532   [(set_attr "type" "mmxadd")
533    (set_attr "prefix_extra" "1")
534    (set_attr "mode" "V2SF")])
535
536 (define_insn "mmx_addsubv2sf3"
537   [(set (match_operand:V2SF 0 "register_operand" "=y")
538         (vec_merge:V2SF
539           (plus:V2SF
540             (match_operand:V2SF 1 "register_operand" "0")
541             (match_operand:V2SF 2 "nonimmediate_operand" "ym"))
542           (minus:V2SF (match_dup 1) (match_dup 2))
543           (const_int 1)))]
544   "TARGET_3DNOW_A"
545   "pfpnacc\t{%2, %0|%0, %2}"
546   [(set_attr "type" "mmxadd")
547    (set_attr "prefix_extra" "1")
548    (set_attr "mode" "V2SF")])
549
550 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
551 ;;
552 ;; Parallel single-precision floating point comparisons
553 ;;
554 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
555
556 (define_expand "mmx_eqv2sf3"
557   [(set (match_operand:V2SI 0 "register_operand" "")
558         (eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "")
559                  (match_operand:V2SF 2 "nonimmediate_operand" "")))]
560   "TARGET_3DNOW"
561   "ix86_fixup_binary_operands_no_copy (EQ, V2SFmode, operands);")
562
563 (define_insn "*mmx_eqv2sf3"
564   [(set (match_operand:V2SI 0 "register_operand" "=y")
565         (eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "%0")
566                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
567   "TARGET_3DNOW && ix86_binary_operator_ok (EQ, V2SFmode, operands)"
568   "pfcmpeq\t{%2, %0|%0, %2}"
569   [(set_attr "type" "mmxcmp")
570    (set_attr "prefix_extra" "1")
571    (set_attr "mode" "V2SF")])
572
573 (define_insn "mmx_gtv2sf3"
574   [(set (match_operand:V2SI 0 "register_operand" "=y")
575         (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
576                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
577   "TARGET_3DNOW"
578   "pfcmpgt\t{%2, %0|%0, %2}"
579   [(set_attr "type" "mmxcmp")
580    (set_attr "prefix_extra" "1")
581    (set_attr "mode" "V2SF")])
582
583 (define_insn "mmx_gev2sf3"
584   [(set (match_operand:V2SI 0 "register_operand" "=y")
585         (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
586                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
587   "TARGET_3DNOW"
588   "pfcmpge\t{%2, %0|%0, %2}"
589   [(set_attr "type" "mmxcmp")
590    (set_attr "prefix_extra" "1")
591    (set_attr "mode" "V2SF")])
592
593 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
594 ;;
595 ;; Parallel single-precision floating point conversion operations
596 ;;
597 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
598
599 (define_insn "mmx_pf2id"
600   [(set (match_operand:V2SI 0 "register_operand" "=y")
601         (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
602   "TARGET_3DNOW"
603   "pf2id\t{%1, %0|%0, %1}"
604   [(set_attr "type" "mmxcvt")
605    (set_attr "prefix_extra" "1")
606    (set_attr "mode" "V2SF")])
607
608 (define_insn "mmx_pf2iw"
609   [(set (match_operand:V2SI 0 "register_operand" "=y")
610         (sign_extend:V2SI
611           (ss_truncate:V2HI
612             (fix:V2SI
613               (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
614   "TARGET_3DNOW_A"
615   "pf2iw\t{%1, %0|%0, %1}"
616   [(set_attr "type" "mmxcvt")
617    (set_attr "prefix_extra" "1")
618    (set_attr "mode" "V2SF")])
619
620 (define_insn "mmx_pi2fw"
621   [(set (match_operand:V2SF 0 "register_operand" "=y")
622         (float:V2SF
623           (sign_extend:V2SI
624             (truncate:V2HI
625               (match_operand:V2SI 1 "nonimmediate_operand" "ym")))))]
626   "TARGET_3DNOW_A"
627   "pi2fw\t{%1, %0|%0, %1}"
628   [(set_attr "type" "mmxcvt")
629    (set_attr "prefix_extra" "1")
630    (set_attr "mode" "V2SF")])
631
632 (define_insn "mmx_floatv2si2"
633   [(set (match_operand:V2SF 0 "register_operand" "=y")
634         (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
635   "TARGET_3DNOW"
636   "pi2fd\t{%1, %0|%0, %1}"
637   [(set_attr "type" "mmxcvt")
638    (set_attr "prefix_extra" "1")
639    (set_attr "mode" "V2SF")])
640
641 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
642 ;;
643 ;; Parallel single-precision floating point element swizzling
644 ;;
645 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
646
647 (define_insn "mmx_pswapdv2sf2"
648   [(set (match_operand:V2SF 0 "register_operand" "=y")
649         (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
650                          (parallel [(const_int 1) (const_int 0)])))]
651   "TARGET_3DNOW_A"
652   "pswapd\t{%1, %0|%0, %1}"
653   [(set_attr "type" "mmxcvt")
654    (set_attr "prefix_extra" "1")
655    (set_attr "mode" "V2SF")])
656
657 (define_insn "*vec_dupv2sf"
658   [(set (match_operand:V2SF 0 "register_operand" "=y")
659         (vec_duplicate:V2SF
660           (match_operand:SF 1 "register_operand" "0")))]
661   "TARGET_MMX"
662   "punpckldq\t%0, %0"
663   [(set_attr "type" "mmxcvt")
664    (set_attr "mode" "DI")])
665
666 (define_insn "*mmx_concatv2sf"
667   [(set (match_operand:V2SF 0 "register_operand"     "=y,y")
668         (vec_concat:V2SF
669           (match_operand:SF 1 "nonimmediate_operand" " 0,rm")
670           (match_operand:SF 2 "vector_move_operand"  "ym,C")))]
671   "TARGET_MMX && !TARGET_SSE"
672   "@
673    punpckldq\t{%2, %0|%0, %2}
674    movd\t{%1, %0|%0, %1}"
675   [(set_attr "type" "mmxcvt,mmxmov")
676    (set_attr "mode" "DI")])
677
678 (define_expand "vec_setv2sf"
679   [(match_operand:V2SF 0 "register_operand" "")
680    (match_operand:SF 1 "register_operand" "")
681    (match_operand 2 "const_int_operand" "")]
682   "TARGET_MMX"
683 {
684   ix86_expand_vector_set (false, operands[0], operands[1],
685                           INTVAL (operands[2]));
686   DONE;
687 })
688
689 ;; Avoid combining registers from different units in a single alternative,
690 ;; see comment above inline_secondary_memory_needed function in i386.c
691 (define_insn_and_split "*vec_extractv2sf_0"
692   [(set (match_operand:SF 0 "nonimmediate_operand"     "=x, m,y ,m,f,r")
693         (vec_select:SF
694           (match_operand:V2SF 1 "nonimmediate_operand" " xm,x,ym,y,m,m")
695           (parallel [(const_int 0)])))]
696   "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
697   "#"
698   "&& reload_completed"
699   [(const_int 0)]
700 {
701   rtx op1 = operands[1];
702   if (REG_P (op1))
703     op1 = gen_rtx_REG (SFmode, REGNO (op1));
704   else
705     op1 = gen_lowpart (SFmode, op1);
706   emit_move_insn (operands[0], op1);
707   DONE;
708 })
709
710 ;; Avoid combining registers from different units in a single alternative,
711 ;; see comment above inline_secondary_memory_needed function in i386.c
712 (define_insn "*vec_extractv2sf_1"
713   [(set (match_operand:SF 0 "nonimmediate_operand"     "=y,x,y,x,f,r")
714         (vec_select:SF
715           (match_operand:V2SF 1 "nonimmediate_operand" " 0,0,o,o,o,o")
716           (parallel [(const_int 1)])))]
717   "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
718   "@
719    punpckhdq\t%0, %0
720    unpckhps\t%0, %0
721    #
722    #
723    #
724    #"
725   [(set_attr "type" "mmxcvt,sselog1,mmxmov,ssemov,fmov,imov")
726    (set_attr "mode" "DI,V4SF,SF,SF,SF,SF")])
727
728 (define_split
729   [(set (match_operand:SF 0 "register_operand" "")
730         (vec_select:SF
731           (match_operand:V2SF 1 "memory_operand" "")
732           (parallel [(const_int 1)])))]
733   "TARGET_MMX && reload_completed"
734   [(const_int 0)]
735 {
736   operands[1] = adjust_address (operands[1], SFmode, 4);
737   emit_move_insn (operands[0], operands[1]);
738   DONE;
739 })
740
741 (define_expand "vec_extractv2sf"
742   [(match_operand:SF 0 "register_operand" "")
743    (match_operand:V2SF 1 "register_operand" "")
744    (match_operand 2 "const_int_operand" "")]
745   "TARGET_MMX"
746 {
747   ix86_expand_vector_extract (false, operands[0], operands[1],
748                               INTVAL (operands[2]));
749   DONE;
750 })
751
752 (define_expand "vec_initv2sf"
753   [(match_operand:V2SF 0 "register_operand" "")
754    (match_operand 1 "" "")]
755   "TARGET_SSE"
756 {
757   ix86_expand_vector_init (false, operands[0], operands[1]);
758   DONE;
759 })
760
761 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
762 ;;
763 ;; Parallel integral arithmetic
764 ;;
765 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
766
767 (define_expand "mmx_<plusminus_insn><mode>3"
768   [(set (match_operand:MMXMODEI8 0 "register_operand" "")
769         (plusminus:MMXMODEI8
770           (match_operand:MMXMODEI8 1 "nonimmediate_operand" "")
771           (match_operand:MMXMODEI8 2 "nonimmediate_operand" "")))]
772   "TARGET_MMX || (TARGET_SSE2 && <MODE>mode == V1DImode)"
773   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
774
775 (define_insn "*mmx_<plusminus_insn><mode>3"
776   [(set (match_operand:MMXMODEI8 0 "register_operand" "=y")
777         (plusminus:MMXMODEI8
778           (match_operand:MMXMODEI8 1 "nonimmediate_operand" "<comm>0")
779           (match_operand:MMXMODEI8 2 "nonimmediate_operand" "ym")))]
780   "(TARGET_MMX || (TARGET_SSE2 && <MODE>mode == V1DImode))
781    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
782   "p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}"
783   [(set_attr "type" "mmxadd")
784    (set_attr "mode" "DI")])
785
786 (define_expand "mmx_<plusminus_insn><mode>3"
787   [(set (match_operand:MMXMODE12 0 "register_operand" "")
788         (sat_plusminus:MMXMODE12
789           (match_operand:MMXMODE12 1 "nonimmediate_operand" "")
790           (match_operand:MMXMODE12 2 "nonimmediate_operand" "")))]
791   "TARGET_MMX"
792   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
793
794 (define_insn "*mmx_<plusminus_insn><mode>3"
795   [(set (match_operand:MMXMODE12 0 "register_operand" "=y")
796         (sat_plusminus:MMXMODE12
797           (match_operand:MMXMODE12 1 "nonimmediate_operand" "<comm>0")
798           (match_operand:MMXMODE12 2 "nonimmediate_operand" "ym")))]
799   "TARGET_MMX && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
800   "p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}"
801   [(set_attr "type" "mmxadd")
802    (set_attr "mode" "DI")])
803
804 (define_expand "mmx_mulv4hi3"
805   [(set (match_operand:V4HI 0 "register_operand" "")
806         (mult:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "")
807                    (match_operand:V4HI 2 "nonimmediate_operand" "")))]
808   "TARGET_MMX"
809   "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
810
811 (define_insn "*mmx_mulv4hi3"
812   [(set (match_operand:V4HI 0 "register_operand" "=y")
813         (mult:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "%0")
814                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
815   "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
816   "pmullw\t{%2, %0|%0, %2}"
817   [(set_attr "type" "mmxmul")
818    (set_attr "mode" "DI")])
819
820 (define_expand "mmx_smulv4hi3_highpart"
821   [(set (match_operand:V4HI 0 "register_operand" "")
822         (truncate:V4HI
823           (lshiftrt:V4SI
824             (mult:V4SI
825               (sign_extend:V4SI
826                 (match_operand:V4HI 1 "nonimmediate_operand" ""))
827               (sign_extend:V4SI
828                 (match_operand:V4HI 2 "nonimmediate_operand" "")))
829             (const_int 16))))]
830   "TARGET_MMX"
831   "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
832
833 (define_insn "*mmx_smulv4hi3_highpart"
834   [(set (match_operand:V4HI 0 "register_operand" "=y")
835         (truncate:V4HI
836           (lshiftrt:V4SI
837             (mult:V4SI
838               (sign_extend:V4SI
839                 (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
840               (sign_extend:V4SI
841                 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
842             (const_int 16))))]
843   "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
844   "pmulhw\t{%2, %0|%0, %2}"
845   [(set_attr "type" "mmxmul")
846    (set_attr "mode" "DI")])
847
848 (define_expand "mmx_umulv4hi3_highpart"
849   [(set (match_operand:V4HI 0 "register_operand" "")
850         (truncate:V4HI
851           (lshiftrt:V4SI
852             (mult:V4SI
853               (zero_extend:V4SI
854                 (match_operand:V4HI 1 "nonimmediate_operand" ""))
855               (zero_extend:V4SI
856                 (match_operand:V4HI 2 "nonimmediate_operand" "")))
857             (const_int 16))))]
858   "TARGET_SSE || TARGET_3DNOW_A"
859   "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
860
861 (define_insn "*mmx_umulv4hi3_highpart"
862   [(set (match_operand:V4HI 0 "register_operand" "=y")
863         (truncate:V4HI
864           (lshiftrt:V4SI
865             (mult:V4SI
866               (zero_extend:V4SI
867                 (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
868               (zero_extend:V4SI
869                 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
870           (const_int 16))))]
871   "(TARGET_SSE || TARGET_3DNOW_A)
872    && ix86_binary_operator_ok (MULT, V4HImode, operands)"
873   "pmulhuw\t{%2, %0|%0, %2}"
874   [(set_attr "type" "mmxmul")
875    (set_attr "mode" "DI")])
876
877 (define_expand "mmx_pmaddwd"
878   [(set (match_operand:V2SI 0 "register_operand" "")
879         (plus:V2SI
880           (mult:V2SI
881             (sign_extend:V2SI
882               (vec_select:V2HI
883                 (match_operand:V4HI 1 "nonimmediate_operand" "")
884                 (parallel [(const_int 0) (const_int 2)])))
885             (sign_extend:V2SI
886               (vec_select:V2HI
887                 (match_operand:V4HI 2 "nonimmediate_operand" "")
888                 (parallel [(const_int 0) (const_int 2)]))))
889           (mult:V2SI
890             (sign_extend:V2SI
891               (vec_select:V2HI (match_dup 1)
892                 (parallel [(const_int 1) (const_int 3)])))
893             (sign_extend:V2SI
894               (vec_select:V2HI (match_dup 2)
895                 (parallel [(const_int 1) (const_int 3)]))))))]
896   "TARGET_MMX"
897   "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
898
899 (define_insn "*mmx_pmaddwd"
900   [(set (match_operand:V2SI 0 "register_operand" "=y")
901         (plus:V2SI
902           (mult:V2SI
903             (sign_extend:V2SI
904               (vec_select:V2HI
905                 (match_operand:V4HI 1 "nonimmediate_operand" "%0")
906                 (parallel [(const_int 0) (const_int 2)])))
907             (sign_extend:V2SI
908               (vec_select:V2HI
909                 (match_operand:V4HI 2 "nonimmediate_operand" "ym")
910                 (parallel [(const_int 0) (const_int 2)]))))
911           (mult:V2SI
912             (sign_extend:V2SI
913               (vec_select:V2HI (match_dup 1)
914                 (parallel [(const_int 1) (const_int 3)])))
915             (sign_extend:V2SI
916               (vec_select:V2HI (match_dup 2)
917                 (parallel [(const_int 1) (const_int 3)]))))))]
918   "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
919   "pmaddwd\t{%2, %0|%0, %2}"
920   [(set_attr "type" "mmxmul")
921    (set_attr "mode" "DI")])
922
923 (define_expand "mmx_pmulhrwv4hi3"
924   [(set (match_operand:V4HI 0 "register_operand" "")
925         (truncate:V4HI
926           (lshiftrt:V4SI
927             (plus:V4SI
928               (mult:V4SI
929                 (sign_extend:V4SI
930                   (match_operand:V4HI 1 "nonimmediate_operand" ""))
931                 (sign_extend:V4SI
932                   (match_operand:V4HI 2 "nonimmediate_operand" "")))
933               (const_vector:V4SI [(const_int 32768) (const_int 32768)
934                                   (const_int 32768) (const_int 32768)]))
935             (const_int 16))))]
936   "TARGET_3DNOW"
937   "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
938
939 (define_insn "*mmx_pmulhrwv4hi3"
940   [(set (match_operand:V4HI 0 "register_operand" "=y")
941         (truncate:V4HI
942           (lshiftrt:V4SI
943             (plus:V4SI
944               (mult:V4SI
945                 (sign_extend:V4SI
946                   (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
947                 (sign_extend:V4SI
948                   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
949               (const_vector:V4SI [(const_int 32768) (const_int 32768)
950                                   (const_int 32768) (const_int 32768)]))
951             (const_int 16))))]
952   "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V4HImode, operands)"
953   "pmulhrw\t{%2, %0|%0, %2}"
954   [(set_attr "type" "mmxmul")
955    (set_attr "prefix_extra" "1")
956    (set_attr "mode" "DI")])
957
958 (define_expand "sse2_umulv1siv1di3"
959   [(set (match_operand:V1DI 0 "register_operand" "")
960         (mult:V1DI
961           (zero_extend:V1DI
962             (vec_select:V1SI
963               (match_operand:V2SI 1 "nonimmediate_operand" "")
964               (parallel [(const_int 0)])))
965           (zero_extend:V1DI
966             (vec_select:V1SI
967               (match_operand:V2SI 2 "nonimmediate_operand" "")
968               (parallel [(const_int 0)])))))]
969   "TARGET_SSE2"
970   "ix86_fixup_binary_operands_no_copy (MULT, V2SImode, operands);")
971
972 (define_insn "*sse2_umulv1siv1di3"
973   [(set (match_operand:V1DI 0 "register_operand" "=y")
974         (mult:V1DI
975           (zero_extend:V1DI
976             (vec_select:V1SI
977               (match_operand:V2SI 1 "nonimmediate_operand" "%0")
978               (parallel [(const_int 0)])))
979           (zero_extend:V1DI
980             (vec_select:V1SI
981               (match_operand:V2SI 2 "nonimmediate_operand" "ym")
982               (parallel [(const_int 0)])))))]
983   "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V2SImode, operands)"
984   "pmuludq\t{%2, %0|%0, %2}"
985   [(set_attr "type" "mmxmul")
986    (set_attr "mode" "DI")])
987
988 (define_expand "mmx_<code>v4hi3"
989   [(set (match_operand:V4HI 0 "register_operand" "")
990         (smaxmin:V4HI
991           (match_operand:V4HI 1 "nonimmediate_operand" "")
992           (match_operand:V4HI 2 "nonimmediate_operand" "")))]
993   "TARGET_SSE || TARGET_3DNOW_A"
994   "ix86_fixup_binary_operands_no_copy (<CODE>, V4HImode, operands);")
995
996 (define_insn "*mmx_<code>v4hi3"
997   [(set (match_operand:V4HI 0 "register_operand" "=y")
998         (smaxmin:V4HI
999           (match_operand:V4HI 1 "nonimmediate_operand" "%0")
1000           (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
1001   "(TARGET_SSE || TARGET_3DNOW_A)
1002    && ix86_binary_operator_ok (<CODE>, V4HImode, operands)"
1003   "p<maxmin_int>w\t{%2, %0|%0, %2}"
1004   [(set_attr "type" "mmxadd")
1005    (set_attr "mode" "DI")])
1006
1007 (define_expand "mmx_<code>v8qi3"
1008   [(set (match_operand:V8QI 0 "register_operand" "")
1009         (umaxmin:V8QI
1010           (match_operand:V8QI 1 "nonimmediate_operand" "")
1011           (match_operand:V8QI 2 "nonimmediate_operand" "")))]
1012   "TARGET_SSE || TARGET_3DNOW_A"
1013   "ix86_fixup_binary_operands_no_copy (<CODE>, V8QImode, operands);")
1014
1015 (define_insn "*mmx_<code>v8qi3"
1016   [(set (match_operand:V8QI 0 "register_operand" "=y")
1017         (umaxmin:V8QI
1018           (match_operand:V8QI 1 "nonimmediate_operand" "%0")
1019           (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
1020   "(TARGET_SSE || TARGET_3DNOW_A)
1021    && ix86_binary_operator_ok (<CODE>, V8QImode, operands)"
1022   "p<maxmin_int>b\t{%2, %0|%0, %2}"
1023   [(set_attr "type" "mmxadd")
1024    (set_attr "mode" "DI")])
1025
1026 (define_insn "mmx_ashr<mode>3"
1027   [(set (match_operand:MMXMODE24 0 "register_operand" "=y")
1028         (ashiftrt:MMXMODE24
1029           (match_operand:MMXMODE24 1 "register_operand" "0")
1030           (match_operand:SI 2 "nonmemory_operand" "yN")))]
1031   "TARGET_MMX"
1032   "psra<mmxvecsize>\t{%2, %0|%0, %2}"
1033   [(set_attr "type" "mmxshft")
1034    (set (attr "length_immediate")
1035      (if_then_else (match_operand 2 "const_int_operand" "")
1036        (const_string "1")
1037        (const_string "0")))
1038    (set_attr "mode" "DI")])
1039
1040 (define_insn "mmx_lshr<mode>3"
1041   [(set (match_operand:MMXMODE248 0 "register_operand" "=y")
1042         (lshiftrt:MMXMODE248
1043           (match_operand:MMXMODE248 1 "register_operand" "0")
1044           (match_operand:SI 2 "nonmemory_operand" "yN")))]
1045   "TARGET_MMX"
1046   "psrl<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_ashl<mode>3"
1055   [(set (match_operand:MMXMODE248 0 "register_operand" "=y")
1056         (ashift:MMXMODE248
1057           (match_operand:MMXMODE248 1 "register_operand" "0")
1058           (match_operand:SI 2 "nonmemory_operand" "yN")))]
1059   "TARGET_MMX"
1060   "psll<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")])