#include "lib9.h"#include "isa.h"#include "interp.h"#include "raise.h" enum{ R8 = 8, /* SUN calls these %o0 - %o7 */ R9 = 9, R10 = 10, R11 = 11, R12 = 12, R13 = 13, R14 = 14, /* SUN %sp */ R15 = 15, /* R15/%o7 is the default link register */ R16 = 16, /* SUN calls these %l0 - %l7 */ R17 = 17, R18 = 18, R19 = 19, R20 = 20, R21 = 21, R22 = 22, R23 = 23, RLINK = 15, RZ = 0, /* Always 0 */ RFP = R23, /* Frame Pointer */ RMP = R22, /* Module Pointer */ RTA = R21, /* Intermediate address for double indirect */ RREG = R20, /* Pointer to REG */ RA3 = R19, /* gpr 3 */ RA2 = R18, /* gpr 2 2+3 = L */ RA1 = R17, /* gpr 1 */ RA0 = R16, /* gpr 0 0+1 = L */ RCON = R8, /* Constant builder */ FA2 = 2, /* Floating */ FA3 = 3, FA4 = 4, FA5 = 5, Olea = (1<<20), /* Pseudo op */ Owry = 48, Omul = 11, Oumul = 10, Osdiv = 15, Osll = 37, Osra = 39, Osrl = 38, Osethi = 4, Oadd = 0, Oaddcc = 16, Oaddx = 8, Osub = 4, Osubcc = 20, Osubx = 12, Oor = 2, Oand = 1, Oxor = 3, Oldw = 0, Oldsh = 10, Ostw = 4, Osth = 6, Ojmpl = 56, Ocall = 1, Ocmp = 20, /* subcc */ Oldbu = 1, Ostb = 5, Oba = 8, Obn = 0, Obne = 9, Obe = 1, Obg = 10, Oble = 2, Obge = 11, Obl = 3, Obgu = 12, Obleu = 4, Obcc = 13, Obcs = 5, Obpos = 14, Obneg = 6, Obvc = 15, Obvs = 7, OfaddD = 66, OfsubD = 70, OfdivD = 78, OfmulD = 74, Oldf = 32, Ostf = 36, OfDtoQ = 206, OfnegS = 5, OfcmpD = 82, Ofba = 8, Ofbe = 9, Ofbg = 6, Ofbge = 11, Ofbl = 4, Ofble = 13, Ofbne = 1, OfWtoD = 200, OfDtoW = 210, Osave = 60, Orestore= 61, 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}; #define OP(n) (n<<30)#define I13(i) ((i)&0x1fff)#define D22(i) ((i)&0x3fffff)#define PC30(pc) (((ulong)(pc) - (ulong)code)>>2) #define CALL(addr) *code=OP(1)|PC30(addr); code++#define FM2I(op2, i, rd) *code=OP(0)|(rd<<25)|(op2<<22)|D22(i); code++#define BRA(cond, disp) *code=OP(0)|(cond<<25)|(2<<22)|D22((disp)); code++#define BRAF(cond, disp) *code=OP(0)|(cond<<25)|(6<<22)|D22((disp)); code++#define BRADIS(r, o) BRA(r, ((ulong)(base+patch[o])-(ulong)code)>>2)#define BRAFDIS(r, o) BRAF(r, ((ulong)(base+patch[o])-(ulong)code)>>2)#define BRAMAC(r, o) BRA(r, ((ulong)(base+macro[o])-(ulong)code)>>2);#define FM3I(op, op3, i, rs1, rd) *code++=OP(op)|(rd<<25)|(op3<<19)|(rs1<<14)|\ (1<<13)|I13(i)#define FM3(op, op3, rs2, rs1, rd) *code++=OP(op)|(rd<<25)|(op3<<19)|(rs1<<14)|rs2#define FMF1(opf, rs2, rs1, rd) *code++=OP(2)|(rd<<25)|(52<<19)|(rs1<<14)|(opf<<5)|rs2#define FMF2(opf, rs2, rs1, rd) *code++=OP(2)|(rd<<25)|(53<<19)|(rs1<<14)|(opf<<5)|rs2#define NOOP *code++=(4<<22)#define RETURN FM3I(2, Ojmpl, 8, RLINK, RZ);#define MOV(s, d) FM3(2, Oor, s, RZ, d) #define RELPC(pc) (ulong)(base+pc)#define PATCH(ptr) *ptr |= (code-ptr) & 0x3fffff static ulong* code;static ulong* base;static ulong* patch;static int pass;static int puntpc = 1;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(ulong*, 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 */}; static voidrdestroy(void){ destroy(R.s);} static voidrmcall(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 voidrmfram(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 voidurk(void){ error(exCompile);} static intbc(long c){ c &= ~0xfffL; if (c == 0 || c == ~0xfffL) return 1; return 0;} static voidcon(ulong o, int r, int opt){ if(opt != 0) { if(bc(o)) { FM3I(2, Oadd, o & 0x1fff, RZ, r); return; } if((o & 0x3ff) == 0) { FM2I(Osethi, o>>10, r); return; } } FM2I(Osethi, o>>10, r); FM3I(2, Oadd, o & 0x3ff, r, r);} static voidmem(int inst, ulong disp, int rm, int r){ int op; op = 3; if(inst == Olea) { op = 2; inst = Oadd; } if(bc(disp)) { FM3I(op, inst, disp, rm, r); return; } con(disp, RCON, 1); FM3(op, inst, RCON, rm, r);} static voidopwld(Inst *i, int mi, int r){ int ir, rta; switch(UXSRC(i->add)) { default: print("%D\n", i); urk(); case SRC(AFP): mem(mi, i->s.ind, RFP, r); return; case SRC(AMP): mem(mi, i->s.ind, RMP, r); return; case SRC(AIMM): con(i->s.imm, r, 1); if(mi == Olea) { mem(Ostw, O(REG, st), RREG, r); con((ulong)&R.st, r, 1); } return; case SRC(AIND|AFP): ir = RFP; break; case SRC(AIND|AMP): ir = RMP; break; } rta = RTA; if(mi == Olea) rta = r; mem(Oldw, i->s.i.f, ir, rta); mem(mi, i->s.i.s, rta, r);} static voidopwst(Inst *i, int mi, int r){ int ir, rta; switch(UXDST(i->add)) { default: print("%D\n", i); urk(); case DST(AIMM): con(i->d.imm, r, 1); return; case DST(AFP): mem(mi, i->d.ind, RFP, r); return; case DST(AMP): mem(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 == Olea) rta = r; mem(Oldw, i->d.i.f, ir, rta); mem(mi, i->d.i.s, rta, r);} static voidopfl(Adr *a, int am, int mi, int r){ int ir; switch(am) { default: urk(); case AFP: mem(mi, a->ind, RFP, r); mem(mi, a->ind+4, RFP, r+1); return; case AMP: mem(mi, a->ind, RMP, r); mem(mi, a->ind+4, RMP, r+1); return; case AIND|AFP: ir = RFP; break; case AIND|AMP: ir = RMP; break; } mem(Oldw, a->i.f, ir, RTA); mem(mi, a->i.s, RTA, r); mem(mi, a->i.s+4, RTA, r+1);} static voidopflld(Inst *i, int mi, int r){ opfl(&i->s, USRC(i->add), mi, r);} static voidopflst(Inst *i, int mi, int r){ opfl(&i->d, UDST(i->add), mi, r);} static voidliteral(ulong imm, int roff){ nlit++; con((ulong)litpool, RTA, 0); mem(Ostw, roff, RREG, RTA); if(pass == 0) return; *litpool = imm; litpool++; } static voidpunt(Inst *i, int m, void (*fn)(void)){ ulong pc; if(m & SRCOP) { if(UXSRC(i->add) == SRC(AIMM)) literal(i->s.imm, O(REG, s)); else { opwld(i, Olea, RA0); mem(Ostw, O(REG, s), RREG, RA0); } } if(m & DSTOP) { opwst(i, Olea, RA0); mem(Ostw, O(REG, d), RREG, RA0); } if(m & WRTPC) { con(RELPC(patch[i-mod->prog+1]), RA0, 0); mem(Ostw, O(REG, PC), RREG, RA0); } if(m & DBRAN) { pc = patch[(Inst*)i->d.imm-mod->prog]; literal(RELPC(pc), O(REG, d)); } switch(i->add&ARM) { case AXNON: if(m & THREOP) { mem(Oldw, O(REG, d), RREG, RA0); mem(Ostw, O(REG, m), RREG, RA0); } break; case AXIMM: literal((short)i->reg, O(REG, m)); break; case AXINF: mem(Olea, i->reg, RFP, RA0); mem(Ostw, O(REG, m), RREG, RA0); break; case AXINM: mem(Olea, i->reg, RMP, RA0); mem(Ostw, O(REG, m), RREG, RA0); break; } CALL(fn); mem(Ostw, O(REG, FP), RREG, RFP); con((ulong)&R, RREG, 1); if(m & TCHECK) { mem(Oldw, O(REG, t), RREG, RA0); FM3I(2, Ocmp, 0, RA0, RZ); BRA(Obe, 5); NOOP; mem(Oldw, O(REG, xpc), RREG, RLINK); RETURN; NOOP; } mem(Oldw, O(REG, FP), RREG, RFP); mem(Oldw, O(REG, MP), RREG, RMP); if(m & NEWPC) { mem(Oldw, O(REG, PC), RREG, RA0); FM3I(2, Ojmpl, 0, RA0, RZ); NOOP; }} static voidmidfl(Inst *i, int mi, int r){ int ir; switch(i->add&ARM) { default:Lines 1–500 of 1882. Load more
#include "lib9.h" #include "isa.h" #include "interp.h" #include "raise.h" enum { R8 = 8, /* SUN calls these %o0 - %o7 */ R9 = 9, R10 = 10, R11 = 11, R12 = 12, R13 = 13, R14 = 14, /* SUN %sp */ R15 = 15, /* R15/%o7 is the default link register */ R16 = 16, /* SUN calls these %l0 - %l7 */ R17 = 17, R18 = 18, R19 = 19, R20 = 20, R21 = 21, R22 = 22, R23 = 23, RLINK = 15, RZ = 0, /* Always 0 */ RFP = R23, /* Frame Pointer */ RMP = R22, /* Module Pointer */ RTA = R21, /* Intermediate address for double indirect */ RREG = R20, /* Pointer to REG */ RA3 = R19, /* gpr 3 */ RA2 = R18, /* gpr 2 2+3 = L */ RA1 = R17, /* gpr 1 */ RA0 = R16, /* gpr 0 0+1 = L */ RCON = R8, /* Constant builder */ FA2 = 2, /* Floating */ FA3 = 3, FA4 = 4, FA5 = 5, Olea = (1<<20), /* Pseudo op */ Owry = 48, Omul = 11, Oumul = 10, Osdiv = 15, Osll = 37, Osra = 39, Osrl = 38, Osethi = 4, Oadd = 0, Oaddcc = 16, Oaddx = 8, Osub = 4, Osubcc = 20, Osubx = 12, Oor = 2, Oand = 1, Oxor = 3, Oldw = 0, Oldsh = 10, Ostw = 4, Osth = 6, Ojmpl = 56, Ocall = 1, Ocmp = 20, /* subcc */ Oldbu = 1, Ostb = 5, Oba = 8, Obn = 0, Obne = 9, Obe = 1, Obg = 10, Oble = 2, Obge = 11, Obl = 3, Obgu = 12, Obleu = 4, Obcc = 13, Obcs = 5, Obpos = 14, Obneg = 6, Obvc = 15, Obvs = 7, OfaddD = 66, OfsubD = 70, OfdivD = 78, OfmulD = 74, Oldf = 32, Ostf = 36, OfDtoQ = 206, OfnegS = 5, OfcmpD = 82, Ofba = 8, Ofbe = 9, Ofbg = 6, Ofbge = 11, Ofbl = 4, Ofble = 13, Ofbne = 1, OfWtoD = 200, OfDtoW = 210, Osave = 60, Orestore= 61, 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 }; #define OP(n) (n<<30) #define I13(i) ((i)&0x1fff) #define D22(i) ((i)&0x3fffff) #define PC30(pc) (((ulong)(pc) - (ulong)code)>>2) #define CALL(addr) *code=OP(1)|PC30(addr); code++ #define FM2I(op2, i, rd) *code=OP(0)|(rd<<25)|(op2<<22)|D22(i); code++ #define BRA(cond, disp) *code=OP(0)|(cond<<25)|(2<<22)|D22((disp)); code++ #define BRAF(cond, disp) *code=OP(0)|(cond<<25)|(6<<22)|D22((disp)); code++ #define BRADIS(r, o) BRA(r, ((ulong)(base+patch[o])-(ulong)code)>>2) #define BRAFDIS(r, o) BRAF(r, ((ulong)(base+patch[o])-(ulong)code)>>2) #define BRAMAC(r, o) BRA(r, ((ulong)(base+macro[o])-(ulong)code)>>2); #define FM3I(op, op3, i, rs1, rd) *code++=OP(op)|(rd<<25)|(op3<<19)|(rs1<<14)|\ (1<<13)|I13(i) #define FM3(op, op3, rs2, rs1, rd) *code++=OP(op)|(rd<<25)|(op3<<19)|(rs1<<14)|rs2 #define FMF1(opf, rs2, rs1, rd) *code++=OP(2)|(rd<<25)|(52<<19)|(rs1<<14)|(opf<<5)|rs2 #define FMF2(opf, rs2, rs1, rd) *code++=OP(2)|(rd<<25)|(53<<19)|(rs1<<14)|(opf<<5)|rs2 #define NOOP *code++=(4<<22) #define RETURN FM3I(2, Ojmpl, 8, RLINK, RZ); #define MOV(s, d) FM3(2, Oor, s, RZ, d) #define RELPC(pc) (ulong)(base+pc) #define PATCH(ptr) *ptr |= (code-ptr) & 0x3fffff static ulong* code; static ulong* base; static ulong* patch; static int pass; static int puntpc = 1; 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(ulong*, 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 */ }; 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; 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(void) { error(exCompile); } static int bc(long c) { c &= ~0xfffL; if (c == 0 || c == ~0xfffL) return 1; return 0; } static void con(ulong o, int r, int opt) { if(opt != 0) { if(bc(o)) { FM3I(2, Oadd, o & 0x1fff, RZ, r); return; } if((o & 0x3ff) == 0) { FM2I(Osethi, o>>10, r); return; } } FM2I(Osethi, o>>10, r); FM3I(2, Oadd, o & 0x3ff, r, r); } static void mem(int inst, ulong disp, int rm, int r) { int op; op = 3; if(inst == Olea) { op = 2; inst = Oadd; } if(bc(disp)) { FM3I(op, inst, disp, rm, r); return; } con(disp, RCON, 1); FM3(op, inst, RCON, rm, r); } 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): mem(mi, i->s.ind, RFP, r); return; case SRC(AMP): mem(mi, i->s.ind, RMP, r); return; case SRC(AIMM): con(i->s.imm, r, 1); if(mi == Olea) { mem(Ostw, O(REG, st), RREG, r); con((ulong)&R.st, r, 1); } return; case SRC(AIND|AFP): ir = RFP; break; case SRC(AIND|AMP): ir = RMP; break; } rta = RTA; if(mi == Olea) rta = r; mem(Oldw, i->s.i.f, ir, rta); mem(mi, i->s.i.s, rta, r); } static void opwst(Inst *i, int mi, int r) { int ir, rta; switch(UXDST(i->add)) { default: print("%D\n", i); urk(); case DST(AIMM): con(i->d.imm, r, 1); return; case DST(AFP): mem(mi, i->d.ind, RFP, r); return; case DST(AMP): mem(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 == Olea) rta = r; mem(Oldw, i->d.i.f, ir, rta); mem(mi, i->d.i.s, rta, r); } static void opfl(Adr *a, int am, int mi, int r) { int ir; switch(am) { default: urk(); case AFP: mem(mi, a->ind, RFP, r); mem(mi, a->ind+4, RFP, r+1); return; case AMP: mem(mi, a->ind, RMP, r); mem(mi, a->ind+4, RMP, r+1); return; case AIND|AFP: ir = RFP; break; case AIND|AMP: ir = RMP; break; } mem(Oldw, a->i.f, ir, RTA); mem(mi, a->i.s, RTA, r); mem(mi, a->i.s+4, RTA, r+1); } static void opflld(Inst *i, int mi, int r) { opfl(&i->s, USRC(i->add), mi, r); } static void opflst(Inst *i, int mi, int r) { opfl(&i->d, UDST(i->add), mi, r); } static void literal(ulong imm, int roff) { nlit++; con((ulong)litpool, RTA, 0); mem(Ostw, roff, RREG, RTA); if(pass == 0) return; *litpool = imm; litpool++; } static void punt(Inst *i, int m, void (*fn)(void)) { ulong pc; if(m & SRCOP) { if(UXSRC(i->add) == SRC(AIMM)) literal(i->s.imm, O(REG, s)); else { opwld(i, Olea, RA0); mem(Ostw, O(REG, s), RREG, RA0); } } if(m & DSTOP) { opwst(i, Olea, RA0); mem(Ostw, O(REG, d), RREG, RA0); } if(m & WRTPC) { con(RELPC(patch[i-mod->prog+1]), RA0, 0); mem(Ostw, O(REG, PC), RREG, RA0); } if(m & DBRAN) { pc = patch[(Inst*)i->d.imm-mod->prog]; literal(RELPC(pc), O(REG, d)); } switch(i->add&ARM) { case AXNON: if(m & THREOP) { mem(Oldw, O(REG, d), RREG, RA0); mem(Ostw, O(REG, m), RREG, RA0); } break; case AXIMM: literal((short)i->reg, O(REG, m)); break; case AXINF: mem(Olea, i->reg, RFP, RA0); mem(Ostw, O(REG, m), RREG, RA0); break; case AXINM: mem(Olea, i->reg, RMP, RA0); mem(Ostw, O(REG, m), RREG, RA0); break; } CALL(fn); mem(Ostw, O(REG, FP), RREG, RFP); con((ulong)&R, RREG, 1); if(m & TCHECK) { mem(Oldw, O(REG, t), RREG, RA0); FM3I(2, Ocmp, 0, RA0, RZ); BRA(Obe, 5); NOOP; mem(Oldw, O(REG, xpc), RREG, RLINK); RETURN; NOOP; } mem(Oldw, O(REG, FP), RREG, RFP); mem(Oldw, O(REG, MP), RREG, RMP); if(m & NEWPC) { mem(Oldw, O(REG, PC), RREG, RA0); FM3I(2, Ojmpl, 0, RA0, RZ); NOOP; } } static void midfl(Inst *i, int mi, int r) { int ir; switch(i->add&ARM) { default: