from ragge;
authorderaadt <deraadt@openbsd.org>
Wed, 31 Jan 1996 05:05:21 +0000 (05:05 +0000)
committerderaadt <deraadt@openbsd.org>
Wed, 31 Jan 1996 05:05:21 +0000 (05:05 +0000)
DDB disassembly is fixed and now works good. Code written and
contributed to Ludd by Bertram Barth.

sys/arch/vax/vax/db_disasm.c
sys/arch/vax/vax/db_disasm.h [new file with mode: 0644]

index 06728df..429d357 100644 (file)
@@ -1,8 +1,11 @@
-/*     $NetBSD: db_disasm.c,v 1.2 1995/11/30 00:59:34 jtc Exp $ */
+/*     $NetBSD: db_disasm.c,v 1.3 1996/01/28 11:31:25 ragge Exp $ */
 /*
- * Copyright (c) 1995 Ludd, University of Lule}, Sweden.
+ * Copyright (c) 1996 Ludd, University of Lule}, Sweden.
  * All rights reserved.
  *
+ * This code is derived from software contributed to Ludd by
+ * Bertram Barth.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
 #include <sys/reboot.h>
 
 #include <ddb/db_variables.h>
-
 #include <machine/db_machdep.h>
+#include <ddb/db_sym.h>
 
+#include "vax/vax/db_disasm.h"
 
+#ifdef VMS_MODE
+#define DEFERRED   '@'
+#define LITERAL    '#'
+#else
+#define DEFERRED   '*'
+#define LITERAL    '$'
+#endif
+/*
+ * disassembling vax instructions works as follows:
+ *
+ * - get first byte as opcode (check for two-byte opcodes!)
+ * - evaluate (variable length) argument list
+ * - for each argument get type (byte, long, address etc.)
+ * - evaluate addressing mode for this argument
+ * - db_printf the opcode and the (value of the) arguments
+ * - return the start of the next instruction
+ *
+ * - if jump/branch calculate (and display) the target-address
+ */
 
-struct vax_insn {
-       char    *insn;
-       int     nargs;
-} instr[] = {
-       "halt", 0,
-       "nop",  0,
-       "rei",  0,
-       "bpt",  0,
-       "ret",  0,
-       "rsb",  0,
-       "ldpctx",       0,
-       "svpctx",       0,
-       "cvtps",        4,
-       "cvtsp",        4,
-       "index",        6,
-       "crc",  4,
-       "prober",       3,
-       "probew",       3,
-       "insque",       2,
-       "remque",       2,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
-       "",     -1,
+/* 
+#define BROKEN_DB_REGS
+*/
+#ifdef  BROKEN_DB_REGS
+struct {                /* Due to order and contents of db_regs[], we can't */
+        char *name;     /* use this array to extract register-names. */
+        void *valuep;   /* eg. "psl" vs "pc", "pc" vs "sp" */
+} my_db_regs[16] = {
+        { "r0",         NULL },
+        { "r1",         NULL },
+        { "r2",         NULL },
+        { "r3",         NULL },
+        { "r4",         NULL },
+        { "r5",         NULL },
+        { "r6",         NULL },
+        { "r7",         NULL },
+        { "r8",         NULL },
+        { "r9",         NULL },
+        { "r10",        NULL },
+        { "r11",        NULL },
+        { "ap",         NULL },         /* aka "r12" */
+        { "fp",         NULL },         /* aka "r13" */
+        { "sp",         NULL },         /* aka "r14" */
+        { "pc",         NULL },         /* aka "r15" */
 };
+#else
+#define my_db_regs db_regs
+#endif
 
+typedef struct {
+       char            dasm[256];      /* disassebled instruction as text */
+       char           *curp;   /* pointer into result */
+       char           *ppc;    /* pseudo PC */
+       int             opc;    /* op-code */
+       char           *argp;   /* pointer into argument-list */
+       int             itype;  /* instruction-type, eg. branch, call, unspec */
+       int             atype;  /* argument-type, eg. byte, long, address */
+       int             off;    /* offset specified by last argument */
+       int             addr;   /* address specified by last argument */
+}       inst_buffer;
+
+#define ITYPE_INVALID  -1
+#define ITYPE_UNSPEC    0
+#define ITYPE_BRANCH    1
+#define ITYPE_CALL      2
+
+int get_byte    __P((inst_buffer * ib));
+int get_word    __P((inst_buffer * ib));
+int get_long    __P((inst_buffer * ib));
+
+int get_opcode  __P((inst_buffer * ib));
+int get_operands __P((inst_buffer * ib));
+int get_operand __P((inst_buffer * ib, int size));
+
+void add_char   __P((inst_buffer * ib, int c));
+void add_str    __P((inst_buffer * ib, char *s));
+void add_int    __P((inst_buffer * ib, int i));
+void add_xint   __P((inst_buffer * ib, int i));
+void add_sym    __P((inst_buffer * ib, int i));
+void add_off    __P((inst_buffer * ib, int i));
+
+#define err_print  printf
 
 /*
  * Disassemble instruction at 'loc'.  'altfmt' specifies an
- * (optional) alternate format.  Return address of start of
- * next instruction.
+ * (optional) alternate format (altfmt for vax: don't assume
+ * that each external label is a procedure entry mask).
+ * Return address of start of next instruction.
+ * Since this function is used by 'examine' and by 'step'
+ * "next instruction" does NOT mean the next instruction to
+ * be executed but the 'linear' next instruction.
  */
 db_addr_t
 db_disasm(loc, altfmt)
-        db_addr_t       loc;
-        boolean_t       altfmt;
+       db_addr_t       loc;
+       boolean_t       altfmt;
 {
-       char *i_pl;
-       int inr, i;
+       db_expr_t       diff;
+       db_sym_t        sym;
+       char           *symname;
 
-       i_pl = (char *)loc;
-       inr = *i_pl;
+       inst_buffer     ib;
 
-       if (instr[*i_pl].nargs < 0) {
-               printf("Ok{nd instruktion: %2x",*i_pl&0xff);
-               i_pl++;
-       } else {
-               printf("\t%s\t",instr[inr].insn);
-               i_pl++;
-               for (i=0;i<instr[inr].nargs;i++) {
-                       i_pl = (char *)argprint(i_pl);
-                       if (i<instr[inr].nargs-1)
-                               printf(",");
+       bzero(&ib, sizeof(ib));
+       ib.ppc = (void *) loc;
+       ib.curp = ib.dasm;
+
+       if (!altfmt) {          /* ignore potential entry masks in altfmt */
+               diff = INT_MAX;
+               symname = NULL;
+               sym = db_search_symbol(loc, DB_STGY_PROC, &diff);
+               db_symbol_values(sym, &symname, 0);
+
+               if (symname && !diff) { /* symbol at loc */
+                       db_printf("function \"%s()\", entry-mask 0x%x\n\t\t",
+                                 symname, (unsigned short) get_word(&ib));
+                       ib.ppc += 2;
                }
        }
+       get_opcode(&ib);
+       get_operands(&ib);
+       db_printf("%s\n", ib.dasm);
+
+       return ((u_int) ib.ppc);
+}
+
+int
+get_opcode(ib)
+       inst_buffer    *ib;
+{
+       ib->opc = get_byte(ib);
+       if (ib->opc >> 2 == 0x3F) {     /* two byte op-code */
+               ib->opc = ib->opc << 8;
+               ib->opc += get_byte(ib);
+       }
+       switch (ib->opc) {
+       case 0xFA:              /* CALLG */
+       case 0xFB:              /* CALLS */
+       case 0xFC:              /* XFC */
+               ib->itype = ITYPE_CALL;
+               break;
+       case 0x16:              /* JSB */
+       case 0x17:              /* JMP */
+               ib->itype = ITYPE_BRANCH;
+               break;
+       default:
+               ib->itype = ITYPE_UNSPEC;
+       }
+       if (ib->opc < 0 || ib->opc > 0xFF) {
+               add_str(ib, "invalid or two-byte opcode ");
+               add_xint(ib, ib->opc);
+               ib->itype = ITYPE_INVALID;
+       } else {
+               add_str(ib, vax_inst[ib->opc].mnemonic);
+               add_char(ib, '\t');
+       }
+       return (ib->opc);
+}
+
+int
+get_operands(ib)
+       inst_buffer    *ib;
+{
+       int             aa = 0; /* absolute address mode ? */
+       int             size;
+
+       if (ib->opc < 0 || ib->opc > 0xFF) {
+               /* invalid or two-byte opcode */
+               ib->argp = NULL;
+               return (-1);
+       }
+       ib->argp = vax_inst[ib->opc].argdesc;
 
+       while (*ib->argp) {
+               switch (*ib->argp) {
 
+               case 'b':       /* branch displacement */
+                       switch (*(++ib->argp)) {
+                       case 'b':
+                               ib->off = (signed char) get_byte(ib);
+                               break;
+                       case 'w':
+                               ib->off = (short) get_word(ib);
+                               break;
+                       case 'l':
+                               ib->off = get_long(ib);
+                               break;
+                       default:
+                               err_print("XXX eror\n");
+                       }
+                       /* add_int(ib, ib->off); */
+                       ib->addr = (u_int) ib->ppc + ib->off;
+                       add_off(ib, ib->addr);
+                       break;
+
+               case 'a':       /* absolute adressing mode */
+                       aa = 1; /* do not break here ! */
+
+               default:
+                       switch (*(++ib->argp)) {
+                       case 'b':       /* Byte */
+                               size = SIZE_BYTE;
+                               break;
+                       case 'w':       /* Word */
+                               size = SIZE_WORD;
+                               break;
+                       case 'l':       /* Long-Word */
+                       case 'f':       /* F_Floating */
+                               size = SIZE_LONG;
+                               break;
+                       case 'q':       /* Quad-Word */
+                       case 'd':       /* D_Floating */
+                       case 'g':       /* G_Floating */
+                               size = SIZE_QWORD;
+                               break;
+                       case 'o':       /* Octa-Word */
+                       case 'h':       /* H_Floating */
+                               size = SIZE_OWORD;
+                               break;
+                       default:
+                               err_print("invalid op-type %X (%c) found.\n",
+                                         *ib->argp, *ib->argp);
+                               size = 0;
+                       }
+                       if (aa) {
+                               /* get the address */
+                               ib->addr = get_operand(ib, size);
+                               add_sym(ib, ib->addr);
+                       } else {
+                               /* get the operand */
+                               ib->addr = get_operand(ib, size);
+                               add_off(ib, ib->addr);
+                       }
+               }
+
+               if (!*ib->argp || !*++ib->argp)
+                       break;
+               if (*ib->argp++ == ',') {
+                       add_char(ib, ',');
+                       add_char(ib, ' ');
+               } else {
+                       err_print("XXX error\n");
+                       add_char(ib, '\0');
+                       return (-1);
+               }
+       }
 
-        return (int)i_pl;
+       add_char(ib, '\0');
+       return (0);
 }
 
-argprint(plats)
-       char *plats;
+int
+get_operand(ib, size)
+       inst_buffer    *ib;
+       int             size;
 {
-       switch (*plats&0xf0) {
-       case 0x00:
-       case 0x10:
-       case 0x20:
-       case 0x30:
-               printf("$%x",*plats++);
+       int             c = get_byte(ib);
+       int             mode = c >> 4;
+       int             reg = c & 0x0F;
+       int             lit = c & 0x3F;
+       int             tmp = 0;
+       char            buf[16];
+
+       switch (mode) {
+       case 0:         /* literal */
+       case 1:         /* literal */
+       case 2:         /* literal */
+       case 3:         /* literal */
+               add_char(ib, LITERAL);
+               add_int(ib, lit);
+               tmp = lit;
                break;
-               
-       case 0xe0:
-               if (*plats++&15 == 15) {
-                       printf("%8x",*(unsigned *)plats + plats);
-                       plats += 4;
-               } else {
-                       printf("Oinpl. s{tt.");
+
+       case 4:         /* indexed */
+               sprintf(buf, "[%s]", my_db_regs[reg].name);
+               get_operand(ib, 0);
+               add_str(ib, buf);
+               break;
+
+       case 5:         /* register */
+               add_str(ib, my_db_regs[reg].name);
+               break;
+
+       case 6:         /* register deferred */
+               add_char(ib, '(');
+               add_str(ib, my_db_regs[reg].name);
+               add_char(ib, ')');
+               break;
+
+       case 7:         /* autodecrement */
+               add_char(ib, '-');
+               add_char(ib, '(');
+               add_str(ib, my_db_regs[reg].name);
+               add_char(ib, ')');
+               if (reg == 0x0F) {      /* pc is not allowed in this mode */
+                       err_print("autodecrement not allowd for PC.\n");
+               }
+               break;
+
+       case 9:         /* autoincrement deferred */
+               add_char(ib, DEFERRED);
+       case 8:         /* autoincrement */
+               if (reg == 0x0F) {      /* pc: immediate ==> special syntax */
+                       switch (size) {
+                       case SIZE_BYTE:
+                               tmp = (signed char) get_byte(ib);
+                               break;
+                       case SIZE_WORD:
+                               tmp = (signed short) get_word(ib);
+                               break;
+                       case SIZE_LONG:
+                               tmp = get_long(ib);
+                               break;
+                       default:
+                               err_print("illegal op-type %d\n", size);
+                               tmp = -1;
+                       }
+                       if (mode == 8)
+                               add_char(ib, LITERAL);
+                       add_int(ib, tmp);
+                       break;
+               }
+               add_char(ib, '(');
+               add_str(ib, my_db_regs[reg].name);
+               add_char(ib, ')');
+               add_char(ib, '+');
+               break;
+
+       case 11:        /* byte displacement deferred/ relative deferred  */
+               add_char(ib, DEFERRED);
+       case 10:        /* byte displacement / relative mode */
+               tmp = (signed char) get_byte(ib);
+               if (reg == 0x0F) {
+                       add_off(ib, (u_int) ib->ppc + tmp);
+                       break;
+               }
+               /* add_str (ib, "b^"); */
+               add_int(ib, tmp);
+               add_char(ib, '(');
+               add_str(ib, my_db_regs[reg].name);
+               add_char(ib, ')');
+               break;
+
+       case 13:                /* word displacement deferred */
+               add_char(ib, DEFERRED);
+       case 12:                /* word displacement */
+               tmp = (signed short) get_word(ib);
+               if (reg == 0x0F) {
+                       add_off(ib, (u_int) ib->ppc + tmp);
+                       break;
+               }
+               /* add_str (ib, "w^"); */
+               add_int(ib, tmp);
+               add_char(ib, '(');
+               add_str(ib, my_db_regs[reg].name);
+               add_char(ib, ')');
+               break;
+
+       case 15:                /* long displacement referred */
+               add_char(ib, DEFERRED);
+       case 14:                /* long displacement */
+               tmp = get_long(ib);
+               if (reg == 0x0F) {
+                       add_off(ib, (u_int) ib->ppc + tmp);
+                       break;
                }
+               /* add_str (ib, "l^"); */
+               add_int(ib, tmp);
+               add_char(ib, '(');
+               add_str(ib, my_db_regs[reg].name);
+               add_char(ib, ')');
                break;
+
        default:
-               printf("Oinpl. s{tt.");
+               err_print("can\'t evaluate operand (%02X).\n", lit);
+               break;
+       }
+
+       return (0);
+}
+
+int
+get_byte(ib)
+       inst_buffer    *ib;
+{
+       return ((unsigned char) *(ib->ppc++));
+}
+
+int
+get_word(ib)
+       inst_buffer    *ib;
+{
+       int             tmp;
+       char           *p = (void *) &tmp;
+       *p++ = get_byte(ib);
+       *p++ = get_byte(ib);
+       return (tmp);
+}
+
+int
+get_long(ib)
+       inst_buffer    *ib;
+{
+       int             tmp;
+       char           *p = (void *) &tmp;
+       *p++ = get_byte(ib);
+       *p++ = get_byte(ib);
+       *p++ = get_byte(ib);
+       *p++ = get_byte(ib);
+       return (tmp);
+}
+
+void
+add_char(ib, c)
+       inst_buffer    *ib;
+       int             c;
+{
+       *ib->curp++ = c;
+}
+
+void
+add_str(ib, s)
+       inst_buffer    *ib;
+       char           *s;
+{
+       while (*ib->curp++ = *s++);
+       *--ib->curp = '\0';
+}
+
+void
+add_int(ib, i)
+       inst_buffer    *ib;
+       int             i;
+{
+       char            buf[32];
+       if (i < 100 && i > -100)
+               sprintf(buf, "%d", i);
+       else
+               sprintf(buf, "0x%x", i);
+       add_str(ib, buf);
+}
+
+void
+add_xint(ib, val)
+       inst_buffer    *ib;
+       int             val;
+{
+       char            buf[32];
+       sprintf(buf, "0x%x", val);
+       add_str(ib, buf);
+}
+
+void
+add_sym(ib, loc)
+       inst_buffer    *ib;
+       int             loc;
+{
+       db_expr_t       diff;
+       db_sym_t        sym;
+       char           *symname;
+
+       if (! loc)
+               return;
+
+       diff = INT_MAX;
+       symname = NULL;
+       sym = db_search_symbol(loc, DB_STGY_ANY, &diff);
+       db_symbol_values(sym, &symname, 0);
+
+       if (symname && !diff) {
+               /* add_char(ib, '<'); */
+               add_str(ib, symname);
+               /* add_char(ib, '>'); */
+       }
+       else
+               add_xint(ib, loc);
+}
+
+void
+add_off(ib, loc)
+       inst_buffer    *ib;
+       int             loc;
+{
+       db_expr_t       diff;
+       db_sym_t        sym;
+       char           *symname;
+
+       if (!loc)
+               return;
+         
+       diff = INT_MAX;
+       symname = NULL;
+       sym = db_search_symbol(loc, DB_STGY_ANY, &diff);
+       db_symbol_values(sym, &symname, 0);
+
+       if (symname) {
+               /* add_char(ib, '<'); */
+               add_str(ib, symname);
+               if (diff) {
+                       add_char(ib, '+');
+                       add_xint(ib, diff);
+               }
+               /* add_char(ib, '>'); */
        }
-       return (int)plats;
+       else
+               add_xint(ib, loc);
 }
diff --git a/sys/arch/vax/vax/db_disasm.h b/sys/arch/vax/vax/db_disasm.h
new file mode 100644 (file)
index 0000000..99efd97
--- /dev/null
@@ -0,0 +1,361 @@
+/*     $NetBSD: db_disasm.h,v 1.1 1996/01/28 11:31:27 ragge Exp $ */
+/*
+ * Copyright (c) 1996 Ludd, University of Lule}, Sweden.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Ludd by
+ * Bertram Barth.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed at Ludd, University of 
+ *      Lule}, Sweden and its contributors.
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+
+#define SIZE_BYTE       1              /* Byte */
+#define SIZE_WORD       2              /* Word */
+#define SIZE_LONG       4              /* Longword */
+#define SIZE_QWORD      8              /* Quadword */
+#define SIZE_OWORD     16              /* Octaword */
+
+/*
+ * The VAX instruction set has a variable length instruction format which 
+ * may be as short as one byte and as long as needed depending on the type 
+ * of instruction. [...] Each instruction consists of an opcode followed 
+ * by zero to six operand specifiers whose number and type depend on the 
+ * opcode. All operand specidiers are, themselves, of the same format -- 
+ * i.e. an address mode plus additional information.
+ *
+ * [VAX Architecture Handbook, p.52:  Instruction Format]
+ */
+
+struct {
+       char *mnemonic;
+       char *argdesc;
+} vax_inst[256] = {
+
+/*
+ * argdesc describes each arguments by two characters denoting
+ * the access-type and the data-type.
+ *
+ * Arguments (Access-Types):
+ *     r: operand is read only
+ *     w: operand is written only
+ *     m: operand is modified (both R and W)
+ *     b: no operand reference. Branch displacement is specified. 
+ *     a: calculate the adress of the specified operand
+ *     v: if not "Rn", same as a. If "RN," R[n+1]R[n]
+ * Arguments (Data-Types):
+ *     b: Byte
+ *     w: Word
+ *     l: Longword
+ *     q: Quadword
+ *     o: Octaword
+ *     d: D_floating
+ *     f: F_floating
+ *     g: G_floating
+ *     h: H_floating
+ *     r: Register
+ *     x: first data type specified by instruction
+ *     y: second data type spcified by instructin
+ *     -: no-args
+ *     ?: unknown (variable?)
+ */
+
+/* 0x00 */     {       "halt",         ""                      },
+/* 0x01 */     {       "nop",          ""                      },
+/* 0x02 */     {       "rei",          ""                      },
+/* 0x03 */     {       "bpt",          ""                      },
+/* 0x04 */     {       "ret",          ""                      },
+/* 0x05 */     {       "rsb",          ""                      },
+/* 0x06 */     {       "ldpctx",       ""                      },
+/* 0x07 */     {       "svpctx",       ""                      },
+/* 0x08 */     {       "cvtps",        "rw,ab,rw,ab"           },
+/* 0x09 */     {       "cvtsp",        "rw,ab,rw,ab"           },
+/* 0x0a */     {       "index",        "rl,rl,rl,rl,rl,wl"     },
+/* 0x0b */     {       "crc",          "ab,rl,rw,ab"           },
+/* 0x0c */     {       "prober",       "rb,rw,ab"              },
+/* 0x0d */     {       "probew",       "rb,rw,ab"              },
+/* 0x0e */     {       "insque",       "ab,wl"                 },
+/* 0x0f */     {       "remque",       "ab,wl"                 },
+          
+/* 0x10 */     {       "bsbb",         "bb"                    },
+/* 0x11 */     {       "brb",          "bb"                    },
+/* 0x12 */     {       "*bneq",        "bb"                    },
+/* 0x13 */     {       "*beql",        "bb"                    },
+/* 0x14 */     {       "bgtr",         "bb"                    },
+/* 0x15 */     {       "bleq",         "bb"                    },
+/* 0x16 */     {       "jsb",          "ab"                    },
+/* 0x17 */     {       "jmp",          "ab"                    },
+/* 0x18 */     {       "bgeq",         "bb"                    },
+/* 0x19 */     {       "blss",         "bb"                    },
+/* 0x1a */     {       "bgtru",        "bb"                    },
+/* 0x1b */     {       "blequ",        "bb"                    },
+/* 0x1c */     {       "bvc",          "bb"                    },
+/* 0x1d */     {       "bvs",          "bb"                    },
+/* 0x1e */     {       "*bcc",         "bb"                    },
+/* 0x1f */     {       "*bcs",         "bb"                    },
+          
+/* 0x20 */     {       "addp4",        "rw,ab,rw,ab"           },
+/* 0x21 */     {       "addp6",        "rw,ab,rw,ab,rw,ab"     },
+/* 0x22 */     {       "subp4",        "rw,ab,rw,ab"           },
+/* 0x23 */     {       "subp6",        "rw,ab,rw,ab,rw,ab"     },
+/* 0x24 */     {       "cvtpt",        "rw,ab,ab,rw,ab"        },
+/* 0x25 */     {       "mulp",         "rw,ab,rw,ab,rw,ab"     },
+/* 0x26 */     {       "cvttp",        "rw,ab,ab,rw,ab"        },
+/* 0x27 */     {       "divp",         "rw,ab,rw,ab,rw,ab"     },
+/* 0x28 */     {       "movc3",        "rw,ab,ab"              },
+/* 0x29 */     {       "cmpc3",        "rw,ab,ab"              },
+/* 0x2a */     {       "scanc",        "rw,ab,ab,rb"           },
+/* 0x2b */     {       "spanc",        "rw,ab,ab,rb"           },
+/* 0x2c */     {       "movc5",        "rw,ab,rb,rw,ab"        },
+/* 0x2d */     {       "cmpc5",        "rw,ab,rb,rw,ab"        },
+/* 0x2e */     {       "movtc",        "rw,ab,rb,ab,rw,ab"     },
+/* 0x2f */     {       "movtuc",       "rw,ab,rb,ab,rw,ab"     },
+          
+/* 0x30 */     {       "bsbw",         "bw"                    },
+/* 0x31 */     {       "brw",          "bw"                    },
+/* 0x32 */     {       "cvtwl",        "rw,wl"                 },
+/* 0x33 */     {       "cvtwb",        "rw,wb"                 },
+/* 0x34 */     {       "movp",         "rw,ab,ab"              },
+/* 0x35 */     {       "cmpp3",        "rw,ab,ab"              },
+/* 0x36 */     {       "cvtpl",        "rw,ab,wl"              },
+/* 0x37 */     {       "cmpp4",        "rw,ab,rw,ab"           },
+/* 0x38 */     {       "editpc",       "rw,ab,ab,ab"           },
+/* 0x39 */     {       "matchc",       "rw,ab,rw,ab"           },
+/* 0x3a */     {       "locc",         "rb,rw,ab"              },
+/* 0x3b */     {       "skpc",         "rb,rw,ab"              },
+/* 0x3c */     {       "movzwl",       "rw,wl"                 },
+/* 0x3d */     {       "acbw",         "rw,rw,mw,bw"           },
+/* 0x3e */     {       "movaw",        "aw,wl"                 },
+/* 0x3f */     {       "pushaw",       "aw"                    },
+          
+/* 0x40 */     {       "addf2",        "rf,mf"                 },
+/* 0x41 */     {       "addf3",        "rf,rf,wf"              },
+/* 0x42 */     {       "subf2",        "rf,mf"                 },
+/* 0x43 */     {       "subf3",        "rf,rf,wf"              },
+/* 0x44 */     {       "mulf2",        "rf,mf"                 },
+/* 0x45 */     {       "mulf3",        "rf,rf,wf"              },
+/* 0x46 */     {       "divf2",        "rf,mf"                 },
+/* 0x47 */     {       "divf3",        "rf,rf,wf"              },
+/* 0x48 */     {       "cvtfb",        "rf,wb"                 },
+/* 0x49 */     {       "cvtfw",        "rf,ww"                 },
+/* 0x4a */     {       "cvtfl",        "rf,wl"                 },
+/* 0x4b */     {       "cvtrfl",       "rf,wl"                 },
+/* 0x4c */     {       "cvtbf",        "rb,wf"                 },
+/* 0x4d */     {       "cvtwf",        "rw,wf"                 },
+/* 0x4e */     {       "cvtlf",        "rl,wf"                 },
+/* 0x4f */     {       "acbf",         "rf,rf,rf,bw"           },
+          
+/* 0x50 */     {       "movf",         "rf,wf"                 },
+/* 0x51 */     {       "cmpf",         "rf,rf"                 },
+/* 0x52 */     {       "mnegf",        "rf,wf"                 },
+/* 0x53 */     {       "tstf",         "rf"                    },
+/* 0x54 */     {       "emodf",        "rf,rb,rf,wl,wf"        },
+/* 0x55 */     {       "polyf",        "rf,rw,ab"              },
+/* 0x56 */     {       "cvtfd",        "rf,wd"                 },
+/* 0x57 */     {       "-reserved-",   ""                      },
+/* 0x58 */     {       "adawi",        "rw,mw"                 },
+/* 0x59 */     {       "-reserved-",   ""                      },
+/* 0x5a */     {       "-reserved-",   ""                      },
+/* 0x5b */     {       "-reserved-",   ""                      },
+/* 0x5c */     {       "insqhi",       "ab,aq"                 },
+/* 0x5d */     {       "insqti",       "ab,aq"                 },
+/* 0x5e */     {       "remqhi",       "aq,wl"                 },
+/* 0x5f */     {       "remqti",       "aq,wl"                 },
+          
+/* 0x60 */     {       "addd2",        "rd,md"                 },
+/* 0x61 */     {       "addd3",        "rd,rd,wd"              },
+/* 0x62 */     {       "subd2",        "rd,md"                 },
+/* 0x63 */     {       "subd3",        "rd,rd,wd"              },
+/* 0x64 */     {       "muld2",        "rd,md"                 },
+/* 0x65 */     {       "muld3",        "rd,rd,wd"              },
+/* 0x66 */     {       "divd2",        "rd,md"                 },
+/* 0x67 */     {       "divd3",        "rd,rd,wd"              },
+/* 0x68 */     {       "cvtdb",        "rd,wb"                 },
+/* 0x69 */     {       "cvtdw",        "rd,ww"                 },
+/* 0x6a */     {       "cvtdl",        "rd,wl"                 },
+/* 0x6b */     {       "cvtrdl",       "rd,wl"                 },
+/* 0x6c */     {       "cvtbd",        "rb,wd"                 },
+/* 0x6d */     {       "cvtwd",        "rw,wd"                 },
+/* 0x6e */     {       "cvtld",        "rl,wd"                 },
+/* 0x6f */     {       "acbd",         "rd,rd,md,bw"           },
+          
+/* 0x70 */     {       "movd",         "rd,wd"                 },
+/* 0x71 */     {       "cmpd",         "rd,rd"                 },
+/* 0x72 */     {       "mnegd",        "rd,wd"                 },
+/* 0x73 */     {       "tstd",         "rd"                    },
+/* 0x74 */     {       "emodd",        "rd,rb,rd,wl,wd"        },
+/* 0x75 */     {       "polyd",        "rd,rw,ab"              },
+/* 0x76 */     {       "cvtdf",        "rd,wf"                 },
+/* 0x77 */     {       "-reserved-",   ""                      },
+/* 0x78 */     {       "ashl",         "rb,rl,wl"              },
+/* 0x79 */     {       "ashq",         "rb,rq,wq"              },
+/* 0x7a */     {       "emul",         "rl,rl,rl,wq"           },
+/* 0x7b */     {       "ediv",         "rl,rq,wl,wl"           },
+/* 0x7c */     {       "*clrq",        "wq"                    },
+/* 0x7d */     {       "movq",         "rq,wq"                 },
+/* 0x7e */     {       "*movaq",       "aq,wl"                 },
+/* 0x7f */     {       "*pushaq",      "aq"                    },
+          
+/* 0x80 */     {       "addb2",        "rb,mb"                 },
+/* 0x81 */     {       "addb3",        "rb,rb,wb"              },
+/* 0x82 */     {       "subb2",        "rb,mb"                 },
+/* 0x83 */     {       "subb3",        "rb,rb,wb"              },
+/* 0x84 */     {       "mulb2",        "rb,mb"                 },
+/* 0x85 */     {       "mulb3",        "rb,rb,wb"              },
+/* 0x86 */     {       "divb2",        "rb,mb"                 },
+/* 0x87 */     {       "divb3",        "rb,rb,wb"              },
+/* 0x88 */     {       "bisb2",        "rb,mb"                 },
+/* 0x89 */     {       "bisb3",        "rb,rb,wb"              },
+/* 0x8a */     {       "bicb2",        "rb,mb"                 },
+/* 0x8b */     {       "bicb3",        "rb,rb,wb"              },
+/* 0x8c */     {       "xorb2",        "rb,mb"                 },
+/* 0x8d */     {       "xorb3",        "rb,rb,wb"              },
+/* 0x8e */     {       "mnegb",        "rb,wb"                 },
+/* 0x8f */     {       "caseb",        "rb,rb,rb,bw-list"      },
+          
+/* 0x90 */     {       "movb",         "rb,wb"                 },
+/* 0x91 */     {       "cmpb",         "rb,rb"                 },
+/* 0x92 */     {       "mcomb",        "rb,wb"                 },
+/* 0x93 */     {       "bitb",         "rb,rb"                 },
+/* 0x94 */     {       "clrb",         "wb"                    },
+/* 0x95 */     {       "tstb",         "rb"                    },
+/* 0x96 */     {       "incb",         "mb"                    },
+/* 0x97 */     {       "decb",         "mb"                    },
+/* 0x98 */     {       "cvtbl",        "rb,wl"                 },
+/* 0x99 */     {       "cvtbw",        "rb,ww"                 },
+/* 0x9a */     {       "movzbl",       "rb,wl"                 },
+/* 0x9b */     {       "movzbw",       "wb,ww"                 },
+/* 0x9c */     {       "rotl",         "rb,rl,wl"              },
+/* 0x9d */     {       "acbb",         "rb,rb,mb,bw"           },
+/* 0x9e */     {       "movab",        "ab,wl"                 },
+/* 0x9f */     {       "pushab",       "ab"                    },
+          
+/* 0xa0 */     {       "addw2",        "rw,mw"                 },
+/* 0xa1 */     {       "addw3",        "rw,rw,ww"              },
+/* 0xa2 */     {       "subw2",        "rw,mw"                 },
+/* 0xa3 */     {       "subw3",        "rw,rw,ww"              },
+/* 0xa4 */     {       "mulw2",        "rw,mw"                 },
+/* 0xa5 */     {       "mulw3",        "rw,rw,ww"              },
+/* 0xa6 */     {       "divw2",        "rw,mw"                 },
+/* 0xa7 */     {       "divw3",        "rw,rw,ww"              },
+/* 0xa8 */     {       "bisw2",        "rw,mw"                 },
+/* 0xa9 */     {       "bisw3",        "rw,rw,ww"              },
+/* 0xaa */     {       "bicw2",        "rw,mw"                 },
+/* 0xab */     {       "bicw3",        "rw,rw,ww"              },
+/* 0xac */     {       "xorw2",        "rw,mw"                 },
+/* 0xad */     {       "xorw3",        "rw,rw,ww"              },
+/* 0xae */     {       "mnegw",        "rw,ww"                 },
+/* 0xaf */     {       "casew",        "rw,rw,rw,bw-list"      },
+          
+/* 0xb0 */     {       "movw",         "rw,ww"                 },
+/* 0xb1 */     {       "cmpw",         "rw,rw"                 },
+/* 0xb2 */     {       "mcomw",        "rw,ww"                 },
+/* 0xb3 */     {       "bitw",         "rw,rw"                 },
+/* 0xb4 */     {       "clrw",         "mw"                    },
+/* 0xb5 */     {       "tstw",         "rw"                    },
+/* 0xb6 */     {       "incw",         "mw"                    },
+/* 0xb7 */     {       "decw",         "mw"                    },
+/* 0xb8 */     {       "bispsw",       "rw"                    },
+/* 0xb9 */     {       "bicpsw",       "rw"                    },
+/* 0xba */     {       "popr",         "rw"                    },
+/* 0xbb */     {       "pushr",        "rw"                    },
+/* 0xbc */     {       "chmk",         "rw"                    },
+/* 0xbd */     {       "chme",         "rw"                    },
+/* 0xbe */     {       "chms",         "rw"                    },
+/* 0xbf */     {       "chmu",         "rw"                    },
+          
+/* 0xc0 */     {       "addl2",        "rl,ml"                 },
+/* 0xc1 */     {       "addl3",        "rl,rl,wl"              },
+/* 0xc2 */     {       "subl2",        "rl,ml"                 },
+/* 0xc3 */     {       "subl3",        "rl,rl,wl"              },
+/* 0xc4 */     {       "mull2",        "rl,ml"                 },
+/* 0xc5 */     {       "mull3",        "rl,rl,wl"              },
+/* 0xc6 */     {       "divl2",        "rl,ml"                 },
+/* 0xc7 */     {       "divl3",        "rl,rl,wl"              },
+/* 0xc8 */     {       "bisl2",        "rl,ml"                 },
+/* 0xc9 */     {       "bisl3",        "rl,rl,wl"              },
+/* 0xca */     {       "bicl2",        "rl,ml"                 },
+/* 0xcb */     {       "bicl3",        "rl,rl,wl"              },
+/* 0xcc */     {       "xorl2",        "rl,ml"                 },
+/* 0xcd */     {       "xorl3",        "rl,rl,wl"              },
+/* 0xce */     {       "mnegl",        "rl,wl"                 },
+/* 0xcf */     {       "casel",        "rl,rl,rl,bw-list"      },
+          
+/* 0xd0 */     {       "movl",         "rl,wl"                 },
+/* 0xd1 */     {       "cmpl",         "rl,rl"                 },
+/* 0xd2 */     {       "mcoml",        "rl,wl"                 },
+/* 0xd3 */     {       "bitl",         "rl,rl"                 },
+/* 0xd4 */     {       "*clrl",        "wl"                    },
+/* 0xd5 */     {       "tstl",         "rl"                    },
+/* 0xd6 */     {       "incl",         "ml"                    },
+/* 0xd7 */     {       "decl",         "ml"                    },
+/* 0xd8 */     {       "adwc",         "rl,ml"                 },
+/* 0xd9 */     {       "sbwc",         "rl,ml"                 },
+/* 0xda */     {       "mtpr",         "rl,rl"                 },
+/* 0xdb */     {       "mfpr",         "rl,wl"                 },
+/* 0xdc */     {       "movpsl",       "wl"                    },
+/* 0xdd */     {       "pushl",        "rl"                    },
+/* 0xde */     {       "*moval",       "al,wl"                 },
+/* 0xdf */     {       "*pushal",      "al"                    },
+          
+/* 0xe0 */     {       "bbs",          "rl,vb,bb"              },
+/* 0xe1 */     {       "bbc",          "rl,vb,bb"              },
+/* 0xe2 */     {       "bbss",         "rl,vb,bb"              },
+/* 0xe3 */     {       "bbcs",         "rl,vb,bb"              },
+/* 0xe4 */     {       "bbsc",         "rl,vb,bb"              },
+/* 0xe5 */     {       "bbcc",         "rl,vb,bb"              },
+/* 0xe6 */     {       "bbssi",        "rl,vb,bb"              },
+/* 0xe7 */     {       "bbcci",        "rl,vb,bb"              },
+/* 0xe8 */     {       "blbs",         "rl,bb"                 },
+/* 0xe9 */     {       "blbc",         "rl,bb"                 },
+/* 0xea */     {       "ffs",          "rl,rb,vb"              },
+/* 0xeb */     {       "ffc",          "rl,rb,vb"              },
+/* 0xec */     {       "cmpv",         "rl,rb,vb,rl"           },
+/* 0xed */     {       "cmpzv",        "rl,rb,vb,rl"           },
+/* 0xee */     {       "extv",         "rl,rb,vb,wl"           },
+/* 0xef */     {       "extzv",        "rl,rb,vb,wl"           },
+          
+/* 0xf0 */     {       "insv",         "rl,rl,rb,vb"           },
+/* 0xf1 */     {       "acbl",         "rl,rl,ml,bw"           },
+/* 0xf2 */     {       "aoblss",       "rl,ml,bb"              },
+/* 0xf3 */     {       "aobleq",       "rl,ml,bb"              },
+/* 0xf4 */     {       "sobgeq",       "ml,bb"                 },
+/* 0xf5 */     {       "sobgtr",       "ml,bb"                 },
+/* 0xf6 */     {       "cvtlb",        "rl,wb"                 },
+/* 0xf7 */     {       "cvtlw",        "rl,ww"                 },
+/* 0xf8 */     {       "ashp",         "rb,rw,ab,rb,rw,ab"     },
+/* 0xf9 */     {       "cvtlp",        "rl,rw,ab"              },
+/* 0xfa */     {       "callg",        "ab,ab"                 },
+/* 0xfb */     {       "calls",        "rl,ab"                 },
+/* 0xfc */     {       "xfc",          "?"                     },
+/* 0xfd */     {       "-reserved-",   ""                      },
+/* 0xfe */     {       "-reserved-",   ""                      },
+/* 0xff */     {       "-reserved-",   ""                      },
+  
+};
+