-/* Target-machine dependent code for Hitachi H8/300, for GDB.
+/* Target-machine dependent code for Renesas H8/300, for GDB.
Copyright 1988, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998,
1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
#include "objfiles.h"
#include "gdbcmd.h"
#include "gdb_assert.h"
+#include "dis-asm.h"
/* Extra info which is saved in each frame_info. */
struct frame_extra_info
h8300h_reg_size = 4,
h8300_max_reg_size = 4,
};
-#define BINWORD (h8300hmode ? h8300h_reg_size : h8300_reg_size)
+
+static int is_h8300hmode (struct gdbarch *gdbarch);
+static int is_h8300smode (struct gdbarch *gdbarch);
+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) ? h8300h_reg_size : h8300_reg_size)
enum gdb_regnum
{
*/
static CORE_ADDR
-h8300_examine_prologue (register CORE_ADDR ip, register CORE_ADDR limit,
+h8300_examine_prologue (CORE_ADDR ip, CORE_ADDR limit,
CORE_ADDR after_prolog_fp, CORE_ADDR *fsr,
struct frame_info *fi)
{
- register CORE_ADDR next_ip;
+ CORE_ADDR next_ip;
int r;
int have_fp = 0;
unsigned short insn_word;
}
/* If the PC isn't valid, quit now. */
- if (ip == 0 || ip & (h8300hmode ? ~0xffffff : ~0xffff))
+ if (ip == 0 || ip & (is_h8300hmode (current_gdbarch) &&
+ !is_h8300_normal_mode (current_gdbarch) ? ~0xffffff : ~0xffff))
return 0;
next_ip = h8300_next_prologue_insn (ip, limit, &insn_word);
{
CORE_ADDR func_addr, func_end;
- if (!get_frame_saved_regs (fi))
+ if (!deprecated_get_frame_saved_regs (fi))
{
frame_saved_regs_zalloc (fi);
? sal.end : get_frame_pc (fi);
/* This will fill in fields in fi. */
h8300_examine_prologue (func_addr, limit, get_frame_base (fi),
- get_frame_saved_regs (fi), fi);
+ deprecated_get_frame_saved_regs (fi), fi);
}
/* Else we're out of luck (can't debug completely stripped code).
FIXME. */
static CORE_ADDR
h8300_frame_chain (struct frame_info *thisframe)
{
- if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (thisframe),
- get_frame_base (thisframe),
- get_frame_base (thisframe)))
+ if (deprecated_pc_in_call_dummy (get_frame_pc (thisframe)))
{ /* initialize the from_pc now */
get_frame_extra_info (thisframe)->from_pc =
deprecated_read_register_dummy (get_frame_pc (thisframe),
E_PC_REGNUM);
return get_frame_base (thisframe);
}
- return get_frame_saved_regs (thisframe)[E_SP_REGNUM];
+ return deprecated_get_frame_saved_regs (thisframe)[E_SP_REGNUM];
}
/* Return the saved PC from this frame.
static CORE_ADDR
h8300_frame_saved_pc (struct frame_info *frame)
{
- if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (frame),
- get_frame_base (frame),
- get_frame_base (frame)))
+ if (deprecated_pc_in_call_dummy (get_frame_pc (frame)))
return deprecated_read_register_dummy (get_frame_pc (frame),
get_frame_base (frame),
E_PC_REGNUM);
}
}
-/* Round N up or down to the nearest multiple of UNIT.
- Evaluate N only once, UNIT several times.
- UNIT must be a power of two. */
-#define round_up(n, unit) (((n) + (unit) - 1) & -(unit))
-#define round_down(n, unit) ((n) & -(unit))
-
/* Function: push_dummy_call
Setup the function arguments for calling a function in the inferior.
In this discussion, a `word' is 16 bits on the H8/300s, and 32 bits
to begin with. */
static CORE_ADDR
-h8300_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
+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)
int argument;
/* First, make sure the stack is properly aligned. */
- sp = round_down (sp, wordsize);
+ sp = align_down (sp, wordsize);
/* Now make sure there's space on the stack for the arguments. We
may over-allocate a little here, but that won't hurt anything. */
for (argument = 0; argument < nargs; argument++)
- stack_alloc += round_up (TYPE_LENGTH (VALUE_TYPE (args[argument])),
+ stack_alloc += align_up (TYPE_LENGTH (VALUE_TYPE (args[argument])),
wordsize);
sp -= stack_alloc;
char *contents = (char *) VALUE_CONTENTS (args[argument]);
/* Pad the argument appropriately. */
- int padded_len = round_up (len, wordsize);
+ int padded_len = align_up (len, wordsize);
char *padded = alloca (padded_len);
memset (padded, 0, padded_len);
unsigned regno;
struct frame_info *frame = get_current_frame ();
- if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (frame),
- get_frame_base (frame),
- get_frame_base (frame)))
+ if (deprecated_pc_in_call_dummy (get_frame_pc (frame)))
{
- generic_pop_dummy_frame ();
+ deprecated_pop_dummy_frame ();
}
else
{
{
/* Don't forget E_SP_REGNUM is a frame_saved_regs struct is the
actual value we want, not the address of the value we want. */
- if (get_frame_saved_regs (frame)[regno] && regno != E_SP_REGNUM)
+ if (deprecated_get_frame_saved_regs (frame)[regno] && regno != E_SP_REGNUM)
write_register (regno,
read_memory_integer
- (get_frame_saved_regs (frame)[regno], BINWORD));
- else if (get_frame_saved_regs (frame)[regno] && regno == E_SP_REGNUM)
+ (deprecated_get_frame_saved_regs (frame)[regno], BINWORD));
+ else if (deprecated_get_frame_saved_regs (frame)[regno] && regno == E_SP_REGNUM)
write_register (regno, get_frame_base (frame) + 2 * BINWORD);
}
void *valbuf)
{
int len = TYPE_LENGTH (type);
- ULONGEST c;
+ ULONGEST c, addr;
switch (len)
{
regcache_cooked_read_unsigned (regcache, E_RET1_REGNUM, &c);
store_unsigned_integer ((void*)((char *)valbuf + 2), 2, c);
break;
- case 8: /* long long, double and long double are all defined
- as 4 byte types so far so this shouldn't happen. */
- error ("I don't know how a 8 byte value is returned.");
+ case 8: /* long long is now 8 bytes. */
+ if (TYPE_CODE (type) == TYPE_CODE_INT)
+ {
+ regcache_cooked_read_unsigned (regcache, E_RET0_REGNUM, &addr);
+ c = read_memory_unsigned_integer ((CORE_ADDR) addr, len);
+ store_unsigned_integer (valbuf, len, c);
+ }
+ else
+ {
+ error ("I don't know how this 8 byte value is returned.");
+ }
break;
}
}
void *valbuf)
{
int len = TYPE_LENGTH (type);
- ULONGEST c;
+ ULONGEST c, addr;
switch (len)
{
regcache_cooked_read_unsigned (regcache, E_RET0_REGNUM, &c);
store_unsigned_integer (valbuf, len, c);
break;
- case 8: /* long long, double and long double are all defined
- as 4 byte types so far so this shouldn't happen. */
- error ("I don't know how a 8 byte value is returned.");
+ case 8: /* long long is now 8 bytes. */
+ if (TYPE_CODE (type) == TYPE_CODE_INT)
+ {
+ regcache_cooked_read_unsigned (regcache, E_RET0_REGNUM, &addr);
+ c = read_memory_unsigned_integer ((CORE_ADDR) addr, len);
+ store_unsigned_integer (valbuf, len, c);
+ }
+ else
+ {
+ error ("I don't know how this 8 byte value is returned.");
+ }
break;
}
}
switch (len)
{
case 1:
- case 2:
+ case 2: /* short... */
val = extract_unsigned_integer (valbuf, len);
regcache_cooked_write_unsigned (regcache, E_RET0_REGNUM, val);
break;
- case 4: /* long, float */
+ case 4: /* long, float */
val = extract_unsigned_integer (valbuf, len);
regcache_cooked_write_unsigned (regcache, E_RET0_REGNUM,
(val >> 16) &0xffff);
regcache_cooked_write_unsigned (regcache, E_RET1_REGNUM, val & 0xffff);
break;
- case 8: /* long long, double and long double are all defined
- as 4 byte types so far so this shouldn't happen. */
- error ("I don't know how to return a 8 byte value.");
+ case 8: /* long long, double and long double are all defined
+ as 4 byte types so far so this shouldn't happen. */
+ error ("I don't know how to return an 8 byte value.");
break;
}
}
{
case 1:
case 2:
- case 4: /* long, float */
+ case 4: /* long, float */
val = extract_unsigned_integer (valbuf, len);
regcache_cooked_write_unsigned (regcache, E_RET0_REGNUM, val);
break;
- case 8: /* long long, double and long double are all defined
- as 4 byte types so far so this shouldn't happen. */
- error ("I don't know how to return a 8 byte value.");
+ case 8: /* long long, double and long double are all defined
+ as 4 byte types so far so this shouldn't happen. */
+ error ("I don't know how to return an 8 byte value.");
break;
}
}
if (!name || !*name)
return;
- frame_read_signed_register (frame, regno, &rval);
+ rval = get_frame_register_signed (frame, regno);
fprintf_filtered (file, "%-14s ", name);
- if (regno == E_PSEUDO_CCR_REGNUM || (regno == E_PSEUDO_EXR_REGNUM && h8300smode))
+ if (regno == E_PSEUDO_CCR_REGNUM ||
+ (regno == E_PSEUDO_EXR_REGNUM && is_h8300smode (current_gdbarch)))
{
fprintf_filtered (file, "0x%02x ", (unsigned char)rval);
print_longest (file, 'u', 1, rval);
if ((Z | (N ^ V)) == 1)
fprintf_filtered (file, "<= ");
}
- else if (regno == E_PSEUDO_EXR_REGNUM && h8300smode)
+ else if (regno == E_PSEUDO_EXR_REGNUM && is_h8300smode (current_gdbarch))
{
/* EXR register */
unsigned char l = rval & 0xff;
h8300_print_register (gdbarch, file, frame, regno);
h8300_print_register (gdbarch, file, frame, E_PSEUDO_CCR_REGNUM);
h8300_print_register (gdbarch, file, frame, E_PC_REGNUM);
- if (h8300smode)
+ if (is_h8300smode (current_gdbarch))
{
h8300_print_register (gdbarch, file, frame, E_PSEUDO_EXR_REGNUM);
- if (h8300sxmode)
+ if (is_h8300sxmode (current_gdbarch))
{
h8300_print_register (gdbarch, file, frame, E_SBR_REGNUM);
h8300_print_register (gdbarch, file, frame, E_VBR_REGNUM);
{
if (regno == E_CCR_REGNUM)
h8300_print_register (gdbarch, file, frame, E_PSEUDO_CCR_REGNUM);
- else if (regno == E_PSEUDO_EXR_REGNUM && h8300smode)
+ else if (regno == E_PSEUDO_EXR_REGNUM && is_h8300smode (current_gdbarch))
h8300_print_register (gdbarch, file, frame, E_PSEUDO_EXR_REGNUM);
else
h8300_print_register (gdbarch, file, frame, regno);
return builtin_type_uint8;
else if (regno == E_PSEUDO_EXR_REGNUM)
return builtin_type_uint8;
- else if (h8300hmode)
+ else if (is_h8300hmode (current_gdbarch))
return builtin_type_int32;
else
return builtin_type_int16;
switch (info.bfd_arch_info->mach)
{
case bfd_mach_h8300:
- h8300sxmode = 0;
- h8300smode = 0;
- h8300hmode = 0;
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);
break;
case bfd_mach_h8300h:
case bfd_mach_h8300hn:
- h8300sxmode = 0;
- h8300smode = 0;
- h8300hmode = 1;
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_ptr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
- set_gdbarch_addr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
+ if(info.bfd_arch_info->mach != bfd_mach_h8300hn)
+ {
+ set_gdbarch_ptr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
+ set_gdbarch_addr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
+ }
+ else
+ {
+ set_gdbarch_ptr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
+ set_gdbarch_addr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
+ }
set_gdbarch_extract_return_value (gdbarch, h8300h_extract_return_value);
set_gdbarch_store_return_value (gdbarch, h8300h_store_return_value);
set_gdbarch_print_insn (gdbarch, print_insn_h8300h);
break;
case bfd_mach_h8300s:
case bfd_mach_h8300sn:
- h8300sxmode = 0;
- h8300smode = 1;
- h8300hmode = 1;
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);
- set_gdbarch_ptr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
- set_gdbarch_addr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
+ if(info.bfd_arch_info->mach != bfd_mach_h8300sn)
+ {
+ set_gdbarch_ptr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
+ set_gdbarch_addr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
+ }
+ else
+ {
+ set_gdbarch_ptr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
+ set_gdbarch_addr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
+ }
set_gdbarch_extract_return_value (gdbarch, h8300h_extract_return_value);
set_gdbarch_store_return_value (gdbarch, h8300h_store_return_value);
set_gdbarch_print_insn (gdbarch, print_insn_h8300s);
break;
case bfd_mach_h8300sx:
case bfd_mach_h8300sxn:
- h8300sxmode = 1;
- h8300smode = 1;
- h8300hmode = 1;
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_ptr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
- set_gdbarch_addr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
+ if(info.bfd_arch_info->mach != bfd_mach_h8300sxn)
+ {
+ set_gdbarch_ptr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
+ set_gdbarch_addr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
+ }
+ else
+ {
+ set_gdbarch_ptr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
+ set_gdbarch_addr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
+ }
set_gdbarch_extract_return_value (gdbarch, h8300h_extract_return_value);
set_gdbarch_store_return_value (gdbarch, h8300h_store_return_value);
set_gdbarch_print_insn (gdbarch, print_insn_h8300s);
/* NOTE: cagney/2002-12-06: This can be deleted when this arch is
ready to unwind the PC first (see frame.c:get_prev_frame()). */
- set_gdbarch_deprecated_init_frame_pc (gdbarch, init_frame_pc_default);
+ set_gdbarch_deprecated_init_frame_pc (gdbarch, deprecated_init_frame_pc_default);
/*
* Basic register fields and methods.
*/
/* Stack grows up. */
set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
- /* PC stops zero byte after a trap instruction
- (which means: exactly on trap instruction). */
- set_gdbarch_decr_pc_after_break (gdbarch, 0);
- /* This value is almost never non-zero... */
- set_gdbarch_function_start_offset (gdbarch, 0);
- /* This value is almost never non-zero... */
- set_gdbarch_frame_args_skip (gdbarch, 0);
- set_gdbarch_frameless_function_invocation (gdbarch,
- frameless_look_for_prologue);
-
- set_gdbarch_extract_struct_value_address (gdbarch,
- h8300_extract_struct_value_address);
+ set_gdbarch_deprecated_frameless_function_invocation (gdbarch, legacy_frameless_look_for_prologue);
+
+ set_gdbarch_deprecated_extract_struct_value_address (gdbarch, h8300_extract_struct_value_address);
set_gdbarch_use_struct_convention (gdbarch, always_use_struct_convention);
set_gdbarch_breakpoint_from_pc (gdbarch, h8300_breakpoint_from_pc);
set_gdbarch_push_dummy_code (gdbarch, h8300_push_dummy_code);
set_gdbarch_int_bit (gdbarch, 2 * TARGET_CHAR_BIT);
set_gdbarch_long_bit (gdbarch, 4 * TARGET_CHAR_BIT);
- set_gdbarch_long_long_bit (gdbarch, 4 * TARGET_CHAR_BIT);
+ set_gdbarch_long_long_bit (gdbarch, 8 * TARGET_CHAR_BIT);
set_gdbarch_double_bit (gdbarch, 4 * TARGET_CHAR_BIT);
set_gdbarch_long_double_bit (gdbarch, 4 * TARGET_CHAR_BIT);
- /* set_gdbarch_stack_align (gdbarch, SOME_stack_align); */
set_gdbarch_believe_pcc_promotion (gdbarch, 1);
+ /* Char is unsigned. */
+ set_gdbarch_char_signed (gdbarch, 0);
+
return gdbarch;
}
{
register_gdbarch_init (bfd_arch_h8300, h8300_gdbarch_init);
}
+
+static int
+is_h8300hmode (struct gdbarch *gdbarch)
+{
+ return gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sx
+ || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sxn
+ || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300s
+ || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sn
+ || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300h
+ || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300hn;
+}
+
+static int
+is_h8300smode (struct gdbarch *gdbarch)
+{
+ return gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sx
+ || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sxn
+ || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300s
+ || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sn;
+}
+
+static int
+is_h8300sxmode (struct gdbarch *gdbarch)
+{
+ return gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sx
+ || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sxn;
+}
+
+static int
+is_h8300_normal_mode (struct gdbarch *gdbarch)
+{
+ return gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sxn
+ || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sn
+ || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300hn;
+}
+