~kris/9p

9hist

02e30f86ab4d12a501f5b79c3a7a353c4f4cb91c — David du Colombier 34 years ago 2b4fb13
Plan 9 from Bell Labs 1992-07-21
2 files changed, 131 insertions(+), 3 deletions(-)

M port/segment.c
M ss/trap.c
M port/segment.c => port/segment.c +1 -1
@@ 402,7 402,7 @@ segattach(Proc *p, ulong attr, char *name, ulong va, ulong len)
	int i, sno;

	USED(p);
	if(va&KZERO)					/* BUG: Only ok for now */
	if((va&KZERO) == KZERO)				/* BUG: Only ok for now */
		error(Ebadarg);

	validaddr((ulong)name, 1, 0);

M ss/trap.c => ss/trap.c +130 -2
@@ 9,6 9,7 @@

void	noted(Ureg**, ulong);
void	rfnote(Ureg**);
int	domuldiv(ulong, Ureg*);

extern	void traplink(void);
extern	void syslink(void);


@@ 27,6 28,7 @@ char *trapname[]={
	"fp: exception",
	"data access exception",
	"tag overflow",
	"watchpoint detected",
};

char*


@@ 37,17 39,23 @@ excname(ulong tbr)
	char *t;

	switch(tbr){
	case 36:
		return "trap: cp disabled";
	case 37:
		return "trap: unimplemented instruction";
	case 40:
		return "trap: cp exception";
	case 42:
		return "trap: divide by zero";
	case 128:
		return "syscall";
	case 129:
		return "breakpoint";
	}
	t = 0;
	if(tbr < sizeof trapname/sizeof(char*))
		t = trapname[tbr];
	else{
	if(t == 0){
		if(tbr >= 130)
			sprint(xx, "trap instruction %d", tbr-128);
		else if(17<=tbr && tbr<=31)


@@ 68,7 76,7 @@ trap(Ureg *ur)
{
	int user, x;
	char buf[64];
	ulong tbr;
	ulong tbr, iw;

	if(u) {
		u->p->pc = ur->pc;		/* BUG */


@@ 118,6 126,14 @@ trap(Ureg *ur)
			}else
				faultsparc(ur);
			goto Return;
		case 2:				/* illegal instr, maybe mul */
			iw = *(ulong*)ur->pc;
			if((iw&0xC1500000) == 0x80500000){
				if(domuldiv(iw, ur))
					goto Return;
				tbr = ur->tbr;
			}
			break;
		case 4:				/* floating point disabled */
			if(u && u->p){
				if(u->p->fpstate == FPinit)


@@ 189,6 205,118 @@ trapinit(void)
}

void
mulu(ulong u1, ulong u2, ulong *lop, ulong *hip)
{
	ulong lo1, lo2, hi1, hi2, lo, hi, t1, t2, t;

	lo1 = u1 & 0xffff;
	lo2 = u2 & 0xffff;
	hi1 = u1 >> 16;
	hi2 = u2 >> 16;

	lo = lo1 * lo2;
	t1 = lo1 * hi2;
	t2 = lo2 * hi1;
	hi = hi1 * hi2;
	t = lo;
	lo += t1 << 16;
	if(lo < t)
		hi++;
	t = lo;
	lo += t2 << 16;
	if(lo < t)
		hi++;
	hi += (t1 >> 16) + (t2 >> 16);
	*lop = lo;
	*hip = hi;
}

void
muls(long l1, long l2, long *lop, long *hip)
{
	ulong t, lo, hi;
	ulong mlo, mhi;
	int sign;

	sign = 0;
	if(l1 < 0){
		sign ^= 1;
		l1 = -l1;
	}
	if(l2 < 0){
		sign ^= 1;
		l2 = -l2;
	}
	mulu(l1, l2, &mlo, &mhi);
	lo = mlo;
	hi = mhi;
	if(sign){
		t = lo = ~lo;
		hi = ~hi;
		lo++;
		if(lo < t)
			hi++;
	}
	*lop = lo;
	*hip = hi;
}

int
domuldiv(ulong iw, Ureg *ur)
{
	long op1, op2;
	long *regp;
	long *regs;

	regs = (long*)ur;
	if(iw & (1<<13)){	/* signed immediate */
		op2 = iw & 0x1FFF;
		if(op2 & 0x1000)
			op2 |= ~0x1FFF;
	}else
		op2 = regs[iw&0x1F];
	op1 = regs[(iw>>14)&0x1F];
	regp = &regs[(iw>>25)&0x1F];

	if(iw & (4<<19)){	/* divide */
		if(ur->y!=0 && ur->y!=~0){
	unimp:
			ur->tbr = 37;	/* "unimplemented instruction" */
			return 0;	/* complex Y is too hard */
		}
		if(op2 == 0){
			ur->tbr = 42;	/* "zero divide" */
			return 0;
		}
		if(iw & (1<<19)){
			if(ur->y && (op1&(1<<31))==0)
				goto unimp;	/* Y not sign extension */
			*regp = op1 / op2;
		}else{
			if(ur->y)
				goto unimp;
			*regp = (ulong)op1 / (ulong)op2;
		}
	}else{
		if(iw & (1<<19))
			muls(op1, op2, regp, (long*)&ur->y);
		else
			mulu(op1, op2, (ulong*)regp, &ur->y);
	}
	if(iw & (16<<19)){	/* set CC */
		ur->psr &= ~(0xF << 20);
		if(*regp & (1<<31))
			ur->psr |= 8 << 20;	/* N */
		if(*regp == 0)
			ur->psr |= 4 << 20;	/* Z */
		/* BUG: don't get overflow right on divide */
	}
	ur->pc += 4;
	ur->npc = ur->pc+4;
	return 1;
}

void
dumpstack(void)
{
	ulong l, v;