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.
Bernd
* doc/tm.texi.in (FUNCTION_ARG_PADDING): Mention FUNCTION_ARG_ROUND_TO_ARG_BOUNDARY. (FUNCTION_ARG_ROUND_TO_ARG_BOUNDARY): Document. * function.c (locate_and_pad_parm): Take it into account. * doc/tm.texi: Regenerate. Index: doc/tm.texi =================================================================== --- doc/tm.texi.orig +++ doc/tm.texi @@ -4163,9 +4163,10 @@ 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{FUNCTION_ARG_ROUND_TO_ARG_BOUNDARY} is defined. 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 +4199,12 @@ with the specified mode and type. The d @code{PARM_BOUNDARY} for all arguments. @end deftypefn +@defmac FUNCTION_ARG_ROUND_TO_ARG_BOUNDARY +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 defmac + @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: doc/tm.texi.in =================================================================== --- doc/tm.texi.in.orig +++ doc/tm.texi.in @@ -4151,9 +4151,10 @@ 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{FUNCTION_ARG_ROUND_TO_ARG_BOUNDARY} is defined. 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 +4187,12 @@ with the specified mode and type. The d @code{PARM_BOUNDARY} for all arguments. @end deftypefn +@defmac FUNCTION_ARG_ROUND_TO_ARG_BOUNDARY +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 defmac + @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: function.c =================================================================== --- function.c.orig +++ 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,11 @@ 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); +#ifdef FUNCTION_ARG_ROUND_TO_ARG_BOUNDARY + round_boundary = boundary; +#else + round_boundary = PARM_BOUNDARY; +#endif locate->where_pad = where_pad; /* Alignment can't exceed MAX_SUPPORTED_STACK_ALIGNMENT. */ @@ -3787,8 +3792,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 +3845,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);