This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
RFA: correct mn10300 saved regs handling
- To: gdb-patches at sources dot redhat dot com
- Subject: RFA: correct mn10300 saved regs handling
- From: Jim Blandy <jimb at zwingli dot cygnus dot com>
- Date: Mon, 7 May 2001 00:31:56 -0500 (EST)
2001-05-06 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.
*** gdb/mn10300-tdep.c.base Fri May 4 16:27:44 2001
--- gdb/mn10300-tdep.c Sun May 6 20:15:55 2001
***************
*** 216,247 ****
if (fi == NULL || movm_args == 0)
return;
! if (movm_args & 0x10)
{
fi->saved_regs[A3_REGNUM] = fi->frame + offset;
offset += 4;
}
! if (movm_args & 0x20)
{
fi->saved_regs[A2_REGNUM] = fi->frame + offset;
offset += 4;
}
! if (movm_args & 0x40)
{
fi->saved_regs[D3_REGNUM] = fi->frame + offset;
offset += 4;
}
! if (movm_args & 0x80)
{
fi->saved_regs[D2_REGNUM] = fi->frame + offset;
offset += 4;
}
! if (AM33_MODE && movm_args & 0x02)
{
! 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;
}
}
--- 216,278 ----
if (fi == NULL || movm_args == 0)
return;
! if (movm_args & movm_other_bit)
! {
! fi->saved_regs[LAR_REGNUM] = fi->frame + offset;
! fi->saved_regs[LIR_REGNUM] = fi->frame + offset + 4;
! fi->saved_regs[MDR_REGNUM] = fi->frame + offset + 8;
! fi->saved_regs[A0_REGNUM + 1] = fi->frame + offset + 12;
! fi->saved_regs[A0_REGNUM] = fi->frame + offset + 16;
! fi->saved_regs[D0_REGNUM + 1] = fi->frame + offset + 20;
! fi->saved_regs[D0_REGNUM] = fi->frame + offset + 24;
! offset += 28;
! }
! if (movm_args & movm_a3_bit)
{
fi->saved_regs[A3_REGNUM] = fi->frame + offset;
offset += 4;
}
! if (movm_args & movm_a2_bit)
{
fi->saved_regs[A2_REGNUM] = fi->frame + offset;
offset += 4;
}
! if (movm_args & movm_d3_bit)
{
fi->saved_regs[D3_REGNUM] = fi->frame + offset;
offset += 4;
}
! if (movm_args & movm_d2_bit)
{
fi->saved_regs[D2_REGNUM] = fi->frame + offset;
offset += 4;
}
! if (AM33_MODE)
{
! 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;
! }
}
}
***************
*** 529,534 ****
--- 560,591 ----
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.
***************
*** 579,597 ****
}
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);
! }
/* Our caller does not have a frame pointer. So his frame starts
at the base of our frame (fi->frame) + register save space
--- 636,642 ----
}
else
{
! 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
***************
*** 767,785 ****
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);
! }
return (read_memory_integer (fi->frame + adjust, REGISTER_SIZE));
}
--- 812,818 ----
static CORE_ADDR
mn10300_frame_saved_pc (struct frame_info *fi)
{
! int adjust = saved_regs_size (fi);
return (read_memory_integer (fi->frame + adjust, REGISTER_SIZE));
}
*** gdb/config/mn10300/tm-mn10300.h.base Fri May 4 14:55:16 2001
--- gdb/config/mn10300/tm-mn10300.h Sun May 6 20:04:25 2001
***************
*** 43,50 ****
--- 43,52 ----
#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,62 ****
--- 55,79 ----
#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
/* start-sanitize-am33-2 */
#define FS0_REGNUM 32
/* end-sanitize-am33-2 */
+
+ 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 */