Charles.Forsyth20060303a828770d19 years agoHistory
2466 lines · 45.1 KB · C
RawDownload
#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.