henesyinit from p9fce6d0435 years agoHistory
715 lines · 10.8 KB · C
RawDownload
#include <u.h>#include <libc.h>#include <bio.h>#include <mach.h>#define Extern extern#include "3210.h" enum{	FPU	= 7,			/* number of fpu cycles kept; safely large */	FMAT	= 6,			/* strange source accum for add-tap */	FNEG	= 1 << 24,		/* negate addend */	FSUB	= 1 << 23,		/* subtract */	NOSTORE	= 7,			/* don't store z */}; #define	ASRC(i)		(((i)>>26)&7)#define	ADEST(i)	(((i)>>21)&3)#define	XARG(i)		(((i)>>14)&0x7f)#define	YARG(i)		(((i)>>7)&0x7f)#define	ZARG(i)		(((i)>>0)&0x7f)#define	FSPEC(i)	(((i)>>23)&0xf) Fpu	fpus[FPU+1];Freg	fzero;Freg	fone;int	cycle;			/* current index in fpus */ Fspec fputab[16] = {	{0,		0,	1,	4,	"ic"},	{0,		0,	4,	1,	"oc"},	{Ffloat16,	sfetch,	2,	4,	"float16"},	{Fint16,	mfetch,	4,	2,	"int16"},	{Fround,	mfetch,	4,	4,	"round"},	{0,		mfetch,	4,	4,	"ifalt"},	{0,		mfetch,	4,	4,	"ifaeq"},	{0,		mfetch,	4,	4,	"ifagt"},	{Ffloat32,	mfetch,	4,	4,	"float32"},	{Fint32,	mfetch,	4,	4,	"int32"},	{0,		0,	0,	0,	"fop10"},	{0,		0,	0,	0,	"fop11"},	{0,		mfetch,	4,	4,	"ieee"},	{0,		mfetch,	4,	4,	"dsp"},	{Fseed,		mfetch,	4,	4,	"seed"},	{0,		0,	0,	0,	"fop15"},}; voidresetfpu(void){	fone.val = 0x00000080;	memset(fpus, 0, sizeof(fpus));	cycle = 0;} /* * perform fpu calculations at end of i-cycle */voidfpuop(void){	Fpu *fpu; 	fpu = &fpus[(cycle - 3) & FPU];	if(fpu->op)		fpu->op(fpu);	fpu = &fpus[(cycle - 4) & FPU];	if(fpu->op && ZARG(fpu->inst) != NOSTORE){		switch(fpu->zinc){		case 4:			putmem_w(fpu->z.a, fpu->z.v.val);			break;		case 2:			putmem_h(fpu->z.a, fpu->z.v.val);			break;		case 1:			putmem_b(fpu->z.a, fpu->z.v.val);			break;		}	}	cycle = (cycle + 1) & FPU;	fpus[cycle].op = 0;} /* * increment the z reg */voidfpuupdate(int s, int t, int u, int v){	Fpu *fpu;	int r; 	fpu = &fpus[(cycle - 1) & FPU];	if(fpu->op){		r = update(ZARG(fpu->inst), fpu->z.a, fpu->zinc);		if(r && (r == s || r == t || r == u || r == v)){			if((ZARG(fpu->inst)&7) == 6)				warn("r%d was decremented in the previous instruction", r);			else				warn("r%d was incremented in the previous instruction", r);		}	}} /* * fetch last cycles fpu mem refs */intfpufetch(void){	Fpu *fpu; 	fpu = &fpus[(cycle - 1) & FPU];	if(fpu->op && fpu->fetch)		return (*fpu->fetch)(fpu);	return 0;} voidDfmadd(char *buf, int n, ulong inst, ulong pc, int rvalid){	char x[16], y[16], z[16];	char *neg, *add, *d, *a; 	USED(pc, rvalid);	fargname(x, XARG(inst), 0);	fargname(y, YARG(inst), 0);	fargname(z, ZARG(inst), 1);	neg = "";	if(inst & FNEG)		neg = "-";	add = "+";	if(inst & FSUB)		add = "-";	d = fregname[ADEST(inst)];	a = fregname[ASRC(inst)]; 	switch(inst >> 29){	case 1:		/*		 * strange instruction encoding		 * for f-add-tap		 */		if(ASRC(inst) == FMAT){			if(*z)				snprint(buf, n, "%s = %s(%s = %s) %s %s", d, neg, z, y, add, x);			else				snprint(buf, n, "%s = %s%s %s %s", d, neg, y, add, x);		}else{			if(*z)				snprint(buf, n, "%s = %s = %s%s %s %s * %s", z, d, neg, y, add, a, x);			else				snprint(buf, n, "%s = %s%s %s %s * %s", d, neg, y, add, a, x);		}		break;	case 2:		if(*z)			snprint(buf, n, "%s = %s%s %s (%s = %s) * %s", d, neg, a, add, z, y, x);		else			snprint(buf, n, "%s = %s%s %s %s * %s", d, neg, a, add, y, x);		break;	case 3:		if(*z)			snprint(buf, n, "%s = %s = %s%s %s %s * %s", z, d, neg, a, add, y, x);		else			snprint(buf, n, "%s = %s%s %s %s * %s", d, neg, a, add, y, x);		break;	default:		snprint(buf, n, "bad fmadd instruction %.8lux\n", inst);	}} /* * 1st instruction cycle for * all multiply-add instructions */voidIfmadd(ulong inst){	Fpu *fpu;	int x, y, s, t, u, v; 	fpu = &fpus[cycle & FPU];	x = XARG(inst);	y = YARG(inst);	fpu->inst = inst;	fpu->zinc = 4;	fpu->x.a = crack(x, 0);	s = update(x, fpu->x.a, 4);	t = increg(x);	fpu->y.a = crack(y, 0);	u = update(y, fpu->y.a, 4);	v = increg(y);	fpuupdate(s, t, u, v);	ldlast(s, t, u, v);	fpu->z.a = crack(ZARG(inst), 1); 	switch(fpu->inst >> 29){	case 1:		/*		 * strange instruction encoding		 * for f-add-tap		 */		if(ASRC(fpu->inst) == FMAT){			fpu->fetch = xyfetch;			fpu->op = addtap;		}else{			fpu->fetch = axyfetch;			fpu->op = multaddstore;		}		break;	case 2:		fpu->fetch = xyfetch;		fpu->op = multacctap;		break;	case 3:		fpu->fetch = xyfetch;		fpu->op = multaccstore;		break;	default:		error("bad fpu instruction %.8lux", inst);	}} voidDfspecial(char *buf, int n, ulong inst, ulong pc, int rvalid){	Fspec *f;	char y[16], z[16], *d; 	USED(pc, rvalid);	fargname(y, YARG(inst), 0);	fargname(z, ZARG(inst), 1);	d = fregname[ADEST(inst)];	f = &fputab[FSPEC(inst)];	if(*z)		snprint(buf, n, "%s = %s = %s(%s)", z, d, f->name, y);	else		snprint(buf, n, "%s = %s(%s)", d, f->name, y);} /* * first cycles of floating special functions */voidIfspecial(ulong inst){	Fpu *fpu;	Fspec *f;	int y, s, t; 	f = &fputab[FSPEC(inst)];	if(!f->op)		error("illegal fpu special instruction %.8lux", inst);	fpu = &fpus[cycle & FPU];	y = YARG(inst);	fpu->inst = inst;	fpu->zinc = f->zinc;	fpu->y.a = crack(y, 0);	s = update(y, fpu->y.a, f->inc);	t = increg(y);	fpuupdate(s, t, 0, 0);	ldlast(s, t, 0, 0);	fpu->z.a = crack(ZARG(inst), 1);	fpu->fetch = f->fetch;	fpu->op = f->op;} voidFfloat16(Fpu *fpu){	Freg f;	long v;	int r; 	yfetch(fpu);	v = fpu->y.v.val >> 16;	if(v & 0x8000)		v |= ~0xffff;	f.val = dtodsp(v);	f.guard = 0;	f = fpuflags(f);	r = ADEST(fpu->inst);	reg.f[r] = f;	fpu->z.v = f;} voidFfloat32(Fpu *fpu){	Freg f;	long v;	int r; 	yfetch(fpu);	v = fpu->y.v.val;	f.val = dtodsp(v);	f.guard = 0;	f = fpuflags(f);	r = ADEST(fpu->inst);	reg.f[r] = f;	fpu->z.v = f;} voidFint16(Fpu *fpu){	Freg f;	ulong v;	int r; 	yfetch(fpu);	v = fpu->y.v.val;	f.val = dtoshort(dsptod(v)) << 16;	f.guard = 0;	r = ADEST(fpu->inst);	reg.f[r] = f; 	f.val >>= 16;	fpu->z.v = f;} voidFint32(Fpu *fpu){	Freg f;	int r; 	yfetch(fpu);	f.val = dtolong(dsptod(fpu->y.v.val));	f.guard = 0;	r = ADEST(fpu->inst);	reg.f[r] = f;	fpu->z.v = f;} voidFround(Fpu *fpu){	Freg f;	int r; 	yfetch(fpu);	r = ADEST(fpu->inst);	f = fround(fpu->y.v);	reg.f[r] = f;	fpu->z.v = f;} /* * strange approximation to inverse of y by * complementing all bits other than sign bit */voidFseed(Fpu *fpu){	Freg f;	int r; 	yfetch(fpu);	r = ADEST(fpu->inst);	f.val = fpu->y.v.val ^ 0x7fffffff;	f.guard = fpu->y.v.guard & 0xff;	f = fpuflags(f);	reg.f[r] = f;	fpu->z.v = f;} /* * astore = (z = y) + 1.0 * x */voidaddtap(Fpu *fpu){	Freg f;	int r; 	yfetch(fpu);	f = fmuladd(fpu->inst & FNEG, fpu->inst & FSUB, fpu->y.v, fone, fpu->x.v);	r = ADEST(fpu->inst);	reg.f[r] = f;	fpu->z.v = fpu->y.v;} /* * z = astore = y + afetch * x */voidmultaddstore(Fpu *fpu){	Freg f;	int r; 	yfetch(fpu);	f = fmuladd(fpu->inst & FNEG, fpu->inst & FSUB, fpu->y.v, fpu->accum, fpu->x.v);	r = ADEST(fpu->inst);	reg.f[r] = f;	fpu->z.v = f;} /* * z = astore = afetch + y * x */voidmultaccstore(Fpu *fpu){	Freg f;	int r; 	fpu->accum = faccum(fpu->inst);	f = fmuladd(fpu->inst & FNEG, fpu->inst & FSUB, fpu->accum, fpu->y.v, fpu->x.v);	r = ADEST(fpu->inst);	reg.f[r] = f;	fpu->z.v = f;} /* * astore = afetch + (z=y) * x */voidmultacctap(Fpu *fpu){	Freg f;	int r; 	fpu->accum = faccum(fpu->inst);	f = fmuladd(fpu->inst & FNEG, fpu->inst & FSUB, fpu->accum, fpu->y.v, fpu->x.v);	r = ADEST(fpu->inst);	reg.f[r] = f;	fpu->z.v = fpu->y.v;} /* * fetch y if a memory operand * return whether y fetched memory */intmfetch(Fpu *fpu){	int y; 	y = YARG(fpu->inst);	if(y >> 3){		fpu->y.v.val = getmem_w(fpu->y.a);		fpu->y.v.guard = 0;		return 1;	}	return 0;} /* * fetch y if not a memory operand */voidyfetch(Fpu *fpu){	int y; 	y = YARG(fpu->inst);	if(y >> 3)		return;	if(y & 4)		error("illegal floating point operand");	fpu->y.v = reg.f[y & 3];} /* * fetch a 16 bit integer y if a memory operand * return whether memory was fetched */intsfetch(Fpu *fpu){	int y; 	y = YARG(fpu->inst);	if(y >> 3){		fpu->y.v.val = getmem_h(fpu->y.a) << 16;		return 1;	}	return 0;} /* * fetch x and y * return whether y fetched memory */intxyfetch(Fpu *fpu){	int y; 	fpu->x.v = ffetch(XARG(fpu->inst), fpu->x.a);	y = YARG(fpu->inst);	fpu->y.v = ffetch(y, fpu->y.a);	if(y >> 3)		return 1;	return 0;} 

Lines 1–500 of 715.