#include <u.h>#include <libc.h>#include <bio.h>#include <mach.h>#define Extern extern#include "mips.h" void unimp(ulong);void Ifcmp(ulong);void Ifdiv(ulong);void Ifmul(ulong);void Ifadd(ulong);void Ifsub(ulong);void Ifmov(ulong);void Icvtd(ulong);void Icvtw(ulong);void Icvts(ulong);void Ifabs(ulong);void Ifneg(ulong); Inst cop1[] = { { Ifadd, "add.f", Ifloat }, { Ifsub, "sub.f", Ifloat }, { Ifmul, "mul.f", Ifloat }, { Ifdiv, "div.f", Ifloat }, { unimp, "", }, { Ifabs, "abs.f", Ifloat }, { Ifmov, "mov.f", Ifloat }, { Ifneg, "neg.f", Ifloat }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { Icvts, "cvt.s", Ifloat }, { Icvtd, "cvt.d", Ifloat }, { unimp, "", }, { unimp, "", }, { Icvtw, "cvt.w", Ifloat }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { Ifcmp, "c.f", Ifloat }, { Ifcmp, "c.un", Ifloat }, { Ifcmp, "c.eq", Ifloat }, { Ifcmp, "c.ueq", Ifloat }, { Ifcmp, "c.olt", Ifloat }, { Ifcmp, "c.ult", Ifloat }, { Ifcmp, "c.ole", Ifloat }, { Ifcmp, "c.ule", Ifloat }, { Ifcmp, "c,sf", Ifloat }, { Ifcmp, "c.ngle",Ifloat }, { Ifcmp, "c.seq", Ifloat }, { Ifcmp, "c.ngl", Ifloat }, { Ifcmp, "c.lt", Ifloat }, { Ifcmp, "c.nge", Ifloat }, { Ifcmp, "c.le", Ifloat }, { Ifcmp, "c.ngt", Ifloat }, { 0 }}; voidunimp(ulong inst){ print("op %ld\n", inst&0x3f); Bprint(bioout, "Unimplemented floating point Trap IR %.8lux\n", inst); longjmp(errjmp, 0);} voidinval(ulong inst){ Bprint(bioout, "Invalid Operation Exception IR %.8lux\n", inst); longjmp(errjmp, 0);} voidifmt(int r){ Bprint(bioout, "Invalid Floating Data Format f%d pc 0x%lux\n", r, reg.pc); longjmp(errjmp, 0);} voidfloatop(int dst, int s1, int s2){ if(reg.ft[s1] == FPd && s1 != 24) ifmt(s1); if(reg.ft[s2] == FPd && s2 != 24) ifmt(s2); reg.ft[dst] = FPs;} voiddoubop(int dst, int s1, int s2){ ulong l; if(reg.ft[s1] != FPd) { if(reg.ft[s1] == FPs && s1 != 24) ifmt(s1); l = reg.di[s1]; reg.di[s1] = reg.di[s1+1]; reg.di[s1+1] = l; reg.ft[s1] = FPd; } if(reg.ft[s2] != FPd) { if(reg.ft[s2] == FPs && s2 != 24) ifmt(s2); l = reg.di[s2]; reg.di[s2] = reg.di[s2+1]; reg.di[s2+1] = l; reg.ft[s2] = FPd; } reg.ft[dst] = FPd;} voidIswc1(ulong inst){ int off; ulong l; int rt, rb, ert; Getrbrt(rb, rt, inst); off = (short)(inst&0xffff); if(trace) itrace("swc1\tf%d,0x%x(r%d) ea=%lux", rt, off, rb, reg.r[rb]+off); ert = rt&~1; if(reg.ft[ert] == FPd) { l = reg.di[ert]; reg.di[ert] = reg.di[ert+1]; reg.di[ert+1] = l; reg.ft[ert] = FPmemory; } putmem_w(reg.r[rb]+off, reg.di[rt]);} voidIfsub(ulong ir){ char fmt; int fs, ft, fd; Getf3(fs, ft, fd, ir); switch((ir>>21)&0xf) { default: unimp(ir); case 0: /* single */ fmt = 's'; floatop(fd, fs, ft); reg.fl[fd] = reg.fl[fs] - reg.fl[ft]; break; case 1: /* double */ fmt = 'd'; doubop(fd, fs, ft); reg.fd[fd>>1] = reg.fd[fs>>1] - reg.fd[ft>>1]; break; case 4: fmt = 'w'; reg.di[fd] = reg.di[fs] - reg.di[ft]; break; } if(trace) itrace("sub.%c\tf%d,f%d,f%d", fmt, fd, fs, ft);} voidIfmov(ulong ir){ char fmt; int fs, fd; Getf2(fs, fd, ir); switch((ir>>21)&0xf) { default: unimp(ir); case 0: /* single */ fmt = 's'; reg.fl[fd] = reg.fl[fs]; reg.ft[fd] = reg.ft[fs]; break; case 1: /* double */ fmt = 'd'; reg.fd[fd>>1] = reg.fd[fs>>1]; reg.ft[fd] = reg.ft[fs]; break; case 4: fmt = 'w'; reg.di[fd] = reg.di[fs]; reg.ft[fd] = reg.ft[fs]; break; } if(trace) itrace("mov.%c\tf%d,f%d", fmt, fd, fs);} voidIfabs(ulong ir){ char fmt; int fs, fd; Getf2(fs, fd, ir); switch((ir>>21)&0xf) { default: unimp(ir); case 0: /* single */ fmt = 's'; floatop(fd, fs, fs); if(reg.fl[fs] < 0.0) reg.fl[fd] = -reg.fl[fs]; else reg.fl[fd] = reg.fl[fs]; break; case 1: /* double */ fmt = 'd'; doubop(fd, fs, fs); if(reg.fd[fs>>1] < 0.0) reg.fd[fd>>1] = -reg.fd[fs>>1]; else reg.fd[fd>>1] = reg.fd[fs>>1]; break; case 4: fmt = 'w'; if((long)reg.di[fs] < 0) reg.di[fd] = -reg.di[fs]; else reg.di[fd] = reg.di[fs]; break; } if(trace) itrace("abs.%c\tf%d,f%d", fmt, fd, fs);} voidIfneg(ulong ir){ char fmt; int fs, fd; Getf2(fs, fd, ir); switch((ir>>21)&0xf) { default: unimp(ir); case 0: /* single */ fmt = 's'; floatop(fd, fs, fs); reg.fl[fd] = -reg.fl[fs]; break; case 1: /* double */ fmt = 'd'; doubop(fd, fs, fs); reg.fd[fd>>1] = -reg.fd[fs>>1]; break; case 4: fmt = 'w'; reg.di[fd] = -reg.di[fs]; break; } if(trace) itrace("neg.%c\tf%d,f%d", fmt, fd, fs);} voidIcvtd(ulong ir){ char fmt; int fs, fd; Getf2(fs, fd, ir); switch((ir>>21)&0xf) { default: unimp(ir); case 0: /* single */ fmt = 's'; floatop(fs, fs, fs); reg.fd[fd>>1] = reg.fl[fs]; reg.ft[fd] = FPd; break; case 1: /* double */ fmt = 'd'; doubop(fd, fs, fs); reg.fd[fd>>1] = reg.fd[fs>>1]; break; case 4: fmt = 'w'; reg.fd[fd>>1] = (long)reg.di[fs]; reg.ft[fd] = FPd; break; } if(trace) itrace("cvt.d.%c\tf%d,f%d", fmt, fd, fs);} voidIcvts(ulong ir){ char fmt; int fs, fd; Getf2(fs, fd, ir); switch((ir>>21)&0xf) { default: unimp(ir); case 0: /* single */ fmt = 's'; floatop(fd, fs, fs); reg.fl[fd] = reg.fl[fs]; break; case 1: /* double */ fmt = 'd'; doubop(fs, fs, fs); reg.fl[fd] = reg.fd[fs>>1]; reg.ft[fd] = FPs; break; case 4: fmt = 'w'; reg.fl[fd] = (long)reg.di[fs]; reg.ft[fd] = FPs; break; } if(trace) itrace("cvt.s.%c\tf%d,f%d", fmt, fd, fs);} voidIcvtw(ulong ir){ long v; char fmt; int fs, fd; Getf2(fs, fd, ir); switch((ir>>21)&0xf) { default: unimp(ir); case 0: /* single */ fmt = 's'; floatop(fs, fs, fs); v = reg.fl[fs]; break; case 1: /* double */ fmt = 'd'; doubop(fs, fs, fs); v = reg.fd[fs>>1]; break; case 4: fmt = 'w'; v = reg.di[fs]; break; } reg.di[fd] = v; reg.ft[fd] = FPmemory; if(trace) itrace("cvt.w.%c\tf%d,f%d", fmt, fd, fs);} voidIfadd(ulong ir){ char fmt; int fs, ft, fd; Getf3(fs, ft, fd, ir); switch((ir>>21)&0xf) { default: unimp(ir); case 0: /* single */ fmt = 's'; floatop(fd, fs, ft); reg.fl[fd] = reg.fl[fs] + reg.fl[ft]; break; case 1: /* double */ fmt = 'd'; doubop(fd, fs, ft); reg.fd[fd>>1] = reg.fd[fs>>1] + reg.fd[ft>>1]; break; case 4: fmt = 'w'; reg.di[fd] = reg.di[fs] + reg.di[ft]; break; } if(trace) itrace("add.%c\tf%d,f%d,f%d", fmt, fd, fs, ft);} voidIfmul(ulong ir){ char fmt; int fs, ft, fd; Getf3(fs, ft, fd, ir); switch((ir>>21)&0xf) { default: unimp(ir); case 0: /* single */ fmt = 's'; floatop(fd, fs, ft); reg.fl[fd] = reg.fl[fs] * reg.fl[ft]; break; case 1: /* double */ fmt = 'd'; doubop(fd, fs, ft); reg.fd[fd>>1] = reg.fd[fs>>1] * reg.fd[ft>>1]; break; case 4: fmt = 'w'; reg.di[fd] = reg.di[fs] * reg.di[ft]; break; } if(trace) itrace("mul.%c\tf%d,f%d,f%d", fmt, fd, fs, ft);} voidIfdiv(ulong ir){ char fmt; int fs, ft, fd; Getf3(fs, ft, fd, ir); switch((ir>>21)&0xf) { default: unimp(ir); case 0: /* single */ fmt = 's'; floatop(fd, fs, ft); reg.fl[fd] = reg.fl[fs] / reg.fl[ft]; break; case 1: /* double */ fmt = 'd'; doubop(fd, fs, ft); reg.fd[fd>>1] = reg.fd[fs>>1] / reg.fd[ft>>1]; break; case 4: fmt = 'w'; reg.di[fd] = reg.di[fs] / reg.di[ft]; break; } if(trace) itrace("div.%c\tf%d,f%d,f%d", fmt, fd, fs, ft);} voidIlwc1(ulong inst){ int rt, rb; int off; Getrbrt(rb, rt, inst); off = (short)(inst&0xffff); if(trace) itrace("lwc1\tf%d,0x%x(r%d) ea=%lux", rt, off, rb, reg.r[rb]+off); reg.di[rt] = getmem_w(reg.r[rb]+off); reg.ft[rt] = FPmemory;} Lines 1–500 of 783. Load more
#include <u.h> #include <libc.h> #include <bio.h> #include <mach.h> #define Extern extern #include "mips.h" void unimp(ulong); void Ifcmp(ulong); void Ifdiv(ulong); void Ifmul(ulong); void Ifadd(ulong); void Ifsub(ulong); void Ifmov(ulong); void Icvtd(ulong); void Icvtw(ulong); void Icvts(ulong); void Ifabs(ulong); void Ifneg(ulong); Inst cop1[] = { { Ifadd, "add.f", Ifloat }, { Ifsub, "sub.f", Ifloat }, { Ifmul, "mul.f", Ifloat }, { Ifdiv, "div.f", Ifloat }, { unimp, "", }, { Ifabs, "abs.f", Ifloat }, { Ifmov, "mov.f", Ifloat }, { Ifneg, "neg.f", Ifloat }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { Icvts, "cvt.s", Ifloat }, { Icvtd, "cvt.d", Ifloat }, { unimp, "", }, { unimp, "", }, { Icvtw, "cvt.w", Ifloat }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { unimp, "", }, { Ifcmp, "c.f", Ifloat }, { Ifcmp, "c.un", Ifloat }, { Ifcmp, "c.eq", Ifloat }, { Ifcmp, "c.ueq", Ifloat }, { Ifcmp, "c.olt", Ifloat }, { Ifcmp, "c.ult", Ifloat }, { Ifcmp, "c.ole", Ifloat }, { Ifcmp, "c.ule", Ifloat }, { Ifcmp, "c,sf", Ifloat }, { Ifcmp, "c.ngle",Ifloat }, { Ifcmp, "c.seq", Ifloat }, { Ifcmp, "c.ngl", Ifloat }, { Ifcmp, "c.lt", Ifloat }, { Ifcmp, "c.nge", Ifloat }, { Ifcmp, "c.le", Ifloat }, { Ifcmp, "c.ngt", Ifloat }, { 0 } }; void unimp(ulong inst) { print("op %ld\n", inst&0x3f); Bprint(bioout, "Unimplemented floating point Trap IR %.8lux\n", inst); longjmp(errjmp, 0); } void inval(ulong inst) { Bprint(bioout, "Invalid Operation Exception IR %.8lux\n", inst); longjmp(errjmp, 0); } void ifmt(int r) { Bprint(bioout, "Invalid Floating Data Format f%d pc 0x%lux\n", r, reg.pc); longjmp(errjmp, 0); } void floatop(int dst, int s1, int s2) { if(reg.ft[s1] == FPd && s1 != 24) ifmt(s1); if(reg.ft[s2] == FPd && s2 != 24) ifmt(s2); reg.ft[dst] = FPs; } void doubop(int dst, int s1, int s2) { ulong l; if(reg.ft[s1] != FPd) { if(reg.ft[s1] == FPs && s1 != 24) ifmt(s1); l = reg.di[s1]; reg.di[s1] = reg.di[s1+1]; reg.di[s1+1] = l; reg.ft[s1] = FPd; } if(reg.ft[s2] != FPd) { if(reg.ft[s2] == FPs && s2 != 24) ifmt(s2); l = reg.di[s2]; reg.di[s2] = reg.di[s2+1]; reg.di[s2+1] = l; reg.ft[s2] = FPd; } reg.ft[dst] = FPd; } void Iswc1(ulong inst) { int off; ulong l; int rt, rb, ert; Getrbrt(rb, rt, inst); off = (short)(inst&0xffff); if(trace) itrace("swc1\tf%d,0x%x(r%d) ea=%lux", rt, off, rb, reg.r[rb]+off); ert = rt&~1; if(reg.ft[ert] == FPd) { l = reg.di[ert]; reg.di[ert] = reg.di[ert+1]; reg.di[ert+1] = l; reg.ft[ert] = FPmemory; } putmem_w(reg.r[rb]+off, reg.di[rt]); } void Ifsub(ulong ir) { char fmt; int fs, ft, fd; Getf3(fs, ft, fd, ir); switch((ir>>21)&0xf) { default: unimp(ir); case 0: /* single */ fmt = 's'; floatop(fd, fs, ft); reg.fl[fd] = reg.fl[fs] - reg.fl[ft]; break; case 1: /* double */ fmt = 'd'; doubop(fd, fs, ft); reg.fd[fd>>1] = reg.fd[fs>>1] - reg.fd[ft>>1]; break; case 4: fmt = 'w'; reg.di[fd] = reg.di[fs] - reg.di[ft]; break; } if(trace) itrace("sub.%c\tf%d,f%d,f%d", fmt, fd, fs, ft); } void Ifmov(ulong ir) { char fmt; int fs, fd; Getf2(fs, fd, ir); switch((ir>>21)&0xf) { default: unimp(ir); case 0: /* single */ fmt = 's'; reg.fl[fd] = reg.fl[fs]; reg.ft[fd] = reg.ft[fs]; break; case 1: /* double */ fmt = 'd'; reg.fd[fd>>1] = reg.fd[fs>>1]; reg.ft[fd] = reg.ft[fs]; break; case 4: fmt = 'w'; reg.di[fd] = reg.di[fs]; reg.ft[fd] = reg.ft[fs]; break; } if(trace) itrace("mov.%c\tf%d,f%d", fmt, fd, fs); } void Ifabs(ulong ir) { char fmt; int fs, fd; Getf2(fs, fd, ir); switch((ir>>21)&0xf) { default: unimp(ir); case 0: /* single */ fmt = 's'; floatop(fd, fs, fs); if(reg.fl[fs] < 0.0) reg.fl[fd] = -reg.fl[fs]; else reg.fl[fd] = reg.fl[fs]; break; case 1: /* double */ fmt = 'd'; doubop(fd, fs, fs); if(reg.fd[fs>>1] < 0.0) reg.fd[fd>>1] = -reg.fd[fs>>1]; else reg.fd[fd>>1] = reg.fd[fs>>1]; break; case 4: fmt = 'w'; if((long)reg.di[fs] < 0) reg.di[fd] = -reg.di[fs]; else reg.di[fd] = reg.di[fs]; break; } if(trace) itrace("abs.%c\tf%d,f%d", fmt, fd, fs); } void Ifneg(ulong ir) { char fmt; int fs, fd; Getf2(fs, fd, ir); switch((ir>>21)&0xf) { default: unimp(ir); case 0: /* single */ fmt = 's'; floatop(fd, fs, fs); reg.fl[fd] = -reg.fl[fs]; break; case 1: /* double */ fmt = 'd'; doubop(fd, fs, fs); reg.fd[fd>>1] = -reg.fd[fs>>1]; break; case 4: fmt = 'w'; reg.di[fd] = -reg.di[fs]; break; } if(trace) itrace("neg.%c\tf%d,f%d", fmt, fd, fs); } void Icvtd(ulong ir) { char fmt; int fs, fd; Getf2(fs, fd, ir); switch((ir>>21)&0xf) { default: unimp(ir); case 0: /* single */ fmt = 's'; floatop(fs, fs, fs); reg.fd[fd>>1] = reg.fl[fs]; reg.ft[fd] = FPd; break; case 1: /* double */ fmt = 'd'; doubop(fd, fs, fs); reg.fd[fd>>1] = reg.fd[fs>>1]; break; case 4: fmt = 'w'; reg.fd[fd>>1] = (long)reg.di[fs]; reg.ft[fd] = FPd; break; } if(trace) itrace("cvt.d.%c\tf%d,f%d", fmt, fd, fs); } void Icvts(ulong ir) { char fmt; int fs, fd; Getf2(fs, fd, ir); switch((ir>>21)&0xf) { default: unimp(ir); case 0: /* single */ fmt = 's'; floatop(fd, fs, fs); reg.fl[fd] = reg.fl[fs]; break; case 1: /* double */ fmt = 'd'; doubop(fs, fs, fs); reg.fl[fd] = reg.fd[fs>>1]; reg.ft[fd] = FPs; break; case 4: fmt = 'w'; reg.fl[fd] = (long)reg.di[fs]; reg.ft[fd] = FPs; break; } if(trace) itrace("cvt.s.%c\tf%d,f%d", fmt, fd, fs); } void Icvtw(ulong ir) { long v; char fmt; int fs, fd; Getf2(fs, fd, ir); switch((ir>>21)&0xf) { default: unimp(ir); case 0: /* single */ fmt = 's'; floatop(fs, fs, fs); v = reg.fl[fs]; break; case 1: /* double */ fmt = 'd'; doubop(fs, fs, fs); v = reg.fd[fs>>1]; break; case 4: fmt = 'w'; v = reg.di[fs]; break; } reg.di[fd] = v; reg.ft[fd] = FPmemory; if(trace) itrace("cvt.w.%c\tf%d,f%d", fmt, fd, fs); } void Ifadd(ulong ir) { char fmt; int fs, ft, fd; Getf3(fs, ft, fd, ir); switch((ir>>21)&0xf) { default: unimp(ir); case 0: /* single */ fmt = 's'; floatop(fd, fs, ft); reg.fl[fd] = reg.fl[fs] + reg.fl[ft]; break; case 1: /* double */ fmt = 'd'; doubop(fd, fs, ft); reg.fd[fd>>1] = reg.fd[fs>>1] + reg.fd[ft>>1]; break; case 4: fmt = 'w'; reg.di[fd] = reg.di[fs] + reg.di[ft]; break; } if(trace) itrace("add.%c\tf%d,f%d,f%d", fmt, fd, fs, ft); } void Ifmul(ulong ir) { char fmt; int fs, ft, fd; Getf3(fs, ft, fd, ir); switch((ir>>21)&0xf) { default: unimp(ir); case 0: /* single */ fmt = 's'; floatop(fd, fs, ft); reg.fl[fd] = reg.fl[fs] * reg.fl[ft]; break; case 1: /* double */ fmt = 'd'; doubop(fd, fs, ft); reg.fd[fd>>1] = reg.fd[fs>>1] * reg.fd[ft>>1]; break; case 4: fmt = 'w'; reg.di[fd] = reg.di[fs] * reg.di[ft]; break; } if(trace) itrace("mul.%c\tf%d,f%d,f%d", fmt, fd, fs, ft); } void Ifdiv(ulong ir) { char fmt; int fs, ft, fd; Getf3(fs, ft, fd, ir); switch((ir>>21)&0xf) { default: unimp(ir); case 0: /* single */ fmt = 's'; floatop(fd, fs, ft); reg.fl[fd] = reg.fl[fs] / reg.fl[ft]; break; case 1: /* double */ fmt = 'd'; doubop(fd, fs, ft); reg.fd[fd>>1] = reg.fd[fs>>1] / reg.fd[ft>>1]; break; case 4: fmt = 'w'; reg.di[fd] = reg.di[fs] / reg.di[ft]; break; } if(trace) itrace("div.%c\tf%d,f%d,f%d", fmt, fd, fs, ft); } void Ilwc1(ulong inst) { int rt, rb; int off; Getrbrt(rb, rt, inst); off = (short)(inst&0xffff); if(trace) itrace("lwc1\tf%d,0x%x(r%d) ea=%lux", rt, off, rb, reg.r[rb]+off); reg.di[rt] = getmem_w(reg.r[rb]+off); reg.ft[rt] = FPmemory; }