Use function_arg_info for TARGET_FUNCTION_(INCOMING_)ARG
This patch makes both TARGET_FUNCTION_ARG and TARGET_FUNCTION_INCOMING_ARG take a function_arg_info. They have to be done together since many targets use the same function for both. The hooks are passed the promoted mode instead of the original type mode. 2019-08-20 Richard Sandiford <richard.sandiford@arm.com> gcc/ * target.def (function_arg, function_incoming_arg): Take a function_arg_info instead of a mode, tree and named flag. * doc/tm.texi: Regenerate. * targhooks.h (default_function_arg): Take a function_arg_info instead of a mode, tree and named flag. (default_function_incoming_arg): Likewise. * targhooks.c (default_function_arg): Likewise. (default_function_incoming_arg): Likewise. * calls.h (function_arg_info::end_marker_p): New function. (function_arg_info::end_marker): Likewise. * calls.c (prepare_call_address, initialize_argument_information) (expand_call, emit_library_call_value_1): Update calls to targetm.calls.function_arg and targetm.calls.function_incoming_arg. * dse.c: Include calls.h. (get_call_args): Update call to targetm.calls.function_arg. * expr.c (block_move_libcall_safe_for_call_parm): Likewise. * var-tracking.c (prepare_call_arguments): Likewise. * function.c (assign_parm_find_entry_rtl): Update call to targetm.calls.function_incoming_arg. * config/aarch64/aarch64.c (aarch64_function_arg): Take a function_arg_info instead of a mode, tree and named flag. * config/alpha/alpha.c (alpha_function_arg): Likewise. * config/arc/arc.c (arc_function_arg): Likewise. * config/arm/arm.c (arm_function_arg): Likewise. (cmse_func_args_or_return_in_stack): Update call accordingly. (arm_function_ok_for_sibcall): Likewise. (cmse_nonsecure_call_clear_caller_saved): Likewise. * config/avr/avr.c (avr_function_arg): Take a function_arg_info instead of a mode, tree and named flag. * config/bfin/bfin.c (bfin_function_arg): Likewise. * config/c6x/c6x.c (c6x_function_arg): Likewise. (c6x_call_saved_register_used): Update call accordingly. * config/cr16/cr16.c (cr16_function_arg): Take a function_arg_info instead of a mode, tree and named flag. * config/cris/cris.c (cris_function_arg, cris_function_incoming_arg) (cris_function_arg_1): Likewise. * config/csky/csky.c (csky_function_arg): Likewise. * config/epiphany/epiphany.c (epiphany_function_arg): Likewise. * config/fr30/fr30.c (fr30_function_arg): Likewise. * config/frv/frv.c (frv_function_arg, frv_function_incoming_arg) (frv_function_arg_1): Likewise. * config/ft32/ft32.c (ft32_function_arg): Likewise. * config/gcn/gcn.c (gcn_function_arg): Likewise. * config/h8300/h8300.c (h8300_function_arg): Likewise. * config/i386/i386.c (ix86_function_arg): Likewise. * config/ia64/ia64.c (ia64_function_arg, ia64_function_incoming_arg) (ia64_function_arg_1): Likewise. * config/iq2000/iq2000.c (iq2000_function_arg): Likewise. (iq2000_expand_prologue, iq2000_pass_by_reference): Update call accordingly. * config/lm32/lm32.c (lm32_function_arg): Take a function_arg_info instead of a mode, tree and named flag. * config/m32c/m32c.c (m32c_function_arg): Likewise. * config/m32r/m32r.c (m32r_function_arg): Likewise. * config/m68k/m68k.c (m68k_function_arg): Likewise. * config/mcore/mcore.c (mcore_function_arg): Likewise. * config/microblaze/microblaze.c (microblaze_function_arg): Likewise. (microblaze_expand_prologue): Update call accordingly. * config/mips/mips.c (mips_function_arg): Take a function_arg_info instead of a mode, tree and named flag. * config/mmix/mmix.c (mmix_function_incoming_arg, mmix_function_arg) (mmix_function_arg_1): Likewise. * config/mn10300/mn10300.c (mn10300_function_arg): Likewise. * config/moxie/moxie.c (moxie_function_arg): Likewise. * config/msp430/msp430.c (msp430_function_arg): Likewise. * config/nds32/nds32.c (nds32_function_arg): Likewise. * config/nios2/nios2.c (nios2_function_arg): Likewise. * config/nvptx/nvptx.c (nvptx_function_arg): Likewise. (nvptx_function_incoming_arg): Likewise. * config/or1k/or1k.c (or1k_function_arg): Likewise. * config/pa/pa.c (pa_function_arg): Likewise. * config/pdp11/pdp11.c (pdp11_function_arg): Likewise. * config/pru/pru.c (pru_function_arg): Likewise. * config/riscv/riscv.c (riscv_function_arg): Likewise. * config/rl78/rl78.c (rl78_function_arg): Likewise. * config/rs6000/rs6000-internal.h (rs6000_function_arg): Likewise. * config/rs6000/rs6000-call.c (rs6000_function_arg): Likewise. (rs6000_parm_needs_stack): Update call accordingly. * config/rx/rx.c (rx_function_arg): Take a function_arg_info instead of a mode, tree and named flag. * config/s390/s390.c (s390_function_arg): Likewise. (s390_call_saved_register_used): Update call accordingly. * config/sh/sh.c (sh_function_arg): Take a function_arg_info instead of a mode, tree and named flag. (sh_output_mi_thunk): Update call accordingly. * config/sparc/sparc.c (sparc_function_arg_1, sparc_function_arg) (sparc_function_incoming_arg): Take a function_arg_info instead of a mode, tree and named flag. * config/spu/spu.c (spu_function_arg): Likewise. * config/stormy16/stormy16.c (xstormy16_function_arg): Likewise. * config/tilegx/tilegx.c (tilegx_function_arg): Likewise. * config/tilepro/tilepro.c (tilepro_function_arg): Likewise. * config/v850/v850.c (v850_function_arg): Likewise. * config/vax/vax.c (vax_function_arg): Likewise. * config/visium/visium.c (visium_function_arg): Likewise. * config/xtensa/xtensa.c (xtensa_function_arg_1, xtensa_function_arg) (xtensa_function_incoming_arg): Likewise. From-SVN: r274700
This commit is contained in:
parent
e7056ca417
commit
6783fdb705
100
gcc/ChangeLog
100
gcc/ChangeLog
|
@ -1,3 +1,103 @@
|
|||
2019-08-20 Richard Sandiford <richard.sandiford@arm.com>
|
||||
|
||||
* target.def (function_arg, function_incoming_arg): Take a
|
||||
function_arg_info instead of a mode, tree and named flag.
|
||||
* doc/tm.texi: Regenerate.
|
||||
* targhooks.h (default_function_arg): Take a function_arg_info
|
||||
instead of a mode, tree and named flag.
|
||||
(default_function_incoming_arg): Likewise.
|
||||
* targhooks.c (default_function_arg): Likewise.
|
||||
(default_function_incoming_arg): Likewise.
|
||||
* calls.h (function_arg_info::end_marker_p): New function.
|
||||
(function_arg_info::end_marker): Likewise.
|
||||
* calls.c (prepare_call_address, initialize_argument_information)
|
||||
(expand_call, emit_library_call_value_1): Update calls to
|
||||
targetm.calls.function_arg and targetm.calls.function_incoming_arg.
|
||||
* dse.c: Include calls.h.
|
||||
(get_call_args): Update call to targetm.calls.function_arg.
|
||||
* expr.c (block_move_libcall_safe_for_call_parm): Likewise.
|
||||
* var-tracking.c (prepare_call_arguments): Likewise.
|
||||
* function.c (assign_parm_find_entry_rtl): Update call to
|
||||
targetm.calls.function_incoming_arg.
|
||||
* config/aarch64/aarch64.c (aarch64_function_arg): Take a
|
||||
function_arg_info instead of a mode, tree and named flag.
|
||||
* config/alpha/alpha.c (alpha_function_arg): Likewise.
|
||||
* config/arc/arc.c (arc_function_arg): Likewise.
|
||||
* config/arm/arm.c (arm_function_arg): Likewise.
|
||||
(cmse_func_args_or_return_in_stack): Update call accordingly.
|
||||
(arm_function_ok_for_sibcall): Likewise.
|
||||
(cmse_nonsecure_call_clear_caller_saved): Likewise.
|
||||
* config/avr/avr.c (avr_function_arg): Take a function_arg_info
|
||||
instead of a mode, tree and named flag.
|
||||
* config/bfin/bfin.c (bfin_function_arg): Likewise.
|
||||
* config/c6x/c6x.c (c6x_function_arg): Likewise.
|
||||
(c6x_call_saved_register_used): Update call accordingly.
|
||||
* config/cr16/cr16.c (cr16_function_arg): Take a function_arg_info
|
||||
instead of a mode, tree and named flag.
|
||||
* config/cris/cris.c (cris_function_arg, cris_function_incoming_arg)
|
||||
(cris_function_arg_1): Likewise.
|
||||
* config/csky/csky.c (csky_function_arg): Likewise.
|
||||
* config/epiphany/epiphany.c (epiphany_function_arg): Likewise.
|
||||
* config/fr30/fr30.c (fr30_function_arg): Likewise.
|
||||
* config/frv/frv.c (frv_function_arg, frv_function_incoming_arg)
|
||||
(frv_function_arg_1): Likewise.
|
||||
* config/ft32/ft32.c (ft32_function_arg): Likewise.
|
||||
* config/gcn/gcn.c (gcn_function_arg): Likewise.
|
||||
* config/h8300/h8300.c (h8300_function_arg): Likewise.
|
||||
* config/i386/i386.c (ix86_function_arg): Likewise.
|
||||
* config/ia64/ia64.c (ia64_function_arg, ia64_function_incoming_arg)
|
||||
(ia64_function_arg_1): Likewise.
|
||||
* config/iq2000/iq2000.c (iq2000_function_arg): Likewise.
|
||||
(iq2000_expand_prologue, iq2000_pass_by_reference): Update call
|
||||
accordingly.
|
||||
* config/lm32/lm32.c (lm32_function_arg): Take a function_arg_info
|
||||
instead of a mode, tree and named flag.
|
||||
* config/m32c/m32c.c (m32c_function_arg): Likewise.
|
||||
* config/m32r/m32r.c (m32r_function_arg): Likewise.
|
||||
* config/m68k/m68k.c (m68k_function_arg): Likewise.
|
||||
* config/mcore/mcore.c (mcore_function_arg): Likewise.
|
||||
* config/microblaze/microblaze.c (microblaze_function_arg): Likewise.
|
||||
(microblaze_expand_prologue): Update call accordingly.
|
||||
* config/mips/mips.c (mips_function_arg): Take a function_arg_info
|
||||
instead of a mode, tree and named flag.
|
||||
* config/mmix/mmix.c (mmix_function_incoming_arg, mmix_function_arg)
|
||||
(mmix_function_arg_1): Likewise.
|
||||
* config/mn10300/mn10300.c (mn10300_function_arg): Likewise.
|
||||
* config/moxie/moxie.c (moxie_function_arg): Likewise.
|
||||
* config/msp430/msp430.c (msp430_function_arg): Likewise.
|
||||
* config/nds32/nds32.c (nds32_function_arg): Likewise.
|
||||
* config/nios2/nios2.c (nios2_function_arg): Likewise.
|
||||
* config/nvptx/nvptx.c (nvptx_function_arg): Likewise.
|
||||
(nvptx_function_incoming_arg): Likewise.
|
||||
* config/or1k/or1k.c (or1k_function_arg): Likewise.
|
||||
* config/pa/pa.c (pa_function_arg): Likewise.
|
||||
* config/pdp11/pdp11.c (pdp11_function_arg): Likewise.
|
||||
* config/pru/pru.c (pru_function_arg): Likewise.
|
||||
* config/riscv/riscv.c (riscv_function_arg): Likewise.
|
||||
* config/rl78/rl78.c (rl78_function_arg): Likewise.
|
||||
* config/rs6000/rs6000-internal.h (rs6000_function_arg): Likewise.
|
||||
* config/rs6000/rs6000-call.c (rs6000_function_arg): Likewise.
|
||||
(rs6000_parm_needs_stack): Update call accordingly.
|
||||
* config/rx/rx.c (rx_function_arg): Take a function_arg_info
|
||||
instead of a mode, tree and named flag.
|
||||
* config/s390/s390.c (s390_function_arg): Likewise.
|
||||
(s390_call_saved_register_used): Update call accordingly.
|
||||
* config/sh/sh.c (sh_function_arg): Take a function_arg_info
|
||||
instead of a mode, tree and named flag.
|
||||
(sh_output_mi_thunk): Update call accordingly.
|
||||
* config/sparc/sparc.c (sparc_function_arg_1, sparc_function_arg)
|
||||
(sparc_function_incoming_arg): Take a function_arg_info instead of
|
||||
a mode, tree and named flag.
|
||||
* config/spu/spu.c (spu_function_arg): Likewise.
|
||||
* config/stormy16/stormy16.c (xstormy16_function_arg): Likewise.
|
||||
* config/tilegx/tilegx.c (tilegx_function_arg): Likewise.
|
||||
* config/tilepro/tilepro.c (tilepro_function_arg): Likewise.
|
||||
* config/v850/v850.c (v850_function_arg): Likewise.
|
||||
* config/vax/vax.c (vax_function_arg): Likewise.
|
||||
* config/visium/visium.c (visium_function_arg): Likewise.
|
||||
* config/xtensa/xtensa.c (xtensa_function_arg_1, xtensa_function_arg)
|
||||
(xtensa_function_incoming_arg): Likewise.
|
||||
|
||||
2019-08-20 Richard Sandiford <richard.sandiford@arm.com>
|
||||
|
||||
* target.def (setup_incoming_varargs): Take a function_arg_info
|
||||
|
|
30
gcc/calls.c
30
gcc/calls.c
|
@ -346,7 +346,8 @@ prepare_call_address (tree fndecl_or_type, rtx funexp, rtx static_chain_value,
|
|||
It is zero if this call doesn't want a structure value.
|
||||
|
||||
NEXT_ARG_REG is the rtx that results from executing
|
||||
targetm.calls.function_arg (&args_so_far, VOIDmode, void_type_node, true)
|
||||
targetm.calls.function_arg (&args_so_far,
|
||||
function_arg_info::end_marker ());
|
||||
just after all the args have had their registers assigned.
|
||||
This could be whatever you like, but normally it is the first
|
||||
arg-register beyond those used for args in this call,
|
||||
|
@ -2124,8 +2125,8 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED,
|
|||
|
||||
targetm.calls.warn_parameter_passing_abi (args_so_far, type);
|
||||
|
||||
args[i].reg = targetm.calls.function_arg (args_so_far, mode, type,
|
||||
argpos < n_named_args);
|
||||
function_arg_info arg (type, mode, argpos < n_named_args);
|
||||
args[i].reg = targetm.calls.function_arg (args_so_far, arg);
|
||||
|
||||
if (args[i].reg && CONST_INT_P (args[i].reg))
|
||||
args[i].reg = NULL;
|
||||
|
@ -2135,12 +2136,10 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED,
|
|||
arguments have to go into the incoming registers. */
|
||||
if (targetm.calls.function_incoming_arg != targetm.calls.function_arg)
|
||||
args[i].tail_call_reg
|
||||
= targetm.calls.function_incoming_arg (args_so_far, mode, type,
|
||||
argpos < n_named_args);
|
||||
= targetm.calls.function_incoming_arg (args_so_far, arg);
|
||||
else
|
||||
args[i].tail_call_reg = args[i].reg;
|
||||
|
||||
function_arg_info arg (type, mode, argpos < n_named_args);
|
||||
if (args[i].reg)
|
||||
args[i].partial = targetm.calls.arg_partial_bytes (args_so_far, arg);
|
||||
|
||||
|
@ -4244,14 +4243,11 @@ expand_call (tree exp, rtx target, int ignore)
|
|||
/* Set up next argument register. For sibling calls on machines
|
||||
with register windows this should be the incoming register. */
|
||||
if (pass == 0)
|
||||
next_arg_reg = targetm.calls.function_incoming_arg (args_so_far,
|
||||
VOIDmode,
|
||||
void_type_node,
|
||||
true);
|
||||
next_arg_reg = targetm.calls.function_incoming_arg
|
||||
(args_so_far, function_arg_info::end_marker ());
|
||||
else
|
||||
next_arg_reg = targetm.calls.function_arg (args_so_far,
|
||||
VOIDmode, void_type_node,
|
||||
true);
|
||||
next_arg_reg = targetm.calls.function_arg
|
||||
(args_so_far, function_arg_info::end_marker ());
|
||||
|
||||
if (pass == 1 && (return_flags & ERF_RETURNS_ARG))
|
||||
{
|
||||
|
@ -4869,8 +4865,7 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
|
|||
argvec[count].partial = 0;
|
||||
|
||||
function_arg_info ptr_arg (Pmode, /*named=*/true);
|
||||
argvec[count].reg = targetm.calls.function_arg (args_so_far,
|
||||
Pmode, NULL_TREE, true);
|
||||
argvec[count].reg = targetm.calls.function_arg (args_so_far, ptr_arg);
|
||||
gcc_assert (targetm.calls.arg_partial_bytes (args_so_far, ptr_arg) == 0);
|
||||
|
||||
locate_and_pad_parm (Pmode, NULL_TREE,
|
||||
|
@ -4953,8 +4948,7 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
|
|||
function_arg_info arg (mode, /*named=*/true);
|
||||
argvec[count].mode = mode;
|
||||
argvec[count].value = convert_modes (mode, GET_MODE (val), val, unsigned_p);
|
||||
argvec[count].reg = targetm.calls.function_arg (args_so_far, mode,
|
||||
NULL_TREE, true);
|
||||
argvec[count].reg = targetm.calls.function_arg (args_so_far, arg);
|
||||
|
||||
argvec[count].partial
|
||||
= targetm.calls.arg_partial_bytes (args_so_far, arg);
|
||||
|
@ -5332,7 +5326,7 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
|
|||
original_args_size.constant, args_size.constant,
|
||||
struct_value_size,
|
||||
targetm.calls.function_arg (args_so_far,
|
||||
VOIDmode, void_type_node, true),
|
||||
function_arg_info::end_marker ()),
|
||||
valreg,
|
||||
old_inhibit_defer_pop + 1, call_fusage, flags, args_so_far);
|
||||
|
||||
|
|
11
gcc/calls.h
11
gcc/calls.h
|
@ -77,6 +77,17 @@ public:
|
|||
return GET_MODE_SIZE (mode);
|
||||
}
|
||||
|
||||
/* True if the argument represents the end of the argument list,
|
||||
as returned by end_marker (). */
|
||||
bool end_marker_p () const { return mode == VOIDmode; }
|
||||
|
||||
/* Return a function_arg_info that represents the end of the
|
||||
argument list. */
|
||||
static function_arg_info end_marker ()
|
||||
{
|
||||
return function_arg_info (void_type_node, /*named=*/true);
|
||||
}
|
||||
|
||||
/* The type of the argument, or null if not known (which is true for
|
||||
libgcc support functions). */
|
||||
tree type;
|
||||
|
|
|
@ -4801,16 +4801,15 @@ on_stack:
|
|||
/* Implement TARGET_FUNCTION_ARG. */
|
||||
|
||||
static rtx
|
||||
aarch64_function_arg (cumulative_args_t pcum_v, machine_mode mode,
|
||||
const_tree type, bool named)
|
||||
aarch64_function_arg (cumulative_args_t pcum_v, const function_arg_info &arg)
|
||||
{
|
||||
CUMULATIVE_ARGS *pcum = get_cumulative_args (pcum_v);
|
||||
gcc_assert (pcum->pcs_variant == ARM_PCS_AAPCS64);
|
||||
|
||||
if (mode == VOIDmode)
|
||||
if (arg.end_marker_p ())
|
||||
return NULL_RTX;
|
||||
|
||||
aarch64_layout_arg (pcum_v, mode, type, named);
|
||||
aarch64_layout_arg (pcum_v, arg.mode, arg.type, arg.named);
|
||||
return pcum->aapcs_reg;
|
||||
}
|
||||
|
||||
|
|
|
@ -5545,38 +5545,32 @@ alpha_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
|
|||
Value is zero to push the argument on the stack,
|
||||
or a hard register in which to store the argument.
|
||||
|
||||
MODE is the argument's machine mode.
|
||||
TYPE is the data type of the argument (as a tree).
|
||||
This is null for libcalls where that information may
|
||||
not be available.
|
||||
CUM is a variable of type CUMULATIVE_ARGS which gives info about
|
||||
the preceding args and about the function being called.
|
||||
NAMED is nonzero if this argument is a named parameter
|
||||
(otherwise it is an extra parameter matching an ellipsis).
|
||||
ARG is a description of the argument.
|
||||
|
||||
On Alpha the first 6 words of args are normally in registers
|
||||
and the rest are pushed. */
|
||||
|
||||
static rtx
|
||||
alpha_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
||||
const_tree type, bool named ATTRIBUTE_UNUSED)
|
||||
alpha_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
|
||||
{
|
||||
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
|
||||
int basereg;
|
||||
int num_args;
|
||||
|
||||
/* Don't get confused and pass small structures in FP registers. */
|
||||
if (type && AGGREGATE_TYPE_P (type))
|
||||
if (arg.aggregate_type_p ())
|
||||
basereg = 16;
|
||||
else
|
||||
{
|
||||
/* With alpha_split_complex_arg, we shouldn't see any raw complex
|
||||
values here. */
|
||||
gcc_checking_assert (!COMPLEX_MODE_P (mode));
|
||||
gcc_checking_assert (!COMPLEX_MODE_P (arg.mode));
|
||||
|
||||
/* Set up defaults for FP operands passed in FP registers, and
|
||||
integral operands passed in integer registers. */
|
||||
if (TARGET_FPREGS && GET_MODE_CLASS (mode) == MODE_FLOAT)
|
||||
if (TARGET_FPREGS && GET_MODE_CLASS (arg.mode) == MODE_FLOAT)
|
||||
basereg = 32 + 16;
|
||||
else
|
||||
basereg = 16;
|
||||
|
@ -5586,12 +5580,12 @@ alpha_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
|||
the two platforms, so we can't avoid conditional compilation. */
|
||||
#if TARGET_ABI_OPEN_VMS
|
||||
{
|
||||
if (mode == VOIDmode)
|
||||
if (arg.end_marker_p ())
|
||||
return alpha_arg_info_reg_val (*cum);
|
||||
|
||||
num_args = cum->num_args;
|
||||
if (num_args >= 6
|
||||
|| targetm.calls.must_pass_in_stack (mode, type))
|
||||
|| targetm.calls.must_pass_in_stack (arg.mode, arg.type))
|
||||
return NULL_RTX;
|
||||
}
|
||||
#elif TARGET_ABI_OSF
|
||||
|
@ -5600,17 +5594,16 @@ alpha_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
|||
return NULL_RTX;
|
||||
num_args = *cum;
|
||||
|
||||
/* VOID is passed as a special flag for "last argument". */
|
||||
if (type == void_type_node)
|
||||
if (arg.end_marker_p ())
|
||||
basereg = 16;
|
||||
else if (targetm.calls.must_pass_in_stack (mode, type))
|
||||
else if (targetm.calls.must_pass_in_stack (arg.mode, arg.type))
|
||||
return NULL_RTX;
|
||||
}
|
||||
#else
|
||||
#error Unhandled ABI
|
||||
#endif
|
||||
|
||||
return gen_rtx_REG (mode, num_args + basereg);
|
||||
return gen_rtx_REG (arg.mode, num_args + basereg);
|
||||
}
|
||||
|
||||
/* Update the data in CUM to advance over an argument
|
||||
|
|
|
@ -6449,63 +6449,27 @@ arc_arg_partial_bytes (cumulative_args_t cum_v, const function_arg_info &arg)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* This function is used to control a function argument is passed in a
|
||||
register, and which register.
|
||||
|
||||
The arguments are CUM, of type CUMULATIVE_ARGS, which summarizes
|
||||
(in a way defined by INIT_CUMULATIVE_ARGS and FUNCTION_ARG_ADVANCE)
|
||||
all of the previous arguments so far passed in registers; MODE, the
|
||||
machine mode of the argument; TYPE, the data type of the argument
|
||||
as a tree node or 0 if that is not known (which happens for C
|
||||
support library functions); and NAMED, which is 1 for an ordinary
|
||||
argument and 0 for nameless arguments that correspond to `...' in
|
||||
the called function's prototype.
|
||||
|
||||
The returned value should either be a `reg' RTX for the hard
|
||||
register in which to pass the argument, or zero to pass the
|
||||
argument on the stack.
|
||||
|
||||
For machines like the Vax and 68000, where normally all arguments
|
||||
are pushed, zero suffices as a definition.
|
||||
|
||||
The usual way to make the ANSI library `stdarg.h' work on a machine
|
||||
where some arguments are usually passed in registers, is to cause
|
||||
nameless arguments to be passed on the stack instead. This is done
|
||||
by making the function return 0 whenever NAMED is 0.
|
||||
|
||||
You may use the macro `MUST_PASS_IN_STACK (MODE, TYPE)' in the
|
||||
definition of this function to determine if this argument is of a
|
||||
type that must be passed in the stack. If `REG_PARM_STACK_SPACE'
|
||||
is not defined and the function returns non-zero for such an
|
||||
argument, the compiler will abort. If `REG_PARM_STACK_SPACE' is
|
||||
defined, the argument will be computed in the stack and then loaded
|
||||
into a register.
|
||||
|
||||
The function is used to implement macro FUNCTION_ARG. */
|
||||
/* On the ARC the first MAX_ARC_PARM_REGS args are normally in registers
|
||||
and the rest are pushed. */
|
||||
/* Implement TARGET_FUNCTION_ARG. On the ARC the first MAX_ARC_PARM_REGS
|
||||
args are normally in registers and the rest are pushed. */
|
||||
|
||||
static rtx
|
||||
arc_function_arg (cumulative_args_t cum_v,
|
||||
machine_mode mode,
|
||||
const_tree type ATTRIBUTE_UNUSED,
|
||||
bool named ATTRIBUTE_UNUSED)
|
||||
arc_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
|
||||
{
|
||||
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
|
||||
int arg_num = *cum;
|
||||
rtx ret;
|
||||
const char *debstr ATTRIBUTE_UNUSED;
|
||||
|
||||
arg_num = ROUND_ADVANCE_CUM (arg_num, mode, type);
|
||||
arg_num = ROUND_ADVANCE_CUM (arg_num, arg.mode, arg.type);
|
||||
/* Return a marker for use in the call instruction. */
|
||||
if (mode == VOIDmode)
|
||||
if (arg.end_marker_p ())
|
||||
{
|
||||
ret = const0_rtx;
|
||||
debstr = "<0>";
|
||||
}
|
||||
else if (GPR_REST_ARG_REGS (arg_num) > 0)
|
||||
{
|
||||
ret = gen_rtx_REG (mode, arg_num);
|
||||
ret = gen_rtx_REG (arg.mode, arg_num);
|
||||
debstr = reg_names [arg_num];
|
||||
}
|
||||
else
|
||||
|
|
|
@ -189,8 +189,7 @@ static rtx_insn *emit_set_insn (rtx, rtx);
|
|||
static rtx emit_multi_reg_push (unsigned long, unsigned long);
|
||||
static int arm_arg_partial_bytes (cumulative_args_t,
|
||||
const function_arg_info &);
|
||||
static rtx arm_function_arg (cumulative_args_t, machine_mode,
|
||||
const_tree, bool);
|
||||
static rtx arm_function_arg (cumulative_args_t, const function_arg_info &);
|
||||
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);
|
||||
|
@ -6658,14 +6657,9 @@ arm_needs_doubleword_align (machine_mode mode, const_tree type)
|
|||
Value is zero to push the argument on the stack,
|
||||
or a hard register in which to store the argument.
|
||||
|
||||
MODE is the argument's machine mode.
|
||||
TYPE is the data type of the argument (as a tree).
|
||||
This is null for libcalls where that information may
|
||||
not be available.
|
||||
CUM is a variable of type CUMULATIVE_ARGS which gives info about
|
||||
the preceding args and about the function being called.
|
||||
NAMED is nonzero if this argument is a named parameter
|
||||
(otherwise it is an extra parameter matching an ellipsis).
|
||||
ARG is a description of the argument.
|
||||
|
||||
On the ARM, normally the first 16 bytes are passed in registers r0-r3; all
|
||||
other arguments are passed on the stack. If (NAMED == 0) (which happens
|
||||
|
@ -6674,31 +6668,31 @@ arm_needs_doubleword_align (machine_mode mode, const_tree type)
|
|||
indeed make it pass in the stack if necessary). */
|
||||
|
||||
static rtx
|
||||
arm_function_arg (cumulative_args_t pcum_v, machine_mode mode,
|
||||
const_tree type, bool named)
|
||||
arm_function_arg (cumulative_args_t pcum_v, const function_arg_info &arg)
|
||||
{
|
||||
CUMULATIVE_ARGS *pcum = get_cumulative_args (pcum_v);
|
||||
int nregs;
|
||||
|
||||
/* Handle the special case quickly. Pick an arbitrary value for op2 of
|
||||
a call insn (op3 of a call_value insn). */
|
||||
if (mode == VOIDmode)
|
||||
if (arg.end_marker_p ())
|
||||
return const0_rtx;
|
||||
|
||||
if (pcum->pcs_variant <= ARM_PCS_AAPCS_LOCAL)
|
||||
{
|
||||
aapcs_layout_arg (pcum, mode, type, named);
|
||||
aapcs_layout_arg (pcum, arg.mode, arg.type, arg.named);
|
||||
return pcum->aapcs_reg;
|
||||
}
|
||||
|
||||
/* Varargs vectors are treated the same as long long.
|
||||
named_count avoids having to change the way arm handles 'named' */
|
||||
if (TARGET_IWMMXT_ABI
|
||||
&& arm_vector_mode_supported_p (mode)
|
||||
&& arm_vector_mode_supported_p (arg.mode)
|
||||
&& pcum->named_count > pcum->nargs + 1)
|
||||
{
|
||||
if (pcum->iwmmxt_nregs <= 9)
|
||||
return gen_rtx_REG (mode, pcum->iwmmxt_nregs + FIRST_IWMMXT_REGNUM);
|
||||
return gen_rtx_REG (arg.mode,
|
||||
pcum->iwmmxt_nregs + FIRST_IWMMXT_REGNUM);
|
||||
else
|
||||
{
|
||||
pcum->can_split = false;
|
||||
|
@ -6709,16 +6703,16 @@ arm_function_arg (cumulative_args_t pcum_v, machine_mode mode,
|
|||
/* Put doubleword aligned quantities in even register pairs. */
|
||||
if ((pcum->nregs & 1) && ARM_DOUBLEWORD_ALIGN)
|
||||
{
|
||||
int res = arm_needs_doubleword_align (mode, type);
|
||||
int res = arm_needs_doubleword_align (arg.mode, arg.type);
|
||||
if (res < 0 && warn_psabi)
|
||||
inform (input_location, "parameter passing for argument of type "
|
||||
"%qT changed in GCC 7.1", type);
|
||||
"%qT changed in GCC 7.1", arg.type);
|
||||
else if (res > 0)
|
||||
{
|
||||
pcum->nregs++;
|
||||
if (res > 1 && warn_psabi)
|
||||
inform (input_location, "parameter passing for argument of type "
|
||||
"%qT changed in GCC 9.1", type);
|
||||
"%qT changed in GCC 9.1", arg.type);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6728,12 +6722,12 @@ arm_function_arg (cumulative_args_t pcum_v, machine_mode mode,
|
|||
if (pcum->can_split)
|
||||
nregs = 1;
|
||||
else
|
||||
nregs = ARM_NUM_REGS2 (mode, type);
|
||||
nregs = ARM_NUM_REGS2 (arg.mode, arg.type);
|
||||
|
||||
if (!named || pcum->nregs + nregs > NUM_ARG_REGS)
|
||||
if (!arg.named || pcum->nregs + nregs > NUM_ARG_REGS)
|
||||
return NULL_RTX;
|
||||
|
||||
return gen_rtx_REG (mode, pcum->nregs);
|
||||
return gen_rtx_REG (arg.mode, pcum->nregs);
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
|
@ -6999,7 +6993,7 @@ cmse_func_args_or_return_in_stack (tree fndecl, tree name, tree fntype)
|
|||
function_arg_info arg (arg_type, /*named=*/true);
|
||||
if (!first_param)
|
||||
arm_function_arg_advance (args_so_far, arg_mode, arg_type, true);
|
||||
arg_rtx = arm_function_arg (args_so_far, arg_mode, arg_type, true);
|
||||
arg_rtx = arm_function_arg (args_so_far, arg);
|
||||
if (!arg_rtx || arm_arg_partial_bytes (args_so_far, arg))
|
||||
{
|
||||
error ("%qE attribute not available to functions with arguments "
|
||||
|
@ -7387,7 +7381,8 @@ arm_function_ok_for_sibcall (tree decl, tree exp)
|
|||
arm_function_arg_advance (cum_v, TYPE_MODE (type), type, true);
|
||||
}
|
||||
|
||||
if (!arm_function_arg (cum_v, SImode, integer_type_node, true))
|
||||
function_arg_info arg (integer_type_node, /*named=*/true);
|
||||
if (!arm_function_arg (cum_v, arg))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -17451,12 +17446,12 @@ cmse_nonsecure_call_clear_caller_saved (void)
|
|||
if (VOID_TYPE_P (arg_type))
|
||||
continue;
|
||||
|
||||
function_arg_info arg (arg_type, /*named=*/true);
|
||||
if (!first_param)
|
||||
arm_function_arg_advance (args_so_far, arg_mode, arg_type,
|
||||
true);
|
||||
|
||||
arg_rtx = arm_function_arg (args_so_far, arg_mode, arg_type,
|
||||
true);
|
||||
arg_rtx = arm_function_arg (args_so_far, arg);
|
||||
gcc_assert (REG_P (arg_rtx));
|
||||
to_clear_args_mask
|
||||
= compute_not_to_clear_mask (arg_type, arg_rtx,
|
||||
|
|
|
@ -3388,14 +3388,13 @@ avr_num_arg_regs (machine_mode mode, const_tree type)
|
|||
in a register, and which register. */
|
||||
|
||||
static rtx
|
||||
avr_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
||||
const_tree type, bool named ATTRIBUTE_UNUSED)
|
||||
avr_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
|
||||
{
|
||||
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
|
||||
int bytes = avr_num_arg_regs (mode, type);
|
||||
int bytes = avr_num_arg_regs (arg.mode, arg.type);
|
||||
|
||||
if (cum->nregs && bytes <= cum->nregs)
|
||||
return gen_rtx_REG (mode, cum->regno - bytes);
|
||||
return gen_rtx_REG (arg.mode, cum->regno - bytes);
|
||||
|
||||
return NULL_RTX;
|
||||
}
|
||||
|
|
|
@ -1682,24 +1682,17 @@ bfin_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
|
|||
Value is zero to push the argument on the stack,
|
||||
or a hard register in which to store the argument.
|
||||
|
||||
MODE is the argument's machine mode.
|
||||
TYPE is the data type of the argument (as a tree).
|
||||
This is null for libcalls where that information may
|
||||
not be available.
|
||||
CUM is a variable of type CUMULATIVE_ARGS which gives info about
|
||||
the preceding args and about the function being called.
|
||||
NAMED is nonzero if this argument is a named parameter
|
||||
(otherwise it is an extra parameter matching an ellipsis). */
|
||||
ARG is a description of the argument. */
|
||||
|
||||
static rtx
|
||||
bfin_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
||||
const_tree type, bool named ATTRIBUTE_UNUSED)
|
||||
bfin_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
|
||||
{
|
||||
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
|
||||
int bytes
|
||||
= (mode == BLKmode) ? int_size_in_bytes (type) : GET_MODE_SIZE (mode);
|
||||
int bytes = arg.promoted_size_in_bytes ();
|
||||
|
||||
if (mode == VOIDmode)
|
||||
if (arg.end_marker_p ())
|
||||
/* Compute operand 2 of the call insn. */
|
||||
return GEN_INT (cum->call_cookie);
|
||||
|
||||
|
@ -1707,7 +1700,7 @@ bfin_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
|||
return NULL_RTX;
|
||||
|
||||
if (cum->nregs)
|
||||
return gen_rtx_REG (mode, *(cum->arg_regs));
|
||||
return gen_rtx_REG (arg.mode, *(cum->arg_regs));
|
||||
|
||||
return NULL_RTX;
|
||||
}
|
||||
|
|
|
@ -499,16 +499,15 @@ c6x_init_cumulative_args (CUMULATIVE_ARGS *cum, const_tree fntype, rtx libname,
|
|||
}
|
||||
}
|
||||
|
||||
/* Implements the macro FUNCTION_ARG defined in c6x.h. */
|
||||
/* Implement TARGET_FUNCTION_ARG. */
|
||||
|
||||
static rtx
|
||||
c6x_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
||||
const_tree type, bool named ATTRIBUTE_UNUSED)
|
||||
c6x_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
|
||||
{
|
||||
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
|
||||
if (cum->count >= cum->nregs)
|
||||
return NULL_RTX;
|
||||
if (type)
|
||||
if (tree type = arg.type)
|
||||
{
|
||||
HOST_WIDE_INT size = int_size_in_bytes (type);
|
||||
if (TARGET_BIG_ENDIAN && AGGREGATE_TYPE_P (type))
|
||||
|
@ -519,11 +518,11 @@ c6x_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
|||
rtx reg2 = gen_rtx_REG (SImode, argument_registers[cum->count]);
|
||||
rtvec vec = gen_rtvec (2, gen_rtx_EXPR_LIST (VOIDmode, reg1, const0_rtx),
|
||||
gen_rtx_EXPR_LIST (VOIDmode, reg2, GEN_INT (4)));
|
||||
return gen_rtx_PARALLEL (mode, vec);
|
||||
return gen_rtx_PARALLEL (arg.mode, vec);
|
||||
}
|
||||
}
|
||||
}
|
||||
return gen_rtx_REG (mode, argument_registers[cum->count]);
|
||||
return gen_rtx_REG (arg.mode, argument_registers[cum->count]);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1134,7 +1133,8 @@ c6x_call_saved_register_used (tree call_expr)
|
|||
type = build_pointer_type (type);
|
||||
}
|
||||
|
||||
parm_rtx = c6x_function_arg (cum, mode, type, 0);
|
||||
function_arg_info arg (type, mode, /*named=*/false);
|
||||
parm_rtx = c6x_function_arg (cum, arg);
|
||||
|
||||
c6x_function_arg_advance (cum, mode, type, 0);
|
||||
|
||||
|
|
|
@ -592,10 +592,9 @@ enough_regs_for_param (CUMULATIVE_ARGS * cum, const_tree type,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Implements the macro FUNCTION_ARG defined in cr16.h. */
|
||||
/* Implement TARGET_FUNCTION_ARG. */
|
||||
static rtx
|
||||
cr16_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
||||
const_tree type, bool named ATTRIBUTE_UNUSED)
|
||||
cr16_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
|
||||
{
|
||||
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
|
||||
cum->last_parm_in_reg = 0;
|
||||
|
@ -604,20 +603,20 @@ cr16_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
|||
had their registers assigned. The rtx that function_arg returns from
|
||||
this type is supposed to pass to 'gen_call' but currently it is not
|
||||
implemented. */
|
||||
if (type == void_type_node)
|
||||
if (arg.end_marker_p ())
|
||||
return NULL_RTX;
|
||||
|
||||
if (targetm.calls.must_pass_in_stack (mode, type) || (cum->ints < 0))
|
||||
if (targetm.calls.must_pass_in_stack (arg.mode, arg.type) || (cum->ints < 0))
|
||||
return NULL_RTX;
|
||||
|
||||
if (mode == BLKmode)
|
||||
if (arg.mode == BLKmode)
|
||||
{
|
||||
/* Enable structures that need padding bytes at the end to pass to a
|
||||
function in registers. */
|
||||
if (enough_regs_for_param (cum, type, mode) != 0)
|
||||
if (enough_regs_for_param (cum, arg.type, arg.mode) != 0)
|
||||
{
|
||||
cum->last_parm_in_reg = 1;
|
||||
return gen_rtx_REG (mode, MIN_REG_FOR_PASSING_ARGS + cum->ints);
|
||||
return gen_rtx_REG (arg.mode, MIN_REG_FOR_PASSING_ARGS + cum->ints);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -625,10 +624,10 @@ cr16_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
|||
return NULL_RTX;
|
||||
else
|
||||
{
|
||||
if (enough_regs_for_param (cum, type, mode) != 0)
|
||||
if (enough_regs_for_param (cum, arg.type, arg.mode) != 0)
|
||||
{
|
||||
cum->last_parm_in_reg = 1;
|
||||
return gen_rtx_REG (mode, MIN_REG_FOR_PASSING_ARGS + cum->ints);
|
||||
return gen_rtx_REG (arg.mode, MIN_REG_FOR_PASSING_ARGS + cum->ints);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -144,10 +144,9 @@ static bool cris_pass_by_reference (cumulative_args_t,
|
|||
const function_arg_info &);
|
||||
static int cris_arg_partial_bytes (cumulative_args_t,
|
||||
const function_arg_info &);
|
||||
static rtx cris_function_arg (cumulative_args_t, machine_mode,
|
||||
const_tree, bool);
|
||||
static rtx cris_function_arg (cumulative_args_t, const function_arg_info &);
|
||||
static rtx cris_function_incoming_arg (cumulative_args_t,
|
||||
machine_mode, const_tree, bool);
|
||||
const function_arg_info &);
|
||||
static void cris_function_arg_advance (cumulative_args_t, machine_mode,
|
||||
const_tree, bool);
|
||||
static rtx_insn *cris_md_asm_adjust (vec<rtx> &, vec<rtx> &,
|
||||
|
@ -4121,15 +4120,13 @@ cris_arg_partial_bytes (cumulative_args_t ca, const function_arg_info &arg)
|
|||
}
|
||||
|
||||
static rtx
|
||||
cris_function_arg_1 (cumulative_args_t ca_v,
|
||||
machine_mode mode ATTRIBUTE_UNUSED,
|
||||
const_tree type ATTRIBUTE_UNUSED,
|
||||
bool named, bool incoming)
|
||||
cris_function_arg_1 (cumulative_args_t ca_v, const function_arg_info &arg,
|
||||
bool incoming)
|
||||
{
|
||||
const CUMULATIVE_ARGS *ca = get_cumulative_args (ca_v);
|
||||
|
||||
if ((!incoming || named) && ca->regs < CRIS_MAX_ARGS_IN_REGS)
|
||||
return gen_rtx_REG (mode, CRIS_FIRST_ARG_REG + ca->regs);
|
||||
if ((!incoming || arg.named) && ca->regs < CRIS_MAX_ARGS_IN_REGS)
|
||||
return gen_rtx_REG (arg.mode, CRIS_FIRST_ARG_REG + ca->regs);
|
||||
else
|
||||
return NULL_RTX;
|
||||
}
|
||||
|
@ -4138,10 +4135,9 @@ cris_function_arg_1 (cumulative_args_t ca_v,
|
|||
The void_type_node is sent as a "closing" call. */
|
||||
|
||||
static rtx
|
||||
cris_function_arg (cumulative_args_t ca, machine_mode mode,
|
||||
const_tree type, bool named)
|
||||
cris_function_arg (cumulative_args_t ca, const function_arg_info &arg)
|
||||
{
|
||||
return cris_function_arg_1 (ca, mode, type, named, false);
|
||||
return cris_function_arg_1 (ca, arg, false);
|
||||
}
|
||||
|
||||
/* Worker function for TARGET_FUNCTION_INCOMING_ARG.
|
||||
|
@ -4149,13 +4145,12 @@ cris_function_arg (cumulative_args_t ca, machine_mode mode,
|
|||
The differences between this and the previous, is that this one checks
|
||||
that an argument is named, since incoming stdarg/varargs arguments are
|
||||
pushed onto the stack, and we don't have to check against the "closing"
|
||||
void_type_node TYPE parameter. */
|
||||
function_arg_info::end_marker parameter. */
|
||||
|
||||
static rtx
|
||||
cris_function_incoming_arg (cumulative_args_t ca, machine_mode mode,
|
||||
const_tree type, bool named)
|
||||
cris_function_incoming_arg (cumulative_args_t ca, const function_arg_info &arg)
|
||||
{
|
||||
return cris_function_arg_1 (ca, mode, type, named, true);
|
||||
return cris_function_arg_1 (ca, arg, true);
|
||||
}
|
||||
|
||||
/* Worker function for TARGET_FUNCTION_ARG_ADVANCE. */
|
||||
|
|
|
@ -1784,23 +1784,16 @@ csky_initial_elimination_offset (int from, int to)
|
|||
Value is zero to push the argument on the stack,
|
||||
or a hard register in which to store the argument.
|
||||
|
||||
MODE is the argument's machine mode.
|
||||
TYPE is the data type of the argument (as a tree).
|
||||
This is null for libcalls where that information may
|
||||
not be available.
|
||||
CUM is a variable of type CUMULATIVE_ARGS which gives info about
|
||||
the preceding args and about the function being called.
|
||||
NAMED is nonzero if this argument is a named parameter
|
||||
(otherwise it is an extra parameter matching an ellipsis). */
|
||||
ARG is a description of the argument. */
|
||||
static rtx
|
||||
csky_function_arg (cumulative_args_t pcum_v, machine_mode mode,
|
||||
const_tree type ATTRIBUTE_UNUSED,
|
||||
bool named ATTRIBUTE_UNUSED)
|
||||
csky_function_arg (cumulative_args_t pcum_v, const function_arg_info &arg)
|
||||
{
|
||||
CUMULATIVE_ARGS *pcum = get_cumulative_args (pcum_v);
|
||||
|
||||
if (*pcum < CSKY_NPARM_REGS)
|
||||
return gen_rtx_REG (mode, CSKY_FIRST_PARM_REGNUM + *pcum);
|
||||
return gen_rtx_REG (arg.mode, CSKY_FIRST_PARM_REGNUM + *pcum);
|
||||
|
||||
return NULL_RTX;
|
||||
}
|
||||
|
|
|
@ -2254,24 +2254,18 @@ epiphany_conditional_register_usage (void)
|
|||
Value is zero to push the argument on the stack,
|
||||
or a hard register in which to store the argument.
|
||||
|
||||
MODE is the argument's machine mode.
|
||||
TYPE is the data type of the argument (as a tree).
|
||||
This is null for libcalls where that information may
|
||||
not be available.
|
||||
CUM is a variable of type CUMULATIVE_ARGS which gives info about
|
||||
the preceding args and about the function being called.
|
||||
NAMED is nonzero if this argument is a named parameter
|
||||
(otherwise it is an extra parameter matching an ellipsis). */
|
||||
ARG is a description of the argument. */
|
||||
/* On the EPIPHANY the first MAX_EPIPHANY_PARM_REGS args are normally in
|
||||
registers and the rest are pushed. */
|
||||
static rtx
|
||||
epiphany_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
||||
const_tree type, bool named ATTRIBUTE_UNUSED)
|
||||
epiphany_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
|
||||
{
|
||||
CUMULATIVE_ARGS cum = *get_cumulative_args (cum_v);
|
||||
|
||||
if (PASS_IN_REG_P (cum, mode, type))
|
||||
return gen_rtx_REG (mode, ROUND_ADVANCE_CUM (cum, mode, type));
|
||||
if (PASS_IN_REG_P (cum, arg.mode, arg.type))
|
||||
return gen_rtx_REG (arg.mode, ROUND_ADVANCE_CUM (cum, arg.mode, arg.type));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -119,8 +119,7 @@ static void fr30_setup_incoming_varargs (cumulative_args_t,
|
|||
static bool fr30_must_pass_in_stack (machine_mode, const_tree);
|
||||
static int fr30_arg_partial_bytes (cumulative_args_t,
|
||||
const function_arg_info &);
|
||||
static rtx fr30_function_arg (cumulative_args_t, machine_mode,
|
||||
const_tree, bool);
|
||||
static rtx fr30_function_arg (cumulative_args_t, const function_arg_info &);
|
||||
static void fr30_function_arg_advance (cumulative_args_t, machine_mode,
|
||||
const_tree, bool);
|
||||
static bool fr30_frame_pointer_required (void);
|
||||
|
@ -800,17 +799,16 @@ fr30_arg_partial_bytes (cumulative_args_t cum_v, const function_arg_info &arg)
|
|||
}
|
||||
|
||||
static rtx
|
||||
fr30_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
||||
const_tree type, bool named)
|
||||
fr30_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
|
||||
{
|
||||
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
|
||||
|
||||
if (!named
|
||||
|| fr30_must_pass_in_stack (mode, type)
|
||||
if (!arg.named
|
||||
|| fr30_must_pass_in_stack (arg.mode, arg.type)
|
||||
|| *cum >= FR30_NUM_ARG_REGS)
|
||||
return NULL_RTX;
|
||||
else
|
||||
return gen_rtx_REG (mode, *cum + FIRST_ARG_REGNUM);
|
||||
return gen_rtx_REG (arg.mode, *cum + FIRST_ARG_REGNUM);
|
||||
}
|
||||
|
||||
/* A C statement (sans semicolon) to update the summarizer variable CUM to
|
||||
|
|
|
@ -382,10 +382,9 @@ static rtx frv_struct_value_rtx (tree, int);
|
|||
static bool frv_must_pass_in_stack (machine_mode mode, const_tree type);
|
||||
static int frv_arg_partial_bytes (cumulative_args_t,
|
||||
const function_arg_info &);
|
||||
static rtx frv_function_arg (cumulative_args_t, machine_mode,
|
||||
const_tree, bool);
|
||||
static rtx frv_function_incoming_arg (cumulative_args_t, machine_mode,
|
||||
const_tree, bool);
|
||||
static rtx frv_function_arg (cumulative_args_t, const function_arg_info &);
|
||||
static rtx frv_function_incoming_arg (cumulative_args_t,
|
||||
const function_arg_info &);
|
||||
static void frv_function_arg_advance (cumulative_args_t, machine_mode,
|
||||
const_tree, bool);
|
||||
static unsigned int frv_function_arg_boundary (machine_mode,
|
||||
|
@ -3099,13 +3098,12 @@ frv_function_arg_boundary (machine_mode mode ATTRIBUTE_UNUSED,
|
|||
}
|
||||
|
||||
static rtx
|
||||
frv_function_arg_1 (cumulative_args_t cum_v, machine_mode mode,
|
||||
const_tree type ATTRIBUTE_UNUSED, bool named,
|
||||
frv_function_arg_1 (cumulative_args_t cum_v, const function_arg_info &arg,
|
||||
bool incoming ATTRIBUTE_UNUSED)
|
||||
{
|
||||
const CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
|
||||
|
||||
machine_mode xmode = (mode == BLKmode) ? SImode : mode;
|
||||
machine_mode xmode = (arg.mode == BLKmode) ? SImode : arg.mode;
|
||||
int arg_num = *cum;
|
||||
rtx ret;
|
||||
const char *debstr;
|
||||
|
@ -3132,23 +3130,22 @@ frv_function_arg_1 (cumulative_args_t cum_v, machine_mode mode,
|
|||
if (TARGET_DEBUG_ARG)
|
||||
fprintf (stderr,
|
||||
"function_arg: words = %2d, mode = %4s, named = %d, size = %3d, arg = %s\n",
|
||||
arg_num, GET_MODE_NAME (mode), named, GET_MODE_SIZE (mode), debstr);
|
||||
arg_num, GET_MODE_NAME (arg.mode), arg.named,
|
||||
GET_MODE_SIZE (arg.mode), debstr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static rtx
|
||||
frv_function_arg (cumulative_args_t cum, machine_mode mode,
|
||||
const_tree type, bool named)
|
||||
frv_function_arg (cumulative_args_t cum, const function_arg_info &arg)
|
||||
{
|
||||
return frv_function_arg_1 (cum, mode, type, named, false);
|
||||
return frv_function_arg_1 (cum, arg, false);
|
||||
}
|
||||
|
||||
static rtx
|
||||
frv_function_incoming_arg (cumulative_args_t cum, machine_mode mode,
|
||||
const_tree type, bool named)
|
||||
frv_function_incoming_arg (cumulative_args_t cum, const function_arg_info &arg)
|
||||
{
|
||||
return frv_function_arg_1 (cum, mode, type, named, true);
|
||||
return frv_function_arg_1 (cum, arg, true);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -657,14 +657,12 @@ ft32_fixed_condition_code_regs (unsigned int *p1, unsigned int *p2)
|
|||
NULL_RTX if there's no more space. */
|
||||
|
||||
static rtx
|
||||
ft32_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
||||
const_tree type ATTRIBUTE_UNUSED,
|
||||
bool named ATTRIBUTE_UNUSED)
|
||||
ft32_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
|
||||
{
|
||||
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
|
||||
|
||||
if (*cum < 8)
|
||||
return gen_rtx_REG (mode, *cum);
|
||||
return gen_rtx_REG (arg.mode, *cum);
|
||||
else
|
||||
return NULL_RTX;
|
||||
}
|
||||
|
|
|
@ -2255,49 +2255,48 @@ gcn_pretend_outgoing_varargs_named (cumulative_args_t cum_v)
|
|||
and if so, which register. */
|
||||
|
||||
static rtx
|
||||
gcn_function_arg (cumulative_args_t cum_v, machine_mode mode, const_tree type,
|
||||
bool named)
|
||||
gcn_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
|
||||
{
|
||||
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
|
||||
if (cum->normal_function)
|
||||
{
|
||||
if (!named || mode == VOIDmode)
|
||||
if (!arg.named || arg.end_marker_p ())
|
||||
return 0;
|
||||
|
||||
if (targetm.calls.must_pass_in_stack (mode, type))
|
||||
if (targetm.calls.must_pass_in_stack (arg.mode, arg.type))
|
||||
return 0;
|
||||
|
||||
int reg_num = FIRST_PARM_REG + cum->num;
|
||||
int num_regs = num_arg_regs (mode, type);
|
||||
int num_regs = num_arg_regs (arg.mode, arg.type);
|
||||
if (num_regs > 0)
|
||||
while (reg_num % num_regs != 0)
|
||||
reg_num++;
|
||||
if (reg_num + num_regs <= FIRST_PARM_REG + NUM_PARM_REGS)
|
||||
return gen_rtx_REG (mode, reg_num);
|
||||
return gen_rtx_REG (arg.mode, reg_num);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cum->num >= cum->args.nargs)
|
||||
{
|
||||
cum->offset = (cum->offset + TYPE_ALIGN (type) / 8 - 1)
|
||||
& -(TYPE_ALIGN (type) / 8);
|
||||
cum->offset = (cum->offset + TYPE_ALIGN (arg.type) / 8 - 1)
|
||||
& -(TYPE_ALIGN (arg.type) / 8);
|
||||
cfun->machine->kernarg_segment_alignment
|
||||
= MAX ((unsigned) cfun->machine->kernarg_segment_alignment,
|
||||
TYPE_ALIGN (type) / 8);
|
||||
TYPE_ALIGN (arg.type) / 8);
|
||||
rtx addr = gen_rtx_REG (DImode,
|
||||
cum->args.reg[KERNARG_SEGMENT_PTR_ARG]);
|
||||
if (cum->offset)
|
||||
addr = gen_rtx_PLUS (DImode, addr,
|
||||
gen_int_mode (cum->offset, DImode));
|
||||
rtx mem = gen_rtx_MEM (mode, addr);
|
||||
set_mem_attributes (mem, const_cast<tree>(type), 1);
|
||||
rtx mem = gen_rtx_MEM (arg.mode, addr);
|
||||
set_mem_attributes (mem, arg.type, 1);
|
||||
set_mem_addr_space (mem, ADDR_SPACE_SCALAR_FLAT);
|
||||
MEM_READONLY_P (mem) = 1;
|
||||
return mem;
|
||||
}
|
||||
|
||||
int a = cum->args.order[cum->num];
|
||||
if (mode != gcn_kernel_arg_types[a].mode)
|
||||
if (arg.mode != gcn_kernel_arg_types[a].mode)
|
||||
{
|
||||
error ("wrong type of argument %s", gcn_kernel_arg_types[a].name);
|
||||
return 0;
|
||||
|
|
|
@ -1081,17 +1081,16 @@ h8300_pr_saveall (struct cpp_reader *pfile ATTRIBUTE_UNUSED)
|
|||
pragma_saveall = 1;
|
||||
}
|
||||
|
||||
/* If the next function argument with MODE and TYPE is to be passed in
|
||||
a register, return a reg RTX for the hard register in which to pass
|
||||
the argument. CUM represents the state after the last argument.
|
||||
If the argument is to be pushed, NULL_RTX is returned.
|
||||
/* If the next function argument ARG is to be passed in a register, return
|
||||
a reg RTX for the hard register in which to pass the argument. CUM
|
||||
represents the state after the last argument. If the argument is to
|
||||
be pushed, NULL_RTX is returned.
|
||||
|
||||
On the H8/300 all normal args are pushed, unless -mquickcall in which
|
||||
case the first 3 arguments are passed in registers. */
|
||||
|
||||
static rtx
|
||||
h8300_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
||||
const_tree type, bool named)
|
||||
h8300_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
|
||||
{
|
||||
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
|
||||
|
||||
|
@ -1119,7 +1118,7 @@ h8300_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
|||
int regpass = 0;
|
||||
|
||||
/* Never pass unnamed arguments in registers. */
|
||||
if (!named)
|
||||
if (!arg.named)
|
||||
return NULL_RTX;
|
||||
|
||||
/* Pass 3 regs worth of data in regs when user asked on the command line. */
|
||||
|
@ -1143,16 +1142,10 @@ h8300_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
|||
|
||||
if (regpass)
|
||||
{
|
||||
int size;
|
||||
|
||||
if (mode == BLKmode)
|
||||
size = int_size_in_bytes (type);
|
||||
else
|
||||
size = GET_MODE_SIZE (mode);
|
||||
|
||||
int size = arg.promoted_size_in_bytes ();
|
||||
if (size + cum->nbytes <= regpass * UNITS_PER_WORD
|
||||
&& cum->nbytes / UNITS_PER_WORD <= 3)
|
||||
result = gen_rtx_REG (mode, cum->nbytes / UNITS_PER_WORD);
|
||||
result = gen_rtx_REG (arg.mode, cum->nbytes / UNITS_PER_WORD);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
|
@ -3206,77 +3206,69 @@ function_arg_ms_64 (const CUMULATIVE_ARGS *cum, machine_mode mode,
|
|||
/* Return where to put the arguments to a function.
|
||||
Return zero to push the argument on the stack, or a hard register in which to store the argument.
|
||||
|
||||
MODE is the argument's machine mode. TYPE is the data type of the
|
||||
argument. It is null for libcalls where that information may not be
|
||||
available. CUM gives information about the preceding args and about
|
||||
the function being called. NAMED is nonzero if this argument is a
|
||||
named parameter (otherwise it is an extra parameter matching an
|
||||
ellipsis). */
|
||||
ARG describes the argument while CUM gives information about the
|
||||
preceding args and about the function being called. */
|
||||
|
||||
static rtx
|
||||
ix86_function_arg (cumulative_args_t cum_v, machine_mode omode,
|
||||
const_tree type, bool named)
|
||||
ix86_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
|
||||
{
|
||||
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
|
||||
machine_mode mode = omode;
|
||||
machine_mode mode = arg.mode;
|
||||
HOST_WIDE_INT bytes, words;
|
||||
rtx arg;
|
||||
rtx reg;
|
||||
|
||||
if (!cum->caller && cfun->machine->func_type != TYPE_NORMAL)
|
||||
{
|
||||
gcc_assert (type != NULL_TREE);
|
||||
if (POINTER_TYPE_P (type))
|
||||
gcc_assert (arg.type != NULL_TREE);
|
||||
if (POINTER_TYPE_P (arg.type))
|
||||
{
|
||||
/* This is the pointer argument. */
|
||||
gcc_assert (TYPE_MODE (type) == Pmode);
|
||||
gcc_assert (TYPE_MODE (arg.type) == Pmode);
|
||||
/* It is at -WORD(AP) in the current frame in interrupt and
|
||||
exception handlers. */
|
||||
arg = plus_constant (Pmode, arg_pointer_rtx, -UNITS_PER_WORD);
|
||||
reg = plus_constant (Pmode, arg_pointer_rtx, -UNITS_PER_WORD);
|
||||
}
|
||||
else
|
||||
{
|
||||
gcc_assert (cfun->machine->func_type == TYPE_EXCEPTION
|
||||
&& TREE_CODE (type) == INTEGER_TYPE
|
||||
&& TYPE_MODE (type) == word_mode);
|
||||
&& TREE_CODE (arg.type) == INTEGER_TYPE
|
||||
&& TYPE_MODE (arg.type) == word_mode);
|
||||
/* The error code is the word-mode integer argument at
|
||||
-2 * WORD(AP) in the current frame of the exception
|
||||
handler. */
|
||||
arg = gen_rtx_MEM (word_mode,
|
||||
reg = gen_rtx_MEM (word_mode,
|
||||
plus_constant (Pmode,
|
||||
arg_pointer_rtx,
|
||||
-2 * UNITS_PER_WORD));
|
||||
}
|
||||
return arg;
|
||||
return reg;
|
||||
}
|
||||
|
||||
if (mode == BLKmode)
|
||||
bytes = int_size_in_bytes (type);
|
||||
else
|
||||
bytes = GET_MODE_SIZE (mode);
|
||||
bytes = arg.promoted_size_in_bytes ();
|
||||
words = CEIL (bytes, UNITS_PER_WORD);
|
||||
|
||||
/* To simplify the code below, represent vector types with a vector mode
|
||||
even if MMX/SSE are not active. */
|
||||
if (type && TREE_CODE (type) == VECTOR_TYPE)
|
||||
mode = type_natural_mode (type, cum, false);
|
||||
if (arg.type && TREE_CODE (arg.type) == VECTOR_TYPE)
|
||||
mode = type_natural_mode (arg.type, cum, false);
|
||||
|
||||
if (TARGET_64BIT)
|
||||
{
|
||||
enum calling_abi call_abi = cum ? cum->call_abi : ix86_abi;
|
||||
|
||||
if (call_abi == MS_ABI)
|
||||
arg = function_arg_ms_64 (cum, mode, omode, named, bytes);
|
||||
reg = function_arg_ms_64 (cum, mode, arg.mode, arg.named, bytes);
|
||||
else
|
||||
arg = function_arg_64 (cum, mode, omode, type, named);
|
||||
reg = function_arg_64 (cum, mode, arg.mode, arg.type, arg.named);
|
||||
}
|
||||
else
|
||||
arg = function_arg_32 (cum, mode, omode, type, bytes, words);
|
||||
reg = function_arg_32 (cum, mode, arg.mode, arg.type, bytes, words);
|
||||
|
||||
/* Track if there are outgoing arguments on stack. */
|
||||
if (arg == NULL_RTX && cum->caller)
|
||||
if (reg == NULL_RTX && cum->caller)
|
||||
cfun->machine->outgoing_args_on_stack = true;
|
||||
|
||||
return arg;
|
||||
return reg;
|
||||
}
|
||||
|
||||
/* A C expression that indicates when an argument must be passed by
|
||||
|
|
|
@ -204,12 +204,9 @@ static void ia64_setup_incoming_varargs (cumulative_args_t,
|
|||
int *, int);
|
||||
static int ia64_arg_partial_bytes (cumulative_args_t,
|
||||
const function_arg_info &);
|
||||
static rtx ia64_function_arg_1 (cumulative_args_t, machine_mode,
|
||||
const_tree, bool, bool);
|
||||
static rtx ia64_function_arg (cumulative_args_t, machine_mode,
|
||||
const_tree, bool);
|
||||
static rtx ia64_function_arg (cumulative_args_t, const function_arg_info &);
|
||||
static rtx ia64_function_incoming_arg (cumulative_args_t,
|
||||
machine_mode, const_tree, bool);
|
||||
const function_arg_info &);
|
||||
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);
|
||||
|
@ -4748,14 +4745,14 @@ ia64_function_arg_offset (const CUMULATIVE_ARGS *cum,
|
|||
registers. */
|
||||
|
||||
static rtx
|
||||
ia64_function_arg_1 (cumulative_args_t cum_v, machine_mode mode,
|
||||
const_tree type, bool named, bool incoming)
|
||||
ia64_function_arg_1 (cumulative_args_t cum_v, const function_arg_info &arg,
|
||||
bool incoming)
|
||||
{
|
||||
const CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
|
||||
|
||||
int basereg = (incoming ? GR_ARG_FIRST : AR_ARG_FIRST);
|
||||
int words = ia64_function_arg_words (type, mode);
|
||||
int offset = ia64_function_arg_offset (cum, type, words);
|
||||
int words = ia64_function_arg_words (arg.type, arg.mode);
|
||||
int offset = ia64_function_arg_offset (cum, arg.type, words);
|
||||
machine_mode hfa_mode = VOIDmode;
|
||||
|
||||
/* For OPEN VMS, emit the instruction setting up the argument register here,
|
||||
|
@ -4763,8 +4760,7 @@ ia64_function_arg_1 (cumulative_args_t cum_v, machine_mode mode,
|
|||
insns. This is not the conceptually best place to do this, but this is
|
||||
the easiest as we have convenient access to cumulative args info. */
|
||||
|
||||
if (TARGET_ABI_OPEN_VMS && mode == VOIDmode && type == void_type_node
|
||||
&& named == 1)
|
||||
if (TARGET_ABI_OPEN_VMS && arg.end_marker_p ())
|
||||
{
|
||||
unsigned HOST_WIDE_INT regval = cum->words;
|
||||
int i;
|
||||
|
@ -4783,19 +4779,19 @@ ia64_function_arg_1 (cumulative_args_t cum_v, machine_mode mode,
|
|||
/* On OpenVMS argument is either in Rn or Fn. */
|
||||
if (TARGET_ABI_OPEN_VMS)
|
||||
{
|
||||
if (FLOAT_MODE_P (mode))
|
||||
return gen_rtx_REG (mode, FR_ARG_FIRST + cum->words);
|
||||
if (FLOAT_MODE_P (arg.mode))
|
||||
return gen_rtx_REG (arg.mode, FR_ARG_FIRST + cum->words);
|
||||
else
|
||||
return gen_rtx_REG (mode, basereg + cum->words);
|
||||
return gen_rtx_REG (arg.mode, basereg + cum->words);
|
||||
}
|
||||
|
||||
/* Check for and handle homogeneous FP aggregates. */
|
||||
if (type)
|
||||
hfa_mode = hfa_element_mode (type, 0);
|
||||
if (arg.type)
|
||||
hfa_mode = hfa_element_mode (arg.type, 0);
|
||||
|
||||
/* Unnamed prototyped hfas are passed as usual. Named prototyped hfas
|
||||
and unprototyped hfas are passed specially. */
|
||||
if (hfa_mode != VOIDmode && (! cum->prototype || named))
|
||||
if (hfa_mode != VOIDmode && (! cum->prototype || arg.named))
|
||||
{
|
||||
rtx loc[16];
|
||||
int i = 0;
|
||||
|
@ -4815,8 +4811,7 @@ ia64_function_arg_1 (cumulative_args_t cum_v, machine_mode mode,
|
|||
/* Fill the FP regs. We do this always. We stop if we reach the end
|
||||
of the argument, the last FP register, or the last argument slot. */
|
||||
|
||||
byte_size = ((mode == BLKmode)
|
||||
? int_size_in_bytes (type) : GET_MODE_SIZE (mode));
|
||||
byte_size = arg.promoted_size_in_bytes ();
|
||||
args_byte_size = int_regs * UNITS_PER_WORD;
|
||||
offset = 0;
|
||||
for (; (offset < byte_size && fp_regs < MAX_ARGUMENT_SLOTS
|
||||
|
@ -4872,31 +4867,31 @@ ia64_function_arg_1 (cumulative_args_t cum_v, machine_mode mode,
|
|||
else if (gr_size > UNITS_PER_WORD)
|
||||
int_regs += gr_size / UNITS_PER_WORD;
|
||||
}
|
||||
return gen_rtx_PARALLEL (mode, gen_rtvec_v (i, loc));
|
||||
return gen_rtx_PARALLEL (arg.mode, gen_rtvec_v (i, loc));
|
||||
}
|
||||
|
||||
/* Integral and aggregates go in general registers. If we have run out of
|
||||
FR registers, then FP values must also go in general registers. This can
|
||||
happen when we have a SFmode HFA. */
|
||||
else if (mode == TFmode || mode == TCmode
|
||||
|| (! FLOAT_MODE_P (mode) || cum->fp_regs == MAX_ARGUMENT_SLOTS))
|
||||
else if (arg.mode == TFmode || arg.mode == TCmode
|
||||
|| !FLOAT_MODE_P (arg.mode)
|
||||
|| cum->fp_regs == MAX_ARGUMENT_SLOTS)
|
||||
{
|
||||
int byte_size = ((mode == BLKmode)
|
||||
? int_size_in_bytes (type) : GET_MODE_SIZE (mode));
|
||||
int byte_size = arg.promoted_size_in_bytes ();
|
||||
if (BYTES_BIG_ENDIAN
|
||||
&& (mode == BLKmode || (type && AGGREGATE_TYPE_P (type)))
|
||||
&& byte_size < UNITS_PER_WORD
|
||||
&& byte_size > 0)
|
||||
&& (arg.mode == BLKmode || arg.aggregate_type_p ())
|
||||
&& byte_size < UNITS_PER_WORD
|
||||
&& byte_size > 0)
|
||||
{
|
||||
rtx gr_reg = gen_rtx_EXPR_LIST (VOIDmode,
|
||||
gen_rtx_REG (DImode,
|
||||
(basereg + cum->words
|
||||
+ offset)),
|
||||
const0_rtx);
|
||||
return gen_rtx_PARALLEL (mode, gen_rtvec (1, gr_reg));
|
||||
return gen_rtx_PARALLEL (arg.mode, gen_rtvec (1, gr_reg));
|
||||
}
|
||||
else
|
||||
return gen_rtx_REG (mode, basereg + cum->words + offset);
|
||||
return gen_rtx_REG (arg.mode, basereg + cum->words + offset);
|
||||
|
||||
}
|
||||
|
||||
|
@ -4904,19 +4899,19 @@ ia64_function_arg_1 (cumulative_args_t cum_v, machine_mode mode,
|
|||
named, and in a GR register when unnamed. */
|
||||
else if (cum->prototype)
|
||||
{
|
||||
if (named)
|
||||
return gen_rtx_REG (mode, FR_ARG_FIRST + cum->fp_regs);
|
||||
if (arg.named)
|
||||
return gen_rtx_REG (arg.mode, FR_ARG_FIRST + cum->fp_regs);
|
||||
/* In big-endian mode, an anonymous SFmode value must be represented
|
||||
as (parallel:SF [(expr_list (reg:DI n) (const_int 0))]) to force
|
||||
the value into the high half of the general register. */
|
||||
else if (BYTES_BIG_ENDIAN && mode == SFmode)
|
||||
return gen_rtx_PARALLEL (mode,
|
||||
else if (BYTES_BIG_ENDIAN && arg.mode == SFmode)
|
||||
return gen_rtx_PARALLEL (arg.mode,
|
||||
gen_rtvec (1,
|
||||
gen_rtx_EXPR_LIST (VOIDmode,
|
||||
gen_rtx_REG (DImode, basereg + cum->words + offset),
|
||||
const0_rtx)));
|
||||
else
|
||||
return gen_rtx_REG (mode, basereg + cum->words + offset);
|
||||
return gen_rtx_REG (arg.mode, basereg + cum->words + offset);
|
||||
}
|
||||
/* If there is no prototype, then FP values go in both FR and GR
|
||||
registers. */
|
||||
|
@ -4924,10 +4919,10 @@ ia64_function_arg_1 (cumulative_args_t cum_v, machine_mode mode,
|
|||
{
|
||||
/* See comment above. */
|
||||
machine_mode inner_mode =
|
||||
(BYTES_BIG_ENDIAN && mode == SFmode) ? DImode : mode;
|
||||
(BYTES_BIG_ENDIAN && arg.mode == SFmode) ? DImode : arg.mode;
|
||||
|
||||
rtx fp_reg = gen_rtx_EXPR_LIST (VOIDmode,
|
||||
gen_rtx_REG (mode, (FR_ARG_FIRST
|
||||
gen_rtx_REG (arg.mode, (FR_ARG_FIRST
|
||||
+ cum->fp_regs)),
|
||||
const0_rtx);
|
||||
rtx gr_reg = gen_rtx_EXPR_LIST (VOIDmode,
|
||||
|
@ -4936,27 +4931,25 @@ ia64_function_arg_1 (cumulative_args_t cum_v, machine_mode mode,
|
|||
+ offset)),
|
||||
const0_rtx);
|
||||
|
||||
return gen_rtx_PARALLEL (mode, gen_rtvec (2, fp_reg, gr_reg));
|
||||
return gen_rtx_PARALLEL (arg.mode, gen_rtvec (2, fp_reg, gr_reg));
|
||||
}
|
||||
}
|
||||
|
||||
/* Implement TARGET_FUNCION_ARG target hook. */
|
||||
|
||||
static rtx
|
||||
ia64_function_arg (cumulative_args_t cum, machine_mode mode,
|
||||
const_tree type, bool named)
|
||||
ia64_function_arg (cumulative_args_t cum, const function_arg_info &arg)
|
||||
{
|
||||
return ia64_function_arg_1 (cum, mode, type, named, false);
|
||||
return ia64_function_arg_1 (cum, arg, false);
|
||||
}
|
||||
|
||||
/* Implement TARGET_FUNCION_INCOMING_ARG target hook. */
|
||||
|
||||
static rtx
|
||||
ia64_function_incoming_arg (cumulative_args_t cum,
|
||||
machine_mode mode,
|
||||
const_tree type, bool named)
|
||||
const function_arg_info &arg)
|
||||
{
|
||||
return ia64_function_arg_1 (cum, mode, type, named, true);
|
||||
return ia64_function_arg_1 (cum, arg, true);
|
||||
}
|
||||
|
||||
/* Return number of bytes, at the beginning of the argument, that must be
|
||||
|
|
|
@ -164,7 +164,7 @@ static bool iq2000_pass_by_reference (cumulative_args_t,
|
|||
static int iq2000_arg_partial_bytes (cumulative_args_t,
|
||||
const function_arg_info &arg);
|
||||
static rtx iq2000_function_arg (cumulative_args_t,
|
||||
machine_mode, const_tree, bool);
|
||||
const function_arg_info &);
|
||||
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);
|
||||
|
@ -1224,14 +1224,15 @@ iq2000_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
|
|||
}
|
||||
}
|
||||
|
||||
/* Return an RTL expression containing the register for the given mode MODE
|
||||
and type TYPE in CUM, or 0 if the argument is to be passed on the stack. */
|
||||
/* Return an RTL expression containing the register for argument ARG in CUM,
|
||||
or 0 if the argument is to be passed on the stack. */
|
||||
|
||||
static rtx
|
||||
iq2000_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
||||
const_tree type, bool named)
|
||||
iq2000_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
|
||||
{
|
||||
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
|
||||
tree type = arg.type;
|
||||
machine_mode mode = arg.mode;
|
||||
rtx ret;
|
||||
int regbase = -1;
|
||||
int bias = 0;
|
||||
|
@ -1248,7 +1249,7 @@ iq2000_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
|||
cum->gp_reg_found, cum->arg_number, cum->arg_words,
|
||||
GET_MODE_NAME (mode));
|
||||
fprintf (stderr, "%p", (const void *) type);
|
||||
fprintf (stderr, ", %d ) = ", named);
|
||||
fprintf (stderr, ", %d ) = ", arg.named);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1306,7 +1307,7 @@ iq2000_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
|||
gcc_assert (regbase != -1);
|
||||
|
||||
if (! type || TREE_CODE (type) != RECORD_TYPE
|
||||
|| ! named || ! TYPE_SIZE_UNIT (type)
|
||||
|| ! arg.named || ! TYPE_SIZE_UNIT (type)
|
||||
|| ! tree_fits_uhwi_p (TYPE_SIZE_UNIT (type)))
|
||||
ret = gen_rtx_REG (mode, regbase + *arg_words + bias);
|
||||
else
|
||||
|
@ -1378,11 +1379,11 @@ iq2000_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
|||
struct_p ? ", [struct]" : "");
|
||||
}
|
||||
|
||||
/* We will be called with a mode of VOIDmode after the last argument
|
||||
/* We will be called with an end marker after the last argument
|
||||
has been seen. Whatever we return will be passed to the call
|
||||
insn. If we need any shifts for small structures, return them in
|
||||
a PARALLEL. */
|
||||
if (mode == VOIDmode)
|
||||
if (arg.end_marker_p ())
|
||||
{
|
||||
if (cum->num_adjusts > 0)
|
||||
ret = gen_rtx_PARALLEL ((machine_mode) cum->fp_code,
|
||||
|
@ -1967,8 +1968,8 @@ iq2000_expand_prologue (void)
|
|||
passed_mode = Pmode;
|
||||
}
|
||||
|
||||
entry_parm = iq2000_function_arg (args_so_far, passed_mode,
|
||||
passed_type, true);
|
||||
function_arg_info arg (passed_type, passed_mode, /*named=*/true);
|
||||
entry_parm = iq2000_function_arg (args_so_far, arg);
|
||||
|
||||
iq2000_function_arg_advance (args_so_far, passed_mode,
|
||||
passed_type, true);
|
||||
|
@ -2013,8 +2014,8 @@ iq2000_expand_prologue (void)
|
|||
iq2000_unction_arg has encoded a PARALLEL rtx, holding a vector of
|
||||
adjustments to be made as the next_arg_reg variable, so we split up
|
||||
the insns, and emit them separately. */
|
||||
next_arg_reg = iq2000_function_arg (args_so_far, VOIDmode,
|
||||
void_type_node, true);
|
||||
next_arg_reg = iq2000_function_arg (args_so_far,
|
||||
function_arg_info::end_marker ());
|
||||
if (next_arg_reg != 0 && GET_CODE (next_arg_reg) == PARALLEL)
|
||||
{
|
||||
rtvec adjust = XVEC (next_arg_reg, 0);
|
||||
|
@ -2309,8 +2310,7 @@ iq2000_pass_by_reference (cumulative_args_t cum_v,
|
|||
CUMULATIVE_ARGS temp;
|
||||
|
||||
temp = *cum;
|
||||
if (iq2000_function_arg (pack_cumulative_args (&temp), arg.mode,
|
||||
arg.type, arg.named) != 0)
|
||||
if (iq2000_function_arg (pack_cumulative_args (&temp), arg) != 0)
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -73,9 +73,7 @@ static bool
|
|||
lm32_legitimate_address_p (machine_mode mode, rtx x, bool strict);
|
||||
static HOST_WIDE_INT lm32_compute_frame_size (int size);
|
||||
static void lm32_option_override (void);
|
||||
static rtx lm32_function_arg (cumulative_args_t cum,
|
||||
machine_mode mode, const_tree type,
|
||||
bool named);
|
||||
static rtx lm32_function_arg (cumulative_args_t, const function_arg_info &);
|
||||
static void lm32_function_arg_advance (cumulative_args_t cum,
|
||||
machine_mode mode,
|
||||
const_tree type, bool named);
|
||||
|
@ -619,32 +617,27 @@ lm32_print_operand_address (FILE * file, rtx addr)
|
|||
Value is zero to push the argument on the stack,
|
||||
or a hard register in which to store the argument.
|
||||
|
||||
MODE is the argument's machine mode.
|
||||
TYPE is the data type of the argument (as a tree).
|
||||
This is null for libcalls where that information may
|
||||
not be available.
|
||||
CUM is a variable of type CUMULATIVE_ARGS which gives info about
|
||||
the preceding args and about the function being called.
|
||||
NAMED is nonzero if this argument is a named parameter
|
||||
(otherwise it is an extra parameter matching an ellipsis). */
|
||||
ARG is a description of the argument. */
|
||||
|
||||
static rtx
|
||||
lm32_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
||||
const_tree type, bool named)
|
||||
lm32_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
|
||||
{
|
||||
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
|
||||
|
||||
if (mode == VOIDmode)
|
||||
if (arg.end_marker_p ())
|
||||
/* Compute operand 2 of the call insn. */
|
||||
return GEN_INT (0);
|
||||
|
||||
if (targetm.calls.must_pass_in_stack (mode, type))
|
||||
if (targetm.calls.must_pass_in_stack (arg.mode, arg.type))
|
||||
return NULL_RTX;
|
||||
|
||||
if (!named || (*cum + LM32_NUM_REGS2 (mode, type) > LM32_NUM_ARG_REGS))
|
||||
if (!arg.named
|
||||
|| *cum + LM32_NUM_REGS2 (arg.mode, arg.type) > LM32_NUM_ARG_REGS)
|
||||
return NULL_RTX;
|
||||
|
||||
return gen_rtx_REG (mode, *cum + LM32_FIRST_ARG_REG);
|
||||
return gen_rtx_REG (arg.mode, *cum + LM32_FIRST_ARG_REG);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -76,8 +76,7 @@ static struct machine_function *m32c_init_machine_status (void);
|
|||
static void m32c_insert_attributes (tree, tree *);
|
||||
static bool m32c_legitimate_address_p (machine_mode, rtx, bool);
|
||||
static bool m32c_addr_space_legitimate_address_p (machine_mode, rtx, bool, addr_space_t);
|
||||
static rtx m32c_function_arg (cumulative_args_t, machine_mode,
|
||||
const_tree, bool);
|
||||
static rtx m32c_function_arg (cumulative_args_t, const function_arg_info &);
|
||||
static bool m32c_pass_by_reference (cumulative_args_t,
|
||||
const function_arg_info &);
|
||||
static void m32c_function_arg_advance (cumulative_args_t, machine_mode,
|
||||
|
@ -1320,8 +1319,7 @@ m32c_push_rounding (poly_int64 n)
|
|||
#undef TARGET_FUNCTION_ARG
|
||||
#define TARGET_FUNCTION_ARG m32c_function_arg
|
||||
static rtx
|
||||
m32c_function_arg (cumulative_args_t ca_v,
|
||||
machine_mode mode, const_tree type, bool named)
|
||||
m32c_function_arg (cumulative_args_t ca_v, const function_arg_info &arg)
|
||||
{
|
||||
CUMULATIVE_ARGS *ca = get_cumulative_args (ca_v);
|
||||
|
||||
|
@ -1329,38 +1327,38 @@ m32c_function_arg (cumulative_args_t ca_v,
|
|||
rtx rv = NULL_RTX;
|
||||
#if DEBUG0
|
||||
fprintf (stderr, "func_arg %d (%s, %d)\n",
|
||||
ca->parm_num, mode_name[mode], named);
|
||||
debug_tree ((tree)type);
|
||||
ca->parm_num, mode_name[arg.mode], arg.named);
|
||||
debug_tree (arg.type);
|
||||
#endif
|
||||
|
||||
if (mode == VOIDmode)
|
||||
if (arg.end_marker_p ())
|
||||
return GEN_INT (0);
|
||||
|
||||
if (ca->force_mem || !named)
|
||||
if (ca->force_mem || !arg.named)
|
||||
{
|
||||
#if DEBUG0
|
||||
fprintf (stderr, "func arg: force %d named %d, mem\n", ca->force_mem,
|
||||
named);
|
||||
arg.named);
|
||||
#endif
|
||||
return NULL_RTX;
|
||||
}
|
||||
|
||||
if (type && INTEGRAL_TYPE_P (type) && POINTER_TYPE_P (type))
|
||||
if (arg.type && INTEGRAL_TYPE_P (arg.type) && POINTER_TYPE_P (arg.type))
|
||||
return NULL_RTX;
|
||||
|
||||
if (type && AGGREGATE_TYPE_P (type))
|
||||
if (arg.aggregate_type_p ())
|
||||
return NULL_RTX;
|
||||
|
||||
switch (ca->parm_num)
|
||||
{
|
||||
case 1:
|
||||
if (GET_MODE_SIZE (mode) == 1 || GET_MODE_SIZE (mode) == 2)
|
||||
rv = gen_rtx_REG (mode, TARGET_A16 ? R1_REGNO : R0_REGNO);
|
||||
if (GET_MODE_SIZE (arg.mode) == 1 || GET_MODE_SIZE (arg.mode) == 2)
|
||||
rv = gen_rtx_REG (arg.mode, TARGET_A16 ? R1_REGNO : R0_REGNO);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (TARGET_A16 && GET_MODE_SIZE (mode) == 2)
|
||||
rv = gen_rtx_REG (mode, R2_REGNO);
|
||||
if (TARGET_A16 && GET_MODE_SIZE (arg.mode) == 2)
|
||||
rv = gen_rtx_REG (arg.mode, R2_REGNO);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -96,8 +96,7 @@ static bool m32r_pass_by_reference (cumulative_args_t,
|
|||
const function_arg_info &arg);
|
||||
static int m32r_arg_partial_bytes (cumulative_args_t,
|
||||
const function_arg_info &);
|
||||
static rtx m32r_function_arg (cumulative_args_t, machine_mode,
|
||||
const_tree, bool);
|
||||
static rtx m32r_function_arg (cumulative_args_t, const function_arg_info &);
|
||||
static void m32r_function_arg_advance (cumulative_args_t, machine_mode,
|
||||
const_tree, bool);
|
||||
static bool m32r_can_eliminate (const int, const int);
|
||||
|
@ -1201,26 +1200,20 @@ m32r_arg_partial_bytes (cumulative_args_t cum_v, const function_arg_info &arg)
|
|||
Value is zero to push the argument on the stack,
|
||||
or a hard register in which to store the argument.
|
||||
|
||||
MODE is the argument's machine mode.
|
||||
TYPE is the data type of the argument (as a tree).
|
||||
This is null for libcalls where that information may
|
||||
not be available.
|
||||
CUM is a variable of type CUMULATIVE_ARGS which gives info about
|
||||
the preceding args and about the function being called.
|
||||
NAMED is nonzero if this argument is a named parameter
|
||||
(otherwise it is an extra parameter matching an ellipsis). */
|
||||
ARG is a description of the argument. */
|
||||
/* On the M32R the first M32R_MAX_PARM_REGS args are normally in registers
|
||||
and the rest are pushed. */
|
||||
|
||||
static rtx
|
||||
m32r_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
||||
const_tree type ATTRIBUTE_UNUSED,
|
||||
bool named ATTRIBUTE_UNUSED)
|
||||
m32r_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
|
||||
{
|
||||
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
|
||||
|
||||
return (PASS_IN_REG_P (*cum, mode, type)
|
||||
? gen_rtx_REG (mode, ROUND_ADVANCE_CUM (*cum, mode, type))
|
||||
return (PASS_IN_REG_P (*cum, arg.mode, arg.type)
|
||||
? gen_rtx_REG (arg.mode,
|
||||
ROUND_ADVANCE_CUM (*cum, arg.mode, arg.type))
|
||||
: NULL_RTX);
|
||||
}
|
||||
|
||||
|
|
|
@ -183,8 +183,7 @@ static poly_int64 m68k_return_pops_args (tree, tree, poly_int64);
|
|||
static rtx m68k_delegitimize_address (rtx);
|
||||
static void m68k_function_arg_advance (cumulative_args_t, machine_mode,
|
||||
const_tree, bool);
|
||||
static rtx m68k_function_arg (cumulative_args_t, machine_mode,
|
||||
const_tree, bool);
|
||||
static rtx m68k_function_arg (cumulative_args_t, const function_arg_info &);
|
||||
static bool m68k_cannot_force_const_mem (machine_mode mode, rtx x);
|
||||
static bool m68k_output_addr_const_extra (FILE *, rtx);
|
||||
static void m68k_init_sync_libfuncs (void) ATTRIBUTE_UNUSED;
|
||||
|
@ -1464,10 +1463,7 @@ m68k_ok_for_sibcall_p (tree decl, tree exp)
|
|||
/* On the m68k all args are always pushed. */
|
||||
|
||||
static rtx
|
||||
m68k_function_arg (cumulative_args_t cum ATTRIBUTE_UNUSED,
|
||||
machine_mode mode ATTRIBUTE_UNUSED,
|
||||
const_tree type ATTRIBUTE_UNUSED,
|
||||
bool named ATTRIBUTE_UNUSED)
|
||||
m68k_function_arg (cumulative_args_t, const function_arg_info &)
|
||||
{
|
||||
return NULL_RTX;
|
||||
}
|
||||
|
|
|
@ -133,8 +133,7 @@ static bool mcore_return_in_memory (const_tree, const_tree);
|
|||
static int mcore_arg_partial_bytes (cumulative_args_t,
|
||||
const function_arg_info &);
|
||||
static rtx mcore_function_arg (cumulative_args_t,
|
||||
machine_mode,
|
||||
const_tree, bool);
|
||||
const function_arg_info &);
|
||||
static void mcore_function_arg_advance (cumulative_args_t,
|
||||
machine_mode,
|
||||
const_tree, bool);
|
||||
|
@ -2788,14 +2787,9 @@ mcore_function_value (const_tree valtype, const_tree func)
|
|||
Value is zero to push the argument on the stack,
|
||||
or a hard register in which to store the argument.
|
||||
|
||||
MODE is the argument's machine mode.
|
||||
TYPE is the data type of the argument (as a tree).
|
||||
This is null for libcalls where that information may
|
||||
not be available.
|
||||
CUM is a variable of type CUMULATIVE_ARGS which gives info about
|
||||
the preceding args and about the function being called.
|
||||
NAMED is nonzero if this argument is a named parameter
|
||||
(otherwise it is an extra parameter matching an ellipsis).
|
||||
ARG is a description of the argument.
|
||||
|
||||
On MCore the first args are normally in registers
|
||||
and the rest are pushed. Any arg that starts within the first
|
||||
|
@ -2803,21 +2797,21 @@ mcore_function_value (const_tree valtype, const_tree func)
|
|||
its data type forbids. */
|
||||
|
||||
static rtx
|
||||
mcore_function_arg (cumulative_args_t cum, machine_mode mode,
|
||||
const_tree type, bool named)
|
||||
mcore_function_arg (cumulative_args_t cum, const function_arg_info &arg)
|
||||
{
|
||||
int arg_reg;
|
||||
|
||||
if (! named || mode == VOIDmode)
|
||||
if (!arg.named || arg.end_marker_p ())
|
||||
return 0;
|
||||
|
||||
if (targetm.calls.must_pass_in_stack (mode, type))
|
||||
if (targetm.calls.must_pass_in_stack (arg.mode, arg.type))
|
||||
return 0;
|
||||
|
||||
arg_reg = ROUND_REG (*get_cumulative_args (cum), mode);
|
||||
arg_reg = ROUND_REG (*get_cumulative_args (cum), arg.mode);
|
||||
|
||||
if (arg_reg < NPARM_REGS)
|
||||
return handle_structs_in_regs (mode, type, FIRST_PARM_REG + arg_reg);
|
||||
return handle_structs_in_regs (arg.mode, arg.type,
|
||||
FIRST_PARM_REG + arg_reg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1596,13 +1596,11 @@ microblaze_function_arg_advance (cumulative_args_t cum_v,
|
|||
}
|
||||
}
|
||||
|
||||
/* Return an RTL expression containing the register for the given mode,
|
||||
/* Return an RTL expression containing the register for the given argument
|
||||
or 0 if the argument is to be passed on the stack. */
|
||||
|
||||
static rtx
|
||||
microblaze_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
||||
const_tree type ATTRIBUTE_UNUSED,
|
||||
bool named ATTRIBUTE_UNUSED)
|
||||
microblaze_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
|
||||
{
|
||||
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
|
||||
|
||||
|
@ -1611,7 +1609,7 @@ microblaze_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
|||
int *arg_words = &cum->arg_words;
|
||||
|
||||
cum->last_arg_fp = 0;
|
||||
switch (mode)
|
||||
switch (arg.mode)
|
||||
{
|
||||
case E_SFmode:
|
||||
case E_DFmode:
|
||||
|
@ -1624,8 +1622,8 @@ microblaze_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
|||
regbase = GP_ARG_FIRST;
|
||||
break;
|
||||
default:
|
||||
gcc_assert (GET_MODE_CLASS (mode) == MODE_COMPLEX_INT
|
||||
|| GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT);
|
||||
gcc_assert (GET_MODE_CLASS (arg.mode) == MODE_COMPLEX_INT
|
||||
|| GET_MODE_CLASS (arg.mode) == MODE_COMPLEX_FLOAT);
|
||||
/* FALLTHRU */
|
||||
case E_BLKmode:
|
||||
regbase = GP_ARG_FIRST;
|
||||
|
@ -1638,10 +1636,10 @@ microblaze_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
|||
{
|
||||
gcc_assert (regbase != -1);
|
||||
|
||||
ret = gen_rtx_REG (mode, regbase + *arg_words);
|
||||
ret = gen_rtx_REG (arg.mode, regbase + *arg_words);
|
||||
}
|
||||
|
||||
if (mode == VOIDmode)
|
||||
if (arg.end_marker_p ())
|
||||
{
|
||||
if (cum->num_adjusts > 0)
|
||||
ret = gen_rtx_PARALLEL ((machine_mode) cum->fp_code,
|
||||
|
@ -2916,8 +2914,8 @@ microblaze_expand_prologue (void)
|
|||
passed_mode = Pmode;
|
||||
}
|
||||
|
||||
entry_parm = targetm.calls.function_arg (args_so_far, passed_mode,
|
||||
passed_type, true);
|
||||
function_arg_info arg (passed_type, passed_mode, /*named=*/true);
|
||||
entry_parm = targetm.calls.function_arg (args_so_far, arg);
|
||||
|
||||
if (entry_parm)
|
||||
{
|
||||
|
@ -2952,8 +2950,8 @@ microblaze_expand_prologue (void)
|
|||
|
||||
/* Split parallel insn into a sequence of insns. */
|
||||
|
||||
next_arg_reg = targetm.calls.function_arg (args_so_far, VOIDmode,
|
||||
void_type_node, true);
|
||||
next_arg_reg = targetm.calls.function_arg (args_so_far,
|
||||
function_arg_info::end_marker ());
|
||||
if (next_arg_reg != 0 && GET_CODE (next_arg_reg) == PARALLEL)
|
||||
{
|
||||
rtvec adjust = XVEC (next_arg_reg, 0);
|
||||
|
|
|
@ -5976,17 +5976,16 @@ mips_strict_argument_naming (cumulative_args_t ca ATTRIBUTE_UNUSED)
|
|||
/* Implement TARGET_FUNCTION_ARG. */
|
||||
|
||||
static rtx
|
||||
mips_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
||||
const_tree type, bool named)
|
||||
mips_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
|
||||
{
|
||||
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
|
||||
struct mips_arg_info info;
|
||||
|
||||
/* We will be called with a mode of VOIDmode after the last argument
|
||||
/* We will be called with an end marker after the last argument
|
||||
has been seen. Whatever we return will be passed to the call expander.
|
||||
If we need a MIPS16 fp_code, return a REG with the code stored as
|
||||
the mode. */
|
||||
if (mode == VOIDmode)
|
||||
if (arg.end_marker_p ())
|
||||
{
|
||||
if (TARGET_MIPS16 && cum->fp_code != 0)
|
||||
return gen_rtx_REG ((machine_mode) cum->fp_code, 0);
|
||||
|
@ -5994,7 +5993,7 @@ mips_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
mips_get_arg_info (&info, cum, mode, type, named);
|
||||
mips_get_arg_info (&info, cum, arg.mode, arg.type, arg.named);
|
||||
|
||||
/* Return straight away if the whole argument is passed on the stack. */
|
||||
if (info.reg_offset == MAX_ARGS_IN_REGISTERS)
|
||||
|
@ -6005,16 +6004,16 @@ mips_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
|||
in a floating-point register. */
|
||||
if (TARGET_NEWABI
|
||||
&& TARGET_HARD_FLOAT
|
||||
&& named
|
||||
&& type != 0
|
||||
&& TREE_CODE (type) == RECORD_TYPE
|
||||
&& TYPE_SIZE_UNIT (type)
|
||||
&& tree_fits_uhwi_p (TYPE_SIZE_UNIT (type)))
|
||||
&& arg.named
|
||||
&& arg.type != 0
|
||||
&& TREE_CODE (arg.type) == RECORD_TYPE
|
||||
&& TYPE_SIZE_UNIT (arg.type)
|
||||
&& tree_fits_uhwi_p (TYPE_SIZE_UNIT (arg.type)))
|
||||
{
|
||||
tree field;
|
||||
|
||||
/* First check to see if there is any such field. */
|
||||
for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
|
||||
for (field = TYPE_FIELDS (arg.type); field; field = DECL_CHAIN (field))
|
||||
if (TREE_CODE (field) == FIELD_DECL
|
||||
&& SCALAR_FLOAT_TYPE_P (TREE_TYPE (field))
|
||||
&& TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD
|
||||
|
@ -6033,10 +6032,10 @@ mips_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
|||
|
||||
/* assign_parms checks the mode of ENTRY_PARM, so we must
|
||||
use the actual mode here. */
|
||||
ret = gen_rtx_PARALLEL (mode, rtvec_alloc (info.reg_words));
|
||||
ret = gen_rtx_PARALLEL (arg.mode, rtvec_alloc (info.reg_words));
|
||||
|
||||
bitpos = 0;
|
||||
field = TYPE_FIELDS (type);
|
||||
field = TYPE_FIELDS (arg.type);
|
||||
for (i = 0; i < info.reg_words; i++)
|
||||
{
|
||||
rtx reg;
|
||||
|
@ -6069,13 +6068,13 @@ mips_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
|||
and the imaginary part goes in the upper register. */
|
||||
if (TARGET_NEWABI
|
||||
&& info.fpr_p
|
||||
&& GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
|
||||
&& GET_MODE_CLASS (arg.mode) == MODE_COMPLEX_FLOAT)
|
||||
{
|
||||
rtx real, imag;
|
||||
machine_mode inner;
|
||||
unsigned int regno;
|
||||
|
||||
inner = GET_MODE_INNER (mode);
|
||||
inner = GET_MODE_INNER (arg.mode);
|
||||
regno = FP_ARG_FIRST + info.reg_offset;
|
||||
if (info.reg_words * UNITS_PER_WORD == GET_MODE_SIZE (inner))
|
||||
{
|
||||
|
@ -6093,11 +6092,11 @@ mips_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
|||
gen_rtx_REG (inner,
|
||||
regno + info.reg_words / 2),
|
||||
GEN_INT (GET_MODE_SIZE (inner)));
|
||||
return gen_rtx_PARALLEL (mode, gen_rtvec (2, real, imag));
|
||||
return gen_rtx_PARALLEL (arg.mode, gen_rtvec (2, real, imag));
|
||||
}
|
||||
}
|
||||
|
||||
return gen_rtx_REG (mode, mips_arg_regno (&info, TARGET_HARD_FLOAT));
|
||||
return gen_rtx_REG (arg.mode, mips_arg_regno (&info, TARGET_HARD_FLOAT));
|
||||
}
|
||||
|
||||
/* Implement TARGET_FUNCTION_ARG_ADVANCE. */
|
||||
|
|
|
@ -151,12 +151,9 @@ static machine_mode mmix_promote_function_mode (const_tree,
|
|||
int *, const_tree, int);
|
||||
static void mmix_function_arg_advance (cumulative_args_t, machine_mode,
|
||||
const_tree, bool);
|
||||
static rtx mmix_function_arg_1 (const cumulative_args_t, machine_mode,
|
||||
const_tree, bool, bool);
|
||||
static rtx mmix_function_incoming_arg (cumulative_args_t, machine_mode,
|
||||
const_tree, bool);
|
||||
static rtx mmix_function_arg (cumulative_args_t, machine_mode,
|
||||
const_tree, bool);
|
||||
static rtx mmix_function_incoming_arg (cumulative_args_t,
|
||||
const function_arg_info &);
|
||||
static rtx mmix_function_arg (cumulative_args_t, const function_arg_info &);
|
||||
static rtx mmix_function_value (const_tree, const_tree, bool);
|
||||
static rtx mmix_libcall_value (machine_mode, const_rtx);
|
||||
static bool mmix_function_value_regno_p (const unsigned int);
|
||||
|
@ -636,28 +633,25 @@ mmix_function_arg_advance (cumulative_args_t argsp_v, machine_mode mode,
|
|||
|
||||
static rtx
|
||||
mmix_function_arg_1 (const cumulative_args_t argsp_v,
|
||||
machine_mode mode,
|
||||
const_tree type,
|
||||
bool named ATTRIBUTE_UNUSED,
|
||||
bool incoming)
|
||||
const function_arg_info &arg, bool incoming)
|
||||
{
|
||||
CUMULATIVE_ARGS *argsp = get_cumulative_args (argsp_v);
|
||||
|
||||
/* Last-argument marker. */
|
||||
if (type == void_type_node)
|
||||
if (arg.end_marker_p ())
|
||||
return (argsp->regs < MMIX_MAX_ARGS_IN_REGS)
|
||||
? gen_rtx_REG (mode,
|
||||
? gen_rtx_REG (arg.mode,
|
||||
(incoming
|
||||
? MMIX_FIRST_INCOMING_ARG_REGNUM
|
||||
: MMIX_FIRST_ARG_REGNUM) + argsp->regs)
|
||||
: NULL_RTX;
|
||||
|
||||
return (argsp->regs < MMIX_MAX_ARGS_IN_REGS
|
||||
&& !targetm.calls.must_pass_in_stack (mode, type)
|
||||
&& (GET_MODE_BITSIZE (mode) <= 64
|
||||
&& !targetm.calls.must_pass_in_stack (arg.mode, arg.type)
|
||||
&& (GET_MODE_BITSIZE (arg.mode) <= 64
|
||||
|| argsp->lib
|
||||
|| TARGET_LIBFUNC))
|
||||
? gen_rtx_REG (mode,
|
||||
? gen_rtx_REG (arg.mode,
|
||||
(incoming
|
||||
? MMIX_FIRST_INCOMING_ARG_REGNUM
|
||||
: MMIX_FIRST_ARG_REGNUM)
|
||||
|
@ -669,21 +663,16 @@ mmix_function_arg_1 (const cumulative_args_t argsp_v,
|
|||
one that must go on stack. */
|
||||
|
||||
static rtx
|
||||
mmix_function_arg (cumulative_args_t argsp,
|
||||
machine_mode mode,
|
||||
const_tree type,
|
||||
bool named)
|
||||
mmix_function_arg (cumulative_args_t argsp, const function_arg_info &arg)
|
||||
{
|
||||
return mmix_function_arg_1 (argsp, mode, type, named, false);
|
||||
return mmix_function_arg_1 (argsp, arg, false);
|
||||
}
|
||||
|
||||
static rtx
|
||||
mmix_function_incoming_arg (cumulative_args_t argsp,
|
||||
machine_mode mode,
|
||||
const_tree type,
|
||||
bool named)
|
||||
const function_arg_info &arg)
|
||||
{
|
||||
return mmix_function_arg_1 (argsp, mode, type, named, true);
|
||||
return mmix_function_arg_1 (argsp, arg, true);
|
||||
}
|
||||
|
||||
/* Returns nonzero for everything that goes by reference, 0 for
|
||||
|
|
|
@ -1532,12 +1532,11 @@ mn10300_pass_by_reference (cumulative_args_t, const function_arg_info &arg)
|
|||
return (size > 8 || size == 0);
|
||||
}
|
||||
|
||||
/* Return an RTX to represent where a value with mode MODE will be returned
|
||||
from a function. If the result is NULL_RTX, the argument is pushed. */
|
||||
/* Return an RTX to represent where argument ARG will be passed to a function.
|
||||
If the result is NULL_RTX, the argument is pushed. */
|
||||
|
||||
static rtx
|
||||
mn10300_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
||||
const_tree type, bool named ATTRIBUTE_UNUSED)
|
||||
mn10300_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
|
||||
{
|
||||
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
|
||||
rtx result = NULL_RTX;
|
||||
|
@ -1547,11 +1546,7 @@ mn10300_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
|||
int nregs = 2;
|
||||
|
||||
/* Figure out the size of the object to be passed. */
|
||||
if (mode == BLKmode)
|
||||
size = int_size_in_bytes (type);
|
||||
else
|
||||
size = GET_MODE_SIZE (mode);
|
||||
|
||||
size = arg.promoted_size_in_bytes ();
|
||||
cum->nbytes = (cum->nbytes + 3) & ~3;
|
||||
|
||||
/* Don't pass this arg via a register if all the argument registers
|
||||
|
@ -1561,17 +1556,17 @@ mn10300_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
|||
|
||||
/* Don't pass this arg via a register if it would be split between
|
||||
registers and memory. */
|
||||
if (type == NULL_TREE
|
||||
if (arg.type == NULL_TREE
|
||||
&& cum->nbytes + size > nregs * UNITS_PER_WORD)
|
||||
return result;
|
||||
|
||||
switch (cum->nbytes / UNITS_PER_WORD)
|
||||
{
|
||||
case 0:
|
||||
result = gen_rtx_REG (mode, FIRST_ARGUMENT_REGNUM);
|
||||
result = gen_rtx_REG (arg.mode, FIRST_ARGUMENT_REGNUM);
|
||||
break;
|
||||
case 1:
|
||||
result = gen_rtx_REG (mode, FIRST_ARGUMENT_REGNUM + 1);
|
||||
result = gen_rtx_REG (arg.mode, FIRST_ARGUMENT_REGNUM + 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -423,14 +423,12 @@ moxie_fixed_condition_code_regs (unsigned int *p1, unsigned int *p2)
|
|||
NULL_RTX if there's no more space. */
|
||||
|
||||
static rtx
|
||||
moxie_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
||||
const_tree type ATTRIBUTE_UNUSED,
|
||||
bool named ATTRIBUTE_UNUSED)
|
||||
moxie_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
|
||||
{
|
||||
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
|
||||
|
||||
if (*cum < 8)
|
||||
return gen_rtx_REG (mode, *cum);
|
||||
return gen_rtx_REG (arg.mode, *cum);
|
||||
else
|
||||
return NULL_RTX;
|
||||
}
|
||||
|
|
|
@ -710,16 +710,14 @@ msp430_promote_prototypes (const_tree fntype ATTRIBUTE_UNUSED)
|
|||
|
||||
rtx
|
||||
msp430_function_arg (cumulative_args_t cap,
|
||||
machine_mode mode,
|
||||
const_tree type,
|
||||
bool named)
|
||||
const function_arg_info &arg)
|
||||
{
|
||||
CUMULATIVE_ARGS *ca = get_cumulative_args (cap);
|
||||
|
||||
msp430_evaluate_arg (cap, mode, type, named);
|
||||
msp430_evaluate_arg (cap, arg.mode, arg.type, arg.named);
|
||||
|
||||
if (ca->reg_count)
|
||||
return gen_rtx_REG (mode, ca->start_reg);
|
||||
return gen_rtx_REG (arg.mode, ca->start_reg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1868,19 +1868,20 @@ nds32_can_eliminate (const int from_reg, const int to_reg)
|
|||
/* -- Passing Arguments in Registers. */
|
||||
|
||||
static rtx
|
||||
nds32_function_arg (cumulative_args_t ca, machine_mode mode,
|
||||
const_tree type, bool named)
|
||||
nds32_function_arg (cumulative_args_t ca, const function_arg_info &arg)
|
||||
{
|
||||
unsigned int regno;
|
||||
CUMULATIVE_ARGS *cum = get_cumulative_args (ca);
|
||||
tree type = arg.type;
|
||||
machine_mode mode = arg.mode;
|
||||
|
||||
/* The last time this hook is called,
|
||||
it is called with MODE == VOIDmode. */
|
||||
if (mode == VOIDmode)
|
||||
it is called with an end marker. */
|
||||
if (arg.end_marker_p ())
|
||||
return NULL_RTX;
|
||||
|
||||
/* For nameless arguments, we need to take care it individually. */
|
||||
if (!named)
|
||||
if (!arg.named)
|
||||
{
|
||||
/* If we are under hard float abi, we have arguments passed on the
|
||||
stack and all situation can be handled by GCC itself. */
|
||||
|
|
|
@ -3362,25 +3362,18 @@ nios2_fpu_insn_asm (enum n2fpu_code code)
|
|||
push the argument on the stack, or a hard register in which to
|
||||
store the argument.
|
||||
|
||||
MODE is the argument's machine mode.
|
||||
TYPE is the data type of the argument (as a tree).
|
||||
This is null for libcalls where that information may
|
||||
not be available.
|
||||
CUM is a variable of type CUMULATIVE_ARGS which gives info about
|
||||
the preceding args and about the function being called.
|
||||
NAMED is nonzero if this argument is a named parameter
|
||||
(otherwise it is an extra parameter matching an ellipsis). */
|
||||
ARG is a description of the argument. */
|
||||
|
||||
static rtx
|
||||
nios2_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
||||
const_tree type ATTRIBUTE_UNUSED,
|
||||
bool named ATTRIBUTE_UNUSED)
|
||||
nios2_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
|
||||
{
|
||||
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
|
||||
rtx return_rtx = NULL_RTX;
|
||||
|
||||
if (cum->regs_used < NUM_ARG_REGS)
|
||||
return_rtx = gen_rtx_REG (mode, FIRST_ARG_REGNO + cum->regs_used);
|
||||
return_rtx = gen_rtx_REG (arg.mode, FIRST_ARG_REGNO + cum->regs_used);
|
||||
|
||||
return return_rtx;
|
||||
}
|
||||
|
|
|
@ -520,30 +520,29 @@ promote_return (machine_mode mode)
|
|||
/* Implement TARGET_FUNCTION_ARG. */
|
||||
|
||||
static rtx
|
||||
nvptx_function_arg (cumulative_args_t ARG_UNUSED (cum_v), machine_mode mode,
|
||||
const_tree, bool named)
|
||||
nvptx_function_arg (cumulative_args_t, const function_arg_info &arg)
|
||||
{
|
||||
if (mode == VOIDmode || !named)
|
||||
if (arg.end_marker_p () || !arg.named)
|
||||
return NULL_RTX;
|
||||
|
||||
return gen_reg_rtx (mode);
|
||||
return gen_reg_rtx (arg.mode);
|
||||
}
|
||||
|
||||
/* Implement TARGET_FUNCTION_INCOMING_ARG. */
|
||||
|
||||
static rtx
|
||||
nvptx_function_incoming_arg (cumulative_args_t cum_v, machine_mode mode,
|
||||
const_tree, bool named)
|
||||
nvptx_function_incoming_arg (cumulative_args_t cum_v,
|
||||
const function_arg_info &arg)
|
||||
{
|
||||
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
|
||||
|
||||
if (mode == VOIDmode || !named)
|
||||
if (arg.end_marker_p () || !arg.named)
|
||||
return NULL_RTX;
|
||||
|
||||
/* No need to deal with split modes here, the only case that can
|
||||
happen is complex modes and those are dealt with by
|
||||
TARGET_SPLIT_COMPLEX_ARG. */
|
||||
return gen_rtx_UNSPEC (mode,
|
||||
return gen_rtx_UNSPEC (arg.mode,
|
||||
gen_rtvec (1, GEN_INT (cum->count)),
|
||||
UNSPEC_ARG_REG);
|
||||
}
|
||||
|
|
|
@ -997,20 +997,19 @@ or1k_strict_argument_naming (cumulative_args_t /* ca */)
|
|||
maybe be passed in registers r3 to r8. */
|
||||
|
||||
static rtx
|
||||
or1k_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
||||
const_tree /* type */, bool named)
|
||||
or1k_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
|
||||
{
|
||||
/* VOIDmode is passed as a special flag for "last argument". */
|
||||
if (mode == VOIDmode)
|
||||
/* Handle the special marker for the end of the arguments. */
|
||||
if (arg.end_marker_p ())
|
||||
return NULL_RTX;
|
||||
|
||||
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
|
||||
int nreg = CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
|
||||
int nreg = CEIL (GET_MODE_SIZE (arg.mode), UNITS_PER_WORD);
|
||||
|
||||
/* Note that all large arguments are passed by reference. */
|
||||
gcc_assert (nreg <= 2);
|
||||
if (named && *cum + nreg <= 6)
|
||||
return gen_rtx_REG (mode, *cum + 3);
|
||||
if (arg.named && *cum + nreg <= 6)
|
||||
return gen_rtx_REG (arg.mode, *cum + 3);
|
||||
else
|
||||
return NULL_RTX;
|
||||
}
|
||||
|
|
|
@ -169,8 +169,7 @@ static bool pa_pass_by_reference (cumulative_args_t,
|
|||
static int pa_arg_partial_bytes (cumulative_args_t, const function_arg_info &);
|
||||
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 rtx pa_function_arg (cumulative_args_t, const function_arg_info &);
|
||||
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);
|
||||
|
@ -9465,10 +9464,11 @@ pa_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
|
|||
??? We might want to restructure this so that it looks more like other
|
||||
ports. */
|
||||
static rtx
|
||||
pa_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
||||
const_tree type, bool named ATTRIBUTE_UNUSED)
|
||||
pa_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
|
||||
{
|
||||
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
|
||||
tree type = arg.type;
|
||||
machine_mode mode = arg.mode;
|
||||
int max_arg_words = (TARGET_64BIT ? 8 : 4);
|
||||
int alignment = 0;
|
||||
int arg_size;
|
||||
|
@ -9476,7 +9476,7 @@ pa_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
|||
int gpr_reg_base;
|
||||
rtx retval;
|
||||
|
||||
if (mode == VOIDmode)
|
||||
if (arg.end_marker_p ())
|
||||
return NULL_RTX;
|
||||
|
||||
arg_size = pa_function_arg_size (mode, type);
|
||||
|
|
|
@ -162,8 +162,7 @@ static rtx pdp11_function_value (const_tree, const_tree, bool);
|
|||
static rtx pdp11_libcall_value (machine_mode, const_rtx);
|
||||
static bool pdp11_function_value_regno_p (const unsigned int);
|
||||
static void pdp11_trampoline_init (rtx, tree, rtx);
|
||||
static rtx pdp11_function_arg (cumulative_args_t, machine_mode,
|
||||
const_tree, bool);
|
||||
static rtx pdp11_function_arg (cumulative_args_t, const function_arg_info &);
|
||||
static void pdp11_function_arg_advance (cumulative_args_t,
|
||||
machine_mode, const_tree, bool);
|
||||
static void pdp11_conditional_register_usage (void);
|
||||
|
@ -2180,26 +2179,10 @@ pdp11_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
|
|||
emit_move_insn (mem, fnaddr);
|
||||
}
|
||||
|
||||
/* Worker function for TARGET_FUNCTION_ARG.
|
||||
|
||||
Determine where to put an argument to a function.
|
||||
Value is zero to push the argument on the stack,
|
||||
or a hard register in which to store the argument.
|
||||
|
||||
MODE is the argument's machine mode.
|
||||
TYPE is the data type of the argument (as a tree).
|
||||
This is null for libcalls where that information may
|
||||
not be available.
|
||||
CUM is a variable of type CUMULATIVE_ARGS which gives info about
|
||||
the preceding args and about the function being called.
|
||||
NAMED is nonzero if this argument is a named parameter
|
||||
(otherwise it is an extra parameter matching an ellipsis). */
|
||||
/* Worker function for TARGET_FUNCTION_ARG. */
|
||||
|
||||
static rtx
|
||||
pdp11_function_arg (cumulative_args_t cum ATTRIBUTE_UNUSED,
|
||||
machine_mode mode ATTRIBUTE_UNUSED,
|
||||
const_tree type ATTRIBUTE_UNUSED,
|
||||
bool named ATTRIBUTE_UNUSED)
|
||||
pdp11_function_arg (cumulative_args_t, const function_arg_info &)
|
||||
{
|
||||
return NULL_RTX;
|
||||
}
|
||||
|
|
|
@ -2152,25 +2152,18 @@ pru_function_arg_regi_mark_slot (int regi,
|
|||
push the argument on the stack, or a hard register in which to
|
||||
store the argument.
|
||||
|
||||
MODE is the argument's machine mode.
|
||||
TYPE is the data type of the argument (as a tree).
|
||||
This is null for libcalls where that information may
|
||||
not be available.
|
||||
CUM is a variable of type CUMULATIVE_ARGS which gives info about
|
||||
the preceding args and about the function being called.
|
||||
NAMED is nonzero if this argument is a named parameter
|
||||
(otherwise it is an extra parameter matching an ellipsis). */
|
||||
ARG is a description of the argument. */
|
||||
|
||||
static rtx
|
||||
pru_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
||||
const_tree type,
|
||||
bool named)
|
||||
pru_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
|
||||
{
|
||||
rtx return_rtx = NULL_RTX;
|
||||
int regi = pru_function_arg_regi (cum_v, mode, type, named);
|
||||
int regi = pru_function_arg_regi (cum_v, arg.mode, arg.type, arg.named);
|
||||
|
||||
if (regi >= 0)
|
||||
return_rtx = gen_rtx_REG (mode, regi);
|
||||
return_rtx = gen_rtx_REG (arg.mode, regi);
|
||||
|
||||
return return_rtx;
|
||||
}
|
||||
|
|
|
@ -2743,16 +2743,15 @@ riscv_get_arg_info (struct riscv_arg_info *info, const CUMULATIVE_ARGS *cum,
|
|||
/* Implement TARGET_FUNCTION_ARG. */
|
||||
|
||||
static rtx
|
||||
riscv_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
||||
const_tree type, bool named)
|
||||
riscv_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
|
||||
{
|
||||
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
|
||||
struct riscv_arg_info info;
|
||||
|
||||
if (mode == VOIDmode)
|
||||
if (arg.end_marker_p ())
|
||||
return NULL;
|
||||
|
||||
return riscv_get_arg_info (&info, cum, mode, type, named, false);
|
||||
return riscv_get_arg_info (&info, cum, arg.mode, arg.type, arg.named, false);
|
||||
}
|
||||
|
||||
/* Implement TARGET_FUNCTION_ARG_ADVANCE. */
|
||||
|
|
|
@ -1737,21 +1737,11 @@ rl78_promote_function_mode (const_tree type ATTRIBUTE_UNUSED,
|
|||
return mode;
|
||||
}
|
||||
|
||||
/* Return an RTL expression describing the register holding a function
|
||||
parameter of mode MODE and type TYPE or NULL_RTX if the parameter should
|
||||
be passed on the stack. CUM describes the previous parameters to the
|
||||
function and NAMED is false if the parameter is part of a variable
|
||||
parameter list, or the last named parameter before the start of a
|
||||
variable parameter list. */
|
||||
|
||||
#undef TARGET_FUNCTION_ARG
|
||||
#define TARGET_FUNCTION_ARG rl78_function_arg
|
||||
|
||||
static rtx
|
||||
rl78_function_arg (cumulative_args_t cum_v ATTRIBUTE_UNUSED,
|
||||
machine_mode mode ATTRIBUTE_UNUSED,
|
||||
const_tree type ATTRIBUTE_UNUSED,
|
||||
bool named ATTRIBUTE_UNUSED)
|
||||
rl78_function_arg (cumulative_args_t, const function_arg_info &)
|
||||
{
|
||||
return NULL_RTX;
|
||||
}
|
||||
|
|
|
@ -1729,15 +1729,10 @@ rs6000_finish_function_arg (machine_mode mode, rtx *rvec, int k)
|
|||
Value is zero to push the argument on the stack,
|
||||
or a hard register in which to store the argument.
|
||||
|
||||
MODE is the argument's machine mode.
|
||||
TYPE is the data type of the argument (as a tree).
|
||||
This is null for libcalls where that information may
|
||||
not be available.
|
||||
CUM is a variable of type CUMULATIVE_ARGS which gives info about
|
||||
the preceding args and about the function being called. It is
|
||||
not modified in this routine.
|
||||
NAMED is nonzero if this argument is a named parameter
|
||||
(otherwise it is an extra parameter matching an ellipsis).
|
||||
ARG is a description of the argument.
|
||||
|
||||
On RS/6000 the first eight words of non-FP are normally in registers
|
||||
and the rest are pushed. Under AIX, the first 13 FP args are in registers.
|
||||
|
@ -1750,14 +1745,15 @@ rs6000_finish_function_arg (machine_mode mode, rtx *rvec, int k)
|
|||
doesn't support PARALLEL anyway.
|
||||
|
||||
Note that for args passed by reference, function_arg will be called
|
||||
with MODE and TYPE set to that of the pointer to the arg, not the arg
|
||||
itself. */
|
||||
with ARG describing the pointer to the arg, not the arg itself. */
|
||||
|
||||
rtx
|
||||
rs6000_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
||||
const_tree type, bool named)
|
||||
rs6000_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
|
||||
{
|
||||
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
|
||||
tree type = arg.type;
|
||||
machine_mode mode = arg.mode;
|
||||
bool named = arg.named;
|
||||
enum rs6000_abi abi = DEFAULT_ABI;
|
||||
machine_mode elt_mode;
|
||||
int n_elts;
|
||||
|
@ -1766,7 +1762,7 @@ rs6000_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
|||
bit that V.4 uses to say fp args were passed in registers.
|
||||
Assume that we don't need the marker for software floating point,
|
||||
or compiler generated library calls. */
|
||||
if (mode == VOIDmode)
|
||||
if (arg.end_marker_p ())
|
||||
{
|
||||
if (abi == ABI_V4
|
||||
&& (cum->call_cookie & CALL_LIBCALL) == 0
|
||||
|
@ -2210,7 +2206,8 @@ rs6000_parm_needs_stack (cumulative_args_t args_so_far, tree type)
|
|||
return true;
|
||||
|
||||
/* If there is no incoming register, we need a stack. */
|
||||
entry_parm = rs6000_function_arg (args_so_far, mode, type, true);
|
||||
function_arg_info arg (type, mode, /*named=*/true);
|
||||
entry_parm = rs6000_function_arg (args_so_far, arg);
|
||||
if (entry_parm == NULL)
|
||||
return true;
|
||||
|
||||
|
@ -2220,7 +2217,6 @@ rs6000_parm_needs_stack (cumulative_args_t args_so_far, tree type)
|
|||
return true;
|
||||
|
||||
/* Also true if we're partially in registers and partially not. */
|
||||
function_arg_info arg (type, mode, /*named=*/true);
|
||||
if (rs6000_arg_partial_bytes (args_so_far, arg) != 0)
|
||||
return true;
|
||||
|
||||
|
|
|
@ -164,8 +164,7 @@ extern void rs6000_function_arg_advance (cumulative_args_t cum,
|
|||
const_tree type, bool named);
|
||||
extern pad_direction rs6000_function_arg_padding (machine_mode mode,
|
||||
const_tree type);
|
||||
extern rtx rs6000_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
||||
const_tree type, bool named);
|
||||
extern rtx rs6000_function_arg (cumulative_args_t, const function_arg_info &);
|
||||
extern rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, const_tree,
|
||||
bool, bool);
|
||||
extern rtx rs6000_internal_arg_pointer (void);
|
||||
|
|
|
@ -1064,24 +1064,19 @@ rx_function_arg_size (machine_mode mode, const_tree type)
|
|||
#define NUM_ARG_REGS 4
|
||||
#define MAX_NUM_ARG_BYTES (NUM_ARG_REGS * UNITS_PER_WORD)
|
||||
|
||||
/* Return an RTL expression describing the register holding a function
|
||||
parameter of mode MODE and type TYPE or NULL_RTX if the parameter should
|
||||
be passed on the stack. CUM describes the previous parameters to the
|
||||
function and NAMED is false if the parameter is part of a variable
|
||||
parameter list, or the last named parameter before the start of a
|
||||
variable parameter list. */
|
||||
/* Return an RTL expression describing the register holding function
|
||||
argument ARG or NULL_RTX if the parameter should be passed on the
|
||||
stack. CUM describes the previous parameters to the function. */
|
||||
|
||||
static rtx
|
||||
rx_function_arg (cumulative_args_t cum, machine_mode mode,
|
||||
const_tree type, bool named)
|
||||
rx_function_arg (cumulative_args_t cum, const function_arg_info &arg)
|
||||
{
|
||||
unsigned int next_reg;
|
||||
unsigned int bytes_so_far = *get_cumulative_args (cum);
|
||||
unsigned int size;
|
||||
unsigned int rounded_size;
|
||||
|
||||
/* An exploded version of rx_function_arg_size. */
|
||||
size = (mode == BLKmode) ? int_size_in_bytes (type) : GET_MODE_SIZE (mode);
|
||||
size = arg.promoted_size_in_bytes ();
|
||||
/* If the size is not known it cannot be passed in registers. */
|
||||
if (size < 1)
|
||||
return NULL_RTX;
|
||||
|
@ -1095,18 +1090,18 @@ rx_function_arg (cumulative_args_t cum, machine_mode mode,
|
|||
|
||||
/* Unnamed arguments and the last named argument in a
|
||||
variadic function are always passed on the stack. */
|
||||
if (!named)
|
||||
if (!arg.named)
|
||||
return NULL_RTX;
|
||||
|
||||
/* Structures must occupy an exact number of registers,
|
||||
otherwise they are passed on the stack. */
|
||||
if ((type == NULL || AGGREGATE_TYPE_P (type))
|
||||
if ((arg.type == NULL || AGGREGATE_TYPE_P (arg.type))
|
||||
&& (size % UNITS_PER_WORD) != 0)
|
||||
return NULL_RTX;
|
||||
|
||||
next_reg = (bytes_so_far / UNITS_PER_WORD) + 1;
|
||||
|
||||
return gen_rtx_REG (mode, next_reg);
|
||||
return gen_rtx_REG (arg.mode, next_reg);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -12021,14 +12021,9 @@ s390_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
|
|||
Value is zero to push the argument on the stack,
|
||||
or a hard register in which to store the argument.
|
||||
|
||||
MODE is the argument's machine mode.
|
||||
TYPE is the data type of the argument (as a tree).
|
||||
This is null for libcalls where that information may
|
||||
not be available.
|
||||
CUM is a variable of type CUMULATIVE_ARGS which gives info about
|
||||
the preceding args and about the function being called.
|
||||
NAMED is nonzero if this argument is a named parameter
|
||||
(otherwise it is an extra parameter matching an ellipsis).
|
||||
ARG is a description of the argument.
|
||||
|
||||
On S/390, we use general purpose registers 2 through 6 to
|
||||
pass integer, pointer, and certain structure arguments, and
|
||||
|
@ -12037,39 +12032,38 @@ s390_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
|
|||
are pushed to the stack. */
|
||||
|
||||
static rtx
|
||||
s390_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
||||
const_tree type, bool named)
|
||||
s390_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
|
||||
{
|
||||
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
|
||||
|
||||
if (!named)
|
||||
s390_check_type_for_vector_abi (type, true, false);
|
||||
if (!arg.named)
|
||||
s390_check_type_for_vector_abi (arg.type, true, false);
|
||||
|
||||
if (s390_function_arg_vector (mode, type))
|
||||
if (s390_function_arg_vector (arg.mode, arg.type))
|
||||
{
|
||||
/* Vector arguments being part of the ellipsis are passed on the
|
||||
stack. */
|
||||
if (!named || (cum->vrs + 1 > VEC_ARG_NUM_REG))
|
||||
if (!arg.named || (cum->vrs + 1 > VEC_ARG_NUM_REG))
|
||||
return NULL_RTX;
|
||||
|
||||
return gen_rtx_REG (mode, cum->vrs + FIRST_VEC_ARG_REGNO);
|
||||
return gen_rtx_REG (arg.mode, cum->vrs + FIRST_VEC_ARG_REGNO);
|
||||
}
|
||||
else if (s390_function_arg_float (mode, type))
|
||||
else if (s390_function_arg_float (arg.mode, arg.type))
|
||||
{
|
||||
if (cum->fprs + 1 > FP_ARG_NUM_REG)
|
||||
return NULL_RTX;
|
||||
else
|
||||
return gen_rtx_REG (mode, cum->fprs + 16);
|
||||
return gen_rtx_REG (arg.mode, cum->fprs + 16);
|
||||
}
|
||||
else if (s390_function_arg_integer (mode, type))
|
||||
else if (s390_function_arg_integer (arg.mode, arg.type))
|
||||
{
|
||||
int size = s390_function_arg_size (mode, type);
|
||||
int size = s390_function_arg_size (arg.mode, arg.type);
|
||||
int n_gprs = (size + UNITS_PER_LONG - 1) / UNITS_PER_LONG;
|
||||
|
||||
if (cum->gprs + n_gprs > GP_ARG_NUM_REG)
|
||||
return NULL_RTX;
|
||||
else if (n_gprs == 1 || UNITS_PER_WORD == UNITS_PER_LONG)
|
||||
return gen_rtx_REG (mode, cum->gprs + 2);
|
||||
return gen_rtx_REG (arg.mode, cum->gprs + 2);
|
||||
else if (n_gprs == 2)
|
||||
{
|
||||
rtvec p = rtvec_alloc (2);
|
||||
|
@ -12081,16 +12075,16 @@ s390_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
|||
= gen_rtx_EXPR_LIST (SImode, gen_rtx_REG (SImode, cum->gprs + 3),
|
||||
GEN_INT (4));
|
||||
|
||||
return gen_rtx_PARALLEL (mode, p);
|
||||
return gen_rtx_PARALLEL (arg.mode, p);
|
||||
}
|
||||
}
|
||||
|
||||
/* After the real arguments, expand_call calls us once again
|
||||
with a void_type_node type. Whatever we return here is
|
||||
passed as operand 2 to the call expanders.
|
||||
/* After the real arguments, expand_call calls us once again with an
|
||||
end marker. Whatever we return here is passed as operand 2 to the
|
||||
call expanders.
|
||||
|
||||
We don't need this feature ... */
|
||||
else if (type == void_type_node)
|
||||
else if (arg.end_marker_p ())
|
||||
return const0_rtx;
|
||||
|
||||
gcc_unreachable ();
|
||||
|
@ -13352,7 +13346,8 @@ s390_call_saved_register_used (tree call_expr)
|
|||
type = build_pointer_type (type);
|
||||
}
|
||||
|
||||
parm_rtx = s390_function_arg (cum, mode, type, true);
|
||||
function_arg_info arg (type, mode, /*named=*/true);
|
||||
parm_rtx = s390_function_arg (cum, arg);
|
||||
|
||||
s390_function_arg_advance (cum, mode, type, true);
|
||||
|
||||
|
|
|
@ -301,8 +301,7 @@ static bool sh_callee_copies (cumulative_args_t, machine_mode,
|
|||
static int sh_arg_partial_bytes (cumulative_args_t, const function_arg_info &);
|
||||
static void sh_function_arg_advance (cumulative_args_t, machine_mode,
|
||||
const_tree, bool);
|
||||
static rtx sh_function_arg (cumulative_args_t, machine_mode,
|
||||
const_tree, bool);
|
||||
static rtx sh_function_arg (cumulative_args_t, const function_arg_info &);
|
||||
static int sh_dwarf_calling_convention (const_tree);
|
||||
static void sh_encode_section_info (tree, rtx, int);
|
||||
static bool sh2a_function_vector_p (tree);
|
||||
|
@ -8010,30 +8009,25 @@ sh_arg_partial_bytes (cumulative_args_t cum_v, const function_arg_info &arg)
|
|||
Value is zero to push the argument on the stack,
|
||||
or a hard register in which to store the argument.
|
||||
|
||||
MODE is the argument's machine mode.
|
||||
TYPE is the data type of the argument (as a tree).
|
||||
This is null for libcalls where that information may
|
||||
not be available.
|
||||
CUM is a variable of type CUMULATIVE_ARGS which gives info about
|
||||
the preceding args and about the function being called.
|
||||
NAMED is nonzero if this argument is a named parameter
|
||||
(otherwise it is an extra parameter matching an ellipsis).
|
||||
ARG is a description of the argument.
|
||||
|
||||
On SH the first args are normally in registers
|
||||
and the rest are pushed. Any arg that starts within the first
|
||||
NPARM_REGS words is at least partially passed in a register unless
|
||||
its data type forbids. */
|
||||
static rtx
|
||||
sh_function_arg (cumulative_args_t ca_v, machine_mode mode,
|
||||
const_tree type, bool named)
|
||||
sh_function_arg (cumulative_args_t ca_v, const function_arg_info &arg)
|
||||
{
|
||||
CUMULATIVE_ARGS *ca = get_cumulative_args (ca_v);
|
||||
machine_mode mode = arg.mode;
|
||||
|
||||
if (mode == VOIDmode)
|
||||
if (arg.end_marker_p ())
|
||||
return ca->renesas_abi ? const1_rtx : const0_rtx;
|
||||
|
||||
if (sh_pass_in_reg_p (*ca, mode, type)
|
||||
&& (named || ! (TARGET_HITACHI || ca->renesas_abi)))
|
||||
if (sh_pass_in_reg_p (*ca, mode, arg.type)
|
||||
&& (arg.named || ! (TARGET_HITACHI || ca->renesas_abi)))
|
||||
{
|
||||
int regno;
|
||||
|
||||
|
@ -10819,8 +10813,8 @@ sh_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
|
|||
|
||||
sh_function_arg_advance (pack_cumulative_args (&cum), Pmode, ptype, true);
|
||||
}
|
||||
this_rtx
|
||||
= sh_function_arg (pack_cumulative_args (&cum), Pmode, ptr_type_node, true);
|
||||
function_arg_info ptr_arg (ptr_type_node, Pmode, /*named=*/true);
|
||||
this_rtx = sh_function_arg (pack_cumulative_args (&cum), ptr_arg);
|
||||
|
||||
/* For SHcompact, we only have r0 for a scratch register: r1 is the
|
||||
static chain pointer (even if you can't have nested virtual functions
|
||||
|
|
|
@ -658,12 +658,9 @@ static bool sparc_pass_by_reference (cumulative_args_t,
|
|||
const function_arg_info &);
|
||||
static void sparc_function_arg_advance (cumulative_args_t,
|
||||
machine_mode, const_tree, bool);
|
||||
static rtx sparc_function_arg_1 (cumulative_args_t,
|
||||
machine_mode, const_tree, bool, bool);
|
||||
static rtx sparc_function_arg (cumulative_args_t,
|
||||
machine_mode, const_tree, bool);
|
||||
static rtx sparc_function_arg (cumulative_args_t, const function_arg_info &);
|
||||
static rtx sparc_function_incoming_arg (cumulative_args_t,
|
||||
machine_mode, const_tree, bool);
|
||||
const function_arg_info &);
|
||||
static pad_direction sparc_function_arg_padding (machine_mode, const_tree);
|
||||
static unsigned int sparc_function_arg_boundary (machine_mode,
|
||||
const_tree);
|
||||
|
@ -7379,24 +7376,22 @@ function_arg_vector_value (int size, int slotno, bool named, int regno)
|
|||
|
||||
CUM is a variable of type CUMULATIVE_ARGS which gives info about
|
||||
the preceding args and about the function being called.
|
||||
MODE is the argument's machine mode.
|
||||
TYPE is the data type of the argument (as a tree).
|
||||
This is null for libcalls where that information may
|
||||
not be available.
|
||||
NAMED is true if this argument is a named parameter
|
||||
(otherwise it is an extra parameter matching an ellipsis).
|
||||
ARG is a description of the argument.
|
||||
INCOMING_P is false for TARGET_FUNCTION_ARG, true for
|
||||
TARGET_FUNCTION_INCOMING_ARG. */
|
||||
|
||||
static rtx
|
||||
sparc_function_arg_1 (cumulative_args_t cum_v, machine_mode mode,
|
||||
const_tree type, bool named, bool incoming)
|
||||
sparc_function_arg_1 (cumulative_args_t cum_v, const function_arg_info &arg,
|
||||
bool incoming)
|
||||
{
|
||||
const CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
|
||||
const int regbase
|
||||
= incoming ? SPARC_INCOMING_INT_ARG_FIRST : SPARC_OUTGOING_INT_ARG_FIRST;
|
||||
int slotno, regno, padding;
|
||||
tree type = arg.type;
|
||||
machine_mode mode = arg.mode;
|
||||
enum mode_class mclass = GET_MODE_CLASS (mode);
|
||||
bool named = arg.named;
|
||||
|
||||
slotno
|
||||
= function_arg_slotno (cum, mode, type, named, incoming, ®no, &padding);
|
||||
|
@ -7495,19 +7490,18 @@ sparc_function_arg_1 (cumulative_args_t cum_v, machine_mode mode,
|
|||
/* Handle the TARGET_FUNCTION_ARG target hook. */
|
||||
|
||||
static rtx
|
||||
sparc_function_arg (cumulative_args_t cum, machine_mode mode,
|
||||
const_tree type, bool named)
|
||||
sparc_function_arg (cumulative_args_t cum, const function_arg_info &arg)
|
||||
{
|
||||
return sparc_function_arg_1 (cum, mode, type, named, false);
|
||||
return sparc_function_arg_1 (cum, arg, false);
|
||||
}
|
||||
|
||||
/* Handle the TARGET_FUNCTION_INCOMING_ARG target hook. */
|
||||
|
||||
static rtx
|
||||
sparc_function_incoming_arg (cumulative_args_t cum, machine_mode mode,
|
||||
const_tree type, bool named)
|
||||
sparc_function_incoming_arg (cumulative_args_t cum,
|
||||
const function_arg_info &arg)
|
||||
{
|
||||
return sparc_function_arg_1 (cum, mode, type, named, true);
|
||||
return sparc_function_arg_1 (cum, arg, true);
|
||||
}
|
||||
|
||||
/* For sparc64, objects requiring 16 byte alignment are passed that way. */
|
||||
|
|
|
@ -3829,9 +3829,7 @@ spu_function_value (const_tree type, const_tree func ATTRIBUTE_UNUSED)
|
|||
}
|
||||
|
||||
static rtx
|
||||
spu_function_arg (cumulative_args_t cum_v,
|
||||
machine_mode mode,
|
||||
const_tree type, bool named ATTRIBUTE_UNUSED)
|
||||
spu_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
|
||||
{
|
||||
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
|
||||
int byte_size;
|
||||
|
@ -3839,8 +3837,7 @@ spu_function_arg (cumulative_args_t cum_v,
|
|||
if (*cum >= MAX_REGISTER_ARGS)
|
||||
return 0;
|
||||
|
||||
byte_size = ((mode == BLKmode)
|
||||
? int_size_in_bytes (type) : GET_MODE_SIZE (mode));
|
||||
byte_size = arg.promoted_size_in_bytes ();
|
||||
|
||||
/* The ABI does not allow parameters to be passed partially in
|
||||
reg and partially in stack. */
|
||||
|
@ -3848,7 +3845,7 @@ spu_function_arg (cumulative_args_t cum_v,
|
|||
return 0;
|
||||
|
||||
/* Make sure small structs are left justified in a register. */
|
||||
if ((mode == BLKmode || (type && AGGREGATE_TYPE_P (type)))
|
||||
if ((arg.mode == BLKmode || arg.aggregate_type_p ())
|
||||
&& byte_size < UNITS_PER_WORD && byte_size > 0)
|
||||
{
|
||||
machine_mode smode;
|
||||
|
@ -3859,10 +3856,10 @@ spu_function_arg (cumulative_args_t cum_v,
|
|||
gr_reg = gen_rtx_EXPR_LIST (VOIDmode,
|
||||
gen_rtx_REG (smode, FIRST_ARG_REGNUM + *cum),
|
||||
const0_rtx);
|
||||
return gen_rtx_PARALLEL (mode, gen_rtvec (1, gr_reg));
|
||||
return gen_rtx_PARALLEL (arg.mode, gen_rtvec (1, gr_reg));
|
||||
}
|
||||
else
|
||||
return gen_rtx_REG (mode, FIRST_ARG_REGNUM + *cum);
|
||||
return gen_rtx_REG (arg.mode, FIRST_ARG_REGNUM + *cum);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -1233,17 +1233,17 @@ xstormy16_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
|
|||
}
|
||||
|
||||
static rtx
|
||||
xstormy16_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
||||
const_tree type, bool named ATTRIBUTE_UNUSED)
|
||||
xstormy16_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
|
||||
{
|
||||
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
|
||||
|
||||
if (mode == VOIDmode)
|
||||
if (arg.end_marker_p ())
|
||||
return const0_rtx;
|
||||
if (targetm.calls.must_pass_in_stack (mode, type)
|
||||
|| *cum + XSTORMY16_WORD_SIZE (type, mode) > NUM_ARGUMENT_REGISTERS)
|
||||
if (targetm.calls.must_pass_in_stack (arg.mode, arg.type)
|
||||
|| (*cum + XSTORMY16_WORD_SIZE (arg.type, arg.mode)
|
||||
> NUM_ARGUMENT_REGISTERS))
|
||||
return NULL_RTX;
|
||||
return gen_rtx_REG (mode, *cum + FIRST_ARGUMENT_REGISTER);
|
||||
return gen_rtx_REG (arg.mode, *cum + FIRST_ARGUMENT_REGISTER);
|
||||
}
|
||||
|
||||
/* Build the va_list type.
|
||||
|
|
|
@ -216,13 +216,10 @@ tilegx_function_arg_boundary (machine_mode mode, const_tree type)
|
|||
|
||||
/* Implement TARGET_FUNCTION_ARG. */
|
||||
static rtx
|
||||
tilegx_function_arg (cumulative_args_t cum_v,
|
||||
machine_mode mode,
|
||||
const_tree type, bool named ATTRIBUTE_UNUSED)
|
||||
tilegx_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
|
||||
{
|
||||
CUMULATIVE_ARGS cum = *get_cumulative_args (cum_v);
|
||||
int byte_size = ((mode == BLKmode)
|
||||
? int_size_in_bytes (type) : GET_MODE_SIZE (mode));
|
||||
int byte_size = arg.promoted_size_in_bytes ();
|
||||
bool doubleword_aligned_p;
|
||||
|
||||
if (cum >= TILEGX_NUM_ARG_REGS)
|
||||
|
@ -230,7 +227,7 @@ tilegx_function_arg (cumulative_args_t cum_v,
|
|||
|
||||
/* See whether the argument has doubleword alignment. */
|
||||
doubleword_aligned_p =
|
||||
tilegx_function_arg_boundary (mode, type) > BITS_PER_WORD;
|
||||
tilegx_function_arg_boundary (arg.mode, arg.type) > BITS_PER_WORD;
|
||||
|
||||
if (doubleword_aligned_p)
|
||||
cum += cum & 1;
|
||||
|
@ -241,7 +238,7 @@ tilegx_function_arg (cumulative_args_t cum_v,
|
|||
> TILEGX_NUM_ARG_REGS)
|
||||
return NULL_RTX;
|
||||
|
||||
return gen_rtx_REG (mode, cum);
|
||||
return gen_rtx_REG (arg.mode, cum);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -168,13 +168,10 @@ tilepro_function_arg_boundary (machine_mode mode, const_tree type)
|
|||
|
||||
/* Implement TARGET_FUNCTION_ARG. */
|
||||
static rtx
|
||||
tilepro_function_arg (cumulative_args_t cum_v,
|
||||
machine_mode mode,
|
||||
const_tree type, bool named ATTRIBUTE_UNUSED)
|
||||
tilepro_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
|
||||
{
|
||||
CUMULATIVE_ARGS cum = *get_cumulative_args (cum_v);
|
||||
int byte_size = ((mode == BLKmode)
|
||||
? int_size_in_bytes (type) : GET_MODE_SIZE (mode));
|
||||
int byte_size = arg.promoted_size_in_bytes ();
|
||||
bool doubleword_aligned_p;
|
||||
|
||||
if (cum >= TILEPRO_NUM_ARG_REGS)
|
||||
|
@ -182,7 +179,7 @@ tilepro_function_arg (cumulative_args_t cum_v,
|
|||
|
||||
/* See whether the argument has doubleword alignment. */
|
||||
doubleword_aligned_p =
|
||||
tilepro_function_arg_boundary (mode, type) > BITS_PER_WORD;
|
||||
tilepro_function_arg_boundary (arg.mode, arg.type) > BITS_PER_WORD;
|
||||
|
||||
if (doubleword_aligned_p)
|
||||
cum += cum & 1;
|
||||
|
@ -193,7 +190,7 @@ tilepro_function_arg (cumulative_args_t cum_v,
|
|||
> TILEPRO_NUM_ARG_REGS)
|
||||
return NULL_RTX;
|
||||
|
||||
return gen_rtx_REG (mode, cum);
|
||||
return gen_rtx_REG (arg.mode, cum);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -119,26 +119,20 @@ v850_pass_by_reference (cumulative_args_t, const function_arg_info &arg)
|
|||
return size > 8;
|
||||
}
|
||||
|
||||
/* Return an RTX to represent where an argument with mode MODE
|
||||
and type TYPE will be passed to a function. If the result
|
||||
is NULL_RTX, the argument will be pushed. */
|
||||
/* Return an RTX to represent where argument ARG will be passed to a function.
|
||||
If the result is NULL_RTX, the argument will be pushed. */
|
||||
|
||||
static rtx
|
||||
v850_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
||||
const_tree type, bool named)
|
||||
v850_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
|
||||
{
|
||||
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
|
||||
rtx result = NULL_RTX;
|
||||
int size, align;
|
||||
|
||||
if (!named)
|
||||
if (!arg.named)
|
||||
return NULL_RTX;
|
||||
|
||||
if (mode == BLKmode)
|
||||
size = int_size_in_bytes (type);
|
||||
else
|
||||
size = GET_MODE_SIZE (mode);
|
||||
|
||||
size = arg.promoted_size_in_bytes ();
|
||||
size = (size + UNITS_PER_WORD -1) & ~(UNITS_PER_WORD -1);
|
||||
|
||||
if (size < 1)
|
||||
|
@ -150,8 +144,8 @@ v850_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
|||
|
||||
if (!TARGET_GCC_ABI)
|
||||
align = UNITS_PER_WORD;
|
||||
else if (size <= UNITS_PER_WORD && type)
|
||||
align = TYPE_ALIGN (type) / BITS_PER_UNIT;
|
||||
else if (size <= UNITS_PER_WORD && arg.type)
|
||||
align = TYPE_ALIGN (arg.type) / BITS_PER_UNIT;
|
||||
else
|
||||
align = size;
|
||||
|
||||
|
@ -160,23 +154,23 @@ v850_function_arg (cumulative_args_t cum_v, machine_mode mode,
|
|||
if (cum->nbytes > 4 * UNITS_PER_WORD)
|
||||
return NULL_RTX;
|
||||
|
||||
if (type == NULL_TREE
|
||||
if (arg.type == NULL_TREE
|
||||
&& cum->nbytes + size > 4 * UNITS_PER_WORD)
|
||||
return NULL_RTX;
|
||||
|
||||
switch (cum->nbytes / UNITS_PER_WORD)
|
||||
{
|
||||
case 0:
|
||||
result = gen_rtx_REG (mode, 6);
|
||||
result = gen_rtx_REG (arg.mode, 6);
|
||||
break;
|
||||
case 1:
|
||||
result = gen_rtx_REG (mode, 7);
|
||||
result = gen_rtx_REG (arg.mode, 7);
|
||||
break;
|
||||
case 2:
|
||||
result = gen_rtx_REG (mode, 8);
|
||||
result = gen_rtx_REG (arg.mode, 8);
|
||||
break;
|
||||
case 3:
|
||||
result = gen_rtx_REG (mode, 9);
|
||||
result = gen_rtx_REG (arg.mode, 9);
|
||||
break;
|
||||
default:
|
||||
result = NULL_RTX;
|
||||
|
|
|
@ -54,8 +54,7 @@ static void vax_output_mi_thunk (FILE *, tree, HOST_WIDE_INT,
|
|||
static int vax_address_cost_1 (rtx);
|
||||
static int vax_address_cost (rtx, machine_mode, addr_space_t, bool);
|
||||
static bool vax_rtx_costs (rtx, machine_mode, int, int, int *, bool);
|
||||
static rtx vax_function_arg (cumulative_args_t, machine_mode,
|
||||
const_tree, bool);
|
||||
static rtx vax_function_arg (cumulative_args_t, const function_arg_info &);
|
||||
static void vax_function_arg_advance (cumulative_args_t, machine_mode,
|
||||
const_tree, bool);
|
||||
static rtx vax_struct_value_rtx (tree, int);
|
||||
|
@ -2141,26 +2140,10 @@ vax_return_pops_args (tree fundecl ATTRIBUTE_UNUSED,
|
|||
return size > 255 * 4 ? 0 : (HOST_WIDE_INT) size;
|
||||
}
|
||||
|
||||
/* Define where to put the arguments to a function.
|
||||
Value is zero to push the argument on the stack,
|
||||
or a hard register in which to store the argument.
|
||||
|
||||
MODE is the argument's machine mode.
|
||||
TYPE is the data type of the argument (as a tree).
|
||||
This is null for libcalls where that information may
|
||||
not be available.
|
||||
CUM is a variable of type CUMULATIVE_ARGS which gives info about
|
||||
the preceding args and about the function being called.
|
||||
NAMED is nonzero if this argument is a named parameter
|
||||
(otherwise it is an extra parameter matching an ellipsis). */
|
||||
|
||||
/* On the VAX all args are pushed. */
|
||||
/* Implement TARGET_FUNCTION_ARG. On the VAX all args are pushed. */
|
||||
|
||||
static rtx
|
||||
vax_function_arg (cumulative_args_t cum ATTRIBUTE_UNUSED,
|
||||
machine_mode mode ATTRIBUTE_UNUSED,
|
||||
const_tree type ATTRIBUTE_UNUSED,
|
||||
bool named ATTRIBUTE_UNUSED)
|
||||
vax_function_arg (cumulative_args_t, const function_arg_info &)
|
||||
{
|
||||
return NULL_RTX;
|
||||
}
|
||||
|
|
|
@ -161,8 +161,7 @@ static struct machine_function *visium_init_machine_status (void);
|
|||
static bool visium_pass_by_reference (cumulative_args_t,
|
||||
const function_arg_info &);
|
||||
|
||||
static rtx visium_function_arg (cumulative_args_t, machine_mode,
|
||||
const_tree, bool);
|
||||
static rtx visium_function_arg (cumulative_args_t, const function_arg_info &);
|
||||
|
||||
static void visium_function_arg_advance (cumulative_args_t, machine_mode,
|
||||
const_tree, bool);
|
||||
|
@ -1330,33 +1329,31 @@ visium_pass_by_reference (cumulative_args_t, const function_arg_info &arg)
|
|||
in general registers. */
|
||||
|
||||
static rtx
|
||||
visium_function_arg (cumulative_args_t pcum_v, machine_mode mode,
|
||||
const_tree type ATTRIBUTE_UNUSED,
|
||||
bool named ATTRIBUTE_UNUSED)
|
||||
visium_function_arg (cumulative_args_t pcum_v, const function_arg_info &arg)
|
||||
{
|
||||
int size;
|
||||
CUMULATIVE_ARGS *ca = get_cumulative_args (pcum_v);
|
||||
|
||||
size = (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
|
||||
if (mode == VOIDmode)
|
||||
size = (GET_MODE_SIZE (arg.mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
|
||||
if (arg.end_marker_p ())
|
||||
return GEN_INT (0);
|
||||
|
||||
/* Scalar or complex single precision floating point arguments are returned
|
||||
in floating registers. */
|
||||
if (TARGET_FPU
|
||||
&& ((GET_MODE_CLASS (mode) == MODE_FLOAT
|
||||
&& GET_MODE_SIZE (mode) <= UNITS_PER_HWFPVALUE)
|
||||
|| (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
|
||||
&& GET_MODE_SIZE (mode) <= UNITS_PER_HWFPVALUE * 2)))
|
||||
&& ((GET_MODE_CLASS (arg.mode) == MODE_FLOAT
|
||||
&& GET_MODE_SIZE (arg.mode) <= UNITS_PER_HWFPVALUE)
|
||||
|| (GET_MODE_CLASS (arg.mode) == MODE_COMPLEX_FLOAT
|
||||
&& GET_MODE_SIZE (arg.mode) <= UNITS_PER_HWFPVALUE * 2)))
|
||||
{
|
||||
if (ca->frcount + size <= MAX_ARGS_IN_FP_REGISTERS)
|
||||
return gen_rtx_REG (mode, FP_ARG_FIRST + ca->frcount);
|
||||
return gen_rtx_REG (arg.mode, FP_ARG_FIRST + ca->frcount);
|
||||
else
|
||||
return NULL_RTX;
|
||||
}
|
||||
|
||||
if (ca->grcount + size <= MAX_ARGS_IN_GP_REGISTERS)
|
||||
return gen_rtx_REG (mode, ca->grcount + GP_ARG_FIRST);
|
||||
return gen_rtx_REG (arg.mode, ca->grcount + GP_ARG_FIRST);
|
||||
|
||||
return NULL_RTX;
|
||||
}
|
||||
|
|
|
@ -143,10 +143,9 @@ static tree xtensa_gimplify_va_arg_expr (tree, tree, gimple_seq *,
|
|||
gimple_seq *);
|
||||
static void xtensa_function_arg_advance (cumulative_args_t, machine_mode,
|
||||
const_tree, bool);
|
||||
static rtx xtensa_function_arg (cumulative_args_t, machine_mode,
|
||||
const_tree, bool);
|
||||
static rtx xtensa_function_arg (cumulative_args_t, const function_arg_info &);
|
||||
static rtx xtensa_function_incoming_arg (cumulative_args_t,
|
||||
machine_mode, const_tree, bool);
|
||||
const function_arg_info &);
|
||||
static rtx xtensa_function_value (const_tree, const_tree, bool);
|
||||
static rtx xtensa_libcall_value (machine_mode, const_rtx);
|
||||
static bool xtensa_function_value_regno_p (const unsigned int);
|
||||
|
@ -2128,13 +2127,13 @@ xtensa_function_arg_advance (cumulative_args_t cum, machine_mode mode,
|
|||
}
|
||||
|
||||
|
||||
/* Return an RTL expression containing the register for the given mode,
|
||||
/* Return an RTL expression containing the register for the given argument,
|
||||
or 0 if the argument is to be passed on the stack. INCOMING_P is nonzero
|
||||
if this is an incoming argument to the current function. */
|
||||
|
||||
static rtx
|
||||
xtensa_function_arg_1 (cumulative_args_t cum_v, machine_mode mode,
|
||||
const_tree type, bool incoming_p)
|
||||
xtensa_function_arg_1 (cumulative_args_t cum_v, const function_arg_info &arg,
|
||||
bool incoming_p)
|
||||
{
|
||||
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
|
||||
int regbase, words, max;
|
||||
|
@ -2145,13 +2144,12 @@ xtensa_function_arg_1 (cumulative_args_t cum_v, machine_mode mode,
|
|||
regbase = (incoming_p ? GP_ARG_FIRST : GP_OUTGOING_ARG_FIRST);
|
||||
max = MAX_ARGS_IN_REGISTERS;
|
||||
|
||||
words = (((mode != BLKmode)
|
||||
? (int) GET_MODE_SIZE (mode)
|
||||
: int_size_in_bytes (type)) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
|
||||
words = ((arg.promoted_size_in_bytes () + UNITS_PER_WORD - 1)
|
||||
/ UNITS_PER_WORD);
|
||||
|
||||
if (type && (TYPE_ALIGN (type) > BITS_PER_WORD))
|
||||
if (arg.type && (TYPE_ALIGN (arg.type) > BITS_PER_WORD))
|
||||
{
|
||||
int align = MIN (TYPE_ALIGN (type), STACK_BOUNDARY) / BITS_PER_WORD;
|
||||
int align = MIN (TYPE_ALIGN (arg.type), STACK_BOUNDARY) / BITS_PER_WORD;
|
||||
*arg_words = (*arg_words + align - 1) & -align;
|
||||
}
|
||||
|
||||
|
@ -2163,25 +2161,24 @@ xtensa_function_arg_1 (cumulative_args_t cum_v, machine_mode mode,
|
|||
if (cum->incoming && regno <= A7_REG && regno + words > A7_REG)
|
||||
cfun->machine->need_a7_copy = TARGET_WINDOWED_ABI;
|
||||
|
||||
return gen_rtx_REG (mode, regno);
|
||||
return gen_rtx_REG (arg.mode, regno);
|
||||
}
|
||||
|
||||
/* Implement TARGET_FUNCTION_ARG. */
|
||||
|
||||
static rtx
|
||||
xtensa_function_arg (cumulative_args_t cum, machine_mode mode,
|
||||
const_tree type, bool named ATTRIBUTE_UNUSED)
|
||||
xtensa_function_arg (cumulative_args_t cum, const function_arg_info &arg)
|
||||
{
|
||||
return xtensa_function_arg_1 (cum, mode, type, false);
|
||||
return xtensa_function_arg_1 (cum, arg, false);
|
||||
}
|
||||
|
||||
/* Implement TARGET_FUNCTION_INCOMING_ARG. */
|
||||
|
||||
static rtx
|
||||
xtensa_function_incoming_arg (cumulative_args_t cum, machine_mode mode,
|
||||
const_tree type, bool named ATTRIBUTE_UNUSED)
|
||||
xtensa_function_incoming_arg (cumulative_args_t cum,
|
||||
const function_arg_info &arg)
|
||||
{
|
||||
return xtensa_function_arg_1 (cum, mode, type, true);
|
||||
return xtensa_function_arg_1 (cum, arg, true);
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
|
|
|
@ -3961,18 +3961,10 @@ This section describes the macros which let you control how various
|
|||
types of arguments are passed in registers or how they are arranged in
|
||||
the stack.
|
||||
|
||||
@deftypefn {Target Hook} rtx TARGET_FUNCTION_ARG (cumulative_args_t @var{ca}, machine_mode @var{mode}, const_tree @var{type}, bool @var{named})
|
||||
Return an RTX indicating whether a function argument is passed in a
|
||||
register and if so, which register.
|
||||
|
||||
The arguments are @var{ca}, which summarizes all the previous
|
||||
arguments; @var{mode}, the machine mode of the argument; @var{type},
|
||||
the data type of the argument as a tree node or 0 if that is not known
|
||||
(which happens for C support library functions); and @var{named},
|
||||
which is @code{true} for an ordinary argument and @code{false} for
|
||||
nameless arguments that correspond to @samp{@dots{}} in the called
|
||||
function's prototype. @var{type} can be an incomplete type if a
|
||||
syntax error has previously occurred.
|
||||
@deftypefn {Target Hook} rtx TARGET_FUNCTION_ARG (cumulative_args_t @var{ca}, const function_arg_info @var{&arg})
|
||||
Return an RTX indicating whether function argument @var{arg} is passed
|
||||
in a register and if so, which register. Argument @var{ca} summarizes all
|
||||
the previous arguments.
|
||||
|
||||
The return value is usually either a @code{reg} RTX for the hard
|
||||
register in which to pass the argument, or zero to pass the argument
|
||||
|
@ -4027,7 +4019,7 @@ definition that is usually appropriate, refer to @file{expr.h} for additional
|
|||
documentation.
|
||||
@end deftypefn
|
||||
|
||||
@deftypefn {Target Hook} rtx TARGET_FUNCTION_INCOMING_ARG (cumulative_args_t @var{ca}, machine_mode @var{mode}, const_tree @var{type}, bool @var{named})
|
||||
@deftypefn {Target Hook} rtx TARGET_FUNCTION_INCOMING_ARG (cumulative_args_t @var{ca}, const function_arg_info @var{&arg})
|
||||
Define this hook if the caller and callee on the target have different
|
||||
views of where arguments are passed. Also define this hook if there are
|
||||
functions that are never directly called, but are invoked by the hardware
|
||||
|
|
|
@ -50,6 +50,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "params.h"
|
||||
#include "rtl-iter.h"
|
||||
#include "cfgcleanup.h"
|
||||
#include "calls.h"
|
||||
|
||||
/* This file contains three techniques for performing Dead Store
|
||||
Elimination (dse).
|
||||
|
@ -2343,7 +2344,8 @@ get_call_args (rtx call_insn, tree fn, rtx *args, int nargs)
|
|||
if (!is_int_mode (TYPE_MODE (TREE_VALUE (arg)), &mode))
|
||||
return false;
|
||||
|
||||
reg = targetm.calls.function_arg (args_so_far, mode, NULL_TREE, true);
|
||||
function_arg_info arg (mode, /*named=*/true);
|
||||
reg = targetm.calls.function_arg (args_so_far, arg);
|
||||
if (!reg || !REG_P (reg) || GET_MODE (reg) != mode)
|
||||
return false;
|
||||
|
||||
|
|
|
@ -1710,8 +1710,7 @@ block_move_libcall_safe_for_call_parm (void)
|
|||
{
|
||||
machine_mode mode = TYPE_MODE (TREE_VALUE (arg));
|
||||
function_arg_info arg_info (mode, /*named=*/true);
|
||||
rtx tmp = targetm.calls.function_arg (args_so_far, mode,
|
||||
NULL_TREE, true);
|
||||
rtx tmp = targetm.calls.function_arg (args_so_far, arg_info);
|
||||
if (!tmp || !REG_P (tmp))
|
||||
return false;
|
||||
if (targetm.calls.arg_partial_bytes (args_so_far, arg_info))
|
||||
|
|
|
@ -2517,11 +2517,9 @@ assign_parm_find_entry_rtl (struct assign_parm_data_all *all,
|
|||
targetm.calls.warn_parameter_passing_abi (all->args_so_far,
|
||||
data->passed_type);
|
||||
|
||||
entry_parm = targetm.calls.function_incoming_arg (all->args_so_far,
|
||||
data->promoted_mode,
|
||||
data->passed_type,
|
||||
data->named_arg);
|
||||
|
||||
function_arg_info arg (data->passed_type, data->promoted_mode,
|
||||
data->named_arg);
|
||||
entry_parm = targetm.calls.function_incoming_arg (all->args_so_far, arg);
|
||||
if (entry_parm == 0)
|
||||
data->promoted_mode = data->passed_mode;
|
||||
|
||||
|
@ -2544,9 +2542,10 @@ assign_parm_find_entry_rtl (struct assign_parm_data_all *all,
|
|||
if (targetm.calls.pretend_outgoing_varargs_named (all->args_so_far))
|
||||
{
|
||||
rtx tem;
|
||||
function_arg_info named_arg (data->passed_type, data->promoted_mode,
|
||||
/*named=*/true);
|
||||
tem = targetm.calls.function_incoming_arg (all->args_so_far,
|
||||
data->promoted_mode,
|
||||
data->passed_type, true);
|
||||
named_arg);
|
||||
in_regs = tem != NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4732,17 +4732,9 @@ constant size shorter than an @code{int}, and upward otherwise.",
|
|||
argument. */
|
||||
DEFHOOK
|
||||
(function_arg,
|
||||
"Return an RTX indicating whether a function argument is passed in a\n\
|
||||
register and if so, which register.\n\
|
||||
\n\
|
||||
The arguments are @var{ca}, which summarizes all the previous\n\
|
||||
arguments; @var{mode}, the machine mode of the argument; @var{type},\n\
|
||||
the data type of the argument as a tree node or 0 if that is not known\n\
|
||||
(which happens for C support library functions); and @var{named},\n\
|
||||
which is @code{true} for an ordinary argument and @code{false} for\n\
|
||||
nameless arguments that correspond to @samp{@dots{}} in the called\n\
|
||||
function's prototype. @var{type} can be an incomplete type if a\n\
|
||||
syntax error has previously occurred.\n\
|
||||
"Return an RTX indicating whether function argument @var{arg} is passed\n\
|
||||
in a register and if so, which register. Argument @var{ca} summarizes all\n\
|
||||
the previous arguments.\n\
|
||||
\n\
|
||||
The return value is usually either a @code{reg} RTX for the hard\n\
|
||||
register in which to pass the argument, or zero to pass the argument\n\
|
||||
|
@ -4788,8 +4780,7 @@ is not defined and @code{TARGET_FUNCTION_ARG} returns nonzero for such an\n\
|
|||
argument, the compiler will abort. If @code{REG_PARM_STACK_SPACE} is\n\
|
||||
defined, the argument will be computed in the stack and then loaded into\n\
|
||||
a register.",
|
||||
rtx, (cumulative_args_t ca, machine_mode mode, const_tree type,
|
||||
bool named),
|
||||
rtx, (cumulative_args_t ca, const function_arg_info &arg),
|
||||
default_function_arg)
|
||||
|
||||
DEFHOOK
|
||||
|
@ -4811,8 +4802,7 @@ so that it can be used to pass special arguments.\n\
|
|||
\n\
|
||||
If @code{TARGET_FUNCTION_INCOMING_ARG} is not defined,\n\
|
||||
@code{TARGET_FUNCTION_ARG} serves both purposes.",
|
||||
rtx, (cumulative_args_t ca, machine_mode mode, const_tree type,
|
||||
bool named),
|
||||
rtx, (cumulative_args_t ca, const function_arg_info &arg),
|
||||
default_function_incoming_arg)
|
||||
|
||||
DEFHOOK
|
||||
|
|
|
@ -828,19 +828,13 @@ default_function_arg_padding (machine_mode mode, const_tree type)
|
|||
}
|
||||
|
||||
rtx
|
||||
default_function_arg (cumulative_args_t ca ATTRIBUTE_UNUSED,
|
||||
machine_mode mode ATTRIBUTE_UNUSED,
|
||||
const_tree type ATTRIBUTE_UNUSED,
|
||||
bool named ATTRIBUTE_UNUSED)
|
||||
default_function_arg (cumulative_args_t, const function_arg_info &)
|
||||
{
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
rtx
|
||||
default_function_incoming_arg (cumulative_args_t ca ATTRIBUTE_UNUSED,
|
||||
machine_mode mode ATTRIBUTE_UNUSED,
|
||||
const_tree type ATTRIBUTE_UNUSED,
|
||||
bool named ATTRIBUTE_UNUSED)
|
||||
default_function_incoming_arg (cumulative_args_t, const function_arg_info &)
|
||||
{
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
|
|
@ -151,10 +151,9 @@ extern void default_function_arg_advance
|
|||
(cumulative_args_t, machine_mode, const_tree, bool);
|
||||
extern HOST_WIDE_INT default_function_arg_offset (machine_mode, const_tree);
|
||||
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
|
||||
(cumulative_args_t, machine_mode, const_tree, bool);
|
||||
extern rtx default_function_arg (cumulative_args_t, const function_arg_info &);
|
||||
extern rtx default_function_incoming_arg (cumulative_args_t,
|
||||
const function_arg_info &);
|
||||
extern unsigned int default_function_arg_boundary (machine_mode,
|
||||
const_tree);
|
||||
extern unsigned int default_function_arg_round_boundary (machine_mode,
|
||||
|
|
|
@ -6294,11 +6294,11 @@ prepare_call_arguments (basic_block bb, rtx_insn *insn)
|
|||
{
|
||||
tree struct_addr = build_pointer_type (TREE_TYPE (type));
|
||||
machine_mode mode = TYPE_MODE (struct_addr);
|
||||
function_arg_info arg (struct_addr, /*named=*/true);
|
||||
rtx reg;
|
||||
INIT_CUMULATIVE_ARGS (args_so_far_v, type, NULL_RTX, fndecl,
|
||||
nargs + 1);
|
||||
reg = targetm.calls.function_arg (args_so_far, mode,
|
||||
struct_addr, true);
|
||||
reg = targetm.calls.function_arg (args_so_far, arg);
|
||||
targetm.calls.function_arg_advance (args_so_far, mode,
|
||||
struct_addr, true);
|
||||
if (reg == NULL_RTX)
|
||||
|
@ -6318,11 +6318,9 @@ prepare_call_arguments (basic_block bb, rtx_insn *insn)
|
|||
nargs);
|
||||
if (obj_type_ref && TYPE_ARG_TYPES (type) != void_list_node)
|
||||
{
|
||||
machine_mode mode;
|
||||
t = TYPE_ARG_TYPES (type);
|
||||
mode = TYPE_MODE (TREE_VALUE (t));
|
||||
this_arg = targetm.calls.function_arg (args_so_far, mode,
|
||||
TREE_VALUE (t), true);
|
||||
function_arg_info arg (TREE_VALUE (t), /*named=*/true);
|
||||
this_arg = targetm.calls.function_arg (args_so_far, arg);
|
||||
if (this_arg && !REG_P (this_arg))
|
||||
this_arg = NULL_RTX;
|
||||
else if (this_arg == NULL_RTX)
|
||||
|
@ -6436,8 +6434,8 @@ prepare_call_arguments (basic_block bb, rtx_insn *insn)
|
|||
if (pass_by_reference (&args_so_far_v, orig_arg))
|
||||
argtype = build_pointer_type (argtype);
|
||||
machine_mode mode = TYPE_MODE (argtype);
|
||||
reg = targetm.calls.function_arg (args_so_far, mode,
|
||||
argtype, true);
|
||||
function_arg_info arg (argtype, /*named=*/true);
|
||||
reg = targetm.calls.function_arg (args_so_far, arg);
|
||||
if (TREE_CODE (argtype) == REFERENCE_TYPE
|
||||
&& INTEGRAL_TYPE_P (TREE_TYPE (argtype))
|
||||
&& reg
|
||||
|
|
Loading…
Reference in New Issue