Commit 648fe28b by Richard Henderson Committed by Richard Henderson

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
parent 1813dafd
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.
......
...@@ -2047,7 +2047,7 @@ ia64_expand_prologue () ...@@ -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) ...@@ -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) ...@@ -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. */
......
...@@ -1269,6 +1269,7 @@ enum reg_class ...@@ -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 ...@@ -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 { \ ...@@ -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)
......
/* 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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment