X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Forg%2Fibex%2Fnestedvm%2FClassFileCompiler.java;h=b799beba6ff0c4cddeb4d2ec37f16644a81b7707;hb=119cb20e2b9d594032653c8464717b1420b6abc7;hp=0d48aba70bd8e05c535ce793a0cabeca584b3f13;hpb=c2b2704764af1ade923ba8f15d517b87f9d16189;p=nestedvm.git diff --git a/src/org/ibex/nestedvm/ClassFileCompiler.java b/src/org/ibex/nestedvm/ClassFileCompiler.java index 0d48aba..b799beb 100644 --- a/src/org/ibex/nestedvm/ClassFileCompiler.java +++ b/src/org/ibex/nestedvm/ClassFileCompiler.java @@ -45,7 +45,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); } @@ -79,7 +79,7 @@ public class ClassFileCompiler extends Compiler implements org.apache.bcel.Const if(!pruneCases) throw new Exn("-o prunecases MUST be enabled for ClassFileCompiler"); // Class - cl = new ClassGen(fullClassName,runtimeClass,source,ACC_SUPER|ACC_PUBLIC,null); + cl = new ClassGen(fullClassName,runtimeClass,source,ACC_SUPER|ACC_PUBLIC|ACC_FINAL,null); cp = cl.getConstantPool(); fac = new InstructionFactory(cl,cp); @@ -151,11 +151,11 @@ public class ClassFileCompiler extends Compiler implements org.apache.bcel.Const int end = ((text.addr + text.size) >>> methodShift); // This data is redundant but BCEL wants it - int[] matches = new int[end-beg]; - for(int i=beg;i"); selectMethod(init); - // Constructor a(InstructionConstants.ALOAD_0); pushConst(pageSize); pushConst(totalPages); - pushConst(fastMem ? 0 : 1); - a(fac.createInvoke(runtimeClass,"",Type.VOID,new Type[]{Type.INT,Type.INT,Type.BOOLEAN},INVOKESPECIAL)); - a(InstructionConstants.ALOAD_0); - pushConst(gp.addr); - a(fac.createFieldAccess(fullClassName,"gp",Type.INT, PUTFIELD)); - - a(InstructionConstants.ALOAD_0); - pushConst(elf.header.entry); - a(fac.createFieldAccess(fullClassName,"entryPoint",Type.INT, PUTFIELD)); - - a(InstructionConstants.ALOAD_0); - pushConst(onePage ? ((highestAddr+4095)&~4095) : ((highestAddr+pageSize-1)&~(pageSize-1))); - a(fac.createFieldAccess(fullClassName,"brkAddr",Type.INT, PUTFIELD)); + a(fac.createInvoke(runtimeClass,"",Type.VOID,new Type[]{Type.INT,Type.INT},INVOKESPECIAL)); - if(userInfo != null) { - a(InstructionConstants.ALOAD_0); - pushConst(userInfo.addr); - a(fac.createFieldAccess(fullClassName,"userInfoBase",Type.INT, PUTFIELD)); - a(InstructionConstants.ALOAD_0); - pushConst(userInfo.size); - a(fac.createFieldAccess(fullClassName,"userInfoSize",Type.INT, PUTFIELD)); - } a(initExtras); - a(InstructionConstants.ALOAD_0); - pushConst(Runtime.INITIALIZED); - a(fac.createFieldAccess(fullClassName,"state",Type.INT, PUTFIELD)); + a(InstructionConstants.RETURN); + init.setMaxLocals(); init.setMaxStack(); cl.addMethod(init.getMethod()); + MethodGen clinit = newMethod(ACC_PRIVATE|ACC_STATIC,Type.VOID, Type.NO_ARGS, ""); selectMethod(clinit); a(clinitExtras); @@ -318,18 +308,14 @@ public class ClassFileCompiler extends Compiler implements org.apache.bcel.Const a(InstructionConstants.ALOAD_1); a(fac.createFieldAccess("org.ibex.nestedvm.Runtime$CPUState","pc",Type.INT,GETFIELD)); a(fac.createFieldAccess(fullClassName,"pc",Type.INT, PUTFIELD)); + a(InstructionConstants.RETURN); setCPUState.setMaxLocals(); setCPUState.setMaxStack(); cl.addMethod(setCPUState.getMethod()); - MethodGen getCPUState = newMethod(ACC_PROTECTED,Type.getType("Lorg/ibex/nestedvm/Runtime$CPUState;"),Type.NO_ARGS,"getCPUState"); + MethodGen getCPUState = newMethod(ACC_PROTECTED,Type.VOID,new Type[]{Type.getType("Lorg/ibex/nestedvm/Runtime$CPUState;")},"getCPUState"); selectMethod(getCPUState); - a(fac.createNew("org.ibex.nestedvm.Runtime$CPUState")); - a(InstructionConstants.DUP); - a(fac.createInvoke("org.ibex.nestedvm.Runtime$CPUState","",Type.VOID,Type.NO_ARGS,INVOKESPECIAL)); - a(InstructionConstants.ASTORE_1); - a(InstructionConstants.ALOAD_1); a(fac.createFieldAccess("org.ibex.nestedvm.Runtime$CPUState","r",new ArrayType(Type.INT,1),GETFIELD)); a(InstructionConstants.ASTORE_2); @@ -368,8 +354,7 @@ public class ClassFileCompiler extends Compiler implements org.apache.bcel.Const a(fac.createFieldAccess(fullClassName,"pc",Type.INT, GETFIELD)); a(fac.createFieldAccess("org.ibex.nestedvm.Runtime$CPUState","pc",Type.INT,PUTFIELD)); - a(InstructionConstants.ALOAD_1); - a(InstructionConstants.ARETURN); + a(InstructionConstants.RETURN); getCPUState.setMaxLocals(); getCPUState.setMaxStack(); cl.addMethod(getCPUState.getMethod()); @@ -377,9 +362,18 @@ public class ClassFileCompiler extends Compiler implements org.apache.bcel.Const 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()); @@ -392,15 +386,32 @@ public class ClassFileCompiler extends Compiler implements org.apache.bcel.Const a(fac.createInvoke(fullClassName,"",Type.VOID,Type.NO_ARGS,INVOKESPECIAL)); a(new PUSH(cp,fullClassName)); a(InstructionConstants.ALOAD_0); - a(fac.createInvoke(fullClassName,"run",Type.INT,new Type[]{Type.STRING,new ArrayType(Type.STRING,1)},INVOKEVIRTUAL)); + 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)); + else + 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); + selectMethod(method); + pushConst(val); + a(InstructionConstants.IRETURN); + method.setMaxLocals(); + method.setMaxStack(); + cl.addMethod(method.getMethod()); + } private static int initDataCount; private void emitData(int addr, DataInputStream dis, int size, boolean readOnly) throws Exn,IOException { @@ -895,7 +906,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); @@ -1006,7 +1017,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; } @@ -1047,7 +1058,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; } @@ -1062,22 +1073,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; } @@ -1137,7 +1136,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)); @@ -1229,8 +1229,8 @@ public class ClassFileCompiler extends Compiler implements org.apache.bcel.Const break; case 1: // SUB.X preSetDouble(F+fd,d); - pushDouble(F+fs,d); pushDouble(F+ft,d); + pushDouble(F+fs,d); a(d ? InstructionConstants.DSUB : InstructionConstants.FSUB); setDouble(d); break; @@ -1719,7 +1719,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); @@ -1732,7 +1732,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