xref: /dragonfly/contrib/gcc-4.7/gcc/config/i386/mmx.md (revision e0b1d537)
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")])
1735