From f36a677906e9f3c1c80d615dad033369a22b4e46 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Mon, 3 Aug 1992 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1992-08-03 --- power/fptrap.c | 124 +++++++++++++++++-------------------------------- power/trap.c | 27 ++++++----- ss/fptrap.c | 2 +- ss/l.s | 2 +- ss/trap.c | 6 +-- 5 files changed, 64 insertions(+), 97 deletions(-) diff --git a/power/fptrap.c b/power/fptrap.c index 747d129e9e54bb5c115bceac2fa99b27675af713..03618f51e471feba02ada20d87fe7dc9ee2ebfbb 100644 --- a/power/fptrap.c +++ b/power/fptrap.c @@ -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; - } diff --git a/power/trap.c b/power/trap.c index a9c7fa860d13bf0d4a3ca79e7ba041aed9defb68..704853c7b58d3b02e59768122a0e7e6724f78a0d 100644 --- a/power/trap.c +++ b/power/trap.c @@ -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<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)){ diff --git a/ss/fptrap.c b/ss/fptrap.c index 42c3a9a7c746d2385da2b1a0f2bb205280705e9b..a0d75440c02272a5672b73123b9964972aad519c 100644 --- a/ss/fptrap.c +++ b/ss/fptrap.c @@ -173,7 +173,7 @@ unfinished(FPsave *f) static void fixq(FPsave *f, int n) { - ulong instr, fsr; + ulong instr; ulong *ip; while(n > 1){ diff --git a/ss/l.s b/ss/l.s index 463a0ec727dfc9c83e53891734b8c258a4757500..d6d0b1f62251ee263b91592d50ee1041da8d0b18 100644 --- a/ss/l.s +++ b/ss/l.s @@ -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 */ diff --git a/ss/trap.c b/ss/trap.c index 6a4264708e1d066b64cf26b39095373db9b41516..19b484460faac20ddfd0cdf30cf99d82dc6812e1 100644 --- a/ss/trap.c +++ b/ss/trap.c @@ -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 */