forsyth20121205-174063a80cc13 years agoHistory
2024 lines · 34.6 KB · C
RawDownload
#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.