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:
Kai Tietz 2008-11-26 11:25:38 +01:00
parent 89d926785d
commit 5d059ed962
3 changed files with 19 additions and 13 deletions

View File

@ -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

View File

@ -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;

View File

@ -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