1169689Skan;; IA-64 machine description for vector operations.
2169689Skan;; Copyright (C) 2004, 2005
3169689Skan;;
4169689Skan;; This file is part of GCC.
5169689Skan;;
6169689Skan;; GCC is free software; you can redistribute it and/or modify
7169689Skan;; it under the terms of the GNU General Public License as published by
8169689Skan;; the Free Software Foundation; either version 2, or (at your option)
9169689Skan;; any later version.
10169689Skan;;
11169689Skan;; GCC is distributed in the hope that it will be useful,
12169689Skan;; but WITHOUT ANY WARRANTY; without even the implied warranty of
13169689Skan;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14169689Skan;; GNU General Public License for more details.
15169689Skan;;
16169689Skan;; You should have received a copy of the GNU General Public License
17169689Skan;; along with GCC; see the file COPYING.  If not, write to
18169689Skan;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
19169689Skan;; Boston, MA 02110-1301, USA.
20169689Skan
21169689Skan
22169689Skan;; Integer vector operations
23169689Skan
24169689Skan(define_mode_macro VECINT [V8QI V4HI V2SI])
25169689Skan(define_mode_macro VECINT12 [V8QI V4HI])
26169689Skan(define_mode_macro VECINT24 [V4HI V2SI])
27169689Skan(define_mode_attr vecsize [(V8QI "1") (V4HI "2") (V2SI "4")])
28169689Skan
29169689Skan(define_expand "mov<mode>"
30169689Skan  [(set (match_operand:VECINT 0 "general_operand" "")
31169689Skan        (match_operand:VECINT 1 "general_operand" ""))]
32169689Skan  ""
33169689Skan{
34169689Skan  rtx op1 = ia64_expand_move (operands[0], operands[1]);
35169689Skan  if (!op1)
36169689Skan    DONE;
37169689Skan  operands[1] = op1;
38169689Skan})
39169689Skan
40169689Skan(define_insn "*mov<mode>_internal"
41169689Skan  [(set (match_operand:VECINT 0 "destination_operand"
42169689Skan					"=r,r,r,r,m ,*f ,*f,Q ,r ,*f")
43169689Skan	(match_operand:VECINT 1 "move_operand"
44169689Skan					"rU,W,i,m,rU,U*f,Q ,*f,*f,r "))]
45169689Skan  "ia64_move_ok (operands[0], operands[1])"
46169689Skan  "@
47169689Skan   mov %0 = %r1
48169689Skan   addl %0 = %v1, r0
49169689Skan   movl %0 = %v1
50169689Skan   ld8%O1 %0 = %1%P1
51169689Skan   st8%Q0 %0 = %r1%P0
52169689Skan   mov %0 = %F1
53169689Skan   ldf8 %0 = %1%P1
54169689Skan   stf8 %0 = %1%P0
55169689Skan   getf.sig %0 = %1
56169689Skan   setf.sig %0 = %1"
57169689Skan  [(set_attr "itanium_class" "ialu,ialu,long_i,ld,st,fmisc,fld,stf,frfr,tofr")])
58169689Skan
59169689Skan(define_insn "one_cmpl<mode>2"
60169689Skan  [(set (match_operand:VECINT 0 "gr_register_operand" "=r")
61169689Skan	(not:VECINT (match_operand:VECINT 1 "gr_register_operand" "r")))]
62169689Skan  ""
63169689Skan  "andcm %0 = -1, %1"
64169689Skan  [(set_attr "itanium_class" "ilog")])
65169689Skan
66169689Skan(define_insn "and<mode>3"
67169689Skan  [(set (match_operand:VECINT 0 "grfr_register_operand" "=r,*f")
68169689Skan	(and:VECINT
69169689Skan	  (match_operand:VECINT 1 "grfr_register_operand" "r,*f")
70169689Skan	  (match_operand:VECINT 2 "grfr_reg_or_8bit_operand" "r,*f")))]
71169689Skan  ""
72169689Skan  "@
73169689Skan   and %0 = %2, %1
74169689Skan   fand %0 = %2, %1"
75169689Skan  [(set_attr "itanium_class" "ilog,fmisc")])
76169689Skan
77169689Skan(define_insn "*andnot<mode>"
78169689Skan  [(set (match_operand:VECINT 0 "grfr_register_operand" "=r,*f")
79169689Skan	(and:VECINT
80169689Skan	  (not:VECINT (match_operand:VECINT 1 "grfr_register_operand" "r,*f"))
81169689Skan	  (match_operand:VECINT 2 "grfr_reg_or_8bit_operand" "r,*f")))]
82169689Skan  ""
83169689Skan  "@
84169689Skan   andcm %0 = %2, %1
85169689Skan   fandcm %0 = %2, %1"
86169689Skan  [(set_attr "itanium_class" "ilog,fmisc")])
87169689Skan
88169689Skan(define_insn "ior<mode>3"
89169689Skan  [(set (match_operand:VECINT 0 "grfr_register_operand" "=r,*f")
90169689Skan	(ior:VECINT
91169689Skan	  (match_operand:VECINT 1 "grfr_register_operand" "r,*f")
92169689Skan	  (match_operand:VECINT 2 "grfr_reg_or_8bit_operand" "r,*f")))]
93169689Skan  ""
94169689Skan  "@
95169689Skan   or %0 = %2, %1
96169689Skan   for %0 = %2, %1"
97169689Skan  [(set_attr "itanium_class" "ilog,fmisc")])
98169689Skan
99169689Skan(define_insn "xor<mode>3"
100169689Skan  [(set (match_operand:VECINT 0 "grfr_register_operand" "=r,*f")
101169689Skan	(xor:VECINT
102169689Skan	  (match_operand:VECINT 1 "grfr_register_operand" "r,*f")
103169689Skan	  (match_operand:VECINT 2 "grfr_reg_or_8bit_operand" "r,*f")))]
104169689Skan  ""
105169689Skan  "@
106169689Skan   xor %0 = %2, %1
107169689Skan   fxor %0 = %2, %1"
108169689Skan  [(set_attr "itanium_class" "ilog,fmisc")])
109169689Skan
110169689Skan(define_insn "neg<mode>2"
111169689Skan  [(set (match_operand:VECINT 0 "gr_register_operand" "=r")
112169689Skan	(neg:VECINT (match_operand:VECINT 1 "gr_register_operand" "r")))]
113169689Skan  ""
114169689Skan  "psub<vecsize> %0 = r0, %1"
115169689Skan  [(set_attr "itanium_class" "mmalua")])
116169689Skan
117169689Skan(define_insn "add<mode>3"
118169689Skan  [(set (match_operand:VECINT 0 "gr_register_operand" "=r")
119169689Skan	(plus:VECINT (match_operand:VECINT 1 "gr_register_operand" "r")
120169689Skan		     (match_operand:VECINT 2 "gr_register_operand" "r")))]
121169689Skan  ""
122169689Skan  "padd<vecsize> %0 = %1, %2"
123169689Skan  [(set_attr "itanium_class" "mmalua")])
124169689Skan
125169689Skan(define_insn "*ssadd<mode>3"
126169689Skan  [(set (match_operand:VECINT12 0 "gr_register_operand" "=r")
127169689Skan	(ss_plus:VECINT12
128169689Skan	  (match_operand:VECINT12 1 "gr_register_operand" "r")
129169689Skan	  (match_operand:VECINT12 2 "gr_register_operand" "r")))]
130169689Skan  ""
131169689Skan  "padd<vecsize>.sss %0 = %1, %2"
132169689Skan  [(set_attr "itanium_class" "mmalua")])
133169689Skan
134169689Skan(define_insn "*usadd<mode>3"
135169689Skan  [(set (match_operand:VECINT12 0 "gr_register_operand" "=r")
136169689Skan	(us_plus:VECINT12
137169689Skan	  (match_operand:VECINT12 1 "gr_register_operand" "r")
138169689Skan	  (match_operand:VECINT12 2 "gr_register_operand" "r")))]
139169689Skan  ""
140169689Skan  "padd<vecsize>.uuu %0 = %1, %2"
141169689Skan  [(set_attr "itanium_class" "mmalua")])
142169689Skan
143169689Skan(define_insn "sub<mode>3"
144169689Skan  [(set (match_operand:VECINT 0 "gr_register_operand" "=r")
145169689Skan	(minus:VECINT (match_operand:VECINT 1 "gr_register_operand" "r")
146169689Skan		      (match_operand:VECINT 2 "gr_register_operand" "r")))]
147169689Skan  ""
148169689Skan  "psub<vecsize> %0 = %1, %2"
149169689Skan  [(set_attr "itanium_class" "mmalua")])
150169689Skan
151169689Skan(define_insn "*sssub<mode>3"
152169689Skan  [(set (match_operand:VECINT12 0 "gr_register_operand" "=r")
153169689Skan	(ss_minus:VECINT12
154169689Skan	  (match_operand:VECINT12 1 "gr_register_operand" "r")
155169689Skan	  (match_operand:VECINT12 2 "gr_register_operand" "r")))]
156169689Skan  ""
157169689Skan  "psub<vecsize>.sss %0 = %1, %2"
158169689Skan  [(set_attr "itanium_class" "mmalua")])
159169689Skan
160169689Skan(define_insn "*ussub<mode>3"
161169689Skan  [(set (match_operand:VECINT12 0 "gr_register_operand" "=r")
162169689Skan	(us_minus:VECINT12
163169689Skan	  (match_operand:VECINT12 1 "gr_register_operand" "r")
164169689Skan	  (match_operand:VECINT12 2 "gr_register_operand" "r")))]
165169689Skan  ""
166169689Skan  "psub<vecsize>.uuu %0 = %1, %2"
167169689Skan  [(set_attr "itanium_class" "mmalua")])
168169689Skan
169169689Skan(define_expand "mulv8qi3"
170169689Skan  [(set (match_operand:V8QI 0 "gr_register_operand" "")
171169689Skan	(mult:V8QI (match_operand:V8QI 1 "gr_register_operand" "r")
172169689Skan		   (match_operand:V8QI 2 "gr_register_operand" "r")))]
173169689Skan  ""
174169689Skan{
175169689Skan  rtx r1, l1, r2, l2, rm, lm;
176169689Skan
177169689Skan  r1 = gen_reg_rtx (V4HImode);
178169689Skan  l1 = gen_reg_rtx (V4HImode);
179169689Skan  r2 = gen_reg_rtx (V4HImode);
180169689Skan  l2 = gen_reg_rtx (V4HImode);
181169689Skan
182169689Skan  /* Zero-extend the QImode elements into two words of HImode elements
183169689Skan     by interleaving them with zero bytes.  */
184169689Skan  emit_insn (gen_mix1_r (gen_lowpart (V8QImode, r1),
185169689Skan                         operands[1], CONST0_RTX (V8QImode)));
186169689Skan  emit_insn (gen_mix1_r (gen_lowpart (V8QImode, r2),
187169689Skan                         operands[2], CONST0_RTX (V8QImode)));
188169689Skan  emit_insn (gen_mix1_l (gen_lowpart (V8QImode, l1),
189169689Skan                         operands[1], CONST0_RTX (V8QImode)));
190169689Skan  emit_insn (gen_mix1_l (gen_lowpart (V8QImode, l2),
191169689Skan                         operands[2], CONST0_RTX (V8QImode)));
192169689Skan
193169689Skan  /* Multiply.  */
194169689Skan  rm = gen_reg_rtx (V4HImode);
195169689Skan  lm = gen_reg_rtx (V4HImode);
196169689Skan  emit_insn (gen_mulv4hi3 (rm, r1, r2));
197169689Skan  emit_insn (gen_mulv4hi3 (lm, l1, l2));
198169689Skan
199169689Skan  /* Zap the high order bytes of the HImode elements by overwriting those
200169689Skan     in one part with the low order bytes of the other.  */
201169689Skan  emit_insn (gen_mix1_r (operands[0],
202169689Skan                         gen_lowpart (V8QImode, rm),
203169689Skan                         gen_lowpart (V8QImode, lm)));
204169689Skan  DONE;
205169689Skan})
206169689Skan
207169689Skan(define_insn "mulv4hi3"
208169689Skan  [(set (match_operand:V4HI 0 "gr_register_operand" "=r")
209169689Skan	(mult:V4HI (match_operand:V4HI 1 "gr_register_operand" "r")
210169689Skan		   (match_operand:V4HI 2 "gr_register_operand" "r")))]
211169689Skan  ""
212169689Skan  "pmpyshr2 %0 = %1, %2, 0"
213169689Skan  [(set_attr "itanium_class" "mmmul")])
214169689Skan
215169689Skan(define_insn "pmpy2_r"
216169689Skan  [(set (match_operand:V2SI 0 "gr_register_operand" "=r")
217169689Skan	(mult:V2SI
218169689Skan	  (vec_select:V2SI
219169689Skan	    (sign_extend:V4SI
220169689Skan	      (match_operand:V4HI 1 "gr_register_operand" "r"))
221169689Skan	    (parallel [(const_int 0) (const_int 2)]))
222169689Skan	  (vec_select:V2SI
223169689Skan	    (sign_extend:V4SI
224169689Skan	      (match_operand:V4HI 2 "gr_register_operand" "r"))
225169689Skan	    (parallel [(const_int 0) (const_int 2)]))))]
226169689Skan  ""
227169689Skan  "pmpy2.r %0 = %1, %2"
228169689Skan  [(set_attr "itanium_class" "mmshf")])
229169689Skan
230169689Skan(define_insn "pmpy2_l"
231169689Skan  [(set (match_operand:V2SI 0 "gr_register_operand" "=r")
232169689Skan	(mult:V2SI
233169689Skan	  (vec_select:V2SI
234169689Skan	    (sign_extend:V4SI
235169689Skan	      (match_operand:V4HI 1 "gr_register_operand" "r"))
236169689Skan	    (parallel [(const_int 1) (const_int 3)]))
237169689Skan	  (vec_select:V2SI
238169689Skan	    (sign_extend:V4SI
239169689Skan	      (match_operand:V4HI 2 "gr_register_operand" "r"))
240169689Skan	    (parallel [(const_int 1) (const_int 3)]))))]
241169689Skan  ""
242169689Skan  "pmpy2.l %0 = %1, %2"
243169689Skan  [(set_attr "itanium_class" "mmshf")])
244169689Skan
245169689Skan(define_expand "umax<mode>3"
246169689Skan  [(set (match_operand:VECINT 0 "gr_register_operand" "")
247169689Skan	(umax:VECINT (match_operand:VECINT 1 "gr_register_operand" "")
248169689Skan		     (match_operand:VECINT 2 "gr_register_operand" "")))]
249169689Skan  ""
250169689Skan{
251169689Skan  if (ia64_expand_vecint_minmax (UMAX, <MODE>mode, operands))
252169689Skan    DONE;
253169689Skan})
254169689Skan
255169689Skan(define_expand "smax<mode>3"
256169689Skan  [(set (match_operand:VECINT 0 "gr_register_operand" "")
257169689Skan	(smax:VECINT (match_operand:VECINT 1 "gr_reg_or_0_operand" "")
258169689Skan		     (match_operand:VECINT 2 "gr_reg_or_0_operand" "")))]
259169689Skan  ""
260169689Skan{
261169689Skan  if (ia64_expand_vecint_minmax (SMAX, <MODE>mode, operands))
262169689Skan    DONE;
263169689Skan})
264169689Skan
265169689Skan(define_expand "umin<mode>3"
266169689Skan  [(set (match_operand:VECINT 0 "gr_register_operand" "")
267169689Skan	(umin:VECINT (match_operand:VECINT 1 "gr_register_operand" "")
268169689Skan		     (match_operand:VECINT 2 "gr_register_operand" "")))]
269169689Skan  ""
270169689Skan{
271169689Skan  if (ia64_expand_vecint_minmax (UMIN, <MODE>mode, operands))
272169689Skan    DONE;
273169689Skan})
274169689Skan
275169689Skan(define_expand "smin<mode>3"
276169689Skan  [(set (match_operand:VECINT 0 "gr_register_operand" "")
277169689Skan	(smin:VECINT (match_operand:VECINT 1 "gr_reg_or_0_operand" "")
278169689Skan		     (match_operand:VECINT 2 "gr_reg_or_0_operand" "")))]
279169689Skan  ""
280169689Skan{
281169689Skan  if (ia64_expand_vecint_minmax (SMIN, <MODE>mode, operands))
282169689Skan    DONE;
283169689Skan})
284169689Skan
285169689Skan(define_insn "*umaxv8qi3"
286169689Skan  [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
287169689Skan	(umax:V8QI (match_operand:V8QI 1 "gr_register_operand" "r")
288169689Skan		   (match_operand:V8QI 2 "gr_register_operand" "r")))]
289169689Skan  ""
290169689Skan  "pmax1.u %0 = %1, %2"
291169689Skan  [(set_attr "itanium_class" "mmshf")])
292169689Skan
293169689Skan(define_insn "*smaxv4hi3"
294169689Skan  [(set (match_operand:V4HI 0 "gr_register_operand" "=r")
295169689Skan	(smax:V4HI (match_operand:V4HI 1 "gr_reg_or_0_operand" "rU")
296169689Skan		   (match_operand:V4HI 2 "gr_reg_or_0_operand" "rU")))]
297169689Skan  ""
298169689Skan  "pmax2 %0 = %r1, %r2"
299169689Skan  [(set_attr "itanium_class" "mmshf")])
300169689Skan
301169689Skan(define_insn "*uminv8qi3"
302169689Skan  [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
303169689Skan	(umin:V8QI (match_operand:V8QI 1 "gr_register_operand" "r")
304169689Skan		   (match_operand:V8QI 2 "gr_register_operand" "r")))]
305169689Skan  ""
306169689Skan  "pmin1.u %0 = %1, %2"
307169689Skan  [(set_attr "itanium_class" "mmshf")])
308169689Skan
309169689Skan(define_insn "*sminv4hi3"
310169689Skan  [(set (match_operand:V4HI 0 "gr_register_operand" "=r")
311169689Skan	(smin:V4HI (match_operand:V4HI 1 "gr_reg_or_0_operand" "rU")
312169689Skan		   (match_operand:V4HI 2 "gr_reg_or_0_operand" "rU")))]
313169689Skan  ""
314169689Skan  "pmin2 %0 = %r1, %r2"
315169689Skan  [(set_attr "itanium_class" "mmshf")])
316169689Skan
317169689Skan(define_insn "ashl<mode>3"
318169689Skan  [(set (match_operand:VECINT24 0 "gr_register_operand" "=r")
319169689Skan	(ashift:VECINT24
320169689Skan	  (match_operand:VECINT24 1 "gr_register_operand" "r")
321169689Skan	  (match_operand:DI 2 "gr_reg_or_5bit_operand" "rn")))]
322169689Skan  ""
323169689Skan  "pshl<vecsize> %0 = %1, %2"
324169689Skan  [(set_attr "itanium_class" "mmshf")])
325169689Skan
326169689Skan(define_insn "ashr<mode>3"
327169689Skan  [(set (match_operand:VECINT24 0 "gr_register_operand" "=r")
328169689Skan	(ashiftrt:VECINT24
329169689Skan	  (match_operand:VECINT24 1 "gr_register_operand" "r")
330169689Skan	  (match_operand:DI 2 "gr_reg_or_5bit_operand" "rn")))]
331169689Skan  ""
332169689Skan  "pshr<vecsize> %0 = %1, %2"
333169689Skan  [(set_attr "itanium_class" "mmshf")])
334169689Skan
335169689Skan(define_insn "lshr<mode>3"
336169689Skan  [(set (match_operand:VECINT24 0 "gr_register_operand" "=r")
337169689Skan	(lshiftrt:VECINT24
338169689Skan	  (match_operand:VECINT24 1 "gr_register_operand" "r")
339169689Skan	  (match_operand:DI 2 "gr_reg_or_5bit_operand" "rn")))]
340169689Skan  ""
341169689Skan  "pshr<vecsize>.u %0 = %1, %2"
342169689Skan  [(set_attr "itanium_class" "mmshf")])
343169689Skan
344169689Skan(define_expand "vec_shl_<mode>"
345169689Skan  [(set (match_operand:VECINT 0 "gr_register_operand" "")
346169689Skan	(ashift:DI (match_operand:VECINT 1 "gr_register_operand" "")
347169689Skan		   (match_operand:DI 2 "gr_reg_or_6bit_operand" "")))]
348169689Skan  ""
349169689Skan{
350169689Skan  operands[0] = gen_lowpart (DImode, operands[0]);
351169689Skan  operands[1] = gen_lowpart (DImode, operands[1]);
352169689Skan})
353169689Skan
354169689Skan(define_expand "vec_shr_<mode>"
355169689Skan  [(set (match_operand:VECINT 0 "gr_register_operand" "")
356169689Skan        (lshiftrt:DI (match_operand:VECINT 1 "gr_register_operand" "")
357169689Skan                     (match_operand:DI 2 "gr_reg_or_6bit_operand" "")))]
358169689Skan  ""
359169689Skan{
360169689Skan  operands[0] = gen_lowpart (DImode, operands[0]);
361169689Skan  operands[1] = gen_lowpart (DImode, operands[1]);
362169689Skan})
363169689Skan
364169689Skan(define_expand "widen_usumv8qi3"
365169689Skan  [(match_operand:V4HI 0 "gr_register_operand" "")
366169689Skan   (match_operand:V8QI 1 "gr_register_operand" "")
367169689Skan   (match_operand:V4HI 2 "gr_register_operand" "")]
368169689Skan  ""
369169689Skan{
370169689Skan  ia64_expand_widen_sum (operands, true);
371169689Skan  DONE;
372169689Skan})
373169689Skan
374169689Skan(define_expand "widen_usumv4hi3"
375169689Skan  [(match_operand:V2SI 0 "gr_register_operand" "")
376169689Skan   (match_operand:V4HI 1 "gr_register_operand" "")
377169689Skan   (match_operand:V2SI 2 "gr_register_operand" "")]
378169689Skan  ""
379169689Skan{
380169689Skan  ia64_expand_widen_sum (operands, true);
381169689Skan  DONE;
382169689Skan})
383169689Skan
384169689Skan(define_expand "widen_ssumv8qi3"
385169689Skan  [(match_operand:V4HI 0 "gr_register_operand" "")
386169689Skan   (match_operand:V8QI 1 "gr_register_operand" "")
387169689Skan   (match_operand:V4HI 2 "gr_register_operand" "")]
388169689Skan  ""
389169689Skan{
390169689Skan  ia64_expand_widen_sum (operands, false);
391169689Skan  DONE;
392169689Skan})
393169689Skan
394169689Skan(define_expand "widen_ssumv4hi3"
395169689Skan  [(match_operand:V2SI 0 "gr_register_operand" "")
396169689Skan   (match_operand:V4HI 1 "gr_register_operand" "")
397169689Skan   (match_operand:V2SI 2 "gr_register_operand" "")]
398169689Skan  ""
399169689Skan{
400169689Skan  ia64_expand_widen_sum (operands, false);
401169689Skan  DONE;
402169689Skan})
403169689Skan
404169689Skan(define_expand "udot_prodv8qi"
405169689Skan  [(match_operand:V2SI 0 "gr_register_operand" "")
406169689Skan   (match_operand:V8QI 1 "gr_register_operand" "")
407169689Skan   (match_operand:V8QI 2 "gr_register_operand" "")
408169689Skan   (match_operand:V2SI 3 "gr_register_operand" "")]
409169689Skan  ""
410169689Skan{
411169689Skan  ia64_expand_dot_prod_v8qi (operands, true);
412169689Skan  DONE;
413169689Skan})
414169689Skan
415169689Skan(define_expand "sdot_prodv8qi"
416169689Skan  [(match_operand:V2SI 0 "gr_register_operand" "")
417169689Skan   (match_operand:V8QI 1 "gr_register_operand" "")
418169689Skan   (match_operand:V8QI 2 "gr_register_operand" "")
419169689Skan   (match_operand:V2SI 3 "gr_register_operand" "")]
420169689Skan  ""
421169689Skan{
422169689Skan  ia64_expand_dot_prod_v8qi (operands, false);
423169689Skan  DONE;
424169689Skan})
425169689Skan
426169689Skan(define_expand "sdot_prodv4hi"
427169689Skan  [(match_operand:V2SI 0 "gr_register_operand" "")
428169689Skan   (match_operand:V4HI 1 "gr_register_operand" "")
429169689Skan   (match_operand:V4HI 2 "gr_register_operand" "")
430169689Skan   (match_operand:V2SI 3 "gr_register_operand" "")]
431169689Skan  ""
432169689Skan{
433169689Skan  rtx l, r, t;
434169689Skan
435169689Skan  r = gen_reg_rtx (V2SImode);
436169689Skan  l = gen_reg_rtx (V2SImode);
437169689Skan  t = gen_reg_rtx (V2SImode);
438169689Skan
439169689Skan  emit_insn (gen_pmpy2_r (r, operands[1], operands[2]));
440169689Skan  emit_insn (gen_pmpy2_l (l, operands[1], operands[2]));
441169689Skan  emit_insn (gen_addv2si3 (t, r, operands[3]));
442169689Skan  emit_insn (gen_addv2si3 (operands[0], t, l));
443169689Skan  DONE;
444169689Skan})
445169689Skan
446169689Skan(define_expand "vcond<mode>"
447169689Skan  [(set (match_operand:VECINT 0 "gr_register_operand" "")
448169689Skan	(if_then_else:VECINT
449169689Skan	  (match_operator 3 "" 
450169689Skan	    [(match_operand:VECINT 4 "gr_reg_or_0_operand" "")
451169689Skan	     (match_operand:VECINT 5 "gr_reg_or_0_operand" "")])
452169689Skan	  (match_operand:VECINT 1 "gr_reg_or_0_operand" "")
453169689Skan	  (match_operand:VECINT 2 "gr_reg_or_0_operand" "")))]
454169689Skan  ""
455169689Skan{
456169689Skan  ia64_expand_vecint_cmov (operands);
457169689Skan  DONE;
458169689Skan})
459169689Skan
460169689Skan(define_expand "vcondu<mode>"
461169689Skan  [(set (match_operand:VECINT 0 "gr_register_operand" "")
462169689Skan	(if_then_else:VECINT
463169689Skan	  (match_operator 3 "" 
464169689Skan	    [(match_operand:VECINT 4 "gr_reg_or_0_operand" "")
465169689Skan	     (match_operand:VECINT 5 "gr_reg_or_0_operand" "")])
466169689Skan	  (match_operand:VECINT 1 "gr_reg_or_0_operand" "")
467169689Skan	  (match_operand:VECINT 2 "gr_reg_or_0_operand" "")))]
468169689Skan  ""
469169689Skan{
470169689Skan  ia64_expand_vecint_cmov (operands);
471169689Skan  DONE;
472169689Skan})
473169689Skan
474169689Skan(define_insn "*cmpeq_<mode>"
475169689Skan  [(set (match_operand:VECINT 0 "gr_register_operand" "=r")
476169689Skan	(eq:VECINT (match_operand:VECINT 1 "gr_reg_or_0_operand" "rU")
477169689Skan		   (match_operand:VECINT 2 "gr_reg_or_0_operand" "rU")))]
478169689Skan  ""
479169689Skan  "pcmp<vecsize>.eq %0 = %r1, %r2"
480169689Skan  [(set_attr "itanium_class" "mmalua")])
481169689Skan
482169689Skan(define_insn "*cmpgt_<mode>"
483169689Skan  [(set (match_operand:VECINT 0 "gr_register_operand" "=r")
484169689Skan	(gt:VECINT (match_operand:VECINT 1 "gr_reg_or_0_operand" "rU")
485169689Skan		   (match_operand:VECINT 2 "gr_reg_or_0_operand" "rU")))]
486169689Skan  ""
487169689Skan  "pcmp<vecsize>.gt %0 = %r1, %r2"
488169689Skan  [(set_attr "itanium_class" "mmalua")])
489169689Skan
490169689Skan(define_insn "pack2_sss"
491169689Skan  [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
492169689Skan	(vec_concat:V8QI
493169689Skan	  (ss_truncate:V4QI
494169689Skan	    (match_operand:V4HI 1 "gr_reg_or_0_operand" "rU"))
495169689Skan	  (ss_truncate:V4QI
496169689Skan	    (match_operand:V4HI 2 "gr_reg_or_0_operand" "rU"))))]
497169689Skan  ""
498169689Skan  "pack2.sss %0 = %r1, %r2"
499169689Skan  [(set_attr "itanium_class" "mmshf")])
500169689Skan
501169689Skan(define_insn "*pack2_uss"
502169689Skan  [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
503169689Skan	(vec_concat:V8QI
504169689Skan	  (us_truncate:V4QI
505169689Skan	    (match_operand:V4HI 1 "gr_reg_or_0_operand" "rU"))
506169689Skan	  (us_truncate:V4QI
507169689Skan	    (match_operand:V4HI 2 "gr_reg_or_0_operand" "rU"))))]
508169689Skan  ""
509169689Skan  "pack2.uss %0 = %r1, %r2"
510169689Skan  [(set_attr "itanium_class" "mmshf")])
511169689Skan
512169689Skan(define_insn "pack4_sss"
513169689Skan  [(set (match_operand:V4HI 0 "gr_register_operand" "=r")
514169689Skan	(vec_concat:V4HI
515169689Skan	  (ss_truncate:V2HI
516169689Skan	    (match_operand:V2SI 1 "gr_reg_or_0_operand" "rU"))
517169689Skan	  (ss_truncate:V2HI
518169689Skan	    (match_operand:V2SI 2 "gr_reg_or_0_operand" "rU"))))]
519169689Skan  ""
520169689Skan  "pack4.sss %0 = %r1, %r2"
521169689Skan  [(set_attr "itanium_class" "mmshf")])
522169689Skan
523169689Skan(define_insn "unpack1_l"
524169689Skan  [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
525169689Skan	(vec_select:V8QI
526169689Skan	  (vec_concat:V16QI
527169689Skan	    (match_operand:V8QI 1 "gr_reg_or_0_operand" "rU")
528169689Skan	    (match_operand:V8QI 2 "gr_reg_or_0_operand" "rU"))
529169689Skan	  (parallel [(const_int 0)
530169689Skan		     (const_int 1)
531169689Skan		     (const_int 2)
532169689Skan		     (const_int 3)
533169689Skan		     (const_int 8)
534169689Skan		     (const_int 9)
535169689Skan		     (const_int 10)
536169689Skan		     (const_int 11)])))]
537169689Skan  ""
538169689Skan  "unpack1.l %0 = %r2, %r1"
539169689Skan  [(set_attr "itanium_class" "mmshf")])
540169689Skan
541169689Skan(define_insn "unpack1_h"
542169689Skan  [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
543169689Skan	(vec_select:V8QI
544169689Skan	  (vec_concat:V16QI
545169689Skan	    (match_operand:V8QI 1 "gr_reg_or_0_operand" "rU")
546169689Skan	    (match_operand:V8QI 2 "gr_reg_or_0_operand" "rU"))
547169689Skan	  (parallel [(const_int 4)
548169689Skan		     (const_int 5)
549169689Skan		     (const_int 6)
550169689Skan		     (const_int 7)
551169689Skan		     (const_int 12)
552169689Skan		     (const_int 13)
553169689Skan		     (const_int 14)
554169689Skan		     (const_int 15)])))]
555169689Skan  ""
556169689Skan  "unpack1.h %0 = %r2, %r1"
557169689Skan  [(set_attr "itanium_class" "mmshf")])
558169689Skan
559169689Skan(define_insn "mix1_r"
560169689Skan  [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
561169689Skan	(vec_select:V8QI
562169689Skan	  (vec_concat:V16QI
563169689Skan	    (match_operand:V8QI 1 "gr_reg_or_0_operand" "rU")
564169689Skan	    (match_operand:V8QI 2 "gr_reg_or_0_operand" "rU"))
565169689Skan	  (parallel [(const_int 0)
566169689Skan		     (const_int 8)
567169689Skan		     (const_int 2)
568169689Skan		     (const_int 10)
569169689Skan		     (const_int 4)
570169689Skan		     (const_int 12)
571169689Skan		     (const_int 6)
572169689Skan		     (const_int 14)])))]
573169689Skan  ""
574169689Skan  "mix1.r %0 = %r2, %r1"
575169689Skan  [(set_attr "itanium_class" "mmshf")])
576169689Skan
577169689Skan(define_insn "mix1_l"
578169689Skan  [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
579169689Skan	(vec_select:V8QI
580169689Skan	  (vec_concat:V16QI
581169689Skan	    (match_operand:V8QI 1 "gr_reg_or_0_operand" "rU")
582169689Skan	    (match_operand:V8QI 2 "gr_reg_or_0_operand" "rU"))
583169689Skan	  (parallel [(const_int 1)
584169689Skan		     (const_int 9)
585169689Skan		     (const_int 3)
586169689Skan		     (const_int 11)
587169689Skan		     (const_int 5)
588169689Skan		     (const_int 13)
589169689Skan		     (const_int 7)
590169689Skan		     (const_int 15)])))]
591169689Skan  ""
592169689Skan  "mix1.l %0 = %r2, %r1"
593169689Skan  [(set_attr "itanium_class" "mmshf")])
594169689Skan
595169689Skan(define_insn "*mux1_rev"
596169689Skan  [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
597169689Skan	(vec_select:V8QI
598169689Skan	  (match_operand:V8QI 1 "gr_register_operand" "r")
599169689Skan	  (parallel [(const_int 7)
600169689Skan		     (const_int 6)
601169689Skan		     (const_int 5)
602169689Skan		     (const_int 4)
603169689Skan		     (const_int 3)
604169689Skan		     (const_int 2)
605169689Skan		     (const_int 1)
606169689Skan		     (const_int 0)])))]
607169689Skan  ""
608169689Skan  "mux1 %0 = %1, @rev"
609169689Skan  [(set_attr "itanium_class" "mmshf")])
610169689Skan
611169689Skan(define_insn "*mux1_mix"
612169689Skan  [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
613169689Skan	(vec_select:V8QI
614169689Skan	  (match_operand:V8QI 1 "gr_register_operand" "r")
615169689Skan	  (parallel [(const_int 0)
616169689Skan		     (const_int 4)
617169689Skan		     (const_int 2)
618169689Skan		     (const_int 6)
619169689Skan		     (const_int 1)
620169689Skan		     (const_int 5)
621169689Skan		     (const_int 3)
622169689Skan		     (const_int 7)])))]
623169689Skan  ""
624169689Skan  "mux1 %0 = %1, @mix"
625169689Skan  [(set_attr "itanium_class" "mmshf")])
626169689Skan
627169689Skan(define_insn "*mux1_shuf"
628169689Skan  [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
629169689Skan	(vec_select:V8QI
630169689Skan	  (match_operand:V8QI 1 "gr_register_operand" "r")
631169689Skan	  (parallel [(const_int 0)
632169689Skan		     (const_int 4)
633169689Skan		     (const_int 1)
634169689Skan		     (const_int 5)
635169689Skan		     (const_int 2)
636169689Skan		     (const_int 6)
637169689Skan		     (const_int 3)
638169689Skan		     (const_int 7)])))]
639169689Skan  ""
640169689Skan  "mux1 %0 = %1, @shuf"
641169689Skan  [(set_attr "itanium_class" "mmshf")])
642169689Skan
643169689Skan(define_insn "*mux1_alt"
644169689Skan  [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
645169689Skan	(vec_select:V8QI
646169689Skan	  (match_operand:V8QI 1 "gr_register_operand" "r")
647169689Skan	  (parallel [(const_int 0)
648169689Skan		     (const_int 2)
649169689Skan		     (const_int 4)
650169689Skan		     (const_int 6)
651169689Skan		     (const_int 1)
652169689Skan		     (const_int 3)
653169689Skan		     (const_int 5)
654169689Skan		     (const_int 7)])))]
655169689Skan  ""
656169689Skan  "mux1 %0 = %1, @alt"
657169689Skan  [(set_attr "itanium_class" "mmshf")])
658169689Skan
659169689Skan(define_insn "*mux1_brcst_v8qi"
660169689Skan  [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
661169689Skan	(vec_select:V8QI
662169689Skan	  (match_operand:V8QI 1 "gr_register_operand" "r")
663169689Skan	  (parallel [(const_int 0)
664169689Skan		     (const_int 0)
665169689Skan		     (const_int 0)
666169689Skan		     (const_int 0)
667169689Skan		     (const_int 0)
668169689Skan		     (const_int 0)
669169689Skan		     (const_int 0)
670169689Skan		     (const_int 0)])))]
671169689Skan  ""
672169689Skan  "mux1 %0 = %1, @brcst"
673169689Skan  [(set_attr "itanium_class" "mmshf")])
674169689Skan
675169689Skan(define_insn "*mux1_brcst_qi"
676169689Skan  [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
677169689Skan	(vec_duplicate:V8QI
678169689Skan	  (match_operand:QI 1 "gr_register_operand" "r")))]
679169689Skan  ""
680169689Skan  "mux1 %0 = %1, @brcst"
681169689Skan  [(set_attr "itanium_class" "mmshf")])
682169689Skan
683169689Skan(define_insn "unpack2_l"
684169689Skan  [(set (match_operand:V4HI 0 "gr_register_operand" "=r")
685169689Skan	(vec_select:V4HI
686169689Skan	  (vec_concat:V8HI
687169689Skan	    (match_operand:V4HI 1 "gr_reg_or_0_operand" "rU")
688169689Skan	    (match_operand:V4HI 2 "gr_reg_or_0_operand" "rU"))
689169689Skan	  (parallel [(const_int 0)
690169689Skan		     (const_int 4)
691169689Skan		     (const_int 1)
692169689Skan		     (const_int 5)])))]
693169689Skan  ""
694169689Skan  "unpack2.l %0 = %r2, %r1"
695169689Skan  [(set_attr "itanium_class" "mmshf")])
696169689Skan
697169689Skan(define_insn "unpack2_h"
698169689Skan  [(set (match_operand:V4HI 0 "gr_register_operand" "=r")
699169689Skan	(vec_select:V4HI
700169689Skan	  (vec_concat:V8HI
701169689Skan	    (match_operand:V4HI 1 "gr_reg_or_0_operand" "rU")
702169689Skan	    (match_operand:V4HI 2 "gr_reg_or_0_operand" "rU"))
703169689Skan	  (parallel [(const_int 2)
704169689Skan		     (const_int 6)
705169689Skan		     (const_int 3)
706169689Skan		     (const_int 7)])))]
707169689Skan  ""
708169689Skan  "unpack2.h %0 = %r2, %r1"
709169689Skan  [(set_attr "itanium_class" "mmshf")])
710169689Skan
711169689Skan(define_insn "*mix2_r"
712169689Skan  [(set (match_operand:V4HI 0 "gr_register_operand" "=r")
713169689Skan	(vec_select:V4HI
714169689Skan	  (vec_concat:V8HI
715169689Skan	    (match_operand:V4HI 1 "gr_reg_or_0_operand" "rU")
716169689Skan	    (match_operand:V4HI 2 "gr_reg_or_0_operand" "rU"))
717169689Skan	  (parallel [(const_int 0)
718169689Skan		     (const_int 4)
719169689Skan		     (const_int 2)
720169689Skan		     (const_int 6)])))]
721169689Skan  ""
722169689Skan  "mix2.r %0 = %r2, %r1"
723169689Skan  [(set_attr "itanium_class" "mmshf")])
724169689Skan
725169689Skan(define_insn "*mix2_l"
726169689Skan  [(set (match_operand:V4HI 0 "gr_register_operand" "=r")
727169689Skan	(vec_select:V4HI
728169689Skan	  (vec_concat:V8HI
729169689Skan	    (match_operand:V4HI 1 "gr_reg_or_0_operand" "rU")
730169689Skan	    (match_operand:V4HI 2 "gr_reg_or_0_operand" "rU"))
731169689Skan	  (parallel [(const_int 1)
732169689Skan		     (const_int 5)
733169689Skan		     (const_int 3)
734169689Skan		     (const_int 7)])))]
735169689Skan  ""
736169689Skan  "mix2.l %0 = %r2, %r1"
737169689Skan  [(set_attr "itanium_class" "mmshf")])
738169689Skan
739169689Skan(define_insn "*mux2"
740169689Skan  [(set (match_operand:V4HI 0 "gr_register_operand" "=r")
741169689Skan	(vec_select:V4HI
742169689Skan	  (match_operand:V4HI 1 "gr_register_operand" "r")
743169689Skan	  (parallel [(match_operand 2 "const_int_2bit_operand" "")
744169689Skan		     (match_operand 3 "const_int_2bit_operand" "")
745169689Skan		     (match_operand 4 "const_int_2bit_operand" "")
746169689Skan		     (match_operand 5 "const_int_2bit_operand" "")])))]
747169689Skan  ""
748169689Skan{
749169689Skan  int mask;
750169689Skan  mask  = INTVAL (operands[2]);
751169689Skan  mask |= INTVAL (operands[3]) << 2;
752169689Skan  mask |= INTVAL (operands[4]) << 4;
753169689Skan  mask |= INTVAL (operands[5]) << 6;
754169689Skan  operands[2] = GEN_INT (mask);
755169689Skan  return "%,mux2 %0 = %1, %2";
756169689Skan}
757169689Skan  [(set_attr "itanium_class" "mmshf")])
758169689Skan
759169689Skan(define_insn "*mux2_brcst_hi"
760169689Skan  [(set (match_operand:V4HI 0 "gr_register_operand" "=r")
761169689Skan	(vec_duplicate:V4HI
762169689Skan	  (match_operand:HI 1 "gr_register_operand" "r")))]
763169689Skan  ""
764169689Skan  "mux2 %0 = %1, 0"
765169689Skan  [(set_attr "itanium_class" "mmshf")])
766169689Skan
767169689Skan;; Note that mix4.r performs the exact same operation.
768169689Skan(define_insn "*unpack4_l"
769169689Skan  [(set (match_operand:V2SI 0 "gr_register_operand" "=r")
770169689Skan	(vec_select:V2SI
771169689Skan	  (vec_concat:V4SI
772169689Skan	    (match_operand:V2SI 1 "gr_reg_or_0_operand" "rU")
773169689Skan	    (match_operand:V2SI 2 "gr_reg_or_0_operand" "rU"))
774169689Skan	  (parallel [(const_int 0)
775169689Skan		     (const_int 2)])))]
776169689Skan  ""
777169689Skan  "unpack4.l %0 = %r2, %r1"
778169689Skan  [(set_attr "itanium_class" "mmshf")])
779169689Skan
780169689Skan;; Note that mix4.l performs the exact same operation.
781169689Skan(define_insn "*unpack4_h"
782169689Skan  [(set (match_operand:V2SI 0 "gr_register_operand" "=r")
783169689Skan	(vec_select:V2SI
784169689Skan	  (vec_concat:V4SI
785169689Skan	    (match_operand:V2SI 1 "gr_reg_or_0_operand" "rU")
786169689Skan	    (match_operand:V2SI 2 "gr_reg_or_0_operand" "rU"))
787169689Skan	  (parallel [(const_int 1)
788169689Skan		     (const_int 3)])))]
789169689Skan  ""
790169689Skan  "unpack4.h %0 = %r2, %r1"
791169689Skan  [(set_attr "itanium_class" "mmshf")])
792169689Skan
793169689Skan(define_expand "vec_initv2si"
794169689Skan  [(match_operand:V2SI 0 "gr_register_operand" "")
795169689Skan   (match_operand 1 "" "")]
796169689Skan  ""
797169689Skan{
798169689Skan  rtx op1 = XVECEXP (operands[1], 0, 0);
799169689Skan  rtx op2 = XVECEXP (operands[1], 0, 1);
800169689Skan  rtx x;
801169689Skan
802169689Skan  if (GET_CODE (op1) == CONST_INT && GET_CODE (op2) == CONST_INT)
803169689Skan    {
804169689Skan      rtvec v = rtvec_alloc (2);
805169689Skan      RTVEC_ELT (v, 0) = TARGET_BIG_ENDIAN ? op2 : op1;
806169689Skan      RTVEC_ELT (v, 1) = TARGET_BIG_ENDIAN ? op1 : op2;;
807169689Skan      x = gen_rtx_CONST_VECTOR (V2SImode, v);
808169689Skan      emit_move_insn (operands[0], x);
809169689Skan      DONE;
810169689Skan    }
811169689Skan
812169689Skan  if (!gr_reg_or_0_operand (op1, SImode))
813169689Skan    op1 = force_reg (SImode, op1);
814169689Skan  if (!gr_reg_or_0_operand (op2, SImode))
815169689Skan    op2 = force_reg (SImode, op2);
816169689Skan
817169689Skan  if (TARGET_BIG_ENDIAN)
818169689Skan    x = gen_rtx_VEC_CONCAT (V2SImode, op2, op1);
819169689Skan  else
820169689Skan    x = gen_rtx_VEC_CONCAT (V2SImode, op1, op2);
821169689Skan  emit_insn (gen_rtx_SET (VOIDmode, operands[0], x));
822169689Skan  DONE;
823169689Skan})
824169689Skan
825169689Skan(define_insn "*vecinit_v2si"
826169689Skan  [(set (match_operand:V2SI 0 "gr_register_operand" "=r")
827169689Skan	(vec_concat:V2SI
828169689Skan	  (match_operand:SI 1 "gr_reg_or_0_operand" "rO")
829169689Skan	  (match_operand:SI 2 "gr_reg_or_0_operand" "rO")))]
830169689Skan  ""
831169689Skan  "unpack4.l %0 = %r2, %r1"
832169689Skan  [(set_attr "itanium_class" "mmshf")])
833169689Skan
834169689Skan;; Missing operations
835169689Skan;; padd.uus
836169689Skan;; pavg
837169689Skan;; pavgsub
838169689Skan;; pmpyshr, general form
839169689Skan;; psad
840169689Skan;; pshladd
841169689Skan;; pshradd
842169689Skan;; psub.uus
843169689Skan
844169689Skan;; Floating point vector operations
845169689Skan
846169689Skan(define_expand "movv2sf"
847169689Skan  [(set (match_operand:V2SF 0 "general_operand" "")
848169689Skan        (match_operand:V2SF 1 "general_operand" ""))]
849169689Skan  ""
850169689Skan{
851169689Skan  rtx op1 = ia64_expand_move (operands[0], operands[1]);
852169689Skan  if (!op1)
853169689Skan    DONE;
854169689Skan  operands[1] = op1;
855169689Skan})
856169689Skan
857169689Skan(define_insn "*movv2sf_internal"
858169689Skan  [(set (match_operand:V2SF 0 "destination_operand"
859169689Skan					"=f,f,f,Q,*r ,*r,*r,*r,m ,f ,*r")
860169689Skan	(match_operand:V2SF 1 "move_operand"
861169689Skan					"fU,Y,Q,f,U*r,W ,i ,m ,*r,*r,f "))]
862169689Skan  "ia64_move_ok (operands[0], operands[1])"
863169689Skan{
864169689Skan  static const char * const alt[] = {
865169689Skan    "%,mov %0 = %F1",
866169689Skan    "%,fpack %0 = %F2, %F1",
867169689Skan    "%,ldf8 %0 = %1%P1",
868169689Skan    "%,stf8 %0 = %1%P0",
869169689Skan    "%,mov %0 = %r1",
870169689Skan    "%,addl %0 = %v1, r0",
871169689Skan    "%,movl %0 = %v1",
872169689Skan    "%,ld8%O1 %0 = %1%P1",
873169689Skan    "%,st8%Q0 %0 = %r1%P0",
874169689Skan    "%,setf.sig %0 = %1",
875169689Skan    "%,getf.sig %0 = %1"
876169689Skan  };
877169689Skan
878169689Skan  if (which_alternative == 1)
879169689Skan    {
880169689Skan      operands[2] = XVECEXP (operands[1], 0, 1);
881169689Skan      operands[1] = XVECEXP (operands[1], 0, 0);
882169689Skan    }
883169689Skan
884169689Skan  return alt[which_alternative];
885169689Skan}
886169689Skan  [(set_attr "itanium_class" "fmisc,fmisc,fld,stf,ialu,ialu,long_i,ld,st,tofr,frfr")])
887169689Skan
888169689Skan(define_insn "absv2sf2"
889169689Skan  [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
890169689Skan	(abs:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")))]
891169689Skan  ""
892169689Skan  "fpabs %0 = %1"
893169689Skan  [(set_attr "itanium_class" "fmisc")])
894169689Skan
895169689Skan(define_insn "negv2sf2"
896169689Skan  [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
897169689Skan	(neg:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")))]
898169689Skan  ""
899169689Skan  "fpneg %0 = %1"
900169689Skan  [(set_attr "itanium_class" "fmisc")])
901169689Skan
902169689Skan(define_insn "*negabsv2sf2"
903169689Skan  [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
904169689Skan	(neg:V2SF
905169689Skan	  (abs:V2SF (match_operand:V2SF 1 "fr_register_operand" "f"))))]
906169689Skan  ""
907169689Skan  "fpnegabs %0 = %1"
908169689Skan  [(set_attr "itanium_class" "fmisc")])
909169689Skan
910169689Skan;; In order to convince combine to merge plus and mult to a useful fpma,
911169689Skan;; we need a couple of extra patterns.
912169689Skan(define_expand "addv2sf3"
913169689Skan  [(parallel
914169689Skan    [(set (match_operand:V2SF 0 "fr_register_operand" "")
915169689Skan	  (plus:V2SF (match_operand:V2SF 1 "fr_register_operand" "")
916169689Skan		     (match_operand:V2SF 2 "fr_register_operand" "")))
917169689Skan     (use (match_dup 3))])]
918169689Skan  ""
919169689Skan{
920169689Skan  rtvec v = gen_rtvec (2, CONST1_RTX (SFmode), CONST1_RTX (SFmode));
921169689Skan  operands[3] = force_reg (V2SFmode, gen_rtx_CONST_VECTOR (V2SFmode, v));
922169689Skan})
923169689Skan
924169689Skan;; The split condition here could be combine_completed, if we had such.
925169689Skan(define_insn_and_split "*addv2sf3_1"
926169689Skan  [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
927169689Skan	(plus:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
928169689Skan		   (match_operand:V2SF 2 "fr_register_operand" "f")))
929169689Skan   (use (match_operand:V2SF 3 "fr_register_operand" "f"))]
930169689Skan  ""
931169689Skan  "#"
932169689Skan  "reload_completed"
933169689Skan  [(set (match_dup 0)
934169689Skan	(plus:V2SF
935169689Skan	  (mult:V2SF (match_dup 1) (match_dup 3))
936169689Skan	  (match_dup 2)))]
937169689Skan  "")
938169689Skan
939169689Skan(define_insn_and_split "*addv2sf3_2"
940169689Skan  [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
941169689Skan	(plus:V2SF
942169689Skan	  (mult:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
943169689Skan		     (match_operand:V2SF 2 "fr_register_operand" "f"))
944169689Skan	  (match_operand:V2SF 3 "fr_register_operand" "f")))
945169689Skan    (use (match_operand:V2SF 4 "" "X"))]
946169689Skan  ""
947169689Skan  "#"
948169689Skan  ""
949169689Skan  [(set (match_dup 0)
950169689Skan	(plus:V2SF
951169689Skan	  (mult:V2SF (match_dup 1) (match_dup 2))
952169689Skan	  (match_dup 3)))]
953169689Skan  "")
954169689Skan
955169689Skan;; In order to convince combine to merge minus and mult to a useful fpms,
956169689Skan;; we need a couple of extra patterns.
957169689Skan(define_expand "subv2sf3"
958169689Skan  [(parallel
959169689Skan    [(set (match_operand:V2SF 0 "fr_register_operand" "")
960169689Skan	  (minus:V2SF (match_operand:V2SF 1 "fr_register_operand" "")
961169689Skan		      (match_operand:V2SF 2 "fr_register_operand" "")))
962169689Skan     (use (match_dup 3))])]
963169689Skan  ""
964169689Skan{
965169689Skan  rtvec v = gen_rtvec (2, CONST1_RTX (SFmode), CONST1_RTX (SFmode));
966169689Skan  operands[3] = force_reg (V2SFmode, gen_rtx_CONST_VECTOR (V2SFmode, v));
967169689Skan})
968169689Skan
969169689Skan;; The split condition here could be combine_completed, if we had such.
970169689Skan(define_insn_and_split "*subv2sf3_1"
971169689Skan  [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
972169689Skan	(minus:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
973169689Skan		    (match_operand:V2SF 2 "fr_register_operand" "f")))
974169689Skan   (use (match_operand:V2SF 3 "fr_register_operand" "f"))]
975169689Skan  ""
976169689Skan  "#"
977169689Skan  "reload_completed"
978169689Skan  [(set (match_dup 0)
979169689Skan	(minus:V2SF
980169689Skan	  (mult:V2SF (match_dup 1) (match_dup 3))
981169689Skan	  (match_dup 2)))]
982169689Skan  "")
983169689Skan
984169689Skan(define_insn_and_split "*subv2sf3_2"
985169689Skan  [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
986169689Skan	(minus:V2SF
987169689Skan	  (mult:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
988169689Skan		     (match_operand:V2SF 2 "fr_register_operand" "f"))
989169689Skan	  (match_operand:V2SF 3 "fr_register_operand" "f")))
990169689Skan    (use (match_operand:V2SF 4 "" "X"))]
991169689Skan  ""
992169689Skan  "#"
993169689Skan  ""
994169689Skan  [(set (match_dup 0)
995169689Skan	(minus:V2SF
996169689Skan	  (mult:V2SF (match_dup 1) (match_dup 2))
997169689Skan	  (match_dup 3)))]
998169689Skan  "")
999169689Skan
1000169689Skan(define_insn "mulv2sf3"
1001169689Skan  [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
1002169689Skan	(mult:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
1003169689Skan		   (match_operand:V2SF 2 "fr_register_operand" "f")))]
1004169689Skan  ""
1005169689Skan  "fpmpy %0 = %1, %2"
1006169689Skan  [(set_attr "itanium_class" "fmac")])
1007169689Skan
1008169689Skan(define_insn "*fpma"
1009169689Skan  [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
1010169689Skan	(plus:V2SF
1011169689Skan	  (mult:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
1012169689Skan		     (match_operand:V2SF 2 "fr_register_operand" "f"))
1013169689Skan	  (match_operand:V2SF 3 "fr_register_operand" "f")))]
1014169689Skan  ""
1015169689Skan  "fpma %0 = %1, %2, %3"
1016169689Skan  [(set_attr "itanium_class" "fmac")])
1017169689Skan
1018169689Skan(define_insn "*fpms"
1019169689Skan  [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
1020169689Skan	(minus:V2SF
1021169689Skan	  (mult:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
1022169689Skan		     (match_operand:V2SF 2 "fr_register_operand" "f"))
1023169689Skan	  (match_operand:V2SF 3 "fr_register_operand" "f")))]
1024169689Skan  ""
1025169689Skan  "fpms %0 = %1, %2, %3"
1026169689Skan  [(set_attr "itanium_class" "fmac")])
1027169689Skan
1028169689Skan(define_insn "*fpnmpy"
1029169689Skan  [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
1030169689Skan	(neg:V2SF
1031169689Skan	  (mult:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
1032169689Skan		     (match_operand:V2SF 2 "fr_register_operand" "f"))))]
1033169689Skan  ""
1034169689Skan  "fpnmpy %0 = %1, %2"
1035169689Skan  [(set_attr "itanium_class" "fmac")])
1036169689Skan
1037169689Skan(define_insn "*fpnma"
1038169689Skan  [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
1039169689Skan	(plus:V2SF
1040169689Skan	  (neg:V2SF
1041169689Skan	    (mult:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
1042169689Skan		       (match_operand:V2SF 2 "fr_register_operand" "f")))
1043169689Skan	  (match_operand:V2SF 3 "fr_register_operand" "f")))]
1044169689Skan  ""
1045169689Skan  "fpnma %0 = %1, %2, %3"
1046169689Skan  [(set_attr "itanium_class" "fmac")])
1047169689Skan
1048169689Skan(define_insn "smaxv2sf3"
1049169689Skan  [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
1050169689Skan	(smax:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
1051169689Skan		   (match_operand:V2SF 2 "fr_register_operand" "f")))]
1052169689Skan  ""
1053169689Skan  "fpmax %0 = %1, %2"
1054169689Skan  [(set_attr "itanium_class" "fmisc")])
1055169689Skan
1056169689Skan(define_insn "sminv2sf3"
1057169689Skan  [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
1058169689Skan	(smin:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
1059169689Skan		   (match_operand:V2SF 2 "fr_register_operand" "f")))]
1060169689Skan  ""
1061169689Skan  "fpmin %0 = %1, %2"
1062169689Skan  [(set_attr "itanium_class" "fmisc")])
1063169689Skan
1064169689Skan(define_expand "reduc_splus_v2sf"
1065169689Skan  [(match_operand:V2SF 0 "fr_register_operand" "")
1066169689Skan   (match_operand:V2SF 1 "fr_register_operand" "")]
1067169689Skan  ""
1068169689Skan{
1069169689Skan  rtx tmp = gen_reg_rtx (V2SFmode);
1070169689Skan  emit_insn (gen_fswap (tmp, operands[1], CONST0_RTX (V2SFmode)));
1071169689Skan  emit_insn (gen_addv2sf3 (operands[0], operands[1], tmp));
1072169689Skan  DONE;
1073169689Skan})
1074169689Skan
1075169689Skan(define_expand "reduc_smax_v2sf"
1076169689Skan  [(match_operand:V2SF 0 "fr_register_operand" "")
1077169689Skan   (match_operand:V2SF 1 "fr_register_operand" "")]
1078169689Skan  ""
1079169689Skan{
1080169689Skan  rtx tmp = gen_reg_rtx (V2SFmode);
1081169689Skan  emit_insn (gen_fswap (tmp, operands[1], CONST0_RTX (V2SFmode)));
1082169689Skan  emit_insn (gen_smaxv2sf3 (operands[0], operands[1], tmp));
1083169689Skan  DONE;
1084169689Skan})
1085169689Skan
1086169689Skan(define_expand "reduc_smin_v2sf"
1087169689Skan  [(match_operand:V2SF 0 "fr_register_operand" "")
1088169689Skan   (match_operand:V2SF 1 "fr_register_operand" "")]
1089169689Skan  ""
1090169689Skan{
1091169689Skan  rtx tmp = gen_reg_rtx (V2SFmode);
1092169689Skan  emit_insn (gen_fswap (tmp, operands[1], CONST0_RTX (V2SFmode)));
1093169689Skan  emit_insn (gen_sminv2sf3 (operands[0], operands[1], tmp));
1094169689Skan  DONE;
1095169689Skan})
1096169689Skan
1097169689Skan(define_expand "vcondv2sf"
1098169689Skan  [(set (match_operand:V2SF 0 "fr_register_operand" "")
1099169689Skan	(if_then_else:V2SF
1100169689Skan	  (match_operator 3 "" 
1101169689Skan	    [(match_operand:V2SF 4 "fr_reg_or_0_operand" "")
1102169689Skan	     (match_operand:V2SF 5 "fr_reg_or_0_operand" "")])
1103169689Skan	  (match_operand:V2SF 1 "fr_reg_or_0_operand" "")
1104169689Skan	  (match_operand:V2SF 2 "fr_reg_or_0_operand" "")))]
1105169689Skan  ""
1106169689Skan{
1107169689Skan  rtx x, cmp;
1108169689Skan
1109169689Skan  cmp = gen_reg_rtx (V2SFmode);
1110169689Skan  PUT_MODE (operands[3], V2SFmode);
1111169689Skan  emit_insn (gen_rtx_SET (VOIDmode, cmp, operands[3]));
1112169689Skan
1113169689Skan  x = gen_rtx_IF_THEN_ELSE (V2SFmode, cmp, operands[1], operands[2]);
1114169689Skan  emit_insn (gen_rtx_SET (VOIDmode, operands[0], x));
1115169689Skan  DONE;
1116169689Skan})
1117169689Skan
1118169689Skan(define_insn "*fpcmp"
1119169689Skan  [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
1120169689Skan	(match_operator:V2SF 3 "comparison_operator"
1121169689Skan	  [(match_operand:V2SF 1 "fr_reg_or_0_operand" "fU")
1122169689Skan	   (match_operand:V2SF 2 "fr_reg_or_0_operand" "fU")]))]
1123169689Skan  ""
1124169689Skan  "fpcmp.%D3 %0 = %F1, %F2"
1125169689Skan  [(set_attr "itanium_class" "fmisc")])
1126169689Skan
1127169689Skan(define_insn "*fselect"
1128169689Skan  [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
1129169689Skan	(if_then_else:V2SF
1130169689Skan	  (match_operand:V2SF 1 "fr_register_operand" "f")
1131169689Skan	  (match_operand:V2SF 2 "fr_reg_or_0_operand" "fU")
1132169689Skan	  (match_operand:V2SF 3 "fr_reg_or_0_operand" "fU")))]
1133169689Skan  ""
1134169689Skan  "fselect %0 = %F2, %F3, %1"
1135169689Skan  [(set_attr "itanium_class" "fmisc")])
1136169689Skan
1137169689Skan(define_expand "vec_initv2sf"
1138169689Skan  [(match_operand:V2SF 0 "fr_register_operand" "")
1139169689Skan   (match_operand 1 "" "")]
1140169689Skan  ""
1141169689Skan{
1142169689Skan  rtx op1 = XVECEXP (operands[1], 0, 0);
1143169689Skan  rtx op2 = XVECEXP (operands[1], 0, 1);
1144169689Skan  rtx x;
1145169689Skan
1146169689Skan  if (GET_CODE (op1) == CONST_DOUBLE && GET_CODE (op2) == CONST_DOUBLE)
1147169689Skan    {
1148169689Skan      x = gen_rtx_CONST_VECTOR (V2SFmode, XVEC (operands[1], 0));
1149169689Skan      emit_move_insn (operands[0], x);
1150169689Skan      DONE;
1151169689Skan    }
1152169689Skan
1153169689Skan  if (!fr_reg_or_fp01_operand (op1, SFmode))
1154169689Skan    op1 = force_reg (SFmode, op1);
1155169689Skan  if (!fr_reg_or_fp01_operand (op2, SFmode))
1156169689Skan    op2 = force_reg (SFmode, op2);
1157169689Skan
1158169689Skan  if (TARGET_BIG_ENDIAN)
1159169689Skan    emit_insn (gen_fpack (operands[0], op2, op1));
1160169689Skan  else
1161169689Skan    emit_insn (gen_fpack (operands[0], op1, op2));
1162169689Skan  DONE;
1163169689Skan})
1164169689Skan
1165169689Skan(define_insn "fpack"
1166169689Skan  [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
1167169689Skan	(vec_concat:V2SF
1168169689Skan	  (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")
1169169689Skan	  (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
1170169689Skan  ""
1171169689Skan  "fpack %0 = %F2, %F1"
1172169689Skan  [(set_attr "itanium_class" "fmisc")])
1173169689Skan
1174169689Skan(define_insn "fswap"
1175169689Skan  [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
1176169689Skan	(vec_select:V2SF
1177169689Skan	  (vec_concat:V4SF
1178169689Skan	    (match_operand:V2SF 1 "fr_reg_or_0_operand" "fU")
1179169689Skan	    (match_operand:V2SF 2 "fr_reg_or_0_operand" "fU"))
1180169689Skan	  (parallel [(const_int 1) (const_int 2)])))]
1181169689Skan  ""
1182169689Skan  "fswap %0 = %F1, %F2"
1183169689Skan  [(set_attr "itanium_class" "fmisc")])
1184169689Skan
1185169689Skan(define_insn "*fmix_l"
1186169689Skan  [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
1187169689Skan	(vec_select:V2SF
1188169689Skan	  (vec_concat:V4SF
1189169689Skan	    (match_operand:V2SF 1 "fr_reg_or_0_operand" "fU")
1190169689Skan	    (match_operand:V2SF 2 "fr_reg_or_0_operand" "fU"))
1191169689Skan	  (parallel [(const_int 1) (const_int 3)])))]
1192169689Skan  ""
1193169689Skan  "fmix.l %0 = %F2, %F1"
1194169689Skan  [(set_attr "itanium_class" "fmisc")])
1195169689Skan
1196169689Skan(define_insn "fmix_r"
1197169689Skan  [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
1198169689Skan	(vec_select:V2SF
1199169689Skan	  (vec_concat:V4SF
1200169689Skan	    (match_operand:V2SF 1 "fr_reg_or_0_operand" "fU")
1201169689Skan	    (match_operand:V2SF 2 "fr_reg_or_0_operand" "fU"))
1202169689Skan	  (parallel [(const_int 0) (const_int 2)])))]
1203169689Skan  ""
1204169689Skan  "fmix.r %0 = %F2, %F1"
1205169689Skan  [(set_attr "itanium_class" "fmisc")])
1206169689Skan
1207169689Skan(define_insn "fmix_lr"
1208169689Skan  [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
1209169689Skan	(vec_select:V2SF
1210169689Skan	  (vec_concat:V4SF
1211169689Skan	    (match_operand:V2SF 1 "fr_reg_or_0_operand" "fU")
1212169689Skan	    (match_operand:V2SF 2 "fr_reg_or_0_operand" "fU"))
1213169689Skan	  (parallel [(const_int 0) (const_int 3)])))]
1214169689Skan  ""
1215169689Skan  "fmix.lr %0 = %F2, %F1"
1216169689Skan  [(set_attr "itanium_class" "fmisc")])
1217169689Skan
1218169689Skan(define_expand "vec_setv2sf"
1219169689Skan  [(match_operand:V2SF 0 "fr_register_operand" "")
1220169689Skan   (match_operand:SF 1 "fr_register_operand" "")
1221169689Skan   (match_operand 2 "const_int_operand" "")]
1222169689Skan  ""
1223169689Skan{
1224169689Skan  rtx tmp = gen_reg_rtx (V2SFmode);
1225169689Skan  emit_insn (gen_fpack (tmp, operands[1], CONST0_RTX (SFmode)));
1226169689Skan
1227169689Skan  switch (INTVAL (operands[2]))
1228169689Skan    {
1229169689Skan    case 0:
1230169689Skan      emit_insn (gen_fmix_lr (operands[0], tmp, operands[0]));
1231169689Skan      break;
1232169689Skan    case 1:
1233169689Skan      emit_insn (gen_fmix_r (operands[0], operands[0], tmp));
1234169689Skan      break;
1235169689Skan    default:
1236169689Skan      gcc_unreachable ();
1237169689Skan    }
1238169689Skan  DONE;
1239169689Skan})
1240169689Skan
1241169689Skan(define_insn_and_split "*vec_extractv2sf_0_le"
1242169689Skan  [(set (match_operand:SF 0 "nonimmediate_operand" "=r,f,m")
1243169689Skan	(unspec:SF [(match_operand:V2SF 1 "nonimmediate_operand" "rfm,rm,r")
1244169689Skan		    (const_int 0)]
1245169689Skan		   UNSPEC_VECT_EXTR))]
1246169689Skan  "!TARGET_BIG_ENDIAN"
1247169689Skan  "#"
1248169689Skan  "reload_completed"
1249169689Skan  [(set (match_dup 0) (match_dup 1))]
1250169689Skan{
1251169689Skan  if (REG_P (operands[1]) && FR_REGNO_P (REGNO (operands[1])))
1252169689Skan    operands[0] = gen_rtx_REG (V2SFmode, REGNO (operands[0]));
1253169689Skan  else if (MEM_P (operands[1]))
1254169689Skan    operands[1] = adjust_address (operands[1], SFmode, 0);
1255169689Skan  else
1256169689Skan    operands[1] = gen_rtx_REG (SFmode, REGNO (operands[1]));
1257169689Skan})
1258169689Skan
1259169689Skan(define_insn_and_split "*vec_extractv2sf_0_be"
1260169689Skan  [(set (match_operand:SF 0 "register_operand" "=r,f")
1261169689Skan	(unspec:SF [(match_operand:V2SF 1 "register_operand" "rf,r")
1262169689Skan		    (const_int 0)]
1263169689Skan		   UNSPEC_VECT_EXTR))]
1264169689Skan  "TARGET_BIG_ENDIAN"
1265169689Skan  "#"
1266169689Skan  "reload_completed"
1267169689Skan  [(set (match_dup 0) (match_dup 1))]
1268169689Skan{
1269169689Skan  if (REG_P (operands[1]) && FR_REGNO_P (REGNO (operands[1])))
1270169689Skan    operands[0] = gen_rtx_REG (V2SFmode, REGNO (operands[0]));
1271169689Skan  else
1272169689Skan    operands[1] = gen_rtx_REG (SFmode, REGNO (operands[1]));
1273169689Skan})
1274169689Skan
1275169689Skan(define_insn_and_split "*vec_extractv2sf_1"
1276169689Skan  [(set (match_operand:SF 0 "register_operand" "=r")
1277169689Skan	(unspec:SF [(match_operand:V2SF 1 "register_operand" "r")
1278169689Skan		    (const_int 1)]
1279169689Skan		   UNSPEC_VECT_EXTR))]
1280169689Skan  ""
1281169689Skan  "#"
1282169689Skan  "reload_completed"
1283169689Skan  [(const_int 0)]
1284169689Skan{
1285169689Skan  operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
1286169689Skan  operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));
1287169689Skan  if (TARGET_BIG_ENDIAN)
1288169689Skan    emit_move_insn (operands[0], operands[1]);
1289169689Skan  else
1290169689Skan    emit_insn (gen_lshrdi3 (operands[0], operands[1], GEN_INT (32)));
1291169689Skan  DONE;
1292169689Skan})
1293169689Skan
1294169689Skan(define_expand "vec_extractv2sf"
1295169689Skan  [(set (match_operand:SF 0 "register_operand" "")
1296169689Skan	(unspec:SF [(match_operand:V2SF 1 "register_operand" "")
1297169689Skan		    (match_operand:DI 2 "const_int_operand" "")]
1298169689Skan		   UNSPEC_VECT_EXTR))]
1299169689Skan  ""
1300169689Skan  "")
1301169689Skan
1302169689Skan;; Missing operations
1303169689Skan;; fprcpa
1304169689Skan;; fpsqrta
1305