summaryrefslogtreecommitdiff
path: root/gdb/d10v-tdep.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/d10v-tdep.c')
-rw-r--r--gdb/d10v-tdep.c137
1 files changed, 68 insertions, 69 deletions
diff --git a/gdb/d10v-tdep.c b/gdb/d10v-tdep.c
index 5cbdddcdce5..0fe222ec2fe 100644
--- a/gdb/d10v-tdep.c
+++ b/gdb/d10v-tdep.c
@@ -616,8 +616,11 @@ struct d10v_unwind_cache
CORE_ADDR base;
int size;
CORE_ADDR *saved_regs;
- LONGEST next_addr;
- LONGEST r11_addr;
+ /* How far the SP and r11 (FP) have been offset from the start of
+ the stack frame (as defined by the previous frame's stack
+ pointer). */
+ LONGEST sp_offset;
+ LONGEST r11_offset;
int uses_frame;
void **regs;
};
@@ -632,8 +635,8 @@ prologue_find_regs (struct d10v_unwind_cache *info, unsigned short op,
if ((op & 0x7E1F) == 0x6C1F)
{
n = (op & 0x1E0) >> 5;
- info->next_addr -= 2;
- info->saved_regs[n] = info->next_addr;
+ info->sp_offset -= 2;
+ info->saved_regs[n] = info->sp_offset;
return 1;
}
@@ -641,9 +644,9 @@ prologue_find_regs (struct d10v_unwind_cache *info, unsigned short op,
else if ((op & 0x7E3F) == 0x6E1F)
{
n = (op & 0x1E0) >> 5;
- info->next_addr -= 4;
- info->saved_regs[n] = info->next_addr;
- info->saved_regs[n + 1] = info->next_addr + 2;
+ info->sp_offset -= 4;
+ info->saved_regs[n] = info->sp_offset;
+ info->saved_regs[n + 1] = info->sp_offset + 2;
return 1;
}
@@ -653,7 +656,7 @@ prologue_find_regs (struct d10v_unwind_cache *info, unsigned short op,
n = (op & 0x1E) >> 1;
if (n == 0)
n = 16;
- info->next_addr -= n;
+ info->sp_offset -= n;
return 1;
}
@@ -661,7 +664,7 @@ prologue_find_regs (struct d10v_unwind_cache *info, unsigned short op,
if (op == 0x417E)
{
info->uses_frame = 1;
- info->r11_addr = info->next_addr;
+ info->r11_offset = info->sp_offset;
return 1;
}
@@ -669,7 +672,7 @@ prologue_find_regs (struct d10v_unwind_cache *info, unsigned short op,
if ((op & 0x7E1F) == 0x6816)
{
n = (op & 0x1E0) >> 5;
- info->saved_regs[n] = info->r11_addr;
+ info->saved_regs[n] = info->r11_offset;
return 1;
}
@@ -681,7 +684,7 @@ prologue_find_regs (struct d10v_unwind_cache *info, unsigned short op,
if ((op & 0x7E1F) == 0x681E)
{
n = (op & 0x1E0) >> 5;
- info->saved_regs[n] = info->next_addr;
+ info->saved_regs[n] = info->sp_offset;
return 1;
}
@@ -689,8 +692,8 @@ prologue_find_regs (struct d10v_unwind_cache *info, unsigned short op,
if ((op & 0x7E3F) == 0x3A1E)
{
n = (op & 0x1E0) >> 5;
- info->saved_regs[n] = info->next_addr;
- info->saved_regs[n + 1] = info->next_addr + 2;
+ info->saved_regs[n] = info->sp_offset;
+ info->saved_regs[n + 1] = info->sp_offset + 2;
return 1;
}
@@ -708,8 +711,8 @@ d10v_frame_unwind_cache (struct frame_info *next_frame,
void **this_cache)
{
CORE_ADDR pc;
- ULONGEST sp;
- ULONGEST base;
+ ULONGEST prev_sp;
+ ULONGEST this_base;
unsigned long op;
unsigned short op1, op2;
int i;
@@ -724,7 +727,7 @@ d10v_frame_unwind_cache (struct frame_info *next_frame,
info->size = 0;
- info->next_addr = 0;
+ info->sp_offset = 0;
pc = get_pc_function_start (frame_pc_unwind (next_frame));
@@ -739,22 +742,22 @@ d10v_frame_unwind_cache (struct frame_info *next_frame,
{
/* add3 sp,sp,n */
short n = op & 0xFFFF;
- info->next_addr += n;
+ info->sp_offset += n;
}
else if ((op & 0x3F0F0000) == 0x340F0000)
{
/* st rn, @(offset,sp) */
short offset = op & 0xFFFF;
short n = (op >> 20) & 0xF;
- info->saved_regs[n] = info->next_addr + offset;
+ info->saved_regs[n] = info->sp_offset + offset;
}
else if ((op & 0x3F1F0000) == 0x350F0000)
{
/* st2w rn, @(offset,sp) */
short offset = op & 0xFFFF;
short n = (op >> 20) & 0xF;
- info->saved_regs[n] = info->next_addr + offset;
- info->saved_regs[n + 1] = info->next_addr + offset + 2;
+ info->saved_regs[n] = info->sp_offset + offset;
+ info->saved_regs[n + 1] = info->sp_offset + offset + 2;
}
else
break;
@@ -779,52 +782,50 @@ d10v_frame_unwind_cache (struct frame_info *next_frame,
pc += 4;
}
- info->size = -info->next_addr;
+ info->size = -info->sp_offset;
- /* Compute the frame's base. */
+ /* Compute the frame's base, and the previous frame's SP. */
if (info->uses_frame)
{
- /* The SP was moved into the FP. This indicates that a new
- frame was created. Get THIS frame's FP value by unwinding it
- from the next frame. */
- frame_unwind_unsigned_register (next_frame, FP_REGNUM, &base);
+ /* The SP was moved to the FP. This indicates that a new frame
+ was created. Get THIS frame's FP value by unwinding it from
+ the next frame. */
+ frame_unwind_unsigned_register (next_frame, FP_REGNUM, &this_base);
/* The FP points at the last saved register. Adjust the FP back
to before the first saved register giving the SP. */
- sp = base + info->size;
+ prev_sp = this_base + info->size;
}
else if (info->saved_regs[SP_REGNUM])
{
/* The SP was saved (which is very unusual), the frame base is
just the PREV's frame's TOP-OF-STACK. */
- base = read_memory_unsigned_integer (info->saved_regs[SP_REGNUM],
- register_size (current_gdbarch,
- SP_REGNUM));
- sp = base;
+ this_base = read_memory_unsigned_integer (info->saved_regs[SP_REGNUM],
+ register_size (current_gdbarch,
+ SP_REGNUM));
+ prev_sp = this_base;
}
else
{
/* Assume that the FP is this frame's SP but with that pushed
stack space added back. */
- frame_unwind_unsigned_register (next_frame, SP_REGNUM, &base);
- sp = base + info->size;
+ frame_unwind_unsigned_register (next_frame, SP_REGNUM, &this_base);
+ prev_sp = this_base + info->size;
}
- info->base = d10v_make_daddr (base);
- sp = d10v_make_daddr (sp);
+ info->base = d10v_make_daddr (this_base);
+ prev_sp = d10v_make_daddr (prev_sp);
/* Adjust all the saved registers so that they contain addresses and
not offsets. */
for (i = 0; i < NUM_REGS - 1; i++)
- {
- if (info->saved_regs[i])
- {
- info->saved_regs[i] = (sp + info->saved_regs[i]);
- }
- }
+ if (info->saved_regs[i])
+ {
+ info->saved_regs[i] = (prev_sp + info->saved_regs[i]);
+ }
/* The SP_REGNUM is special. Instead of the address of the SP, the
previous frame's SP value is saved. */
- info->saved_regs[SP_REGNUM] = sp;
+ info->saved_regs[SP_REGNUM] = prev_sp;
return info;
}
@@ -1432,22 +1433,12 @@ display_trace (int low, int high)
}
}
-
static CORE_ADDR
-d10v_frame_pc_unwind (struct frame_info *next_frame,
- void **this_cache)
+d10v_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
{
- /* FIXME: This shouldn't be needed. Instead single per-architecture
- method should be called for all frames. */
- CORE_ADDR lr;
- struct d10v_unwind_cache *info
- = d10v_frame_unwind_cache (next_frame, this_cache);
- void *buffer = alloca (max_register_size (current_gdbarch));
- saved_regs_unwind (next_frame, info->saved_regs, LR_REGNUM, buffer);
- lr = extract_unsigned_integer (buffer, register_size (current_gdbarch,
- LR_REGNUM));
- return d10v_make_iaddr (lr);
-
+ ULONGEST pc;
+ frame_unwind_unsigned_register (next_frame, PC_REGNUM, &pc);
+ return d10v_make_iaddr (pc);
}
/* Given the next frame, determine the address of this function's
@@ -1587,18 +1578,6 @@ d10v_frame_register_unwind (struct frame_info *next_frame,
lvalp, addrp, realnump, bufferp);
}
-
-static struct frame_id
-d10v_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
-{
- ULONGEST base;
- struct frame_id id;
- id.pc = frame_pc_unwind (next_frame);
- frame_unwind_unsigned_register (next_frame, SP_REGNUM, &base);
- id.base = d10v_make_daddr (base);
- return id;
-}
-
static void
d10v_frame_pop (struct frame_info *next_frame, void **this_cache,
struct regcache *regcache)
@@ -1635,7 +1614,6 @@ d10v_frame_pop (struct frame_info *next_frame, void **this_cache,
static struct frame_unwind d10v_frame_unwind = {
d10v_frame_pop,
- d10v_frame_pc_unwind,
d10v_frame_id_unwind,
d10v_frame_register_unwind
};
@@ -1646,6 +1624,22 @@ d10v_frame_p (CORE_ADDR pc)
return &d10v_frame_unwind;
}
+/* Assuming NEXT_FRAME->prev is a dummy, return the frame ID of that
+ dummy frame. The frame ID's base needs to match the TOS value
+ saved by save_dummy_frame_tos(), and the PC match the dummy frame's
+ breakpoint. */
+
+static struct frame_id
+d10v_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
+{
+ ULONGEST base;
+ struct frame_id id;
+ id.pc = frame_pc_unwind (next_frame);
+ frame_unwind_unsigned_register (next_frame, SP_REGNUM, &base);
+ id.base = d10v_make_daddr (base);
+ return id;
+}
+
static gdbarch_init_ftype d10v_gdbarch_init;
static struct gdbarch *
@@ -1782,9 +1776,14 @@ d10v_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
set_gdbarch_print_registers_info (gdbarch, d10v_print_registers_info);
frame_unwind_append_predicate (gdbarch, d10v_frame_p);
+
+ /* Methods for saving / extracting a dummy frame's ID. */
set_gdbarch_unwind_dummy_id (gdbarch, d10v_unwind_dummy_id);
set_gdbarch_save_dummy_frame_tos (gdbarch, generic_save_dummy_frame_tos);
+ /* Return the unwound PC value. */
+ set_gdbarch_unwind_pc (gdbarch, d10v_unwind_pc);
+
return gdbarch;
}