X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Forg%2Fxwt%2Fmips%2FInterpreter.java;h=9b0f11bd553fcee613751803a847864fe8afb7be;hb=0b0673bbc7f06c5d5418d5ab7ad5961a464e2de0;hp=a957297f1ac11efff4d05237e6cb771ca3551f72;hpb=7f5df8070a5551fe66abd11a589677e285ca62f8;p=org.ibex.core.git diff --git a/src/org/xwt/mips/Interpreter.java b/src/org/xwt/mips/Interpreter.java index a957297..9b0f11b 100644 --- a/src/org/xwt/mips/Interpreter.java +++ b/src/org/xwt/mips/Interpreter.java @@ -1,21 +1,19 @@ -// Copyright 2003 Adam Megacz -// Author Brian Alliet -// Based on org.xwt.mips.Compiler by Adam Megacz - +// Copyright 2003 Brian Alliet +// Based on org.xwt.imp.MIPS by Adam Megacz +// Portions Copyright 2003 Adam Megacz package org.xwt.mips; -import java.io.*; -public class Interpreter extends VM { +import java.io.*; +public class Interpreter extends Runtime { // Registers private int[] registers = new int[32]; private int hi,lo; // Floating Point Registers private int[] fpregs = new int[32]; - // 24-31 - unused - // 23 - conditional bit + // 23 - conditional bit // 18-22 - unused // 12-17 - cause bits (unimplemented) // 7-11 - enables bits (unimplemented) @@ -25,9 +23,6 @@ public class Interpreter extends VM { private int nextPC; - // The filename if the binary we're running - private Object image; - // Register Operations private final void setFC(boolean b) { fcsr = (fcsr&~0x800000) | (b ? 0x800000 : 0x000000); } private final int roundingMode() { return fcsr & 3; /* bits 0-1 */ } @@ -41,19 +36,14 @@ public class Interpreter extends VM { private final float getFloat(int r) { return Float.intBitsToFloat(fpregs[r]); } private final void setFloat(int r, float f) { fpregs[r] = Float.floatToRawIntBits(f); } - // Main run loop - public void execute() throws EmulationException { - int[] r = registers; - if(state == PAUSED) state = RUNNING; - if(state != RUNNING) throw new IllegalStateException("execute() called in inappropriate state"); - runSome(nextPC); - } + protected void _execute() throws ExecutionException { runSome(); } - // Main interpretor (also used for compilation) + // Main interpretor // the return value is meaningless, its just to catch people typing "return" by accident - private int runSome(int pc) throws FaultException,EmulationException { + private final int runSome() throws FaultException,ExecutionException { int[] r = registers; int[] f = fpregs; + int pc = nextPC; int nextPC = pc + 4; try { OUTER: for(;;) { @@ -96,15 +86,14 @@ public class Interpreter extends VM { case 3: // SRA r[rd] = r[rt] >> shamt; break; - // FIXME: Do we need % 32 on the r[rs] ? case 4: // SLLV - r[rd] = r[rt] << r[rs]; + r[rd] = r[rt] << (r[rs]&0x1f); break; case 6: // SRLV - r[rd] = r[rt] >>> r[rs]; + r[rd] = r[rt] >>> (r[rs]&0x1f); break; case 7: // SRAV - r[rd] = r[rt] >> r[rs]; + r[rd] = r[rt] >> (r[rs]&0x1f); break; case 8: // JR tmp = r[rs]; pc += 4; nextPC = tmp; @@ -120,7 +109,7 @@ public class Interpreter extends VM { } break; case 13: // BREAK - throw new EmulationException("Break"); + throw new ExecutionException("Break"); case 16: // MFHI r[rd] = hi; break; @@ -154,14 +143,18 @@ public class Interpreter extends VM { lo = (int)((r[rs] & 0xffffffffL) / (r[rt] & 0xffffffffL)); break; case 32: // ADD - r[rd] = r[rs] + r[rt]; // FIXME: Trap on overflow - break; + throw new ExecutionException("ADD (add with oveflow trap) not suported"); + /*This must trap on overflow + r[rd] = r[rs] + r[rt]; + break;*/ case 33: // ADDU r[rd] = r[rs] + r[rt]; break; case 34: // SUB - r[rd] = r[rs] - r[rt]; // FIXME: Trap on overflow - break; + throw new ExecutionException("SUB (sub with oveflow trap) not suported"); + /*This must trap on overflow + r[rd] = r[rs] - r[rt]; + break;*/ case 35: // SUBU r[rd] = r[rs] - r[rt]; break; @@ -184,7 +177,7 @@ public class Interpreter extends VM { r[rd] = ((r[rs] & 0xffffffffL) < (r[rt] & 0xffffffffL)) ? 1 : 0; break; default: - throw new EmulationException("Illegal instruction 0/" + subcode); + throw new ExecutionException("Illegal instruction 0/" + subcode); } break; } @@ -215,7 +208,7 @@ public class Interpreter extends VM { } break; default: - throw new EmulationException("Illegal Instruction"); + throw new ExecutionException("Illegal Instruction"); } break; } @@ -278,29 +271,29 @@ public class Interpreter extends VM { r[rt] = unsignedImmediate << 16; break; case 16: - throw new EmulationException("TLB/Exception support not implemented"); + throw new ExecutionException("TLB/Exception support not implemented"); case 17: { // FPU boolean debug = false; - String line = debug ? sourceLine(pc) : ""; + String line = ""; boolean debugon = debug && (line.indexOf("dtoa.c:51") >= 0 || line.indexOf("dtoa.c:52") >= 0 || line.indexOf("test.c") >= 0); if(rs > 8 && debugon) System.out.println(" FP Op: " + op + "/" + rs + "/" + subcode + " " + line); - // FIXME: This could probably be removed. I don't think gcc will ever generate code that does this + // FEATURE: This could probably be removed. I don't think gcc will ever generate code that does this if(roundingMode() != 0 && rs != 6 /*CTC.1*/ && !((rs==16 || rs==17) && subcode == 36 /* CVT.W.Z */)) - throw new EmulationException("Non-cvt.w.z operation attempted with roundingMode != round to nearest"); + throw new ExecutionException("Non-cvt.w.z operation attempted with roundingMode != round to nearest"); switch(rs) { case 0: // MFC.1 r[rt] = f[rd]; break; case 2: // CFC.1 - if(fs != 31) throw new EmulationException("FCR " + fs + " unavailable"); + if(fs != 31) throw new ExecutionException("FCR " + fs + " unavailable"); r[rt] = fcsr; break; case 4: // MTC.1 f[rd] = r[rt]; break; case 6: // CTC.1 - if(fs != 31) throw new EmulationException("FCR " + fs + " unavailable"); + if(fs != 31) throw new ExecutionException("FCR " + fs + " unavailable"); fcsr = r[rt]; break; case 8: // BC1F, BC1T @@ -330,7 +323,7 @@ public class Interpreter extends VM { f[fd] = f[fs]; break; case 7: // NEG.S - setFloat(fd,-getFloat(fs)); // FIXME: just flip the sign bit + setFloat(fd,-getFloat(fs)); // FEATURE: just flip the sign bit break; case 33: // CVT.D.S setDouble(fd,getFloat(fs)); @@ -344,12 +337,12 @@ public class Interpreter extends VM { } break; case -50: // C.EQ.S - setFC(getFloat(fs) == getFloat(ft)); // FIXME: just compare the ints, be sure things are normalized + setFC(getFloat(fs) == getFloat(ft)); // FEATURE: just compare the ints, be sure things are normalized break; case 60: // C.LT.S setFC(getFloat(fs) < getFloat(ft)); break; - default: throw new EmulationException("Invalid Instruction 17/" + rs + "/" + subcode + " at " + sourceLine(pc)); + default: throw new ExecutionException("Invalid Instruction 17/" + rs + "/" + subcode); } break; } @@ -378,7 +371,7 @@ public class Interpreter extends VM { f[fd+1] = f[fs+1]; break; case 7: // NEG.D - setDouble(fd,-getDouble(fs)); // FIXME: just flip the sign bit + setDouble(fd,-getDouble(fs)); // FEATURE: just flip the sign bit break; case 32: // CVT.S.D setFloat(fd,(float)getDouble(fs)); @@ -394,7 +387,7 @@ public class Interpreter extends VM { if(debugon) System.out.println("CVT.W.D: f" + fd + ":" + f[fd]); break; case 50: // C.EQ.D - setFC(getDouble(fs) == getDouble(ft)); // FIXME: just compare the ints, be sure things are normalized + setFC(getDouble(fs) == getDouble(ft)); // FEATURE: just compare the ints, be sure things are normalized break; case 60: // C.LT.D setFC(getDouble(fs) < getDouble(ft)); @@ -402,7 +395,7 @@ public class Interpreter extends VM { case 62: // C.LE.D setFC(getDouble(fs) <= getDouble(ft)); break; - default: throw new EmulationException("Invalid Instruction 17/" + rs + "/" + subcode + " at " + sourceLine(pc)); + default: throw new ExecutionException("Invalid Instruction 17/" + rs + "/" + subcode); } break; } @@ -411,21 +404,21 @@ public class Interpreter extends VM { case 33: // CVT.D.W setDouble(fd,(double)f[fs]); break; - default: throw new EmulationException("Invalid Instruction 17/" + rs + "/" + subcode + " at " + sourceLine(pc)); + default: throw new ExecutionException("Invalid Instruction 17/" + rs + "/" + subcode); } break; } default: - throw new EmulationException("Invalid Instruction 17/" + rs); + throw new ExecutionException("Invalid Instruction 17/" + rs); } break; } case 18: case 19: - throw new EmulationException("No coprocessor installed"); + throw new ExecutionException("No coprocessor installed"); case 32: { // LB addr = r[rs] + signedImmediate; try { - tmp = readPages[addr>>>PAGE_SHIFT][(addr>>>2)&PAGE_WORDS-1]; + tmp = readPages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)]; } catch(RuntimeException e) { tmp = memRead(addr&~3); } @@ -442,7 +435,7 @@ public class Interpreter extends VM { case 33: { // LH addr = r[rs] + signedImmediate; try { - tmp = readPages[addr>>>PAGE_SHIFT][(addr>>>2)&PAGE_WORDS-1]; + tmp = readPages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)]; } catch(RuntimeException e) { tmp = memRead(addr&~3); } @@ -457,7 +450,7 @@ public class Interpreter extends VM { case 34: { // LWL; addr = r[rs] + signedImmediate; try { - tmp = readPages[addr>>>PAGE_SHIFT][(addr>>>2)&PAGE_WORDS-1]; + tmp = readPages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)]; } catch(RuntimeException e) { tmp = memRead(addr&~3); } @@ -472,7 +465,7 @@ public class Interpreter extends VM { case 35: // LW addr = r[rs] + signedImmediate; try { - r[rt] = readPages[addr>>>PAGE_SHIFT][(addr>>>2)&PAGE_WORDS-1]; + r[rt] = readPages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)]; } catch(RuntimeException e) { r[rt] = memRead(addr); } @@ -480,7 +473,7 @@ public class Interpreter extends VM { case 36: { // LBU addr = r[rs] + signedImmediate; try { - tmp = readPages[addr>>>PAGE_SHIFT][(addr>>>2)&PAGE_WORDS-1]; + tmp = readPages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)]; } catch(RuntimeException e) { tmp = memRead(addr); } @@ -495,7 +488,7 @@ public class Interpreter extends VM { case 37: { // LHU addr = r[rs] + signedImmediate; try { - tmp = readPages[addr>>>PAGE_SHIFT][(addr>>>2)&PAGE_WORDS-1]; + tmp = readPages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)]; } catch(RuntimeException e) { tmp = memRead(addr&~3); } @@ -508,7 +501,7 @@ public class Interpreter extends VM { case 38: { // LWR addr = r[rs] + signedImmediate; try { - tmp = readPages[addr>>>PAGE_SHIFT][(addr>>>2)&PAGE_WORDS-1]; + tmp = readPages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)]; } catch(RuntimeException e) { tmp = memRead(addr&~3); } @@ -523,7 +516,7 @@ public class Interpreter extends VM { case 40: { // SB addr = r[rs] + signedImmediate; try { - tmp = readPages[addr>>>PAGE_SHIFT][(addr>>>2)&PAGE_WORDS-1]; + tmp = readPages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)]; } catch(RuntimeException e) { tmp = memRead(addr&~3); } @@ -534,7 +527,7 @@ public class Interpreter extends VM { case 3: tmp = (tmp&0xffffff00) | ((r[rt]&0xff)<< 0); break; } try { - writePages[addr>>>PAGE_SHIFT][(addr>>>2)&PAGE_WORDS-1] = tmp; + writePages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)] = tmp; } catch(RuntimeException e) { memWrite(addr&~3,tmp); } @@ -543,7 +536,7 @@ public class Interpreter extends VM { case 41: { // SH addr = r[rs] + signedImmediate; try { - tmp = readPages[addr>>>PAGE_SHIFT][(addr>>>2)&PAGE_WORDS-1]; + tmp = readPages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)]; } catch(RuntimeException e) { tmp = memRead(addr&~3); } @@ -552,7 +545,7 @@ public class Interpreter extends VM { case 2: tmp = (tmp&0xffff0000) | ((r[rt]&0xffff)<< 0); break; } try { - writePages[addr>>>PAGE_SHIFT][(addr>>>2)&PAGE_WORDS-1] = tmp; + writePages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)] = tmp; } catch(RuntimeException e) { memWrite(addr&~3,tmp); } @@ -568,7 +561,7 @@ public class Interpreter extends VM { case 3: tmp=(tmp&0xffffff00)|(r[rt]>>>24); break; } try { - writePages[addr>>>PAGE_SHIFT][(addr>>>2)&PAGE_WORDS-1] = tmp; + writePages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)] = tmp; } catch(RuntimeException e) { memWrite(addr&~3,tmp); } @@ -577,7 +570,7 @@ public class Interpreter extends VM { case 43: // SW addr = r[rs] + signedImmediate; try { - writePages[addr>>>PAGE_SHIFT][(addr>>>2)&PAGE_WORDS-1] = r[rt]; + writePages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)] = r[rt]; } catch(RuntimeException e) { memWrite(addr&~3,r[rt]); } @@ -601,12 +594,12 @@ public class Interpreter extends VM { memWrite(r[rs] + signedImmediate,f[rt]); break; default: - throw new EmulationException("Invalid Instruction: " + op); + throw new ExecutionException("Invalid Instruction: " + op); } pc = nextPC; nextPC = pc + 4; } // for(;;) - } catch(EmulationException e) { + } catch(ExecutionException e) { this.nextPC = pc; throw e; } @@ -615,9 +608,7 @@ public class Interpreter extends VM { // Image loading function void loadImage(Object file) throws IOException { - ELF elf = null; - if (file instanceof String) elf = new ELF(new RandomAccessFile((String)file,"r")); - else if (file instanceof byte[]) elf = new ELF((byte[])file); + ELF elf = new ELF(file); if(elf.header.type != ELF.ELFHeader.ET_EXEC) throw new IOException("Binary is not an executable"); if(elf.header.machine != ELF.ELFHeader.EM_MIPS) @@ -653,41 +644,25 @@ public class Interpreter extends VM { dis.close(); } } - image = file; state = INITIALIZED; } protected void _start(int pc) { + registers[K0] = STUFF_BASE; + registers[K1] = PAGE_SIZE; registers[SP] = INITIAL_SP; registers[RA] = 0xdeadbeef; nextPC = pc; } - public Interpreter() { } - public Interpreter(String image) throws IOException { loadImage(image); } - public Interpreter(byte[] image) throws IOException { loadImage(image); } - - // Debug functions - // NOTE: This probably requires a jdk > 1.1, however, it is only used for debugging - public String sourceLine(int pc) { - final String addr2line = "mips-unknown-elf-addr2line"; - String line; - if(image==null) return null; - try { - Process p = Runtime.getRuntime().exec(new String[]{addr2line,"-e",image.toString(),toHex(pc)}); - line = new BufferedReader(new InputStreamReader(p.getInputStream())).readLine(); - if(line == null) return null; - while(line.startsWith("../")) line = line.substring(3); - return line; - } catch(IOException e) { - return null; - } - } + public Interpreter() { super(true); /* allow empty pages */ } + public Interpreter(String filename) throws IOException { loadImage(filename); } + public Interpreter(byte[] bytes) throws IOException { loadImage(bytes); } public class DebugShutdownHook implements Runnable { public void run() { int pc = nextPC; if(getState() == RUNNING) - System.err.print("\nCPU Executing " + toHex(pc) + ": " + sourceLine(pc) + "\n"); + System.err.print("\nCPU Executing " + toHex(pc) + "\n"); } } @@ -695,7 +670,7 @@ public class Interpreter extends VM { String image = argv[0]; Interpreter emu = new Interpreter(); emu.loadImage(image); - Runtime.getRuntime().addShutdownHook(new Thread(emu.new DebugShutdownHook())); + java.lang.Runtime.getRuntime().addShutdownHook(new Thread(emu.new DebugShutdownHook())); // User data int addr = emu.sbrk(PAGE_SIZE); for(int i=0;i<10;i++) { @@ -711,5 +686,3 @@ public class Interpreter extends VM { System.exit(status); } } - -