vect.md revision 169689
15918SN/A;; IA-64 machine description for vector operations.
214745Snishjain;; Copyright (C) 2004, 2005
35918SN/A;;
45918SN/A;; This file is part of GCC.
55918SN/A;;
65918SN/A;; GCC is free software; you can redistribute it and/or modify
75918SN/A;; it under the terms of the GNU General Public License as published by
85918SN/A;; the Free Software Foundation; either version 2, or (at your option)
95918SN/A;; any later version.
105918SN/A;;
115918SN/A;; GCC is distributed in the hope that it will be useful,
125918SN/A;; but WITHOUT ANY WARRANTY; without even the implied warranty of
135918SN/A;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
145918SN/A;; GNU General Public License for more details.
155918SN/A;;
165918SN/A;; You should have received a copy of the GNU General Public License
175918SN/A;; along with GCC; see the file COPYING.  If not, write to
185918SN/A;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
195918SN/A;; Boston, MA 02110-1301, USA.
205918SN/A
215918SN/A
225918SN/A;; Integer vector operations
235918SN/A
245918SN/A(define_mode_macro VECINT [V8QI V4HI V2SI])
255918SN/A(define_mode_macro VECINT12 [V8QI V4HI])
265918SN/A(define_mode_macro VECINT24 [V4HI V2SI])
275918SN/A(define_mode_attr vecsize [(V8QI "1") (V4HI "2") (V2SI "4")])
285918SN/A
295918SN/A(define_expand "mov<mode>"
305918SN/A  [(set (match_operand:VECINT 0 "general_operand" "")
315918SN/A        (match_operand:VECINT 1 "general_operand" ""))]
325918SN/A  ""
335918SN/A{
345918SN/A  rtx op1 = ia64_expand_move (operands[0], operands[1]);
355918SN/A  if (!op1)
365918SN/A    DONE;
375918SN/A  operands[1] = op1;
385918SN/A})
395918SN/A
405918SN/A(define_insn "*mov<mode>_internal"
415918SN/A  [(set (match_operand:VECINT 0 "destination_operand"
425918SN/A					"=r,r,r,r,m ,*f ,*f,Q ,r ,*f")
435918SN/A	(match_operand:VECINT 1 "move_operand"
445918SN/A					"rU,W,i,m,rU,U*f,Q ,*f,*f,r "))]
455918SN/A  "ia64_move_ok (operands[0], operands[1])"
465918SN/A  "@
475918SN/A   mov %0 = %r1
485918SN/A   addl %0 = %v1, r0
495918SN/A   movl %0 = %v1
505918SN/A   ld8%O1 %0 = %1%P1
515918SN/A   st8%Q0 %0 = %r1%P0
525918SN/A   mov %0 = %F1
535918SN/A   ldf8 %0 = %1%P1
545918SN/A   stf8 %0 = %1%P0
555918SN/A   getf.sig %0 = %1
565918SN/A   setf.sig %0 = %1"
575918SN/A  [(set_attr "itanium_class" "ialu,ialu,long_i,ld,st,fmisc,fld,stf,frfr,tofr")])
585918SN/A
595918SN/A(define_insn "one_cmpl<mode>2"
605918SN/A  [(set (match_operand:VECINT 0 "gr_register_operand" "=r")
615918SN/A	(not:VECINT (match_operand:VECINT 1 "gr_register_operand" "r")))]
625918SN/A  ""
635918SN/A  "andcm %0 = -1, %1"
645918SN/A  [(set_attr "itanium_class" "ilog")])
655918SN/A
665918SN/A(define_insn "and<mode>3"
675918SN/A  [(set (match_operand:VECINT 0 "grfr_register_operand" "=r,*f")
685918SN/A	(and:VECINT
695918SN/A	  (match_operand:VECINT 1 "grfr_register_operand" "r,*f")
705918SN/A	  (match_operand:VECINT 2 "grfr_reg_or_8bit_operand" "r,*f")))]
715918SN/A  ""
725918SN/A  "@
735918SN/A   and %0 = %2, %1
745918SN/A   fand %0 = %2, %1"
755918SN/A  [(set_attr "itanium_class" "ilog,fmisc")])
765918SN/A
775918SN/A(define_insn "*andnot<mode>"
785918SN/A  [(set (match_operand:VECINT 0 "grfr_register_operand" "=r,*f")
795918SN/A	(and:VECINT
805918SN/A	  (not:VECINT (match_operand:VECINT 1 "grfr_register_operand" "r,*f"))
815918SN/A	  (match_operand:VECINT 2 "grfr_reg_or_8bit_operand" "r,*f")))]
825918SN/A  ""
835918SN/A  "@
845918SN/A   andcm %0 = %2, %1
855918SN/A   fandcm %0 = %2, %1"
865918SN/A  [(set_attr "itanium_class" "ilog,fmisc")])
875918SN/A
885918SN/A(define_insn "ior<mode>3"
895918SN/A  [(set (match_operand:VECINT 0 "grfr_register_operand" "=r,*f")
905918SN/A	(ior:VECINT
915918SN/A	  (match_operand:VECINT 1 "grfr_register_operand" "r,*f")
925918SN/A	  (match_operand:VECINT 2 "grfr_reg_or_8bit_operand" "r,*f")))]
935918SN/A  ""
945918SN/A  "@
955918SN/A   or %0 = %2, %1
965918SN/A   for %0 = %2, %1"
975918SN/A  [(set_attr "itanium_class" "ilog,fmisc")])
985918SN/A
995918SN/A(define_insn "xor<mode>3"
1005918SN/A  [(set (match_operand:VECINT 0 "grfr_register_operand" "=r,*f")
1015918SN/A	(xor:VECINT
1025918SN/A	  (match_operand:VECINT 1 "grfr_register_operand" "r,*f")
1035918SN/A	  (match_operand:VECINT 2 "grfr_reg_or_8bit_operand" "r,*f")))]
1045918SN/A  ""
1055918SN/A  "@
1065918SN/A   xor %0 = %2, %1
1075918SN/A   fxor %0 = %2, %1"
1085918SN/A  [(set_attr "itanium_class" "ilog,fmisc")])
1095918SN/A
11015221Snishjain(define_insn "neg<mode>2"
11115221Snishjain  [(set (match_operand:VECINT 0 "gr_register_operand" "=r")
11215221Snishjain	(neg:VECINT (match_operand:VECINT 1 "gr_register_operand" "r")))]
11315221Snishjain  ""
11415221Snishjain  "psub<vecsize> %0 = r0, %1"
11515221Snishjain  [(set_attr "itanium_class" "mmalua")])
11615221Snishjain
11715221Snishjain(define_insn "add<mode>3"
11815221Snishjain  [(set (match_operand:VECINT 0 "gr_register_operand" "=r")
11915221Snishjain	(plus:VECINT (match_operand:VECINT 1 "gr_register_operand" "r")
12015221Snishjain		     (match_operand:VECINT 2 "gr_register_operand" "r")))]
1215918SN/A  ""
12215221Snishjain  "padd<vecsize> %0 = %1, %2"
1235918SN/A  [(set_attr "itanium_class" "mmalua")])
1245918SN/A
12515221Snishjain(define_insn "*ssadd<mode>3"
1265918SN/A  [(set (match_operand:VECINT12 0 "gr_register_operand" "=r")
1275918SN/A	(ss_plus:VECINT12
1285918SN/A	  (match_operand:VECINT12 1 "gr_register_operand" "r")
12914848Snishjain	  (match_operand:VECINT12 2 "gr_register_operand" "r")))]
1305918SN/A  ""
1315918SN/A  "padd<vecsize>.sss %0 = %1, %2"
1325918SN/A  [(set_attr "itanium_class" "mmalua")])
13315221Snishjain
13415221Snishjain(define_insn "*usadd<mode>3"
1355918SN/A  [(set (match_operand:VECINT12 0 "gr_register_operand" "=r")
1365918SN/A	(us_plus:VECINT12
1375918SN/A	  (match_operand:VECINT12 1 "gr_register_operand" "r")
1385918SN/A	  (match_operand:VECINT12 2 "gr_register_operand" "r")))]
1395918SN/A  ""
1405918SN/A  "padd<vecsize>.uuu %0 = %1, %2"
1415918SN/A  [(set_attr "itanium_class" "mmalua")])
1425918SN/A
1435918SN/A(define_insn "sub<mode>3"
1445918SN/A  [(set (match_operand:VECINT 0 "gr_register_operand" "=r")
14515221Snishjain	(minus:VECINT (match_operand:VECINT 1 "gr_register_operand" "r")
14615221Snishjain		      (match_operand:VECINT 2 "gr_register_operand" "r")))]
14715221Snishjain  ""
14815221Snishjain  "psub<vecsize> %0 = %1, %2"
14915221Snishjain  [(set_attr "itanium_class" "mmalua")])
15015221Snishjain
15115221Snishjain(define_insn "*sssub<mode>3"
15215221Snishjain  [(set (match_operand:VECINT12 0 "gr_register_operand" "=r")
15315221Snishjain	(ss_minus:VECINT12
15415221Snishjain	  (match_operand:VECINT12 1 "gr_register_operand" "r")
15515221Snishjain	  (match_operand:VECINT12 2 "gr_register_operand" "r")))]
15615221Snishjain  ""
15715221Snishjain  "psub<vecsize>.sss %0 = %1, %2"
15815221Snishjain  [(set_attr "itanium_class" "mmalua")])
15915221Snishjain
16015221Snishjain(define_insn "*ussub<mode>3"
16115221Snishjain  [(set (match_operand:VECINT12 0 "gr_register_operand" "=r")
16215221Snishjain	(us_minus:VECINT12
16315221Snishjain	  (match_operand:VECINT12 1 "gr_register_operand" "r")
16415221Snishjain	  (match_operand:VECINT12 2 "gr_register_operand" "r")))]
16515221Snishjain  ""
16615221Snishjain  "psub<vecsize>.uuu %0 = %1, %2"
16715221Snishjain  [(set_attr "itanium_class" "mmalua")])
16815221Snishjain
16915221Snishjain(define_expand "mulv8qi3"
17015221Snishjain  [(set (match_operand:V8QI 0 "gr_register_operand" "")
17115221Snishjain	(mult:V8QI (match_operand:V8QI 1 "gr_register_operand" "r")
17215221Snishjain		   (match_operand:V8QI 2 "gr_register_operand" "r")))]
17315221Snishjain  ""
17415221Snishjain{
17515221Snishjain  rtx r1, l1, r2, l2, rm, lm;
17615221Snishjain
17715221Snishjain  r1 = gen_reg_rtx (V4HImode);
17815221Snishjain  l1 = gen_reg_rtx (V4HImode);
17915221Snishjain  r2 = gen_reg_rtx (V4HImode);
18015221Snishjain  l2 = gen_reg_rtx (V4HImode);
18115221Snishjain
18215221Snishjain  /* Zero-extend the QImode elements into two words of HImode elements
18315221Snishjain     by interleaving them with zero bytes.  */
18415221Snishjain  emit_insn (gen_mix1_r (gen_lowpart (V8QImode, r1),
18515221Snishjain                         operands[1], CONST0_RTX (V8QImode)));
18615221Snishjain  emit_insn (gen_mix1_r (gen_lowpart (V8QImode, r2),
18715221Snishjain                         operands[2], CONST0_RTX (V8QImode)));
18815221Snishjain  emit_insn (gen_mix1_l (gen_lowpart (V8QImode, l1),
18915221Snishjain                         operands[1], CONST0_RTX (V8QImode)));
19015221Snishjain  emit_insn (gen_mix1_l (gen_lowpart (V8QImode, l2),
19115221Snishjain                         operands[2], CONST0_RTX (V8QImode)));
19215221Snishjain
19315221Snishjain  /* Multiply.  */
19415221Snishjain  rm = gen_reg_rtx (V4HImode);
19515221Snishjain  lm = gen_reg_rtx (V4HImode);
19615221Snishjain  emit_insn (gen_mulv4hi3 (rm, r1, r2));
1975918SN/A  emit_insn (gen_mulv4hi3 (lm, l1, l2));
1985918SN/A
19915221Snishjain  /* Zap the high order bytes of the HImode elements by overwriting those
20015221Snishjain     in one part with the low order bytes of the other.  */
20115221Snishjain  emit_insn (gen_mix1_r (operands[0],
20215221Snishjain                         gen_lowpart (V8QImode, rm),
20315221Snishjain                         gen_lowpart (V8QImode, lm)));
20415221Snishjain  DONE;
20515221Snishjain})
20615221Snishjain
20715221Snishjain(define_insn "mulv4hi3"
20815221Snishjain  [(set (match_operand:V4HI 0 "gr_register_operand" "=r")
20915221Snishjain	(mult:V4HI (match_operand:V4HI 1 "gr_register_operand" "r")
2105918SN/A		   (match_operand:V4HI 2 "gr_register_operand" "r")))]
21115221Snishjain  ""
2125918SN/A  "pmpyshr2 %0 = %1, %2, 0"
2135918SN/A  [(set_attr "itanium_class" "mmmul")])
21415221Snishjain
2155918SN/A(define_insn "pmpy2_r"
2165918SN/A  [(set (match_operand:V2SI 0 "gr_register_operand" "=r")
2175918SN/A	(mult:V2SI
2185918SN/A	  (vec_select:V2SI
21914848Snishjain	    (sign_extend:V4SI
2205918SN/A	      (match_operand:V4HI 1 "gr_register_operand" "r"))
2215918SN/A	    (parallel [(const_int 0) (const_int 2)]))
2225918SN/A	  (vec_select:V2SI
2235918SN/A	    (sign_extend:V4SI
2245918SN/A	      (match_operand:V4HI 2 "gr_register_operand" "r"))
2255918SN/A	    (parallel [(const_int 0) (const_int 2)]))))]
22615221Snishjain  ""
22715221Snishjain  "pmpy2.r %0 = %1, %2"
22815221Snishjain  [(set_attr "itanium_class" "mmshf")])
22915221Snishjain
23015221Snishjain(define_insn "pmpy2_l"
23115221Snishjain  [(set (match_operand:V2SI 0 "gr_register_operand" "=r")
2325918SN/A	(mult:V2SI
2335918SN/A	  (vec_select:V2SI
2345918SN/A	    (sign_extend:V4SI
2355918SN/A	      (match_operand:V4HI 1 "gr_register_operand" "r"))
2365918SN/A	    (parallel [(const_int 1) (const_int 3)]))
2375918SN/A	  (vec_select:V2SI
23815221Snishjain	    (sign_extend:V4SI
23915221Snishjain	      (match_operand:V4HI 2 "gr_register_operand" "r"))
24015221Snishjain	    (parallel [(const_int 1) (const_int 3)]))))]
24115221Snishjain  ""
24215221Snishjain  "pmpy2.l %0 = %1, %2"
24315221Snishjain  [(set_attr "itanium_class" "mmshf")])
24415221Snishjain
24515221Snishjain(define_expand "umax<mode>3"
24615221Snishjain  [(set (match_operand:VECINT 0 "gr_register_operand" "")
24715221Snishjain	(umax:VECINT (match_operand:VECINT 1 "gr_register_operand" "")
24815221Snishjain		     (match_operand:VECINT 2 "gr_register_operand" "")))]
24915221Snishjain  ""
25015221Snishjain{
25115221Snishjain  if (ia64_expand_vecint_minmax (UMAX, <MODE>mode, operands))
25215221Snishjain    DONE;
25315221Snishjain})
25415221Snishjain
25515221Snishjain(define_expand "smax<mode>3"
25615221Snishjain  [(set (match_operand:VECINT 0 "gr_register_operand" "")
25715221Snishjain	(smax:VECINT (match_operand:VECINT 1 "gr_reg_or_0_operand" "")
25815221Snishjain		     (match_operand:VECINT 2 "gr_reg_or_0_operand" "")))]
25915221Snishjain  ""
26015221Snishjain{
26115221Snishjain  if (ia64_expand_vecint_minmax (SMAX, <MODE>mode, operands))
26215221Snishjain    DONE;
26315221Snishjain})
26415221Snishjain
26515221Snishjain(define_expand "umin<mode>3"
26615221Snishjain  [(set (match_operand:VECINT 0 "gr_register_operand" "")
26715221Snishjain	(umin:VECINT (match_operand:VECINT 1 "gr_register_operand" "")
26815221Snishjain		     (match_operand:VECINT 2 "gr_register_operand" "")))]
26915221Snishjain  ""
27015221Snishjain{
27115221Snishjain  if (ia64_expand_vecint_minmax (UMIN, <MODE>mode, operands))
27215221Snishjain    DONE;
27315221Snishjain})
27415221Snishjain
27515221Snishjain(define_expand "smin<mode>3"
27615221Snishjain  [(set (match_operand:VECINT 0 "gr_register_operand" "")
27715221Snishjain	(smin:VECINT (match_operand:VECINT 1 "gr_reg_or_0_operand" "")
27815221Snishjain		     (match_operand:VECINT 2 "gr_reg_or_0_operand" "")))]
27915221Snishjain  ""
28015221Snishjain{
28115221Snishjain  if (ia64_expand_vecint_minmax (SMIN, <MODE>mode, operands))
28215221Snishjain    DONE;
28315221Snishjain})
28415221Snishjain
28515221Snishjain(define_insn "*umaxv8qi3"
28615221Snishjain  [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
28715221Snishjain	(umax:V8QI (match_operand:V8QI 1 "gr_register_operand" "r")
28815221Snishjain		   (match_operand:V8QI 2 "gr_register_operand" "r")))]
28915221Snishjain  ""
29015221Snishjain  "pmax1.u %0 = %1, %2"
29115221Snishjain  [(set_attr "itanium_class" "mmshf")])
29215221Snishjain
29315221Snishjain(define_insn "*smaxv4hi3"
29415221Snishjain  [(set (match_operand:V4HI 0 "gr_register_operand" "=r")
29515221Snishjain	(smax:V4HI (match_operand:V4HI 1 "gr_reg_or_0_operand" "rU")
29615221Snishjain		   (match_operand:V4HI 2 "gr_reg_or_0_operand" "rU")))]
29715221Snishjain  ""
29815221Snishjain  "pmax2 %0 = %r1, %r2"
29915221Snishjain  [(set_attr "itanium_class" "mmshf")])
30015221Snishjain
30115221Snishjain(define_insn "*uminv8qi3"
30215221Snishjain  [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
30315221Snishjain	(umin:V8QI (match_operand:V8QI 1 "gr_register_operand" "r")
30415221Snishjain		   (match_operand:V8QI 2 "gr_register_operand" "r")))]
30515221Snishjain  ""
30615221Snishjain  "pmin1.u %0 = %1, %2"
30715221Snishjain  [(set_attr "itanium_class" "mmshf")])
30815221Snishjain
30915221Snishjain(define_insn "*sminv4hi3"
31015221Snishjain  [(set (match_operand:V4HI 0 "gr_register_operand" "=r")
31115221Snishjain	(smin:V4HI (match_operand:V4HI 1 "gr_reg_or_0_operand" "rU")
31215221Snishjain		   (match_operand:V4HI 2 "gr_reg_or_0_operand" "rU")))]
31315221Snishjain  ""
31415221Snishjain  "pmin2 %0 = %r1, %r2"
31515221Snishjain  [(set_attr "itanium_class" "mmshf")])
31615221Snishjain
31715221Snishjain(define_insn "ashl<mode>3"
31815221Snishjain  [(set (match_operand:VECINT24 0 "gr_register_operand" "=r")
31915221Snishjain	(ashift:VECINT24
32015221Snishjain	  (match_operand:VECINT24 1 "gr_register_operand" "r")
3215918SN/A	  (match_operand:DI 2 "gr_reg_or_5bit_operand" "rn")))]
3225918SN/A  ""
3235918SN/A  "pshl<vecsize> %0 = %1, %2"
3245918SN/A  [(set_attr "itanium_class" "mmshf")])
3255918SN/A
3265918SN/A(define_insn "ashr<mode>3"
3275918SN/A  [(set (match_operand:VECINT24 0 "gr_register_operand" "=r")
3285918SN/A	(ashiftrt:VECINT24
3295918SN/A	  (match_operand:VECINT24 1 "gr_register_operand" "r")
3305918SN/A	  (match_operand:DI 2 "gr_reg_or_5bit_operand" "rn")))]
3315918SN/A  ""
3325918SN/A  "pshr<vecsize> %0 = %1, %2"
3335918SN/A  [(set_attr "itanium_class" "mmshf")])
3345918SN/A
3355918SN/A(define_insn "lshr<mode>3"
3365918SN/A  [(set (match_operand:VECINT24 0 "gr_register_operand" "=r")
3375918SN/A	(lshiftrt:VECINT24
3385918SN/A	  (match_operand:VECINT24 1 "gr_register_operand" "r")
3395918SN/A	  (match_operand:DI 2 "gr_reg_or_5bit_operand" "rn")))]
3405918SN/A  ""
3415918SN/A  "pshr<vecsize>.u %0 = %1, %2"
3425918SN/A  [(set_attr "itanium_class" "mmshf")])
3435918SN/A
3445918SN/A(define_expand "vec_shl_<mode>"
3455918SN/A  [(set (match_operand:VECINT 0 "gr_register_operand" "")
3465918SN/A	(ashift:DI (match_operand:VECINT 1 "gr_register_operand" "")
3475918SN/A		   (match_operand:DI 2 "gr_reg_or_6bit_operand" "")))]
3485918SN/A  ""
34915221Snishjain{
35015221Snishjain  operands[0] = gen_lowpart (DImode, operands[0]);
35115221Snishjain  operands[1] = gen_lowpart (DImode, operands[1]);
35215221Snishjain})
35315221Snishjain
35415221Snishjain(define_expand "vec_shr_<mode>"
35515221Snishjain  [(set (match_operand:VECINT 0 "gr_register_operand" "")
35615221Snishjain        (lshiftrt:DI (match_operand:VECINT 1 "gr_register_operand" "")
35715221Snishjain                     (match_operand:DI 2 "gr_reg_or_6bit_operand" "")))]
35815221Snishjain  ""
35915221Snishjain{
36015221Snishjain  operands[0] = gen_lowpart (DImode, operands[0]);
3615918SN/A  operands[1] = gen_lowpart (DImode, operands[1]);
3625918SN/A})
3635918SN/A
3645918SN/A(define_expand "widen_usumv8qi3"
3655918SN/A  [(match_operand:V4HI 0 "gr_register_operand" "")
3665918SN/A   (match_operand:V8QI 1 "gr_register_operand" "")
3675918SN/A   (match_operand:V4HI 2 "gr_register_operand" "")]
36816027Snishjain  ""
3695918SN/A{
3705918SN/A  ia64_expand_widen_sum (operands, true);
37114848Snishjain  DONE;
37215221Snishjain})
37315221Snishjain
3745918SN/A(define_expand "widen_usumv4hi3"
3755918SN/A  [(match_operand:V2SI 0 "gr_register_operand" "")
3765918SN/A   (match_operand:V4HI 1 "gr_register_operand" "")
3775918SN/A   (match_operand:V2SI 2 "gr_register_operand" "")]
3785918SN/A  ""
37915221Snishjain{
3805918SN/A  ia64_expand_widen_sum (operands, true);
3815918SN/A  DONE;
3825918SN/A})
3835918SN/A
3845918SN/A(define_expand "widen_ssumv8qi3"
3855918SN/A  [(match_operand:V4HI 0 "gr_register_operand" "")
38615221Snishjain   (match_operand:V8QI 1 "gr_register_operand" "")
38715221Snishjain   (match_operand:V4HI 2 "gr_register_operand" "")]
38815221Snishjain  ""
38915221Snishjain{
39015221Snishjain  ia64_expand_widen_sum (operands, false);
39115221Snishjain  DONE;
39215221Snishjain})
39315221Snishjain
39415221Snishjain(define_expand "widen_ssumv4hi3"
39515221Snishjain  [(match_operand:V2SI 0 "gr_register_operand" "")
39615221Snishjain   (match_operand:V4HI 1 "gr_register_operand" "")
39715221Snishjain   (match_operand:V2SI 2 "gr_register_operand" "")]
39815221Snishjain  ""
39915221Snishjain{
40015221Snishjain  ia64_expand_widen_sum (operands, false);
40115221Snishjain  DONE;
40216027Snishjain})
40315221Snishjain
40415221Snishjain(define_expand "udot_prodv8qi"
40515221Snishjain  [(match_operand:V2SI 0 "gr_register_operand" "")
40615221Snishjain   (match_operand:V8QI 1 "gr_register_operand" "")
40715221Snishjain   (match_operand:V8QI 2 "gr_register_operand" "")
40815221Snishjain   (match_operand:V2SI 3 "gr_register_operand" "")]
40915221Snishjain  ""
41015221Snishjain{
41115221Snishjain  ia64_expand_dot_prod_v8qi (operands, true);
41215221Snishjain  DONE;
41315221Snishjain})
41415221Snishjain
41515221Snishjain(define_expand "sdot_prodv8qi"
41615221Snishjain  [(match_operand:V2SI 0 "gr_register_operand" "")
41715221Snishjain   (match_operand:V8QI 1 "gr_register_operand" "")
41815221Snishjain   (match_operand:V8QI 2 "gr_register_operand" "")
41915221Snishjain   (match_operand:V2SI 3 "gr_register_operand" "")]
42015221Snishjain  ""
42115221Snishjain{
42215221Snishjain  ia64_expand_dot_prod_v8qi (operands, false);
42315221Snishjain  DONE;
42415221Snishjain})
42515221Snishjain
42615221Snishjain(define_expand "sdot_prodv4hi"
42715221Snishjain  [(match_operand:V2SI 0 "gr_register_operand" "")
42815221Snishjain   (match_operand:V4HI 1 "gr_register_operand" "")
42915221Snishjain   (match_operand:V4HI 2 "gr_register_operand" "")
43015221Snishjain   (match_operand:V2SI 3 "gr_register_operand" "")]
43115221Snishjain  ""
43215221Snishjain{
43315221Snishjain  rtx l, r, t;
43415221Snishjain
43515221Snishjain  r = gen_reg_rtx (V2SImode);
43615221Snishjain  l = gen_reg_rtx (V2SImode);
43715221Snishjain  t = gen_reg_rtx (V2SImode);
43815221Snishjain
43915221Snishjain  emit_insn (gen_pmpy2_r (r, operands[1], operands[2]));
44015221Snishjain  emit_insn (gen_pmpy2_l (l, operands[1], operands[2]));
44115221Snishjain  emit_insn (gen_addv2si3 (t, r, operands[3]));
44215221Snishjain  emit_insn (gen_addv2si3 (operands[0], t, l));
44315221Snishjain  DONE;
44415221Snishjain})
44515221Snishjain
44615221Snishjain(define_expand "vcond<mode>"
44715221Snishjain  [(set (match_operand:VECINT 0 "gr_register_operand" "")
44815221Snishjain	(if_then_else:VECINT
4495918SN/A	  (match_operator 3 "" 
45016027Snishjain	    [(match_operand:VECINT 4 "gr_reg_or_0_operand" "")
4515918SN/A	     (match_operand:VECINT 5 "gr_reg_or_0_operand" "")])
4525918SN/A	  (match_operand:VECINT 1 "gr_reg_or_0_operand" "")
4535918SN/A	  (match_operand:VECINT 2 "gr_reg_or_0_operand" "")))]
4545918SN/A  ""
4555918SN/A{
4565918SN/A  ia64_expand_vecint_cmov (operands);
4575918SN/A  DONE;
4585918SN/A})
4595918SN/A
4605918SN/A(define_expand "vcondu<mode>"
4615918SN/A  [(set (match_operand:VECINT 0 "gr_register_operand" "")
4625918SN/A	(if_then_else:VECINT
4635918SN/A	  (match_operator 3 "" 
4645918SN/A	    [(match_operand:VECINT 4 "gr_reg_or_0_operand" "")
4655918SN/A	     (match_operand:VECINT 5 "gr_reg_or_0_operand" "")])
4665918SN/A	  (match_operand:VECINT 1 "gr_reg_or_0_operand" "")
4675918SN/A	  (match_operand:VECINT 2 "gr_reg_or_0_operand" "")))]
4685918SN/A  ""
4695918SN/A{
4705918SN/A  ia64_expand_vecint_cmov (operands);
4715918SN/A  DONE;
4725918SN/A})
4735918SN/A
4745918SN/A(define_insn "*cmpeq_<mode>"
4755918SN/A  [(set (match_operand:VECINT 0 "gr_register_operand" "=r")
4765918SN/A	(eq:VECINT (match_operand:VECINT 1 "gr_reg_or_0_operand" "rU")
4775918SN/A		   (match_operand:VECINT 2 "gr_reg_or_0_operand" "rU")))]
4785918SN/A  ""
4795918SN/A  "pcmp<vecsize>.eq %0 = %r1, %r2"
4805918SN/A  [(set_attr "itanium_class" "mmalua")])
4815918SN/A
4825918SN/A(define_insn "*cmpgt_<mode>"
4835918SN/A  [(set (match_operand:VECINT 0 "gr_register_operand" "=r")
4845918SN/A	(gt:VECINT (match_operand:VECINT 1 "gr_reg_or_0_operand" "rU")
4855918SN/A		   (match_operand:VECINT 2 "gr_reg_or_0_operand" "rU")))]
4865918SN/A  ""
4875918SN/A  "pcmp<vecsize>.gt %0 = %r1, %r2"
4885918SN/A  [(set_attr "itanium_class" "mmalua")])
4895918SN/A
4905918SN/A(define_insn "pack2_sss"
4915918SN/A  [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
4925918SN/A	(vec_concat:V8QI
4935918SN/A	  (ss_truncate:V4QI
4945918SN/A	    (match_operand:V4HI 1 "gr_reg_or_0_operand" "rU"))
4955918SN/A	  (ss_truncate:V4QI
4965918SN/A	    (match_operand:V4HI 2 "gr_reg_or_0_operand" "rU"))))]
4975918SN/A  ""
4985918SN/A  "pack2.sss %0 = %r1, %r2"
4995918SN/A  [(set_attr "itanium_class" "mmshf")])
5005918SN/A
5015918SN/A(define_insn "*pack2_uss"
5025918SN/A  [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
5035918SN/A	(vec_concat:V8QI
5045918SN/A	  (us_truncate:V4QI
5055918SN/A	    (match_operand:V4HI 1 "gr_reg_or_0_operand" "rU"))
5065918SN/A	  (us_truncate:V4QI
5075918SN/A	    (match_operand:V4HI 2 "gr_reg_or_0_operand" "rU"))))]
5085918SN/A  ""
5095918SN/A  "pack2.uss %0 = %r1, %r2"
5105918SN/A  [(set_attr "itanium_class" "mmshf")])
5115918SN/A
5125918SN/A(define_insn "pack4_sss"
5135918SN/A  [(set (match_operand:V4HI 0 "gr_register_operand" "=r")
5145918SN/A	(vec_concat:V4HI
5155918SN/A	  (ss_truncate:V2HI
5165918SN/A	    (match_operand:V2SI 1 "gr_reg_or_0_operand" "rU"))
5175918SN/A	  (ss_truncate:V2HI
5185918SN/A	    (match_operand:V2SI 2 "gr_reg_or_0_operand" "rU"))))]
5195918SN/A  ""
5205918SN/A  "pack4.sss %0 = %r1, %r2"
5215918SN/A  [(set_attr "itanium_class" "mmshf")])
5225918SN/A
5235918SN/A(define_insn "unpack1_l"
5245918SN/A  [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
5255918SN/A	(vec_select:V8QI
5265918SN/A	  (vec_concat:V16QI
5275918SN/A	    (match_operand:V8QI 1 "gr_reg_or_0_operand" "rU")
5285918SN/A	    (match_operand:V8QI 2 "gr_reg_or_0_operand" "rU"))
5295918SN/A	  (parallel [(const_int 0)
5305918SN/A		     (const_int 1)
5315918SN/A		     (const_int 2)
5325918SN/A		     (const_int 3)
5335918SN/A		     (const_int 8)
5345918SN/A		     (const_int 9)
5355918SN/A		     (const_int 10)
5365918SN/A		     (const_int 11)])))]
5375918SN/A  ""
5385918SN/A  "unpack1.l %0 = %r2, %r1"
53916027Snishjain  [(set_attr "itanium_class" "mmshf")])
54016027Snishjain
54116027Snishjain(define_insn "unpack1_h"
54216027Snishjain  [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
54316027Snishjain	(vec_select:V8QI
54416027Snishjain	  (vec_concat:V16QI
54516027Snishjain	    (match_operand:V8QI 1 "gr_reg_or_0_operand" "rU")
54616027Snishjain	    (match_operand:V8QI 2 "gr_reg_or_0_operand" "rU"))
54716027Snishjain	  (parallel [(const_int 4)
54816027Snishjain		     (const_int 5)
54916027Snishjain		     (const_int 6)
55016027Snishjain		     (const_int 7)
55116027Snishjain		     (const_int 12)
55216027Snishjain		     (const_int 13)
55316027Snishjain		     (const_int 14)
5545918SN/A		     (const_int 15)])))]
5555918SN/A  ""
5565918SN/A  "unpack1.h %0 = %r2, %r1"
5575918SN/A  [(set_attr "itanium_class" "mmshf")])
5585918SN/A
5595918SN/A(define_insn "mix1_r"
5605918SN/A  [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
5615918SN/A	(vec_select:V8QI
56216027Snishjain	  (vec_concat:V16QI
56316027Snishjain	    (match_operand:V8QI 1 "gr_reg_or_0_operand" "rU")
5645918SN/A	    (match_operand:V8QI 2 "gr_reg_or_0_operand" "rU"))
5655918SN/A	  (parallel [(const_int 0)
56616027Snishjain		     (const_int 8)
5675918SN/A		     (const_int 2)
56816027Snishjain		     (const_int 10)
56916027Snishjain		     (const_int 4)
5705918SN/A		     (const_int 12)
57116027Snishjain		     (const_int 6)
5725918SN/A		     (const_int 14)])))]
5735918SN/A  ""
5745918SN/A  "mix1.r %0 = %r2, %r1"
5755918SN/A  [(set_attr "itanium_class" "mmshf")])
5765918SN/A
5775918SN/A(define_insn "mix1_l"
5785918SN/A  [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
5795918SN/A	(vec_select:V8QI
5805918SN/A	  (vec_concat:V16QI
5815918SN/A	    (match_operand:V8QI 1 "gr_reg_or_0_operand" "rU")
5825918SN/A	    (match_operand:V8QI 2 "gr_reg_or_0_operand" "rU"))
5835918SN/A	  (parallel [(const_int 1)
5845918SN/A		     (const_int 9)
5855918SN/A		     (const_int 3)
5865918SN/A		     (const_int 11)
5875918SN/A		     (const_int 5)
5885918SN/A		     (const_int 13)
5895918SN/A		     (const_int 7)
5905918SN/A		     (const_int 15)])))]
5915918SN/A  ""
5925918SN/A  "mix1.l %0 = %r2, %r1"
5935918SN/A  [(set_attr "itanium_class" "mmshf")])
5945918SN/A
5955918SN/A(define_insn "*mux1_rev"
5965918SN/A  [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
5975918SN/A	(vec_select:V8QI
5985918SN/A	  (match_operand:V8QI 1 "gr_register_operand" "r")
59916027Snishjain	  (parallel [(const_int 7)
60016027Snishjain		     (const_int 6)
60116027Snishjain		     (const_int 5)
6025918SN/A		     (const_int 4)
6035918SN/A		     (const_int 3)
6045918SN/A		     (const_int 2)
6055918SN/A		     (const_int 1)
6065918SN/A		     (const_int 0)])))]
6075918SN/A  ""
6085918SN/A  "mux1 %0 = %1, @rev"
6095918SN/A  [(set_attr "itanium_class" "mmshf")])
6105918SN/A
6115918SN/A(define_insn "*mux1_mix"
6125918SN/A  [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
6135918SN/A	(vec_select:V8QI
6145918SN/A	  (match_operand:V8QI 1 "gr_register_operand" "r")
6155918SN/A	  (parallel [(const_int 0)
6165918SN/A		     (const_int 4)
6175918SN/A		     (const_int 2)
6185918SN/A		     (const_int 6)
6195918SN/A		     (const_int 1)
6205918SN/A		     (const_int 5)
6215918SN/A		     (const_int 3)
6225918SN/A		     (const_int 7)])))]
6235918SN/A  ""
6245918SN/A  "mux1 %0 = %1, @mix"
6255918SN/A  [(set_attr "itanium_class" "mmshf")])
6265918SN/A
6275918SN/A(define_insn "*mux1_shuf"
6285918SN/A  [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
6295918SN/A	(vec_select:V8QI
6305918SN/A	  (match_operand:V8QI 1 "gr_register_operand" "r")
6315918SN/A	  (parallel [(const_int 0)
6325918SN/A		     (const_int 4)
6335918SN/A		     (const_int 1)
6345918SN/A		     (const_int 5)
6355918SN/A		     (const_int 2)
6365918SN/A		     (const_int 6)
63714848Snishjain		     (const_int 3)
6385918SN/A		     (const_int 7)])))]
6395918SN/A  ""
6405918SN/A  "mux1 %0 = %1, @shuf"
6415918SN/A  [(set_attr "itanium_class" "mmshf")])
6425918SN/A
6435918SN/A(define_insn "*mux1_alt"
6445918SN/A  [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
6455918SN/A	(vec_select:V8QI
6465918SN/A	  (match_operand:V8QI 1 "gr_register_operand" "r")
6475918SN/A	  (parallel [(const_int 0)
6485918SN/A		     (const_int 2)
6495918SN/A		     (const_int 4)
6505918SN/A		     (const_int 6)
6515918SN/A		     (const_int 1)
6525918SN/A		     (const_int 3)
65314848Snishjain		     (const_int 5)
6545918SN/A		     (const_int 7)])))]
6555918SN/A  ""
6565918SN/A  "mux1 %0 = %1, @alt"
6575918SN/A  [(set_attr "itanium_class" "mmshf")])
6585918SN/A
6595918SN/A(define_insn "*mux1_brcst_v8qi"
6605918SN/A  [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
6615918SN/A	(vec_select:V8QI
6625918SN/A	  (match_operand:V8QI 1 "gr_register_operand" "r")
6635918SN/A	  (parallel [(const_int 0)
6645918SN/A		     (const_int 0)
6655918SN/A		     (const_int 0)
6665918SN/A		     (const_int 0)
6675918SN/A		     (const_int 0)
6685918SN/A		     (const_int 0)
6695918SN/A		     (const_int 0)
6705918SN/A		     (const_int 0)])))]
6715918SN/A  ""
6725918SN/A  "mux1 %0 = %1, @brcst"
6735918SN/A  [(set_attr "itanium_class" "mmshf")])
6745918SN/A
6755918SN/A(define_insn "*mux1_brcst_qi"
6765918SN/A  [(set (match_operand:V8QI 0 "gr_register_operand" "=r")
6775918SN/A	(vec_duplicate:V8QI
6785918SN/A	  (match_operand:QI 1 "gr_register_operand" "r")))]
6795918SN/A  ""
6805918SN/A  "mux1 %0 = %1, @brcst"
681  [(set_attr "itanium_class" "mmshf")])
682
683(define_insn "unpack2_l"
684  [(set (match_operand:V4HI 0 "gr_register_operand" "=r")
685	(vec_select:V4HI
686	  (vec_concat:V8HI
687	    (match_operand:V4HI 1 "gr_reg_or_0_operand" "rU")
688	    (match_operand:V4HI 2 "gr_reg_or_0_operand" "rU"))
689	  (parallel [(const_int 0)
690		     (const_int 4)
691		     (const_int 1)
692		     (const_int 5)])))]
693  ""
694  "unpack2.l %0 = %r2, %r1"
695  [(set_attr "itanium_class" "mmshf")])
696
697(define_insn "unpack2_h"
698  [(set (match_operand:V4HI 0 "gr_register_operand" "=r")
699	(vec_select:V4HI
700	  (vec_concat:V8HI
701	    (match_operand:V4HI 1 "gr_reg_or_0_operand" "rU")
702	    (match_operand:V4HI 2 "gr_reg_or_0_operand" "rU"))
703	  (parallel [(const_int 2)
704		     (const_int 6)
705		     (const_int 3)
706		     (const_int 7)])))]
707  ""
708  "unpack2.h %0 = %r2, %r1"
709  [(set_attr "itanium_class" "mmshf")])
710
711(define_insn "*mix2_r"
712  [(set (match_operand:V4HI 0 "gr_register_operand" "=r")
713	(vec_select:V4HI
714	  (vec_concat:V8HI
715	    (match_operand:V4HI 1 "gr_reg_or_0_operand" "rU")
716	    (match_operand:V4HI 2 "gr_reg_or_0_operand" "rU"))
717	  (parallel [(const_int 0)
718		     (const_int 4)
719		     (const_int 2)
720		     (const_int 6)])))]
721  ""
722  "mix2.r %0 = %r2, %r1"
723  [(set_attr "itanium_class" "mmshf")])
724
725(define_insn "*mix2_l"
726  [(set (match_operand:V4HI 0 "gr_register_operand" "=r")
727	(vec_select:V4HI
728	  (vec_concat:V8HI
729	    (match_operand:V4HI 1 "gr_reg_or_0_operand" "rU")
730	    (match_operand:V4HI 2 "gr_reg_or_0_operand" "rU"))
731	  (parallel [(const_int 1)
732		     (const_int 5)
733		     (const_int 3)
734		     (const_int 7)])))]
735  ""
736  "mix2.l %0 = %r2, %r1"
737  [(set_attr "itanium_class" "mmshf")])
738
739(define_insn "*mux2"
740  [(set (match_operand:V4HI 0 "gr_register_operand" "=r")
741	(vec_select:V4HI
742	  (match_operand:V4HI 1 "gr_register_operand" "r")
743	  (parallel [(match_operand 2 "const_int_2bit_operand" "")
744		     (match_operand 3 "const_int_2bit_operand" "")
745		     (match_operand 4 "const_int_2bit_operand" "")
746		     (match_operand 5 "const_int_2bit_operand" "")])))]
747  ""
748{
749  int mask;
750  mask  = INTVAL (operands[2]);
751  mask |= INTVAL (operands[3]) << 2;
752  mask |= INTVAL (operands[4]) << 4;
753  mask |= INTVAL (operands[5]) << 6;
754  operands[2] = GEN_INT (mask);
755  return "%,mux2 %0 = %1, %2";
756}
757  [(set_attr "itanium_class" "mmshf")])
758
759(define_insn "*mux2_brcst_hi"
760  [(set (match_operand:V4HI 0 "gr_register_operand" "=r")
761	(vec_duplicate:V4HI
762	  (match_operand:HI 1 "gr_register_operand" "r")))]
763  ""
764  "mux2 %0 = %1, 0"
765  [(set_attr "itanium_class" "mmshf")])
766
767;; Note that mix4.r performs the exact same operation.
768(define_insn "*unpack4_l"
769  [(set (match_operand:V2SI 0 "gr_register_operand" "=r")
770	(vec_select:V2SI
771	  (vec_concat:V4SI
772	    (match_operand:V2SI 1 "gr_reg_or_0_operand" "rU")
773	    (match_operand:V2SI 2 "gr_reg_or_0_operand" "rU"))
774	  (parallel [(const_int 0)
775		     (const_int 2)])))]
776  ""
777  "unpack4.l %0 = %r2, %r1"
778  [(set_attr "itanium_class" "mmshf")])
779
780;; Note that mix4.l performs the exact same operation.
781(define_insn "*unpack4_h"
782  [(set (match_operand:V2SI 0 "gr_register_operand" "=r")
783	(vec_select:V2SI
784	  (vec_concat:V4SI
785	    (match_operand:V2SI 1 "gr_reg_or_0_operand" "rU")
786	    (match_operand:V2SI 2 "gr_reg_or_0_operand" "rU"))
787	  (parallel [(const_int 1)
788		     (const_int 3)])))]
789  ""
790  "unpack4.h %0 = %r2, %r1"
791  [(set_attr "itanium_class" "mmshf")])
792
793(define_expand "vec_initv2si"
794  [(match_operand:V2SI 0 "gr_register_operand" "")
795   (match_operand 1 "" "")]
796  ""
797{
798  rtx op1 = XVECEXP (operands[1], 0, 0);
799  rtx op2 = XVECEXP (operands[1], 0, 1);
800  rtx x;
801
802  if (GET_CODE (op1) == CONST_INT && GET_CODE (op2) == CONST_INT)
803    {
804      rtvec v = rtvec_alloc (2);
805      RTVEC_ELT (v, 0) = TARGET_BIG_ENDIAN ? op2 : op1;
806      RTVEC_ELT (v, 1) = TARGET_BIG_ENDIAN ? op1 : op2;;
807      x = gen_rtx_CONST_VECTOR (V2SImode, v);
808      emit_move_insn (operands[0], x);
809      DONE;
810    }
811
812  if (!gr_reg_or_0_operand (op1, SImode))
813    op1 = force_reg (SImode, op1);
814  if (!gr_reg_or_0_operand (op2, SImode))
815    op2 = force_reg (SImode, op2);
816
817  if (TARGET_BIG_ENDIAN)
818    x = gen_rtx_VEC_CONCAT (V2SImode, op2, op1);
819  else
820    x = gen_rtx_VEC_CONCAT (V2SImode, op1, op2);
821  emit_insn (gen_rtx_SET (VOIDmode, operands[0], x));
822  DONE;
823})
824
825(define_insn "*vecinit_v2si"
826  [(set (match_operand:V2SI 0 "gr_register_operand" "=r")
827	(vec_concat:V2SI
828	  (match_operand:SI 1 "gr_reg_or_0_operand" "rO")
829	  (match_operand:SI 2 "gr_reg_or_0_operand" "rO")))]
830  ""
831  "unpack4.l %0 = %r2, %r1"
832  [(set_attr "itanium_class" "mmshf")])
833
834;; Missing operations
835;; padd.uus
836;; pavg
837;; pavgsub
838;; pmpyshr, general form
839;; psad
840;; pshladd
841;; pshradd
842;; psub.uus
843
844;; Floating point vector operations
845
846(define_expand "movv2sf"
847  [(set (match_operand:V2SF 0 "general_operand" "")
848        (match_operand:V2SF 1 "general_operand" ""))]
849  ""
850{
851  rtx op1 = ia64_expand_move (operands[0], operands[1]);
852  if (!op1)
853    DONE;
854  operands[1] = op1;
855})
856
857(define_insn "*movv2sf_internal"
858  [(set (match_operand:V2SF 0 "destination_operand"
859					"=f,f,f,Q,*r ,*r,*r,*r,m ,f ,*r")
860	(match_operand:V2SF 1 "move_operand"
861					"fU,Y,Q,f,U*r,W ,i ,m ,*r,*r,f "))]
862  "ia64_move_ok (operands[0], operands[1])"
863{
864  static const char * const alt[] = {
865    "%,mov %0 = %F1",
866    "%,fpack %0 = %F2, %F1",
867    "%,ldf8 %0 = %1%P1",
868    "%,stf8 %0 = %1%P0",
869    "%,mov %0 = %r1",
870    "%,addl %0 = %v1, r0",
871    "%,movl %0 = %v1",
872    "%,ld8%O1 %0 = %1%P1",
873    "%,st8%Q0 %0 = %r1%P0",
874    "%,setf.sig %0 = %1",
875    "%,getf.sig %0 = %1"
876  };
877
878  if (which_alternative == 1)
879    {
880      operands[2] = XVECEXP (operands[1], 0, 1);
881      operands[1] = XVECEXP (operands[1], 0, 0);
882    }
883
884  return alt[which_alternative];
885}
886  [(set_attr "itanium_class" "fmisc,fmisc,fld,stf,ialu,ialu,long_i,ld,st,tofr,frfr")])
887
888(define_insn "absv2sf2"
889  [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
890	(abs:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")))]
891  ""
892  "fpabs %0 = %1"
893  [(set_attr "itanium_class" "fmisc")])
894
895(define_insn "negv2sf2"
896  [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
897	(neg:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")))]
898  ""
899  "fpneg %0 = %1"
900  [(set_attr "itanium_class" "fmisc")])
901
902(define_insn "*negabsv2sf2"
903  [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
904	(neg:V2SF
905	  (abs:V2SF (match_operand:V2SF 1 "fr_register_operand" "f"))))]
906  ""
907  "fpnegabs %0 = %1"
908  [(set_attr "itanium_class" "fmisc")])
909
910;; In order to convince combine to merge plus and mult to a useful fpma,
911;; we need a couple of extra patterns.
912(define_expand "addv2sf3"
913  [(parallel
914    [(set (match_operand:V2SF 0 "fr_register_operand" "")
915	  (plus:V2SF (match_operand:V2SF 1 "fr_register_operand" "")
916		     (match_operand:V2SF 2 "fr_register_operand" "")))
917     (use (match_dup 3))])]
918  ""
919{
920  rtvec v = gen_rtvec (2, CONST1_RTX (SFmode), CONST1_RTX (SFmode));
921  operands[3] = force_reg (V2SFmode, gen_rtx_CONST_VECTOR (V2SFmode, v));
922})
923
924;; The split condition here could be combine_completed, if we had such.
925(define_insn_and_split "*addv2sf3_1"
926  [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
927	(plus:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
928		   (match_operand:V2SF 2 "fr_register_operand" "f")))
929   (use (match_operand:V2SF 3 "fr_register_operand" "f"))]
930  ""
931  "#"
932  "reload_completed"
933  [(set (match_dup 0)
934	(plus:V2SF
935	  (mult:V2SF (match_dup 1) (match_dup 3))
936	  (match_dup 2)))]
937  "")
938
939(define_insn_and_split "*addv2sf3_2"
940  [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
941	(plus:V2SF
942	  (mult:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
943		     (match_operand:V2SF 2 "fr_register_operand" "f"))
944	  (match_operand:V2SF 3 "fr_register_operand" "f")))
945    (use (match_operand:V2SF 4 "" "X"))]
946  ""
947  "#"
948  ""
949  [(set (match_dup 0)
950	(plus:V2SF
951	  (mult:V2SF (match_dup 1) (match_dup 2))
952	  (match_dup 3)))]
953  "")
954
955;; In order to convince combine to merge minus and mult to a useful fpms,
956;; we need a couple of extra patterns.
957(define_expand "subv2sf3"
958  [(parallel
959    [(set (match_operand:V2SF 0 "fr_register_operand" "")
960	  (minus:V2SF (match_operand:V2SF 1 "fr_register_operand" "")
961		      (match_operand:V2SF 2 "fr_register_operand" "")))
962     (use (match_dup 3))])]
963  ""
964{
965  rtvec v = gen_rtvec (2, CONST1_RTX (SFmode), CONST1_RTX (SFmode));
966  operands[3] = force_reg (V2SFmode, gen_rtx_CONST_VECTOR (V2SFmode, v));
967})
968
969;; The split condition here could be combine_completed, if we had such.
970(define_insn_and_split "*subv2sf3_1"
971  [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
972	(minus:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
973		    (match_operand:V2SF 2 "fr_register_operand" "f")))
974   (use (match_operand:V2SF 3 "fr_register_operand" "f"))]
975  ""
976  "#"
977  "reload_completed"
978  [(set (match_dup 0)
979	(minus:V2SF
980	  (mult:V2SF (match_dup 1) (match_dup 3))
981	  (match_dup 2)))]
982  "")
983
984(define_insn_and_split "*subv2sf3_2"
985  [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
986	(minus:V2SF
987	  (mult:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
988		     (match_operand:V2SF 2 "fr_register_operand" "f"))
989	  (match_operand:V2SF 3 "fr_register_operand" "f")))
990    (use (match_operand:V2SF 4 "" "X"))]
991  ""
992  "#"
993  ""
994  [(set (match_dup 0)
995	(minus:V2SF
996	  (mult:V2SF (match_dup 1) (match_dup 2))
997	  (match_dup 3)))]
998  "")
999
1000(define_insn "mulv2sf3"
1001  [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
1002	(mult:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
1003		   (match_operand:V2SF 2 "fr_register_operand" "f")))]
1004  ""
1005  "fpmpy %0 = %1, %2"
1006  [(set_attr "itanium_class" "fmac")])
1007
1008(define_insn "*fpma"
1009  [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
1010	(plus:V2SF
1011	  (mult:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
1012		     (match_operand:V2SF 2 "fr_register_operand" "f"))
1013	  (match_operand:V2SF 3 "fr_register_operand" "f")))]
1014  ""
1015  "fpma %0 = %1, %2, %3"
1016  [(set_attr "itanium_class" "fmac")])
1017
1018(define_insn "*fpms"
1019  [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
1020	(minus:V2SF
1021	  (mult:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
1022		     (match_operand:V2SF 2 "fr_register_operand" "f"))
1023	  (match_operand:V2SF 3 "fr_register_operand" "f")))]
1024  ""
1025  "fpms %0 = %1, %2, %3"
1026  [(set_attr "itanium_class" "fmac")])
1027
1028(define_insn "*fpnmpy"
1029  [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
1030	(neg:V2SF
1031	  (mult:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
1032		     (match_operand:V2SF 2 "fr_register_operand" "f"))))]
1033  ""
1034  "fpnmpy %0 = %1, %2"
1035  [(set_attr "itanium_class" "fmac")])
1036
1037(define_insn "*fpnma"
1038  [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
1039	(plus:V2SF
1040	  (neg:V2SF
1041	    (mult:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
1042		       (match_operand:V2SF 2 "fr_register_operand" "f")))
1043	  (match_operand:V2SF 3 "fr_register_operand" "f")))]
1044  ""
1045  "fpnma %0 = %1, %2, %3"
1046  [(set_attr "itanium_class" "fmac")])
1047
1048(define_insn "smaxv2sf3"
1049  [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
1050	(smax:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
1051		   (match_operand:V2SF 2 "fr_register_operand" "f")))]
1052  ""
1053  "fpmax %0 = %1, %2"
1054  [(set_attr "itanium_class" "fmisc")])
1055
1056(define_insn "sminv2sf3"
1057  [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
1058	(smin:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
1059		   (match_operand:V2SF 2 "fr_register_operand" "f")))]
1060  ""
1061  "fpmin %0 = %1, %2"
1062  [(set_attr "itanium_class" "fmisc")])
1063
1064(define_expand "reduc_splus_v2sf"
1065  [(match_operand:V2SF 0 "fr_register_operand" "")
1066   (match_operand:V2SF 1 "fr_register_operand" "")]
1067  ""
1068{
1069  rtx tmp = gen_reg_rtx (V2SFmode);
1070  emit_insn (gen_fswap (tmp, operands[1], CONST0_RTX (V2SFmode)));
1071  emit_insn (gen_addv2sf3 (operands[0], operands[1], tmp));
1072  DONE;
1073})
1074
1075(define_expand "reduc_smax_v2sf"
1076  [(match_operand:V2SF 0 "fr_register_operand" "")
1077   (match_operand:V2SF 1 "fr_register_operand" "")]
1078  ""
1079{
1080  rtx tmp = gen_reg_rtx (V2SFmode);
1081  emit_insn (gen_fswap (tmp, operands[1], CONST0_RTX (V2SFmode)));
1082  emit_insn (gen_smaxv2sf3 (operands[0], operands[1], tmp));
1083  DONE;
1084})
1085
1086(define_expand "reduc_smin_v2sf"
1087  [(match_operand:V2SF 0 "fr_register_operand" "")
1088   (match_operand:V2SF 1 "fr_register_operand" "")]
1089  ""
1090{
1091  rtx tmp = gen_reg_rtx (V2SFmode);
1092  emit_insn (gen_fswap (tmp, operands[1], CONST0_RTX (V2SFmode)));
1093  emit_insn (gen_sminv2sf3 (operands[0], operands[1], tmp));
1094  DONE;
1095})
1096
1097(define_expand "vcondv2sf"
1098  [(set (match_operand:V2SF 0 "fr_register_operand" "")
1099	(if_then_else:V2SF
1100	  (match_operator 3 "" 
1101	    [(match_operand:V2SF 4 "fr_reg_or_0_operand" "")
1102	     (match_operand:V2SF 5 "fr_reg_or_0_operand" "")])
1103	  (match_operand:V2SF 1 "fr_reg_or_0_operand" "")
1104	  (match_operand:V2SF 2 "fr_reg_or_0_operand" "")))]
1105  ""
1106{
1107  rtx x, cmp;
1108
1109  cmp = gen_reg_rtx (V2SFmode);
1110  PUT_MODE (operands[3], V2SFmode);
1111  emit_insn (gen_rtx_SET (VOIDmode, cmp, operands[3]));
1112
1113  x = gen_rtx_IF_THEN_ELSE (V2SFmode, cmp, operands[1], operands[2]);
1114  emit_insn (gen_rtx_SET (VOIDmode, operands[0], x));
1115  DONE;
1116})
1117
1118(define_insn "*fpcmp"
1119  [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
1120	(match_operator:V2SF 3 "comparison_operator"
1121	  [(match_operand:V2SF 1 "fr_reg_or_0_operand" "fU")
1122	   (match_operand:V2SF 2 "fr_reg_or_0_operand" "fU")]))]
1123  ""
1124  "fpcmp.%D3 %0 = %F1, %F2"
1125  [(set_attr "itanium_class" "fmisc")])
1126
1127(define_insn "*fselect"
1128  [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
1129	(if_then_else:V2SF
1130	  (match_operand:V2SF 1 "fr_register_operand" "f")
1131	  (match_operand:V2SF 2 "fr_reg_or_0_operand" "fU")
1132	  (match_operand:V2SF 3 "fr_reg_or_0_operand" "fU")))]
1133  ""
1134  "fselect %0 = %F2, %F3, %1"
1135  [(set_attr "itanium_class" "fmisc")])
1136
1137(define_expand "vec_initv2sf"
1138  [(match_operand:V2SF 0 "fr_register_operand" "")
1139   (match_operand 1 "" "")]
1140  ""
1141{
1142  rtx op1 = XVECEXP (operands[1], 0, 0);
1143  rtx op2 = XVECEXP (operands[1], 0, 1);
1144  rtx x;
1145
1146  if (GET_CODE (op1) == CONST_DOUBLE && GET_CODE (op2) == CONST_DOUBLE)
1147    {
1148      x = gen_rtx_CONST_VECTOR (V2SFmode, XVEC (operands[1], 0));
1149      emit_move_insn (operands[0], x);
1150      DONE;
1151    }
1152
1153  if (!fr_reg_or_fp01_operand (op1, SFmode))
1154    op1 = force_reg (SFmode, op1);
1155  if (!fr_reg_or_fp01_operand (op2, SFmode))
1156    op2 = force_reg (SFmode, op2);
1157
1158  if (TARGET_BIG_ENDIAN)
1159    emit_insn (gen_fpack (operands[0], op2, op1));
1160  else
1161    emit_insn (gen_fpack (operands[0], op1, op2));
1162  DONE;
1163})
1164
1165(define_insn "fpack"
1166  [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
1167	(vec_concat:V2SF
1168	  (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")
1169	  (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
1170  ""
1171  "fpack %0 = %F2, %F1"
1172  [(set_attr "itanium_class" "fmisc")])
1173
1174(define_insn "fswap"
1175  [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
1176	(vec_select:V2SF
1177	  (vec_concat:V4SF
1178	    (match_operand:V2SF 1 "fr_reg_or_0_operand" "fU")
1179	    (match_operand:V2SF 2 "fr_reg_or_0_operand" "fU"))
1180	  (parallel [(const_int 1) (const_int 2)])))]
1181  ""
1182  "fswap %0 = %F1, %F2"
1183  [(set_attr "itanium_class" "fmisc")])
1184
1185(define_insn "*fmix_l"
1186  [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
1187	(vec_select:V2SF
1188	  (vec_concat:V4SF
1189	    (match_operand:V2SF 1 "fr_reg_or_0_operand" "fU")
1190	    (match_operand:V2SF 2 "fr_reg_or_0_operand" "fU"))
1191	  (parallel [(const_int 1) (const_int 3)])))]
1192  ""
1193  "fmix.l %0 = %F2, %F1"
1194  [(set_attr "itanium_class" "fmisc")])
1195
1196(define_insn "fmix_r"
1197  [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
1198	(vec_select:V2SF
1199	  (vec_concat:V4SF
1200	    (match_operand:V2SF 1 "fr_reg_or_0_operand" "fU")
1201	    (match_operand:V2SF 2 "fr_reg_or_0_operand" "fU"))
1202	  (parallel [(const_int 0) (const_int 2)])))]
1203  ""
1204  "fmix.r %0 = %F2, %F1"
1205  [(set_attr "itanium_class" "fmisc")])
1206
1207(define_insn "fmix_lr"
1208  [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
1209	(vec_select:V2SF
1210	  (vec_concat:V4SF
1211	    (match_operand:V2SF 1 "fr_reg_or_0_operand" "fU")
1212	    (match_operand:V2SF 2 "fr_reg_or_0_operand" "fU"))
1213	  (parallel [(const_int 0) (const_int 3)])))]
1214  ""
1215  "fmix.lr %0 = %F2, %F1"
1216  [(set_attr "itanium_class" "fmisc")])
1217
1218(define_expand "vec_setv2sf"
1219  [(match_operand:V2SF 0 "fr_register_operand" "")
1220   (match_operand:SF 1 "fr_register_operand" "")
1221   (match_operand 2 "const_int_operand" "")]
1222  ""
1223{
1224  rtx tmp = gen_reg_rtx (V2SFmode);
1225  emit_insn (gen_fpack (tmp, operands[1], CONST0_RTX (SFmode)));
1226
1227  switch (INTVAL (operands[2]))
1228    {
1229    case 0:
1230      emit_insn (gen_fmix_lr (operands[0], tmp, operands[0]));
1231      break;
1232    case 1:
1233      emit_insn (gen_fmix_r (operands[0], operands[0], tmp));
1234      break;
1235    default:
1236      gcc_unreachable ();
1237    }
1238  DONE;
1239})
1240
1241(define_insn_and_split "*vec_extractv2sf_0_le"
1242  [(set (match_operand:SF 0 "nonimmediate_operand" "=r,f,m")
1243	(unspec:SF [(match_operand:V2SF 1 "nonimmediate_operand" "rfm,rm,r")
1244		    (const_int 0)]
1245		   UNSPEC_VECT_EXTR))]
1246  "!TARGET_BIG_ENDIAN"
1247  "#"
1248  "reload_completed"
1249  [(set (match_dup 0) (match_dup 1))]
1250{
1251  if (REG_P (operands[1]) && FR_REGNO_P (REGNO (operands[1])))
1252    operands[0] = gen_rtx_REG (V2SFmode, REGNO (operands[0]));
1253  else if (MEM_P (operands[1]))
1254    operands[1] = adjust_address (operands[1], SFmode, 0);
1255  else
1256    operands[1] = gen_rtx_REG (SFmode, REGNO (operands[1]));
1257})
1258
1259(define_insn_and_split "*vec_extractv2sf_0_be"
1260  [(set (match_operand:SF 0 "register_operand" "=r,f")
1261	(unspec:SF [(match_operand:V2SF 1 "register_operand" "rf,r")
1262		    (const_int 0)]
1263		   UNSPEC_VECT_EXTR))]
1264  "TARGET_BIG_ENDIAN"
1265  "#"
1266  "reload_completed"
1267  [(set (match_dup 0) (match_dup 1))]
1268{
1269  if (REG_P (operands[1]) && FR_REGNO_P (REGNO (operands[1])))
1270    operands[0] = gen_rtx_REG (V2SFmode, REGNO (operands[0]));
1271  else
1272    operands[1] = gen_rtx_REG (SFmode, REGNO (operands[1]));
1273})
1274
1275(define_insn_and_split "*vec_extractv2sf_1"
1276  [(set (match_operand:SF 0 "register_operand" "=r")
1277	(unspec:SF [(match_operand:V2SF 1 "register_operand" "r")
1278		    (const_int 1)]
1279		   UNSPEC_VECT_EXTR))]
1280  ""
1281  "#"
1282  "reload_completed"
1283  [(const_int 0)]
1284{
1285  operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
1286  operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));
1287  if (TARGET_BIG_ENDIAN)
1288    emit_move_insn (operands[0], operands[1]);
1289  else
1290    emit_insn (gen_lshrdi3 (operands[0], operands[1], GEN_INT (32)));
1291  DONE;
1292})
1293
1294(define_expand "vec_extractv2sf"
1295  [(set (match_operand:SF 0 "register_operand" "")
1296	(unspec:SF [(match_operand:V2SF 1 "register_operand" "")
1297		    (match_operand:DI 2 "const_int_operand" "")]
1298		   UNSPEC_VECT_EXTR))]
1299  ""
1300  "")
1301
1302;; Missing operations
1303;; fprcpa
1304;; fpsqrta
1305