aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Blandy <jimb@codesourcery.com>2001-05-09 02:44:01 +0000
committerJim Blandy <jimb@codesourcery.com>2001-05-09 02:44:01 +0000
commitae83b20d8f8eff60f8bd9d7a131f7f60b06db772 (patch)
treeaeaa7e456aedb3bb9fd4920c45000ce961d4dff0
parentbf4b70a5e89748322ccec3aa1c2423fee502e100 (diff)
downloadgdb-ae83b20d8f8eff60f8bd9d7a131f7f60b06db772.zip
gdb-ae83b20d8f8eff60f8bd9d7a131f7f60b06db772.tar.gz
gdb-ae83b20d8f8eff60f8bd9d7a131f7f60b06db772.tar.bz2
Correct and expand handling of `movm' instruction, and register
saves in general. * config/mn10300/tm-mn10300.h (D0_REGNUM, A0_REGNUM, MDRQ_REGNUM, MCRH_REGNUM, MCRL_REGNUM, MCVF_REGNUM): New definitions. (enum movm_register_bits): New enum. * mn10300-tdep.c (set_movm_offsets): Use symbolic names for the bits, not hex literals. Handle the `other', `exreg0', and `exother' bits. Correct handling of `exreg1': it saves r4, r5, r6, and r7, not r2, r3, r4, and r5. (saved_regs_size): New function. (mn10300_frame_chain, mn10300_frame_saved_pc): Use it, instead of computing the same thing inline, incorrectly.
-rw-r--r--gdb/ChangeLog13
-rw-r--r--gdb/config/mn10300/tm-mn10300.h17
-rw-r--r--gdb/mn10300-tdep.c106
3 files changed, 101 insertions, 35 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index ae6ea44..6714b67 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,18 @@
2001-05-08 Jim Blandy <jimb@redhat.com>
+ Correct and expand handling of `movm' instruction, and register
+ saves in general.
+ * config/mn10300/tm-mn10300.h (D0_REGNUM, A0_REGNUM, MDRQ_REGNUM,
+ MCRH_REGNUM, MCRL_REGNUM, MCVF_REGNUM): New definitions.
+ (enum movm_register_bits): New enum.
+ * mn10300-tdep.c (set_movm_offsets): Use symbolic names for the
+ bits, not hex literals. Handle the `other', `exreg0', and
+ `exother' bits. Correct handling of `exreg1': it saves r4, r5,
+ r6, and r7, not r2, r3, r4, and r5.
+ (saved_regs_size): New function.
+ (mn10300_frame_chain, mn10300_frame_saved_pc): Use it, instead
+ of computing the same thing inline, incorrectly.
+
* mn10300-tdep.c (mn10300_gdbarch_init): We do have a
dummy_breakpoint_offset; it's zero.
diff --git a/gdb/config/mn10300/tm-mn10300.h b/gdb/config/mn10300/tm-mn10300.h
index 87d8423..5178015 100644
--- a/gdb/config/mn10300/tm-mn10300.h
+++ b/gdb/config/mn10300/tm-mn10300.h
@@ -43,8 +43,10 @@
#define REGISTER_RAW_SIZE(REG) 4
#endif
+#define D0_REGNUM 0
#define D2_REGNUM 2
#define D3_REGNUM 3
+#define A0_REGNUM 4
#define A2_REGNUM 6
#define A3_REGNUM 7
#define SP_REGNUM 8
@@ -53,7 +55,22 @@
#define PSW_REGNUM 11
#define LIR_REGNUM 12
#define LAR_REGNUM 13
+#define MDRQ_REGNUM 14
#define E0_REGNUM 15
+#define MCRH_REGNUM 26
+#define MCRL_REGNUM 27
+#define MCVF_REGNUM 28
+
+enum movm_register_bits {
+ movm_exother_bit = 0x01,
+ movm_exreg1_bit = 0x02,
+ movm_exreg0_bit = 0x04,
+ movm_other_bit = 0x08,
+ movm_a3_bit = 0x10,
+ movm_a2_bit = 0x20,
+ movm_d3_bit = 0x40,
+ movm_d2_bit = 0x80
+};
#define INIT_FRAME_PC /* Not necessary */
diff --git a/gdb/mn10300-tdep.c b/gdb/mn10300-tdep.c
index ca73a06..ae7d2f5 100644
--- a/gdb/mn10300-tdep.c
+++ b/gdb/mn10300-tdep.c
@@ -197,32 +197,66 @@ set_movm_offsets (struct frame_info *fi, int movm_args)
if (fi == NULL || movm_args == 0)
return;
- if (movm_args & 0x10)
+ if (movm_args & movm_other_bit)
+ {
+ /* The `other' bit leaves a blank area of four bytes at the
+ beginning of its block of saved registers, making it 32 bytes
+ long in total. */
+ fi->saved_regs[LAR_REGNUM] = fi->frame + offset + 4;
+ fi->saved_regs[LIR_REGNUM] = fi->frame + offset + 8;
+ fi->saved_regs[MDR_REGNUM] = fi->frame + offset + 12;
+ fi->saved_regs[A0_REGNUM + 1] = fi->frame + offset + 16;
+ fi->saved_regs[A0_REGNUM] = fi->frame + offset + 20;
+ fi->saved_regs[D0_REGNUM + 1] = fi->frame + offset + 24;
+ fi->saved_regs[D0_REGNUM] = fi->frame + offset + 28;
+ offset += 32;
+ }
+ if (movm_args & movm_a3_bit)
{
fi->saved_regs[A3_REGNUM] = fi->frame + offset;
offset += 4;
}
- if (movm_args & 0x20)
+ if (movm_args & movm_a2_bit)
{
fi->saved_regs[A2_REGNUM] = fi->frame + offset;
offset += 4;
}
- if (movm_args & 0x40)
+ if (movm_args & movm_d3_bit)
{
fi->saved_regs[D3_REGNUM] = fi->frame + offset;
offset += 4;
}
- if (movm_args & 0x80)
+ if (movm_args & movm_d2_bit)
{
fi->saved_regs[D2_REGNUM] = fi->frame + offset;
offset += 4;
}
- if (AM33_MODE && movm_args & 0x02)
+ if (AM33_MODE)
{
- fi->saved_regs[E0_REGNUM + 5] = fi->frame + offset;
- fi->saved_regs[E0_REGNUM + 4] = fi->frame + offset + 4;
- fi->saved_regs[E0_REGNUM + 3] = fi->frame + offset + 8;
- fi->saved_regs[E0_REGNUM + 2] = fi->frame + offset + 12;
+ if (movm_args & movm_exother_bit)
+ {
+ fi->saved_regs[MCVF_REGNUM] = fi->frame + offset;
+ fi->saved_regs[MCRL_REGNUM] = fi->frame + offset + 4;
+ fi->saved_regs[MCRH_REGNUM] = fi->frame + offset + 8;
+ fi->saved_regs[MDRQ_REGNUM] = fi->frame + offset + 12;
+ fi->saved_regs[E0_REGNUM + 1] = fi->frame + offset + 16;
+ fi->saved_regs[E0_REGNUM + 0] = fi->frame + offset + 20;
+ offset += 24;
+ }
+ if (movm_args & movm_exreg1_bit)
+ {
+ fi->saved_regs[E0_REGNUM + 7] = fi->frame + offset;
+ fi->saved_regs[E0_REGNUM + 6] = fi->frame + offset + 4;
+ fi->saved_regs[E0_REGNUM + 5] = fi->frame + offset + 8;
+ fi->saved_regs[E0_REGNUM + 4] = fi->frame + offset + 12;
+ offset += 16;
+ }
+ if (movm_args & movm_exreg0_bit)
+ {
+ fi->saved_regs[E0_REGNUM + 3] = fi->frame + offset;
+ fi->saved_regs[E0_REGNUM + 2] = fi->frame + offset + 4;
+ offset += 8;
+ }
}
}
@@ -510,6 +544,32 @@ mn10300_analyze_prologue (struct frame_info *fi, CORE_ADDR pc)
return addr;
}
+
+/* Function: saved_regs_size
+ Return the size in bytes of the register save area, based on the
+ saved_regs array in FI. */
+static int
+saved_regs_size (struct frame_info *fi)
+{
+ int adjust = 0;
+ int i;
+
+ /* Reserve four bytes for every register saved. */
+ for (i = 0; i < NUM_REGS; i++)
+ if (fi->saved_regs[i])
+ adjust += 4;
+
+ /* If we saved LIR, then it's most likely we used a `movm'
+ instruction with the `other' bit set, in which case the SP is
+ decremented by an extra four bytes, "to simplify calculation
+ of the transfer area", according to the processor manual. */
+ if (fi->saved_regs[LIR_REGNUM])
+ adjust += 4;
+
+ return adjust;
+}
+
+
/* Function: frame_chain
Figure out and return the caller's frame pointer given current
frame_info struct.
@@ -560,19 +620,7 @@ mn10300_frame_chain (struct frame_info *fi)
}
else
{
- int adjust = 0;
-
- adjust += (fi->saved_regs[D2_REGNUM] ? 4 : 0);
- adjust += (fi->saved_regs[D3_REGNUM] ? 4 : 0);
- adjust += (fi->saved_regs[A2_REGNUM] ? 4 : 0);
- adjust += (fi->saved_regs[A3_REGNUM] ? 4 : 0);
- if (AM33_MODE)
- {
- adjust += (fi->saved_regs[E0_REGNUM + 5] ? 4 : 0);
- adjust += (fi->saved_regs[E0_REGNUM + 4] ? 4 : 0);
- adjust += (fi->saved_regs[E0_REGNUM + 3] ? 4 : 0);
- adjust += (fi->saved_regs[E0_REGNUM + 2] ? 4 : 0);
- }
+ int adjust = saved_regs_size (fi);
/* Our caller does not have a frame pointer. So his frame starts
at the base of our frame (fi->frame) + register save space
@@ -748,19 +796,7 @@ mn10300_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
static CORE_ADDR
mn10300_frame_saved_pc (struct frame_info *fi)
{
- int adjust = 0;
-
- adjust += (fi->saved_regs[D2_REGNUM] ? 4 : 0);
- adjust += (fi->saved_regs[D3_REGNUM] ? 4 : 0);
- adjust += (fi->saved_regs[A2_REGNUM] ? 4 : 0);
- adjust += (fi->saved_regs[A3_REGNUM] ? 4 : 0);
- if (AM33_MODE)
- {
- adjust += (fi->saved_regs[E0_REGNUM + 5] ? 4 : 0);
- adjust += (fi->saved_regs[E0_REGNUM + 4] ? 4 : 0);
- adjust += (fi->saved_regs[E0_REGNUM + 3] ? 4 : 0);
- adjust += (fi->saved_regs[E0_REGNUM + 2] ? 4 : 0);
- }
+ int adjust = saved_regs_size (fi);
return (read_memory_integer (fi->frame + adjust, REGISTER_SIZE));
}