123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502 |
- #include <u.h>
- #include <libc.h>
- #include <bio.h>
- #include <mach.h>
- /*
- * amd29k-specific debugger interface
- */
- static int a29000inst(Map*, ulong, char, char*, int);
- static int a29000das(Map*, ulong, char*, int);
- static int a29000instlen(Map*, ulong);
- /*
- * Debugger interface
- */
- Machdata a29000mach =
- {
- {0, 0, 0, 0}, /* break point */
- 4, /* break point size */
- beswab, /* short to local byte order */
- beswal, /* long to local byte order */
- beswav, /* vlong to local byte order */
- risctrace, /* C traceback */
- riscframe, /* Frame finder */
- 0, /* print exception */
- 0, /* breakpoint fixup */
- beieeesftos, /* single precision float printer */
- beieeedftos, /* double precisioin float printer */
- 0, /* following addresses */
- a29000inst, /* print instruction */
- a29000das, /* dissembler */
- a29000instlen, /* instruction size */
- };
- /* mips disassembler and related functions */
- static char FRAMENAME[] = ".frame";
- /* amd 29k native disassembler */
- typedef struct {
- long addr; /* pc of instr */
- uchar op; /* bits 31-24 */
- uchar rc; /* bits 23-16 */
- uchar ra; /* bits 15-8 */
- uchar rb; /* bits 0-7 */
- ushort imm; /* bits 23-16 and bits 0-7 */
- long w0;
- char *curr; /* current fill point */
- char *end; /* end of buffer */
- char *err;
- } Instr;
- typedef struct {
- char *mnemonic;
- char *fmt;
- } Opcode;
- static char amdunk[] = "%w";
- static char amdalu2op[] = "r%c,r%a";
- static char amdaluasop[] = "$%c,r%a,r%b";
- static char amdaluasopi[] = "$%c,r%a,%s";
- static char amdalu3op[] = "r%c,r%a,r%b";
- static char amdalu3opi[] = "r%c,r%a,%s";
- static char amdjs[] = "r%a,%j";
- static char amdju[] = "r%a,%J";
- static char amdji[] = "r%a,r%b";
- static char amdmem[] = "%m,r%a,r%b";
- static char amdmemi[] = "%m,r%a,%s";
- static char *memacc[8] = { "L", "B", "H", "HW" };
- static Opcode opcodes[256] = {
- 0, 0,
- "constn", "r%a,%i",
- "consth", "r%a,%I0000",
- "const", "r%a,%I",
- "mtsrim", "s%a,%I",
- 0, 0,
- "loadl", amdmem,
- "loadl", amdmemi,
- "clz", amdunk,
- "clz", amdunk,
- "exbyte", amdalu3op,
- "exbyte", amdalu3opi,
- "inbyte", amdalu3op,
- "inbyte", amdalu3opi,
- "storel", amdmem,
- "storel", amdmemi,
- "adds", amdalu3op,
- "adds", amdalu3opi,
- "addu", amdalu3op,
- "addu", amdalu3opi,
- "add", amdalu3op,
- "add", amdalu3opi,
- "load", amdmem,
- "load", amdmemi,
- "addcs", amdalu3op,
- "addcs", amdalu3opi,
- "addcu", amdalu3op,
- "addcu", amdalu3opi,
- "addc", amdalu3op,
- "addc", amdalu3opi,
- "store", amdmem,
- "store", amdmemi,
- "subs", amdalu3op,
- "subs", amdalu3opi,
- "subu", amdalu3op,
- "subu", amdalu3opi,
- "sub", amdalu3op,
- "sub", amdalu3opi,
- "loadset", amdmem,
- "loadset", amdmemi,
- "subcs", amdalu3op,
- "subcs", amdalu3opi,
- "subcu", amdalu3op,
- "subcu", amdalu3opi,
- "subc", amdalu3op,
- "subc", amdalu3opi,
- "cpbyte", amdalu3op,
- "cpbyte", amdalu3opi,
- "subrs", amdalu3op,
- "subrs", amdalu3opi,
- "subru", amdalu3op,
- "subru", amdalu3opi,
- "subr", amdalu3op,
- "subr", amdalu3opi,
- "loadm", amdmem,
- "loadm", amdmemi,
- "subrcs", amdalu3op,
- "subrcs", amdalu3opi,
- "subrcu", amdalu3op,
- "subrcu", amdalu3opi,
- "subrc", amdalu3op,
- "subrc", amdalu3opi,
- "storem", amdmem,
- "storem", amdmemi,
- "cplt", amdalu3op,
- "cplt", amdalu3opi,
- "cpltu", amdalu3op,
- "cpltu", amdalu3opi,
- "cple", amdalu3op,
- "cple", amdalu3opi,
- "cpleu", amdalu3op,
- "cpleu", amdalu3opi,
- "cpgt", amdalu3op,
- "cpgt", amdalu3opi,
- "cpgtu", amdalu3op,
- "cpgtu", amdalu3opi,
- "cpge", amdalu3op,
- "cpge", amdalu3opi,
- "cpgeu", amdalu3op,
- "cpgeu", amdalu3opi,
- "aslt", amdaluasop,
- "aslt", amdaluasopi,
- "asltu", amdaluasop,
- "asltu", amdaluasopi,
- "asle", amdaluasop,
- "asle", amdaluasopi,
- "asleu", amdaluasop,
- "asleu", amdaluasopi,
- "asgt", amdaluasop,
- "asgt", amdaluasopi,
- "asgtu", amdaluasop,
- "asgtu", amdaluasopi,
- "asge", amdaluasop,
- "asge", amdaluasopi,
- "asgeu", amdaluasop,
- "asgeu", amdaluasopi,
- "cpeq", amdalu3op,
- "cpeq", amdalu3opi,
- "cpneq", amdalu3op,
- "cpneq", amdalu3opi,
- "mul", amdalu3op,
- "mul", amdalu3opi,
- "mull", amdalu3op,
- "mull", amdalu3opi,
- "div0", amdalu3op,
- "div0", amdalu3opi,
- "div", amdalu3op,
- "div", amdalu3opi,
- "divl", amdalu3op,
- "divl", amdalu3opi,
- "divrem", amdalu3op,
- "divrem", amdalu3opi,
- "aseq", amdaluasop,
- "aseq", amdaluasopi,
- "asneq", amdaluasop,
- "asneq", amdaluasopi,
- "mulu", amdalu3op,
- "mulu", amdalu3opi,
- 0, 0,
- 0, 0,
- "inhw", amdalu3op,
- "inhw", amdalu3opi,
- "extract", amdalu3op,
- "extract", amdalu3opi,
- "exhw", amdalu3op,
- "exhw", amdalu3opi,
- "exhws", amdalu2op,
- 0, 0,
- "sll", amdalu3op,
- "sll", amdalu3opi,
- "srl", amdalu3op,
- "srl", amdalu3opi,
- 0, 0,
- 0, 0,
- "sra", amdalu3op,
- "sra", amdalu3opi,
- "iret", amdunk,
- "halt", amdunk,
- 0, 0,
- 0, 0,
- "iretinv", amdunk,
- 0, 0,
- 0, 0,
- 0, 0,
- "and", amdalu3op,
- "and", amdalu3opi,
- "or", amdalu3op,
- "or", amdalu3opi,
- "xor", amdalu3op,
- "xor", amdalu3opi,
- "xnor", amdalu3op,
- "xnor", amdalu3opi,
- "nor", amdalu3op,
- "nor", amdalu3opi,
- "nand", amdalu3op,
- "nand", amdalu3opi,
- "andn", amdalu3op,
- "andn", amdalu3opi,
- "setip", amdalu3op,
- "inv", amdunk,
- "jmp", "%j",
- "jmp", "%J",
- 0, 0,
- 0, 0,
- "jmpf", amdjs,
- "jmpf", amdju,
- 0, 0,
- 0, 0,
- "call", amdjs,
- "call", amdju,
- 0, 0,
- 0, 0,
- "jmpt", amdjs,
- "jmpt", amdju,
- 0, 0,
- 0, 0,
- 0, 0,
- 0, 0,
- 0, 0,
- 0, 0,
- "jmpfdec", amdunk,
- "jmpfdec", amdunk,
- "mftlb", "r%c,r%a",
- 0, 0,
- 0, 0,
- 0, 0,
- 0, 0,
- 0, 0,
- 0, 0,
- 0, 0,
- "mttlb", "r%a,r%b",
- 0, 0,
- "jmpi", "r%b",
- 0, 0,
- 0, 0,
- 0, 0,
- "jmpfi", amdji,
- 0, 0,
- "mfsr", "r%c,s%a",
- 0, 0,
- "calli", amdji,
- 0, 0,
- 0, 0,
- 0, 0,
- "jmpti", amdji,
- 0, 0,
- "mtsr", "s%a,r%b",
- 0, 0,
- 0, 0,
- 0, 0,
- 0, 0,
- 0, 0,
- 0, 0,
- 0, 0,
- 0, 0,
- "emulate", amdunk,
- 0, 0, /* D8: vector 24 */
- 0, 0,
- 0, 0,
- 0, 0,
- 0, 0,
- 0, 0, /* DD: vector 29 */
- "multm", amdalu3op,
- "multmu", amdalu3op,
- "multiply", amdalu3op,
- "divide", amdalu3op,
- "multiplu", amdalu3op,
- "dividu", amdalu3op,
- "convert", amdunk,
- "sqrt", amdunk,
- "class", amdunk,
- 0, 0, /* E7: vector 39 */
- 0, 0,
- 0, 0, /* E9: vector 41 */
- "feq", amdunk,
- "deq", amdunk,
- "fgt", amdunk,
- "dgt", amdunk,
- "fge", amdunk,
- "dge", amdunk,
- "fadd", amdunk,
- "dadd", amdunk,
- "fsub", amdunk,
- "dsub", amdunk,
- "fmul", amdunk,
- "dmul", amdunk,
- "fdiv", amdunk,
- "ddiv", amdunk,
- 0, 0, /* F8: vector 56 */
- "fdmul", amdunk,
- 0, 0, /* FA: vector 58 */
- 0, 0,
- 0, 0,
- 0, 0,
- 0, 0,
- 0, 0, /* FF: vector 63 */
- };
- static int
- mkinstr(Instr *i, ulong pc, ulong w)
- {
- i->addr = pc;
- i->op = (w >> 24) & 0xFF;
- i->rc = (w >> 16) & 0xFF;
- i->ra = (w >> 8) & 0xFF;
- i->rb = (w >> 0) & 0xFF;
- i->imm = ((w >> 8) & 0xFF00) | (w & 0xFF);
- i->w0 = w;
- return 1;
- }
- 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);
- }
- static void
- format(char *mnemonic, Instr *i, char *f)
- {
- char *s;
- int a;
- if (mnemonic)
- format(0, i, mnemonic);
- if (f == 0)
- return;
- if (i->curr < i->end)
- *i->curr++ = '\t';
- for ( ; *f && i->curr < i->end; f++) {
- if (*f != '%') {
- *i->curr++ = *f;
- continue;
- }
- switch (*++f) {
- case 'm':
- s = memacc[i->rc & 7];
- if(s == 0 || i->rc & (7<<6)){
- bprint(i, "?0x%.2x", i->rc);
- break;
- }
- if(i->rc & (1<<5))
- bprint(i, "%c", 'P');
- if(i->rc & (1<<4))
- bprint(i, "%c", 'S');
- if(i->rc & (1<<3))
- bprint(i, "%c", 'U');
- bprint(i, "%s", s);
- break;
- 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 's':
- bprint(i, "$%.2ux", i->rb);
- break;
- case 'i':
- bprint(i, "$%.4ux", i->imm | ~0xFFFF);
- break;
- case 'I':
- bprint(i, "$%.4ux", i->imm);
- break;
- case 'j':
- a = i->imm;
- if(a & 0x8000)
- a |= ~0xFFFF;
- i->curr += symoff(i->curr, i->end-i->curr, i->addr+(a<<2), CANY);
- bprint(i, "(SB)");
- break;
- case 'J':
- a = i->imm;
- i->curr += symoff(i->curr, i->end-i->curr, a<<2, CANY);
- bprint(i, "(SB)");
- break;
- case 'w':
- bprint(i, "[%.8lux]", i->w0);
- break;
- case '\0':
- bprint(i, "%");
- return;
- default:
- bprint(i, "%%%c", *f);
- break;
- }
- }
- }
- /*
- * used by 9i
- */
- int
- _a29000disinst(ulong pc, ulong w, char *buf, int n)
- {
- Instr i;
- Opcode *o;
- i.curr = buf;
- i.end = buf+n-1;
- mkinstr(&i, pc, w);
- o = &opcodes[i.op];
- format(o->mnemonic, &i, o->fmt);
- *i.curr = '\0';
- return 4;
- }
- static int
- a29000inst(Map *map, ulong pc, char, char *buf, int n)
- {
- Instr i;
- Opcode *o;
- long w;
- if (get4(map, pc, &w) < 0) {
- werrstr("can't read instruction: %r");
- return -1;
- }
- i.curr = buf;
- i.end = buf+n-1;
- mkinstr(&i, pc, w);
- o = &opcodes[i.op];
- format(o->mnemonic, &i, o->fmt);
- return 4;
- }
- static int
- a29000das(Map *map, ulong pc, char *buf, int n)
- {
- Instr i;
- long w;
- if (get4(map, pc, &w) < 0) {
- werrstr("can't read instruction: %r");
- return -1;
- }
- i.curr = buf;
- i.end = buf+n;
- if (i.end-i.curr > 8)
- i.curr = _hexify(buf, w, 7);
- *i.curr = 0;
- return 4;
- }
- static int
- a29000instlen(Map*, ulong)
- {
- return 4;
- }
|