target.h (targetm.calls.arg_partial_bytes): New.
* target.h (targetm.calls.arg_partial_bytes): New. * target-def.h (TARGET_ARG_PARTIAL_BYTES): New. * calls.c (store_unaligned_arguments_into_pseudos): Update for partial in bytes. (load_register_parameters): Likewise. (store_one_arg): Likewise. (initialize_argument_information): Use targetm.calls.arg_partial_bytes. (emit_library_call_value_1): Likewise. * expr.c (block_move_libcall_safe_for_call_parm): Likewise. (emit_push_insn): Update for partial in bytes. * expr.h (FUNCTION_ARG_PARTIAL_NREGS): Remove. * function.c (assign_parm_find_entry_rtl): Use targetm.calls.arg_partial_bytes. Update for result in bytes. (locate_and_pad_parm): Update for partial in bytes. * system.h (FUNCTION_ARG_PARTIAL_NREGS): Poison. * targhooks.c (hook_int_CUMULATIVE_ARGS_mode_tree_bool_0): New. * targhooks.h (hook_int_CUMULATIVE_ARGS_mode_tree_bool_0): Declare. * doc/tm.texi (TARGET_ARG_PARTIAL_BYTES): Rename and update from FUNCTION_ARG_PARTIAL_NREGS. * config/arc/arc.h, config/c4x/c4x.h, config/i386/i386.h, config/i860/i860.h, config/m68hc11/m68hc11.h, config/m68k/m68k.h, config/pdp11/pdp11.h, config/s390/s390.h, config/stormy16/stormy16.h, config/xtensa/xtensa.h (FUNCTION_ARG_PARTIAL_NREGS): Remove. * config/alpha/alpha.c (alpha_arg_partial_bytes): New. (TARGET_ARG_PARTIAL_BYTES): New. * config/alpha/alpha.h, config/alpha/unicosmk.h, config/alpha/vms.h (FUNCTION_ARG_PARTIAL_NREGS): Remove. * config/arm/arm.h (FUNCTION_ARG_PARTIAL_NREGS): Move ... * config/arm/arm.c (arm_arg_partial_bytes): ... here. (TARGET_ARG_PARTIAL_BYTES): New. * config/cris/cris.h (FUNCTION_ARG_PARTIAL_NREGS): Move ... * config/cris/cris.c (cris_arg_partial_bytes): ... here. (TARGET_ARG_PARTIAL_BYTES): New. * config/fr30/fr30.h (FUNCTION_ARG_PARTIAL_NREGS): Remove. * config/fr30/fr30.c (fr30_arg_partial_bytes): Rename from fr30_function_arg_partial_nregs. Adjust to return bytes. (TARGET_ARG_PARTIAL_BYTES): New. * config/fr30/fr30-protos.h: Update. * config/frv/frv.h (FUNCTION_ARG_PARTIAL_NREGS): Remove. * config/frv/frv.c (frv_arg_partial_bytes): Rename from frv_function_arg_partial_nregs. Adjust to return bytes. (TARGET_ARG_PARTIAL_BYTES): New. * config/frv/frv-protos.h: Update. * config/ia64/ia64.h (FUNCTION_ARG_PARTIAL_NREGS): Remove. * config/ia64/ia64.c (ia64_arg_partial_bytes): Rename from ia64_function_arg_partial_nregs. Adjust to return bytes. (TARGET_ARG_PARTIAL_BYTES): New. * config/ia64/ia64-protos.h: Update. * config/iq2000/iq2000.h (FUNCTION_ARG_PARTIAL_NREGS): Remove. * config/iq2000/iq2000.c (iq2000_arg_partial_bytes): Rename from function_arg_partial_nregs. Adjust to return bytes. (TARGET_ARG_PARTIAL_BYTES): New. * config/iq2000/iq2000-protos.h: Update. * config/m32r/m32r.h (FUNCTION_ARG_PARTIAL_NREGS): Remove. * config/m32r/m32r.c (m32r_arg_partial_bytes): Rename from function_arg_partial_nregs. Adjust to return bytes. (TARGET_ARG_PARTIAL_BYTES): New. * config/m32r/m32r-protos.h: Update. * config/mcore/mcore.h (FUNCTION_ARG_PARTIAL_NREGS): Remove. * config/mcore/mcore.c (mcore_arg_partial_bytes): Rename from mcore_function_arg_partial_nregs. Adjust to return bytes. (TARGET_ARG_PARTIAL_BYTES): New. * config/mcore/mcore-protos.h: Update. * config/mips/mips.h (FUNCTION_ARG_PARTIAL_NREGS): Remove. * config/mips/mips.c (mips_arg_partial_bytes): Rename from function_arg_partial_nregs. Adjust to return bytes. (TARGET_ARG_PARTIAL_BYTES): New. * config/mips/mips-protos.h: Update. * config/mn10300/mn10300.h (FUNCTION_ARG_PARTIAL_NREGS): Remove. * config/mn10300/mn10300.c (mn10300_arg_partial_bytes): Rename from function_arg_partial_nregs. Adjust to return bytes. (TARGET_ARG_PARTIAL_BYTES): New. * config/mn10300/mn10300-protos.h: Update. * config/ns32k/ns32k.h (FUNCTION_ARG_PARTIAL_NREGS): Move ... * config/ns32k/ns32k.c (ns32k_arg_partial_bytes): ... here. (TARGET_ARG_PARTIAL_BYTES): New. * config/pa/pa.h (FUNCTION_ARG_PARTIAL_NREGS): Remove. * config/pa/pa.c (pa_arg_partial_bytes): Rename from function_arg_partial_nregs. Handle 32-bit. Adjust to return bytes. (TARGET_ARG_PARTIAL_BYTES): New. * config/pa/pa-protos.h: Update. * config/rs6000/rs6000.h (FUNCTION_ARG_PARTIAL_NREGS): Remove. * config/rs6000/rs6000.c (rs6000_arg_partial_bytes): Rename from function_arg_partial_nregs. Adjust to return bytes. (TARGET_ARG_PARTIAL_BYTES): New. * config/rs6000/rs6000-protos.h: Update. * config/sh/sh.h (FUNCTION_ARG_PARTIAL_NREGS): Move ... * config/sh/sh.c (sh_arg_partial_bytes): ... here. (TARGET_ARG_PARTIAL_BYTES): New. * config/sparc/sparc.h (FUNCTION_ARG_PARTIAL_NREGS): Remove. * config/sparc/sparc.c (sparc_arg_partial_bytes): Rename from function_arg_partial_nregs. Adjust to return bytes. (TARGET_ARG_PARTIAL_BYTES): New. * config/sparc/sparc-protos.h: Update. * config/v850/v850.h (FUNCTION_ARG_PARTIAL_NREGS): Remove. * config/v850/v850.c (v850_arg_partial_bytes): Rename from function_arg_partial_nregs. Adjust to return bytes. (TARGET_ARG_PARTIAL_BYTES): New. * config/v850/v850-protos.h: Update. From-SVN: r92726
This commit is contained in:
parent
86cdac1133
commit
78a52f1158
69 changed files with 464 additions and 424 deletions
120
gcc/ChangeLog
120
gcc/ChangeLog
|
@ -1,3 +1,123 @@
|
|||
2004-12-29 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* target.h (targetm.calls.arg_partial_bytes): New.
|
||||
* target-def.h (TARGET_ARG_PARTIAL_BYTES): New.
|
||||
* calls.c (store_unaligned_arguments_into_pseudos): Update for
|
||||
partial in bytes.
|
||||
(load_register_parameters): Likewise.
|
||||
(store_one_arg): Likewise.
|
||||
(initialize_argument_information): Use targetm.calls.arg_partial_bytes.
|
||||
(emit_library_call_value_1): Likewise.
|
||||
* expr.c (block_move_libcall_safe_for_call_parm): Likewise.
|
||||
(emit_push_insn): Update for partial in bytes.
|
||||
* expr.h (FUNCTION_ARG_PARTIAL_NREGS): Remove.
|
||||
* function.c (assign_parm_find_entry_rtl): Use
|
||||
targetm.calls.arg_partial_bytes. Update for result in bytes.
|
||||
(locate_and_pad_parm): Update for partial in bytes.
|
||||
* system.h (FUNCTION_ARG_PARTIAL_NREGS): Poison.
|
||||
* targhooks.c (hook_int_CUMULATIVE_ARGS_mode_tree_bool_0): New.
|
||||
* targhooks.h (hook_int_CUMULATIVE_ARGS_mode_tree_bool_0): Declare.
|
||||
* doc/tm.texi (TARGET_ARG_PARTIAL_BYTES): Rename and update from
|
||||
FUNCTION_ARG_PARTIAL_NREGS.
|
||||
|
||||
* config/arc/arc.h, config/c4x/c4x.h, config/i386/i386.h,
|
||||
config/i860/i860.h, config/m68hc11/m68hc11.h, config/m68k/m68k.h,
|
||||
config/pdp11/pdp11.h, config/s390/s390.h, config/stormy16/stormy16.h,
|
||||
config/xtensa/xtensa.h (FUNCTION_ARG_PARTIAL_NREGS): Remove.
|
||||
|
||||
* config/alpha/alpha.c (alpha_arg_partial_bytes): New.
|
||||
(TARGET_ARG_PARTIAL_BYTES): New.
|
||||
* config/alpha/alpha.h, config/alpha/unicosmk.h,
|
||||
config/alpha/vms.h (FUNCTION_ARG_PARTIAL_NREGS): Remove.
|
||||
|
||||
* config/arm/arm.h (FUNCTION_ARG_PARTIAL_NREGS): Move ...
|
||||
* config/arm/arm.c (arm_arg_partial_bytes): ... here.
|
||||
(TARGET_ARG_PARTIAL_BYTES): New.
|
||||
|
||||
* config/cris/cris.h (FUNCTION_ARG_PARTIAL_NREGS): Move ...
|
||||
* config/cris/cris.c (cris_arg_partial_bytes): ... here.
|
||||
(TARGET_ARG_PARTIAL_BYTES): New.
|
||||
|
||||
* config/fr30/fr30.h (FUNCTION_ARG_PARTIAL_NREGS): Remove.
|
||||
* config/fr30/fr30.c (fr30_arg_partial_bytes): Rename from
|
||||
fr30_function_arg_partial_nregs. Adjust to return bytes.
|
||||
(TARGET_ARG_PARTIAL_BYTES): New.
|
||||
* config/fr30/fr30-protos.h: Update.
|
||||
|
||||
* config/frv/frv.h (FUNCTION_ARG_PARTIAL_NREGS): Remove.
|
||||
* config/frv/frv.c (frv_arg_partial_bytes): Rename from
|
||||
frv_function_arg_partial_nregs. Adjust to return bytes.
|
||||
(TARGET_ARG_PARTIAL_BYTES): New.
|
||||
* config/frv/frv-protos.h: Update.
|
||||
|
||||
* config/ia64/ia64.h (FUNCTION_ARG_PARTIAL_NREGS): Remove.
|
||||
* config/ia64/ia64.c (ia64_arg_partial_bytes): Rename from
|
||||
ia64_function_arg_partial_nregs. Adjust to return bytes.
|
||||
(TARGET_ARG_PARTIAL_BYTES): New.
|
||||
* config/ia64/ia64-protos.h: Update.
|
||||
|
||||
* config/iq2000/iq2000.h (FUNCTION_ARG_PARTIAL_NREGS): Remove.
|
||||
* config/iq2000/iq2000.c (iq2000_arg_partial_bytes): Rename from
|
||||
function_arg_partial_nregs. Adjust to return bytes.
|
||||
(TARGET_ARG_PARTIAL_BYTES): New.
|
||||
* config/iq2000/iq2000-protos.h: Update.
|
||||
|
||||
* config/m32r/m32r.h (FUNCTION_ARG_PARTIAL_NREGS): Remove.
|
||||
* config/m32r/m32r.c (m32r_arg_partial_bytes): Rename from
|
||||
function_arg_partial_nregs. Adjust to return bytes.
|
||||
(TARGET_ARG_PARTIAL_BYTES): New.
|
||||
* config/m32r/m32r-protos.h: Update.
|
||||
|
||||
* config/mcore/mcore.h (FUNCTION_ARG_PARTIAL_NREGS): Remove.
|
||||
* config/mcore/mcore.c (mcore_arg_partial_bytes): Rename from
|
||||
mcore_function_arg_partial_nregs. Adjust to return bytes.
|
||||
(TARGET_ARG_PARTIAL_BYTES): New.
|
||||
* config/mcore/mcore-protos.h: Update.
|
||||
|
||||
* config/mips/mips.h (FUNCTION_ARG_PARTIAL_NREGS): Remove.
|
||||
* config/mips/mips.c (mips_arg_partial_bytes): Rename from
|
||||
function_arg_partial_nregs. Adjust to return bytes.
|
||||
(TARGET_ARG_PARTIAL_BYTES): New.
|
||||
* config/mips/mips-protos.h: Update.
|
||||
|
||||
* config/mn10300/mn10300.h (FUNCTION_ARG_PARTIAL_NREGS): Remove.
|
||||
* config/mn10300/mn10300.c (mn10300_arg_partial_bytes): Rename from
|
||||
function_arg_partial_nregs. Adjust to return bytes.
|
||||
(TARGET_ARG_PARTIAL_BYTES): New.
|
||||
* config/mn10300/mn10300-protos.h: Update.
|
||||
|
||||
* config/ns32k/ns32k.h (FUNCTION_ARG_PARTIAL_NREGS): Move ...
|
||||
* config/ns32k/ns32k.c (ns32k_arg_partial_bytes): ... here.
|
||||
(TARGET_ARG_PARTIAL_BYTES): New.
|
||||
|
||||
* config/pa/pa.h (FUNCTION_ARG_PARTIAL_NREGS): Remove.
|
||||
* config/pa/pa.c (pa_arg_partial_bytes): Rename from
|
||||
function_arg_partial_nregs. Handle 32-bit. Adjust to return bytes.
|
||||
(TARGET_ARG_PARTIAL_BYTES): New.
|
||||
* config/pa/pa-protos.h: Update.
|
||||
|
||||
* config/rs6000/rs6000.h (FUNCTION_ARG_PARTIAL_NREGS): Remove.
|
||||
* config/rs6000/rs6000.c (rs6000_arg_partial_bytes): Rename from
|
||||
function_arg_partial_nregs. Adjust to return bytes.
|
||||
(TARGET_ARG_PARTIAL_BYTES): New.
|
||||
* config/rs6000/rs6000-protos.h: Update.
|
||||
|
||||
* config/sh/sh.h (FUNCTION_ARG_PARTIAL_NREGS): Move ...
|
||||
* config/sh/sh.c (sh_arg_partial_bytes): ... here.
|
||||
(TARGET_ARG_PARTIAL_BYTES): New.
|
||||
|
||||
* config/sparc/sparc.h (FUNCTION_ARG_PARTIAL_NREGS): Remove.
|
||||
* config/sparc/sparc.c (sparc_arg_partial_bytes): Rename from
|
||||
function_arg_partial_nregs. Adjust to return bytes.
|
||||
(TARGET_ARG_PARTIAL_BYTES): New.
|
||||
* config/sparc/sparc-protos.h: Update.
|
||||
|
||||
* config/v850/v850.h (FUNCTION_ARG_PARTIAL_NREGS): Remove.
|
||||
* config/v850/v850.c (v850_arg_partial_bytes): Rename from
|
||||
function_arg_partial_nregs. Adjust to return bytes.
|
||||
(TARGET_ARG_PARTIAL_BYTES): New.
|
||||
* config/v850/v850-protos.h: Update.
|
||||
|
||||
2004-12-30 Hans-Peter Nilsson <hp@bitrange.com>
|
||||
|
||||
* config/mmix/mmix.h (ASM_OUTPUT_INTERNAL_LABEL): Define.
|
||||
|
|
54
gcc/calls.c
54
gcc/calls.c
|
@ -832,10 +832,19 @@ store_unaligned_arguments_into_pseudos (struct arg_data *args, int num_actuals)
|
|||
< (unsigned int) MIN (BIGGEST_ALIGNMENT, BITS_PER_WORD)))
|
||||
{
|
||||
int bytes = int_size_in_bytes (TREE_TYPE (args[i].tree_value));
|
||||
int nregs = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
|
||||
int endian_correction = 0;
|
||||
|
||||
args[i].n_aligned_regs = args[i].partial ? args[i].partial : nregs;
|
||||
if (args[i].partial)
|
||||
{
|
||||
gcc_assert (args[i].partial % UNITS_PER_WORD == 0);
|
||||
args[i].n_aligned_regs = args[i].partial / UNITS_PER_WORD;
|
||||
}
|
||||
else
|
||||
{
|
||||
args[i].n_aligned_regs
|
||||
= (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
|
||||
}
|
||||
|
||||
args[i].aligned_regs = xmalloc (sizeof (rtx) * args[i].n_aligned_regs);
|
||||
|
||||
/* Structures smaller than a word are normally aligned to the
|
||||
|
@ -973,7 +982,7 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED,
|
|||
args[i].reg is nonzero if all or part is passed in registers.
|
||||
|
||||
args[i].partial is nonzero if part but not all is passed in registers,
|
||||
and the exact value says how many words are passed in registers.
|
||||
and the exact value says how many bytes are passed in registers.
|
||||
|
||||
args[i].pass_on_stack is nonzero if the argument must at least be
|
||||
computed on the stack. It may then be loaded back into registers
|
||||
|
@ -1079,8 +1088,8 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED,
|
|||
|
||||
if (args[i].reg)
|
||||
args[i].partial
|
||||
= FUNCTION_ARG_PARTIAL_NREGS (*args_so_far, mode, type,
|
||||
argpos < n_named_args);
|
||||
= targetm.calls.arg_partial_bytes (args_so_far, mode, type,
|
||||
argpos < n_named_args);
|
||||
|
||||
args[i].pass_on_stack = targetm.calls.must_pass_in_stack (mode, type);
|
||||
|
||||
|
@ -1454,8 +1463,13 @@ load_register_parameters (struct arg_data *args, int num_actuals,
|
|||
we just use a normal move insn. This value can be zero if the
|
||||
argument is a zero size structure with no fields. */
|
||||
nregs = -1;
|
||||
if (partial)
|
||||
nregs = partial;
|
||||
if (GET_CODE (reg) == PARALLEL)
|
||||
;
|
||||
else if (partial)
|
||||
{
|
||||
gcc_assert (partial % UNITS_PER_WORD == 0);
|
||||
nregs = partial / UNITS_PER_WORD;
|
||||
}
|
||||
else if (TYPE_MODE (TREE_TYPE (args[i].tree_value)) == BLKmode)
|
||||
{
|
||||
size = int_size_in_bytes (TREE_TYPE (args[i].tree_value));
|
||||
|
@ -3286,7 +3300,6 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
|
|||
if (mem_value && struct_value == 0 && ! pcc_struct_value)
|
||||
{
|
||||
rtx addr = XEXP (mem_value, 0);
|
||||
int partial;
|
||||
|
||||
nargs++;
|
||||
|
||||
|
@ -3300,8 +3313,8 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
|
|||
argvec[count].partial = 0;
|
||||
|
||||
argvec[count].reg = FUNCTION_ARG (args_so_far, Pmode, NULL_TREE, 1);
|
||||
partial = FUNCTION_ARG_PARTIAL_NREGS (args_so_far, Pmode, NULL_TREE, 1);
|
||||
gcc_assert (!partial);
|
||||
gcc_assert (targetm.calls.arg_partial_bytes (&args_so_far, Pmode,
|
||||
NULL_TREE, 1) == 0);
|
||||
|
||||
locate_and_pad_parm (Pmode, NULL_TREE,
|
||||
#ifdef STACK_PARMS_IN_REG_PARM_AREA
|
||||
|
@ -3387,7 +3400,7 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
|
|||
argvec[count].reg = FUNCTION_ARG (args_so_far, mode, NULL_TREE, 1);
|
||||
|
||||
argvec[count].partial
|
||||
= FUNCTION_ARG_PARTIAL_NREGS (args_so_far, mode, NULL_TREE, 1);
|
||||
= targetm.calls.arg_partial_bytes (&args_so_far, mode, NULL_TREE, 1);
|
||||
|
||||
locate_and_pad_parm (mode, NULL_TREE,
|
||||
#ifdef STACK_PARMS_IN_REG_PARM_AREA
|
||||
|
@ -4097,20 +4110,11 @@ store_one_arg (struct arg_data *arg, rtx argblock, int flags,
|
|||
}
|
||||
else
|
||||
{
|
||||
/* PUSH_ROUNDING has no effect on us, because
|
||||
emit_push_insn for BLKmode is careful to avoid it. */
|
||||
if (reg && GET_CODE (reg) == PARALLEL)
|
||||
{
|
||||
/* Use the size of the elt to compute excess. */
|
||||
rtx elt = XEXP (XVECEXP (reg, 0, 0), 0);
|
||||
excess = (arg->locate.size.constant
|
||||
- int_size_in_bytes (TREE_TYPE (pval))
|
||||
+ partial * GET_MODE_SIZE (GET_MODE (elt)));
|
||||
}
|
||||
else
|
||||
excess = (arg->locate.size.constant
|
||||
- int_size_in_bytes (TREE_TYPE (pval))
|
||||
+ partial * UNITS_PER_WORD);
|
||||
/* PUSH_ROUNDING has no effect on us, because emit_push_insn
|
||||
for BLKmode is careful to avoid it. */
|
||||
excess = (arg->locate.size.constant
|
||||
- int_size_in_bytes (TREE_TYPE (pval))
|
||||
+ partial);
|
||||
size_rtx = expand_expr (size_in_bytes (TREE_TYPE (pval)),
|
||||
NULL_RTX, TYPE_MODE (sizetype), 0);
|
||||
}
|
||||
|
|
|
@ -5190,6 +5190,31 @@ function_arg (CUMULATIVE_ARGS cum, enum machine_mode mode, tree type,
|
|||
return gen_rtx_REG (mode, num_args + basereg);
|
||||
}
|
||||
|
||||
static int
|
||||
alpha_arg_partial_bytes (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
|
||||
enum machine_mode mode ATTRIBUTE_UNUSED,
|
||||
tree type ATTRIBUTE_UNUSED,
|
||||
bool named ATTRIBUTE_UNUSED)
|
||||
{
|
||||
int words = 0;
|
||||
|
||||
#if TARGET_ABI_OPEN_VMS
|
||||
if (cum->num_args < 6
|
||||
&& 6 < cum->num_args + ALPHA_ARG_SIZE (mode, type, named))
|
||||
words = 6 - (CUM).num_args;
|
||||
#elif TARGET_ABI_UNICOSMK
|
||||
/* Never any split arguments. */
|
||||
#elif TARGET_ABI_OSF
|
||||
if (*cum < 6 && 6 < *cum + ALPHA_ARG_SIZE (mode, type, named))
|
||||
words = 6 - *cum;
|
||||
#else
|
||||
#error Unhandled ABI
|
||||
#endif
|
||||
|
||||
return words * UNITS_PER_WORD;
|
||||
}
|
||||
|
||||
|
||||
/* Return true if TYPE must be returned in memory, instead of in registers. */
|
||||
|
||||
static bool
|
||||
|
@ -9453,6 +9478,8 @@ alpha_init_libfuncs (void)
|
|||
#define TARGET_SPLIT_COMPLEX_ARG alpha_split_complex_arg
|
||||
#undef TARGET_GIMPLIFY_VA_ARG_EXPR
|
||||
#define TARGET_GIMPLIFY_VA_ARG_EXPR alpha_gimplify_va_arg
|
||||
#undef TARGET_ARG_PARTIAL_BYTES
|
||||
#define TARGET_ARG_PARTIAL_BYTES alpha_arg_partial_bytes
|
||||
|
||||
#undef TARGET_SCALAR_MODE_SUPPORTED_P
|
||||
#define TARGET_SCALAR_MODE_SUPPORTED_P alpha_scalar_mode_supported_p
|
||||
|
|
|
@ -1067,14 +1067,6 @@ extern int alpha_memory_latency;
|
|||
#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
|
||||
function_arg((CUM), (MODE), (TYPE), (NAMED))
|
||||
|
||||
/* For an arg passed partly in registers and partly in memory,
|
||||
this is the number of registers used.
|
||||
For args passed entirely in registers or entirely in memory, zero. */
|
||||
|
||||
#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
|
||||
((CUM) < 6 && 6 < (CUM) + ALPHA_ARG_SIZE (MODE, TYPE, NAMED) \
|
||||
? 6 - (CUM) : 0)
|
||||
|
||||
/* Try to output insns to set TARGET equal to the constant C if it can be
|
||||
done in less than N insns. Do all computations in MODE. Returns the place
|
||||
where the output has been placed if it can be done and the insns have been
|
||||
|
|
|
@ -210,11 +210,6 @@ do { \
|
|||
++(CUM).num_args; \
|
||||
} while(0)
|
||||
|
||||
/* An argument is passed either entirely in registers or entirely on stack. */
|
||||
|
||||
#undef FUNCTION_ARG_PARTIAL_NREGS
|
||||
/* #define FUNCTION_ARG_PARTIAL_NREGS(CUM,MODE,TYPE,NAMED) 0 */
|
||||
|
||||
/* This ensures that $15 increments/decrements in leaf functions won't get
|
||||
eliminated. */
|
||||
|
||||
|
|
|
@ -189,16 +189,6 @@ typedef struct {int num_args; enum avms_arg_type atypes[6];} avms_arg_info;
|
|||
(CUM).num_args += ALPHA_ARG_SIZE (MODE, TYPE, NAMED); \
|
||||
}
|
||||
|
||||
/* For an arg passed partly in registers and partly in memory,
|
||||
this is the number of registers used.
|
||||
For args passed entirely in registers or entirely in memory, zero. */
|
||||
|
||||
#undef FUNCTION_ARG_PARTIAL_NREGS
|
||||
#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
|
||||
((CUM).num_args < 6 && 6 < (CUM).num_args \
|
||||
+ ALPHA_ARG_SIZE (MODE, TYPE, NAMED) \
|
||||
? 6 - (CUM).num_args : 0)
|
||||
|
||||
/* ABI has stack checking, but it's broken. */
|
||||
#undef STACK_CHECK_BUILTIN
|
||||
#define STACK_CHECK_BUILTIN 0
|
||||
|
|
|
@ -681,21 +681,6 @@ extern enum reg_class arc_regno_reg_class[FIRST_PSEUDO_REGISTER];
|
|||
? gen_rtx_REG ((MODE), ROUND_ADVANCE_CUM ((CUM), (MODE), (TYPE))) \
|
||||
: 0)
|
||||
|
||||
/* 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 @var{n} words of arguments are passed in registers, and the rest
|
||||
on the stack. If a multi-word argument (a @code{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. */
|
||||
#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) 0
|
||||
|
||||
/* Update the data in CUM to advance over an argument
|
||||
of mode MODE and data type TYPE.
|
||||
(TYPE is null for libcalls where that information may not be available.) */
|
||||
|
|
|
@ -147,6 +147,8 @@ static rtx arm_expand_binop_builtin (enum insn_code, tree, rtx);
|
|||
static rtx arm_expand_unop_builtin (enum insn_code, tree, rtx, int);
|
||||
static rtx arm_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
|
||||
static void emit_constant_insn (rtx cond, rtx pattern);
|
||||
static int arm_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
|
||||
tree, bool);
|
||||
|
||||
#ifndef ARM_PE
|
||||
static void arm_encode_section_info (tree, rtx, int);
|
||||
|
@ -272,6 +274,8 @@ static unsigned HOST_WIDE_INT arm_shift_truncation_mask (enum machine_mode);
|
|||
#define TARGET_PROMOTE_PROTOTYPES arm_promote_prototypes
|
||||
#undef TARGET_PASS_BY_REFERENCE
|
||||
#define TARGET_PASS_BY_REFERENCE arm_pass_by_reference
|
||||
#undef TARGET_ARG_PARTIAL_BYTES
|
||||
#define TARGET_ARG_PARTIAL_BYTES arm_arg_partial_bytes
|
||||
|
||||
#undef TARGET_STRUCT_VALUE_RTX
|
||||
#define TARGET_STRUCT_VALUE_RTX arm_struct_value_rtx
|
||||
|
@ -2527,6 +2531,23 @@ arm_function_arg (CUMULATIVE_ARGS *pcum, enum machine_mode mode,
|
|||
return gen_rtx_REG (mode, pcum->nregs);
|
||||
}
|
||||
|
||||
static int
|
||||
arm_arg_partial_bytes (CUMULATIVE_ARGS *pcum, enum machine_mode mode,
|
||||
tree type, bool named ATTRIBUTE_UNUSED)
|
||||
{
|
||||
int nregs = pcum->nregs;
|
||||
|
||||
if (arm_vector_mode_supported_p (mode))
|
||||
return 0;
|
||||
|
||||
if (NUM_ARG_REGS > nregs
|
||||
&& (NUM_ARG_REGS < nregs + ARM_NUM_REGS2 (mode, type))
|
||||
&& pcum->can_split)
|
||||
return (NUM_ARG_REGS - nregs) * UNITS_PER_WORD;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Variable sized types are passed by reference. This is a GCC
|
||||
extension to the ARM ABI. */
|
||||
|
||||
|
|
|
@ -1743,16 +1743,6 @@ typedef struct
|
|||
#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
|
||||
arm_function_arg (&(CUM), (MODE), (TYPE), (NAMED))
|
||||
|
||||
/* For an arg passed partly in registers and partly in memory,
|
||||
this is the number of registers used.
|
||||
For args passed entirely in registers or entirely in memory, zero. */
|
||||
#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
|
||||
(arm_vector_mode_supported_p (MODE) ? 0 : \
|
||||
NUM_ARG_REGS > (CUM).nregs \
|
||||
&& (NUM_ARG_REGS < ((CUM).nregs + ARM_NUM_REGS2 (MODE, TYPE)) \
|
||||
&& (CUM).can_split) \
|
||||
? NUM_ARG_REGS - (CUM).nregs : 0)
|
||||
|
||||
/* Initialize a variable CUM of type CUMULATIVE_ARGS
|
||||
for a call to a function whose data type is FNTYPE.
|
||||
For a library call, FNTYPE is 0.
|
||||
|
|
|
@ -1128,8 +1128,6 @@ CUMULATIVE_ARGS;
|
|||
|
||||
#define CALLER_SAVE_PROFITABLE(REFS,CALLS) 0
|
||||
|
||||
#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) 0
|
||||
|
||||
/* 1 if N is a possible register number for function argument passing. */
|
||||
|
||||
#define FUNCTION_ARG_REGNO_P(REGNO) \
|
||||
|
|
|
@ -117,6 +117,8 @@ static bool cris_rtx_costs (rtx, int, int, int *);
|
|||
static int cris_address_cost (rtx);
|
||||
static bool cris_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
|
||||
tree, bool);
|
||||
static int cris_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
|
||||
tree, bool);
|
||||
|
||||
/* The function cris_target_asm_function_epilogue puts the last insn to
|
||||
output here. It always fits; there won't be a symbol operand. Used in
|
||||
|
@ -191,6 +193,8 @@ int cris_cpu_version = CRIS_DEFAULT_CPU_VERSION;
|
|||
#define TARGET_SETUP_INCOMING_VARARGS cris_setup_incoming_varargs
|
||||
#undef TARGET_PASS_BY_REFERENCE
|
||||
#define TARGET_PASS_BY_REFERENCE cris_pass_by_reference
|
||||
#undef TARGET_ARG_PARTIAL_BYTES
|
||||
#define TARGET_ARG_PARTIAL_BYTES cris_arg_partial_bytes
|
||||
|
||||
struct gcc_target targetm = TARGET_INITIALIZER;
|
||||
|
||||
|
@ -3184,6 +3188,20 @@ cris_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
|
|||
}
|
||||
|
||||
|
||||
static int
|
||||
cris_arg_partial_bytes (CUMULATIVE_ARGS *ca, enum machine_mode mode,
|
||||
tree type, bool named ATTRIBUTE_UNUSED)
|
||||
{
|
||||
if (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)
|
||||
return UNITS_PER_WORD;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
/* Various small functions to replace macros. Only called from a
|
||||
debugger. They might collide with gcc functions or system functions,
|
||||
|
|
|
@ -953,13 +953,6 @@ enum reg_class {NO_REGS, ALL_REGS, LIM_REG_CLASSES};
|
|||
? gen_rtx_REG (MODE, CRIS_FIRST_ARG_REG + (CUM).regs) \
|
||||
: NULL_RTX)
|
||||
|
||||
#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
|
||||
(((CUM).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) \
|
||||
? 1 : 0)
|
||||
|
||||
/* Contrary to what you'd believe, defining FUNCTION_ARG_CALLEE_COPIES
|
||||
seems like a (small total) loss, at least for gcc-2.7.2 compiling and
|
||||
running gcc-2.1 (small win in size, small loss running -- 100.1%),
|
||||
|
|
|
@ -29,8 +29,6 @@ extern void fr30_print_operand_address (FILE *, rtx);
|
|||
extern rtx fr30_move_double (rtx *);
|
||||
#ifdef TREE_CODE
|
||||
extern int fr30_num_arg_regs (enum machine_mode, tree);
|
||||
extern int fr30_function_arg_partial_nregs (CUMULATIVE_ARGS,
|
||||
enum machine_mode, tree, int);
|
||||
#endif /* TREE_CODE */
|
||||
#ifdef HAVE_MACHINE_MODES
|
||||
#define Mmode enum machine_mode
|
||||
|
|
|
@ -124,6 +124,9 @@ static struct fr30_frame_info zero_frame_info;
|
|||
static void fr30_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode,
|
||||
tree, int *, int);
|
||||
static bool fr30_must_pass_in_stack (enum machine_mode, tree);
|
||||
static int fr30_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
|
||||
tree, bool);
|
||||
|
||||
|
||||
#define FRAME_POINTER_MASK (1 << (FRAME_POINTER_REGNUM))
|
||||
#define RETURN_POINTER_MASK (1 << (RETURN_POINTER_REGNUM))
|
||||
|
@ -154,6 +157,8 @@ static bool fr30_must_pass_in_stack (enum machine_mode, tree);
|
|||
#define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_true
|
||||
#undef TARGET_PASS_BY_REFERENCE
|
||||
#define TARGET_PASS_BY_REFERENCE hook_pass_by_reference_must_pass_in_stack
|
||||
#undef TARGET_ARG_PARTIAL_BYTES
|
||||
#define TARGET_ARG_PARTIAL_BYTES fr30_arg_partial_bytes
|
||||
|
||||
#undef TARGET_SETUP_INCOMING_VARARGS
|
||||
#define TARGET_SETUP_INCOMING_VARARGS fr30_setup_incoming_varargs
|
||||
|
@ -697,22 +702,21 @@ fr30_num_arg_regs (enum machine_mode mode, tree type)
|
|||
return (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
|
||||
}
|
||||
|
||||
/* Implements the FUNCTION_ARG_PARTIAL_NREGS macro.
|
||||
Returns the number of argument registers required to hold *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.
|
||||
/* 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. */
|
||||
|
||||
int
|
||||
fr30_function_arg_partial_nregs (CUMULATIVE_ARGS cum, enum machine_mode mode,
|
||||
tree type, int named)
|
||||
static int
|
||||
fr30_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
||||
tree type, bool named)
|
||||
{
|
||||
/* 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 (named == 0 || *cum >= FR30_NUM_ARG_REGS)
|
||||
return 0;
|
||||
|
||||
/* Work out how many argument registers would be needed if this
|
||||
|
@ -721,11 +725,10 @@ fr30_function_arg_partial_nregs (CUMULATIVE_ARGS cum, enum 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 (mode, type) <= FR30_NUM_ARG_REGS)
|
||||
return 0;
|
||||
|
||||
/* Otherwise return the number of registers that would be used. */
|
||||
return FR30_NUM_ARG_REGS - cum;
|
||||
return (FR30_NUM_ARG_REGS - *cum) * UNITS_PER_WORD;
|
||||
}
|
||||
|
||||
/*}}}*/
|
||||
|
|
|
@ -676,24 +676,6 @@ enum reg_class
|
|||
the number of bytes of argument accumulated so far. */
|
||||
#define CUMULATIVE_ARGS int
|
||||
|
||||
/* 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. */
|
||||
#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
|
||||
fr30_function_arg_partial_nregs (CUM, MODE, TYPE, NAMED)
|
||||
|
||||
/* A C statement (sans semicolon) for initializing the variable CUM for the
|
||||
state at the beginning of the argument list. The variable has type
|
||||
`CUMULATIVE_ARGS'. The value of FNTYPE is the tree node for the data type
|
||||
|
|
|
@ -84,10 +84,6 @@ extern void frv_function_arg_advance (CUMULATIVE_ARGS *,
|
|||
enum machine_mode,
|
||||
tree, int);
|
||||
|
||||
extern int frv_function_arg_partial_nregs (CUMULATIVE_ARGS *,
|
||||
enum machine_mode,
|
||||
tree, int);
|
||||
|
||||
extern void frv_expand_builtin_va_start (tree, rtx);
|
||||
#endif /* TREE_CODE */
|
||||
|
||||
|
|
|
@ -376,6 +376,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 (enum machine_mode mode, tree type);
|
||||
static int frv_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
|
||||
tree, bool);
|
||||
|
||||
/* Initialize the GCC target structure. */
|
||||
#undef TARGET_ASM_FUNCTION_PROLOGUE
|
||||
|
@ -418,6 +420,8 @@ static bool frv_must_pass_in_stack (enum machine_mode mode, tree type);
|
|||
#define TARGET_MUST_PASS_IN_STACK frv_must_pass_in_stack
|
||||
#undef TARGET_PASS_BY_REFERENCE
|
||||
#define TARGET_PASS_BY_REFERENCE hook_pass_by_reference_must_pass_in_stack
|
||||
#undef TARGET_ARG_PARTIAL_BYTES
|
||||
#define TARGET_ARG_PARTIAL_BYTES frv_arg_partial_bytes
|
||||
|
||||
#undef TARGET_EXPAND_BUILTIN_SAVEREGS
|
||||
#define TARGET_EXPAND_BUILTIN_SAVEREGS frv_expand_builtin_saveregs
|
||||
|
@ -3192,11 +3196,9 @@ frv_function_arg_advance (CUMULATIVE_ARGS *cum,
|
|||
used by the caller for this argument; likewise `FUNCTION_INCOMING_ARG', for
|
||||
the called function. */
|
||||
|
||||
int
|
||||
frv_function_arg_partial_nregs (CUMULATIVE_ARGS *cum,
|
||||
enum machine_mode mode,
|
||||
tree type ATTRIBUTE_UNUSED,
|
||||
int named ATTRIBUTE_UNUSED)
|
||||
static int
|
||||
frv_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
||||
tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED)
|
||||
{
|
||||
enum machine_mode xmode = (mode == BLKmode) ? SImode : mode;
|
||||
int bytes = GET_MODE_SIZE (xmode);
|
||||
|
@ -3207,12 +3209,12 @@ frv_function_arg_partial_nregs (CUMULATIVE_ARGS *cum,
|
|||
ret = ((arg_num <= LAST_ARG_REGNUM && arg_num + words > LAST_ARG_REGNUM+1)
|
||||
? LAST_ARG_REGNUM - arg_num + 1
|
||||
: 0);
|
||||
ret *= UNITS_PER_WORD;
|
||||
|
||||
if (TARGET_DEBUG_ARG && ret)
|
||||
fprintf (stderr, "function_arg_partial_nregs: %d\n", ret);
|
||||
fprintf (stderr, "frv_arg_partial_bytes: %d\n", ret);
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1884,26 +1884,6 @@ struct machine_function GTY(())
|
|||
#define FUNCTION_INCOMING_ARG(CUM, MODE, TYPE, NAMED) \
|
||||
frv_function_arg (&CUM, MODE, TYPE, NAMED, TRUE)
|
||||
|
||||
/* 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. */
|
||||
#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
|
||||
frv_function_arg_partial_nregs (&CUM, MODE, TYPE, NAMED)
|
||||
|
||||
/* extern int frv_function_arg_partial_nregs (CUMULATIVE_ARGS, int, Tree, int); */
|
||||
|
||||
/* A C type for declaring a variable that is used as the first argument of
|
||||
`FUNCTION_ARG' and other related values. For some target machines, the type
|
||||
`int' suffices and can hold the number of bytes of argument so far.
|
||||
|
|
|
@ -1777,12 +1777,6 @@ typedef struct ix86_args {
|
|||
#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
|
||||
function_arg (&(CUM), (MODE), (TYPE), (NAMED))
|
||||
|
||||
/* For an arg passed partly in registers and partly in memory,
|
||||
this is the number of registers used.
|
||||
For args passed entirely in registers or entirely in memory, zero. */
|
||||
|
||||
#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) 0
|
||||
|
||||
/* Implement `va_start' for varargs and stdarg. */
|
||||
#define EXPAND_BUILTIN_VA_START(VALIST, NEXTARG) \
|
||||
ix86_va_start (VALIST, NEXTARG)
|
||||
|
|
|
@ -529,12 +529,6 @@ struct cumulative_args { int ints, floats; };
|
|||
: 0) \
|
||||
: 0)
|
||||
|
||||
/* For an arg passed partly in registers and partly in memory,
|
||||
this is the number of registers used.
|
||||
For args passed entirely in registers or entirely in memory, zero. */
|
||||
|
||||
#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) 0
|
||||
|
||||
/* If defined, a C expression that gives the alignment boundary, in
|
||||
bits, of an argument with the specified mode and type. If it is
|
||||
not defined, `PARM_BOUNDARY' is used for all arguments. */
|
||||
|
|
|
@ -73,8 +73,6 @@ extern rtx ia64_va_arg (tree, tree);
|
|||
extern rtx ia64_function_value (tree, tree);
|
||||
#endif /* RTX_CODE */
|
||||
|
||||
extern int ia64_function_arg_partial_nregs (CUMULATIVE_ARGS *,
|
||||
enum machine_mode, tree, int);
|
||||
extern void ia64_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode,
|
||||
tree, int);
|
||||
extern int ia64_function_arg_boundary (enum machine_mode, tree);
|
||||
|
|
|
@ -191,6 +191,8 @@ static void ia64_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode,
|
|||
tree, int *, int);
|
||||
static bool ia64_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
|
||||
tree, bool);
|
||||
static int ia64_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
|
||||
tree, bool);
|
||||
static bool ia64_function_ok_for_sibcall (tree, tree);
|
||||
static bool ia64_return_in_memory (tree, tree);
|
||||
static bool ia64_rtx_costs (rtx, int, int, int *);
|
||||
|
@ -362,6 +364,8 @@ static const struct attribute_spec ia64_attribute_table[] =
|
|||
#define TARGET_FUNCTION_OK_FOR_SIBCALL ia64_function_ok_for_sibcall
|
||||
#undef TARGET_PASS_BY_REFERENCE
|
||||
#define TARGET_PASS_BY_REFERENCE ia64_pass_by_reference
|
||||
#undef TARGET_ARG_PARTIAL_BYTES
|
||||
#define TARGET_ARG_PARTIAL_BYTES ia64_arg_partial_bytes
|
||||
|
||||
#undef TARGET_ASM_OUTPUT_MI_THUNK
|
||||
#define TARGET_ASM_OUTPUT_MI_THUNK ia64_output_mi_thunk
|
||||
|
@ -3250,13 +3254,13 @@ ia64_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
|
|||
}
|
||||
}
|
||||
|
||||
/* Return number of words, at the beginning of the argument, that must be
|
||||
/* Return number of bytes, at the beginning of the argument, that must be
|
||||
put in registers. 0 is the argument is entirely in registers or entirely
|
||||
in memory. */
|
||||
|
||||
int
|
||||
ia64_function_arg_partial_nregs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
||||
tree type, int named ATTRIBUTE_UNUSED)
|
||||
static int
|
||||
ia64_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
||||
tree type, bool named ATTRIBUTE_UNUSED)
|
||||
{
|
||||
int words = ia64_function_arg_words (type, mode);
|
||||
int offset = ia64_function_arg_offset (cum, type, words);
|
||||
|
@ -3273,7 +3277,7 @@ ia64_function_arg_partial_nregs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
|||
if (words + cum->words + offset <= MAX_ARGUMENT_SLOTS)
|
||||
return 0;
|
||||
|
||||
return MAX_ARGUMENT_SLOTS - cum->words - offset;
|
||||
return (MAX_ARGUMENT_SLOTS - cum->words - offset) * UNITS_PER_WORD;
|
||||
}
|
||||
|
||||
/* Update CUM to point after this argument. This is patterned after
|
||||
|
|
|
@ -1326,13 +1326,6 @@ enum reg_class
|
|||
#define FUNCTION_INCOMING_ARG(CUM, MODE, TYPE, NAMED) \
|
||||
ia64_function_arg (&CUM, MODE, TYPE, NAMED, 1)
|
||||
|
||||
/* 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. */
|
||||
|
||||
#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
|
||||
ia64_function_arg_partial_nregs (&CUM, MODE, TYPE, NAMED)
|
||||
|
||||
/* A C type for declaring a variable that is used as the first argument of
|
||||
`FUNCTION_ARG' and other related values. For some target machines, the type
|
||||
`int' suffices and can hold the number of bytes of argument so far. */
|
||||
|
|
|
@ -49,7 +49,6 @@ extern void gen_conditional_branch (rtx *, enum rtx_code);
|
|||
extern void init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx);
|
||||
extern void function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode, tree, int);
|
||||
extern struct rtx_def * function_arg (CUMULATIVE_ARGS *, enum machine_mode, tree, int);
|
||||
extern int function_arg_partial_nregs (CUMULATIVE_ARGS *, enum machine_mode, tree, int);
|
||||
extern void iq2000_va_start (tree, rtx);
|
||||
extern rtx iq2000_function_value (tree, tree);
|
||||
#endif
|
||||
|
|
|
@ -174,6 +174,8 @@ static void iq2000_select_section (tree, int, unsigned HOST_WIDE_INT);
|
|||
static bool iq2000_return_in_memory (tree, tree);
|
||||
static bool iq2000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
|
||||
tree, bool);
|
||||
static int iq2000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
|
||||
tree, bool);
|
||||
|
||||
#undef TARGET_INIT_BUILTINS
|
||||
#define TARGET_INIT_BUILTINS iq2000_init_builtins
|
||||
|
@ -201,6 +203,8 @@ static bool iq2000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
|
|||
#define TARGET_PASS_BY_REFERENCE iq2000_pass_by_reference
|
||||
#undef TARGET_CALLEE_COPIES
|
||||
#define TARGET_CALLEE_COPIES hook_callee_copies_named
|
||||
#undef TARGET_ARG_PARTIAL_BYTES
|
||||
#define TARGET_ARG_PARTIAL_BYTES iq2000_arg_partial_bytes
|
||||
|
||||
#undef TARGET_SETUP_INCOMING_VARARGS
|
||||
#define TARGET_SETUP_INCOMING_VARARGS iq2000_setup_incoming_varargs
|
||||
|
@ -1552,18 +1556,16 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
|
|||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
function_arg_partial_nregs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
||||
tree type ATTRIBUTE_UNUSED,
|
||||
int named ATTRIBUTE_UNUSED)
|
||||
static int
|
||||
iq2000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
||||
tree type ATTRIBUTE_UNUSED,
|
||||
bool named ATTRIBUTE_UNUSED)
|
||||
{
|
||||
if (mode == DImode
|
||||
&& cum->arg_words == MAX_ARGS_IN_REGISTERS - (unsigned)1)
|
||||
if (mode == DImode && cum->arg_words == MAX_ARGS_IN_REGISTERS - 1)
|
||||
{
|
||||
if (TARGET_DEBUG_D_MODE)
|
||||
fprintf (stderr, "function_arg_partial_nregs = 1\n");
|
||||
|
||||
return 1;
|
||||
fprintf (stderr, "iq2000_arg_partial_bytes=%d\n", UNITS_PER_WORD);
|
||||
return UNITS_PER_WORD;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -438,9 +438,6 @@ enum reg_class
|
|||
#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
|
||||
function_arg (& CUM, MODE, TYPE, NAMED)
|
||||
|
||||
#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
|
||||
function_arg_partial_nregs (& CUM, MODE, TYPE, NAMED)
|
||||
|
||||
#define MAX_ARGS_IN_REGISTERS 8
|
||||
|
||||
typedef struct iq2000_args
|
||||
|
|
|
@ -35,10 +35,6 @@ extern void m32r_load_pic_register (void);
|
|||
|
||||
#ifdef TREE_CODE
|
||||
extern enum m32r_function_type m32r_compute_function_type (tree);
|
||||
|
||||
#ifdef HAVE_MACHINE_MODES
|
||||
extern int function_arg_partial_nregs (CUMULATIVE_ARGS *, Mmode, tree, int);
|
||||
#endif
|
||||
#endif /* TREE_CODE */
|
||||
|
||||
#ifdef RTX_CODE
|
||||
|
|
|
@ -102,6 +102,8 @@ static void init_idents (void);
|
|||
static bool m32r_rtx_costs (rtx, int, int, int *);
|
||||
static bool m32r_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
|
||||
tree, bool);
|
||||
static int m32r_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
|
||||
tree, bool);
|
||||
|
||||
/* Initialize the GCC target structure. */
|
||||
#undef TARGET_ATTRIBUTE_TABLE
|
||||
|
@ -145,6 +147,8 @@ static bool m32r_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
|
|||
#define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
|
||||
#undef TARGET_PASS_BY_REFERENCE
|
||||
#define TARGET_PASS_BY_REFERENCE m32r_pass_by_reference
|
||||
#undef TARGET_ARG_PARTIAL_BYTES
|
||||
#define TARGET_ARG_PARTIAL_BYTES m32r_arg_partial_bytes
|
||||
|
||||
struct gcc_target targetm = TARGET_INITIALIZER;
|
||||
|
||||
|
@ -1321,13 +1325,11 @@ gen_split_move_double (rtx operands[])
|
|||
}
|
||||
|
||||
|
||||
/* Implements the FUNCTION_ARG_PARTIAL_NREGS macro. */
|
||||
|
||||
int
|
||||
function_arg_partial_nregs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
||||
tree type, int named ATTRIBUTE_UNUSED)
|
||||
static int
|
||||
m32r_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
||||
tree type, bool named ATTRIBUTE_UNUSED)
|
||||
{
|
||||
int ret;
|
||||
int words;
|
||||
unsigned int size =
|
||||
(((mode == BLKmode && type)
|
||||
? (unsigned int) int_size_in_bytes (type)
|
||||
|
@ -1335,13 +1337,13 @@ function_arg_partial_nregs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
|||
/ UNITS_PER_WORD;
|
||||
|
||||
if (*cum >= M32R_MAX_PARM_REGS)
|
||||
ret = 0;
|
||||
words = 0;
|
||||
else if (*cum + size > M32R_MAX_PARM_REGS)
|
||||
ret = (*cum + size) - M32R_MAX_PARM_REGS;
|
||||
words = (*cum + size) - M32R_MAX_PARM_REGS;
|
||||
else
|
||||
ret = 0;
|
||||
words = 0;
|
||||
|
||||
return ret;
|
||||
return words * UNITS_PER_WORD;
|
||||
}
|
||||
|
||||
/* Worker function for TARGET_RETURN_IN_MEMORY. */
|
||||
|
|
|
@ -1099,22 +1099,6 @@ extern enum reg_class m32r_regno_reg_class[FIRST_PSEUDO_REGISTER];
|
|||
? gen_rtx_REG ((MODE), ROUND_ADVANCE_CUM ((CUM), (MODE), (TYPE))) \
|
||||
: 0)
|
||||
|
||||
/* 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 @var{n} words of arguments are passed in registers, and the rest
|
||||
on the stack. If a multi-word argument (a @code{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. */
|
||||
#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
|
||||
function_arg_partial_nregs (&CUM, (int)MODE, TYPE, NAMED)
|
||||
|
||||
/* Update the data in CUM to advance over an argument
|
||||
of mode MODE and data type TYPE.
|
||||
(TYPE is null for libcalls where that information may not be available.) */
|
||||
|
|
|
@ -1083,14 +1083,6 @@ typedef struct m68hc11_args
|
|||
caller saving results in spill failure. */
|
||||
#define CALLER_SAVE_PROFITABLE(REFS,CALLS) 0
|
||||
|
||||
/* For an arg passed partly in registers and partly in memory,
|
||||
this is the number of registers used.
|
||||
For args passed entirely in registers or entirely in memory, zero.
|
||||
|
||||
Passing an arg partly in register and memory does not work at all.
|
||||
Don't do that. */
|
||||
#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) (0)
|
||||
|
||||
/* 1 if N is a possible register number for function argument passing.
|
||||
D is for 16-bit values, X is for 32-bit (X+D). */
|
||||
#define FUNCTION_ARG_REGNO_P(N) \
|
||||
|
|
|
@ -733,7 +733,6 @@ extern enum reg_class regno_reg_class[];
|
|||
|
||||
/* On the m68k all args are always pushed. */
|
||||
#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) 0
|
||||
#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) 0
|
||||
|
||||
#define FUNCTION_PROFILER(FILE, LABELNO) \
|
||||
asm_fprintf (FILE, "\tlea %LLP%d,%Ra0\n\tjsr mcount\n", (LABELNO))
|
||||
|
|
|
@ -36,7 +36,6 @@ extern int mcore_naked_function_p (void);
|
|||
|
||||
#ifdef TREE_CODE
|
||||
#ifdef HAVE_MACHINE_MODES
|
||||
extern int mcore_function_arg_partial_nregs (CUMULATIVE_ARGS, enum machine_mode, tree, int);
|
||||
extern int mcore_num_arg_regs (enum machine_mode, tree);
|
||||
#endif /* HAVE_MACHINE_MODES */
|
||||
|
||||
|
|
|
@ -149,6 +149,9 @@ static int mcore_ior_cost (rtx);
|
|||
static bool mcore_rtx_costs (rtx, int, int, int *);
|
||||
static void mcore_external_libcall (rtx);
|
||||
static bool mcore_return_in_memory (tree, tree);
|
||||
static int mcore_arg_partial_bytes (CUMULATIVE_ARGS *,
|
||||
enum machine_mode,
|
||||
tree, bool);
|
||||
|
||||
|
||||
/* Initialize the GCC target structure. */
|
||||
|
@ -197,6 +200,8 @@ static bool mcore_return_in_memory (tree, tree);
|
|||
#define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
|
||||
#undef TARGET_PASS_BY_REFERENCE
|
||||
#define TARGET_PASS_BY_REFERENCE hook_pass_by_reference_must_pass_in_stack
|
||||
#undef TARGET_ARG_PARTIAL_BYTES
|
||||
#define TARGET_ARG_PARTIAL_BYTES mcore_arg_partial_bytes
|
||||
|
||||
#undef TARGET_SETUP_INCOMING_VARARGS
|
||||
#define TARGET_SETUP_INCOMING_VARARGS mcore_setup_incoming_varargs
|
||||
|
@ -3107,19 +3112,18 @@ mcore_function_arg (CUMULATIVE_ARGS cum, enum machine_mode mode,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Implements the FUNCTION_ARG_PARTIAL_NREGS macro.
|
||||
Returns the number of argument registers required to hold *part* of
|
||||
a parameter of machine mode MODE and type TYPE (which may be NULL if
|
||||
/* 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. */
|
||||
|
||||
int
|
||||
mcore_function_arg_partial_nregs (CUMULATIVE_ARGS cum, enum machine_mode mode,
|
||||
tree type, int named)
|
||||
static int
|
||||
mcore_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
||||
tree type, bool named)
|
||||
{
|
||||
int reg = ROUND_REG (cum, mode);
|
||||
int reg = ROUND_REG (*cum, mode);
|
||||
|
||||
if (named == 0)
|
||||
return 0;
|
||||
|
@ -3148,7 +3152,7 @@ mcore_function_arg_partial_nregs (CUMULATIVE_ARGS cum, enum machine_mode mode,
|
|||
reg = NPARM_REGS - reg;
|
||||
|
||||
/* Return partially in registers and partially on the stack. */
|
||||
return reg;
|
||||
return reg * UNITS_PER_WORD;
|
||||
}
|
||||
|
||||
/* Return nonzero if SYMBOL is marked as being dllexport'd. */
|
||||
|
|
|
@ -704,14 +704,6 @@ extern const enum reg_class reg_class_from_letter[];
|
|||
#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
|
||||
mcore_function_arg (CUM, MODE, TYPE, NAMED)
|
||||
|
||||
/* For an arg passed partly in registers and partly in memory,
|
||||
this is the number of registers used.
|
||||
For args passed entirely in registers or entirely in memory, zero.
|
||||
Any arg that starts in the first NPARM_REGS regs but won't entirely
|
||||
fit in them needs partial registers on the MCore. */
|
||||
#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
|
||||
mcore_function_arg_partial_nregs (CUM, MODE, TYPE, NAMED)
|
||||
|
||||
/* Call the function profiler with a given profile label. */
|
||||
#define FUNCTION_PROFILER(STREAM,LABELNO) \
|
||||
{ \
|
||||
|
|
|
@ -141,8 +141,6 @@ extern void function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode,
|
|||
tree, int);
|
||||
extern struct rtx_def *function_arg (const CUMULATIVE_ARGS *,
|
||||
enum machine_mode, tree, int);
|
||||
extern int function_arg_partial_nregs (const CUMULATIVE_ARGS *,
|
||||
enum machine_mode, tree, int);
|
||||
extern int function_arg_boundary (enum machine_mode, tree);
|
||||
extern bool mips_pad_arg_upward (enum machine_mode, tree);
|
||||
extern bool mips_pad_reg_upward (enum machine_mode, tree);
|
||||
|
|
|
@ -352,6 +352,8 @@ static bool mips_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode mode,
|
|||
tree, bool);
|
||||
static bool mips_callee_copies (CUMULATIVE_ARGS *, enum machine_mode mode,
|
||||
tree, bool);
|
||||
static int mips_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode mode,
|
||||
tree, bool);
|
||||
static bool mips_valid_pointer_mode (enum machine_mode);
|
||||
static bool mips_scalar_mode_supported_p (enum machine_mode);
|
||||
static bool mips_vector_mode_supported_p (enum machine_mode);
|
||||
|
@ -798,6 +800,8 @@ const struct mips_cpu_info mips_cpu_info_table[] = {
|
|||
#define TARGET_PASS_BY_REFERENCE mips_pass_by_reference
|
||||
#undef TARGET_CALLEE_COPIES
|
||||
#define TARGET_CALLEE_COPIES mips_callee_copies
|
||||
#undef TARGET_ARG_PARTIAL_BYTES
|
||||
#define TARGET_ARG_PARTIAL_BYTES mips_arg_partial_bytes
|
||||
|
||||
#undef TARGET_VECTOR_MODE_SUPPORTED_P
|
||||
#define TARGET_VECTOR_MODE_SUPPORTED_P mips_vector_mode_supported_p
|
||||
|
@ -3316,16 +3320,16 @@ function_arg (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
|||
}
|
||||
|
||||
|
||||
/* Implement FUNCTION_ARG_PARTIAL_NREGS. */
|
||||
/* Implement TARGET_ARG_PARTIAL_BYTES. */
|
||||
|
||||
int
|
||||
function_arg_partial_nregs (const CUMULATIVE_ARGS *cum,
|
||||
enum machine_mode mode, tree type, int named)
|
||||
static int
|
||||
mips_arg_partial_bytes (CUMULATIVE_ARGS *cum,
|
||||
enum machine_mode mode, tree type, bool named)
|
||||
{
|
||||
struct mips_arg_info info;
|
||||
|
||||
mips_arg_info (cum, mode, type, named, &info);
|
||||
return info.stack_words > 0 ? info.reg_words : 0;
|
||||
return info.stack_words > 0 ? info.reg_words * UNITS_PER_WORD : 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -2279,13 +2279,6 @@ typedef struct mips_args {
|
|||
#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
|
||||
function_arg( &CUM, MODE, TYPE, NAMED)
|
||||
|
||||
/* For an arg passed partly in registers and partly in memory,
|
||||
this is the number of registers used.
|
||||
For args passed entirely in registers or entirely in memory, zero. */
|
||||
|
||||
#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
|
||||
function_arg_partial_nregs (&CUM, MODE, TYPE, NAMED)
|
||||
|
||||
#define FUNCTION_ARG_BOUNDARY function_arg_boundary
|
||||
|
||||
#define FUNCTION_ARG_PADDING(MODE, TYPE) \
|
||||
|
|
|
@ -50,8 +50,6 @@ extern bool mn10300_wide_const_load_uses_clr (rtx operands[2]);
|
|||
#ifdef TREE_CODE
|
||||
extern struct rtx_def *function_arg (CUMULATIVE_ARGS *,
|
||||
enum machine_mode, tree, int);
|
||||
extern int function_arg_partial_nregs (CUMULATIVE_ARGS *,
|
||||
enum machine_mode, tree, int);
|
||||
#endif /* TREE_CODE */
|
||||
|
||||
extern void expand_prologue (void);
|
||||
|
|
|
@ -73,6 +73,8 @@ static bool mn10300_return_in_memory (tree, tree);
|
|||
static rtx mn10300_builtin_saveregs (void);
|
||||
static bool mn10300_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
|
||||
tree, bool);
|
||||
static int mn10300_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
|
||||
tree, bool);
|
||||
|
||||
/* Initialize the GCC target structure. */
|
||||
#undef TARGET_ASM_ALIGNED_HI_OP
|
||||
|
@ -99,6 +101,8 @@ static bool mn10300_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
|
|||
#define TARGET_PASS_BY_REFERENCE mn10300_pass_by_reference
|
||||
#undef TARGET_CALLEE_COPIES
|
||||
#define TARGET_CALLEE_COPIES hook_bool_CUMULATIVE_ARGS_mode_tree_bool_true
|
||||
#undef TARGET_ARG_PARTIAL_BYTES
|
||||
#define TARGET_ARG_PARTIAL_BYTES mn10300_arg_partial_bytes
|
||||
|
||||
#undef TARGET_EXPAND_BUILTIN_SAVEREGS
|
||||
#define TARGET_EXPAND_BUILTIN_SAVEREGS mn10300_builtin_saveregs
|
||||
|
@ -1528,12 +1532,12 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
|||
return result;
|
||||
}
|
||||
|
||||
/* Return the number of registers to use for an argument passed partially
|
||||
in registers and partially in memory. */
|
||||
/* Return the number of bytes of registers to use for an argument passed
|
||||
partially in registers and partially in memory. */
|
||||
|
||||
int
|
||||
function_arg_partial_nregs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
||||
tree type, int named ATTRIBUTE_UNUSED)
|
||||
static int
|
||||
mn10300_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
||||
tree type, bool named ATTRIBUTE_UNUSED)
|
||||
{
|
||||
int size, align;
|
||||
|
||||
|
@ -1565,7 +1569,7 @@ function_arg_partial_nregs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
|||
&& cum->nbytes + size > nregs * UNITS_PER_WORD)
|
||||
return 0;
|
||||
|
||||
return (nregs * UNITS_PER_WORD - cum->nbytes) / UNITS_PER_WORD;
|
||||
return nregs * UNITS_PER_WORD - cum->nbytes;
|
||||
}
|
||||
|
||||
/* Output a tst insn. */
|
||||
|
|
|
@ -609,9 +609,6 @@ struct cum_arg {int nbytes; };
|
|||
#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
|
||||
function_arg (&CUM, MODE, TYPE, NAMED)
|
||||
|
||||
#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
|
||||
function_arg_partial_nregs (&CUM, MODE, TYPE, NAMED)
|
||||
|
||||
/* Define how to find the value returned by a function.
|
||||
VALTYPE is the data type of the value (as a tree).
|
||||
If the precise function being called is known, FUNC is its FUNCTION_DECL;
|
||||
|
|
|
@ -74,6 +74,8 @@ static void ns32k_output_function_epilogue (FILE *, HOST_WIDE_INT);
|
|||
static bool ns32k_rtx_costs (rtx, int, int, int *);
|
||||
static int ns32k_address_cost (rtx);
|
||||
static rtx ns32k_struct_value_rtx (tree, int);
|
||||
static int ns32k_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
|
||||
tree, bool);
|
||||
|
||||
/* Initialize the GCC target structure. */
|
||||
#undef TARGET_ATTRIBUTE_TABLE
|
||||
|
@ -100,6 +102,9 @@ static rtx ns32k_struct_value_rtx (tree, int);
|
|||
#undef TARGET_STRUCT_VALUE_RTX
|
||||
#define TARGET_STRUCT_VALUE_RTX ns32k_struct_value_rtx
|
||||
|
||||
#undef TARGET_ARG_PARTIAL_BYTES
|
||||
#define TARGET_ARG_PARTIAL_BYTES ns32k_arg_partial_bytes
|
||||
|
||||
#undef TARGET_ASM_FILE_START_APP_OFF
|
||||
#define TARGET_ASM_FILE_START_APP_OFF true
|
||||
|
||||
|
@ -1639,3 +1644,27 @@ ns32k_notice_update_cc (rtx exp, rtx insn ATTRIBUTE_UNUSED)
|
|||
&& reg_overlap_mentioned_p (cc_status.value1, cc_status.value2))
|
||||
abort ();
|
||||
}
|
||||
|
||||
/* Implement TARGET_ARG_PARTIAL_BYTES. */
|
||||
|
||||
static int
|
||||
ns32k_arg_partial_bytes (CUMULATIVE_ARGS *pcum, enum machine_mode mode,
|
||||
tree type, bool named ATTRIBUTE_UNUSED)
|
||||
{
|
||||
int cum = *pcum;
|
||||
|
||||
if (TARGET_REGPARM && cum < 8)
|
||||
{
|
||||
HOST_WIDE_INT size;
|
||||
|
||||
if (mode == BLKmode)
|
||||
size = int_size_in_bytes (type);
|
||||
else
|
||||
size = GET_MODE_SIZE (mode);
|
||||
|
||||
if (8 < cum + size)
|
||||
return 8 - cum;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -708,17 +708,6 @@ enum reg_class
|
|||
#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
|
||||
((TARGET_REGPARM && (CUM) < 8) ? gen_rtx_REG ((MODE), (CUM) / 4) : 0)
|
||||
|
||||
/* For an arg passed partly in registers and partly in memory,
|
||||
this is the number of registers used.
|
||||
For args passed entirely in registers or entirely in memory, zero. */
|
||||
|
||||
#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
|
||||
((TARGET_REGPARM && (CUM) < 8 \
|
||||
&& 8 < ((CUM) + ((MODE) == BLKmode \
|
||||
? int_size_in_bytes (TYPE) \
|
||||
: GET_MODE_SIZE (MODE)))) \
|
||||
? 2 - (CUM) / 4 : 0)
|
||||
|
||||
/* Output assembler code to FILE to increment profiler label # LABELNO
|
||||
for profiling a function entry.
|
||||
|
||||
|
|
|
@ -160,9 +160,6 @@ extern rtx function_arg (CUMULATIVE_ARGS *, enum machine_mode,
|
|||
tree, int);
|
||||
extern rtx function_value (tree, tree);
|
||||
#endif
|
||||
extern int function_arg_partial_nregs (CUMULATIVE_ARGS *,
|
||||
enum machine_mode,
|
||||
tree, int);
|
||||
extern bool pa_return_in_memory (tree, tree);
|
||||
#endif /* TREE_CODE */
|
||||
|
||||
|
|
|
@ -141,8 +141,10 @@ static void output_deferred_plabels (void);
|
|||
static void pa_hpux_init_libfuncs (void);
|
||||
#endif
|
||||
static rtx pa_struct_value_rtx (tree, int);
|
||||
static bool pa_pass_by_reference (CUMULATIVE_ARGS *ca, enum machine_mode,
|
||||
static bool pa_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
|
||||
tree, bool);
|
||||
static int pa_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
|
||||
tree, bool);
|
||||
static struct machine_function * pa_init_machine_status (void);
|
||||
|
||||
|
||||
|
@ -282,6 +284,8 @@ static size_t n_deferred_plabels = 0;
|
|||
#define TARGET_PASS_BY_REFERENCE pa_pass_by_reference
|
||||
#undef TARGET_CALLEE_COPIES
|
||||
#define TARGET_CALLEE_COPIES hook_bool_CUMULATIVE_ARGS_mode_tree_bool_true
|
||||
#undef TARGET_ARG_PARTIAL_BYTES
|
||||
#define TARGET_ARG_PARTIAL_BYTES pa_arg_partial_bytes
|
||||
|
||||
#undef TARGET_EXPAND_BUILTIN_SAVEREGS
|
||||
#define TARGET_EXPAND_BUILTIN_SAVEREGS hppa_builtin_saveregs
|
||||
|
@ -9069,7 +9073,7 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
|
|||
arg_size = FUNCTION_ARG_SIZE (mode, type);
|
||||
|
||||
/* If this arg would be passed partially or totally on the stack, then
|
||||
this routine should return zero. FUNCTION_ARG_PARTIAL_NREGS will
|
||||
this routine should return zero. pa_arg_partial_bytes will
|
||||
handle arguments which are split between regs and stack slots if
|
||||
the ABI mandates split arguments. */
|
||||
if (! TARGET_64BIT)
|
||||
|
@ -9238,15 +9242,18 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
|
|||
|
||||
|
||||
/* If this arg would be passed totally in registers or totally on the stack,
|
||||
then this routine should return zero. It is currently called only for
|
||||
the 64-bit target. */
|
||||
int
|
||||
function_arg_partial_nregs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
||||
tree type, int named ATTRIBUTE_UNUSED)
|
||||
then this routine should return zero. */
|
||||
|
||||
static int
|
||||
pa_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
||||
tree type, bool named ATTRIBUTE_UNUSED)
|
||||
{
|
||||
unsigned int max_arg_words = 8;
|
||||
unsigned int offset = 0;
|
||||
|
||||
if (!TARGET_64BIT)
|
||||
return 0;
|
||||
|
||||
if (FUNCTION_ARG_SIZE (mode, type) > 1 && (cum->words & 1))
|
||||
offset = 1;
|
||||
|
||||
|
@ -9258,7 +9265,7 @@ function_arg_partial_nregs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
|||
return 0;
|
||||
else
|
||||
/* Arg is split. */
|
||||
return max_arg_words - cum->words - offset;
|
||||
return (max_arg_words - cum->words - offset) * UNITS_PER_WORD;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -923,15 +923,6 @@ struct hppa_args {int words, nargs_prototype, incoming, indirect; };
|
|||
#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
|
||||
function_arg (&CUM, MODE, TYPE, NAMED)
|
||||
|
||||
/* For an arg passed partly in registers and partly in memory,
|
||||
this is the number of registers used.
|
||||
For args passed entirely in registers or entirely in memory, zero. */
|
||||
|
||||
/* For PA32 there are never split arguments. PA64, on the other hand, can
|
||||
pass arguments partially in registers and partially in memory. */
|
||||
#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
|
||||
(TARGET_64BIT ? function_arg_partial_nregs (&CUM, MODE, TYPE, NAMED) : 0)
|
||||
|
||||
/* If defined, a C expression that gives the alignment boundary, in
|
||||
bits, of an argument with the specified mode and type. If it is
|
||||
not defined, `PARM_BOUNDARY' is used for all arguments. */
|
||||
|
|
|
@ -628,12 +628,6 @@ maybe ac0 ? - as option someday! */
|
|||
FUNCTION_ARG (CUM, MODE, TYPE, NAMED)
|
||||
*/
|
||||
|
||||
/* For an arg passed partly in registers and partly in memory,
|
||||
this is the number of registers used.
|
||||
For args passed entirely in registers or entirely in memory, zero. */
|
||||
|
||||
#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) 0
|
||||
|
||||
/* Output assembler code to FILE to increment profiler label # LABELNO
|
||||
for profiling a function entry. */
|
||||
|
||||
|
|
|
@ -160,8 +160,6 @@ extern void function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode,
|
|||
extern int function_arg_boundary (enum machine_mode, tree);
|
||||
extern struct rtx_def *function_arg (CUMULATIVE_ARGS *,
|
||||
enum machine_mode, tree, int);
|
||||
extern int function_arg_partial_nregs (CUMULATIVE_ARGS *,
|
||||
enum machine_mode, tree, int);
|
||||
extern rtx rs6000_function_value (tree, tree);
|
||||
extern rtx rs6000_libcall_value (enum machine_mode);
|
||||
extern struct rtx_def *rs6000_va_arg (tree, tree);
|
||||
|
|
|
@ -756,6 +756,8 @@ static void setup_incoming_varargs (CUMULATIVE_ARGS *,
|
|||
int *, int);
|
||||
static bool rs6000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
|
||||
tree, bool);
|
||||
static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
|
||||
tree, bool);
|
||||
#if TARGET_MACHO
|
||||
static void macho_branch_islands (void);
|
||||
static void add_compiler_branch_island (tree, tree, int);
|
||||
|
@ -991,6 +993,8 @@ static const char alt_reg_names[][8] =
|
|||
#define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
|
||||
#undef TARGET_PASS_BY_REFERENCE
|
||||
#define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
|
||||
#undef TARGET_ARG_PARTIAL_BYTES
|
||||
#define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
|
||||
|
||||
#undef TARGET_BUILD_BUILTIN_VA_LIST
|
||||
#define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
|
||||
|
@ -5306,6 +5310,8 @@ rs6000_mixed_function_arg (enum machine_mode mode, tree type, int align_words)
|
|||
In any case, the code to store the whole arg to memory is often
|
||||
more efficient than code to store pieces, and we know that space
|
||||
is available in the right place for the whole arg. */
|
||||
/* FIXME: This should be fixed since the conversion to
|
||||
TARGET_ARG_PARTIAL_BYTES. */
|
||||
rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
|
||||
|
||||
i = 0;
|
||||
|
@ -5606,11 +5612,11 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
|||
the number of registers used. For args passed entirely in registers
|
||||
or entirely in memory, zero. When an arg is described by a PARALLEL,
|
||||
perhaps using more than one register type, this function returns the
|
||||
number of registers used by the first element of the PARALLEL. */
|
||||
number of bytes of registers used by the PARALLEL. */
|
||||
|
||||
int
|
||||
function_arg_partial_nregs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
||||
tree type, int named)
|
||||
static int
|
||||
rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
||||
tree type, bool named)
|
||||
{
|
||||
int ret = 0;
|
||||
int align;
|
||||
|
@ -5648,8 +5654,10 @@ function_arg_partial_nregs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
|||
&& GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
|
||||
ret = GP_ARG_NUM_REG - align_words;
|
||||
|
||||
ret *= (TARGET_32BIT ? 4 : 8);
|
||||
|
||||
if (ret != 0 && TARGET_DEBUG_ARG)
|
||||
fprintf (stderr, "function_arg_partial_nregs: %d\n", ret);
|
||||
fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -1744,13 +1744,6 @@ typedef struct rs6000_args
|
|||
#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
|
||||
function_arg (&CUM, MODE, TYPE, NAMED)
|
||||
|
||||
/* For an arg passed partly in registers and partly in memory,
|
||||
this is the number of registers used.
|
||||
For args passed entirely in registers or entirely in memory, zero. */
|
||||
|
||||
#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
|
||||
function_arg_partial_nregs (&CUM, MODE, TYPE, NAMED)
|
||||
|
||||
/* If defined, a C expression which determines whether, and in which
|
||||
direction, to pad out an argument with extra space. The value
|
||||
should be of type `enum direction': either `upward' to pad above
|
||||
|
|
|
@ -717,8 +717,6 @@ CUMULATIVE_ARGS;
|
|||
#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
|
||||
s390_function_arg (&CUM, MODE, TYPE, NAMED)
|
||||
|
||||
#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) 0
|
||||
|
||||
/* Arguments can be placed in general registers 2 to 6,
|
||||
or in floating point registers 0 and 2. */
|
||||
#define FUNCTION_ARG_REGNO_P(N) (((N) >=2 && (N) <7) || \
|
||||
|
|
|
@ -286,6 +286,8 @@ static bool sh_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
|
|||
tree, bool);
|
||||
static bool sh_callee_copies (CUMULATIVE_ARGS *, enum machine_mode,
|
||||
tree, bool);
|
||||
static int sh_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
|
||||
tree, bool);
|
||||
static int sh_dwarf_calling_convention (tree);
|
||||
|
||||
|
||||
|
@ -444,6 +446,8 @@ static int sh_dwarf_calling_convention (tree);
|
|||
#define TARGET_PASS_BY_REFERENCE sh_pass_by_reference
|
||||
#undef TARGET_CALLEE_COPIES
|
||||
#define TARGET_CALLEE_COPIES sh_callee_copies
|
||||
#undef TARGET_ARG_PARTIAL_BYTES
|
||||
#define TARGET_ARG_PARTIAL_BYTES sh_arg_partial_bytes
|
||||
|
||||
#undef TARGET_BUILD_BUILTIN_VA_LIST
|
||||
#define TARGET_BUILD_BUILTIN_VA_LIST sh_build_builtin_va_list
|
||||
|
@ -6668,6 +6672,30 @@ sh_callee_copies (CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
|||
% SH_MIN_ALIGN_FOR_CALLEE_COPY == 0));
|
||||
}
|
||||
|
||||
static int
|
||||
sh_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
||||
tree type, bool named ATTRIBUTE_UNUSED)
|
||||
{
|
||||
int words = 0;
|
||||
|
||||
if (!TARGET_SH5
|
||||
&& PASS_IN_REG_P (*cum, mode, type)
|
||||
&& !(TARGET_SH4 || TARGET_SH2A_DOUBLE)
|
||||
&& (ROUND_REG (*cum, mode)
|
||||
+ (mode != BLKmode
|
||||
? ROUND_ADVANCE (GET_MODE_SIZE (mode))
|
||||
: ROUND_ADVANCE (int_size_in_bytes (type)))
|
||||
> NPARM_REGS (mode)))
|
||||
words = NPARM_REGS (mode) - ROUND_REG (*cum, mode);
|
||||
|
||||
else if (!TARGET_SHCOMPACT
|
||||
&& SH5_WOULD_BE_PARTIAL_NREGS (*cum, mode, type, named))
|
||||
words = NPARM_REGS (SImode) - cum->arg_count[SH_ARG_INT];
|
||||
|
||||
return words * UNITS_PER_WORD;
|
||||
}
|
||||
|
||||
|
||||
/* 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.
|
||||
|
|
|
@ -2204,27 +2204,6 @@ struct sh_args {
|
|||
(REG)), \
|
||||
const0_rtx))))
|
||||
|
||||
/* For an arg passed partly in registers and partly in memory,
|
||||
this is the number of registers used.
|
||||
For args passed entirely in registers or entirely in memory, zero.
|
||||
|
||||
We sometimes split args. */
|
||||
|
||||
#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
|
||||
((! TARGET_SH5 \
|
||||
&& PASS_IN_REG_P ((CUM), (MODE), (TYPE)) \
|
||||
&& ! (TARGET_SH4 || TARGET_SH2A_DOUBLE) \
|
||||
&& (ROUND_REG ((CUM), (MODE)) \
|
||||
+ ((MODE) != BLKmode \
|
||||
? ROUND_ADVANCE (GET_MODE_SIZE (MODE)) \
|
||||
: ROUND_ADVANCE (int_size_in_bytes (TYPE))) \
|
||||
> NPARM_REGS (MODE))) \
|
||||
? NPARM_REGS (MODE) - ROUND_REG ((CUM), (MODE)) \
|
||||
: (SH5_WOULD_BE_PARTIAL_NREGS ((CUM), (MODE), (TYPE), (NAMED)) \
|
||||
&& ! TARGET_SHCOMPACT) \
|
||||
? NPARM_REGS (SImode) - (CUM).arg_count[(int) SH_ARG_INT] \
|
||||
: 0)
|
||||
|
||||
#define SH5_WOULD_BE_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
|
||||
(TARGET_SH5 \
|
||||
&& ((MODE) == BLKmode || (MODE) == TImode || (MODE) == CDImode \
|
||||
|
|
|
@ -30,8 +30,6 @@ extern void function_arg_advance (CUMULATIVE_ARGS *,
|
|||
enum machine_mode, tree, int);
|
||||
extern struct rtx_def *function_arg (const CUMULATIVE_ARGS *,
|
||||
enum machine_mode, tree, int, int);
|
||||
extern int function_arg_partial_nregs (const CUMULATIVE_ARGS *,
|
||||
enum machine_mode, tree, int);
|
||||
#ifdef RTX_CODE
|
||||
extern void init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree);
|
||||
extern void sparc_va_start (tree, rtx);
|
||||
|
|
|
@ -356,6 +356,8 @@ static tree sparc_gimplify_va_arg (tree, tree, tree *, tree *);
|
|||
static bool sparc_vector_mode_supported_p (enum machine_mode);
|
||||
static bool sparc_pass_by_reference (CUMULATIVE_ARGS *,
|
||||
enum machine_mode, tree, bool);
|
||||
static int sparc_arg_partial_bytes (CUMULATIVE_ARGS *,
|
||||
enum machine_mode, tree, bool);
|
||||
static void sparc_dwarf_handle_frame_unspec (const char *, rtx, int);
|
||||
#ifdef SUBTARGET_ATTRIBUTE_TABLE
|
||||
const struct attribute_spec sparc_attribute_table[];
|
||||
|
@ -469,6 +471,8 @@ enum processor_type sparc_cpu;
|
|||
#define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
|
||||
#undef TARGET_PASS_BY_REFERENCE
|
||||
#define TARGET_PASS_BY_REFERENCE sparc_pass_by_reference
|
||||
#undef TARGET_ARG_PARTIAL_BYTES
|
||||
#define TARGET_ARG_PARTIAL_BYTES sparc_arg_partial_bytes
|
||||
|
||||
#undef TARGET_EXPAND_BUILTIN_SAVEREGS
|
||||
#define TARGET_EXPAND_BUILTIN_SAVEREGS sparc_builtin_saveregs
|
||||
|
@ -5618,7 +5622,7 @@ function_arg_record_value (tree type, enum machine_mode mode,
|
|||
/* If at least one field must be passed on the stack, generate
|
||||
(parallel [(expr_list (nil) ...) ...]) so that all fields will
|
||||
also be passed on the stack. We can't do much better because the
|
||||
semantics of FUNCTION_ARG_PARTIAL_NREGS doesn't handle the case
|
||||
semantics of TARGET_ARG_PARTIAL_BYTES doesn't handle the case
|
||||
of structures for which the fields passed exclusively in registers
|
||||
are not at the beginning of the structure. */
|
||||
if (parms.stack)
|
||||
|
@ -5857,9 +5861,8 @@ function_arg (const struct sparc_args *cum, enum machine_mode mode,
|
|||
return reg;
|
||||
}
|
||||
|
||||
/* Handle the FUNCTION_ARG_PARTIAL_NREGS macro.
|
||||
For an arg passed partly in registers and partly in memory,
|
||||
this is the number of registers used.
|
||||
/* For an arg passed partly in registers and partly in memory,
|
||||
this is the number of bytes of registers used.
|
||||
For args passed entirely in registers or entirely in memory, zero.
|
||||
|
||||
Any arg that starts in the first 6 regs but won't entirely fit in them
|
||||
|
@ -5868,9 +5871,9 @@ function_arg (const struct sparc_args *cum, enum machine_mode mode,
|
|||
values that begin in the last fp reg [where "last fp reg" varies with the
|
||||
mode] will be split between that reg and memory. */
|
||||
|
||||
int
|
||||
function_arg_partial_nregs (const struct sparc_args *cum,
|
||||
enum machine_mode mode, tree type, int named)
|
||||
static int
|
||||
sparc_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
||||
tree type, bool named)
|
||||
{
|
||||
int slotno, regno, padding;
|
||||
|
||||
|
@ -5886,13 +5889,13 @@ function_arg_partial_nregs (const struct sparc_args *cum,
|
|||
? ROUND_ADVANCE (int_size_in_bytes (type))
|
||||
: ROUND_ADVANCE (GET_MODE_SIZE (mode))))
|
||||
> SPARC_INT_ARG_MAX)
|
||||
return SPARC_INT_ARG_MAX - slotno;
|
||||
return (SPARC_INT_ARG_MAX - slotno) * UNITS_PER_WORD;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 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 1 if the argument is partially passed in registers. */
|
||||
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))
|
||||
{
|
||||
|
@ -5900,7 +5903,7 @@ function_arg_partial_nregs (const struct sparc_args *cum,
|
|||
|
||||
if (size > UNITS_PER_WORD
|
||||
&& slotno == SPARC_INT_ARG_MAX - 1)
|
||||
return 1;
|
||||
return UNITS_PER_WORD;
|
||||
}
|
||||
else if (GET_MODE_CLASS (mode) == MODE_COMPLEX_INT
|
||||
|| (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
|
||||
|
@ -5909,13 +5912,13 @@ function_arg_partial_nregs (const struct sparc_args *cum,
|
|||
/* The complex types are passed as packed types. */
|
||||
if (GET_MODE_SIZE (mode) > UNITS_PER_WORD
|
||||
&& slotno == SPARC_INT_ARG_MAX - 1)
|
||||
return 1;
|
||||
return UNITS_PER_WORD;
|
||||
}
|
||||
else if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
|
||||
{
|
||||
if ((slotno + GET_MODE_SIZE (mode) / UNITS_PER_WORD)
|
||||
> SPARC_FP_ARG_MAX)
|
||||
return 1;
|
||||
return UNITS_PER_WORD;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1737,13 +1737,6 @@ function_arg (& (CUM), (MODE), (TYPE), (NAMED), 0)
|
|||
#define FUNCTION_INCOMING_ARG(CUM, MODE, TYPE, NAMED) \
|
||||
function_arg (& (CUM), (MODE), (TYPE), (NAMED), 1)
|
||||
|
||||
/* For an arg passed partly in registers and partly in memory,
|
||||
this is the number of registers used.
|
||||
For args passed entirely in registers or entirely in memory, zero. */
|
||||
|
||||
#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
|
||||
function_arg_partial_nregs (& (CUM), (MODE), (TYPE), (NAMED))
|
||||
|
||||
/* If defined, a C expression which determines whether, and in which direction,
|
||||
to pad out an argument with extra space. The value should be of type
|
||||
`enum direction': either `upward' to pad above the argument,
|
||||
|
|
|
@ -417,8 +417,6 @@ enum reg_class
|
|||
#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
|
||||
xstormy16_function_arg (CUM, MODE, TYPE, NAMED)
|
||||
|
||||
#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) 0
|
||||
|
||||
/* For this platform, the value of CUMULATIVE_ARGS is the number of words
|
||||
of arguments that have been passed in registers so far. */
|
||||
#define CUMULATIVE_ARGS int
|
||||
|
|
|
@ -80,9 +80,6 @@ extern void v850_output_aligned_bss (FILE *, tree, const char *, int, in
|
|||
extern void v850_output_common (FILE *, tree, const char *, int, int);
|
||||
extern void v850_output_local (FILE *, tree, const char *, int, int);
|
||||
extern v850_data_area v850_get_data_area (tree);
|
||||
#ifdef HAVE_MACHINE_MODES
|
||||
extern int function_arg_partial_nregs (CUMULATIVE_ARGS *, Mmode, tree, int);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
extern void ghs_pragma_section (struct cpp_reader *);
|
||||
|
|
|
@ -69,6 +69,8 @@ static void v850_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode,
|
|||
tree, int *, int);
|
||||
static bool v850_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
|
||||
tree, bool);
|
||||
static int v850_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
|
||||
tree, bool);
|
||||
|
||||
/* Information about the various small memory areas. */
|
||||
struct small_memory_info small_memory[ (int)SMALL_MEMORY_max ] =
|
||||
|
@ -137,6 +139,9 @@ static int v850_interrupt_p = FALSE;
|
|||
#undef TARGET_SETUP_INCOMING_VARARGS
|
||||
#define TARGET_SETUP_INCOMING_VARARGS v850_setup_incoming_varargs
|
||||
|
||||
#undef TARGET_ARG_PARTIAL_BYTES
|
||||
#define TARGET_ARG_PARTIAL_BYTES v850_arg_partial_bytes
|
||||
|
||||
struct gcc_target targetm = TARGET_INITIALIZER;
|
||||
|
||||
/* Sometimes certain combinations of command options do not make
|
||||
|
@ -257,14 +262,12 @@ function_arg (CUMULATIVE_ARGS * cum,
|
|||
}
|
||||
|
||||
|
||||
/* Return the number of words which must be put into registers
|
||||
/* Return the number of bytes which must be put into registers
|
||||
for values which are part in registers and part in memory. */
|
||||
|
||||
int
|
||||
function_arg_partial_nregs (CUMULATIVE_ARGS * cum,
|
||||
enum machine_mode mode,
|
||||
tree type,
|
||||
int named)
|
||||
static int
|
||||
v850_arg_partial_bytes (CUMULATIVE_ARGS * cum, enum machine_mode mode,
|
||||
tree type, bool named)
|
||||
{
|
||||
int size, align;
|
||||
|
||||
|
@ -293,7 +296,7 @@ function_arg_partial_nregs (CUMULATIVE_ARGS * cum,
|
|||
&& cum->nbytes + size > 4 * UNITS_PER_WORD)
|
||||
return 0;
|
||||
|
||||
return (4 * UNITS_PER_WORD - cum->nbytes) / UNITS_PER_WORD;
|
||||
return 4 * UNITS_PER_WORD - cum->nbytes;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -746,9 +746,6 @@ struct cum_arg { int nbytes; int anonymous_args; };
|
|||
#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
|
||||
function_arg (&CUM, MODE, TYPE, NAMED)
|
||||
|
||||
#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
|
||||
function_arg_partial_nregs (&CUM, MODE, TYPE, NAMED)
|
||||
|
||||
/* Initialize a variable CUM of type CUMULATIVE_ARGS
|
||||
for a call to a function whose data type is FNTYPE.
|
||||
For a library call, FNTYPE is 0. */
|
||||
|
|
|
@ -762,9 +762,6 @@ typedef struct xtensa_args
|
|||
#define FUNCTION_INCOMING_ARG(CUM, MODE, TYPE, NAMED) \
|
||||
function_arg (&CUM, MODE, TYPE, TRUE)
|
||||
|
||||
/* Arguments are never passed partly in memory and partly in registers. */
|
||||
#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) (0)
|
||||
|
||||
/* Specify function argument alignment. */
|
||||
#define FUNCTION_ARG_BOUNDARY(MODE, TYPE) \
|
||||
((TYPE) != 0 \
|
||||
|
|
|
@ -3748,25 +3748,24 @@ If @code{FUNCTION_INCOMING_ARG} is not defined, @code{FUNCTION_ARG}
|
|||
serves both purposes.
|
||||
@end defmac
|
||||
|
||||
@defmac FUNCTION_ARG_PARTIAL_NREGS (@var{cum}, @var{mode}, @var{type}, @var{named})
|
||||
A C expression for the number of words, at the beginning of an
|
||||
argument, that must be put in registers. The value must be zero for
|
||||
@deftypefn {Target Hook} int TARGET_ARG_PARTIAL_BYTES (CUMULATIVE_ARGS *@var{cum}, enum machine_mode @var{mode}, tree @var{type}, bool @var{named})
|
||||
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
|
||||
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 @var{n} words of arguments are passed in registers, and the rest
|
||||
first few words of arguments are passed in registers, and the rest
|
||||
on the stack. If a multi-word argument (a @code{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.
|
||||
compiler when this occurs, and how many bytes should go in registers.
|
||||
|
||||
@code{FUNCTION_ARG} for these arguments should return the first
|
||||
register to be used by the caller for this argument; likewise
|
||||
@code{FUNCTION_INCOMING_ARG}, for the called function.
|
||||
@end defmac
|
||||
@end deftypefn
|
||||
|
||||
@deftypefn {Target Hook} bool TARGET_PASS_BY_REFERENCE (CUMULATIVE_ARGS *@var{cum}, enum machine_mode @var{mode}, tree @var{type}, bool @var{named})
|
||||
This target hook should return @code{true} if an argument at the
|
||||
|
|
32
gcc/expr.c
32
gcc/expr.c
|
@ -1220,8 +1220,7 @@ block_move_libcall_safe_for_call_parm (void)
|
|||
rtx tmp = FUNCTION_ARG (args_so_far, mode, NULL_TREE, 1);
|
||||
if (!tmp || !REG_P (tmp))
|
||||
return false;
|
||||
if (FUNCTION_ARG_PARTIAL_NREGS (args_so_far, mode,
|
||||
NULL_TREE, 1))
|
||||
if (targetm.calls.arg_partial_bytes (&args_so_far, mode, NULL, 1))
|
||||
return false;
|
||||
FUNCTION_ARG_ADVANCE (args_so_far, mode, NULL_TREE, 1);
|
||||
}
|
||||
|
@ -3343,9 +3342,8 @@ emit_single_push_insn (enum machine_mode mode, rtx x, tree type)
|
|||
ALIGN (in bits) is maximum alignment we can assume.
|
||||
|
||||
If PARTIAL and REG are both nonzero, then copy that many of the first
|
||||
words of X into registers starting with REG, and push the rest of X.
|
||||
The amount of space pushed is decreased by PARTIAL words,
|
||||
rounded *down* to a multiple of PARM_BOUNDARY.
|
||||
bytes of X into registers starting with REG, and push the rest of X.
|
||||
The amount of space pushed is decreased by PARTIAL bytes.
|
||||
REG must be a hard register in this case.
|
||||
If REG is zero but PARTIAL is not, take any all others actions for an
|
||||
argument partially in registers, but do not actually load any
|
||||
|
@ -3397,24 +3395,15 @@ emit_push_insn (rtx x, enum machine_mode mode, tree type, rtx size,
|
|||
/* Copy a block into the stack, entirely or partially. */
|
||||
|
||||
rtx temp;
|
||||
int used = partial * UNITS_PER_WORD;
|
||||
int used;
|
||||
int offset;
|
||||
int skip;
|
||||
|
||||
if (reg && GET_CODE (reg) == PARALLEL)
|
||||
{
|
||||
/* Use the size of the elt to compute offset. */
|
||||
rtx elt = XEXP (XVECEXP (reg, 0, 0), 0);
|
||||
used = partial * GET_MODE_SIZE (GET_MODE (elt));
|
||||
offset = used % (PARM_BOUNDARY / BITS_PER_UNIT);
|
||||
}
|
||||
else
|
||||
offset = used % (PARM_BOUNDARY / BITS_PER_UNIT);
|
||||
offset = partial % (PARM_BOUNDARY / BITS_PER_UNIT);
|
||||
used = partial - offset;
|
||||
|
||||
gcc_assert (size);
|
||||
|
||||
used -= offset;
|
||||
|
||||
/* USED is now the # of bytes we need not copy to the stack
|
||||
because registers will take care of them. */
|
||||
|
||||
|
@ -3525,7 +3514,7 @@ emit_push_insn (rtx x, enum machine_mode mode, tree type, rtx size,
|
|||
int size = GET_MODE_SIZE (mode) / UNITS_PER_WORD;
|
||||
int i;
|
||||
int not_stack;
|
||||
/* # words of start of argument
|
||||
/* # bytes of start of argument
|
||||
that we must make space for but need not store. */
|
||||
int offset = partial % (PARM_BOUNDARY / BITS_PER_WORD);
|
||||
int args_offset = INTVAL (args_so_far);
|
||||
|
@ -3546,7 +3535,7 @@ emit_push_insn (rtx x, enum machine_mode mode, tree type, rtx size,
|
|||
|
||||
/* Now NOT_STACK gets the number of words that we don't need to
|
||||
allocate on the stack. */
|
||||
not_stack = partial - offset;
|
||||
not_stack = (partial - offset) / UNITS_PER_WORD;
|
||||
|
||||
/* If the partial register-part of the arg counts in its stack size,
|
||||
skip the part of stack space corresponding to the registers.
|
||||
|
@ -3630,7 +3619,10 @@ emit_push_insn (rtx x, enum machine_mode mode, tree type, rtx size,
|
|||
if (GET_CODE (reg) == PARALLEL)
|
||||
emit_group_load (reg, x, type, -1);
|
||||
else
|
||||
move_block_to_reg (REGNO (reg), x, partial, mode);
|
||||
{
|
||||
gcc_assert (partial % UNITS_PER_WORD == 0);
|
||||
move_block_to_reg (REGNO (reg), x, partial / UNITS_PER_WORD, mode);
|
||||
}
|
||||
}
|
||||
|
||||
if (extra && args_addr == 0 && where_pad == stack_direction)
|
||||
|
|
|
@ -183,10 +183,6 @@ do { \
|
|||
#define FUNCTION_ARG_BOUNDARY(MODE, TYPE) PARM_BOUNDARY
|
||||
#endif
|
||||
|
||||
#ifndef FUNCTION_ARG_PARTIAL_NREGS
|
||||
#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) 0
|
||||
#endif
|
||||
|
||||
/* Supply a default definition of STACK_SAVEAREA_MODE for emit_stack_save.
|
||||
Normally move_insn, so Pmode stack pointer. */
|
||||
|
||||
|
|
|
@ -2296,10 +2296,10 @@ assign_parm_find_entry_rtl (struct assign_parm_data_all *all,
|
|||
{
|
||||
int partial;
|
||||
|
||||
partial = FUNCTION_ARG_PARTIAL_NREGS (all->args_so_far,
|
||||
data->promoted_mode,
|
||||
data->passed_type,
|
||||
data->named_arg);
|
||||
partial = targetm.calls.arg_partial_bytes (&all->args_so_far,
|
||||
data->promoted_mode,
|
||||
data->passed_type,
|
||||
data->named_arg);
|
||||
data->partial = partial;
|
||||
|
||||
/* The caller might already have allocated stack space for the
|
||||
|
@ -2325,7 +2325,7 @@ assign_parm_find_entry_rtl (struct assign_parm_data_all *all,
|
|||
argument on the stack. */
|
||||
gcc_assert (!all->extra_pretend_bytes && !all->pretend_args_size);
|
||||
|
||||
pretend_bytes = partial * UNITS_PER_WORD;
|
||||
pretend_bytes = partial;
|
||||
all->pretend_args_size = CEIL_ROUND (pretend_bytes, STACK_BYTES);
|
||||
|
||||
/* We want to align relative to the actual stack pointer, so
|
||||
|
@ -2449,8 +2449,11 @@ assign_parm_adjust_entry_rtl (struct assign_parm_data_one *data)
|
|||
data->passed_type,
|
||||
int_size_in_bytes (data->passed_type));
|
||||
else
|
||||
move_block_from_reg (REGNO (entry_parm), validize_mem (stack_parm),
|
||||
data->partial);
|
||||
{
|
||||
gcc_assert (data->partial % UNITS_PER_WORD == 0);
|
||||
move_block_from_reg (REGNO (entry_parm), validize_mem (stack_parm),
|
||||
data->partial / UNITS_PER_WORD);
|
||||
}
|
||||
|
||||
entry_parm = stack_parm;
|
||||
}
|
||||
|
@ -3399,11 +3402,7 @@ locate_and_pad_parm (enum machine_mode passed_mode, tree type, int in_regs,
|
|||
}
|
||||
#endif /* REG_PARM_STACK_SPACE */
|
||||
|
||||
part_size_in_regs = 0;
|
||||
if (reg_parm_stack_space == 0)
|
||||
part_size_in_regs = ((partial * UNITS_PER_WORD)
|
||||
/ (PARM_BOUNDARY / BITS_PER_UNIT)
|
||||
* (PARM_BOUNDARY / BITS_PER_UNIT));
|
||||
part_size_in_regs = (reg_parm_stack_space == 0 ? partial : 0);
|
||||
|
||||
sizetree
|
||||
= type ? size_in_bytes (type) : size_int (GET_MODE_SIZE (passed_mode));
|
||||
|
|
|
@ -614,7 +614,8 @@ extern void fancy_abort (const char *, int, const char *) ATTRIBUTE_NORETURN;
|
|||
DEFAULT_SHORT_ENUMS SPLIT_COMPLEX_ARGS MD_ASM_CLOBBERS \
|
||||
HANDLE_PRAGMA_REDEFINE_EXTNAME HANDLE_PRAGMA_EXTERN_PREFIX \
|
||||
MUST_PASS_IN_STACK FUNCTION_ARG_PASS_BY_REFERENCE \
|
||||
VECTOR_MODE_SUPPORTED_P TARGET_SUPPORTS_HIDDEN
|
||||
VECTOR_MODE_SUPPORTED_P TARGET_SUPPORTS_HIDDEN \
|
||||
FUNCTION_ARG_PARTIAL_NREGS
|
||||
|
||||
/* Other obsolete target macros, or macros that used to be in target
|
||||
headers and were not used, and may be obsolete or may never have
|
||||
|
|
|
@ -399,6 +399,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
#define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size_or_pad
|
||||
#define TARGET_CALLEE_COPIES hook_bool_CUMULATIVE_ARGS_mode_tree_bool_false
|
||||
#define TARGET_ARG_PARTIAL_BYTES hook_int_CUMULATIVE_ARGS_mode_tree_bool_0
|
||||
|
||||
#define TARGET_CALLS { \
|
||||
TARGET_PROMOTE_FUNCTION_ARGS, \
|
||||
|
@ -414,7 +415,8 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
TARGET_PRETEND_OUTGOING_VARARGS_NAMED, \
|
||||
TARGET_SPLIT_COMPLEX_ARG, \
|
||||
TARGET_MUST_PASS_IN_STACK, \
|
||||
TARGET_CALLEE_COPIES \
|
||||
TARGET_CALLEE_COPIES, \
|
||||
TARGET_ARG_PARTIAL_BYTES \
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -537,6 +537,12 @@ struct gcc_target
|
|||
the caller. It is never called for TYPE requiring constructors. */
|
||||
bool (* callee_copies) (CUMULATIVE_ARGS *ca, enum machine_mode mode,
|
||||
tree type, bool named);
|
||||
|
||||
/* Return zero for arguments passed entirely on the stack or entirely
|
||||
in registers. If passed in both, return the number of bytes passed
|
||||
in registers; the balance is therefore passed on the stack. */
|
||||
int (* arg_partial_bytes) (CUMULATIVE_ARGS *ca, enum machine_mode mode,
|
||||
tree type, bool named);
|
||||
} calls;
|
||||
|
||||
/* Functions specific to the C++ frontend. */
|
||||
|
|
|
@ -279,3 +279,12 @@ hook_bool_CUMULATIVE_ARGS_mode_tree_bool_true (
|
|||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int
|
||||
hook_int_CUMULATIVE_ARGS_mode_tree_bool_0 (
|
||||
CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
|
||||
enum machine_mode mode ATTRIBUTE_UNUSED,
|
||||
tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -58,3 +58,5 @@ extern bool hook_bool_CUMULATIVE_ARGS_mode_tree_bool_false
|
|||
(CUMULATIVE_ARGS *, enum machine_mode, tree, bool);
|
||||
extern bool hook_bool_CUMULATIVE_ARGS_mode_tree_bool_true
|
||||
(CUMULATIVE_ARGS *, enum machine_mode, tree, bool);
|
||||
extern int hook_int_CUMULATIVE_ARGS_mode_tree_bool_0
|
||||
(CUMULATIVE_ARGS *, enum machine_mode, tree, bool);
|
||||
|
|
Loading…
Add table
Reference in a new issue