aboutsummaryrefslogtreecommitdiff
path: root/gdb/d30v-tdep.c
diff options
context:
space:
mode:
authorDavid Taylor <taylor@redhat.com>1997-12-16 07:43:26 +0000
committerDavid Taylor <taylor@redhat.com>1997-12-16 07:43:26 +0000
commit7ae2b4337a08580658720dd758d36e80eba1ac0e (patch)
tree1ac6951f250357749dcbfb260822c3378e6be96e /gdb/d30v-tdep.c
parenteae435160e165737504d5f423a885a6ca8267fc5 (diff)
downloadfsf-binutils-gdb-7ae2b4337a08580658720dd758d36e80eba1ac0e.zip
fsf-binutils-gdb-7ae2b4337a08580658720dd758d36e80eba1ac0e.tar.gz
fsf-binutils-gdb-7ae2b4337a08580658720dd758d36e80eba1ac0e.tar.bz2
back trace now works when using external memory and frameless functions; all
arguments are passed in args registers until we run out; finding saved regs now has two offsets not just one doing double duty. TARGET_READ_SP / TARGET_WRITE_SP are (temporarily?) commented out.
Diffstat (limited to 'gdb/d30v-tdep.c')
-rw-r--r--gdb/d30v-tdep.c52
1 files changed, 33 insertions, 19 deletions
diff --git a/gdb/d30v-tdep.c b/gdb/d30v-tdep.c
index 50b3d0d..09cd9e3 100644
--- a/gdb/d30v-tdep.c
+++ b/gdb/d30v-tdep.c
@@ -320,7 +320,7 @@ d30v_frame_chain (frame)
if (!read_memory_unsigned_integer(fsr.regs[FP_REGNUM],4))
return (CORE_ADDR)0;
- return read_memory_unsigned_integer(fsr.regs[FP_REGNUM],4)| DMEM_START;
+ return read_memory_unsigned_integer(fsr.regs[FP_REGNUM],4);
}
static int next_addr, uses_frame;
@@ -440,16 +440,16 @@ prologue_find_regs (op, fsr, addr)
if ((op & OP_MASK_ALL_BUT_IMM) == OP_SUB_SP_IMM)
{
offset = EXTRACT_IMM6(op);
- next_addr -= offset;
+ frame_size += -offset;
return 1;
}
- /* st rn, @(sp,0) */
+ /* st rn, @(sp,0) -- observed */
if (((op & OP_MASK_ALL_BUT_RA) == OP_STW_SP_R0) ||
((op & OP_MASK_ALL_BUT_RA) == OP_STW_SP_IMM0))
{
n = EXTRACT_RA(op);
- fsr->regs[n] = next_addr;
+ fsr->regs[n] = (- frame_size);
return 1;
}
@@ -458,8 +458,8 @@ prologue_find_regs (op, fsr, addr)
((op & OP_MASK_ALL_BUT_RA) == OP_ST2W_SP_IMM0))
{
n = EXTRACT_RA(op);
- fsr->regs[n] = next_addr;
- fsr->regs[n+1] = next_addr+4;
+ fsr->regs[n] = (- frame_size);
+ fsr->regs[n+1] = (- frame_size) + 4;
return 1;
}
@@ -490,7 +490,7 @@ d30v_frame_find_saved_regs (fi, fsr)
pc = get_pc_function_start (fi->pc);
uses_frame = 0;
- while (1)
+ while (pc < fi->pc)
{
opl = (unsigned long)read_memory_integer (pc, 4);
opr = (unsigned long)read_memory_integer (pc+4, 4);
@@ -554,7 +554,7 @@ d30v_frame_find_saved_regs (fi, fsr)
}
fi->size = frame_size;
- if (!fp)
+ if (!fp || !uses_frame)
#if 0
fp = read_register(SP_REGNUM) | DMEM_START;
#else
@@ -571,7 +571,7 @@ d30v_frame_find_saved_regs (fi, fsr)
else
fi->return_pc = read_register(LR_REGNUM);
- /* th SP is not normally (ever?) saved, but check anyway */
+ /* the SP is not normally (ever?) saved, but check anyway */
if (!fsr->regs[SP_REGNUM])
{
/* if the FP was saved, that means the current FP is valid, */
@@ -861,27 +861,37 @@ d30v_push_arguments (nargs, args, sp, struct_return, struct_addr)
struct type *arg_type = check_typedef (VALUE_TYPE (arg));
len = TYPE_LENGTH (arg_type);
contents = VALUE_CONTENTS(arg);
- val = extract_signed_integer (contents, len);
if (len > 4)
{
/* we need multiple registers */
int ndx;
- for (ndx = 0; ndx < len; ndx += 4, len -= 4)
+ for (ndx = 0; len > 0; ndx += 8, len -= 8)
{
+ if (regnum & 1)
+ regnum++; /* all args > 4 bytes start in even register */
+
if (regnum < 18)
{
- if (len > 4)
- val = extract_signed_integer (&contents[ndx], 4);
- else
- val = extract_signed_integer (&contents[ndx], len);
+ val = extract_signed_integer (&contents[ndx], 4);
+ write_register (regnum++, val);
+ if (len >= 8)
+ val = extract_signed_integer (&contents[ndx+4], 4);
+ else
+ val = extract_signed_integer (&contents[ndx+4], len-4);
write_register (regnum++, val);
}
else
{
/* no more registers available. put it on the stack */
- sp -= len;
+
+ /* all args > 4 bytes are padded to a multiple of 8 bytes
+ and start on an 8 byte boundary */
+ if (sp & 7)
+ sp -= (sp & 7); /* align it */
+
+ sp -= ((len + 7) & ~7); /* allocate space */
write_memory (sp, &contents[ndx], len);
break;
}
@@ -891,16 +901,20 @@ d30v_push_arguments (nargs, args, sp, struct_return, struct_addr)
{
if (regnum < 18 )
{
+ val = extract_signed_integer (contents, len);
write_register (regnum++, val);
}
else
{
- sp -= len;
- store_address (buffer, len, val);
- write_memory (sp, buffer, len);
+ /* all args are padded to a multiple of 4 bytes (at least) */
+ sp -= ((len + 3) & ~3);
+ write_memory (sp, contents, len);
}
}
}
+ if (sp & 7)
+ /* stack pointer is not on an 8 byte boundary -- align it */
+ sp -= (sp & 7);
return sp;
}