aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKai Tietz <ktietz@gcc.gnu.org>2008-11-26 11:25:38 +0100
committerKai Tietz <ktietz@gcc.gnu.org>2008-11-26 11:25:38 +0100
commit5d059ed962692fac1fca10ede9e25c248c4eb726 (patch)
tree621ef40c81da803e778b7b7894a67ca0ec7220d4
parent89d926785d4e8a8f28318d6d3ea90d634d983e55 (diff)
downloadgcc-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.c24
-rw-r--r--gcc/config/i386/i386.c6
-rw-r--r--gcc/doc/tm.texi2
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