calls.c (expand_call): Pass to REG_PARM_STACK_SPACE the type of the function...
2008-11-26 Kai Tietz <kai.tietz@onevision.com> PR/38227 * calls.c (expand_call): Pass to REG_PARM_STACK_SPACE the type of the function, when there is no FUNCTION_DECL available. OUTGOING_REG_PARM_STACK_SPACE pass fntype, when no fndecl is available. (compute_argument_block_size): Add fntype argument. OUTGOING_REG_PARM_STACK_SPACE pass fntype, when no fndecl is available. (emit_library_call_value_1): Likewise. OUTGOING_REG_PARM_STACK_SPACE pass fntype, when no fndecl is available. * config/i386/i386.c (ix86_reg_parm_stack_space): Handle function types. * doc/tm.texi (REG_PARM_STACK_SPACE): Adjust documentation. From-SVN: r142215
This commit is contained in:
parent
89d926785d
commit
5d059ed962
24
gcc/calls.c
24
gcc/calls.c
|
@ -132,7 +132,7 @@ static void store_unaligned_arguments_into_pseudos (struct arg_data *, int);
|
||||||
static int finalize_must_preallocate (int, int, struct arg_data *,
|
static int finalize_must_preallocate (int, int, struct arg_data *,
|
||||||
struct args_size *);
|
struct args_size *);
|
||||||
static void precompute_arguments (int, struct arg_data *);
|
static void precompute_arguments (int, struct arg_data *);
|
||||||
static int compute_argument_block_size (int, struct args_size *, tree, int);
|
static int compute_argument_block_size (int, struct args_size *, tree, tree, int);
|
||||||
static void initialize_argument_information (int, struct arg_data *,
|
static void initialize_argument_information (int, struct arg_data *,
|
||||||
struct args_size *, int,
|
struct args_size *, int,
|
||||||
tree, tree,
|
tree, tree,
|
||||||
|
@ -1205,6 +1205,7 @@ static int
|
||||||
compute_argument_block_size (int reg_parm_stack_space,
|
compute_argument_block_size (int reg_parm_stack_space,
|
||||||
struct args_size *args_size,
|
struct args_size *args_size,
|
||||||
tree fndecl ATTRIBUTE_UNUSED,
|
tree fndecl ATTRIBUTE_UNUSED,
|
||||||
|
tree fntype ATTRIBUTE_UNUSED,
|
||||||
int preferred_stack_boundary ATTRIBUTE_UNUSED)
|
int preferred_stack_boundary ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
int unadjusted_args_size = args_size->constant;
|
int unadjusted_args_size = args_size->constant;
|
||||||
|
@ -1242,7 +1243,7 @@ compute_argument_block_size (int reg_parm_stack_space,
|
||||||
|
|
||||||
/* The area corresponding to register parameters is not to count in
|
/* The area corresponding to register parameters is not to count in
|
||||||
the size of the block we need. So make the adjustment. */
|
the size of the block we need. So make the adjustment. */
|
||||||
if (! OUTGOING_REG_PARM_STACK_SPACE ((!fndecl ? NULL_TREE : TREE_TYPE (fndecl))))
|
if (! OUTGOING_REG_PARM_STACK_SPACE ((!fndecl ? fntype : TREE_TYPE (fndecl))))
|
||||||
args_size->var
|
args_size->var
|
||||||
= size_binop (MINUS_EXPR, args_size->var,
|
= size_binop (MINUS_EXPR, args_size->var,
|
||||||
ssize_int (reg_parm_stack_space));
|
ssize_int (reg_parm_stack_space));
|
||||||
|
@ -1263,7 +1264,7 @@ compute_argument_block_size (int reg_parm_stack_space,
|
||||||
args_size->constant = MAX (args_size->constant,
|
args_size->constant = MAX (args_size->constant,
|
||||||
reg_parm_stack_space);
|
reg_parm_stack_space);
|
||||||
|
|
||||||
if (! OUTGOING_REG_PARM_STACK_SPACE ((!fndecl ? NULL_TREE : TREE_TYPE (fndecl))))
|
if (! OUTGOING_REG_PARM_STACK_SPACE ((!fndecl ? fntype : TREE_TYPE (fndecl))))
|
||||||
args_size->constant -= reg_parm_stack_space;
|
args_size->constant -= reg_parm_stack_space;
|
||||||
}
|
}
|
||||||
return unadjusted_args_size;
|
return unadjusted_args_size;
|
||||||
|
@ -2077,10 +2078,10 @@ expand_call (tree exp, rtx target, int ignore)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef REG_PARM_STACK_SPACE
|
#ifdef REG_PARM_STACK_SPACE
|
||||||
reg_parm_stack_space = REG_PARM_STACK_SPACE (fndecl);
|
reg_parm_stack_space = REG_PARM_STACK_SPACE (!fndecl ? fntype : fndecl);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (! OUTGOING_REG_PARM_STACK_SPACE ((!fndecl ? NULL_TREE : TREE_TYPE (fndecl)))
|
if (! OUTGOING_REG_PARM_STACK_SPACE ((!fndecl ? fntype : TREE_TYPE (fndecl)))
|
||||||
&& reg_parm_stack_space > 0 && PUSH_ARGS)
|
&& reg_parm_stack_space > 0 && PUSH_ARGS)
|
||||||
must_preallocate = 1;
|
must_preallocate = 1;
|
||||||
|
|
||||||
|
@ -2404,7 +2405,7 @@ expand_call (tree exp, rtx target, int ignore)
|
||||||
unadjusted_args_size
|
unadjusted_args_size
|
||||||
= compute_argument_block_size (reg_parm_stack_space,
|
= compute_argument_block_size (reg_parm_stack_space,
|
||||||
&adjusted_args_size,
|
&adjusted_args_size,
|
||||||
fndecl,
|
fndecl, fntype,
|
||||||
(pass == 0 ? 0
|
(pass == 0 ? 0
|
||||||
: preferred_stack_boundary));
|
: preferred_stack_boundary));
|
||||||
|
|
||||||
|
@ -2480,7 +2481,7 @@ expand_call (tree exp, rtx target, int ignore)
|
||||||
/* Since we will be writing into the entire argument area,
|
/* Since we will be writing into the entire argument area,
|
||||||
the map must be allocated for its entire size, not just
|
the map must be allocated for its entire size, not just
|
||||||
the part that is the responsibility of the caller. */
|
the part that is the responsibility of the caller. */
|
||||||
if (! OUTGOING_REG_PARM_STACK_SPACE ((!fndecl ? NULL_TREE : TREE_TYPE (fndecl))))
|
if (! OUTGOING_REG_PARM_STACK_SPACE ((!fndecl ? fntype : TREE_TYPE (fndecl))))
|
||||||
needed += reg_parm_stack_space;
|
needed += reg_parm_stack_space;
|
||||||
|
|
||||||
#ifdef ARGS_GROW_DOWNWARD
|
#ifdef ARGS_GROW_DOWNWARD
|
||||||
|
@ -2579,7 +2580,7 @@ expand_call (tree exp, rtx target, int ignore)
|
||||||
{
|
{
|
||||||
rtx push_size
|
rtx push_size
|
||||||
= GEN_INT (adjusted_args_size.constant
|
= GEN_INT (adjusted_args_size.constant
|
||||||
+ (OUTGOING_REG_PARM_STACK_SPACE ((!fndecl ? NULL
|
+ (OUTGOING_REG_PARM_STACK_SPACE ((!fndecl ? fntype
|
||||||
: TREE_TYPE (fndecl))) ? 0
|
: TREE_TYPE (fndecl))) ? 0
|
||||||
: reg_parm_stack_space));
|
: reg_parm_stack_space));
|
||||||
if (old_stack_level == 0)
|
if (old_stack_level == 0)
|
||||||
|
@ -2750,7 +2751,7 @@ expand_call (tree exp, rtx target, int ignore)
|
||||||
/* If register arguments require space on the stack and stack space
|
/* If register arguments require space on the stack and stack space
|
||||||
was not preallocated, allocate stack space here for arguments
|
was not preallocated, allocate stack space here for arguments
|
||||||
passed in registers. */
|
passed in registers. */
|
||||||
if (OUTGOING_REG_PARM_STACK_SPACE ((!fndecl ? NULL_TREE : TREE_TYPE (fndecl)))
|
if (OUTGOING_REG_PARM_STACK_SPACE ((!fndecl ? fntype : TREE_TYPE (fndecl)))
|
||||||
&& !ACCUMULATE_OUTGOING_ARGS
|
&& !ACCUMULATE_OUTGOING_ARGS
|
||||||
&& must_preallocate == 0 && reg_parm_stack_space > 0)
|
&& must_preallocate == 0 && reg_parm_stack_space > 0)
|
||||||
anti_adjust_stack (GEN_INT (reg_parm_stack_space));
|
anti_adjust_stack (GEN_INT (reg_parm_stack_space));
|
||||||
|
@ -3230,6 +3231,7 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
|
||||||
/* Todo, choose the correct decl type of orgfun. Sadly this information
|
/* Todo, choose the correct decl type of orgfun. Sadly this information
|
||||||
isn't present here, so we default to native calling abi here. */
|
isn't present here, so we default to native calling abi here. */
|
||||||
tree fndecl ATTRIBUTE_UNUSED = NULL_TREE; /* library calls default to host calling abi ? */
|
tree fndecl ATTRIBUTE_UNUSED = NULL_TREE; /* library calls default to host calling abi ? */
|
||||||
|
tree fntype ATTRIBUTE_UNUSED = NULL_TREE; /* library calls default to host calling abi ? */
|
||||||
int inc;
|
int inc;
|
||||||
int count;
|
int count;
|
||||||
rtx argblock = 0;
|
rtx argblock = 0;
|
||||||
|
@ -3487,7 +3489,7 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
|
||||||
args_size.constant = MAX (args_size.constant,
|
args_size.constant = MAX (args_size.constant,
|
||||||
reg_parm_stack_space);
|
reg_parm_stack_space);
|
||||||
|
|
||||||
if (! OUTGOING_REG_PARM_STACK_SPACE ((!fndecl ? NULL_TREE : TREE_TYPE (fndecl))))
|
if (! OUTGOING_REG_PARM_STACK_SPACE ((!fndecl ? fntype : TREE_TYPE (fndecl))))
|
||||||
args_size.constant -= reg_parm_stack_space;
|
args_size.constant -= reg_parm_stack_space;
|
||||||
|
|
||||||
if (args_size.constant > crtl->outgoing_args_size)
|
if (args_size.constant > crtl->outgoing_args_size)
|
||||||
|
@ -3512,7 +3514,7 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
|
||||||
/* Since we will be writing into the entire argument area, the
|
/* Since we will be writing into the entire argument area, the
|
||||||
map must be allocated for its entire size, not just the part that
|
map must be allocated for its entire size, not just the part that
|
||||||
is the responsibility of the caller. */
|
is the responsibility of the caller. */
|
||||||
if (! OUTGOING_REG_PARM_STACK_SPACE ((!fndecl ? NULL_TREE : TREE_TYPE (fndecl))))
|
if (! OUTGOING_REG_PARM_STACK_SPACE ((!fndecl ? fntype : TREE_TYPE (fndecl))))
|
||||||
needed += reg_parm_stack_space;
|
needed += reg_parm_stack_space;
|
||||||
|
|
||||||
#ifdef ARGS_GROW_DOWNWARD
|
#ifdef ARGS_GROW_DOWNWARD
|
||||||
|
|
|
@ -4552,9 +4552,11 @@ ix86_reg_parm_stack_space (const_tree fndecl)
|
||||||
/* For libcalls it is possible that there is no fndecl at hand.
|
/* For libcalls it is possible that there is no fndecl at hand.
|
||||||
Therefore assume for this case the default abi of the target. */
|
Therefore assume for this case the default abi of the target. */
|
||||||
if (!fndecl)
|
if (!fndecl)
|
||||||
call_abi = DEFAULT_ABI;
|
call_abi = (cfun ? cfun->machine->call_abi : DEFAULT_ABI);
|
||||||
else
|
else if (TREE_CODE (fndecl) == FUNCTION_DECL)
|
||||||
call_abi = ix86_function_abi (fndecl);
|
call_abi = ix86_function_abi (fndecl);
|
||||||
|
else
|
||||||
|
call_abi = ix86_function_type_abi (fndecl);
|
||||||
if (call_abi == 1)
|
if (call_abi == 1)
|
||||||
return 32;
|
return 32;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -3817,6 +3817,8 @@ registers.
|
||||||
The value of this macro is the size, in bytes, of the area reserved for
|
The value of this macro is the size, in bytes, of the area reserved for
|
||||||
arguments passed in registers for the function represented by @var{fndecl},
|
arguments passed in registers for the function represented by @var{fndecl},
|
||||||
which can be zero if GCC is calling a library function.
|
which can be zero if GCC is calling a library function.
|
||||||
|
The argument @var{fndecl} can be the FUNCTION_DECL, or the type itself
|
||||||
|
of the function.
|
||||||
|
|
||||||
This space can be allocated by the caller, or be a part of the
|
This space can be allocated by the caller, or be a part of the
|
||||||
machine-dependent stack frame: @code{OUTGOING_REG_PARM_STACK_SPACE} says
|
machine-dependent stack frame: @code{OUTGOING_REG_PARM_STACK_SPACE} says
|
||||||
|
|
Loading…
Reference in New Issue