summaryrefslogtreecommitdiff
path: root/libinterp/das-thumb.c
diff options
context:
space:
mode:
Diffstat (limited to 'libinterp/das-thumb.c')
-rw-r--r--libinterp/das-thumb.c548
1 files changed, 0 insertions, 548 deletions
diff --git a/libinterp/das-thumb.c b/libinterp/das-thumb.c
deleted file mode 100644
index 2609bbe5..00000000
--- a/libinterp/das-thumb.c
+++ /dev/null
@@ -1,548 +0,0 @@
-#include <lib9.h>
-
-typedef struct Instr Instr;
-struct Instr
-{
- ulong w;
- ulong addr;
- uchar op; /* super opcode */
-
- uchar rd;
- uchar rn;
- uchar rs;
-
- long imm; /* imm */
- char* curr; /* fill point in buffer */
- char* end; /* end of buffer */
- char* err; /* error message */
-};
-
-typedef struct Opcode Opcode;
-struct Opcode
-{
- char* o;
- void (*f)(Opcode*, Instr*);
- int unused; /* remove field some time */
- char* a;
-};
-
-static void format(char*, Instr*, char*);
-static int thumbinst(ulong, char, char*, int);
-static int thumbdas(ulong, char*, int);
-
-static
-char* cond[16] =
-{
- "EQ", "NE", "CS", "CC",
- "MI", "PL", "VS", "VC",
- "HI", "LS", "GE", "LT",
- "GT", "LE", 0, "NV"
-};
-
-static int
-get4(ulong addr, long *v)
-{
- *v = *(ulong*)addr;
- return 1;
-}
-
-static int
-get2(ulong addr, ushort *v)
-{
- *v = *(ushort*)addr;
- return 1;
-}
-
-static char *
-_hexify(char *buf, ulong p, int zeros)
-{
- ulong d;
-
- d = p/16;
- if(d)
- buf = _hexify(buf, d, zeros-1);
- else
- while(zeros--)
- *buf++ = '0';
- *buf++ = "0123456789abcdef"[p&0x0f];
- return buf;
-}
-
-#define B(h, l) bits(ins, h, l)
-
-static int
-bits(int i, int h, int l)
-{
- if(h < l)
- print("h < l in bits");
- return (i&(((1<<(h-l+1))-1)<<l))>>l;
-}
-
-int
-thumbclass(long w)
-{
- int o;
- int ins = w;
-
- if(ins&0xffff0000)
- return 3+2+2+4+16+4+1+8+6+2+2+2+4+1+1+1+2;
- o = B(15, 13);
- switch(o){
- case 0:
- o = B(12, 11);
- switch(o){
- case 0:
- case 1:
- case 2:
- return B(12, 11);
- case 3:
- if(B(10, 10) == 0)
- return 3+B(9, 9);
- else
- return 3+2+B(9, 9);
- }
- case 1:
- return 3+2+2+B(12, 11);
- case 2:
- o = B(12, 10);
- if(o == 0)
- return 3+2+2+4+B(9, 6);
- if(o == 1){
- o = B(9, 8);
- if(o == 3)
- return 3+2+2+4+16+B(9, 8);
- return 3+2+2+4+16+B(9, 8);
- }
- if(o == 2 || o == 3)
- return 3+2+2+4+16+4;
- return 3+2+2+4+16+4+1+B(11, 9);
- case 3:
- return 3+2+2+4+16+4+1+8+B(12, 11);
- case 4:
- if(B(12, 12) == 0)
- return 3+2+2+4+16+4+1+8+4+B(11, 11);
- return 3+2+2+4+16+4+1+8+6+B(11, 11);
- case 5:
- if(B(12, 12) == 0)
- return 3+2+2+4+16+4+1+8+6+2+B(11, 11);
- if(B(11, 8) == 0)
- return 3+2+2+4+16+4+1+8+6+2+2+B(7, 7);
- return 3+2+2+4+16+4+1+8+6+2+2+2+B(11, 11);
- case 6:
- if(B(12, 12) == 0)
- return 3+2+2+4+16+4+1+8+6+2+2+2+2+B(11, 11);
- if(B(11, 8) == 0xf)
- return 3+2+2+4+16+4+1+8+6+2+2+2+4;
- return 3+2+2+4+16+4+1+8+6+2+2+2+4+1;
- case 7:
- o = B(12, 11);
- switch(o){
- case 0:
- return 3+2+2+4+16+4+1+8+6+2+2+2+4+1+1;
- case 1:
- return 3+2+2+4+16+4+1+8+6+2+2+2+4+1+1+1+2;
- case 2:
- return 3+2+2+4+16+4+1+8+6+2+2+2+4+1+1+1;
- case 3:
- return 3+2+2+4+16+4+1+8+6+2+2+2+4+1+1+1+1;
- }
- }
-}
-
-static int
-decode(ulong pc, Instr *i)
-{
- ushort w;
-
- get2(pc, &w);
- i->w = w;
- i->addr = pc;
- i->op = thumbclass(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
-thumbshift(Opcode *o, Instr *i)
-{
- int ins = i->w;
-
- i->rd = B(2, 0);
- i->rn = B(5, 3);
- i->imm = B(10, 6);
- format(o->o, i, o->a);
-}
-
-static void
-thumbrrr(Opcode *o, Instr *i)
-{
- int ins = i->w;
-
- i->rd = B(2, 0);
- i->rn = B(5, 3);
- i->rs = B(8, 6);
- format(o->o, i, o->a);
-}
-
-static void
-thumbirr(Opcode *o, Instr *i)
-{
- int ins = i->w;
-
- i->rd = B(2, 0);
- i->rn = B(5, 3);
- i->imm = B(8, 6);
- format(o->o, i, o->a);
-}
-
-static void
-thumbir(Opcode *o, Instr *i)
-{
- int ins = i->w;
-
- i->rd = B(10, 8);
- i->imm = B(7, 0);
- format(o->o, i, o->a);
-}
-
-static void
-thumbrr(Opcode *o, Instr *i)
-{
- int ins = i->w;
-
- i->rd = B(2, 0);
- i->rn = B(5, 3);
- format(o->o, i, o->a);
-}
-
-static void
-thumbrrh(Opcode *o, Instr *i)
-{
- int ins = i->w;
-
- i->rd = B(2, 0);
- i->rn = B(5, 3);
- if(B(6, 6))
- i->rn += 8;
- if(B(7, 7))
- i->rd += 8;
- if(o != nil){
- if(i->w == 0x46b7 || i->w == 0x46f7 || i->w == 0x4730 || i->w == 0x4770) // mov r6, pc or mov lr, pc or bx r6 or bx lr
- format("RET", i, "");
- else
- format(o->o, i, o->a);
- }
-}
-
-static void
-thumbpcrel(Opcode *o, Instr *i)
-{
- int ins = i->w;
-
- i->rn = 15;
- i->rd = B(10, 8);
- i->imm = 4*(B(7, 0)+1);
- if(i->addr & 3)
- i->imm -= 2;
- format(o->o, i, o->a);
-}
-
-static void
-thumbmovirr(Opcode *o, Instr *i)
-{
- int ins = i->w;
-
- i->rd = B(2, 0);
- i->rn = B(5, 3);
- i->imm = B(10, 6);
- if(strcmp(o->o, "MOVW") == 0)
- i->imm *= 4;
- else if(strncmp(o->o, "MOVH", 4) == 0)
- i->imm *= 2;
- format(o->o, i, o->a);
-}
-
-static void
-thumbmovsp(Opcode *o, Instr *i)
-{
- int ins = i->w;
-
- i->rn = 13;
- i->rd = B(10, 8);
- i->imm = 4*B(7, 0);
- format(o->o, i, o->a);
-}
-
-static void
-thumbaddsppc(Opcode *o, Instr *i)
-{
- int ins = i->w;
-
- i->rd = B(10, 8);
- i->imm = 4*B(7, 0);
- if(i->op == 48)
- i->imm += 4;
- format(o->o, i, o->a);
-}
-
-static void
-thumbaddsp(Opcode *o, Instr *i)
-{
- int ins = i->w;
-
- i->imm = 4*B(6, 0);
- format(o->o, i, o->a);
-}
-
-static void
-thumbswi(Opcode *o, Instr *i)
-{
- int ins = i->w;
-
- i->imm = B(7, 0);
- format(o->o, i, o->a);
-}
-
-static void
-thumbbcc(Opcode *o, Instr *i)
-{
- int off, ins = i->w;
-
- off = B(7, 0);
- if(off & 0x80)
- off |= 0xffffff00;
- i->imm = i->addr + 2*off + 4;
- if(o != nil)
- format(o->o, i, o->a);
-}
-
-static void
-thumbb(Opcode *o, Instr *i)
-{
- int off, ins = i->w;
-
- off = B(10, 0);
- if(off & 0x400)
- off |= 0xfffff800;
- i->imm = i->addr + 2*off + 4;
- if(o != nil)
- format(o->o, i, o->a);
-}
-
-static void
-thumbbl(Opcode *o, Instr *i)
-{
- int off, h, ins = i->w;
- static int reglink;
-
- h = B(11, 11);
- off = B(10, 0);
- if(h == 0){
- if(off & 0x400)
- off |= 0xfffff800;
- i->imm = i->addr + (off<<12) + 4;
- reglink = i->imm;
- }
- else{
- i->imm = reglink + 2*off;
- }
- if(o != nil)
- format(o->o, i, o->a);
-}
-
-static void
-thumbregs(Opcode *o, Instr *i)
-{
- int ins = i->w;
-
- if(i->op == 52 || i->op == 53)
- i->rd = 13;
- else
- i->rd = B(10, 8);
- i->imm = B(7, 0);
- format(o->o, i, o->a);
-}
-
-static void
-thumbunk(Opcode *o, Instr *i)
-{
- format(o->o, i, o->a);
-}
-
-static Opcode opcodes[] =
-{
- "LSL", thumbshift, 0, "$#%i,R%n,R%d", // 0
- "LSR", thumbshift, 0, "$#%i,R%n,R%d", // 1
- "ASR", thumbshift, 0, "$#%i,R%n,R%d", // 2
- "ADD", thumbrrr, 0, "R%s,R%n,R%d", // 3
- "SUB", thumbrrr, 0, "R%s,R%n,R%d", // 4
- "ADD", thumbirr, 0, "$#%i,R%n,R%d", // 5
- "SUB", thumbirr, 0, "$#%i,R%n,R%d", // 6
- "MOVW", thumbir, 0, "$#%i,R%d", // 7
- "CMP", thumbir, 0, "$#%i,R%d", // 8
- "ADD", thumbir, 0, "$#%i,R%d,R%d", // 9
- "SUB", thumbir, 0, "$#%i,R%d,R%d", // 10
- "AND", thumbrr, 0, "R%n,R%d,R%d", // 11
- "EOR", thumbrr, 0, "R%n,R%d,R%d", // 12
- "LSL", thumbrr, 0, "R%n,R%d,R%d", // 13
- "LSR", thumbrr, 0, "R%n,R%d,R%d", // 14
- "ASR", thumbrr, 0, "R%n,R%d,R%d", // 15
- "ADC", thumbrr, 0, "R%n,R%d,R%d", // 16
- "SBC", thumbrr, 0, "R%n,R%d,R%d", // 17
- "ROR", thumbrr, 0, "R%n,R%d,R%d", // 18
- "TST", thumbrr, 0, "R%n,R%d", // 19
- "NEG", thumbrr, 0, "R%n,R%d", // 20
- "CMP", thumbrr, 0, "R%n,R%d", // 21
- "CMPN", thumbrr, 0, "R%n,R%d", // 22
- "OR", thumbrr, 0, "R%n,R%d,R%d", // 23
- "MUL", thumbrr, 0, "R%n,R%d,R%d", // 24
- "BITC", thumbrr, 0, "R%n,R%d,R%d", // 25
- "MOVN", thumbrr, 0, "R%n,R%d", // 26
- "ADD", thumbrrh, 0, "R%n,R%d,R%d", // 27
- "CMP", thumbrrh, 0, "R%n,R%d", // 28
- "MOVW", thumbrrh, 0, "R%n,R%d", // 29
- "BX", thumbrrh, 0, "R%n", // 30
- "MOVW", thumbpcrel, 0, "%i(PC),R%d", // 31
- "MOVW", thumbrrr, 0, "R%d, [R%s,R%n]", // 32
- "MOVH", thumbrrr, 0, "R%d, [R%s,R%n]", // 33
- "MOVB", thumbrrr, 0, "R%d, [R%s,R%n]", // 34
- "MOVB", thumbrrr, 0, "[R%s,R%n],R%d", // 35
- "MOVW", thumbrrr, 0, "[R%s,R%n],R%d", // 36
- "MOVHU", thumbrrr, 0, "[R%s,R%n],R%d", // 37
- "MOVBU", thumbrrr, 0, "[R%s,R%n],R%d", // 38
- "MOVH", thumbrrr, 0, "[R%s,R%n],R%d", // 39
- "MOVW", thumbmovirr, 0, "R%d,%i(R%n)", // 40
- "MOVW", thumbmovirr, 0, "%i(R%n),R%d", // 41
- "MOVB", thumbmovirr, 0, "R%d,%i(R%n)", // 42
- "MOVBU", thumbmovirr, 0, "%i(R%n),R%d", // 43
- "MOVH", thumbmovirr, 0, "R%d,%i(R%n)", // 44
- "MOVHU", thumbmovirr, 0, "%i(R%n),R%d", // 45
- "MOVW", thumbmovsp, 0, "R%d,%i(SP)", // 46
- "MOVW", thumbmovsp, 0, "%i(SP),R%d", // 47
- "ADD", thumbaddsppc,0, "$#%i,PC,R%d", // 48
- "ADD", thumbaddsppc,0, "$#%i,SP,R%d", // 49
- "ADD", thumbaddsp, 0, "$#%i,SP,SP", // 50
- "SUB", thumbaddsp, 0, "$#%i,SP,SP", // 51
- "PUSH", thumbregs, 0, "R%d, %r", // 52
- "POP", thumbregs, 0, "R%d, %r", // 53
- "STMIA", thumbregs, 0, "R%d, %r", // 54
- "LDMIA", thumbregs, 0, "R%d, %r", // 55
- "SWI", thumbswi, 0, "$#%i", // 56
- "B%c", thumbbcc, 0, "%b", // 57
- "B", thumbb, 0, "%b", // 58
- "BL", thumbbl, 0, "", // 59
- "BL", thumbbl, 0, "%b", // 60
- "UNK", thumbunk, 0, "", // 61
-};
-
-static void
-format(char *mnemonic, Instr *i, char *f)
-{
- int j, k, m, n;
- int ins = i->w;
-
- 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 'c': /* Bcc */
- bprint(i, "%s", cond[B(11, 8)]);
- break;
-
- case 's':
- bprint(i, "%d", i->rs);
- break;
-
- case 'n':
- bprint(i, "%d", i->rn);
- break;
-
- case 'd':
- bprint(i, "%d", i->rd);
- break;
-
- case 'i':
- bprint(i, "%lux", i->imm);
- break;
-
- case 'b':
- bprint(i, "%lux", i->imm);
- break;
-
- case 'r':
- n = i->imm&0xff;
- j = 0;
- k = 0;
- while(n) {
- m = j;
- while(n&0x1) {
- j++;
- n >>= 1;
- }
- if(j != m) {
- if(k)
- bprint(i, ",");
- if(j == m+1)
- bprint(i, "R%d", m);
- else
- bprint(i, "R%d-R%d", m, j-1);
- k = 1;
- }
- j++;
- n >>= 1;
- }
- break;
-
- case '\0':
- *i->curr++ = '%';
- return;
-
- default:
- bprint(i, "%%%c", *f);
- break;
- }
- }
- *i->curr = 0;
-}
-
-void
-das(ulong *x, int n)
-{
- ulong pc;
- Instr i;
- char buf[128];
-
- pc = (ulong)x;
- while(n > 0) {
- i.curr = buf;
- i.end = buf+sizeof(buf)-1;
-
- if(decode(pc, &i) < 0)
- sprint(buf, "???");
- else
- (*opcodes[i.op].f)(&opcodes[i.op], &i);
-
- print("%.8lux %.8lux\t%s\n", pc, i.w, buf);
- pc += 2;
- n--;
- }
-}