Commit 0cdca92b by Dale Johannesen Committed by Dale Johannesen

calls.c (load_register_parameters): Add is_sibcall, sibcall_failure parameters.


2003-01-10  Dale Johannesen <dalej@apple.com>
        * calls.c (load_register_parameters):  Add is_sibcall, sibcall_failure
        parameters.  Call check_sibcall_argument_overlap if indicated.
        (check_sibcall_argument_overlap):  Add mark_stored_args_map
        parameter.  Don't mark parameter area as clobbered if not set.
        (expand_call):  Adjust calls to above.

From-SVN: r61165
parent 43a4a12b
2003-01-10 Kelley Cook <kelleycook@comcast.net> 2003-01-10 Dale Johannesen <dalej@apple.com>
* calls.c (load_register_parameters): Add is_sibcall, sibcall_failure
parameters. Call check_sibcall_argument_overlap if indicated.
(check_sibcall_argument_overlap): Add mark_stored_args_map
parameter. Don't mark parameter area as clobbered if not set.
(expand_call): Adjust calls to above.
2003-01-10 Kelley Cook <kelleycook@comcast.net>
* configure.in (linker read-only and read-write section mixing): * configure.in (linker read-only and read-write section mixing):
Squelch some assembler warnings. Squelch some assembler warnings.
......
...@@ -182,7 +182,8 @@ static void compute_argument_addresses PARAMS ((struct arg_data *, ...@@ -182,7 +182,8 @@ static void compute_argument_addresses PARAMS ((struct arg_data *,
rtx, int)); rtx, int));
static rtx rtx_for_function_call PARAMS ((tree, tree)); static rtx rtx_for_function_call PARAMS ((tree, tree));
static void load_register_parameters PARAMS ((struct arg_data *, static void load_register_parameters PARAMS ((struct arg_data *,
int, rtx *, int)); int, rtx *, int,
int, int *));
static rtx emit_library_call_value_1 PARAMS ((int, rtx, rtx, static rtx emit_library_call_value_1 PARAMS ((int, rtx, rtx,
enum libcall_type, enum libcall_type,
enum machine_mode, enum machine_mode,
...@@ -191,7 +192,8 @@ static int special_function_p PARAMS ((tree, int)); ...@@ -191,7 +192,8 @@ static int special_function_p PARAMS ((tree, int));
static rtx try_to_integrate PARAMS ((tree, tree, rtx, static rtx try_to_integrate PARAMS ((tree, tree, rtx,
int, tree, rtx)); int, tree, rtx));
static int check_sibcall_argument_overlap_1 PARAMS ((rtx)); static int check_sibcall_argument_overlap_1 PARAMS ((rtx));
static int check_sibcall_argument_overlap PARAMS ((rtx, struct arg_data *)); static int check_sibcall_argument_overlap PARAMS ((rtx, struct arg_data *,
int));
static int combine_pending_stack_adjustment_and_call static int combine_pending_stack_adjustment_and_call
PARAMS ((int, struct args_size *, int)); PARAMS ((int, struct args_size *, int));
...@@ -1698,14 +1700,20 @@ rtx_for_function_call (fndecl, exp) ...@@ -1698,14 +1700,20 @@ rtx_for_function_call (fndecl, exp)
expressions were already evaluated. expressions were already evaluated.
Mark all register-parms as living through the call, putting these USE Mark all register-parms as living through the call, putting these USE
insns in the CALL_INSN_FUNCTION_USAGE field. */ insns in the CALL_INSN_FUNCTION_USAGE field.
When IS_SIBCALL, perform the check_sibcall_overlap_argument_overlap
checking, setting *SIBCALL_FAILURE if appropriate. */
static void static void
load_register_parameters (args, num_actuals, call_fusage, flags) load_register_parameters (args, num_actuals, call_fusage, flags,
is_sibcall, sibcall_failure)
struct arg_data *args; struct arg_data *args;
int num_actuals; int num_actuals;
rtx *call_fusage; rtx *call_fusage;
int flags; int flags;
int is_sibcall;
int *sibcall_failure;
{ {
int i, j; int i, j;
...@@ -1722,6 +1730,7 @@ load_register_parameters (args, num_actuals, call_fusage, flags) ...@@ -1722,6 +1730,7 @@ load_register_parameters (args, num_actuals, call_fusage, flags)
if (reg) if (reg)
{ {
rtx before_arg = get_last_insn ();
/* Set to non-negative if must move a word at a time, even if just /* Set to non-negative if must move a word at a time, even if just
one word (e.g, partial == 1 && mode == DFmode). Set to -1 if one word (e.g, partial == 1 && mode == DFmode). Set to -1 if
we just use a normal move insn. This value can be zero if the we just use a normal move insn. This value can be zero if the
...@@ -1759,6 +1768,13 @@ load_register_parameters (args, num_actuals, call_fusage, flags) ...@@ -1759,6 +1768,13 @@ load_register_parameters (args, num_actuals, call_fusage, flags)
validize_mem (args[i].value), nregs, validize_mem (args[i].value), nregs,
args[i].mode); args[i].mode);
/* When a parameter is a block, and perhaps in other cases, it is
possible that it did a load from an argument slot that was
already clobbered. */
if (is_sibcall
&& check_sibcall_argument_overlap (before_arg, &args[i], 0))
*sibcall_failure = 1;
/* Handle calls that pass values in multiple non-contiguous /* Handle calls that pass values in multiple non-contiguous
locations. The Irix 6 ABI has examples of this. */ locations. The Irix 6 ABI has examples of this. */
if (GET_CODE (reg) == PARALLEL) if (GET_CODE (reg) == PARALLEL)
...@@ -2015,14 +2031,16 @@ check_sibcall_argument_overlap_1 (x) ...@@ -2015,14 +2031,16 @@ check_sibcall_argument_overlap_1 (x)
/* Scan sequence after INSN if it does not dereference any argument slots /* Scan sequence after INSN if it does not dereference any argument slots
we already clobbered by tail call arguments (as noted in stored_args_map we already clobbered by tail call arguments (as noted in stored_args_map
bitmap). Add stack slots for ARG to stored_args_map bitmap afterwards. bitmap). If MARK_STORED_ARGS_MAP, add stack slots for ARG to
Return nonzero if sequence after INSN dereferences such argument slots, stored_args_map bitmap afterwards (when ARG is a register MARK_STORED_ARGS_MAP
zero otherwise. */ should be 0). Return nonzero if sequence after INSN dereferences such argument
slots, zero otherwise. */
static int static int
check_sibcall_argument_overlap (insn, arg) check_sibcall_argument_overlap (insn, arg, mark_stored_args_map)
rtx insn; rtx insn;
struct arg_data *arg; struct arg_data *arg;
int mark_stored_args_map;
{ {
int low, high; int low, high;
...@@ -2036,6 +2054,8 @@ check_sibcall_argument_overlap (insn, arg) ...@@ -2036,6 +2054,8 @@ check_sibcall_argument_overlap (insn, arg)
&& check_sibcall_argument_overlap_1 (PATTERN (insn))) && check_sibcall_argument_overlap_1 (PATTERN (insn)))
break; break;
if (mark_stored_args_map)
{
#ifdef ARGS_GROW_DOWNWARD #ifdef ARGS_GROW_DOWNWARD
low = -arg->slot_offset.constant - arg->size.constant; low = -arg->slot_offset.constant - arg->size.constant;
#else #else
...@@ -2044,6 +2064,7 @@ check_sibcall_argument_overlap (insn, arg) ...@@ -2044,6 +2064,7 @@ check_sibcall_argument_overlap (insn, arg)
for (high = low + arg->size.constant; low < high; low++) for (high = low + arg->size.constant; low < high; low++)
SET_BIT (stored_args_map, low); SET_BIT (stored_args_map, low);
}
return insn != NULL_RTX; return insn != NULL_RTX;
} }
...@@ -2959,7 +2980,7 @@ expand_call (exp, target, ignore) ...@@ -2959,7 +2980,7 @@ expand_call (exp, target, ignore)
reg_parm_stack_space) reg_parm_stack_space)
|| (pass == 0 || (pass == 0
&& check_sibcall_argument_overlap (before_arg, && check_sibcall_argument_overlap (before_arg,
&args[i]))) &args[i], 1)))
sibcall_failure = 1; sibcall_failure = 1;
} }
...@@ -2983,7 +3004,7 @@ expand_call (exp, target, ignore) ...@@ -2983,7 +3004,7 @@ expand_call (exp, target, ignore)
reg_parm_stack_space) reg_parm_stack_space)
|| (pass == 0 || (pass == 0
&& check_sibcall_argument_overlap (before_arg, && check_sibcall_argument_overlap (before_arg,
&args[i]))) &args[i], 1)))
sibcall_failure = 1; sibcall_failure = 1;
} }
...@@ -3018,7 +3039,8 @@ expand_call (exp, target, ignore) ...@@ -3018,7 +3039,8 @@ expand_call (exp, target, ignore)
funexp = prepare_call_address (funexp, fndecl, &call_fusage, funexp = prepare_call_address (funexp, fndecl, &call_fusage,
reg_parm_seen, pass == 0); reg_parm_seen, pass == 0);
load_register_parameters (args, num_actuals, &call_fusage, flags); load_register_parameters (args, num_actuals, &call_fusage, flags,
pass == 0, &sibcall_failure);
/* Perform postincrements before actually calling the function. */ /* Perform postincrements before actually calling the function. */
emit_queue (); emit_queue ();
......
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