This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

patch: cleanup PPC builtins


the PPC builtins have exponentially grown, and boy are they ugly
to look at!

i've been looking over the code coming up with ways of simplifying things.

here's a start.  i'm moving a lot of the common, but not trivial,
builtins into separate functions and trying to group by functionality.

boring patch, but removes some complexity.  there are 4 new functions,
but the net loss in source lines is still about 16.  yay!

in the long run we really need to come up with some auto-magical way
of generating the trivial builtins with rtl annotations.  i already have a 
plan... :)

regtested on ppc-linux.

ok?

2002-06-27  Aldy Hernandez  <aldyh@redhat.com>

	* config/rs6000/rs6000.c (altivec_expand_builtin): Move
	lvx/stv/dst builtins...
	(altivec_expand_ld_builtin): ...to here.
	(altivec_expand_st_builtin): ...here.
	(altivec_expand_dst_builtin): ...and here (respectively).

Index: config/rs6000/rs6000.c
===================================================================
RCS file: /cvs/uberbaum/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.333
diff -c -p -r1.333 rs6000.c
*** config/rs6000/rs6000.c	28 Jun 2002 04:21:17 -0000	1.333
--- config/rs6000/rs6000.c	28 Jun 2002 16:17:29 -0000
*************** static rtx rs6000_expand_ternop_builtin 
*** 192,197 ****
--- 192,200 ----
  static rtx rs6000_expand_builtin PARAMS ((tree, rtx, rtx, enum machine_mode, int));
  static void altivec_init_builtins PARAMS ((void));
  static rtx altivec_expand_builtin PARAMS ((tree, rtx, bool *));
+ static rtx altivec_expand_ld_builtin PARAMS ((tree, rtx, bool *));
+ static rtx altivec_expand_st_builtin PARAMS ((tree, rtx, bool *));
+ static rtx altivec_expand_dst_builtin PARAMS ((tree, rtx, bool *));
  static rtx altivec_expand_abs_builtin PARAMS ((enum insn_code, tree, rtx));
  static rtx altivec_expand_predicate_builtin PARAMS ((enum insn_code, const char *, tree, rtx));
  static rtx altivec_expand_stv_builtin PARAMS ((enum insn_code, tree));
*************** rs6000_expand_ternop_builtin (icode, arg
*** 3888,4076 ****
    return target;
  }
  
- /* Expand the builtin in EXP and store the result in TARGET.  Store
-    true in *EXPANDEDP if we found a builtin to expand.  */
  static rtx
! altivec_expand_builtin (exp, target, expandedp)
       tree exp;
       rtx target;
       bool *expandedp;
  {
-   struct builtin_description *d;
-   struct builtin_description_predicates *dp;
-   size_t i;
-   enum insn_code icode;
    tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
    tree arglist = TREE_OPERAND (exp, 1);
-   tree arg0, arg1, arg2;
-   rtx op0, op1, op2, pat;
-   enum machine_mode tmode, mode0, mode1, mode2;
    unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
! 
!   *expandedp = true;
  
    switch (fcode)
      {
      case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
        icode = CODE_FOR_altivec_lvx_16qi;
!       arg0 = TREE_VALUE (arglist);
!       op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
!       tmode = insn_data[icode].operand[0].mode;
!       mode0 = insn_data[icode].operand[1].mode;
! 
!       if (target == 0
! 	  || GET_MODE (target) != tmode
! 	  || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
! 	target = gen_reg_rtx (tmode);
! 
!       if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
! 	op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
! 
!       pat = GEN_FCN (icode) (target, op0);
!       if (! pat)
! 	return 0;
!       emit_insn (pat);
!       return target;
! 
      case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
        icode = CODE_FOR_altivec_lvx_8hi;
!       arg0 = TREE_VALUE (arglist);
!       op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
!       tmode = insn_data[icode].operand[0].mode;
!       mode0 = insn_data[icode].operand[1].mode;
! 
!       if (target == 0
! 	  || GET_MODE (target) != tmode
! 	  || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
! 	target = gen_reg_rtx (tmode);
! 
!       if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
! 	op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
! 
!       pat = GEN_FCN (icode) (target, op0);
!       if (! pat)
! 	return 0;
!       emit_insn (pat);
!       return target;
! 
      case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
        icode = CODE_FOR_altivec_lvx_4si;
!       arg0 = TREE_VALUE (arglist);
!       op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
!       tmode = insn_data[icode].operand[0].mode;
!       mode0 = insn_data[icode].operand[1].mode;
! 
!       if (target == 0
! 	  || GET_MODE (target) != tmode
! 	  || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
! 	target = gen_reg_rtx (tmode);
  
!       if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
! 	op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
  
!       pat = GEN_FCN (icode) (target, op0);
!       if (! pat)
! 	return 0;
!       emit_insn (pat);
!       return target;
  
!     case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
!       icode = CODE_FOR_altivec_lvx_4sf;
!       arg0 = TREE_VALUE (arglist);
!       op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
!       tmode = insn_data[icode].operand[0].mode;
!       mode0 = insn_data[icode].operand[1].mode;
  
!       if (target == 0
! 	  || GET_MODE (target) != tmode
! 	  || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
! 	target = gen_reg_rtx (tmode);
  
!       if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
! 	op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
  
!       pat = GEN_FCN (icode) (target, op0);
!       if (! pat)
! 	return 0;
!       emit_insn (pat);
!       return target;
  
      case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
        icode = CODE_FOR_altivec_stvx_16qi;
!       arg0 = TREE_VALUE (arglist);
!       arg1 = TREE_VALUE (TREE_CHAIN (arglist));
!       op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
!       op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
!       mode0 = insn_data[icode].operand[0].mode;
!       mode1 = insn_data[icode].operand[1].mode;
  
!       if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
! 	op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
!       if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
! 	op1 = copy_to_mode_reg (mode1, op1);
  
!       pat = GEN_FCN (icode) (op0, op1);
!       if (pat)
! 	emit_insn (pat);
!       return NULL_RTX;
  
!     case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
!       icode = CODE_FOR_altivec_stvx_8hi;
!       arg0 = TREE_VALUE (arglist);
!       arg1 = TREE_VALUE (TREE_CHAIN (arglist));
!       op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
!       op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
!       mode0 = insn_data[icode].operand[0].mode;
!       mode1 = insn_data[icode].operand[1].mode;
  
!       if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
! 	op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
!       if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
! 	op1 = copy_to_mode_reg (mode1, op1);
  
!       pat = GEN_FCN (icode) (op0, op1);
!       if (pat)
! 	emit_insn (pat);
!       return NULL_RTX;
  
!     case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
!       icode = CODE_FOR_altivec_stvx_4si;
!       arg0 = TREE_VALUE (arglist);
!       arg1 = TREE_VALUE (TREE_CHAIN (arglist));
!       op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
!       op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
!       mode0 = insn_data[icode].operand[0].mode;
!       mode1 = insn_data[icode].operand[1].mode;
  
!       if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
! 	op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
!       if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
! 	op1 = copy_to_mode_reg (mode1, op1);
  
!       pat = GEN_FCN (icode) (op0, op1);
!       if (pat)
! 	emit_insn (pat);
!       return NULL_RTX;
  
!     case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
!       icode = CODE_FOR_altivec_stvx_4sf;
!       arg0 = TREE_VALUE (arglist);
!       arg1 = TREE_VALUE (TREE_CHAIN (arglist));
!       op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
!       op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
!       mode0 = insn_data[icode].operand[0].mode;
!       mode1 = insn_data[icode].operand[1].mode;
  
!       if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
! 	op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
!       if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
! 	op1 = copy_to_mode_reg (mode1, op1);
  
!       pat = GEN_FCN (icode) (op0, op1);
!       if (pat)
! 	emit_insn (pat);
!       return NULL_RTX;
  
      case ALTIVEC_BUILTIN_STVX:
        return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, arglist);
      case ALTIVEC_BUILTIN_STVEBX:
--- 3891,4100 ----
    return target;
  }
  
  static rtx
! altivec_expand_ld_builtin (exp, target, expandedp)
       tree exp;
       rtx target;
       bool *expandedp;
  {
    tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
    tree arglist = TREE_OPERAND (exp, 1);
    unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
!   tree arg0;
!   enum machine_mode tmode, mode0;
!   rtx pat, target, op0;
!   enum insn_code icode;
  
    switch (fcode)
      {
      case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
        icode = CODE_FOR_altivec_lvx_16qi;
!       break;
      case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
        icode = CODE_FOR_altivec_lvx_8hi;
!       break;
      case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
        icode = CODE_FOR_altivec_lvx_4si;
!       break;
!     case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
!       icode = CODE_FOR_altivec_lvx_4sf;
!       break;
!     default:
!       *expandedp = false;
!       return NULL_RTX;
!     }
  
!   *expandedp = true;
  
!   arg0 = TREE_VALUE (arglist);
!   op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
!   tmode = insn_data[icode].operand[0].mode;
!   mode0 = insn_data[icode].operand[1].mode;
  
!   if (target == 0
!       || GET_MODE (target) != tmode
!       || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
!     target = gen_reg_rtx (tmode);
  
!   if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
!     op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
  
!   pat = GEN_FCN (icode) (target, op0);
!   if (! pat)
!     return 0;
!   emit_insn (pat);
!   return target;
! }
  
! static rtx
! altivec_expand_st_builtin (exp, target, expandedp)
!      tree exp;
!      rtx target;
!      bool *expandedp;
! {
!   tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
!   tree arglist = TREE_OPERAND (exp, 1);
!   unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
!   tree arg0, arg1;
!   enum machine_mode mode0, mode1;
!   rtx pat, target, op0, op1;
!   enum insn_code icode;
  
+   switch (fcode)
+     {
      case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
        icode = CODE_FOR_altivec_stvx_16qi;
!       break;
!     case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
!       icode = CODE_FOR_altivec_stvx_8hi;
!       break;
!     case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
!       icode = CODE_FOR_altivec_stvx_4si;
!       break;
!     case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
!       icode = CODE_FOR_altivec_stvx_4sf;
!       break;
!     default:
!       *expandedp = false;
!       return NULL_RTX;
!     }
  
!   arg0 = TREE_VALUE (arglist);
!   arg1 = TREE_VALUE (TREE_CHAIN (arglist));
!   op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
!   op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
!   mode0 = insn_data[icode].operand[0].mode;
!   mode1 = insn_data[icode].operand[1].mode;
! 
!   if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
!     op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
!   if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
!     op1 = copy_to_mode_reg (mode1, op1);
  
!   pat = GEN_FCN (icode) (op0, op1);
!   if (pat)
!     emit_insn (pat);
  
!   *expandedp = true;
!   return NULL_RTX;
! }
  
! static rtx
! altivec_expand_dst_builtin (exp, target, expandedp)
!      tree exp;
!      rtx target;
!      bool *expandedp;
! {
!   tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
!   tree arglist = TREE_OPERAND (exp, 1);
!   unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
!   tree arg0, arg1, arg2;
!   enum machine_mode mode0, mode1, mode2;
!   rtx pat, target, op0, op1, op2;
!   struct builtin_description *d;
!   int i;
  
!   *expandedp = false;
  
!   /* Handle DST variants.  */
!   d = (struct builtin_description *) bdesc_dst;
!   for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
!     if (d->code == fcode)
!       {
! 	arg0 = TREE_VALUE (arglist);
! 	arg1 = TREE_VALUE (TREE_CHAIN (arglist));
! 	arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
! 	op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
! 	op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
! 	op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
! 	mode0 = insn_data[d->icode].operand[0].mode;
! 	mode1 = insn_data[d->icode].operand[1].mode;
! 	mode2 = insn_data[d->icode].operand[2].mode;
  
! 	/* Invalid arguments, bail out before generating bad rtl.  */
! 	if (arg0 == error_mark_node
! 	    || arg1 == error_mark_node
! 	    || arg2 == error_mark_node)
! 	  return const0_rtx;
  
! 	if (TREE_CODE (arg2) != INTEGER_CST
! 	    || TREE_INT_CST_LOW (arg2) & ~0x3)
! 	  {
! 	    error ("argument to `%s' must be a 2-bit unsigned literal", d->name);
! 	    return const0_rtx;
! 	  }
  
! 	if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
! 	  op0 = copy_to_mode_reg (mode0, op0);
! 	if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
! 	  op1 = copy_to_mode_reg (mode1, op1);
  
! 	pat = GEN_FCN (d->icode) (op0, op1, op2);
! 	if (pat != 0)
! 	  emit_insn (pat);
  
! 	*expandedp = true;
! 	return NULL_RTX;
!       }
! 
!   return NULL_RTX;
! }
! 
! /* Expand the builtin in EXP and store the result in TARGET.  Store
!    true in *EXPANDEDP if we found a builtin to expand.  */
! static rtx
! altivec_expand_builtin (exp, target, expandedp)
!      tree exp;
!      rtx target;
!      bool *expandedp;
! {
!   struct builtin_description *d;
!   struct builtin_description_predicates *dp;
!   size_t i;
!   enum insn_code icode;
!   tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
!   tree arglist = TREE_OPERAND (exp, 1);
!   tree arg0, arg1, arg2;
!   rtx op0, op1, op2, pat;
!   enum machine_mode tmode, mode0, mode1, mode2;
!   unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
! 
!   target = altivec_expand_ld_builtin (exp, target, expandedp);
!   if (*expandedp)
!     return target;
! 
!   target = altivec_expand_st_builtin (exp, target, expandedp);
!   if (*expandedp)
!     return target;
! 
!   target = altivec_expand_dst_builtin (exp, target, expandedp);
!   if (*expandedp)
!     return target;
! 
!   *expandedp = true;
  
+   switch (fcode)
+     {
      case ALTIVEC_BUILTIN_STVX:
        return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, arglist);
      case ALTIVEC_BUILTIN_STVEBX:
*************** altivec_expand_builtin (exp, target, exp
*** 4081,4087 ****
        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;
--- 4105,4111 ----
        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, exp
*** 4114,4120 ****
        if (pat)
  	emit_insn (pat);
        return NULL_RTX;
!       
      case ALTIVEC_BUILTIN_DSSALL:
        emit_insn (gen_altivec_dssall ());
        return NULL_RTX;
--- 4138,4144 ----
        if (pat)
  	emit_insn (pat);
        return NULL_RTX;
! 
      case ALTIVEC_BUILTIN_DSSALL:
        emit_insn (gen_altivec_dssall ());
        return NULL_RTX;
*************** altivec_expand_builtin (exp, target, exp
*** 4142,4187 ****
        emit_insn (gen_altivec_dss (op0));
        return NULL_RTX;
      }
- 
-   /* Handle DST variants.  */
-   d = (struct builtin_description *) bdesc_dst;
-   for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
-     if (d->code == fcode)
-       {
- 	arg0 = TREE_VALUE (arglist);
- 	arg1 = TREE_VALUE (TREE_CHAIN (arglist));
- 	arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
- 	op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
- 	op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
- 	op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
- 	mode0 = insn_data[d->icode].operand[0].mode;
- 	mode1 = insn_data[d->icode].operand[1].mode;
- 	mode2 = insn_data[d->icode].operand[2].mode;
- 
- 	/* Invalid arguments, bail out before generating bad rtl.  */
- 	if (arg0 == error_mark_node
- 	    || arg1 == error_mark_node
- 	    || arg2 == error_mark_node)
- 	  return const0_rtx;
- 
-       if (TREE_CODE (arg2) != INTEGER_CST
- 	  || TREE_INT_CST_LOW (arg2) & ~0x3)
- 	{
- 	  error ("argument to `%s' must be a 2-bit unsigned literal", d->name);
- 	  return const0_rtx;
- 	}
- 
- 	if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
- 	  op0 = copy_to_mode_reg (mode0, op0);
- 	if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
- 	  op1 = copy_to_mode_reg (mode1, op1);
- 
- 	pat = GEN_FCN (d->icode) (op0, op1, op2);
- 	if (pat != 0)
- 	  emit_insn (pat);
- 
- 	return NULL_RTX;
-       }
  
    /* Expand abs* operations.  */
    d = (struct builtin_description *) bdesc_abs;
--- 4166,4171 ----


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]