i386-protos.h (function_arg_pass_by_reference): Declare.

* config/i386/i386-protos.h (function_arg_pass_by_reference): Declare.
	* config/i386/i386.h (FUNCTION_ARG_PASS_BY_REFERENCE): Use it.
	* config/i386/i386.c (function_arg_pass_by_reference): New.
	(ix86_va_arg): Support arguments passed by reference.

From-SVN: r61731
This commit is contained in:
Zdenek Dvorak 2003-01-24 21:48:47 +01:00 committed by Zdenek Dvorak
parent 3d436d2ac5
commit 09b2e78d66
4 changed files with 60 additions and 0 deletions

View file

@ -1,3 +1,10 @@
2003-01-24 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
* config/i386/i386-protos.h (function_arg_pass_by_reference): Declare.
* config/i386/i386.h (FUNCTION_ARG_PASS_BY_REFERENCE): Use it.
* config/i386/i386.c (function_arg_pass_by_reference): New.
(ix86_va_arg): Support arguments passed by reference.
2003-01-24 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
* cfgloopanal.c: New file.

View file

@ -195,6 +195,9 @@ extern void x86_function_profiler PARAMS ((FILE *, int));
#ifdef TREE_CODE
extern void init_cumulative_args PARAMS ((CUMULATIVE_ARGS *, tree, rtx));
extern rtx function_arg PARAMS ((CUMULATIVE_ARGS *, enum machine_mode, tree, int));
extern int function_arg_pass_by_reference PARAMS ((CUMULATIVE_ARGS *,
enum machine_mode,
tree, int));
extern void function_arg_advance PARAMS ((CUMULATIVE_ARGS *, enum machine_mode,
tree, int));
extern rtx ix86_function_value PARAMS ((tree));

View file

@ -2488,6 +2488,32 @@ function_arg (cum, mode, type, named)
return ret;
}
/* A C expression that indicates when an argument must be passed by
reference. If nonzero for an argument, a copy of that argument is
made in memory and a pointer to the argument is passed instead of
the argument itself. The pointer is passed in whatever way is
appropriate for passing a pointer to that type. */
int
function_arg_pass_by_reference (cum, mode, type, named)
CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED;
enum machine_mode mode ATTRIBUTE_UNUSED;
tree type;
int named ATTRIBUTE_UNUSED;
{
if (!TARGET_64BIT)
return 0;
if (type && int_size_in_bytes (type) == -1)
{
if (TARGET_DEBUG_ARG)
fprintf (stderr, "function_arg_pass_by_reference\n");
return 1;
}
return 0;
}
/* Gives the alignment boundary, in bits, of an argument with the specified mode
and type. */
@ -2843,6 +2869,7 @@ ix86_va_arg (valist, type)
rtx lab_false, lab_over = NULL_RTX;
rtx addr_rtx, r;
rtx container;
int indirect_p = 0;
/* Only 64bit target needs something special. */
if (!TARGET_64BIT)
@ -2862,6 +2889,13 @@ ix86_va_arg (valist, type)
sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
size = int_size_in_bytes (type);
if (size == -1)
{
/* Passed by reference. */
indirect_p = 1;
type = build_pointer_type (type);
size = int_size_in_bytes (type);
}
rsize = (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
container = construct_container (TYPE_MODE (type), type, 0,
@ -3052,6 +3086,13 @@ ix86_va_arg (valist, type)
if (container)
emit_label (lab_over);
if (indirect_p)
{
r = gen_rtx_MEM (Pmode, addr_rtx);
set_mem_alias_set (r, get_varargs_alias_set ());
emit_move_insn (addr_rtx, r);
}
return addr_rtx;
}

View file

@ -1753,6 +1753,15 @@ typedef struct ix86_args {
#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) 0
/* A C expression that indicates when an argument must be passed by
reference. If nonzero for an argument, a copy of that argument is
made in memory and a pointer to the argument is passed instead of
the argument itself. The pointer is passed in whatever way is
appropriate for passing a pointer to that type. */
#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \
function_arg_pass_by_reference(&CUM, MODE, TYPE, NAMED)
/* Perform any needed actions needed for a function that is receiving a
variable number of arguments.