| plan 9 kernel history: overview | file list | diff list |
1992/0721/ss/trap.c (diff list | history)
| 1992/0720/sys/src/9/ss/trap.c:9,14 – 1992/0721/sys/src/9/ss/trap.c:9,15 (short | long | prev | next) | ||
| 1990/1223 | ||
| 1991/0717 | void noted(Ureg**, ulong); | |
| 1990/1223 | void rfnote(Ureg**); | |
| 1992/0721 | int domuldiv(ulong, Ureg*); | |
| 1990/1223 | ||
| 1990/1226 | extern void traplink(void); extern void syslink(void); | |
| 1992/0720/sys/src/9/ss/trap.c:27,32 – 1992/0721/sys/src/9/ss/trap.c:28,34 | ||
| 1991/12171 | "fp: exception", | |
| 1990/1226 | "data access exception", "tag overflow", | |
| 1992/0721 | "watchpoint detected", | |
| 1990/1223 | }; char* | |
| 1992/0720/sys/src/9/ss/trap.c:37,53 – 1992/0721/sys/src/9/ss/trap.c:39,61 | ||
| 1991/1218 | char *t; | |
| 1990/1223 | ||
| 1991/1218 | switch(tbr){ | |
| 1992/0721 | case 36: | |
| 1991/1218 | return "trap: cp disabled"; | |
| 1992/0721 | case 37: return "trap: unimplemented instruction"; | |
| 1991/1113 | case 40: | |
| 1991/1218 | return "trap: cp exception"; | |
| 1992/0721 | case 42: return "trap: divide by zero"; | |
| 1991/1113 | case 128: return "syscall"; case 129: return "breakpoint"; } | |
| 1992/0721 | t = 0; | |
| 1991/1218 | if(tbr < sizeof trapname/sizeof(char*)) t = trapname[tbr]; | |
| 1992/0721 | if(t == 0){ | |
| 1991/1218 | if(tbr >= 130) sprint(xx, "trap instruction %d", tbr-128); else if(17<=tbr && tbr<=31) | |
| 1992/0720/sys/src/9/ss/trap.c:68,74 – 1992/0721/sys/src/9/ss/trap.c:76,82 | ||
| 1990/1223 | { | |
| 1991/01151 | int user, x; | |
| 1990/1223 | char buf[64]; | |
| 1990/1227 |
| |
| 1992/0721 | ulong tbr, iw; | |
| 1990/1223 | ||
| 1991/1113 | if(u) { | |
| 1990/1223 | u->p->pc = ur->pc; /* BUG */ | |
| 1992/0720/sys/src/9/ss/trap.c:118,123 – 1992/0721/sys/src/9/ss/trap.c:126,139 | ||
| 1991/01151 | }else faultsparc(ur); goto Return; | |
| 1992/0721 | case 2: /* illegal instr, maybe mul */ iw = *(ulong*)ur->pc; if((iw&0xC1500000) == 0x80500000){ if(domuldiv(iw, ur)) goto Return; tbr = ur->tbr; } break; | |
| 1991/01151 | case 4: /* floating point disabled */ if(u && u->p){ if(u->p->fpstate == FPinit) | |
| 1992/0720/sys/src/9/ss/trap.c:186,191 – 1992/0721/sys/src/9/ss/trap.c:202,319 | ||
| 1990/1226 | *(ulong*)(t+4) = 0xa7480000; /* MOVW PSR, R19 */ | |
| 1991/1113 | ||
| 1990/1226 | puttbr(TRAPS); | |
| 1992/0721 | } 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 = ®s[(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; | |
| 1990/1226 | } void | |