import org.ibex.nestedvm.util.*;
import java.io.*;
-public class Interpreter extends UnixRuntime {
+public class Interpreter extends UnixRuntime implements Cloneable {
// Registers
private int[] registers = new int[32];
private int hi,lo;
}
}
+ protected Object clone() throws CloneNotSupportedException {
+ Interpreter r = (Interpreter) super.clone();
+ r.registers = (int[]) registers.clone();
+ r.fpregs = (int[]) fpregs.clone();
+ return r;
+ }
+
// Main interpretor
// the return value is meaningless, its just to catch people typing "return" by accident
private final int runSome() throws FaultException,ExecutionException {
+ final int PAGE_WORDS = (1<<pageShift)>>2;
int[] r = registers;
int[] f = fpregs;
int pc = this.pc;
OUTER: for(;;) {
int insn;
try {
- insn = readPages[pc>>>PAGE_SHIFT][(pc>>>2)&PAGE_WORDS-1];
+ insn = readPages[pc>>>pageShift][(pc>>>2)&PAGE_WORDS-1];
} catch (RuntimeException e) {
+ if(pc == 0xdeadbeef) throw new Error("fell off cpu: r2: " + r[2]);
insn = memRead(pc);
}
int tmp, addr; // temporaries
r[ZERO] = 0;
-
+
switch(op) {
case 0: {
switch(subcode) {
continue OUTER;
case 12: // SYSCALL
this.pc = pc;
- r[V0] = syscall(r[V0],r[A0],r[A1],r[A2],r[A3]);
+ r[V0] = syscall(r[V0],r[A0],r[A1],r[A2],r[A3],r[T0],r[T1]);
if(state != RUNNING) { this.pc = nextPC; break OUTER; }
break;
case 13: // BREAK
lo = r[rs];
break;
case 24: { // MULT
- long hilo = (long)(r[rs]) * ((long)r[rt]);
+ long hilo = ((long)r[rs]) * ((long)r[rt]);
hi = (int) (hilo >>> 32);
lo = (int) hilo;
break;
r[rt] = r[rs] < signedImmediate ? 1 : 0;
break;
case 11: // SLTIU
- r[rt] = (r[rs]&0xffffffffL) < (unsignedImmediate&0xffffffffL) ? 1 : 0;
+ r[rt] = (r[rs]&0xffffffffL) < (signedImmediate&0xffffffffL) ? 1 : 0;
break;
case 12: // ANDI
r[rt] = r[rs] & unsignedImmediate;
case 60: // C.LT.S
setFC(getFloat(fs) < getFloat(ft));
break;
+ case 62: // C.LE.S
+ setFC(getFloat(fs) <= getFloat(ft));
+ break;
default: throw new ExecutionException("Invalid Instruction 17/" + rs + "/" + subcode + " at " + sourceLine(pc));
}
break;
}
case 20: { // Integer
switch(subcode) {
+ case 32: // CVT.S.W
+ setFloat(fd,f[fs]);
+ break;
case 33: // CVT.D.W
setDouble(fd,f[fs]);
break;
case 32: { // LB
addr = r[rs] + signedImmediate;
try {
- tmp = readPages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)];
+ tmp = readPages[addr>>>pageShift][(addr>>>2)&(PAGE_WORDS-1)];
} catch(RuntimeException e) {
tmp = memRead(addr&~3);
}
case 33: { // LH
addr = r[rs] + signedImmediate;
try {
- tmp = readPages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)];
+ tmp = readPages[addr>>>pageShift][(addr>>>2)&(PAGE_WORDS-1)];
} catch(RuntimeException e) {
tmp = memRead(addr&~3);
}
case 34: { // LWL;
addr = r[rs] + signedImmediate;
try {
- tmp = readPages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)];
+ tmp = readPages[addr>>>pageShift][(addr>>>2)&(PAGE_WORDS-1)];
} catch(RuntimeException e) {
tmp = memRead(addr&~3);
}
case 35: // LW
addr = r[rs] + signedImmediate;
try {
- r[rt] = readPages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)];
+ r[rt] = readPages[addr>>>pageShift][(addr>>>2)&(PAGE_WORDS-1)];
} catch(RuntimeException e) {
r[rt] = memRead(addr);
}
case 36: { // LBU
addr = r[rs] + signedImmediate;
try {
- tmp = readPages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)];
+ tmp = readPages[addr>>>pageShift][(addr>>>2)&(PAGE_WORDS-1)];
} catch(RuntimeException e) {
tmp = memRead(addr);
}
case 37: { // LHU
addr = r[rs] + signedImmediate;
try {
- tmp = readPages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)];
+ tmp = readPages[addr>>>pageShift][(addr>>>2)&(PAGE_WORDS-1)];
} catch(RuntimeException e) {
tmp = memRead(addr&~3);
}
case 38: { // LWR
addr = r[rs] + signedImmediate;
try {
- tmp = readPages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)];
+ tmp = readPages[addr>>>pageShift][(addr>>>2)&(PAGE_WORDS-1)];
} catch(RuntimeException e) {
tmp = memRead(addr&~3);
}
case 40: { // SB
addr = r[rs] + signedImmediate;
try {
- tmp = readPages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)];
+ tmp = readPages[addr>>>pageShift][(addr>>>2)&(PAGE_WORDS-1)];
} catch(RuntimeException e) {
tmp = memRead(addr&~3);
}
case 3: tmp = (tmp&0xffffff00) | ((r[rt]&0xff)<< 0); break;
}
try {
- writePages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)] = tmp;
+ writePages[addr>>>pageShift][(addr>>>2)&(PAGE_WORDS-1)] = tmp;
} catch(RuntimeException e) {
memWrite(addr&~3,tmp);
}
case 41: { // SH
addr = r[rs] + signedImmediate;
try {
- tmp = readPages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)];
+ tmp = readPages[addr>>>pageShift][(addr>>>2)&(PAGE_WORDS-1)];
} catch(RuntimeException e) {
tmp = memRead(addr&~3);
}
case 2: tmp = (tmp&0xffff0000) | ((r[rt]&0xffff)<< 0); break;
}
try {
- writePages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)] = tmp;
+ writePages[addr>>>pageShift][(addr>>>2)&(PAGE_WORDS-1)] = tmp;
} catch(RuntimeException e) {
memWrite(addr&~3,tmp);
}
case 3: tmp=(tmp&0xffffff00)|(r[rt]>>>24); break;
}
try {
- writePages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)] = tmp;
+ writePages[addr>>>pageShift][(addr>>>2)&(PAGE_WORDS-1)] = tmp;
} catch(RuntimeException e) {
memWrite(addr&~3,tmp);
}
case 43: // SW
addr = r[rs] + signedImmediate;
try {
- writePages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)] = r[rt];
+ writePages[addr>>>pageShift][(addr>>>2)&(PAGE_WORDS-1)] = r[rt];
} catch(RuntimeException e) {
memWrite(addr&~3,r[rt]);
}
memWrite(addr&~3,tmp);
break;
}
- // FEATURE: Needs to be atomic w/ threads
+ // Needs to be atomic w/ threads
case 48: // LWC0/LL
r[rt] = memRead(r[rs] + signedImmediate);
break;
case 49: // LWC1
f[rt] = memRead(r[rs] + signedImmediate);
break;
- // FEATURE: Needs to be atomic w/ threads
+ // Needs to be atomic w/ threads
case 56:
memWrite(r[rs] + signedImmediate,r[rt]);
r[rt] = 1;
return sym == null ? -1 : sym.addr;
}
+ private int gp;
+ protected int gp() { return gp; }
+
+ private ELF.Symbol userInfo;
+ protected int userInfoBae() { return userInfo == null ? 0 : userInfo.addr; }
+ protected int userInfoSize() { return userInfo == null ? 0 : userInfo.size; }
+
+ private int entryPoint;
+ protected int entryPoint() { return entryPoint; }
+
+ private int heapStart;
+ protected int heapStart() { return heapStart; }
+
// Image loading function
private void loadImage(Seekable data) throws IOException {
- if(state != UNINITIALIZED) throw new IllegalStateException("loadImage called on initialized runtime");
-
ELF elf = new ELF(data);
symtab = elf.getSymtab();
ELF.Symtab symtab = elf.getSymtab();
if(symtab == null) throw new IOException("No symtab in binary (did you strip it?)");
- ELF.Symbol userInfo = symtab.getGlobalSymbol("user_info");
+ userInfo = symtab.getGlobalSymbol("user_info");
ELF.Symbol gpsym = symtab.getGlobalSymbol("_gp");
if(gpsym == null) throw new IOException("NO _gp symbol!");
gp = gpsym.addr;
- if(userInfo != null) {
- userInfoBase = userInfo.addr;
- userInfoSize = userInfo.size;
- }
+ entryPoint = elf.header.entry;
ELF.PHeader[] pheaders = elf.pheaders;
int brk = 0;
+ int pageSize = (1<<pageShift);
+ int pageWords = (1<<pageShift) >> 2;
for(int i=0;i<pheaders.length;i++) {
ELF.PHeader ph = pheaders[i];
if(ph.type != ELF.PHeader.PT_LOAD) continue;
if(addr == 0x0) throw new IOException("pheader vaddr == 0x0");
brk = max(addr+memsize,brk);
- for(int j=0;j<memsize+PAGE_SIZE-1;j+=PAGE_SIZE) {
- int page = (j+addr) >>> PAGE_SHIFT;
+ for(int j=0;j<memsize+pageSize-1;j+=pageSize) {
+ int page = (j+addr) >>> pageShift;
if(readPages[page] == null)
- readPages[page] = new int[PAGE_WORDS];
+ readPages[page] = new int[pageWords];
if(ph.writable()) writePages[page] = readPages[page];
}
if(filesize != 0) {
filesize = filesize & ~3;
DataInputStream dis = new DataInputStream(ph.getInputStream());
do {
- readPages[addr >>> PAGE_SHIFT][(addr >>> 2)&(PAGE_WORDS-1)] = dis.readInt();
+ readPages[addr >>> pageShift][(addr >>> 2)&(pageWords-1)] = dis.readInt();
addr+=4;
filesize-=4;
} while(filesize > 0);
dis.close();
}
}
- brkAddr = (brk+PAGE_SIZE-1)&~(PAGE_SIZE-1);
- state = INITIALIZED;
+ heapStart = (brk+pageSize-1)&~(pageSize-1);
}
protected void setCPUState(CPUState state) {
pc=state.pc;
}
- protected CPUState getCPUState() {
- CPUState state = new CPUState();
+ protected void getCPUState(CPUState state) {
for(int i=1;i<32;i++) state.r[i] = registers[i];
for(int i=0;i<32;i++) state.f[i] = fpregs[i];
state.hi=hi; state.lo=lo; state.fcsr=fcsr;
state.pc=pc;
- return state;
}
- // This is package private for fork() which does all kinds of ugly things behind the scenes
- Interpreter() { super(4096,65536,true); }
- public Interpreter(Seekable data) throws IOException { this(); loadImage(data); }
+ public Interpreter(Seekable data) throws IOException {
+ super(4096,65536);
+ loadImage(data);
+ }
public Interpreter(String filename) throws IOException {
this(new Seekable.File(filename,false));
image = filename;