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,AVR] Tidy up builtins expansion


This patch merges the tree functions that handled builtins with
one, two, three arguments to one function.

Code is clearer and smaller if the arguments are handled in a loop
instead of hand-unrolled loops as with the old functions.

Ok for trunk?

Johann

	* config/avr/avr.c (avr_default_expand_builtin): New function.
	(avr_expand_builtin): Use it.
	(avr_expand_unop_builtin): Remove.
	(avr_expand_binop_builtin): Remove.
	(avr_expand_triop_builtin): Remove.

Index: config/avr/avr.c
===================================================================
--- config/avr/avr.c	(revision 188267)
+++ config/avr/avr.c	(working copy)
@@ -10389,170 +10389,64 @@ avr_init_builtins (void)
 }
 
 
-/* Subroutine of avr_expand_builtin to take care of unop insns.  */
+/* Subroutine of avr_expand_builtin to expand vanilla builtins
+   with non-void result and 1 ... 3 arguments.  */
 
 static rtx
-avr_expand_unop_builtin (enum insn_code icode, tree exp,
-                         rtx target)
+avr_default_expand_builtin (enum insn_code icode, tree exp, rtx target)
 {
-  rtx pat;
-  tree arg0 = CALL_EXPR_ARG (exp, 0);
-  rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
-  enum machine_mode op0mode = GET_MODE (op0);
+  rtx pat, xop[3];
+  int n, n_args = call_expr_nargs (exp);
   enum machine_mode tmode = insn_data[icode].operand[0].mode;
-  enum machine_mode mode0 = insn_data[icode].operand[1].mode;
 
-  if (! target
+  gcc_assert (n_args >= 1 && n_args <= 3);
+              
+  if (target == NULL_RTX
       || GET_MODE (target) != tmode
-      || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
+      || !insn_data[icode].operand[0].predicate (target, tmode))
     {
       target = gen_reg_rtx (tmode);
     }
 
-  if (op0mode == SImode && mode0 == HImode)
+  for (n = 0; n < n_args; n++)
     {
-      op0mode = HImode;
-      op0 = gen_lowpart (HImode, op0);
-    }
-  
-  gcc_assert (op0mode == mode0 || op0mode == VOIDmode);
+      tree arg = CALL_EXPR_ARG (exp, n);
+      rtx op = expand_expr (arg, NULL_RTX, VOIDmode, EXPAND_NORMAL);
+      enum machine_mode opmode = GET_MODE (op);
+      enum machine_mode mode = insn_data[icode].operand[n+1].mode;
 
-  if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
-    op0 = copy_to_mode_reg (mode0, op0);
+      if ((opmode == SImode || opmode == VOIDmode) && mode == HImode)
+        {
+          opmode = HImode;
+          op = gen_lowpart (HImode, op);
+        }
 
-  pat = GEN_FCN (icode) (target, op0);
-  if (! pat)
-    return 0;
-  
-  emit_insn (pat);
+      /* In case the insn wants input operands in modes different from
+         the result, abort.  */
   
-  return target;
-}
-
-
-/* Subroutine of avr_expand_builtin to take care of binop insns.  */
+      gcc_assert (opmode == mode || opmode == VOIDmode);
 
-static rtx
-avr_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
-{
-  rtx pat;
-  tree arg0 = CALL_EXPR_ARG (exp, 0);
-  tree arg1 = CALL_EXPR_ARG (exp, 1);
-  rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
-  rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, EXPAND_NORMAL);
-  enum machine_mode op0mode = GET_MODE (op0);
-  enum machine_mode op1mode = GET_MODE (op1);
-  enum machine_mode tmode = insn_data[icode].operand[0].mode;
-  enum machine_mode mode0 = insn_data[icode].operand[1].mode;
-  enum machine_mode mode1 = insn_data[icode].operand[2].mode;
+      if (!insn_data[icode].operand[n+1].predicate (op, mode))
+        op = copy_to_mode_reg (mode, op);
 
-  if (! target
-      || GET_MODE (target) != tmode
-      || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
-    {
-      target = gen_reg_rtx (tmode);
+      xop[n] = op;
     }
 
-  if ((op0mode == SImode || op0mode == VOIDmode) && mode0 == HImode)
+  switch (n_args)
     {
-      op0mode = HImode;
-      op0 = gen_lowpart (HImode, op0);
-    }
-  
-  if ((op1mode == SImode || op1mode == VOIDmode) && mode1 == HImode)
-    {
-      op1mode = HImode;
-      op1 = gen_lowpart (HImode, op1);
-    }
-  
-  /* In case the insn wants input operands in modes different from
-     the result, abort.  */
-  
-  gcc_assert ((op0mode == mode0 || op0mode == VOIDmode)
-              && (op1mode == mode1 || op1mode == VOIDmode));
-
-  if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
-    op0 = copy_to_mode_reg (mode0, op0);
-  
-  if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
-    op1 = copy_to_mode_reg (mode1, op1);
-
-  pat = GEN_FCN (icode) (target, op0, op1);
-  
-  if (! pat)
-    return 0;
+    case 1: pat = GEN_FCN (icode) (target, xop[0]); break;
+    case 2: pat = GEN_FCN (icode) (target, xop[0], xop[1]); break;
+    case 3: pat = GEN_FCN (icode) (target, xop[0], xop[1], xop[2]); break;
 
-  emit_insn (pat);
-  return target;
-}
-
-/* Subroutine of avr_expand_builtin to take care of 3-operand insns.  */
-
-static rtx
-avr_expand_triop_builtin (enum insn_code icode, tree exp, rtx target)
-{
-  rtx pat;
-  tree arg0 = CALL_EXPR_ARG (exp, 0);
-  tree arg1 = CALL_EXPR_ARG (exp, 1);
-  tree arg2 = CALL_EXPR_ARG (exp, 2);
-  rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
-  rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, EXPAND_NORMAL);
-  rtx op2 = expand_expr (arg2, NULL_RTX, VOIDmode, EXPAND_NORMAL);
-  enum machine_mode op0mode = GET_MODE (op0);
-  enum machine_mode op1mode = GET_MODE (op1);
-  enum machine_mode op2mode = GET_MODE (op2);
-  enum machine_mode tmode = insn_data[icode].operand[0].mode;
-  enum machine_mode mode0 = insn_data[icode].operand[1].mode;
-  enum machine_mode mode1 = insn_data[icode].operand[2].mode;
-  enum machine_mode mode2 = insn_data[icode].operand[3].mode;
-
-  if (! target
-      || GET_MODE (target) != tmode
-      || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
-    {
-      target = gen_reg_rtx (tmode);
-    }
-
-  if ((op0mode == SImode || op0mode == VOIDmode) && mode0 == HImode)
-    {
-      op0mode = HImode;
-      op0 = gen_lowpart (HImode, op0);
+    default:
+      gcc_unreachable();
     }
   
-  if ((op1mode == SImode || op1mode == VOIDmode) && mode1 == HImode)
-    {
-      op1mode = HImode;
-      op1 = gen_lowpart (HImode, op1);
-    }
-  
-  if ((op2mode == SImode || op2mode == VOIDmode) && mode2 == HImode)
-    {
-      op2mode = HImode;
-      op2 = gen_lowpart (HImode, op2);
-    }
-  
-  /* In case the insn wants input operands in modes different from
-     the result, abort.  */
-  
-  gcc_assert ((op0mode == mode0 || op0mode == VOIDmode)
-              && (op1mode == mode1 || op1mode == VOIDmode)
-              && (op2mode == mode2 || op2mode == VOIDmode));
-
-  if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
-    op0 = copy_to_mode_reg (mode0, op0);
-  
-  if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
-    op1 = copy_to_mode_reg (mode1, op1);
-
-  if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
-    op2 = copy_to_mode_reg (mode2, op2);
-
-  pat = GEN_FCN (icode) (target, op0, op1, op2);
-  
-  if (! pat)
-    return 0;
+  if (pat == NULL_RTX)
+    return NULL_RTX;
 
   emit_insn (pat);
+
   return target;
 }
 
@@ -10571,7 +10465,7 @@ avr_expand_builtin (tree exp, rtx target
                     int ignore ATTRIBUTE_UNUSED)
 {
   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
-  const char* bname = IDENTIFIER_POINTER (DECL_NAME (fndecl));
+  const char *bname = IDENTIFIER_POINTER (DECL_NAME (fndecl));
   unsigned int id = DECL_FUNCTION_CODE (fndecl);
   const struct avr_builtin_description *d = &avr_bdesc[id];
   tree arg0;
@@ -10595,7 +10489,7 @@ avr_expand_builtin (tree exp, rtx target
         else
           avr_expand_delay_cycles (op0);
 
-        return 0;
+        return NULL_RTX;
       }
 
     case AVR_BUILTIN_INSERT_BITS:
@@ -10613,24 +10507,16 @@ avr_expand_builtin (tree exp, rtx target
     }
 
   /* No special treatment needed: vanilla expand.  */
-  
-  switch (d->n_args)
+
+  gcc_assert (d->n_args == call_expr_nargs (exp));
+
+  if (d->n_args == 0)
     {
-    case 0:
       emit_insn ((GEN_FCN (d->icode)) (target));
-      return 0;
-      
-    case 1:
-      return avr_expand_unop_builtin (d->icode, exp, target);
-      
-    case 2:
-      return avr_expand_binop_builtin (d->icode, exp, target);
-      
-    case 3:
-      return avr_expand_triop_builtin (d->icode, exp, target);
+      return NULL_RTX;
     }
-  
-  gcc_unreachable ();
+
+  return avr_default_expand_builtin (d->icode, exp, target);
 }
 
 


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