#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 2static int pass; static voidOP(int o, int o1, int o2, char *s){ if(o < o1 || o > o2) print("error: bad op %d in %s\n", o, s);} static voidIMM(int i, int i1, int i2, char *s) { if(i < i1 || i > i2) print("error: bad imm %d in %s\n", i, s);} static voidMULT(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 voidLOWREG(int r, char *s){ if(r < 0 || r >= 8) print("error: %s: bad low reg %d\n", s, r);} static voidHIGHREG(int r, char *s){ if(r < 8) print("error: %s: bad high reg %d\n", s, r);} static voidCKIRRS(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 voidCKRRR(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 voidCKIRR(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 voidCKIR(int op, int i, int rd){ OP(op, Mov, Sub, "IR"); IMM(i, 0, 255, "IR"); LOWREG(rd, "IR rd");} static voidCKRR(int op, int rs, int rd){ OP(op, And, Mvn, "RR"); LOWREG(rs, "RR rs"); LOWREG(rd, "RR rd");} static voidCKRH(int op, int rs, int rd){ OP(op, Add, Movh, "RH"); LOWREG(rs, "RH"); HIGHREG(rd, "RH");} static voidCKHR(int op, int rs, int rd){ OP(op, Add, Movh, "HR"); HIGHREG(rs, "HR"); LOWREG(rd, "HR");} static voidCKHH(int op, int rs, int rd){ OP(op, Add, Movh, "HH"); HIGHREG(rs, "HH"); HIGHREG(rd, "HH");} static voidCKLS(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 voidCKLSR(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 voidCKLPCR(int o, int rd){ LOWREG(rd, "LPCR"); if(o&3) o += 2; MULT(o, 4, "LPCR"); IMM(o/4, 0, 255, "LPCR");} static voidCKB(int o){ if(pass == FIRSTPASS) return; MULT(o, 2, "B"); IMM(o, -2048, 2046, "B");} static voidCKBCC(int o){ if(pass == FIRSTPASS) return; MULT(o, 2, "BCC"); IMM(o, -256, 254, "BCC");} static voidCKBL(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 voidcbranch(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 voidbranch(long o){ long off = o-4; if(pass == FIRSTPASS || (off >= -2048 && off <= 2046)) BRA(o); else{ if((int)CODE&2) PAD(); BRALONG(o); }} static voidcall(long o){ long off = o-4; if(pass == FIRSTPASS || (off >= -4194304 && off <= 4194302)) genc(o); else{ if(!((int)CODE&2)) PAD(); CALLLONG(o); }} static voidrdestroy(void){ destroy(R.s);} static voidrmcall(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);}Lines 1–500 of 2466. Load more
#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); }