/* Target-machine dependent code for the AMD 29000
- Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
+ Copyright 1990, 1991, 1992, 1993, 1994, 1995
+ Free Software Foundation, Inc.
Contributed by Cygnus Support. Written by Jim Kingdon.
-This file is part of GDB.
+ This file is part of GDB.
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
#include "defs.h"
#include "gdbcore.h"
static CORE_ADDR rstack_high_address = UINT_MAX;
+
+/* Should call_function allocate stack space for a struct return? */
+/* On the a29k objects over 16 words require the caller to allocate space. */
+int
+a29k_use_struct_convention (int gcc_p, struct type *type)
+{
+ return (TYPE_LENGTH (type) > 16 * 4);
+}
+
+
/* Structure to hold cached info about function prologues. */
struct prologue_info
{
CORE_ADDR pc; /* First addr after fn prologue */
unsigned rsize, msize; /* register stack frame size, mem stack ditto */
- unsigned mfp_used : 1; /* memory frame pointer used */
- unsigned rsize_valid : 1; /* Validity bits for the above */
- unsigned msize_valid : 1;
- unsigned mfp_valid : 1;
+ unsigned mfp_used:1; /* memory frame pointer used */
+ unsigned rsize_valid:1; /* Validity bits for the above */
+ unsigned msize_valid:1;
+ unsigned mfp_valid:1;
};
/* Examine the prologue of a function which starts at PC. Return
frame pointer is being used. */
CORE_ADDR
-examine_prologue (pc, rsize, msize, mfp_used)
- CORE_ADDR pc;
- unsigned *msize;
- unsigned *rsize;
- int *mfp_used;
+examine_prologue (CORE_ADDR pc, unsigned *rsize, unsigned *msize, int *mfp_used)
{
long insn;
CORE_ADDR p = pc;
struct prologue_info *mi = 0;
if (msymbol != NULL)
- mi = (struct prologue_info *) msymbol -> info;
+ mi = (struct prologue_info *) msymbol->info;
if (mi != 0)
{
*msize = 0;
if (mfp_used != NULL)
*mfp_used = 0;
-
+
/* Prologue must start with subtracting a constant from gr1.
Normally this is sub gr1,gr1,<rsize * 4>. */
insn = read_memory_integer (p, 4);
if ((insn & 0xffffff00) != 0x25010100)
{
/* If the frame is large, instead of a single instruction it
- might be a pair of instructions:
- const <reg>, <rsize * 4>
- sub gr1,gr1,<reg>
- */
+ might be a pair of instructions:
+ const <reg>, <rsize * 4>
+ sub gr1,gr1,<reg>
+ */
int reg;
/* Possible value for rsize. */
unsigned int rsize0;
-
+
if ((insn & 0xff000000) != 0x03000000)
{
p = pc;
* way down.
*/
insn = read_memory_integer (p, 4);
- if ((insn & 0xff00ffff) == (0x5e000100|RAB_HW_REGNUM))
+ if ((insn & 0xff00ffff) == (0x5e000100 | RAB_HW_REGNUM))
{
p += 4;
}
else
{
/* However, for large frames it can be
- const <reg>, <size *4>
- add lr1,gr1,<reg>
- */
+ const <reg>, <size *4>
+ add lr1,gr1,<reg>
+ */
int reg;
CORE_ADDR q;
to be looking for a "sub" instruction here, but the mask was set
up to lose all the time. */
insn = read_memory_integer (p, 4);
- if (((insn & 0xff80ffff) == (0x15800000|(MSP_HW_REGNUM<<8))) /* add */
- || ((insn & 0xff80ffff) == (0x81800000|(MSP_HW_REGNUM<<8)))) /* sll */
+ if (((insn & 0xff80ffff) == (0x15800000 | (MSP_HW_REGNUM << 8))) /* add */
+ || ((insn & 0xff80ffff) == (0x81800000 | (MSP_HW_REGNUM << 8)))) /* sll */
{
p += 4;
if (mfp_used != NULL)
Normally this is just
sub msp,msp,<msize>
- */
+ */
insn = read_memory_integer (p, 4);
- if ((insn & 0xffffff00) ==
- (0x25000000|(MSP_HW_REGNUM<<16)|(MSP_HW_REGNUM<<8)))
+ if ((insn & 0xffffff00) ==
+ (0x25000000 | (MSP_HW_REGNUM << 16) | (MSP_HW_REGNUM << 8)))
{
p += 4;
- if (msize != NULL)
+ if (msize != NULL)
*msize = insn & 0xff;
}
else
{
/* For large frames, instead of a single instruction it might
- be
+ be
- const <reg>, <msize>
- consth <reg>, <msize> ; optional
- sub msp,msp,<reg>
- */
+ const <reg>, <msize>
+ consth <reg>, <msize> ; optional
+ sub msp,msp,<reg>
+ */
int reg;
unsigned msize0;
CORE_ADDR q = p;
insn = read_memory_integer (q, 4);
}
/* Check for sub msp,msp,<reg>. */
- if ((insn & 0xffffff00) ==
- (0x24000000|(MSP_HW_REGNUM<<16)|(MSP_HW_REGNUM<<8))
+ if ((insn & 0xffffff00) ==
+ (0x24000000 | (MSP_HW_REGNUM << 16) | (MSP_HW_REGNUM << 8))
&& (insn & 0xff) == reg)
{
p = q + 4;
* way down after everything else.
*/
insn = read_memory_integer (p, 4);
- if ((insn & 0xff00ffff) == (0x5e000100|RAB_HW_REGNUM))
+ if ((insn & 0xff00ffff) == (0x5e000100 | RAB_HW_REGNUM))
{
p += 4;
}
- done:
+done:
if (msymbol != NULL)
{
if (mi == 0)
{
/* Add a new cache entry. */
- mi = (struct prologue_info *)xmalloc (sizeof (struct prologue_info));
- msymbol -> info = (char *)mi;
+ mi = (struct prologue_info *) xmalloc (sizeof (struct prologue_info));
+ msymbol->info = (char *) mi;
mi->rsize_valid = 0;
mi->msize_valid = 0;
mi->mfp_valid = 0;
to reach some "real" code. */
CORE_ADDR
-skip_prologue (pc)
- CORE_ADDR pc;
+a29k_skip_prologue (CORE_ADDR pc)
{
return examine_prologue (pc, NULL, NULL, NULL);
}
* msize is return in bytes.
*/
-static int /* 0/1 - failure/success of finding the tag word */
-examine_tag (p, is_trans, argcount, msize, mfp_used)
- CORE_ADDR p;
- int *is_trans;
- int *argcount;
- unsigned *msize;
- int *mfp_used;
+static int /* 0/1 - failure/success of finding the tag word */
+examine_tag (CORE_ADDR p, int *is_trans, int *argcount, unsigned *msize,
+ int *mfp_used)
{
unsigned int tag1, tag2;
tag1 = read_memory_integer (p, 4);
if ((tag1 & TAGWORD_ZERO_MASK) != 0) /* Not a tag word */
return 0;
- if (tag1 & (1<<23)) /* A two word tag */
+ if (tag1 & (1 << 23)) /* A two word tag */
{
- tag2 = read_memory_integer (p-4, 4);
- if (msize)
- *msize = tag2 * 2;
+ tag2 = read_memory_integer (p - 4, 4);
+ if (msize)
+ *msize = tag2 * 2;
}
- else /* A one word tag */
+ else
+ /* A one word tag */
{
- if (msize)
- *msize = tag1 & 0x7ff;
+ if (msize)
+ *msize = tag1 & 0x7ff;
}
if (is_trans)
- *is_trans = ((tag1 & (1<<21)) ? 1 : 0);
+ *is_trans = ((tag1 & (1 << 21)) ? 1 : 0);
/* Note that this includes the frame pointer and the return address
register, so the actual number of registers of arguments is two less.
argcount can be zero, however, sometimes, for strange assembler
if (argcount)
*argcount = (tag1 >> 16) & 0x1f;
if (mfp_used)
- *mfp_used = ((tag1 & (1<<22)) ? 1 : 0);
+ *mfp_used = ((tag1 & (1 << 22)) ? 1 : 0);
return 1;
}
of stacks and the frame cache in tm-a29k.h for more detail. */
static void
-init_frame_info (innermost_frame, frame)
- int innermost_frame;
- struct frame_info *frame;
+init_frame_info (int innermost_frame, struct frame_info *frame)
{
CORE_ADDR p;
long insn;
frame->frame = read_register (GR1_REGNUM);
else
frame->frame = frame->next->frame + frame->next->rsize;
-
-#if CALL_DUMMY_LOCATION == ON_STACK
+
+#if 0 /* CALL_DUMMY_LOCATION == ON_STACK */
This wont work;
#else
if (PC_IN_CALL_DUMMY (p, 0, 0))
{
frame->rsize = DUMMY_FRAME_RSIZE;
/* This doesn't matter since we never try to get locals or args
- from a dummy frame. */
+ from a dummy frame. */
frame->msize = 0;
/* Dummy frames always use a memory frame pointer. */
- frame->saved_msp =
+ frame->saved_msp =
read_register_stack_integer (frame->frame + DUMMY_FRAME_RSIZE - 4, 4);
- frame->flags |= (TRANSPARENT|MFP_USED);
+ frame->flags |= (TRANSPARENT_FRAME | MFP_USED);
return;
}
-
+
func = find_pc_function (p);
if (func != NULL)
p = BLOCK_START (SYMBOL_BLOCK_VALUE (func));
else
{
/* Search backward to find the trace-back tag. However,
- do not trace back beyond the start of the text segment
- (just as a sanity check to avoid going into never-never land). */
+ do not trace back beyond the start of the text segment
+ (just as a sanity check to avoid going into never-never land). */
#if 1
while (p >= text_start
- && ((insn = read_memory_integer (p, 4)) & TAGWORD_ZERO_MASK) != 0)
+ && ((insn = read_memory_integer (p, 4)) & TAGWORD_ZERO_MASK) != 0)
p -= 4;
#else /* 0 */
- char pat[4] = {0, 0, 0, 0};
+ char pat[4] =
+ {0, 0, 0, 0};
char mask[4];
char insn_raw[4];
store_unsigned_integer (mask, 4, TAGWORD_ZERO_MASK);
/* Enable this once target_search is enabled and tested. */
- target_search (4, pat, mask, p, -4, text_start, p+1, &p, &insn_raw);
+ target_search (4, pat, mask, p, -4, text_start, p + 1, &p, &insn_raw);
insn = extract_unsigned_integer (insn_raw, 4);
#endif /* 0 */
frame->saved_msp = 0;
frame->rsize = 0;
frame->msize = 0;
- frame->flags = TRANSPARENT;
+ frame->flags = TRANSPARENT_FRAME;
return;
}
else
If one doesn't exist, try using a more exhaustive search of
the prologue. */
- if (examine_tag(p-4,&trans,(int *)NULL,&msize,&mfp_used)) /* Found good tag */
- examine_prologue (p, &rsize, 0, 0);
- else /* No tag try prologue */
- examine_prologue (p, &rsize, &msize, &mfp_used);
+ if (examine_tag (p - 4, &trans, (int *) NULL, &msize, &mfp_used)) /* Found good tag */
+ examine_prologue (p, &rsize, 0, 0);
+ else /* No tag try prologue */
+ examine_prologue (p, &rsize, &msize, &mfp_used);
frame->rsize = rsize;
frame->msize = msize;
frame->flags = 0;
if (mfp_used)
- frame->flags |= MFP_USED;
+ frame->flags |= MFP_USED;
if (trans)
- frame->flags |= TRANSPARENT;
+ frame->flags |= TRANSPARENT_FRAME;
if (innermost_frame)
{
frame->saved_msp = read_register (MSP_REGNUM) + msize;
else
{
if (mfp_used)
- frame->saved_msp =
- read_register_stack_integer (frame->frame + rsize - 4, 4);
+ frame->saved_msp =
+ read_register_stack_integer (frame->frame + rsize - 4, 4);
else
- frame->saved_msp = frame->next->saved_msp + msize;
+ frame->saved_msp = frame->next->saved_msp + msize;
}
}
void
-init_extra_frame_info (frame)
- struct frame_info *frame;
+init_extra_frame_info (struct frame_info *frame)
{
if (frame->next == 0)
/* Assume innermost frame. May produce strange results for "info frame"
but there isn't any way to tell the difference. */
init_frame_info (1, frame);
- else {
- /* We're in get_prev_frame_info.
+ else
+ {
+ /* We're in get_prev_frame.
Take care of everything in init_frame_pc. */
;
}
}
void
-init_frame_pc (fromleaf, frame)
- int fromleaf;
- struct frame_info *frame;
+init_frame_pc (int fromleaf, struct frame_info *frame)
{
frame->pc = (fromleaf ? SAVED_PC_AFTER_CALL (frame->next) :
- frame->next ? FRAME_SAVED_PC (frame->next) : read_pc ());
+ frame->next ? FRAME_SAVED_PC (frame->next) : read_pc ());
init_frame_info (fromleaf, frame);
}
\f
saved_msp (gcc). */
CORE_ADDR
-frame_locals_address (fi)
- struct frame_info *fi;
+frame_locals_address (struct frame_info *fi)
{
- if (fi->flags & MFP_USED)
+ if (fi->flags & MFP_USED)
return fi->saved_msp;
else
return fi->saved_msp - fi->msize;
on where it came from. The contents written into MYADDR are in
target format. */
void
-read_register_stack (memaddr, myaddr, actual_mem_addr, lval)
- CORE_ADDR memaddr;
- char *myaddr;
- CORE_ADDR *actual_mem_addr;
- enum lval_type *lval;
+read_register_stack (CORE_ADDR memaddr, char *myaddr,
+ CORE_ADDR *actual_mem_addr, enum lval_type *lval)
{
long rfb = read_register (RFB_REGNUM);
long rsp = read_register (RSP_REGNUM);
/* If we don't do this 'info register' stops in the middle. */
- if (memaddr >= rstack_high_address)
+ if (memaddr >= rstack_high_address)
{
/* a bogus value */
- static char val[] = {~0, ~0, ~0, ~0};
+ static char val[] =
+ {~0, ~0, ~0, ~0};
/* It's in a local register, but off the end of the stack. */
int regnum = (memaddr - rsp) / 4 + LR0_REGNUM;
if (myaddr != NULL)
/* Provide bogusness */
memcpy (myaddr, val, 4);
}
- supply_register(regnum, val); /* More bogusness */
+ supply_register (regnum, val); /* More bogusness */
if (lval != NULL)
*lval = lval_register;
if (actual_mem_addr != NULL)
else
{
/* It's in the memory portion of the register stack. */
- if (myaddr != NULL)
+ if (myaddr != NULL)
read_memory (memaddr, myaddr, 4);
if (lval != NULL)
*lval = lval_memory;
/* Analogous to read_memory_integer
except the length is understood to be 4. */
long
-read_register_stack_integer (memaddr, len)
- CORE_ADDR memaddr;
- int len;
+read_register_stack_integer (CORE_ADDR memaddr, int len)
{
char buf[4];
read_register_stack (memaddr, buf, NULL, NULL);
at MEMADDR and put the actual address written into in
*ACTUAL_MEM_ADDR. */
static void
-write_register_stack (memaddr, myaddr, actual_mem_addr)
- CORE_ADDR memaddr;
- char *myaddr;
- CORE_ADDR *actual_mem_addr;
+write_register_stack (CORE_ADDR memaddr, char *myaddr,
+ CORE_ADDR *actual_mem_addr)
{
long rfb = read_register (RFB_REGNUM);
long rsp = read_register (RSP_REGNUM);
/* If we don't do this 'info register' stops in the middle. */
- if (memaddr >= rstack_high_address)
+ if (memaddr >= rstack_high_address)
{
/* It's in a register, but off the end of the stack. */
if (actual_mem_addr != NULL)
- *actual_mem_addr = 0;
+ *actual_mem_addr = 0;
}
else if (memaddr < rfb)
{
if (regnum < LR0_REGNUM || regnum > LR0_REGNUM + 127)
error ("Attempt to read register stack out of range.");
if (myaddr != NULL)
- write_register (regnum, *(long *)myaddr);
+ write_register (regnum, *(long *) myaddr);
if (actual_mem_addr != NULL)
*actual_mem_addr = 0;
}
The argument RAW_BUFFER must point to aligned memory. */
void
-get_saved_register (raw_buffer, optimized, addrp, frame, regnum, lvalp)
- char *raw_buffer;
- int *optimized;
- CORE_ADDR *addrp;
- struct frame_info *frame;
- int regnum;
- enum lval_type *lvalp;
+a29k_get_saved_register (char *raw_buffer, int *optimized, CORE_ADDR *addrp,
+ struct frame_info *frame, int regnum,
+ enum lval_type *lvalp)
{
struct frame_info *fi;
CORE_ADDR addr;
enum lval_type lval;
+ if (!target_has_registers)
+ error ("No registers.");
+
+ /* Probably now redundant with the target_has_registers check. */
if (frame == 0)
return;
*lvalp = not_lval;
return;
}
- else if (regnum == PC_REGNUM)
+ else if (regnum == PC_REGNUM && frame->next != NULL)
{
if (raw_buffer != NULL)
{
else if (regnum < LR0_REGNUM || regnum >= LR0_REGNUM + 128)
{
/* These registers are not saved over procedure calls,
- so just print out the current values. */
+ so just print out the current values. */
if (raw_buffer != NULL)
read_register_gen (regnum, raw_buffer);
if (lvalp != NULL)
*addrp = REGISTER_BYTE (regnum);
return;
}
-
+
addr = frame->frame + (regnum - LR0_REGNUM) * 4;
if (raw_buffer != NULL)
read_register_stack (addr, raw_buffer, &addr, &lval);
restoring all saved registers. */
void
-pop_frame ()
+pop_frame (void)
{
struct frame_info *frame = get_current_frame ();
- CORE_ADDR rfb = read_register (RFB_REGNUM);
- CORE_ADDR gr1 = fi->frame + fi->rsize;
- CORE_ADDR lr1;
+ CORE_ADDR rfb = read_register (RFB_REGNUM);
+ CORE_ADDR gr1 = frame->frame + frame->rsize;
+ CORE_ADDR lr1;
CORE_ADDR original_lr0;
int must_fix_lr0 = 0;
int i;
read_register (SP_REGNUM),
FRAME_FP (frame)))
{
- int lrnum = LR0_REGNUM + DUMMY_ARG/4;
+ int lrnum = LR0_REGNUM + DUMMY_ARG / 4;
for (i = 0; i < DUMMY_SAVE_SR128; ++i)
- write_register (SR_REGNUM (i + 128),read_register (lrnum++));
+ write_register (SR_REGNUM (i + 128), read_register (lrnum++));
for (i = 0; i < DUMMY_SAVE_SR160; ++i)
- write_register (SR_REGNUM(i+160), read_register (lrnum++));
+ write_register (SR_REGNUM (i + 160), read_register (lrnum++));
for (i = 0; i < DUMMY_SAVE_GREGS; ++i)
write_register (RETURN_REGNUM + i, read_register (lrnum++));
/* Restore the PCs and prepare to restore LR0. */
- write_register(PC_REGNUM, read_register (lrnum++));
- write_register(NPC_REGNUM, read_register (lrnum++));
- write_register(PC2_REGNUM, read_register (lrnum++));
+ write_register (PC_REGNUM, read_register (lrnum++));
+ write_register (NPC_REGNUM, read_register (lrnum++));
+ write_register (PC2_REGNUM, read_register (lrnum++));
original_lr0 = read_register (lrnum++);
must_fix_lr0 = 1;
}
/* Restore the memory stack pointer. */
write_register (MSP_REGNUM, frame->saved_msp);
- /* Restore the register stack pointer. */
+ /* Restore the register stack pointer. */
write_register (GR1_REGNUM, gr1);
/* If we popped a dummy frame, restore lr0 now that gr1 has been restored. */
- if (must_fix_lr0)
+ if (must_fix_lr0)
write_register (LR0_REGNUM, original_lr0);
- /* Check whether we need to fill registers. */
- lr1 = read_register (LR0_REGNUM + 1);
- if (lr1 > rfb)
- {
- /* Fill. */
+ /* Check whether we need to fill registers. */
+ lr1 = read_register (LR0_REGNUM + 1);
+ if (lr1 > rfb)
+ {
+ /* Fill. */
int num_bytes = lr1 - rfb;
- int i;
+ int i;
long word;
-
- write_register (RAB_REGNUM, read_register (RAB_REGNUM) + num_bytes);
- write_register (RFB_REGNUM, lr1);
- for (i = 0; i < num_bytes; i += 4)
- {
+
+ write_register (RAB_REGNUM, read_register (RAB_REGNUM) + num_bytes);
+ write_register (RFB_REGNUM, lr1);
+ for (i = 0; i < num_bytes; i += 4)
+ {
/* Note: word is in host byte order. */
- word = read_memory_integer (rfb + i, 4);
- write_register (LR0_REGNUM + ((rfb - gr1) % 0x80) + i / 4, word);
- }
+ word = read_memory_integer (rfb + i, 4);
+ write_register (LR0_REGNUM + ((rfb - gr1) % 0x80) + i / 4, word);
+ }
}
- flush_cached_frames ();
+ flush_cached_frames ();
}
/* Push an empty stack frame, to record the current PC, etc. */
-void
-push_dummy_frame ()
+void
+push_dummy_frame (void)
{
long w;
CORE_ADDR rab, gr1;
CORE_ADDR msp = read_register (MSP_REGNUM);
int lrnum, i;
CORE_ADDR original_lr0;
-
+
/* Read original lr0 before changing gr1. This order isn't really needed
since GDB happens to have a snapshot of all the regs and doesn't toss
it when gr1 is changed. But it's The Right Thing To Do. */
original_lr0 = read_register (LR0_REGNUM);
- /* Allocate the new frame. */
+ /* Allocate the new frame. */
gr1 = read_register (GR1_REGNUM) - DUMMY_FRAME_RSIZE;
write_register (GR1_REGNUM, gr1);
+#ifdef VXWORKS_TARGET
+ /* We force re-reading all registers to get the new local registers set
+ after gr1 has been modified. This fix is due to the lack of single
+ register read/write operation in the RPC interface between VxGDB and
+ VxWorks. This really must be changed ! */
+
+ vx_read_register (-1);
+
+#endif /* VXWORK_TARGET */
+
rab = read_register (RAB_REGNUM);
if (gr1 < rab)
{
write_register (MSP_REGNUM, msp - 16 * 4);
/* Save registers. */
- lrnum = LR0_REGNUM + DUMMY_ARG/4;
+ lrnum = LR0_REGNUM + DUMMY_ARG / 4;
for (i = 0; i < DUMMY_SAVE_SR128; ++i)
write_register (lrnum++, read_register (SR_REGNUM (i + 128)));
for (i = 0; i < DUMMY_SAVE_SR160; ++i)
good job. */
struct frame_info *
-setup_arbitrary_frame (argc, argv)
- int argc;
- CORE_ADDR *argv;
+setup_arbitrary_frame (int argc, CORE_ADDR *argv)
{
struct frame_info *frame;
frame = create_new_frame (argv[0], argv[1]);
if (!frame)
- fatal ("internal: create_new_frame returned invalid frame id");
-
+ internal_error ("create_new_frame returned invalid frame id");
+
/* Creating a new frame munges the `frame' value from the current
GR1, so we restore it again here. FIXME, untangle all this
29K frame stuff... */
return frame;
}
+int
+gdb_print_insn_a29k (bfd_vma memaddr, disassemble_info *info)
+{
+ if (TARGET_BYTE_ORDER == BIG_ENDIAN)
+ return print_insn_big_a29k (memaddr, info);
+ else
+ return print_insn_little_a29k (memaddr, info);
+}
+
enum a29k_processor_types processor_type = a29k_unknown;
void
-a29k_get_processor_type ()
+a29k_get_processor_type (void)
{
unsigned int cfg_reg = (unsigned int) read_register (CFG_REGNUM);
fprintf_filtered (gdb_stderr, " revision %c\n", 'A' + ((cfg_reg >> 24) & 0x0f));
}
+#ifdef GET_LONGJMP_TARGET
+/* Figure out where the longjmp will land. We expect that we have just entered
+ longjmp and haven't yet setup the stack frame, so the args are still in the
+ output regs. lr2 (LR2_REGNUM) points at the jmp_buf structure from which we
+ extract the pc (JB_PC) that we will land at. The pc is copied into ADDR.
+ This routine returns true on success */
+
+int
+get_longjmp_target (CORE_ADDR *pc)
+{
+ CORE_ADDR jb_addr;
+ char buf[sizeof (CORE_ADDR)];
+
+ jb_addr = read_register (LR2_REGNUM);
+
+ if (target_read_memory (jb_addr + JB_PC * JB_ELEMENT_SIZE, (char *) buf,
+ sizeof (CORE_ADDR)))
+ return 0;
+
+ *pc = extract_address ((PTR) buf, sizeof (CORE_ADDR));
+ return 1;
+}
+#endif /* GET_LONGJMP_TARGET */
+
void
-_initialize_29k()
+_initialize_a29k_tdep (void)
{
extern CORE_ADDR text_end;
+ tm_print_insn = gdb_print_insn_a29k;
+
/* FIXME, there should be a way to make a CORE_ADDR variable settable. */
add_show_from_set
(add_set_cmd ("rstack_high_address", class_support, var_uinteger,
- (char *)&rstack_high_address,
+ (char *) &rstack_high_address,
"Set top address in memory of the register stack.\n\
Attempts to access registers saved above this address will be ignored\n\
or will produce the value -1.", &setlist),
/* FIXME, there should be a way to make a CORE_ADDR variable settable. */
add_show_from_set
(add_set_cmd ("call_scratch_address", class_support, var_uinteger,
- (char *)&text_end,
-"Set address in memory where small amounts of RAM can be used\n\
+ (char *) &text_end,
+ "Set address in memory where small amounts of RAM can be used\n\
when making function calls into the inferior.", &setlist),
&showlist);
}