#include "lib9.h"#include "isa.h"#include "interp.h"#include "raise.h" #define P4(o) ((o) < (1 << 4))#define N4(o) (~(o) < (1 << 4))#define P13(o) ((o) < (1 << 13))#define N13(o) (~(o) < (1 << 13))#define B4(o) ((o) & M4)#define B11(o) ((o) & M11)#define B13(o) ((o) & M13)#define B21(o) ((o) & M21) #define DOT ((ulong)code)#define RELPC(pc) ((ulong)(base+pc)) #define nop() arith(Aor, RZ, RZ, RZ)#define bra(o) BL(RZ, (o))#define add(r, c) LDSTpos(Oldo, c, r, r)#define displ(ix) ((ulong)(base+patch[ix]-code-2))#define mdispl(ix) ((ulong)(base+macro[ix]-code-2))#define mbra(ix) bra(mdispl(ix)) enum{ R0 = 0, R1 = 1, R2 = 2, R19 = 19, R20 = 20, R21 = 21, R22 = 22, R23 = 23, R24 = 24, R25 = 25, R26 = 26, R27 = 27, R28 = 28, R29 = 29, R30 = 30, R31 = 31, RLINK = R2, /* Function linkage */ RZ = R0, /* Always 0 */ RFP = R26, /* Frame Pointer */ RMP = R25, /* Module Pointer */ RREG = R24, /* Pointer to REG */ RTA = R29, /* Intermediate address for double indirect */ RCON = R23, /* Constant builder */ RCALL = R31, /* Call temp and link dest */ RA3 = R22, /* gpr 3 */ RA2 = R21, /* gpr 2 2+3 = big */ RA1 = R20, /* gpr 1 */ RA0 = R19, /* gpr 0 0+1 = big */ RCSP = R30, /* C stack pointer */ RARG0 = R26, /* C arg0 */ RMILLI0 = R22, /* Millicode arg0 */ /* Floating */ FRZ = 0, /* Zero */ FR0 = 4, FR1 = 5, /* opcodes */ Osys = 0x00, Oarith = 0x02, Oldwx = 0x03, Oldil = 0x08, Oldo = 0x0D, Oldb = 0x10, Oldh = 0x11, Oldw = 0x12, Ostb = 0x18, Osth = 0x19, Ostw = 0x1A, Ocombt = 0x20, Ocomibt = 0x21, Ocombf = 0x22, Ocomibf = 0x23, Oaddibt = 0x29, Oaddibf = 0x2B, Oextrs = 0x34, Obe = 0x38, Oble = 0x39, Obr = 0x3A, Oflldst = 0x0B, Ofltc = 0x0C, Ftst = 0x2420, Fload = 0, Fstore = 1, /* psuedo opcodes */ Pld = 0x10, /* base of loads */ Pst = 0x18, /* base of stores */ /* sub opcodes */ Aand = 0x10, Aor = 0x12, Axor = 0x14, Asub = 0x20, Aadd = 0x30, Ash1add = 0x32, Ash2add = 0x34, /* FP sub codes */ Fadd = 0, Fsub = 1, Fmul = 2, Fdiv = 3, Sldsid = 0x85, Smtsp = 0xC1, /* conditions */ Cnever = 0, Cequal = 1, Cless = 2, Cleq = 3, Clessu = 4, Clequ = 5, Csv = 6, Codd = 7, /* FP conditions */ Fnever = 0, Fequal = 1, Fless = 2, Fleq = 3, Fgrt = 4, Fgeq = 5, Fneq = 6, Falways = 7, /* masks */ M4 = 0xF, M5 = 0x1F, M10 = 0x3FF, M11 = 0x7FF, M13 = 0x1FFF, M21 = 0x1FFFFF, /* spaces */ STemp = 0, SCode = 4, SData = 5, PRESZ = 20, /* punt ops */ 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 ulong* code;static ulong* 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 ulong *dataptr;extern void calldata();extern void calltext();extern long dyncall; #define T(r) *((void**)(R.r)) static voidprlast(){ print("%x\t%x\n", code - 1, code[-1]);} 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) error(p->kill);} static voidrmfram(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 voidurk(void){ error("compile failed");} static intmkspace(int s){ return ((s & 4) << 11) | ((s & 3) << 14);} static ulongposdisp(int disp){ return (((disp & M10) << 1) | ((disp >> 10) & 1)) << 2;} static ulongdisp11(int disp){ return posdisp(disp) | (disp < 0 ? 1 : 0);} static voidopatch(ulong *b){ *b |= posdisp(code - b - 2);} static ulongfrig17(ulong v){ return ((v & M10) << 3) | ((v & (1 << 10)) >> 8) | ((v & (M5 << 11)) << 5) | ((v >> 16) & 1);} static ulongfrig21(ulong v){ return ((v >> 20) & 1) | ((v >> 8) & (M11 << 1)) | ((v & 3) << 12) | ((v & (3 << 7)) << 7) | ((v & (M5 << 2)) << 14);} static voidBLE(int r, int off, int s){ *code++ = (Oble << 26) | (r << 21) | mkspace(s) | frig17(off >> 2);} static voidBE(int r, int off, int s){ *code++ = (Obe << 26) | (r << 21) | mkspace(s) | frig17(off);} static voidBL(int r, int off){ *code++ = (Obr << 26) | (r << 21) | frig17(off);} static voidBV(int r){ *code++ = (Obr << 26) | (r << 21) | (6 << 13);} static voidLDIL(int r, ulong imm){ *code++ = (Oldil << 26) | (r << 21) | frig21(imm);} static voidLDWX(int i, int b, int r, int t){ *code++ = (Oldwx << 26) | (b << 21) | (r << 16) | ((i - Pld) << 6) | t;} static voidLDSTneg(int i, ulong off, int b, int r){ *code++ = (i << 26) | (b << 21) | (r << 16) | (B13(off) << 1) | 1;} static voidLDSTpos(int i, ulong off, int b, int r){ *code++ = (i << 26) | (b << 21) | (r << 16) | (off << 1);} static voidFLDSTneg(int inst, ulong disp, int rm, int r){ *code++ = (Oflldst << 26) | (rm << 21) | (B4(disp) << 17) | (1 << 16) | (1 << 12) | (inst << 9) | r;} static voidFLDSTpos(int inst, ulong disp, int rm, int r){ *code++ = (Oflldst << 26) | (rm << 21) | (disp << 17) | (1 << 12) | (inst << 9) | r;} static voidFLDSTX(int inst, int b, int x, int r){ *code++ = (Oflldst << 26) | (b << 21) | (x << 17) | (inst << 9) | r;} static voidFCMP(int r, int c, int b){ *code++ = (Ofltc << 26) | (r << 21) | (b << 16) | (6 << 9) | (c << 2);} static voidFTEST(){ *code++ = (Ofltc << 26) | Ftst;} static voidfarith(int o, int r1, int r2, int t){ *code++ = (Ofltc << 26) | (r1 << 21) | (r2 << 16) | (o << 13) | (7 << 9) | t;} static voidarith(int o, int s, int m, int d){ *code++ = (Oarith << 26) | (m << 21) | (s << 16) | (o << 5) | d;} static voidmov(int s, int d){ LDSTpos(Oldo, 0, s, d);} static voidshrs(int r, int s, int t){ *code++ = (Oextrs << 26) | (r << 21) | (t << 16) | (7 << 10) | ((31 - s) << 5) | s;} static voidcomb(int op, int r1, int c, int r2, int off){ *code++ = (op << 26) | (r2 << 21) | (r1 << 16) | (c << 13) | disp11(off);} static intes5(int v){ return (B4(v) << 1) | (v < 0 ? 1 : 0);} static voidcombt(int r1, int c, int r2, int off){ comb(Ocombt, r1, c, r2, off);} static voidcomibt(int r1, int c, int v, int off){ comb(Ocomibt, es5(v), c, r1, off);} static voidcombf(int r1, int c, int r2, int off){ comb(Ocombf, r1, c, r2, off);} static voidcomibf(int r1, int c, int v, int off){ comb(Ocomibf, es5(v), c, r1, off);} static voidcombdis(int r1, int c, int r2, int f, int ix){ comb(f ? Ocombf : Ocombt, r1, c, r2, displ(ix));} static voidaddibt(int r1, int c, int v, int off){ comb(Oaddibt, es5(v), c, r1, off);} static voidaddibf(int r1, int c, int v, int off){ comb(Oaddibf, es5(v), c, r1, off);} static voidcon(ulong o, int r, int opt){ if(opt) { if(P13(o)) { LDSTpos(Oldo, o, RZ, r); return; } if(N13(o)) { LDSTneg(Oldo, o, RZ, r); return; } LDIL(r, B21(o >> 11)); if(B11(o) != 0) LDSTpos(Oldo, B11(o), r, r); } else { LDIL(r, B21(o >> 11));Lines 1–500 of 2024. Load more
#include "lib9.h" #include "isa.h" #include "interp.h" #include "raise.h" #define P4(o) ((o) < (1 << 4)) #define N4(o) (~(o) < (1 << 4)) #define P13(o) ((o) < (1 << 13)) #define N13(o) (~(o) < (1 << 13)) #define B4(o) ((o) & M4) #define B11(o) ((o) & M11) #define B13(o) ((o) & M13) #define B21(o) ((o) & M21) #define DOT ((ulong)code) #define RELPC(pc) ((ulong)(base+pc)) #define nop() arith(Aor, RZ, RZ, RZ) #define bra(o) BL(RZ, (o)) #define add(r, c) LDSTpos(Oldo, c, r, r) #define displ(ix) ((ulong)(base+patch[ix]-code-2)) #define mdispl(ix) ((ulong)(base+macro[ix]-code-2)) #define mbra(ix) bra(mdispl(ix)) enum { R0 = 0, R1 = 1, R2 = 2, R19 = 19, R20 = 20, R21 = 21, R22 = 22, R23 = 23, R24 = 24, R25 = 25, R26 = 26, R27 = 27, R28 = 28, R29 = 29, R30 = 30, R31 = 31, RLINK = R2, /* Function linkage */ RZ = R0, /* Always 0 */ RFP = R26, /* Frame Pointer */ RMP = R25, /* Module Pointer */ RREG = R24, /* Pointer to REG */ RTA = R29, /* Intermediate address for double indirect */ RCON = R23, /* Constant builder */ RCALL = R31, /* Call temp and link dest */ RA3 = R22, /* gpr 3 */ RA2 = R21, /* gpr 2 2+3 = big */ RA1 = R20, /* gpr 1 */ RA0 = R19, /* gpr 0 0+1 = big */ RCSP = R30, /* C stack pointer */ RARG0 = R26, /* C arg0 */ RMILLI0 = R22, /* Millicode arg0 */ /* Floating */ FRZ = 0, /* Zero */ FR0 = 4, FR1 = 5, /* opcodes */ Osys = 0x00, Oarith = 0x02, Oldwx = 0x03, Oldil = 0x08, Oldo = 0x0D, Oldb = 0x10, Oldh = 0x11, Oldw = 0x12, Ostb = 0x18, Osth = 0x19, Ostw = 0x1A, Ocombt = 0x20, Ocomibt = 0x21, Ocombf = 0x22, Ocomibf = 0x23, Oaddibt = 0x29, Oaddibf = 0x2B, Oextrs = 0x34, Obe = 0x38, Oble = 0x39, Obr = 0x3A, Oflldst = 0x0B, Ofltc = 0x0C, Ftst = 0x2420, Fload = 0, Fstore = 1, /* psuedo opcodes */ Pld = 0x10, /* base of loads */ Pst = 0x18, /* base of stores */ /* sub opcodes */ Aand = 0x10, Aor = 0x12, Axor = 0x14, Asub = 0x20, Aadd = 0x30, Ash1add = 0x32, Ash2add = 0x34, /* FP sub codes */ Fadd = 0, Fsub = 1, Fmul = 2, Fdiv = 3, Sldsid = 0x85, Smtsp = 0xC1, /* conditions */ Cnever = 0, Cequal = 1, Cless = 2, Cleq = 3, Clessu = 4, Clequ = 5, Csv = 6, Codd = 7, /* FP conditions */ Fnever = 0, Fequal = 1, Fless = 2, Fleq = 3, Fgrt = 4, Fgeq = 5, Fneq = 6, Falways = 7, /* masks */ M4 = 0xF, M5 = 0x1F, M10 = 0x3FF, M11 = 0x7FF, M13 = 0x1FFF, M21 = 0x1FFFFF, /* spaces */ STemp = 0, SCode = 4, SData = 5, PRESZ = 20, /* punt ops */ 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 ulong* code; static ulong* 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 ulong *dataptr; extern void calldata(); extern void calltext(); extern long dyncall; #define T(r) *((void**)(R.r)) static void prlast() { print("%x\t%x\n", code - 1, code[-1]); } 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) 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 void urk(void) { error("compile failed"); } static int mkspace(int s) { return ((s & 4) << 11) | ((s & 3) << 14); } static ulong posdisp(int disp) { return (((disp & M10) << 1) | ((disp >> 10) & 1)) << 2; } static ulong disp11(int disp) { return posdisp(disp) | (disp < 0 ? 1 : 0); } static void opatch(ulong *b) { *b |= posdisp(code - b - 2); } static ulong frig17(ulong v) { return ((v & M10) << 3) | ((v & (1 << 10)) >> 8) | ((v & (M5 << 11)) << 5) | ((v >> 16) & 1); } static ulong frig21(ulong v) { return ((v >> 20) & 1) | ((v >> 8) & (M11 << 1)) | ((v & 3) << 12) | ((v & (3 << 7)) << 7) | ((v & (M5 << 2)) << 14); } static void BLE(int r, int off, int s) { *code++ = (Oble << 26) | (r << 21) | mkspace(s) | frig17(off >> 2); } static void BE(int r, int off, int s) { *code++ = (Obe << 26) | (r << 21) | mkspace(s) | frig17(off); } static void BL(int r, int off) { *code++ = (Obr << 26) | (r << 21) | frig17(off); } static void BV(int r) { *code++ = (Obr << 26) | (r << 21) | (6 << 13); } static void LDIL(int r, ulong imm) { *code++ = (Oldil << 26) | (r << 21) | frig21(imm); } static void LDWX(int i, int b, int r, int t) { *code++ = (Oldwx << 26) | (b << 21) | (r << 16) | ((i - Pld) << 6) | t; } static void LDSTneg(int i, ulong off, int b, int r) { *code++ = (i << 26) | (b << 21) | (r << 16) | (B13(off) << 1) | 1; } static void LDSTpos(int i, ulong off, int b, int r) { *code++ = (i << 26) | (b << 21) | (r << 16) | (off << 1); } static void FLDSTneg(int inst, ulong disp, int rm, int r) { *code++ = (Oflldst << 26) | (rm << 21) | (B4(disp) << 17) | (1 << 16) | (1 << 12) | (inst << 9) | r; } static void FLDSTpos(int inst, ulong disp, int rm, int r) { *code++ = (Oflldst << 26) | (rm << 21) | (disp << 17) | (1 << 12) | (inst << 9) | r; } static void FLDSTX(int inst, int b, int x, int r) { *code++ = (Oflldst << 26) | (b << 21) | (x << 17) | (inst << 9) | r; } static void FCMP(int r, int c, int b) { *code++ = (Ofltc << 26) | (r << 21) | (b << 16) | (6 << 9) | (c << 2); } static void FTEST() { *code++ = (Ofltc << 26) | Ftst; } static void farith(int o, int r1, int r2, int t) { *code++ = (Ofltc << 26) | (r1 << 21) | (r2 << 16) | (o << 13) | (7 << 9) | t; } static void arith(int o, int s, int m, int d) { *code++ = (Oarith << 26) | (m << 21) | (s << 16) | (o << 5) | d; } static void mov(int s, int d) { LDSTpos(Oldo, 0, s, d); } static void shrs(int r, int s, int t) { *code++ = (Oextrs << 26) | (r << 21) | (t << 16) | (7 << 10) | ((31 - s) << 5) | s; } static void comb(int op, int r1, int c, int r2, int off) { *code++ = (op << 26) | (r2 << 21) | (r1 << 16) | (c << 13) | disp11(off); } static int es5(int v) { return (B4(v) << 1) | (v < 0 ? 1 : 0); } static void combt(int r1, int c, int r2, int off) { comb(Ocombt, r1, c, r2, off); } static void comibt(int r1, int c, int v, int off) { comb(Ocomibt, es5(v), c, r1, off); } static void combf(int r1, int c, int r2, int off) { comb(Ocombf, r1, c, r2, off); } static void comibf(int r1, int c, int v, int off) { comb(Ocomibf, es5(v), c, r1, off); } static void combdis(int r1, int c, int r2, int f, int ix) { comb(f ? Ocombf : Ocombt, r1, c, r2, displ(ix)); } static void addibt(int r1, int c, int v, int off) { comb(Oaddibt, es5(v), c, r1, off); } static void addibf(int r1, int c, int v, int off) { comb(Oaddibf, es5(v), c, r1, off); } static void con(ulong o, int r, int opt) { if(opt) { if(P13(o)) { LDSTpos(Oldo, o, RZ, r); return; } if(N13(o)) { LDSTneg(Oldo, o, RZ, r); return; } LDIL(r, B21(o >> 11)); if(B11(o) != 0) LDSTpos(Oldo, B11(o), r, r); } else { LDIL(r, B21(o >> 11));