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:
Richard Henderson 2002-03-22 11:23:05 -08:00 committed by Richard Henderson
parent 1813dafd90
commit 648fe28b9d
4 changed files with 40 additions and 7 deletions

View File

@ -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> 2002-03-22 Andrew MacLeod <amacleod@redhat.com>
* expr.c (expand_expr): A RESULT_DECL is part of a call. * expr.c (expand_expr): A RESULT_DECL is part of a call.

View File

@ -2047,7 +2047,7 @@ ia64_expand_prologue ()
/* We don't need an alloc instruction if we've used no outputs or locals. */ /* We don't need an alloc instruction if we've used no outputs or locals. */
if (current_frame_info.n_local_regs == 0 if (current_frame_info.n_local_regs == 0
&& current_frame_info.n_output_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 /* If there is no alloc, but there are input registers used, then we
need a .regstk directive. */ 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 FR registers, then FP values must also go in general registers. This can
happen when we have a SFmode HFA. */ happen when we have a SFmode HFA. */
else if (! FLOAT_MODE_P (mode) || cum->fp_regs == MAX_ARGUMENT_SLOTS) 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 /* If there is a prototype, then FP values go in a FR register when
named, and in a GR registeer when unnamed. */ named, and in a GR registeer when unnamed. */
else if (cum->prototype) else if (cum->prototype)
{ {
if (! named) if (! named)
return; cum->int_regs = cum->words;
else else
/* ??? Complex types should not reach here. */ /* ??? Complex types should not reach here. */
cum->fp_regs += (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT ? 2 : 1); 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 /* If there is no prototype, then FP values go in both FR and GR
registers. */ registers. */
else else
/* ??? Complex types should not reach here. */ {
cum->fp_regs += (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT ? 2 : 1); /* ??? Complex types should not reach here. */
cum->fp_regs += (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT ? 2 : 1);
return; cum->int_regs = cum->words;
}
} }
/* Implement va_start. */ /* Implement va_start. */

View File

@ -1269,6 +1269,7 @@ enum reg_class
typedef struct ia64_args typedef struct ia64_args
{ {
int words; /* # words of arguments so far */ int words; /* # words of arguments so far */
int int_regs; /* # GR registers used so far */
int fp_regs; /* # FR registers used so far */ int fp_regs; /* # FR registers used so far */
int prototype; /* whether function prototyped */ int prototype; /* whether function prototyped */
} CUMULATIVE_ARGS; } CUMULATIVE_ARGS;
@ -1279,6 +1280,7 @@ typedef struct ia64_args
#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT) \ #define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT) \
do { \ do { \
(CUM).words = 0; \ (CUM).words = 0; \
(CUM).int_regs = 0; \
(CUM).fp_regs = 0; \ (CUM).fp_regs = 0; \
(CUM).prototype = ((FNTYPE) && TYPE_ARG_TYPES (FNTYPE)) || (LIBNAME); \ (CUM).prototype = ((FNTYPE) && TYPE_ARG_TYPES (FNTYPE)) || (LIBNAME); \
} while (0) } while (0)
@ -1292,6 +1294,7 @@ do { \
#define INIT_CUMULATIVE_INCOMING_ARGS(CUM, FNTYPE, LIBNAME) \ #define INIT_CUMULATIVE_INCOMING_ARGS(CUM, FNTYPE, LIBNAME) \
do { \ do { \
(CUM).words = 0; \ (CUM).words = 0; \
(CUM).int_regs = 0; \
(CUM).fp_regs = 0; \ (CUM).fp_regs = 0; \
(CUM).prototype = 1; \ (CUM).prototype = 1; \
} while (0) } while (0)

View 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;
}