* arc-tdep.c (arc_bfd_mach_type): New static global.
(codestream_fill): Handle byte order differences. (setup_prologue_scan): Don't read stdarg function's "sub sp,sp,N". (arc_get_frame_setup): Read it here. (arc_frame_saved_pc): And here. (arc_print_insn): New function. (arc_set_cpu_type): Set arc_bfd_mach_type. Don't set tm_print_insn. (_initialize_arc_tdep): Set tm_print_insn to arc_print_insn.
This commit is contained in:
parent
1cb0d00d8f
commit
4f36d4ab73
@ -1,3 +1,16 @@
|
||||
start-sanitize-arc
|
||||
Fri Jun 2 11:17:23 1995 Doug Evans <dje@canuck.cygnus.com>
|
||||
|
||||
* arc-tdep.c (arc_bfd_mach_type): New static global.
|
||||
(codestream_fill): Handle byte order differences.
|
||||
(setup_prologue_scan): Don't read stdarg function's "sub sp,sp,N".
|
||||
(arc_get_frame_setup): Read it here.
|
||||
(arc_frame_saved_pc): And here.
|
||||
(arc_print_insn): New function.
|
||||
(arc_set_cpu_type): Set arc_bfd_mach_type. Don't set tm_print_insn.
|
||||
(_initialize_arc_tdep): Set tm_print_insn to arc_print_insn.
|
||||
end-sanitize-arc
|
||||
|
||||
Wed May 31 12:04:01 1995 J.T. Conklin <jtc@rtl.cygnus.com>
|
||||
|
||||
* nlm/{configure.in, Makefile.in}: Converted to use autoconf.
|
||||
|
116
gdb/arc-tdep.c
116
gdb/arc-tdep.c
@ -27,6 +27,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#include "gdbcmd.h"
|
||||
|
||||
/* Current CPU, set with the "set cpu" command. */
|
||||
static int arc_bfd_mach_type;
|
||||
char *arc_cpu_type;
|
||||
char *tmp_arc_cpu_type;
|
||||
|
||||
@ -53,7 +54,8 @@ int debug_pipeline_p;
|
||||
|
||||
#define OPMASK 0xf8000000
|
||||
|
||||
/* Instruction field accessor macros. */
|
||||
/* Instruction field accessor macros.
|
||||
See the Programmer's Reference Manual. */
|
||||
#define X_OP(i) (((i) >> 27) & 0x1f)
|
||||
#define X_A(i) (((i) >> 21) & 0x3f)
|
||||
#define X_B(i) (((i) >> 15) & 0x3f)
|
||||
@ -108,14 +110,25 @@ codestream_fill (peek_flag)
|
||||
codestream_next_addr += CODESTREAM_BUFSIZ * sizeof (codestream_buf[0]);
|
||||
codestream_off = 0;
|
||||
codestream_cnt = CODESTREAM_BUFSIZ;
|
||||
/* FIXME: need to handle byte order differences. */
|
||||
read_memory (codestream_addr, (char *) codestream_buf,
|
||||
CODESTREAM_BUFSIZ * sizeof (codestream_buf[0]));
|
||||
/* FIXME: check return code? */
|
||||
|
||||
/* Handle byte order differences. */
|
||||
if (HOST_BYTE_ORDER != TARGET_BYTE_ORDER)
|
||||
{
|
||||
register unsigned int i, j, n = sizeof (codestream_buf[0]);
|
||||
register char tmp, *p;
|
||||
for (i = 0, p = (char *) codestream_buf; i < CODESTREAM_BUFSIZ;
|
||||
++i, p += n)
|
||||
for (j = 0; j < n / 2; ++j)
|
||||
tmp = p[j], p[j] = p[n - 1 - j], p[n - 1 - j] = tmp;
|
||||
}
|
||||
|
||||
if (peek_flag)
|
||||
return (codestream_peek());
|
||||
return codestream_peek ();
|
||||
else
|
||||
return (codestream_get());
|
||||
return codestream_get ();
|
||||
}
|
||||
|
||||
static void
|
||||
@ -126,10 +139,12 @@ codestream_seek (place)
|
||||
codestream_next_addr *= CODESTREAM_BUFSIZ;
|
||||
codestream_cnt = 0;
|
||||
codestream_fill (1);
|
||||
while (codestream_tell() != place)
|
||||
while (codestream_tell () != place)
|
||||
codestream_get ();
|
||||
}
|
||||
|
||||
/* This function is currently unused but leave in for now. */
|
||||
|
||||
static void
|
||||
codestream_read (buf, count)
|
||||
unsigned int *buf;
|
||||
@ -142,8 +157,7 @@ codestream_read (buf, count)
|
||||
*p++ = codestream_get ();
|
||||
}
|
||||
|
||||
/* Set up prologue scanning and return the first insn,
|
||||
not including the "sub sp,sp,32" of a stdarg function. */
|
||||
/* Set up prologue scanning and return the first insn. */
|
||||
|
||||
static unsigned int
|
||||
setup_prologue_scan (pc)
|
||||
@ -154,12 +168,6 @@ setup_prologue_scan (pc)
|
||||
codestream_seek (pc);
|
||||
insn = codestream_get ();
|
||||
|
||||
/* The authority for what appears here is the home-grown ABI. */
|
||||
|
||||
/* First insn may be "sub sp,sp,32" if stdarg fn. */
|
||||
if (insn == BUILD_INSN (10, SP_REGNUM, SP_REGNUM, SHIMM_REGNUM, 32))
|
||||
insn = codestream_get ();
|
||||
|
||||
return insn;
|
||||
}
|
||||
|
||||
@ -176,17 +184,30 @@ arc_get_frame_setup (pc)
|
||||
{
|
||||
unsigned int insn;
|
||||
/* Size of frame or -1 if unrecognizable prologue. */
|
||||
int n = -1;
|
||||
int frame_size = -1;
|
||||
/* An initial "sub sp,sp,N" may or may not be for a stdarg fn. */
|
||||
int maybe_stdarg_decr = -1;
|
||||
|
||||
insn = setup_prologue_scan (pc);
|
||||
|
||||
/* The authority for what appears here is the home-grown ABI.
|
||||
The most recent version is 1.2. */
|
||||
|
||||
/* First insn may be "sub sp,sp,N" if stdarg fn. */
|
||||
if ((insn & BUILD_INSN (-1, -1, -1, -1, 0))
|
||||
== BUILD_INSN (10, SP_REGNUM, SP_REGNUM, SHIMM_REGNUM, 0))
|
||||
{
|
||||
maybe_stdarg_decr = X_D (insn);
|
||||
insn = codestream_get ();
|
||||
}
|
||||
|
||||
if ((insn & BUILD_INSN (-1, 0, -1, -1, -1)) /* st blink,[sp,4] */
|
||||
== BUILD_INSN (2, 0, SP_REGNUM, BLINK_REGNUM, 4))
|
||||
{
|
||||
insn = codestream_get ();
|
||||
/* Frame may not be necessary, even though blink is saved.
|
||||
At least this is something we recognize. */
|
||||
n = 0;
|
||||
frame_size = 0;
|
||||
}
|
||||
|
||||
if ((insn & BUILD_INSN (-1, 0, -1, -1, -1)) /* st fp,[sp] */
|
||||
@ -197,18 +218,18 @@ arc_get_frame_setup (pc)
|
||||
!= BUILD_INSN (12, FP_REGNUM, SP_REGNUM, SP_REGNUM, 0))
|
||||
return -1;
|
||||
|
||||
/* Check for stack adjustment sub sp,sp,nnn. */
|
||||
/* Check for stack adjustment sub sp,sp,N. */
|
||||
insn = codestream_peek ();
|
||||
if ((insn & BUILD_INSN (-1, -1, -1, 0, 0))
|
||||
== BUILD_INSN (10, SP_REGNUM, SP_REGNUM, 0, 0))
|
||||
{
|
||||
if (LIMM_P (X_C (insn)))
|
||||
n = codestream_get ();
|
||||
frame_size = codestream_get ();
|
||||
else if (SHIMM_P (X_C (insn)))
|
||||
n = X_D (insn);
|
||||
frame_size = X_D (insn);
|
||||
else
|
||||
return -1;
|
||||
if (n < 0)
|
||||
if (frame_size < 0)
|
||||
return -1;
|
||||
|
||||
codestream_get ();
|
||||
@ -222,11 +243,20 @@ arc_get_frame_setup (pc)
|
||||
/* Frameless fn. */
|
||||
else
|
||||
{
|
||||
n = 0;
|
||||
frame_size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return n;
|
||||
/* If we found a "sub sp,sp,N" and nothing else, it may or may not be a
|
||||
stdarg fn. The stdarg decrement is not treated as part of the frame size,
|
||||
so we have a dilemma: what do we return? For now, if we get a
|
||||
"sub sp,sp,N" and nothing else assume this isn't a stdarg fn. One way
|
||||
to fix this completely would be to add a bit to the function descriptor
|
||||
that says the function is a stdarg function. */
|
||||
|
||||
if (frame_size < 0 && maybe_stdarg_decr > 0)
|
||||
return maybe_stdarg_decr;
|
||||
return frame_size;
|
||||
}
|
||||
|
||||
/* Given a pc value, skip it forward past the function prologue by
|
||||
@ -283,13 +313,21 @@ arc_frame_saved_pc (frame)
|
||||
return ARC_PC_TO_REAL_ADDRESS (read_memory_integer (FRAME_FP (frame) + 4, 4));
|
||||
}
|
||||
|
||||
/* If the first insn is "st blink,[sp,4]" we can get blink from there.
|
||||
/* The authority for what appears here is the home-grown ABI.
|
||||
The most recent version is 1.2. */
|
||||
|
||||
insn = setup_prologue_scan (func_start);
|
||||
|
||||
/* First insn may be "sub sp,sp,N" if stdarg fn. */
|
||||
if ((insn & BUILD_INSN (-1, -1, -1, -1, 0))
|
||||
== BUILD_INSN (10, SP_REGNUM, SP_REGNUM, SHIMM_REGNUM, 0))
|
||||
insn = codestream_get ();
|
||||
|
||||
/* If the next insn is "st blink,[sp,4]" we can get blink from there.
|
||||
Otherwise this is a leaf function and we can use blink. Note that
|
||||
this still allows for the case where a leaf function saves/clobbers/
|
||||
restores blink. */
|
||||
|
||||
insn = setup_prologue_scan (func_start);
|
||||
|
||||
if ((insn & BUILD_INSN (-1, 0, -1, -1, -1)) /* st blink,[sp,4] */
|
||||
!= BUILD_INSN (2, 0, SP_REGNUM, BLINK_REGNUM, 4))
|
||||
return ARC_PC_TO_REAL_ADDRESS (read_register (BLINK_REGNUM));
|
||||
@ -574,6 +612,30 @@ get_longjmp_target(pc)
|
||||
}
|
||||
#endif /* GET_LONGJMP_TARGET */
|
||||
|
||||
/* Disassemble one instruction. */
|
||||
|
||||
static int
|
||||
arc_print_insn (vma, info)
|
||||
bfd_vma vma;
|
||||
disassemble_info *info;
|
||||
{
|
||||
static int current_mach;
|
||||
static int current_endian;
|
||||
static disassembler_ftype current_disasm;
|
||||
|
||||
if (current_disasm == NULL
|
||||
|| arc_bfd_mach_type != current_mach
|
||||
|| TARGET_BYTE_ORDER != current_endian)
|
||||
{
|
||||
current_mach = arc_bfd_mach_type;
|
||||
current_endian = TARGET_BYTE_ORDER;
|
||||
current_disasm = arc_get_disassembler (current_mach,
|
||||
current_endian == BIG_ENDIAN);
|
||||
}
|
||||
|
||||
return (*current_disasm) (vma, info);
|
||||
}
|
||||
|
||||
/* Command to set cpu type. */
|
||||
|
||||
void
|
||||
@ -627,8 +689,7 @@ arc_set_cpu_type (str)
|
||||
if (strcasecmp (str, arc_cpu_type_table[i].name) == 0)
|
||||
{
|
||||
arc_cpu_type = str;
|
||||
tm_print_insn = arc_get_disassembler (arc_cpu_type_table[i].value,
|
||||
TARGET_BYTE_ORDER == BIG_ENDIAN);
|
||||
arc_bfd_mach_type = arc_cpu_type_table[i].value;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@ -680,6 +741,5 @@ A negative value disables the timer.",
|
||||
&setlist);
|
||||
c = add_show_from_set (c, &showlist);
|
||||
|
||||
/* FIXME: must be done after for now. */
|
||||
tm_print_insn = arc_get_disassembler (bfd_mach_arc_base, 1 /*FIXME*/);
|
||||
tm_print_insn = arc_print_insn;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user