/* Target-machine dependent code for Renesas H8/300, for GDB.
- Copyright (C) 1988-2014 Free Software Foundation, Inc.
+ Copyright (C) 1988-2017 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"
}
else if (IS_MOVL_EXT (w2))
{
- int w3 = read_memory_integer (pc + 4, 2, byte_order);
-
if (IS_MOVL_Rn24_SP (read_memory_integer (pc + 4, 2, byte_order)))
{
LONGEST disp = read_memory_integer (pc + 6, 4, byte_order);
CORE_ADDR current_pc;
if (*this_cache)
- return *this_cache;
+ return (struct h8300_frame_cache *) *this_cache;
cache = FRAME_OBSTACK_ZALLOC (struct h8300_frame_cache);
h8300_init_frame_cache (gdbarch, cache);
for (argument = 0; argument < nargs; argument++)
{
- struct cleanup *back_to;
struct type *type = value_type (args[argument]);
int len = TYPE_LENGTH (type);
char *contents = (char *) value_contents (args[argument]);
/* Pad the argument appropriately. */
int padded_len = align_up (len, wordsize);
- gdb_byte *padded = xmalloc (padded_len);
- back_to = make_cleanup (xfree, padded);
+ /* Use std::vector here to get zero initialization. */
+ std::vector<gdb_byte> padded (padded_len);
- memset (padded, 0, padded_len);
- memcpy (len < wordsize ? padded + padded_len - len : padded,
+ memcpy ((len < wordsize ? padded.data () + padded_len - len
+ : padded.data ()),
contents, len);
/* Could the argument fit in the remaining registers? */
if (len > wordsize && len % wordsize)
{
/* I feel so unclean. */
- write_memory (sp + stack_offset, padded, padded_len);
+ write_memory (sp + stack_offset, padded.data (), padded_len);
stack_offset += padded_len;
/* That's right --- even though we passed the argument
for (offset = 0; offset < padded_len; offset += wordsize)
{
ULONGEST word
- = extract_unsigned_integer (padded + offset,
+ = extract_unsigned_integer (&padded[offset],
wordsize, byte_order);
regcache_cooked_write_unsigned (regcache, reg++, word);
}
else
{
/* It doesn't fit in registers! Onto the stack it goes. */
- write_memory (sp + stack_offset, padded, padded_len);
+ write_memory (sp + stack_offset, padded.data (), padded_len);
stack_offset += padded_len;
/* Once one argument has spilled onto the stack, all
subsequent arguments go on the stack. */
reg = E_ARGLAST_REGNUM + 1;
}
-
- do_cleanups (back_to);
}
/* Store return address. */
static void
h8300_extract_return_value (struct type *type, struct regcache *regcache,
- void *valbuf)
+ gdb_byte *valbuf)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
int len = TYPE_LENGTH (type);
ULONGEST c, addr;
regcache_cooked_read_unsigned (regcache, E_RET0_REGNUM, &c);
store_unsigned_integer (valbuf, 2, byte_order, c);
regcache_cooked_read_unsigned (regcache, E_RET1_REGNUM, &c);
- store_unsigned_integer ((void *)((char *) valbuf + 2), 2, byte_order, c);
+ store_unsigned_integer (valbuf + 2, 2, byte_order, c);
break;
case 8: /* long long is now 8 bytes. */
if (TYPE_CODE (type) == TYPE_CODE_INT)
static void
h8300h_extract_return_value (struct type *type, struct regcache *regcache,
- void *valbuf)
+ gdb_byte *valbuf)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
ULONGEST c;
regcache_cooked_read_unsigned (regcache, E_RET0_REGNUM, &c);
store_unsigned_integer (valbuf, 4, byte_order, c);
regcache_cooked_read_unsigned (regcache, E_RET1_REGNUM, &c);
- store_unsigned_integer ((void *) ((char *) valbuf + 4), 4,
- byte_order, c);
+ store_unsigned_integer (valbuf + 4, 4, byte_order, c);
}
else
{
static void
h8300_store_return_value (struct type *type, struct regcache *regcache,
- const void *valbuf)
+ const gdb_byte *valbuf)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
ULONGEST val;
static void
h8300h_store_return_value (struct type *type, struct regcache *regcache,
- const void *valbuf)
+ const gdb_byte *valbuf)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
ULONGEST val;
return RETURN_VALUE_REGISTER_CONVENTION;
}
-static struct cmd_list_element *setmachinelist;
-
/* Implementation of 'register_sim_regno' gdbarch method. */
static int
{
/* The register names change depending on which h8300 processor
type is selected. */
- static char *register_names[] = {
+ static const char *register_names[] = {
"r0", "r1", "r2", "r3", "r4", "r5", "r6",
"sp", "", "pc", "cycles", "tick", "inst",
"ccr", /* pseudo register */
static const char *
h8300s_register_name (struct gdbarch *gdbarch, int regno)
{
- static char *register_names[] = {
+ static const char *register_names[] = {
"er0", "er1", "er2", "er3", "er4", "er5", "er6",
"sp", "", "pc", "cycles", "", "tick", "inst",
"mach", "macl",
static const char *
h8300sx_register_name (struct gdbarch *gdbarch, int regno)
{
- static char *register_names[] = {
+ static const char *register_names[] = {
"er0", "er1", "er2", "er3", "er4", "er5", "er6",
"sp", "", "pc", "cycles", "", "tick", "inst",
"mach", "macl", "sbr", "vbr",
fprintf_filtered (file, "u> ");
if ((C | Z) == 1)
fprintf_filtered (file, "u<= ");
- if ((C == 0))
+ if (C == 0)
fprintf_filtered (file, "u>= ");
if (C == 1)
fprintf_filtered (file, "u< ");
}
}
+/* 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;
}
-static const unsigned char *
-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 */
-
- *lenptr = sizeof (breakpoint);
- return breakpoint;
-}
+/*static unsigned char breakpoint[] = { 0x7A, 0xFF }; *//* ??? */
+constexpr gdb_byte h8300_break_insn[] = { 0x01, 0x80 }; /* Sleep */
-static void
-h8300_print_float_info (struct gdbarch *gdbarch, struct ui_file *file,
- struct frame_info *frame, const char *args)
-{
- fprintf_filtered (file, "\
-No floating-point info available for this processor.\n");
-}
+typedef BP_MANIPULATION (h8300_break_insn) h8300_breakpoint;
static struct gdbarch *
h8300_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
{
- struct gdbarch_tdep *tdep = NULL;
struct gdbarch *gdbarch;
arches = gdbarch_list_lookup_by_info (arches, &info);
if (arches != NULL)
return arches->gdbarch;
-#if 0
- tdep = (struct gdbarch_tdep *) xmalloc (sizeof (struct gdbarch_tdep));
-#endif
-
if (info.bfd_arch_info->arch != bfd_arch_h8300)
return NULL;
set_gdbarch_ptr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
set_gdbarch_addr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
set_gdbarch_return_value (gdbarch, h8300_return_value);
- set_gdbarch_print_insn (gdbarch, print_insn_h8300);
break;
case bfd_mach_h8300h:
case bfd_mach_h8300hn:
set_gdbarch_addr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
}
set_gdbarch_return_value (gdbarch, h8300h_return_value);
- set_gdbarch_print_insn (gdbarch, print_insn_h8300h);
break;
case bfd_mach_h8300s:
case bfd_mach_h8300sn:
set_gdbarch_addr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
}
set_gdbarch_return_value (gdbarch, h8300h_return_value);
- set_gdbarch_print_insn (gdbarch, print_insn_h8300s);
break;
case bfd_mach_h8300sx:
case bfd_mach_h8300sxn:
set_gdbarch_addr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
}
set_gdbarch_return_value (gdbarch, h8300h_return_value);
- set_gdbarch_print_insn (gdbarch, print_insn_h8300s);
break;
}
set_gdbarch_pc_regnum (gdbarch, E_PC_REGNUM);
set_gdbarch_register_type (gdbarch, h8300_register_type);
set_gdbarch_print_registers_info (gdbarch, h8300_print_registers_info);
- set_gdbarch_print_float_info (gdbarch, h8300_print_float_info);
/*
* Frame Info
/* Stack grows up. */
set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
- set_gdbarch_breakpoint_from_pc (gdbarch, h8300_breakpoint_from_pc);
+ set_gdbarch_breakpoint_kind_from_pc (gdbarch,
+ h8300_breakpoint::kind_from_pc);
+ set_gdbarch_sw_breakpoint_from_kind (gdbarch,
+ h8300_breakpoint::bp_from_kind);
set_gdbarch_push_dummy_call (gdbarch, h8300_push_dummy_call);
set_gdbarch_char_signed (gdbarch, 0);
set_gdbarch_int_bit (gdbarch, 2 * TARGET_CHAR_BIT);
set_gdbarch_long_bit (gdbarch, 4 * TARGET_CHAR_BIT);
set_gdbarch_long_long_bit (gdbarch, 8 * TARGET_CHAR_BIT);
+
+ set_gdbarch_wchar_bit (gdbarch, 2 * TARGET_CHAR_BIT);
+ set_gdbarch_wchar_signed (gdbarch, 0);
+
set_gdbarch_double_bit (gdbarch, 4 * TARGET_CHAR_BIT);
set_gdbarch_double_format (gdbarch, floatformats_ieee_single);
set_gdbarch_long_double_bit (gdbarch, 4 * TARGET_CHAR_BIT);
}
-extern initialize_file_ftype _initialize_h8300_tdep; /* -Wmissing-prototypes */
-
void
_initialize_h8300_tdep (void)
{