if (packageName != null) p("package " + packageName + ";");
if(runtimeStats) p("import java.util.*;");
p();
- p("public class " + className + " extends " + runtimeClass + " {");
+ p("public final class " + className + " extends " + runtimeClass + " {");
indent++;
p("/* program counter */");
// Constructor
p("public " + className + "() {");
indent++;
- p("super(" + pageSize + "," + totalPages + "," + (fastMem?"false":"true") + ");");
- p("entryPoint = " + toHex(elf.header.entry) + ";");
- if(userInfo != null) {
- p("userInfoBase=" + toHex(userInfo.addr) + ";");
- p("userInfoSize=" + userInfo.size + ";");
- }
- p("gp = " + toHex(gp.addr) + ";");
- if(onePage)
- p("brkAddr = " + toHex((highestAddr+4095)&~4095) + ";");
- else
- p("brkAddr = " + toHex((highestAddr+pageSize-1)&~(pageSize-1)) + ";");
+ p("super(" + pageSize + "," + totalPages + ");");
pblock(inits);
- p("state = INITIALIZED;");
indent--;
p("}");
p();
+ p("protected int entryPoint() { return " + toHex(elf.header.entry) + "; }");
+ p("protected int heapStart() { return " + toHex(highestAddr) + "; }");
+ p("protected int gp() { return " + toHex(gp.addr) + "; }");
+ if(userInfo != null) {
+ p("protected int userInfoBase() { return " + toHex(userInfo.addr) + "; }");
+ p("protected int userInfoSize() { return " + toHex(userInfo.size) + "; }");
+ }
+
// main() function
p("public static void main(String[] args) throws Exception {");
indent++;
p("pc=state.pc;");
indent--;
p("}");
- p("protected CPUState getCPUState() {");
+ p("protected void getCPUState(CPUState state) {");
indent++;
- p("CPUState state = new CPUState();");
for(int i=1;i<32;i++) p("state.r[" + i + "]=r" + i+ ";");
for(int i=0;i<32;i++) p("state.f[" + i + "]=f" + i +";");
p("state.hi=hi; state.lo=lo; state.fcsr=fcsr;");
p("state.pc=pc;");
- p("return state;");
indent--;
p("}");
p();
private void endMethod() { endMethod(endOfMethod); }
private void endMethod(int lastAddr) {
if(startOfMethod == 0) return;
- // FEATURE: We should be able to use if(!unreachable) here (i think)
+ // We should be able to use if(!unreachable) here (i think)
// This isn't strictly necessary; its just here to work around unreachable code errors
p("case " + toHex(lastAddr) + ":");
indent++;
break;
case 12: // SYSCALL
p("pc = " + toHex(pc) + ";");
- p( "r"+V0+" = syscall(r"+V0+",r"+A0+",r"+A1+",r"+A2+",r"+A3+");");
+ p( "r"+V0+" = syscall(r"+V0+",r"+A0+",r"+A1+",r"+A2+",r"+A3+",r"+T0+",r"+T1+");");
p("if (state != RUNNING) {");
indent++;
p("pc = " + toHex(pc+4) + ";");
if(pc == -1) throw new Error("pc modifying insn in delay slot");
int target = (pc&0xf0000000)|(jumpTarget << 2);
emitInstruction(-1,nextInsn,-1);
- if(optimizedMemcpy && (target == memcpy || target == memset)) {
- if(target == memcpy)
- p("memcpy(r4,r5,r6);");
- else if(target == memset)
- p("memset(r4,r5,r6);");
- p("r2 = r4;");
- branch(pc,pc+8);
- } else {
- p("r" + RA + "=" + constant(pc+8 /*skip this insn and delay slot*/) + ";");
- branch(pc, target);
- }
+ p("r" + RA + "=" + constant(pc+8 /*skip this insn and delay slot*/) + ";");
+ branch(pc, target);
unreachable = true;
break;
}
p( "r"+rt+" = r"+rs+" < "+signedImmediate+" ? 1 : 0;");
break;
case 11: // SLTIU
- p( "r"+rt+" = (r"+rs+"&0xffffffffL) < ("+unsignedImmediate+"&0xffffffffL) ? 1 : 0;");
+ p( "r"+rt+" = (r"+rs+"&0xffffffffL) < ("+signedImmediate+"&0xffffffffL) ? 1 : 0;");
break;
case 12: // ANDI
p( "r"+rt+" = r"+rs+" & "+unsignedImmediate+";");
memWrite("addr","tmp");
break;
}
- // FEATURE: Need to be atomic if threads
+ // Need to be atomic if threads
case 48: // LWC0/LL
memRead("r"+rs+"+"+signedImmediate,"r"+rt);
break;
case 49: // LWC1
memRead("r"+rs+"+"+signedImmediate,"f"+rt);
break;
- // FEATURE: Needs to be atomic if threads
+ // Needs to be atomic if threads
case 56: // SWC1/SC
memWrite("r"+rs+"+"+signedImmediate,"r"+rt);
p("r" + rt + "=1;");