Commit c9024c00 authored by George Hotz's avatar George Hotz

refactor branch delay slot handling

parent 8cab46fb
...@@ -25,7 +25,10 @@ contract MIPS { ...@@ -25,7 +25,10 @@ contract MIPS {
uint32 constant public REG_HI = REG_OFFSET + 0x21*4; uint32 constant public REG_HI = REG_OFFSET + 0x21*4;
uint32 constant public REG_LO = REG_OFFSET + 0x22*4; uint32 constant public REG_LO = REG_OFFSET + 0x22*4;
uint32 constant public REG_HEAP = REG_OFFSET + 0x23*4; uint32 constant public REG_HEAP = REG_OFFSET + 0x23*4;
uint64 constant public STORE_LINK = 0x100000000; uint32 constant public REG_PENDPC = REG_OFFSET + 0x24*4;
uint32 constant public PC_FLAG = 0x80000000;
uint32 constant public PC_MASK = 0x7FFFFFFF;
uint32 constant public HEAP_START = 0x20000000; uint32 constant public HEAP_START = 0x20000000;
uint32 constant public BRK_START = 0x40000000; uint32 constant public BRK_START = 0x40000000;
...@@ -70,17 +73,6 @@ contract MIPS { ...@@ -70,17 +73,6 @@ contract MIPS {
return uint32(dat&mask | (isSigned ? signed : 0)); return uint32(dat&mask | (isSigned ? signed : 0));
} }
// will revert if any required input state is missing
function Step(bytes32 stateHash) public returns (bytes32) {
// instruction fetch
uint32 pc = ReadMemory(stateHash, REG_PC);
if (pc == 0xdead0000) {
return stateHash;
}
/*stateHash = WriteMemory(stateHash, REG_PC, pc+4);
return stateHash;*/
return stepNextPC(stateHash, pc, pc+4);
}
function handleSyscall(bytes32 stateHash) internal returns (bytes32) { function handleSyscall(bytes32 stateHash) internal returns (bytes32) {
uint32 syscall_no = ReadMemory(stateHash, REG_OFFSET+2*4); uint32 syscall_no = ReadMemory(stateHash, REG_OFFSET+2*4);
...@@ -110,7 +102,28 @@ contract MIPS { ...@@ -110,7 +102,28 @@ contract MIPS {
return stateHash; return stateHash;
} }
function stepNextPC(bytes32 stateHash, uint32 pc, uint64 nextPC) internal returns (bytes32) { function branchDelay(bytes32 stateHash, uint32 pc, uint32 nextPC) internal returns (bytes32) {
stateHash = WriteMemory(stateHash, REG_PENDPC, nextPC);
stateHash = WriteMemory(stateHash, REG_PC, PC_FLAG | pc);
return stateHash;
}
// will revert if any required input state is missing
function Step(bytes32 stateHash) public returns (bytes32) {
// instruction fetch
uint32 pc = ReadMemory(stateHash, REG_PC);
if (pc == 0xdead0000) {
return stateHash;
}
uint32 nextPC;
if (pc & PC_FLAG == 0) {
nextPC = pc + 4;
} else {
pc = pc & PC_MASK;
nextPC = ReadMemory(stateHash, REG_PENDPC);
}
uint32 insn = ReadMemory(stateHash, pc); uint32 insn = ReadMemory(stateHash, pc);
uint32 opcode = insn >> 26; // 6-bits uint32 opcode = insn >> 26; // 6-bits
...@@ -118,8 +131,8 @@ contract MIPS { ...@@ -118,8 +131,8 @@ contract MIPS {
// j-type j/jal // j-type j/jal
if (opcode == 2 || opcode == 3) { if (opcode == 2 || opcode == 3) {
return stepNextPC(stateHash, uint32(nextPC), return branchDelay(stateHash, nextPC,
(SE(insn&0x03FFFFFF, 26) << 2) | (opcode == 3 ? STORE_LINK : 0)); (SE(insn&0x03FFFFFF, 26) << 2) | (opcode == 3 ? PC_FLAG : 0));
} }
// register fetch // register fetch
...@@ -185,11 +198,12 @@ contract MIPS { ...@@ -185,11 +198,12 @@ contract MIPS {
if (shouldBranch) { if (shouldBranch) {
uint32 val = pc + 4 + (SE(insn&0xFFFF, 16)<<2); uint32 val = pc + 4 + (SE(insn&0xFFFF, 16)<<2);
return stepNextPC(stateHash, uint32(nextPC), val); return branchDelay(stateHash, nextPC, val);
} else { } else {
// branch not taken // branch not taken
return stepNextPC(stateHash, uint32(nextPC), uint32(nextPC)+4); return branchDelay(stateHash, nextPC, nextPC+4);
} }
} }
// ALU // ALU
...@@ -201,7 +215,7 @@ contract MIPS { ...@@ -201,7 +215,7 @@ contract MIPS {
if (opcode == 0 && func >= 8 && func < 0x1c) { if (opcode == 0 && func >= 8 && func < 0x1c) {
if (func == 8 || func == 9) { if (func == 8 || func == 9) {
// jr/jalr // jr/jalr
return stepNextPC(stateHash, uint32(nextPC), val | (func == 9 ? STORE_LINK : 0)); return branchDelay(stateHash, nextPC, val | (func == 9 ? PC_FLAG : 0));
} }
// handle movz and movn when they don't write back // handle movz and movn when they don't write back
...@@ -262,11 +276,11 @@ contract MIPS { ...@@ -262,11 +276,11 @@ contract MIPS {
stateHash = WriteMemory(stateHash, storeAddr, val); stateHash = WriteMemory(stateHash, storeAddr, val);
} }
if (nextPC & STORE_LINK == STORE_LINK) { if (nextPC & PC_FLAG != 0) {
stateHash = WriteMemory(stateHash, REG_LR, pc+4); stateHash = WriteMemory(stateHash, REG_LR, pc+4);
} }
stateHash = WriteMemory(stateHash, REG_PC, uint32(nextPC)); stateHash = WriteMemory(stateHash, REG_PC, nextPC & PC_MASK);
return stateHash; return stateHash;
} }
......
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