Commit 599f965a authored by George Hotz's avatar George Hotz

hi lo

parent b6100120
...@@ -25,6 +25,8 @@ contract MIPS { ...@@ -25,6 +25,8 @@ contract MIPS {
uint32 constant public REG_OFFSET = 0xc0000000; uint32 constant public REG_OFFSET = 0xc0000000;
uint32 constant public REG_PC = REG_OFFSET + 0x20*4; uint32 constant public REG_PC = REG_OFFSET + 0x20*4;
uint32 constant public REG_HI = REG_OFFSET + 0x21*4;
uint32 constant public REG_LO = REG_OFFSET + 0x22*4;
constructor(IMIPSMemory _m) { constructor(IMIPSMemory _m) {
m = _m; m = _m;
...@@ -114,23 +116,37 @@ contract MIPS { ...@@ -114,23 +116,37 @@ contract MIPS {
storeAddr = REG_PC; storeAddr = REG_PC;
} }
bool shouldBranch = false;
uint32 val; uint32 val;
if (opcode == 4 || opcode == 5) { // beq/bne if (opcode == 4 || opcode == 5) { // beq/bne
rt = m.ReadMemory(stateHash, REG_OFFSET + ((insn >> 14) & 0x7C)); rt = m.ReadMemory(stateHash, REG_OFFSET + ((insn >> 14) & 0x7C));
if ((rs == rt && opcode == 4) || (rs != rt && opcode == 5)) { shouldBranch = (rs == rt && opcode == 4) || (rs != rt && opcode == 5);
val = pc + (SE(insn&0xFFFF, 16)<<2); } else if (opcode == 6) { shouldBranch = int32(rs) <= 0; // blez
storeAddr = REG_PC; } else if (opcode == 7) { shouldBranch = int32(rs) > 0; // bgtz
} } else if (opcode == 1) {
} else if (opcode == 6 || opcode == 7) { // blez/bgtz // regimm
if ((int32(rs) > 0 && opcode == 7) || (int32(rs) <= 0 && opcode == 6)) { uint32 rtv = ((insn >> 16) & 0x1F);
val = pc + (SE(insn&0xFFFF, 16)<<2); if (rtv == 0) shouldBranch = int32(rs) < 0; // bltz
storeAddr = REG_PC; if (rtv == 1) shouldBranch = int32(rs) >= 0; // bgez
}
} else { } else {
// ALU // ALU
val = execute(insn, rs, rt, mem); val = execute(insn, rs, rt, mem);
} }
// mflo/mthi
if (opcode == 0) {
if (func == 0x10) val = m.ReadMemory(stateHash, REG_HI); // mfhi
else if (func == 0x11) storeAddr = REG_HI; // mthi
else if (func == 0x12) val = m.ReadMemory(stateHash, REG_LO); // mflo
else if (func == 0x13) storeAddr = REG_LO; // mtlo
}
if (shouldBranch) {
val = pc + (SE(insn&0xFFFF, 16)<<2);
storeAddr = REG_PC;
}
// write back // write back
if (storeAddr != 0xFFFFFFFF) { if (storeAddr != 0xFFFFFFFF) {
// does this ever not happen? yes, on untaken beq/bne // does this ever not happen? yes, on untaken beq/bne
...@@ -143,7 +159,6 @@ contract MIPS { ...@@ -143,7 +159,6 @@ contract MIPS {
return stateHash; return stateHash;
} }
// TODO: move pure testable stuff to LibMIPS.sol
function execute(uint32 insn, uint32 rs, uint32 rt, uint32 mem) public pure returns (uint32) { function execute(uint32 insn, uint32 rs, uint32 rt, uint32 mem) public pure returns (uint32) {
uint32 opcode = insn >> 26; // 6-bits uint32 opcode = insn >> 26; // 6-bits
uint32 func = insn & 0x3f; // 6-bits uint32 func = insn & 0x3f; // 6-bits
...@@ -169,8 +184,8 @@ contract MIPS { ...@@ -169,8 +184,8 @@ contract MIPS {
} else if (func == 0x04) { return rt << rs; // sllv } else if (func == 0x04) { return rt << rs; // sllv
} else if (func == 0x06) { return rt >> rs; // srlv } else if (func == 0x06) { return rt >> rs; // srlv
} else if (func == 0x07) { return SE(rt >> rs, 32-rs); // srav } else if (func == 0x07) { return SE(rt >> rs, 32-rs); // srav
} else if (func == 0x08) { return rs; // jr //} else if (func == 0x08) { return rs; // jr
} else if (func == 0x09) { return rs; // jalr //} else if (func == 0x09) { return rs; // jalr
// 0x10-0x13 = mfhi, mthi, mflo, mtlo // 0x10-0x13 = mfhi, mthi, mflo, mtlo
// R-type (ArithLog) // R-type (ArithLog)
} else if (func == 0x20 || func == 0x21) { return rs+rt; // add or addu } else if (func == 0x20 || func == 0x21) { return rs+rt; // add or addu
...@@ -209,6 +224,6 @@ contract MIPS { ...@@ -209,6 +224,6 @@ contract MIPS {
return rt; return rt;
} else if (opcode == 0xf) { return rt<<16; // lui } else if (opcode == 0xf) { return rt<<16; // lui
} }
return rs;
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment