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