Patchwork C6X port 8/11: A new FUNCTION_ARG macro

login
register
mail settings
Submitter Bernd Schmidt
Date May 12, 2011, 3:40 p.m.
Message ID <4DCBFF53.2050205@codesourcery.com>
Download mbox | patch
Permalink /patch/95333/
State New
Headers show

Comments

Bernd Schmidt - May 12, 2011, 3:40 p.m.
On 05/10/2011 06:57 PM, Joseph S. Myers wrote:
> On Tue, 10 May 2011, Bernd Schmidt wrote:
> 
>> On C6X, we have PARM_BOUNDARY == 8 (one byte), but some function
>> argument slots still must be rounded to a larger value. As far as I
>> could tell there's currently no way of telling gcc about this, hence a
>> new target macro which controls this behaviour.
> 
> Is there a good reason this has to be a macro rather than a hook in 
> targetm.calls?  Hooks are generally strongly preferred.

New version below. An adapted version of the C6X port will follow.


Bernd
* doc/tm.texi.in (FUNCTION_ARG_PADDING): Mention
	TARGET_FUNCTION_ARG_ROUND_TO_ARG_BOUNDARY.
	(TARGET_FUNCTION_ARG_ROUND_TO_ARG_BOUNDARY): Add hook.
	* function.c (locate_and_pad_parm): Take it into account.
	* target.def (function_arg_round_to_arg_boundary): New hook.
	* hooks.c (hook_bool_mode_const_tree_false): New function.
	* hooks.h (hook_bool_mode_const_tree_false): Declare.
	* doc/tm.texi: Regenerate.
Paolo Bonzini - May 17, 2011, 6:34 a.m.
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.

Paolo

Patch

Index: gcc/doc/tm.texi
===================================================================
--- gcc/doc/tm.texi.orig
+++ gcc/doc/tm.texi
@@ -4163,9 +4163,11 @@  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.  It is
+always just enough to reach the next multiple of the alignment boundary,
+which is usually @code{PARM_BOUNDARY}, or @code{FUNCTION_ARG_BOUNDARY}
+if @code{TARGET_FUNCTION_ARG_ROUND_TO_ARG_BOUNDARY} is overridden to
+return true.
 
 This macro has a default definition which is right for most systems.
 For little-endian machines, the default is to pad upward.  For
@@ -4198,6 +4200,12 @@  with the specified mode and type.  The d
 @code{PARM_BOUNDARY} for all arguments.
 @end deftypefn
 
+@deftypefn {Target Hook} bool TARGET_FUNCTION_ARG_ROUND_TO_ARG_BOUNDARY (enum machine_mode @var{mode}, const_tree @var{type})
+Normally, the size of an argument is rounded up to @code{PARM_BOUNDARY}.
+Define this macro if you want the value of @code{FUNCTION_ARG_BOUNDARY}
+to be used for this rounding instead.
+@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.orig
+++ gcc/doc/tm.texi.in
@@ -4151,9 +4151,11 @@  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.  It is
+always just enough to reach the next multiple of the alignment boundary,
+which is usually @code{PARM_BOUNDARY}, or @code{FUNCTION_ARG_BOUNDARY}
+if @code{TARGET_FUNCTION_ARG_ROUND_TO_ARG_BOUNDARY} is overridden to
+return true.
 
 This macro has a default definition which is right for most systems.
 For little-endian machines, the default is to pad upward.  For
@@ -4186,6 +4188,8 @@  with the specified mode and type.  The d
 @code{PARM_BOUNDARY} for all arguments.
 @end deftypefn
 
+@hook TARGET_FUNCTION_ARG_ROUND_TO_ARG_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/function.c
===================================================================
--- gcc/function.c.orig
+++ gcc/function.c
@@ -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,10 @@  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);
+  if (targetm.calls.function_arg_round_to_arg_boundary (passed_mode, type))
+    round_boundary = boundary;
+  else
+    round_boundary = PARM_BOUNDARY;
   locate->where_pad = where_pad;
 
   /* Alignment can't exceed MAX_SUPPORTED_STACK_ALIGNMENT.  */
@@ -3787,8 +3791,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 +3844,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);
 
Index: gcc/hooks.c
===================================================================
--- gcc/hooks.c.orig
+++ gcc/hooks.c
@@ -85,6 +85,14 @@  hook_bool_mode_true (enum machine_mode m
   return true;
 }
 
+/* Generic hook that takes (enum machine_mode, const_tree) and returns false.  */
+bool
+hook_bool_mode_const_tree_false (enum machine_mode mode ATTRIBUTE_UNUSED,
+				 const_tree value ATTRIBUTE_UNUSED)
+{
+  return false;
+}
+
 /* Generic hook that takes (enum machine_mode, const_rtx) and returns false.  */
 bool
 hook_bool_mode_const_rtx_false (enum machine_mode mode ATTRIBUTE_UNUSED,
Index: gcc/target.def
===================================================================
--- gcc/target.def.orig
+++ gcc/target.def
@@ -2053,6 +2053,14 @@  DEFHOOK
  unsigned int, (enum machine_mode mode, const_tree type),
  default_function_arg_boundary)
 
+DEFHOOK
+(function_arg_round_to_arg_boundary,
+ "Normally, the size of an argument is rounded up to @code{PARM_BOUNDARY}.\n\
+Define this macro if you want the value of @code{FUNCTION_ARG_BOUNDARY}\n\
+to be used for this rounding instead.",
+ bool, (enum machine_mode mode, const_tree type),
+ hook_bool_mode_const_tree_false)
+
 /* Return the diagnostic message string if function without a prototype
    is not allowed for this 'val' argument; NULL otherwise. */
 DEFHOOK
Index: gcc/hooks.h
===================================================================
--- gcc/hooks.h.orig
+++ gcc/hooks.h
@@ -32,6 +32,7 @@  extern bool hook_bool_bool_gcc_optionsp_
 extern bool hook_bool_const_int_const_int_true (const int, const int);
 extern bool hook_bool_mode_false (enum machine_mode);
 extern bool hook_bool_mode_true (enum machine_mode);
+extern bool hook_bool_mode_const_tree_false (enum machine_mode, const_tree);
 extern bool hook_bool_mode_const_rtx_false (enum machine_mode, const_rtx);
 extern bool hook_bool_mode_const_rtx_true (enum machine_mode, const_rtx);
 extern bool hook_bool_mode_rtx_false (enum machine_mode, rtx);