diff options
author | Jim Blandy <jimb@codesourcery.com> | 2001-05-09 02:44:01 +0000 |
---|---|---|
committer | Jim Blandy <jimb@codesourcery.com> | 2001-05-09 02:44:01 +0000 |
commit | ae83b20d8f8eff60f8bd9d7a131f7f60b06db772 (patch) | |
tree | aeaa7e456aedb3bb9fd4920c45000ce961d4dff0 | |
parent | bf4b70a5e89748322ccec3aa1c2423fee502e100 (diff) | |
download | gdb-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/ChangeLog | 13 | ||||
-rw-r--r-- | gdb/config/mn10300/tm-mn10300.h | 17 | ||||
-rw-r--r-- | gdb/mn10300-tdep.c | 106 |
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)); } |