clarify licensing
[nestedvm.git] / src / org / ibex / nestedvm / Interpreter.java
index 276eea7..2e8252f 100644 (file)
@@ -1,3 +1,7 @@
+// Copyright 2000-2005 the Contributors, as shown in the revision logs.
+// Licensed under the Apache License 2.0 ("the License").
+// You may not use this file except in compliance with the License.
+
 // Copyright 2003 Brian Alliet
 // Based on org.xwt.imp.MIPS by Adam Megacz
 // Portions Copyright 2003 Adam Megacz
 // Copyright 2003 Brian Alliet
 // Based on org.xwt.imp.MIPS by Adam Megacz
 // Portions Copyright 2003 Adam Megacz
@@ -7,7 +11,7 @@ package org.ibex.nestedvm;
 import org.ibex.nestedvm.util.*;
 import java.io.*;
 
 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;
     // Registers
     private int[] registers = new int[32];
     private int hi,lo;
@@ -51,6 +55,13 @@ 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 {
     // Main interpretor
     // the return value is meaningless, its just to catch people typing "return" by accident
     private final int runSome() throws FaultException,ExecutionException {
@@ -65,6 +76,7 @@ public class Interpreter extends UnixRuntime {
         try {
             insn = readPages[pc>>>pageShift][(pc>>>2)&PAGE_WORDS-1];
         } catch (RuntimeException e) {
         try {
             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);
         }
 
             insn = memRead(pc);
         }
 
@@ -86,7 +98,7 @@ public class Interpreter extends UnixRuntime {
         int tmp, addr; // temporaries
         
         r[ZERO] = 0;
         int tmp, addr; // temporaries
         
         r[ZERO] = 0;
-    
+        
         switch(op) {
             case 0: {
                 switch(subcode) {
         switch(op) {
             case 0: {
                 switch(subcode) {
@@ -117,7 +129,7 @@ public class Interpreter extends UnixRuntime {
                         continue OUTER;
                     case 12: // SYSCALL
                         this.pc = pc;
                         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
                         if(state != RUNNING) { this.pc = nextPC; break OUTER; }
                         break;
                     case 13: // BREAK
@@ -135,7 +147,7 @@ public class Interpreter extends UnixRuntime {
                         lo = r[rs];
                         break;
                     case 24: { // MULT
                         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;
                         hi = (int) (hilo >>> 32);
                         lo = (int) hilo;
                         break;
@@ -270,7 +282,7 @@ public class Interpreter extends UnixRuntime {
                 r[rt] = r[rs] < signedImmediate ? 1 : 0;
                 break;
             case 11: // SLTIU
                 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;
                 break;
             case 12: // ANDI
                 r[rt] = r[rs] & unsignedImmediate;
@@ -355,6 +367,9 @@ public class Interpreter extends UnixRuntime {
                             case 60: // C.LT.S
                                 setFC(getFloat(fs) < getFloat(ft));
                                 break;
                             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;
                             default: throw new ExecutionException("Invalid Instruction 17/" + rs + "/" + subcode + " at " + sourceLine(pc));
                         }
                         break;
@@ -414,6 +429,9 @@ public class Interpreter extends UnixRuntime {
                     }
                     case 20: { // Integer
                         switch(subcode) {
                     }
                     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 33: // CVT.D.W
                                 setDouble(fd,f[fs]);
                                 break;
@@ -452,9 +470,10 @@ public class Interpreter extends UnixRuntime {
                 } catch(RuntimeException e) {
                     tmp = memRead(addr&~3);
                 }
                 } catch(RuntimeException e) {
                     tmp = memRead(addr&~3);
                 }
-                switch(addr&2) {
+                switch(addr&3) {
                     case 0: tmp = (tmp>>>16)&0xffff; break;
                     case 2: tmp = (tmp>>> 0)&0xffff; break;
                     case 0: tmp = (tmp>>>16)&0xffff; break;
                     case 2: tmp = (tmp>>> 0)&0xffff; break;
+                    default: throw new ReadFaultException(addr);
                 }
                 if((tmp&0x8000)!=0) tmp |= 0xffff0000; // sign extend
                 r[rt] = tmp;
                 }
                 if((tmp&0x8000)!=0) tmp |= 0xffff0000; // sign extend
                 r[rt] = tmp;
@@ -505,9 +524,10 @@ public class Interpreter extends UnixRuntime {
                 } catch(RuntimeException e) {
                     tmp = memRead(addr&~3);
                 }
                 } catch(RuntimeException e) {
                     tmp = memRead(addr&~3);
                 }
-                switch(addr&2) {
+                switch(addr&3) {
                     case 0: r[rt] = (tmp>>>16)&0xffff; break;
                     case 2: r[rt] = (tmp>>> 0)&0xffff; break;
                     case 0: r[rt] = (tmp>>>16)&0xffff; break;
                     case 2: r[rt] = (tmp>>> 0)&0xffff; break;
+                    default: throw new ReadFaultException(addr);
                 }
                 break;
             }
                 }
                 break;
             }
@@ -553,9 +573,10 @@ public class Interpreter extends UnixRuntime {
                 } catch(RuntimeException e) {
                     tmp = memRead(addr&~3);
                 }
                 } catch(RuntimeException e) {
                     tmp = memRead(addr&~3);
                 }
-                switch(addr&2) {
+                switch(addr&3) {
                     case 0: tmp = (tmp&0x0000ffff) | ((r[rt]&0xffff)<<16); break;
                     case 2: tmp = (tmp&0xffff0000) | ((r[rt]&0xffff)<< 0); break;
                     case 0: tmp = (tmp&0x0000ffff) | ((r[rt]&0xffff)<<16); break;
                     case 2: tmp = (tmp&0xffff0000) | ((r[rt]&0xffff)<< 0); break;
+                    default: throw new WriteFaultException(addr);
                 }
                 try {
                     writePages[addr>>>pageShift][(addr>>>2)&(PAGE_WORDS-1)] = tmp;
                 }
                 try {
                     writePages[addr>>>pageShift][(addr>>>2)&(PAGE_WORDS-1)] = tmp;
@@ -600,14 +621,14 @@ public class Interpreter extends UnixRuntime {
                 memWrite(addr&~3,tmp);
                 break;
             }
                 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;
             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;
             case 56:
                 memWrite(r[rs] + signedImmediate,r[rt]);
                 r[rt] = 1;
@@ -651,9 +672,9 @@ public class Interpreter extends UnixRuntime {
         ELF elf = new ELF(data);
         symtab = elf.getSymtab();
         
         ELF elf = new ELF(data);
         symtab = elf.getSymtab();
         
-        if(elf.header.type != ELF.ELFHeader.ET_EXEC) throw new IOException("Binary is not an executable");
-        if(elf.header.machine != ELF.ELFHeader.EM_MIPS) throw new IOException("Binary is not for the MIPS I Architecture");
-        if(elf.ident.data != ELF.ELFIdent.ELFDATA2MSB) throw new IOException("Binary is not big endian");
+        if(elf.header.type != ELF.ET_EXEC) throw new IOException("Binary is not an executable");
+        if(elf.header.machine != ELF.EM_MIPS) throw new IOException("Binary is not for the MIPS I Architecture");
+        if(elf.ident.data != ELF.ELFDATA2MSB) throw new IOException("Binary is not big endian");
         
         entryPoint = elf.header.entry;
         
         
         entryPoint = elf.header.entry;
         
@@ -673,7 +694,7 @@ public class Interpreter extends UnixRuntime {
         int pageWords = (1<<pageShift) >> 2;
         for(int i=0;i<pheaders.length;i++) {
             ELF.PHeader ph = pheaders[i];
         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(ph.type != ELF.PT_LOAD) continue;
             int memsize = ph.memsz;
             int filesize = ph.filesz;
             if(memsize == 0) continue;
             int memsize = ph.memsz;
             int filesize = ph.filesz;
             if(memsize == 0) continue;