summaryrefslogtreecommitdiff
path: root/sys/src/libmach/7db.c
diff options
context:
space:
mode:
authorTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
committerTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
commite5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch)
treed8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/libmach/7db.c
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/libmach/7db.c')
-rwxr-xr-xsys/src/libmach/7db.c925
1 files changed, 925 insertions, 0 deletions
diff --git a/sys/src/libmach/7db.c b/sys/src/libmach/7db.c
new file mode 100755
index 000000000..bf101dd27
--- /dev/null
+++ b/sys/src/libmach/7db.c
@@ -0,0 +1,925 @@
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include <mach.h>
+/*
+ * Alpha-specific debugger interface
+ */
+
+static char *alphaexcep(Map*, Rgetter);
+static int alphafoll(Map*, uvlong, Rgetter, uvlong*);
+static int alphainst(Map*, uvlong, char, char*, int);
+static int alphadas(Map*, uvlong, char*, int);
+static int alphainstlen(Map*, uvlong);
+/*
+ * Debugger interface
+ */
+Machdata alphamach =
+{
+ {0x80, 0, 0, 0}, /* break point */
+ 4, /* break point size */
+
+ leswab, /* short to local byte order */
+ leswal, /* long to local byte order */
+ leswav, /* vlong to local byte order */
+ risctrace, /* C traceback */
+ riscframe, /* Frame finder */
+ alphaexcep, /* print exception */
+ 0, /* breakpoint fixup */
+ leieeesftos, /* single precision float printer */
+ leieeedftos, /* double precisioin float printer */
+ alphafoll, /* following addresses */
+ alphainst, /* print instruction */
+ alphadas, /* dissembler */
+ alphainstlen, /* instruction size */
+};
+
+static char *illegaltype[] = {
+ "breakpoint",
+ "bugchk",
+ "gentrap",
+ "fen",
+ "illegal instruction",
+};
+
+static char *
+alphaexcep(Map *map, Rgetter rget)
+{
+ ulong type, a0, a1;
+ static char buf[256];
+
+ type = (*rget)(map, "TYPE");
+ a0 = (*rget)(map, "A0");
+ a1 = (*rget)(map, "A1");
+/* a2 = (*rget)(map, "A2"); */
+
+ switch (type) {
+ case 1: /* arith */
+ sprint(buf, "trap: arithmetic trap 0x%lux", a0);
+ break;
+ case 2: /* bad instr or FEN */
+ if (a0 <= 4)
+ return illegaltype[a0];
+ else
+ sprint(buf, "illegal instr trap, unknown type %lud", a0);
+ break;
+ case 3: /* intr */
+ sprint(buf, "interrupt type %lud", a0);
+ break;
+ case 4: /* memory fault */
+ sprint(buf, "fault %s addr=0x%lux", (a1&1)?"write":"read", a0);
+ break;
+ case 5: /* syscall() */
+ return "system call";
+ case 6: /* alignment fault */
+ sprint(buf, "unaligned op 0x%lux addr 0x%lux", a1, a0);
+ break;
+ default: /* cannot happen */
+ sprint(buf, "unknown exception type %lud", type);
+ break;
+ }
+ return buf;
+}
+
+ /* alpha disassembler and related functions */
+
+static char FRAMENAME[] = ".frame";
+
+typedef struct {
+ uvlong addr;
+ uchar op; /* bits 31-26 */
+ uchar ra; /* bits 25-21 */
+ uchar rb; /* bits 20-16 */
+ uchar rc; /* bits 4-0 */
+ long mem; /* bits 15-0 */
+ long branch; /* bits 20-0 */
+ uchar function; /* bits 11-5 */
+ uchar literal; /* bits 20-13 */
+ uchar islit; /* bit 12 */
+ uchar fpfn; /* bits 10-5 */
+ uchar fpmode; /* bits 15-11 */
+ long w0;
+ long w1;
+ int size; /* instruction size */
+ char *curr; /* fill point in buffer */
+ char *end; /* end of buffer */
+ char *err; /* error message */
+} Instr;
+
+static Map *mymap;
+
+static int
+decode(uvlong pc, Instr *i)
+{
+ ulong w;
+
+ if (get4(mymap, pc, &w) < 0) {
+ werrstr("can't read instruction: %r");
+ return -1;
+ }
+ i->addr = pc;
+ i->size = 1;
+ i->op = (w >> 26) & 0x3F;
+ i->ra = (w >> 21) & 0x1F;
+ i->rb = (w >> 16) & 0x1F;
+ i->rc = w & 0x1F;
+ i->function = (w >> 5) & 0x7F;
+ i->mem = w & 0xFFFF;
+ if (i->mem & 0x8000)
+ i->mem -= 0x10000;
+ i->branch = w & 0x1FFFFF;
+ if (i->branch & 0x100000)
+ i->branch -= 0x200000;
+ i->function = (w >> 5) & 0x7F;
+ i->literal = (w >> 13) & 0xFF;
+ i->islit = (w >> 12) & 0x01;
+ i->fpfn = (w >> 5) & 0x3F;
+ i->fpmode = (w >> 11) & 0x1F;
+ i->w0 = w;
+ return 1;
+}
+
+static int
+mkinstr(uvlong pc, Instr *i)
+{
+/* Instr x; */
+
+ if (decode(pc, i) < 0)
+ return -1;
+
+#ifdef frommips
+/* we probably want to do something like this for alpha... */
+ /*
+ * if it's a LUI followed by an ORI,
+ * it's an immediate load of a large constant.
+ * fix the LUI immediate in any case.
+ */
+ if (i->op == 0x0F) {
+ if (decode(pc+4, &x) < 0)
+ return 0;
+ i->immediate <<= 16;
+ if (x.op == 0x0D && x.rs == x.rt && x.rt == i->rt) {
+ i->immediate |= (x.immediate & 0xFFFF);
+ i->w1 = x.w0;
+ i->size++;
+ return 1;
+ }
+ }
+#endif
+ return 1;
+}
+
+#pragma varargck argpos bprint 2
+
+static void
+bprint(Instr *i, char *fmt, ...)
+{
+ va_list arg;
+
+ va_start(arg, fmt);
+ i->curr = vseprint(i->curr, i->end, fmt, arg);
+ va_end(arg);
+}
+
+typedef struct Opcode Opcode;
+
+struct Opcode {
+ char *mnemonic;
+ void (*f)(Opcode *, Instr *);
+ char *ken;
+};
+
+static void format(char *, Instr *, char *);
+
+static int
+plocal(Instr *i, char *m, char r, int store)
+{
+ int offset;
+ char *reg;
+ Symbol s;
+
+ if (!findsym(i->addr, CTEXT, &s) || !findlocal(&s, FRAMENAME, &s))
+ return 0;
+ if (s.value > i->mem) {
+ if(!getauto(&s, s.value-i->mem, CAUTO, &s))
+ return 0;
+ reg = "(SP)";
+ offset = i->mem;
+ } else {
+ offset = i->mem-s.value-8;
+ if (!getauto(&s, offset, CPARAM, &s))
+ return 0;
+ reg = "(FP)";
+ }
+ if (store)
+ bprint(i, "%s\t%c%d,%s+%d%s", m, r, i->ra, s.name, offset, reg);
+ else
+ bprint(i, "%s\t%s+%d%s,%c%d", m, s.name, offset, reg, r, i->ra);
+ return 1;
+}
+
+static void
+_load(Opcode *o, Instr *i, char r)
+{
+ char *m;
+
+ m = o->mnemonic;
+ if (i->rb == 30 && plocal(i, m, r, 0))
+ return;
+ if (i->rb == 29 && mach->sb) {
+ bprint(i, "%s\t", m);
+ i->curr += symoff(i->curr, i->end-i->curr, i->mem+mach->sb, CANY);
+ bprint(i, "(SB),%c%d", r, i->ra);
+ return;
+ }
+ format(m, i, o->ken);
+}
+
+static void
+load(Opcode *o, Instr *i)
+{
+ _load(o, i, 'R');
+}
+
+static void
+loadf(Opcode *o, Instr *i)
+{
+ _load(o, i, 'F');
+}
+
+static void
+_store(Opcode *o, Instr *i, char r)
+{
+ char *m;
+
+ m = o->mnemonic;
+ if (i->rb == 30 && plocal(i, m, r, 1))
+ return;
+ if (i->rb == 29 && mach->sb) {
+ bprint(i, "%s\t%c%d,", m, r, i->ra);
+ i->curr += symoff(i->curr, i->end-i->curr, i->mem+mach->sb, CANY);
+ bprint(i, "(SB)");
+ return;
+ }
+ format(o->mnemonic, i, o->ken);
+}
+
+static void
+store(Opcode *o, Instr *i)
+{
+ _store(o, i, 'R');
+}
+
+static void
+storef(Opcode *o, Instr *i)
+{
+ _store(o, i, 'F');
+}
+
+static void
+misc(Opcode *o, Instr *i)
+{
+ char *f;
+
+ USED(o);
+ switch (i->mem&0xFFFF) {
+ case 0x0000:
+ f = "TRAPB";
+ break;
+ case 0x4000:
+ f = "MB";
+ break;
+ case 0x8000:
+ f = "FETCH\t0(R%b)";
+ break;
+ case 0xA000:
+ f = "FETCH_M\t0(R%b)";
+ break;
+ case 0xC000:
+ f = "RPCC\tR%a";
+ break;
+ case 0xE000:
+ f = "RC\tR%a";
+ break;
+ case 0xF000:
+ f = "RS\tR%a";
+ break;
+ default:
+ f = "%w";
+ }
+ format(0, i, f);
+}
+
+static char *jmpcode[4] = { "JMP", "JSR", "RET", "JSR_COROUTINE" };
+
+static void
+jmp(Opcode *o, Instr *i)
+{
+ int hint;
+ char *m;
+
+ USED(o);
+ hint = (i->mem >> 14) & 3;
+ m = jmpcode[hint];
+ if (i->ra == 31) {
+ if (hint == 2 && i->rb == 29)
+ bprint(i, m);
+ else
+ format(m, i, "(R%b)");
+ }
+ else
+ format(m, i, "R%a,(R%b)");
+}
+
+static void
+br(Opcode *o, Instr *i)
+{
+ if (i->ra == 31)
+ format(o->mnemonic, i, "%B");
+ else
+ format(o->mnemonic, i, o->ken);
+}
+
+static void
+bsr(Opcode *o, Instr *i)
+{
+ if (i->ra == 26)
+ format(o->mnemonic, i, "%B");
+ else
+ format(o->mnemonic, i, o->ken);
+}
+
+static void
+mult(Opcode *o, Instr *i)
+{
+ char *m;
+
+ switch (i->function) {
+ case 0x00:
+ m = "MULL";
+ break;
+ case 0x20:
+ m = "MULQ";
+ break;
+ case 0x40:
+ m = "MULL/V";
+ break;
+ case 0x60:
+ m = "MULQ/V";
+ break;
+ case 0x30:
+ m = "UMULH";
+ break;
+ default:
+ format("???", i, "%w");
+ return;
+ }
+ format(m, i, o->ken);
+}
+
+static char alphaload[] = "%l,R%a";
+static char alphafload[] = "%l,F%a";
+static char alphastore[] = "R%a,%l";
+static char alphafstore[] = "F%a,%l";
+static char alphabranch[] = "R%a,%B";
+static char alphafbranch[] = "F%a,%B";
+static char alphaint[] = "%v,R%a,R%c";
+static char alphafp[] = "F%b,F%a,F%c";
+static char alphafp2[] = "F%b,F%c";
+static char alphaxxx[] = "%w";
+
+static Opcode opcodes[64] = {
+ "PAL", 0, alphaxxx,
+ "OPC01", 0, alphaxxx,
+ "OPC02", 0, alphaxxx,
+ "OPC03", 0, alphaxxx,
+ "OPC04", 0, alphaxxx,
+ "OPC05", 0, alphaxxx,
+ "OPC06", 0, alphaxxx,
+ "OPC07", 0, alphaxxx,
+ "MOVQA", load, alphaload,
+ "MOVQAH", load, alphaload,
+ "MOVBU", load, alphaload, /* v 3 */
+ "MOVQU", load, alphaload,
+ "MOVWU", load, alphaload, /* v 3 */
+ "MOVWU", store, alphastore, /* v 3 */
+ "MOVBU", store, alphastore, /* v 3 */
+ "MOVQU", store, alphastore,
+ 0, 0, 0, /* int arith */
+ 0, 0, 0, /* logical */
+ 0, 0, 0, /* shift */
+ 0, mult, alphaint,
+ "OPC14", 0, alphaxxx,
+ "vax", 0, alphafp, /* vax */
+ 0, 0, 0, /* ieee */
+ 0, 0, 0, /* fp */
+ 0, misc, alphaxxx,
+ "PAL19 [HW_MFPR]",0, alphaxxx,
+ "JSR", jmp, 0,
+ "PAL1B [HW_LD]",0, alphaxxx,
+ "OPC1C", 0, alphaxxx,
+ "PAL1D [HW_MTPR]",0, alphaxxx,
+ "PAL1E [HW_REI]",0, alphaxxx,
+ "PAL1F [HW_ST]",0, alphaxxx,
+ "MOVF", loadf, alphafload,
+ "MOVG", loadf, alphafload,
+ "MOVS", loadf, alphafload,
+ "MOVT", loadf, alphafload,
+ "MOVF", storef, alphafstore,
+ "MOVG", storef, alphafstore,
+ "MOVS", storef, alphafstore,
+ "MOVT", storef, alphafstore,
+ "MOVL", load, alphaload,
+ "MOVQ", load, alphaload,
+ "MOVLL", load, alphaload,
+ "MOVQL", load, alphaload,
+ "MOVL", store, alphastore,
+ "MOVQ", store, alphastore,
+ "MOVLC", store, alphastore,
+ "MOVQC", store, alphastore,
+ "JMP", br, alphabranch,
+ "FBEQ", 0, alphafbranch,
+ "FBLT", 0, alphafbranch,
+ "FBLE", 0, alphafbranch,
+ "JSR", bsr, alphabranch,
+ "FBNE", 0, alphafbranch,
+ "FBGE", 0, alphafbranch,
+ "FBGT", 0, alphafbranch,
+ "BLBC", 0, alphafbranch,
+ "BEQ", 0, alphabranch,
+ "BLT", 0, alphabranch,
+ "BLE", 0, alphabranch,
+ "BLBS", 0, alphabranch,
+ "BNE", 0, alphabranch,
+ "BGE", 0, alphabranch,
+ "BGT", 0, alphabranch,
+};
+
+static Opcode fpopcodes[64] = {
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+
+ "CVTLQ", 0, alphafp2,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+
+ "CPYS", 0, alphafp,
+ "CPYSN", 0, alphafp,
+ "CPYSE", 0, alphafp,
+ "???", 0, alphaxxx,
+ "MOVT", 0, "FPCR,F%a",
+ "MOVT", 0, "F%a,FPCR",
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "FCMOVEQ", 0, alphafp,
+ "FCMOVNE", 0, alphafp,
+ "FCMOVLT", 0, alphafp,
+ "FCMOVGE", 0, alphafp,
+ "FCMOVLE", 0, alphafp,
+ "FCMOVGT", 0, alphafp,
+
+ "CVTQL", 0, alphafp2,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+};
+
+static Opcode ieeeopcodes[64] = {
+ "ADDS", 0, alphafp,
+ "SUBS", 0, alphafp,
+ "MULS", 0, alphafp,
+ "DIVS", 0, alphafp,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+
+ "ADDT", 0, alphafp,
+ "SUBT", 0, alphafp,
+ "MULT", 0, alphafp,
+ "DIVT", 0, alphafp,
+ "CMPTUN", 0, alphafp,
+ "CMPTEQ", 0, alphafp,
+ "CMPTLT", 0, alphafp,
+ "CMPTLE", 0, alphafp,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "CVTTS", 0, alphafp2,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "CVTTQ", 0, alphafp2,
+
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "???", 0, alphaxxx,
+ "CVTQS", 0, alphafp2,
+ "???", 0, alphaxxx,
+ "CVTQT", 0, alphafp2,
+ "???", 0, alphaxxx,
+};
+
+static uchar amap[128] = {
+ [0x00] 1,
+ [0x40] 2,
+ [0x20] 3,
+ [0x60] 4,
+ [0x09] 5,
+ [0x49] 6,
+ [0x29] 7,
+ [0x69] 8,
+ [0x2D] 9,
+ [0x4D] 10,
+ [0x6D] 11,
+ [0x1D] 12,
+ [0x3D] 13,
+ [0x0F] 14,
+ [0x02] 15,
+ [0x0B] 16,
+ [0x12] 17,
+ [0x1B] 18,
+ [0x22] 19,
+ [0x2B] 20,
+ [0x32] 21,
+ [0x3B] 22,
+};
+
+static Opcode arithopcodes[64] = {
+ "???", 0, alphaxxx,
+ "ADDL", 0, alphaint,
+ "ADDL/V", 0, alphaint,
+ "ADDQ", 0, alphaint,
+ "ADDQ/V", 0, alphaint,
+ "SUBL", 0, alphaint,
+ "SUBL/V", 0, alphaint,
+ "SUBQ", 0, alphaint,
+ "SUBQ/V", 0, alphaint,
+ "CMPEQ", 0, alphaint,
+ "CMPLT", 0, alphaint,
+ "CMPLE", 0, alphaint,
+ "CMPULT", 0, alphaint,
+ "CMPULE", 0, alphaint,
+ "CMPBGE", 0, alphaint,
+ "S4ADDL", 0, alphaint,
+ "S4SUBL", 0, alphaint,
+ "S8ADDL", 0, alphaint,
+ "S8SUBL", 0, alphaint,
+ "S4ADDQ", 0, alphaint,
+ "S4SUBQ", 0, alphaint,
+ "S8ADDQ", 0, alphaint,
+ "S8SUBQ", 0, alphaint,
+};
+
+static uchar lmap[128] = {
+ [0x00] 1,
+ [0x20] 2,
+ [0x40] 3,
+ [0x08] 4,
+ [0x28] 5,
+ [0x48] 6,
+ [0x24] 7,
+ [0x44] 8,
+ [0x64] 9,
+ [0x26] 7,
+ [0x46] 8,
+ [0x66] 9,
+ [0x14] 10,
+ [0x16] 11,
+};
+
+static Opcode logicalopcodes[64] = {
+ "???", 0, alphaxxx,
+ "AND", 0, alphaint,
+ "OR", 0, alphaint,
+ "XOR", 0, alphaint,
+ "ANDNOT", 0, alphaint,
+ "ORNOT", 0, alphaint,
+ "XORNOT", 0, alphaint,
+ "CMOVEQ", 0, alphaint,
+ "CMOVLT", 0, alphaint,
+ "CMOVLE", 0, alphaint,
+ "CMOVNE", 0, alphaint,
+ "CMOVGE", 0, alphaint,
+ "CMOVGT", 0, alphaint,
+ "CMOVLBS", 0, alphaint,
+ "CMOVLBC", 0, alphaint,
+};
+
+static uchar smap[128] = {
+ [0x39] 1,
+ [0x3C] 2,
+ [0x34] 3,
+ [0x06] 4,
+ [0x16] 5,
+ [0x26] 6,
+ [0x36] 7,
+ [0x5A] 8,
+ [0x6A] 9,
+ [0x7A] 10,
+ [0x0B] 11,
+ [0x1B] 12,
+ [0x2B] 13,
+ [0x3B] 14,
+ [0x57] 15,
+ [0x67] 16,
+ [0x77] 17,
+ [0x02] 18,
+ [0x12] 19,
+ [0x22] 20,
+ [0x32] 21,
+ [0x52] 22,
+ [0x62] 23,
+ [0x72] 24,
+ [0x30] 25,
+ [0x31] 26,
+};
+
+static Opcode shiftopcodes[64] = {
+ "???", 0, alphaxxx,
+ "SLLQ", 0, alphaint,
+ "SRAQ", 0, alphaint,
+ "SRLQ", 0, alphaint,
+ "EXTBL", 0, alphaint,
+ "EXTWL", 0, alphaint,
+ "EXTLL", 0, alphaint,
+ "EXTQL", 0, alphaint,
+ "EXTWH", 0, alphaint,
+ "EXTLH", 0, alphaint,
+ "EXTQH", 0, alphaint,
+ "INSBL", 0, alphaint,
+ "INSWL", 0, alphaint,
+ "INSLL", 0, alphaint,
+ "INSQL", 0, alphaint,
+ "INSWH", 0, alphaint,
+ "INSLH", 0, alphaint,
+ "INSQH", 0, alphaint,
+ "MSKBL", 0, alphaint,
+ "MSKWL", 0, alphaint,
+ "MSKLL", 0, alphaint,
+ "MSKQL", 0, alphaint,
+ "MSKWH", 0, alphaint,
+ "MSKLH", 0, alphaint,
+ "MSKQH", 0, alphaint,
+ "ZAP", 0, alphaint,
+ "ZAPNOT", 0, alphaint,
+};
+
+static void
+format(char *mnemonic, Instr *i, char *f)
+{
+ if (mnemonic)
+ format(0, i, mnemonic);
+ if (f == 0)
+ return;
+ if (mnemonic)
+ if (i->curr < i->end)
+ *i->curr++ = '\t';
+ for ( ; *f && i->curr < i->end; f++) {
+ if (*f != '%') {
+ *i->curr++ = *f;
+ continue;
+ }
+ switch (*++f) {
+
+ case 'a':
+ bprint(i, "%d", i->ra);
+ break;
+
+ case 'b':
+ bprint(i, "%d", i->rb);
+ break;
+
+ case 'c':
+ bprint(i, "%d", i->rc);
+ break;
+
+ case 'v':
+ if (i->islit)
+ bprint(i, "$%ux", i->literal);
+ else
+ bprint(i, "R%d", i->rb);
+ break;
+
+ case 'l':
+ bprint(i, "%lx(R%d)", i->mem, i->rb);
+ break;
+
+ case 'i':
+ bprint(i, "$%lx", i->mem);
+ break;
+
+ case 'B':
+ i->curr += symoff(i->curr, i->end-i->curr,
+ (i->branch<<2)+i->addr+4, CANY);
+ break;
+
+ case 'w':
+ bprint(i, "[%lux]", i->w0);
+ break;
+
+ case '\0':
+ *i->curr++ = '%';
+ return;
+
+ default:
+ bprint(i, "%%%c", *f);
+ break;
+ }
+ }
+ *i->curr = 0;
+}
+
+static int
+printins(Map *map, uvlong pc, char *buf, int n)
+{
+ Instr i;
+ Opcode *o;
+ uchar op;
+
+ i.curr = buf;
+ i.end = buf+n-1;
+ mymap = map;
+ if (mkinstr(pc, &i) < 0)
+ return -1;
+ switch (i.op) {
+
+ case 0x10: /* INTA */
+ o = arithopcodes;
+ op = amap[i.function];
+ break;
+
+ case 0x11: /* INTL */
+ o = logicalopcodes;
+ op = lmap[i.function];
+ break;
+
+ case 0x12: /* INTS */
+ o = shiftopcodes;
+ op = smap[i.function];
+ break;
+
+ case 0x16: /* FLTI */
+ o = ieeeopcodes;
+ op = i.fpfn;
+ break;
+
+ case 0x17: /* FLTL */
+ o = fpopcodes;
+ op = i.fpfn;
+ break;
+
+ default:
+ o = opcodes;
+ op = i.op;
+ break;
+ }
+ if (o[op].f)
+ (*o[op].f)(&o[op], &i);
+ else
+ format(o[op].mnemonic, &i, o[op].ken);
+ return i.size*4;
+}
+
+static int
+alphainst(Map *map, uvlong pc, char modifier, char *buf, int n)
+{
+ USED(modifier);
+ return printins(map, pc, buf, n);
+}
+
+static int
+alphadas(Map *map, uvlong pc, char *buf, int n)
+{
+ Instr i;
+
+ i.curr = buf;
+ i.end = buf+n;
+ mymap = map;
+ if (mkinstr(pc, &i) < 0)
+ return -1;
+ if (i.end-i.curr > 8)
+ i.curr = _hexify(buf, i.w0, 7);
+ if (i.size == 2 && i.end-i.curr > 9) {
+ *i.curr++ = ' ';
+ i.curr = _hexify(i.curr, i.w1, 7);
+ }
+ *i.curr = 0;
+ return i.size*4;
+}
+
+static int
+alphainstlen(Map *map, uvlong pc)
+{
+ Instr i;
+
+ mymap = map;
+ if (mkinstr(pc, &i) < 0)
+ return -1;
+ return i.size*4;
+}
+
+static int
+alphafoll(Map *map, uvlong pc, Rgetter rget, uvlong *foll)
+{
+ char buf[8];
+ Instr i;
+
+ mymap = map;
+ if (mkinstr(pc, &i) < 0)
+ return -1;
+
+ switch(i.op) {
+ case 0x1A: /* JMP/JSR/RET */
+ sprint(buf, "R%d", i.rb);
+ foll[0] = (*rget)(map, buf);
+ return 1;
+ case 0x30: /* BR */
+ case 0x34: /* BSR */
+ foll[0] = pc+4 + (i.branch<<2);
+ return 1;
+ default:
+ if (i.op > 0x30) { /* cond */
+ foll[0] = pc+4;
+ foll[1] = pc+4 + (i.branch<<2);
+ return 2;
+ }
+ foll[0] = pc+i.size*4;
+ return 1;
+ }
+}