2005-04-01 Michael Snyder <msnyder@redhat.com>

* mn10300-tdep.c (mn10300_frame_unwind_cache): Use
	find_partial_func instead of unwind_pc to identify frame.
	(mn10300_push_dummy_call): Handle struct args, struct_return.
This commit is contained in:
Michael Snyder 2005-04-02 00:40:51 +00:00
parent 9b3c083c83
commit 1fb1ca2782
2 changed files with 45 additions and 13 deletions

View file

@ -1,5 +1,9 @@
2005-04-01 Michael Snyder <msnyder@redhat.com> 2005-04-01 Michael Snyder <msnyder@redhat.com>
* mn10300-tdep.c (mn10300_frame_unwind_cache): Use
find_partial_func instead of unwind_pc to identify frame.
(mn10300_push_dummy_call): Handle struct args, struct_return.
* mn10300-prologue.c (set_movm_offsets): Don't test variable * mn10300-prologue.c (set_movm_offsets): Don't test variable
before setting it. before setting it.
* mn10300-tdep.c (mn10300_skip_prologue): Use analyze_prologue * mn10300-tdep.c (mn10300_skip_prologue): Use analyze_prologue

View file

@ -313,7 +313,7 @@ mn10300_frame_unwind_cache (struct frame_info *next_frame,
void **this_prologue_cache) void **this_prologue_cache)
{ {
struct trad_frame_cache *cache; struct trad_frame_cache *cache;
CORE_ADDR pc; CORE_ADDR pc, start, end;
if (*this_prologue_cache) if (*this_prologue_cache)
return (*this_prologue_cache); return (*this_prologue_cache);
@ -321,7 +321,11 @@ mn10300_frame_unwind_cache (struct frame_info *next_frame,
cache = trad_frame_cache_zalloc (next_frame); cache = trad_frame_cache_zalloc (next_frame);
pc = gdbarch_unwind_pc (current_gdbarch, next_frame); pc = gdbarch_unwind_pc (current_gdbarch, next_frame);
mn10300_analyze_prologue (next_frame, (void **) &cache, pc); mn10300_analyze_prologue (next_frame, (void **) &cache, pc);
if (find_pc_partial_function (pc, NULL, &start, &end))
trad_frame_set_id (cache,
frame_id_build (trad_frame_get_this_base (cache),
start));
else
trad_frame_set_id (cache, trad_frame_set_id (cache,
frame_id_build (trad_frame_get_this_base (cache), frame_id_build (trad_frame_get_this_base (cache),
frame_func_unwind (next_frame))); frame_func_unwind (next_frame)));
@ -445,15 +449,17 @@ mn10300_push_dummy_call (struct gdbarch *gdbarch,
CORE_ADDR struct_addr) CORE_ADDR struct_addr)
{ {
const int push_size = register_size (gdbarch, E_PC_REGNUM); const int push_size = register_size (gdbarch, E_PC_REGNUM);
int regs_used = struct_return ? 1 : 0; int regs_used;
int len, arg_len; int len, arg_len;
int stack_offset = 0; int stack_offset = 0;
int argnum; int argnum;
char *val; char *val, valbuf[MAX_REGISTER_SIZE];
#if 0
/* FIXME temp, don't handle struct args at all. */ /* FIXME temp, don't handle struct args at all. */
if (struct_return) if (struct_return)
error ("Target doesn't handle struct return"); error ("Target doesn't handle struct return");
#endif
/* This should be a nop, but align the stack just in case something /* This should be a nop, but align the stack just in case something
went wrong. Stacks are four byte aligned on the mn10300. */ went wrong. Stacks are four byte aligned on the mn10300. */
@ -463,11 +469,14 @@ mn10300_push_dummy_call (struct gdbarch *gdbarch,
XXX This doesn't appear to handle pass-by-invisible reference XXX This doesn't appear to handle pass-by-invisible reference
arguments. */ arguments. */
regs_used = struct_return ? 1 : 0;
for (len = 0, argnum = 0; argnum < nargs; argnum++) for (len = 0, argnum = 0; argnum < nargs; argnum++)
{ {
arg_len = (TYPE_LENGTH (value_type (args[argnum])) + 3) & ~3; arg_len = (TYPE_LENGTH (value_type (args[argnum])) + 3) & ~3;
#if 0
if (TYPE_CODE (value_type (args[argnum])) == TYPE_CODE_STRUCT) if (TYPE_CODE (value_type (args[argnum])) == TYPE_CODE_STRUCT)
error ("Target does not handle struct args"); error ("Target does not handle struct args");
#endif
while (regs_used < 2 && arg_len > 0) while (regs_used < 2 && arg_len > 0)
{ {
regs_used++; regs_used++;
@ -479,18 +488,37 @@ mn10300_push_dummy_call (struct gdbarch *gdbarch,
/* Allocate stack space. */ /* Allocate stack space. */
sp -= len; sp -= len;
regs_used = struct_return ? 1 : 0; if (struct_return)
{
regs_used = 1;
write_register (E_D0_REGNUM, struct_addr);
}
else
regs_used = 0;
/* Push all arguments onto the stack. */ /* Push all arguments onto the stack. */
for (argnum = 0; argnum < nargs; argnum++) for (argnum = 0; argnum < nargs; argnum++)
{ {
/* FIXME what about structs? */ /* FIXME what about structs? Unions? */
if (TYPE_CODE (value_type (*args)) == TYPE_CODE_STRUCT
&& TYPE_LENGTH (value_type (*args)) > 8)
{
/* Change to pointer-to-type. */
arg_len = push_size;
store_unsigned_integer (valbuf, push_size,
VALUE_ADDRESS (*args));
val = &valbuf[0];
}
else
{
arg_len = TYPE_LENGTH (value_type (*args)); arg_len = TYPE_LENGTH (value_type (*args));
val = (char *) value_contents (*args); val = (char *) value_contents (*args);
}
while (regs_used < 2 && arg_len > 0) while (regs_used < 2 && arg_len > 0)
{ {
write_register (regs_used, extract_unsigned_integer (val, write_register (regs_used,
push_size)); extract_unsigned_integer (val, push_size));
val += push_size; val += push_size;
arg_len -= push_size; arg_len -= push_size;
regs_used++; regs_used++;