/* Target-dependent code for the Toshiba MeP for GDB, the GNU debugger.
- Copyright (C) 2001-2017 Free Software Foundation, Inc.
+ Copyright (C) 2001-2019 Free Software Foundation, Inc.
Contributed by Red Hat, Inc.
#include "arch-utils.h"
#include "regcache.h"
#include "remote.h"
-#include "floatformat.h"
#include "sim-regno.h"
#include "disasm.h"
#include "trad-frame.h"
/* Given a hardware table entry HW representing a register set, return
a pointer to the keyword table with all the register names. If HW
- is NULL, return NULL, to propage the "no such register set" info
+ is NULL, return NULL, to propagate the "no such register set" info
along. */
static CGEN_KEYWORD *
register_set_keyword_table (const CGEN_HW_ENTRY *hw)
/* Given a keyword table KEYWORD and a register number REGNUM, return
the name of the register, or "" if KEYWORD contains no register
whose number is REGNUM. */
-static char *
+static const char *
register_name_from_keyword (CGEN_KEYWORD *keyword_table, int regnum)
{
const CGEN_KEYWORD_ENTRY *entry
static const char *
mep_register_name (struct gdbarch *gdbarch, int regnr)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
/* General-purpose registers. */
static const char *gpr_names[] = {
"r0", "r1", "r2", "r3", /* 0 */
return builtin_type (gdbarch)->builtin_uint32;
}
-
-static CORE_ADDR
-mep_read_pc (struct regcache *regcache)
-{
- ULONGEST pc;
- regcache_cooked_read_unsigned (regcache, MEP_PC_REGNUM, &pc);
- return pc;
-}
-
static enum register_status
mep_pseudo_cr32_read (struct gdbarch *gdbarch,
- struct regcache *regcache,
+ readable_regcache *regcache,
int cookednum,
gdb_byte *buf)
{
gdb_assert (TYPE_LENGTH (register_type (gdbarch, rawnum)) == sizeof (buf64));
gdb_assert (TYPE_LENGTH (register_type (gdbarch, cookednum)) == 4);
- status = regcache_raw_read (regcache, rawnum, buf64);
+ status = regcache->raw_read (rawnum, buf64);
if (status == REG_VALID)
{
/* Slow, but legible. */
static enum register_status
mep_pseudo_cr64_read (struct gdbarch *gdbarch,
- struct regcache *regcache,
+ readable_regcache *regcache,
int cookednum,
gdb_byte *buf)
{
- return regcache_raw_read (regcache, mep_pseudo_to_raw[cookednum], buf);
+ return regcache->raw_read (mep_pseudo_to_raw[cookednum], buf);
}
static enum register_status
mep_pseudo_register_read (struct gdbarch *gdbarch,
- struct regcache *regcache,
+ readable_regcache *regcache,
int cookednum,
gdb_byte *buf)
{
if (IS_CSR_REGNUM (cookednum)
|| IS_CCR_REGNUM (cookednum))
- return regcache_raw_read (regcache, mep_pseudo_to_raw[cookednum], buf);
+ return regcache->raw_read (mep_pseudo_to_raw[cookednum], buf);
else if (IS_CR32_REGNUM (cookednum)
|| IS_FP_CR32_REGNUM (cookednum))
return mep_pseudo_cr32_read (gdbarch, regcache, cookednum, buf);
/* Slow, but legible. */
store_unsigned_integer (buf64, 8, byte_order,
extract_unsigned_integer (buf, 4, byte_order));
- regcache_raw_write (regcache, rawnum, buf64);
+ regcache->raw_write (rawnum, buf64);
}
int cookednum,
const gdb_byte *buf)
{
- regcache_raw_write (regcache, mep_pseudo_to_raw[cookednum], buf);
+ regcache->raw_write (mep_pseudo_to_raw[cookednum], buf);
}
|| IS_FP_CR64_REGNUM (cookednum))
mep_pseudo_cr64_write (gdbarch, regcache, cookednum, buf);
else if (IS_CCR_REGNUM (cookednum))
- regcache_raw_write (regcache, mep_pseudo_to_raw[cookednum], buf);
+ regcache->raw_write (mep_pseudo_to_raw[cookednum], buf);
else
gdb_assert_not_reached ("unexpected pseudo register");
}
{
return (is_arg_reg (value)
&& pv_is_register (addr, MEP_SP_REGNUM)
- && ! pv_area_find_reg (stack, gdbarch, value.reg, 0));
+ && ! stack->find_reg (gdbarch, value.reg, 0));
}
/* Function for finding saved registers in a 'struct pv_area'; we pass
- this to pv_area_scan.
+ this to pv_area::scan.
If VALUE is a saved register, ADDR says it was saved at a constant
offset from the frame base, and SIZE indicates that the whole
{
CORE_ADDR pc;
unsigned long insn;
- int rn;
- int found_lp = 0;
pv_t reg[MEP_NUM_REGS];
- struct pv_area *stack;
- struct cleanup *back_to;
CORE_ADDR after_last_frame_setup_insn = start_pc;
memset (result, 0, sizeof (*result));
result->gdbarch = gdbarch;
- for (rn = 0; rn < MEP_NUM_REGS; rn++)
+ for (int rn = 0; rn < MEP_NUM_REGS; rn++)
{
reg[rn] = pv_register (rn, 0);
result->reg_offset[rn] = 1;
}
- stack = make_pv_area (MEP_SP_REGNUM, gdbarch_addr_bit (gdbarch));
- back_to = make_cleanup_free_pv_area (stack);
+ pv_area stack (MEP_SP_REGNUM, gdbarch_addr_bit (gdbarch));
pc = start_pc;
while (pc < limit_pc)
/* If simulating this store would require us to forget
everything we know about the stack frame in the name of
accuracy, it would be better to just quit now. */
- if (pv_area_store_would_trash (stack, reg[rm]))
+ if (stack.store_would_trash (reg[rm]))
break;
- if (is_arg_spill (gdbarch, reg[rn], reg[rm], stack))
+ if (is_arg_spill (gdbarch, reg[rn], reg[rm], &stack))
after_last_frame_setup_insn = next_pc;
- pv_area_store (stack, reg[rm], 4, reg[rn]);
+ stack.store (reg[rm], 4, reg[rn]);
}
else if (IS_SW_IMMD (insn))
{
/* If simulating this store would require us to forget
everything we know about the stack frame in the name of
accuracy, it would be better to just quit now. */
- if (pv_area_store_would_trash (stack, addr))
+ if (stack.store_would_trash (addr))
break;
- if (is_arg_spill (gdbarch, reg[rn], addr, stack))
+ if (is_arg_spill (gdbarch, reg[rn], addr, &stack))
after_last_frame_setup_insn = next_pc;
- pv_area_store (stack, addr, 4, reg[rn]);
+ stack.store (addr, 4, reg[rn]);
}
else if (IS_MOV (insn))
{
: (gdb_assert (IS_SW (insn)), 4));
pv_t addr = pv_add_constant (reg[rm], disp);
- if (pv_area_store_would_trash (stack, addr))
+ if (stack.store_would_trash (addr))
break;
- if (is_arg_spill (gdbarch, reg[rn], addr, stack))
+ if (is_arg_spill (gdbarch, reg[rn], addr, &stack))
after_last_frame_setup_insn = next_pc;
- pv_area_store (stack, addr, size, reg[rn]);
+ stack.store (addr, size, reg[rn]);
}
else if (IS_LDC (insn))
{
int offset = LW_OFFSET (insn);
pv_t addr = pv_add_constant (reg[rm], offset);
- reg[rn] = pv_area_fetch (stack, addr, 4);
+ reg[rn] = stack.fetch (addr, 4);
}
else if (IS_BRA (insn) && BRA_DISP (insn) > 0)
{
}
/* Record where all the registers were saved. */
- pv_area_scan (stack, check_for_saved, (void *) result);
+ stack.scan (check_for_saved, (void *) result);
result->prologue_end = after_last_frame_setup_insn;
-
- do_cleanups (back_to);
}
MEP_LP_REGNUM);
lp = value_as_long (value);
release_value (value);
- value_free (value);
return frame_unwind_got_constant (this_frame, regnum, lp & ~1);
}
psw = value_as_long (value);
release_value (value);
- value_free (value);
/* Get the LP's value, too. */
value = get_frame_register_value (this_frame, MEP_LP_REGNUM);
lp = value_as_long (value);
release_value (value);
- value_free (value);
/* If LP.LTOM is set, then toggle PSW.OM. */
if (lp & 0x1)
default_frame_sniffer
};
-
-/* Our general unwinding function can handle unwinding the PC. */
-static CORE_ADDR
-mep_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
-{
- return frame_unwind_register_unsigned (next_frame, MEP_PC_REGNUM);
-}
-
-
-/* Our general unwinding function can handle unwinding the SP. */
-static CORE_ADDR
-mep_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
-{
- return frame_unwind_register_unsigned (next_frame, MEP_SP_REGNUM);
-}
-
-
\f
/* Return values. */
offset = 0;
/* Return values that do fit in a single register are returned in R0. */
- regcache_cooked_read_part (regcache, MEP_R0_REGNUM,
- offset, TYPE_LENGTH (type),
- valbuf);
+ regcache->cooked_read_part (MEP_R0_REGNUM, offset, TYPE_LENGTH (type),
+ valbuf);
}
else
offset = 0;
- regcache_cooked_write_part (regcache, MEP_R0_REGNUM,
- offset, TYPE_LENGTH (type),
- valbuf);
+ regcache->cooked_write_part (MEP_R0_REGNUM, offset, TYPE_LENGTH (type),
+ valbuf);
}
/* Return values larger than a single register are returned in
mep_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
struct regcache *regcache, CORE_ADDR bp_addr,
int argc, struct value **argv, CORE_ADDR sp,
- int struct_return,
+ function_call_return_method return_method,
CORE_ADDR struct_addr)
{
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
CORE_ADDR *copy = (CORE_ADDR *) alloca (argc * sizeof (copy[0]));
- CORE_ADDR func_addr = find_function_addr (function, NULL);
int i;
/* The number of the next register available to hold an argument. */
/* If we're returning a structure by value, push the pointer to the
buffer as the first argument. */
- if (struct_return)
+ if (return_method == return_method_struct)
{
regcache_cooked_write_unsigned (regcache, arg_reg, struct_addr);
arg_reg++;
return sp;
}
-
-static struct frame_id
-mep_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
-{
- CORE_ADDR sp = get_frame_register_unsigned (this_frame, MEP_SP_REGNUM);
- return frame_id_build (sp, get_frame_pc (this_frame));
-}
-
-
\f
/* Initialization. */
if (gdbarch_tdep (arches->gdbarch)->me_module == me_module)
return arches->gdbarch;
- tdep = XNEW (struct gdbarch_tdep);
+ tdep = XCNEW (struct gdbarch_tdep);
gdbarch = gdbarch_alloc (&info, tdep);
/* Get a CGEN CPU descriptor for this architecture. */
tdep->me_module = me_module;
/* Register set. */
- set_gdbarch_read_pc (gdbarch, mep_read_pc);
set_gdbarch_num_regs (gdbarch, MEP_NUM_RAW_REGS);
set_gdbarch_pc_regnum (gdbarch, MEP_PC_REGNUM);
set_gdbarch_sp_regnum (gdbarch, MEP_SP_REGNUM);
/* Frames and frame unwinding. */
frame_unwind_append_unwinder (gdbarch, &mep_frame_unwind);
- set_gdbarch_unwind_pc (gdbarch, mep_unwind_pc);
- set_gdbarch_unwind_sp (gdbarch, mep_unwind_sp);
set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
set_gdbarch_frame_args_skip (gdbarch, 0);
/* Inferior function calls. */
set_gdbarch_frame_align (gdbarch, mep_frame_align);
set_gdbarch_push_dummy_call (gdbarch, mep_push_dummy_call);
- set_gdbarch_dummy_id (gdbarch, mep_dummy_id);
return gdbarch;
}
-/* Provide a prototype to silence -Wmissing-prototypes. */
-extern initialize_file_ftype _initialize_mep_tdep;
-
void
_initialize_mep_tdep (void)
{