/* Target-dependent code for the Sanyo Xstormy16a (LC590000) processor.
- Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GDB.
#include "defs.h"
#include "value.h"
#include "inferior.h"
-#include "symfile.h"
#include "arch-utils.h"
#include "regcache.h"
#include "gdbcore.h"
#include "objfiles.h"
+#include "dis-asm.h"
struct gdbarch_tdep
{
return xstormy16_reg_size;
}
-/* Function: xstormy16_register_virtual_size
- Returns the number of bytes occupied by the register as represented
- internally by gdb. */
-
-static int
-xstormy16_register_virtual_size (int regnum)
-{
- return xstormy16_register_raw_size (regnum);
-}
-
/* Function: xstormy16_reg_virtual_type
Returns the default type for register N. */
}
/* Function: xstormy16_get_saved_register
- Find a register's saved value on the call stack. */
+ Find a register's saved value on the call stack.
+
+ Find register number REGNUM relative to FRAME and put its (raw,
+ target format) contents in *RAW_BUFFER.
+
+ Set *OPTIMIZED if the variable was optimized out (and thus can't be
+ fetched). Note that this is never set to anything other than zero
+ in this implementation.
+
+ Set *LVAL to lval_memory, lval_register, or not_lval, depending on
+ whether the value was fetched from memory, from a register, or in a
+ strange and non-modifiable way (e.g. a frame pointer which was
+ calculated rather than fetched). We will use not_lval for values
+ fetched from generic dummy frames.
+
+ Set *ADDRP to the address, either in memory or as a
+ DEPRECATED_REGISTER_BYTE offset into the registers array. If the
+ value is stored in a dummy frame, set *ADDRP to zero.
+
+ The argument RAW_BUFFER must point to aligned memory.
+
+ The GET_SAVED_REGISTER architecture interface is entirely
+ redundant. New architectures should implement per-frame unwinders
+ (ref "frame-unwind.h"). */
static void
-xstormy16_get_saved_register (char *raw_buffer,
- int *optimized,
+xstormy16_get_saved_register (char *raw_buffer, int *optimized,
CORE_ADDR *addrp,
- struct frame_info *fi,
- int regnum, enum lval_type *lval)
+ struct frame_info *frame, int regnum,
+ enum lval_type *lval)
{
- deprecated_generic_get_saved_register (raw_buffer, optimized, addrp, fi, regnum, lval);
+ if (!target_has_registers)
+ error ("No registers.");
+
+ /* Normal systems don't optimize out things with register numbers. */
+ if (optimized != NULL)
+ *optimized = 0;
+
+ if (addrp) /* default assumption: not found in memory */
+ *addrp = 0;
+
+ /* Note: since the current frame's registers could only have been
+ saved by frames INTERIOR TO the current frame, we skip examining
+ the current frame itself: otherwise, we would be getting the
+ previous frame's registers which were saved by the current frame. */
+
+ if (frame != NULL)
+ {
+ for (frame = get_next_frame (frame);
+ get_frame_type (frame) != SENTINEL_FRAME;
+ frame = get_next_frame (frame))
+ {
+ if (get_frame_type (frame) == DUMMY_FRAME)
+ {
+ if (lval) /* found it in a CALL_DUMMY frame */
+ *lval = not_lval;
+ if (raw_buffer)
+ {
+ LONGEST val;
+ /* FIXME: cagney/2002-06-26: This should be via the
+ gdbarch_register_read() method so that it, on the
+ fly, constructs either a raw or pseudo register
+ from the raw register cache. */
+ val = deprecated_read_register_dummy (get_frame_pc (frame),
+ get_frame_base (frame),
+ regnum);
+ store_unsigned_integer (raw_buffer,
+ register_size (current_gdbarch, regnum),
+ val);
+ }
+ return;
+ }
+
+ DEPRECATED_FRAME_INIT_SAVED_REGS (frame);
+ if (deprecated_get_frame_saved_regs (frame) != NULL
+ && deprecated_get_frame_saved_regs (frame)[regnum] != 0)
+ {
+ if (lval) /* found it saved on the stack */
+ *lval = lval_memory;
+ if (regnum == SP_REGNUM)
+ {
+ if (raw_buffer) /* SP register treated specially */
+ /* NOTE: cagney/2003-05-09: In-line store_address()
+ with it's body - store_unsigned_integer(). */
+ store_unsigned_integer (raw_buffer,
+ register_size (current_gdbarch, regnum),
+ deprecated_get_frame_saved_regs (frame)[regnum]);
+ }
+ else
+ {
+ if (addrp) /* any other register */
+ *addrp = deprecated_get_frame_saved_regs (frame)[regnum];
+ if (raw_buffer)
+ read_memory (deprecated_get_frame_saved_regs (frame)[regnum], raw_buffer,
+ register_size (current_gdbarch, regnum));
+ }
+ return;
+ }
+ }
+ }
+
+ /* If we get thru the loop to this point, it means the register was
+ not saved in any frame. Return the actual live-register value. */
+
+ if (lval) /* found it in a live register */
+ *lval = lval_register;
+ if (addrp)
+ *addrp = DEPRECATED_REGISTER_BYTE (regnum);
+ if (raw_buffer)
+ deprecated_read_register_gen (regnum, raw_buffer);
}
/* Function: xstormy16_type_is_scalar
/* Scalar return values of <= 12 bytes are returned in
E_1ST_ARG_REGNUM to E_LST_ARG_REGNUM. */
memcpy (valbuf,
- ®buf[REGISTER_BYTE (E_1ST_ARG_REGNUM)] + offset,
+ ®buf[DEPRECATED_REGISTER_BYTE (E_1ST_ARG_REGNUM)] + offset,
TYPE_LENGTH (type));
}
else
/* Aggregates and return values > 12 bytes are returned in memory,
pointed to by R2. */
return_buffer =
- extract_address (regbuf + REGISTER_BYTE (E_PTR_RET_REGNUM),
- REGISTER_RAW_SIZE (E_PTR_RET_REGNUM));
+ extract_unsigned_integer (regbuf + DEPRECATED_REGISTER_BYTE (E_PTR_RET_REGNUM),
+ register_size (current_gdbarch, E_PTR_RET_REGNUM));
read_memory (return_buffer, valbuf, TYPE_LENGTH (type));
}
(which may or may not be the same as before).
*/
-CORE_ADDR
+static CORE_ADDR
xstormy16_push_return_address (CORE_ADDR pc, CORE_ADDR sp)
{
unsigned char buf[xstormy16_pc_size];
- store_unsigned_integer (buf, xstormy16_pc_size, CALL_DUMMY_ADDRESS ());
+ store_unsigned_integer (buf, xstormy16_pc_size, entry_point_address ());
write_memory (sp, buf, xstormy16_pc_size);
return sp + xstormy16_pc_size;
}
if (fi == NULL)
return; /* paranoia */
- if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (fi), get_frame_base (fi),
- get_frame_base (fi)))
+ if (deprecated_pc_in_call_dummy (get_frame_pc (fi)))
{
- generic_pop_dummy_frame ();
+ deprecated_pop_dummy_frame ();
}
else
{
/* Restore the saved regs. */
for (i = 0; i < NUM_REGS; i++)
- if (get_frame_saved_regs (fi)[i])
+ if (deprecated_get_frame_saved_regs (fi)[i])
{
if (i == SP_REGNUM)
- write_register (i, get_frame_saved_regs (fi)[i]);
+ write_register (i, deprecated_get_frame_saved_regs (fi)[i]);
else if (i == E_PC_REGNUM)
- write_register (i, read_memory_integer (get_frame_saved_regs (fi)[i],
+ write_register (i, read_memory_integer (deprecated_get_frame_saved_regs (fi)[i],
xstormy16_pc_size));
else
- write_register (i, read_memory_integer (get_frame_saved_regs (fi)[i],
+ write_register (i, read_memory_integer (deprecated_get_frame_saved_regs (fi)[i],
xstormy16_reg_size));
}
/* Restore the PC */
}
else if (xstormy16_type_is_scalar (type) &&
TYPE_LENGTH (type) <= E_MAX_RETTYPE_SIZE_IN_REGS)
- deprecated_write_register_bytes (REGISTER_BYTE (E_1ST_ARG_REGNUM),
+ deprecated_write_register_bytes (DEPRECATED_REGISTER_BYTE (E_1ST_ARG_REGNUM),
valbuf, TYPE_LENGTH (type));
else
{
*/
static CORE_ADDR
-xstormy16_extract_struct_value_address (char *regbuf)
+xstormy16_extract_struct_value_address (struct regcache *regcache)
{
- return extract_address (regbuf +
- xstormy16_register_byte (E_PTR_RET_REGNUM),
- xstormy16_reg_size);
+ /* FIXME: cagney/2004-01-17: Does the ABI guarantee that the return
+ address regster is preserved across function calls? Probably
+ not, making this function wrong. */
+ ULONGEST val;
+ regcache_raw_read_unsigned (regcache, E_PTR_RET_REGNUM, &val);
+ return val;
}
/* Function: xstormy16_use_struct_convention
int size = xstormy16_register_raw_size (regnum);
char *buf = (char *) alloca (size);
- deprecated_generic_get_saved_register (buf, NULL, NULL, fi, regnum, NULL);
+ xstormy16_get_saved_register (buf, NULL, NULL, fi, regnum, NULL);
return (CORE_ADDR) extract_unsigned_integer (buf, size);
}
if (fi)
{
/* In a call dummy, don't touch the frame. */
- if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (fi), get_frame_base (fi),
- get_frame_base (fi)))
+ if (deprecated_pc_in_call_dummy (get_frame_pc (fi)))
return start_addr;
/* Grab the frame-relative values of SP and FP, needed below.
if (fi)
{
regnum = inst & 0x000f;
- get_frame_saved_regs (fi)[regnum] = get_frame_extra_info (fi)->framesize;
+ deprecated_get_frame_saved_regs (fi)[regnum] = get_frame_extra_info (fi)->framesize;
get_frame_extra_info (fi)->framesize += xstormy16_reg_size;
}
}
if (offset & 0x0800)
offset -= 0x1000;
- get_frame_saved_regs (fi)[regnum] = get_frame_extra_info (fi)->framesize + offset;
+ deprecated_get_frame_saved_regs (fi)[regnum] = get_frame_extra_info (fi)->framesize + offset;
}
next_addr += xstormy16_inst_size;
}
previous value would have been pushed). */
if (get_frame_extra_info (fi)->frameless_p)
{
- get_frame_saved_regs (fi)[E_SP_REGNUM] = sp - get_frame_extra_info (fi)->framesize;
+ deprecated_get_frame_saved_regs (fi)[E_SP_REGNUM] = sp - get_frame_extra_info (fi)->framesize;
deprecated_update_frame_base_hack (fi, sp);
}
else
{
- get_frame_saved_regs (fi)[E_SP_REGNUM] = fp - get_frame_extra_info (fi)->framesize;
+ deprecated_get_frame_saved_regs (fi)[E_SP_REGNUM] = fp - get_frame_extra_info (fi)->framesize;
deprecated_update_frame_base_hack (fi, fp);
}
sp, fp and framesize. We know the beginning of the frame
so we can translate the register offsets to real addresses. */
for (regnum = 0; regnum < E_SP_REGNUM; ++regnum)
- if (get_frame_saved_regs (fi)[regnum])
- get_frame_saved_regs (fi)[regnum] += get_frame_saved_regs (fi)[E_SP_REGNUM];
+ if (deprecated_get_frame_saved_regs (fi)[regnum])
+ deprecated_get_frame_saved_regs (fi)[regnum] += deprecated_get_frame_saved_regs (fi)[E_SP_REGNUM];
/* Save address of PC on stack. */
- get_frame_saved_regs (fi)[E_PC_REGNUM] = get_frame_saved_regs (fi)[E_SP_REGNUM];
+ deprecated_get_frame_saved_regs (fi)[E_PC_REGNUM] = deprecated_get_frame_saved_regs (fi)[E_SP_REGNUM];
}
return next_addr;
return plg_end;
/* Found a function. */
- sym = lookup_symbol (func_name, NULL, VAR_NAMESPACE, NULL, NULL);
+ sym = lookup_symbol (func_name, NULL, VAR_DOMAIN, NULL, NULL);
/* Don't use line number debug info for assembly source files. */
if (sym && SYMBOL_LANGUAGE (sym) != language_asm)
{
{
CORE_ADDR func_addr, func_end;
- if (!get_frame_saved_regs (fi))
+ if (!deprecated_get_frame_saved_regs (fi))
{
frame_saved_regs_zalloc (fi);
/* Function: xstormy16_frame_saved_pc
Returns the return address for the selected frame.
- Called by frame_info, frame_chain_valid, and sometimes by
- get_prev_frame.
-*/
+ Called by frame_info, legacy_frame_chain_valid, and sometimes by
+ get_prev_frame. */
static CORE_ADDR
xstormy16_frame_saved_pc (struct frame_info *fi)
{
CORE_ADDR saved_pc;
- if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (fi), get_frame_base (fi),
- get_frame_base (fi)))
+ if (deprecated_pc_in_call_dummy (get_frame_pc (fi)))
{
saved_pc = deprecated_read_register_dummy (get_frame_pc (fi),
get_frame_base (fi),
}
else
{
- saved_pc = read_memory_unsigned_integer (get_frame_saved_regs (fi)[E_PC_REGNUM],
+ saved_pc = read_memory_unsigned_integer (deprecated_get_frame_saved_regs (fi)[E_PC_REGNUM],
xstormy16_pc_size);
}
static CORE_ADDR
xstormy16_frame_chain (struct frame_info *fi)
{
- if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (fi), get_frame_base (fi),
- get_frame_base (fi)))
+ if (deprecated_pc_in_call_dummy (get_frame_pc (fi)))
{
/* Call dummy's frame is the same as caller's. */
return get_frame_base (fi);
xstormy16_pointer_to_address (struct type *type, const void *buf)
{
enum type_code target = TYPE_CODE (TYPE_TARGET_TYPE (type));
- CORE_ADDR addr = extract_address (buf, TYPE_LENGTH (type));
+ CORE_ADDR addr = extract_unsigned_integer (buf, TYPE_LENGTH (type));
if (target == TYPE_CODE_FUNC || target == TYPE_CODE_METHOD)
{
if (addr2)
addr = addr2;
}
- store_address (buf, TYPE_LENGTH (type), addr);
+ store_unsigned_integer (buf, TYPE_LENGTH (type), addr);
}
static CORE_ADDR
return addr;
}
-void
+static void
xstormy16_save_dummy_frame_tos (CORE_ADDR sp)
{
generic_save_dummy_frame_tos (sp - xstormy16_pc_size);
static struct gdbarch *
xstormy16_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
{
- static LONGEST call_dummy_words[1] = { 0 };
struct gdbarch_tdep *tdep = NULL;
struct gdbarch *gdbarch;
/* 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.
set_gdbarch_num_regs (gdbarch, E_NUM_REGS);
set_gdbarch_num_pseudo_regs (gdbarch, 0);
set_gdbarch_sp_regnum (gdbarch, E_SP_REGNUM);
- set_gdbarch_fp_regnum (gdbarch, E_FP_REGNUM);
+ set_gdbarch_deprecated_fp_regnum (gdbarch, E_FP_REGNUM);
set_gdbarch_pc_regnum (gdbarch, E_PC_REGNUM);
set_gdbarch_register_name (gdbarch, xstormy16_register_name);
- set_gdbarch_register_size (gdbarch, xstormy16_reg_size);
- set_gdbarch_register_bytes (gdbarch, E_ALL_REGS_SIZE);
- set_gdbarch_register_byte (gdbarch, xstormy16_register_byte);
- set_gdbarch_register_raw_size (gdbarch, xstormy16_register_raw_size);
- set_gdbarch_deprecated_max_register_raw_size (gdbarch, xstormy16_pc_size);
- set_gdbarch_register_virtual_size (gdbarch, xstormy16_register_raw_size);
- set_gdbarch_deprecated_max_register_virtual_size (gdbarch, 4);
- set_gdbarch_register_virtual_type (gdbarch, xstormy16_reg_virtual_type);
+ set_gdbarch_deprecated_register_size (gdbarch, xstormy16_reg_size);
+ set_gdbarch_deprecated_register_byte (gdbarch, xstormy16_register_byte);
+ set_gdbarch_deprecated_register_raw_size (gdbarch, xstormy16_register_raw_size);
+ set_gdbarch_deprecated_register_virtual_size (gdbarch, xstormy16_register_raw_size);
+ set_gdbarch_deprecated_register_virtual_type (gdbarch, xstormy16_reg_virtual_type);
/*
* Frame Info
xstormy16_frame_init_saved_regs);
set_gdbarch_deprecated_frame_chain (gdbarch, xstormy16_frame_chain);
set_gdbarch_deprecated_get_saved_register (gdbarch, xstormy16_get_saved_register);
- set_gdbarch_saved_pc_after_call (gdbarch, xstormy16_saved_pc_after_call);
+ set_gdbarch_deprecated_saved_pc_after_call (gdbarch, xstormy16_saved_pc_after_call);
set_gdbarch_deprecated_frame_saved_pc (gdbarch, xstormy16_frame_saved_pc);
set_gdbarch_skip_prologue (gdbarch, xstormy16_skip_prologue);
set_gdbarch_deprecated_frame_chain_valid (gdbarch, xstormy16_frame_chain_valid);
*/
/* Stack grows up. */
set_gdbarch_inner_than (gdbarch, core_addr_greaterthan);
- /* 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);
- /* OK to default this value to 'unknown'. */
- set_gdbarch_frame_num_args (gdbarch, frame_num_args_unknown);
/*
* Call Dummies
set_gdbarch_deprecated_store_struct_return (gdbarch, xstormy16_store_struct_return);
set_gdbarch_deprecated_store_return_value (gdbarch, xstormy16_store_return_value);
set_gdbarch_deprecated_extract_struct_value_address (gdbarch, xstormy16_extract_struct_value_address);
- set_gdbarch_use_struct_convention (gdbarch,
- xstormy16_use_struct_convention);
- set_gdbarch_call_dummy_start_offset (gdbarch, 0);
- set_gdbarch_call_dummy_length (gdbarch, 0);
- set_gdbarch_call_dummy_words (gdbarch, call_dummy_words);
- set_gdbarch_sizeof_call_dummy_words (gdbarch, 0);
+ set_gdbarch_deprecated_use_struct_convention (gdbarch, xstormy16_use_struct_convention);
set_gdbarch_breakpoint_from_pc (gdbarch, xstormy16_breakpoint_from_pc);
set_gdbarch_char_signed (gdbarch, 0);
set_gdbarch_address_to_pointer (gdbarch, xstormy16_address_to_pointer);
set_gdbarch_pointer_to_address (gdbarch, xstormy16_pointer_to_address);
- set_gdbarch_stack_align (gdbarch, xstormy16_stack_align);
+ set_gdbarch_deprecated_stack_align (gdbarch, xstormy16_stack_align);
- set_gdbarch_save_dummy_frame_tos (gdbarch, xstormy16_save_dummy_frame_tos);
+ set_gdbarch_deprecated_save_dummy_frame_tos (gdbarch, xstormy16_save_dummy_frame_tos);
set_gdbarch_skip_trampoline_code (gdbarch, xstormy16_skip_trampoline_code);
xstormy16_in_solib_call_trampoline);
/* Should be using push_dummy_call. */
- set_gdbarch_deprecated_dummy_write_sp (gdbarch, generic_target_write_sp);
+ set_gdbarch_deprecated_dummy_write_sp (gdbarch, deprecated_write_sp);
+
+ set_gdbarch_print_insn (gdbarch, print_insn_xstormy16);
return gdbarch;
}
Initializer function for the Sanyo Xstormy16a module.
Called by gdb at start-up. */
+extern initialize_file_ftype _initialize_xstormy16_tdep; /* -Wmissing-prototypes */
+
void
_initialize_xstormy16_tdep (void)
{
- extern int print_insn_xstormy16 ();
-
register_gdbarch_init (bfd_arch_xstormy16, xstormy16_gdbarch_init);
- tm_print_insn = print_insn_xstormy16;
}