Turn FUNCTION_ARG_PADDING into a target hook
This involved renaming the rather general-sounding "enum direction" to "enum pad_direction" to avoid a conflict with the Fortran frontend. 2017-09-04 Richard Sandiford <richard.sandiford@linaro.org> Alan Hayward <alan.hayward@arm.com> David Sherwood <david.sherwood@arm.com> gcc/ * coretypes.h (pad_direction): New enum. * defaults.h (DEFAULT_FUNCTION_ARG_PADDING): Delete. (FUNCTION_ARG_PADDING): Likewise. * target.def (function_arg_padding): New hook. * targhooks.h (default_function_arg_padding): Declare. * targhooks.c (default_function_arg_padding): New function. * doc/tm.texi.in (FUNCTION_ARG_PADDING): Replace with... (TARGET_FUNCTION_ARG_PADDING): ...this. * doc/tm.texi: Regenerate. * calls.c (store_unaligned_arguments_into_pseudos): Use pad_direction instead of direction. (compute_argument_addresses): Likewise. (load_register_parameters): Likewise. (emit_library_call_value_1): Likewise. (store_one_arg): Use targetm.calls.function_arg_padding instead of FUNCTION_ARG_PADDING. (must_pass_in_stack_var_size_or_pad): Likewise. * expr.c (emit_group_load_1): Use pad_direction instead of direction. (emit_group_store): Likewise. (emit_single_push_insn_1): Use targetm.calls.function_arg_padding instead of FUNCTION_ARG_PADDING. (emit_push_insn): Likewise, and propagate enum change throughout function. * function.h (direction): Delete. (locate_and_pad_arg_data::where_pad): Use pad_direction instead of direction. * function.c (assign_parm_find_stack_rtl): Likewise. (assign_parm_setup_block_p): Likewise. (assign_parm_setup_block): Likewise. (gimplify_parameters): Likewise. (locate_and_pad_parm): Use targetm.calls.function_arg_padding instead of FUNCTION_ARG_PADDING, and propagate enum change throughout function. * config/aarch64/aarch64.h (FUNCTION_ARG_PADDING): Delete. (BLOCK_REG_PADDING): Use pad_direction instead of direction. * config/aarch64/aarch64-protos.h (aarch64_pad_arg_upward): Delete. * config/aarch64/aarch64.c (aarch64_pad_arg_upward): Replace with... (aarch64_function_arg_padding): ...this new function. (aarch64_gimplify_va_arg_expr): Use pad_direction instead of direction. (TARGET_FUNCTION_ARG_PADDING): Redefine. * config/arm/arm.h (FUNCTION_ARG_PADDING): Delete. (BLOCK_REG_PADDING): Use pad_direction instead of direction. * config/arm/arm-protos.h (arm_pad_arg_upward): Delete. * config/arm/arm.c (TARGET_FUNCTION_ARG_PADDING): Redefine. (arm_pad_arg_upward): Replace with... (arm_function_arg_padding): ...this new function. * config/c6x/c6x.h (BLOCK_REG_PADDING): Use pad_direction instead of direction. * config/ia64/hpux.h (FUNCTION_ARG_PADDING): Delete. * config/ia64/ia64-protos.h (ia64_hpux_function_arg_padding): Delete. * config/ia64/ia64.c (TARGET_FUNCTION_ARG_PADDING): Redefine. (ia64_hpux_function_arg_padding): Replace with... (ia64_function_arg_padding): ...this new function. Use pad_direction instead of direction. Check for TARGET_HPUX. * config/iq2000/iq2000.h (FUNCTION_ARG_PADDING): Delete. * config/iq2000/iq2000.c (TARGET_FUNCTION_ARG_PADDING): Redefine. (iq2000_function_arg_padding): New function. * config/mips/mips-protos.h (mips_pad_arg_upward): Delete. * config/mips/mips.c (mips_pad_arg_upward): Replace with... (mips_function_arg_padding): ...this new function. (mips_pad_reg_upward): Update accordingly. (TARGET_FUNCTION_ARG_PADDING): Redefine. * config/mips/mips.h (PAD_VARARGS_DOWN): Use targetm.calls.function_arg_padding. (FUNCTION_ARG_PADDING): Delete. (BLOCK_REG_PADDING): Use pad_direction instead of direction. * config/nios2/nios2.h (FUNCTION_ARG_PADDING): Delete. (PAD_VARARGS_DOWN): Use targetm.calls.function_arg_padding. * config/nios2/nios2-protos.h (nios2_function_arg_padding): Delete. (nios2_block_reg_padding): Return pad_direction instead of direction. * config/nios2/nios2.c (nios2_block_reg_padding): Return pad_direction instead of direction. (nios2_function_arg_padding): Likewise. Make static. (TARGET_FUNCTION_ARG_PADDING): Redefine. * config/pa/pa.h (FUNCTION_ARG_PADDING): Delete. (BLOCK_REG_PADDING): Use targetm.calls.function_arg_padding. * config/pa/pa-protos.h (pa_function_arg_padding): Delete. * config/pa/pa.c (TARGET_FUNCTION_ARG_PADDING): Redefine. (pa_function_arg_padding): Make static. Return pad_direction instead of direction. * config/powerpcspe/powerpcspe.h (FUNCTION_ARG_PADDING): Delete. (PAD_VARARGS_DOWN): Use targetm.calls.function_arg_padding. * config/powerpcspe/aix.h (BLOCK_REG_PADDING): Use pad_direction instead of direction. Use targetm.calls.function_arg_padding. * config/powerpcspe/darwin.h (BLOCK_REG_PADDING): Likewise. * config/powerpcspe/freebsd64.h (BLOCK_REG_PADDING): Likewise. * config/powerpcspe/linux64.h (BLOCK_REG_PADDING): Likewise. * config/powerpcspe/powerpcspe-protos.h (function_arg_padding): Delete. * config/powerpcspe/powerpcspe.c (TARGET_FUNCTION_ARG_PADDING): Redefine. (function_arg_padding): Rename to... (rs6000_function_arg_padding): ...this. Make static. Return pad_direction instead of direction. (rs6000_return_in_msb): Use rs6000_function_arg_padding. * config/rs6000/rs6000.h (FUNCTION_ARG_PADDING): Delete. (PAD_VARARGS_DOWN): Use targetm.calls.function_arg_padding. * config/rs6000/aix.h (BLOCK_REG_PADDING): Use pad_direction instead of direction. Use targetm.calls.function_arg_padding. * config/rs6000/darwin.h (BLOCK_REG_PADDING): Likewise. * config/rs6000/freebsd64.h (BLOCK_REG_PADDING): Likewise. * config/rs6000/linux64.h (BLOCK_REG_PADDING): Likewise. * config/rs6000/rs6000-protos.h (function_arg_padding): Delete. * config/rs6000/rs6000.c (TARGET_FUNCTION_ARG_PADDING): Redefine. (function_arg_padding): Rename to... (rs6000_function_arg_padding): ...this. Make static. Return pad_direction instead of direction. (rs6000_return_in_msb): Use rs6000_function_arg_padding. * config/s390/s390.h (FUNCTION_ARG_PADDING): Delete. * config/s390/s390.c (s390_function_arg_padding): New function. (TARGET_FUNCTION_ARG_PADDING): Redefine. * config/sparc/sparc.h (FUNCTION_ARG_PADDING): Delete. * config/sparc/sparc-protos.h (function_arg_padding): Delete. * config/sparc/sparc.c (TARGET_FUNCTION_ARG_PADDING): Redefine. (function_arg_padding): Rename to... (sparc_function_arg_padding): ...this. Make static. Return pad_direction instead of direction. * config/spu/spu.h (FUNCTION_ARG_PADDING): Delete. * config/spu/spu.c (spu_function_arg_padding): New function. (TARGET_FUNCTION_ARG_PADDING): Redefine. * system.h (FUNCTION_ARG_PADDING): Poison. Co-Authored-By: Alan Hayward <alan.hayward@arm.com> Co-Authored-By: David Sherwood <david.sherwood@arm.com> From-SVN: r251648
This commit is contained in:
parent
99e1629ff1
commit
76b0cbf8b6
125
gcc/ChangeLog
125
gcc/ChangeLog
@ -1,3 +1,128 @@
|
||||
2017-09-04 Richard Sandiford <richard.sandiford@linaro.org>
|
||||
Alan Hayward <alan.hayward@arm.com>
|
||||
David Sherwood <david.sherwood@arm.com>
|
||||
|
||||
* coretypes.h (pad_direction): New enum.
|
||||
* defaults.h (DEFAULT_FUNCTION_ARG_PADDING): Delete.
|
||||
(FUNCTION_ARG_PADDING): Likewise.
|
||||
* target.def (function_arg_padding): New hook.
|
||||
* targhooks.h (default_function_arg_padding): Declare.
|
||||
* targhooks.c (default_function_arg_padding): New function.
|
||||
* doc/tm.texi.in (FUNCTION_ARG_PADDING): Replace with...
|
||||
(TARGET_FUNCTION_ARG_PADDING): ...this.
|
||||
* doc/tm.texi: Regenerate.
|
||||
* calls.c (store_unaligned_arguments_into_pseudos): Use pad_direction
|
||||
instead of direction.
|
||||
(compute_argument_addresses): Likewise.
|
||||
(load_register_parameters): Likewise.
|
||||
(emit_library_call_value_1): Likewise.
|
||||
(store_one_arg): Use targetm.calls.function_arg_padding instead
|
||||
of FUNCTION_ARG_PADDING.
|
||||
(must_pass_in_stack_var_size_or_pad): Likewise.
|
||||
* expr.c (emit_group_load_1): Use pad_direction instead of direction.
|
||||
(emit_group_store): Likewise.
|
||||
(emit_single_push_insn_1): Use targetm.calls.function_arg_padding
|
||||
instead of FUNCTION_ARG_PADDING.
|
||||
(emit_push_insn): Likewise, and propagate enum change throughout
|
||||
function.
|
||||
* function.h (direction): Delete.
|
||||
(locate_and_pad_arg_data::where_pad): Use pad_direction instead
|
||||
of direction.
|
||||
* function.c (assign_parm_find_stack_rtl): Likewise.
|
||||
(assign_parm_setup_block_p): Likewise.
|
||||
(assign_parm_setup_block): Likewise.
|
||||
(gimplify_parameters): Likewise.
|
||||
(locate_and_pad_parm): Use targetm.calls.function_arg_padding
|
||||
instead of FUNCTION_ARG_PADDING, and propagate enum change throughout
|
||||
function.
|
||||
* config/aarch64/aarch64.h (FUNCTION_ARG_PADDING): Delete.
|
||||
(BLOCK_REG_PADDING): Use pad_direction instead of direction.
|
||||
* config/aarch64/aarch64-protos.h (aarch64_pad_arg_upward): Delete.
|
||||
* config/aarch64/aarch64.c (aarch64_pad_arg_upward): Replace with...
|
||||
(aarch64_function_arg_padding): ...this new function.
|
||||
(aarch64_gimplify_va_arg_expr): Use pad_direction instead of direction.
|
||||
(TARGET_FUNCTION_ARG_PADDING): Redefine.
|
||||
* config/arm/arm.h (FUNCTION_ARG_PADDING): Delete.
|
||||
(BLOCK_REG_PADDING): Use pad_direction instead of direction.
|
||||
* config/arm/arm-protos.h (arm_pad_arg_upward): Delete.
|
||||
* config/arm/arm.c (TARGET_FUNCTION_ARG_PADDING): Redefine.
|
||||
(arm_pad_arg_upward): Replace with...
|
||||
(arm_function_arg_padding): ...this new function.
|
||||
* config/c6x/c6x.h (BLOCK_REG_PADDING): Use pad_direction instead
|
||||
of direction.
|
||||
* config/ia64/hpux.h (FUNCTION_ARG_PADDING): Delete.
|
||||
* config/ia64/ia64-protos.h (ia64_hpux_function_arg_padding): Delete.
|
||||
* config/ia64/ia64.c (TARGET_FUNCTION_ARG_PADDING): Redefine.
|
||||
(ia64_hpux_function_arg_padding): Replace with...
|
||||
(ia64_function_arg_padding): ...this new function. Use pad_direction
|
||||
instead of direction. Check for TARGET_HPUX.
|
||||
* config/iq2000/iq2000.h (FUNCTION_ARG_PADDING): Delete.
|
||||
* config/iq2000/iq2000.c (TARGET_FUNCTION_ARG_PADDING): Redefine.
|
||||
(iq2000_function_arg_padding): New function.
|
||||
* config/mips/mips-protos.h (mips_pad_arg_upward): Delete.
|
||||
* config/mips/mips.c (mips_pad_arg_upward): Replace with...
|
||||
(mips_function_arg_padding): ...this new function.
|
||||
(mips_pad_reg_upward): Update accordingly.
|
||||
(TARGET_FUNCTION_ARG_PADDING): Redefine.
|
||||
* config/mips/mips.h (PAD_VARARGS_DOWN): Use
|
||||
targetm.calls.function_arg_padding.
|
||||
(FUNCTION_ARG_PADDING): Delete.
|
||||
(BLOCK_REG_PADDING): Use pad_direction instead of direction.
|
||||
* config/nios2/nios2.h (FUNCTION_ARG_PADDING): Delete.
|
||||
(PAD_VARARGS_DOWN): Use targetm.calls.function_arg_padding.
|
||||
* config/nios2/nios2-protos.h (nios2_function_arg_padding): Delete.
|
||||
(nios2_block_reg_padding): Return pad_direction instead of direction.
|
||||
* config/nios2/nios2.c (nios2_block_reg_padding): Return pad_direction
|
||||
instead of direction.
|
||||
(nios2_function_arg_padding): Likewise. Make static.
|
||||
(TARGET_FUNCTION_ARG_PADDING): Redefine.
|
||||
* config/pa/pa.h (FUNCTION_ARG_PADDING): Delete.
|
||||
(BLOCK_REG_PADDING): Use targetm.calls.function_arg_padding.
|
||||
* config/pa/pa-protos.h (pa_function_arg_padding): Delete.
|
||||
* config/pa/pa.c (TARGET_FUNCTION_ARG_PADDING): Redefine.
|
||||
(pa_function_arg_padding): Make static. Return pad_direction instead
|
||||
of direction.
|
||||
* config/powerpcspe/powerpcspe.h (FUNCTION_ARG_PADDING): Delete.
|
||||
(PAD_VARARGS_DOWN): Use targetm.calls.function_arg_padding.
|
||||
* config/powerpcspe/aix.h (BLOCK_REG_PADDING): Use pad_direction
|
||||
instead of direction. Use targetm.calls.function_arg_padding.
|
||||
* config/powerpcspe/darwin.h (BLOCK_REG_PADDING): Likewise.
|
||||
* config/powerpcspe/freebsd64.h (BLOCK_REG_PADDING): Likewise.
|
||||
* config/powerpcspe/linux64.h (BLOCK_REG_PADDING): Likewise.
|
||||
* config/powerpcspe/powerpcspe-protos.h (function_arg_padding): Delete.
|
||||
* config/powerpcspe/powerpcspe.c (TARGET_FUNCTION_ARG_PADDING):
|
||||
Redefine.
|
||||
(function_arg_padding): Rename to...
|
||||
(rs6000_function_arg_padding): ...this. Make static. Return
|
||||
pad_direction instead of direction.
|
||||
(rs6000_return_in_msb): Use rs6000_function_arg_padding.
|
||||
* config/rs6000/rs6000.h (FUNCTION_ARG_PADDING): Delete.
|
||||
(PAD_VARARGS_DOWN): Use targetm.calls.function_arg_padding.
|
||||
* config/rs6000/aix.h (BLOCK_REG_PADDING): Use pad_direction
|
||||
instead of direction. Use targetm.calls.function_arg_padding.
|
||||
* config/rs6000/darwin.h (BLOCK_REG_PADDING): Likewise.
|
||||
* config/rs6000/freebsd64.h (BLOCK_REG_PADDING): Likewise.
|
||||
* config/rs6000/linux64.h (BLOCK_REG_PADDING): Likewise.
|
||||
* config/rs6000/rs6000-protos.h (function_arg_padding): Delete.
|
||||
* config/rs6000/rs6000.c (TARGET_FUNCTION_ARG_PADDING): Redefine.
|
||||
(function_arg_padding): Rename to...
|
||||
(rs6000_function_arg_padding): ...this. Make static. Return
|
||||
pad_direction instead of direction.
|
||||
(rs6000_return_in_msb): Use rs6000_function_arg_padding.
|
||||
* config/s390/s390.h (FUNCTION_ARG_PADDING): Delete.
|
||||
* config/s390/s390.c (s390_function_arg_padding): New function.
|
||||
(TARGET_FUNCTION_ARG_PADDING): Redefine.
|
||||
* config/sparc/sparc.h (FUNCTION_ARG_PADDING): Delete.
|
||||
* config/sparc/sparc-protos.h (function_arg_padding): Delete.
|
||||
* config/sparc/sparc.c (TARGET_FUNCTION_ARG_PADDING): Redefine.
|
||||
(function_arg_padding): Rename to...
|
||||
(sparc_function_arg_padding): ...this. Make static. Return
|
||||
pad_direction instead of direction.
|
||||
* config/spu/spu.h (FUNCTION_ARG_PADDING): Delete.
|
||||
* config/spu/spu.c (spu_function_arg_padding): New function.
|
||||
(TARGET_FUNCTION_ARG_PADDING): Redefine.
|
||||
* system.h (FUNCTION_ARG_PADDING): Poison.
|
||||
|
||||
2017-09-04 Richard Sandiford <richard.sandiford@linaro.org>
|
||||
Alan Hayward <alan.hayward@arm.com>
|
||||
David Sherwood <david.sherwood@arm.com>
|
||||
|
23
gcc/calls.c
23
gcc/calls.c
@ -1154,7 +1154,7 @@ store_unaligned_arguments_into_pseudos (struct arg_data *args, int num_actuals)
|
||||
#ifdef BLOCK_REG_PADDING
|
||||
&& (BLOCK_REG_PADDING (args[i].mode,
|
||||
TREE_TYPE (args[i].tree_value), 1)
|
||||
== downward)
|
||||
== PAD_DOWNWARD)
|
||||
#else
|
||||
&& BYTES_BIG_ENDIAN
|
||||
#endif
|
||||
@ -2222,7 +2222,7 @@ compute_argument_addresses (struct arg_data *args, rtx argblock, int num_actuals
|
||||
}
|
||||
align = BITS_PER_UNIT;
|
||||
boundary = args[i].locate.boundary;
|
||||
if (args[i].locate.where_pad != downward)
|
||||
if (args[i].locate.where_pad != PAD_DOWNWARD)
|
||||
align = boundary;
|
||||
else if (CONST_INT_P (offset))
|
||||
{
|
||||
@ -2519,7 +2519,7 @@ load_register_parameters (struct arg_data *args, int num_actuals,
|
||||
upward on a BYTES_BIG_ENDIAN machine. */
|
||||
if (size < UNITS_PER_WORD
|
||||
&& (args[i].locate.where_pad
|
||||
== (BYTES_BIG_ENDIAN ? upward : downward)))
|
||||
== (BYTES_BIG_ENDIAN ? PAD_UPWARD : PAD_DOWNWARD)))
|
||||
{
|
||||
rtx x;
|
||||
int shift = (UNITS_PER_WORD - size) * BITS_PER_UNIT;
|
||||
@ -2580,7 +2580,7 @@ load_register_parameters (struct arg_data *args, int num_actuals,
|
||||
/* Handle a BLKmode that needs shifting. */
|
||||
if (nregs == 1 && size < UNITS_PER_WORD
|
||||
#ifdef BLOCK_REG_PADDING
|
||||
&& args[i].locate.where_pad == downward
|
||||
&& args[i].locate.where_pad == PAD_DOWNWARD
|
||||
#else
|
||||
&& BYTES_BIG_ENDIAN
|
||||
#endif
|
||||
@ -4919,7 +4919,7 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
|
||||
upward on a BYTES_BIG_ENDIAN machine. */
|
||||
if (size < UNITS_PER_WORD
|
||||
&& (argvec[argnum].locate.where_pad
|
||||
== (BYTES_BIG_ENDIAN ? upward : downward)))
|
||||
== (BYTES_BIG_ENDIAN ? PAD_UPWARD : PAD_DOWNWARD)))
|
||||
{
|
||||
rtx x;
|
||||
int shift = (UNITS_PER_WORD - size) * BITS_PER_UNIT;
|
||||
@ -5397,14 +5397,16 @@ store_one_arg (struct arg_data *arg, rtx argblock, int flags,
|
||||
|
||||
/* Compute how much space the argument should get:
|
||||
round up to a multiple of the alignment for arguments. */
|
||||
if (none != FUNCTION_ARG_PADDING (arg->mode, TREE_TYPE (pval)))
|
||||
if (targetm.calls.function_arg_padding (arg->mode, TREE_TYPE (pval))
|
||||
!= PAD_NONE)
|
||||
used = (((size + PARM_BOUNDARY / BITS_PER_UNIT - 1)
|
||||
/ (PARM_BOUNDARY / BITS_PER_UNIT))
|
||||
* (PARM_BOUNDARY / BITS_PER_UNIT));
|
||||
|
||||
/* Compute the alignment of the pushed argument. */
|
||||
parm_align = arg->locate.boundary;
|
||||
if (FUNCTION_ARG_PADDING (arg->mode, TREE_TYPE (pval)) == downward)
|
||||
if (targetm.calls.function_arg_padding (arg->mode, TREE_TYPE (pval))
|
||||
== PAD_DOWNWARD)
|
||||
{
|
||||
int pad = used - size;
|
||||
if (pad)
|
||||
@ -5463,7 +5465,8 @@ store_one_arg (struct arg_data *arg, rtx argblock, int flags,
|
||||
|
||||
/* When an argument is padded down, the block is aligned to
|
||||
PARM_BOUNDARY, but the actual argument isn't. */
|
||||
if (FUNCTION_ARG_PADDING (arg->mode, TREE_TYPE (pval)) == downward)
|
||||
if (targetm.calls.function_arg_padding (arg->mode, TREE_TYPE (pval))
|
||||
== PAD_DOWNWARD)
|
||||
{
|
||||
if (arg->locate.size.var)
|
||||
parm_align = BITS_PER_UNIT;
|
||||
@ -5614,8 +5617,8 @@ must_pass_in_stack_var_size_or_pad (machine_mode mode, const_tree type)
|
||||
a register would put it into the wrong part of the register. */
|
||||
if (mode == BLKmode
|
||||
&& int_size_in_bytes (type) % (PARM_BOUNDARY / BITS_PER_UNIT)
|
||||
&& (FUNCTION_ARG_PADDING (mode, type)
|
||||
== (BYTES_BIG_ENDIAN ? upward : downward)))
|
||||
&& (targetm.calls.function_arg_padding (mode, type)
|
||||
== (BYTES_BIG_ENDIAN ? PAD_UPWARD : PAD_DOWNWARD)))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
@ -347,7 +347,6 @@ rtx aarch64_reverse_mask (machine_mode);
|
||||
bool aarch64_offset_7bit_signed_scaled_p (machine_mode, HOST_WIDE_INT);
|
||||
char *aarch64_output_scalar_simd_mov_immediate (rtx, machine_mode);
|
||||
char *aarch64_output_simd_mov_immediate (rtx, machine_mode, unsigned);
|
||||
bool aarch64_pad_arg_upward (machine_mode, const_tree);
|
||||
bool aarch64_pad_reg_upward (machine_mode, const_tree, bool);
|
||||
bool aarch64_regno_ok_for_base_p (int, bool);
|
||||
bool aarch64_regno_ok_for_index_p (int, bool);
|
||||
|
@ -2593,22 +2593,19 @@ aarch64_function_arg_boundary (machine_mode mode, const_tree type)
|
||||
return MIN (MAX (alignment, PARM_BOUNDARY), STACK_BOUNDARY);
|
||||
}
|
||||
|
||||
/* For use by FUNCTION_ARG_PADDING (MODE, TYPE).
|
||||
|
||||
Return true if an argument passed on the stack should be padded upwards,
|
||||
i.e. if the least-significant byte of the stack slot has useful data.
|
||||
/* Implement TARGET_FUNCTION_ARG_PADDING.
|
||||
|
||||
Small aggregate types are placed in the lowest memory address.
|
||||
|
||||
The related parameter passing rules are B.4, C.3, C.5 and C.14. */
|
||||
|
||||
bool
|
||||
aarch64_pad_arg_upward (machine_mode mode, const_tree type)
|
||||
static pad_direction
|
||||
aarch64_function_arg_padding (machine_mode mode, const_tree type)
|
||||
{
|
||||
/* On little-endian targets, the least significant byte of every stack
|
||||
argument is passed at the lowest byte address of the stack slot. */
|
||||
if (!BYTES_BIG_ENDIAN)
|
||||
return true;
|
||||
return PAD_UPWARD;
|
||||
|
||||
/* Otherwise, integral, floating-point and pointer types are padded downward:
|
||||
the least significant byte of a stack argument is passed at the highest
|
||||
@ -2617,10 +2614,10 @@ aarch64_pad_arg_upward (machine_mode mode, const_tree type)
|
||||
? (INTEGRAL_TYPE_P (type) || SCALAR_FLOAT_TYPE_P (type)
|
||||
|| POINTER_TYPE_P (type))
|
||||
: (SCALAR_INT_MODE_P (mode) || SCALAR_FLOAT_MODE_P (mode)))
|
||||
return false;
|
||||
return PAD_DOWNWARD;
|
||||
|
||||
/* Everything else padded upward, i.e. data in first byte of stack slot. */
|
||||
return true;
|
||||
return PAD_UPWARD;
|
||||
}
|
||||
|
||||
/* Similarly, for use by BLOCK_REG_PADDING (MODE, TYPE, FIRST).
|
||||
@ -10633,7 +10630,7 @@ aarch64_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
|
||||
if (BYTES_BIG_ENDIAN && GET_MODE_SIZE (ag_mode) < UNITS_PER_VREG)
|
||||
adjust = UNITS_PER_VREG - GET_MODE_SIZE (ag_mode);
|
||||
}
|
||||
else if (BLOCK_REG_PADDING (mode, type, 1) == downward
|
||||
else if (BLOCK_REG_PADDING (mode, type, 1) == PAD_DOWNWARD
|
||||
&& size < UNITS_PER_VREG)
|
||||
{
|
||||
adjust = UNITS_PER_VREG - size;
|
||||
@ -10652,7 +10649,7 @@ aarch64_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
|
||||
if (align > 8)
|
||||
dw_align = true;
|
||||
|
||||
if (BLOCK_REG_PADDING (mode, type, 1) == downward
|
||||
if (BLOCK_REG_PADDING (mode, type, 1) == PAD_DOWNWARD
|
||||
&& size < UNITS_PER_WORD)
|
||||
{
|
||||
adjust = UNITS_PER_WORD - size;
|
||||
@ -10727,7 +10724,7 @@ aarch64_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
|
||||
/* String up with arg */
|
||||
on_stack = build2 (COMPOUND_EXPR, TREE_TYPE (arg), t, arg);
|
||||
/* Big-endianness related address adjustment. */
|
||||
if (BLOCK_REG_PADDING (mode, type, 1) == downward
|
||||
if (BLOCK_REG_PADDING (mode, type, 1) == PAD_DOWNWARD
|
||||
&& size < UNITS_PER_WORD)
|
||||
{
|
||||
t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (arg), arg,
|
||||
@ -15385,6 +15382,9 @@ aarch64_run_selftests (void)
|
||||
#undef TARGET_FUNCTION_ARG_BOUNDARY
|
||||
#define TARGET_FUNCTION_ARG_BOUNDARY aarch64_function_arg_boundary
|
||||
|
||||
#undef TARGET_FUNCTION_ARG_PADDING
|
||||
#define TARGET_FUNCTION_ARG_PADDING aarch64_function_arg_padding
|
||||
|
||||
#undef TARGET_FUNCTION_OK_FOR_SIBCALL
|
||||
#define TARGET_FUNCTION_OK_FOR_SIBCALL aarch64_function_ok_for_sibcall
|
||||
|
||||
|
@ -668,11 +668,8 @@ typedef struct
|
||||
} CUMULATIVE_ARGS;
|
||||
#endif
|
||||
|
||||
#define FUNCTION_ARG_PADDING(MODE, TYPE) \
|
||||
(aarch64_pad_arg_upward (MODE, TYPE) ? upward : downward)
|
||||
|
||||
#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \
|
||||
(aarch64_pad_reg_upward (MODE, TYPE, FIRST) ? upward : downward)
|
||||
(aarch64_pad_reg_upward (MODE, TYPE, FIRST) ? PAD_UPWARD : PAD_DOWNWARD)
|
||||
|
||||
#define PAD_VARARGS_DOWN 0
|
||||
|
||||
|
@ -177,7 +177,6 @@ extern bool arm_coproc_ldc_stc_legitimate_address (rtx);
|
||||
|
||||
#if defined TREE_CODE
|
||||
extern void arm_init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree);
|
||||
extern bool arm_pad_arg_upward (machine_mode, const_tree);
|
||||
extern bool arm_pad_reg_upward (machine_mode, tree, int);
|
||||
#endif
|
||||
extern int arm_apply_result_size (void);
|
||||
|
@ -186,6 +186,7 @@ static rtx arm_function_arg (cumulative_args_t, machine_mode,
|
||||
const_tree, bool);
|
||||
static void arm_function_arg_advance (cumulative_args_t, machine_mode,
|
||||
const_tree, bool);
|
||||
static pad_direction arm_function_arg_padding (machine_mode, const_tree);
|
||||
static unsigned int arm_function_arg_boundary (machine_mode, const_tree);
|
||||
static rtx aapcs_allocate_return_reg (machine_mode, const_tree,
|
||||
const_tree);
|
||||
@ -536,6 +537,8 @@ static const struct attribute_spec arm_attribute_table[] =
|
||||
#define TARGET_FUNCTION_ARG arm_function_arg
|
||||
#undef TARGET_FUNCTION_ARG_ADVANCE
|
||||
#define TARGET_FUNCTION_ARG_ADVANCE arm_function_arg_advance
|
||||
#undef TARGET_FUNCTION_ARG_PADDING
|
||||
#define TARGET_FUNCTION_ARG_PADDING arm_function_arg_padding
|
||||
#undef TARGET_FUNCTION_ARG_BOUNDARY
|
||||
#define TARGET_FUNCTION_ARG_BOUNDARY arm_function_arg_boundary
|
||||
|
||||
@ -15155,22 +15158,21 @@ arm_must_pass_in_stack (machine_mode mode, const_tree type)
|
||||
}
|
||||
|
||||
|
||||
/* For use by FUNCTION_ARG_PADDING (MODE, TYPE).
|
||||
Return true if an argument passed on the stack should be padded upwards,
|
||||
i.e. if the least-significant byte has useful data.
|
||||
For legacy APCS ABIs we use the default. For AAPCS based ABIs small
|
||||
aggregate types are placed in the lowest memory address. */
|
||||
/* Implement TARGET_FUNCTION_ARG_PADDING; return PAD_UPWARD if the lowest
|
||||
byte of a stack argument has useful data. For legacy APCS ABIs we use
|
||||
the default. For AAPCS based ABIs small aggregate types are placed
|
||||
in the lowest memory address. */
|
||||
|
||||
bool
|
||||
arm_pad_arg_upward (machine_mode mode ATTRIBUTE_UNUSED, const_tree type)
|
||||
static pad_direction
|
||||
arm_function_arg_padding (machine_mode mode, const_tree type)
|
||||
{
|
||||
if (!TARGET_AAPCS_BASED)
|
||||
return DEFAULT_FUNCTION_ARG_PADDING(mode, type) == upward;
|
||||
return default_function_arg_padding (mode, type);
|
||||
|
||||
if (type && BYTES_BIG_ENDIAN && INTEGRAL_TYPE_P (type))
|
||||
return false;
|
||||
return PAD_DOWNWARD;
|
||||
|
||||
return true;
|
||||
return PAD_UPWARD;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1480,11 +1480,8 @@ typedef struct
|
||||
} CUMULATIVE_ARGS;
|
||||
#endif
|
||||
|
||||
#define FUNCTION_ARG_PADDING(MODE, TYPE) \
|
||||
(arm_pad_arg_upward (MODE, TYPE) ? upward : downward)
|
||||
|
||||
#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \
|
||||
(arm_pad_reg_upward (MODE, TYPE, FIRST) ? upward : downward)
|
||||
(arm_pad_reg_upward (MODE, TYPE, FIRST) ? PAD_UPWARD : PAD_DOWNWARD)
|
||||
|
||||
/* For AAPCS, padding should never be below the argument. For other ABIs,
|
||||
* mimic the default. */
|
||||
|
@ -345,7 +345,7 @@ struct c6x_args {
|
||||
c6x_init_cumulative_args (&cum, fntype, libname, n_named_args)
|
||||
|
||||
#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \
|
||||
(c6x_block_reg_pad_upward (MODE, TYPE, FIRST) ? upward : downward)
|
||||
(c6x_block_reg_pad_upward (MODE, TYPE, FIRST) ? PAD_UPWARD : PAD_DOWNWARD)
|
||||
|
||||
#define FUNCTION_ARG_REGNO_P(r) \
|
||||
(((r) >= REG_A4 && (r) <= REG_A13) || ((r) >= REG_B4 && (r) <= REG_B13))
|
||||
|
@ -125,10 +125,6 @@ do { \
|
||||
ASM_OUTPUT_TYPE_DIRECTIVE (FILE, XSTR (FUN, 0), "function"); \
|
||||
} while (0)
|
||||
|
||||
#undef FUNCTION_ARG_PADDING
|
||||
#define FUNCTION_ARG_PADDING(MODE, TYPE) \
|
||||
ia64_hpux_function_arg_padding ((MODE), (TYPE))
|
||||
|
||||
#undef PAD_VARARGS_DOWN
|
||||
#define PAD_VARARGS_DOWN (!AGGREGATE_TYPE_P (type))
|
||||
|
||||
|
@ -89,11 +89,6 @@ extern int ia64_dbx_register_number (int);
|
||||
extern rtx ia64_return_addr_rtx (HOST_WIDE_INT, rtx);
|
||||
extern void ia64_split_return_addr_rtx (rtx);
|
||||
|
||||
#ifdef ARGS_SIZE_RTX
|
||||
/* expr.h defines ARGS_SIZE_RTX and `enum direction'. */
|
||||
extern enum direction ia64_hpux_function_arg_padding (machine_mode, const_tree);
|
||||
#endif /* ARGS_SIZE_RTX */
|
||||
|
||||
extern void ia64_hpux_handle_builtin_pragma (struct cpp_reader *);
|
||||
extern void ia64_output_function_profiler (FILE *, int);
|
||||
extern void ia64_profile_hook (int);
|
||||
|
@ -209,6 +209,7 @@ static rtx ia64_function_incoming_arg (cumulative_args_t,
|
||||
machine_mode, const_tree, bool);
|
||||
static void ia64_function_arg_advance (cumulative_args_t, machine_mode,
|
||||
const_tree, bool);
|
||||
static pad_direction ia64_function_arg_padding (machine_mode, const_tree);
|
||||
static unsigned int ia64_function_arg_boundary (machine_mode,
|
||||
const_tree);
|
||||
static bool ia64_function_ok_for_sibcall (tree, tree);
|
||||
@ -509,6 +510,8 @@ static const struct attribute_spec ia64_attribute_table[] =
|
||||
#define TARGET_FUNCTION_INCOMING_ARG ia64_function_incoming_arg
|
||||
#undef TARGET_FUNCTION_ARG_ADVANCE
|
||||
#define TARGET_FUNCTION_ARG_ADVANCE ia64_function_arg_advance
|
||||
#undef TARGET_FUNCTION_ARG_PADDING
|
||||
#define TARGET_FUNCTION_ARG_PADDING ia64_function_arg_padding
|
||||
#undef TARGET_FUNCTION_ARG_BOUNDARY
|
||||
#define TARGET_FUNCTION_ARG_BOUNDARY ia64_function_arg_boundary
|
||||
|
||||
@ -10608,20 +10611,23 @@ ia64_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
|
||||
return ia64_builtins[code];
|
||||
}
|
||||
|
||||
/* For the HP-UX IA64 aggregate parameters are passed stored in the
|
||||
/* Implement TARGET_FUNCTION_ARG_PADDING.
|
||||
|
||||
For the HP-UX IA64 aggregate parameters are passed stored in the
|
||||
most significant bits of the stack slot. */
|
||||
|
||||
enum direction
|
||||
ia64_hpux_function_arg_padding (machine_mode mode, const_tree type)
|
||||
static pad_direction
|
||||
ia64_function_arg_padding (machine_mode mode, const_tree type)
|
||||
{
|
||||
/* Exception to normal case for structures/unions/etc. */
|
||||
/* Exception to normal case for structures/unions/etc. */
|
||||
if (TARGET_HPUX
|
||||
&& type
|
||||
&& AGGREGATE_TYPE_P (type)
|
||||
&& int_size_in_bytes (type) < UNITS_PER_WORD)
|
||||
return PAD_UPWARD;
|
||||
|
||||
if (type && AGGREGATE_TYPE_P (type)
|
||||
&& int_size_in_bytes (type) < UNITS_PER_WORD)
|
||||
return upward;
|
||||
|
||||
/* Fall back to the default. */
|
||||
return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
|
||||
/* Fall back to the default. */
|
||||
return default_function_arg_padding (mode, type);
|
||||
}
|
||||
|
||||
/* Emit text to declare externally defined variables and functions, because
|
||||
|
@ -165,6 +165,7 @@ static rtx iq2000_function_arg (cumulative_args_t,
|
||||
machine_mode, const_tree, bool);
|
||||
static void iq2000_function_arg_advance (cumulative_args_t,
|
||||
machine_mode, const_tree, bool);
|
||||
static pad_direction iq2000_function_arg_padding (machine_mode, const_tree);
|
||||
static unsigned int iq2000_function_arg_boundary (machine_mode,
|
||||
const_tree);
|
||||
static void iq2000_va_start (tree, rtx);
|
||||
@ -231,6 +232,8 @@ static bool iq2000_modes_tieable_p (machine_mode, machine_mode);
|
||||
#define TARGET_FUNCTION_ARG iq2000_function_arg
|
||||
#undef TARGET_FUNCTION_ARG_ADVANCE
|
||||
#define TARGET_FUNCTION_ARG_ADVANCE iq2000_function_arg_advance
|
||||
#undef TARGET_FUNCTION_ARG_PADDING
|
||||
#define TARGET_FUNCTION_ARG_PADDING iq2000_function_arg_padding
|
||||
#undef TARGET_FUNCTION_ARG_BOUNDARY
|
||||
#define TARGET_FUNCTION_ARG_BOUNDARY iq2000_function_arg_boundary
|
||||
|
||||
@ -1376,6 +1379,22 @@ iq2000_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Implement TARGET_FUNCTION_ARG_PADDING. */
|
||||
|
||||
static pad_direction
|
||||
iq2000_function_arg_padding (machine_mode mode, const_tree type)
|
||||
{
|
||||
return (! BYTES_BIG_ENDIAN
|
||||
? PAD_UPWARD
|
||||
: ((mode == BLKmode
|
||||
? (type
|
||||
&& TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
|
||||
&& int_size_in_bytes (type) < (PARM_BOUNDARY / BITS_PER_UNIT))
|
||||
: (GET_MODE_BITSIZE (mode) < PARM_BOUNDARY
|
||||
&& GET_MODE_CLASS (mode) == MODE_INT))
|
||||
? PAD_DOWNWARD : PAD_UPWARD));
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
iq2000_function_arg_boundary (machine_mode mode, const_tree type)
|
||||
{
|
||||
|
@ -308,16 +308,6 @@ typedef struct iq2000_args
|
||||
#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \
|
||||
init_cumulative_args (& CUM, FNTYPE, LIBNAME) \
|
||||
|
||||
#define FUNCTION_ARG_PADDING(MODE, TYPE) \
|
||||
(! BYTES_BIG_ENDIAN \
|
||||
? upward \
|
||||
: (((MODE) == BLKmode \
|
||||
? ((TYPE) && TREE_CODE (TYPE_SIZE (TYPE)) == INTEGER_CST \
|
||||
&& int_size_in_bytes (TYPE) < (PARM_BOUNDARY / BITS_PER_UNIT))\
|
||||
: (GET_MODE_BITSIZE (MODE) < PARM_BOUNDARY \
|
||||
&& (GET_MODE_CLASS (MODE) == MODE_INT))) \
|
||||
? downward : upward))
|
||||
|
||||
#define FUNCTION_ARG_REGNO_P(N) \
|
||||
(((N) >= GP_ARG_FIRST && (N) <= GP_ARG_LAST))
|
||||
|
||||
|
@ -246,7 +246,6 @@ extern bool mips_expand_block_move (rtx, rtx, rtx);
|
||||
extern void mips_expand_synci_loop (rtx, rtx);
|
||||
|
||||
extern void mips_init_cumulative_args (CUMULATIVE_ARGS *, tree);
|
||||
extern bool mips_pad_arg_upward (machine_mode, const_tree);
|
||||
extern bool mips_pad_reg_upward (machine_mode, tree);
|
||||
|
||||
extern bool mips_expand_ext_as_unaligned_load (rtx, rtx, HOST_WIDE_INT,
|
||||
|
@ -6117,18 +6117,17 @@ mips_get_reg_raw_mode (int regno)
|
||||
return default_get_reg_raw_mode (regno);
|
||||
}
|
||||
|
||||
/* Return true if FUNCTION_ARG_PADDING (MODE, TYPE) should return
|
||||
upward rather than downward. In other words, return true if the
|
||||
first byte of the stack slot has useful data, false if the last
|
||||
byte does. */
|
||||
/* Implement TARGET_FUNCTION_ARG_PADDING; return PAD_UPWARD if the first
|
||||
byte of the stack slot has useful data, PAD_DOWNWARD if the last byte
|
||||
does. */
|
||||
|
||||
bool
|
||||
mips_pad_arg_upward (machine_mode mode, const_tree type)
|
||||
static pad_direction
|
||||
mips_function_arg_padding (machine_mode mode, const_tree type)
|
||||
{
|
||||
/* On little-endian targets, the first byte of every stack argument
|
||||
is passed in the first byte of the stack slot. */
|
||||
if (!BYTES_BIG_ENDIAN)
|
||||
return true;
|
||||
return PAD_UPWARD;
|
||||
|
||||
/* Otherwise, integral types are padded downward: the last byte of a
|
||||
stack argument is passed in the last byte of the stack slot. */
|
||||
@ -6138,22 +6137,24 @@ mips_pad_arg_upward (machine_mode mode, const_tree type)
|
||||
|| FIXED_POINT_TYPE_P (type))
|
||||
: (SCALAR_INT_MODE_P (mode)
|
||||
|| ALL_SCALAR_FIXED_POINT_MODE_P (mode)))
|
||||
return false;
|
||||
return PAD_DOWNWARD;
|
||||
|
||||
/* Big-endian o64 pads floating-point arguments downward. */
|
||||
if (mips_abi == ABI_O64)
|
||||
if (type != 0 ? FLOAT_TYPE_P (type) : GET_MODE_CLASS (mode) == MODE_FLOAT)
|
||||
return false;
|
||||
return PAD_DOWNWARD;
|
||||
|
||||
/* Other types are padded upward for o32, o64, n32 and n64. */
|
||||
if (mips_abi != ABI_EABI)
|
||||
return true;
|
||||
return PAD_UPWARD;
|
||||
|
||||
/* Arguments smaller than a stack slot are padded downward. */
|
||||
if (mode != BLKmode)
|
||||
return GET_MODE_BITSIZE (mode) >= PARM_BOUNDARY;
|
||||
else
|
||||
return int_size_in_bytes (type) >= (PARM_BOUNDARY / BITS_PER_UNIT);
|
||||
if (mode != BLKmode
|
||||
? GET_MODE_BITSIZE (mode) >= PARM_BOUNDARY
|
||||
: int_size_in_bytes (type) >= (PARM_BOUNDARY / BITS_PER_UNIT))
|
||||
return PAD_UPWARD;
|
||||
|
||||
return PAD_DOWNWARD;
|
||||
}
|
||||
|
||||
/* Likewise BLOCK_REG_PADDING (MODE, TYPE, ...). Return !BYTES_BIG_ENDIAN
|
||||
@ -6169,7 +6170,7 @@ mips_pad_reg_upward (machine_mode mode, tree type)
|
||||
|
||||
/* Otherwise, apply the same padding to register arguments as we do
|
||||
to stack arguments. */
|
||||
return mips_pad_arg_upward (mode, type);
|
||||
return mips_function_arg_padding (mode, type) == PAD_UPWARD;
|
||||
}
|
||||
|
||||
/* Return nonzero when an argument must be passed by reference. */
|
||||
@ -22459,6 +22460,8 @@ mips_promote_function_mode (const_tree type ATTRIBUTE_UNUSED,
|
||||
#define TARGET_FUNCTION_ARG mips_function_arg
|
||||
#undef TARGET_FUNCTION_ARG_ADVANCE
|
||||
#define TARGET_FUNCTION_ARG_ADVANCE mips_function_arg_advance
|
||||
#undef TARGET_FUNCTION_ARG_PADDING
|
||||
#define TARGET_FUNCTION_ARG_PADDING mips_function_arg_padding
|
||||
#undef TARGET_FUNCTION_ARG_BOUNDARY
|
||||
#define TARGET_FUNCTION_ARG_BOUNDARY mips_function_arg_boundary
|
||||
#undef TARGET_GET_RAW_RESULT_MODE
|
||||
|
@ -1679,7 +1679,7 @@ FP_ASM_SPEC "\
|
||||
DATA_ALIGNMENT (TYPE, ALIGN)
|
||||
|
||||
#define PAD_VARARGS_DOWN \
|
||||
(FUNCTION_ARG_PADDING (TYPE_MODE (type), type) == downward)
|
||||
(targetm.calls.function_arg_padding (TYPE_MODE (type), type) == PAD_DOWNWARD)
|
||||
|
||||
/* Define if operations between registers always perform the operation
|
||||
on the full register even if a narrower mode is specified. */
|
||||
@ -2521,11 +2521,8 @@ typedef struct mips_args {
|
||||
#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \
|
||||
mips_init_cumulative_args (&CUM, FNTYPE)
|
||||
|
||||
#define FUNCTION_ARG_PADDING(MODE, TYPE) \
|
||||
(mips_pad_arg_upward (MODE, TYPE) ? upward : downward)
|
||||
|
||||
#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \
|
||||
(mips_pad_reg_upward (MODE, TYPE) ? upward : downward)
|
||||
(mips_pad_reg_upward (MODE, TYPE) ? PAD_UPWARD : PAD_DOWNWARD)
|
||||
|
||||
/* True if using EABI and varargs can be passed in floating-point
|
||||
registers. Under these conditions, we need a more complex form
|
||||
|
@ -59,14 +59,8 @@ extern bool gen_ldstwm_peep (bool, int, rtx, rtx *);
|
||||
|
||||
extern void nios2_adjust_reg_alloc_order (void);
|
||||
|
||||
#ifdef TREE_CODE
|
||||
#ifdef ARGS_SIZE_RTX
|
||||
/* expr.h defines both ARGS_SIZE_RTX and `enum direction' */
|
||||
extern enum direction nios2_function_arg_padding (machine_mode, const_tree);
|
||||
extern enum direction nios2_block_reg_padding (machine_mode, tree, int);
|
||||
#endif /* ARGS_SIZE_RTX */
|
||||
extern pad_direction nios2_block_reg_padding (machine_mode, tree, int);
|
||||
|
||||
#endif /* TREE_CODE */
|
||||
#endif /* RTX_CODE */
|
||||
|
||||
#endif /* GCC_NIOS2_PROTOS_H */
|
||||
|
@ -2983,30 +2983,31 @@ nios2_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
|
||||
cum->regs_used += param_size;
|
||||
}
|
||||
|
||||
enum direction
|
||||
static pad_direction
|
||||
nios2_function_arg_padding (machine_mode mode, const_tree type)
|
||||
{
|
||||
/* On little-endian targets, the first byte of every stack argument
|
||||
is passed in the first byte of the stack slot. */
|
||||
if (!BYTES_BIG_ENDIAN)
|
||||
return upward;
|
||||
return PAD_UPWARD;
|
||||
|
||||
/* Otherwise, integral types are padded downward: the last byte of a
|
||||
stack argument is passed in the last byte of the stack slot. */
|
||||
if (type != 0
|
||||
? INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type)
|
||||
: GET_MODE_CLASS (mode) == MODE_INT)
|
||||
return downward;
|
||||
return PAD_DOWNWARD;
|
||||
|
||||
/* Arguments smaller than a stack slot are padded downward. */
|
||||
if (mode != BLKmode)
|
||||
return (GET_MODE_BITSIZE (mode) >= PARM_BOUNDARY) ? upward : downward;
|
||||
return (GET_MODE_BITSIZE (mode) >= PARM_BOUNDARY
|
||||
? PAD_UPWARD : PAD_DOWNWARD);
|
||||
|
||||
return ((int_size_in_bytes (type) >= (PARM_BOUNDARY / BITS_PER_UNIT))
|
||||
? upward : downward);
|
||||
? PAD_UPWARD : PAD_DOWNWARD);
|
||||
}
|
||||
|
||||
enum direction
|
||||
pad_direction
|
||||
nios2_block_reg_padding (machine_mode mode, tree type,
|
||||
int first ATTRIBUTE_UNUSED)
|
||||
{
|
||||
@ -5009,6 +5010,9 @@ nios2_adjust_reg_alloc_order (void)
|
||||
#undef TARGET_FUNCTION_ARG_ADVANCE
|
||||
#define TARGET_FUNCTION_ARG_ADVANCE nios2_function_arg_advance
|
||||
|
||||
#undef TARGET_FUNCTION_ARG_PADDING
|
||||
#define TARGET_FUNCTION_ARG_PADDING nios2_function_arg_padding
|
||||
|
||||
#undef TARGET_ARG_PARTIAL_BYTES
|
||||
#define TARGET_ARG_PARTIAL_BYTES nios2_arg_partial_bytes
|
||||
|
||||
|
@ -294,11 +294,8 @@ typedef struct nios2_args
|
||||
#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, FNDECL, N_NAMED_ARGS) \
|
||||
do { (CUM).regs_used = 0; } while (0)
|
||||
|
||||
#define FUNCTION_ARG_PADDING(MODE, TYPE) \
|
||||
(nios2_function_arg_padding ((MODE), (TYPE)))
|
||||
|
||||
#define PAD_VARARGS_DOWN \
|
||||
(FUNCTION_ARG_PADDING (TYPE_MODE (type), type) == downward)
|
||||
(targetm.calls.function_arg_padding (TYPE_MODE (type), type) == PAD_DOWNWARD)
|
||||
|
||||
#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \
|
||||
(nios2_block_reg_padding ((MODE), (TYPE), (FIRST)))
|
||||
|
@ -71,12 +71,6 @@ extern rtx pa_legitimize_reload_address (rtx, machine_mode,
|
||||
|
||||
extern rtx pa_return_addr_rtx (int, rtx);
|
||||
|
||||
#ifdef ARGS_SIZE_RTX
|
||||
/* expr.h defines ARGS_SIZE_RTX and `enum direction' */
|
||||
#ifdef TREE_CODE
|
||||
extern enum direction pa_function_arg_padding (machine_mode, const_tree);
|
||||
#endif
|
||||
#endif /* ARGS_SIZE_RTX */
|
||||
extern int pa_insn_refs_are_delayed (rtx_insn *);
|
||||
extern rtx pa_get_deferred_plabel (rtx);
|
||||
extern rtx pa_maybe_emit_compare_and_swap_exchange_loop (rtx, rtx, rtx);
|
||||
|
@ -172,6 +172,7 @@ static void pa_function_arg_advance (cumulative_args_t, machine_mode,
|
||||
const_tree, bool);
|
||||
static rtx pa_function_arg (cumulative_args_t, machine_mode,
|
||||
const_tree, bool);
|
||||
static pad_direction pa_function_arg_padding (machine_mode, const_tree);
|
||||
static unsigned int pa_function_arg_boundary (machine_mode, const_tree);
|
||||
static struct machine_function * pa_init_machine_status (void);
|
||||
static reg_class_t pa_secondary_reload (bool, rtx, reg_class_t,
|
||||
@ -355,6 +356,8 @@ static size_t n_deferred_plabels = 0;
|
||||
#define TARGET_FUNCTION_ARG pa_function_arg
|
||||
#undef TARGET_FUNCTION_ARG_ADVANCE
|
||||
#define TARGET_FUNCTION_ARG_ADVANCE pa_function_arg_advance
|
||||
#undef TARGET_FUNCTION_ARG_PADDING
|
||||
#define TARGET_FUNCTION_ARG_PADDING pa_function_arg_padding
|
||||
#undef TARGET_FUNCTION_ARG_BOUNDARY
|
||||
#define TARGET_FUNCTION_ARG_BOUNDARY pa_function_arg_boundary
|
||||
|
||||
@ -6241,7 +6244,9 @@ pa_pass_by_reference (cumulative_args_t ca ATTRIBUTE_UNUSED,
|
||||
return size <= 0 || size > 8;
|
||||
}
|
||||
|
||||
enum direction
|
||||
/* Implement TARGET_FUNCTION_ARG_PADDING. */
|
||||
|
||||
static pad_direction
|
||||
pa_function_arg_padding (machine_mode mode, const_tree type)
|
||||
{
|
||||
if (mode == BLKmode
|
||||
@ -6251,11 +6256,11 @@ pa_function_arg_padding (machine_mode mode, const_tree type)
|
||||
|| TREE_CODE (type) == COMPLEX_TYPE
|
||||
|| TREE_CODE (type) == VECTOR_TYPE)))
|
||||
{
|
||||
/* Return none if justification is not required. */
|
||||
/* Return PAD_NONE if justification is not required. */
|
||||
if (type
|
||||
&& TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
|
||||
&& (int_size_in_bytes (type) * BITS_PER_UNIT) % PARM_BOUNDARY == 0)
|
||||
return none;
|
||||
return PAD_NONE;
|
||||
|
||||
/* The directions set here are ignored when a BLKmode argument larger
|
||||
than a word is placed in a register. Different code is used for
|
||||
@ -6265,18 +6270,18 @@ pa_function_arg_padding (machine_mode mode, const_tree type)
|
||||
the stack and in registers should be identical. */
|
||||
if (TARGET_64BIT)
|
||||
/* The 64-bit runtime specifies left justification for aggregates. */
|
||||
return upward;
|
||||
return PAD_UPWARD;
|
||||
else
|
||||
/* The 32-bit runtime architecture specifies right justification.
|
||||
When the argument is passed on the stack, the argument is padded
|
||||
with garbage on the left. The HP compiler pads with zeros. */
|
||||
return downward;
|
||||
return PAD_DOWNWARD;
|
||||
}
|
||||
|
||||
if (GET_MODE_BITSIZE (mode) < PARM_BOUNDARY)
|
||||
return downward;
|
||||
return PAD_DOWNWARD;
|
||||
else
|
||||
return none;
|
||||
return PAD_NONE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -663,11 +663,6 @@ struct hppa_args {int words, nargs_prototype, incoming, indirect; };
|
||||
the standard parameter passing conventions on the RS6000. That's why
|
||||
you'll see lots of similar code in rs6000.h. */
|
||||
|
||||
/* If defined, a C expression which determines whether, and in which
|
||||
direction, to pad out an argument with extra space. */
|
||||
#define FUNCTION_ARG_PADDING(MODE, TYPE) \
|
||||
pa_function_arg_padding ((MODE), (TYPE))
|
||||
|
||||
/* Specify padding for the last element of a block move between registers
|
||||
and memory.
|
||||
|
||||
@ -678,7 +673,7 @@ struct hppa_args {int words, nargs_prototype, incoming, indirect; };
|
||||
so that there is only one element. This allows the object to be
|
||||
correctly padded. */
|
||||
#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \
|
||||
pa_function_arg_padding ((MODE), (TYPE))
|
||||
targetm.calls.function_arg_padding ((MODE), (TYPE))
|
||||
|
||||
|
||||
/* On HPPA, we emit profiling code as rtl via PROFILE_HOOK rather than
|
||||
|
@ -248,7 +248,7 @@
|
||||
registers and memory. FIRST is nonzero if this is the only
|
||||
element. */
|
||||
#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \
|
||||
(!(FIRST) ? upward : FUNCTION_ARG_PADDING (MODE, TYPE))
|
||||
(!(FIRST) ? PAD_UPWARD : targetm.calls.function_arg_padding (MODE, TYPE))
|
||||
|
||||
/* Indicate that jump tables go in the text section. */
|
||||
|
||||
|
@ -344,7 +344,7 @@ extern int darwin_emit_branch_islands;
|
||||
registers and memory. FIRST is nonzero if this is the only
|
||||
element. */
|
||||
#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \
|
||||
(!(FIRST) ? upward : FUNCTION_ARG_PADDING (MODE, TYPE))
|
||||
(!(FIRST) ? PAD_UPWARD : targetm.calls.function_arg_padding (MODE, TYPE))
|
||||
|
||||
#define DOUBLE_INT_ASM_OP "\t.quad\t"
|
||||
|
||||
|
@ -225,7 +225,7 @@ extern int dot_symbols;
|
||||
registers and memory. FIRST is nonzero if this is the only
|
||||
element. */
|
||||
#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \
|
||||
(!(FIRST) ? upward : FUNCTION_ARG_PADDING (MODE, TYPE))
|
||||
(!(FIRST) ? PAD_UPWARD : targetm.calls.function_arg_padding (MODE, TYPE))
|
||||
|
||||
/* FreeBSD doesn't support saving and restoring 64-bit regs with a 32-bit
|
||||
kernel. This is supported when running on a 64-bit kernel with
|
||||
|
@ -340,7 +340,7 @@ extern int dot_symbols;
|
||||
registers and memory. FIRST is nonzero if this is the only
|
||||
element. */
|
||||
#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \
|
||||
(!(FIRST) ? upward : FUNCTION_ARG_PADDING (MODE, TYPE))
|
||||
(!(FIRST) ? PAD_UPWARD : targetm.calls.function_arg_padding (MODE, TYPE))
|
||||
|
||||
/* Linux doesn't support saving and restoring 64-bit regs in a 32-bit
|
||||
process. */
|
||||
|
@ -196,10 +196,6 @@ extern void rs6000_xcoff_asm_output_aligned_decl_common (FILE *, tree,
|
||||
unsigned HOST_WIDE_INT);
|
||||
extern void rs6000_elf_declare_function_name (FILE *, const char *, tree);
|
||||
extern bool rs6000_elf_in_small_data_p (const_tree);
|
||||
#ifdef ARGS_SIZE_RTX
|
||||
/* expr.h defines ARGS_SIZE_RTX and `enum direction' */
|
||||
extern enum direction function_arg_padding (machine_mode, const_tree);
|
||||
#endif /* ARGS_SIZE_RTX */
|
||||
|
||||
#endif /* TREE_CODE */
|
||||
|
||||
|
@ -88,6 +88,8 @@
|
||||
#define min(A,B) ((A) < (B) ? (A) : (B))
|
||||
#define max(A,B) ((A) > (B) ? (A) : (B))
|
||||
|
||||
static pad_direction rs6000_function_arg_padding (machine_mode, const_tree);
|
||||
|
||||
/* Structure used to define the rs6000 stack */
|
||||
typedef struct rs6000_stack {
|
||||
int reload_completed; /* stack info won't change from here on */
|
||||
@ -1809,6 +1811,8 @@ static const struct attribute_spec rs6000_attribute_table[] =
|
||||
#define TARGET_FUNCTION_ARG_ADVANCE rs6000_function_arg_advance
|
||||
#undef TARGET_FUNCTION_ARG
|
||||
#define TARGET_FUNCTION_ARG rs6000_function_arg
|
||||
#undef TARGET_FUNCTION_ARG_PADDING
|
||||
#define TARGET_FUNCTION_ARG_PADDING rs6000_function_arg_padding
|
||||
#undef TARGET_FUNCTION_ARG_BOUNDARY
|
||||
#define TARGET_FUNCTION_ARG_BOUNDARY rs6000_function_arg_boundary
|
||||
|
||||
@ -11813,7 +11817,8 @@ rs6000_return_in_msb (const_tree valtype)
|
||||
return (DEFAULT_ABI == ABI_ELFv2
|
||||
&& BYTES_BIG_ENDIAN
|
||||
&& AGGREGATE_TYPE_P (valtype)
|
||||
&& FUNCTION_ARG_PADDING (TYPE_MODE (valtype), valtype) == upward);
|
||||
&& rs6000_function_arg_padding (TYPE_MODE (valtype),
|
||||
valtype) == PAD_UPWARD);
|
||||
}
|
||||
|
||||
#ifdef HAVE_AS_GNU_ATTRIBUTE
|
||||
@ -12030,17 +12035,13 @@ abi_v4_pass_in_fpr (machine_mode mode)
|
||||
return false;
|
||||
}
|
||||
|
||||
/* If defined, a C expression which determines whether, and in which
|
||||
direction, to pad out an argument with extra space. The value
|
||||
should be of type `enum direction': either `upward' to pad above
|
||||
the argument, `downward' to pad below, or `none' to inhibit
|
||||
padding.
|
||||
/* Implement TARGET_FUNCTION_ARG_PADDING
|
||||
|
||||
For the AIX ABI structs are always stored left shifted in their
|
||||
argument slot. */
|
||||
|
||||
enum direction
|
||||
function_arg_padding (machine_mode mode, const_tree type)
|
||||
static pad_direction
|
||||
rs6000_function_arg_padding (machine_mode mode, const_tree type)
|
||||
{
|
||||
#ifndef AGGREGATE_PADDING_FIXED
|
||||
#define AGGREGATE_PADDING_FIXED 0
|
||||
@ -12052,7 +12053,7 @@ function_arg_padding (machine_mode mode, const_tree type)
|
||||
if (!AGGREGATE_PADDING_FIXED)
|
||||
{
|
||||
/* GCC used to pass structures of the same size as integer types as
|
||||
if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
|
||||
if they were in fact integers, ignoring TARGET_FUNCTION_ARG_PADDING.
|
||||
i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
|
||||
passed padded downward, except that -mstrict-align further
|
||||
muddied the water in that multi-component structures of 2 and 4
|
||||
@ -12073,19 +12074,19 @@ function_arg_padding (machine_mode mode, const_tree type)
|
||||
size = GET_MODE_SIZE (mode);
|
||||
|
||||
if (size == 1 || size == 2 || size == 4)
|
||||
return downward;
|
||||
return PAD_DOWNWARD;
|
||||
}
|
||||
return upward;
|
||||
return PAD_UPWARD;
|
||||
}
|
||||
|
||||
if (AGGREGATES_PAD_UPWARD_ALWAYS)
|
||||
{
|
||||
if (type != 0 && AGGREGATE_TYPE_P (type))
|
||||
return upward;
|
||||
return PAD_UPWARD;
|
||||
}
|
||||
|
||||
/* Fall back to the default. */
|
||||
return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
|
||||
return default_function_arg_padding (mode, type);
|
||||
}
|
||||
|
||||
/* If defined, a C expression that gives the alignment boundary, in bits,
|
||||
|
@ -1901,16 +1901,8 @@ typedef struct rs6000_args
|
||||
init_cumulative_args (&CUM, NULL_TREE, LIBNAME, FALSE, TRUE, \
|
||||
0, NULL_TREE, MODE)
|
||||
|
||||
/* If defined, a C expression which determines whether, and in which
|
||||
direction, to pad out an argument with extra space. The value
|
||||
should be of type `enum direction': either `upward' to pad above
|
||||
the argument, `downward' to pad below, or `none' to inhibit
|
||||
padding. */
|
||||
|
||||
#define FUNCTION_ARG_PADDING(MODE, TYPE) function_arg_padding (MODE, TYPE)
|
||||
|
||||
#define PAD_VARARGS_DOWN \
|
||||
(FUNCTION_ARG_PADDING (TYPE_MODE (type), type) == downward)
|
||||
(targetm.calls.function_arg_padding (TYPE_MODE (type), type) == PAD_DOWNWARD)
|
||||
|
||||
/* Output assembler code to FILE to increment profiler label # LABELNO
|
||||
for profiling a function entry. */
|
||||
|
@ -248,7 +248,7 @@
|
||||
registers and memory. FIRST is nonzero if this is the only
|
||||
element. */
|
||||
#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \
|
||||
(!(FIRST) ? upward : FUNCTION_ARG_PADDING (MODE, TYPE))
|
||||
(!(FIRST) ? PAD_UPWARD : targetm.calls.function_arg_padding (MODE, TYPE))
|
||||
|
||||
/* Indicate that jump tables go in the text section. */
|
||||
|
||||
|
@ -339,7 +339,7 @@ extern int darwin_emit_branch_islands;
|
||||
registers and memory. FIRST is nonzero if this is the only
|
||||
element. */
|
||||
#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \
|
||||
(!(FIRST) ? upward : FUNCTION_ARG_PADDING (MODE, TYPE))
|
||||
(!(FIRST) ? PAD_UPWARD : targetm.calls.function_arg_padding (MODE, TYPE))
|
||||
|
||||
#define DOUBLE_INT_ASM_OP "\t.quad\t"
|
||||
|
||||
|
@ -225,7 +225,7 @@ extern int dot_symbols;
|
||||
registers and memory. FIRST is nonzero if this is the only
|
||||
element. */
|
||||
#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \
|
||||
(!(FIRST) ? upward : FUNCTION_ARG_PADDING (MODE, TYPE))
|
||||
(!(FIRST) ? PAD_UPWARD : targetm.calls.function_arg_padding (MODE, TYPE))
|
||||
|
||||
/* FreeBSD doesn't support saving and restoring 64-bit regs with a 32-bit
|
||||
kernel. This is supported when running on a 64-bit kernel with
|
||||
|
@ -340,7 +340,7 @@ extern int dot_symbols;
|
||||
registers and memory. FIRST is nonzero if this is the only
|
||||
element. */
|
||||
#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \
|
||||
(!(FIRST) ? upward : FUNCTION_ARG_PADDING (MODE, TYPE))
|
||||
(!(FIRST) ? PAD_UPWARD : targetm.calls.function_arg_padding (MODE, TYPE))
|
||||
|
||||
/* Linux doesn't support saving and restoring 64-bit regs in a 32-bit
|
||||
process. */
|
||||
|
@ -197,10 +197,6 @@ extern void rs6000_xcoff_asm_output_aligned_decl_common (FILE *, tree,
|
||||
unsigned HOST_WIDE_INT);
|
||||
extern void rs6000_elf_declare_function_name (FILE *, const char *, tree);
|
||||
extern bool rs6000_elf_in_small_data_p (const_tree);
|
||||
#ifdef ARGS_SIZE_RTX
|
||||
/* expr.h defines ARGS_SIZE_RTX and `enum direction' */
|
||||
extern enum direction function_arg_padding (machine_mode, const_tree);
|
||||
#endif /* ARGS_SIZE_RTX */
|
||||
|
||||
#endif /* TREE_CODE */
|
||||
|
||||
|
@ -89,6 +89,8 @@
|
||||
#define min(A,B) ((A) < (B) ? (A) : (B))
|
||||
#define max(A,B) ((A) > (B) ? (A) : (B))
|
||||
|
||||
static pad_direction rs6000_function_arg_padding (machine_mode, const_tree);
|
||||
|
||||
/* Structure used to define the rs6000 stack */
|
||||
typedef struct rs6000_stack {
|
||||
int reload_completed; /* stack info won't change from here on */
|
||||
@ -1794,6 +1796,8 @@ static const struct attribute_spec rs6000_attribute_table[] =
|
||||
#define TARGET_FUNCTION_ARG_ADVANCE rs6000_function_arg_advance
|
||||
#undef TARGET_FUNCTION_ARG
|
||||
#define TARGET_FUNCTION_ARG rs6000_function_arg
|
||||
#undef TARGET_FUNCTION_ARG_PADDING
|
||||
#define TARGET_FUNCTION_ARG_PADDING rs6000_function_arg_padding
|
||||
#undef TARGET_FUNCTION_ARG_BOUNDARY
|
||||
#define TARGET_FUNCTION_ARG_BOUNDARY rs6000_function_arg_boundary
|
||||
|
||||
@ -11247,7 +11251,8 @@ rs6000_return_in_msb (const_tree valtype)
|
||||
return (DEFAULT_ABI == ABI_ELFv2
|
||||
&& BYTES_BIG_ENDIAN
|
||||
&& AGGREGATE_TYPE_P (valtype)
|
||||
&& FUNCTION_ARG_PADDING (TYPE_MODE (valtype), valtype) == upward);
|
||||
&& (rs6000_function_arg_padding (TYPE_MODE (valtype), valtype)
|
||||
== PAD_UPWARD));
|
||||
}
|
||||
|
||||
#ifdef HAVE_AS_GNU_ATTRIBUTE
|
||||
@ -11464,17 +11469,13 @@ abi_v4_pass_in_fpr (machine_mode mode)
|
||||
return false;
|
||||
}
|
||||
|
||||
/* If defined, a C expression which determines whether, and in which
|
||||
direction, to pad out an argument with extra space. The value
|
||||
should be of type `enum direction': either `upward' to pad above
|
||||
the argument, `downward' to pad below, or `none' to inhibit
|
||||
padding.
|
||||
/* Implement TARGET_FUNCTION_ARG_PADDING.
|
||||
|
||||
For the AIX ABI structs are always stored left shifted in their
|
||||
argument slot. */
|
||||
|
||||
enum direction
|
||||
function_arg_padding (machine_mode mode, const_tree type)
|
||||
static pad_direction
|
||||
rs6000_function_arg_padding (machine_mode mode, const_tree type)
|
||||
{
|
||||
#ifndef AGGREGATE_PADDING_FIXED
|
||||
#define AGGREGATE_PADDING_FIXED 0
|
||||
@ -11486,7 +11487,7 @@ function_arg_padding (machine_mode mode, const_tree type)
|
||||
if (!AGGREGATE_PADDING_FIXED)
|
||||
{
|
||||
/* GCC used to pass structures of the same size as integer types as
|
||||
if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
|
||||
if they were in fact integers, ignoring TARGET_FUNCTION_ARG_PADDING.
|
||||
i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
|
||||
passed padded downward, except that -mstrict-align further
|
||||
muddied the water in that multi-component structures of 2 and 4
|
||||
@ -11507,19 +11508,19 @@ function_arg_padding (machine_mode mode, const_tree type)
|
||||
size = GET_MODE_SIZE (mode);
|
||||
|
||||
if (size == 1 || size == 2 || size == 4)
|
||||
return downward;
|
||||
return PAD_DOWNWARD;
|
||||
}
|
||||
return upward;
|
||||
return PAD_UPWARD;
|
||||
}
|
||||
|
||||
if (AGGREGATES_PAD_UPWARD_ALWAYS)
|
||||
{
|
||||
if (type != 0 && AGGREGATE_TYPE_P (type))
|
||||
return upward;
|
||||
return PAD_UPWARD;
|
||||
}
|
||||
|
||||
/* Fall back to the default. */
|
||||
return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
|
||||
return default_function_arg_padding (mode, type);
|
||||
}
|
||||
|
||||
/* If defined, a C expression that gives the alignment boundary, in bits,
|
||||
|
@ -1803,16 +1803,8 @@ typedef struct rs6000_args
|
||||
init_cumulative_args (&CUM, NULL_TREE, LIBNAME, FALSE, TRUE, \
|
||||
0, NULL_TREE, MODE)
|
||||
|
||||
/* If defined, a C expression which determines whether, and in which
|
||||
direction, to pad out an argument with extra space. The value
|
||||
should be of type `enum direction': either `upward' to pad above
|
||||
the argument, `downward' to pad below, or `none' to inhibit
|
||||
padding. */
|
||||
|
||||
#define FUNCTION_ARG_PADDING(MODE, TYPE) function_arg_padding (MODE, TYPE)
|
||||
|
||||
#define PAD_VARARGS_DOWN \
|
||||
(FUNCTION_ARG_PADDING (TYPE_MODE (type), type) == downward)
|
||||
(targetm.calls.function_arg_padding (TYPE_MODE (type), type) == PAD_DOWNWARD)
|
||||
|
||||
/* Output assembler code to FILE to increment profiler label # LABELNO
|
||||
for profiling a function entry. */
|
||||
|
@ -12124,6 +12124,18 @@ s390_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
/* Implement TARGET_FUNCTION_ARG_BOUNDARY. Vector arguments are
|
||||
left-justified when placed on the stack during parameter passing. */
|
||||
|
||||
static pad_direction
|
||||
s390_function_arg_padding (machine_mode mode, const_tree type)
|
||||
{
|
||||
if (s390_function_arg_vector (mode, type))
|
||||
return PAD_UPWARD;
|
||||
|
||||
return default_function_arg_padding (mode, type);
|
||||
}
|
||||
|
||||
/* Return true if return values of type TYPE should be returned
|
||||
in a memory buffer whose address is passed by the caller as
|
||||
hidden first argument. */
|
||||
@ -15886,6 +15898,8 @@ s390_asan_shadow_offset (void)
|
||||
#define TARGET_FUNCTION_ARG s390_function_arg
|
||||
#undef TARGET_FUNCTION_ARG_ADVANCE
|
||||
#define TARGET_FUNCTION_ARG_ADVANCE s390_function_arg_advance
|
||||
#undef TARGET_FUNCTION_ARG_PADDING
|
||||
#define TARGET_FUNCTION_ARG_PADDING s390_function_arg_padding
|
||||
#undef TARGET_FUNCTION_VALUE
|
||||
#define TARGET_FUNCTION_VALUE s390_function_value
|
||||
#undef TARGET_LIBCALL_VALUE
|
||||
|
@ -273,13 +273,6 @@ extern const char *s390_host_detect_local_cpu (int argc, const char **argv);
|
||||
|
||||
#define STACK_SIZE_MODE (Pmode)
|
||||
|
||||
/* Vector arguments are left-justified when placed on the stack during
|
||||
parameter passing. */
|
||||
#define FUNCTION_ARG_PADDING(MODE, TYPE) \
|
||||
(s390_function_arg_vector ((MODE), (TYPE)) \
|
||||
? upward \
|
||||
: DEFAULT_FUNCTION_ARG_PADDING ((MODE), (TYPE)))
|
||||
|
||||
#ifndef IN_LIBGCC2
|
||||
|
||||
/* Width of a word, in units (bytes). */
|
||||
|
@ -28,10 +28,6 @@ along with GCC; see the file COPYING3. If not see
|
||||
extern void init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree);
|
||||
#endif
|
||||
extern unsigned long sparc_type_code (tree);
|
||||
#ifdef ARGS_SIZE_RTX
|
||||
/* expr.h defines ARGS_SIZE_RTX and `enum direction' */
|
||||
extern enum direction function_arg_padding (machine_mode, const_tree);
|
||||
#endif /* ARGS_SIZE_RTX */
|
||||
#endif /* TREE_CODE */
|
||||
|
||||
extern void order_regs_for_local_alloc (void);
|
||||
|
@ -648,6 +648,7 @@ static rtx sparc_function_arg (cumulative_args_t,
|
||||
machine_mode, const_tree, bool);
|
||||
static rtx sparc_function_incoming_arg (cumulative_args_t,
|
||||
machine_mode, const_tree, bool);
|
||||
static pad_direction sparc_function_arg_padding (machine_mode, const_tree);
|
||||
static unsigned int sparc_function_arg_boundary (machine_mode,
|
||||
const_tree);
|
||||
static int sparc_arg_partial_bytes (cumulative_args_t,
|
||||
@ -796,6 +797,8 @@ char sparc_hard_reg_printed[8];
|
||||
#define TARGET_FUNCTION_ARG sparc_function_arg
|
||||
#undef TARGET_FUNCTION_INCOMING_ARG
|
||||
#define TARGET_FUNCTION_INCOMING_ARG sparc_function_incoming_arg
|
||||
#undef TARGET_FUNCTION_ARG_PADDING
|
||||
#define TARGET_FUNCTION_ARG_PADDING sparc_function_arg_padding
|
||||
#undef TARGET_FUNCTION_ARG_BOUNDARY
|
||||
#define TARGET_FUNCTION_ARG_BOUNDARY sparc_function_arg_boundary
|
||||
|
||||
@ -7315,18 +7318,17 @@ sparc_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle the FUNCTION_ARG_PADDING macro.
|
||||
For the 64-bit ABI structs are always stored left shifted in their
|
||||
argument slot. */
|
||||
/* Implement TARGET_FUNCTION_ARG_PADDING. For the 64-bit ABI structs
|
||||
are always stored left shifted in their argument slot. */
|
||||
|
||||
enum direction
|
||||
function_arg_padding (machine_mode mode, const_tree type)
|
||||
static pad_direction
|
||||
sparc_function_arg_padding (machine_mode mode, const_tree type)
|
||||
{
|
||||
if (TARGET_ARCH64 && type && AGGREGATE_TYPE_P (type))
|
||||
return upward;
|
||||
return PAD_UPWARD;
|
||||
|
||||
/* Fall back to the default. */
|
||||
return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
|
||||
return default_function_arg_padding (mode, type);
|
||||
}
|
||||
|
||||
/* Handle the TARGET_RETURN_IN_MEMORY target hook.
|
||||
|
@ -1215,14 +1215,6 @@ struct sparc_args {
|
||||
#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, FNDECL, N_NAMED_ARGS) \
|
||||
init_cumulative_args (& (CUM), (FNTYPE), (LIBNAME), (FNDECL));
|
||||
|
||||
/* If defined, a C expression which determines whether, and in which direction,
|
||||
to pad out an argument with extra space. The value should be of type
|
||||
`enum direction': either `upward' to pad above the argument,
|
||||
`downward' to pad below, or `none' to inhibit padding. */
|
||||
|
||||
#define FUNCTION_ARG_PADDING(MODE, TYPE) \
|
||||
function_arg_padding ((MODE), (TYPE))
|
||||
|
||||
|
||||
/* Generate the special assembly code needed to tell the assembler whatever
|
||||
it might need to know about the return value of a function.
|
||||
|
@ -3873,6 +3873,14 @@ spu_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
|
||||
: HARD_REGNO_NREGS (cum, mode));
|
||||
}
|
||||
|
||||
/* Implement TARGET_FUNCTION_ARG_PADDING. */
|
||||
|
||||
static pad_direction
|
||||
spu_function_arg_padding (machine_mode, const_tree)
|
||||
{
|
||||
return PAD_UPWARD;
|
||||
}
|
||||
|
||||
/* Variable sized types are passed by reference. */
|
||||
static bool
|
||||
spu_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED,
|
||||
@ -7265,6 +7273,9 @@ static const struct attribute_spec spu_attribute_table[] =
|
||||
#undef TARGET_FUNCTION_ARG_ADVANCE
|
||||
#define TARGET_FUNCTION_ARG_ADVANCE spu_function_arg_advance
|
||||
|
||||
#undef TARGET_FUNCTION_ARG_PADDING
|
||||
#define TARGET_FUNCTION_ARG_PADDING spu_function_arg_padding
|
||||
|
||||
#undef TARGET_MUST_PASS_IN_STACK
|
||||
#define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
|
||||
|
||||
|
@ -329,8 +329,6 @@ targetm.resolve_overloaded_builtin = spu_resolve_overloaded_builtin; \
|
||||
? (4 - GET_MODE_SIZE (MODE)) \
|
||||
: 0)
|
||||
|
||||
#define FUNCTION_ARG_PADDING(MODE,TYPE) upward
|
||||
|
||||
#define PAD_VARARGS_DOWN 0
|
||||
|
||||
#define FUNCTION_ARG_REGNO_P(N) ((N) >= (FIRST_ARG_REGNUM) && (N) <= (LAST_ARG_REGNUM))
|
||||
|
@ -230,6 +230,22 @@ enum optimization_type {
|
||||
OPTIMIZE_FOR_SIZE
|
||||
};
|
||||
|
||||
/* Enumerates a padding direction. */
|
||||
enum pad_direction {
|
||||
/* No padding is required. */
|
||||
PAD_NONE,
|
||||
|
||||
/* Insert padding above the data, i.e. at higher memeory addresses
|
||||
when dealing with memory, and at the most significant end when
|
||||
dealing with registers. */
|
||||
PAD_UPWARD,
|
||||
|
||||
/* Insert padding below the data, i.e. at lower memeory addresses
|
||||
when dealing with memory, and at the least significant end when
|
||||
dealing with registers. */
|
||||
PAD_DOWNWARD
|
||||
};
|
||||
|
||||
/* Possible initialization status of a variable. When requested
|
||||
by the user, this information is tracked and recorded in the DWARF
|
||||
debug information, along with the variable's location. */
|
||||
|
@ -1355,24 +1355,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
#define SET_RATIO(speed) MOVE_RATIO (speed)
|
||||
#endif
|
||||
|
||||
/* Supply a default definition for FUNCTION_ARG_PADDING:
|
||||
usually pad upward, but pad short args downward on
|
||||
big-endian machines. */
|
||||
|
||||
#define DEFAULT_FUNCTION_ARG_PADDING(MODE, TYPE) \
|
||||
(! BYTES_BIG_ENDIAN \
|
||||
? upward \
|
||||
: (((MODE) == BLKmode \
|
||||
? ((TYPE) && TREE_CODE (TYPE_SIZE (TYPE)) == INTEGER_CST \
|
||||
&& int_size_in_bytes (TYPE) < (PARM_BOUNDARY / BITS_PER_UNIT)) \
|
||||
: GET_MODE_BITSIZE (MODE) < PARM_BOUNDARY) \
|
||||
? downward : upward))
|
||||
|
||||
#ifndef FUNCTION_ARG_PADDING
|
||||
#define FUNCTION_ARG_PADDING(MODE, TYPE) \
|
||||
DEFAULT_FUNCTION_ARG_PADDING ((MODE), (TYPE))
|
||||
#endif
|
||||
|
||||
/* Supply a default definition of STACK_SAVEAREA_MODE for emit_stack_save.
|
||||
Normally move_insn, so Pmode stack pointer. */
|
||||
|
||||
|
@ -4096,21 +4096,21 @@ slot that is in the middle of the quad word instead of starting at the
|
||||
top.
|
||||
@end defmac
|
||||
|
||||
@defmac FUNCTION_ARG_PADDING (@var{mode}, @var{type})
|
||||
If defined, a C expression which determines whether, and in which direction,
|
||||
to pad out an argument with extra space. The value should be of type
|
||||
@code{enum direction}: either @code{upward} to pad above the argument,
|
||||
@code{downward} to pad below, or @code{none} to inhibit padding.
|
||||
@deftypefn {Target Hook} pad_direction TARGET_FUNCTION_ARG_PADDING (machine_mode @var{mode}, const_tree @var{type})
|
||||
This hook determines whether, and in which direction, to pad out
|
||||
an argument of mode @var{mode} and type @var{type}. It returns
|
||||
@code{PAD_UPWARD} to insert padding above the argument, @code{PAD_DOWNWARD}
|
||||
to insert padding below the argument, or @code{PAD_NONE} to inhibit padding.
|
||||
|
||||
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.
|
||||
The @emph{amount} of padding is not controlled by this hook, but by
|
||||
@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.
|
||||
This hook has a default definition that is right for most systems.
|
||||
For little-endian machines, the default is to pad upward. For
|
||||
big-endian machines, the default is to pad downward for an argument of
|
||||
constant size shorter than an @code{int}, and upward otherwise.
|
||||
@end defmac
|
||||
@end deftypefn
|
||||
|
||||
@defmac PAD_VARARGS_DOWN
|
||||
If defined, a C expression which determines whether the default
|
||||
|
@ -3363,21 +3363,7 @@ slot that is in the middle of the quad word instead of starting at the
|
||||
top.
|
||||
@end defmac
|
||||
|
||||
@defmac FUNCTION_ARG_PADDING (@var{mode}, @var{type})
|
||||
If defined, a C expression which determines whether, and in which direction,
|
||||
to pad out an argument with extra space. The value should be of type
|
||||
@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 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
|
||||
big-endian machines, the default is to pad downward for an argument of
|
||||
constant size shorter than an @code{int}, and upward otherwise.
|
||||
@end defmac
|
||||
@hook TARGET_FUNCTION_ARG_PADDING
|
||||
|
||||
@defmac PAD_VARARGS_DOWN
|
||||
If defined, a C expression which determines whether the default
|
||||
|
27
gcc/expr.c
27
gcc/expr.c
@ -2150,7 +2150,7 @@ emit_group_load_1 (rtx *tmps, rtx dst, rtx orig_src, tree type, int ssize)
|
||||
if (
|
||||
#ifdef BLOCK_REG_PADDING
|
||||
BLOCK_REG_PADDING (GET_MODE (orig_src), type, i == start)
|
||||
== (BYTES_BIG_ENDIAN ? upward : downward)
|
||||
== (BYTES_BIG_ENDIAN ? PAD_UPWARD : PAD_DOWNWARD)
|
||||
#else
|
||||
BYTES_BIG_ENDIAN
|
||||
#endif
|
||||
@ -2564,7 +2564,7 @@ emit_group_store (rtx orig_dst, rtx src, tree type ATTRIBUTE_UNUSED, int ssize)
|
||||
if (
|
||||
#ifdef BLOCK_REG_PADDING
|
||||
BLOCK_REG_PADDING (GET_MODE (orig_dst), type, i == start)
|
||||
== (BYTES_BIG_ENDIAN ? upward : downward)
|
||||
== (BYTES_BIG_ENDIAN ? PAD_UPWARD : PAD_DOWNWARD)
|
||||
#else
|
||||
BYTES_BIG_ENDIAN
|
||||
#endif
|
||||
@ -4130,7 +4130,7 @@ emit_single_push_insn_1 (machine_mode mode, rtx x, tree type)
|
||||
then store X into the stack location using an offset. This is
|
||||
because emit_move_insn does not know how to pad; it does not have
|
||||
access to type. */
|
||||
else if (FUNCTION_ARG_PADDING (mode, type) == downward)
|
||||
else if (targetm.calls.function_arg_padding (mode, type) == PAD_DOWNWARD)
|
||||
{
|
||||
unsigned padding_size = rounded_size - GET_MODE_SIZE (mode);
|
||||
HOST_WIDE_INT offset;
|
||||
@ -4274,18 +4274,19 @@ emit_push_insn (rtx x, machine_mode mode, tree type, rtx size,
|
||||
rtx alignment_pad, bool sibcall_p)
|
||||
{
|
||||
rtx xinner;
|
||||
enum direction stack_direction = STACK_GROWS_DOWNWARD ? downward : upward;
|
||||
pad_direction stack_direction
|
||||
= STACK_GROWS_DOWNWARD ? PAD_DOWNWARD : PAD_UPWARD;
|
||||
|
||||
/* Decide where to pad the argument: `downward' for below,
|
||||
`upward' for above, or `none' for don't pad it.
|
||||
/* Decide where to pad the argument: PAD_DOWNWARD for below,
|
||||
PAD_UPWARD for above, or PAD_NONE for don't pad it.
|
||||
Default is below for small data on big-endian machines; else above. */
|
||||
enum direction where_pad = FUNCTION_ARG_PADDING (mode, type);
|
||||
pad_direction where_pad = targetm.calls.function_arg_padding (mode, type);
|
||||
|
||||
/* Invert direction if stack is post-decrement.
|
||||
FIXME: why? */
|
||||
if (STACK_PUSH_CODE == POST_DEC)
|
||||
if (where_pad != none)
|
||||
where_pad = (where_pad == downward ? upward : downward);
|
||||
if (where_pad != PAD_NONE)
|
||||
where_pad = (where_pad == PAD_DOWNWARD ? PAD_UPWARD : PAD_DOWNWARD);
|
||||
|
||||
xinner = x;
|
||||
|
||||
@ -4357,7 +4358,7 @@ emit_push_insn (rtx x, machine_mode mode, tree type, rtx size,
|
||||
or if padding below and stack grows up.
|
||||
But if space already allocated, this has already been done. */
|
||||
if (extra && args_addr == 0
|
||||
&& where_pad != none && where_pad != stack_direction)
|
||||
&& where_pad != PAD_NONE && where_pad != stack_direction)
|
||||
anti_adjust_stack (GEN_INT (extra));
|
||||
|
||||
move_by_pieces (NULL, xinner, INTVAL (size) - used, align, 0);
|
||||
@ -4386,7 +4387,7 @@ emit_push_insn (rtx x, machine_mode mode, tree type, rtx size,
|
||||
A single stack adjust will do. */
|
||||
if (! args_addr)
|
||||
{
|
||||
temp = push_block (size, extra, where_pad == downward);
|
||||
temp = push_block (size, extra, where_pad == PAD_DOWNWARD);
|
||||
extra = 0;
|
||||
}
|
||||
else if (CONST_INT_P (args_so_far))
|
||||
@ -4480,7 +4481,7 @@ emit_push_insn (rtx x, machine_mode mode, tree type, rtx size,
|
||||
or if padding below and stack grows up.
|
||||
But if space already allocated, this has already been done. */
|
||||
if (extra && args_addr == 0
|
||||
&& where_pad != none && where_pad != stack_direction)
|
||||
&& where_pad != PAD_NONE && where_pad != stack_direction)
|
||||
anti_adjust_stack (GEN_INT (extra));
|
||||
|
||||
/* If we make space by pushing it, we might as well push
|
||||
@ -4531,7 +4532,7 @@ emit_push_insn (rtx x, machine_mode mode, tree type, rtx size,
|
||||
or if padding below and stack grows up.
|
||||
But if space already allocated, this has already been done. */
|
||||
if (extra && args_addr == 0
|
||||
&& where_pad != none && where_pad != stack_direction)
|
||||
&& where_pad != PAD_NONE && where_pad != stack_direction)
|
||||
anti_adjust_stack (GEN_INT (extra));
|
||||
|
||||
#ifdef PUSH_ROUNDING
|
||||
|
@ -2713,7 +2713,7 @@ assign_parm_find_stack_rtl (tree parm, struct assign_parm_data_one *data)
|
||||
is TARGET_FUNCTION_ARG_BOUNDARY. If we're using slot_offset, we're
|
||||
intentionally forcing upward padding. Otherwise we have to come
|
||||
up with a guess at the alignment based on OFFSET_RTX. */
|
||||
if (data->locate.where_pad != downward || data->entry_parm)
|
||||
if (data->locate.where_pad != PAD_DOWNWARD || data->entry_parm)
|
||||
align = boundary;
|
||||
else if (CONST_INT_P (offset_rtx))
|
||||
{
|
||||
@ -2867,7 +2867,7 @@ assign_parm_setup_block_p (struct assign_parm_data_one *data)
|
||||
if (REG_P (data->entry_parm)
|
||||
&& GET_MODE_SIZE (data->promoted_mode) < UNITS_PER_WORD
|
||||
&& (BLOCK_REG_PADDING (data->passed_mode, data->passed_type, 1)
|
||||
== (BYTES_BIG_ENDIAN ? upward : downward)))
|
||||
== (BYTES_BIG_ENDIAN ? PAD_UPWARD : PAD_DOWNWARD)))
|
||||
return true;
|
||||
#endif
|
||||
|
||||
@ -2985,7 +2985,7 @@ assign_parm_setup_block (struct assign_parm_data_all *all,
|
||||
#ifdef BLOCK_REG_PADDING
|
||||
&& (size == UNITS_PER_WORD
|
||||
|| (BLOCK_REG_PADDING (mode, data->passed_type, 1)
|
||||
!= (BYTES_BIG_ENDIAN ? upward : downward)))
|
||||
!= (BYTES_BIG_ENDIAN ? PAD_UPWARD : PAD_DOWNWARD)))
|
||||
#endif
|
||||
)
|
||||
{
|
||||
@ -3025,7 +3025,7 @@ assign_parm_setup_block (struct assign_parm_data_all *all,
|
||||
gcc_checking_assert (BYTES_BIG_ENDIAN
|
||||
&& (BLOCK_REG_PADDING (mode,
|
||||
data->passed_type, 1)
|
||||
== upward));
|
||||
== PAD_UPWARD));
|
||||
|
||||
int by = (UNITS_PER_WORD - size) * BITS_PER_UNIT;
|
||||
|
||||
@ -3046,7 +3046,7 @@ assign_parm_setup_block (struct assign_parm_data_all *all,
|
||||
else if (size != UNITS_PER_WORD
|
||||
#ifdef BLOCK_REG_PADDING
|
||||
&& (BLOCK_REG_PADDING (mode, data->passed_type, 1)
|
||||
== downward)
|
||||
== PAD_DOWNWARD)
|
||||
#else
|
||||
&& BYTES_BIG_ENDIAN
|
||||
#endif
|
||||
@ -3070,7 +3070,7 @@ assign_parm_setup_block (struct assign_parm_data_all *all,
|
||||
#ifdef BLOCK_REG_PADDING
|
||||
gcc_checking_assert (BLOCK_REG_PADDING (GET_MODE (mem),
|
||||
data->passed_type, 0)
|
||||
== upward);
|
||||
== PAD_UPWARD);
|
||||
#endif
|
||||
emit_move_insn (mem, entry_parm);
|
||||
}
|
||||
@ -4098,7 +4098,7 @@ gimplify_parameters (void)
|
||||
rounding affects the initial and starting offsets, but not the argument
|
||||
size.
|
||||
|
||||
The second, controlled by FUNCTION_ARG_PADDING and PARM_BOUNDARY,
|
||||
The second, controlled by TARGET_FUNCTION_ARG_PADDING and PARM_BOUNDARY,
|
||||
optionally rounds the size of the parm to PARM_BOUNDARY. The
|
||||
initial offset is not affected by this rounding, while the size always
|
||||
is and the starting offset may be. */
|
||||
@ -4116,7 +4116,7 @@ locate_and_pad_parm (machine_mode passed_mode, tree type, int in_regs,
|
||||
struct locate_and_pad_arg_data *locate)
|
||||
{
|
||||
tree sizetree;
|
||||
enum direction where_pad;
|
||||
pad_direction where_pad;
|
||||
unsigned int boundary, round_boundary;
|
||||
int part_size_in_regs;
|
||||
|
||||
@ -4142,7 +4142,7 @@ locate_and_pad_parm (machine_mode passed_mode, tree type, int in_regs,
|
||||
|
||||
sizetree
|
||||
= type ? size_in_bytes (type) : size_int (GET_MODE_SIZE (passed_mode));
|
||||
where_pad = FUNCTION_ARG_PADDING (passed_mode, type);
|
||||
where_pad = targetm.calls.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);
|
||||
@ -4191,7 +4191,7 @@ locate_and_pad_parm (machine_mode passed_mode, tree type, int in_regs,
|
||||
|
||||
{
|
||||
tree s2 = sizetree;
|
||||
if (where_pad != none
|
||||
if (where_pad != PAD_NONE
|
||||
&& (!tree_fits_uhwi_p (sizetree)
|
||||
|| (tree_to_uhwi (sizetree) * BITS_PER_UNIT) % round_boundary))
|
||||
s2 = round_up (s2, round_boundary / BITS_PER_UNIT);
|
||||
@ -4216,7 +4216,7 @@ locate_and_pad_parm (machine_mode passed_mode, tree type, int in_regs,
|
||||
/* Pad_below needs the pre-rounded size to know how much to pad
|
||||
below. */
|
||||
locate->offset = locate->slot_offset;
|
||||
if (where_pad == downward)
|
||||
if (where_pad == PAD_DOWNWARD)
|
||||
pad_below (&locate->offset, passed_mode, sizetree);
|
||||
|
||||
}
|
||||
@ -4235,10 +4235,10 @@ locate_and_pad_parm (machine_mode passed_mode, tree type, int in_regs,
|
||||
/* Pad_below needs the pre-rounded size to know how much to pad below
|
||||
so this must be done before rounding up. */
|
||||
locate->offset = locate->slot_offset;
|
||||
if (where_pad == downward)
|
||||
if (where_pad == PAD_DOWNWARD)
|
||||
pad_below (&locate->offset, passed_mode, sizetree);
|
||||
|
||||
if (where_pad != none
|
||||
if (where_pad != PAD_NONE
|
||||
&& (!tree_fits_uhwi_p (sizetree)
|
||||
|| (tree_to_uhwi (sizetree) * BITS_PER_UNIT) % round_boundary))
|
||||
sizetree = round_up (sizetree, round_boundary / BITS_PER_UNIT);
|
||||
|
@ -469,8 +469,6 @@ set_loops_for_fn (struct function *fn, struct loops *loops)
|
||||
data structures. */
|
||||
extern struct machine_function * (*init_machine_status) (void);
|
||||
|
||||
enum direction {none, upward, downward};
|
||||
|
||||
/* Structure to record the size of a sequence of arguments
|
||||
as the sum of a tree-expression and a constant. This structure is
|
||||
also used to store offsets from the stack, which might be negative,
|
||||
@ -499,7 +497,7 @@ struct locate_and_pad_arg_data
|
||||
force alignment for the next argument. */
|
||||
struct args_size alignment_pad;
|
||||
/* Which way we should pad this arg. */
|
||||
enum direction where_pad;
|
||||
pad_direction where_pad;
|
||||
/* slot_offset is at least this aligned. */
|
||||
unsigned int boundary;
|
||||
};
|
||||
|
@ -912,7 +912,7 @@ extern void fancy_abort (const char *, int, const char *)
|
||||
CLEAR_BY_PIECES_P MOVE_BY_PIECES_P SET_BY_PIECES_P \
|
||||
STORE_BY_PIECES_P TARGET_FLT_EVAL_METHOD \
|
||||
HARD_REGNO_CALL_PART_CLOBBERED HARD_REGNO_MODE_OK \
|
||||
MODES_TIEABLE_P
|
||||
MODES_TIEABLE_P FUNCTION_ARG_PADDING
|
||||
|
||||
/* Target macros only used for code built for the target, that have
|
||||
moved to libgcc-tm.h or have never been present elsewhere. */
|
||||
|
@ -4533,6 +4533,24 @@ used for arguments without any special help.",
|
||||
(cumulative_args_t ca, machine_mode mode, const_tree type, bool named),
|
||||
default_function_arg_advance)
|
||||
|
||||
DEFHOOK
|
||||
(function_arg_padding,
|
||||
"This hook determines whether, and in which direction, to pad out\n\
|
||||
an argument of mode @var{mode} and type @var{type}. It returns\n\
|
||||
@code{PAD_UPWARD} to insert padding above the argument, @code{PAD_DOWNWARD}\n\
|
||||
to insert padding below the argument, or @code{PAD_NONE} to inhibit padding.\n\
|
||||
\n\
|
||||
The @emph{amount} of padding is not controlled by this hook, but by\n\
|
||||
@code{TARGET_FUNCTION_ARG_ROUND_BOUNDARY}. It is always just enough\n\
|
||||
to reach the next multiple of that boundary.\n\
|
||||
\n\
|
||||
This hook has a default definition that is right for most systems.\n\
|
||||
For little-endian machines, the default is to pad upward. For\n\
|
||||
big-endian machines, the default is to pad downward for an argument of\n\
|
||||
constant size shorter than an @code{int}, and upward otherwise.",
|
||||
pad_direction, (machine_mode mode, const_tree type),
|
||||
default_function_arg_padding)
|
||||
|
||||
/* Return zero if the argument described by the state of CA should
|
||||
be placed on a stack, or a hard register in which to store the
|
||||
argument. The values MODE, TYPE, and NAMED describe that
|
||||
|
@ -734,6 +734,31 @@ default_function_arg_advance (cumulative_args_t ca ATTRIBUTE_UNUSED,
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
/* Default implementation of TARGET_FUNCTION_ARG_PADDING: usually pad
|
||||
upward, but pad short args downward on big-endian machines. */
|
||||
|
||||
pad_direction
|
||||
default_function_arg_padding (machine_mode mode, const_tree type)
|
||||
{
|
||||
if (!BYTES_BIG_ENDIAN)
|
||||
return PAD_UPWARD;
|
||||
|
||||
unsigned HOST_WIDE_INT size;
|
||||
if (mode == BLKmode)
|
||||
{
|
||||
if (!type || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
|
||||
return PAD_UPWARD;
|
||||
size = int_size_in_bytes (type);
|
||||
}
|
||||
else
|
||||
size = GET_MODE_SIZE (mode);
|
||||
|
||||
if (size < (PARM_BOUNDARY / BITS_PER_UNIT))
|
||||
return PAD_DOWNWARD;
|
||||
|
||||
return PAD_UPWARD;
|
||||
}
|
||||
|
||||
rtx
|
||||
default_function_arg (cumulative_args_t ca ATTRIBUTE_UNUSED,
|
||||
machine_mode mode ATTRIBUTE_UNUSED,
|
||||
|
@ -132,6 +132,7 @@ extern const char *hook_invalid_arg_for_unprototyped_fn
|
||||
(const_tree, const_tree, const_tree);
|
||||
extern void default_function_arg_advance
|
||||
(cumulative_args_t, machine_mode, const_tree, bool);
|
||||
extern pad_direction default_function_arg_padding (machine_mode, const_tree);
|
||||
extern rtx default_function_arg
|
||||
(cumulative_args_t, machine_mode, const_tree, bool);
|
||||
extern rtx default_function_incoming_arg
|
||||
|
Loading…
x
Reference in New Issue
Block a user