Use function_arg_info for TARGET_ARG_PARTIAL_BYTES

This patch adds the function_arg_info class and uses it for
TARGET_ARG_PARTIAL_BYTES.

The hook is passed the promoted mode instead of the original type mode.

The arguments aren't mentioned in the documentation, which is why the
target.def change is so small.

The patch changes "true" to "arg.named" in:

  gcc_assert (!epiphany_pass_by_reference (cum, mode, type, /* named */ true));

but epiphany_pass_by_reference doesn't care about the named flag.

2019-08-20  Richard Sandiford  <richard.sandiford@arm.com>

gcc/
	* target.def (arg_partial_bytes): Take a function_arg_info instead
	of a mode, type and named flag.
	* doc/tm.texi: Regenerate.
	* target.h (function_arg_info): Declare.
	* calls.h (function_arg_info): New class.
	* targhooks.h (hook_int_CUMULATIVE_ARGS_mode_tree_bool_0): Delete.
	(hook_int_CUMULATIVE_ARGS_arg_info_0): Declare.
	* targhooks.c (hook_int_CUMULATIVE_ARGS_mode_tree_bool_0): Delete.
	(hook_int_CUMULATIVE_ARGS_arg_info_0): New function.
	* calls.c (initialize_argument_information): Update call to
	targetm.calls.partial_bytes.
	(emit_library_call_value_1): Likewise.
	* expr.c (block_move_libcall_safe_for_call_parm): Likewise.
	* function.c (assign_parm_find_entry_rtl): Likewise.
	* config/alpha/alpha.c (alpha_arg_partial_bytes): Take a
	function_arg_info instead of a mode, type and named flag.
	* config/arc/arc.c (arc_arg_partial_bytes): Likewise.
	* config/arm/arm.c (arm_arg_partial_bytes): Likewise.
	(cmse_func_args_or_return_in_stack): Update accordingly.
	* config/bfin/bfin.c (bfin_arg_partial_bytes): Take a
	function_arg_info instead of a mode, type and named flag.
	* config/cris/cris.c (cris_arg_partial_bytes): Likewise.
	* config/csky/csky.c (csky_arg_partial_bytes): Likewise.
	* config/epiphany/epiphany.c (epiphany_arg_partial_bytes): Likewise.
	* config/fr30/fr30.c: Include calls.h.
	(fr30_arg_partial_bytes): Take a function_arg_info instead of a mode,
	type and named flag.
	* config/frv/frv.c: Include calls.h.
	(frv_arg_partial_bytes): Take a function_arg_info instead of a mode,
	type and named flag.
	* config/ft32/ft32.c (ft32_arg_partial_bytes): Likewise.
	* config/gcn/gcn.c (gcn_arg_partial_bytes): Likewise.
	* config/ia64/ia64.c (ia64_arg_partial_bytes): Likewise.
	* config/iq2000/iq2000.c (iq2000_arg_partial_bytes): Likewise.
	* config/m32r/m32r.c (m32r_arg_partial_bytes): Likewise.
	* config/mcore/mcore.c (mcore_arg_partial_bytes): Likewise.
	* config/microblaze/microblaze.c (function_arg_partial_bytes):
	Likewise.
	* config/mips/mips.c (mips_arg_partial_bytes): Likewise.
	* config/mn10300/mn10300.c (mn10300_arg_partial_bytes): Likewise.
	* config/moxie/moxie.c (moxie_arg_partial_bytes): Likewise.
	* config/msp430/msp430.c (msp430_arg_partial_bytes): Likewise.
	* config/nds32/nds32.c (nds32_arg_partial_bytes): Likewise.
	* config/nios2/nios2.c (nios2_arg_partial_bytes): Likewise.
	* config/pa/pa.c (pa_arg_partial_bytes): Likewise.
	* config/pru/pru.c (pru_arg_partial_bytes): Likewise.
	* config/riscv/riscv.c (riscv_arg_partial_bytes): Likewise.
	* config/rs6000/rs6000-internal.h (rs6000_arg_partial_bytes): Likewise.
	* config/rs6000/rs6000-call.c (rs6000_arg_partial_bytes): Likewise.
	(rs6000_parm_needs_stack): Update call accordingly.
	* config/sh/sh.c (sh_arg_partial_bytes): Take a
	function_arg_info instead of a mode, type and named flag.
	* config/sparc/sparc.c (sparc_arg_partial_bytes): Likewise.
	* config/v850/v850.c (v850_arg_partial_bytes): Likewise.

From-SVN: r274697
This commit is contained in:
Richard Sandiford 2019-08-20 08:52:17 +00:00 committed by Richard Sandiford
parent 4f53599cb5
commit a7c81bc1fb
40 changed files with 315 additions and 260 deletions

View File

@ -1,3 +1,60 @@
2019-08-20 Richard Sandiford <richard.sandiford@arm.com>
* target.def (arg_partial_bytes): Take a function_arg_info instead
of a mode, type and named flag.
* doc/tm.texi: Regenerate.
* target.h (function_arg_info): Declare.
* calls.h (function_arg_info): New class.
* targhooks.h (hook_int_CUMULATIVE_ARGS_mode_tree_bool_0): Delete.
(hook_int_CUMULATIVE_ARGS_arg_info_0): Declare.
* targhooks.c (hook_int_CUMULATIVE_ARGS_mode_tree_bool_0): Delete.
(hook_int_CUMULATIVE_ARGS_arg_info_0): New function.
* calls.c (initialize_argument_information): Update call to
targetm.calls.partial_bytes.
(emit_library_call_value_1): Likewise.
* expr.c (block_move_libcall_safe_for_call_parm): Likewise.
* function.c (assign_parm_find_entry_rtl): Likewise.
* config/alpha/alpha.c (alpha_arg_partial_bytes): Take a
function_arg_info instead of a mode, type and named flag.
* config/arc/arc.c (arc_arg_partial_bytes): Likewise.
* config/arm/arm.c (arm_arg_partial_bytes): Likewise.
(cmse_func_args_or_return_in_stack): Update accordingly.
* config/bfin/bfin.c (bfin_arg_partial_bytes): Take a
function_arg_info instead of a mode, type and named flag.
* config/cris/cris.c (cris_arg_partial_bytes): Likewise.
* config/csky/csky.c (csky_arg_partial_bytes): Likewise.
* config/epiphany/epiphany.c (epiphany_arg_partial_bytes): Likewise.
* config/fr30/fr30.c: Include calls.h.
(fr30_arg_partial_bytes): Take a function_arg_info instead of a mode,
type and named flag.
* config/frv/frv.c: Include calls.h.
(frv_arg_partial_bytes): Take a function_arg_info instead of a mode,
type and named flag.
* config/ft32/ft32.c (ft32_arg_partial_bytes): Likewise.
* config/gcn/gcn.c (gcn_arg_partial_bytes): Likewise.
* config/ia64/ia64.c (ia64_arg_partial_bytes): Likewise.
* config/iq2000/iq2000.c (iq2000_arg_partial_bytes): Likewise.
* config/m32r/m32r.c (m32r_arg_partial_bytes): Likewise.
* config/mcore/mcore.c (mcore_arg_partial_bytes): Likewise.
* config/microblaze/microblaze.c (function_arg_partial_bytes):
Likewise.
* config/mips/mips.c (mips_arg_partial_bytes): Likewise.
* config/mn10300/mn10300.c (mn10300_arg_partial_bytes): Likewise.
* config/moxie/moxie.c (moxie_arg_partial_bytes): Likewise.
* config/msp430/msp430.c (msp430_arg_partial_bytes): Likewise.
* config/nds32/nds32.c (nds32_arg_partial_bytes): Likewise.
* config/nios2/nios2.c (nios2_arg_partial_bytes): Likewise.
* config/pa/pa.c (pa_arg_partial_bytes): Likewise.
* config/pru/pru.c (pru_arg_partial_bytes): Likewise.
* config/riscv/riscv.c (riscv_arg_partial_bytes): Likewise.
* config/rs6000/rs6000-internal.h (rs6000_arg_partial_bytes): Likewise.
* config/rs6000/rs6000-call.c (rs6000_arg_partial_bytes): Likewise.
(rs6000_parm_needs_stack): Update call accordingly.
* config/sh/sh.c (sh_arg_partial_bytes): Take a
function_arg_info instead of a mode, type and named flag.
* config/sparc/sparc.c (sparc_arg_partial_bytes): Likewise.
* config/v850/v850.c (v850_arg_partial_bytes): Likewise.
2019-08-20 Richard Sandiford <richard.sandiford@arm.com>
* calls.h (must_pass_va_arg_in_stack): Declare.

View File

@ -2142,10 +2142,9 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED,
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, mode, type,
argpos < n_named_args);
args[i].partial = targetm.calls.arg_partial_bytes (args_so_far, arg);
args[i].pass_on_stack = targetm.calls.must_pass_in_stack (mode, type);
@ -4871,10 +4870,10 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
argvec[count].mode = Pmode;
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);
gcc_assert (targetm.calls.arg_partial_bytes (args_so_far, Pmode,
NULL_TREE, 1) == 0);
gcc_assert (targetm.calls.arg_partial_bytes (args_so_far, ptr_arg) == 0);
locate_and_pad_parm (Pmode, NULL_TREE,
#ifdef STACK_PARMS_IN_REG_PARM_AREA
@ -4952,13 +4951,14 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
}
mode = promote_function_mode (NULL_TREE, mode, &unsigned_p, NULL_TREE, 0);
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].partial
= targetm.calls.arg_partial_bytes (args_so_far, mode, NULL_TREE, 1);
= targetm.calls.arg_partial_bytes (args_so_far, arg);
if (argvec[count].reg == 0
|| argvec[count].partial != 0

View File

@ -20,6 +20,77 @@ along with GCC; see the file COPYING3. If not see
#ifndef GCC_CALLS_H
#define GCC_CALLS_H
/* Describes a function argument.
Each argument conceptually has a gimple-level type. Usually this type
is available directly as a tree via the TYPE field, but when calling
libgcc support functions it might instead be inferred from a mode,
in which case the type isn't available directly.
This gimple-level type might go through promotion before being passed to
the target function. Depending on the context, the MODE field is either
the mode of the gimple-level type (whether explicitly given or not)
or the mode after promotion has been performed. */
class function_arg_info
{
public:
function_arg_info () : type (NULL_TREE), mode (VOIDmode), named (false) {}
/* Initialize an argument of mode MODE, either before or after promotion. */
function_arg_info (machine_mode mode, bool named)
: type (NULL_TREE), mode (mode), named (named)
{}
/* Initialize an unpromoted argument of type TYPE. */
function_arg_info (tree type, bool named)
: type (type), mode (TYPE_MODE (type)), named (named)
{}
/* Initialize an argument with explicit properties. */
function_arg_info (tree type, machine_mode mode, bool named)
: type (type), mode (mode), named (named)
{}
/* Return true if the gimple-level type is an aggregate. */
bool aggregate_type_p () const { return type && AGGREGATE_TYPE_P (type); }
/* Return the size of the gimple-level type, or -1 if the size is
variable or otherwise not representable as a poly_int64.
Use this function when MODE is the mode of the type before promotion,
or in any context if the target never promotes function arguments. */
poly_int64 type_size_in_bytes () const
{
if (type)
return int_size_in_bytes (type);
return GET_MODE_SIZE (mode);
}
/* Return the size of the argument after promotion, or -1 if the size
is variable or otherwise not representable as a poly_int64.
Use this function when MODE is the mode of the type after promotion. */
poly_int64 promoted_size_in_bytes () const
{
if (mode == BLKmode)
return int_size_in_bytes (type);
return GET_MODE_SIZE (mode);
}
/* The type of the argument, or null if not known (which is true for
libgcc support functions). */
tree type;
/* The mode of the argument. Depending on context, this might be
the mode of the argument type or the mode after promotion. */
machine_mode mode;
/* True if the argument is treated as a named argument, false if it is
treated as an unnamed variadic argument (i.e. one passed through
"..."). See also TARGET_STRICT_ARGUMENT_NAMING. */
unsigned int named : 1;
};
extern int flags_from_decl_or_type (const_tree);
extern int call_expr_flags (const_tree);
extern int setjmp_call_p (const_tree);

View File

@ -5635,20 +5635,17 @@ alpha_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
}
static int
alpha_arg_partial_bytes (cumulative_args_t cum_v,
machine_mode mode ATTRIBUTE_UNUSED,
tree type ATTRIBUTE_UNUSED,
bool named ATTRIBUTE_UNUSED)
alpha_arg_partial_bytes (cumulative_args_t cum_v, const function_arg_info &arg)
{
int words = 0;
CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED = get_cumulative_args (cum_v);
#if TARGET_ABI_OPEN_VMS
if (cum->num_args < 6
&& 6 < cum->num_args + ALPHA_ARG_SIZE (mode, type))
&& 6 < cum->num_args + ALPHA_ARG_SIZE (arg.mode, arg.type))
words = 6 - cum->num_args;
#elif TARGET_ABI_OSF
if (*cum < 6 && 6 < *cum + ALPHA_ARG_SIZE (mode, type))
if (*cum < 6 && 6 < *cum + ALPHA_ARG_SIZE (arg.mode, arg.type))
words = 6 - *cum;
#else
#error Unhandled ABI

View File

@ -6432,17 +6432,15 @@ arc_output_pic_addr_const (FILE * file, rtx x, int code)
/* Implement TARGET_ARG_PARTIAL_BYTES. */
static int
arc_arg_partial_bytes (cumulative_args_t cum_v, machine_mode mode,
tree type, bool named ATTRIBUTE_UNUSED)
arc_arg_partial_bytes (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) : (int) GET_MODE_SIZE (mode));
int bytes = arg.promoted_size_in_bytes ();
int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
int arg_num = *cum;
int ret;
arg_num = ROUND_ADVANCE_CUM (arg_num, mode, type);
arg_num = ROUND_ADVANCE_CUM (arg_num, arg.mode, arg.type);
ret = GPR_REST_ARG_REGS (arg_num);
/* ICEd at function.c:2361, and ret is copied to data->partial */

View File

@ -187,8 +187,8 @@ static int arm_memory_move_cost (machine_mode, reg_class_t, bool);
static void emit_constant_insn (rtx cond, rtx pattern);
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, machine_mode,
tree, bool);
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 void arm_function_arg_advance (cumulative_args_t, machine_mode,
@ -6754,23 +6754,22 @@ arm_function_arg_boundary (machine_mode mode, const_tree type)
}
static int
arm_arg_partial_bytes (cumulative_args_t pcum_v, machine_mode mode,
tree type, bool named)
arm_arg_partial_bytes (cumulative_args_t pcum_v, const function_arg_info &arg)
{
CUMULATIVE_ARGS *pcum = get_cumulative_args (pcum_v);
int nregs = pcum->nregs;
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_partial;
}
if (TARGET_IWMMXT_ABI && arm_vector_mode_supported_p (mode))
if (TARGET_IWMMXT_ABI && arm_vector_mode_supported_p (arg.mode))
return 0;
if (NUM_ARG_REGS > nregs
&& (NUM_ARG_REGS < nregs + ARM_NUM_REGS2 (mode, type))
&& (NUM_ARG_REGS < nregs + ARM_NUM_REGS2 (arg.mode, arg.type))
&& pcum->can_split)
return (NUM_ARG_REGS - nregs) * UNITS_PER_WORD;
@ -6999,11 +6998,11 @@ cmse_func_args_or_return_in_stack (tree fndecl, tree name, tree fntype)
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);
if (!arg_rtx
|| arm_arg_partial_bytes (args_so_far, arg_mode, arg_type, true))
if (!arg_rtx || arm_arg_partial_bytes (args_so_far, arg))
{
error ("%qE attribute not available to functions with arguments "
"passed on the stack", name);

View File

@ -1723,12 +1723,9 @@ bfin_function_arg (cumulative_args_t cum_v, machine_mode mode,
stack. */
static int
bfin_arg_partial_bytes (cumulative_args_t cum, machine_mode mode,
tree type ATTRIBUTE_UNUSED,
bool named ATTRIBUTE_UNUSED)
bfin_arg_partial_bytes (cumulative_args_t cum, const function_arg_info &arg)
{
int bytes
= (mode == BLKmode) ? int_size_in_bytes (type) : GET_MODE_SIZE (mode);
int bytes = arg.promoted_size_in_bytes ();
int bytes_left = get_cumulative_args (cum)->nregs * UNITS_PER_WORD;
if (bytes == -1)

View File

@ -141,8 +141,8 @@ static bool cris_rtx_costs (rtx, machine_mode, int, int, int *, bool);
static int cris_address_cost (rtx, machine_mode, addr_space_t, bool);
static bool cris_pass_by_reference (cumulative_args_t, machine_mode,
const_tree, bool);
static int cris_arg_partial_bytes (cumulative_args_t, machine_mode,
tree, bool);
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_incoming_arg (cumulative_args_t,
@ -4111,13 +4111,12 @@ cris_function_value_regno_p (const unsigned int regno)
}
static int
cris_arg_partial_bytes (cumulative_args_t ca, machine_mode mode,
tree type, bool named ATTRIBUTE_UNUSED)
cris_arg_partial_bytes (cumulative_args_t ca, const function_arg_info &arg)
{
if (get_cumulative_args (ca)->regs == CRIS_MAX_ARGS_IN_REGS - 1
&& !targetm.calls.must_pass_in_stack (mode, type)
&& CRIS_FUNCTION_ARG_SIZE (mode, type) > 4
&& CRIS_FUNCTION_ARG_SIZE (mode, type) <= 8)
&& !targetm.calls.must_pass_in_stack (arg.mode, arg.type)
&& CRIS_FUNCTION_ARG_SIZE (arg.mode, arg.type) > 4
&& CRIS_FUNCTION_ARG_SIZE (arg.mode, arg.type) <= 8)
return UNITS_PER_WORD;
else
return 0;

View File

@ -1917,11 +1917,10 @@ csky_return_addr (int count, rtx frame ATTRIBUTE_UNUSED)
that are passed entirely in registers or
that are entirely pushed on the stack. */
static int
csky_arg_partial_bytes (cumulative_args_t pcum_v, machine_mode mode,
tree type, bool named ATTRIBUTE_UNUSED)
csky_arg_partial_bytes (cumulative_args_t pcum_v, const function_arg_info &arg)
{
CUMULATIVE_ARGS *pcum = get_cumulative_args (pcum_v);
int param_size = csky_num_arg_regs (mode, type);
int param_size = csky_num_arg_regs (arg.mode, arg.type);
if (*pcum < CSKY_NPARM_REGS
&& *pcum + param_size > CSKY_NPARM_REGS)

View File

@ -744,18 +744,20 @@ epiphany_setup_incoming_varargs (cumulative_args_t cum, machine_mode mode,
}
static int
epiphany_arg_partial_bytes (cumulative_args_t cum, machine_mode mode,
tree type, bool named ATTRIBUTE_UNUSED)
epiphany_arg_partial_bytes (cumulative_args_t cum,
const function_arg_info &arg)
{
int words = 0, rounded_cum;
gcc_assert (!epiphany_pass_by_reference (cum, mode, type, /* named */ true));
gcc_assert (!epiphany_pass_by_reference (cum, arg.mode, arg.type,
arg.named));
rounded_cum = ROUND_ADVANCE_CUM (*get_cumulative_args (cum), mode, type);
rounded_cum = ROUND_ADVANCE_CUM (*get_cumulative_args (cum),
arg.mode, arg.type);
if (rounded_cum < MAX_EPIPHANY_PARM_REGS)
{
words = MAX_EPIPHANY_PARM_REGS - rounded_cum;
if (words >= ROUND_ADVANCE_ARG (mode, type))
if (words >= ROUND_ADVANCE_ARG (arg.mode, arg.type))
words = 0;
}
return words * UNITS_PER_WORD;

View File

@ -39,6 +39,7 @@
#include "output.h"
#include "expr.h"
#include "builtins.h"
#include "calls.h"
/* This file should be included last. */
#include "target-def.h"
@ -115,8 +116,8 @@ static struct fr30_frame_info zero_frame_info;
static void fr30_setup_incoming_varargs (cumulative_args_t, machine_mode,
tree, int *, int);
static bool fr30_must_pass_in_stack (machine_mode, const_tree);
static int fr30_arg_partial_bytes (cumulative_args_t, machine_mode,
tree, bool);
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 void fr30_function_arg_advance (cumulative_args_t, machine_mode,
@ -770,23 +771,20 @@ fr30_num_arg_regs (machine_mode mode, const_tree type)
return (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
}
/* Returns the number of bytes in which *part* of a parameter of machine
mode MODE and tree type TYPE (which may be NULL if the type is not known).
If the argument fits entirely in the argument registers, or entirely on
the stack, then 0 is returned.
CUM is the number of argument registers already used by earlier
parameters to the function. */
/* Returns the number of bytes of argument registers required to hold *part*
of argument ARG. If the argument fits entirely in the argument registers,
or entirely on the stack, then 0 is returned. CUM is the number of
argument registers already used by earlier parameters to the function. */
static int
fr30_arg_partial_bytes (cumulative_args_t cum_v, machine_mode mode,
tree type, bool named)
fr30_arg_partial_bytes (cumulative_args_t cum_v, const function_arg_info &arg)
{
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
/* Unnamed arguments, i.e. those that are prototyped as ...
are always passed on the stack.
Also check here to see if all the argument registers are full. */
if (named == 0 || *cum >= FR30_NUM_ARG_REGS)
if (!arg.named || *cum >= FR30_NUM_ARG_REGS)
return 0;
/* Work out how many argument registers would be needed if this
@ -795,7 +793,7 @@ fr30_arg_partial_bytes (cumulative_args_t cum_v, machine_mode mode,
are needed because the parameter must be passed on the stack)
then return zero, as this parameter does not require partial
register, partial stack stack space. */
if (*cum + fr30_num_arg_regs (mode, type) <= FR30_NUM_ARG_REGS)
if (*cum + fr30_num_arg_regs (arg.mode, arg.type) <= FR30_NUM_ARG_REGS)
return 0;
return (FR30_NUM_ARG_REGS - *cum) * UNITS_PER_WORD;

View File

@ -49,6 +49,7 @@ along with GCC; see the file COPYING3. If not see
#include "builtins.h"
#include "ifcvt.h"
#include "rtl-iter.h"
#include "calls.h"
/* This file should be included last. */
#include "target-def.h"
@ -379,8 +380,8 @@ static void frv_output_const_unspec (FILE *,
static bool frv_function_ok_for_sibcall (tree, tree);
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, machine_mode,
tree, bool);
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,
@ -3183,28 +3184,12 @@ frv_function_arg_advance (cumulative_args_t cum_v,
}
/* A C expression for the number of words, at the beginning of an argument,
must be put in registers. The value must be zero for arguments that are
passed entirely in registers or that are entirely pushed on the stack.
On some machines, certain arguments must be passed partially in registers
and partially in memory. On these machines, typically the first N words of
arguments are passed in registers, and the rest on the stack. If a
multi-word argument (a `double' or a structure) crosses that boundary, its
first few words must be passed in registers and the rest must be pushed.
This macro tells the compiler when this occurs, and how many of the words
should go in registers.
`FUNCTION_ARG' for these arguments should return the first register to be
used by the caller for this argument; likewise `FUNCTION_INCOMING_ARG', for
the called function. */
/* Implement TARGET_ARG_PARTIAL_BYTES. */
static int
frv_arg_partial_bytes (cumulative_args_t cum, machine_mode mode,
tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED)
frv_arg_partial_bytes (cumulative_args_t cum, const function_arg_info &arg)
{
machine_mode xmode = (mode == BLKmode) ? SImode : mode;
machine_mode xmode = (arg.mode == BLKmode) ? SImode : arg.mode;
int bytes = GET_MODE_SIZE (xmode);
int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
int arg_num = *get_cumulative_args (cum);

View File

@ -711,8 +711,7 @@ ft32_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED,
that fit in argument passing registers. */
static int
ft32_arg_partial_bytes (cumulative_args_t cum_v,
machine_mode mode, tree type, bool named)
ft32_arg_partial_bytes (cumulative_args_t cum_v, const function_arg_info &arg)
{
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
int bytes_left, size;
@ -720,16 +719,16 @@ ft32_arg_partial_bytes (cumulative_args_t cum_v,
if (*cum >= 8)
return 0;
if (ft32_pass_by_reference (cum_v, mode, type, named))
if (ft32_pass_by_reference (cum_v, arg.mode, arg.type, arg.named))
size = 4;
else if (type)
else if (arg.type)
{
if (AGGREGATE_TYPE_P (type))
if (AGGREGATE_TYPE_P (arg.type))
return 0;
size = int_size_in_bytes (type);
size = int_size_in_bytes (arg.type);
}
else
size = GET_MODE_SIZE (mode);
size = GET_MODE_SIZE (arg.mode);
bytes_left = (4 * 6) - ((*cum - 2) * 4);

View File

@ -2349,22 +2349,21 @@ gcn_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
in registers or that are entirely pushed on the stack. */
static int
gcn_arg_partial_bytes (cumulative_args_t cum_v, machine_mode mode, tree type,
bool named)
gcn_arg_partial_bytes (cumulative_args_t cum_v, const function_arg_info &arg)
{
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
if (!named)
if (!arg.named)
return 0;
if (targetm.calls.must_pass_in_stack (mode, type))
if (targetm.calls.must_pass_in_stack (arg.mode, arg.type))
return 0;
if (cum->num >= NUM_PARM_REGS)
return 0;
/* If the argument fits entirely in registers, return 0. */
if (cum->num + num_arg_regs (mode, type) <= NUM_PARM_REGS)
if (cum->num + num_arg_regs (arg.mode, arg.type) <= NUM_PARM_REGS)
return 0;
return (NUM_PARM_REGS - cum->num) * UNITS_PER_WORD;

View File

@ -201,8 +201,8 @@ static bool ia64_can_eliminate (const int, const int);
static machine_mode hfa_element_mode (const_tree, bool);
static void ia64_setup_incoming_varargs (cumulative_args_t, machine_mode,
tree, int *, int);
static int ia64_arg_partial_bytes (cumulative_args_t, machine_mode,
tree, bool);
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,
@ -4961,13 +4961,12 @@ ia64_function_incoming_arg (cumulative_args_t cum,
in memory. */
static int
ia64_arg_partial_bytes (cumulative_args_t cum_v, machine_mode mode,
tree type, bool named ATTRIBUTE_UNUSED)
ia64_arg_partial_bytes (cumulative_args_t cum_v, const function_arg_info &arg)
{
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
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);
/* If all argument slots are used, then it must go on the stack. */
if (cum->words + offset >= MAX_ARGUMENT_SLOTS)

View File

@ -161,8 +161,8 @@ static section *iq2000_select_section (tree, int, unsigned HOST_WIDE_INT);
static rtx iq2000_legitimize_address (rtx, rtx, machine_mode);
static bool iq2000_pass_by_reference (cumulative_args_t, machine_mode,
const_tree, bool);
static int iq2000_arg_partial_bytes (cumulative_args_t, machine_mode,
tree, bool);
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);
static void iq2000_function_arg_advance (cumulative_args_t,
@ -1421,13 +1421,12 @@ iq2000_function_arg_boundary (machine_mode mode, const_tree type)
}
static int
iq2000_arg_partial_bytes (cumulative_args_t cum_v, machine_mode mode,
tree type ATTRIBUTE_UNUSED,
bool named ATTRIBUTE_UNUSED)
iq2000_arg_partial_bytes (cumulative_args_t cum_v,
const function_arg_info &arg)
{
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
if (mode == DImode && cum->arg_words == MAX_ARGS_IN_REGISTERS - 1)
if (arg.mode == DImode && cum->arg_words == MAX_ARGS_IN_REGISTERS - 1)
{
if (TARGET_DEBUG_D_MODE)
fprintf (stderr, "iq2000_arg_partial_bytes=%d\n", UNITS_PER_WORD);

View File

@ -93,8 +93,8 @@ static bool m32r_rtx_costs (rtx, machine_mode, int, int, int *, bool speed);
static int m32r_memory_move_cost (machine_mode, reg_class_t, bool);
static bool m32r_pass_by_reference (cumulative_args_t, machine_mode,
const_tree, bool);
static int m32r_arg_partial_bytes (cumulative_args_t, machine_mode,
tree, bool);
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 void m32r_function_arg_advance (cumulative_args_t, machine_mode,
@ -1164,17 +1164,13 @@ gen_split_move_double (rtx operands[])
static int
m32r_arg_partial_bytes (cumulative_args_t cum_v, machine_mode mode,
tree type, bool named ATTRIBUTE_UNUSED)
m32r_arg_partial_bytes (cumulative_args_t cum_v, const function_arg_info &arg)
{
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
int words;
unsigned int size =
(((mode == BLKmode && type)
? (unsigned int) int_size_in_bytes (type)
: GET_MODE_SIZE (mode)) + UNITS_PER_WORD - 1)
/ UNITS_PER_WORD;
(arg.promoted_size_in_bytes () + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
if (*cum >= M32R_MAX_PARM_REGS)
words = 0;

View File

@ -129,8 +129,7 @@ static bool mcore_rtx_costs (rtx, machine_mode, int, int,
static void mcore_external_libcall (rtx);
static bool mcore_return_in_memory (const_tree, const_tree);
static int mcore_arg_partial_bytes (cumulative_args_t,
machine_mode,
tree, bool);
const function_arg_info &);
static rtx mcore_function_arg (cumulative_args_t,
machine_mode,
const_tree, bool);
@ -2841,22 +2840,19 @@ mcore_function_arg_boundary (machine_mode mode,
}
/* Returns the number of bytes of argument registers required to hold *part*
of a parameter of machine mode MODE and type TYPE (which may be NULL if
the type is not known). If the argument fits entirely in the argument
registers, or entirely on the stack, then 0 is returned. CUM is the
number of argument registers already used by earlier parameters to
the function. */
of argument ARG. If the argument fits entirely in the argument registers,
or entirely on the stack, then 0 is returned. CUM is the number of
argument registers already used by earlier parameters to the function. */
static int
mcore_arg_partial_bytes (cumulative_args_t cum, machine_mode mode,
tree type, bool named)
mcore_arg_partial_bytes (cumulative_args_t cum, const function_arg_info &arg)
{
int reg = ROUND_REG (*get_cumulative_args (cum), mode);
int reg = ROUND_REG (*get_cumulative_args (cum), arg.mode);
if (named == 0)
if (!arg.named)
return 0;
if (targetm.calls.must_pass_in_stack (mode, type))
if (targetm.calls.must_pass_in_stack (arg.mode, arg.type))
return 0;
/* REG is not the *hardware* register number of the register that holds
@ -2871,7 +2867,7 @@ mcore_arg_partial_bytes (cumulative_args_t cum, machine_mode mode,
return 0;
/* If the argument fits entirely in registers, return 0. */
if (reg + mcore_num_arg_regs (mode, type) <= NPARM_REGS)
if (reg + mcore_num_arg_regs (arg.mode, arg.type) <= NPARM_REGS)
return 0;
/* The argument overflows the number of available argument registers.

View File

@ -1653,30 +1653,25 @@ microblaze_function_arg (cumulative_args_t cum_v, machine_mode mode,
/* Return number of bytes of argument to put in registers. */
static int
function_arg_partial_bytes (cumulative_args_t cum_v, machine_mode mode,
tree type, bool named ATTRIBUTE_UNUSED)
function_arg_partial_bytes (cumulative_args_t cum_v,
const function_arg_info &arg)
{
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
if ((mode == BLKmode
|| GET_MODE_CLASS (mode) != MODE_COMPLEX_INT
|| GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT)
if ((arg.mode == BLKmode
|| GET_MODE_CLASS (arg.mode) != MODE_COMPLEX_INT
|| GET_MODE_CLASS (arg.mode) != MODE_COMPLEX_FLOAT)
&& cum->arg_words < MAX_ARGS_IN_REGISTERS)
{
int words;
if (mode == BLKmode)
words = ((int_size_in_bytes (type) + UNITS_PER_WORD - 1)
/ UNITS_PER_WORD);
else
words = (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
int words = ((arg.promoted_size_in_bytes () + UNITS_PER_WORD - 1)
/ UNITS_PER_WORD);
if (words + cum->arg_words <= MAX_ARGS_IN_REGISTERS)
return 0; /* structure fits in registers */
return (MAX_ARGS_IN_REGISTERS - cum->arg_words) * UNITS_PER_WORD;
}
else if (mode == DImode && cum->arg_words == MAX_ARGS_IN_REGISTERS - 1)
else if (arg.mode == DImode && cum->arg_words == MAX_ARGS_IN_REGISTERS - 1)
return UNITS_PER_WORD;
return 0;

View File

@ -6140,12 +6140,12 @@ mips_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
/* Implement TARGET_ARG_PARTIAL_BYTES. */
static int
mips_arg_partial_bytes (cumulative_args_t cum,
machine_mode mode, tree type, bool named)
mips_arg_partial_bytes (cumulative_args_t cum, const function_arg_info &arg)
{
struct mips_arg_info info;
mips_get_arg_info (&info, get_cumulative_args (cum), mode, type, named);
mips_get_arg_info (&info, get_cumulative_args (cum),
arg.mode, arg.type, arg.named);
return info.stack_words > 0 ? info.reg_words * UNITS_PER_WORD : 0;
}

View File

@ -1607,8 +1607,8 @@ mn10300_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
partially in registers and partially in memory. */
static int
mn10300_arg_partial_bytes (cumulative_args_t cum_v, machine_mode mode,
tree type, bool named ATTRIBUTE_UNUSED)
mn10300_arg_partial_bytes (cumulative_args_t cum_v,
const function_arg_info &arg)
{
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
int size;
@ -1617,11 +1617,7 @@ mn10300_arg_partial_bytes (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
@ -1634,7 +1630,7 @@ mn10300_arg_partial_bytes (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 0;

View File

@ -478,9 +478,7 @@ moxie_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED,
that fit in argument passing registers. */
static int
moxie_arg_partial_bytes (cumulative_args_t cum_v,
machine_mode mode,
tree type, bool named)
moxie_arg_partial_bytes (cumulative_args_t cum_v, const function_arg_info &arg)
{
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
int bytes_left, size;
@ -488,16 +486,16 @@ moxie_arg_partial_bytes (cumulative_args_t cum_v,
if (*cum >= 8)
return 0;
if (moxie_pass_by_reference (cum_v, mode, type, named))
if (moxie_pass_by_reference (cum_v, arg.mode, arg.type, arg.named))
size = 4;
else if (type)
else if (arg.type)
{
if (AGGREGATE_TYPE_P (type))
if (AGGREGATE_TYPE_P (arg.type))
return 0;
size = int_size_in_bytes (type);
size = int_size_in_bytes (arg.type);
}
else
size = GET_MODE_SIZE (mode);
size = GET_MODE_SIZE (arg.mode);
bytes_left = (4 * 6) - ((*cum - 2) * 4);

View File

@ -728,14 +728,11 @@ msp430_function_arg (cumulative_args_t cap,
#define TARGET_ARG_PARTIAL_BYTES msp430_arg_partial_bytes
int
msp430_arg_partial_bytes (cumulative_args_t cap,
machine_mode mode,
tree type,
bool named)
msp430_arg_partial_bytes (cumulative_args_t cap, 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 && ca->mem_count)
return ca->reg_count * UNITS_PER_WORD;

View File

@ -1963,8 +1963,7 @@ nds32_must_pass_in_stack (machine_mode mode, const_tree type)
}
static int
nds32_arg_partial_bytes (cumulative_args_t ca, machine_mode mode,
tree type, bool named ATTRIBUTE_UNUSED)
nds32_arg_partial_bytes (cumulative_args_t ca, const function_arg_info &arg)
{
/* Returns the number of bytes at the beginning of an argument that
must be put in registers. The value must be zero for arguments that are
@ -1985,18 +1984,19 @@ nds32_arg_partial_bytes (cumulative_args_t ca, machine_mode mode,
/* If we have already runned out of argument registers, return zero
so that the argument will be entirely pushed on the stack. */
if (NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type)
if (NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, arg.mode, arg.type)
>= NDS32_GPR_ARG_FIRST_REGNUM + NDS32_MAX_GPR_REGS_FOR_ARGS)
return 0;
/* Calculate how many registers do we need for this argument. */
needed_reg_count = NDS32_NEED_N_REGS_FOR_ARG (mode, type);
needed_reg_count = NDS32_NEED_N_REGS_FOR_ARG (arg.mode, arg.type);
/* Calculate how many argument registers have left for passing argument.
Note that we should count it from next available register number. */
remaining_reg_count
= NDS32_MAX_GPR_REGS_FOR_ARGS
- (NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type)
- (NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset,
arg.mode, arg.type)
- NDS32_GPR_ARG_FIRST_REGNUM);
/* Note that we have to return the nubmer of bytes, not registers count. */

View File

@ -3390,20 +3390,11 @@ nios2_function_arg (cumulative_args_t cum_v, machine_mode mode,
in memory. */
static int
nios2_arg_partial_bytes (cumulative_args_t cum_v,
machine_mode mode, tree type ATTRIBUTE_UNUSED,
bool named ATTRIBUTE_UNUSED)
nios2_arg_partial_bytes (cumulative_args_t cum_v, const function_arg_info &arg)
{
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
HOST_WIDE_INT param_size;
if (mode == BLKmode)
{
param_size = int_size_in_bytes (type);
gcc_assert (param_size >= 0);
}
else
param_size = GET_MODE_SIZE (mode);
HOST_WIDE_INT param_size = arg.promoted_size_in_bytes ();
gcc_assert (param_size >= 0);
/* Convert to words (round up). */
param_size = (UNITS_PER_WORD - 1 + param_size) / UNITS_PER_WORD;

View File

@ -166,8 +166,7 @@ static void pa_init_libfuncs (void);
static rtx pa_struct_value_rtx (tree, int);
static bool pa_pass_by_reference (cumulative_args_t, machine_mode,
const_tree, bool);
static int pa_arg_partial_bytes (cumulative_args_t, machine_mode,
tree, bool);
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,
@ -9685,8 +9684,7 @@ pa_function_arg_boundary (machine_mode mode, const_tree type)
then this routine should return zero. */
static int
pa_arg_partial_bytes (cumulative_args_t cum_v, machine_mode mode,
tree type, bool named ATTRIBUTE_UNUSED)
pa_arg_partial_bytes (cumulative_args_t cum_v, const function_arg_info &arg)
{
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
unsigned int max_arg_words = 8;
@ -9695,10 +9693,11 @@ pa_arg_partial_bytes (cumulative_args_t cum_v, machine_mode mode,
if (!TARGET_64BIT)
return 0;
if (pa_function_arg_size (mode, type) > 1 && (cum->words & 1))
if (pa_function_arg_size (arg.mode, arg.type) > 1 && (cum->words & 1))
offset = 1;
if (cum->words + offset + pa_function_arg_size (mode, type) <= max_arg_words)
if (cum->words + offset + pa_function_arg_size (arg.mode, arg.type)
<= max_arg_words)
/* Arg fits fully into registers. */
return 0;
else if (cum->words + offset >= max_arg_words)

View File

@ -2179,10 +2179,7 @@ pru_function_arg (cumulative_args_t cum_v, machine_mode mode,
between registers and memory, so we can return 0. */
static int
pru_arg_partial_bytes (cumulative_args_t cum_v ATTRIBUTE_UNUSED,
machine_mode mode ATTRIBUTE_UNUSED,
tree type ATTRIBUTE_UNUSED,
bool named ATTRIBUTE_UNUSED)
pru_arg_partial_bytes (cumulative_args_t, const function_arg_info &)
{
return 0;
}

View File

@ -2778,11 +2778,12 @@ riscv_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
static int
riscv_arg_partial_bytes (cumulative_args_t cum,
machine_mode mode, tree type, bool named)
const function_arg_info &generic_arg)
{
struct riscv_arg_info arg;
riscv_get_arg_info (&arg, get_cumulative_args (cum), mode, type, named, false);
riscv_get_arg_info (&arg, get_cumulative_args (cum), generic_arg.mode,
generic_arg.type, generic_arg.named, false);
return arg.stack_p ? arg.num_gprs * UNITS_PER_WORD : 0;
}

View File

@ -2007,8 +2007,8 @@ rs6000_function_arg (cumulative_args_t cum_v, machine_mode mode,
returns the number of bytes used by the first element of the PARALLEL. */
int
rs6000_arg_partial_bytes (cumulative_args_t cum_v, machine_mode mode,
tree type, bool named)
rs6000_arg_partial_bytes (cumulative_args_t cum_v,
const function_arg_info &arg)
{
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
bool passed_in_gprs = true;
@ -2017,12 +2017,13 @@ rs6000_arg_partial_bytes (cumulative_args_t cum_v, machine_mode mode,
machine_mode elt_mode;
int n_elts;
rs6000_discover_homogeneous_aggregate (mode, type, &elt_mode, &n_elts);
rs6000_discover_homogeneous_aggregate (arg.mode, arg.type,
&elt_mode, &n_elts);
if (DEFAULT_ABI == ABI_V4)
return 0;
if (USE_ALTIVEC_FOR_ARG_P (cum, elt_mode, named))
if (USE_ALTIVEC_FOR_ARG_P (cum, elt_mode, arg.named))
{
/* If we are passing this arg in the fixed parameter save area (gprs or
memory) as well as VRs, we do not use the partial bytes mechanism;
@ -2041,14 +2042,13 @@ rs6000_arg_partial_bytes (cumulative_args_t cum_v, machine_mode mode,
}
/* In this complicated case we just disable the partial_nregs code. */
if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
if (TARGET_MACHO && rs6000_darwin64_struct_check_p (arg.mode, arg.type))
return 0;
align_words = rs6000_parm_start (mode, type, cum->words);
align_words = rs6000_parm_start (arg.mode, arg.type, cum->words);
if (USE_FP_FOR_ARG_P (cum, elt_mode)
&& !(TARGET_AIX && !TARGET_ELF
&& type != NULL && AGGREGATE_TYPE_P (type)))
&& !(TARGET_AIX && !TARGET_ELF && arg.aggregate_type_p ()))
{
unsigned long n_fpreg = (GET_MODE_SIZE (elt_mode) + 7) >> 3;
@ -2056,7 +2056,7 @@ rs6000_arg_partial_bytes (cumulative_args_t cum_v, machine_mode mode,
(gprs or memory) as well as FPRs, we do not use the partial
bytes mechanism; instead, rs6000_function_arg will return a
PARALLEL including a memory element as necessary. */
if (type
if (arg.type
&& (cum->nargs_prototype <= 0
|| ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
&& TARGET_XL_COMPAT
@ -2087,7 +2087,7 @@ rs6000_arg_partial_bytes (cumulative_args_t cum_v, machine_mode mode,
if (passed_in_gprs
&& align_words < GP_ARG_NUM_REG
&& GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
&& GP_ARG_NUM_REG < align_words + rs6000_arg_size (arg.mode, arg.type))
ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
if (ret != 0 && TARGET_DEBUG_ARG)
@ -2222,7 +2222,8 @@ 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. */
if (rs6000_arg_partial_bytes (args_so_far, mode, type, true) != 0)
function_arg_info arg (type, mode, /*named=*/true);
if (rs6000_arg_partial_bytes (args_so_far, arg) != 0)
return true;
/* Update info on where next arg arrives in registers. */

View File

@ -159,9 +159,8 @@ extern void setup_incoming_varargs (cumulative_args_t cum, machine_mode mode,
extern unsigned int rs6000_function_arg_boundary (machine_mode mode,
const_tree type);
extern bool rs6000_must_pass_in_stack (machine_mode mode, const_tree type);
extern int rs6000_arg_partial_bytes (cumulative_args_t cum_v,
machine_mode mode, tree type,
bool named);
extern int rs6000_arg_partial_bytes (cumulative_args_t,
const function_arg_info &);
extern void rs6000_function_arg_advance (cumulative_args_t cum,
machine_mode mode,
const_tree type, bool named);

View File

@ -298,8 +298,7 @@ static bool sh_pass_by_reference (cumulative_args_t, machine_mode,
const_tree, bool);
static bool sh_callee_copies (cumulative_args_t, machine_mode,
const_tree, bool);
static int sh_arg_partial_bytes (cumulative_args_t, machine_mode,
tree, bool);
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,
@ -7992,20 +7991,17 @@ sh_pass_in_reg_p (const CUMULATIVE_ARGS& cum, machine_mode mode,
}
static int
sh_arg_partial_bytes (cumulative_args_t cum_v, machine_mode mode,
tree type, bool named ATTRIBUTE_UNUSED)
sh_arg_partial_bytes (cumulative_args_t cum_v, const function_arg_info &arg)
{
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
int words = 0;
if (sh_pass_in_reg_p (*cum, mode, type)
if (sh_pass_in_reg_p (*cum, arg.mode, arg.type)
&& !TARGET_FPU_DOUBLE
&& (sh_round_reg (*cum, mode)
+ (mode != BLKmode
? CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD)
: CEIL (int_size_in_bytes (type), UNITS_PER_WORD))
> NPARM_REGS (mode)))
words = NPARM_REGS (mode) - sh_round_reg (*cum, mode);
&& (sh_round_reg (*cum, arg.mode)
+ CEIL (arg.promoted_size_in_bytes (), UNITS_PER_WORD)
> NPARM_REGS (arg.mode)))
words = NPARM_REGS (arg.mode) - sh_round_reg (*cum, arg.mode);
return words * UNITS_PER_WORD;
}

View File

@ -668,7 +668,7 @@ static pad_direction sparc_function_arg_padding (machine_mode, const_tree);
static unsigned int sparc_function_arg_boundary (machine_mode,
const_tree);
static int sparc_arg_partial_bytes (cumulative_args_t,
machine_mode, tree, bool);
const function_arg_info &);
static bool sparc_return_in_memory (const_tree, const_tree);
static rtx sparc_struct_value_rtx (tree, int);
static rtx sparc_function_value (const_tree, const_tree, bool);
@ -7533,14 +7533,13 @@ sparc_function_arg_boundary (machine_mode mode, const_tree type)
mode] will be split between that reg and memory. */
static int
sparc_arg_partial_bytes (cumulative_args_t cum, machine_mode mode,
tree type, bool named)
sparc_arg_partial_bytes (cumulative_args_t cum, const function_arg_info &arg)
{
int slotno, regno, padding;
/* We pass false for incoming here, it doesn't matter. */
slotno = function_arg_slotno (get_cumulative_args (cum), mode, type, named,
false, &regno, &padding);
slotno = function_arg_slotno (get_cumulative_args (cum), arg.mode, arg.type,
arg.named, false, &regno, &padding);
if (slotno == -1)
return 0;
@ -7550,7 +7549,7 @@ sparc_arg_partial_bytes (cumulative_args_t cum, machine_mode mode,
/* We are guaranteed by pass_by_reference that the size of the
argument is not greater than 8 bytes, so we only need to return
one word if the argument is partially passed in registers. */
const int size = GET_MODE_SIZE (mode);
const int size = GET_MODE_SIZE (arg.mode);
if (size > UNITS_PER_WORD && slotno == SPARC_INT_ARG_MAX - 1)
return UNITS_PER_WORD;
@ -7560,33 +7559,33 @@ sparc_arg_partial_bytes (cumulative_args_t cum, machine_mode mode,
/* We are guaranteed by pass_by_reference that the size of the
argument is not greater than 16 bytes, so we only need to return
one word if the argument is partially passed in registers. */
if (type && AGGREGATE_TYPE_P (type))
if (arg.aggregate_type_p ())
{
const int size = int_size_in_bytes (type);
const int size = int_size_in_bytes (arg.type);
if (size > UNITS_PER_WORD
&& (slotno == SPARC_INT_ARG_MAX - 1
|| slotno == SPARC_FP_ARG_MAX - 1))
return UNITS_PER_WORD;
}
else if (GET_MODE_CLASS (mode) == MODE_COMPLEX_INT
|| ((GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
|| (type && VECTOR_TYPE_P (type)))
&& !(TARGET_FPU && named)))
else if (GET_MODE_CLASS (arg.mode) == MODE_COMPLEX_INT
|| ((GET_MODE_CLASS (arg.mode) == MODE_COMPLEX_FLOAT
|| (arg.type && VECTOR_TYPE_P (arg.type)))
&& !(TARGET_FPU && arg.named)))
{
const int size = (type && VECTOR_FLOAT_TYPE_P (type))
? int_size_in_bytes (type)
: GET_MODE_SIZE (mode);
const int size = (arg.type && VECTOR_FLOAT_TYPE_P (arg.type))
? int_size_in_bytes (arg.type)
: GET_MODE_SIZE (arg.mode);
if (size > UNITS_PER_WORD && slotno == SPARC_INT_ARG_MAX - 1)
return UNITS_PER_WORD;
}
else if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
|| (type && VECTOR_TYPE_P (type)))
else if (GET_MODE_CLASS (arg.mode) == MODE_COMPLEX_FLOAT
|| (arg.type && VECTOR_TYPE_P (arg.type)))
{
const int size = (type && VECTOR_FLOAT_TYPE_P (type))
? int_size_in_bytes (type)
: GET_MODE_SIZE (mode);
const int size = (arg.type && VECTOR_FLOAT_TYPE_P (arg.type))
? int_size_in_bytes (arg.type)
: GET_MODE_SIZE (arg.mode);
if (size > UNITS_PER_WORD && slotno == SPARC_FP_ARG_MAX - 1)
return UNITS_PER_WORD;

View File

@ -196,27 +196,22 @@ v850_function_arg (cumulative_args_t cum_v, machine_mode mode,
/* Return the number of bytes which must be put into registers
for values which are part in registers and part in memory. */
static int
v850_arg_partial_bytes (cumulative_args_t cum_v, machine_mode mode,
tree type, bool named)
v850_arg_partial_bytes (cumulative_args_t cum_v, const function_arg_info &arg)
{
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
int size, align;
if (!named)
if (!arg.named)
return 0;
if (mode == BLKmode)
size = int_size_in_bytes (type);
else
size = GET_MODE_SIZE (mode);
size = arg.promoted_size_in_bytes ();
if (size < 1)
size = 1;
if (!TARGET_GCC_ABI)
align = UNITS_PER_WORD;
else if (type)
align = TYPE_ALIGN (type) / BITS_PER_UNIT;
else if (arg.type)
align = TYPE_ALIGN (arg.type) / BITS_PER_UNIT;
else
align = size;
@ -228,7 +223,7 @@ v850_arg_partial_bytes (cumulative_args_t cum_v, machine_mode mode,
if (cum->nbytes + size <= 4 * UNITS_PER_WORD)
return 0;
if (type == NULL_TREE
if (arg.type == NULL_TREE
&& cum->nbytes + size > 4 * UNITS_PER_WORD)
return 0;

View File

@ -4057,7 +4057,7 @@ Perform a target dependent initialization of pic_offset_table_rtx.
This hook is called at the start of register allocation.
@end deftypefn
@deftypefn {Target Hook} int TARGET_ARG_PARTIAL_BYTES (cumulative_args_t @var{cum}, machine_mode @var{mode}, tree @var{type}, bool @var{named})
@deftypefn {Target Hook} int TARGET_ARG_PARTIAL_BYTES (cumulative_args_t @var{cum}, const function_arg_info @var{&arg})
This target hook returns the number of bytes at the beginning of an
argument that must be put in registers. The value must be zero for
arguments that are passed entirely in registers or that are entirely

View File

@ -1709,11 +1709,12 @@ block_move_libcall_safe_for_call_parm (void)
for ( ; arg != void_list_node ; arg = TREE_CHAIN (arg))
{
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);
if (!tmp || !REG_P (tmp))
return false;
if (targetm.calls.arg_partial_bytes (args_so_far, mode, NULL, 1))
if (targetm.calls.arg_partial_bytes (args_so_far, arg_info))
return false;
targetm.calls.function_arg_advance (args_so_far, mode,
NULL_TREE, true);

View File

@ -2559,10 +2559,9 @@ assign_parm_find_entry_rtl (struct assign_parm_data_all *all,
{
int partial;
partial = targetm.calls.arg_partial_bytes (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);
partial = targetm.calls.arg_partial_bytes (all->args_so_far, arg);
data->partial = partial;
/* The caller might already have allocated stack space for the

View File

@ -4677,8 +4677,8 @@ compiler when this occurs, and how many bytes should go in registers.\n\
@code{TARGET_FUNCTION_ARG} for these arguments should return the first\n\
register to be used by the caller for this argument; likewise\n\
@code{TARGET_FUNCTION_INCOMING_ARG}, for the called function.",
int, (cumulative_args_t cum, machine_mode mode, tree type, bool named),
hook_int_CUMULATIVE_ARGS_mode_tree_bool_0)
int, (cumulative_args_t cum, const function_arg_info &arg),
hook_int_CUMULATIVE_ARGS_arg_info_0)
/* Update the state in CA to advance past an argument in the
argument list. The values MODE, TYPE, and NAMED describe that

View File

@ -149,6 +149,9 @@ class ao_ref;
/* This is defined in tree-vectorizer.h. */
class _stmt_vec_info;
/* This is defined in calls.h. */
class function_arg_info;
/* These are defined in tree-vect-stmts.c. */
extern tree stmt_vectype (class _stmt_vec_info *);
extern bool stmt_in_inner_loop_p (class _stmt_vec_info *);

View File

@ -768,10 +768,8 @@ hook_bool_CUMULATIVE_ARGS_mode_tree_bool_true (
}
int
hook_int_CUMULATIVE_ARGS_mode_tree_bool_0 (
cumulative_args_t ca ATTRIBUTE_UNUSED,
machine_mode mode ATTRIBUTE_UNUSED,
tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED)
hook_int_CUMULATIVE_ARGS_arg_info_0 (cumulative_args_t,
const function_arg_info &)
{
return 0;
}

View File

@ -137,8 +137,8 @@ extern bool hook_bool_CUMULATIVE_ARGS_mode_tree_bool_false
(cumulative_args_t, machine_mode, const_tree, bool);
extern bool hook_bool_CUMULATIVE_ARGS_mode_tree_bool_true
(cumulative_args_t, machine_mode, const_tree, bool);
extern int hook_int_CUMULATIVE_ARGS_mode_tree_bool_0
(cumulative_args_t, machine_mode, tree, bool);
extern int hook_int_CUMULATIVE_ARGS_arg_info_0
(cumulative_args_t, const function_arg_info &);
extern void hook_void_CUMULATIVE_ARGS_tree
(cumulative_args_t, tree);
extern const char *hook_invalid_arg_for_unprototyped_fn