1169689Skan;; GCC machine description for MMX and 3dNOW! instructions
2169689Skan;; Copyright (C) 2005
3169689Skan;; Free Software Foundation, Inc.
4169689Skan;;
5169689Skan;; This file is part of GCC.
6169689Skan;;
7169689Skan;; GCC is free software; you can redistribute it and/or modify
8169689Skan;; it under the terms of the GNU General Public License as published by
9169689Skan;; the Free Software Foundation; either version 2, or (at your option)
10169689Skan;; any later version.
11169689Skan;;
12169689Skan;; GCC is distributed in the hope that it will be useful,
13169689Skan;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14169689Skan;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15169689Skan;; GNU General Public License for more details.
16169689Skan;;
17169689Skan;; You should have received a copy of the GNU General Public License
18169689Skan;; along with GCC; see the file COPYING.  If not, write to
19169689Skan;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
20169689Skan;; Boston, MA 02110-1301, USA.
21169689Skan
22169689Skan;; The MMX and 3dNOW! patterns are in the same file because they use
23169689Skan;; the same register file, and 3dNOW! adds a number of extensions to
24169689Skan;; the base integer MMX isa.
25169689Skan
26169689Skan;; Note!  Except for the basic move instructions, *all* of these 
27169689Skan;; patterns are outside the normal optabs namespace.  This is because
28169689Skan;; use of these registers requires the insertion of emms or femms
29169689Skan;; instructions to return to normal fpu mode.  The compiler doesn't
30169689Skan;; know how to do that itself, which means it's up to the user.  Which
31169689Skan;; means that we should never use any of these patterns except at the
32169689Skan;; direction of the user via a builtin.
33169689Skan
34169689Skan;; 8 byte integral modes handled by MMX (and by extension, SSE)
35169689Skan(define_mode_macro MMXMODEI [V8QI V4HI V2SI])
36169689Skan
37169689Skan;; All 8-byte vector modes handled by MMX
38169689Skan(define_mode_macro MMXMODE [V8QI V4HI V2SI V2SF])
39169689Skan
40169689Skan;; Mix-n-match
41169689Skan(define_mode_macro MMXMODE12 [V8QI V4HI])
42169689Skan(define_mode_macro MMXMODE24 [V4HI V2SI])
43169689Skan
44169689Skan;; Mapping from integer vector mode to mnemonic suffix
45169689Skan(define_mode_attr mmxvecsize [(V8QI "b") (V4HI "w") (V2SI "d") (DI "q")])
46169689Skan
47169689Skan;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
48169689Skan;;
49169689Skan;; Move patterns
50169689Skan;;
51169689Skan;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
52169689Skan
53169689Skan;; All of these patterns are enabled for MMX as well as 3dNOW.
54169689Skan;; This is essential for maintaining stable calling conventions.
55169689Skan
56169689Skan(define_expand "mov<mode>"
57169689Skan  [(set (match_operand:MMXMODEI 0 "nonimmediate_operand" "")
58169689Skan	(match_operand:MMXMODEI 1 "nonimmediate_operand" ""))]
59169689Skan  "TARGET_MMX"
60169689Skan{
61169689Skan  ix86_expand_vector_move (<MODE>mode, operands);
62169689Skan  DONE;
63169689Skan})
64169689Skan
65169689Skan(define_insn "*mov<mode>_internal_rex64"
66169689Skan  [(set (match_operand:MMXMODEI 0 "nonimmediate_operand"
67169689Skan				"=rm,r,*y,*y ,m ,*y,Y ,x,x ,m,r,x")
68169689Skan	(match_operand:MMXMODEI 1 "vector_move_operand"
69169689Skan				"Cr ,m,C ,*ym,*y,Y ,*y,C,xm,x,x,r"))]
70169689Skan  "TARGET_64BIT && TARGET_MMX
71169689Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
72169689Skan  "@
73169689Skan    movq\t{%1, %0|%0, %1}
74169689Skan    movq\t{%1, %0|%0, %1}
75169689Skan    pxor\t%0, %0
76169689Skan    movq\t{%1, %0|%0, %1}
77169689Skan    movq\t{%1, %0|%0, %1}
78169689Skan    movdq2q\t{%1, %0|%0, %1}
79169689Skan    movq2dq\t{%1, %0|%0, %1}
80169689Skan    pxor\t%0, %0
81169689Skan    movq\t{%1, %0|%0, %1}
82169689Skan    movq\t{%1, %0|%0, %1}
83169689Skan    movd\t{%1, %0|%0, %1}
84169689Skan    movd\t{%1, %0|%0, %1}"
85169689Skan  [(set_attr "type" "imov,imov,mmx,mmxmov,mmxmov,ssecvt,ssecvt,sselog1,ssemov,ssemov,ssemov,ssemov")
86169689Skan   (set_attr "unit" "*,*,*,*,*,mmx,mmx,*,*,*,*,*")
87169689Skan   (set_attr "mode" "DI")])
88169689Skan
89169689Skan(define_insn "*mov<mode>_internal"
90169689Skan  [(set (match_operand:MMXMODEI 0 "nonimmediate_operand"
91169689Skan			"=*y,*y ,m ,*y,*Y,*Y,*Y ,m ,*x,*x,*x,m ,?r ,?m")
92169689Skan	(match_operand:MMXMODEI 1 "vector_move_operand"
93169689Skan			"C  ,*ym,*y,*Y,*y,C ,*Ym,*Y,C ,*x,m ,*x,irm,r"))]
94169689Skan  "TARGET_MMX
95169689Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
96169689Skan  "@
97169689Skan    pxor\t%0, %0
98169689Skan    movq\t{%1, %0|%0, %1}
99169689Skan    movq\t{%1, %0|%0, %1}
100169689Skan    movdq2q\t{%1, %0|%0, %1}
101169689Skan    movq2dq\t{%1, %0|%0, %1}
102169689Skan    pxor\t%0, %0
103169689Skan    movq\t{%1, %0|%0, %1}
104169689Skan    movq\t{%1, %0|%0, %1}
105169689Skan    xorps\t%0, %0
106169689Skan    movaps\t{%1, %0|%0, %1}
107169689Skan    movlps\t{%1, %0|%0, %1}
108169689Skan    movlps\t{%1, %0|%0, %1}
109169689Skan    #
110169689Skan    #"
111169689Skan  [(set_attr "type" "mmx,mmxmov,mmxmov,ssecvt,ssecvt,sselog1,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov,*,*")
112169689Skan   (set_attr "unit" "*,*,*,mmx,mmx,*,*,*,*,*,*,*,*,*")
113169689Skan   (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,DI,V4SF,V4SF,V2SF,V2SF,DI,DI")])
114169689Skan
115169689Skan(define_expand "movv2sf"
116169689Skan  [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
117169689Skan	(match_operand:V2SF 1 "nonimmediate_operand" ""))]
118169689Skan  "TARGET_MMX"
119169689Skan{
120169689Skan  ix86_expand_vector_move (V2SFmode, operands);
121169689Skan  DONE;
122169689Skan})
123169689Skan
124169689Skan(define_insn "*movv2sf_internal_rex64"
125169689Skan  [(set (match_operand:V2SF 0 "nonimmediate_operand"
126169689Skan				"=rm,r,*y ,*y ,m ,*y,Y ,x,x,x,m,r,x")
127169689Skan        (match_operand:V2SF 1 "vector_move_operand"
128169689Skan				"Cr ,m ,C ,*ym,*y,Y ,*y,C,x,m,x,x,r"))]
129169689Skan  "TARGET_64BIT && TARGET_MMX
130169689Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
131169689Skan  "@
132169689Skan    movq\t{%1, %0|%0, %1}
133169689Skan    movq\t{%1, %0|%0, %1}
134169689Skan    pxor\t%0, %0
135169689Skan    movq\t{%1, %0|%0, %1}
136169689Skan    movq\t{%1, %0|%0, %1}
137169689Skan    movdq2q\t{%1, %0|%0, %1}
138169689Skan    movq2dq\t{%1, %0|%0, %1}
139169689Skan    xorps\t%0, %0
140169689Skan    movaps\t{%1, %0|%0, %1}
141169689Skan    movlps\t{%1, %0|%0, %1}
142169689Skan    movlps\t{%1, %0|%0, %1}
143169689Skan    movd\t{%1, %0|%0, %1}
144169689Skan    movd\t{%1, %0|%0, %1}"
145169689Skan  [(set_attr "type" "imov,imov,mmx,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,sselog1,ssemov,ssemov,ssemov,ssemov")
146169689Skan   (set_attr "unit" "*,*,*,*,*,mmx,mmx,*,*,*,*,*,*")
147169689Skan   (set_attr "mode" "DI,DI,DI,DI,DI,DI,DI,V4SF,V4SF,V2SF,V2SF,DI,DI")])
148169689Skan
149169689Skan(define_insn "*movv2sf_internal"
150169689Skan  [(set (match_operand:V2SF 0 "nonimmediate_operand"
151169689Skan					"=*y,*y ,m,*y,*Y,*x,*x,*x,m ,?r ,?m")
152169689Skan        (match_operand:V2SF 1 "vector_move_operand"
153169689Skan					"C ,*ym,*y,*Y,*y,C ,*x,m ,*x,irm,r"))]
154169689Skan  "TARGET_MMX
155169689Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
156169689Skan  "@
157169689Skan    pxor\t%0, %0
158169689Skan    movq\t{%1, %0|%0, %1}
159169689Skan    movq\t{%1, %0|%0, %1}
160169689Skan    movdq2q\t{%1, %0|%0, %1}
161169689Skan    movq2dq\t{%1, %0|%0, %1}
162169689Skan    xorps\t%0, %0
163169689Skan    movaps\t{%1, %0|%0, %1}
164169689Skan    movlps\t{%1, %0|%0, %1}
165169689Skan    movlps\t{%1, %0|%0, %1}
166169689Skan    #
167169689Skan    #"
168169689Skan  [(set_attr "type" "mmx,mmxmov,mmxmov,ssecvt,ssecvt,sselog1,ssemov,ssemov,ssemov,*,*")
169169689Skan   (set_attr "unit" "*,*,*,mmx,mmx,*,*,*,*,*,*")
170169689Skan   (set_attr "mode" "DI,DI,DI,DI,DI,V4SF,V4SF,V2SF,V2SF,DI,DI")])
171169689Skan
172169689Skan;; %%% This multiword shite has got to go.
173169689Skan(define_split
174169689Skan  [(set (match_operand:MMXMODE 0 "nonimmediate_operand" "")
175169689Skan        (match_operand:MMXMODE 1 "general_operand" ""))]
176169689Skan  "!TARGET_64BIT && reload_completed
177169689Skan   && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
178169689Skan   && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
179169689Skan  [(const_int 0)]
180169689Skan  "ix86_split_long_move (operands); DONE;")
181169689Skan
182169689Skan(define_expand "push<mode>1"
183169689Skan  [(match_operand:MMXMODE 0 "register_operand" "")]
184169689Skan  "TARGET_MMX"
185169689Skan{
186169689Skan  ix86_expand_push (<MODE>mode, operands[0]);
187169689Skan  DONE;
188169689Skan})
189169689Skan
190169689Skan(define_expand "movmisalign<mode>"
191169689Skan  [(set (match_operand:MMXMODE 0 "nonimmediate_operand" "")
192169689Skan	(match_operand:MMXMODE 1 "nonimmediate_operand" ""))]
193169689Skan  "TARGET_MMX"
194169689Skan{
195169689Skan  ix86_expand_vector_move (<MODE>mode, operands);
196169689Skan  DONE;
197169689Skan})
198169689Skan
199169689Skan(define_insn "sse_movntdi"
200169689Skan  [(set (match_operand:DI 0 "memory_operand" "=m")
201169689Skan	(unspec:DI [(match_operand:DI 1 "register_operand" "y")]
202169689Skan		   UNSPEC_MOVNT))]
203169689Skan  "TARGET_SSE || TARGET_3DNOW_A"
204169689Skan  "movntq\t{%1, %0|%0, %1}"
205169689Skan  [(set_attr "type" "mmxmov")
206169689Skan   (set_attr "mode" "DI")])
207169689Skan
208169689Skan;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
209169689Skan;;
210169689Skan;; Parallel single-precision floating point arithmetic
211169689Skan;;
212169689Skan;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
213169689Skan
214169689Skan(define_insn "mmx_addv2sf3"
215169689Skan  [(set (match_operand:V2SF 0 "register_operand" "=y")
216169689Skan	(plus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
217169689Skan		   (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
218169689Skan  "TARGET_3DNOW && ix86_binary_operator_ok (PLUS, V2SFmode, operands)"
219169689Skan  "pfadd\\t{%2, %0|%0, %2}"
220169689Skan  [(set_attr "type" "mmxadd")
221169689Skan   (set_attr "mode" "V2SF")])
222169689Skan
223169689Skan(define_insn "mmx_subv2sf3"
224169689Skan  [(set (match_operand:V2SF 0 "register_operand" "=y,y")
225169689Skan        (minus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "0,ym")
226169689Skan		    (match_operand:V2SF 2 "nonimmediate_operand" "ym,0")))]
227169689Skan  "TARGET_3DNOW && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
228169689Skan  "@
229169689Skan   pfsub\\t{%2, %0|%0, %2}
230169689Skan   pfsubr\\t{%2, %0|%0, %2}"
231169689Skan  [(set_attr "type" "mmxadd")
232169689Skan   (set_attr "mode" "V2SF")])
233169689Skan
234169689Skan(define_expand "mmx_subrv2sf3"
235169689Skan  [(set (match_operand:V2SF 0 "register_operand" "")
236169689Skan        (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "")
237169689Skan		    (match_operand:V2SF 1 "nonimmediate_operand" "")))]
238169689Skan  "TARGET_3DNOW && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
239169689Skan  "")
240169689Skan
241169689Skan(define_insn "mmx_mulv2sf3"
242169689Skan  [(set (match_operand:V2SF 0 "register_operand" "=y")
243169689Skan	(mult:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
244169689Skan		   (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
245169689Skan  "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V2SFmode, operands)"
246169689Skan  "pfmul\\t{%2, %0|%0, %2}"
247169689Skan  [(set_attr "type" "mmxmul")
248169689Skan   (set_attr "mode" "V2SF")])
249169689Skan
250169689Skan(define_insn "mmx_smaxv2sf3"
251169689Skan  [(set (match_operand:V2SF 0 "register_operand" "=y")
252169689Skan        (smax:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
253169689Skan                   (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
254169689Skan  "TARGET_3DNOW && ix86_binary_operator_ok (SMAX, V2SFmode, operands)"
255169689Skan  "pfmax\\t{%2, %0|%0, %2}"
256169689Skan  [(set_attr "type" "mmxadd")
257169689Skan   (set_attr "mode" "V2SF")])
258169689Skan
259169689Skan(define_insn "mmx_sminv2sf3"
260169689Skan  [(set (match_operand:V2SF 0 "register_operand" "=y")
261169689Skan        (smin:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
262169689Skan                   (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
263169689Skan  "TARGET_3DNOW && ix86_binary_operator_ok (SMIN, V2SFmode, operands)"
264169689Skan  "pfmin\\t{%2, %0|%0, %2}"
265169689Skan  [(set_attr "type" "mmxadd")
266169689Skan   (set_attr "mode" "V2SF")])
267169689Skan
268169689Skan(define_insn "mmx_rcpv2sf2"
269169689Skan  [(set (match_operand:V2SF 0 "register_operand" "=y")
270169689Skan        (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
271169689Skan		     UNSPEC_PFRCP))]
272169689Skan  "TARGET_3DNOW"
273169689Skan  "pfrcp\\t{%1, %0|%0, %1}"
274169689Skan  [(set_attr "type" "mmx")
275169689Skan   (set_attr "mode" "V2SF")])
276169689Skan
277169689Skan(define_insn "mmx_rcpit1v2sf3"
278169689Skan  [(set (match_operand:V2SF 0 "register_operand" "=y")
279169689Skan	(unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
280169689Skan		      (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
281169689Skan		     UNSPEC_PFRCPIT1))]
282169689Skan  "TARGET_3DNOW"
283169689Skan  "pfrcpit1\\t{%2, %0|%0, %2}"
284169689Skan  [(set_attr "type" "mmx")
285169689Skan   (set_attr "mode" "V2SF")])
286169689Skan
287169689Skan(define_insn "mmx_rcpit2v2sf3"
288169689Skan  [(set (match_operand:V2SF 0 "register_operand" "=y")
289169689Skan	(unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
290169689Skan		      (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
291169689Skan		     UNSPEC_PFRCPIT2))]
292169689Skan  "TARGET_3DNOW"
293169689Skan  "pfrcpit2\\t{%2, %0|%0, %2}"
294169689Skan  [(set_attr "type" "mmx")
295169689Skan   (set_attr "mode" "V2SF")])
296169689Skan
297169689Skan(define_insn "mmx_rsqrtv2sf2"
298169689Skan  [(set (match_operand:V2SF 0 "register_operand" "=y")
299169689Skan	(unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
300169689Skan		     UNSPEC_PFRSQRT))]
301169689Skan  "TARGET_3DNOW"
302169689Skan  "pfrsqrt\\t{%1, %0|%0, %1}"
303169689Skan  [(set_attr "type" "mmx")
304169689Skan   (set_attr "mode" "V2SF")])
305169689Skan		
306169689Skan(define_insn "mmx_rsqit1v2sf3"
307169689Skan  [(set (match_operand:V2SF 0 "register_operand" "=y")
308169689Skan	(unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
309169689Skan		      (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
310169689Skan		     UNSPEC_PFRSQIT1))]
311169689Skan  "TARGET_3DNOW"
312169689Skan  "pfrsqit1\\t{%2, %0|%0, %2}"
313169689Skan  [(set_attr "type" "mmx")
314169689Skan   (set_attr "mode" "V2SF")])
315169689Skan
316169689Skan(define_insn "mmx_haddv2sf3"
317169689Skan  [(set (match_operand:V2SF 0 "register_operand" "=y")
318169689Skan	(vec_concat:V2SF
319169689Skan	  (plus:SF
320169689Skan	    (vec_select:SF
321169689Skan	      (match_operand:V2SF 1 "register_operand" "0")
322169689Skan	      (parallel [(const_int  0)]))
323169689Skan	    (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
324169689Skan	  (plus:SF
325169689Skan            (vec_select:SF
326169689Skan	      (match_operand:V2SF 2 "nonimmediate_operand" "ym")
327169689Skan	      (parallel [(const_int  0)]))
328169689Skan	    (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
329169689Skan  "TARGET_3DNOW"
330169689Skan  "pfacc\\t{%2, %0|%0, %2}"
331169689Skan  [(set_attr "type" "mmxadd")
332169689Skan   (set_attr "mode" "V2SF")])
333169689Skan
334169689Skan(define_insn "mmx_hsubv2sf3"
335169689Skan  [(set (match_operand:V2SF 0 "register_operand" "=y")
336169689Skan	(vec_concat:V2SF
337169689Skan	  (minus:SF
338169689Skan	    (vec_select:SF
339169689Skan	      (match_operand:V2SF 1 "register_operand" "0")
340169689Skan	      (parallel [(const_int  0)]))
341169689Skan	    (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
342169689Skan	  (minus:SF
343169689Skan            (vec_select:SF
344169689Skan	      (match_operand:V2SF 2 "nonimmediate_operand" "ym")
345169689Skan	      (parallel [(const_int  0)]))
346169689Skan	    (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
347169689Skan  "TARGET_3DNOW_A"
348169689Skan  "pfnacc\\t{%2, %0|%0, %2}"
349169689Skan  [(set_attr "type" "mmxadd")
350169689Skan   (set_attr "mode" "V2SF")])
351169689Skan
352169689Skan(define_insn "mmx_addsubv2sf3"
353169689Skan  [(set (match_operand:V2SF 0 "register_operand" "=y")
354169689Skan        (vec_merge:V2SF
355169689Skan          (plus:V2SF
356169689Skan            (match_operand:V2SF 1 "register_operand" "0")
357169689Skan            (match_operand:V2SF 2 "nonimmediate_operand" "ym"))
358169689Skan          (minus:V2SF (match_dup 1) (match_dup 2))
359169689Skan          (const_int 1)))]
360169689Skan  "TARGET_3DNOW_A"
361169689Skan  "pfpnacc\\t{%2, %0|%0, %2}"
362169689Skan  [(set_attr "type" "mmxadd")
363169689Skan   (set_attr "mode" "V2SF")])
364169689Skan
365169689Skan;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
366169689Skan;;
367169689Skan;; Parallel single-precision floating point comparisons
368169689Skan;;
369169689Skan;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
370169689Skan
371169689Skan(define_insn "mmx_gtv2sf3"
372169689Skan  [(set (match_operand:V2SI 0 "register_operand" "=y")
373169689Skan	(gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
374169689Skan		 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
375169689Skan  "TARGET_3DNOW"
376169689Skan  "pfcmpgt\\t{%2, %0|%0, %2}"
377169689Skan  [(set_attr "type" "mmxcmp")
378169689Skan   (set_attr "mode" "V2SF")])
379169689Skan
380169689Skan(define_insn "mmx_gev2sf3"
381169689Skan  [(set (match_operand:V2SI 0 "register_operand" "=y")
382169689Skan	(ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
383169689Skan		 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
384169689Skan  "TARGET_3DNOW"
385169689Skan  "pfcmpge\\t{%2, %0|%0, %2}"
386169689Skan  [(set_attr "type" "mmxcmp")
387169689Skan   (set_attr "mode" "V2SF")])
388169689Skan
389169689Skan(define_insn "mmx_eqv2sf3"
390169689Skan  [(set (match_operand:V2SI 0 "register_operand" "=y")
391169689Skan	(eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "%0")
392169689Skan		 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
393169689Skan  "TARGET_3DNOW && ix86_binary_operator_ok (EQ, V2SFmode, operands)"
394169689Skan  "pfcmpeq\\t{%2, %0|%0, %2}"
395169689Skan  [(set_attr "type" "mmxcmp")
396169689Skan   (set_attr "mode" "V2SF")])
397169689Skan
398169689Skan;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
399169689Skan;;
400169689Skan;; Parallel single-precision floating point conversion operations
401169689Skan;;
402169689Skan;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
403169689Skan
404169689Skan(define_insn "mmx_pf2id"
405169689Skan  [(set (match_operand:V2SI 0 "register_operand" "=y")
406169689Skan	(fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
407169689Skan  "TARGET_3DNOW"
408169689Skan  "pf2id\\t{%1, %0|%0, %1}"
409169689Skan  [(set_attr "type" "mmxcvt")
410169689Skan   (set_attr "mode" "V2SF")])
411169689Skan
412169689Skan(define_insn "mmx_pf2iw"
413169689Skan  [(set (match_operand:V2SI 0 "register_operand" "=y")
414169689Skan	(sign_extend:V2SI
415169689Skan	  (ss_truncate:V2HI
416169689Skan	    (fix:V2SI
417169689Skan	      (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
418169689Skan  "TARGET_3DNOW_A"
419169689Skan  "pf2iw\\t{%1, %0|%0, %1}"
420169689Skan  [(set_attr "type" "mmxcvt")
421169689Skan   (set_attr "mode" "V2SF")])
422169689Skan
423169689Skan(define_insn "mmx_pi2fw"
424169689Skan  [(set (match_operand:V2SF 0 "register_operand" "=y")
425169689Skan	(float:V2SF
426169689Skan	  (sign_extend:V2SI
427169689Skan	    (truncate:V2HI
428169689Skan	      (match_operand:V2SI 1 "nonimmediate_operand" "ym")))))]
429169689Skan  "TARGET_3DNOW_A"
430169689Skan  "pi2fw\\t{%1, %0|%0, %1}"
431169689Skan  [(set_attr "type" "mmxcvt")
432169689Skan   (set_attr "mode" "V2SF")])
433169689Skan
434169689Skan(define_insn "mmx_floatv2si2"
435169689Skan  [(set (match_operand:V2SF 0 "register_operand" "=y")
436169689Skan	(float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
437169689Skan  "TARGET_3DNOW"
438169689Skan  "pi2fd\\t{%1, %0|%0, %1}"
439169689Skan  [(set_attr "type" "mmxcvt")
440169689Skan   (set_attr "mode" "V2SF")])
441169689Skan
442169689Skan;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
443169689Skan;;
444169689Skan;; Parallel single-precision floating point element swizzling
445169689Skan;;
446169689Skan;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
447169689Skan
448169689Skan(define_insn "mmx_pswapdv2sf2"
449169689Skan  [(set (match_operand:V2SF 0 "register_operand" "=y")
450169689Skan	(vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
451169689Skan			 (parallel [(const_int 1) (const_int 0)])))]
452169689Skan  "TARGET_3DNOW_A"
453169689Skan  "pswapd\\t{%1, %0|%0, %1}"
454169689Skan  [(set_attr "type" "mmxcvt")
455169689Skan   (set_attr "mode" "V2SF")])
456169689Skan
457169689Skan(define_insn "*vec_dupv2sf"
458169689Skan  [(set (match_operand:V2SF 0 "register_operand" "=y")
459169689Skan	(vec_duplicate:V2SF
460169689Skan	  (match_operand:SF 1 "register_operand" "0")))]
461169689Skan  "TARGET_MMX"
462169689Skan  "punpckldq\t%0, %0"
463169689Skan  [(set_attr "type" "mmxcvt")
464169689Skan   (set_attr "mode" "DI")])
465169689Skan
466169689Skan(define_insn "*mmx_concatv2sf"
467169689Skan  [(set (match_operand:V2SF 0 "register_operand"     "=y,y")
468169689Skan	(vec_concat:V2SF
469169689Skan	  (match_operand:SF 1 "nonimmediate_operand" " 0,rm")
470169689Skan	  (match_operand:SF 2 "vector_move_operand"  "ym,C")))]
471169689Skan  "TARGET_MMX && !TARGET_SSE"
472169689Skan  "@
473169689Skan   punpckldq\t{%2, %0|%0, %2}
474169689Skan   movd\t{%1, %0|%0, %1}"
475169689Skan  [(set_attr "type" "mmxcvt,mmxmov")
476169689Skan   (set_attr "mode" "DI")])
477169689Skan
478169689Skan(define_expand "vec_setv2sf"
479169689Skan  [(match_operand:V2SF 0 "register_operand" "")
480169689Skan   (match_operand:SF 1 "register_operand" "")
481169689Skan   (match_operand 2 "const_int_operand" "")]
482169689Skan  "TARGET_MMX"
483169689Skan{
484169689Skan  ix86_expand_vector_set (false, operands[0], operands[1],
485169689Skan			  INTVAL (operands[2]));
486169689Skan  DONE;
487169689Skan})
488169689Skan
489169689Skan(define_insn_and_split "*vec_extractv2sf_0"
490169689Skan  [(set (match_operand:SF 0 "nonimmediate_operand"     "=x,y,m,m,frxy")
491169689Skan	(vec_select:SF
492169689Skan	  (match_operand:V2SF 1 "nonimmediate_operand" " x,y,x,y,m")
493169689Skan	  (parallel [(const_int 0)])))]
494169689Skan  "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
495169689Skan  "#"
496169689Skan  "&& reload_completed"
497169689Skan  [(const_int 0)]
498169689Skan{
499169689Skan  rtx op1 = operands[1];
500169689Skan  if (REG_P (op1))
501169689Skan    op1 = gen_rtx_REG (SFmode, REGNO (op1));
502169689Skan  else
503169689Skan    op1 = gen_lowpart (SFmode, op1);
504169689Skan  emit_move_insn (operands[0], op1);
505169689Skan  DONE;
506169689Skan})
507169689Skan
508169689Skan(define_insn "*vec_extractv2sf_1"
509169689Skan  [(set (match_operand:SF 0 "nonimmediate_operand"     "=y,x,frxy")
510169689Skan	(vec_select:SF
511169689Skan	  (match_operand:V2SF 1 "nonimmediate_operand" " 0,0,o")
512169689Skan	  (parallel [(const_int 1)])))]
513169689Skan  "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
514169689Skan  "@
515169689Skan   punpckhdq\t%0, %0
516169689Skan   unpckhps\t%0, %0
517169689Skan   #"
518169689Skan  [(set_attr "type" "mmxcvt,sselog1,*")
519169689Skan   (set_attr "mode" "DI,V4SF,SI")])
520169689Skan
521169689Skan(define_split
522169689Skan  [(set (match_operand:SF 0 "register_operand" "")
523169689Skan	(vec_select:SF
524169689Skan	  (match_operand:V2SF 1 "memory_operand" "")
525169689Skan	  (parallel [(const_int 1)])))]
526169689Skan  "TARGET_MMX && reload_completed"
527169689Skan  [(const_int 0)]
528169689Skan{
529169689Skan  operands[1] = adjust_address (operands[1], SFmode, 4);
530169689Skan  emit_move_insn (operands[0], operands[1]);
531169689Skan  DONE;
532169689Skan})
533169689Skan
534169689Skan(define_expand "vec_extractv2sf"
535169689Skan  [(match_operand:SF 0 "register_operand" "")
536169689Skan   (match_operand:V2SF 1 "register_operand" "")
537169689Skan   (match_operand 2 "const_int_operand" "")]
538169689Skan  "TARGET_MMX"
539169689Skan{
540169689Skan  ix86_expand_vector_extract (false, operands[0], operands[1],
541169689Skan			      INTVAL (operands[2]));
542169689Skan  DONE;
543169689Skan})
544169689Skan
545169689Skan(define_expand "vec_initv2sf"
546169689Skan  [(match_operand:V2SF 0 "register_operand" "")
547169689Skan   (match_operand 1 "" "")]
548169689Skan  "TARGET_SSE"
549169689Skan{
550169689Skan  ix86_expand_vector_init (false, operands[0], operands[1]);
551169689Skan  DONE;
552169689Skan})
553169689Skan
554169689Skan;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
555169689Skan;;
556169689Skan;; Parallel integral arithmetic
557169689Skan;;
558169689Skan;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
559169689Skan
560169689Skan(define_insn "mmx_add<mode>3"
561169689Skan  [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
562169689Skan        (plus:MMXMODEI
563169689Skan	  (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
564169689Skan	  (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
565169689Skan  "TARGET_MMX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
566169689Skan  "padd<mmxvecsize>\t{%2, %0|%0, %2}"
567169689Skan  [(set_attr "type" "mmxadd")
568169689Skan   (set_attr "mode" "DI")])
569169689Skan
570169689Skan(define_insn "mmx_adddi3"
571169689Skan  [(set (match_operand:DI 0 "register_operand" "=y")
572169689Skan        (unspec:DI
573169689Skan	 [(plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
574169689Skan		   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
575169689Skan	 UNSPEC_NOP))]
576169689Skan  "TARGET_SSE2 && ix86_binary_operator_ok (PLUS, DImode, operands)"
577169689Skan  "paddq\t{%2, %0|%0, %2}"
578169689Skan  [(set_attr "type" "mmxadd")
579169689Skan   (set_attr "mode" "DI")])
580169689Skan
581169689Skan(define_insn "mmx_ssadd<mode>3"
582169689Skan  [(set (match_operand:MMXMODE12 0 "register_operand" "=y")
583169689Skan        (ss_plus:MMXMODE12
584169689Skan	  (match_operand:MMXMODE12 1 "nonimmediate_operand" "%0")
585169689Skan	  (match_operand:MMXMODE12 2 "nonimmediate_operand" "ym")))]
586169689Skan  "TARGET_MMX"
587169689Skan  "padds<mmxvecsize>\t{%2, %0|%0, %2}"
588169689Skan  [(set_attr "type" "mmxadd")
589169689Skan   (set_attr "mode" "DI")])
590169689Skan
591169689Skan(define_insn "mmx_usadd<mode>3"
592169689Skan  [(set (match_operand:MMXMODE12 0 "register_operand" "=y")
593169689Skan        (us_plus:MMXMODE12
594169689Skan	  (match_operand:MMXMODE12 1 "nonimmediate_operand" "%0")
595169689Skan	  (match_operand:MMXMODE12 2 "nonimmediate_operand" "ym")))]
596169689Skan  "TARGET_MMX"
597169689Skan  "paddus<mmxvecsize>\t{%2, %0|%0, %2}"
598169689Skan  [(set_attr "type" "mmxadd")
599169689Skan   (set_attr "mode" "DI")])
600169689Skan
601169689Skan(define_insn "mmx_sub<mode>3"
602169689Skan  [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
603169689Skan        (minus:MMXMODEI
604169689Skan	  (match_operand:MMXMODEI 1 "register_operand" "0")
605169689Skan	  (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
606169689Skan  "TARGET_MMX"
607169689Skan  "psub<mmxvecsize>\t{%2, %0|%0, %2}"
608169689Skan  [(set_attr "type" "mmxadd")
609169689Skan   (set_attr "mode" "DI")])
610169689Skan
611169689Skan(define_insn "mmx_subdi3"
612169689Skan  [(set (match_operand:DI 0 "register_operand" "=y")
613169689Skan        (unspec:DI
614169689Skan	 [(minus:DI (match_operand:DI 1 "register_operand" "0")
615169689Skan		    (match_operand:DI 2 "nonimmediate_operand" "ym"))]
616169689Skan	 UNSPEC_NOP))]
617169689Skan  "TARGET_SSE2"
618169689Skan  "psubq\t{%2, %0|%0, %2}"
619169689Skan  [(set_attr "type" "mmxadd")
620169689Skan   (set_attr "mode" "DI")])
621169689Skan
622169689Skan(define_insn "mmx_sssub<mode>3"
623169689Skan  [(set (match_operand:MMXMODE12 0 "register_operand" "=y")
624169689Skan        (ss_minus:MMXMODE12
625169689Skan	  (match_operand:MMXMODE12 1 "register_operand" "0")
626169689Skan	  (match_operand:MMXMODE12 2 "nonimmediate_operand" "ym")))]
627169689Skan  "TARGET_MMX"
628169689Skan  "psubs<mmxvecsize>\t{%2, %0|%0, %2}"
629169689Skan  [(set_attr "type" "mmxadd")
630169689Skan   (set_attr "mode" "DI")])
631169689Skan
632169689Skan(define_insn "mmx_ussub<mode>3"
633169689Skan  [(set (match_operand:MMXMODE12 0 "register_operand" "=y")
634169689Skan        (us_minus:MMXMODE12
635169689Skan	  (match_operand:MMXMODE12 1 "register_operand" "0")
636169689Skan	  (match_operand:MMXMODE12 2 "nonimmediate_operand" "ym")))]
637169689Skan  "TARGET_MMX"
638169689Skan  "psubus<mmxvecsize>\t{%2, %0|%0, %2}"
639169689Skan  [(set_attr "type" "mmxadd")
640169689Skan   (set_attr "mode" "DI")])
641169689Skan
642169689Skan(define_insn "mmx_mulv4hi3"
643169689Skan  [(set (match_operand:V4HI 0 "register_operand" "=y")
644169689Skan        (mult:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "%0")
645169689Skan		   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
646169689Skan  "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
647169689Skan  "pmullw\t{%2, %0|%0, %2}"
648169689Skan  [(set_attr "type" "mmxmul")
649169689Skan   (set_attr "mode" "DI")])
650169689Skan
651169689Skan(define_insn "mmx_smulv4hi3_highpart"
652169689Skan  [(set (match_operand:V4HI 0 "register_operand" "=y")
653169689Skan	(truncate:V4HI
654169689Skan	 (lshiftrt:V4SI
655169689Skan	  (mult:V4SI (sign_extend:V4SI
656169689Skan		      (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
657169689Skan		     (sign_extend:V4SI
658169689Skan		      (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
659169689Skan	  (const_int 16))))]
660169689Skan  "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
661169689Skan  "pmulhw\t{%2, %0|%0, %2}"
662169689Skan  [(set_attr "type" "mmxmul")
663169689Skan   (set_attr "mode" "DI")])
664169689Skan
665169689Skan(define_insn "mmx_umulv4hi3_highpart"
666169689Skan  [(set (match_operand:V4HI 0 "register_operand" "=y")
667169689Skan	(truncate:V4HI
668169689Skan	 (lshiftrt:V4SI
669169689Skan	  (mult:V4SI (zero_extend:V4SI
670169689Skan		      (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
671169689Skan		     (zero_extend:V4SI
672169689Skan		      (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
673169689Skan	  (const_int 16))))]
674169689Skan  "(TARGET_SSE || TARGET_3DNOW_A)
675169689Skan   && ix86_binary_operator_ok (MULT, V4HImode, operands)"
676169689Skan  "pmulhuw\t{%2, %0|%0, %2}"
677169689Skan  [(set_attr "type" "mmxmul")
678169689Skan   (set_attr "mode" "DI")])
679169689Skan
680169689Skan(define_insn "mmx_pmaddwd"
681169689Skan  [(set (match_operand:V2SI 0 "register_operand" "=y")
682169689Skan        (plus:V2SI
683169689Skan	  (mult:V2SI
684169689Skan	    (sign_extend:V2SI
685169689Skan	      (vec_select:V2HI
686169689Skan		(match_operand:V4HI 1 "nonimmediate_operand" "%0")
687169689Skan		(parallel [(const_int 0) (const_int 2)])))
688169689Skan	    (sign_extend:V2SI
689169689Skan	      (vec_select:V2HI
690169689Skan		(match_operand:V4HI 2 "nonimmediate_operand" "ym")
691169689Skan		(parallel [(const_int 0) (const_int 2)]))))
692169689Skan	  (mult:V2SI
693169689Skan	    (sign_extend:V2SI
694169689Skan	      (vec_select:V2HI (match_dup 1)
695169689Skan		(parallel [(const_int 1) (const_int 3)])))
696169689Skan	    (sign_extend:V2SI
697169689Skan	      (vec_select:V2HI (match_dup 2)
698169689Skan		(parallel [(const_int 1) (const_int 3)]))))))]
699169689Skan  "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
700169689Skan  "pmaddwd\t{%2, %0|%0, %2}"
701169689Skan  [(set_attr "type" "mmxmul")
702169689Skan   (set_attr "mode" "DI")])
703169689Skan
704169689Skan(define_insn "mmx_pmulhrwv4hi3"
705169689Skan  [(set (match_operand:V4HI 0 "register_operand" "=y")
706169689Skan	(truncate:V4HI
707169689Skan	  (lshiftrt:V4SI
708169689Skan	    (plus:V4SI
709169689Skan	      (mult:V4SI
710169689Skan	        (sign_extend:V4SI
711169689Skan		  (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
712169689Skan	        (sign_extend:V4SI
713169689Skan		  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
714169689Skan	      (const_vector:V4SI [(const_int 32768) (const_int 32768)
715169689Skan				  (const_int 32768) (const_int 32768)]))
716169689Skan	    (const_int 16))))]
717169689Skan  "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V4HImode, operands)"
718169689Skan  "pmulhrw\\t{%2, %0|%0, %2}"
719169689Skan  [(set_attr "type" "mmxmul")
720169689Skan   (set_attr "mode" "DI")])
721169689Skan
722169689Skan(define_insn "sse2_umulsidi3"
723169689Skan  [(set (match_operand:DI 0 "register_operand" "=y")
724169689Skan        (mult:DI
725169689Skan	  (zero_extend:DI
726169689Skan	    (vec_select:SI
727169689Skan	      (match_operand:V2SI 1 "nonimmediate_operand" "%0")
728169689Skan	      (parallel [(const_int 0)])))
729169689Skan	  (zero_extend:DI
730169689Skan	    (vec_select:SI
731169689Skan	      (match_operand:V2SI 2 "nonimmediate_operand" "ym")
732169689Skan	      (parallel [(const_int 0)])))))]
733169689Skan  "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V2SImode, operands)"
734169689Skan  "pmuludq\t{%2, %0|%0, %2}"
735169689Skan  [(set_attr "type" "mmxmul")
736169689Skan   (set_attr "mode" "DI")])
737169689Skan
738169689Skan(define_insn "mmx_umaxv8qi3"
739169689Skan  [(set (match_operand:V8QI 0 "register_operand" "=y")
740169689Skan        (umax:V8QI (match_operand:V8QI 1 "nonimmediate_operand" "%0")
741169689Skan		   (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
742169689Skan  "(TARGET_SSE || TARGET_3DNOW_A)
743169689Skan   && ix86_binary_operator_ok (UMAX, V8QImode, operands)"
744169689Skan  "pmaxub\t{%2, %0|%0, %2}"
745169689Skan  [(set_attr "type" "mmxadd")
746169689Skan   (set_attr "mode" "DI")])
747169689Skan
748169689Skan(define_insn "mmx_smaxv4hi3"
749169689Skan  [(set (match_operand:V4HI 0 "register_operand" "=y")
750169689Skan        (smax:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "%0")
751169689Skan		   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
752169689Skan  "(TARGET_SSE || TARGET_3DNOW_A)
753169689Skan   && ix86_binary_operator_ok (SMAX, V4HImode, operands)"
754169689Skan  "pmaxsw\t{%2, %0|%0, %2}"
755169689Skan  [(set_attr "type" "mmxadd")
756169689Skan   (set_attr "mode" "DI")])
757169689Skan
758169689Skan(define_insn "mmx_uminv8qi3"
759169689Skan  [(set (match_operand:V8QI 0 "register_operand" "=y")
760169689Skan        (umin:V8QI (match_operand:V8QI 1 "nonimmediate_operand" "%0")
761169689Skan		   (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
762169689Skan  "(TARGET_SSE || TARGET_3DNOW_A)
763169689Skan   && ix86_binary_operator_ok (UMIN, V8QImode, operands)"
764169689Skan  "pminub\t{%2, %0|%0, %2}"
765169689Skan  [(set_attr "type" "mmxadd")
766169689Skan   (set_attr "mode" "DI")])
767169689Skan
768169689Skan(define_insn "mmx_sminv4hi3"
769169689Skan  [(set (match_operand:V4HI 0 "register_operand" "=y")
770169689Skan        (smin:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "%0")
771169689Skan		   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
772169689Skan  "(TARGET_SSE || TARGET_3DNOW_A)
773169689Skan   && ix86_binary_operator_ok (SMIN, V4HImode, operands)"
774169689Skan  "pminsw\t{%2, %0|%0, %2}"
775169689Skan  [(set_attr "type" "mmxadd")
776169689Skan   (set_attr "mode" "DI")])
777169689Skan
778169689Skan(define_insn "mmx_ashr<mode>3"
779169689Skan  [(set (match_operand:MMXMODE24 0 "register_operand" "=y")
780169689Skan        (ashiftrt:MMXMODE24
781169689Skan	  (match_operand:MMXMODE24 1 "register_operand" "0")
782169689Skan	  (match_operand:DI 2 "nonmemory_operand" "yi")))]
783169689Skan  "TARGET_MMX"
784169689Skan  "psra<mmxvecsize>\t{%2, %0|%0, %2}"
785169689Skan  [(set_attr "type" "mmxshft")
786169689Skan   (set_attr "mode" "DI")])
787169689Skan
788169689Skan(define_insn "mmx_lshr<mode>3"
789169689Skan  [(set (match_operand:MMXMODE24 0 "register_operand" "=y")
790169689Skan        (lshiftrt:MMXMODE24
791169689Skan	  (match_operand:MMXMODE24 1 "register_operand" "0")
792169689Skan	  (match_operand:DI 2 "nonmemory_operand" "yi")))]
793169689Skan  "TARGET_MMX"
794169689Skan  "psrl<mmxvecsize>\t{%2, %0|%0, %2}"
795169689Skan  [(set_attr "type" "mmxshft")
796169689Skan   (set_attr "mode" "DI")])
797169689Skan
798169689Skan(define_insn "mmx_lshrdi3"
799169689Skan  [(set (match_operand:DI 0 "register_operand" "=y")
800169689Skan        (unspec:DI
801169689Skan	  [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
802169689Skan		       (match_operand:DI 2 "nonmemory_operand" "yi"))]
803169689Skan	  UNSPEC_NOP))]
804169689Skan  "TARGET_MMX"
805169689Skan  "psrlq\t{%2, %0|%0, %2}"
806169689Skan  [(set_attr "type" "mmxshft")
807169689Skan   (set_attr "mode" "DI")])
808169689Skan
809169689Skan(define_insn "mmx_ashl<mode>3"
810169689Skan  [(set (match_operand:MMXMODE24 0 "register_operand" "=y")
811169689Skan        (ashift:MMXMODE24
812169689Skan	  (match_operand:MMXMODE24 1 "register_operand" "0")
813169689Skan	  (match_operand:DI 2 "nonmemory_operand" "yi")))]
814169689Skan  "TARGET_MMX"
815169689Skan  "psll<mmxvecsize>\t{%2, %0|%0, %2}"
816169689Skan  [(set_attr "type" "mmxshft")
817169689Skan   (set_attr "mode" "DI")])
818169689Skan
819169689Skan(define_insn "mmx_ashldi3"
820169689Skan  [(set (match_operand:DI 0 "register_operand" "=y")
821169689Skan        (unspec:DI
822169689Skan	 [(ashift:DI (match_operand:DI 1 "register_operand" "0")
823169689Skan		     (match_operand:DI 2 "nonmemory_operand" "yi"))]
824169689Skan	 UNSPEC_NOP))]
825169689Skan  "TARGET_MMX"
826169689Skan  "psllq\t{%2, %0|%0, %2}"
827169689Skan  [(set_attr "type" "mmxshft")
828169689Skan   (set_attr "mode" "DI")])
829169689Skan
830169689Skan;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
831169689Skan;;
832169689Skan;; Parallel integral comparisons
833169689Skan;;
834169689Skan;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
835169689Skan
836169689Skan(define_insn "mmx_eq<mode>3"
837169689Skan  [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
838169689Skan        (eq:MMXMODEI
839169689Skan	  (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
840169689Skan	  (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
841169689Skan  "TARGET_MMX && ix86_binary_operator_ok (EQ, <MODE>mode, operands)"
842169689Skan  "pcmpeq<mmxvecsize>\t{%2, %0|%0, %2}"
843169689Skan  [(set_attr "type" "mmxcmp")
844169689Skan   (set_attr "mode" "DI")])
845169689Skan
846169689Skan(define_insn "mmx_gt<mode>3"
847169689Skan  [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
848169689Skan        (gt:MMXMODEI
849169689Skan	  (match_operand:MMXMODEI 1 "register_operand" "0")
850169689Skan	  (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
851169689Skan  "TARGET_MMX"
852169689Skan  "pcmpgt<mmxvecsize>\t{%2, %0|%0, %2}"
853169689Skan  [(set_attr "type" "mmxcmp")
854169689Skan   (set_attr "mode" "DI")])
855169689Skan
856169689Skan;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
857169689Skan;;
858169689Skan;; Parallel integral logical operations
859169689Skan;;
860169689Skan;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
861169689Skan
862169689Skan(define_insn "mmx_and<mode>3"
863169689Skan  [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
864169689Skan	(and:MMXMODEI
865169689Skan	  (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
866169689Skan	  (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
867169689Skan  "TARGET_MMX && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
868169689Skan  "pand\t{%2, %0|%0, %2}"
869169689Skan  [(set_attr "type" "mmxadd")
870169689Skan   (set_attr "mode" "DI")])
871169689Skan
872169689Skan(define_insn "mmx_nand<mode>3"
873169689Skan  [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
874169689Skan	(and:MMXMODEI
875169689Skan	  (not:MMXMODEI (match_operand:MMXMODEI 1 "register_operand" "0"))
876169689Skan	  (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
877169689Skan  "TARGET_MMX"
878169689Skan  "pandn\t{%2, %0|%0, %2}"
879169689Skan  [(set_attr "type" "mmxadd")
880169689Skan   (set_attr "mode" "DI")])
881169689Skan
882169689Skan(define_insn "mmx_ior<mode>3"
883169689Skan  [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
884169689Skan        (ior:MMXMODEI
885169689Skan	  (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
886169689Skan	  (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
887169689Skan  "TARGET_MMX && ix86_binary_operator_ok (IOR, <MODE>mode, operands)"
888169689Skan  "por\t{%2, %0|%0, %2}"
889169689Skan  [(set_attr "type" "mmxadd")
890169689Skan   (set_attr "mode" "DI")])
891169689Skan
892169689Skan(define_insn "mmx_xor<mode>3"
893169689Skan  [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
894169689Skan	(xor:MMXMODEI
895169689Skan	  (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
896169689Skan	  (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
897169689Skan  "TARGET_MMX && ix86_binary_operator_ok (XOR, <MODE>mode, operands)"
898169689Skan  "pxor\t{%2, %0|%0, %2}"
899169689Skan  [(set_attr "type" "mmxadd")
900169689Skan   (set_attr "mode" "DI")
901169689Skan   (set_attr "memory" "none")])
902169689Skan
903169689Skan;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
904169689Skan;;
905169689Skan;; Parallel integral element swizzling
906169689Skan;;
907169689Skan;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
908169689Skan
909169689Skan(define_insn "mmx_packsswb"
910169689Skan  [(set (match_operand:V8QI 0 "register_operand" "=y")
911169689Skan	(vec_concat:V8QI
912169689Skan	  (ss_truncate:V4QI
913169689Skan	    (match_operand:V4HI 1 "register_operand" "0"))
914169689Skan	  (ss_truncate:V4QI
915169689Skan	    (match_operand:V4HI 2 "nonimmediate_operand" "ym"))))]
916169689Skan  "TARGET_MMX"
917169689Skan  "packsswb\t{%2, %0|%0, %2}"
918169689Skan  [(set_attr "type" "mmxshft")
919169689Skan   (set_attr "mode" "DI")])
920169689Skan
921169689Skan(define_insn "mmx_packssdw"
922169689Skan  [(set (match_operand:V4HI 0 "register_operand" "=y")
923169689Skan	(vec_concat:V4HI
924169689Skan	  (ss_truncate:V2HI
925169689Skan	    (match_operand:V2SI 1 "register_operand" "0"))
926169689Skan	  (ss_truncate:V2HI
927169689Skan	    (match_operand:V2SI 2 "nonimmediate_operand" "ym"))))]
928169689Skan  "TARGET_MMX"
929169689Skan  "packssdw\t{%2, %0|%0, %2}"
930169689Skan  [(set_attr "type" "mmxshft")
931169689Skan   (set_attr "mode" "DI")])
932169689Skan
933169689Skan(define_insn "mmx_packuswb"
934169689Skan  [(set (match_operand:V8QI 0 "register_operand" "=y")
935169689Skan	(vec_concat:V8QI
936169689Skan	  (us_truncate:V4QI
937169689Skan	    (match_operand:V4HI 1 "register_operand" "0"))
938169689Skan	  (us_truncate:V4QI
939169689Skan	    (match_operand:V4HI 2 "nonimmediate_operand" "ym"))))]
940169689Skan  "TARGET_MMX"
941169689Skan  "packuswb\t{%2, %0|%0, %2}"
942169689Skan  [(set_attr "type" "mmxshft")
943169689Skan   (set_attr "mode" "DI")])
944169689Skan
945169689Skan(define_insn "mmx_punpckhbw"
946169689Skan  [(set (match_operand:V8QI 0 "register_operand" "=y")
947169689Skan	(vec_select:V8QI
948169689Skan	  (vec_concat:V16QI
949169689Skan	    (match_operand:V8QI 1 "register_operand" "0")
950169689Skan	    (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
951169689Skan          (parallel [(const_int 4) (const_int 12)
952169689Skan                     (const_int 5) (const_int 13)
953169689Skan                     (const_int 6) (const_int 14)
954169689Skan                     (const_int 7) (const_int 15)])))]
955169689Skan  "TARGET_MMX"
956169689Skan  "punpckhbw\t{%2, %0|%0, %2}"
957169689Skan  [(set_attr "type" "mmxcvt")
958169689Skan   (set_attr "mode" "DI")])
959169689Skan
960169689Skan(define_insn "mmx_punpcklbw"
961169689Skan  [(set (match_operand:V8QI 0 "register_operand" "=y")
962169689Skan	(vec_select:V8QI
963169689Skan	  (vec_concat:V16QI
964169689Skan	    (match_operand:V8QI 1 "register_operand" "0")
965169689Skan	    (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
966169689Skan          (parallel [(const_int 0) (const_int 8)
967169689Skan                     (const_int 1) (const_int 9)
968169689Skan                     (const_int 2) (const_int 10)
969169689Skan                     (const_int 3) (const_int 11)])))]
970169689Skan  "TARGET_MMX"
971169689Skan  "punpcklbw\t{%2, %0|%0, %2}"
972169689Skan  [(set_attr "type" "mmxcvt")
973169689Skan   (set_attr "mode" "DI")])
974169689Skan
975169689Skan(define_insn "mmx_punpckhwd"
976169689Skan  [(set (match_operand:V4HI 0 "register_operand" "=y")
977169689Skan	(vec_select:V4HI
978169689Skan	  (vec_concat:V8HI
979169689Skan	    (match_operand:V4HI 1 "register_operand" "0")
980169689Skan	    (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
981169689Skan          (parallel [(const_int 2) (const_int 6)
982169689Skan                     (const_int 3) (const_int 7)])))]
983169689Skan  "TARGET_MMX"
984169689Skan  "punpckhwd\t{%2, %0|%0, %2}"
985169689Skan  [(set_attr "type" "mmxcvt")
986169689Skan   (set_attr "mode" "DI")])
987169689Skan
988169689Skan(define_insn "mmx_punpcklwd"
989169689Skan  [(set (match_operand:V4HI 0 "register_operand" "=y")
990169689Skan	(vec_select:V4HI
991169689Skan	  (vec_concat:V8HI
992169689Skan	    (match_operand:V4HI 1 "register_operand" "0")
993169689Skan	    (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
994169689Skan          (parallel [(const_int 0) (const_int 4)
995169689Skan                     (const_int 1) (const_int 5)])))]
996169689Skan  "TARGET_MMX"
997169689Skan  "punpcklwd\t{%2, %0|%0, %2}"
998169689Skan  [(set_attr "type" "mmxcvt")
999169689Skan   (set_attr "mode" "DI")])
1000169689Skan
1001169689Skan(define_insn "mmx_punpckhdq"
1002169689Skan  [(set (match_operand:V2SI 0 "register_operand" "=y")
1003169689Skan	(vec_select:V2SI
1004169689Skan	  (vec_concat:V4SI
1005169689Skan	    (match_operand:V2SI 1 "register_operand" "0")
1006169689Skan	    (match_operand:V2SI 2 "nonimmediate_operand" "ym"))
1007169689Skan	  (parallel [(const_int 1)
1008169689Skan		     (const_int 3)])))]
1009169689Skan  "TARGET_MMX"
1010169689Skan  "punpckhdq\t{%2, %0|%0, %2}"
1011169689Skan  [(set_attr "type" "mmxcvt")
1012169689Skan   (set_attr "mode" "DI")])
1013169689Skan
1014169689Skan(define_insn "mmx_punpckldq"
1015169689Skan  [(set (match_operand:V2SI 0 "register_operand" "=y")
1016169689Skan	(vec_select:V2SI
1017169689Skan	  (vec_concat:V4SI
1018169689Skan	    (match_operand:V2SI 1 "register_operand" "0")
1019169689Skan	    (match_operand:V2SI 2 "nonimmediate_operand" "ym"))
1020169689Skan	  (parallel [(const_int 0)
1021169689Skan		     (const_int 2)])))]
1022169689Skan  "TARGET_MMX"
1023169689Skan  "punpckldq\t{%2, %0|%0, %2}"
1024169689Skan  [(set_attr "type" "mmxcvt")
1025169689Skan   (set_attr "mode" "DI")])
1026169689Skan
1027169689Skan(define_expand "mmx_pinsrw"
1028169689Skan  [(set (match_operand:V4HI 0 "register_operand" "")
1029169689Skan        (vec_merge:V4HI
1030169689Skan          (vec_duplicate:V4HI
1031169689Skan            (match_operand:SI 2 "nonimmediate_operand" ""))
1032169689Skan	  (match_operand:V4HI 1 "register_operand" "")
1033169689Skan          (match_operand:SI 3 "const_0_to_3_operand" "")))]
1034169689Skan  "TARGET_SSE || TARGET_3DNOW_A"
1035169689Skan{
1036169689Skan  operands[2] = gen_lowpart (HImode, operands[2]);
1037169689Skan  operands[3] = GEN_INT (1 << INTVAL (operands[3]));
1038169689Skan})
1039169689Skan
1040169689Skan(define_insn "*mmx_pinsrw"
1041169689Skan  [(set (match_operand:V4HI 0 "register_operand" "=y")
1042169689Skan        (vec_merge:V4HI
1043169689Skan          (vec_duplicate:V4HI
1044169689Skan            (match_operand:HI 2 "nonimmediate_operand" "rm"))
1045169689Skan	  (match_operand:V4HI 1 "register_operand" "0")
1046169689Skan          (match_operand:SI 3 "const_pow2_1_to_8_operand" "n")))]
1047169689Skan  "TARGET_SSE || TARGET_3DNOW_A"
1048169689Skan{
1049169689Skan  operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
1050169689Skan  return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}";
1051169689Skan}
1052169689Skan  [(set_attr "type" "mmxcvt")
1053169689Skan   (set_attr "mode" "DI")])
1054169689Skan
1055169689Skan(define_insn "mmx_pextrw"
1056169689Skan  [(set (match_operand:SI 0 "register_operand" "=r")
1057169689Skan        (zero_extend:SI
1058169689Skan	  (vec_select:HI
1059169689Skan	    (match_operand:V4HI 1 "register_operand" "y")
1060169689Skan	    (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n")]))))]
1061169689Skan  "TARGET_SSE || TARGET_3DNOW_A"
1062169689Skan  "pextrw\t{%2, %1, %0|%0, %1, %2}"
1063169689Skan  [(set_attr "type" "mmxcvt")
1064169689Skan   (set_attr "mode" "DI")])
1065169689Skan
1066169689Skan(define_expand "mmx_pshufw"
1067169689Skan  [(match_operand:V4HI 0 "register_operand" "")
1068169689Skan   (match_operand:V4HI 1 "nonimmediate_operand" "")
1069169689Skan   (match_operand:SI 2 "const_int_operand" "")]
1070169689Skan  "TARGET_SSE || TARGET_3DNOW_A"
1071169689Skan{
1072169689Skan  int mask = INTVAL (operands[2]);
1073169689Skan  emit_insn (gen_mmx_pshufw_1 (operands[0], operands[1],
1074169689Skan                               GEN_INT ((mask >> 0) & 3),
1075169689Skan                               GEN_INT ((mask >> 2) & 3),
1076169689Skan                               GEN_INT ((mask >> 4) & 3),
1077169689Skan                               GEN_INT ((mask >> 6) & 3)));
1078169689Skan  DONE;
1079169689Skan})
1080169689Skan
1081169689Skan(define_insn "mmx_pshufw_1"
1082169689Skan  [(set (match_operand:V4HI 0 "register_operand" "=y")
1083169689Skan        (vec_select:V4HI
1084169689Skan          (match_operand:V4HI 1 "nonimmediate_operand" "ym")
1085169689Skan          (parallel [(match_operand 2 "const_0_to_3_operand" "")
1086169689Skan                     (match_operand 3 "const_0_to_3_operand" "")
1087169689Skan                     (match_operand 4 "const_0_to_3_operand" "")
1088169689Skan                     (match_operand 5 "const_0_to_3_operand" "")])))]
1089169689Skan  "TARGET_SSE || TARGET_3DNOW_A"
1090169689Skan{
1091169689Skan  int mask = 0;
1092169689Skan  mask |= INTVAL (operands[2]) << 0;
1093169689Skan  mask |= INTVAL (operands[3]) << 2;
1094169689Skan  mask |= INTVAL (operands[4]) << 4;
1095169689Skan  mask |= INTVAL (operands[5]) << 6;
1096169689Skan  operands[2] = GEN_INT (mask);
1097169689Skan
1098169689Skan  return "pshufw\t{%2, %1, %0|%0, %1, %2}";
1099169689Skan}
1100169689Skan  [(set_attr "type" "mmxcvt")
1101169689Skan   (set_attr "mode" "DI")])
1102169689Skan
1103169689Skan(define_insn "mmx_pswapdv2si2"
1104169689Skan  [(set (match_operand:V2SI 0 "register_operand" "=y")
1105169689Skan	(vec_select:V2SI
1106169689Skan	  (match_operand:V2SI 1 "nonimmediate_operand" "ym")
1107169689Skan	  (parallel [(const_int 1) (const_int 0)])))]
1108169689Skan  "TARGET_3DNOW_A"
1109169689Skan  "pswapd\\t{%1, %0|%0, %1}"
1110169689Skan  [(set_attr "type" "mmxcvt")
1111169689Skan   (set_attr "mode" "DI")])
1112169689Skan
1113169689Skan(define_insn "*vec_dupv4hi"
1114169689Skan  [(set (match_operand:V4HI 0 "register_operand" "=y")
1115169689Skan	(vec_duplicate:V4HI
1116169689Skan	  (truncate:HI
1117169689Skan	    (match_operand:SI 1 "register_operand" "0"))))]
1118169689Skan  "TARGET_SSE || TARGET_3DNOW_A"
1119169689Skan  "pshufw\t{$0, %0, %0|%0, %0, 0}"
1120169689Skan  [(set_attr "type" "mmxcvt")
1121169689Skan   (set_attr "mode" "DI")])
1122169689Skan
1123169689Skan(define_insn "*vec_dupv2si"
1124169689Skan  [(set (match_operand:V2SI 0 "register_operand" "=y")
1125169689Skan	(vec_duplicate:V2SI
1126169689Skan	  (match_operand:SI 1 "register_operand" "0")))]
1127169689Skan  "TARGET_MMX"
1128169689Skan  "punpckldq\t%0, %0"
1129169689Skan  [(set_attr "type" "mmxcvt")
1130169689Skan   (set_attr "mode" "DI")])
1131169689Skan
1132169689Skan(define_insn "*mmx_concatv2si"
1133169689Skan  [(set (match_operand:V2SI 0 "register_operand"     "=y,y")
1134169689Skan	(vec_concat:V2SI
1135169689Skan	  (match_operand:SI 1 "nonimmediate_operand" " 0,rm")
1136169689Skan	  (match_operand:SI 2 "vector_move_operand"  "ym,C")))]
1137169689Skan  "TARGET_MMX && !TARGET_SSE"
1138169689Skan  "@
1139169689Skan   punpckldq\t{%2, %0|%0, %2}
1140169689Skan   movd\t{%1, %0|%0, %1}"
1141169689Skan  [(set_attr "type" "mmxcvt,mmxmov")
1142169689Skan   (set_attr "mode" "DI")])
1143169689Skan
1144169689Skan(define_expand "vec_setv2si"
1145169689Skan  [(match_operand:V2SI 0 "register_operand" "")
1146169689Skan   (match_operand:SI 1 "register_operand" "")
1147169689Skan   (match_operand 2 "const_int_operand" "")]
1148169689Skan  "TARGET_MMX"
1149169689Skan{
1150169689Skan  ix86_expand_vector_set (false, operands[0], operands[1],
1151169689Skan			  INTVAL (operands[2]));
1152169689Skan  DONE;
1153169689Skan})
1154169689Skan
1155169689Skan(define_insn_and_split "*vec_extractv2si_0"
1156169689Skan  [(set (match_operand:SI 0 "nonimmediate_operand"     "=x,y,m,m,frxy")
1157169689Skan	(vec_select:SI
1158169689Skan	  (match_operand:V2SI 1 "nonimmediate_operand" " x,y,x,y,m")
1159169689Skan	  (parallel [(const_int 0)])))]
1160169689Skan  "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1161169689Skan  "#"
1162169689Skan  "&& reload_completed"
1163169689Skan  [(const_int 0)]
1164169689Skan{
1165169689Skan  rtx op1 = operands[1];
1166169689Skan  if (REG_P (op1))
1167169689Skan    op1 = gen_rtx_REG (SImode, REGNO (op1));
1168169689Skan  else
1169169689Skan    op1 = gen_lowpart (SImode, op1);
1170169689Skan  emit_move_insn (operands[0], op1);
1171169689Skan  DONE;
1172169689Skan})
1173169689Skan
1174169689Skan(define_insn "*vec_extractv2si_1"
1175169689Skan  [(set (match_operand:SI 0 "nonimmediate_operand"     "=y,Y,Y,x,frxy")
1176169689Skan	(vec_select:SI
1177169689Skan	  (match_operand:V2SI 1 "nonimmediate_operand" " 0,0,Y,0,o")
1178169689Skan	  (parallel [(const_int 1)])))]
1179169689Skan  "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1180169689Skan  "@
1181169689Skan   punpckhdq\t%0, %0
1182169689Skan   punpckhdq\t%0, %0
1183169689Skan   pshufd\t{$85, %1, %0|%0, %1, 85}
1184169689Skan   unpckhps\t%0, %0
1185169689Skan   #"
1186169689Skan  [(set_attr "type" "mmxcvt,sselog1,sselog1,sselog1,*")
1187169689Skan   (set_attr "mode" "DI,TI,TI,V4SF,SI")])
1188169689Skan
1189169689Skan(define_split
1190169689Skan  [(set (match_operand:SI 0 "register_operand" "")
1191169689Skan	(vec_select:SI
1192169689Skan	  (match_operand:V2SI 1 "memory_operand" "")
1193169689Skan	  (parallel [(const_int 1)])))]
1194169689Skan  "TARGET_MMX && reload_completed"
1195169689Skan  [(const_int 0)]
1196169689Skan{
1197169689Skan  operands[1] = adjust_address (operands[1], SImode, 4);
1198169689Skan  emit_move_insn (operands[0], operands[1]);
1199169689Skan  DONE;
1200169689Skan})
1201169689Skan
1202169689Skan(define_expand "vec_extractv2si"
1203169689Skan  [(match_operand:SI 0 "register_operand" "")
1204169689Skan   (match_operand:V2SI 1 "register_operand" "")
1205169689Skan   (match_operand 2 "const_int_operand" "")]
1206169689Skan  "TARGET_MMX"
1207169689Skan{
1208169689Skan  ix86_expand_vector_extract (false, operands[0], operands[1],
1209169689Skan			      INTVAL (operands[2]));
1210169689Skan  DONE;
1211169689Skan})
1212169689Skan
1213169689Skan(define_expand "vec_initv2si"
1214169689Skan  [(match_operand:V2SI 0 "register_operand" "")
1215169689Skan   (match_operand 1 "" "")]
1216169689Skan  "TARGET_SSE"
1217169689Skan{
1218169689Skan  ix86_expand_vector_init (false, operands[0], operands[1]);
1219169689Skan  DONE;
1220169689Skan})
1221169689Skan
1222169689Skan(define_expand "vec_setv4hi"
1223169689Skan  [(match_operand:V4HI 0 "register_operand" "")
1224169689Skan   (match_operand:HI 1 "register_operand" "")
1225169689Skan   (match_operand 2 "const_int_operand" "")]
1226169689Skan  "TARGET_MMX"
1227169689Skan{
1228169689Skan  ix86_expand_vector_set (false, operands[0], operands[1],
1229169689Skan			  INTVAL (operands[2]));
1230169689Skan  DONE;
1231169689Skan})
1232169689Skan
1233169689Skan(define_expand "vec_extractv4hi"
1234169689Skan  [(match_operand:HI 0 "register_operand" "")
1235169689Skan   (match_operand:V4HI 1 "register_operand" "")
1236169689Skan   (match_operand 2 "const_int_operand" "")]
1237169689Skan  "TARGET_MMX"
1238169689Skan{
1239169689Skan  ix86_expand_vector_extract (false, operands[0], operands[1],
1240169689Skan			      INTVAL (operands[2]));
1241169689Skan  DONE;
1242169689Skan})
1243169689Skan
1244169689Skan(define_expand "vec_initv4hi"
1245169689Skan  [(match_operand:V4HI 0 "register_operand" "")
1246169689Skan   (match_operand 1 "" "")]
1247169689Skan  "TARGET_SSE"
1248169689Skan{
1249169689Skan  ix86_expand_vector_init (false, operands[0], operands[1]);
1250169689Skan  DONE;
1251169689Skan})
1252169689Skan
1253169689Skan(define_expand "vec_setv8qi"
1254169689Skan  [(match_operand:V8QI 0 "register_operand" "")
1255169689Skan   (match_operand:QI 1 "register_operand" "")
1256169689Skan   (match_operand 2 "const_int_operand" "")]
1257169689Skan  "TARGET_MMX"
1258169689Skan{
1259169689Skan  ix86_expand_vector_set (false, operands[0], operands[1],
1260169689Skan			  INTVAL (operands[2]));
1261169689Skan  DONE;
1262169689Skan})
1263169689Skan
1264169689Skan(define_expand "vec_extractv8qi"
1265169689Skan  [(match_operand:QI 0 "register_operand" "")
1266169689Skan   (match_operand:V8QI 1 "register_operand" "")
1267169689Skan   (match_operand 2 "const_int_operand" "")]
1268169689Skan  "TARGET_MMX"
1269169689Skan{
1270169689Skan  ix86_expand_vector_extract (false, operands[0], operands[1],
1271169689Skan			      INTVAL (operands[2]));
1272169689Skan  DONE;
1273169689Skan})
1274169689Skan
1275169689Skan(define_expand "vec_initv8qi"
1276169689Skan  [(match_operand:V8QI 0 "register_operand" "")
1277169689Skan   (match_operand 1 "" "")]
1278169689Skan  "TARGET_SSE"
1279169689Skan{
1280169689Skan  ix86_expand_vector_init (false, operands[0], operands[1]);
1281169689Skan  DONE;
1282169689Skan})
1283169689Skan
1284169689Skan;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1285169689Skan;;
1286169689Skan;; Miscellaneous
1287169689Skan;;
1288169689Skan;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1289169689Skan
1290169689Skan(define_insn "mmx_uavgv8qi3"
1291169689Skan  [(set (match_operand:V8QI 0 "register_operand" "=y")
1292169689Skan	(truncate:V8QI
1293169689Skan	  (lshiftrt:V8HI
1294169689Skan	    (plus:V8HI
1295169689Skan	      (plus:V8HI
1296169689Skan		(zero_extend:V8HI
1297169689Skan		  (match_operand:V8QI 1 "nonimmediate_operand" "%0"))
1298169689Skan		(zero_extend:V8HI
1299169689Skan		  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))
1300169689Skan	      (const_vector:V8HI [(const_int 1) (const_int 1)
1301169689Skan				  (const_int 1) (const_int 1)
1302169689Skan				  (const_int 1) (const_int 1)
1303169689Skan				  (const_int 1) (const_int 1)]))
1304169689Skan	    (const_int 1))))]
1305169689Skan  "(TARGET_SSE || TARGET_3DNOW)
1306169689Skan   && ix86_binary_operator_ok (PLUS, V8QImode, operands)"
1307169689Skan{
1308169689Skan  /* These two instructions have the same operation, but their encoding
1309169689Skan     is different.  Prefer the one that is de facto standard.  */
1310169689Skan  if (TARGET_SSE || TARGET_3DNOW_A)
1311169689Skan    return "pavgb\t{%2, %0|%0, %2}";
1312169689Skan  else
1313169689Skan    return "pavgusb\\t{%2, %0|%0, %2}";
1314169689Skan}
1315169689Skan  [(set_attr "type" "mmxshft")
1316169689Skan   (set_attr "mode" "DI")])
1317169689Skan
1318169689Skan(define_insn "mmx_uavgv4hi3"
1319169689Skan  [(set (match_operand:V4HI 0 "register_operand" "=y")
1320169689Skan	(truncate:V4HI
1321169689Skan	  (lshiftrt:V4SI
1322169689Skan	    (plus:V4SI
1323169689Skan	      (plus:V4SI
1324169689Skan		(zero_extend:V4SI
1325169689Skan		  (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
1326169689Skan		(zero_extend:V4SI
1327169689Skan		  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
1328169689Skan	      (const_vector:V4SI [(const_int 1) (const_int 1)
1329169689Skan				  (const_int 1) (const_int 1)]))
1330169689Skan	    (const_int 1))))]
1331169689Skan  "(TARGET_SSE || TARGET_3DNOW_A)
1332169689Skan   && ix86_binary_operator_ok (PLUS, V4HImode, operands)"
1333169689Skan  "pavgw\t{%2, %0|%0, %2}"
1334169689Skan  [(set_attr "type" "mmxshft")
1335169689Skan   (set_attr "mode" "DI")])
1336169689Skan
1337169689Skan(define_insn "mmx_psadbw"
1338169689Skan  [(set (match_operand:DI 0 "register_operand" "=y")
1339169689Skan        (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
1340169689Skan		    (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
1341169689Skan		   UNSPEC_PSADBW))]
1342169689Skan  "TARGET_SSE || TARGET_3DNOW_A"
1343169689Skan  "psadbw\t{%2, %0|%0, %2}"
1344169689Skan  [(set_attr "type" "mmxshft")
1345169689Skan   (set_attr "mode" "DI")])
1346169689Skan
1347169689Skan(define_insn "mmx_pmovmskb"
1348169689Skan  [(set (match_operand:SI 0 "register_operand" "=r")
1349169689Skan	(unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
1350169689Skan		   UNSPEC_MOVMSK))]
1351169689Skan  "TARGET_SSE || TARGET_3DNOW_A"
1352169689Skan  "pmovmskb\t{%1, %0|%0, %1}"
1353169689Skan  [(set_attr "type" "mmxcvt")
1354169689Skan   (set_attr "mode" "DI")])
1355169689Skan
1356169689Skan(define_expand "mmx_maskmovq"
1357169689Skan  [(set (match_operand:V8QI 0 "memory_operand" "")
1358169689Skan	(unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
1359169689Skan		      (match_operand:V8QI 2 "register_operand" "y")
1360169689Skan		      (match_dup 0)]
1361169689Skan		     UNSPEC_MASKMOV))]
1362169689Skan  "TARGET_SSE || TARGET_3DNOW_A"
1363169689Skan  "")
1364169689Skan
1365169689Skan(define_insn "*mmx_maskmovq"
1366169689Skan  [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
1367169689Skan	(unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
1368169689Skan		      (match_operand:V8QI 2 "register_operand" "y")
1369169689Skan		      (mem:V8QI (match_dup 0))]
1370169689Skan		     UNSPEC_MASKMOV))]
1371169689Skan  "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
1372169689Skan  ;; @@@ check ordering of operands in intel/nonintel syntax
1373169689Skan  "maskmovq\t{%2, %1|%1, %2}"
1374169689Skan  [(set_attr "type" "mmxcvt")
1375169689Skan   (set_attr "mode" "DI")])
1376169689Skan
1377169689Skan(define_insn "*mmx_maskmovq_rex"
1378169689Skan  [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
1379169689Skan	(unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
1380169689Skan		      (match_operand:V8QI 2 "register_operand" "y")
1381169689Skan		      (mem:V8QI (match_dup 0))]
1382169689Skan		     UNSPEC_MASKMOV))]
1383169689Skan  "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
1384169689Skan  ;; @@@ check ordering of operands in intel/nonintel syntax
1385169689Skan  "maskmovq\t{%2, %1|%1, %2}"
1386169689Skan  [(set_attr "type" "mmxcvt")
1387169689Skan   (set_attr "mode" "DI")])
1388169689Skan
1389169689Skan(define_insn "mmx_emms"
1390169689Skan  [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
1391169689Skan   (clobber (reg:XF 8))
1392169689Skan   (clobber (reg:XF 9))
1393169689Skan   (clobber (reg:XF 10))
1394169689Skan   (clobber (reg:XF 11))
1395169689Skan   (clobber (reg:XF 12))
1396169689Skan   (clobber (reg:XF 13))
1397169689Skan   (clobber (reg:XF 14))
1398169689Skan   (clobber (reg:XF 15))
1399237021Spfg   (clobber (reg:DI 29))
1400169689Skan   (clobber (reg:DI 30))
1401169689Skan   (clobber (reg:DI 31))
1402169689Skan   (clobber (reg:DI 32))
1403169689Skan   (clobber (reg:DI 33))
1404169689Skan   (clobber (reg:DI 34))
1405169689Skan   (clobber (reg:DI 35))
1406237021Spfg   (clobber (reg:DI 36))]
1407169689Skan  "TARGET_MMX"
1408169689Skan  "emms"
1409169689Skan  [(set_attr "type" "mmx")
1410169689Skan   (set_attr "memory" "unknown")])
1411169689Skan
1412169689Skan(define_insn "mmx_femms"
1413169689Skan  [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
1414169689Skan   (clobber (reg:XF 8))
1415169689Skan   (clobber (reg:XF 9))
1416169689Skan   (clobber (reg:XF 10))
1417169689Skan   (clobber (reg:XF 11))
1418169689Skan   (clobber (reg:XF 12))
1419169689Skan   (clobber (reg:XF 13))
1420169689Skan   (clobber (reg:XF 14))
1421169689Skan   (clobber (reg:XF 15))
1422237021Spfg   (clobber (reg:DI 29))
1423169689Skan   (clobber (reg:DI 30))
1424169689Skan   (clobber (reg:DI 31))
1425169689Skan   (clobber (reg:DI 32))
1426169689Skan   (clobber (reg:DI 33))
1427169689Skan   (clobber (reg:DI 34))
1428169689Skan   (clobber (reg:DI 35))
1429237021Spfg   (clobber (reg:DI 36))]
1430169689Skan  "TARGET_3DNOW"
1431169689Skan  "femms"
1432169689Skan  [(set_attr "type" "mmx")
1433169689Skan   (set_attr "memory" "none")]) 
1434