From 18b46e7c5378bb16c32827413376fa5982a4d8eb Mon Sep 17 00:00:00 2001 From: Stan Shebs Date: Tue, 17 Jan 1995 04:36:51 +0000 Subject: 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. --- gdb/i960-tdep.c | 154 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 152 insertions(+), 2 deletions(-) (limited to 'gdb/i960-tdep.c') 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; } -- cgit v1.1