aboutsummaryrefslogtreecommitdiff
path: root/gdb/sh-tdep.c
diff options
context:
space:
mode:
authorSteve Chamberlain <sac@cygnus>1994-09-09 00:35:09 +0000
committerSteve Chamberlain <sac@cygnus>1994-09-09 00:35:09 +0000
commitc4deed18c0fd02ae4a9fffca7c0a21bb572dbd9d (patch)
treef12937acf4fd49e2b4ca1afdcaa38c8ef861e804 /gdb/sh-tdep.c
parenteb4fd16f4d64e76336c027f91d8254e53e403dd8 (diff)
downloadgdb-c4deed18c0fd02ae4a9fffca7c0a21bb572dbd9d.zip
gdb-c4deed18c0fd02ae4a9fffca7c0a21bb572dbd9d.tar.gz
gdb-c4deed18c0fd02ae4a9fffca7c0a21bb572dbd9d.tar.bz2
Thu Sep 8 17:14:43 1994 Steve Chamberlain (sac@jonny.cygnus.com)
* remote.c (fromhex): Make error more explicit. (read_frame): Don't print bad checksum information unless remote_debugging. Don't use repeat count unless it's > 0. * remote-e7000.c (expect): When echoing, ignore multiple newlines. (e7000_insert_breakpoint, e7000_remove_breakpoint, target_ops): Optionally cope with BC style breakpoints. (e7000_command): After command send directly to the E7000 mark registers as changed. (why_stop, e7000_wait: Understand BC style stop condition. * sh-tdep.c (sh_skip_prologue): Understand more complicated sequences. (frame_find_saved_regs): Likewise. * config/h8500/tm-h8500.h (target_write_pc, TARGET_WRITE_PC): Handle extra arg. * config/i386/xm-go32.h (GDBINIT_FILENAME): Set to gdb.ini. (more work here to come) * config/sh/tm-sh.h (EXTRA_FRAME_INFO): Add f_offset and leaf_function fields.
Diffstat (limited to 'gdb/sh-tdep.c')
-rw-r--r--gdb/sh-tdep.c58
1 files changed, 48 insertions, 10 deletions
diff --git a/gdb/sh-tdep.c b/gdb/sh-tdep.c
index c965926..4973d8f 100644
--- a/gdb/sh-tdep.c
+++ b/gdb/sh-tdep.c
@@ -47,7 +47,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#define GET_PUSHED_REG(x) (((x) >> 4) & 0xf)
#define IS_MOV_SP_FP(x) ((x) == 0x6ef3)
#define IS_ADD_SP(x) (((x) & 0xff00) == 0x7f00)
-
+#define IS_MOV_R3(x) (((x) & 0xff00) == 0x1a00)
+#define IS_SHLL_R3(x) ((x) == 0x4300)
+#define IS_ADD_R3SP(x) ((x) == 0x3f3c)
/* Skip any prologue before the guts of a function */
@@ -61,7 +63,11 @@ sh_skip_prologue (start_pc)
w = read_memory_integer (start_pc, 2);
while (IS_STS (w)
|| IS_PUSH (w)
- || IS_MOV_SP_FP (w))
+ || IS_MOV_SP_FP (w)
+ || IS_MOV_R3(w)
+ || IS_ADD_R3SP(w)
+ || IS_ADD_SP(w)
+ || IS_SHLL_R3(w))
{
start_pc += 2;
w = read_memory_integer (start_pc, 2);
@@ -94,7 +100,7 @@ sh_frame_chain (thisframe)
FRAME thisframe;
{
if (!inside_entry_file (thisframe->pc))
- return (read_memory_integer (FRAME_FP (thisframe), 4));
+ return (read_memory_integer (FRAME_FP (thisframe) + thisframe->f_offset, 4));
else
return 0;
}
@@ -118,11 +124,16 @@ frame_find_saved_regs (fi, fsr)
int pc;
int opc;
int insn;
+ int hadf;
+ int r3_val = 0;
opc = pc = get_pc_function_start (fi->pc);
insn = read_memory_integer (pc, 2);
+ fi->leaf_function = 1;
+ fi->f_offset = 0;
+
for (rn = 0; rn < NUM_REGS; rn++)
where[rn] = -1;
@@ -146,8 +157,28 @@ frame_find_saved_regs (fi, fsr)
pc += 2;
where[PR_REGNUM] = depth;
insn = read_memory_integer (pc, 2);
+ /* If we're storing the pr then this isn't a leaf */
+ fi->leaf_function = 0;
depth += 4;
}
+ else if (IS_MOV_R3 (insn))
+ {
+ r3_val = (char)(insn & 0xff);
+ pc+=2;
+ insn = read_memory_integer (pc, 2);
+ }
+ else if (IS_SHLL_R3 (insn))
+ {
+ r3_val <<=1;
+ pc+=2;
+ insn = read_memory_integer (pc, 2);
+ }
+ else if (IS_ADD_R3SP (insn))
+ {
+ depth += -r3_val;
+ pc+=2;
+ insn = read_memory_integer (pc, 2);
+ }
else if (IS_ADD_SP (insn))
{
pc += 2;
@@ -184,18 +215,25 @@ frame_find_saved_regs (fi, fsr)
fsr->regs[SP_REGNUM] = fi->frame - 4;
}
-
+ fi->f_offset = depth - where[FP_REGNUM] - 4;
/* Work out the return pc - either from the saved pr or the pr
value */
-
- if (fsr->regs[PR_REGNUM])
- {
- fi->return_pc = read_memory_integer (fsr->regs[PR_REGNUM], 4) + 4;
- }
- else
+ /* Just called, so dig out the real return */
+ if (fi->return_pc == 0)
{
fi->return_pc = read_register (PR_REGNUM) + 4;
}
+ else {
+
+ if (fsr->regs[PR_REGNUM])
+ {
+ fi->return_pc = read_memory_integer (fsr->regs[PR_REGNUM], 4) + 4;
+ }
+ else
+ {
+ fi->return_pc = read_register (PR_REGNUM) + 4;
+ }
+ }
}
/* initialize the extra info saved in a FRAME */