Charles.Forsyth20090627-2207a39e3d917 years agoHistory
2258 lines · 42.4 KB · C
RawDownload
#include "lib9.h"#include "isa.h"#include "interp.h"#include "raise.h" /* * to do: *	eliminate litpool? *	eliminate long constants in comi/comd *	enable and check inline FP code (not much point with fpemu) */ #define	RESCHED 1	/* check for interpreter reschedule */ enum{	R0	= 0,	R1	= 1,	R2	= 2,	R3	= 3,	R4	= 4,	R5	= 5,	R6	= 6,	R7	= 7,	R8	= 8,	R9	= 9,	R10	= 10,	R11	= 11,	R12	= 12,		/* C's SB */	R13	= 13,		/* C's SP */	R14	= 14,		/* Link Register */	R15	= 15,		/* PC */ 	RLINK	= 14, 	RFP	= R9,		/* Frame Pointer */	RMP	= R8,		/* Module Pointer */	RTA	= R7,		/* Intermediate address for double indirect */	RCON	= R6,		/* Constant builder */	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 */  	FA2	= 2,		/* Floating */	FA3	= 3,	FA4	= 4,	FA5	= 5, 	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, 	HS	= CS,	LO	= CC, 	And	= 0,	Eor	= 1,	Sub	= 2,	Rsb	= 3,	Add	= 4,	Adc	= 5,	Sbc	= 6,	Rsc	= 7,	Tst	= 8,	Teq	= 9,	Cmp	= 10,	Cmn	= 11,	Orr	= 12,	Mov	= 13,	Bic	= 14,	Mvn	= 15, 	Adf	= 0,	Muf	= 1,	Suf	= 2,	Rsf	= 3,	Dvf	= 4,	Rdf	= 5,	Rmf	= 8, 	Mvf	= 0,	Mnf	= 1,	Abs	= 2,	Rnd	= 3, 	Flt	= 0,	Fix	= 1, 	Cmf	= 4,	Cnf	= 5, 	Lea	= 100,		/* macro memory ops */	Ldw,	Ldb,	Stw,	Stb,	Ldf,	Stf,	Ldh, 	Blo	= 0,	/* offset of low order word in big */	Bhi	= 4,	/* offset of high order word in big */ 	NCON	= (0xFFC-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 BITS(B)				(1<<B)#define IMM(O)				(O & ((1<<12)-1))#define SBIT	(1<<20)#define PBIT	(1<<24)#define UPBIT	(1<<23) #define LDW(C, Rn, Rd, O)		*code++ = (C<<28)|(1<<26)|(1<<24)|(1<<23)|(1<<20)|\					  (Rn<<16)|(Rd<<12)|IMM(O)#define STW(C, Rn, Rd, O)		*code++ = (C<<28)|(1<<26)|(1<<24)|(1<<23)|\					  (Rn<<16)|(Rd<<12)|IMM(O)#define LDB(C, Rn, Rd, O)		*code++ = (C<<28)|(1<<26)|(1<<24)|(1<<23)|(1<<20)|(1<<22)|\					  (Rn<<16)|(Rd<<12)|IMM(O)#define STB(C, Rn, Rd, O)		*code++ = (C<<28)|(1<<26)|(1<<24)|(1<<23)|(1<<22)|\					  (Rn<<16)|(Rd<<12)|IMM(O) #define LDxP(C, Rn, Rd, O, B)		*code++ = (C<<28)|(1<<26)|(B<<22)|(1<<23)|(1<<20)|\					  (Rn<<16)|(Rd<<12)|IMM(O)#define STxP(C, Rn, Rd, O, B)		*code++ = (C<<28)|(1<<26)|(B<<22)|(1<<23)|\					  (Rn<<16)|(Rd<<12)|IMM(O)#define LDRW(C, Rn, Rd, SH, R)		*code++ = (C<<28)|(3<<25)|(1<<24)|(1<<23)|(1<<20)|\					  (Rn<<16)|(Rd<<12)|(SH<<4)|R#define STRW(C, Rn, Rd, SH, R)		*code++ = (C<<28)|(3<<25)|(1<<24)|(1<<23)|\					  (Rn<<16)|(Rd<<12)|(SH<<4)|R#define LDRB(C, Rn, Rd, SH, R)		*code++ = (C<<28)|(3<<25)|(1<<24)|(1<<23)|(1<<20)|(1<<22)|\					  (Rn<<16)|(Rd<<12)|(SH<<4)|R#define STRB(C, Rn, Rd, SH, R)		*code++ = (C<<28)|(3<<25)|(1<<24)|(1<<23)|(1<<22)|\					  (Rn<<16)|(Rd<<12)|(SH<<4)|R #define DPI(C, Op, Rn, Rd, RO, O)	*code++ = (C<<28)|(1<<25)|(Op<<21)|\					  (Rn<<16)|(Rd<<12)|(RO<<8)|((O)&0xff)#define DP(C, Op, Rn, Rd, Sh, Ro)	*code++ = (C<<28)|(Op<<21)|(Rn<<16)|\					  (Rd<<12)|((Sh)<<4)|Ro#define CMPI(C, Rn, Rd, RO, O)	*code++ = (C<<28)|(1<<25)|(Cmp<<21)|(1<<20)|\					  (Rn<<16)|(Rd<<12)|(RO<<8)|((O)&0xff)#define CMNI(C, Rn, Rd, RO, O)	*code++ = (C<<28)|(1<<25)|(Cmn<<21)|(1<<20)|\					  (Rn<<16)|(Rd<<12)|(RO<<8)|((O)&0xff)#define CMP(C, Rn, Rd, Sh, Ro)	*code++ = (C<<28)|(Cmp<<21)|(Rn<<16)|(1<<20)|\					  (Rd<<12)|((Sh)<<4)|Ro#define CMN(C, Rn, Rd, Sh, Ro)	*code++ = (C<<28)|(Cmn<<21)|(Rn<<16)|(1<<20)|\					  (Rd<<12)|((Sh)<<4)|Ro#define MUL(C, Rm, Rs, Rd)		*code++ = (C<<28)|(Rd<<16)|(Rm<<0)|(Rs<<8)|\					  (9<<4) #define LDF(C, Rn, Fd, O)		*code++ = (C<<28)|(6<<25)|(1<<24)|(1<<23)|(1<<20)|\					  (Rn<<16)|(1<<15)|(Fd<<12)|(1<<8)|((O)&0xff)#define STF(C, Rn, Fd, O)		*code++ = (C<<28)|(6<<25)|(1<<24)|(1<<23)|\					  (Rn<<16)|(1<<15)|(Fd<<12)|(1<<8)|((O)&0xff)#define CMF(C, Fn, Fm)	*code++ = (C<<28)|(7<<25)|(4<<21)|(1<<20)|(Fn<<16)|\						(0xF<<12)|(1<<8)|(1<<4)|(Fm) #define LDH(C, Rn, Rd, O)		*code++ = (C<<28)|(0<<25)|(1<<24)|(1<<23)|(1<<22)|(1<<20)|\					  (Rn<<16)|(Rd<<12)|(((O)&0xf0)<<4)|(0xb<<4)|((O)&0xf)#define LDRH(C, Rn, Rd, Rm)		*code++ = (C<<28)|(0<<25)|(1<<24)|(1<<23)|(1<<20)|\					  (Rn<<16)|(Rd<<12)|(0xb<<4)|Rm #define CPDO2(C, Op, Fn, Fd, Fm)	*code++ = (C<<28)|(0xE<<24)|(Op<<20)|(Fn<<16)|(Fd<<12)|(1<<8)|(1<<7)|(Fm)#define CPDO1(C, Op, Fd, Fm)	CPDO2((C),(Op),0,(Fd),(Fm))|(1<<15)#define CPFLT(C, Fn, Rd)	*code++ = (C<<28)|(0xE<<24)|(0<<20)|(Fn<<16)|(Rd<<12)|(1<<8)|(9<<4)#define CPFIX(C, Rd, Fm)	*code++ = (C<<28)|(0xE<<24)|(1<<20)|(0<<16)|(Rd<<12)|(1<<8)|(9<<4)|(Fm) #define BRAW(C, o)			((C<<28)|(5<<25)|((o) & 0x00ffffff))#define BRA(C, o)			gen(BRAW((C),(o)))#define IA(s, o)			(ulong)(base+s[o])#define BRADIS(C, o)			BRA(C, (IA(patch, o)-(ulong)code-8)>>2)#define BRAMAC(r, o)			BRA(r, (IA(macro, o)-(ulong)code-8)>>2)#define BRANCH(C, o)				gen(BRAW(C, ((ulong)(o)-(ulong)code-8)>>2))#define CALL(o)				gen(BRAW(AL, ((ulong)(o)-(ulong)code-8)>>2)|(1<<24))#define CCALL(C,o)				gen(BRAW((C), ((ulong)(o)-(ulong)code-8)>>2)|(1<<24))#define CALLMAC(C,o)			gen(BRAW((C), (IA(macro, o)-(ulong)code-8)>>2)|(1<<24))#define RELPC(pc)			(ulong)(base+(pc))#define RETURN				DPI(AL, Add, RLINK, R15, 0, 0)				#define CRETURN(C)				DPI(C, Add, RLINK, R15, 0, 0)				#define PATCH(ptr)			*ptr |= (((ulong)code-(ulong)(ptr)-8)>>2) & 0x00ffffff #define MOV(src, dst)			DP(AL, Mov, 0, dst, 0, src)#define FITS8(v)	((ulong)(v)<BITS(8))#define FITS5(v)	((ulong)(v)<BITS(5)) /* assumes H==-1 */#define CMPH(C, r)		CMNI(C, r, 0, 0, 1)#define NOTNIL(r)	(CMPH(AL, (r)), CCALL(EQ, bounds)) /* array bounds checking */#define BCK(r, rb)	(CMP(AL, rb, 0, 0, r), CCALL(LS, bounds))#define BCKI(i, rb)	(CMPI(AL, rb, 0, 0, i), CCALL(LS, bounds)) static	ulong*	code;static	ulong*	base;static	ulong*	patch;static	ulong	codeoff;static	int	pass;static	int	puntpc = 1;static	Module*	mod;static	uchar*	tinit;static	ulong*	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(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 */	MacRELQ,		macrelq,	/* reschedule */}; typedef struct Const Const;struct Const{	ulong	o;	ulong*	code;	ulong*	pc;}; typedef struct Con Con;struct Con{	int	ptr;	Const	table[NCON];	};static Con rcon; 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);} 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(char *s){	USED(s);	error(exCompile);	//production	//panic("compile failed: urk: %s\n", s);	//debugging} static voidgen(ulong w){	*code++ = w;} static longimmrot(ulong v){	int i; 	for(i=0; i<16; i++) {		if((v & ~0xff) == 0)			return (i<<8) | v | (1<<25);		v = (v<<2) | (v>>30);	}	return 0;} static longimmaddr(long v){ 	if(v >= 0 && v <= 0xfff)		return (v & 0xfff) |			(1<<24) |	/* pre indexing */			(1<<23);	/* pre indexing, up */	if(v >= -0xfff && v < 0)		return (-v & 0xfff) |			(1<<24);	/* pre indexing */	return 0;} static voidflushcon(int genbr){	int i;	Const *c;	ulong disp; 	if(rcon.ptr == 0)		return;	if(genbr){		if(0)print("BR %d(PC)=%8.8p (len=%d)\n", (rcon.ptr*4+4-8)>>2, code+rcon.ptr+1, rcon.ptr);		BRA(AL, (rcon.ptr*4+4-8)>>2);	}	c = &rcon.table[0];	for(i = 0; i < rcon.ptr; i++) {		if(pass){			disp = (code - c->code) * sizeof(*code) - 8;			if(disp >= BITS(12))				print("INVALID constant range %lud", disp);			if(0)print("data %8.8p %8.8lux (%8.8p, ins=%8.8lux cpc=%8.8p)\n", code, c->o, c->code, *c->code, c->pc);			*c->code |= (disp&0xfff);		}		*code++ = c->o;		c++;	}	rcon.ptr = 0;} static voidflushchk(void){	if(rcon.ptr >= NCON || rcon.ptr > 0 && (code+codeoff+2-rcon.table[0].pc)*sizeof(*code) >= BITS(12)-256){  // 256 allows for a little delay in calling flushchk		if(0)print("flushed constant table: len %ux disp %ld\n", rcon.ptr, (code+codeoff-rcon.table[0].pc)*sizeof(*code)-8);		flushcon(1);	}} static voidccon(int cc, ulong o, int r, int opt){	ulong u;	Const *c; 	if(opt != 0) {		u = o & ~0xff;		if(u == 0) {			DPI(cc, Mov, 0, r, 0, o);			return;				}		if(u == ~0xff) {			DPI(cc, Mvn, 0, r, 0, ~o);			return;		}		u = immrot(o);		if(u) {			DPI(cc, Mov, 0, r, 0, 0) | u;			return;		}		u = o & ~0xffff;		if(u == 0) {			DPI(cc, Mov, 0, r, 0, o);			DPI(cc, Orr, r, r, (24/2), o>>8);			return;		}	}	flushchk();	c = &rcon.table[rcon.ptr++];	c->o = o;	c->code = code;	c->pc = code+codeoff;	LDW(cc, R15, r, 0);} static voidmemc(int c, int inst, ulong disp, int rm, int r){	int bit; 	if(inst == Lea) {		if(disp < BITS(8)) {			DPI(c, Add, rm, r, 0, disp);			return;		}		if(-disp < BITS(8)) {			DPI(c, Sub, rm, r, 0, -disp);			return;		}		bit = immrot(disp);		if(bit) {			DPI(c, Add, rm, r, 0, 0) | bit;			return;		}		ccon(c, disp, RCON, 1);		DP(c, Add, rm, r, 0, RCON);		return;	} 	if(disp < BITS(12) || -disp < BITS(12)) {	/* Direct load */		if(disp < BITS(12))			bit = 0;		else {			disp = -disp;			bit = UPBIT;		}		switch(inst) {		case Ldw:			LDW(c, rm, r, disp);			break;		case Ldb:			LDB(c, rm, r, disp);			break;

Lines 1–500 of 2258.