diff options
author | Kai Tietz <ktietz@gcc.gnu.org> | 2008-11-26 11:25:38 +0100 |
---|---|---|
committer | Kai Tietz <ktietz@gcc.gnu.org> | 2008-11-26 11:25:38 +0100 |
commit | 5d059ed962692fac1fca10ede9e25c248c4eb726 (patch) | |
tree | 621ef40c81da803e778b7b7894a67ca0ec7220d4 | |
parent | 89d926785d4e8a8f28318d6d3ea90d634d983e55 (diff) | |
download | gcc-5d059ed962692fac1fca10ede9e25c248c4eb726.zip gcc-5d059ed962692fac1fca10ede9e25c248c4eb726.tar.gz gcc-5d059ed962692fac1fca10ede9e25c248c4eb726.tar.bz2 |
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
-rw-r--r-- | gcc/calls.c | 24 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 6 | ||||
-rw-r--r-- | gcc/doc/tm.texi | 2 |
3 files changed, 19 insertions, 13 deletions
diff --git a/gcc/calls.c b/gcc/calls.c index 096dde4..e2c4fcb 100644 --- a/gcc/calls.c +++ b/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 *, struct args_size *); 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 *, struct args_size *, int, tree, tree, @@ -1205,6 +1205,7 @@ static int compute_argument_block_size (int reg_parm_stack_space, struct args_size *args_size, tree fndecl ATTRIBUTE_UNUSED, + tree fntype ATTRIBUTE_UNUSED, int preferred_stack_boundary ATTRIBUTE_UNUSED) { 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 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 = size_binop (MINUS_EXPR, args_size->var, 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, 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; } return unadjusted_args_size; @@ -2077,10 +2078,10 @@ expand_call (tree exp, rtx target, int ignore) } #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 - 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) must_preallocate = 1; @@ -2404,7 +2405,7 @@ expand_call (tree exp, rtx target, int ignore) unadjusted_args_size = compute_argument_block_size (reg_parm_stack_space, &adjusted_args_size, - fndecl, + fndecl, fntype, (pass == 0 ? 0 : 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, the map must be allocated for its entire size, not just 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; #ifdef ARGS_GROW_DOWNWARD @@ -2579,7 +2580,7 @@ expand_call (tree exp, rtx target, int ignore) { rtx push_size = GEN_INT (adjusted_args_size.constant - + (OUTGOING_REG_PARM_STACK_SPACE ((!fndecl ? NULL + + (OUTGOING_REG_PARM_STACK_SPACE ((!fndecl ? fntype : TREE_TYPE (fndecl))) ? 0 : reg_parm_stack_space)); 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 was not preallocated, allocate stack space here for arguments 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 && must_preallocate == 0 && reg_parm_stack_space > 0) 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 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 fntype ATTRIBUTE_UNUSED = NULL_TREE; /* library calls default to host calling abi ? */ int inc; int count; 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, 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; 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 map must be allocated for its entire size, not just 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; #ifdef ARGS_GROW_DOWNWARD diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 1f7d506..7f806d4 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -4552,9 +4552,11 @@ ix86_reg_parm_stack_space (const_tree fndecl) /* For libcalls it is possible that there is no fndecl at hand. Therefore assume for this case the default abi of the target. */ if (!fndecl) - call_abi = DEFAULT_ABI; - else + call_abi = (cfun ? cfun->machine->call_abi : DEFAULT_ABI); + else if (TREE_CODE (fndecl) == FUNCTION_DECL) call_abi = ix86_function_abi (fndecl); + else + call_abi = ix86_function_type_abi (fndecl); if (call_abi == 1) return 32; return 0; diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 880884f..7dfb46b 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -3817,6 +3817,8 @@ registers. 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}, 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 machine-dependent stack frame: @code{OUTGOING_REG_PARM_STACK_SPACE} says |