/* Target-dependent code for the Matsushita MN10300 for GDB, the GNU debugger.
- Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
- Free Software Foundation, Inc.
+ Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
+ 2007 Free Software Foundation, Inc.
This file is part of GDB.
}
static CORE_ADDR
-mn10300_read_pc (ptid_t ptid)
+mn10300_read_pc (struct regcache *regcache)
{
- return read_register_pid (E_PC_REGNUM, ptid);
+ ULONGEST val;
+ regcache_cooked_read_unsigned (regcache, E_PC_REGNUM, &val);
+ return val;
}
static void
-mn10300_write_pc (CORE_ADDR val, ptid_t ptid)
+mn10300_write_pc (struct regcache *regcache, CORE_ADDR val)
{
- return write_register_pid (E_PC_REGNUM, val, ptid);
+ regcache_cooked_write_unsigned (regcache, E_PC_REGNUM, val);
}
/* The breakpoint instruction must be the same size as the smallest
[mov sp,a3] [mov sp,a3]
[add -SIZE2,sp] [add -SIZE2,sp] */
+ /* Remember the address at which we started in the event that we
+ don't ultimately find an fmov instruction. Once we're certain
+ that we matched one of the above patterns, we'll set
+ ``restore_addr'' to the appropriate value. Note: At one time
+ in the past, this code attempted to not adjust ``addr'' until
+ there was a fair degree of certainty that the pattern would be
+ matched. However, that code did not wait until an fmov instruction
+ was actually encountered. As a consequence, ``addr'' would
+ sometimes be advanced even when no fmov instructions were found. */
+ CORE_ADDR restore_addr = addr;
+
/* First, look for add -SIZE,sp (i.e. add imm8,sp (0xf8feXX)
or add imm16,sp (0xfafeXXXX)
or add imm32,sp (0xfcfeXXXXXXXX)) */
This is a one byte instruction: mov sp,aN = 0011 11XX
where XX is the register number.
- Skip this instruction by incrementing addr. (We're
- committed now.) The "fmov" instructions will have the
- form "fmov fs#,(aN+)" in this case, but that will not
- necessitate a change in the "fmov" parsing logic below. */
+ Skip this instruction by incrementing addr. The "fmov"
+ instructions will have the form "fmov fs#,(aN+)" in this
+ case, but that will not necessitate a change in the
+ "fmov" parsing logic below. */
addr++;
if (buf[0] != 0xf9 && buf[0] != 0xfb)
break;
+ /* An fmov instruction has just been seen. We can
+ now really commit to the pattern match. Set the
+ address to restore at the end of this speculative
+ bit of code to the actually address that we've
+ been incrementing (or not) throughout the
+ speculation. */
+ restore_addr = addr;
+
/* Get the floating point register number from the
2nd and 3rd bytes of the "fmov" instruction:
Machine Code: 0000 00X0 YYYY 0000 =>
{
/* No "fmov" was found. Reread the two bytes at the original
"addr" to reset the state. */
+ addr = restore_addr;
if (!safe_frame_unwind_memory (fi, addr, buf, 2))
goto finish_prologue;
}
instruction. Handle this below. */
}
/* else no "add -SIZE,sp" was found indicating no floating point
- registers are saved in this prologue. Do not increment addr. Pretend
- this bit of code never happened. */
+ registers are saved in this prologue. */
+
+ /* In the pattern match code contained within this block, `restore_addr'
+ is set to the starting address at the very beginning and then
+ iteratively to the next address to start scanning at once the
+ pattern match has succeeded. Thus `restore_addr' will contain
+ the address to rewind to if the pattern match failed. If the
+ match succeeded, `restore_addr' and `addr' will already have the
+ same value. */
+ addr = restore_addr;
}
/* Now see if we set up a frame pointer via "mov sp,a3" */
goto finish_prologue;
/* Note the size of the stack. */
- stack_extra_size += extract_signed_integer (buf, imm_size);
+ stack_extra_size -= extract_signed_integer (buf, imm_size);
/* We just consumed 2 + imm_size bytes. */
addr += 2 + imm_size;
frame_id_build (trad_frame_get_this_base (cache),
start));
else
- trad_frame_set_id (cache,
- frame_id_build (trad_frame_get_this_base (cache),
- frame_func_unwind (next_frame)));
+ {
+ start = frame_func_unwind (next_frame, NORMAL_FRAME);
+ trad_frame_set_id (cache,
+ frame_id_build (trad_frame_get_this_base (cache),
+ start));
+ }
(*this_prologue_cache) = cache;
return cache;
if (struct_return)
{
regs_used = 1;
- write_register (E_D0_REGNUM, struct_addr);
+ regcache_cooked_write_unsigned (regcache, E_D0_REGNUM, struct_addr);
}
else
regs_used = 0;
while (regs_used < 2 && arg_len > 0)
{
- write_register (regs_used,
- extract_unsigned_integer (val, push_size));
+ regcache_cooked_write_unsigned (regcache, regs_used,
+ extract_unsigned_integer (val, push_size));
val += push_size;
arg_len -= push_size;
regs_used++;
/* Push the return address that contains the magic breakpoint. */
sp -= 4;
write_memory_unsigned_integer (sp, push_size, bp_addr);
+
+ /* The CPU also writes the return address always into the
+ MDR register on "call". */
+ regcache_cooked_write_unsigned (regcache, E_MDR_REGNUM, bp_addr);
+
/* Update $sp. */
regcache_cooked_write_unsigned (regcache, E_SP_REGNUM, sp);
return sp;
static int
mn10300_dwarf2_reg_to_regnum (int dwarf2)
{
- /* This table is supposed to be shaped like the REGISTER_NAMES
+ /* This table is supposed to be shaped like the gdbarch_register_name
initializer in gcc/config/mn10300/mn10300.h. Registers which
appear in GCC's numbering, but have no counterpart in GDB's
world, are marked with a -1. */