~kris/9p

9hist

f36a677906e9f3c1c80d615dad033369a22b4e46 — David du Colombier 34 years ago 5a95dc0
Plan 9 from Bell Labs 1992-08-03
5 files changed, 64 insertions(+), 97 deletions(-)

M power/fptrap.c
M power/trap.c
M ss/fptrap.c
M ss/l.s
M ss/trap.c
M power/fptrap.c => power/fptrap.c +43 -81
@@ 7,27 7,13 @@
#include	"io.h"
#include	"../port/error.h"

typedef struct	FPinstr	FPinstr;
struct FPinstr
{
	ulong	op;
	ulong	load;
	ulong	store;
	ulong	branch;
	ulong	fmt;
	ulong	fs;
	ulong	fd;
	ulong	ft;
	ulong	cft;
};

enum	/* op */
{
	ABS =	5,
	ADD =	0,
	CVTD = 	65,
	CVTS =	64,
	CVTW =	68,
	CVTD = 	33,
	CVTS =	32,
	CVTW =	36,
	DIV =	3,
	MOV =	6,
	MUL =	2,


@@ 35,44 21,22 @@ enum	/* op */
	SUB =	1,
};

static int	fpunimp(Ureg*, ulong, ulong);
static int	fpunimp(ulong);
static ulong	branch(Ureg*, ulong);

int
fptrap(Ureg *ur, ulong fcr31)
{
	ulong iw, x, npc;
	int i, ret;
	ulong iw, npc;

	savefpregs(&u->fpsave);
	if((fcr31&(1<<17)) == 0)
		return 0;
	if(ur->cause & (1<<31))
		iw = *(ulong*)(ur->pc+4);
	else
		iw = *(ulong*)ur->pc;
	ret = 0;
	x = fcr31>>12;
	fcr31 &= ~(0x3F<<12);
	for(i=0; i<6; i++,x>>=1)
		if(x & 1)
			switch(i){
			case 0:	/* inexact */
pprint("inexact\n");
return 0;
			case 1: /* underflow */
pprint("underflow\n");
return 0;
			case 2:	/* overflow */
pprint("overflow\n");
return 0;
			case 3: /* division by zero */
				return 0;
			case 4: /* invalid operation */
pprint("invalid op\n");
return 0;
			case 5:	/* unimplemented operation */
				ret = fpunimp(ur, fcr31, iw);
			}
	if(ret){
	if(fpunimp(iw)){
		if(ur->cause & (1<<31)){
			npc = branch(ur, fcr31);
			if(npc)


@@ 83,23 47,7 @@ return 0;
			ur->pc += 4;
		restfpregs(&u->fpsave, fcr31);
	}
	return ret;
}

static int
fpdas(ulong iw, FPinstr *fp)
{
	memset(fp, ~0, sizeof(*fp));
	if((iw>>25) == 0x23){
		fp->op = iw & ((1<<5)-1);
		fp->fmt = (iw>>21) & ((1<<4)-1);
		fp->ft = (iw>>16) & ((1<<5)-1);
		fp->fs = (iw>>11) & ((1<<5)-1);
		fp->fd = (iw>>6) & ((1<<5)-1);
		fp->cft = (iw>>21) & ((1<<5)-1);
		return 1;
	}
	return 0;
	return 1;
}

static void


@@ 113,11 61,8 @@ unpack(FPsave *f, int fmt, int reg, int *sign, int *exp)
		*exp = ((f->fpreg[reg]>>23)&0xFF) - ((1<<7)-2);
		break;
	case 1:
		if(reg & 1){
			pprint("unaligned double fp register\n");
		if(reg & 1)	/* shouldn't happen */
			reg &= ~1;
		}
pprint("%lux %lux\n", f->fpreg[reg], f->fpreg[reg+1]);
		*exp = ((f->fpreg[reg]>>20)&0x7FF) - ((1<<10)-2);
		break;
	}


@@ 145,25 90,26 @@ zeroreg(FPsave *f, int fmt, int reg, int sign)
}

static int
fpunimp(Ureg *ur, ulong fcr31, ulong iw)
fpunimp(ulong iw)
{
	FPinstr instr;
	int ss, st, sd;
	int es, et, ed;
	int maxe, maxm;
	ulong op, fmt, ft, fs, fd;

pprint("fpunimp %lux %lux\n", iw, iw>>25);
	if(!fpdas(iw, &instr))
	if((iw>>25) != 0x23)
		return 0;
pprint("%d\n", instr.op);
	if(instr.op == ~0)
		return 0;
	unpack(&u->fpsave, instr.fmt, instr.fs, &ss, &es);
	unpack(&u->fpsave, instr.fmt, instr.ft, &st, &et);
	op = iw & ((1<<6)-1);
	fmt = (iw>>21) & ((1<<4)-1);
	ft = (iw>>16) & ((1<<5)-1);
	fs = (iw>>11) & ((1<<5)-1);
	fd = (iw>>6) & ((1<<5)-1);
	unpack(&u->fpsave, fmt, fs, &ss, &es);
	unpack(&u->fpsave, fmt, ft, &st, &et);
	ed = 0;
	maxe = 0;
	maxm = 0;
	switch(instr.fmt){
	switch(fmt){
	case 0:
		maxe = 1<<7;
		maxm = 24;


@@ 173,7 119,15 @@ pprint("%d\n", instr.op);
		maxm = 53;
		break;
	}
	switch(instr.op){
	switch(op){
	case ABS:
		u->fpsave.fpreg[fd] &= ~0x80000000;
		return 1;

	case NEG:
		u->fpsave.fpreg[fd] ^= 0x80000000;
		return 1;

	case SUB:
		st = -st;
	case ADD:


@@ 193,13 147,22 @@ pprint("%d\n", instr.op);
			sd = -1;
		ed = es + et;
		break;

	case CVTS:
		if(fmt != 1)
			return 0;
		fmt = 0;	/* convert FROM double TO single */
		maxe = 1<<7;
		ed = es;
		sd = ss;
		break;

	default:
		pprint("unknown unimplemented fp op\n");
		/* shouldn't get here */
		return 0;
	}
	if(ed <= -(maxe-4)){	/* guess: underflow */
pprint("guess underflow\n");
		zeroreg(&u->fpsave, instr.fmt, instr.fd, sd);
		zeroreg(&u->fpsave, fmt, fd, sd);
		return 1;
	}
	return 0;


@@ 309,7 272,6 @@ branch(Ureg *ur, ulong fcr31)
				return ur->pc+4 + offset;
			return ur->pc + 8;
		}
	pprint("fptrap: can't do jump %lux\n", iw);
	/* shouldn't get here */
	return 0;

}

M power/trap.c => power/trap.c +16 -11
@@ 41,9 41,9 @@ char *excname[] =
	"trap: arithmetic overflow",
	"trap: undefined 13",
	"trap: undefined 14",
	"trap: undefined 15",				/* used as sys call for debugger */
	"trap: undefined 15",			/* used as sys call for debugger */
	/* the following is made up */
	"trap: floating point exception"		/* FPEXC */
	"trap: floating point exception"	/* FPEXC */
};
char	*fpexcname(ulong);



@@ 146,7 146,7 @@ trap(Ureg *ur)
		}
	Default:
		/*
		 * This isn't good enough; can still deadlock because we may 
		 * This isn't good enough; can still deadlock because we may
		 * hold print's locks in this processor.
		 */
		if(user){


@@ 319,8 319,8 @@ intr(Ureg *ur)
		panic("cause %lux %lux\n", u, cause);
}

char *
fpexcname(ulong x)
char*
fpexcname(ulong fcr31)
{
	static char *str[]={
		"inexact operation",


@@ 328,13 328,15 @@ fpexcname(ulong x)
		"overflow",
		"division by zero",
		"invalid operation",
		"unimplemented operation",
	};
	int i;

	x >>= 12;
	for(i=0; i<6; i++, x>>=1)
		if(x & 1)
	if(fcr31 & (1<<17))
		return "unimplemented operation";
	fcr31 >>= 7;		/* trap enable bits */
	fcr31 &= (fcr31>>5);	/* anded with exceptions */
	for(i=0; i<5; i++)
		if(fcr31 & (1<<i))
			return str[i];
	return "no floating point exception";
}


@@ 518,6 520,9 @@ syscall(Ureg *aur)
	}
	spllo();

	if(p->procctl)
		procctl(p);

	u->scallnr = ur->r1;
	sp = ur->sp;
	u->nerrlab = 0;


@@ 542,13 547,13 @@ syscall(Ureg *aur)
		p->psstate = sysctab[u->scallnr];

		ret = (*systab[u->scallnr])(u->s.args);
		poperror();
	}
	ur->pc += 4;
	u->nerrlab = 0;

	p->psstate = 0;
	p->insyscall = 0;
	if(u->scallnr == NOTED)					/* ugly hack */
	if(u->scallnr == NOTED)				/* ugly hack */
		noted(&aur, *(ulong*)(sp+BY2WD));	/* doesn't return */
	splhi();
	if(u->scallnr!=RFORK && (p->procctl || u->nnote)){

M ss/fptrap.c => ss/fptrap.c +1 -1
@@ 173,7 173,7 @@ unfinished(FPsave *f)
static void
fixq(FPsave *f, int n)
{
	ulong instr, fsr;
	ulong instr;
	ulong *ip;

	while(n > 1){

M ss/l.s => ss/l.s +1 -1
@@ 27,7 27,7 @@ TEXT	startvirt(SB), $-4
	MOVW	$(SPL(0xF)|PSREF|PSRSUPER), R7
	MOVW	R7, PSR

	MOVW	$(0x35<<22), R7		/* NVM OFM DZM AU */
	MOVW	$(0x35<<22), R7		/* NVM OFM DZM NS */
	MOVW	R7, fsr+0(SB)
	MOVW	fsr+0(SB), FSR
	FMOVD	$0.5, F26		/* 0.5 -> F26 */

M ss/trap.c => ss/trap.c +3 -3
@@ 536,6 536,9 @@ syscall(Ureg *aur)
	}
	spllo();

	if(u->p->procctl)
		procctl(u->p);

	u->scallnr = ur->r7;
	sp = ur->usp;



@@ 567,9 570,6 @@ syscall(Ureg *aur)
	ur->pc += 4;
	ur->npc = ur->pc+4;
	u->nerrlab = 0;
	if(u->p->procctl)
		procctl(u->p);

	u->p->insyscall = 0;
	u->p->psstate = 0;
	if(u->scallnr == NOTED)	/* ugly hack */