/* Target-machine dependent code for Motorola 88000 series, for GDB.
- Copyright 1988, 1990, 1991, 1994, 1995 Free Software Foundation, Inc.
+
+ Copyright 1988, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998,
+ 2000, 2001, 2002 Free Software Foundation, Inc.
This file is part of GDB.
#include "symtab.h"
#include "setjmp.h"
#include "value.h"
+#include "regcache.h"
/* Size of an instruction */
#define BYTES_PER_88K_INSN 4
int target_is_m88110 = 0;
+void
+m88k_target_write_pc (CORE_ADDR pc, ptid_t ptid)
+{
+ /* According to the MC88100 RISC Microprocessor User's Manual,
+ section 6.4.3.1.2:
+
+ ... can be made to return to a particular instruction by placing
+ a valid instruction address in the SNIP and the next sequential
+ instruction address in the SFIP (with V bits set and E bits
+ clear). The rte resumes execution at the instruction pointed to
+ by the SNIP, then the SFIP.
+
+ The E bit is the least significant bit (bit 0). The V (valid)
+ bit is bit 1. This is why we logical or 2 into the values we are
+ writing below. It turns out that SXIP plays no role when
+ returning from an exception so nothing special has to be done
+ with it. We could even (presumably) give it a totally bogus
+ value.
+
+ -- Kevin Buettner */
+
+ write_register_pid (SXIP_REGNUM, pc, ptid);
+ write_register_pid (SNIP_REGNUM, (pc | 2), ptid);
+ write_register_pid (SFIP_REGNUM, (pc | 2) + 4, ptid);
+}
+
+/* The type of a register. */
+struct type *
+m88k_register_type (int regnum)
+{
+ if (regnum >= XFP_REGNUM)
+ return builtin_type_m88110_ext;
+ else if (regnum == PC_REGNUM || regnum == FP_REGNUM || regnum == SP_REGNUM)
+ return builtin_type_void_func_ptr;
+ else
+ return builtin_type_int32;
+}
+
+
/* The m88k kernel aligns all instructions on 4-byte boundaries. The
kernel also uses the least significant two bits for its own hocus
pocus. When gdb receives an address from the kernel, it needs to
of an instruction. Shrug. */
CORE_ADDR
-m88k_addr_bits_remove (addr)
- CORE_ADDR addr;
+m88k_addr_bits_remove (CORE_ADDR addr)
{
return ((addr) & ~3);
}
the function prologue to determine the caller's sp value, and return it. */
CORE_ADDR
-frame_chain (thisframe)
- struct frame_info *thisframe;
+frame_chain (struct frame_info *thisframe)
{
frame_find_saved_regs (thisframe, (struct frame_saved_regs *) 0);
}
int
-frameless_function_invocation (frame)
- struct frame_info *frame;
+frameless_function_invocation (struct frame_info *frame)
{
frame_find_saved_regs (frame, (struct frame_saved_regs *) 0);
}
void
-init_extra_frame_info (fromleaf, frame)
- int fromleaf;
- struct frame_info *frame;
+init_extra_frame_info (int fromleaf, struct frame_info *frame)
{
frame->fsr = 0; /* Not yet allocated */
frame->args_pointer = 0; /* Unknown */
is stored at 'pword1'. */
CORE_ADDR
-next_insn (memaddr, pword1)
- unsigned long *pword1;
- CORE_ADDR memaddr;
+next_insn (CORE_ADDR memaddr, unsigned long *pword1)
{
*pword1 = read_memory_integer (memaddr, BYTES_PER_88K_INSN);
return memaddr + BYTES_PER_88K_INSN;
/* Read a register from frames called by us (or from the hardware regs). */
static int
-read_next_frame_reg (frame, regno)
- struct frame_info *frame;
- int regno;
+read_next_frame_reg (struct frame_info *frame, int regno)
{
for (; frame; frame = frame->next)
{
to reflect the offsets of the arg pointer and the locals pointer. */
static CORE_ADDR
-examine_prologue (ip, limit, frame_sp, fsr, fi)
- register CORE_ADDR ip;
- register CORE_ADDR limit;
- CORE_ADDR frame_sp;
- struct frame_saved_regs *fsr;
- struct frame_info *fi;
+examine_prologue (register CORE_ADDR ip, register CORE_ADDR limit,
+ CORE_ADDR frame_sp, struct frame_saved_regs *fsr,
+ struct frame_info *fi)
{
register CORE_ADDR next_ip;
register int src;
- unsigned int insn;
+ unsigned long insn;
int size, offset;
char must_adjust[32]; /* If set, must adjust offsets in fsr */
int sp_offset = -1; /* -1 means not set (valid must be mult of 8) */
/* (we hope...) */
if (fsr->regs[SP_REGNUM] != 0
&& fsr->regs[SP_REGNUM] != frame_sp - sp_offset)
- fprintf_unfiltered (gdb_stderr, "Bad saved SP value %x != %x, offset %x!\n",
+ fprintf_unfiltered (gdb_stderr, "Bad saved SP value %lx != %lx, offset %x!\n",
fsr->regs[SP_REGNUM],
frame_sp - sp_offset, sp_offset);
prologue. */
CORE_ADDR
-m88k_skip_prologue (ip)
-CORE_ADDR (ip);
+m88k_skip_prologue (CORE_ADDR ip)
{
struct frame_saved_regs saved_regs_dummy;
struct symtab_and_line sal;
fairly expensive. */
void
-frame_find_saved_regs (fi, fsr)
- struct frame_info *fi;
- struct frame_saved_regs *fsr;
+frame_find_saved_regs (struct frame_info *fi, struct frame_saved_regs *fsr)
{
register struct frame_saved_regs *cache_fsr;
CORE_ADDR ip;
argument pointer, so this is the same as frame_args_address(). */
CORE_ADDR
-frame_locals_address (fi)
- struct frame_info *fi;
+frame_locals_address (struct frame_info *fi)
{
struct frame_saved_regs fsr;
described by FI. Returns 0 if the address is unknown. */
CORE_ADDR
-frame_args_address (fi)
- struct frame_info *fi;
+frame_args_address (struct frame_info *fi)
{
struct frame_saved_regs fsr;
just use the register SRP_REGNUM itself. */
CORE_ADDR
-frame_saved_pc (frame)
- struct frame_info *frame;
+frame_saved_pc (struct frame_info *frame)
{
return read_next_frame_reg (frame, SRP_REGNUM);
}
#define DUMMY_FRAME_SIZE 192
static void
-write_word (sp, word)
- CORE_ADDR sp;
- ULONGEST word;
+write_word (CORE_ADDR sp, ULONGEST word)
{
register int len = REGISTER_SIZE;
char buffer[MAX_REGISTER_RAW_SIZE];
}
void
-m88k_push_dummy_frame ()
+m88k_push_dummy_frame (void)
{
register CORE_ADDR sp = read_register (SP_REGNUM);
register int rn;
}
void
-pop_frame ()
+pop_frame (void)
{
register struct frame_info *frame = get_current_frame ();
- register CORE_ADDR fp;
register int regnum;
struct frame_saved_regs fsr;
- fp = FRAME_FP (frame);
get_frame_saved_regs (frame, &fsr);
- if (PC_IN_CALL_DUMMY (read_pc (), read_register (SP_REGNUM), FRAME_FP (fi)))
+ if (PC_IN_CALL_DUMMY (read_pc (), read_register (SP_REGNUM), frame->frame))
{
/* FIXME: I think get_frame_saved_regs should be handling this so
that we can deal with the saved registers properly (e.g. frame
}
void
-_initialize_m88k_tdep ()
+_initialize_m88k_tdep (void)
{
tm_print_insn = print_insn_m88k;
}