X-Git-Url: http://git.megacz.com/?p=nestedvm.git;a=blobdiff_plain;f=src%2Forg%2Fibex%2Fnestedvm%2FClassFileCompiler.java;h=f0b9153f7e0ee2edda35a0fe7338024cd7a990f7;hp=0c4dd67a25f78fd1b25f509510fc671181e11ace;hb=abe7c48fc6762412703430702e60db9cd834b55a;hpb=034a42fa65955289442614ef9914e5474fac62aa diff --git a/src/org/ibex/nestedvm/ClassFileCompiler.java b/src/org/ibex/nestedvm/ClassFileCompiler.java index 0c4dd67..f0b9153 100644 --- a/src/org/ibex/nestedvm/ClassFileCompiler.java +++ b/src/org/ibex/nestedvm/ClassFileCompiler.java @@ -1,6 +1,8 @@ package org.ibex.nestedvm; import java.io.*; +import java.util.Hashtable; + import org.ibex.nestedvm.util.*; import org.apache.bcel.generic.*; @@ -45,7 +47,7 @@ public class ClassFileCompiler extends Compiler implements org.apache.bcel.Const // Handy wrappers around the BCEL functions private InstructionList insnList; - private void selectMethod(MethodGen m) { insnList = m.getInstructionList(); } + private void selectMethod(MethodGen m) { insnList = m.getInstructionList(); } private void selectList(InstructionList l) { insnList = l; } private InstructionHandle a(Instruction i) { return insnList.append(i); } private BranchHandle a(BranchInstruction i) { return insnList.append(i); } @@ -148,7 +150,7 @@ public class ClassFileCompiler extends Compiler implements org.apache.bcel.Const a(InstructionConstants.IUSHR); int beg = text.addr >>> methodShift; - int end = ((text.addr + text.size) >>> methodShift); + int end = ((text.addr + text.size + maxBytesPerMethod - 1) >>> methodShift); // This data is redundant but BCEL wants it int[] matches = new int[end-beg]; @@ -263,8 +265,9 @@ public class ClassFileCompiler extends Compiler implements org.apache.bcel.Const a(fac.createCheckCast(new ObjectType("java.lang.Integer"))); a(fac.createInvoke("java.lang.Integer","intValue",Type.INT,Type.NO_ARGS,INVOKEVIRTUAL)); a(InstructionConstants.IRETURN); - bh.setTarget(a(InstructionConstants.ICONST_M1)); - a(InstructionConstants.IRETURN); + bh.setTarget(a(InstructionConstants.POP)); + a(InstructionConstants.ICONST_M1); + a(InstructionConstants.IRETURN); lookupSymbol.setMaxLocals(); lookupSymbol.setMaxStack(); cl.addMethod(lookupSymbol.getMethod()); @@ -360,12 +363,20 @@ public class ClassFileCompiler extends Compiler implements org.apache.bcel.Const cl.addMethod(getCPUState.getMethod()); - // FEATURE: Catch RuntimeException and turn it into a fault exception MethodGen execute = newMethod(ACC_PROTECTED,Type.VOID,Type.NO_ARGS,"_execute"); selectMethod(execute); - a(InstructionConstants.ALOAD_0); - a(fac.createInvoke(fullClassName,"trampoline",Type.VOID,Type.NO_ARGS,INVOKESPECIAL)); + InstructionHandle tryStart = a(InstructionConstants.ALOAD_0); + InstructionHandle tryEnd = a(fac.createInvoke(fullClassName,"trampoline",Type.VOID,Type.NO_ARGS,INVOKESPECIAL)); a(InstructionConstants.RETURN); + + InstructionHandle catchInsn = a(InstructionConstants.ASTORE_1); + a(fac.createNew("org.ibex.nestedvm.Runtime$FaultException")); + a(InstructionConstants.DUP); + a(InstructionConstants.ALOAD_1); + a(fac.createInvoke("org.ibex.nestedvm.Runtime$FaultException","",Type.VOID,new Type[]{new ObjectType("java.lang.RuntimeException")},INVOKESPECIAL)); + a(InstructionConstants.ATHROW); + + execute.addExceptionHandler(tryStart,tryEnd,catchInsn,new ObjectType("java.lang.RuntimeException")); execute.setMaxLocals(); execute.setMaxStack(); cl.addMethod(execute.getMethod()); @@ -380,21 +391,23 @@ public class ClassFileCompiler extends Compiler implements org.apache.bcel.Const a(InstructionConstants.ALOAD_0); if(unixRuntime) a(fac.createInvoke("org.ibex.nestedvm.UnixRuntime","runAndExec",Type.INT, - new Type[]{Type.getType("Lorg/ibex/nestedvm/UnixRuntime;"),Type.STRING,new ArrayType(Type.STRING,1)}, - INVOKESTATIC)); + new Type[]{Type.getType("Lorg/ibex/nestedvm/UnixRuntime;"),Type.STRING,new ArrayType(Type.STRING,1)}, + INVOKESTATIC)); else - a(fac.createInvoke(fullClassName,"run",Type.INT,new Type[]{Type.STRING,new ArrayType(Type.STRING,1)},INVOKEVIRTUAL)); + a(fac.createInvoke(fullClassName,"run",Type.INT,new Type[]{Type.STRING,new ArrayType(Type.STRING,1)},INVOKEVIRTUAL)); a(fac.createInvoke("java.lang.System","exit",Type.VOID,new Type[]{Type.INT},INVOKESTATIC)); a(InstructionConstants.RETURN); main.setMaxLocals(); main.setMaxStack(); cl.addMethod(main.getMethod()); + if(printStats) + System.out.println("Constant Pool Size: " + cp.getSize()); cl.getJavaClass().dump(os); } private void addConstReturnMethod(String name, int val) { - MethodGen method = newMethod(ACC_PROTECTED,Type.INT, Type.NO_ARGS,name); + MethodGen method = newMethod(ACC_PROTECTED,Type.INT, Type.NO_ARGS,name); selectMethod(method); pushConst(val); a(InstructionConstants.IRETURN); @@ -896,7 +909,7 @@ public class ClassFileCompiler extends Compiler implements org.apache.bcel.Const case 32: // ADD throw new Exn("ADD (add with oveflow trap) not suported"); case 33: // ADDU - preSetReg(R+rd); + preSetReg(R+rd); if(rt != 0 && rs != 0) { pushReg(R+rs); pushReg(R+rt); @@ -1007,7 +1020,7 @@ public class ClassFileCompiler extends Compiler implements org.apache.bcel.Const setReg(); break; default: - throw new RuntimeException("Illegal instruction 0/" + subcode); + throw new Exn("Illegal instruction 0/" + subcode); } break; } @@ -1048,7 +1061,7 @@ public class ClassFileCompiler extends Compiler implements org.apache.bcel.Const if(b1 == null) unreachable = true; break; default: - throw new RuntimeException("Illegal Instruction 1/" + rt); + throw new Exn("Illegal Instruction 1/" + rt); } break; } @@ -1063,22 +1076,10 @@ public class ClassFileCompiler extends Compiler implements org.apache.bcel.Const if(pc == -1) throw new Exn("pc modifying insn in delay slot"); int target = (pc&0xf0000000)|(jumpTarget << 2); emitInstruction(-1,nextInsn,-1); - if(optimizedMemcpy && (target == memcpy || target == memset)) { - a(InstructionConstants.ALOAD_0); - pushRegZ(R+4); - pushRegZ(R+5); - pushRegZ(R+6); - a(fac.createInvoke(fullClassName,target==memcpy ? "memcpy" : "memset", Type.VOID, new Type[]{Type.INT,Type.INT,Type.INT},INVOKEVIRTUAL)); - preSetReg(R+2); - pushReg(R+4); - setReg(); - branch(pc,pc+8); - } else { - preSetReg(R+RA); - pushConst(pc+8); - setReg(); - branch(pc, target); - } + preSetReg(R+RA); + pushConst(pc+8); + setReg(); + branch(pc, target); unreachable = true; break; } @@ -1138,7 +1139,8 @@ public class ClassFileCompiler extends Compiler implements org.apache.bcel.Const a(InstructionConstants.I2L); pushConst(0xffffffffL); a(InstructionConstants.LAND); - pushConst((long)unsignedImmediate); + // Yes, this is correct, you have to sign extend the immediate then do an UNSIGNED comparison + pushConst(signedImmediate&0xffffffffL); a(InstructionConstants.LCMP); b1 = a(InstructionFactory.createBranchInstruction(IFLT,null)); @@ -1233,7 +1235,7 @@ public class ClassFileCompiler extends Compiler implements org.apache.bcel.Const pushDouble(F+fs,d); pushDouble(F+ft,d); a(d ? InstructionConstants.DSUB : InstructionConstants.FSUB); - setDouble(d); + setDouble(d); break; case 2: // MUL.X preSetDouble(F+fd,d); @@ -1276,26 +1278,28 @@ public class ClassFileCompiler extends Compiler implements org.apache.bcel.Const pushReg(F+fs); setReg(); - preSetReg(F+fd+1); - pushReg(F+fs+1); - setReg(); + if(d) { + preSetReg(F+fd+1); + pushReg(F+fs+1); + setReg(); + } break; case 7: // NEG.X preSetDouble(F+fd,d); pushDouble(F+fs,d); a(d ? InstructionConstants.DNEG : InstructionConstants.FNEG); - setDouble(d); + setDouble(d); break; case 32: // CVT.S.X preSetFloat(F+fd); - pushDouble(F+fd,d); + pushDouble(F+fs,d); if(d) a(InstructionConstants.D2F); setFloat(); break; case 33: // CVT.D.X preSetDouble(F+fd); - pushDouble(F+fd,d); + pushDouble(F+fs,d); if(!d) a(InstructionConstants.F2D); setDouble(); break; @@ -1355,7 +1359,7 @@ public class ClassFileCompiler extends Compiler implements org.apache.bcel.Const case 62: b1 = a(InstructionFactory.createBranchInstruction(IFLE,null)); break; default: b1 = null; } - + // FIXME: We probably don't need to pushConst(0x00000) pushConst(0x000000); b2 = a(InstructionFactory.createBranchInstruction(GOTO,null)); b1.setTarget(pushConst(0x800000)); @@ -1720,7 +1724,7 @@ public class ClassFileCompiler extends Compiler implements org.apache.bcel.Const memWrite(); break; } - // FEATURE: This need to be atomic if we ever support threads (see SWC0/SC) + // This need to be atomic if we ever support threads (see SWC0/SC) case 48: // LWC0/LL preSetReg(R+rt); memRead(R+rs,signedImmediate); @@ -1733,7 +1737,7 @@ public class ClassFileCompiler extends Compiler implements org.apache.bcel.Const setReg(); break; - /* FEATURE: This needs to fail (set rt to 0) if the memory location was modified + /* This needs to fail (set rt to 0) if the memory location was modified * between the LL and SC if we every support threads. */ case 56: // SWC0/SC @@ -1809,18 +1813,34 @@ public class ClassFileCompiler extends Compiler implements org.apache.bcel.Const } } - private String regField(int reg) { - String field; + private static final String[] regField = { + "r0","r1","r2","r3","r4","r5","r6","r7", + "r8","r9","r10","r11","r12","r13","r14","r15", + "r16","r17","r18","r19","r20","r21","r22","r23", + "r24","r25","r26","r27","r28","r29","r30","r31", + + "f0","f1","f2","f3","f4","f5","f6","f7", + "f8","f9","f10","f11","f12","f13","f14","f15", + "f16","f17","f18","f19","f20","f21","f22","f23", + "f24","f25","f26","f27","f28","f29","f30","f31", + + "hi","lo","fcsr" + }; + + private static String regField(int reg) { + return regField[reg]; + + /*String field; switch(reg) { case HI: field = "hi"; break; case LO: field = "lo"; break; case FCSR: field = "fcsr"; break; default: - if(reg > R && reg < R+32) field="r"+(reg-R); - else if(reg >= F && reg < F+32) field="f"+(reg-F); + if(reg > R && reg < R+32) regFieldR[reg-R]; + else if(reg >= F && reg < F+32) return regFieldF[ else throw new IllegalArgumentException(""+reg); } - return field; + return field;*/ } private boolean doLocal(int reg) { @@ -1942,9 +1962,12 @@ public class ClassFileCompiler extends Compiler implements org.apache.bcel.Const return h; } + private Hashtable intCache = new Hashtable(); + private InstructionHandle pushConst(int n) { - if(n >= 0 && n <= 5) { + if(n >= -1 && n <= 5) { switch(n) { + case -1: return a(InstructionConstants.ICONST_M1); case 0: return a(InstructionConstants.ICONST_0); case 1: return a(InstructionConstants.ICONST_1); case 2: return a(InstructionConstants.ICONST_2); @@ -1953,8 +1976,6 @@ public class ClassFileCompiler extends Compiler implements org.apache.bcel.Const case 5: return a(InstructionConstants.ICONST_5); default: return null; } - } else if(n == -1) { - return a(InstructionConstants.ICONST_M1); } else if(n >= -128 && n <= 127) { return a(new BIPUSH((byte) n)); } else if(n >= -32768 && n <= 32767) {