📄 float.c
字号:
#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;}voidIbcfbct(ulong inst){ int takeit; int off; ulong npc; off = (short)(inst&0xffff); takeit = 0; npc = reg.pc + (off<<2) + 4; if(inst&(1<<16)) { if(trace) itrace("bc1t\t0x%lux", npc); if(reg.fpsr&FP_CBIT) takeit = 1; } else { if(trace) itrace("bc1f\t0x%lux", npc); if((reg.fpsr&FP_CBIT) == 0) takeit = 1; } if(takeit) { /* Do the delay slot */ reg.ir = ifetch(reg.pc+4); Statbra(); Iexec(reg.ir); reg.pc = npc-4; }}voidImtct(ulong ir){ int rt, fs; SpecialGetrtrd(rt, fs, ir); if(ir&(1<<22)) { /* CT */ if(trace) itrace("ctc1\tr%d,f%d", rt, fs); } else { /* MT */ if(trace) itrace("mtc1\tr%d,f%d", rt, fs); reg.di[fs] = reg.r[rt]; reg.ft[fs] = FPmemory; }}voidImfcf(ulong ir){ int rt, fs; SpecialGetrtrd(rt, fs, ir); if(ir&(1<<22)) { /* CF */ if(trace) itrace("cfc1\tr%d,f%d", rt, fs); } else { /* MF */ if(trace) itrace("mfc1\tr%d,f%d", rt, fs); reg.r[rt] = reg.di[fs]; }}voidIcop1(ulong ir){ Inst *i; switch((ir>>23)&7) { case 0: Imfcf(ir); break; case 1: Imtct(ir); break; case 2: case 3: Ibcfbct(ir); break; case 4: case 5: case 6: case 7: i = &cop1[ir&0x3f]; i->count++; (*i->func)(ir); }}voidIfcmp(ulong ir){ char fmt; int fc; int ft, fs; SpecialGetrtrd(ft, fs, ir); SET(fc); switch((ir>>21)&0xf) { default: unimp(ir); case 0: /* single */ fmt = 's'; floatop(fs, fs, ft); if(isNaN(reg.fl[fs]) || isNaN(reg.fl[ft])) { fc = FP_U; break; } if(reg.fl[fs] == reg.fl[ft]) { fc = FP_E; break; } if(reg.fl[fs] < reg.fl[ft]) { fc = FP_L; break; } if(reg.fl[fs] > reg.fl[ft]) { fc = FP_G; break; } print("vi: bad in fcmp"); break; case 1: /* double */ fmt = 'd'; doubop(fs, fs, ft); if(isNaN(reg.fd[fs>>1]) || isNaN(reg.fd[ft>>1])) { fc = FP_U; break; } if(reg.fd[fs>>1] == reg.fd[ft>>1]) { fc = FP_E; break; } if(reg.fd[fs>>1] < reg.fd[ft>>1]) { fc = FP_L; break; } if(reg.fd[fs>>1] > reg.fd[ft>>1]) { fc = FP_G; break; } print("vi: bad in fcmp"); break; case 4: fmt = 'w'; if(reg.di[fs] == reg.di[ft]) { fc = FP_E; break; } if(reg.di[fs] < reg.di[ft]) { fc = FP_L; break; } if(reg.di[fs] > reg.di[ft]) { fc = FP_G; break; } break; } reg.fpsr &= ~FP_CBIT; switch(ir&0xf) { case 0: if(trace) itrace("c.f.%c\tf%d,f%d", fmt, fs, ft); break; case 1: if(trace) itrace("c.un.%c\tf%d,f%d", fmt, fs, ft); if(fc == FP_U) reg.fpsr |= FP_CBIT; break; case 2: if(trace) itrace("c.eq.%c\tf%d,f%d", fmt, fs, ft); if(fc == FP_E) reg.fpsr |= FP_CBIT; break; case 3: if(trace) itrace("c.ueq.%c\tf%d,f%d", fmt, fs, ft); if(fc == FP_E || fc == FP_U) reg.fpsr |= FP_CBIT; break; case 4: if(trace) itrace("c.lt.%c\tf%d,f%d", fmt, fs, ft); if(fc == FP_L) reg.fpsr |= FP_CBIT; break; case 5: if(trace) itrace("c.ult.%c\tf%d,f%d", fmt, fs, ft); if(fc == FP_L || fc == FP_U) reg.fpsr |= FP_CBIT; break; case 6: if(trace) itrace("c.le.%c\tf%d,f%d", fmt, fs, ft); if(fc == FP_E || fc == FP_L) reg.fpsr |= FP_CBIT; break; case 7: if(trace) itrace("c.ule.%c\tf%d,f%d", fmt, fs, ft); if(fc == FP_E || fc == FP_L || fc == FP_U) reg.fpsr |= FP_CBIT; break; case 8: if(trace) itrace("c.sf.%c\tf%d,f%d", fmt, fs, ft); if(fc == FP_U) inval(ir); break; case 9: if(trace) itrace("c.ngle.%c\tf%d,f%d", fmt, fs, ft); if(fc == FP_U) { reg.fpsr |= FP_CBIT; inval(ir); } break; case 10: if(trace) itrace("c.seq.%c\tf%d,f%d", fmt, fs, ft); if(fc == FP_E) reg.fpsr |= FP_CBIT; if(fc == FP_U) inval(ir); break; case 11: if(trace) itrace("c.ngl.%c\tf%d,f%d", fmt, fs, ft); if(fc == FP_E || fc == FP_U) reg.fpsr |= FP_CBIT; if(fc == FP_U) inval(ir); break; case 12: if(trace) itrace("c.lt.%c\tf%d,f%d", fmt, fs, ft); if(fc == FP_L) reg.fpsr |= FP_CBIT; if(fc == FP_U) inval(ir); break; case 13: if(trace) itrace("c.nge.%c\tf%d,f%d", fmt, fs, ft); if(fc == FP_L || fc == FP_U) reg.fpsr |= FP_CBIT; if(fc == FP_U) inval(ir); break; case 14: if(trace) itrace("c.le.%c\tf%d,f%d", fmt, fs, ft); if(fc == FP_E || fc == FP_L) reg.fpsr |= FP_CBIT; if(fc == FP_U) inval(ir); break; case 15: if(trace) itrace("c.ngt.%c\tf%d,f%d", fmt, fs, ft); if(fc == FP_E || fc == FP_L || fc == FP_U) reg.fpsr |= FP_CBIT; if(fc == FP_U) inval(ir); break; } USED(fmt);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -