#include #include #include #include #define Extern extern #include "mips.h" void Snor(ulong); void Ssll(ulong); void Ssra(ulong); void Sslt(ulong); void Ssltu(ulong); void Sand(ulong); void Saddu(ulong); void Sadd(ulong); void Sjr(ulong); void Sor(ulong); void Ssubu(ulong); void Sjalr(ulong); void Sdivu(ulong); void Smfhi(ulong); void Smflo(ulong); void Sxor(ulong); void Smult(ulong); void Smultu(ulong); void Sdiv(ulong); void Ssrl(ulong); void Ssllv(ulong); void Ssrlv(ulong); void Ssrav(ulong); Inst ispec[] = { { Ssll, "sll", Iarith }, { undef, "" }, { Ssrl, "srl", Iarith }, { Ssra, "sra", Iarith }, { Ssllv, "sllv", Iarith }, { undef, "" }, { Ssrlv, "srlv", Iarith }, { Ssrav, "srav", Iarith }, { Sjr, "jr", Ibranch }, { Sjalr, "jalr", Ibranch }, { undef, "" }, { undef, "" }, { Ssyscall, "sysc", Isyscall }, { undef, "" }, { undef, "" }, { undef, "" }, { Smfhi, "mfhi", Ireg }, { undef, "" }, { Smflo, "mflo", Ireg }, { undef, "" }, { undef, "" }, { undef, "" }, { undef, "" }, { undef, "" }, { Smult, "mult", Iarith }, { Smultu, "multu" }, { Sdiv, "div", Iarith }, { Sdivu, "divu", Iarith }, { undef, "" }, { undef, "" }, { undef, "" }, { undef, "" }, { Sadd, "add", Iarith }, { Saddu, "addu", Iarith }, { undef, "" }, { Ssubu, "subu", Iarith }, { Sand, "and", Iarith }, { Sor, "or", Iarith }, { Sxor, "xor", Iarith }, { Snor, "nor", Iarith }, { undef, "" }, { undef, "" }, { Sslt, "slt", Iarith }, { Ssltu, "sltu", Iarith }, { undef, "" }, { undef, "" }, { undef, "" }, { undef, "" }, { undef, "" }, { undef, "" }, { undef, "" }, { undef, "" }, { undef, "" }, { undef, "" }, { undef, "" }, { undef, "" }, { undef, "" }, { undef, "" }, { undef, "" }, { undef, "" }, { undef, "" }, { undef, "" }, { undef, "" }, { undef, "" }, { 0 } }; void Ispecial(ulong inst) { Inst *i; i = &ispec[inst&0x3f]; reg.ip = i; i->count++; (*i->func)(inst); } void Snor(ulong inst) { int rs, rt, rd; Get3(rs, rt, rd, inst); if(trace) itrace("nor\tr%d,r%d,r%d", rd, rs, rt); if(inst == INOP) nopcount++; else reg.r[rd] = ~(reg.r[rt]|reg.r[rs]); } void Ssll(ulong inst) { int rd, rt, shamt; SpecialGetrtrd(rt, rd, inst); shamt = (inst>>6)&0x1f; if(trace) itrace("sll\tr%d,r%d,%d", rd, rt, shamt); reg.r[rd] = reg.r[rt]<> (reg.r[rs]&0x1f); } void Ssrav(ulong inst) { int rd, rt, rs, shamt; Get3(rs, rt, rd, inst); if(trace) itrace("srav\tr%d,r%d,r%d", rd, rt, rs); shamt = reg.r[rs]&0x1f; if(shamt != 0 && (reg.r[rt] & SIGNBIT)) reg.r[rd] = reg.r[rt]>>shamt | ~((1<<(32-shamt))-1); else reg.r[rd] = reg.r[rt]>>shamt; } void Ssrl(ulong inst) { int rd, rt, shamt; SpecialGetrtrd(rt, rd, inst); shamt = (inst>>6)&0x1f; if(trace) itrace("srl\tr%d,r%d,%d", rd, rt, shamt); reg.r[rd] = (ulong)reg.r[rt] >> shamt; } void Ssra(ulong inst) { int rd, rt, shamt; SpecialGetrtrd(rt, rd, inst); shamt = (inst>>6)&0x1f; if(trace) itrace("sra\tr%d,r%d,%d", rd, rt, shamt); if(shamt != 0 && (reg.r[rt] & SIGNBIT)) reg.r[rd] = reg.r[rt]>>shamt | ~((1<<(32-shamt))-1); else reg.r[rd] = reg.r[rt]>>shamt; } void Sslt(ulong inst) { int rs, rt, rd; Get3(rs, rt, rd, inst); if(trace) itrace("slt\tr%d,r%d,r%d", rd, rs, rt); reg.r[rd] = reg.r[rs] < reg.r[rt] ? 1 : 0; } void Ssltu(ulong inst) { int rs, rt, rd; Get3(rs, rt, rd, inst); if(trace) itrace("sltu\tr%d,r%d,r%d", rd, rs, rt); reg.r[rd] = (unsigned)reg.r[rs] < (unsigned)reg.r[rt] ? 1 : 0; } void Sand(ulong inst) { int rs, rt, rd; Get3(rs, rt, rd, inst); if(trace) itrace("and\tr%d,r%d,r%d", rd, rs, rt); reg.r[rd] = reg.r[rs] & reg.r[rt]; } void Saddu(ulong inst) { int rs, rt, rd; Get3(rs, rt, rd, inst); if(trace) itrace("addu\tr%d,r%d,r%d", rd, rs, rt); reg.r[rd] = reg.r[rs] + reg.r[rt]; } void Sadd(ulong inst) { int rs, rt, rd; Get3(rs, rt, rd, inst); if(trace) itrace("add\tr%d,r%d,r%d", rd, rs, rt); reg.r[rd] = reg.r[rs] + reg.r[rt]; } void Ssubu(ulong inst) { int rs, rt, rd; Get3(rs, rt, rd, inst); if(trace) itrace("subu\tr%d,r%d,r%d", rd, rs, rt); reg.r[rd] = reg.r[rs] - reg.r[rt]; } void Sor(ulong inst) { int rs, rt, rd; Get3(rs, rt, rd, inst); if(trace) itrace("or\tr%d,r%d,r%d", rd, rs, rt); reg.r[rd] = reg.r[rs] | reg.r[rt]; } void Sxor(ulong inst) { int rs, rt, rd; Get3(rs, rt, rd, inst); if(trace) itrace("or\tr%d,r%d,r%d", rd, rs, rt); reg.r[rd] = reg.r[rs] ^ reg.r[rt]; } void Sjr(ulong inst) { ulong npc; int rs; Symbol s; rs = (inst>>21)&0x1f; npc = reg.r[rs]; if(trace) itrace("jr\t0x%lux", npc); /* Do the delay slot */ reg.ir = ifetch(reg.pc+4); Statbra(); Iexec(reg.ir); if(calltree) { if(rs == 31 || rs == 2) { findsym(npc, CTEXT, &s); Bprint(bioout, "%8lux return to %lux %s r1=%lux\n", reg.pc, npc, s.name, reg.r[1]); } } reg.pc = npc-4; } void Sjalr(ulong inst) { ulong npc; int rs, rd; Symbol s; rs = (inst>>21)&0x1f; rd = (inst>>11)&0x1f; npc = reg.r[rs]; if(trace) itrace("jalr\tr%d,r%d", rd, rs); reg.r[rd] = reg.pc+8; /* Do the delay slot */ reg.ir = ifetch(reg.pc+4); Statbra(); Iexec(reg.ir); if(calltree) { findsym(npc, CTEXT, &s); if(rs == 31) Bprint(bioout, "%8lux return to %8lux %s\n", reg.pc, npc, s.name); else { printparams(&s, reg.r[29]); Bputc(bioout, '\n'); } } reg.pc = npc-4; } void Sdivu(ulong inst) { int rs, rt; Getrsrt(rs,rt,inst); if(trace) itrace("divu\tr%d,r%d", rs, rt); reg.mlo = (ulong)reg.r[rs]/(ulong)reg.r[rt]; reg.mhi = (ulong)reg.r[rs]%(ulong)reg.r[rt]; } void Sdiv(ulong inst) { int rs, rt; Getrsrt(rs,rt,inst); if(trace) itrace("div\tr%d,r%d", rs, rt); reg.mlo = reg.r[rs]/reg.r[rt]; reg.mhi = reg.r[rs]%reg.r[rt]; } void Smfhi(ulong inst) { int rd; rd = (inst>>11)&0x1ff; if(trace) itrace("mfhi\tr%d", rd); reg.r[rd] = reg.mhi; } void Smflo(ulong inst) { int rd; rd = (inst>>11)&0x1ff; if(trace) itrace("mflo\tr%d", rd); reg.r[rd] = reg.mlo; } void Smult(ulong inst) { int rs, rt; Mul m; Getrsrt(rs,rt,inst); if(trace) itrace("mult\tr%d,r%d", rs,rt); m = mul(reg.r[rs], reg.r[rt]); reg.mlo = m.lo; reg.mhi = m.hi; } void Smultu(ulong inst) { int rs, rt; Mulu m; Getrsrt(rs,rt,inst); if(trace) itrace("multu\tr%d,r%d", rs,rt); m = mulu(reg.r[rs], reg.r[rt]); reg.mlo = m.lo; reg.mhi = m.hi; }