altivec: the last patch...plus the rest of the builtins

Aldy Hernandez aldyh@redhat.com
Thu Jan 10 19:27:00 GMT 2002


since it hasn't been approved yet, and i had some more stuff to add
to it...

here is the last patch plus...*sigh*... the rest of the builtins.

finally done.  now off to bug hunting, testing, and <altivec.h>.

tested on darwin.

ok to commit?

ps.  the builtins have become too many.  i'm going to start cleaning
up and writing functions to do the common tasks.  no sense duplicating
code all over.

2002-01-10  Aldy Hernandez  <aldyh@redhat.com>

	* config/rs6000/rs6000.c (altivec_init_builtins): Add support for
	lvebx, lvehx, lvewx, lvxl, lvx, stvx, stvebx, stvehx, stvewx,
	stvxl.
	(altivec_expand_builtin): Same.
	(altivec_expand_stv_builtin): New.

	* config/rs6000/rs6000.h (rs6000_builtins): Same.

	* config/rs6000/rs6000.md ("altivec_lvebx"): New.
	("altivec_lvehx"): New.
	("altivec_lvewx"): New.
	("altivec_lvxl"): New.
	("altivec_lvx"): New.
	("altivec_stvx"): New.
	("altivec_stvebx"): New.
	("altivec_stvehx"): New.
	("altivec_stvewx"): New.
	("altivec_stvxl"): New.

	* gcc.dg/altivec-4.c: Add tests for lvebx, lvehx, lvewx, lvxl,
	lvx, stvx, stvebx, stvehx, stvewx, stvxl.

Index: config/rs6000/rs6000.c
===================================================================
RCS file: /cvs/uberbaum/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.276
diff -c -p -r1.276 rs6000.c
*** rs6000.c	2002/01/10 02:51:01	1.276
--- rs6000.c	2002/01/11 03:20:31
*************** static rtx altivec_expand_builtin PARAMS
*** 164,169 ****
--- 164,170 ----
  static rtx altivec_expand_unop_builtin PARAMS ((enum insn_code, tree, rtx));
  static rtx altivec_expand_binop_builtin PARAMS ((enum insn_code, tree, rtx));
  static rtx altivec_expand_ternop_builtin PARAMS ((enum insn_code, tree, rtx));
+ static rtx altivec_expand_stv_builtin PARAMS ((enum insn_code, tree));
  static void rs6000_parse_abi_options PARAMS ((void));
  static int first_altivec_reg_to_save PARAMS ((void));
  static unsigned int compute_vrsave_mask PARAMS ((void));
*************** altivec_expand_binop_builtin (icode, arg
*** 3473,3479 ****
--- 3474,3516 ----
  
    return target;
  }
+ 
  static rtx
+ altivec_expand_stv_builtin (icode, arglist)
+      enum insn_code icode;
+      tree arglist;
+ {
+   tree arg0 = TREE_VALUE (arglist);
+   tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
+   tree arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
+   rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
+   rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
+   rtx op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
+   rtx pat;
+   enum machine_mode mode0 = insn_data[icode].operand[0].mode;
+   enum machine_mode mode1 = insn_data[icode].operand[1].mode;
+   enum machine_mode mode2 = insn_data[icode].operand[2].mode;
+ 
+   /* Invalid arguments.  Bail before doing anything stoopid!  */
+   if (arg0 == error_mark_node
+       || arg1 == error_mark_node
+       || arg2 == error_mark_node)
+     return NULL_RTX;
+ 
+   if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
+     op0 = copy_to_mode_reg (mode2, op0);
+   if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
+     op1 = copy_to_mode_reg (mode0, op1);
+   if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
+     op2 = copy_to_mode_reg (mode1, op2);
+ 
+   pat = GEN_FCN (icode) (op1, op2, op0);
+   if (pat)
+     emit_insn (pat);
+   return NULL_RTX;
+ }
+ 
+ static rtx
  altivec_expand_ternop_builtin (icode, arglist, target)
       enum insn_code icode;
       tree arglist;
*************** altivec_expand_builtin (exp, target)
*** 3693,3698 ****
--- 3730,3746 ----
  	emit_insn (pat);
        return NULL_RTX;
  
+     case ALTIVEC_BUILTIN_STVX:
+       return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, arglist);
+     case ALTIVEC_BUILTIN_STVEBX:
+       return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, arglist);
+     case ALTIVEC_BUILTIN_STVEHX:
+       return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, arglist);
+     case ALTIVEC_BUILTIN_STVEWX:
+       return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, arglist);
+     case ALTIVEC_BUILTIN_STVXL:
+       return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, arglist);
+   
      case ALTIVEC_BUILTIN_MFVSCR:
        icode = CODE_FOR_altivec_mfvscr;
        tmode = insn_data[icode].operand[0].mode;
*************** altivec_expand_builtin (exp, target)
*** 3798,3810 ****
      if (d->code == fcode)
        return altivec_expand_binop_builtin (d->icode, arglist, target);
  
!   /* LVS* are funky.  We initialized them differently.  */
!   if (fcode == ALTIVEC_BUILTIN_LVSL)
!     return altivec_expand_binop_builtin (CODE_FOR_altivec_lvsl,
! 					 arglist, target);
!   if (fcode == ALTIVEC_BUILTIN_LVSR)
!     return altivec_expand_binop_builtin (CODE_FOR_altivec_lvsr,
! 					 arglist, target);
  
    /* Handle simple ternary operations.  */
    d = (struct builtin_description *) bdesc_3arg;
--- 3846,3879 ----
      if (d->code == fcode)
        return altivec_expand_binop_builtin (d->icode, arglist, target);
  
!   /* LV* are funky.  We initialized them differently.  */
!   switch (fcode)
!     {
!     case ALTIVEC_BUILTIN_LVSL:
!       return altivec_expand_binop_builtin (CODE_FOR_altivec_lvsl,
! 					   arglist, target);
!     case ALTIVEC_BUILTIN_LVSR:
!       return altivec_expand_binop_builtin (CODE_FOR_altivec_lvsr,
! 					   arglist, target);
!     case ALTIVEC_BUILTIN_LVEBX:
!       return altivec_expand_binop_builtin (CODE_FOR_altivec_lvebx,
! 					   arglist, target);
!     case ALTIVEC_BUILTIN_LVEHX:
!       return altivec_expand_binop_builtin (CODE_FOR_altivec_lvehx,
! 					   arglist, target);
!     case ALTIVEC_BUILTIN_LVEWX:
!       return altivec_expand_binop_builtin (CODE_FOR_altivec_lvewx,
! 					   arglist, target);
!     case ALTIVEC_BUILTIN_LVXL:
!       return altivec_expand_binop_builtin (CODE_FOR_altivec_lvxl,
! 					   arglist, target);
!     case ALTIVEC_BUILTIN_LVX:
!       return altivec_expand_binop_builtin (CODE_FOR_altivec_lvx,
! 					   arglist, target);
!     default:
!       break;
!       /* Fall through.  */
!     }
  
    /* Handle simple ternary operations.  */
    d = (struct builtin_description *) bdesc_3arg;
*************** altivec_init_builtins (void)
*** 3967,3972 ****
--- 4036,4068 ----
  			   tree_cons (NULL_TREE, V4SI_type_node,
  				      endlink));
  
+   /* void foo (vint, int, void *).  */
+   tree void_ftype_v4si_int_pvoid
+     = build_function_type (void_type_node,
+ 			   tree_cons (NULL_TREE, V4SI_type_node,
+ 				      tree_cons (NULL_TREE, integer_type_node,
+ 						 tree_cons (NULL_TREE,
+ 							    pvoid_type_node,
+ 							    endlink))));
+ 
+   /* void foo (vchar, int, void *).  */
+   tree void_ftype_v16qi_int_pvoid
+     = build_function_type (void_type_node,
+ 			   tree_cons (NULL_TREE, V16QI_type_node,
+ 				      tree_cons (NULL_TREE, integer_type_node,
+ 						 tree_cons (NULL_TREE,
+ 							    pvoid_type_node,
+ 							    endlink))));
+ 
+   /* void foo (vshort, int, void *).  */
+   tree void_ftype_v8hi_int_pvoid
+     = build_function_type (void_type_node,
+ 			   tree_cons (NULL_TREE, V8HI_type_node,
+ 				      tree_cons (NULL_TREE, integer_type_node,
+ 						 tree_cons (NULL_TREE,
+ 							    pvoid_type_node,
+ 							    endlink))));
+ 
    /* void foo (char).  */
    tree void_ftype_qi
      = build_function_type (void_type_node,
*************** altivec_init_builtins (void)
*** 4191,4196 ****
--- 4287,4304 ----
  				      tree_cons (NULL_TREE, pvoid_type_node,
  						 endlink)));
  
+   tree v4si_ftype_int_pvoid
+     = build_function_type (V4SI_type_node,
+ 			   tree_cons (NULL_TREE, integer_type_node,
+ 				      tree_cons (NULL_TREE, pvoid_type_node,
+ 						 endlink)));
+ 
+   tree v8hi_ftype_int_pvoid
+     = build_function_type (V8HI_type_node,
+ 			   tree_cons (NULL_TREE, integer_type_node,
+ 				      tree_cons (NULL_TREE, pvoid_type_node,
+ 						 endlink)));
+ 
    tree int_ftype_v8hi_v8hi
      = build_function_type (integer_type_node,
  			   tree_cons (NULL_TREE, V8HI_type_node,
*************** altivec_init_builtins (void)
*** 4211,4217 ****
    def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_qi, ALTIVEC_BUILTIN_DSS);
    def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_int_pvoid, ALTIVEC_BUILTIN_LVSL);
    def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_int_pvoid, ALTIVEC_BUILTIN_LVSR);
! 
    /* Add the simple ternary operators.  */
    d = (struct builtin_description *) bdesc_3arg;
    for (i = 0; i < sizeof (bdesc_3arg) / sizeof *d; i++, d++)
--- 4319,4335 ----
    def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_qi, ALTIVEC_BUILTIN_DSS);
    def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_int_pvoid, ALTIVEC_BUILTIN_LVSL);
    def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_int_pvoid, ALTIVEC_BUILTIN_LVSR);
!   def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_int_pvoid, ALTIVEC_BUILTIN_LVEBX);
!   def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_int_pvoid, ALTIVEC_BUILTIN_LVEHX);
!   def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_int_pvoid, ALTIVEC_BUILTIN_LVEWX);
!   def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_int_pvoid, ALTIVEC_BUILTIN_LVXL);
!   def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_int_pvoid, ALTIVEC_BUILTIN_LVX);
!   def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_int_pvoid, ALTIVEC_BUILTIN_STVX);
!   def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_int_pvoid, ALTIVEC_BUILTIN_STVEBX);
!   def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_int_pvoid, ALTIVEC_BUILTIN_STVEHX);
!   def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_int_pvoid, ALTIVEC_BUILTIN_STVEWX);
!   def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_int_pvoid, ALTIVEC_BUILTIN_STVXL);
!   
    /* Add the simple ternary operators.  */
    d = (struct builtin_description *) bdesc_3arg;
    for (i = 0; i < sizeof (bdesc_3arg) / sizeof *d; i++, d++)
Index: config/rs6000/rs6000.h
===================================================================
RCS file: /cvs/uberbaum/gcc/config/rs6000/rs6000.h,v
retrieving revision 1.172
diff -c -p -r1.172 rs6000.h
*** rs6000.h	2002/01/10 02:51:01	1.172
--- rs6000.h	2002/01/11 03:20:36
*************** enum rs6000_builtins
*** 2977,2981 ****
    ALTIVEC_BUILTIN_DSTT,
    ALTIVEC_BUILTIN_DSTST,
    ALTIVEC_BUILTIN_DSTSTT,
!   ALTIVEC_BUILTIN_DST
  };
--- 2977,2991 ----
    ALTIVEC_BUILTIN_DSTT,
    ALTIVEC_BUILTIN_DSTST,
    ALTIVEC_BUILTIN_DSTSTT,
!   ALTIVEC_BUILTIN_DST,
!   ALTIVEC_BUILTIN_LVEBX,
!   ALTIVEC_BUILTIN_LVEHX,
!   ALTIVEC_BUILTIN_LVEWX,
!   ALTIVEC_BUILTIN_LVXL,
!   ALTIVEC_BUILTIN_LVX,
!   ALTIVEC_BUILTIN_STVX,
!   ALTIVEC_BUILTIN_STVEBX,
!   ALTIVEC_BUILTIN_STVEHX,
!   ALTIVEC_BUILTIN_STVEWX,
!   ALTIVEC_BUILTIN_STVXL
  };
Index: config/rs6000/rs6000.md
===================================================================
RCS file: /cvs/uberbaum/gcc/config/rs6000/rs6000.md,v
retrieving revision 1.155
diff -c -p -r1.155 rs6000.md
*** rs6000.md	2002/01/10 02:51:02	1.155
--- rs6000.md	2002/01/11 03:20:40
***************
*** 15473,15475 ****
--- 15473,15568 ----
    "TARGET_ALTIVEC"
    "lvsr %0,%1,%2"
    [(set_attr "type" "vecload")])
+ 
+ (define_insn "altivec_lvebx"
+   [(set (match_operand:V16QI 0 "register_operand" "=v")
+ 	(unspec:V16QI [(match_operand:SI 1 "register_operand" "r")
+ 		       (match_operand:SI 2 "register_operand" "r")] 196))]
+   "TARGET_ALTIVEC"
+   "lvebx %0,%1,%2"
+   [(set_attr "type" "vecload")])
+ 
+ (define_insn "altivec_lvehx"
+   [(set (match_operand:V8HI 0 "register_operand" "=v")
+ 	(unspec:V8HI [(match_operand:SI 1 "register_operand" "r")
+ 		      (match_operand:SI 2 "register_operand" "r")] 197))]
+   "TARGET_ALTIVEC"
+   "lvehx %0,%1,%2"
+   [(set_attr "type" "vecload")])
+ 
+ (define_insn "altivec_lvewx"
+   [(set (match_operand:V4SI 0 "register_operand" "=v")
+ 	(unspec:V4SI [(match_operand:SI 1 "register_operand" "r")
+ 		      (match_operand:SI 2 "register_operand" "r")] 198))]
+   "TARGET_ALTIVEC"
+   "lvewx %0,%1,%2"
+   [(set_attr "type" "vecload")])
+ 
+ (define_insn "altivec_lvxl"
+   [(set (match_operand:V4SI 0 "register_operand" "=v")
+ 	(unspec:V4SI [(match_operand:SI 1 "register_operand" "r")
+ 		      (match_operand:SI 2 "register_operand" "r")] 199))]
+   "TARGET_ALTIVEC"
+   "lvxl %0,%1,%2"
+   [(set_attr "type" "vecload")])
+ 
+ (define_insn "altivec_lvx"
+   [(set (match_operand:V4SI 0 "register_operand" "=v")
+ 	(unspec:V4SI [(match_operand:SI 1 "register_operand" "r")
+ 		      (match_operand:SI 2 "register_operand" "r")] 200))]
+   "TARGET_ALTIVEC"
+   "lvx %0,%1,%2"
+   [(set_attr "type" "vecload")])
+ 
+ (define_insn "altivec_stvx"
+   [(set (mem:V4SI
+ 	 (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
+ 			  (match_operand:SI 1 "register_operand" "r"))
+ 		 (const_int -16)))
+ 	(match_operand:V4SI 2 "register_operand" "v"))]
+   "TARGET_ALTIVEC"
+   "stvx %2,%0,%1"
+   [(set_attr "type" "vecstore")])
+ 
+ (define_insn "altivec_stvxl"
+   [(parallel
+     [(set (mem:V4SI
+ 	   (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
+ 			    (match_operand:SI 1 "register_operand" "r"))
+ 		   (const_int -16)))
+ 	  (match_operand:V4SI 2 "register_operand" "v"))
+      (unspec [(const_int 0)] 201)])]
+   "TARGET_ALTIVEC"
+   "stvxl %2,%0,%1"
+   [(set_attr "type" "vecstore")])
+ 
+ (define_insn "altivec_stvebx"
+   [(parallel
+     [(set (mem:V16QI
+ 	   (plus:SI (match_operand:SI 0 "register_operand" "r")
+ 		    (match_operand:SI 1 "register_operand" "r")))
+ 	  (match_operand:V16QI 2 "register_operand" "v"))
+      (unspec [(const_int 0)] 202)])]
+   "TARGET_ALTIVEC"
+   "stvebx %2,%0,%1"
+   [(set_attr "type" "vecstore")])
+ 
+ (define_insn "altivec_stvehx"
+   [(set (mem:V8HI
+ 	 (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
+ 			  (match_operand:SI 1 "register_operand" "r"))
+ 		 (const_int -2)))
+ 	(match_operand:V8HI 2 "register_operand" "v"))]
+   "TARGET_ALTIVEC"
+   "stvehx %2,%0,%1"
+   [(set_attr "type" "vecstore")])
+ 
+ (define_insn "altivec_stvewx"
+   [(set (mem:V4SI
+ 	 (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
+ 			  (match_operand:SI 1 "register_operand" "r"))
+ 		 (const_int -4)))
+ 	(match_operand:V4SI 2 "register_operand" "v"))]
+   "TARGET_ALTIVEC"
+   "stvewx %2,%0,%1"
+   [(set_attr "type" "vecstore")])
Index: testsuite/gcc.dg/altivec-4.c
===================================================================
RCS file: /cvs/uberbaum/gcc/testsuite/gcc.dg/altivec-4.c,v
retrieving revision 1.4
diff -c -p -r1.4 altivec-4.c
*** altivec-4.c	2002/01/10 02:54:12	1.4
--- altivec-4.c	2002/01/11 03:20:40
*************** b()
*** 49,52 ****
--- 49,64 ----
  
    uc = (vector unsigned char) __builtin_altivec_lvsl (int1 + 69, pi);
    uc = (vector unsigned char) __builtin_altivec_lvsr (int1 + 69, pi);
+ 
+   c = __builtin_altivec_lvebx (int1, pi);
+   s = __builtin_altivec_lvehx (int1, pi);
+   i = __builtin_altivec_lvewx (int1, pi);
+   i = __builtin_altivec_lvxl (int1, pi);
+   i = __builtin_altivec_lvx (int1, pi);
+ 
+   __builtin_altivec_stvx (i, int2, pi);
+   __builtin_altivec_stvebx (c, int2, pi);
+   __builtin_altivec_stvehx (s, int2, pi);
+   __builtin_altivec_stvewx (i, int2, pi);
+   __builtin_altivec_stvxl (i, int2, pi);
  }



More information about the Gcc-patches mailing list