/* Target-machine dependent code for Renesas H8/300, for GDB.
- Copyright (C) 1988, 1990-1996, 1998-2003, 2005, 2007-2012 Free
- Software Foundation, Inc.
+ Copyright (C) 1988-2014 Free Software Foundation, Inc.
This file is part of GDB.
#include "regcache.h"
#include "gdbcore.h"
#include "objfiles.h"
-#include "gdb_assert.h"
#include "dis-asm.h"
#include "dwarf2-frame.h"
#include "frame-base.h"
return RETURN_VALUE_REGISTER_CONVENTION;
}
-static struct cmd_list_element *setmachinelist;
+/* Implementation of 'register_sim_regno' gdbarch method. */
+
+static int
+h8300_register_sim_regno (struct gdbarch *gdbarch, int regnum)
+{
+ /* Only makes sense to supply raw registers. */
+ gdb_assert (regnum >= 0 && regnum < gdbarch_num_regs (gdbarch));
+
+ /* We hide the raw ccr from the user by making it nameless. Because
+ the default register_sim_regno hook returns
+ LEGACY_SIM_REGNO_IGNORE for unnamed registers, we need to
+ override it. The sim register numbering is compatible with
+ gdb's. */
+ return regnum;
+}
static const char *
h8300_register_name (struct gdbarch *gdbarch, int regno)
}
}
+/* Helpers for h8300_pseudo_register_read. We expose ccr/exr as
+ pseudo-registers to users with smaller sizes than the corresponding
+ raw registers. These helpers extend/narrow the values. */
+
+static enum register_status
+pseudo_from_raw_register (struct gdbarch *gdbarch, struct regcache *regcache,
+ gdb_byte *buf, int pseudo_regno, int raw_regno)
+{
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ enum register_status status;
+ ULONGEST val;
+
+ status = regcache_raw_read_unsigned (regcache, raw_regno, &val);
+ if (status == REG_VALID)
+ store_unsigned_integer (buf,
+ register_size (gdbarch, pseudo_regno),
+ byte_order, val);
+ return status;
+}
+
+/* See pseudo_from_raw_register. */
+
+static void
+raw_from_pseudo_register (struct gdbarch *gdbarch, struct regcache *regcache,
+ const gdb_byte *buf, int raw_regno, int pseudo_regno)
+{
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ ULONGEST val;
+
+ val = extract_unsigned_integer (buf, register_size (gdbarch, pseudo_regno),
+ byte_order);
+ regcache_raw_write_unsigned (regcache, raw_regno, val);
+}
+
static enum register_status
h8300_pseudo_register_read (struct gdbarch *gdbarch,
struct regcache *regcache, int regno,
gdb_byte *buf)
{
if (regno == E_PSEUDO_CCR_REGNUM (gdbarch))
- return regcache_raw_read (regcache, E_CCR_REGNUM, buf);
+ {
+ return pseudo_from_raw_register (gdbarch, regcache, buf,
+ regno, E_CCR_REGNUM);
+ }
else if (regno == E_PSEUDO_EXR_REGNUM (gdbarch))
- return regcache_raw_read (regcache, E_EXR_REGNUM, buf);
+ {
+ return pseudo_from_raw_register (gdbarch, regcache, buf,
+ regno, E_EXR_REGNUM);
+ }
else
return regcache_raw_read (regcache, regno, buf);
}
const gdb_byte *buf)
{
if (regno == E_PSEUDO_CCR_REGNUM (gdbarch))
- regcache_raw_write (regcache, E_CCR_REGNUM, buf);
+ raw_from_pseudo_register (gdbarch, regcache, buf, E_CCR_REGNUM, regno);
else if (regno == E_PSEUDO_EXR_REGNUM (gdbarch))
- regcache_raw_write (regcache, E_EXR_REGNUM, buf);
+ raw_from_pseudo_register (gdbarch, regcache, buf, E_EXR_REGNUM, regno);
else
regcache_raw_write (regcache, regno, buf);
}
return regno;
}
-const static unsigned char *
+static const unsigned char *
h8300_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr,
int *lenptr)
{
gdbarch = gdbarch_alloc (&info, 0);
+ set_gdbarch_register_sim_regno (gdbarch, h8300_register_sim_regno);
+
switch (info.bfd_arch_info->mach)
{
case bfd_mach_h8300: