/* Target-machine dependent code for Renesas H8/300, for GDB.
Copyright (C) 1988, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999,
- 2000, 2001, 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
+ 2000, 2001, 2002, 2003, 2005, 2007, 2008, 2009
+ Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA. */
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
/*
Contributed by Steve Chamberlain
#define H8300_MAX_NUM_REGS 18
-#define E_PSEUDO_CCR_REGNUM (NUM_REGS)
-#define E_PSEUDO_EXR_REGNUM (NUM_REGS+1)
+#define E_PSEUDO_CCR_REGNUM(gdbarch) (gdbarch_num_regs (gdbarch))
+#define E_PSEUDO_EXR_REGNUM(gdbarch) (gdbarch_num_regs (gdbarch)+1)
struct h8300_frame_cache
{
static int is_h8300sxmode (struct gdbarch *gdbarch);
static int is_h8300_normal_mode (struct gdbarch *gdbarch);
-#define BINWORD ((is_h8300hmode (current_gdbarch) \
- && !is_h8300_normal_mode (current_gdbarch)) \
+#define BINWORD(gdbarch) ((is_h8300hmode (gdbarch) \
+ && !is_h8300_normal_mode (gdbarch)) \
? h8300h_reg_size : h8300_reg_size)
static CORE_ADDR
}
static struct frame_id
-h8300_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
+h8300_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
{
- return frame_id_build (h8300_unwind_sp (gdbarch, next_frame),
- frame_pc_unwind (next_frame));
+ CORE_ADDR sp = get_frame_register_unsigned (this_frame, E_SP_REGNUM);
+ return frame_id_build (sp, get_frame_pc (this_frame));
}
/* Normal frames. */
/* Allocate and initialize a frame cache. */
static void
-h8300_init_frame_cache (struct h8300_frame_cache *cache)
+h8300_init_frame_cache (struct gdbarch *gdbarch,
+ struct h8300_frame_cache *cache)
{
int i;
/* Saved registers. We initialize these to -1 since zero is a valid
offset (that's where %fp is supposed to be stored). */
- for (i = 0; i < NUM_REGS; i++)
+ for (i = 0; i < gdbarch_num_regs (gdbarch); i++)
cache->saved_regs[i] = -1;
}
}
static struct h8300_frame_cache *
-h8300_frame_cache (struct frame_info *next_frame, void **this_cache)
+h8300_frame_cache (struct frame_info *this_frame, void **this_cache)
{
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
struct h8300_frame_cache *cache;
char buf[4];
int i;
return *this_cache;
cache = FRAME_OBSTACK_ZALLOC (struct h8300_frame_cache);
- h8300_init_frame_cache (cache);
+ h8300_init_frame_cache (gdbarch, cache);
*this_cache = cache;
/* In principle, for normal frames, %fp holds the frame pointer,
optional. For these "frameless" functions the frame pointer is
actually the frame pointer of the calling frame. */
- cache->base = frame_unwind_register_unsigned (next_frame, E_FP_REGNUM);
+ cache->base = get_frame_register_unsigned (this_frame, E_FP_REGNUM);
if (cache->base == 0)
return cache;
- cache->saved_regs[E_PC_REGNUM] = -BINWORD;
+ cache->saved_regs[E_PC_REGNUM] = -BINWORD (gdbarch);
- cache->pc = frame_func_unwind (next_frame);
- current_pc = frame_pc_unwind (next_frame);
+ cache->pc = get_frame_func (this_frame);
+ current_pc = get_frame_pc (this_frame);
if (cache->pc != 0)
h8300_analyze_prologue (cache->pc, current_pc, cache);
frame by looking at the stack pointer. For truly "frameless"
functions this might work too. */
- cache->base = frame_unwind_register_unsigned (next_frame, E_SP_REGNUM)
+ cache->base = get_frame_register_unsigned (this_frame, E_SP_REGNUM)
+ cache->sp_offset;
- cache->saved_sp = cache->base + BINWORD;
+ cache->saved_sp = cache->base + BINWORD (gdbarch);
cache->saved_regs[E_PC_REGNUM] = 0;
}
else
{
- cache->saved_sp = cache->base + 2 * BINWORD;
- cache->saved_regs[E_PC_REGNUM] = -BINWORD;
+ cache->saved_sp = cache->base + 2 * BINWORD (gdbarch);
+ cache->saved_regs[E_PC_REGNUM] = -BINWORD (gdbarch);
}
/* Adjust all the saved registers such that they contain addresses
instead of offsets. */
- for (i = 0; i < NUM_REGS; i++)
+ for (i = 0; i < gdbarch_num_regs (gdbarch); i++)
if (cache->saved_regs[i] != -1)
cache->saved_regs[i] = cache->base - cache->saved_regs[i];
}
static void
-h8300_frame_this_id (struct frame_info *next_frame, void **this_cache,
+h8300_frame_this_id (struct frame_info *this_frame, void **this_cache,
struct frame_id *this_id)
{
struct h8300_frame_cache *cache =
- h8300_frame_cache (next_frame, this_cache);
+ h8300_frame_cache (this_frame, this_cache);
/* This marks the outermost frame. */
if (cache->base == 0)
*this_id = frame_id_build (cache->saved_sp, cache->pc);
}
-static void
-h8300_frame_prev_register (struct frame_info *next_frame, void **this_cache,
- int regnum, int *optimizedp,
- enum lval_type *lvalp, CORE_ADDR *addrp,
- int *realnump, gdb_byte *valuep)
+static struct value *
+h8300_frame_prev_register (struct frame_info *this_frame, void **this_cache,
+ int regnum)
{
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
struct h8300_frame_cache *cache =
- h8300_frame_cache (next_frame, this_cache);
+ h8300_frame_cache (this_frame, this_cache);
gdb_assert (regnum >= 0);
if (regnum == E_SP_REGNUM && cache->saved_sp)
- {
- *optimizedp = 0;
- *lvalp = not_lval;
- *addrp = 0;
- *realnump = -1;
- if (valuep)
- store_unsigned_integer (valuep, BINWORD, cache->saved_sp);
- return;
- }
+ return frame_unwind_got_constant (this_frame, regnum, cache->saved_sp);
- if (regnum < NUM_REGS && cache->saved_regs[regnum] != -1)
- {
- *optimizedp = 0;
- *lvalp = lval_memory;
- *addrp = cache->saved_regs[regnum];
- *realnump = -1;
- if (valuep)
- read_memory (*addrp, valuep, register_size (current_gdbarch, regnum));
- return;
- }
+ if (regnum < gdbarch_num_regs (gdbarch)
+ && cache->saved_regs[regnum] != -1)
+ return frame_unwind_got_memory (this_frame, regnum,
+ cache->saved_regs[regnum]);
- *optimizedp = 0;
- *lvalp = lval_register;
- *addrp = 0;
- *realnump = regnum;
- if (valuep)
- frame_unwind_register (next_frame, *realnump, valuep);
+ return frame_unwind_got_register (this_frame, regnum, regnum);
}
static const struct frame_unwind h8300_frame_unwind = {
NORMAL_FRAME,
h8300_frame_this_id,
- h8300_frame_prev_register
+ h8300_frame_prev_register,
+ NULL,
+ default_frame_sniffer
};
-static const struct frame_unwind *
-h8300_frame_sniffer (struct frame_info *next_frame)
-{
- return &h8300_frame_unwind;
-}
-
static CORE_ADDR
-h8300_frame_base_address (struct frame_info *next_frame, void **this_cache)
+h8300_frame_base_address (struct frame_info *this_frame, void **this_cache)
{
- struct h8300_frame_cache *cache = h8300_frame_cache (next_frame, this_cache);
+ struct h8300_frame_cache *cache = h8300_frame_cache (this_frame, this_cache);
return cache->base;
}
};
static CORE_ADDR
-h8300_skip_prologue (CORE_ADDR pc)
+h8300_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
{
CORE_ADDR func_addr = 0 , func_end = 0;
return sal.end;
/* No useable line symbol. Use prologue parsing method. */
- h8300_init_frame_cache (&cache);
+ h8300_init_frame_cache (gdbarch, &cache);
return h8300_analyze_prologue (func_addr, func_end, &cache);
}
int struct_return, CORE_ADDR struct_addr)
{
int stack_alloc = 0, stack_offset = 0;
- int wordsize = BINWORD;
+ int wordsize = BINWORD (gdbarch);
int reg = E_ARG0_REGNUM;
int argument;
}
}
-int
+static int
h8300_use_struct_convention (struct type *value_type)
{
/* Types of 1, 2 or 4 bytes are returned in R0/R1, everything else on the
|| TYPE_LENGTH (value_type) == 4);
}
-int
+static int
h8300h_use_struct_convention (struct type *value_type)
{
/* Types of 1, 2 or 4 bytes are returned in R0, INT types of 8 bytes are
}
static enum return_value_convention
-h8300_return_value (struct gdbarch *gdbarch, struct type *type,
- struct regcache *regcache,
+h8300_return_value (struct gdbarch *gdbarch, struct type *func_type,
+ struct type *type, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf)
{
if (h8300_use_struct_convention (type))
}
static enum return_value_convention
-h8300h_return_value (struct gdbarch *gdbarch, struct type *type,
- struct regcache *regcache,
+h8300h_return_value (struct gdbarch *gdbarch, struct type *func_type,
+ struct type *type, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf)
{
if (h8300h_use_struct_convention (type))
static struct cmd_list_element *setmachinelist;
static const char *
-h8300_register_name (int regno)
+h8300_register_name (struct gdbarch *gdbarch, int regno)
{
/* The register names change depending on which h8300 processor
type is selected. */
}
static const char *
-h8300s_register_name (int regno)
+h8300s_register_name (struct gdbarch *gdbarch, int regno)
{
static char *register_names[] = {
"er0", "er1", "er2", "er3", "er4", "er5", "er6",
}
static const char *
-h8300sx_register_name (int regno)
+h8300sx_register_name (struct gdbarch *gdbarch, int regno)
{
static char *register_names[] = {
"er0", "er1", "er2", "er3", "er4", "er5", "er6",
rval = get_frame_register_signed (frame, regno);
fprintf_filtered (file, "%-14s ", name);
- if ((regno == E_PSEUDO_CCR_REGNUM) || \
- (regno == E_PSEUDO_EXR_REGNUM && is_h8300smode (current_gdbarch)))
+ if ((regno == E_PSEUDO_CCR_REGNUM (gdbarch)) || \
+ (regno == E_PSEUDO_EXR_REGNUM (gdbarch) && is_h8300smode (gdbarch)))
{
fprintf_filtered (file, "0x%02x ", (unsigned char) rval);
print_longest (file, 'u', 1, rval);
}
else
{
- fprintf_filtered (file, "0x%s ", phex ((ULONGEST) rval, BINWORD));
+ fprintf_filtered (file, "0x%s ", phex ((ULONGEST) rval,
+ BINWORD (gdbarch)));
print_longest (file, 'd', 1, rval);
}
- if (regno == E_PSEUDO_CCR_REGNUM)
+ if (regno == E_PSEUDO_CCR_REGNUM (gdbarch))
{
/* CCR register */
int C, Z, N, V;
if ((Z | (N ^ V)) == 1)
fprintf_filtered (file, "<= ");
}
- else if (regno == E_PSEUDO_EXR_REGNUM && is_h8300smode (current_gdbarch))
+ else if (regno == E_PSEUDO_EXR_REGNUM (gdbarch) && is_h8300smode (gdbarch))
{
/* EXR register */
unsigned char l = rval & 0xff;
{
for (regno = E_R0_REGNUM; regno <= E_SP_REGNUM; ++regno)
h8300_print_register (gdbarch, file, frame, regno);
- h8300_print_register (gdbarch, file, frame, E_PSEUDO_CCR_REGNUM);
+ h8300_print_register (gdbarch, file, frame,
+ E_PSEUDO_CCR_REGNUM (gdbarch));
h8300_print_register (gdbarch, file, frame, E_PC_REGNUM);
- if (is_h8300smode (current_gdbarch))
+ if (is_h8300smode (gdbarch))
{
- h8300_print_register (gdbarch, file, frame, E_PSEUDO_EXR_REGNUM);
- if (is_h8300sxmode (current_gdbarch))
+ h8300_print_register (gdbarch, file, frame,
+ E_PSEUDO_EXR_REGNUM (gdbarch));
+ if (is_h8300sxmode (gdbarch))
{
h8300_print_register (gdbarch, file, frame, E_SBR_REGNUM);
h8300_print_register (gdbarch, file, frame, E_VBR_REGNUM);
else
{
if (regno == E_CCR_REGNUM)
- h8300_print_register (gdbarch, file, frame, E_PSEUDO_CCR_REGNUM);
- else if (regno == E_PSEUDO_EXR_REGNUM
- && is_h8300smode (current_gdbarch))
- h8300_print_register (gdbarch, file, frame, E_PSEUDO_EXR_REGNUM);
+ h8300_print_register (gdbarch, file, frame,
+ E_PSEUDO_CCR_REGNUM (gdbarch));
+ else if (regno == E_PSEUDO_EXR_REGNUM (gdbarch)
+ && is_h8300smode (gdbarch))
+ h8300_print_register (gdbarch, file, frame,
+ E_PSEUDO_EXR_REGNUM (gdbarch));
else
h8300_print_register (gdbarch, file, frame, regno);
}
static struct type *
h8300_register_type (struct gdbarch *gdbarch, int regno)
{
- if (regno < 0 || regno >= NUM_REGS + NUM_PSEUDO_REGS)
+ if (regno < 0 || regno >= gdbarch_num_regs (gdbarch)
+ + gdbarch_num_pseudo_regs (gdbarch))
internal_error (__FILE__, __LINE__,
"h8300_register_type: illegal register number %d", regno);
else
switch (regno)
{
case E_PC_REGNUM:
- return builtin_type_void_func_ptr;
+ return builtin_type (gdbarch)->builtin_func_ptr;
case E_SP_REGNUM:
case E_FP_REGNUM:
- return builtin_type_void_data_ptr;
+ return builtin_type (gdbarch)->builtin_data_ptr;
default:
- if (regno == E_PSEUDO_CCR_REGNUM)
+ if (regno == E_PSEUDO_CCR_REGNUM (gdbarch))
return builtin_type_uint8;
- else if (regno == E_PSEUDO_EXR_REGNUM)
+ else if (regno == E_PSEUDO_EXR_REGNUM (gdbarch))
return builtin_type_uint8;
- else if (is_h8300hmode (current_gdbarch))
+ else if (is_h8300hmode (gdbarch))
return builtin_type_int32;
else
return builtin_type_int16;
struct regcache *regcache, int regno,
gdb_byte *buf)
{
- if (regno == E_PSEUDO_CCR_REGNUM)
+ if (regno == E_PSEUDO_CCR_REGNUM (gdbarch))
regcache_raw_read (regcache, E_CCR_REGNUM, buf);
- else if (regno == E_PSEUDO_EXR_REGNUM)
+ else if (regno == E_PSEUDO_EXR_REGNUM (gdbarch))
regcache_raw_read (regcache, E_EXR_REGNUM, buf);
else
regcache_raw_read (regcache, regno, buf);
struct regcache *regcache, int regno,
const gdb_byte *buf)
{
- if (regno == E_PSEUDO_CCR_REGNUM)
+ if (regno == E_PSEUDO_CCR_REGNUM (gdbarch))
regcache_raw_write (regcache, E_CCR_REGNUM, buf);
- else if (regno == E_PSEUDO_EXR_REGNUM)
+ else if (regno == E_PSEUDO_EXR_REGNUM (gdbarch))
regcache_raw_write (regcache, E_EXR_REGNUM, buf);
else
regcache_raw_write (regcache, regno, buf);
}
static int
-h8300_dbg_reg_to_regnum (int regno)
+h8300_dbg_reg_to_regnum (struct gdbarch *gdbarch, int regno)
{
if (regno == E_CCR_REGNUM)
- return E_PSEUDO_CCR_REGNUM;
+ return E_PSEUDO_CCR_REGNUM (gdbarch);
return regno;
}
static int
-h8300s_dbg_reg_to_regnum (int regno)
+h8300s_dbg_reg_to_regnum (struct gdbarch *gdbarch, int regno)
{
if (regno == E_CCR_REGNUM)
- return E_PSEUDO_CCR_REGNUM;
+ return E_PSEUDO_CCR_REGNUM (gdbarch);
if (regno == E_EXR_REGNUM)
- return E_PSEUDO_EXR_REGNUM;
+ return E_PSEUDO_EXR_REGNUM (gdbarch);
return regno;
}
const static unsigned char *
-h8300_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
+h8300_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr,
+ int *lenptr)
{
/*static unsigned char breakpoint[] = { 0x7A, 0xFF }; *//* ??? */
static unsigned char breakpoint[] = { 0x01, 0x80 }; /* Sleep */
set_gdbarch_num_regs (gdbarch, 13);
set_gdbarch_num_pseudo_regs (gdbarch, 1);
set_gdbarch_ecoff_reg_to_regnum (gdbarch, h8300_dbg_reg_to_regnum);
- set_gdbarch_dwarf_reg_to_regnum (gdbarch, h8300_dbg_reg_to_regnum);
set_gdbarch_dwarf2_reg_to_regnum (gdbarch, h8300_dbg_reg_to_regnum);
set_gdbarch_stab_reg_to_regnum (gdbarch, h8300_dbg_reg_to_regnum);
set_gdbarch_register_name (gdbarch, h8300_register_name);
set_gdbarch_num_regs (gdbarch, 13);
set_gdbarch_num_pseudo_regs (gdbarch, 1);
set_gdbarch_ecoff_reg_to_regnum (gdbarch, h8300_dbg_reg_to_regnum);
- set_gdbarch_dwarf_reg_to_regnum (gdbarch, h8300_dbg_reg_to_regnum);
set_gdbarch_dwarf2_reg_to_regnum (gdbarch, h8300_dbg_reg_to_regnum);
set_gdbarch_stab_reg_to_regnum (gdbarch, h8300_dbg_reg_to_regnum);
set_gdbarch_register_name (gdbarch, h8300_register_name);
set_gdbarch_num_regs (gdbarch, 16);
set_gdbarch_num_pseudo_regs (gdbarch, 2);
set_gdbarch_ecoff_reg_to_regnum (gdbarch, h8300s_dbg_reg_to_regnum);
- set_gdbarch_dwarf_reg_to_regnum (gdbarch, h8300s_dbg_reg_to_regnum);
set_gdbarch_dwarf2_reg_to_regnum (gdbarch, h8300s_dbg_reg_to_regnum);
set_gdbarch_stab_reg_to_regnum (gdbarch, h8300s_dbg_reg_to_regnum);
set_gdbarch_register_name (gdbarch, h8300s_register_name);
set_gdbarch_num_regs (gdbarch, 18);
set_gdbarch_num_pseudo_regs (gdbarch, 2);
set_gdbarch_ecoff_reg_to_regnum (gdbarch, h8300s_dbg_reg_to_regnum);
- set_gdbarch_dwarf_reg_to_regnum (gdbarch, h8300s_dbg_reg_to_regnum);
set_gdbarch_dwarf2_reg_to_regnum (gdbarch, h8300s_dbg_reg_to_regnum);
set_gdbarch_stab_reg_to_regnum (gdbarch, h8300s_dbg_reg_to_regnum);
set_gdbarch_register_name (gdbarch, h8300sx_register_name);
/* Frame unwinder. */
set_gdbarch_unwind_pc (gdbarch, h8300_unwind_pc);
set_gdbarch_unwind_sp (gdbarch, h8300_unwind_sp);
- set_gdbarch_unwind_dummy_id (gdbarch, h8300_unwind_dummy_id);
+ set_gdbarch_dummy_id (gdbarch, h8300_dummy_id);
frame_base_set_default (gdbarch, &h8300_frame_base);
/*
set_gdbarch_believe_pcc_promotion (gdbarch, 1);
/* Hook in the DWARF CFI frame unwinder. */
- frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer);
- frame_unwind_append_sniffer (gdbarch, h8300_frame_sniffer);
+ dwarf2_append_unwinders (gdbarch);
+ frame_unwind_append_unwinder (gdbarch, &h8300_frame_unwind);
return gdbarch;