aboutsummaryrefslogtreecommitdiff
path: root/gdb/i960-tdep.c
diff options
context:
space:
mode:
authorStan Shebs <shebs@codesourcery.com>1995-01-17 04:36:51 +0000
committerStan Shebs <shebs@codesourcery.com>1995-01-17 04:36:51 +0000
commit18b46e7c5378bb16c32827413376fa5982a4d8eb (patch)
treebd8cfc626d718a51ef2326c9ba8f79e102525bc9 /gdb/i960-tdep.c
parent83d9bb1416873498a6eb2da72e01fcdcb51b6370 (diff)
downloadgdb-18b46e7c5378bb16c32827413376fa5982a4d8eb.zip
gdb-18b46e7c5378bb16c32827413376fa5982a4d8eb.tar.gz
gdb-18b46e7c5378bb16c32827413376fa5982a4d8eb.tar.bz2
General cleanup and simplication of disassembler interface.
* a29k-pinsn.c, arm-pinsn.c, convex-pinsn.c, gould-pinsn.c, hppa-pinsn.c, i386-pinsn.c, i960-pinsn.c, m68k-pinsn.c, m88k-pinsn.c, mips-pinsn.c, ns32k-pinsn.c, pyr-pinsn.c, rs6000-pinsn.c, sparc-pinsn.c, tahoe-pinsn.c, vax-pinsn.c: Remove. * gould-tdep.c, ns32k-tdep.c, tahoe-tdep.c, vax-tdep.c: New files, had been -pinsn.c files. * Makefile.in (ALLDEPFILES): Remove removed files. (a29k-pinsn.o, arm-pinsn.o, convex-pinsn.o, gould-pinsn.o, hppa-pinsn.o, i386-pinsn.o, i960-pinsn.o, m68k-pinsn.o, m88k-pinsn.o, mips-pinsn.o, ns32k-pinsn.o, pyr-pinsn.o, rs6000-pinsn.o, sparc-pinsn.o, tahoe-pinsn.o, vax-pinsn.o): Remove compile actions. * arm-tdep.o, gould-tdep.o, ns32k-tdep.o, tahoe-tdep.o, vax-tdep.o: Add compile actions. * defs.h (tm_print_insn): New global. * a29k-tdep.c (gdb_print_insn_a29k): New function. (_initialize_a29k_tdep): Rename from _initialize_29k, set tm_print_insn. * alpha-tdep.c (print_insn): Remove. (_initialize_alpha_tdep): Set tm_print_insn. * arm-tdep.c (arm_print_insn): New function, was print_insn in arm-pinsn.c. * convex-tdep.c (convex_print_insn): New function, was print_insn in convex-pinsn.c. * h8300-tdep.c (print_insn): Remove. (gdb_print_insn_h8300): New function. (_initialize_h8300_tdep): New function. * h8500-tdep.c (print_insn): Remove. (_initialize_h8500_tdep): New function. * hppa-tdep.c (_initialize_hppa_tdep): Set tm_print_insn. * i386-tdep.c (_initialize_i386_tdep): New function. * i960-tdep.c (mem, next_insn): New functions, were in i960-pinsn.c. (_initialize_i960_tdep): Set tm_print_insn. * m68k-tdep.c (_initialize_m68k_tdep): New function. * m88k-tdep.c (_initialize_m88k_tdep): New function. * mips-tdep.c (gdb_print_insn_mips): New function. (_initialize_mips_tdep): Set tm_print_insn. * pyr-tdep.c (pyr_print_insn): New function, was print_insn in pyr-pinsn.c. * rs6000-tdep.c (_initialize_rs6000_tdep): New function. * sh-tdep.c (print_insn): Remove. (gdb_print_insn_sh): New function. (_initialize_sh_tdep): Set tm_print_insn. * sparc-tdep.c (_initialize_sparc_tdep): New function. * w65-tdep.c (print_insn): Remove. (_initialize_w65_tdep): New function. * z8k-tdep.c (print_insn): Remove. (gdb_print_insn_z8k): New function. (_initialize_z8k_tdep): Set tm_print_insn. * printcmd.c (print_insn): New function, generic disassembler. * config/*/*.mt (TDEPFILES): Remove refs to *-pinsn.o. * defs.h (query_hook, error_hook): Fix prototypes.
Diffstat (limited to 'gdb/i960-tdep.c')
-rw-r--r--gdb/i960-tdep.c154
1 files changed, 152 insertions, 2 deletions
diff --git a/gdb/i960-tdep.c b/gdb/i960-tdep.c
index 013bf82..3ea7011 100644
--- a/gdb/i960-tdep.c
+++ b/gdb/i960-tdep.c
@@ -1,5 +1,5 @@
/* Target-machine dependent code for the Intel 960
- Copyright (C) 1991 Free Software Foundation, Inc.
+ Copyright 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
Contributed by Intel Corporation.
examine_prologue and other parts contributed by Wind River Systems.
@@ -26,6 +26,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "floatformat.h"
#include "target.h"
+static CORE_ADDR next_insn PARAMS ((CORE_ADDR memaddr,
+ unsigned long *pword1,
+ unsigned long *pword2));
+
/* gdb960 is always running on a non-960 host. Check its characteristics.
This routine must be called as part of gdb initialization. */
@@ -610,10 +614,156 @@ i960_fault_to_signal (fault)
}
}
-/* Initialization stub */
+/****************************************/
+/* MEM format */
+/****************************************/
+
+struct tabent {
+ char *name;
+ char numops;
+};
+
+static int /* returns instruction length: 4 or 8 */
+mem( memaddr, word1, word2, noprint )
+ unsigned long memaddr;
+ unsigned long word1, word2;
+ int noprint; /* If TRUE, return instruction length, but
+ don't output any text. */
+{
+ int i, j;
+ int len;
+ int mode;
+ int offset;
+ const char *reg1, *reg2, *reg3;
+
+ /* This lookup table is too sparse to make it worth typing in, but not
+ * so large as to make a sparse array necessary. We allocate the
+ * table at runtime, initialize all entries to empty, and copy the
+ * real ones in from an initialization table.
+ *
+ * NOTE: In this table, the meaning of 'numops' is:
+ * 1: single operand
+ * 2: 2 operands, load instruction
+ * -2: 2 operands, store instruction
+ */
+ static struct tabent *mem_tab = NULL;
+/* Opcodes of 0x8X, 9X, aX, bX, and cX must be in the table. */
+#define MEM_MIN 0x80
+#define MEM_MAX 0xcf
+#define MEM_SIZ ((MEM_MAX-MEM_MIN+1) * sizeof(struct tabent))
+
+ static struct { int opcode; char *name; char numops; } mem_init[] = {
+ 0x80, "ldob", 2,
+ 0x82, "stob", -2,
+ 0x84, "bx", 1,
+ 0x85, "balx", 2,
+ 0x86, "callx", 1,
+ 0x88, "ldos", 2,
+ 0x8a, "stos", -2,
+ 0x8c, "lda", 2,
+ 0x90, "ld", 2,
+ 0x92, "st", -2,
+ 0x98, "ldl", 2,
+ 0x9a, "stl", -2,
+ 0xa0, "ldt", 2,
+ 0xa2, "stt", -2,
+ 0xb0, "ldq", 2,
+ 0xb2, "stq", -2,
+ 0xc0, "ldib", 2,
+ 0xc2, "stib", -2,
+ 0xc8, "ldis", 2,
+ 0xca, "stis", -2,
+ 0, NULL, 0
+ };
+
+ if ( mem_tab == NULL ){
+ mem_tab = (struct tabent *) xmalloc( MEM_SIZ );
+ memset( mem_tab, '\0', MEM_SIZ );
+ for ( i = 0; mem_init[i].opcode != 0; i++ ){
+ j = mem_init[i].opcode - MEM_MIN;
+ mem_tab[j].name = mem_init[i].name;
+ mem_tab[j].numops = mem_init[i].numops;
+ }
+ }
+
+ i = ((word1 >> 24) & 0xff) - MEM_MIN;
+ mode = (word1 >> 10) & 0xf;
+
+ if ( (mem_tab[i].name != NULL) /* Valid instruction */
+ && ((mode == 5) || (mode >=12)) ){ /* With 32-bit displacement */
+ len = 8;
+ } else {
+ len = 4;
+ }
+
+ if ( noprint ){
+ return len;
+ }
+ abort ();
+}
+
+/* Read the i960 instruction at 'memaddr' and return the address of
+ the next instruction after that, or 0 if 'memaddr' is not the
+ address of a valid instruction. The first word of the instruction
+ is stored at 'pword1', and the second word, if any, is stored at
+ 'pword2'. */
+
+static CORE_ADDR
+next_insn (memaddr, pword1, pword2)
+ unsigned long *pword1, *pword2;
+ CORE_ADDR memaddr;
+{
+ int len;
+ char buf[8];
+
+ /* Read the two (potential) words of the instruction at once,
+ to eliminate the overhead of two calls to read_memory ().
+ FIXME: Loses if the first one is readable but the second is not
+ (e.g. last word of the segment). */
+
+ read_memory (memaddr, buf, 8);
+ *pword1 = extract_unsigned_integer (buf, 4);
+ *pword2 = extract_unsigned_integer (buf + 4, 4);
+
+ /* Divide instruction set into classes based on high 4 bits of opcode*/
+
+ switch ((*pword1 >> 28) & 0xf)
+ {
+ case 0x0:
+ case 0x1: /* ctrl */
+
+ case 0x2:
+ case 0x3: /* cobr */
+
+ case 0x5:
+ case 0x6:
+ case 0x7: /* reg */
+ len = 4;
+ break;
+
+ case 0x8:
+ case 0x9:
+ case 0xa:
+ case 0xb:
+ case 0xc:
+ len = mem (memaddr, *pword1, *pword2, 1);
+ break;
+
+ default: /* invalid instruction */
+ len = 0;
+ break;
+ }
+
+ if (len)
+ return memaddr + len;
+ else
+ return 0;
+}
void
_initialize_i960_tdep ()
{
check_host ();
+
+ tm_print_insn = print_insn_i960;
}