interpreter fixes
[nestedvm.git] / src / org / ibex / nestedvm / Interpreter.java
index cd82365..45d433c 100644 (file)
@@ -7,7 +7,7 @@ package org.ibex.nestedvm;
 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;
@@ -51,9 +51,17 @@ public class Interpreter extends UnixRuntime {
         }
     }
     
+    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;
@@ -62,8 +70,9 @@ public class Interpreter extends UnixRuntime {
     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);
         }
 
@@ -269,7 +278,7 @@ public class Interpreter extends UnixRuntime {
                 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;
@@ -413,6 +422,9 @@ public class Interpreter extends UnixRuntime {
                     }
                     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;
@@ -430,7 +442,7 @@ public class Interpreter extends UnixRuntime {
             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);
                 }
@@ -447,7 +459,7 @@ public class Interpreter extends UnixRuntime {
             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);
                 }
@@ -462,7 +474,7 @@ public class Interpreter extends UnixRuntime {
             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);
                 }
@@ -477,7 +489,7 @@ public class Interpreter extends UnixRuntime {
             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);
                 }
@@ -485,7 +497,7 @@ public class Interpreter extends UnixRuntime {
             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);
                 }
@@ -500,7 +512,7 @@ public class Interpreter extends UnixRuntime {
             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);
                 }
@@ -513,7 +525,7 @@ public class Interpreter extends UnixRuntime {
             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);
                 }
@@ -528,7 +540,7 @@ public class Interpreter extends UnixRuntime {
             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);
                 }
@@ -539,7 +551,7 @@ public class Interpreter extends UnixRuntime {
                     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);
                 }
@@ -548,7 +560,7 @@ public class Interpreter extends UnixRuntime {
             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);
                 }
@@ -557,7 +569,7 @@ public class Interpreter extends UnixRuntime {
                     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);
                 }
@@ -573,7 +585,7 @@ public class Interpreter extends UnixRuntime {
                     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);
                 }
@@ -582,7 +594,7 @@ public class Interpreter extends UnixRuntime {
             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]);
                 }
@@ -599,14 +611,14 @@ public class Interpreter extends UnixRuntime {
                 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;
@@ -632,10 +644,21 @@ public class Interpreter extends UnixRuntime {
         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();
         
@@ -647,19 +670,18 @@ public class Interpreter extends UnixRuntime {
         
         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;
@@ -671,25 +693,24 @@ public class Interpreter extends UnixRuntime {
             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) {
@@ -699,18 +720,17 @@ public class Interpreter extends UnixRuntime {
         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;