re PR target/3177 (Invalid sibcall optimisation on ia64)
PR target/3177 * config/ia64/ia64.h (CUMULATIVE_ARGS): Add int_regs. (INIT_CUMULATIVE_ARGS, INIT_CUMULATIVE_INCOMING_ARGS): Update. * config/ia64/ia64.c (ia64_function_arg_advance): Set int_regs. (ia64_expand_prologue): Look at int_regs, not words, for number of incomming int regs. From-SVN: r51180
This commit is contained in:
parent
1813dafd90
commit
648fe28b9d
4 changed files with 40 additions and 7 deletions
|
@ -1,3 +1,12 @@
|
|||
2002-03-22 Richard Henderson <rth@redhat.com>
|
||||
|
||||
PR target/3177
|
||||
* config/ia64/ia64.h (CUMULATIVE_ARGS): Add int_regs.
|
||||
(INIT_CUMULATIVE_ARGS, INIT_CUMULATIVE_INCOMING_ARGS): Update.
|
||||
* config/ia64/ia64.c (ia64_function_arg_advance): Set int_regs.
|
||||
(ia64_expand_prologue): Look at int_regs, not words, for number
|
||||
of incomming int regs.
|
||||
|
||||
2002-03-22 Andrew MacLeod <amacleod@redhat.com>
|
||||
|
||||
* expr.c (expand_expr): A RESULT_DECL is part of a call.
|
||||
|
|
|
@ -2047,7 +2047,7 @@ ia64_expand_prologue ()
|
|||
/* We don't need an alloc instruction if we've used no outputs or locals. */
|
||||
if (current_frame_info.n_local_regs == 0
|
||||
&& current_frame_info.n_output_regs == 0
|
||||
&& current_frame_info.n_input_regs <= current_function_args_info.words)
|
||||
&& current_frame_info.n_input_regs <= current_function_args_info.int_regs)
|
||||
{
|
||||
/* If there is no alloc, but there are input registers used, then we
|
||||
need a .regstk directive. */
|
||||
|
@ -3188,14 +3188,14 @@ ia64_function_arg_advance (cum, mode, type, named)
|
|||
FR registers, then FP values must also go in general registers. This can
|
||||
happen when we have a SFmode HFA. */
|
||||
else if (! FLOAT_MODE_P (mode) || cum->fp_regs == MAX_ARGUMENT_SLOTS)
|
||||
return;
|
||||
cum->int_regs = cum->words;
|
||||
|
||||
/* If there is a prototype, then FP values go in a FR register when
|
||||
named, and in a GR registeer when unnamed. */
|
||||
else if (cum->prototype)
|
||||
{
|
||||
if (! named)
|
||||
return;
|
||||
cum->int_regs = cum->words;
|
||||
else
|
||||
/* ??? Complex types should not reach here. */
|
||||
cum->fp_regs += (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT ? 2 : 1);
|
||||
|
@ -3203,10 +3203,11 @@ ia64_function_arg_advance (cum, mode, type, named)
|
|||
/* If there is no prototype, then FP values go in both FR and GR
|
||||
registers. */
|
||||
else
|
||||
/* ??? Complex types should not reach here. */
|
||||
cum->fp_regs += (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT ? 2 : 1);
|
||||
|
||||
return;
|
||||
{
|
||||
/* ??? Complex types should not reach here. */
|
||||
cum->fp_regs += (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT ? 2 : 1);
|
||||
cum->int_regs = cum->words;
|
||||
}
|
||||
}
|
||||
|
||||
/* Implement va_start. */
|
||||
|
|
|
@ -1269,6 +1269,7 @@ enum reg_class
|
|||
typedef struct ia64_args
|
||||
{
|
||||
int words; /* # words of arguments so far */
|
||||
int int_regs; /* # GR registers used so far */
|
||||
int fp_regs; /* # FR registers used so far */
|
||||
int prototype; /* whether function prototyped */
|
||||
} CUMULATIVE_ARGS;
|
||||
|
@ -1279,6 +1280,7 @@ typedef struct ia64_args
|
|||
#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT) \
|
||||
do { \
|
||||
(CUM).words = 0; \
|
||||
(CUM).int_regs = 0; \
|
||||
(CUM).fp_regs = 0; \
|
||||
(CUM).prototype = ((FNTYPE) && TYPE_ARG_TYPES (FNTYPE)) || (LIBNAME); \
|
||||
} while (0)
|
||||
|
@ -1292,6 +1294,7 @@ do { \
|
|||
#define INIT_CUMULATIVE_INCOMING_ARGS(CUM, FNTYPE, LIBNAME) \
|
||||
do { \
|
||||
(CUM).words = 0; \
|
||||
(CUM).int_regs = 0; \
|
||||
(CUM).fp_regs = 0; \
|
||||
(CUM).prototype = 1; \
|
||||
} while (0)
|
||||
|
|
20
gcc/testsuite/gcc.c-torture/execute/20020321-1.c
Normal file
20
gcc/testsuite/gcc.c-torture/execute/20020321-1.c
Normal file
|
@ -0,0 +1,20 @@
|
|||
/* PR 3177 */
|
||||
/* Produced a SIGILL on ia64 with sibcall from F to G. We hadn't
|
||||
widened the register window to allow for the fourth outgoing
|
||||
argument as an "in" register. */
|
||||
|
||||
float g (void *a, void *b, int e, int c, float d)
|
||||
{
|
||||
return d;
|
||||
}
|
||||
|
||||
float f (void *a, void *b, int c, float d)
|
||||
{
|
||||
return g (a, b, 0, c, d);
|
||||
}
|
||||
|
||||
int main ()
|
||||
{
|
||||
f (0, 0, 1, 1);
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Reference in a new issue