import org.ibex.classgen.*;
// FEATURE: Use IINC where possible
-// FEATURE: Use BCEL to do peephole optimization
+// FEATURE: Some kind of peephole optimization
// FEATURE: Special mode to support single-precision only - regs are floats not ints
/* FEATURE: Span large binaries across several classfiles
int start = tramp.size();
tramp.add(ALOAD_0);
tramp.add(GETFIELD,new FieldRef(me,"state",Type.INT));
- tramp.add(LDC,Runtime.RUNNING);
+ int stateCheck = tramp.add(IFNE);
- int stateCheck = tramp.add(IF_ICMPNE);
tramp.add(ALOAD_0);
tramp.add(ALOAD_0);
tramp.add(GETFIELD,new FieldRef(me,"pc",Type.INT));
mg.add(LDC,pc);
setPC();
+ // FEATURE: This is actually broken, but it happens to work for our code
+ // a func could theoretically jump back to here from a future point
restoreChangedRegs();
preSetReg(R+V0);
mg.add(ALOAD_0);
mg.add(GETFIELD,new FieldRef(me,"state",Type.INT));
- // FEATURE: Set Runtime.RUNNING to 0 and just use IFEQ here
- mg.add(LDC,Runtime.RUNNING);
- b1 = mg.add(IF_ICMPEQ);
+ b1 = mg.add(IFEQ);
preSetPC();
mg.add(LDC,pc+4);
setPC();
private static final int FCSR = 66;
private static final int REG_COUNT=67;
- // FEATURE: Clean this up
private int[] regLocalMapping = new int[REG_COUNT];
private int[] regLocalReadCount = new int[REG_COUNT];
private int[] regLocalWriteCount = new int[REG_COUNT];
private int nextAvailLocal;
+ private int loadsStart;
+ private static final int MAX_LOCALS = 4;
+ private static final int LOAD_LENGTH = 3;
+
+ private boolean doLocal(int reg) {
+ return reg == R+2 || reg == R+3 || reg == R+4 || reg == R+29;
+ }
private int getLocalForReg(int reg) {
if(regLocalMapping[reg] != 0) return regLocalMapping[reg];
return regLocalMapping[reg];
}
-
- private int loadsStart;
private void fixupRegsStart() {
for(int i=0;i<REG_COUNT;i++)
regLocalMapping[i] = regLocalReadCount[i] = regLocalWriteCount[i] = 0;
}
}
- private static final int MAX_LOCALS = 4;
- private static final int LOAD_LENGTH = 3;
- private boolean doLocal(int reg) {
- return reg == R+2 || reg == R+3 || reg == R+4 || reg == R+29;
- }
-
private void restoreChangedRegs() {
for(int i=0;i<REG_COUNT;i++) {
if(regLocalWriteCount[i] > 0) {
}
private int pushRegZ(int reg) {
- if(reg == R+0) return mg.add(LDC,0);
+ if(reg == R+0) return mg.add(ICONST_0);
else return pushReg(reg);
}
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++;
// Based on org.xwt.imp.MIPS by Adam Megacz
// Portions Copyright 2003 Adam Megacz
+// FEATURE: Add a patch to gcc that enabled -Wall -Werror by default
+// FIXME: Get a hotel for IVME :)
+
package org.ibex.nestedvm;
import org.ibex.nestedvm.util.*;
/** When the process started */
private long startTime;
- /** Text/Data loaded in memory */
- public final static int STOPPED = 0;
/** Program is executing instructions */
- public final static int RUNNING = 1;
+ public final static int RUNNING = 0; // Horrible things will happen if this isn't 0
+ /** Text/Data loaded in memory */
+ public final static int STOPPED = 1;
/** Prgram has been started but is paused */
public final static int PAUSED = 2;
/** Program is executing a callJava() method */
public FStat _fstat() { return new FStat() { public int type() { return S_IFCHR; } public int mode() { return 0600; } }; }
}
- // FEATURE: TextInputStream: This is pretty inefficient but it is only used for reading from the console on win32
+ // This is pretty inefficient but it is only used for reading from the console on win32
static class TextInputStream extends InputStream {
private int pushedBack = -1;
private final InputStream parent;
// FEATURE: This need a lot of work to support binaries spanned across many classes
public class RuntimeCompiler {
- // FEATURE: Do we need to periodicly create a new classloader to allow old clases to be GCed?
- private static SingleClassLoader singleClassLoader = new SingleClassLoader();
- // FEATURE: Is it ok if this overflows?
- private static long nextID = 1;
- private static synchronized String uniqueID() { return Long.toString(nextID++); }
+ private static SingleClassLoader singleClassLoader;
+ private static int nextID;
- public static Class compile(Seekable data) throws IOException, Compiler.Exn {
- String className = "nextedvm.runtimecompiled_" + uniqueID();
+ public static Class compile(Seekable data) throws IOException, Compiler.Exn { return compile(data,null); }
+ public static Class compile(Seekable data, String extraoptions) throws IOException, Compiler.Exn {
+ int id;
+ synchronized(RuntimeCompiler.class) {
+ if(nextID == 32 || singleClassLoader == null) {
+ singleClassLoader = new SingleClassLoader();
+ nextID = 0;
+ }
+ id = nextID++;
+ }
+ String className = "nextedvm.runtimecompiled_" + id;
System.err.println("RuntimeCompiler: Building " + className);
+ String options = "nosupportcall";
+ if(extraoptions != null) options += "," + extraoptions;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ClassFileCompiler c = new ClassFileCompiler(data,className,baos);
- // FEATURE: make this Optional, pass options on compile arguments
- c.parseOptions("unixruntime,nosupportcall,maxinsnpermethod=512");
+ c.parseOptions(options);
c.go();
baos.close();
byte[] bytecode = baos.toByteArray();
public byte type;
public byte binding;
public byte other;
+ public short shndx;
public SHeader sheader;
public final static int STT_FUNC = 2;
type = (byte)(info&0xf);
binding = (byte)(info>>4);
other = readByte();
- // FEATURE: This should point to some other entry or something
- readShort();
+ shndx = readShort();
}
}