aboutsummaryrefslogtreecommitdiff
path: root/gdb/arc-tdep.c
diff options
context:
space:
mode:
authorDavid Edelsohn <dje.gcc@gmail.com>1995-06-02 18:29:46 +0000
committerDavid Edelsohn <dje.gcc@gmail.com>1995-06-02 18:29:46 +0000
commit4f36d4ab734add92c54ed67f2ec1a7e571d060eb (patch)
treec45daefa45f835a7decb7433071b8e0dd2fae81d /gdb/arc-tdep.c
parent1cb0d00d8fdfdf32c5f575f98d50ee002fbc710e (diff)
downloadfsf-binutils-gdb-4f36d4ab734add92c54ed67f2ec1a7e571d060eb.zip
fsf-binutils-gdb-4f36d4ab734add92c54ed67f2ec1a7e571d060eb.tar.gz
fsf-binutils-gdb-4f36d4ab734add92c54ed67f2ec1a7e571d060eb.tar.bz2
* 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.
Diffstat (limited to 'gdb/arc-tdep.c')
-rw-r--r--gdb/arc-tdep.c116
1 files changed, 88 insertions, 28 deletions
diff --git a/gdb/arc-tdep.c b/gdb/arc-tdep.c
index e76aa93..c684f0b 100644
--- a/gdb/arc-tdep.c
+++ b/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;
}