/* Target-machine dependent code for Renesas H8/300, for GDB.
- Copyright (C) 1988-2018 Free Software Foundation, Inc.
+ Copyright (C) 1988-2022 Free Software Foundation, Inc.
This file is part of GDB.
#include "gdbcore.h"
#include "objfiles.h"
#include "dis-asm.h"
-#include "dwarf2-frame.h"
+#include "dwarf2/frame.h"
#include "frame-base.h"
#include "frame-unwind.h"
&& !is_h8300_normal_mode (gdbarch)) \
? h8300h_reg_size : h8300_reg_size)
-static CORE_ADDR
-h8300_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
-{
- return frame_unwind_register_unsigned (next_frame, E_PC_REGNUM);
-}
-
-static CORE_ADDR
-h8300_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
-{
- return frame_unwind_register_unsigned (next_frame, E_SP_REGNUM);
-}
-
-static struct frame_id
-h8300_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_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. */
if (IS_MOVB_Rn24_SP (read_memory_unsigned_integer (pc + 2,
2, byte_order)))
{
- LONGEST disp = read_memory_integer (pc + 4, 4, byte_order);
+ ULONGEST disp = read_memory_unsigned_integer (pc + 4, 4, byte_order);
/* ... and d:24 is negative. */
- if (disp < 0 && disp > 0xffffff)
+ if ((disp & 0x00800000) != 0)
return 8;
}
}
if (IS_MOVW_Rn24_SP (read_memory_unsigned_integer (pc + 2,
2, byte_order)))
{
- LONGEST disp = read_memory_integer (pc + 4, 4, byte_order);
+ ULONGEST disp = read_memory_unsigned_integer (pc + 4, 4, byte_order);
/* ... and d:24 is negative. */
- if (disp < 0 && disp > 0xffffff)
+ if ((disp & 0x00800000) != 0)
return 8;
}
}
{
if (IS_MOVL_Rn24_SP (read_memory_integer (pc + 4, 2, byte_order)))
{
- LONGEST disp = read_memory_integer (pc + 6, 4, byte_order);
+ ULONGEST disp = read_memory_unsigned_integer (pc + 6, 4,
+ byte_order);
/* ... and d:24 is negative. */
- if (disp < 0 && disp > 0xffffff)
+ if ((disp & 0x00800000) != 0)
return 10;
}
}
cache->saved_regs[E_FP_REGNUM] = 0;
pc += 4;
if (pc >= current_pc)
- return current_pc;
+ return current_pc;
op = read_memory_unsigned_integer (pc, 2, byte_order);
if (IS_MOV_SP_FP (op))
{
pc += 2;
}
else if (IS_MOV_IMM_Rn (op))
- {
+ {
int offset = read_memory_integer (pc + 2, 2, byte_order);
regno = op & 0x000f;
op = read_memory_unsigned_integer (pc + 4, 2, byte_order);
if (IS_PUSH (op1))
{
/* Since the prefix is 0x01x0, this is not a simple pushm but a
- stm.l reglist,@-sp */
+ stm.l reglist,@-sp */
i = ((op & 0x0030) >> 4) + 1;
regno = op1 & 0x000f;
for (; i > 0; regno++, --i)
This could also be an initializing store from non-prologue code,
but I don't think there's any harm in skipping that. */
while ((spill_size = h8300_is_argument_spill (gdbarch, pc)) > 0
- && pc + spill_size <= current_pc)
+ && pc + spill_size <= current_pc)
pc += spill_size;
return pc;
if (!cache->uses_fp)
{
/* We didn't find a valid frame, which means that CACHE->base
- currently holds the frame pointer for our calling frame. If
- we're at the start of a function, or somewhere half-way its
- prologue, the function's frame probably hasn't been fully
- setup yet. Try to reconstruct the base address for the stack
- frame by looking at the stack pointer. For truly "frameless"
- functions this might work too. */
+ currently holds the frame pointer for our calling frame. If
+ we're at the start of a function, or somewhere half-way its
+ prologue, the function's frame probably hasn't been fully
+ setup yet. Try to reconstruct the base address for the stack
+ frame by looking at the stack pointer. For truly "frameless"
+ functions this might work too. */
cache->base = get_frame_register_unsigned (this_frame, E_SP_REGNUM)
+ cache->sp_offset;
if (regnum < gdbarch_num_regs (gdbarch)
&& cache->saved_regs[regnum] != -1)
return frame_unwind_got_memory (this_frame, regnum,
- cache->saved_regs[regnum]);
+ cache->saved_regs[regnum]);
return frame_unwind_got_register (this_frame, regnum, regnum);
}
static const struct frame_unwind h8300_frame_unwind = {
+ "h8300 prologue",
NORMAL_FRAME,
default_frame_unwind_stop_reason,
h8300_frame_this_id,
/* Found a function. */
sal = find_pc_line (func_addr, 0);
if (sal.end && sal.end < func_end)
- /* Found a line number, use it as end of prologue. */
- return sal.end;
+ /* Found a line number, use it as end of prologue. */
+ return sal.end;
/* No useable line symbol. Use prologue parsing method. */
h8300_init_frame_cache (gdbarch, &cache);
h8300_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
struct regcache *regcache, CORE_ADDR bp_addr,
int nargs, struct value **args, CORE_ADDR sp,
- int struct_return, CORE_ADDR struct_addr)
+ function_call_return_method return_method,
+ CORE_ADDR struct_addr)
{
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
int stack_alloc = 0, stack_offset = 0;
If we're returning a structure by value, then we must pass a
pointer to the buffer for the return value as an invisible first
argument. */
- if (struct_return)
+ if (return_method == return_method_struct)
regcache_cooked_write_unsigned (regcache, reg++, struct_addr);
for (argument = 0; argument < nargs; argument++)
{
struct type *type = value_type (args[argument]);
int len = TYPE_LENGTH (type);
- char *contents = (char *) value_contents (args[argument]);
+ char *contents = (char *) value_contents (args[argument]).data ();
/* Pad the argument appropriately. */
int padded_len = align_up (len, wordsize);
stack_offset += padded_len;
/* That's right --- even though we passed the argument
- on the stack, we consume the registers anyway! Love
- me, love my dog. */
+ on the stack, we consume the registers anyway! Love
+ me, love my dog. */
reg += padded_len / wordsize;
}
else
{
/* Heavens to Betsy --- it's really going in registers!
- Note that on the h8/300s, there are gaps between the
- registers in the register file. */
+ Note that on the h8/300s, there are gaps between the
+ registers in the register file. */
int offset;
for (offset = 0; offset < padded_len; offset += wordsize)
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)
+ if (type->code () == TYPE_CODE_INT)
{
regcache_cooked_read_unsigned (regcache, E_RET0_REGNUM, &addr);
c = read_memory_unsigned_integer ((CORE_ADDR) addr, len, byte_order);
store_unsigned_integer (valbuf, TYPE_LENGTH (type), byte_order, c);
break;
case 8: /* long long is now 8 bytes. */
- if (TYPE_CODE (type) == TYPE_CODE_INT)
+ if (type->code () == TYPE_CODE_INT)
{
regcache_cooked_read_unsigned (regcache, E_RET0_REGNUM, &c);
store_unsigned_integer (valbuf, 4, byte_order, c);
/* Types of 1, 2 or 4 bytes are returned in R0/R1, everything else on the
stack. */
- if (TYPE_CODE (value_type) == TYPE_CODE_STRUCT
- || TYPE_CODE (value_type) == TYPE_CODE_UNION)
+ if (value_type->code () == TYPE_CODE_STRUCT
+ || value_type->code () == TYPE_CODE_UNION)
return 1;
return !(TYPE_LENGTH (value_type) == 1
|| TYPE_LENGTH (value_type) == 2
{
/* Types of 1, 2 or 4 bytes are returned in R0, INT types of 8 bytes are
returned in R0/R1, everything else on the stack. */
- if (TYPE_CODE (value_type) == TYPE_CODE_STRUCT
- || TYPE_CODE (value_type) == TYPE_CODE_UNION)
+ if (value_type->code () == TYPE_CODE_STRUCT
+ || value_type->code () == TYPE_CODE_UNION)
return 1;
return !(TYPE_LENGTH (value_type) == 1
|| TYPE_LENGTH (value_type) == 2
|| TYPE_LENGTH (value_type) == 4
|| (TYPE_LENGTH (value_type) == 8
- && TYPE_CODE (value_type) == TYPE_CODE_INT));
+ && value_type->code () == TYPE_CODE_INT));
}
/* Function: store_return_value
return regnum;
}
+static const char *
+h8300_register_name_common (const char *regnames[], int numregs,
+ struct gdbarch *gdbarch, int regno)
+{
+ if (regno < 0
+ || regno >= numregs)
+ internal_error (__FILE__, __LINE__,
+ _("h8300_register_name_common: illegal register number %d"),
+ regno);
+ else
+ return regnames[regno];
+}
+
static const char *
h8300_register_name (struct gdbarch *gdbarch, int regno)
{
"sp", "", "pc", "cycles", "tick", "inst",
"ccr", /* pseudo register */
};
- if (regno < 0
- || regno >= (sizeof (register_names) / sizeof (*register_names)))
- internal_error (__FILE__, __LINE__,
- _("h8300_register_name: illegal register number %d"),
- regno);
- else
- return register_names[regno];
+ return h8300_register_name_common(register_names, ARRAY_SIZE(register_names),
+ gdbarch, regno);
+}
+
+static const char *
+h8300h_register_name (struct gdbarch *gdbarch, int regno)
+{
+ static const char *register_names[] = {
+ "er0", "er1", "er2", "er3", "er4", "er5", "er6",
+ "sp", "", "pc", "cycles", "tick", "inst",
+ "ccr", /* pseudo register */
+ };
+ return h8300_register_name_common(register_names, ARRAY_SIZE(register_names),
+ gdbarch, regno);
}
static const char *
"mach", "macl",
"ccr", "exr" /* pseudo registers */
};
- if (regno < 0
- || regno >= (sizeof (register_names) / sizeof (*register_names)))
- internal_error (__FILE__, __LINE__,
- _("h8300s_register_name: illegal register number %d"),
- regno);
- else
- return register_names[regno];
+ return h8300_register_name_common(register_names, ARRAY_SIZE(register_names),
+ gdbarch, regno);
}
static const char *
"mach", "macl", "sbr", "vbr",
"ccr", "exr" /* pseudo registers */
};
- if (regno < 0
- || regno >= (sizeof (register_names) / sizeof (*register_names)))
- internal_error (__FILE__, __LINE__,
- _("h8300sx_register_name: illegal register number %d"),
- regno);
- else
- return register_names[regno];
+ return h8300_register_name_common(register_names, ARRAY_SIZE(register_names),
+ gdbarch, regno);
}
static void
rval = get_frame_register_signed (frame, regno);
- fprintf_filtered (file, "%-14s ", name);
+ gdb_printf (file, "%-14s ", name);
if ((regno == E_PSEUDO_CCR_REGNUM (gdbarch)) || \
(regno == E_PSEUDO_EXR_REGNUM (gdbarch) && is_h8300smode (gdbarch)))
{
- fprintf_filtered (file, "0x%02x ", (unsigned char) rval);
+ gdb_printf (file, "0x%02x ", (unsigned char) rval);
print_longest (file, 'u', 1, rval);
}
else
{
- fprintf_filtered (file, "0x%s ", phex ((ULONGEST) rval,
- BINWORD (gdbarch)));
+ gdb_printf (file, "0x%s ", phex ((ULONGEST) rval,
+ BINWORD (gdbarch)));
print_longest (file, 'd', 1, rval);
}
if (regno == E_PSEUDO_CCR_REGNUM (gdbarch))
/* CCR register */
int C, Z, N, V;
unsigned char l = rval & 0xff;
- fprintf_filtered (file, "\t");
- fprintf_filtered (file, "I-%d ", (l & 0x80) != 0);
- fprintf_filtered (file, "UI-%d ", (l & 0x40) != 0);
- fprintf_filtered (file, "H-%d ", (l & 0x20) != 0);
- fprintf_filtered (file, "U-%d ", (l & 0x10) != 0);
+ gdb_printf (file, "\t");
+ gdb_printf (file, "I-%d ", (l & 0x80) != 0);
+ gdb_printf (file, "UI-%d ", (l & 0x40) != 0);
+ gdb_printf (file, "H-%d ", (l & 0x20) != 0);
+ gdb_printf (file, "U-%d ", (l & 0x10) != 0);
N = (l & 0x8) != 0;
Z = (l & 0x4) != 0;
V = (l & 0x2) != 0;
C = (l & 0x1) != 0;
- fprintf_filtered (file, "N-%d ", N);
- fprintf_filtered (file, "Z-%d ", Z);
- fprintf_filtered (file, "V-%d ", V);
- fprintf_filtered (file, "C-%d ", C);
+ gdb_printf (file, "N-%d ", N);
+ gdb_printf (file, "Z-%d ", Z);
+ gdb_printf (file, "V-%d ", V);
+ gdb_printf (file, "C-%d ", C);
if ((C | Z) == 0)
- fprintf_filtered (file, "u> ");
+ gdb_printf (file, "u> ");
if ((C | Z) == 1)
- fprintf_filtered (file, "u<= ");
+ gdb_printf (file, "u<= ");
if (C == 0)
- fprintf_filtered (file, "u>= ");
+ gdb_printf (file, "u>= ");
if (C == 1)
- fprintf_filtered (file, "u< ");
+ gdb_printf (file, "u< ");
if (Z == 0)
- fprintf_filtered (file, "!= ");
+ gdb_printf (file, "!= ");
if (Z == 1)
- fprintf_filtered (file, "== ");
+ gdb_printf (file, "== ");
if ((N ^ V) == 0)
- fprintf_filtered (file, ">= ");
+ gdb_printf (file, ">= ");
if ((N ^ V) == 1)
- fprintf_filtered (file, "< ");
+ gdb_printf (file, "< ");
if ((Z | (N ^ V)) == 0)
- fprintf_filtered (file, "> ");
+ gdb_printf (file, "> ");
if ((Z | (N ^ V)) == 1)
- fprintf_filtered (file, "<= ");
+ gdb_printf (file, "<= ");
}
else if (regno == E_PSEUDO_EXR_REGNUM (gdbarch) && is_h8300smode (gdbarch))
{
/* EXR register */
unsigned char l = rval & 0xff;
- fprintf_filtered (file, "\t");
- fprintf_filtered (file, "T-%d - - - ", (l & 0x80) != 0);
- fprintf_filtered (file, "I2-%d ", (l & 4) != 0);
- fprintf_filtered (file, "I1-%d ", (l & 2) != 0);
- fprintf_filtered (file, "I0-%d", (l & 1) != 0);
+ gdb_printf (file, "\t");
+ gdb_printf (file, "T-%d - - - ", (l & 0x80) != 0);
+ gdb_printf (file, "I2-%d ", (l & 4) != 0);
+ gdb_printf (file, "I1-%d ", (l & 2) != 0);
+ gdb_printf (file, "I0-%d", (l & 1) != 0);
}
- fprintf_filtered (file, "\n");
+ gdb_printf (file, "\n");
}
static void
static struct type *
h8300_register_type (struct gdbarch *gdbarch, int regno)
{
- if (regno < 0 || regno >= gdbarch_num_regs (gdbarch)
- + gdbarch_num_pseudo_regs (gdbarch))
+ if (regno < 0 || regno >= gdbarch_num_cooked_regs (gdbarch))
internal_error (__FILE__, __LINE__,
_("h8300_register_type: illegal register number %d"),
regno);
case bfd_mach_h8300:
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_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);
case bfd_mach_h8300hn:
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_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_register_name (gdbarch, h8300h_register_name);
if (info.bfd_arch_info->mach != bfd_mach_h8300hn)
{
set_gdbarch_ptr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
case bfd_mach_h8300sn:
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_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);
case bfd_mach_h8300sxn:
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_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);
set_gdbarch_skip_prologue (gdbarch, h8300_skip_prologue);
/* Frame unwinder. */
- set_gdbarch_unwind_pc (gdbarch, h8300_unwind_pc);
- set_gdbarch_unwind_sp (gdbarch, h8300_unwind_sp);
- set_gdbarch_dummy_id (gdbarch, h8300_dummy_id);
frame_base_set_default (gdbarch, &h8300_frame_base);
/*
- * Miscelany
+ * Miscellany
*/
/* Stack grows up. */
set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
}
+void _initialize_h8300_tdep ();
void
-_initialize_h8300_tdep (void)
+_initialize_h8300_tdep ()
{
register_gdbarch_init (bfd_arch_h8300, h8300_gdbarch_init);
}