OSDN Git Service

* config/ia64/ia64.c (TARGET_VECTOR_MODE_SUPPORTED_P): New.
[pf3gnuchains/gcc-fork.git] / gcc / config / ia64 / vect.md
1 ;; IA-64 machine description for vector operations.
2 ;; Copyright (C) 2004
3 ;;
4 ;; This file is part of GCC.
5 ;;
6 ;; GCC is free software; you can redistribute it and/or modify
7 ;; it under the terms of the GNU General Public License as published by
8 ;; the Free Software Foundation; either version 2, or (at your option)
9 ;; any later version.
10 ;;
11 ;; GCC is distributed in the hope that it will be useful,
12 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 ;; GNU General Public License for more details.
15 ;;
16 ;; You should have received a copy of the GNU General Public License
17 ;; along with GCC; see the file COPYING.  If not, write to
18 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
19 ;; Boston, MA 02111-1307, USA.
20
21
22 ;; Integer vector operations
23
24 (define_mode_macro VECINT [V8QI V4HI V2SI])
25 (define_mode_macro VECINT12 [V8QI V4HI])
26 (define_mode_macro VECINT24 [V4HI V2SI])
27 (define_mode_attr vecsize [(V8QI "1") (V4HI "2") (V2SI "4")])
28
29 (define_expand "mov<mode>"
30   [(set (match_operand:VECINT 0 "general_operand" "")
31         (match_operand:VECINT 1 "general_operand" ""))]
32   ""
33 {
34   rtx op1 = ia64_expand_move (operands[0], operands[1]);
35   if (!op1)
36     DONE;
37   operands[1] = op1;
38 })
39
40 (define_insn "*mov<mode>_internal"
41   [(set (match_operand:VECINT 0 "destination_operand"
42                                         "=r,r,r,r,m ,*f ,*f,Q ,r ,*f")
43         (match_operand:VECINT 1 "move_operand"
44                                         "rU,W,i,m,rU,U*f,Q ,*f,*f,r "))]
45   "ia64_move_ok (operands[0], operands[1])"
46   "@
47    mov %0 = %r1
48    addl %0 = %v1, r0
49    movl %0 = %v1
50    ld8%O1 %0 = %1%P1
51    st8%Q0 %0 = %r1%P0
52    mov %0 = %F1
53    ldf8 %0 = %1%P1
54    stf8 %0 = %1%P0
55    getf.sig %0 = %1
56    setf.sig %0 = %1"
57   [(set_attr "itanium_class" "ialu,ialu,long_i,ld,st,fmisc,fld,stf,frfr,tofr")])
58
59 (define_insn "one_cmpl<mode>2"
60   [(set (match_operand:VECINT 0 "gr_register_operand" "=r")
61         (not:VECINT (match_operand:VECINT 1 "gr_register_operand" "r")))]
62   ""
63   "andcm %0 = -1, %1"
64   [(set_attr "itanium_class" "ilog")])
65
66 (define_insn "and<mode>3"
67   [(set (match_operand:VECINT 0 "grfr_register_operand" "=r,*f")
68         (and:VECINT
69           (match_operand:VECINT 1 "grfr_register_operand" "r,*f")
70           (match_operand:VECINT 2 "grfr_reg_or_8bit_operand" "r,*f")))]
71   ""
72   "@
73    and %0 = %2, %1
74    fand %0 = %2, %1"
75   [(set_attr "itanium_class" "ilog,fmisc")])
76
77 (define_insn "*andnot<mode>"
78   [(set (match_operand:VECINT 0 "grfr_register_operand" "=r,*f")
79         (and:VECINT
80           (not:VECINT (match_operand:VECINT 1 "grfr_register_operand" "r,*f"))
81           (match_operand:VECINT 2 "grfr_reg_or_8bit_operand" "r,*f")))]
82   ""
83   "@
84    andcm %0 = %2, %1
85    fandcm %0 = %2, %1"
86   [(set_attr "itanium_class" "ilog,fmisc")])
87
88 (define_insn "ior<mode>3"
89   [(set (match_operand:VECINT 0 "grfr_register_operand" "=r,*f")
90         (ior:VECINT
91           (match_operand:VECINT 1 "grfr_register_operand" "r,*f")
92           (match_operand:VECINT 2 "grfr_reg_or_8bit_operand" "r,*f")))]
93   ""
94   "@
95    or %0 = %2, %1
96    for %0 = %2, %1"
97   [(set_attr "itanium_class" "ilog,fmisc")])
98
99 (define_insn "xor<mode>3"
100   [(set (match_operand:VECINT 0 "grfr_register_operand" "=r,*f")
101         (xor:VECINT
102           (match_operand:VECINT 1 "grfr_register_operand" "r,*f")
103           (match_operand:VECINT 2 "grfr_reg_or_8bit_operand" "r,*f")))]
104   ""
105   "@
106    xor %0 = %2, %1
107    fxor %0 = %2, %1"
108   [(set_attr "itanium_class" "ilog,fmisc")])
109
110 (define_insn "neg<mode>2"
111   [(set (match_operand:VECINT 0 "gr_register_operand" "=r")
112         (neg:VECINT (match_operand:VECINT 1 "gr_register_operand" "r")))]
113   ""
114   "psub<vecsize> %0 = r0, %1"
115   [(set_attr "itanium_class" "mmalua")])
116
117 (define_insn "add<mode>3"
118   [(set (match_operand:VECINT 0 "gr_register_operand" "=r")
119         (plus:VECINT (match_operand:VECINT 1 "gr_register_operand" "r")
120                      (match_operand:VECINT 2 "gr_register_operand" "r")))]
121   ""
122   "padd<vecsize> %0 = %1, %2"
123   [(set_attr "itanium_class" "mmalua")])
124
125 (define_insn "*ssadd<mode>3"
126   [(set (match_operand:VECINT12 0 "gr_register_operand" "=r")
127         (ss_plus:VECINT12
128           (match_operand:VECINT12 1 "gr_register_operand" "r")
129           (match_operand:VECINT12 2 "gr_register_operand" "r")))]
130   ""
131   "padd<vecsize>.sss %0 = %1, %2"
132   [(set_attr "itanium_class" "mmalua")])
133
134 (define_insn "*usadd<mode>3"
135   [(set (match_operand:VECINT12 0 "gr_register_operand" "=r")
136         (us_plus:VECINT12
137           (match_operand:VECINT12 1 "gr_register_operand" "r")
138           (match_operand:VECINT12 2 "gr_register_operand" "r")))]
139   ""
140   "padd<vecsize>.uuu %0 = %1, %2"
141   [(set_attr "itanium_class" "mmalua")])
142
143 (define_insn "sub<mode>3"
144   [(set (match_operand:VECINT 0 "gr_register_operand" "=r")
145         (minus:VECINT (match_operand:VECINT 1 "gr_register_operand" "r")
146                       (match_operand:VECINT 2 "gr_register_operand" "r")))]
147   ""
148   "psub<vecsize> %0 = %1, %2"
149   [(set_attr "itanium_class" "mmalua")])
150
151 (define_insn "*sssub<mode>3"
152   [(set (match_operand:VECINT12 0 "gr_register_operand" "=r")
153         (ss_minus:VECINT12
154           (match_operand:VECINT12 1 "gr_register_operand" "r")
155           (match_operand:VECINT12 2 "gr_register_operand" "r")))]
156   ""
157   "psub<vecsize>.sss %0 = %1, %2"
158   [(set_attr "itanium_class" "mmalua")])
159
160 (define_insn "*ussub<mode>3"
161   [(set (match_operand:VECINT12 0 "gr_register_operand" "=r")
162         (us_minus:VECINT12
163           (match_operand:VECINT12 1 "gr_register_operand" "r")
164           (match_operand:VECINT12 2 "gr_register_operand" "r")))]
165   ""
166   "psub<vecsize>.uuu %0 = %1, %2"
167   [(set_attr "itanium_class" "mmalua")])
168
169 (define_expand "mulv8qi3"
170   [(set (match_operand:V8QI 0 "gr_register_operand" "")
171         (mult:V8QI (match_operand:V8QI 1 "gr_register_operand" "r")
172                    (match_operand:V8QI 2 "gr_register_operand" "r")))]
173   ""
174 {
175   rtx l1, h1, l2, h2, lm, hm, lz, hz;
176
177   l1 = gen_reg_rtx (V4HImode);
178   h1 = gen_reg_rtx (V4HImode);
179   l2 = gen_reg_rtx (V4HImode);
180   h2 = gen_reg_rtx (V4HImode);
181
182   /* Zero-extend the QImode elements into two words of HImode elements.  */
183   emit_insn (gen_unpack1_l (gen_lowpart (V8QImode, l1),
184                             operands[1], CONST0_RTX (V8QImode)));
185   emit_insn (gen_unpack1_l (gen_lowpart (V8QImode, l2),
186                             operands[2], CONST0_RTX (V8QImode)));
187   emit_insn (gen_unpack1_h (gen_lowpart (V8QImode, h1),
188                             operands[1], CONST0_RTX (V8QImode)));
189   emit_insn (gen_unpack1_h (gen_lowpart (V8QImode, h2),
190                             operands[2], CONST0_RTX (V8QImode)));
191
192   /* Multiply.  */
193   lm = gen_reg_rtx (V4HImode);
194   hm = gen_reg_rtx (V4HImode);
195   emit_insn (gen_mulv4hi3 (lm, l1, l2));
196   emit_insn (gen_mulv4hi3 (hm, h1, h2));
197
198   /* Zap the high order bytes of the HImode elements.  There are several
199      ways that this could be done.  On Itanium2, there's 1 cycle latency
200      moving between the ALU units and the PALU units, so using AND would
201      be 3 cycles latency into the eventual pack insn, whereas using MIX
202      is only 2 cycles.  */
203   lz = gen_reg_rtx (V4HImode);
204   hz = gen_reg_rtx (V4HImode);
205   emit_insn (gen_mix1_r (gen_lowpart (V8QImode, lz),
206                          gen_lowpart (V8QImode, lm), CONST0_RTX (V8QImode)));
207   emit_insn (gen_mix1_r (gen_lowpart (V8QImode, lz),
208                          gen_lowpart (V8QImode, lm), CONST0_RTX (V8QImode)));
209
210   /* Repack the HImode elements as QImode elements.  */
211   emit_insn (gen_pack2_sss (operands[0], lz, hz));
212   DONE;
213 })
214
215 (define_insn "mulv4hi3"
216   [(set (match_operand:V4HI 0 "gr_register_operand" "=r")
217         (mult:V4HI (match_operand:V4HI 1 "gr_register_operand" "r")
218                    (match_operand:V4HI 2 "gr_register_operand" "r")))]
219   ""
220   "pmpyshr2 %0 = %1, %2, 0"
221   [(set_attr "itanium_class" "mmalua")])
222
223 (define_expand "umax<mode>3"
224   [(set (match_operand:VECINT 0 "gr_register_operand" "")
225         (smax:VECINT (match_operand:VECINT 1 "gr_register_operand" "")
226                      (match_operand:VECINT 2 "gr_register_operand" "")))]
227   ""
228 {
229   if (ia64_expand_vecint_minmax (UMAX, <MODE>mode, operands))
230     DONE;
231 })
232
233 (define_expand "smax<mode>3"
234   [(set (match_operand:VECINT 0 "gr_register_operand" "")
235         (smax:VECINT (match_operand:VECINT 1 "gr_reg_or_0_operand" "")
236                      (match_operand:VECINT 2 "gr_reg_or_0_operand" "")))]
237   ""
238 {
239   if (ia64_expand_vecint_minmax (SMAX, <MODE>mode, operands))
240     DONE;
241 })
242
243 (define_expand "umin<mode>3"
244   [(set (match_operand:VECINT 0 "gr_register_operand" "")
245         (umin:VECINT (match_operand:VECINT 1 "gr_register_operand" "")
246                      (match_operand:VECINT 2 "gr_register_operand" "")))]
247   ""
248 {
249   if (ia64_expand_vecint_minmax (UMIN, <MODE>mode, operands))
250     DONE;
251 })
252
253 (define_expand "smin<mode>3"
254   [(set (match_operand:VECINT 0 "gr_register_operand" "")
255         (smin:VECINT (match_operand:VECINT 1 "gr_reg_or_0_operand" "")
256                      (match_operand:VECINT 2 "gr_reg_or_0_operand" "")))]
257   ""
258 {
259   if (ia64_expand_vecint_minmax (SMIN, <MODE>mode, operands))
260     DONE;
261 })
262
263 (define_insn "*umaxv8qi3"
264   [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
265         (umax:V8QI (match_operand:V8QI 1 "gr_register_operand" "r")
266                    (match_operand:V8QI 2 "gr_register_operand" "r")))]
267   ""
268   "pmax1.u %0 = %1, %2"
269   [(set_attr "itanium_class" "mmshf")])
270
271 (define_insn "*smaxv4hi3"
272   [(set (match_operand:V4HI 0 "gr_register_operand" "=r")
273         (smax:V4HI (match_operand:V4HI 1 "gr_reg_or_0_operand" "rU")
274                    (match_operand:V4HI 2 "gr_reg_or_0_operand" "rU")))]
275   ""
276   "pmax2 %0 = %r1, %r2"
277   [(set_attr "itanium_class" "mmshf")])
278
279 (define_insn "*uminv8qi3"
280   [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
281         (umin:V8QI (match_operand:V8QI 1 "gr_register_operand" "r")
282                    (match_operand:V8QI 2 "gr_register_operand" "r")))]
283   ""
284   "pmin1.u %0 = %1, %2"
285   [(set_attr "itanium_class" "mmshf")])
286
287 (define_insn "*sminv4hi3"
288   [(set (match_operand:V4HI 0 "gr_register_operand" "=r")
289         (smin:V4HI (match_operand:V4HI 1 "gr_reg_or_0_operand" "rU")
290                    (match_operand:V4HI 2 "gr_reg_or_0_operand" "rU")))]
291   ""
292   "pmin2 %0 = %r1, %r2"
293   [(set_attr "itanium_class" "mmshf")])
294
295 (define_insn "ashl<mode>3"
296   [(set (match_operand:VECINT24 0 "gr_register_operand" "=r")
297         (ashift:VECINT24
298           (match_operand:VECINT24 1 "gr_register_operand" "r")
299           (match_operand:VECINT24 2 "gr_reg_or_5bit_operand" "rn")))]
300   ""
301   "pshl<vecsize> %0 = %1, %2"
302   [(set_attr "itanium_class" "mmshf")])
303
304 (define_insn "ashr<mode>3"
305   [(set (match_operand:VECINT24 0 "gr_register_operand" "=r")
306         (ashiftrt:VECINT24
307           (match_operand:VECINT24 1 "gr_register_operand" "r")
308           (match_operand:VECINT24 2 "gr_reg_or_5bit_operand" "rn")))]
309   ""
310   "pshr<vecsize> %0 = %1, %2"
311   [(set_attr "itanium_class" "mmshf")])
312
313 (define_insn "lshr<mode>3"
314   [(set (match_operand:VECINT24 0 "gr_register_operand" "=r")
315         (lshiftrt:VECINT24
316           (match_operand:VECINT24 1 "gr_register_operand" "r")
317           (match_operand:VECINT24 2 "gr_reg_or_5bit_operand" "rn")))]
318   ""
319   "pshr<vecsize>.u %0 = %1, %2"
320   [(set_attr "itanium_class" "mmshf")])
321
322 (define_expand "vcond<mode>"
323   [(set (match_operand:VECINT 0 "gr_register_operand" "")
324         (if_then_else:VECINT
325           (match_operator 3 "" 
326             [(match_operand:VECINT 4 "gr_reg_or_0_operand" "")
327              (match_operand:VECINT 5 "gr_reg_or_0_operand" "")])
328           (match_operand:VECINT 1 "gr_reg_or_0_operand" "")
329           (match_operand:VECINT 2 "gr_reg_or_0_operand" "")))]
330   ""
331 {
332   ia64_expand_vecint_cmov (operands);
333   DONE;
334 })
335
336 (define_expand "vcondu<mode>"
337   [(set (match_operand:VECINT 0 "gr_register_operand" "")
338         (if_then_else:VECINT
339           (match_operator 3 "" 
340             [(match_operand:VECINT 4 "gr_reg_or_0_operand" "")
341              (match_operand:VECINT 5 "gr_reg_or_0_operand" "")])
342           (match_operand:VECINT 1 "gr_reg_or_0_operand" "")
343           (match_operand:VECINT 2 "gr_reg_or_0_operand" "")))]
344   ""
345 {
346   ia64_expand_vecint_cmov (operands);
347   DONE;
348 })
349
350 (define_insn "*cmpeq_<mode>"
351   [(set (match_operand:VECINT 0 "gr_register_operand" "=r")
352         (eq:VECINT (match_operand:VECINT 1 "gr_reg_or_0_operand" "rU")
353                    (match_operand:VECINT 2 "gr_reg_or_0_operand" "rU")))]
354   ""
355   "pcmp<vecsize>.eq %0 = %r1, %r2"
356   [(set_attr "itanium_class" "mmalua")])
357
358 (define_insn "*cmpgt_<mode>"
359   [(set (match_operand:VECINT 0 "gr_register_operand" "=r")
360         (gt:VECINT (match_operand:VECINT 1 "gr_reg_or_0_operand" "rU")
361                    (match_operand:VECINT 2 "gr_reg_or_0_operand" "rU")))]
362   ""
363   "pcmp<vecsize>.gt %0 = %r1, %r2"
364   [(set_attr "itanium_class" "mmalua")])
365
366 (define_insn "pack2_sss"
367   [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
368         (vec_concat:V8QI
369           (ss_truncate:V4QI
370             (match_operand:V4HI 1 "gr_reg_or_0_operand" "rU"))
371           (ss_truncate:V4QI
372             (match_operand:V4HI 2 "gr_reg_or_0_operand" "rU"))))]
373   ""
374   "pack2.sss %0 = %r1, %r2"
375   [(set_attr "itanium_class" "mmshf")])
376
377 (define_insn "*pack2_uss"
378   [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
379         (vec_concat:V8QI
380           (us_truncate:V4QI
381             (match_operand:V4HI 1 "gr_reg_or_0_operand" "rU"))
382           (us_truncate:V4QI
383             (match_operand:V4HI 2 "gr_reg_or_0_operand" "rU"))))]
384   ""
385   "pack2.uss %0 = %r1, %r2"
386   [(set_attr "itanium_class" "mmshf")])
387
388 (define_insn "pack4_sss"
389   [(set (match_operand:V4HI 0 "gr_register_operand" "=r")
390         (vec_concat:V4HI
391           (ss_truncate:V2HI
392             (match_operand:V2SI 1 "gr_reg_or_0_operand" "rU"))
393           (ss_truncate:V2HI
394             (match_operand:V2SI 2 "gr_reg_or_0_operand" "rU"))))]
395   ""
396   "pack4.sss %0 = %r1, %r2"
397   [(set_attr "itanium_class" "mmshf")])
398
399 (define_insn "unpack1_l"
400   [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
401         (vec_select:V8QI
402           (vec_concat:V16QI
403             (match_operand:V8QI 1 "gr_reg_or_0_operand" "rU")
404             (match_operand:V8QI 2 "gr_reg_or_0_operand" "rU"))
405           (parallel [(const_int 0)
406                      (const_int 1)
407                      (const_int 2)
408                      (const_int 3)
409                      (const_int 8)
410                      (const_int 9)
411                      (const_int 10)
412                      (const_int 11)])))]
413   ""
414   "unpack1.l %0 = %r2, %r1"
415   [(set_attr "itanium_class" "mmshf")])
416
417 (define_insn "unpack1_h"
418   [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
419         (vec_select:V8QI
420           (vec_concat:V16QI
421             (match_operand:V8QI 1 "gr_reg_or_0_operand" "rU")
422             (match_operand:V8QI 2 "gr_reg_or_0_operand" "rU"))
423           (parallel [(const_int 4)
424                      (const_int 5)
425                      (const_int 6)
426                      (const_int 7)
427                      (const_int 12)
428                      (const_int 13)
429                      (const_int 14)
430                      (const_int 15)])))]
431   ""
432   "unpack1.h %0 = %r2, %r1"
433   [(set_attr "itanium_class" "mmshf")])
434
435 (define_insn "mix1_r"
436   [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
437         (vec_select:V8QI
438           (vec_concat:V16QI
439             (match_operand:V8QI 1 "gr_reg_or_0_operand" "rU")
440             (match_operand:V8QI 2 "gr_reg_or_0_operand" "rU"))
441           (parallel [(const_int 0)
442                      (const_int 8)
443                      (const_int 2)
444                      (const_int 10)
445                      (const_int 4)
446                      (const_int 12)
447                      (const_int 6)
448                      (const_int 14)])))]
449   ""
450   "mix1.r %0 = %r2, %r1"
451   [(set_attr "itanium_class" "mmshf")])
452
453 (define_insn "*mix1_l"
454   [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
455         (vec_select:V8QI
456           (vec_concat:V16QI
457             (match_operand:V8QI 1 "gr_reg_or_0_operand" "rU")
458             (match_operand:V8QI 2 "gr_reg_or_0_operand" "rU"))
459           (parallel [(const_int 1)
460                      (const_int 9)
461                      (const_int 3)
462                      (const_int 11)
463                      (const_int 5)
464                      (const_int 13)
465                      (const_int 7)
466                      (const_int 15)])))]
467   ""
468   "mix1.l %0 = %r2, %r1"
469   [(set_attr "itanium_class" "mmshf")])
470
471 (define_insn "*mux1_rev"
472   [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
473         (vec_select:V8QI
474           (match_operand:V8QI 1 "gr_register_operand" "r")
475           (parallel [(const_int 7)
476                      (const_int 6)
477                      (const_int 5)
478                      (const_int 4)
479                      (const_int 3)
480                      (const_int 2)
481                      (const_int 1)
482                      (const_int 0)])))]
483   ""
484   "mux1 %0 = %1, @rev"
485   [(set_attr "itanium_class" "mmshf")])
486
487 (define_insn "*mux1_mix"
488   [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
489         (vec_select:V8QI
490           (match_operand:V8QI 1 "gr_register_operand" "r")
491           (parallel [(const_int 0)
492                      (const_int 4)
493                      (const_int 2)
494                      (const_int 6)
495                      (const_int 1)
496                      (const_int 5)
497                      (const_int 3)
498                      (const_int 7)])))]
499   ""
500   "mux1 %0 = %1, @mix"
501   [(set_attr "itanium_class" "mmshf")])
502
503 (define_insn "*mux1_shuf"
504   [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
505         (vec_select:V8QI
506           (match_operand:V8QI 1 "gr_register_operand" "r")
507           (parallel [(const_int 0)
508                      (const_int 4)
509                      (const_int 1)
510                      (const_int 5)
511                      (const_int 2)
512                      (const_int 6)
513                      (const_int 3)
514                      (const_int 7)])))]
515   ""
516   "mux1 %0 = %1, @shuf"
517   [(set_attr "itanium_class" "mmshf")])
518
519 (define_insn "*mux1_alt"
520   [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
521         (vec_select:V8QI
522           (match_operand:V8QI 1 "gr_register_operand" "r")
523           (parallel [(const_int 0)
524                      (const_int 2)
525                      (const_int 4)
526                      (const_int 6)
527                      (const_int 1)
528                      (const_int 3)
529                      (const_int 5)
530                      (const_int 7)])))]
531   ""
532   "mux1 %0 = %1, @alt"
533   [(set_attr "itanium_class" "mmshf")])
534
535 (define_insn "*mux1_brcst_v8qi"
536   [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
537         (vec_select:V8QI
538           (match_operand:V8QI 1 "gr_register_operand" "r")
539           (parallel [(const_int 0)
540                      (const_int 0)
541                      (const_int 0)
542                      (const_int 0)
543                      (const_int 0)
544                      (const_int 0)
545                      (const_int 0)
546                      (const_int 0)])))]
547   ""
548   "mux1 %0 = %1, @brcst"
549   [(set_attr "itanium_class" "mmshf")])
550
551 (define_insn "*mux1_brcst_qi"
552   [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
553         (vec_duplicate:V8QI
554           (match_operand:QI 1 "gr_register_operand" "r")))]
555   ""
556   "mux1 %0 = %1, @brcst"
557   [(set_attr "itanium_class" "mmshf")])
558
559 (define_insn "unpack2_l"
560   [(set (match_operand:V4HI 0 "gr_register_operand" "=r")
561         (vec_select:V4HI
562           (vec_concat:V8HI
563             (match_operand:V4HI 1 "gr_reg_or_0_operand" "rU")
564             (match_operand:V4HI 2 "gr_reg_or_0_operand" "rU"))
565           (parallel [(const_int 0)
566                      (const_int 4)
567                      (const_int 1)
568                      (const_int 5)])))]
569   ""
570   "unpack2.l %0 = %r2, %r1"
571   [(set_attr "itanium_class" "mmshf")])
572
573 (define_insn "unpack2_h"
574   [(set (match_operand:V4HI 0 "gr_register_operand" "=r")
575         (vec_select:V4HI
576           (vec_concat:V8HI
577             (match_operand:V4HI 1 "gr_reg_or_0_operand" "rU")
578             (match_operand:V4HI 2 "gr_reg_or_0_operand" "rU"))
579           (parallel [(const_int 2)
580                      (const_int 6)
581                      (const_int 3)
582                      (const_int 7)])))]
583   ""
584   "unpack2.h %0 = %r2, %r1"
585   [(set_attr "itanium_class" "mmshf")])
586
587 (define_insn "*mix2_r"
588   [(set (match_operand:V4HI 0 "gr_register_operand" "=r")
589         (vec_select:V4HI
590           (vec_concat:V8HI
591             (match_operand:V4HI 1 "gr_reg_or_0_operand" "rU")
592             (match_operand:V4HI 2 "gr_reg_or_0_operand" "rU"))
593           (parallel [(const_int 0)
594                      (const_int 4)
595                      (const_int 2)
596                      (const_int 6)])))]
597   ""
598   "mix2.r %0 = %r2, %r1"
599   [(set_attr "itanium_class" "mmshf")])
600
601 (define_insn "*mix2_l"
602   [(set (match_operand:V4HI 0 "gr_register_operand" "=r")
603         (vec_select:V4HI
604           (vec_concat:V8HI
605             (match_operand:V4HI 1 "gr_reg_or_0_operand" "rU")
606             (match_operand:V4HI 2 "gr_reg_or_0_operand" "rU"))
607           (parallel [(const_int 1)
608                      (const_int 5)
609                      (const_int 3)
610                      (const_int 7)])))]
611   ""
612   "mix2.l %0 = %r2, %r1"
613   [(set_attr "itanium_class" "mmshf")])
614
615 (define_insn "*mux2"
616   [(set (match_operand:V4HI 0 "gr_register_operand" "=r")
617         (vec_select:V4HI
618           (match_operand:V4HI 1 "gr_register_operand" "r")
619           (parallel [(match_operand 2 "const_int_2bit_operand" "")
620                      (match_operand 3 "const_int_2bit_operand" "")
621                      (match_operand 4 "const_int_2bit_operand" "")
622                      (match_operand 5 "const_int_2bit_operand" "")])))]
623   ""
624 {
625   int mask;
626   mask  = INTVAL (operands[2]);
627   mask |= INTVAL (operands[3]) << 2;
628   mask |= INTVAL (operands[4]) << 4;
629   mask |= INTVAL (operands[5]) << 6;
630   operands[2] = GEN_INT (mask);
631   return "%,mux2 %0 = %1, %2";
632 }
633   [(set_attr "itanium_class" "mmshf")])
634
635 (define_insn "*mux2_brcst_hi"
636   [(set (match_operand:V4HI 0 "gr_register_operand" "=r")
637         (vec_duplicate:V4HI
638           (match_operand:HI 1 "gr_register_operand" "r")))]
639   ""
640   "mux2 %0 = %1, 0"
641   [(set_attr "itanium_class" "mmshf")])
642
643 ;; Note that mix4.r performs the exact same operation.
644 (define_insn "*unpack4_l"
645   [(set (match_operand:V2SI 0 "gr_register_operand" "=r")
646         (vec_select:V2SI
647           (vec_concat:V4SI
648             (match_operand:V2SI 1 "gr_reg_or_0_operand" "rU")
649             (match_operand:V2SI 2 "gr_reg_or_0_operand" "rU"))
650           (parallel [(const_int 0)
651                      (const_int 2)])))]
652   ""
653   "unpack4.l %0 = %r2, %r1"
654   [(set_attr "itanium_class" "mmshf")])
655
656 ;; Note that mix4.l performs the exact same operation.
657 (define_insn "*unpack4_h"
658   [(set (match_operand:V2SI 0 "gr_register_operand" "=r")
659         (vec_select:V2SI
660           (vec_concat:V4SI
661             (match_operand:V2SI 1 "gr_reg_or_0_operand" "rU")
662             (match_operand:V2SI 2 "gr_reg_or_0_operand" "rU"))
663           (parallel [(const_int 1)
664                      (const_int 3)])))]
665   ""
666   "unpack4.h %0 = %r2, %r1"
667   [(set_attr "itanium_class" "mmshf")])
668
669 (define_expand "vec_initv2si"
670   [(match_operand:V2SF 0 "gr_register_operand" "")
671    (match_operand 1 "" "")]
672   ""
673 {
674   rtx op1 = XVECEXP (operands[1], 0, 0);
675   rtx op2 = XVECEXP (operands[1], 0, 1);
676   rtx x;
677
678   if (GET_CODE (op1) == CONST_INT && GET_CODE (op2) == CONST_INT)
679     {
680       x = gen_rtx_CONST_VECTOR (V2SImode, XVEC (operands[1], 0));
681       emit_move_insn (operands[0], x);
682       DONE;
683     }
684
685   if (!gr_reg_or_0_operand (op1, SImode))
686     op1 = force_reg (SImode, op1);
687   if (!gr_reg_or_0_operand (op2, SImode))
688     op2 = force_reg (SImode, op2);
689
690   x = gen_rtx_VEC_CONCAT (V2SImode, op1, op2);
691   emit_insn (gen_rtx_SET (VOIDmode, operands[0], x));
692   DONE;
693 })
694
695 (define_insn "*vecinit_v2si"
696   [(set (match_operand:V2SI 0 "gr_register_operand" "=r")
697         (vec_concat:V2SI
698           (match_operand:SI 1 "gr_reg_or_0_operand" "rO")
699           (match_operand:SI 2 "gr_reg_or_0_operand" "rO")))]
700   ""
701   "unpack4.l %0 = %r2, %r1"
702   [(set_attr "itanium_class" "mmshf")])
703
704 ;; Missing operations
705 ;; padd.uus
706 ;; pavg
707 ;; pavgsub
708 ;; pmpy
709 ;; pmpyshr, general form
710 ;; psad
711 ;; pshladd
712 ;; pshradd
713 ;; psub.uus
714 ;; vec_set<mode>
715 ;; vec_extract<mode>
716 ;; vec_init<mode>
717 \f
718 ;; Floating point vector operations
719
720 (define_expand "movv2sf"
721   [(set (match_operand:V2SF 0 "general_operand" "")
722         (match_operand:V2SF 1 "general_operand" ""))]
723   ""
724 {
725   rtx op1 = ia64_expand_move (operands[0], operands[1]);
726   if (!op1)
727     DONE;
728   operands[1] = op1;
729 })
730
731 (define_insn "*movv2sf_internal"
732   [(set (match_operand:V2SF 0 "destination_operand"
733                                         "=f,f,f,Q,*r ,*r,*r,*r,m ,f ,*r")
734         (match_operand:V2SF 1 "move_operand"
735                                         "fU,Y,Q,f,U*r,W ,i ,m ,*r,*r,f "))]
736   "ia64_move_ok (operands[0], operands[1])"
737 {
738   static const char * const alt[] = {
739     "%,mov %0 = %F1",
740     "%,fpack %0 = %F2, %F1",
741     "%,ldf8 %0 = %1%P1",
742     "%,stf8 %0 = %1%P0",
743     "%,mov %0 = %r1",
744     "%,addl %0 = %v1, r0",
745     "%,movl %0 = %v1",
746     "%,ld8%O1 %0 = %1%P1",
747     "%,st8%Q0 %0 = %r1%P0",
748     "%,setf.sig %0 = %1",
749     "%,getf.sig %0 = %1"
750   };
751
752   if (which_alternative == 1)
753     {
754       operands[2] = XVECEXP (operands[1], 0, 1);
755       operands[1] = XVECEXP (operands[1], 0, 0);
756     }
757
758   return alt[which_alternative];
759 }
760   [(set_attr "itanium_class" "fmisc,fmisc,fld,stf,ialu,ialu,long_i,ld,st,tofr,frfr")])
761
762 (define_insn "absv2sf2"
763   [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
764         (abs:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")))]
765   ""
766   "fpabs %0 = %1"
767   [(set_attr "itanium_class" "fmisc")])
768
769 (define_insn "negv2sf2"
770   [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
771         (neg:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")))]
772   ""
773   "fpneg %0 = %1"
774   [(set_attr "itanium_class" "fmisc")])
775
776 (define_insn "*negabsv2sf2"
777   [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
778         (neg:V2SF
779           (abs:V2SF (match_operand:V2SF 1 "fr_register_operand" "f"))))]
780   ""
781   "fpnegabs %0 = %1"
782   [(set_attr "itanium_class" "fmisc")])
783
784 (define_expand "addv2sf3"
785   [(set (match_operand:V2SF 0 "fr_register_operand" "")
786         (plus:V2SF
787           (mult:V2SF (match_operand:V2SF 1 "fr_register_operand" "")
788                      (match_dup 3))
789           (match_operand:V2SF 2 "fr_register_operand" "")))]
790   ""
791 {
792   rtvec v = gen_rtvec (2, CONST1_RTX (SFmode), CONST1_RTX (SFmode));
793   operands[3] = force_reg (V2SFmode, gen_rtx_CONST_VECTOR (V2SFmode, v));
794 })
795
796 (define_expand "subv2sf3"
797   [(set (match_operand:V2SF 0 "fr_register_operand" "")
798         (minus:V2SF
799           (mult:V2SF (match_operand:V2SF 1 "fr_register_operand" "")
800                      (match_dup 3))
801           (match_operand:V2SF 2 "fr_register_operand" "")))]
802   ""
803 {
804   rtvec v = gen_rtvec (2, CONST1_RTX (SFmode), CONST1_RTX (SFmode));
805   operands[3] = force_reg (V2SFmode, gen_rtx_CONST_VECTOR (V2SFmode, v));
806 })
807
808 (define_insn "mulv2sf3"
809   [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
810         (mult:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
811                    (match_operand:V2SF 2 "fr_register_operand" "f")))]
812   ""
813   "fpmpy %0 = %1, %2"
814   [(set_attr "itanium_class" "fmac")])
815
816 (define_insn "*fpma"
817   [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
818         (plus:V2SF
819           (mult:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
820                      (match_operand:V2SF 2 "fr_register_operand" "f"))
821           (match_operand:V2SF 3 "fr_register_operand" "f")))]
822   ""
823   "fpma %0 = %1, %2, %3"
824   [(set_attr "itanium_class" "fmac")])
825
826 (define_insn "*fpms"
827   [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
828         (minus:V2SF
829           (mult:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
830                      (match_operand:V2SF 2 "fr_register_operand" "f"))
831           (match_operand:V2SF 3 "fr_register_operand" "f")))]
832   ""
833   "fpms %0 = %1, %2, %3"
834   [(set_attr "itanium_class" "fmac")])
835
836 (define_insn "*fpnmpy"
837   [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
838         (neg:V2SF
839           (mult:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
840                      (match_operand:V2SF 2 "fr_register_operand" "f"))))]
841   ""
842   "fpnmpy %0 = %1, %2"
843   [(set_attr "itanium_class" "fmac")])
844
845 (define_insn "*fpnma"
846   [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
847         (plus:V2SF
848           (neg:V2SF
849             (mult:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
850                        (match_operand:V2SF 2 "fr_register_operand" "f")))
851           (match_operand:V2SF 3 "fr_register_operand" "f")))]
852   ""
853   "fpnma %0 = %1, %2, %3"
854   [(set_attr "itanium_class" "fmac")])
855
856 (define_insn "smaxv2sf2"
857   [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
858         (smax:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
859                    (match_operand:V2SF 2 "fr_register_operand" "f")))]
860   ""
861   "fpmax %0 = %1, %2"
862   [(set_attr "itanium_class" "fmisc")])
863
864 (define_insn "sminv2sf2"
865   [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
866         (smin:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
867                    (match_operand:V2SF 2 "fr_register_operand" "f")))]
868   ""
869   "fpmin %0 = %1, %2"
870   [(set_attr "itanium_class" "fmisc")])
871
872 (define_expand "vcondv2sf"
873   [(set (match_operand:V2SF 0 "fr_register_operand" "")
874         (if_then_else:V2SF
875           (match_operator 3 "" 
876             [(match_operand:V2SF 4 "fr_reg_or_0_operand" "")
877              (match_operand:V2SF 5 "fr_reg_or_0_operand" "")])
878           (match_operand:V2SF 1 "fr_reg_or_0_operand" "")
879           (match_operand:V2SF 2 "fr_reg_or_0_operand" "")))]
880   ""
881 {
882   rtx x, cmp;
883
884   PUT_MODE (operands[3], V2SFmode);
885   switch (GET_CODE (operands[3]))
886     {
887     case EQ:
888     case NE:
889     case LT:
890     case LE:
891     case UNORDERED:
892     case ORDERED:
893       break;
894
895     case GT:
896     case GE:
897       x = XEXP (operands[3], 0);
898       XEXP (operands[3], 0) = XEXP (operands[3], 1);
899       XEXP (operands[3], 1) = x;
900       PUT_CODE (operands[3], swap_condition (GET_CODE (operands[3])));
901       break;
902
903     default:
904       abort ();
905     }
906
907   cmp = gen_reg_rtx (V2SFmode);
908   emit_insn (gen_rtx_SET (VOIDmode, cmp, operands[3]));
909
910   x = gen_rtx_IF_THEN_ELSE (V2SFmode, cmp, operands[1], operands[2]);
911   emit_insn (gen_rtx_SET (VOIDmode, operands[0], x));
912   DONE;
913 })
914
915 (define_insn "*fpcmp"
916   [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
917         (if_then_else:V2SF
918           (match_operand:V2SF 1 "fr_register_operand" "f")
919           (match_operand:V2SF 2 "fr_reg_or_0_operand" "fU")
920           (match_operand:V2SF 3 "fr_reg_or_0_operand" "fU")))]
921   ""
922   "fselect %0 = %2, %3, %1"
923   [(set_attr "itanium_class" "fmisc")])
924
925 (define_expand "vec_initv2sf"
926   [(match_operand:V2SF 0 "fr_register_operand" "")
927    (match_operand 1 "" "")]
928   ""
929 {
930   rtx op1 = XVECEXP (operands[1], 0, 0);
931   rtx op2 = XVECEXP (operands[1], 0, 1);
932   rtx x;
933
934   if (GET_CODE (op1) == CONST_DOUBLE && GET_CODE (op2) == CONST_DOUBLE)
935     {
936       x = gen_rtx_CONST_VECTOR (V2SFmode, XVEC (operands[1], 0));
937       emit_move_insn (operands[0], x);
938       DONE;
939     }
940
941   if (!fr_reg_or_fp01_operand (op1, SFmode))
942     op1 = force_reg (SFmode, op1);
943   if (!fr_reg_or_fp01_operand (op2, SFmode))
944     op2 = force_reg (SFmode, op2);
945
946   x = gen_rtx_VEC_CONCAT (V2SFmode, op1, op2);
947   emit_insn (gen_rtx_SET (VOIDmode, operands[0], x));
948   DONE;
949 })
950
951 (define_insn "*fpack_sfsf"
952   [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
953         (vec_concat:V2SF
954           (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")
955           (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
956   ""
957   "fpack %0 = %F2, %F1"
958   [(set_attr "itanium_class" "fmisc")])
959
960 (define_insn "*fpack_sfxf"
961   [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
962         (vec_concat:V2SF
963           (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")
964           (float_truncate:SF
965             (match_operand 2 "fr_register_operand" "f"))))]
966   "GET_MODE (operands[2]) == DFmode || GET_MODE (operands[2]) == XFmode"
967   "fpack %0 = %2, %F1"
968   [(set_attr "itanium_class" "fmisc")])
969
970 (define_insn "*fpack_xfsf"
971   [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
972         (vec_concat:V2SF
973           (float_truncate:SF
974             (match_operand 1 "fr_register_operand" "f"))
975           (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
976   "GET_MODE (operands[1]) == DFmode || GET_MODE (operands[1]) == XFmode"
977   "fpack %0 = %F2, %1"
978   [(set_attr "itanium_class" "fmisc")])
979
980 (define_insn "*fpack_xfxf"
981   [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
982         (vec_concat:V2SF
983           (float_truncate:SF
984             (match_operand 1 "fr_register_operand" "f"))
985           (float_truncate:SF
986             (match_operand 2 "fr_register_operand" "f"))))]
987   "(GET_MODE (operands[1]) == DFmode || GET_MODE (operands[1]) == XFmode)
988    && (GET_MODE (operands[2]) == DFmode || GET_MODE (operands[2]) == XFmode)"
989   "fpack %0 = %2, %1"
990   [(set_attr "itanium_class" "fmisc")])
991
992 ;; Missing operations
993 ;; fprcpa
994 ;; fpsqrta
995 ;; vec_setv2sf
996 ;; vec_extractv2sf