diff options
| author | Charles Forsyth <charles.forsyth@gmail.com> | 2013-06-04 08:30:40 +0000 |
|---|---|---|
| committer | Charles Forsyth <charles.forsyth@gmail.com> | 2013-06-04 08:30:40 +0000 |
| commit | a7053ac4b096681d5ae89a863c1b81811e7716a4 (patch) | |
| tree | 3d680d53183d786d857e9419916c0587657c292c | |
| parent | 4a4256626644b5e413cfb1c228d396d27364030b (diff) | |
remove 68k, thumb
| -rw-r--r-- | libinterp/comp-68020.c | 2074 | ||||
| -rw-r--r-- | libinterp/comp-thumb.c | 2466 | ||||
| -rw-r--r-- | libinterp/das-68000.c | 1 | ||||
| -rw-r--r-- | libinterp/das-68020.c | 1940 | ||||
| -rw-r--r-- | libinterp/das-thumb.c | 548 | ||||
| -rw-r--r-- | libinterp/mkfile | 1 |
6 files changed, 0 insertions, 7030 deletions
diff --git a/libinterp/comp-68020.c b/libinterp/comp-68020.c deleted file mode 100644 index 0c5e9b7c..00000000 --- a/libinterp/comp-68020.c +++ /dev/null @@ -1,2074 +0,0 @@ -#include "lib9.h" -#include "isa.h" -#include "interp.h" -#include "raise.h" - -enum -{ - RAX = 0, - RCX = 1, /* Be careful with RCX, smashed in bra() */ - RTA = 2, - RTMP = 3, - RFP = 4, - RMP = 5, - R7 = 7, - - DTMP = 0, - DTMP1 = 1, - DTMP2 = 2, - DTMP3 = 3, - - Oadd = 0xD000, - OaddaR = 0xD1E8, /* ADDA (d16,Rr), Rr */ - Oaddi = 0x0600, - OaddRD = 0xD0A8, - OaslbD = 0xE120, - OaslwD = 0xE1A0, - OasrbD = 0xE020, - OasrwD = 0xE0A0, - Oand = 0xC000, - Oandi = 0x0200, - Obra = 0x6000, - Obsr = 0x6100, - OclrwD = 0x4280, - OcmpiwR = 0x0CA8, /* cmpi.l offset(Rrm), imm.long */ - OcmpwR = 0xB1E8, /* cmpa $offset(Rrm), Rr */ - OcmpbD = 0xB028, /* cmp.b $offset(Rrm), Dr */ - OcmpwD = 0xB0A8, /* cmp.l $offset(Rx), Dr */ - OcmpwDD = 0xB080, /* cmp.l Dr, Dx */ - Odbeq = 0x57C8, - OdecrwRind = 0x53A8, /* SUBQ.L $0x1, offset(Rr) */ - Odivs = 0x81C0, - Oeor = 0xB000, - Oeori = 0x0A00, - OexgRR = 0xC148, /* exg Rx, Ry */ - Oextw = 0x4880, /* EXT.W Dx extend byte to 16-bit */ - Oextbw = 0x49C0, /* EXTB.L Dx extend byte to 32-bit */ - OincrwR = 0x5288, /* ADDQ.L $0x1, Rr */ - OincrwRind = 0x52A8, /* ADDQ.L $0x1, offset(Rr) */ - Ojhi = 0x6200, /* BHI */ - Ojhs = 0x6400, /* BCC(HS) */ - Ojlo = 0x6500, /* BCS(LO) */ - Ojls = 0x6300, /* BLS */ - Ojeq = 0x6700, /* BEQ */ - Ojge = 0x6C00, /* BGE */ - Ojgt = 0x6E00, /* BGT */ - Ojle = 0x6F00, /* BLE */ - Ojlt = 0x6D00, /* BLT */ - Ojne = 0x6600, /* BNE */ - OjmpRind= 0x4ED0, /* jmp (Rn) */ - OjmpRindoffs= 0x4EE8, /* jmp $offs(Rn) */ - OjsrRind= 0x4E90, - OldbD = 0x1028, /* $offset(Rrm).b -> Dr */ - OldbR = 0x1058, /* $offset(Rrm).b -> Rr */ - OldwD = 0x2028, /* $offset(Rrm) -> Dr */ - OldwR = 0x2068, /* $offset(Rrm) -> Rr */ - OleaR = 0x41E8, /* addr($offset(Rrm) -> Rr */ - OlslD = 0xE388, - Olsl2D = 0xE588, - OlsrD = 0xE288, - OlslbD = 0xE128, - OlslwD = 0xE1A8, - OlsrbD = 0xE028, - OlsrwD = 0xE0A8, - OmovelitwR= 0x207C, /* move $xx, Rr */ - OmovelitwD= 0x203C, /* move $xx, Dr */ - Omoveal = 0x2040, - OmovwR = 0x217C, /* imm.long -> $offset(Rrm) */ - OmovwRR = 0x2048, /* movea.l Rr, Rx */ - OmovwRD = 0x2008, /* move.l Rr, Dx */ - Omuls = 0xC1C0, - OnegwD = 0x4480, - Oor = 0x8000, - Oori = 0x0000, - OpopwR = 0x205F, /* MOVEA.L (A7)+, Rr */ - OpushwR = 0x2F08, /* MOVE.L Rr, -(A7) */ - Opushil = 0x2F3C, /* MOVE.L imm., -(A7) */ - OroxlD = 0xE390, - OroxrD = 0xE290, - Orts = 0x4E75, - OstbD = 0x1140, /* Dr.b -> $offset(Rrm) !!!!! ostbR does NOT exist */ - OstwD = 0x2140, /* Dr -> $offset(Rrm) */ - OstwR = 0x2148, /* Rr -> $offset(Rrm) */ - Osub = 0x9000, - Osubi = 0x0400, - OaddqwR = 0x5088, - Oswap = 0x4840, - OtstbD = 0x4A00, /* tst.b Dr */ - OtstwR = 0x4AA8, /* tst.l $offset(Rx) */ - Oill = 0x4afc, /* illegal instruction trap */ - Onop = 0x4E71, - SRCOP = (1<<0), - DSTOP = (1<<1), - WRTPC = (1<<2), - TCHECK = (1<<3), - NEWPC = (1<<4), - DBRAN = (1<<5), - THREOP = (1<<6), - - ANDAND = 1, - OROR = 2, - EQAND = 3, - - MacFRP = 0, - MacRET = 1, - MacCASE = 2, - MacCOLR = 3, - MacMCAL = 4, - MacFRAM = 5, - MacMFRA = 6, - NMACRO -}; - -static uchar* code; -static uchar* base; -static ulong* patch; -static int pass; -static Module* mod; -static uchar* tinit; -static ulong* litpool; -static int nlit; -static void macfrp(void); -static void macret(void); -static void maccase(void); -static void maccolr(void); -static void macmcal(void); -static void macfram(void); -static void macmfra(void); -static ulong macro[NMACRO]; - void (*comvec)(void); -extern void das(uchar*, int); - -extern void _mull(void); -extern void _divsl(void); - -#define T(r) *((void**)(R.r)) - -struct -{ - int idx; - void (*gen)(void); -} mactab[] = -{ - MacFRP, macfrp, /* decrement and free pointer */ - MacRET, macret, /* return instruction */ - MacCASE, maccase, /* case instruction */ - MacCOLR, maccolr, /* increment and color pointer */ - MacMCAL, macmcal, /* mcall bottom half */ - MacFRAM, macfram, /* frame instruction */ - MacMFRA, macmfra, /* punt mframe because t->initialize==0 */ -}; - -static void -rdestroy(void) -{ - destroy(R.s); -} - -static void -rmcall(void) -{ - Prog *p; - Frame *f; - - f = (Frame*)R.FP; - if(f == H) - error(exModule); - - f->mr = nil; - ((void(*)(Frame*))R.dt)(f); - R.SP = (uchar*)f; - R.FP = f->fp; - if(f->t == nil) - unextend(f); - else - freeptrs(f, f->t); - p = currun(); - if(p->kill != nil) - error(p->kill); -} - -static void -rmfram(void) -{ - Type *t; - Frame *f; - uchar *nsp; - - t = (Type*)R.s; - nsp = R.SP + t->size; - if(nsp >= R.TS) { - R.s = t; - extend(); - T(d) = R.s; - return; - } - f = (Frame*)R.SP; - R.SP = nsp; - f->t = t; - f->mr = nil; - initmem(t, f); - T(d) = f; -} - -static int -bc(int o) -{ - if(o < 127 && o > -128) - return 1; - return 0; -} - -static int -wc(int o) -{ - if(o < 65535 && o > -65536) - return 1; - return 0; -} - -static void -urk(void) -{ - error(exCompile); -} - -static void -gen2(uchar o1, uchar o2) -{ - code[0] = o1; - code[1] = o2; - code += 2; -} - -static void -genw(ulong o) -{ - code[0] = (o>>8)&0xFF; - code[1] = o&0xFF; - code += 2; -} - -static void -genl(ulong o) -{ - *(ulong*)code = o; - code += 4; -} - -static void -modrm(int inst, ulong disp, int rm, int r) -{ - switch (inst) { - case OstwD: - case OstwR: - case OstbD: - if (!disp) { - inst&=0xfe3f; - inst|=0x0080; - } - genw(inst | (rm<<9) | r); - if (disp) - genw(disp); - break; - case Oadd|0x28|(0x6<<6): - case Oadd|0x28|(0x4<<6): - case Osub|0x28|(0x6<<6): - case Osub|0x28|(0x4<<6): - case Oor|0x28|(0x6<<6): - case Oor|0x28|(0x4<<6): - case Oand|0x28|(0x6<<6): - case Oand|0x28|(0x4<<6): - case Oeor|0x28|(0x6<<6): - case Oeor|0x28|(0x4<<6): - case Oaddi|0x28|(0x2<<6): - case Oori|0x28|(0x2<<6): - case Oandi|0x28|(0x2<<6): - case Oeori|0x28|(0x2<<6): - case Osubi|0x28|(0x2<<6): - case Oaddi|0x28: - case Oori|0x28: - case Oandi|0x28: - case Oeori|0x28: - case Osubi|0x28: - case OldbD: - case OldwD: - case OldwR: - case OldbR: - case OleaR: - case OaddRD: - case OcmpwR: - case OcmpwD: - case OcmpbD: - case OdecrwRind: - case OincrwRind: - case OtstwR: - if (!disp) { - inst&=0xffc7; - inst|=0x0010; - } - genw(inst | (r<<9) | rm); - if (disp) - genw(disp); - break; - default: - print("modrm: urk on opcode 0x%ux\n",inst); - urk(); - } -} - -static void -conR(ulong o, int r) -{ - if(o == 0) { - genw(0x91C8|(r<<9)|r); /* SUBA Rr, Rr */ - return; - } - genw(Omoveal|(r<<9)|0x7C); /* MOVEA.L $o,Rr */ - genl(o); -} - -static void -conD(ulong o, int r) -{ - if(o == 0) { - genw(OclrwD|r); /* CLR.L Dr */ - return; - } - genw(OmovelitwD|(r<<9)); /* MOVEA.L $o,Dr */ - genl(o); -} - -static void -opwld(Inst *i, int mi, int r) -{ - int ir, rta; - switch(UXSRC(i->add)) { - default: - print("%D\n", i); - urk(); - case SRC(AFP): - modrm(mi, i->s.ind, RFP, r); - return; - case SRC(AMP): - modrm(mi, i->s.ind, RMP, r); - return; - case SRC(AIMM): - conR(i->s.imm, r); - return; - case SRC(AIND|AFP): - ir = RFP; - break; - case SRC(AIND|AMP): - ir = RMP; - break; - } - rta = RTA; - if(mi == OleaR) - rta = r; - modrm(OldwR, i->s.i.f, ir, rta); - modrm(mi, i->s.i.s, rta, r); -} - -static void -opwldD(Inst *i, int mi, int r) -{ - int ir, rta; - switch(UXSRC(i->add)) { - default: - print("%D\n", i); - urk(); - case SRC(AFP): - modrm(mi, i->s.ind, RFP, r); - return; - case SRC(AMP): - modrm(mi, i->s.ind, RMP, r); - return; - case SRC(AIMM): - conD(i->s.imm, r); - return; - case SRC(AIND|AFP): - ir = RFP; - break; - case SRC(AIND|AMP): - ir = RMP; - break; - } - rta = RTA; - modrm(OldwR, i->s.i.f, ir, rta); - modrm(mi, i->s.i.s, rta, r); -} - -static int -opwst(Inst *i, int mi, int r) -{ - int ir, rta; - - switch(UXDST(i->add)) { - default: - print("%D\n", i); - urk(); - case DST(AIMM): - conR(i->d.imm, r); - return 0; - case DST(AFP): - modrm(mi, i->d.ind, RFP, r); - return i->d.ind; - case DST(AMP): - modrm(mi, i->d.ind, RMP, r); - return i->d.ind; - case DST(AIND|AFP): - ir = RFP; - break; - case DST(AIND|AMP): - ir = RMP; - break; - } - rta = RTA; - if(mi == OleaR) - rta = r; - modrm(OldwR, i->d.i.f, ir, rta); - modrm(mi, i->d.i.s, rta, r); - return i->d.i.s; -} - -static void -opwstD(Inst *i, int mi, int r) -{ - int ir, rta; - - switch(UXDST(i->add)) { - default: - print("%D\n", i); - urk(); - case DST(AIMM): - conD(i->d.imm, r); - return; - case DST(AFP): - modrm(mi, i->d.ind, RFP, r); - return; - case DST(AMP): - modrm(mi, i->d.ind, RMP, r); - return; - case DST(AIND|AFP): - ir = RFP; - break; - case DST(AIND|AMP): - ir = RMP; - break; - } - rta = RTA; - if(mi == OleaR) - rta = r; - modrm(OldwR, i->d.i.f, ir, rta); - modrm(mi, i->d.i.s, rta, r); -} - -static int -swapbraop(int b) -{ - switch(b) { - case Ojge: - return Ojlt; - case Ojle: - return Ojgt; - case Ojgt: - return Ojle; - case Ojlt: - return Ojge; - case Ojhi: - return Ojls; - case Ojlo: - return Ojhs; - case Ojhs: - return Ojlo; - case Ojls: - return Ojhi; - case Ojeq: - return Ojne; - case Ojne: - return Ojeq; - } - return b; -} - -static void -bra(ulong dst, int op) -{ - ulong ddst; - switch (op) { - case Obsr: - genw(OmovelitwR|(RCX<<9)); - genl(dst); - genw(OjsrRind|RCX); - break; - case Obra: -dojmp: - ddst=dst-((ulong)code+2); - if (bc(ddst)) { - genw(Obra|(uchar)ddst); - genw(Onop); - genw(Onop); - genw(Onop); - } else if (wc(ddst)) { - genw(Obra); - genw(ddst); - genw(Onop); - genw(Onop); - } else { - genw(OmovelitwR|(RCX<<9)); - genl(dst); - genw(OjmpRind|RCX); - } - break; - case Ojhi: - case Ojhs: - case Ojlo: - case Ojls: - case Ojeq: - case Ojge: - case Ojgt: - case Ojle: - case Ojlt: - case Ojne: - genw(swapbraop(op)|0x8); - goto dojmp; - default: - print("bra: urk op opcode 0x%ux\n",op); - urk(); - break; - } -} - -static void -rbra(ulong dst, int op) -{ - dst += (ulong)base; - bra(dst,op); -} - -static void -literal(ulong imm, int roff) -{ - nlit++; - genw(OmovelitwR|(RAX<<9)); - genl((ulong)litpool); - modrm(OstwR, roff, RTMP, RAX); - - if(pass == 0) - return; - - *litpool = imm; - litpool++; -} - - -static void -punt(Inst *i, int m, void (*fn)(void)) -{ - ulong pc; - conR((ulong)&R, RTMP); - - if(m & SRCOP) { - if(UXSRC(i->add) == SRC(AIMM)) { - literal(i->s.imm, O(REG, s)); - } - else { - opwld(i, OleaR, RAX); - modrm(OstwR, O(REG, s), RTMP, RAX); - } - } - - if(m & DSTOP) { - if(UXDST(i->add) == DST(AIMM)) { - literal(i->d.imm, O(REG, d)); - } else { - opwst(i, OleaR, RAX); - modrm(OstwR, O(REG, d), RTMP, RAX); - } - } - if(m & WRTPC) { - genw(OmovwR|(RTMP<<9)); - pc = patch[i-mod->prog+1]; - genl((ulong)base + pc); - genw(O(REG, PC)); - } - if(m & DBRAN) { - pc = patch[(Inst*)i->d.imm-mod->prog]; - - literal((ulong)base+pc, O(REG, d)); - } - - switch(i->add&ARM) { - case AXNON: - if(m & THREOP) { - modrm(OldwR, O(REG, d), RTMP, RAX); - modrm(OstwR, O(REG, m), RTMP, RAX); - } - break; - case AXIMM: - literal((short)i->reg, O(REG, m)); - break; - case AXINF: - modrm(OleaR, i->reg, RFP, RAX); - modrm(OstwR, O(REG, m), RTMP, RAX); - break; - case AXINM: - modrm(OleaR, i->reg, RMP, RAX); - modrm(OstwR, O(REG, m), RTMP, RAX); - break; - } - modrm(OstwR, O(REG, FP), RTMP, RFP); - - bra((ulong)fn, Obsr); - - conR((ulong)&R, RTMP); - if(m & TCHECK) { - genw(Orts); - } - - modrm(OldwR, O(REG, FP), RTMP, RFP); - modrm(OldwR, O(REG, MP), RTMP, RMP); - - if(m & NEWPC) { - modrm(OldwR, O(REG, PC), RTMP, RAX); - genw(OjmpRind|RAX); - } -} - -static void -mid(Inst *i, int mi, int r) -{ - int ir; - switch(i->add&ARM) { - default: - opwst(i, mi, r); - return; - case AXIMM: - conR((short)i->reg, r); - return; - case AXINF: - ir = RFP; - break; - case AXINM: - ir = RMP; - break; - } - modrm(mi, i->reg, ir, r); -} - -static void -midD(Inst *i, int mi, int r) -{ - int ir; - switch(i->add&ARM) { - default: - opwstD(i, mi, r); - return; - case AXIMM: - conD((short)i->reg, r); - return; - case AXINF: - ir = RFP; - break; - case AXINM: - ir = RMP; - break; - } - modrm(mi, i->reg, ir, r); -} - -static void -arithimms(Inst *i, int opcode, int opmode) -{ - uchar off[3]; - int hasoff; - if(i->add&ARM) { - midD(i,(opmode)?OldwD:OldbD,DTMP); - if (((opcode==Oaddi)||(opcode==Osubi))&&(i->s.imm>0)&&(i->s.imm<=8)) - genw(0x5000|((opcode==Osubi)?0x100:0)|(((opmode)?0x2:0x0)<<6)|(((uchar)i->s.imm)<<9)|DTMP); - else { - genw(opcode|DTMP|(((opmode)?0x2:0)<<6)); - if (opmode) - genl(i->s.imm); - else - genw(i->s.imm); - } - opwstD(i, (opmode)?OstwD:OstbD, DTMP); - return; - } - if (hasoff=opwst(i, opcode|0x28|(((opmode)?0x2:0)<<6), 0)) { - code-=2; - off[0]=code[0]; off[1]=code[1]; - } - if (((opcode==Oaddi)||(opcode==Osubi))&&(i->s.imm>0)&&(i->s.imm<=8)) { - code-=2; - off[2]=code[1]; - genw(0x5000|((opcode==Osubi)?0x100:0)|(((opmode)?0x2:0x0)<<6)|(((uchar)i->s.imm)<<9)|((hasoff)?0x28:0x10)|(off[2]&0x7)); - } - else { - if (opmode) - genl(i->s.imm); - else - genw(i->s.imm); - } - if (hasoff) - gen2(off[0],off[1]); -} - -static void -arith(Inst *i, int opcode, int opmode) -{ - opwldD(i, (opmode)?OldwD:OldbD, DTMP1); - if(i->add&ARM) { - midD(i,(opmode)?OldwD:OldbD,DTMP); - genw(opcode|(DTMP<<9)|DTMP1|(((opmode)?0x2:0)<<6)); - opwstD(i, (opmode)?OstwD:OstbD, DTMP); - return; - } - opwst(i, opcode|0x28|(((opmode)?0x6:0x4)<<6), DTMP1); -} - -static void -oldarithsub(Inst *i, int opmode) -{ - opwldD(i, (opmode)?OldwD:OldbD, DTMP1); - if(i->add&ARM) - midD(i,(opmode)?OldwD:OldbD,DTMP); - else - opwstD(i, (opmode)?OldwD:OldbD, DTMP); - genw(Osub|(DTMP<<9)|DTMP1|(((opmode)?0x2:0)<<6)); - opwstD(i, (opmode)?OstwD:OstbD, DTMP); -} - -static void -shift(Inst *i, int ld, int st, int op) -{ - midD(i, ld, DTMP); - opwldD(i, OldwD, DTMP1); - genw(op|(DTMP1<<9)|DTMP); - opwstD(i, st, DTMP); -} - -static void -cmpl(int r, ulong v) -{ - genw(0xB1FC|(r<<9)); - genl(v); -} - -static int -swapforcbra(int jmp) { - switch(jmp) { - case Ojge: - return Ojle; - case Ojle: - return Ojge; - case Ojgt: - return Ojlt; - case Ojlt: - return Ojgt; - case Ojhi: - return Ojlo; - case Ojlo: - return Ojhi; - case Ojhs: - return Ojls; - case Ojls: - return Ojhs; - default: - return jmp; - } - -} -static void -cbra(Inst *i, int jmp) -{ - midD(i, OldwD, DTMP); - if (UXSRC(i->add)==SRC(AIMM)) { - genw(0xB0BC|DTMP); - genl(i->s.imm); - } - else - opwldD(i,OcmpwD,DTMP); - rbra(patch[i->d.ins-mod->prog], swapforcbra(jmp)); -} - -static void -cbral(Inst *i, int jmsw, int jlsw, int mode) -{ - ulong dst; - uchar *label; - opwld(i, OleaR, RTMP); - mid(i, OleaR, RTA); - modrm(OldwR, 4, RTMP, RAX); - modrm(OcmpwR, 4, RTA, RAX); - label = 0; - dst = patch[i->d.ins-mod->prog]; - switch(mode) { - case ANDAND: - genw(jmsw); - label = code-1; - break; - case OROR: - rbra(dst, jmsw); - break; - case EQAND: - rbra(dst, jmsw); - genw(Ojne); - label = code-1; - break; - } - modrm(OldwR, 0, RTMP, RAX); - modrm(OcmpwR, 0, RTA, RAX); - rbra(dst, jlsw); - if(label != nil) - *label = code-label-1; -} - -static void -cbrab(Inst *i, int jmp) -{ - if(UXSRC(i->add) == SRC(AIMM)) - urk(); - - midD(i, OldbD, DTMP); - opwldD(i,OcmpbD,DTMP); - rbra(patch[i->d.ins-mod->prog], swapforcbra(jmp)); -} - -static void -comcase(Inst *i, int w) -{ - int l; - WORD *t, *e; - - USED (w); - - t = (WORD*)(mod->origmp+i->d.ind+4); - l = t[-1]; - - /* have to take care not to relocate the same table twice - - * the limbo compiler can duplicate a case instruction - * during its folding phase - */ - - if(pass == 0) { - if(l >= 0) - t[-1] = -l-1; /* Mark it not done */ - return; - } - if(l >= 0) /* Check pass 2 done */ - return; - t[-1] = -l-1; /* Set real count */ - e = t + t[-1]*3; - while(t < e) { - t[2] = (ulong)base + patch[t[2]]; - t += 3; - } - t[0] = (ulong)base + patch[t[0]]; -} - -static void -comcasel(Inst *i) -{ - int l; - WORD *t, *e; - - t = (WORD*)(mod->origmp+i->d.ind+8); - l = t[-2]; - if(pass == 0) { - if(l >= 0) - t[-2] = -l-1; /* Mark it not done */ - return; - } - if(l >= 0) /* Check pass 2 done */ - return; - t[-2] = -l-1; /* Set real count */ - e = t + t[-2]*6; - while(t < e) { - t[4] = (ulong)base + patch[t[4]]; - t += 6; - } - t[0] = (ulong)base + patch[t[0]]; -} - -static void -commframe(Inst *i) -{ - int o; - uchar *punt, *mlnil; - - opwld(i, OldwR, RAX); - cmpl(RAX, (ulong)H); - genw(Ojeq); - mlnil = code - 1; - o = OA(Modlink, links)+i->reg*sizeof(Modl)+O(Modl, frame); - modrm(OldwR, o, RAX, RTA); - modrm(OtstwR,O(Type, initialize),RTA,0); - genw(Ojne); - punt = code - 1; - genw(OexgRR|RAX|(RTA<<9)); - opwst(i, OleaR, RTA); - *mlnil = code-mlnil-1; - rbra(macro[MacMFRA], Obsr); - rbra(patch[i-mod->prog+1], Obra); - - *punt = code-punt-1; - rbra(macro[MacFRAM], Obsr); - opwst(i, OstwR, RAX); -} - -static void -commcall(Inst *i) -{ - conR((ulong)&R, RTMP); // MOVL $R, RTMP - opwld(i, OldwR, RTA); - genw(OmovwR|(RTA<<9)); // MOVL $.+1, lr(RTA) f->lr = R.PC - genl((ulong)base+patch[i-mod->prog+1]); - genw(O(Frame, lr)); - modrm(OstwR, O(Frame, fp), RTA, RFP); // MOVL RFP, fp(RTA) f->fp = R.FP - modrm(OldwD, O(REG, M), RTMP, DTMP); // MOVL R.M, DTMP - modrm(OstwD, O(Frame, mr), RTA, DTMP); // MOVL RTA, mr(RTA) f->mr = R.M - opwst(i, OldwR, RAX); // MOVL ml, RAX - modrm(OldwD, O(Modlink, m), RAX, DTMP); // MOVL ml->m, DTMP - modrm(OldwR, OA(Modlink, links)+i->reg*sizeof(Modl)+O(Modl, u.pc), RAX, RAX); - rbra(macro[MacMCAL], Obsr); -} - -static void -laritha(Inst *i, int opc) -{ - if((i->add&ARM) != AXNON) { - mid(i, OleaR, RTMP); - opwst(i, OleaR, RTA); - genw(0x20D8|(RTA<<9)|RTMP); // MOVL (RTMP)+, (RTA)+ - genw(0x20D8|(RTA<<9)|RTMP); // MOVL (RTMP)+, (RTA)+ - } - else { - mid(i, OleaR, RTA); - genw(0x5088|RTA); // ADDQ.l #8, RTA - } - - opwld(i, OleaR, RTMP); - genw(0x5088|RTMP); // ADDQ.l #8, RTMP - - genw(0x44FC); // MOVE imm16, CCR - genw(0); - genw(opc|RTMP|(RTA<<9)); // ADDX (-RTMP), (-RTA) - genw(opc|RTMP|(RTA<<9)); // ADDX (-RTMP), (-RTA) -} - -static void -larith(Inst *i, int op) -{ - if((i->add&ARM) != AXNON) { - mid(i, OleaR, RTMP); - opwst(i, OleaR, RTA); - genw(0x20D8|RTMP|(RTA<<9)); // MOVL (RTMP)+, (RTA)+ - genw(0x2090|RTMP|(RTA<<9)); // MOVL (RTMP), (RTA) - genw(0x5988|RTA); // SUBQ.l #4, RTA - } - else - mid(i, OleaR, RTA); - - - opwld(i, OleaR, RTMP); - genw(0x2018|RTMP|(DTMP<<9)); // MOVL (RTMP+), DTMP - genw(op|RTA|(DTMP<<9)); // ORL DTMP, (RTA+) - genw(0x2010|(DTMP<<9)|RTMP); // MOVL (RTMP) DTMP - genw((op&0xFFF7)|RTA|(DTMP<<9)); // ORL DTMP, (RTA) -} - -static void -shll(Inst *i) -{ - uchar *label; - - opwldD(i, OldwD, DTMP); // The number of shifts -> DTMP - mid(i, OleaR, RTA); // LEA source, RTA - genw(0x2018|(DTMP1<<9)|RTA); // move (RTA+), DTMP1 - genw(0x2010|(DTMP2<<9)|RTA); // move (RTA), DTMP2 - - genw(Obra); - label=code-1; - - genw(OlslD|DTMP2); - genw(OroxlD|DTMP1); - *label=code-label-1; - genw(Odbeq); - genw(label-code+1); - - opwst(i, OleaR, RTA); - genw(0x2080|(RTA<<9)|DTMP2); // move DTMP2, (RTA) - genw(0x2100|(RTA<<9)|DTMP1); // move DTMP1, (-RTA) -} - -static void -shrl(Inst *i) -{ - uchar *label; - - opwldD(i, OldwD, DTMP); // The number of shifts -> DTMP - mid(i, OleaR, RTA); // LEA source, RTA - genw(0x2018|(DTMP1<<9)|RTA); // move (RTA+), DTMP1 - genw(0x2010|(DTMP2<<9)|RTA); // move (RTA), DTMP2 - - genw(Obra); - label=code-1; - - genw(OlsrD|DTMP2); - genw(OroxrD|DTMP1); - *label=code-label-1; - genw(Odbeq); - genw(label-code+1); - - opwst(i, OleaR, RTA); - genw(0x2080|(RTA<<9)|DTMP2); // move DTMP2, (RTA) - genw(0x2100|(RTA<<9)|DTMP1); // move DTMP1, (-RTA) -} - -static int myic; - -static -void -compdbg(void) -{ - print("%s:%lud@%.8lux\n", R.M->m->name, *(ulong*)R.m, *(ulong*)R.s); -} - -static void -comp(Inst *i) -{ - int r; - WORD *t, *e; - char buf[64]; - - if(0) { - Inst xx; - xx.add = AXIMM|SRC(AIMM); - xx.s.imm = (ulong)code; - xx.reg = i-mod->prog; - punt(&xx, SRCOP, compdbg); - } - - switch(i->op) { - default: - snprint(buf, sizeof buf, "%s compile, no '%D'", mod->name, i); - error(buf); - break; - case IMCALL: - if((i->add&ARM) == AXIMM) - commcall(i); - else - punt(i, SRCOP|DSTOP|THREOP|WRTPC|NEWPC, optab[i->op]); - break; - case ISEND: - case IRECV: - case IALT: - punt(i, SRCOP|DSTOP|TCHECK|WRTPC, optab[i->op]); - break; - case ISPAWN: - punt(i, SRCOP|DBRAN, optab[i->op]); - break; - case IBNEC: - case IBEQC: - case IBLTC: - case IBLEC: - case IBGTC: - case IBGEC: - punt(i, SRCOP|DBRAN|NEWPC|WRTPC, optab[i->op]); - break; - case ICASEC: - comcase(i, 0); - punt(i, SRCOP|DSTOP|NEWPC, optab[i->op]); - break; - case ICASEL: - comcasel(i); - punt(i, SRCOP|DSTOP|NEWPC, optab[i->op]); - break; - case IADDC: - case IMULL: - case IDIVL: - case IMODL: - case ILOAD: - case IMSPAWN: - case ISLICEA: - case ISLICELA: - case ISLICEC: - punt(i, SRCOP|DSTOP|THREOP, optab[i->op]); - break; - case INEWA: - case INEW: - case ICONSB: - case ICONSW: - case ICONSF: - case ICONSM: - case ICONSMP: - case ICONSP: - case IMOVMP: - case IHEADMP: - case IINSC: - case ICVTAC: - case ICVTCW: - case ICVTWC: - case ICVTLC: - case ICVTCL: - case ICVTFC: - case ICVTCF: - case ICVTCA: - case INBALT: - punt(i, SRCOP|DSTOP, optab[i->op]); - break; - case INEWCM: - case INEWCMP: - punt(i, SRCOP|DSTOP|THREOP, optab[i->op]); - break; - case IMFRAME: - if((i->add&ARM) == AXIMM) - commframe(i); - else - punt(i, SRCOP|DSTOP|THREOP, optab[i->op]); - break; - case INEWCB: - case INEWCW: - case INEWCF: - case INEWCP: - case INEWCL: - punt(i, DSTOP|THREOP, optab[i->op]); - break; - case IEXIT: - punt(i, 0, optab[i->op]); - break; - case ICVTBW: - genw(OclrwD| DTMP); - opwldD(i, OldbD, DTMP); - opwstD(i, OstwD, DTMP); - break; - case ICVTWB: - opwldD(i, OldwD, DTMP); - opwstD(i, OstbD, DTMP); - break; - case ICVTFW: - case ICVTWF: - case ICVTLF: - case ICVTFL: - punt(i, SRCOP|DSTOP, optab[i->op]); - break; - case IHEADM: - case IMOVM: - punt(i, SRCOP|DSTOP|THREOP, optab[i->op]); - break; - case IRET: - rbra(macro[MacRET], Obra); - break; - case IFRAME: - if(UXSRC(i->add) != SRC(AIMM)) { - punt(i, SRCOP|DSTOP, optab[i->op]); - break; - } - tinit[i->s.imm] = 1; - conR((ulong)mod->type[i->s.imm], RTA); - rbra(macro[MacFRAM], Obsr); - opwst(i, OstwR, RAX); - break; - case ILEA: - if(UXSRC(i->add) == SRC(AIMM)) { - genw(Obra|4); - genl(i->s.imm); - conR((ulong)(code-4), RAX); - } - else - opwld(i, OleaR, RAX); - opwst(i, OstwR, RAX); - break; - case IHEADW: - opwld(i, OldwR, RAX); - modrm(OldwR, OA(List, data), RAX, RAX); - opwst(i, OstwR, RAX); - break; - case IHEADF: - punt(i, SRCOP|DSTOP, optab[i->op]); - break; - case IHEADB: - opwld(i, OldwR, RAX); - modrm(OldbD, OA(List, data), RAX, DTMP); - opwstD(i, OstbD, DTMP); - break; - case ITAIL: - opwld(i, OldwR, RAX); - modrm(OldwR, O(List, tail), RAX, RTMP); - goto movp; - case IMOVP: - case IHEADP: - opwld(i, OldwR, RTMP); - if(i->op == IHEADP) - modrm(OldwR, OA(List, data), RTMP, RTMP); - movp: - {uchar *label; - cmpl(RTMP, (ulong)H); - genw(Ojeq); - label=code-1; - rbra(macro[MacCOLR], Obsr); - *label=code-label-1; - opwst(i, OldwR, RAX); - opwst(i, OstwR, RTMP); - rbra(macro[MacFRP], Obsr); - } - break; - case ILENA: - opwld(i, OldwR, RTMP); - conR(0, RAX); - cmpl(RTMP, (ulong)H); - genw(Ojeq|0x2); - modrm(OldwR, O(Array, len), RTMP, RAX); - opwst(i, OstwR, RAX); - break; - case ILENC: - {uchar *label; - opwld(i, OldwR, RTMP); - conD(0, DTMP); - cmpl(RTMP, (ulong)H); - genw(Ojeq); - label=code-1; - modrm(OldwD, O(String, len), RTMP, DTMP); - genw(0x4A80|RAX); // TSTL DTMP - genw(Ojge|0x02); - genw(OnegwD|DTMP); - *label=code-label-1; - opwstD(i, OstwD, DTMP); - } - break; - case ILENL: - {uchar *label,*l2; - conR(0, RAX); - opwld(i, OldwR, RTMP); - l2=code-1; - cmpl(RTMP, (ulong)H); - genw(Ojeq); - label=code-1; - modrm(OldwR, O(List, tail), RTMP, RTMP); - genw(OincrwR|RAX); - genw(Obra|(uchar)(l2-code-1)); - *label=code-label-1; - opwst(i, OstwR, RAX); - } - break; - case IBEQF: - case IBNEF: - case IBLEF: - case IBLTF: - case IBGEF: - case IBGTF: - punt(i, SRCOP|DBRAN|NEWPC|WRTPC, optab[i->op]); - break; - case IBEQW: - cbra(i, Ojeq); - break; - case IBLEW: - cbra(i, Ojle); - break; - case IBNEW: - cbra(i, Ojne); - break; - case IBGTW: - cbra(i, Ojgt); - break; - case IBLTW: - cbra(i, Ojlt); - break; - case IBGEW: - cbra(i, Ojge); - break; - case IBEQB: - cbrab(i, Ojeq); - break; - case IBLEB: - cbrab(i, Ojls); - break; - case IBNEB: - cbrab(i, Ojne); - break; - case IBGTB: - cbrab(i, Ojhi); - break; - case IBLTB: - cbrab(i, Ojlo); - break; - case IBGEB: - cbrab(i, Ojhs); - break; - case ISUBW: - if (UXSRC(i->add)==SRC(AIMM)) - arithimms(i,Osubi,1); - else - arith(i, Osub, 1); - break; - case ISUBB: - if (UXSRC(i->add)==SRC(AIMM)) - arithimms(i,Osubi,1); - else - arith(i, Osub, 0); - break; - case ISUBF: - punt(i, SRCOP|DSTOP|THREOP, optab[i->op]); - break; - case IADDW: - if (UXSRC(i->add)==SRC(AIMM)) - arithimms(i,Oaddi,1); - else - arith(i, Oadd, 1); - break; - case IADDB: - if (UXSRC(i->add)==SRC(AIMM)) - arithimms(i,Oaddi,0); - else - arith(i, Oadd, 0); - break; - case IADDF: - punt(i, SRCOP|DSTOP|THREOP, optab[i->op]); - break; - case IORW: - if (UXSRC(i->add)==SRC(AIMM)) - arithimms(i,Oori,1); - else - arith(i, Oor, 1); - break; - case IORB: - if (UXSRC(i->add)==SRC(AIMM)) - arithimms(i,Oori,0); - else - arith(i, Oor, 0); - break; - case IANDW: - arith(i, Oand, 1); - break; - case IANDB: - arith(i, Oand, 0); - break; - case IXORW: - if (UXSRC(i->add)==SRC(AIMM)) - arithimms(i,Oeori,1); - else - arith(i, Oeor, 1); - break; - case IXORB: - if (UXSRC(i->add)==SRC(AIMM)) - arithimms(i,Oeori,0); - else - arith(i, Oeor, 0); - break; - case ISHLW: - shift(i, OldwD, OstwD, OaslwD); - break; - case ISHLB: - shift(i, OldbD, OstbD, OaslbD); - break; - case ISHRW: - shift(i, OldwD, OstwD, OasrwD); - break; - case ISHRB: - shift(i, OldbD, OstbD, OasrbD); - break; - case IMOVF: - case INEGF: - punt(i, SRCOP|DSTOP, optab[i->op]); - break; - case IMOVB: - opwldD(i, OldbD, DTMP); - opwstD(i, OstbD, DTMP); - break; - case IMOVW: - opwldD(i, OldwD, DTMP); - opwstD(i, OstwD, DTMP); - break; - case ICVTLW: - case ICVTWL: - punt(i, SRCOP|DSTOP, optab[i->op]); - break; - case ICALL: - opwld(i, OldwR, RAX); - genw(OmovwR|(RAX<<9)); // MOVL $.+1, lr(AX) - genl((ulong)base+patch[i-mod->prog+1]); - genw(O(Frame, lr)); - modrm(OstwR, O(Frame, fp), RAX, RFP); // MOVL RFP, fp(AX) - genw(OmovwRR|(RFP<<9)|RAX); // MOVL AX,RFP - /* no break */ - case IJMP: - rbra(patch[i->d.ins-mod->prog], Obra); - break; - case IGOTO: - opwst(i, OleaR, RTMP); - opwldD(i, OldwD, DTMP); - genw(OlslwD|DTMP); - genw(Oadd|(RTMP<<9)|(7<<6)|DTMP); - genw(OjmpRind|RTMP); - - if(pass == 0) - break; - - t = (WORD*)(mod->origmp+i->d.ind); - e = t + t[-1]; - t[-1] = 0; - while(t < e) { - t[0] = (ulong)base + patch[t[0]]; - t++; - } - break; - case IMULF: - case IDIVF: - punt(i, SRCOP|DSTOP|THREOP, optab[i->op]); - break; - case IMODW: - case IDIVW: - case IMULW: - opwld(i, OldwR, RAX); - genw(OpushwR|RAX); - mid(i, OldwR, RAX); - genw(OpushwR|RAX); - switch(i->op) { - case IMULW: - bra((ulong)_mull,Obsr); - genw(OaddqwR|(4<<9)|R7); - genw(OpopwR|(RAX<<9)); - break; - case IMODW: - bra((ulong)_divsl,Obsr); - genw(OaddqwR|(4<<9)|R7); - genw(OpopwR|(RAX<<9)); - break; - case IDIVW: - bra((ulong)_divsl,Obsr); - genw(OpopwR|(RAX<<9)); - genw(OaddqwR|(4<<9)|R7); - break; - } - opwst(i, OstwR, RAX); - break; - case IMODB: - case IDIVB: - case IMULB: - midD(i, OldbD, DTMP); - genw(Oextw|DTMP); - opwldD(i, OldbD, DTMP2); - if (i->op == IMULB) - if(i->op == IMULB) { - genw(Oextw|DTMP2); - genw(Omuls|(DTMP<<9)|DTMP2); - } - else { - genw(Oextbw|DTMP2); - genw(Odivs|(DTMP<<9)|DTMP2); - } - if (i->op == IMODB) - genw(Oswap|DTMP); - opwstD(i, OstbD, DTMP); - break; - case IINDX: - opwld(i, OldwR, RTMP); // MOVW xx(s), RTMP - modrm(OldwR, O(Array, t), RTMP, RAX); // MOVW t(RTMP), AX - modrm(OldwD, O(Type, size), RAX, DTMP1); // MOVW size(AX), DTMP1 - opwstD(i, OldwD, DTMP2); // MOVW indx, DTMP2 - genl(0x70204283); // loop to MULW DTMP1, DTMP2, DTMP3 - genl(0xe2996402); - genl(0xd682e38a); - genl(0x57c8fff6); - - modrm(OldwR, O(Array, data), RTMP, RTMP); - genw(Oadd|(DTMP3<<9)|0x0088|RTMP); // ADDL data(RTMP), DTMP3 - r = RMP; - if((i->add&ARM) == AXINF) - r = RFP; - modrm(OstwD, i->reg, r, DTMP3); - break; - case IINDB: - r = 0; - goto idx; - case IINDF: - punt(i, SRCOP|THREOP|DSTOP, optab[i->op]); - break; - case IINDL: - r = 3; - goto idx; - case IINDW: - r = 2; - idx: - opwld(i, OldwR, RAX); - opwstD(i, OldwD, DTMP); - modrm(OldwR, O(Array, data), RAX, RTMP); - - if (r) - genw(0xE188|(r<<9)|DTMP); - genw(Oadd|(RTMP<<9)|(7<<6)|DTMP); /* lea (AX)(DTMP*r) */ - - r = RMP; - if((i->add&ARM) == AXINF) - r = RFP; - modrm(OstwR, i->reg, r, RTMP); - break; - case IINDC: - { uchar *label; - opwld(i, OldwR, RAX); // string - midD(i, OldwD, DTMP); // index - modrm(OtstwR,O(String, len),RAX,0); - modrm(OleaR, O(String, data), RAX, RAX); - genw(Ojge); // Ascii only, jump - label=code-1; - - genw(OnegwD|DTMP); - genw(Olsl2D|DTMP); // << 2; index is times 4 bytes - genw(Oadd|(RAX<<9)|0x01C0|DTMP); - modrm(OldwD, 0, RAX, DTMP); - genw(Obra|0x4); - *label=code-label-1; - genw(Oadd|(RAX<<9)|0x01C0|DTMP); - modrm(OldbD, 0, RAX, DTMP); - - opwst(i, OstwD, DTMP); - } - break; - case ICASE: - comcase(i, 1); - punt(i, SRCOP|DSTOP|NEWPC, optab[i->op]); - break; - case IMOVL: - opwld(i, OleaR, RTA); - opwst(i, OleaR, RTMP); - genw(0x20D8|(RTMP<<9)|RTA); // MOVE.l (RTA+), (RTMP+) - genw(0x2090|(RTMP<<9)|RTA); // MOVE.l (RTA), (RTMP) - break; - case IADDL: - laritha(i, 0xD188); // ADDX.l (-R0), (-R0) - break; - case ISUBL: - laritha(i, 0x9188); // SUBX.l (-R0), (-R0) - break; - case IORL: - larith(i, 0x8198); // OR.l D0, (R0+) - break; - case IANDL: - larith(i, 0xC198); // AND.l D0, (R0+) - break; - case IXORL: - larith(i, 0xB198); // EOR.l D0, (R0+) - break; - case IBEQL: - cbral(i, Ojne, Ojeq, ANDAND); - break; - case IBNEL: - cbral(i, Ojne, Ojne, OROR); - break; - case IBLEL: - cbral(i, Ojlt, Ojls, EQAND); - break; - case IBGTL: - cbral(i, Ojgt, Ojhi, EQAND); - break; - case IBLTL: - cbral(i, Ojlt, Ojlo, EQAND); - break; - case IBGEL: - cbral(i, Ojgt, Ojhs, EQAND); - break; - case ISHLL: - shll(i); - break; - case ISHRL: - shrl(i); - break; - case IRAISE: - punt(i, SRCOP|WRTPC|NEWPC, optab[i->op]); - break; - case IMULX: - case IDIVX: - case ICVTXX: - case IMULX0: - case IDIVX0: - case ICVTXX0: - case IMULX1: - case IDIVX1: - case ICVTXX1: - case ICVTFX: - case ICVTXF: - case IEXPW: - case IEXPL: - case IEXPF: - punt(i, SRCOP|DSTOP|THREOP, optab[i->op]); - break; - case ISELF: - punt(i, DSTOP, optab[i->op]); - break; - } -} - -static void -preamble(void) -{ - uchar *s; - if(comvec) - return; - - comvec = malloc(32); - if(comvec == nil) - error(exNomem); - code = (uchar*)comvec; - s = code; - - conR((ulong)&R, RAX); - modrm(OldwR, O(REG, FP), RAX, RFP); - modrm(OldwR, O(REG, MP), RAX, RMP); - modrm(OldwR, O(REG, PC), RAX, RAX); - genw(OjmpRind|RAX); - - segflush(comvec, 32); - - if(cflag > 2) { - print("preamble\n"); - das(s, code-s); - } -} - -static void -maccase(void) -{ - /* Not used yet, done with punt() */ -} - -static void -macfrp(void) -{ - uchar *label,*s; - s=code; - cmpl(RAX, (ulong)H); // CMPL AX, $H - genw(Ojne|0x2); // JNE .+2 - genw(Orts); // RET - genw(OcmpiwR|(RAX<<9)); - genl(0x01); // CMP AX.ref, $1 - genw(O(Heap, ref)-sizeof(Heap)); - genw(Ojeq); // JEQ - label=code-1; - modrm(OdecrwRind, O(Heap, ref)-sizeof(Heap), RAX, 0); // DEC AX.ref - genw(Orts); // RET - *label=code-label-1; - - conR((ulong)&R, RTMP); // MOV $R, RTMP - modrm(OstwR, O(REG, FP), RTMP, RFP); // MOVL RFP, R.FP - modrm(OstwR, O(REG, s), RTMP, RAX); // MOVL RAX, R.s - // CALL rdestroy - bra((ulong)rdestroy, Obsr); - conR((ulong)&R, RTMP); // MOVL $R, RTMP - modrm(OldwR, O(REG, FP), RTMP, RFP); // MOVL R.FP, RFP - modrm(OldwR, O(REG, MP), RTMP, RMP); // MOVL R.MP, RMP - genw(Orts); - if(pass&&(cflag > 2)) { - print("macfrp\n"); - das(s, code-s); - } -} - -static void -macret(void) -{ - Inst i; - uchar *s; - static ulong lpunt, lnomr, lfrmr,linterp; - - s = code; - - lpunt -= 2; - lnomr -= 2; - lfrmr -= 2; - linterp -= 2; - - modrm(OldwR, O(Frame, t), RFP, RAX); // MOVL t(FP), RAX - genw(OmovwRD|(DTMP<<9)|RAX); - genw(0x4A80|DTMP); // TSTL DTMP - genw(Ojeq|(uchar)(lpunt-(code-s))); // JEQ lpunt - modrm(OldwR, O(Type, destroy), RAX, RAX); // MOVL destroy(RAX), RAX - genw(OmovwRD|(DTMP<<9)|RAX); - genw(0x4A80|DTMP); // TSTL DTMP - genw(Ojeq|(uchar)(lpunt-(code-s))); // JEQ lpunt - modrm(OtstwR, O(Frame, fp), RFP, 0); // TSTL fp(RFP) - genw(Ojeq|(uchar)(lpunt-(code-s))); // JEQ lpunt - modrm(OtstwR, O(Frame, mr), RFP, 0); // TSTL mr(RFP) - genw(Ojeq|(uchar)(lnomr-(code-s))); // JEQ lnomr - conR((ulong)&R, RTMP); // MOVL $R, RTMP - modrm(OldwR, O(REG, M), RTMP, RTA); // MOVL R.M, RTA - modrm(OdecrwRind, O(Module, ref), RTA, 0); // DECL ref(RTA) - genw(Ojne|(uchar)(lfrmr-(code-s))); // JNE lfrmr - modrm(OincrwRind, O(Module, ref), RTA, 0); // INCL ref(RTA) - genw(Obra|(uchar)(lpunt-(code-s))); // JMP lpunt - lfrmr = code - s; - modrm(OldwR, O(Frame, mr), RFP, RTA); // MOVL mr(RFP), RTA - modrm(OstwR, O(REG, M), RTMP, RTA); // MOVL RTA, R.M - modrm(OldwR, O(Modlink, MP), RTA, RMP); // MOVL mp(RTA), RMP - modrm(OstwR, O(REG, MP), RTMP, RMP); // MOVL RMP, R.MP - - modrm(OtstwR, O(Modlink, compiled), RTA, 0); // CMPL $0, M.compiled - genw(Ojeq|(uchar)(linterp-(code-s))); - - lnomr = code - s; - genw(OjsrRind|RAX); // CALL* AX - conR((ulong)&R, RTMP); // MOVL $R, RTMP - modrm(OstwR, O(REG, SP), RTMP, RFP); // MOVL RFP, R.SP - modrm(OldwR, O(Frame, lr), RFP, RAX); // MOVL lr(RFP), RAX - modrm(OldwR, O(Frame, fp), RFP, RFP); // MOVL fp(RFP), RFP - modrm(OstwR, O(REG, FP), RTMP, RFP); // MOVL RFP, R.FP - genw(OjmpRind|RAX); // JMP*L AX - - linterp = code - s; - genw(OjsrRind|RAX); // CALL* AX - conR((ulong)&R, RTMP); // MOVL $R, RTMP - modrm(OstwR, O(REG, SP), RTMP, RFP); // MOVL RFP, R.SP - modrm(OldwR, O(Frame, lr), RFP, RAX); // MOVL lr(RFP), RAX - modrm(OstwR, O(REG, PC), RTMP, RAX); // MOVL RAX, R.PC - modrm(OldwR, O(Frame, fp), RFP, RFP); // MOVL fp(RFP), RFP - modrm(OstwR, O(REG, FP), RTMP, RFP); // MOVL RFP, R.FP - - genw(Orts); - lpunt = code - s; // label: - i.add = AXNON; - punt(&i, NEWPC, optab[IRET]); - if(pass&&(cflag > 2)) { - print("macret\n"); - das(s, code-s); - } -} - -static void -maccolr(void) -{ - uchar *s; - s=code; - modrm(OincrwRind, O(Heap, ref)-sizeof(Heap), RTMP, 0); // INCL ref(RTMP) - genw(0x2079|(RAX<<9)); // MOVL (mutator), RAX - genl((ulong)&mutator); - modrm(OcmpwR, O(Heap, color)-sizeof(Heap), RTMP, RAX); // CMPL color(RTMP), RAX - genw(Ojne|0x02); - genw(Orts); - conR(propagator, RAX); // MOVL $propagator,RAX - modrm(OstwR, O(Heap, color)-sizeof(Heap), RTMP, RAX); // MOVL RAX, color(RTMP) - genw(0x23C8|RAX); // can be any !0 value - genl((ulong)&nprop); // MOVL RAX, (nprop) - genw(Orts); - if(pass&&(cflag > 2)) { - print("maccolr\n"); - das(s, code-s); - } -} - -static void -macmcal(void) -{ - uchar *s,*label,*interp; - s=code; - - genw(0x2040|(RCX<<9)|DTMP); - modrm(OtstwR,O(Module, prog),RCX,0); // TSTL ml->m->prog - - genw(Ojne); // JNE patch - label = code-1; - modrm(OstwR, O(REG, FP), RTMP, RTA); - modrm(OstwR, O(REG, dt), RTMP, RAX); - // CALL rmcall - bra((ulong)rmcall, Obsr); - - conR((ulong)&R, RTMP); // MOVL $R, RTMP - modrm(OldwR, O(REG, FP), RTMP, RFP); - modrm(OldwR, O(REG, MP), RTMP, RMP); - genw(Orts); // RET - *label = code-label-1; // patch: - genw(0x2048|(RFP<<9)|RTA); // MOVL RTA, RFP R.FP = f - modrm(OstwR, O(REG, M), RTMP, RCX); // MOVL RCX, R.M - modrm(OincrwRind, O(Module, ref), RCX, 0); // INC.L R.M->ref - modrm(OldwR, O(Modlink, MP), RCX, RMP); // MOVL R.M->mp, RMP - modrm(OstwR, O(REG, MP), RTMP, RMP); // MOVL RCX, R.MP R.MP = ml->m - modrm(OtstwR, O(Module, compiled), RCX, 0);// CMPL $0, M.compiled - - genw(OpopwR|(RCX<<9)); // balance call - genw(Ojeq); // JEQ interp - interp=code-1; - genw(OjmpRind|RAX); // JMP*L AX - *interp= code-interp-1; - modrm(OstwR, O(REG, FP), RTMP, RFP); // MOVL FP, R.FP - modrm(OstwR, O(REG, PC), RTMP, RAX); // MOVL PC, R.PC - genw(Orts); - if(pass&&(cflag > 2)) { - print("macmcal\n"); - das(s, code-s); - } -} - -static void -macfram(void) -{ - uchar *label,*s; - s=code; - conR((ulong)&R, RTMP); // MOVL $R, RTMP - modrm(OldwD, O(REG, SP), RTMP, DTMP); // MOVL R.SP, DTMP - modrm(OaddRD, O(Type, size), RTA, DTMP);// ADDL size(RTA), DTMP - modrm(OcmpwD, O(REG, TS), RTMP, DTMP); // CMPL DTMP, R.TS - genw(Ojlt); // JLT .+(patch) - label = code-1; - - modrm(OstwR, O(REG, s), RTMP, RTA); - modrm(OstwR, O(REG, FP), RTMP, RFP); // MOVL RFP, R.FP - // BSR extend - bra((ulong)extend, Obsr); - conR((ulong)&R, RTMP); - modrm(OldwR, O(REG, FP), RTMP, RFP); // MOVL R.MP, RMP - modrm(OldwR, O(REG, MP), RTMP, RMP); // MOVL R.FP, RFP - modrm(OldwR, O(REG, s), RTMP, RAX); // MOVL R.s, *R.d - genw(Orts); // RET - *label = code-label-1; - modrm(OldwR, O(REG, SP), RTMP, RAX); // MOVL R.SP, RAX - modrm(OstwD, O(REG, SP), RTMP, DTMP); // MOVL DTMP, R.SP - - modrm(OstwR, O(Frame, t), RAX, RTA); // MOVL RTA, t(RAX) f->t = t - genw(OmovwR|(RAX<<9)); // MOVL $0, mr(RAX) f->mr - genl(0); - genw(REGMOD*4); - - modrm(OldwR, O(Type, initialize), RTA, RTA); - genw(OjmpRind|RTA); // JMP*L RTA - genw(Orts); // RET - if(pass&&(cflag > 2)) { - print("macfram\n"); - das(s, code-s); - } -} - -static void -macmfra(void) -{ - uchar *s; - s=code; - conR((ulong)&R, RTMP); // MOVL $R, RTMP - modrm(OstwR, O(REG, FP), RTMP, RFP); - modrm(OstwR, O(REG, s), RTMP, RAX); // Save type - modrm(OstwR, O(REG, d), RTMP, RTA); // Save destination - // CALL rmfram - bra((ulong)rmfram, Obsr); - conR((ulong)&R, RTMP); // MOVL $R, RTMP - modrm(OldwR, O(REG, FP), RTMP, RFP); - modrm(OldwR, O(REG, MP), RTMP, RMP); - genw(Orts); // RET - if(pass&&(cflag > 2)) { - print("macmfra\n"); - das(s, code-s); - } -} - -void -comd(Type *t) -{ - int i, j, m, c; - - for(i = 0; i < t->np; i++) { - c = t->map[i]; - j = i<<5; - for(m = 0x80; m != 0; m >>= 1) { - if(c & m) { - modrm(OldwR, j, RFP, RAX); - rbra(macro[MacFRP], Obsr); - } - j += sizeof(WORD*); - } - } - genw(Orts); -} - -void -comi(Type *t) -{ - int i, j, m, c; - - conD((ulong)H, DTMP); - for(i = 0; i < t->np; i++) { - c = t->map[i]; - j = i<<5; - for(m = 0x80; m != 0; m >>= 1) { - if(c & m) - modrm(OstwD, j, RAX, DTMP); - j += sizeof(WORD*); - } - } - genw(Orts); -} - -void -typecom(Type *t) -{ - int n; - uchar *tmp; - tmp=malloc(4096); - - if(tmp == nil) - error(exNomem); - if(t == nil || t->initialize != 0) - return; - - code = tmp; - comi(t); - n = code - tmp; - code = tmp; - comd(t); - n += code - tmp; - - code = mallocz(n, 0); - if(code == nil) - return; - - t->initialize = code; - comi(t); - t->destroy = code; - comd(t); - - segflush(t->initialize, n); - - if(cflag > 1) { - print("typ= %.8p %4d i %.8p d %.8p asm=%d\n", - t, t->size, t->initialize, t->destroy, n); - if (cflag > 2) - das(t->destroy, code-(uchar*)t->destroy); - } - free(tmp); -} - -static void -patchex(Module *m, ulong *p) -{ - Handler *h; - Except *e; - - if((h = m->htab) == nil) - return; - for( ; h->etab != nil; h++){ - h->pc1 = p[h->pc1]; - h->pc2 = p[h->pc2]; - for(e = h->etab; e->s != nil; e++) - e->pc = p[e->pc]; - if(e->pc != -1) - e->pc = p[e->pc]; - } -} - -int -compile(Module *m, int size, Modlink *ml) -{ - ulong v; - Link *l; - Modl *e; - int i, n; - uchar *s, *tmp; - base = nil; - - tmp=malloc(4096); - patch = mallocz(size*sizeof(*patch), 0); - tinit = malloc(m->ntype*sizeof(*tinit)); - if(tinit == nil || patch == nil || tmp == nil) - goto bad; - - preamble(); - - mod = m; - n = 0; - pass = 0; - nlit = 0; - - for(i = 0; i < size; i++) { - code = tmp; - comp(&m->prog[i]); - if(code >= &tmp[4096]) { - print("tmp ovlo\n%3d %D\n", i, &m->prog[i]); - urk(); - } - patch[i] = n; - n += code - tmp; - } - - for(i = 0; i < nelem(mactab); i++) { - code = tmp; - (*mactab[i].gen)(); - macro[mactab[i].idx] = n; - n += code - tmp; - } - - nlit *= sizeof(ulong); - base = mallocz(n + nlit, 0); - if(base == nil) - goto bad; - - if(cflag > 1) - print("dis=%5d %5d 386=%5d asm=%.8p lit=%d: %s\n", - size, size*sizeof(Inst), n, base, nlit, m->name); - - pass++; - nlit = 0; - litpool = (ulong*)(base+n); - code = base; - n = 0; - for(i = 0; i < size; i++) { - s = code; - comp(&m->prog[i]); - if(patch[i] != n) { - print("phase error\n%3d %D\n", i, &m->prog[i]); - urk(); - } - n += code - s; - if(cflag > 1) { - print("%d: %D\n", i,&m->prog[i]); - das(s, code-s); - } - } - - for(i = 0; i < nelem(mactab); i++) { - if(macro[mactab[i].idx] != n) { - print("phase error\nmactab %d\n", mactab[i].idx); - urk(); - } - s = code; - (*mactab[i].gen)(); - n += code-s; - if(cflag > 1) { - print("mactab %d\n", mactab[i].idx); - das(s, code-s); - } - } - - v = (ulong)base; - for(l = m->ext; l->name; l++) { -//print("### link: %lux ",l->u.pc-m->prog); - l->u.pc = (Inst*)(v+patch[l->u.pc-m->prog]); -//print("%lux\n",l->u.pc); - typecom(l->frame); - } - if(ml != nil) { - e = &ml->links[0]; - for(i = 0; i < ml->nlinks; i++) { - e->u.pc = (Inst*)(v+patch[e->u.pc-m->prog]); - typecom(e->frame); - e++; - } - } - for(i = 0; i < m->ntype; i++) { - if(tinit[i] != 0) - typecom(m->type[i]); - } - patchex(m, patch); - m->entry = (Inst*)(v+patch[mod->entry-mod->prog]); - free(patch); - free(tinit); - free(tmp); - free(m->prog); - m->prog = (Inst*)base; - m->compiled = 1; - segflush(base, n*sizeof(*base)); - return 1; -bad: - free(tmp); - free(patch); - free(tinit); - free(base); - return 0; -} diff --git a/libinterp/comp-thumb.c b/libinterp/comp-thumb.c deleted file mode 100644 index 03aaa20e..00000000 --- a/libinterp/comp-thumb.c +++ /dev/null @@ -1,2466 +0,0 @@ -#include "lib9.h" -#include "isa.h" -#include "interp.h" -#include "raise.h" - -#define RESCHED 1 /* check for interpreter reschedule */ - -enum -{ - R0 = 0, // why wasn't this used ? - R1 = 1, - R2 = 2, - R3 = 3, - R4 = 4, - R5 = 5, - R6 = 6, - R7 = 7, - R8 = 8, - R9 = 9, - R10 = 10, // unused - R11 = 11, // unused - R12 = 12, /* C's SB */ - R13 = 13, /* C's SP */ - R14 = 14, /* Link Register */ - R15 = 15, /* PC */ - - RSB = R12, - RLINK = R14, - RPC = R15, - - RTMP = R11, /* linker temp */ - RHT = R8, /* high temp */ - RFP = R7, /* Frame Pointer */ - RMP = R6, /* Module Pointer */ - RREG = R5, /* Pointer to REG */ - RA3 = R4, /* gpr 3 */ - RA2 = R3, /* gpr 2 2+3 = L */ - RA1 = R2, /* gpr 1 */ - RA0 = R1, /* gpr 0 0+1 = L */ - RCON = R0, /* Constant builder */ - - EQ = 0, - NE = 1, - CS = 2, - CC = 3, - MI = 4, - PL = 5, - VS = 6, - VC = 7, - HI = 8, - LS = 9, - GE = 10, - LT = 11, - GT = 12, - LE = 13, - AL = 14, - NV = 15, - - And = 0, - Eor = 1, - Lsl = 2, - Lsr = 3, - Asr = 4, - Adc = 5, - Sbc = 6, - Ror = 7, - Tst = 8, - Neg = 9, - Cmp = 10, - Cmn = 11, - Orr = 12, - Mul = 13, - Bic = 14, - Mvn = 15, - - Mov = 16, - Cmpi = 17, - Add = 18, - Sub = 19, - - Cmph = 19, - Movh = 20, - - Lea = 100, /* macro memory ops */ - Ldw, - Ldb, - Stw, - Stb, - - NCON = (0x3fc-8)/4, - - SRCOP = (1<<0), - DSTOP = (1<<1), - WRTPC = (1<<2), - TCHECK = (1<<3), - NEWPC = (1<<4), - DBRAN = (1<<5), - THREOP = (1<<6), - - ANDAND = 1, - OROR = 2, - EQAND = 3, - - MacFRP = 0, - MacRET, - MacCASE, - MacCOLR, - MacMCAL, - MacFRAM, - MacMFRA, - MacRELQ, - NMACRO -}; - -#define FIRSTPASS 0 -#define MIDDLEPASS 1 -#define LASTPASS 2 -static int pass; - -static void -OP(int o, int o1, int o2, char *s) -{ - if(o < o1 || o > o2) print("error: bad op %d in %s\n", o, s); -} - -static void -IMM(int i, int i1, int i2, char *s) -{ - if(i < i1 || i > i2) print("error: bad imm %d in %s\n", i, s); -} - -static void -MULT(int o, int m, char *s) -{ - if((o/m)*m != o) print("error: %d not multiple of %d in %s\n", o, m, s); -} - -static void -LOWREG(int r, char *s) -{ - if(r < 0 || r >= 8) print("error: %s: bad low reg %d\n", s, r); -} - -static void -HIGHREG(int r, char *s) -{ - if(r < 8) print("error: %s: bad high reg %d\n", s, r); -} - -static void -CKIRRS(int op, int i, int rm, int rd) -{ - OP(op, Lsl, Asr, "IRRS"); - IMM(i, 0, 31, "IRRS"); - LOWREG(rm, "IRRS rm"); - LOWREG(rd, "IRRS rd"); -} - -static void -CKRRR(int op, int rs, int rm, int rd) -{ - OP(op, Add, Sub, "RRR"); - LOWREG(rs, "RRR rs"); - LOWREG(rm, "RRR rm"); - LOWREG(rd, "RRR rd"); -} - -static void -CKIRR(int op, int i, int rm, int rd) -{ - OP(op, Add, Sub, "IRR"); - IMM(i, 0, 7, "IRR"); - LOWREG(rm, "IRR rm"); - LOWREG(rd, "IRR rd"); -} - -static void -CKIR(int op, int i, int rd) -{ - OP(op, Mov, Sub, "IR"); - IMM(i, 0, 255, "IR"); - LOWREG(rd, "IR rd"); -} - -static void -CKRR(int op, int rs, int rd) -{ - OP(op, And, Mvn, "RR"); - LOWREG(rs, "RR rs"); - LOWREG(rd, "RR rd"); -} - -static void -CKRH(int op, int rs, int rd) -{ - OP(op, Add, Movh, "RH"); - LOWREG(rs, "RH"); - HIGHREG(rd, "RH"); -} - -static void -CKHR(int op, int rs, int rd) -{ - OP(op, Add, Movh, "HR"); - HIGHREG(rs, "HR"); - LOWREG(rd, "HR"); -} - -static void -CKHH(int op, int rs, int rd) -{ - OP(op, Add, Movh, "HH"); - HIGHREG(rs, "HH"); - HIGHREG(rd, "HH"); -} - -static void -CKLS(int rn, int o, int rd, int s, int l) -{ - char buf[16]; - - sprint(buf, "LS %d %d", s, l); - LOWREG(rn, buf); - LOWREG(rd, buf); - MULT(o, s, buf); - IMM(o/s, 0, 31, buf); -} - -static void -CKLSR(int rn, int rm, int rd, int s, int l) -{ - char buf[16]; - - sprint(buf, "LSR %d %d", s, l); - LOWREG(rn, buf); - LOWREG(rm, buf); - LOWREG(rd, buf); -} - -static void -CKLPCR(int o, int rd) -{ - LOWREG(rd, "LPCR"); - if(o&3) - o += 2; - MULT(o, 4, "LPCR"); - IMM(o/4, 0, 255, "LPCR"); -} - -static void -CKB(int o) -{ - if(pass == FIRSTPASS) - return; - MULT(o, 2, "B"); - IMM(o, -2048, 2046, "B"); -} - -static void -CKBCC(int o) -{ - if(pass == FIRSTPASS) - return; - MULT(o, 2, "BCC"); - IMM(o, -256, 254, "BCC"); -} - -static void -CKBL(int o) -{ - if(pass == FIRSTPASS) - return; - MULT(o, 2, "BL"); - IMM(o, -4194304, 4194302, "BL"); -} - -#define DPIRRS(op, i, rm, rd) (CKIRRS(op, i, rm, rd), *code++ = ((op-Lsl)<<11) | (i<<6) | (rm<<3) | rd) -#define DPRRR(op, rs, rm, rd) (CKRRR(op, rs, rm, rd), *code++ = (6<<10) | ((op-Add)<<9) | (rs<<6) | (rm<<3) | rd) -#define DPIRR(op, i, rm, rd) (CKIRR(op, i, rm, rd), *code++ = (7<<10) | ((op-Add)<<9) | (i<<6) | (rm<<3) | rd) -#define DPIR(op, i, rd) (CKIR(op, i, rd), *code++ = (1<<13) | ((op-Mov)<<11) | (rd<<8) | i) -#define DPRR(op, rs, rd) (CKRR(op, rs, rd), *code++ = (1<<14) | (op<<6) | (rs<<3) | rd) - -#define DPRH(op, rs, hd) (CKRH(op, rs, hd), *code++ = (17<<10) | ((op-Add)<<8) | (1<<7) | (rs<<3) | (hd-8)) -#define DPHR(op, hs, rd) (CKHR(op, hs, rd), *code++ = (17<<10) | ((op-Add)<<8) | (1<<6) | ((hs-8)<<3) | rd) -#define DPHH(op, hs, hd) (CKHH(op, hs, hd), *code++ = (17<<10) | ((op-Add)<<8) | (3<<6) | ((hs-8)<<3) | (hd-8)) - -#define LDW(rs, o, rd) (CKLS(rs, o, rd, 4, 1), *code++ = (13<<11)|((o/4)<<6)|(rs<<3)|rd) -#define STW(rs, o, rd) (CKLS(rs, o, rd, 4, 0), *code++ = (12<<11)|((o/4)<<6)|(rs<<3)|rd) -#define LDH(rs, o, rd) (CKLS(rs, o, rd, 2, 0), *code++ = (17<<11)|((o/2)<<6)|(rs<<3)|rd) -#define STH(rs, o, rd) (CKLS(rs, o, rd, 2, 1), *code++ = (16<<11)|((o/2)<<6)|(rs<<3)|rd) -#define LDB(rs, o, rd) (CKLS(rs, o, rd, 1, 1), *code++ = (15<<11)|(o<<6)|(rs<<3)|rd) -#define STB(rs, o, rd) (CKLS(rs, o, rd, 1, 0), *code++ = (14<<11)|(o<<6)|(rs<<3)|rd) -#define LDRW(rs, rm, rd) (CKLSR(rs, rm, rd, 4, 1), *code++ = (44<<9)|(rs<<6)|(rm<<3)|rd) -#define STRW(rs, rm, rd) (CKLSR(rs, rm, rd, 4, 1), *code++ = (40<<9)|(rs<<6)|(rm<<3)|rd) -#define LDRH(rs, rm, rd) (CKLSR(rs, rm, rd, 4, 1), *code++ = (45<<9)|(rs<<6)|(rm<<3)|rd) -#define STRH(rs, rm, rd) (CKLSR(rs, rm, rd, 4, 1), *code++ = (41<<9)|(rs<<6)|(rm<<3)|rd) -#define LDRB(rs, rm, rd) (CKLSR(rs, rm, rd, 4, 1), *code++ = (46<<9)|(rs<<6)|(rm<<3)|rd) -#define STRB(rs, rm, rd) (CKLSR(rs, rm, rd, 4, 1), *code++ = (42<<9)|(rs<<6)|(rm<<3)|rd) - -#define LDWPCREL(o, rd) (CKLPCR(o, rd), *code++ = (9<<11)|(rd<<8)|(o/4)) - -#define CMPI(i, rn) DPIR(Cmpi, i, rn) -#define CMP(rs, rn) DPRR(Cmp, rs, rn) -#define CMPRH(rs, rn) DPRH(Cmph, rs, rn) -#define CMPHR(rs, rn) DPHR(Cmph, rs, rn) -#define CMPHH(rs, rn) DPHH(Cmph, rs, rn) -#define MOV(src, dst) DPIRRS(Lsl, 0, src, dst) -#define MOVRH(s, d) DPRH(Movh, s, d) -#define MOVHR(s, d) DPHR(Movh, s, d) -#define MOVHH(s, d) DPHH(Movh, s, d) -#define MUL(rs, rd) DPRR(Mul, rs, rd) - -#define CODE (code+codeoff) -#define IA(s, o) (ulong)(base+s[o]) -#define RELPC(pc) (ulong)(base+(pc)) - -#define RINV(c) ((c)&1 ? (c)-1 : (c)+1) -#define FPX(fp) (((ulong)(fp))&~1) -#define NOBR 4 - -#define BRAU(o) ((28<<11) | (((o)>>1)&0x7ff)) -#define BRAC(c, o) ((13<<12) | ((c)<<8) | (((o)>>1)&0xff)) -#define BRAL1(o) ((30<<11) | ((o)&0x7ff)) -#define BRAL2(o) ((31<<11) | ((o)&0x7ff)) - -#define CJUMP(c, o) CBRA(RINV(c), o) -#define BRA(o) (CKB((o)-4), gen(BRAU((o)-4))) -#define CBRA(c, o) (CKBCC((o)-4), gen(BRAC(c, (o)-4))) -#define BRADIS(o) branch(IA(patch, o)-(ulong)CODE) -#define CBRADIS(c, o) cbranch(c, IA(patch, o)-(ulong)CODE) -#define BRAMAC(o) branch(IA(macro, o)-(ulong)CODE) -#define RETURN MOVHH(RLINK, RPC) -#define CALL(o) call((ulong)(FPX(o))-(ulong)CODE) -#define CALLMAC(o) call(IA(macro, o)-(ulong)CODE) - -#define PATCH(ptr) (CKB((ulong)code-(ulong)ptr-4), *ptr |= (((ulong)code-(ulong)(ptr)-4)>>1) & 0x7ff) -#define CPATCH(ptr) (CKBCC((ulong)code-(ulong)ptr-4), *ptr |= (((ulong)code-(ulong)(ptr)-4)>>1) & 0xff) -#define BPATCH(ptr) ((ulong)ptr-(ulong)code) - -/* long branches */ -#define DWORD(o) (*code++ = (o)&0xffff, *code++ = ((o)>>16)&0xffff) -#define BRALONG(o) (LDWPCREL(0, RCON), MOVRH(RCON, RPC), DWORD(o+(ulong)code-4)) -#define CALLLONG(o) (MOVHR(RPC, RCON), DPIR(Add, 10, RCON), MOVRH(RCON, RLINK), BRALONG(o)) - -#define PAD() MOVHH(RSB, RSB) - -#define BITS(B) (1<<B) - -#define FITS8(v) ((ulong)(v)<BITS(8)) -#define FITS5(v) ((ulong)(v)<BITS(5)) -#define FITS3(v) ((ulong)(v)<BITS(3)) - -/* assumes H==-1 */ -#define CMPH(r, scr) DPIRR(Add, 1, r, scr) -#define NOTNIL(r, scr) (CMPH(r, scr), label = code, CJUMP(EQ, NOBR), CALL(bounds), CPATCH(label)) - -#define ADDSP(o) *code++ = (11<<12) | (0<<7) | (o>>2) -#define SUBSP(o) *code++ = (11<<12) | (1<<7) | (o>>2) -#define LDSP(o, r) *code++ = (19<<11) | (r<<8) | (o>>2) -#define STSP(o, r) *code++ = (18<<11) | (r<<8) | (o>>2) - -static ushort* code; -static ushort* base; -static ulong* patch; -static ulong codeoff; -static Module* mod; -static uchar* tinit; -static ushort* litpool; -static int nlit; -static ulong macro[NMACRO]; - void (*comvec)(void); -static void macfrp(void); -static void macret(void); -static void maccase(void); -static void maccolr(void); -static void macmcal(void); -static void macfram(void); -static void macmfra(void); -static void macrelq(void); -static void movmem(Inst*); -static void mid(Inst*, int, int); -extern void das(ushort*, int); - -#define T(r) *((void**)(R.r)) - -struct -{ - int idx; - void (*gen)(void); - char* name; -} mactab[] = -{ - MacFRP, macfrp, "FRP", /* decrement and free pointer */ - MacRET, macret, "RET", /* return instruction */ - MacCASE, maccase, "CASE", /* case instruction */ - MacCOLR, maccolr, "COLR", /* increment and color pointer */ - MacMCAL, macmcal, "MCAL", /* mcall bottom half */ - MacFRAM, macfram, "FRAM", /* frame instruction */ - MacMFRA, macmfra, "MFRA", /* punt mframe because t->initialize==0 */ - MacRELQ, macrelq, /* reschedule */ -}; - -typedef struct Const Const; -struct Const -{ - ulong o; - ushort* code; - ushort* pc; -}; - -typedef struct Con Con; -struct Con -{ - int ptr; - Const table[NCON]; -}; -static Con rcon; - -static void gen(ulong), genc(ulong); - -/* only CBRADIS could be too long by the look of things */ -static void -cbranch(int c, long o) -{ - long off = o-4; - - if(pass == FIRSTPASS || (off >= -256 && off <= 254)) - CBRA(c, o); - else if(off >= -2046 && off <= 2048){ - CBRA(RINV(c), 4); - BRA(o-2); - } - else{ - if(!((int)CODE&2)) - PAD(); - CBRA(RINV(c), 10); - BRALONG(o); - } -} - -/* only BRADIS, BRAMAC could be too long */ -static void -branch(long o) -{ - long off = o-4; - - if(pass == FIRSTPASS || (off >= -2048 && off <= 2046)) - BRA(o); - else{ - if((int)CODE&2) - PAD(); - BRALONG(o); - } -} - -static void -call(long o) -{ - long off = o-4; - - if(pass == FIRSTPASS || (off >= -4194304 && off <= 4194302)) - genc(o); - else{ - if(!((int)CODE&2)) - PAD(); - CALLLONG(o); - } -} - -static void -rdestroy(void) -{ - destroy(R.s); -} - -static void -rmcall(void) -{ - Frame *f; - Prog *p; - - if((void*)R.dt == H) - error(exModule); - - f = (Frame*)R.FP; - if(f == H) - error(exModule); - - f->mr = nil; - ((void(*)(Frame*))R.dt)(f); - R.SP = (uchar*)f; - R.FP = f->fp; - if(f->t == nil) - unextend(f); - else - freeptrs(f, f->t); - p = currun(); - if(p->kill != nil) - error(p->kill); -} - -static void -rmfram(void) -{ - Type *t; - Frame *f; - uchar *nsp; - - if(R.d == H) - error(exModule); - t = (Type*)R.s; - if(t == H) - error(exModule); - nsp = R.SP + t->size; - if(nsp >= R.TS) { - R.s = t; - extend(); - T(d) = R.s; - return; - } - f = (Frame*)R.SP; - R.SP = nsp; - f->t = t; - f->mr = nil; - initmem(t, f); - T(d) = f; -} - -static void -urk(char *s) -{ - USED(s); - error(exCompile); //production - //panic("compile failed: urk: %s\n", s); //debugging -} - -static void -gen(ulong w) -{ - *code++ = w; -} - -static void -genc(ulong o) -{ - o -= 4; - CKBL(o); - *code++ = BRAL1(o>>12); - *code++ = BRAL2(o>>1); -} - -static void -flushcon(int genbr) -{ - int i; - Const *c; - ulong disp; - - if(rcon.ptr == 0) - return; - if(genbr ^ (((int)CODE&2)>>1)) - PAD(); - if(genbr) - BRA(rcon.ptr*4+2); - c = &rcon.table[0]; - for(i = 0; i < rcon.ptr; i++) { - if(pass == LASTPASS){ - disp = (code - c->code) * sizeof(*code) - 4; - if(disp >= BITS(10)) - print("error: INVALID constant range %lud", disp); - CKLPCR(disp, R0); // any reg will do - if(disp & 3) - disp += 2; // ensure M(4) offset - *c->code |= (disp/4); - } - *code++ = (c->o)&0xffff; - *code++ = (c->o >> 16)&0xffff; - c++; - } - rcon.ptr = 0; -} - -static void -flushchk(void) -{ - if(rcon.ptr >= NCON || rcon.ptr > 0 && (code+codeoff+2-rcon.table[0].pc)*sizeof(*code) >= BITS(10)-256) // 256 allows for a little delay in calling flushchk - flushcon(1); -} - -static void -con(ulong o, int r, int opt) -{ - Const *c; - - LOWREG(r, "con"); - if(opt != 0) { - if(o >= 0 && o <= 255){ - DPIR(Mov, o, r); - return; - } - if(-o >= 0 && -o <= 255){ - DPIR(Mov, -o, r); - DPRR(Neg, r, r); - return; - } - if(o >= 256 && o <= 510){ - DPIR(Mov, 255, r); - DPIR(Add, o-255, r); - return; - } - if(o > 0){ - int n = 0; - ulong m = o; - - while(!(m & 1)){ - n++; - m >>= 1; - } - if(m >= 0 && m <= 255){ - DPIR(Mov, m, r); - DPIRRS(Lsl, n, r, r); - return; - } - } - } - flushchk(); - c = &rcon.table[rcon.ptr++]; - c->o = o; - c->code = code; - c->pc = code+codeoff; - LDWPCREL(0, r); -} - -static void -mem(int inst, ulong disp, int rm, int r) -{ - LOWREG(rm, "mem"); - LOWREG(r, "mem"); - LOWREG(RCON, "mem"); - if(inst == Lea) { - if(rm == r){ - if(disp < BITS(8)){ - DPIR(Add, disp, r); - return; - } - if(-disp < BITS(8)){ - DPIR(Sub, -disp, r); - return; - } - } - else{ - if(disp < BITS(3)){ - DPIRR(Add, disp, rm, r); - return; - } - if(-disp < BITS(3)){ - DPIRR(Sub, -disp, rm, r); - return; - } - } - con(disp, RCON, 1); - DPRRR(Add, RCON, rm, r); - return; - } - - switch(inst) { - case Ldw: - if(disp < BITS(7)){ - LDW(rm, disp, r); - return; - } - break; - case Ldb: - if(disp < BITS(5)){ - LDB(rm, disp, r); - return; - } - break; - case Stw: - if(disp < BITS(7)){ - STW(rm, disp, r); - return; - } - break; - case Stb: - if(disp < BITS(5)){ - STB(rm, disp, r); - return; - } - break; - } - - con(disp, RCON, 1); - switch(inst) { - case Ldw: - LDRW(rm, RCON, r); - break; - case Ldb: - LDRB(rm, RCON, r); - break; - case Stw: - STRW(rm, RCON, r); - break; - case Stb: - STRB(rm, RCON, r); - break; - } -} - -static void -memh(int inst, ulong disp, int rm, int r) -{ - HIGHREG(r, "memh"); - if(inst == Stw || inst == Stb) - MOVHR(r, RCON); - mem(inst, disp, rm, RCON); - if(inst != Stw && inst != Stb) - MOVRH(RCON, r); -} - -static void -opx(int mode, Adr *a, int mi, int r, int li) -{ - int ir, rta; - - switch(mode) { - default: - urk("opx"); - case AFP: - mem(mi, a->ind, RFP, r); - return; - case AMP: - mem(mi, a->ind, RMP, r); - return; - case AIMM: - con(a->imm, r, 1); - if(mi == Lea) { /* could be simpler if con generates reachable literal */ - mem(Stw, li, RREG, r); - mem(Lea, li, RREG, r); - } - return; - case AIND|AFP: - ir = RFP; - break; - case AIND|AMP: - ir = RMP; - break; - } - if(mi == Lea || mi == Ldb || mi == Ldw) - rta = r; - else if(r == RA3) /* seems safe - have to squeeze reg use */ - rta = RA2; - else - rta = RA3; - mem(Ldw, a->i.f, ir, rta); - mem(mi, a->i.s, rta, r); -} - -static void -opwld(Inst *i, int op, int reg) -{ - opx(USRC(i->add), &i->s, op, reg, O(REG, st)); -} - -static void -opwst(Inst *i, int op, int reg) -{ - opx(UDST(i->add), &i->d, op, reg, O(REG, dt)); -} - -static void -literal(ulong imm, int roff) -{ - nlit++; - - con((ulong)litpool, RCON, 0); - mem(Stw, roff, RREG, RCON); - - if(pass != LASTPASS) - return; - - *litpool++ = imm&0xffff; - *litpool++ = (imm>>16)&0xffff; -} - -static void -schedcheck(Inst *i) -{ - ushort *label; - - if(RESCHED && i->d.ins <= i){ - mem(Ldw, O(REG, IC), RREG, RA0); - DPIR(Sub, 1, RA0); - mem(Stw, O(REG, IC), RREG, RA0); - /* CMPI(1, RA0); */ - label = code; - CBRA(LE, NOBR); - /* CJUMP(LE, NOBR); */ - CALLMAC(MacRELQ); - CPATCH(label); - } -} - -static void -bounds(void) -{ - /* mem(Stw, O(REG,FP), RREG, RFP); */ - error(exBounds); -} - -/* -static void -called(int x) -{ - extern void ttrace(void); - - if(x) - mem(Stw, O(REG, FP), RREG, RFP); - CALL(ttrace); - con((ulong)&R, RREG, 1); - mem(Ldw, O(REG, FP), RREG, RFP); - mem(Ldw, O(REG, MP), RREG, RMP); -} -*/ - -static void -punt(Inst *i, int m, void (*fn)(void)) -{ - ulong pc; - ushort *label; - - if(m & SRCOP) { - if(UXSRC(i->add) == SRC(AIMM)) - literal(i->s.imm, O(REG, s)); - else { - opwld(i, Lea, RA0); - mem(Stw, O(REG, s), RREG, RA0); - } - } - - if(m & DSTOP) { - opwst(i, Lea, RA0); - mem(Stw, O(REG, d), RREG, RA0); - } - if(m & WRTPC) { - con(RELPC(patch[i-mod->prog+1]), RA0, 0); - mem(Stw, O(REG, PC), RREG, RA0); - } - if(m & DBRAN) { - pc = patch[i->d.ins-mod->prog]; - literal((ulong)(base+pc), O(REG, d)); - } - - switch(i->add&ARM) { - case AXNON: - if(m & THREOP) { - mem(Ldw, O(REG, d), RREG, RA0); - mem(Stw, O(REG, m), RREG, RA0); - } - break; - case AXIMM: - literal((short)i->reg, O(REG,m)); - break; - case AXINF: - mem(Lea, i->reg, RFP, RA2); - mem(Stw, O(REG, m), RREG, RA2); - break; - case AXINM: - mem(Lea, i->reg, RMP, RA2); - mem(Stw, O(REG, m), RREG, RA2); - break; - } - mem(Stw, O(REG, FP), RREG, RFP); - - CALL(fn); - - con((ulong)&R, RREG, 1); - if(m & TCHECK) { - mem(Ldw, O(REG, t), RREG, RA0); - CMPI(0, RA0); - label = code; - CJUMP(NE, NOBR); - memh(Ldw, O(REG, xpc), RREG, RLINK); - RETURN; /* if(R.t) goto(R.xpc) */ - CPATCH(label); - } - mem(Ldw, O(REG, FP), RREG, RFP); - mem(Ldw, O(REG, MP), RREG, RMP); - - if(m & NEWPC){ - memh(Ldw, O(REG, PC), RREG, RPC); - flushcon(0); - } -} - -static void -mid(Inst *i, int mi, int r) -{ - int ir; - - switch(i->add&ARM) { - default: - opwst(i, mi, r); - return; - case AXIMM: - if(mi == Lea) - urk("mid/lea"); - con((short)i->reg, r, 1); - return; - case AXINF: - ir = RFP; - break; - case AXINM: - ir = RMP; - break; - } - mem(mi, i->reg, ir, r); -} - -static int -swapbraop(int b) -{ - switch(b) { - case GE: - return LE; - case LE: - return GE; - case GT: - return LT; - case LT: - return GT; - } - return b; -} - -static void -cbra(Inst *i, int r) -{ - if(RESCHED) - schedcheck(i); - if(UXSRC(i->add) == SRC(AIMM) && FITS8(i->s.imm)) { - mid(i, Ldw, RA1); - CMPI(i->s.imm, RA1); - r = swapbraop(r); - } else if((i->add & ARM) == AXIMM && FITS8(i->reg)) { - opwld(i, Ldw, RA1); - CMPI(i->reg, RA1); - } else { - opwld(i, Ldw, RA0); - mid(i, Ldw, RA1); - CMP(RA1, RA0); - } - CBRADIS(r, i->d.ins-mod->prog); -} - -static void -cbrab(Inst *i, int r) -{ - if(RESCHED) - schedcheck(i); - if(UXSRC(i->add) == SRC(AIMM)) { - mid(i, Ldb, RA1); - CMPI(i->s.imm&0xff, RA1); - r = swapbraop(r); - } else if((i->add & ARM) == AXIMM) { - opwld(i, Ldb, RA1); - CMPI(i->reg&0xff, RA1); - } else { - opwld(i, Ldb, RA0); - mid(i, Ldb, RA1); - CMP(RA1, RA0); - } - CBRADIS(r, i->d.ins-mod->prog); -} - -static void -cbral(Inst *i, int jmsw, int jlsw, int mode) -{ - ulong dst; - ushort *label; - - if(RESCHED) - schedcheck(i); - opwld(i, Lea, RA1); - mid(i, Lea, RA3); - mem(Ldw, 0, RA1, RA2); - mem(Ldw, 0, RA3, RA0); - CMP(RA0, RA2); - label = nil; - dst = i->d.ins-mod->prog; - switch(mode) { - case ANDAND: - label = code; - CBRA(jmsw, NOBR); - break; - case OROR: - CBRADIS(jmsw, dst); - break; - case EQAND: - CBRADIS(jmsw, dst); - label = code; - CBRA(NE, NOBR); - break; - } - mem(Ldw, 4, RA3, RA0); - mem(Ldw, 4, RA1, RA2); - CMP(RA0, RA2); - CBRADIS(jlsw, dst); - if(label != nil) - CPATCH(label); -} - -static void -cbraf(Inst *i, int r) -{ - USED(r); - if(RESCHED) - schedcheck(i); - punt(i, SRCOP|THREOP|DBRAN|NEWPC|WRTPC, optab[i->op]); -} - -static void -comcase(Inst *i, int w) -{ - int l; - WORD *t, *e; - - if(w != 0) { - opwld(i, Ldw, RA1); // v - opwst(i, Lea, RA3); // table - BRAMAC(MacCASE); - } - - t = (WORD*)(mod->origmp+i->d.ind+4); - l = t[-1]; - - /* have to take care not to relocate the same table twice - - * the limbo compiler can duplicate a case instruction - * during its folding phase - */ - - if(pass == FIRSTPASS || pass == MIDDLEPASS) { - if(l >= 0) - t[-1] = -l-1; /* Mark it not done */ - return; - } - if(l >= 0) /* Check pass 2 done */ - return; - t[-1] = -l-1; /* Set real count */ - e = t + t[-1]*3; - while(t < e) { - t[2] = RELPC(patch[t[2]]); - t += 3; - } - t[0] = RELPC(patch[t[0]]); -} - - -static void -comcasel(Inst *i) -{ - int l; - WORD *t, *e; - - t = (WORD*)(mod->origmp+i->d.ind+8); - l = t[-2]; - if(pass == FIRSTPASS || pass == MIDDLEPASS) { - if(l >= 0) - t[-2] = -l-1; /* Mark it not done */ - return; - } - if(l >= 0) /* Check pass 2 done */ - return; - t[-2] = -l-1; /* Set real count */ - e = t + t[-2]*6; - while(t < e) { - t[4] = RELPC(patch[t[4]]); - t += 6; - } - t[0] = RELPC(patch[t[0]]); -} - -static void -commframe(Inst *i) -{ - ushort *punt, *mlnil; - - opwld(i, Ldw, RA0); - CMPH(RA0, RA3); - mlnil = code; - CBRA(EQ, NOBR); - - if((i->add&ARM) == AXIMM) { - mem(Ldw, OA(Modlink, links)+i->reg*sizeof(Modl)+O(Modl, frame), RA0, RA3); - } else { - mid(i, Ldw, RA1); - // RA1 = RA0 + (RA1<<3) - DPIRRS(Lsl, 3, RA1, RA1); - DPRRR(Add, RA0, RA1, RA1); // assumes sizeof(Modl) == 8 - mem(Ldw, OA(Modlink, links)+O(Modl, frame), RA1, RA3); - } - - mem(Ldw, O(Type, initialize), RA3, RA1); - CMPI(0, RA1); - punt = code; - CBRA(NE, NOBR); - - opwst(i, Lea, RA0); - - /* Type in RA3, destination in RA0 */ - CPATCH(mlnil); - con(RELPC(patch[i-mod->prog+1]), RA2, 0); - MOVRH(RA2, RLINK); - BRAMAC(MacMFRA); - - /* Type in RA3 */ - CPATCH(punt); - CALLMAC(MacFRAM); - opwst(i, Stw, RA2); -} - -static void -commcall(Inst *i) -{ - ushort *mlnil; - - opwld(i, Ldw, RA2); - con(RELPC(patch[i-mod->prog+1]), RA0, 0); - mem(Stw, O(Frame, lr), RA2, RA0); - mem(Stw, O(Frame, fp), RA2, RFP); - mem(Ldw, O(REG, M), RREG, RA3); - mem(Stw, O(Frame, mr), RA2, RA3); - opwst(i, Ldw, RA3); - CMPH(RA3, RA0); - mlnil = code; - CBRA(EQ, NOBR); - if((i->add&ARM) == AXIMM) { - mem(Ldw, OA(Modlink, links)+i->reg*sizeof(Modl)+O(Modl, u.pc), RA3, RA0); - } else { - mid(i, Ldw, RA1); - DPIRRS(Lsl, 3, RA1, RA1); - DPRRR(Add, RA1, RA3, RA1); // assumes sizeof(Modl) == 8 - mem(Ldw, OA(Modlink, links)+O(Modl, u.pc), RA1, RA0); - } - CPATCH(mlnil); - CALLMAC(MacMCAL); -} - -static void -larith(Inst *i, int op, int opc) -{ - opwld(i, Lea, RA0); - mid(i, Lea, RA3); - mem(Ldw, 4, RA0, RA1); // ls (big endian `big' even in little endian mode) - mem(Ldw, 4, RA3, RA2); - if(op == Add || op == Sub) - DPRRR(op, RA1, RA2, RA2); - else - DPRR(op, RA1, RA2); // ls: RA2 = RA2 op RA1 - mem(Ldw, 0, RA0, RA1); - mem(Ldw, 0, RA3, RA0); - DPRR(opc, RA1, RA0); // ms: RA0 = RA0 opc RA1 - if((i->add&ARM) != AXNON) - opwst(i, Lea, RA3); - mem(Stw, 0, RA3, RA0); - mem(Stw, 4, RA3, RA2); -} - -static void -movloop(Inst *i, int s) -{ - ushort *label; - - opwst(i, Lea, RA2); - label = code; - if(s == 1) - LDB(RA1, 0, RA0); - else - LDW(RA1, 0, RA0); - DPIR(Add, s, RA1); - if(s == 1) - STB(RA2, 0, RA0); - else - STW(RA2, 0, RA0); - DPIR(Add, s, RA2); - DPIR(Sub, 1, RA3); - CBRA(NE, BPATCH(label)); -} - -static void -movmem(Inst *i) -{ - ushort *cp; - - // source address already in RA1 - if((i->add&ARM) != AXIMM){ - mid(i, Ldw, RA3); - CMPI(0, RA3); - cp = code; - CBRA(LE, NOBR); - movloop(i, 1); - CPATCH(cp); - return; - } - switch(i->reg){ - case 0: - break; - case 4: - LDW(RA1, 0, RA2); - opwst(i, Stw, RA2); - break; - case 8: - LDW(RA1, 0, RA2); - opwst(i, Lea, RA3); - LDW(RA1, 4, RA1); - STW(RA3, 0, RA2); - STW(RA3, 4, RA1); - break; - default: - // could use ldm/stm loop... - if((i->reg&3) == 0) { - con(i->reg>>2, RA3, 1); - movloop(i, 4); - } else { - con(i->reg, RA3, 1); - movloop(i, 1); - } - break; - } -} - -static -void -compdbg(void) -{ - print("%s:%lud@%.8lux\n", R.M->m->name, *(ulong*)R.m, *(ulong*)R.s); -} - -static void -comgoto(Inst *i) -{ - WORD *t, *e; - - opwld(i, Ldw, RA1); - opwst(i, Lea, RA0); - DPIRRS(Lsl, 2, RA1, RA1); - LDRW(RA0, RA1, RA0); - MOVRH(RA0, RPC); - flushcon(0); - - if(pass != LASTPASS) - return; - - t = (WORD*)(mod->origmp+i->d.ind); - e = t + t[-1]; - t[-1] = 0; - while(t < e) { - t[0] = RELPC(patch[t[0]]); - t++; - } -} - -static void -comp(Inst *i) -{ - int r, imm; - char buf[64]; - ushort *label, *label1; - - flushchk(); - - switch(i->op) { - default: - snprint(buf, sizeof buf, "%s compile, no '%D'", mod->name, i); - error(buf); - break; - case IMCALL: - if((i->add&ARM) == AXIMM) - commcall(i); - else - punt(i, SRCOP|DSTOP|THREOP|WRTPC|NEWPC, optab[i->op]); - break; - case ISEND: - case IRECV: - case IALT: - punt(i, SRCOP|DSTOP|TCHECK|WRTPC, optab[i->op]); - break; - case ISPAWN: - punt(i, SRCOP|DBRAN, optab[i->op]); - break; - case IBNEC: - case IBEQC: - case IBLTC: - case IBLEC: - case IBGTC: - case IBGEC: - punt(i, SRCOP|DBRAN|NEWPC|WRTPC, optab[i->op]); - break; - case ICASEC: - comcase(i, 0); - punt(i, SRCOP|DSTOP|NEWPC, optab[i->op]); - break; - case ICASEL: - comcasel(i); - punt(i, SRCOP|DSTOP|NEWPC, optab[i->op]); - break; - case IADDC: - case IMULL: - case IDIVL: - case IMODL: - case IMNEWZ: - // case ILSRW: - case ILSRL: - case IMODW: - case IMODB: - case IDIVW: - case IDIVB: - punt(i, SRCOP|DSTOP|THREOP, optab[i->op]); - break; -/* - case IMODW: - case IMODB: - case IDIVW: - case IDIVB: - SUBSP(8); - mid(i, Ldw, RA0); - MOVRH(RA0, RTMP); - opwld(i, Ldw, RA0); - STSP(4, RA0); // movw RA0, 4(SP) - call // need to save, restore context - MOVHR(RTMP, RA0); - opwst(i, Stw, RA0); - ADDSP(8); -*/ - case ILOAD: - case INEWA: - case INEWAZ: - case INEW: - case INEWZ: - case ISLICEA: - case ISLICELA: - case ICONSB: - case ICONSW: - case ICONSL: - case ICONSF: - case ICONSM: - case ICONSMP: - case ICONSP: - case IMOVMP: - case IHEADMP: - // case IHEADB: - // case IHEADW: - // case IHEADL: - // case IHEADF: - case IINSC: - case ICVTAC: - case ICVTCW: - case ICVTWC: - case ICVTLC: - case ICVTCL: - case ICVTFC: - case ICVTCF: - case ICVTRF: - case ICVTFR: - case ICVTWS: - case ICVTSW: - case IMSPAWN: - case ICVTCA: - case ISLICEC: - case INBALT: - punt(i, SRCOP|DSTOP, optab[i->op]); - break; - case INEWCM: - case INEWCMP: - punt(i, SRCOP|DSTOP|THREOP, optab[i->op]); - break; - case IMFRAME: - if((i->add&ARM) == AXIMM) - commframe(i); - else - punt(i, SRCOP|DSTOP|THREOP, optab[i->op]); - break; - case ICASE: - comcase(i, 1); - //comcase(i, 0); - //punt(i, SRCOP|DSTOP|NEWPC, optab[i->op]); break; - break; - case IGOTO: - comgoto(i); - //punt(i, SRCOP|DSTOP|NEWPC, optab[i->op]); break; - break; - case IMOVL: - case IMOVF: - opwld(i, Lea, RA1); - LDW(RA1, 0, RA2); - LDW(RA1, 4, RA3); - opwst(i, Lea, RA1); - STW(RA1, 0, RA2); - STW(RA1, 4, RA3); - break; - case IHEADM: - //punt(i, SRCOP|DSTOP, optab[i->op]); break; - opwld(i, Ldw, RA1); - NOTNIL(RA1, RA2); - DPIR(Add, OA(List,data), RA1); - movmem(i); - break; - case IMOVM: - //punt(i, SRCOP|DSTOP, optab[i->op]); break; - opwld(i, Lea, RA1); - movmem(i); - break; - case IFRAME: - if(UXSRC(i->add) != SRC(AIMM)) { - punt(i, SRCOP|DSTOP, optab[i->op]); - break; - } - tinit[i->s.imm] = 1; - con((ulong)mod->type[i->s.imm], RA3, 1); - CALL(base+macro[MacFRAM]); - opwst(i, Stw, RA2); - break; - case INEWCB: - case INEWCW: - case INEWCF: - case INEWCP: - case INEWCL: - punt(i, DSTOP|THREOP, optab[i->op]); - break; - case IEXIT: - punt(i, 0, optab[i->op]); - break; - case ICVTBW: - opwld(i, Ldb, RA0); - opwst(i, Stw, RA0); - break; - case ICVTWB: - opwld(i, Ldw, RA0); - opwst(i, Stb, RA0); - break; - case ILEA: - opwld(i, Lea, RA0); - opwst(i, Stw, RA0); - break; - case IHEADW: - opwld(i, Ldw, RA0); - mem(Ldw, OA(List, data), RA0, RA0); - opwst(i, Stw, RA0); - break; - case IHEADB: - opwld(i, Ldw, RA0); - mem(Ldb, OA(List, data), RA0, RA0); - opwst(i, Stb, RA0); - break; - case IHEADL: - case IHEADF: - opwld(i, Ldw, RA0); - mem(Lea, OA(List, data), RA0, RA0); - LDW(RA0, 0, RA1); - LDW(RA0, 4, RA2); - opwst(i, Lea, RA0); - STW(RA0, 0, RA1); - STW(RA0, 4, RA2); - break; - case IMOVW: - opwld(i, Ldw, RA0); - opwst(i, Stw, RA0); - break; - case IMOVB: - opwld(i, Ldb, RA0); - opwst(i, Stb, RA0); - break; - case ITAIL: - opwld(i, Ldw, RA0); - NOTNIL(RA0, RA1); - mem(Ldw, O(List, tail), RA0, RA1); - goto movp; - case IMOVP: - opwld(i, Ldw, RA1); - goto movp; - case IHEADP: - opwld(i, Ldw, RA0); - NOTNIL(RA0, RA1); - mem(Ldw, OA(List, data), RA0, RA1); - movp: - CMPH(RA1, RA2); - label = code; - CJUMP(NE, NOBR); - CALLMAC(MacCOLR); // colour if not H - CPATCH(label); - opwst(i, Lea, RA2); - mem(Ldw, 0, RA2, RA0); - mem(Stw, 0, RA2, RA1); - CALLMAC(MacFRP); - break; - case ILENA: - opwld(i, Ldw, RA1); - con(0, RA0, 1); - CMPH(RA1, RA2); - CJUMP(NE, 4); - LDW(RA1, O(Array,len), RA0); - opwst(i, Stw, RA0); - break; - case ILENC: - opwld(i, Ldw, RA1); - con(0, RA0, 1); - CMPH(RA1, RA2); - label = code; - CJUMP(NE, NOBR); - mem(Ldw, O(String,len),RA1, RA0); - CPATCH(label); - CMPI(0, RA0); - CJUMP(LT, 4); - DPRR(Neg, RA0, RA0); - opwst(i, Stw, RA0); - break; - case ILENL: - con(0, RA0, 1); - opwld(i, Ldw, RA1); - - label = code; - CMPH(RA1, RA2); - label1 = code; - CJUMP(NE, NOBR); - LDW(RA1, O(List, tail), RA1); - DPIR(Add, 1, RA0); - BRA(BPATCH(label)); - CPATCH(label1); - - opwst(i, Stw, RA0); - break; - case ICALL: - opwld(i, Ldw, RA0); - con(RELPC(patch[i-mod->prog+1]), RA1, 0); - mem(Stw, O(Frame, lr), RA0, RA1); - mem(Stw, O(Frame, fp), RA0, RFP); - MOV(RA0, RFP); - BRADIS(i->d.ins-mod->prog); - flushcon(0); - break; - case IJMP: - if(RESCHED) - schedcheck(i); - BRADIS(i->d.ins-mod->prog); - flushcon(0); - break; - case IBEQW: - cbra(i, EQ); - break; - case IBNEW: - cbra(i, NE); - break; - case IBLTW: - cbra(i, LT); - break; - case IBLEW: - cbra(i, LE); - break; - case IBGTW: - cbra(i, GT); - break; - case IBGEW: - cbra(i, GE); - break; - case IBEQB: - cbrab(i, EQ); - break; - case IBNEB: - cbrab(i, NE); - break; - case IBLTB: - cbrab(i, LT); - break; - case IBLEB: - cbrab(i, LE); - break; - case IBGTB: - cbrab(i, GT); - break; - case IBGEB: - cbrab(i, GE); - break; - case IBEQF: - cbraf(i, EQ); - break; - case IBNEF: - cbraf(i, NE); - break; - case IBLTF: - cbraf(i, LT); - break; - case IBLEF: - cbraf(i, LE); - break; - case IBGTF: - cbraf(i, GT); - break; - case IBGEF: - cbraf(i, GE); - break; - case IRET: - //punt(i, TCHECK|NEWPC, optab[i->op]); break; - mem(Ldw, O(Frame,t), RFP, RA1); - BRAMAC(MacRET); - break; - case IMULW: - opwld(i, Ldw, RA1); - mid(i, Ldw, RA0); - MUL(RA1, RA0); - opwst(i, Stw, RA0); - break; - case IMULB: - opwld(i, Ldb, RA1); - mid(i, Ldb, RA0); - MUL(RA1, RA0); - opwst(i, Stb, RA0); - break; - case IORW: - r = Orr; - goto arithw; - case IANDW: - r = And; - goto arithw; - case IXORW: - r = Eor; - goto arithw; - case ISUBW: - r = Sub; - goto arithw; - case IADDW: - r = Add; - arithw: - mid(i, Ldw, RA1); - if((r == Add || r == Sub) && UXSRC(i->add) == SRC(AIMM) && FITS3(i->s.imm)){ - DPIRR(r, i->s.imm, RA1, RA0); - opwst(i, Stw, RA0); - } - else { - opwld(i, Ldw, RA0); - if(r == Add || r == Sub){ - DPRRR(r, RA0, RA1, RA0); - opwst(i, Stw, RA0); - } - else{ - DPRR(r, RA0, RA1); - opwst(i, Stw, RA1); - } - } - break; - case ISHRW: - r = Asr; - shiftw: - mid(i, Ldw, RA1); - if(UXSRC(i->add) == SRC(AIMM) && FITS5(i->s.imm)){ - DPIRRS(r, i->s.imm, RA1, RA0); - opwst(i, Stw, RA0); - } - else { - opwld(i, Ldw, RA0); - DPRR(r, RA0, RA1); - opwst(i, Stw, RA1); - } - break; - case ISHLW: - r = Lsl; - goto shiftw; - break; - case ILSRW: - r = Lsr; - goto shiftw; - break; - case IORB: - r = Orr; - goto arithb; - case IANDB: - r = And; - goto arithb; - case IXORB: - r = Eor; - goto arithb; - case ISUBB: - r = Sub; - goto arithb; - case IADDB: - r = Add; - arithb: - mid(i, Ldb, RA1); - if((r == Add || r == Sub) && UXSRC(i->add) == SRC(AIMM) && FITS3(i->s.imm)){ - DPIRR(r, i->s.imm, RA1, RA0); - opwst(i, Stb, RA0); - } - else { - opwld(i, Ldb, RA0); - if(r == Add || r == Sub){ - DPRRR(r, RA0, RA1, RA0); - opwst(i, Stb, RA0); - } - else{ - DPRR(r, RA0, RA1); - opwst(i, Stb, RA1); - } - } - break; - case ISHRB: - r = Asr; - goto shiftb; - case ISHLB: - r = Lsl; - shiftb: - mid(i, Ldb, RA1); - if(UXSRC(i->add) == SRC(AIMM) && FITS5(i->s.imm)){ - DPIRRS(r, i->s.imm, RA1, RA0); - opwst(i, Stb, RA0); - } - else { - opwld(i, Ldw, RA0); - DPRR(r, RA0, RA1); - opwst(i, Stb, RA1); - } - break; - case IINDC: - opwld(i, Ldw, RA1); // RA1 = string - NOTNIL(RA1, RA2); - imm = 1; - if((i->add&ARM) != AXIMM || !FITS8((short)i->reg<<1)){ - mid(i, Ldw, RA2); // RA2 = i - imm = 0; - } - mem(Ldw, O(String,len),RA1, RA0); // len<0 => index Runes, otherwise bytes - // BUG: check !((ulong)i >= abs(a->len)) - DPIR(Add, O(String,data), RA1); - CMPI(0, RA0); - if(imm){ - label = code; - CJUMP(GE, NOBR); - if(i->reg < BITS(5)) - LDB(RA1, i->reg, RA3); - else{ - con(i->reg, RCON, 1); - LDRB(RA1, RCON, RA3); - } - CPATCH(label); - label = code; - CJUMP(LT, NOBR); - if((ushort)((short)i->reg<<1) < BITS(6)) - LDH(RA1, (short)i->reg<<1, RA3); - else{ - con((short)i->reg<<1, RCON, 1); - LDRH(RA1, RCON, RA3); - } - CPATCH(label); - } else { - CJUMP(GE, 4); - LDRB(RA1, RA2, RA3); - CJUMP(LT, 6); - DPIRRS(Lsl, 1, RA2, RA2); - LDRH(RA1, RA2, RA3); - } - opwst(i, Stw, RA3); - break; - case IINDL: - case IINDF: - case IINDW: - case IINDB: - opwld(i, Ldw, RA0); /* a */ - NOTNIL(RA0, RA1); - mem(Ldw, O(Array, data), RA0, RA0); - r = 0; - switch(i->op) { - case IINDL: - case IINDF: - r = 3; - break; - case IINDW: - r = 2; - break; - } - if(UXDST(i->add) == DST(AIMM) && FITS8(i->d.imm<<r)) { - DPIR(Add, (i->d.imm<<r), RA0); - } else { - opwst(i, Ldw, RA1); - DPIRRS(Lsl, r, RA1, RA1); - DPRRR(Add, RA0, RA1, RA0); - } - mid(i, Stw, RA0); - break; - case IINDX: - opwld(i, Ldw, RA0); /* a */ - NOTNIL(RA0, RA1); - opwst(i, Ldw, RA1); /* i */ - - mem(Ldw, O(Array, t), RA0, RA2); - mem(Ldw, O(Array, data), RA0, RA0); - mem(Ldw, O(Type, size), RA2, RA2); - MUL(RA2, RA1); - DPRRR(Add, RA0, RA1, RA0); - mid(i, Stw, RA0); - break; - case IADDL: - larith(i, Add, Adc); - break; - case ISUBL: - larith(i, Sub, Sbc); - break; - case IORL: - larith(i, Orr, Orr); - break; - case IANDL: - larith(i, And, And); - break; - case IXORL: - larith(i, Eor, Eor); - break; - case ICVTWL: - opwld(i, Ldw, RA1); - opwst(i, Lea, RA2); - DPIRRS(Asr, 16, RA1, RA0); - DPIRRS(Asr, 16, RA0, RA0); - STW(RA2, 0, RA0); - STW(RA2, 4, RA1); - break; - case ICVTLW: - opwld(i, Lea, RA0); - mem(Ldw, 4, RA0, RA0); - opwst(i, Stw, RA0); - break; - case IBEQL: - cbral(i, NE, EQ, ANDAND); - break; - case IBNEL: - cbral(i, NE, NE, OROR); - break; - case IBLEL: - cbral(i, LT, LS, EQAND); - break; - case IBGTL: - cbral(i, GT, HI, EQAND); - break; - case IBLTL: - cbral(i, LT, CC, EQAND); - break; - case IBGEL: - cbral(i, GT, CS, EQAND); - break; - case ICVTFL: - case ICVTLF: - punt(i, SRCOP|DSTOP, optab[i->op]); - break; - // case IMOVF: - // punt(i, SRCOP|DSTOP, optab[i->op]); - // break; - case IDIVF: - goto arithf; - case IMULF: - goto arithf; - case ISUBF: - goto arithf; - case IADDF: - arithf: - punt(i, SRCOP|DSTOP|THREOP, optab[i->op]); - break; - case INEGF: - punt(i, SRCOP|DSTOP, optab[i->op]); - break; - case ICVTWF: - punt(i, SRCOP|DSTOP, optab[i->op]); - break; - case ICVTFW: - punt(i, SRCOP|DSTOP, optab[i->op]); - break; - case ISHLL: - punt(i, SRCOP|DSTOP|THREOP, optab[i->op]); - break; - case ISHRL: - punt(i, SRCOP|DSTOP|THREOP, optab[i->op]); - break; - case IRAISE: - punt(i, SRCOP|WRTPC|NEWPC, optab[i->op]); - break; - case IMULX: - case IDIVX: - case ICVTXX: - case IMULX0: - case IDIVX0: - case ICVTXX0: - case IMULX1: - case IDIVX1: - case ICVTXX1: - case ICVTFX: - case ICVTXF: - case IEXPW: - case IEXPL: - case IEXPF: - punt(i, SRCOP|DSTOP|THREOP, optab[i->op]); - break; - case ISELF: - punt(i, DSTOP, optab[i->op]); - break; - } -} - -static void -preamble(void) -{ - if(comvec) - return; - - comvec = malloc(10 * sizeof(*code)); - if(comvec == nil) - error(exNomem); - code = (ushort*)comvec; - - con((ulong)&R, RREG, 0); - memh(Stw, O(REG, xpc), RREG, RLINK); - mem(Ldw, O(REG, FP), RREG, RFP); - mem(Ldw, O(REG, MP), RREG, RMP); - memh(Ldw, O(REG, PC), RREG, RPC); - pass = LASTPASS; - flushcon(0); - pass = FIRSTPASS; - // print("preamble\n"); - // das((ushort*)comvec, code-(ushort*)comvec); - segflush(comvec, 10 * sizeof(*code)); - comvec =(void *)((ulong)comvec | 1); /* T bit */ -} - -static void -maccase(void) -{ - ushort *cp1, *loop, *inner, *label; -/* - * RA1, RHT = value (input arg), t - * RA2 = count, n - * RA3 = table pointer (input arg) - * RA0 = n/2, n2 - * RCON = pivot element t+n/2*3, l - */ - MOVRH(RA1, RHT); - LDW(RA3, 0, RA2); // count from table - MOVRH(RA3, RLINK); // initial table pointer - - loop = code; // loop: - CMPI(0, RA2); - cp1 = code; - CBRA(LE, NOBR); // n <= 0? goto out - - inner = code; - DPIRRS(Lsr, 1, RA2, RA0); - DPIRRS(Lsl, 1, RA0, RCON); - DPRRR(Add, RA0, RCON, RCON); - DPIRRS(Lsl, 2, RCON, RCON); - DPRRR(Add, RA3, RCON, RCON); - - LDW(RCON, 4, RA1); - CMPRH(RA1, RHT); - label = code; - CJUMP(LT, NOBR); - MOV(RA0, RA2); - BRA(BPATCH(loop)); // v < l[1]? goto loop - CPATCH(label); - - LDW(RCON, 8, RA1); - CMPRH(RA1, RHT); - CJUMP(LT, 6); - LDW(RCON, 12, RA1); - MOVRH(RA1, RPC); // v >= l[1] && v < l[2] => found; goto l[3] - - // v >= l[2] (high) - DPIRR(Add, 7, RCON, RA3); - DPIR(Add, 5, RA3); - DPIRR(Add, 1, RA0, RA1); - DPRRR(Sub, RA1, RA2, RA2); - CBRA(GT, BPATCH(inner)); // n > 0? goto loop - - CPATCH(cp1); // out: - MOVHR(RLINK, RA2); - LDW(RA2, 0, RA2); // initial n - DPIRRS(Lsl, 1, RA2, RA0); - DPRRR(Add, RA2, RA0, RA2); - DPIRRS(Lsl, 2, RA2, RA2); - DPRH(Add, RA2, RLINK); - MOVHR(RLINK, RA2); - LDW(RA2, 4, RA1); - MOVRH(RA1, RPC); // goto (initial t)[n*3+1] -} - -static void -macfrp(void) -{ - ushort *label; - - /* destroy the pointer in RA0 */ - CMPH(RA0, RA2); - CJUMP(EQ, 4); - RETURN; // arg == H? => return - - mem(Ldw, O(Heap, ref)-sizeof(Heap), RA0, RA2); - DPIR(Sub, 1, RA2); - label = code; - CJUMP(NE, NOBR); - mem(Stw, O(Heap, ref)-sizeof(Heap), RA0, RA2); - RETURN; // --h->ref != 0 => return - CPATCH(label); - - mem(Stw, O(REG, FP), RREG, RFP); - memh(Stw, O(REG, st), RREG, RLINK); - mem(Stw, O(REG, s), RREG, RA0); - CALL(rdestroy); - con((ulong)&R, RREG, 1); - memh(Ldw, O(REG, st), RREG, RLINK); - mem(Ldw, O(REG, FP), RREG, RFP); - mem(Ldw, O(REG, MP), RREG, RMP); - RETURN; - flushcon(0); -} - -static void -maccolr(void) -{ - /* color the pointer in RA1 */ - mem(Ldw, O(Heap, ref)-sizeof(Heap), RA1, RA0); - DPIR(Add, 1, RA0); - mem(Stw, O(Heap, ref)-sizeof(Heap), RA1, RA0); // h->ref++ - con((ulong)&mutator, RA2, 1); - mem(Ldw, O(Heap, color)-sizeof(Heap), RA1, RA0); - mem(Ldw, 0, RA2, RA2); - CMP(RA2, RA0); - CJUMP(EQ, 4); - RETURN; // return if h->color == mutator - con(propagator, RA2, 1); - mem(Stw, O(Heap, color)-sizeof(Heap), RA1, RA2); // h->color = propagator - con((ulong)&nprop, RA2, 1); - mem(Stw, 0, RA2, RA2); // nprop = !0 - RETURN; - flushcon(0); -} - -static void -macret(void) -{ - Inst i; - ushort *cp1, *cp2, *cp3, *cp4, *cp5, *linterp; - - CMPI(0, RA1); - cp1 = code; - CBRA(EQ, NOBR); // t(Rfp) == 0 - - mem(Ldw, O(Type,destroy),RA1, RA0); - CMPI(0, RA0); - cp2 = code; - CBRA(EQ, NOBR); // destroy(t(fp)) == 0 - - mem(Ldw, O(Frame,fp),RFP, RA2); - CMPI(0, RA2); - cp3 = code; - CBRA(EQ, NOBR); // fp(Rfp) == 0 - - mem(Ldw, O(Frame,mr),RFP, RA3); - CMPI(0, RA3); - cp4 = code; - CBRA(EQ, NOBR); // mr(Rfp) == 0 - - mem(Ldw, O(REG,M),RREG, RA2); - mem(Ldw, O(Heap,ref)-sizeof(Heap),RA2, RA3); - DPIR(Sub, 1, RA3); - cp5 = code; - CBRA(EQ, NOBR); // --ref(arg) == 0 - mem(Stw, O(Heap,ref)-sizeof(Heap),RA2, RA3); - - mem(Ldw, O(Frame,mr),RFP, RA1); - mem(Stw, O(REG,M),RREG, RA1); - mem(Ldw, O(Modlink,MP),RA1, RMP); - mem(Stw, O(REG,MP),RREG, RMP); - mem(Ldw, O(Modlink,compiled), RA1, RA3); // R.M->compiled - CMPI(0, RA3); - linterp = code; - CBRA(EQ, NOBR); - - CPATCH(cp4); - MOVHH(RPC, RLINK); // call destroy(t(fp)) - MOVRH(RA0, RPC); - - mem(Stw, O(REG,SP),RREG, RFP); - mem(Ldw, O(Frame,lr),RFP, RA1); - mem(Ldw, O(Frame,fp),RFP, RFP); - mem(Stw, O(REG,FP),RREG, RFP); // R.FP = RFP - MOVRH(RA1, RPC); - - CPATCH(linterp); - MOVHH(RPC, RLINK); // call destroy(t(fp)) - MOVRH(RA0, RPC); - - mem(Stw, O(REG,SP),RREG, RFP); - mem(Ldw, O(Frame,lr),RFP, RA1); - mem(Ldw, O(Frame,fp),RFP, RFP); - mem(Stw, O(REG,PC),RREG, RA1); // R.PC = fp->lr - mem(Stw, O(REG,FP),RREG, RFP); // R.FP = RFP - memh(Ldw, O(REG, xpc), RREG, RLINK); - RETURN; // return to xec uncompiled code - - CPATCH(cp1); - CPATCH(cp2); - CPATCH(cp3); - CPATCH(cp5); - i.add = AXNON; - punt(&i, TCHECK|NEWPC, optab[IRET]); -} - -static void -macmcal(void) -{ - ushort *lab, *label; - - CMPH(RA0, RA1); - label = code; - CJUMP(NE, NOBR); - mem(Ldw, O(Modlink, prog), RA3, RA1); // RA0 != H - CMPI(0, RA1); // RA0 != H - lab = code; - CBRA(NE, NOBR); // RA0 != H && m->prog!=0 - CPATCH(label); - - memh(Stw, O(REG, st), RREG, RLINK); - mem(Stw, O(REG, FP), RREG, RA2); - mem(Stw, O(REG, dt), RREG, RA0); - CALL(rmcall); // CALL rmcall - - con((ulong)&R, RREG, 1); // MOVL $R, RREG - memh(Ldw, O(REG, st), RREG, RLINK); - mem(Ldw, O(REG, FP), RREG, RFP); - mem(Ldw, O(REG, MP), RREG, RMP); - RETURN; - - CPATCH(lab); // patch: - MOV(RA2, RFP); - mem(Stw, O(REG, M), RREG, RA3); // MOVL RA3, R.M - mem(Ldw, O(Heap, ref)-sizeof(Heap), RA3, RA1); - DPIR(Add, 1, RA1); - mem(Stw, O(Heap, ref)-sizeof(Heap), RA3, RA1); - mem(Ldw, O(Modlink, MP), RA3, RMP); // MOVL R.M->mp, RMP - mem(Stw, O(REG, MP), RREG, RMP); // MOVL RA3, R.MP R.MP = ml->m - mem(Ldw, O(Modlink,compiled), RA3, RA1); // M.compiled? - CMPI(0, RA1); - CJUMP(NE, 4); - MOVRH(RA0, RPC); - mem(Stw, O(REG,FP),RREG, RFP); // R.FP = RFP - mem(Stw, O(REG,PC),RREG, RA0); // R.PC = RPC - memh(Ldw, O(REG, xpc), RREG, RLINK); - RETURN; // return to xec uncompiled code - flushcon(0); -} - -static void -macfram(void) -{ - ushort *lab1; - - mem(Ldw, O(REG, SP), RREG, RA0); // MOVL R.SP, RA0 - mem(Ldw, O(Type, size), RA3, RA1); - DPRRR(Add, RA0, RA1, RA0); - mem(Ldw, O(REG, TS), RREG, RA1); - CMP(RA1, RA0); // nsp :: R.TS - lab1 = code; - CBRA(CS, NOBR); // nsp >= R.TS; must expand - - mem(Ldw, O(REG, SP), RREG, RA2); // MOVL R.SP, RA2 - mem(Stw, O(REG, SP), RREG, RA0); // MOVL RA0, R.SP - - mem(Stw, O(Frame, t), RA2, RA3); // MOVL RA3, t(RA2) f->t = t - con(0, RA0, 1); - mem(Stw, O(Frame,mr), RA2, RA0); // MOVL $0, mr(RA2) f->mr - memh(Ldw, O(Type, initialize), RA3, RPC); // become t->init(RA2), returning RA2 - - CPATCH(lab1); - mem(Stw, O(REG, s), RREG, RA3); - memh(Stw, O(REG, st), RREG, RLINK); - mem(Stw, O(REG, FP), RREG, RFP); // MOVL RFP, R.FP - CALL(extend); // CALL extend - - con((ulong)&R, RREG, 1); - memh(Ldw, O(REG, st), RREG, RLINK); - mem(Ldw, O(REG, FP), RREG, RFP); // MOVL R.FP, RFP - mem(Ldw, O(REG, s), RREG, RA2); // MOVL R.s, *R.d - mem(Ldw, O(REG, MP), RREG, RMP); // MOVL R.MP, RMP - RETURN; // RET -} - -static void -macmfra(void) -{ - memh(Stw, O(REG, st), RREG, RLINK); - mem(Stw, O(REG, s), RREG, RA3); // Save type - mem(Stw, O(REG, d), RREG, RA0); // Save destination - mem(Stw, O(REG, FP), RREG, RFP); - CALL(rmfram); // CALL rmfram - - con((ulong)&R, RREG, 1); - memh(Ldw, O(REG, st), RREG, RLINK); - mem(Ldw, O(REG, FP), RREG, RFP); - mem(Ldw, O(REG, MP), RREG, RMP); - RETURN; -} - -static void -macrelq(void) -{ - mem(Stw, O(REG,FP),RREG, RFP); // R.FP = RFP - memh(Stw, O(REG,PC),RREG, RLINK); // R.PC = RLINK - memh(Ldw, O(REG, xpc), RREG, RLINK); - RETURN; -} - -void -comd(Type *t) -{ - int i, j, m, c; - - memh(Stw, O(REG, dt), RREG, RLINK); - for(i = 0; i < t->np; i++) { - c = t->map[i]; - j = i<<5; - for(m = 0x80; m != 0; m >>= 1) { - if(c & m) { - mem(Ldw, j, RFP, RA0); - CALL(base+macro[MacFRP]); - } - j += sizeof(WORD*); - } - flushchk(); - } - memh(Ldw, O(REG, dt), RREG, RLINK); - RETURN; - flushcon(0); -} - -void -comi(Type *t) -{ - int i, j = 0, m, c, r; - - if(t->np > 4){ - r = RA3; - MOV(RA2, RA3); - } - else - r = RA2; - con((ulong)H, RA0, 1); - for(i = 0; i < t->np; i++) { - c = t->map[i]; - if(j == 128){ - if(t->np <= 4) print("error: bad j in comi\n"); - DPIR(Add, 128, RA3); - j = 0; - } - for(m = 0x80; m != 0; m >>= 1) { - if(c & m) - mem(Stw, j, r, RA0); - j += sizeof(WORD*); - } - flushchk(); - } - RETURN; - flushcon(0); -} - -void -typecom(Type *t) -{ - int n; - ushort *tmp, *start; - - if(t == nil || t->initialize != 0) - return; - - tmp = mallocz(4096*sizeof(ulong), 0); - if(tmp == nil) - error(exNomem); - - code = tmp; - comi(t); - n = code - tmp; - code = tmp; - comd(t); - n += code - tmp; - free(tmp); - - n *= sizeof(*code); - code = mallocz(n, 0); - if(code == nil) - return; - - start = code; - t->initialize = code; - comi(t); - t->destroy = code; - comd(t); - - segflush(start, n); - -// print("type\n"); -// das(start, code-start); - - if(cflag > 1) - print("typ= %.8lux %4d i %.8lux d %.8lux asm=%d\n", - t, t->size, t->initialize, t->destroy, n); -} - -static void -patchex(Module *m, ulong *p) -{ - Handler *h; - Except *e; - - if((h = m->htab) == nil) - return; - for( ; h->etab != nil; h++){ - h->pc1 = p[h->pc1]; - h->pc2 = p[h->pc2]; - for(e = h->etab; e->s != nil; e++) - e->pc = p[e->pc]; - if(e->pc != -1) - e->pc = p[e->pc]; - } -} - -int -compile(Module *m, int size, Modlink *ml) -{ - Link *l; - Modl *e; - int i, n; - ushort *s, *tmp; - int again, lastc = 0, lastn = 0; - - base = nil; - patch = mallocz(size*sizeof(*patch), 0); - tinit = malloc(m->ntype*sizeof(*tinit)); - tmp = malloc(4096*sizeof(ulong)); - base = tmp; - if(tinit == nil || patch == nil || tmp == nil) - goto bad; - - preamble(); - - mod = m; - pass = FIRSTPASS; - - do{ - again = 0; - n = 0; - nlit = 0; - - for(i = 0; i < size; i++) { - codeoff = n; - code = tmp; - comp(&m->prog[i]); - if(patch[i] != n) - again = 1; - patch[i] = n; - n += code - tmp; - } - - for(i = 0; i < nelem(mactab); i++) { - codeoff = n; - code = tmp; - mactab[i].gen(); - if(macro[mactab[i].idx] != n) - again = 1; - macro[mactab[i].idx] = n; - n += code - tmp; - } - code = tmp; - flushcon(0); - n += code - tmp; - if(code-tmp != lastc || n != lastn) - again = 1; - lastc = code-tmp; - lastn = n; - - if(pass == FIRSTPASS) - pass = MIDDLEPASS; - - }while(again); - - base = mallocz((n+nlit)*sizeof(*code), 0); - if(base == nil) - goto bad; - - if(cflag > 1) - print("dis=%5d %5d 386=%5d asm=%.8lux: %s\n", - size, size*sizeof(Inst), n, base, m->name); - - pass = LASTPASS; - nlit = 0; - litpool = base+n; - code = base; - n = 0; - codeoff = 0; - for(i = 0; i < size; i++) { - s = code; - comp(&m->prog[i]); - if(patch[i] != n) { - print("%3d %D\n", i, &m->prog[i]); - print("error: %lud != %d\n", patch[i], n); - urk("phase error"); - } - n += code - s; - if(cflag > 2) { - print("%3d %D\n", i, &m->prog[i]); - das(s, code-s); - } - } - - for(i = 0; i < nelem(mactab); i++) { - s = code; - mactab[i].gen(); - if(macro[mactab[i].idx] != n){ - print("error: mac phase err: %lud != %d\n", macro[mactab[i].idx], n); - urk("phase error"); - } - n += code - s; - if(cflag > 2) { - print("%s:\n", mactab[i].name); - das(s, code-s); - } - } - s = code; - flushcon(0); - n += code - s; - - for(l = m->ext; l->name; l++) { - l->u.pc = (Inst*)RELPC(patch[l->u.pc-m->prog]); - typecom(l->frame); - } - if(ml != nil) { - e = &ml->links[0]; - for(i = 0; i < ml->nlinks; i++) { - e->u.pc = (Inst*)RELPC(patch[e->u.pc-m->prog]); - typecom(e->frame); - e++; - } - } - for(i = 0; i < m->ntype; i++) { - if(tinit[i] != 0) - typecom(m->type[i]); - } - patchex(m, patch); - m->entry = (Inst*)RELPC(patch[mod->entry-mod->prog]); - free(patch); - free(tinit); - free(tmp); - free(m->prog); - m->prog = (Inst*)base; - m->compiled = 1; - segflush(base, n*sizeof(*base)); -// print("comvec at %lux\n", (ulong)comvec); -// print("base at %lux-%lux\n", (ulong)base, (ulong)base+2*n); -// print("entry %lux prog %lux\n", (ulong)m->entry, (ulong)m->prog); - return 1; -bad: - free(patch); - free(tinit); - free(base); - free(tmp); - return 0; -} diff --git a/libinterp/das-68000.c b/libinterp/das-68000.c deleted file mode 100644 index 9676141f..00000000 --- a/libinterp/das-68000.c +++ /dev/null @@ -1 +0,0 @@ -#include "das-68020.c" diff --git a/libinterp/das-68020.c b/libinterp/das-68020.c deleted file mode 100644 index baca98ec..00000000 --- a/libinterp/das-68020.c +++ /dev/null @@ -1,1940 +0,0 @@ -#include <lib9.h> -#include <kernel.h> - -/* - * 68020-specific debugger interface - */ - -static int m68020inst(ulong, char, char*, int); -static int m68020das(ulong, char*, int); -static int m68020instlen(ulong); - -#define werrstr print -/* - * 68020 exception frames - */ - -#define BPTTRAP 4 /* breakpoint gives illegal inst */ - -static char * excep[] = { - [2] "bus error", - [3] "address error", - [4] "illegal instruction", - [5] "zero divide", - [6] "CHK", - [7] "TRAP", - [8] "privilege violation", - [9] "Trace", - [10] "line 1010", - [11] "line 1011", - [13] "coprocessor protocol violation", - [24] "spurious", - [25] "incon", - [26] "tac", - [27] "auto 3", - [28] "clock", - [29] "auto 5", - [30] "parity", - [31] "mouse", - [32] "system call", - [33] "system call 1", - [48] "FPCP branch", - [49] "FPCP inexact", - [50] "FPCP zero div", - [51] "FPCP underflow", - [52] "FPCP operand err", - [53] "FPCP overflow", - [54] "FPCP signal NAN", -}; - -static int m68020vec; -static -struct ftype{ - short fmt; - short len; - char *name; -} ftype[] = { /* section 6.5.7 page 6-24 */ - { 0, 4*2, "Short Format" }, - { 1, 4*2, "Throwaway" }, - { 2, 6*2, "Instruction Exception" }, - { 3, 6*2, "MC68040 Floating Point Exception" }, - { 8, 29*2, "MC68010 Bus Fault" }, - { 7, 30*2, "MC68040 Bus Fault" }, - { 9, 10*2, "Coprocessor mid-Instruction" }, - { 10, 16*2, "MC68020 Short Bus Fault" }, - { 11, 46*2, "MC68020 Long Bus Fault" }, - { 0, 0, 0 } -}; -static uchar *dasdata; - -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; -} - - /* 68020 Disassembler and related functions */ -/* -not supported: cpBcc, cpDBcc, cpGEN, cpScc, cpTRAPcc, cpRESTORE, cpSAVE - -opcode: 1 1 1 1 1 1 - 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 -%y - register number x x x -%f - trap vector x x x -%e - destination eff addr x x x x x x -%p - conditional predicate x x x x x x -%s - size code x x -%C - cache code x x -%E - source eff addr. x x x x x x -%d - direction bit x -%c - condition code x x x x -%x - register number x x x -%b - shift count x x x -%q - daffy 3-bit quick operand or shift count x x x -%i - immediate operand <varies> -%t - offset(PC) <varies> - -word 1: 1 1 1 1 1 1 - 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 -%a - register number x x x -%w - bit field width x x x x x -%L - MMU function code (SFC/DFC/D%a/#[0-3]) x x x x x -%P - conditional predicate x x x x x x -%k - k factor x x x x x x x -%m - register mask x x x x x x x x -%N - control register id x x x x x x x x x x x x -%j - (Dq != Dr) ? Dq:Dr : Dr x x x x x x -%K - dynamic k register x x x -%h - register number x x x -%I - MMU function code mask x x x x -%o - bit field offset x x x x x -%u - register number x x x -%D - float dest reg x x x -%F - (fdr==fsr) ? "F%D" :"F%B,F%D" x x x x x x -%S - float source type x x x -%B - float source register x x x -%Z - ATC level number x x x -%H - MMU register x x x x -%r - register type/number x x x x - -word 2: 1 1 1 1 1 1 - 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 -%A - register number x x x -%U - register number x x x -%R - register type,number x x x x - ------------------------------------------------------------------------------ - -%a - register [word 1: 0-2] -%c - condition code [opcode: 8-11] -%d - direction [opcode: 8] -%e - destination effective address [opcode: 0-5] -%f - trap vector [opcode: 0-3] -%h - register [word 1: 5-7] -%i - immediate operand (1, 2, or 4 bytes) -%j - Dq:Dr if Dq != Dr; else Dr => Dr [word 1: 0-2] Dq [word 1: 12-14] -%k - k factor [word 1: 0-6] -%m - register mask [word 1: 0-7] -%o - bit field offset [word 1: 6-10] -%p - conditional predicate [opcode: 0-5] -%q - daffy 3-bit quick operand [opcode: 9-11] -%r - register type, [word 1: 15], register [word 1: 12-14] -%s - size [opcode: 6-7] -%t - offset beyond pc (text address) (2 or 4 bytes) -%u - register [word 1: 6-8] -%w - bit field width [word 1: 0-4] -%x - register [opcode: 9-11] -%y - register [opcode: 0-2] -%A - register [word 2: 0-2] -%B - float source register [word 1: 10-12] -%C - cache identifier [opcode: 6-7] (IC, DC, or BC) -%D - float dest reg [word 1: 7-9] -%E - dest effective address [opcode: 6-11] -%F - float dest reg == float src reg => "F%D"; else "F%B,F%D" -%H - MMU reg [word 1: 10-13] (see above & p 4-53/54) -%I - MMU function code mask [word 1: 5-8] -%K - dynamic k factor register [word 1: 4-6] -%L - MMU function code [word 1: 0-4] (SFC, DFC, D%a, or #[0-3]) -%N - control register [word 1: 0-11] -%P - conditional predicate [word 1: 0-5] -%R - register type, [word 2: 15], register [word 2: 12-14] -%S - float source type code [word 1: 10-12] -%U - register [word 2: 6-8] -%Z - ATC level number [word 1: 10-12] -%1 - Special case: EA as second operand -*/ - /* Operand classes */ -enum { - EAPI = 1, /* extended address: pre decrement only */ - EACA, /* extended address: control alterable */ - EACAD, /* extended address: control alterable or Dreg */ - EACAPI, /* extended address: control alterable or post-incr */ - EACAPD, /* extended address: control alterable or pre-decr */ - EAMA, /* extended address: memory alterable */ - EADA, /* extended address: data alterable */ - EAA, /* extended address: alterable */ - EAC, /* extended address: control addressing */ - EACPI, /* extended address: control addressing or post-incr */ - EACD, /* extended address: control addressing or Dreg */ - EAD, /* extended address: data addressing */ - EAM, /* extended address: memory addressing */ - EAM_B, /* EAM with byte immediate data */ - EADI, /* extended address: data addressing or immediate */ - EADI_L, /* EADI with long immediate data */ - EADI_W, /* EADI with word immediate data */ - EAALL, /* extended address: all modes */ - EAALL_L, /* EAALL with long immediate data */ - EAALL_W, /* EAALL with word immediate data */ - EAALL_B, /* EAALL with byte immediate date */ - /* special codes not directly used for validation */ - EAFLT, /* extended address: EADI for B, W, L, or S; else EAM */ - EADDA, /* destination extended address: EADA */ - BREAC, /* EAC operand for JMP or CALL */ - OP8, /* low 8 bits of op word */ - I8, /* low 8-bits of first extension word */ - I16, /* 16 bits in first extension word */ - I32, /* 32 bits in first and second extension words */ - IV, /* 8, 16 or 32 bit data in first & 2nd extension words */ - C16, /* CAS2 16 bit immediate with bits 9-11 & 3-5 zero */ - BR8, /* 8 bits in op word or 16 or 32 bits in extension words - branch instruction format (p. 2-25) */ - BR16, /* 16-bit branch displacement */ - BR32, /* 32-bit branch displacement */ - STACK, /* return PC on stack - follow set only */ -}; - /* validation bit masks for various EA classes */ -enum { - Dn = 0x0001, /* Data register */ - An = 0x0002, /* Address register */ - Ind = 0x0004, /* Address register indirect */ - Pinc = 0x0008, /* Address register indirect post-increment */ - Pdec = 0x0010, /* Address register indirect pre-decrement */ - Bdisp = 0x0020, /* Base/Displacement in all its forms */ - PCrel = 0x0040, /* PC relative addressing in all its forms */ - Imm = 0x0080, /* Immediate data */ - Abs = 0x0100, /* Absolute */ -}; - /* EA validation table indexed by operand class number */ - -static short validea[] = -{ - 0, /* none */ - Pdec, /* EAPI */ - Abs|Bdisp|Ind, /* EACA */ - Abs|Bdisp|Ind|Dn, /* EACAD */ - Abs|Bdisp|Pinc|Ind, /* EACAPI */ - Abs|Bdisp|Pdec|Ind, /* EACAPD */ - Abs|Bdisp|Pdec|Pinc|Ind, /* EAMA */ - Abs|Bdisp|Pdec|Pinc|Ind|Dn, /* EADA */ - Abs|Bdisp|Pdec|Pinc|Ind|An|Dn, /* EAA */ - Abs|PCrel|Bdisp|Ind, /* EAC */ - Abs|PCrel|Bdisp|Pinc|Ind, /* EACPI */ - Abs|PCrel|Bdisp|Ind|Dn, /* EACD */ - Abs|PCrel|Bdisp|Pdec|Pinc|Ind|Dn, /* EAD */ - Abs|Imm|PCrel|Bdisp|Pdec|Pinc|Ind, /* EAM */ - Abs|Imm|PCrel|Bdisp|Pdec|Pinc|Ind, /* EAM_B */ - Abs|Imm|PCrel|Bdisp|Pdec|Pinc|Ind|Dn, /* EADI */ - Abs|Imm|PCrel|Bdisp|Pdec|Pinc|Ind|Dn, /* EADI_L */ - Abs|Imm|PCrel|Bdisp|Pdec|Pinc|Ind|Dn, /* EADI_W */ - Abs|Imm|PCrel|Bdisp|Pdec|Pinc|Ind|An|Dn, /* EAALL */ - Abs|Imm|PCrel|Bdisp|Pdec|Pinc|Ind|An|Dn, /* EAALL_L */ - Abs|Imm|PCrel|Bdisp|Pdec|Pinc|Ind|An|Dn, /* EAALL_W */ - Abs|Imm|PCrel|Bdisp|Pdec|Pinc|Ind|An|Dn, /* EAALL_B */ -}; - /* EA types */ -enum -{ - Dreg, /* Dn */ - Areg, /* An */ - AInd, /* (An) */ - APdec, /* -(An) */ - APinc, /* (An)+ */ - ADisp, /* Displacement beyond (An) */ - BXD, /* Base, Index, Displacement */ - PDisp, /* Displacement beyond PC */ - PXD, /* PC, Index, Displacement */ - ABS, /* absolute */ - IMM, /* immediate */ - IREAL, /* single precision real immediate */ - IEXT, /* extended precision real immediate */ - IPACK, /* packed real immediate */ - IDBL, /* double precision real immediate */ -}; - -typedef struct optable Optable; -typedef struct operand Operand; -typedef struct inst Inst; - -struct optable -{ - ushort opcode; - ushort mask0; - ushort op2; - ushort mask1; - char opdata[2]; - char *format; -}; - -struct operand -{ - int eatype; - short ext; - union { - long immediate; /* sign-extended integer byte/word/long */ - struct { /* index mode displacements */ - long disp; - long outer; - }; - char floater[24]; /* floating point immediates */ - }; -}; - -struct inst -{ - int n; /* # bytes in instruction */ - ulong addr; /* addr of start of instruction */ - ushort raw[4+12]; /* longest instruction: 24 byte packed immediate */ - Operand and[2]; - char *end; /* end of print buffer */ - char *curr; /* current fill point in buffer */ - char *errmsg; -}; - /* class 0: bit field, MOVEP & immediate instructions */ -static Optable t0[] = { -{ 0x003c, 0xffff, 0x0000, 0xff00, {I8}, "ORB %i,CCR" }, -{ 0x007c, 0xffff, 0x0000, 0x0000, {I16}, "ORW %i,SR" }, -{ 0x023c, 0xffff, 0x0000, 0xff00, {I8}, "ANDB %i,CCR" }, -{ 0x027c, 0xffff, 0x0000, 0x0000, {I16}, "ANDW %i,SR" }, -{ 0x0a3c, 0xffff, 0x0000, 0xff00, {I8}, "EORB %i,CCR" }, -{ 0x0a7c, 0xffff, 0x0000, 0x0000, {I16}, "EORW %i,SR" }, -{ 0x0cfc, 0xffff, 0x0000, 0x0000, {C16,C16}, "CAS2W R%a:R%A,R%u:R%U,(%r):(%R)"} , -{ 0x0efc, 0xffff, 0x0000, 0x0000, {C16,C16}, "CAS2L R%a:R%A,R%u:R%U,(%r):(%R)"} , - -{ 0x06c0, 0xfff8, 0x0000, 0x0000, {0}, "RTM R%y" }, -{ 0x06c8, 0xfff8, 0x0000, 0x0000, {0}, "RTM A%y" }, -{ 0x0800, 0xfff8, 0x0000, 0x0000, {I16}, "BTSTL %i,R%y" }, -{ 0x0840, 0xfff8, 0x0000, 0x0000, {I16}, "BCHGL %i,R%y" }, -{ 0x0880, 0xfff8, 0x0000, 0x0000, {I16}, "BCLRL %i,R%y" }, - -{ 0x00c0, 0xffc0, 0x0000, 0x0fff, {EAC}, "CMP2B %e,%r" }, -{ 0x00c0, 0xffc0, 0x0800, 0x0fff, {EAC}, "CHK2B %e,%r" }, -{ 0x02c0, 0xffc0, 0x0000, 0x0fff, {EAC}, "CMP2W %e,%r" }, -{ 0x02c0, 0xffc0, 0x0800, 0x0fff, {EAC}, "CHK2W %e,%r" }, -{ 0x04c0, 0xffc0, 0x0000, 0x0fff, {EAC}, "CMP2L %e,%r" }, -{ 0x04c0, 0xffc0, 0x0800, 0x0fff, {EAC}, "CHK2L %e,%r" }, -{ 0x06c0, 0xffc0, 0x0000, 0x0000, {I16, BREAC}, "CALLM %i,%e" }, -{ 0x0800, 0xffc0, 0x0000, 0x0000, {I16, EAD}, "BTSTB %i,%e" }, -{ 0x0840, 0xffc0, 0x0000, 0x0000, {I16, EADA}, "BCHG %i,%e" }, -{ 0x0880, 0xffc0, 0x0000, 0x0000, {I16, EADA}, "BCLR %i,%e" }, -{ 0x08c0, 0xffc0, 0x0000, 0x0000, {I16, EADA}, "BSET %i,%e" }, -{ 0x0ac0, 0xffc0, 0x0000, 0xfe38, {EAMA}, "CASB R%a,R%u,%e" }, -{ 0x0cc0, 0xffc0, 0x0000, 0xfe38, {EAMA}, "CASW R%a,R%u,%e" }, -{ 0x0ec0, 0xffc0, 0x0000, 0xfe38, {EAMA}, "CASL R%a,R%u,%e" }, - -{ 0x0000, 0xff00, 0x0000, 0x0000, {IV, EADA}, "OR%s %i,%e" }, -{ 0x0200, 0xff00, 0x0000, 0x0000, {IV, EADA}, "AND%s %i,%e" }, -{ 0x0400, 0xff00, 0x0000, 0x0000, {IV, EADA}, "SUB%s %i,%e" }, -{ 0x0600, 0xff00, 0x0000, 0x0000, {IV, EADA}, "ADD%s %i,%e" }, -{ 0x0a00, 0xff00, 0x0000, 0x0000, {IV, EADA}, "EOR%s %i,%e" }, -{ 0x0c00, 0xff00, 0x0000, 0x0000, {IV, EAD}, "CMP%s %i,%e" }, -{ 0x0e00, 0xff00, 0x0000, 0x0800, {EAMA}, "MOVES%s %e,%r" }, -{ 0x0e00, 0xff00, 0x0800, 0x0800, {EAMA}, "MOVES%s %r,%e" }, - -{ 0x0108, 0xf1f8, 0x0000, 0x0000, {I16}, "MOVEPW (%i,A%y),R%x" }, -{ 0x0148, 0xf1f8, 0x0000, 0x0000, {I16}, "MOVEPL (%i,A%y),R%x" }, -{ 0x0188, 0xf1f8, 0x0000, 0x0000, {I16}, "MOVEPW R%x,(%i,A%y)" }, -{ 0x01c8, 0xf1f8, 0x0000, 0x0000, {I16}, "MOVEPL R%x,(%i,A%y)" }, -{ 0x0100, 0xf1f8, 0x0000, 0x0000, {0}, "BTSTL R%x,R%y" }, -{ 0x0140, 0xf1f8, 0x0000, 0x0000, {0}, "BCHGL R%x,R%y" }, -{ 0x0180, 0xf1f8, 0x0000, 0x0000, {0}, "BCLRL R%x,R%y" }, -{ 0x01c0, 0xf1f8, 0x0000, 0x0000, {0}, "BSET R%x,R%y" }, - -{ 0x0100, 0xf1c0, 0x0000, 0x0000, {EAM_B}, "BTSTB R%x,%e" }, -{ 0x0140, 0xf1c0, 0x0000, 0x0000, {EAMA}, "BCHG R%x,%e" }, -{ 0x0180, 0xf1c0, 0x0000, 0x0000, {EAMA}, "BCLR R%x,%e" }, -{ 0x01c0, 0xf1c0, 0x0000, 0x0000, {EAMA}, "BSET R%x,%e" }, -{ 0,0,0,0,{0},0 }, -}; - /* class 1: move byte */ -static Optable t1[] = { -{ 0x1000, 0xf000, 0x0000, 0x0000, {EAALL_B,EADDA},"MOVB %e,%E" }, -{ 0,0,0,0,{0},0 }, -}; - /* class 2: move long */ -static Optable t2[] = { -{ 0x2040, 0xf1c0, 0x0000, 0x0000, {EAALL_L}, "MOVL %e,A%x" }, - -{ 0x2000, 0xf000, 0x0000, 0x0000, {EAALL_L,EADDA},"MOVL %e,%E" }, -{ 0,0,0,0,{0},0 }, -}; - /* class 3: move word */ -static Optable t3[] = { -{ 0x3040, 0xf1c0, 0x0000, 0x0000, {EAALL_W}, "MOVW %e,A%x" }, - -{ 0x3000, 0xf000, 0x0000, 0x0000, {EAALL_W,EADDA},"MOVW %e,%E" }, -{ 0,0,0,0,{0},0 }, -}; - /* class 4: miscellaneous */ -static Optable t4[] = { -{ 0x4e75, 0xffff, 0x0000, 0x0000, {STACK}, "RTS" }, -{ 0x4e77, 0xffff, 0x0000, 0x0000, {STACK}, "RTR" }, -{ 0x4afc, 0xffff, 0x0000, 0x0000, {0}, "ILLEGAL" }, -{ 0x4e71, 0xffff, 0x0000, 0x0000, {0}, "NOP" }, -{ 0x4e74, 0xffff, 0x0000, 0x0000, {I16, STACK}, "RTD %i" }, -{ 0x4e76, 0xffff, 0x0000, 0x0000, {0}, "TRAPV" }, -{ 0x4e70, 0xffff, 0x0000, 0x0000, {0}, "RESET" }, -{ 0x4e72, 0xffff, 0x0000, 0x0000, {I16}, "STOP %i" }, -{ 0x4e73, 0xffff, 0x0000, 0x0000, {0}, "RTE" }, -{ 0x4e7a, 0xffff, 0x0000, 0x0000, {I16}, "MOVEL %N,%r" }, -{ 0x4e7b, 0xffff, 0x0000, 0x0000, {I16}, "MOVEL %r,%N" }, - -{ 0x4808, 0xfff8, 0x0000, 0x0000, {I32}, "LINKL A%y,%i" }, -{ 0x4840, 0xfff8, 0x0000, 0x0000, {0}, "SWAPW R%y" }, -{ 0x4848, 0xfff8, 0x0000, 0x0000, {0}, "BKPT #%y" }, -{ 0x4880, 0xfff8, 0x0000, 0x0000, {0}, "EXTW R%y" }, -{ 0x48C0, 0xfff8, 0x0000, 0x0000, {0}, "EXTL R%y" }, -{ 0x49C0, 0xfff8, 0x0000, 0x0000, {0}, "EXTBL R%y" }, -{ 0x4e50, 0xfff8, 0x0000, 0x0000, {I16}, "LINKW A%y,%i" }, -{ 0x4e58, 0xfff8, 0x0000, 0x0000, {0}, "UNLK A%y" }, -{ 0x4e60, 0xfff8, 0x0000, 0x0000, {0}, "MOVEL (A%y),USP" }, -{ 0x4e68, 0xfff8, 0x0000, 0x0000, {0}, "MOVEL USP,(A%y)" }, - -{ 0x4e40, 0xfff0, 0x0000, 0x0000, {0}, "SYS %f" }, - -{ 0x40c0, 0xffc0, 0x0000, 0x0000, {EADA}, "MOVW SR,%e" }, -{ 0x42c0, 0xffc0, 0x0000, 0x0000, {EADA}, "MOVW CCR,%e" }, -{ 0x44c0, 0xffc0, 0x0000, 0x0000, {EADI_W}, "MOVW %e,CCR" }, -{ 0x46c0, 0xffc0, 0x0000, 0x0000, {EADI_W}, "MOVW %e,SR" }, -{ 0x4800, 0xffc0, 0x0000, 0x0000, {EADA}, "NBCDB %e" }, -{ 0x4840, 0xffc0, 0x0000, 0x0000, {EAC}, "PEA %e" }, -{ 0x4880, 0xffc0, 0x0000, 0x0000, {I16, EACAPD},"MOVEMW %i,%e" }, -{ 0x48c0, 0xffc0, 0x0000, 0x0000, {I16, EACAPD},"MOVEML %i,%e" }, -{ 0x4ac0, 0xffc0, 0x0000, 0x0000, {EADA}, "TAS %e" }, -{ 0x4a00, 0xffc0, 0x0000, 0x0000, {EAD}, "TSTB %e" }, -{ 0x4c00, 0xffc0, 0x0000, 0x8ff8, {EADI_L}, "MULUL %e,%r" }, -{ 0x4c00, 0xffc0, 0x0400, 0x8ff8, {EADI_L}, "MULUL %e,R%a:%r" }, -{ 0x4c00, 0xffc0, 0x0800, 0x8ff8, {EADI_L}, "MULSL %e,%r" }, -{ 0x4c00, 0xffc0, 0x0c00, 0x8ff8, {EADI_L}, "MULSL %e,R%a:%r" }, -{ 0x4c40, 0xffc0, 0x0000, 0x8ff8, {EADI_L}, "DIVUL %e,%j" }, -{ 0x4c40, 0xffc0, 0x0400, 0x8ff8, {EADI_L}, "DIVUD %e,%r:R%a" }, -{ 0x4c40, 0xffc0, 0x0800, 0x8ff8, {EADI_L}, "DIVSL %e,%j" }, -{ 0x4c40, 0xffc0, 0x0c00, 0x8ff8, {EADI_L}, "DIVSD %e,%r:R%a" }, -{ 0x4c80, 0xffc0, 0x0000, 0x0000, {I16, EACPI}, "MOVEMW %1,%i" }, -{ 0x4cc0, 0xffc0, 0x0000, 0x0000, {I16, EACPI}, "MOVEML %1,%i" }, -{ 0x4e80, 0xffc0, 0x0000, 0x0000, {BREAC}, "JSR %e" }, -{ 0x4ec0, 0xffc0, 0x0000, 0x0000, {BREAC}, "JMP %e" }, - -{ 0x4000, 0xff00, 0x0000, 0x0000, {EADA}, "NEGX%s %e" }, -{ 0x4200, 0xff00, 0x0000, 0x0000, {EADA}, "CLR%s %e" }, -{ 0x4400, 0xff00, 0x0000, 0x0000, {EADA}, "NEG%s %e" }, -{ 0x4600, 0xff00, 0x0000, 0x0000, {EADA}, "NOT%s %e" }, -{ 0x4a00, 0xff00, 0x0000, 0x0000, {EAALL}, "TST%s %e" }, - -{ 0x4180, 0xf1c0, 0x0000, 0x0000, {EADI_W}, "CHKW %e,R%x" }, -{ 0x41c0, 0xf1c0, 0x0000, 0x0000, {EAC}, "LEA %e,A%x" }, -{ 0x4100, 0xf1c0, 0x0000, 0x0000, {EADI_L}, "CHKL %e,R%x" }, -{ 0,0,0,0,{0},0 }, -}; - /* class 5: miscellaneous quick, branch & trap instructions */ -static Optable t5[] = { -{ 0x5000, 0xf1c0, 0x0000, 0x0000, {EADA}, "ADDB $Q#%q,%e" }, -{ 0x5100, 0xf1c0, 0x0000, 0x0000, {EADA}, "SUBB $Q#%q,%e" }, - -{ 0x50c8, 0xf1f8, 0x0000, 0x0000, {BR16}, "DB%c R%y,%t" }, -{ 0x51c8, 0xf1f8, 0x0000, 0x0000, {BR16}, "DB%c R%y,%t" }, - -{ 0x5000, 0xf1c0, 0x0000, 0x0000, {EAA}, "ADDB $Q#%q,%e" }, -{ 0x5040, 0xf1c0, 0x0000, 0x0000, {EAA}, "ADDW $Q#%q,%e" }, -{ 0x5080, 0xf1c0, 0x0000, 0x0000, {EAA}, "ADDL $Q#%q,%e" }, -{ 0x5100, 0xf1c0, 0x0000, 0x0000, {EAA}, "SUBB $Q#%q,%e" }, -{ 0x5140, 0xf1c0, 0x0000, 0x0000, {EAA}, "SUBW $Q#%q,%e" }, -{ 0x5180, 0xf1c0, 0x0000, 0x0000, {EAA}, "SUBL $Q#%q,%e" }, - -{ 0x50fa, 0xf0ff, 0x0000, 0x0000, {I16}, "TRAP%cW %i" }, -{ 0x50fb, 0xf0ff, 0x0000, 0x0000, {I32}, "TRAP%cL %i" }, -{ 0x50fc, 0xf0ff, 0x0000, 0x0000, {0}, "TRAP%c" }, - -{ 0x50c0, 0xf0c0, 0x0000, 0x0000, {EADA}, "S%c %e" }, -{ 0,0,0,0,{0},0 }, -}; - /* class 6: branch instructions */ -static Optable t6[] = { -{ 0x6000, 0xff00, 0x0000, 0x0000, {BR8}, "BRA %t" }, -{ 0x6100, 0xff00, 0x0000, 0x0000, {BR8}, "BSR %t" }, -{ 0x6000, 0xf000, 0x0000, 0x0000, {BR8}, "B%c %t" }, -{ 0,0,0,0,{0},0 }, -}; - /* class 7: move quick */ -static Optable t7[] = { -{ 0x7000, 0xf100, 0x0000, 0x0000, {OP8}, "MOVL $Q%i,R%x" }, -{ 0,0,0,0,{0},0 }, -}; - /* class 8: BCD operations, DIV, and OR instructions */ -static Optable t8[] = { -{ 0x8100, 0xf1f8, 0x0000, 0x0000, {0}, "SBCDB R%y,R%x" }, -{ 0x8108, 0xf1f8, 0x0000, 0x0000, {0}, "SBCDB -(A%y),-(A%x)" }, -{ 0x8140, 0xf1f8, 0x0000, 0x0000, {I16}, "PACK R%y,R%x,%i" }, -{ 0x8148, 0xf1f8, 0x0000, 0x0000, {I16}, "PACK -(A%y),-(A%x),%i" }, -{ 0x8180, 0xf1f8, 0x0000, 0x0000, {I16}, "UNPK R%y,R%x,%i" }, -{ 0x8188, 0xf1f8, 0x0000, 0x0000, {I16}, "UNPK -(A%y),-(A%x),%i" }, - -{ 0x80c0, 0xf1c0, 0x0000, 0x0000, {EADI_W}, "DIVUW %e,R%x" }, -{ 0x81c0, 0xf1c0, 0x0000, 0x0000, {EADI_W}, "DIVSW %e,R%x" }, - -{ 0x8000, 0xf100, 0x0000, 0x0000, {EADI}, "OR%s %e,R%x" }, -{ 0x8100, 0xf100, 0x0000, 0x0000, {EAMA}, "OR%s R%x,%e" }, -{ 0,0,0,0,{0},0 }, -}; - /* class 9: subtract instruction */ -static Optable t9[] = { -{ 0x90c0, 0xf1c0, 0x0000, 0x0000, {EAALL_W}, "SUBW %e,A%x" }, -{ 0x91c0, 0xf1c0, 0x0000, 0x0000, {EAALL_L}, "SUBL %e,A%x" }, - -{ 0x9100, 0xf138, 0x0000, 0x0000, {0}, "SUBX%s R%y,R%x" }, -{ 0x9108, 0xf138, 0x0000, 0x0000, {0}, "SUBX%s -(A%y),-(A%x)" }, - -{ 0x9000, 0xf100, 0x0000, 0x0000, {EAALL}, "SUB%s %e,R%x" }, -{ 0x9100, 0xf100, 0x0000, 0x0000, {EAMA}, "SUB%s R%x,%e" }, -{ 0,0,0,0,{0},0 }, -}; - /* class b: CMP & EOR */ -static Optable tb[] = { -{ 0xb000, 0xf1c0, 0x0000, 0x0000, {EADI}, "CMPB R%x,%e" }, -{ 0xb040, 0xf1c0, 0x0000, 0x0000, {EAALL_W}, "CMPW R%x,%e" }, -{ 0xb080, 0xf1c0, 0x0000, 0x0000, {EAALL_L}, "CMPL R%x,%e" }, -{ 0xb0c0, 0xf1c0, 0x0000, 0x0000, {EAALL_W}, "CMPW A%x,%e" }, -{ 0xb1c0, 0xf1c0, 0x0000, 0x0000, {EAALL_L}, "CMPL A%x,%e" }, - -{ 0xb108, 0xf138, 0x0000, 0x0000, {0}, "CMP%s (A%y)+,(A%x)+" }, - -{ 0xb100, 0xf100, 0x0000, 0x0000, {EADA}, "EOR%s %e,R%x" }, -{ 0,0,0,0,{0},0 }, -}; - /* class c: AND, MUL, BCD & Exchange */ -static Optable tc[] = { -{ 0xc100, 0xf1f8, 0x0000, 0x0000, {0}, "ABCDB R%y,R%x" }, -{ 0xc108, 0xf1f8, 0x0000, 0x0000, {0}, "ABCDB -(A%y),-(A%x)" }, -{ 0xc140, 0xf1f8, 0x0000, 0x0000, {0}, "EXG R%x,R%y" }, -{ 0xc148, 0xf1f8, 0x0000, 0x0000, {0}, "EXG A%x,A%y" }, -{ 0xc188, 0xf1f8, 0x0000, 0x0000, {0}, "EXG R%x,A%y" }, - -{ 0xc0c0, 0xf1c0, 0x0000, 0x0000, {EADI_W}, "MULUW %e,R%x" }, -{ 0xc1c0, 0xf1c0, 0x0000, 0x0000, {EADI_W}, "MULSW %e,R%x" }, - -{ 0xc000, 0xf100, 0x0000, 0x0000, {EADI}, "AND%s %e,R%x" }, -{ 0xc100, 0xf100, 0x0000, 0x0000, {EAMA}, "AND%s R%x,%e" }, -{ 0,0,0,0,{0},0 }, -}; - /* class d: addition */ -static Optable td[] = { -{ 0xd000, 0xf1c0, 0x0000, 0x0000, {EADI}, "ADDB %e,R%x" }, -{ 0xd0c0, 0xf1c0, 0x0000, 0x0000, {EAALL_W}, "ADDW %e,A%x" }, -{ 0xd1c0, 0xf1c0, 0x0000, 0x0000, {EAALL_L}, "ADDL %e,A%x" }, - -{ 0xd100, 0xf138, 0x0000, 0x0000, {0}, "ADDX%s R%y,R%x" }, -{ 0xd108, 0xf138, 0x0000, 0x0000, {0}, "ADDX%s -(A%y),-(A%x)" }, - -{ 0xd000, 0xf100, 0x0000, 0x0000, {EAALL}, "ADD%s %e,R%x" }, -{ 0xd100, 0xf100, 0x0000, 0x0000, {EAMA}, "ADD%s R%x,%e" }, -{ 0,0,0,0,{0},0 }, -}; - /* class e: shift, rotate, bit field operations */ -static Optable te[] = { -{ 0xe8c0, 0xffc0, 0x0820, 0xfe38, {EACD}, "BFTST %e{R%u:R%a}" }, -{ 0xe8c0, 0xffc0, 0x0800, 0xfe20, {EACD}, "BFTST %e{R%u:%w}" }, -{ 0xe8c0, 0xffc0, 0x0020, 0xf838, {EACD}, "BFTST %e{%o:R%a}" }, -{ 0xe8c0, 0xffc0, 0x0000, 0xf820, {EACD}, "BFTST %e{%o:%w}" }, - -{ 0xe9c0, 0xffc0, 0x0820, 0x8e38, {EACD}, "BFEXTU %e{R%u:R%a},%r" }, -{ 0xe9c0, 0xffc0, 0x0800, 0x8e20, {EACD}, "BFEXTU %e{R%u:%w},%r" }, -{ 0xe9c0, 0xffc0, 0x0020, 0x8838, {EACD}, "BFEXTU %e{%o:R%a},%r" }, -{ 0xe9c0, 0xffc0, 0x0000, 0x8820, {EACD}, "BFEXTU %e{%o:%w},%r" }, - -{ 0xeac0, 0xffc0, 0x0820, 0xfe38, {EACAD}, "BFCHG %e{R%u:R%a}" }, -{ 0xeac0, 0xffc0, 0x0800, 0xfe20, {EACAD}, "BFCHG %e{R%u:%w}" }, -{ 0xeac0, 0xffc0, 0x0020, 0xf838, {EACAD}, "BFCHG %e{%o:R%a}" }, -{ 0xeac0, 0xffc0, 0x0000, 0xf820, {EACAD}, "BFCHG %e{%o:%w}" }, - -{ 0xebc0, 0xffc0, 0x0820, 0x8e38, {EACD}, "BFEXTS %e{R%u:R%a},%r" }, -{ 0xebc0, 0xffc0, 0x0800, 0x8e20, {EACD}, "BFEXTS %e{R%u:%w},%r" }, -{ 0xebc0, 0xffc0, 0x0020, 0x8838, {EACD}, "BFEXTS %e{%o:R%a},%r" }, -{ 0xebc0, 0xffc0, 0x0000, 0x8820, {EACD}, "BFEXTS %e{%o:%w},%r" }, - -{ 0xecc0, 0xffc0, 0x0820, 0xfe38, {EACAD}, "BFCLR %e{R%u:R%a}" }, -{ 0xecc0, 0xffc0, 0x0800, 0xfe20, {EACAD}, "BFCLR %e{R%u:%w}" }, -{ 0xecc0, 0xffc0, 0x0020, 0xf838, {EACAD}, "BFCLR %e{%o:R%a}" }, -{ 0xecc0, 0xffc0, 0x0000, 0xf820, {EACAD}, "BFCLR %e{%o:%w}" }, - -{ 0xedc0, 0xffc0, 0x0820, 0x8e38, {EACAD}, "BFFFO %e{R%u:R%a},%r" }, -{ 0xedc0, 0xffc0, 0x0800, 0x8e20, {EACAD}, "BFFFO %e{R%u:%w},%r" }, -{ 0xedc0, 0xffc0, 0x0020, 0x8838, {EACAD}, "BFFFO %e{%o:R%a},%r" }, -{ 0xedc0, 0xffc0, 0x0000, 0x8820, {EACAD}, "BFFFO %e{%o:%w},%r" }, - -{ 0xeec0, 0xffc0, 0x0820, 0xfe38, {EACAD}, "BFSET %e{R%u:R%a}" }, -{ 0xeec0, 0xffc0, 0x0800, 0xfe20, {EACAD}, "BFSET %e{R%u:%w}" }, -{ 0xeec0, 0xffc0, 0x0020, 0xf838, {EACAD}, "BFSET %e{%o:R%a}" }, -{ 0xeec0, 0xffc0, 0x0000, 0xf820, {EACAD}, "BFSET %e{%o:%w}" }, - -{ 0xefc0, 0xffc0, 0x0820, 0x8e38, {EACAD}, "BFINS %r,%e{R%u:R%a}" }, -{ 0xefc0, 0xffc0, 0x0800, 0x8e20, {EACAD}, "BFINS %r,%e{R%u:%w}" }, -{ 0xefc0, 0xffc0, 0x0020, 0x8838, {EACAD}, "BFINS %r,%e{%o:R%a}" }, -{ 0xefc0, 0xffc0, 0x0000, 0x8820, {EACAD}, "BFINS %r,%e{%o:%w}" }, - -{ 0xe0c0, 0xfec0, 0x0000, 0x0000, {EAMA}, "AS%dW %e" }, -{ 0xe2c0, 0xfec0, 0x0000, 0x0000, {EAMA}, "LS%dW %e" }, -{ 0xe4c0, 0xfec0, 0x0000, 0x0000, {EAMA}, "ROX%dW %e" }, -{ 0xe6c0, 0xfec0, 0x0000, 0x0000, {EAMA}, "RO%dW %e" }, - -{ 0xe000, 0xf038, 0x0000, 0x0000, {0}, "AS%d%s #%q,R%y" }, -{ 0xe008, 0xf038, 0x0000, 0x0000, {0}, "LS%d%s #%q,R%y" }, -{ 0xe010, 0xf038, 0x0000, 0x0000, {0}, "ROX%d%s #%q,R%y" }, -{ 0xe018, 0xf038, 0x0000, 0x0000, {0}, "RO%d%s #%q,R%y" }, -{ 0xe020, 0xf038, 0x0000, 0x0000, {0}, "AS%d%s R%x,R%y" }, -{ 0xe028, 0xf038, 0x0000, 0x0000, {0}, "LS%d%s R%x,R%y" }, -{ 0xe030, 0xf038, 0x0000, 0x0000, {0}, "ROX%d%s R%x,R%y" }, -{ 0xe038, 0xf038, 0x0000, 0x0000, {0}, "RO%d%s R%x,R%y" }, -{ 0,0,0,0,{0},0 }, -}; - /* class f: coprocessor and mmu instructions */ -static Optable tf[] = { -{ 0xf280, 0xffff, 0x0000, 0xffff, {0}, "FNOP" }, -{ 0xf200, 0xffff, 0x5c00, 0xfc00, {0}, "FMOVECRX %k,F%D" }, -{ 0xf27a, 0xffff, 0x0000, 0xffc0, {I16}, "FTRAP%P %i" }, -{ 0xf27b, 0xffff, 0x0000, 0xffc0, {I32}, "FTRAP%P %i" }, -{ 0xf27c, 0xffff, 0x0000, 0xffc0, {0}, "FTRAP%P" }, - -{ 0xf248, 0xfff8, 0x0000, 0xffc0, {BR16}, "FDB%P R%y,%t" }, -{ 0xf620, 0xfff8, 0x8000, 0x8fff, {0}, "MOVE16 (A%y)+,(%r)+" }, -{ 0xf500, 0xfff8, 0x0000, 0x0000, {0}, "PFLUSHN (A%y)" }, -{ 0xf508, 0xfff8, 0x0000, 0x0000, {0}, "PFLUSH (A%y)" }, -{ 0xf510, 0xfff8, 0x0000, 0x0000, {0}, "PFLUSHAN" }, -{ 0xf518, 0xfff8, 0x0000, 0x0000, {0}, "PFLUSHA" }, -{ 0xf548, 0xfff8, 0x0000, 0x0000, {0}, "PTESTW (A%y)" }, -{ 0xf568, 0xfff8, 0x0000, 0x0000, {0}, "PTESTR (A%y)" }, -{ 0xf600, 0xfff8, 0x0000, 0x0000, {I32}, "MOVE16 (A%y)+,$%i" }, -{ 0xf608, 0xfff8, 0x0000, 0x0000, {I32}, "MOVE16 $%i,(A%y)-" }, -{ 0xf610, 0xfff8, 0x0000, 0x0000, {I32}, "MOVE16 (A%y),$%i" }, -{ 0xf618, 0xfff8, 0x0000, 0x0000, {I32}, "MOVE16 $%i,(A%y)" }, - -{ 0xf000, 0xffc0, 0x0800, 0xffff, {EACA}, "PMOVE %e,TT0" }, -{ 0xf000, 0xffc0, 0x0900, 0xffff, {EACA}, "PMOVEFD %e,TT0" }, -{ 0xf000, 0xffc0, 0x0a00, 0xffff, {EACA}, "PMOVE TT0,%e" }, -{ 0xf000, 0xffc0, 0x0b00, 0xffff, {EACA}, "PMOVEFD TT0,%e" }, -{ 0xf000, 0xffc0, 0x0c00, 0xffff, {EACA}, "PMOVE %e,TT1" }, -{ 0xf000, 0xffc0, 0x0d00, 0xffff, {EACA}, "PMOVEFD %e,TT1" }, -{ 0xf000, 0xffc0, 0x0e00, 0xffff, {EACA}, "PMOVE TT1,%e" }, -{ 0xf000, 0xffc0, 0x0f00, 0xffff, {EACA}, "PMOVEFD TT1,%e" }, -{ 0xf000, 0xffc0, 0x2400, 0xffff, {0}, "PFLUSHA" }, -{ 0xf000, 0xffc0, 0x2800, 0xffff, {EACA}, "PVALID VAL,%e" }, -{ 0xf000, 0xffc0, 0x6000, 0xffff, {EACA}, "PMOVE %e,MMUSR" }, -{ 0xf000, 0xffc0, 0x6200, 0xffff, {EACA}, "PMOVE MMUSR,%e" }, -{ 0xf000, 0xffc0, 0x2800, 0xfff8, {EACA}, "PVALID A%a,%e" }, -{ 0xf000, 0xffc0, 0x2000, 0xffe0, {EACA}, "PLOADW %L,%e" }, -{ 0xf000, 0xffc0, 0x2200, 0xffe0, {EACA}, "PLOADR %L,%e" }, -{ 0xf000, 0xffc0, 0x8000, 0xffe0, {EACA}, "PTESTW %L,%e,#0" }, -{ 0xf000, 0xffc0, 0x8200, 0xffe0, {EACA}, "PTESTR %L,%e,#0" }, -{ 0xf000, 0xffc0, 0x3000, 0xfe00, {0}, "PFLUSH %L,#%I" }, -{ 0xf000, 0xffc0, 0x3800, 0xfe00, {EACA}, "PFLUSH %L,#%I,%e" }, -{ 0xf000, 0xffc0, 0x8000, 0xe300, {EACA}, "PTESTW %L,%e,#%Z" }, -{ 0xf000, 0xffc0, 0x8100, 0xe300, {EACA}, "PTESTW %L,%e,#%Z,A%h" }, -{ 0xf000, 0xffc0, 0x8200, 0xe300, {EACA}, "PTESTR %L,%e,#%Z" }, -{ 0xf000, 0xffc0, 0x8300, 0xe300, {EACA}, "PTESTR %L,%e,#%Z,A%h" }, -{ 0xf000, 0xffc0, 0x4000, 0xc3ff, {EACA}, "PMOVE %e,%H" }, -{ 0xf000, 0xffc0, 0x4100, 0xc3ff, {EACA}, "PMOVEFD %e,%H" }, -{ 0xf000, 0xffc0, 0x4200, 0xc3ff, {EACA}, "PMOVE %H,%e" }, - - /* floating point (coprocessor 1)*/ - -{ 0xf200, 0xffc0, 0x8400, 0xffff, {EAALL_L}, "FMOVEL %e,FPIAR" }, -{ 0xf200, 0xffc0, 0x8800, 0xffff, {EADI_L}, "FMOVEL %e,FPSR" }, -{ 0xf200, 0xffc0, 0x9000, 0xffff, {EADI_L}, "FMOVEL %e,FPCR" }, -{ 0xf200, 0xffc0, 0xa400, 0xffff, {EAA}, "FMOVEL FPIAR,%e" }, -{ 0xf200, 0xffc0, 0xa800, 0xffff, {EADA}, "FMOVEL FPSR,%e" }, -{ 0xf200, 0xffc0, 0xb000, 0xffff, {EADA}, "FMOVEL FPCR,%e" }, - -{ 0xf240, 0xffc0, 0x0000, 0xffc0, {EADA}, "FS%P %e" }, - -{ 0xf200, 0xffc0, 0xd000, 0xff00, {EACPI}, "FMOVEMX %e,%m" }, -{ 0xf200, 0xffc0, 0xd800, 0xff00, {EACPI}, "FMOVEMX %e,R%K" }, -{ 0xf200, 0xffc0, 0xe000, 0xff00, {EAPI}, "FMOVEMX %m,-(A%y)" }, -{ 0xf200, 0xffc0, 0xe800, 0xff00, {EAPI}, "FMOVEMX R%K,-(A%y)" }, -{ 0xf200, 0xffc0, 0xf000, 0xff00, {EACAPD}, "FMOVEMX %m,%e" }, -{ 0xf200, 0xffc0, 0xf800, 0xff00, {EACAPD}, "FMOVEMX R%K,%e" }, - -{ 0xf200, 0xffc0, 0x6800, 0xfc00, {EAMA}, "FMOVEX F%D,%e" }, -{ 0xf200, 0xffc0, 0x6c00, 0xfc00, {EAMA}, "FMOVEP F%D,%e,{%k}" }, -{ 0xf200, 0xffc0, 0x7400, 0xfc00, {EAMA}, "FMOVED F%D,%e" }, -{ 0xf200, 0xffc0, 0x7c00, 0xfc00, {EAMA}, "FMOVEP F%D,%e,{R%K}" }, - -{ 0xf200, 0xffc0, 0x8000, 0xe3ff, {EAM}, "FMOVEML #%B,%e" }, -{ 0xf200, 0xffc0, 0xa000, 0xe3ff, {EAMA}, "FMOVEML %e,#%B" }, - -{ 0xf200, 0xffc0, 0x0000, 0xe07f, {0}, "FMOVE F%B,F%D" }, -{ 0xf200, 0xffc0, 0x0001, 0xe07f, {0}, "FINTX %F" }, -{ 0xf200, 0xffc0, 0x0002, 0xe07f, {0}, "FSINHX %F" }, -{ 0xf200, 0xffc0, 0x0003, 0xe07f, {0}, "FINTRZ %F" }, -{ 0xf200, 0xffc0, 0x0004, 0xe07f, {0}, "FSQRTX %F" }, -{ 0xf200, 0xffc0, 0x0006, 0xe07f, {0}, "FLOGNP1X %F" }, -{ 0xf200, 0xffc0, 0x0009, 0xe07f, {0}, "FTANHX %F" }, -{ 0xf200, 0xffc0, 0x000a, 0xe07f, {0}, "FATANX %F" }, -{ 0xf200, 0xffc0, 0x000c, 0xe07f, {0}, "FASINX %F" }, -{ 0xf200, 0xffc0, 0x000d, 0xe07f, {0}, "FATANHX %F" }, -{ 0xf200, 0xffc0, 0x000e, 0xe07f, {0}, "FSINX %F" }, -{ 0xf200, 0xffc0, 0x000f, 0xe07f, {0}, "FTANX %F" }, -{ 0xf200, 0xffc0, 0x0010, 0xe07f, {0}, "FETOXX %F" }, -{ 0xf200, 0xffc0, 0x0011, 0xe07f, {0}, "FTWOTOXX %F" }, -{ 0xf200, 0xffc0, 0x0012, 0xe07f, {0}, "FTENTOXX %F" }, -{ 0xf200, 0xffc0, 0x0014, 0xe07f, {0}, "FLOGNX %F" }, -{ 0xf200, 0xffc0, 0x0015, 0xe07f, {0}, "FLOG10X %F" }, -{ 0xf200, 0xffc0, 0x0016, 0xe07f, {0}, "FLOG2X %F" }, -{ 0xf200, 0xffc0, 0x0018, 0xe07f, {0}, "FABSX %F" }, -{ 0xf200, 0xffc0, 0x0019, 0xe07f, {0}, "FCOSHX %F" }, -{ 0xf200, 0xffc0, 0x001a, 0xe07f, {0}, "FNEGX %F" }, -{ 0xf200, 0xffc0, 0x001c, 0xe07f, {0}, "FACOSX %F" }, -{ 0xf200, 0xffc0, 0x001d, 0xe07f, {0}, "FCOSX %F" }, -{ 0xf200, 0xffc0, 0x001e, 0xe07f, {0}, "FGETEXPX %F" }, -{ 0xf200, 0xffc0, 0x001f, 0xe07f, {0}, "FGETMANX %F" }, -{ 0xf200, 0xffc0, 0x0020, 0xe07f, {0}, "FDIVX F%B,F%D" }, -{ 0xf200, 0xffc0, 0x0021, 0xe07f, {0}, "FMODX F%B,F%D" }, -{ 0xf200, 0xffc0, 0x0022, 0xe07f, {0}, "FADDX F%B,F%D" }, -{ 0xf200, 0xffc0, 0x0023, 0xe07f, {0}, "FMULX F%B,F%D" }, -{ 0xf200, 0xffc0, 0x0024, 0xe07f, {0}, "FSGLDIVX F%B,F%D" }, -{ 0xf200, 0xffc0, 0x0025, 0xe07f, {0}, "FREMX F%B,F%D" }, -{ 0xf200, 0xffc0, 0x0026, 0xe07f, {0}, "FSCALEX F%B,F%D" }, -{ 0xf200, 0xffc0, 0x0027, 0xe07f, {0}, "FSGLMULX F%B,F%D" }, -{ 0xf200, 0xffc0, 0x0028, 0xe07f, {0}, "FSUBX F%B,F%D" }, -{ 0xf200, 0xffc0, 0x0038, 0xe07f, {0}, "FCMPX F%B,F%D" }, -{ 0xf200, 0xffc0, 0x003a, 0xe07f, {0}, "FTSTX F%B" }, -{ 0xf200, 0xffc0, 0x0040, 0xe07f, {0}, "FSMOVE F%B,F%D" }, -{ 0xf200, 0xffc0, 0x0041, 0xe07f, {0}, "FSSQRTX %F"}, -{ 0xf200, 0xffc0, 0x0044, 0xe07f, {0}, "FDMOVE F%B,F%D" }, -{ 0xf200, 0xffc0, 0x0045, 0xe07f, {0}, "FDSQRTX %F" }, -{ 0xf200, 0xffc0, 0x0058, 0xe07f, {0}, "FSABSX %F" }, -{ 0xf200, 0xffc0, 0x005a, 0xe07f, {0}, "FSNEGX %F" }, -{ 0xf200, 0xffc0, 0x005c, 0xe07f, {0}, "FDABSX %F" }, -{ 0xf200, 0xffc0, 0x005e, 0xe07f, {0}, "FDNEGX %F" }, -{ 0xf200, 0xffc0, 0x0060, 0xe07f, {0}, "FSDIVX F%B,F%D" }, -{ 0xf200, 0xffc0, 0x0062, 0xe07f, {0}, "FSADDX F%B,F%D" }, -{ 0xf200, 0xffc0, 0x0063, 0xe07f, {0}, "FSMULX F%B,F%D" }, -{ 0xf200, 0xffc0, 0x0064, 0xe07f, {0}, "FDDIVX F%B,F%D" }, -{ 0xf200, 0xffc0, 0x0066, 0xe07f, {0}, "FDADDX F%B,F%D" }, -{ 0xf200, 0xffc0, 0x0067, 0xe07f, {0}, "FDMULX F%B,F%D" }, -{ 0xf200, 0xffc0, 0x0068, 0xe07f, {0}, "FSSUBX F%B,F%D" }, -{ 0xf200, 0xffc0, 0x006c, 0xe07f, {0}, "FDSUBX F%B,F%D" }, -{ 0xf200, 0xffc0, 0x4000, 0xe07f, {EAFLT}, "FMOVE%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4001, 0xe07f, {EAFLT}, "FINT%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4002, 0xe07f, {EAFLT}, "FSINH%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4003, 0xe07f, {EAFLT}, "FINTRZ%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4004, 0xe07f, {EAFLT}, "FSQRT%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4006, 0xe07f, {EAFLT}, "FLOGNP1%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4009, 0xe07f, {EAFLT}, "FTANH%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x400a, 0xe07f, {EAFLT}, "FATAN%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x400c, 0xe07f, {EAFLT}, "FASIN%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x400d, 0xe07f, {EAFLT}, "FATANH%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x400e, 0xe07f, {EAFLT}, "FSIN%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x400f, 0xe07f, {EAFLT}, "FTAN%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4010, 0xe07f, {EAFLT}, "FETOX%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4011, 0xe07f, {EAFLT}, "FTWOTOX%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4012, 0xe07f, {EAFLT}, "FTENTOX%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4014, 0xe07f, {EAFLT}, "FLOGN%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4015, 0xe07f, {EAFLT}, "FLOG10%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4016, 0xe07f, {EAFLT}, "FLOG2%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4018, 0xe07f, {EAFLT}, "FABS%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4019, 0xe07f, {EAFLT}, "FCOSH%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x401a, 0xe07f, {EAFLT}, "FNEG%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x401c, 0xe07f, {EAFLT}, "FACOS%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x401d, 0xe07f, {EAFLT}, "FCOS%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x401e, 0xe07f, {EAFLT}, "FGETEXP%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x401f, 0xe07f, {EAFLT}, "FGETMAN%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4020, 0xe07f, {EAFLT}, "FDIV%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4021, 0xe07f, {EAFLT}, "FMOD%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4022, 0xe07f, {EAFLT}, "FADD%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4023, 0xe07f, {EAFLT}, "FMUL%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4024, 0xe07f, {EAFLT}, "FSGLDIV%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4025, 0xe07f, {EAFLT}, "FREM%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4026, 0xe07f, {EAFLT}, "FSCALE%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4027, 0xe07f, {EAFLT}, "FSGLMUL%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4028, 0xe07f, {EAFLT}, "FSUB%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4038, 0xe07f, {EAFLT}, "FCMP%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x403a, 0xe07f, {EAFLT}, "FTST%S %e" }, -{ 0xf200, 0xffc0, 0x4040, 0xe07f, {EAFLT}, "FSMOVE%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4041, 0xe07f, {EAFLT}, "FSSQRT%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4044, 0xe07f, {EAFLT}, "FDMOVE%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4045, 0xe07f, {EAFLT}, "FDSQRT%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4058, 0xe07f, {EAFLT}, "FSABS%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x405a, 0xe07f, {EAFLT}, "FSNEG%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x405c, 0xe07f, {EAFLT}, "FDABS%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x405e, 0xe07f, {EAFLT}, "FDNEG%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4060, 0xe07f, {EAFLT}, "FSDIV%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4062, 0xe07f, {EAFLT}, "FSADD%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4063, 0xe07f, {EAFLT}, "FSMUL%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4064, 0xe07f, {EAFLT}, "FDDIV%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4066, 0xe07f, {EAFLT}, "FDADD%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4067, 0xe07f, {EAFLT}, "FDMUL%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x4068, 0xe07f, {EAFLT}, "FSSUB%S %e,F%D" }, -{ 0xf200, 0xffc0, 0x406c, 0xe07f, {EAFLT}, "FDSUB%S %e,F%D" }, - -{ 0xf200, 0xffc0, 0x0030, 0xe078, {0}, "FSINCOSX F%B,F%a:F%D" }, -{ 0xf200, 0xffc0, 0x4030, 0xe078, {EAFLT}, "FSINCOS%S %e,F%a:F%D" }, - -{ 0xf200, 0xffc0, 0x6000, 0xe000, {EADA}, "FMOVE%S F%D,%e" }, - -{ 0xf300, 0xffc0, 0x0000, 0x0000, {EACAPD}, "FSAVE %e" }, -{ 0xf340, 0xffc0, 0x0000, 0x0000, {EACAPI}, "FRESTORE %e" }, - -{ 0xf280, 0xffc0, 0x0000, 0x0000, {BR16}, "FB%p %t" }, -{ 0xf2c0, 0xffc0, 0x0000, 0x0000, {BR32}, "FB%p %t" }, - -{ 0xf408, 0xff38, 0x0000, 0x0000, {0}, "CINVL %C,(A%y)" }, -{ 0xf410, 0xff38, 0x0000, 0x0000, {0}, "CINVP %C,(A%y)" }, -{ 0xf418, 0xff38, 0x0000, 0x0000, {0}, "CINVA %C" }, -{ 0xf428, 0xff38, 0x0000, 0x0000, {0}, "CPUSHL %C,(A%y)" }, -{ 0xf430, 0xff38, 0x0000, 0x0000, {0}, "CPUSHP %C,(A%y)" }, -{ 0xf438, 0xff38, 0x0000, 0x0000, {0}, "CPUSHA %C" }, -{ 0,0,0,0,{0},0 }, -}; - -static Optable *optables[] = -{ - t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, 0, tb, tc, td, te, tf, -}; - -static int -dumpinst(Inst *ip, char *buf, int n) -{ - int i; - - if (n <= 0) - return 0; - - *buf++ = '#'; - for (i = 0; i < ip->n && i*4+1 < n-4; i++, buf += 4) - _hexify(buf, ip->raw[i], 3); - *buf = 0; - return i*4+1; -} - -static int -get2(long offset, ushort *buf) { - buf[0]=((ushort*)dasdata)[offset/2]; - return 2; -} - -static int -get1(long offset, uchar *buf,int size) { - memmove(buf,&dasdata[offset],size); - return 1; -} - -static int -getword(Inst *ip, long offset) -{ - if (ip->n < nelem(ip->raw)) { - if (get2(offset, &ip->raw[ip->n++]) > 0) - return 1; - werrstr("can't read instruction: %r"); - } else - werrstr("instruction too big: %r"); - return -1; -} - -static int -getshorts(Inst *ip, void *where, int n) -{ - if (ip->n+n < nelem(ip->raw)) { - if (get1(ip->addr+ip->n*2, (uchar*)&ip->raw[ip->n], n*2) < 0) { - werrstr("can't read instruction: %r"); - return 0; - } - memmove(where, &ip->raw[ip->n], n*2); - ip->n += n; - return 1; - } - werrstr("instruction too big: %r"); - return 0; -} - -static int -i8(Inst *ip, long *l) -{ - if (getword(ip, ip->addr+ip->n*2) < 0) - return -1; - *l = ip->raw[ip->n-1]&0xff; - if (*l&0x80) - *l |= ~0xff; - return 1; -} - -static int -i16(Inst *ip, long *l) -{ - if (getword(ip, ip->addr+ip->n*2) < 0) - return -1; - *l = ip->raw[ip->n-1]; - if (*l&0x8000) - *l |= ~0xffff; - return 1; -} -static int -i32(Inst *ip, long *l) -{ - if (getword(ip, ip->addr+ip->n*2) < 0) - return -1; - if (getword(ip, ip->addr+ip->n*2) < 0) - return -1; - *l = (ip->raw[ip->n-2]<<16)|ip->raw[ip->n-1]; - return 1; -} - -static int -getimm(Inst *ip, Operand *ap, int mode) -{ - ap->eatype = IMM; - switch(mode) - { - case EAM_B: /* byte */ - case EAALL_B: - return i8(ip, &ap->immediate); - case EADI_W: /* word */ - case EAALL_W: - return i16(ip, &ap->immediate); - case EADI_L: /* long */ - case EAALL_L: - return i32(ip, &ap->immediate); - case EAFLT: /* floating point - size in bits 10-12 or word 1 */ - switch((ip->raw[1]>>10)&0x07) - { - case 0: /* long integer */ - return i32(ip, &ap->immediate); - case 1: /* single precision real */ - ap->eatype = IREAL; - return getshorts(ip, ap->floater, 2); - case 2: /* extended precision real - not supported */ - ap->eatype = IEXT; - return getshorts(ip, ap->floater, 6); - case 3: /* packed decimal real - not supported */ - ap->eatype = IPACK; - return getshorts(ip, ap->floater, 12); - case 4: /* integer word */ - return i16(ip, &ap->immediate); - case 5: /* double precision real */ - ap->eatype = IDBL; - return getshorts(ip, ap->floater, 4); - case 6: /* integer byte */ - return i8(ip, &ap->immediate); - default: - ip->errmsg = "bad immediate float data"; - return -1; - } - break; - case IV: /* size encoded in bits 6&7 of opcode word */ - default: - switch((ip->raw[0]>>6)&0x03) - { - case 0x00: /* integer byte */ - return i8(ip, &ap->immediate); - case 0x01: /* integer word */ - return i16(ip, &ap->immediate); - case 0x02: /* integer long */ - return i32(ip, &ap->immediate); - default: - ip->errmsg = "bad immediate size"; - return -1; - } - break; - } - return 1; -} - -static int -getdisp(Inst *ip, Operand *ap) -{ - short ext; - - if (getword(ip, ip->addr+ip->n*2) < 0) - return -1; - ext = ip->raw[ip->n-1]; - ap->ext = ext; - if ((ext&0x100) == 0) { /* indexed with 7-bit displacement */ - ap->disp = ext&0x7f; - if (ap->disp&0x40) - ap->disp |= ~0x7f; - return 1; - } - switch(ext&0x30) /* first (inner) displacement */ - { - case 0x10: - break; - case 0x20: - if (i16(ip, &ap->disp) < 0) - return -1; - break; - case 0x30: - if (i32(ip, &ap->disp) < 0) - return -1; - break; - default: - ip->errmsg = "bad EA displacement"; - return -1; - } - switch (ext&0x03) /* outer displacement */ - { - case 0x02: /* 16 bit displacement */ - return i16(ip, &ap->outer); - case 0x03: /* 32 bit displacement */ - return i32(ip, &ap->outer); - default: - break; - } - return 1; -} - -static int -ea(Inst *ip, int ea, Operand *ap, int mode) -{ - int type, size; - - type = 0; - ap->ext = 0; - switch((ea>>3)&0x07) - { - case 0x00: - ap->eatype = Dreg; - type = Dn; - break; - case 0x01: - ap->eatype = Areg; - type = An; - break; - case 0x02: - ap->eatype = AInd; - type = Ind; - break; - case 0x03: - ap->eatype = APinc; - type = Pinc; - break; - case 0x04: - ap->eatype = APdec; - type = Pdec; - break; - case 0x05: - ap->eatype = ADisp; - type = Bdisp; - if (i16(ip, &ap->disp) < 0) - return -1; - break; - case 0x06: - ap->eatype = BXD; - type = Bdisp; - if (getdisp(ip, ap) < 0) - return -1; - break; - case 0x07: - switch(ea&0x07) - { - case 0x00: - type = Abs; - ap->eatype = ABS; - if (i16(ip, &ap->immediate) < 0) - return -1; - break; - case 0x01: - type = Abs; - ap->eatype = ABS; - if (i32(ip, &ap->immediate) < 0) - return -1; - break; - case 0x02: - type = PCrel; - ap->eatype = PDisp; - if (i16(ip, &ap->disp) < 0) - return -1; - break; - case 0x03: - type = PCrel; - ap->eatype = PXD; - if (getdisp(ip, ap) < 0) - return -1; - break; - case 0x04: - type = Imm; - if (getimm(ip, ap, mode) < 0) - return -1; - break; - default: - ip->errmsg = "bad EA mode"; - return -1; - } - } - /* Allowable floating point EAs are restricted for packed, - * extended, and double precision operands - */ - if (mode == EAFLT) { - size = (ip->raw[1]>>10)&0x07; - if (size == 2 || size == 3 || size == 5) - mode = EAM; - else - mode = EADI; - } - if (!(validea[mode]&type)) { - ip->errmsg = "invalid EA"; - return -1; - } - return 1; -} - -static int -decode(Inst *ip, Optable *op) -{ - int i, t, mode; - Operand *ap; - short opcode; - - opcode = ip->raw[0]; - for (i = 0; i < nelem(op->opdata) && op->opdata[i]; i++) { - ap = &ip->and[i]; - mode = op->opdata[i]; - switch(mode) - { - case EAPI: /* normal EA modes */ - case EACA: - case EACAD: - case EACAPI: - case EACAPD: - case EAMA: - case EADA: - case EAA: - case EAC: - case EACPI: - case EACD: - case EAD: - case EAM: - case EAM_B: - case EADI: - case EADI_L: - case EADI_W: - case EAALL: - case EAALL_L: - case EAALL_W: - case EAALL_B: - case EAFLT: - if (ea(ip, opcode&0x3f, ap, mode) < 0) - return -1; - break; - case EADDA: /* stupid bit flop required */ - t = ((opcode>>9)&0x07)|((opcode>>3)&0x38); - if (ea(ip, t, ap, EADA)< 0) - return -1; - break; - case BREAC: /* EAC JMP or CALL operand */ - if (ea(ip, opcode&0x3f, ap, EAC) < 0) - return -1; - break; - case OP8: /* weird movq instruction */ - ap->eatype = IMM; - ap->immediate = opcode&0xff; - if (opcode&0x80) - ap->immediate |= ~0xff; - break; - case I8: /* must be two-word opcode */ - ap->eatype = IMM; - ap->immediate = ip->raw[1]&0xff; - if (ap->immediate&0x80) - ap->immediate |= ~0xff; - break; - case I16: /* 16 bit immediate */ - case BR16: - ap->eatype = IMM; - if (i16(ip, &ap->immediate) < 0) - return -1; - break; - case C16: /* CAS2 16 bit immediate */ - ap->eatype = IMM; - if (i16(ip, &ap->immediate) < 0) - return -1; - if (ap->immediate & 0x0e38) { - ip->errmsg = "bad CAS2W operand"; - return 0; - } - break; - case I32: /* 32 bit immediate */ - case BR32: - ap->eatype = IMM; - if (i32(ip, &ap->immediate) < 0) - return -1; - break; - case IV: /* immediate data depends on size field */ - if (getimm(ip, ap, IV) < 0) - return -1; - break; - case BR8: /* branch displacement format */ - ap->eatype = IMM; - ap->immediate = opcode&0xff; - if (ap->immediate == 0) { - if (i16(ip, &ap->immediate) < 0) - return -1; - } else if (ap->immediate == 0xff) { - if (i32(ip, &ap->immediate) < 0) - return -1; - } else if (ap->immediate & 0x80) - ap->immediate |= ~0xff; - break; - case STACK: /* Dummy operand type for Return instructions */ - default: - break; - } - } - return 1; -} - -static Optable * -instruction(Inst *ip) -{ - ushort opcode, op2; - Optable *op; - int class; - - ip->n = 0; - if (getword(ip, ip->addr) < 0) - return 0; - opcode = ip->raw[0]; - if (get2(ip->addr+2, &op2) < 0) - op2 = 0; - class = (opcode>>12)&0x0f; - for (op = optables[class]; op && op->format; op++) { - if (op->opcode != (opcode&op->mask0)) - continue; - if (op->op2 != (op2&op->mask1)) - continue; - if (op->mask1) - ip->raw[ip->n++] = op2; - return op; - } - ip->errmsg = "Invalid opcode"; - return 0; -} - -static void -bprint(Inst *i, char *fmt, ...) -{ - va_list arg; - - va_start(arg, fmt); - i->curr = vseprint(i->curr, i->end, fmt, arg); - va_end(arg); -} - -static char *regname[] = -{ - "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "A0", - "A1", "A2", "A3", "A4", "A5", "A6", "A7", "PC", "SB" -}; - -#define CANY 0 -#define CTEXT 0 - -int -symoff(char *buf, int n, long v, int) -{ - return snprint(buf, n, "%lux", v); -} -static void -plocal(Inst *ip, Operand *ap) -{ - bprint(ip, "%lux", ap->disp); -} - -/* - * this guy does all the work of printing the base and index component - * of an EA. - */ -static int -pidx(Inst *ip, int ext, int reg, char *bfmt, char *ifmt, char *nobase) -{ - char *s; - int printed; - char buf[512]; - - printed = 1; - if (ext&0x80) { /* Base suppressed */ - if (reg == 16) - bprint(ip, bfmt, "(ZPC)"); - else if (nobase) - bprint(ip, nobase); - else - printed = 0; - } else /* format base reg */ - bprint(ip, bfmt, regname[reg]); - if (ext & 0x40) /* index suppressed */ - return printed; - switch ((ext>>9)&0x03) - { - case 0x01: - s = "*2"; - break; - case 0x02: - s = "*4"; - break; - case 0x03: - s = "*8"; - break; - default: - if (ext&0x80) - s = "*1"; - else - s = ""; - break; - } - sprint(buf, "%s.%c%s", regname[(ext>>12)&0x0f], (ext&0x800) ? 'L' : 'W', s); - if (!printed) - bprint(ip, ifmt, buf); - else - bprint(ip, "(%s)", buf); - return 1; -} - -static void -prindex(Inst *ip, int reg, Operand *ap) -{ - short ext; - int left; - int disp; - - left = ip->end-ip->curr; - if (left <= 0) - return; - ext = ap->ext; - disp = ap->disp; - /* look for static base register references */ - if ((ext&0x100) == 0) { /* brief form */ - if (reg == 15) - plocal(ip, ap); - else if (disp) - ip->curr += symoff(ip->curr, left, disp, CANY); - pidx(ip, ext&0xff00, reg, "(%s)", "(%s)", 0); - return; - } - switch(ext&0x3f) /* bd size, && i/is */ - { - case 0x10: - if (!pidx(ip, ext, reg, "(%s)", "(%s)", 0)) - bprint(ip, "#0"); - break; - case 0x11: - if (pidx(ip, ext, reg, "((%s)", "((%s)", 0)) - bprint(ip, ")"); - else - bprint(ip, "#0"); - break; - case 0x12: - case 0x13: - ip->curr += symoff(ip->curr, left, ap->outer, CANY); - if (pidx(ip, ext, reg, "((%s)", "((%s)", 0)) - bprint(ip, ")"); - break; - case 0x15: - if (!pidx(ip, ext, reg, "((%s))", "(%s)", 0)) - bprint(ip, "#0"); - break; - case 0x16: - case 0x17: - ip->curr += symoff(ip->curr, left, ap->outer, CANY); - pidx(ip, ext, reg, "((%s))", "(%s)", 0); - break; - case 0x20: - case 0x30: - if (reg == 15) - plocal(ip, ap); - else - ip->curr += symoff(ip->curr, left, disp, CANY); - pidx(ip, ext, reg, "(%s)", "(%s)", 0); - break; - case 0x21: - case 0x31: - *ip->curr++ = '('; - if (reg == 15) - plocal(ip, ap); - else - ip->curr += symoff(ip->curr, left-1, disp, CANY); - pidx(ip, ext, reg, "(%s)", "(%s)", 0); - bprint(ip, ")"); - break; - case 0x22: - case 0x23: - case 0x32: - case 0x33: - ip->curr += symoff(ip->curr, left, ap->outer, CANY); - bprint(ip, "("); - if (reg == 15) - plocal(ip, ap); - else - ip->curr += symoff(ip->curr, ip->end-ip->curr, disp, CANY); - pidx(ip, ext, reg, "(%s)", "(%s)", 0); - bprint(ip, ")"); - break; - case 0x25: - case 0x35: - *ip->curr++ = '('; - if (reg == 15) - plocal(ip, ap); - else - ip->curr += symoff(ip->curr, left-1, disp, CANY); - if (!pidx(ip, ext, reg, "(%s))", "(%s)", "())")) - bprint(ip, ")"); - break; - case 0x26: - case 0x27: - case 0x36: - case 0x37: - ip->curr += symoff(ip->curr, left, ap->outer, CANY); - bprint(ip, "("); - if (reg == 15) - plocal(ip, ap); - else - ip->curr += symoff(ip->curr, ip->end-ip->curr, disp, CANY); - pidx(ip, ext, reg, "(%s))", "(%s)", "())"); - break; - default: - bprint(ip, "??%x??", ext); - ip->errmsg = "bad EA"; - break; - } -} - -static void -pea(int reg, Inst *ip, Operand *ap) -{ - int i, left; - - left = ip->end-ip->curr; - if (left < 0) - return; - switch(ap->eatype) - { - case Dreg: - bprint(ip, "R%d", reg); - break; - case Areg: - bprint(ip, "A%d", reg); - break; - case AInd: - bprint(ip, "(A%d)", reg); - break; - case APinc: - bprint(ip, "(A%d)+", reg); - break; - case APdec: - bprint(ip, "-(A%d)", reg); - break; - case PDisp: - ip->curr += symoff(ip->curr, left, ip->addr+2+ap->disp, CANY); - break; - case PXD: - prindex(ip, 16, ap); - break; - case ADisp: - ip->curr += symoff(ip->curr, left, ap->disp, CANY); - bprint(ip, "(A%d)", reg); - break; - case BXD: - prindex(ip, reg+8, ap); - break; - case ABS: - ip->curr += symoff(ip->curr, left, ap->immediate, CANY); - bprint(ip, "($0)"); - break; - case IMM: - *ip->curr++ = '$'; - ip->curr += symoff(ip->curr, left-1, ap->immediate, CANY); - break; - case IPACK: - bprint(ip, "$#"); - for (i = 0; i < 24 && ip->curr < ip->end-1; i++) { - _hexify(ip->curr, ap->floater[i], 1); - ip->curr += 2; - } - break; - default: - bprint(ip, "??%x??", ap->eatype); - ip->errmsg = "bad EA type"; - break; - } -} - -static char *cctab[] = { "F", "T", "HI", "LS", "CC", "CS", "NE", "EQ", - "VC", "VS", "PL", "MI", "GE", "LT", "GT", "LE" }; -static char *fcond[] = -{ - "F", "EQ", "OGT", "OGE", "OLT", "OLE", "OGL", "OR", - "UN", "UEQ", "UGT", "UGE", "ULT", "ULE", "NE", "T", - "SF", "SEQ", "GT", "GE", "LT", "LE", "GL", "GLE", - "NGLE", "NGL", "NLE", "NLT", "NGE", "NGT", "SNE", "ST" -}; -static char *cachetab[] = { "NC", "DC", "IC", "BC" }; -static char *mmutab[] = { "TC", "??", "SRP", "CRP" }; -static char *crtab0[] = -{ - "SFC", "DFC", "CACR", "TC", "ITT0", "ITT1", "DTT0", "DTT1", -}; -static char *crtab1[] = -{ - "USP", "VBR", "CAAR", "MSP", "ISP", "MMUSR", "URP", "SRP", -}; -static char typetab[] = { 'L', 'S', 'X', 'P', 'W', 'D', 'B', '?', }; -static char sztab[] = {'?', 'B', 'W', 'L', '?' }; - -static void -formatins(char *fmt, Inst *ip) -{ - short op, w1; - int r1, r2; - int currand; - - op = ip->raw[0]; - w1 = ip->raw[1]; - currand = 0; - for (; *fmt && ip->curr < ip->end; fmt++) { - if (*fmt != '%') - *ip->curr++ = *fmt; - else switch(*++fmt) - { - case '%': - *ip->curr++ = '%'; - break; - case 'a': /* register number; word 1:[0-2] */ - *ip->curr++ = (w1&0x07)+'0'; - break; - case 'c': /* condition code; opcode: [8-11] */ - bprint(ip, cctab[(op>>8)&0x0f]); - break; - case 'd': /* shift direction; opcode: [8] */ - if (op&0x100) - *ip->curr++ = 'L'; - else - *ip->curr++ = 'R'; - break; - case 'e': /* source effective address */ - pea(op&0x07, ip, &ip->and[currand++]); - break; - case 'f': /* trap vector; op code: [0-3] */ - bprint(ip, "%x", op&0x0f); - break; - case 'h': /* register number; word 1: [5-7] */ - *ip->curr++ = (w1>>5)&0x07+'0'; - break; - case 'i': /* immediate operand */ - ip->curr += symoff(ip->curr, ip->end-ip->curr, - ip->and[currand++].immediate, CANY); - break; - case 'j': /* data registers; word 1: [0-2] & [12-14] */ - r1 = w1&0x07; - r2 = (w1>>12)&0x07; - if (r1 == r2) - bprint(ip, "R%d", r1); - else - bprint(ip, "R%d:R%d", r2, r1); - break; - case 'k': /* k factor; word 1 [0-6] */ - bprint(ip, "%x", w1&0x7f); - break; - case 'm': /* register mask; word 1 [0-7] */ - bprint(ip, "%x", w1&0xff); - break; - case 'o': /* bit field offset; word1: [6-10] */ - bprint(ip, "%d", (w1>>6)&0x3f); - break; - case 'p': /* conditional predicate; opcode: [0-5] - only bits 0-4 are defined */ - bprint(ip, fcond[op&0x1f]); - break; - case 'q': /* 3-bit immediate value; opcode[9-11] */ - r1 = (op>>9)&0x07; - if (r1 == 0) - *ip->curr++ = '8'; - else - *ip->curr++ = r1+'0'; - break; - case 'r': /* register type & number; word 1: [12-15] */ - bprint(ip, regname[(w1>>12)&0x0f]); - break; - case 's': /* size; opcode [6-7] */ - *ip->curr = sztab[((op>>6)&0x03)+1]; - if (*ip->curr++ == '?') - ip->errmsg = "bad size code"; - break; - case 't': /* text offset */ - ip->curr += symoff(ip->curr, ip->end-ip->curr, - ip->and[currand++].immediate+ip->addr+2, CTEXT); - break; - case 'u': /* register number; word 1: [6-8] */ - *ip->curr++ = ((w1>>6)&0x07)+'0'; - break; - case 'w': /* bit field width; word 1: [0-4] */ - bprint(ip, "%d", w1&0x0f); - break; - case 'x': /* register number; opcode: [9-11] */ - *ip->curr++ = ((op>>9)&0x07)+'0'; - break; - case 'y': /* register number; opcode: [0-2] */ - *ip->curr++ = (op&0x07)+'0'; - break; - case 'z': /* shift count; opcode: [9-11] */ - *ip->curr++ = ((op>>9)&0x07)+'0'; - break; - case 'A': /* register number; word 2: [0-2] */ - *ip->curr++ = (ip->raw[2]&0x07)+'0'; - break; - case 'B': /* float source reg; word 1: [10-12] */ - *ip->curr++ = ((w1>>10)&0x07)+'0'; - break; - case 'C': /* cache identifier; opcode: [6-7] */ - bprint(ip, cachetab[(op>>6)&0x03]); - break; - case 'D': /* float dest reg; word 1: [7-9] */ - *ip->curr++ = ((w1>>7)&0x07)+'0'; - break; - case 'E': /* destination EA; opcode: [6-11] */ - pea((op>>9)&0x07, ip, &ip->and[currand++]); - break; - case 'F': /* float dest register(s); word 1: [7-9] & [10-12] */ - r1 = (w1>>7)&0x07; - r2 = (w1>>10)&0x07; - if (r1 == r2) - bprint(ip, "F%d", r1); - else - bprint(ip, "F%d,F%d", r2, r1); - break; - case 'H': /* MMU register; word 1 [10-13] */ - bprint(ip, mmutab[(w1>>10)&0x03]); - if (ip->curr[-1] == '?') - ip->errmsg = "bad mmu register"; - break; - case 'I': /* MMU function code mask; word 1: [5-8] */ - bprint(ip, "%x", (w1>>4)&0x0f); - break; - case 'K': /* dynamic k-factor register; word 1: [5-8] */ - bprint(ip, "%d", (w1>>4)&0x0f); - break; - case 'L': /* MMU function code; word 1: [0-6] */ - if (w1&0x10) - bprint(ip, "%x", w1&0x0f); - else if (w1&0x08) - bprint(ip, "R%d",w1&0x07); - else if (w1&0x01) - bprint(ip, "DFC"); - else - bprint(ip, "SFC"); - break; - case 'N': /* control register; word 1: [0-11] */ - r1 = w1&0xfff; - if (r1&0x800) - bprint(ip, crtab1[r1&0x07]); - else - bprint(ip, crtab0[r1&0x07]); - break; - case 'P': /* conditional predicate; word 1: [0-5] */ - bprint(ip, fcond[w1&0x1f]); - break; - case 'R': /* register type & number; word 2 [12-15] */ - bprint(ip, regname[(ip->raw[2]>>12)&0x0f]); - break; - case 'S': /* float source type code; word 1: [10-12] */ - *ip->curr = typetab[(w1>>10)&0x07]; - if (*ip->curr++ == '?') - ip->errmsg = "bad float type"; - break; - case 'U': /* register number; word 2: [6-8] */ - *ip->curr++ = ((ip->raw[2]>>6)&0x07)+'0'; - break; - case 'Z': /* ATC level number; word 1: [10-12] */ - bprint(ip, "%x", (w1>>10)&0x07); - break; - case '1': /* effective address in second operand*/ - pea(op&0x07, ip, &ip->and[1]); - break; - default: - bprint(ip, "%%%c", *fmt); - break; - } - } - *ip->curr = 0; /* there's always room for 1 byte */ -} - -static int -dispsize(Inst *ip) -{ - ushort ext; - static int dsize[] = {0, 0, 1, 2}; /* in words */ - - if (get2(ip->addr+ip->n*2, &ext) < 0) - return -1; - if ((ext&0x100) == 0) - return 1; - return dsize[(ext>>4)&0x03]+dsize[ext&0x03]+1; -} - -static int -immsize(Inst *ip, int mode) -{ - static int fsize[] = { 2, 2, 6, 12, 1, 4, 1, -1 }; - static int isize[] = { 1, 1, 2, -1 }; - - switch(mode) - { - case EAM_B: /* byte */ - case EAALL_B: - case EADI_W: /* word */ - case EAALL_W: - return 1; - case EADI_L: /* long */ - case EAALL_L: - return 2; - case EAFLT: /* floating point - size in bits 10-12 or word 1 */ - return fsize[(ip->raw[1]>>10)&0x07]; - case IV: /* size encoded in bits 6&7 of opcode word */ - default: - return isize[(ip->raw[0]>>6)&0x03]; - } - return -1; -} - -static int -easize(Inst *ip, int ea, int mode) -{ - switch((ea>>3)&0x07) - { - case 0x00: - case 0x01: - case 0x02: - case 0x03: - case 0x04: - return 0; - case 0x05: - return 1; - case 0x06: - return dispsize(ip); - case 0x07: - switch(ea&0x07) - { - case 0x00: - case 0x02: - return 1; - case 0x01: - return 2; - case 0x03: - return dispsize(ip); - case 0x04: - return immsize(ip, mode); - default: - return -1; - } - } - return -1; -} - -static int -instrsize(Inst *ip, Optable *op) -{ - int i, t, mode; - short opcode; - - opcode = ip->raw[0]; - for (i = 0; i < nelem(op->opdata) && op->opdata[i]; i++) { - mode = op->opdata[i]; - switch(mode) - { - case EAPI: /* normal EA modes */ - case EACA: - case EACAD: - case EACAPI: - case EACAPD: - case EAMA: - case EADA: - case EAA: - case EAC: - case EACPI: - case EACD: - case EAD: - case EAM: - case EAM_B: - case EADI: - case EADI_L: - case EADI_W: - case EAALL: - case EAALL_L: - case EAALL_W: - case EAALL_B: - case EAFLT: - t = easize(ip, opcode&0x3f, mode); - if (t < 0) - return -1; - ip->n += t; - break; - case EADDA: /* stupid bit flop required */ - t = ((opcode>>9)&0x07)|((opcode>>3)&0x38); - t = easize(ip, t, mode); - if (t < 0) - return -1; - ip->n += t; - break; - case BREAC: /* EAC JMP or CALL operand */ - /* easy displacements for follow set */ - if ((opcode&0x038) == 0x28 || (opcode&0x3f) == 0x3a) { - if (i16(ip, &ip->and[i].immediate) < 0) - return -1; - } else { - t = easize(ip, opcode&0x3f, mode); - if (t < 0) - return -1; - ip->n += t; - } - break; - case I16: /* 16 bit immediate */ - case C16: /* CAS2 16 bit immediate */ - ip->n++; - break; - case BR16: /* 16 bit branch displacement */ - if (i16(ip, &ip->and[i].immediate) < 0) - return -1; - break; - case BR32: /* 32 bit branch displacement */ - if (i32(ip, &ip->and[i].immediate) < 0) - return -1; - break; - case I32: /* 32 bit immediate */ - ip->n += 2; - break; - case IV: /* immediate data depends on size field */ - t = (ip->raw[0]>>6)&0x03; - if (t < 2) - ip->n++; - else if (t == 2) - ip->n += 2; - else - return -1; - break; - case BR8: /* loony branch displacement format */ - t = opcode&0xff; - if (t == 0) { - if (i16(ip, &ip->and[i].immediate) < 0) - return -1; - } else if (t == 0xff) { - if (i32(ip, &ip->and[i].immediate) < 0) - return -1; - } else { - ip->and[i].immediate = t; - if (t & 0x80) - ip->and[i].immediate |= ~0xff; - } - break; - case STACK: /* Dummy operand for Return instructions */ - case OP8: /* weird movq instruction */ - case I8: /* must be two-word opcode */ - default: - break; - } - } - return 1; -} - -static int -m68020instlen(ulong pc) -{ - Inst i; - Optable *op; - - i.addr = pc; - i.errmsg = 0; - op = instruction(&i); - if (op && instrsize(&i, op) > 0) - return i.n*2; - return -1; -} - -static int -m68020inst(ulong pc, char modifier, char *buf, int n) -{ - Inst i; - Optable *op; - - USED(modifier); - i.addr = pc; - i.curr = buf; - i.end = buf+n-1; - i.errmsg = 0; - op = instruction(&i); - if (!op) - return -1; - if (decode(&i, op) > 0) - formatins(op->format, &i); - if (i.errmsg) { - if (i.curr != buf) - bprint(&i, "\t\t;"); - bprint(&i, "%s: ", i.errmsg); - dumpinst(&i, i.curr, i.end-i.curr); - } - return i.n*2; -} - -static int -m68020das(ulong pc, char *buf, int n) -{ - Inst i; - Optable *op; - - i.addr = pc; - i.curr = buf; - i.end = buf+n-1; - i.errmsg = 0; - - op = instruction(&i); - if (!op) - return -1; - decode(&i, op); - if (i.errmsg) - bprint(&i, "%s: ", i.errmsg); - dumpinst(&i, i.curr, i.end-i.curr); - return i.n*2; -} - -void -das(uchar *x, int n) -{ - int l, pc; - char buf[128]; - -/* int i; - for(i = 0; i < n; i++) - print("%.2ux", x[i]); - print("\n"); -*/ - dasdata = x; - pc = 0; - while(n > 0) { - if (m68020das(pc, buf, sizeof(buf))==-1) - sprint(buf,"illegal\t"); - print("%.8lux %2x %-20s ", dasdata+pc, pc, buf); - l = m68020inst(pc, 'i', buf, sizeof(buf)); - if (l!=-1) { - print("\t%s\n", buf); - buf[0]=0; - - pc += l; - n -= l; - } else { - print("Illegal\n"); - pc+=2; - n+=2; - } - } -} 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--; - } -} diff --git a/libinterp/mkfile b/libinterp/mkfile index 81f39198..8881dca8 100644 --- a/libinterp/mkfile +++ b/libinterp/mkfile @@ -117,7 +117,6 @@ freetype.$O: freetypemod.h $ROOT/include/freetype.h math.$O: $ROOT/include/mathi.h das-spim.c:N: das-mips.c -das-68000.c:N: das-68020.c comp-spim.c:N: comp-mips.c # optab.h: $ROOT/include/isa.h mkoptab |
