Commit 6e366d35 authored by George Hotz's avatar George Hotz

with branch delay slot support, all tests pass

parent dc615639
...@@ -62,6 +62,10 @@ contract MIPS { ...@@ -62,6 +62,10 @@ contract MIPS {
if (pc == 0xdead0000) { if (pc == 0xdead0000) {
return stateHash; return stateHash;
} }
return stepNextPC(stateHash, pc, pc+4);
}
function stepNextPC(bytes32 stateHash, uint32 pc, uint32 nextPC) public view returns (bytes32) {
uint32 insn = m.ReadMemory(stateHash, pc); uint32 insn = m.ReadMemory(stateHash, pc);
uint32 opcode = insn >> 26; // 6-bits uint32 opcode = insn >> 26; // 6-bits
uint32 func = insn & 0x3f; // 6-bits uint32 func = insn & 0x3f; // 6-bits
...@@ -149,39 +153,41 @@ contract MIPS { ...@@ -149,39 +153,41 @@ contract MIPS {
hi = uint32(acc>>32); hi = uint32(acc>>32);
val = uint32(acc); val = uint32(acc);
} else if (func == 0x1a) { // div } else if (func == 0x1a) { // div
// TODO: totally wrong
val = uint32(int32(rs)/int32(rt)); val = uint32(int32(rs)/int32(rt));
hi = uint32(int32(rs)%int32(rt)); hi = uint32(int32(rs)%int32(rt));
} else if (func == 0x1b) { // divu
val = rs/rt;
hi = rs%rt;
} }
// lo/hi writeback // lo/hi writeback
if (func == 0x18 || func == 0x19 || func == 0x1a) { if (func == 0x18 || func == 0x19 || func == 0x1a || func == 0x1b) {
stateHash = m.WriteMemory(stateHash, REG_HI, hi); stateHash = m.WriteMemory(stateHash, REG_HI, hi);
storeAddr = REG_LO; storeAddr = REG_LO;
} }
} }
// jumps // jumps (with branch delay slot)
if (opcode == 0 && func == 8) { if (opcode == 0 && func == 8) {
// jr (val is already right) // jr (val is already right)
storeAddr = REG_PC; return stepNextPC(stateHash, nextPC, val);
} }
if (opcode == 0 && func == 9) { if (opcode == 0 && func == 9) {
// jalr // jalr
stateHash = m.WriteMemory(stateHash, storeAddr, pc+8); stateHash = m.WriteMemory(stateHash, storeAddr, pc+8);
storeAddr = REG_PC; return stepNextPC(stateHash, nextPC, val);
} }
if (opcode == 2 || opcode == 3) { if (opcode == 2 || opcode == 3) {
if (opcode == 3) stateHash = m.WriteMemory(stateHash, REG_LR, pc+8); if (opcode == 3) stateHash = m.WriteMemory(stateHash, REG_LR, pc+8);
val = SE(insn&0x03FFFFFF, 26) << 2; val = SE(insn&0x03FFFFFF, 26) << 2;
storeAddr = REG_PC; return stepNextPC(stateHash, nextPC, val);
} }
if (shouldBranch) { if (shouldBranch) {
val = pc + 4 + (SE(insn&0xFFFF, 16)<<2); val = pc + 4 + (SE(insn&0xFFFF, 16)<<2);
storeAddr = REG_PC; return stepNextPC(stateHash, nextPC, val);
} }
if (opcode == 0 && func == 0xa) { // movz if (opcode == 0 && func == 0xa) { // movz
...@@ -196,7 +202,8 @@ contract MIPS { ...@@ -196,7 +202,8 @@ contract MIPS {
stateHash = m.WriteMemory(stateHash, storeAddr, val); stateHash = m.WriteMemory(stateHash, storeAddr, val);
} }
if (storeAddr != REG_PC) { if (storeAddr != REG_PC) {
stateHash = m.WriteMemory(stateHash, REG_PC, pc+4); // should always be true now
stateHash = m.WriteMemory(stateHash, REG_PC, nextPC);
} }
return stateHash; return stateHash;
......
...@@ -14,7 +14,7 @@ for d in os.listdir("test/"): ...@@ -14,7 +14,7 @@ for d in os.listdir("test/"):
continue continue
print("building", d) print("building", d)
# which mips is go # which mips is go
os.system("%s/mips-elf-as -defsym big_endian=1 -march=mips32 -o /tmp/mips/%s test/%s" % (path, d, d)) os.system("%s/mips-elf-as -defsym big_endian=1 -march=mips32r2 -o /tmp/mips/%s test/%s" % (path, d, d))
elffile = ELFFile(open("/tmp/mips/"+d, "rb")) elffile = ELFFile(open("/tmp/mips/"+d, "rb"))
#print(elffile) #print(elffile)
for sec in elffile.iter_sections(): for sec in elffile.iter_sections():
......
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