On 05/17/2011 06:34 AM, Paolo Bonzini wrote:
> On 05/12/2011 05:40 PM, Bernd Schmidt wrote:
>> +  if (targetm.calls.function_arg_round_to_arg_boundary (passed_mode,
>> type))
>> +    round_boundary = boundary;
>> +  else
>> +    round_boundary = PARM_BOUNDARY;
> 
> Why add an if, instead of making the new target hook
> function_arg_round_boundary?  The default implementation can then reuse
> default_function_arg_boundary and C6X will redefine it to
> c6x_function_arg_boundary.

Like this? Untested so far beyond making sure it builds.


Bernd
        * doc/tm.texi.in (FUNCTION_ARG_PADDING): Mention
        TARGET_FUNCTION_ARG_ROUND_BOUNDARY.
        (TARGET_FUNCTION_ARG_ROUND_BOUNDARY): Add hook.
        * function.c (locate_and_pad_parm): Take it into account.
        * target.def (function_arg_round_boundary): New hook.
        * targhooks.c (default_function_arg_round_boundary): New function.
        * targhooks.h (default_function_arg_round_boundary): Declare.
        * doc/tm.texi: Regenerate.

Index: gcc/doc/tm.texi
===================================================================
--- gcc/doc/tm.texi     (revision 174339)
+++ gcc/doc/tm.texi     (working copy)
@@ -4165,9 +4165,9 @@ to pad out an argument with extra space.
 @code{enum direction}: either @code{upward} to pad above the argument,
 @code{downward} to pad below, or @code{none} to inhibit padding.
 
-The @emph{amount} of padding is always just enough to reach the next
-multiple of @code{TARGET_FUNCTION_ARG_BOUNDARY}; this macro does not
-control it.
+The @emph{amount} of padding is not controlled by this macro, but by the
+target hook @code{TARGET_FUNCTION_ARG_ROUND_BOUNDARY}.  It is
+always just enough to reach the next multiple of that boundary. 
 
 This macro has a default definition which is right for most systems.
 For little-endian machines, the default is to pad upward.  For
@@ -4200,6 +4200,13 @@ with the specified mode and type.  The d
 @code{PARM_BOUNDARY} for all arguments.
 @end deftypefn
 
+@deftypefn {Target Hook} {unsigned int} TARGET_FUNCTION_ARG_ROUND_BOUNDARY 
(enum machine_mode @var{mode}, const_tree @var{type})
+Normally, the size of an argument is rounded up to @code{PARM_BOUNDARY},
+which is the default value for this hook.  You can define this hook to
+return a different value if an argument size must be rounded to a larger
+value.
+@end deftypefn
+
 @defmac FUNCTION_ARG_REGNO_P (@var{regno})
 A C expression that is nonzero if @var{regno} is the number of a hard
 register in which function arguments are sometimes passed.  This does
Index: gcc/doc/tm.texi.in
===================================================================
--- gcc/doc/tm.texi.in  (revision 174339)
+++ gcc/doc/tm.texi.in  (working copy)
@@ -4153,9 +4153,9 @@ to pad out an argument with extra space.
 @code{enum direction}: either @code{upward} to pad above the argument,
 @code{downward} to pad below, or @code{none} to inhibit padding.
 
-The @emph{amount} of padding is always just enough to reach the next
-multiple of @code{TARGET_FUNCTION_ARG_BOUNDARY}; this macro does not
-control it.
+The @emph{amount} of padding is not controlled by this macro, but by the
+target hook @code{TARGET_FUNCTION_ARG_ROUND_BOUNDARY}.  It is
+always just enough to reach the next multiple of that boundary. 
 
 This macro has a default definition which is right for most systems.
 For little-endian machines, the default is to pad upward.  For
@@ -4188,6 +4188,8 @@ with the specified mode and type.  The d
 @code{PARM_BOUNDARY} for all arguments.
 @end deftypefn
 
+@hook TARGET_FUNCTION_ARG_ROUND_BOUNDARY
+
 @defmac FUNCTION_ARG_REGNO_P (@var{regno})
 A C expression that is nonzero if @var{regno} is the number of a hard
 register in which function arguments are sometimes passed.  This does
Index: gcc/targhooks.c
===================================================================
--- gcc/targhooks.c     (revision 174339)
+++ gcc/targhooks.c     (working copy)
@@ -614,6 +614,13 @@ default_function_arg_boundary (enum mach
   return PARM_BOUNDARY;
 }
 
+unsigned int
+default_function_arg_round_boundary (enum machine_mode mode ATTRIBUTE_UNUSED,
+                                    const_tree type ATTRIBUTE_UNUSED)
+{
+  return PARM_BOUNDARY;
+}
+
 void
 hook_void_bitmap (bitmap regs ATTRIBUTE_UNUSED)
 {
Index: gcc/targhooks.h
===================================================================
--- gcc/targhooks.h     (revision 174339)
+++ gcc/targhooks.h     (working copy)
@@ -115,6 +115,8 @@ extern rtx default_function_incoming_arg
   (CUMULATIVE_ARGS *, enum machine_mode, const_tree, bool);
 extern unsigned int default_function_arg_boundary (enum machine_mode,
                                                   const_tree);
+extern unsigned int default_function_arg_round_boundary (enum machine_mode,
+                                                        const_tree);
 extern bool hook_bool_const_rtx_commutative_p (const_rtx, int);
 extern rtx default_function_value (const_tree, const_tree, bool);
 extern rtx default_libcall_value (enum machine_mode, const_rtx);
Index: gcc/target.def
===================================================================
--- gcc/target.def      (revision 174339)
+++ gcc/target.def      (working copy)
@@ -2055,6 +2055,15 @@ DEFHOOK
  unsigned int, (enum machine_mode mode, const_tree type),
  default_function_arg_boundary)
 
+DEFHOOK
+(function_arg_round_boundary,
+ "Normally, the size of an argument is rounded up to @code{PARM_BOUNDARY},\n\
+which is the default value for this hook.  You can define this hook to\n\
+return a different value if an argument size must be rounded to a larger\n\
+value.",
+ unsigned int, (enum machine_mode mode, const_tree type),
+ default_function_arg_round_boundary)
+
 /* Return the diagnostic message string if function without a prototype
    is not allowed for this 'val' argument; NULL otherwise. */
 DEFHOOK
Index: gcc/function.c
===================================================================
--- gcc/function.c      (revision 174339)
+++ gcc/function.c      (working copy)
@@ -3709,7 +3709,7 @@ locate_and_pad_parm (enum machine_mode p
 {
   tree sizetree;
   enum direction where_pad;
-  unsigned int boundary;
+  unsigned int boundary, round_boundary;
   int reg_parm_stack_space = 0;
   int part_size_in_regs;
 
@@ -3741,6 +3741,8 @@ locate_and_pad_parm (enum machine_mode p
     = type ? size_in_bytes (type) : size_int (GET_MODE_SIZE (passed_mode));
   where_pad = FUNCTION_ARG_PADDING (passed_mode, type);
   boundary = targetm.calls.function_arg_boundary (passed_mode, type);
+  round_boundary = targetm.calls.function_arg_round_boundary (passed_mode,
+                                                             type);
   locate->where_pad = where_pad;
 
   /* Alignment can't exceed MAX_SUPPORTED_STACK_ALIGNMENT.  */
@@ -3787,8 +3789,8 @@ locate_and_pad_parm (enum machine_mode p
     tree s2 = sizetree;
     if (where_pad != none
        && (!host_integerp (sizetree, 1)
-           || (tree_low_cst (sizetree, 1) * BITS_PER_UNIT) % PARM_BOUNDARY))
-      s2 = round_up (s2, PARM_BOUNDARY / BITS_PER_UNIT);
+           || (tree_low_cst (sizetree, 1) * BITS_PER_UNIT) % round_boundary))
+      s2 = round_up (s2, round_boundary / BITS_PER_UNIT);
     SUB_PARM_SIZE (locate->slot_offset, s2);
   }
 
@@ -3840,8 +3842,8 @@ locate_and_pad_parm (enum machine_mode p
 
   if (where_pad != none
       && (!host_integerp (sizetree, 1)
-         || (tree_low_cst (sizetree, 1) * BITS_PER_UNIT) % PARM_BOUNDARY))
-    sizetree = round_up (sizetree, PARM_BOUNDARY / BITS_PER_UNIT);
+         || (tree_low_cst (sizetree, 1) * BITS_PER_UNIT) % round_boundary))
+    sizetree = round_up (sizetree, round_boundary / BITS_PER_UNIT);
 
   ADD_PARM_SIZE (locate->size, sizetree);
 

Reply via email to