From: <mic...@us...> - 2007-08-11 11:29:13
|
Revision: 163 http://pearcolator.svn.sourceforge.net/pearcolator/?rev=163&view=rev Author: michael_baer Date: 2007-08-11 04:28:50 -0700 (Sat, 11 Aug 2007) Log Message: ----------- - Fixed bugs with Lazy Evaluation - Added option to determine ARM inlining behaviour Modified Paths: -------------- src/org/binarytranslator/DBT.java src/org/binarytranslator/DBT_Options.java src/org/binarytranslator/Main.java src/org/binarytranslator/arch/arm/decoder/ARM2IR.java src/org/binarytranslator/arch/arm/decoder/ARM_Instructions.java src/org/binarytranslator/arch/arm/decoder/ARM_Interpreter.java src/org/binarytranslator/arch/arm/decoder/ARM_Options.java src/org/binarytranslator/arch/arm/decoder/ARM_Translator.java src/org/binarytranslator/generic/decoder/CodeTranslator.java Modified: src/org/binarytranslator/DBT.java =================================================================== --- src/org/binarytranslator/DBT.java 2007-08-08 10:22:45 UTC (rev 162) +++ src/org/binarytranslator/DBT.java 2007-08-11 11:28:50 UTC (rev 163) @@ -17,7 +17,7 @@ */ public final class DBT { /** Should the following assertion be checked? */ - public static final boolean VerifyAssertions = true; + public static final boolean VerifyAssertions = VM.VerifyAssertions; /** * Assert the following condition is true, if false then fail with stack trace Modified: src/org/binarytranslator/DBT_Options.java =================================================================== --- src/org/binarytranslator/DBT_Options.java 2007-08-08 10:22:45 UTC (rev 162) +++ src/org/binarytranslator/DBT_Options.java 2007-08-11 11:28:50 UTC (rev 163) @@ -25,7 +25,7 @@ public final static boolean buildForSunVM = false; /** Enable the profiling of application during interpretation? */ - public final static boolean profileDuringInterpretation = true; + public final static boolean profileDuringInterpretation = false; /** Debug binary loading */ public final static boolean debugLoader = true; @@ -182,8 +182,10 @@ private static void parseArmOption(String key, String value) { if (key.equalsIgnoreCase("optimizeByProfiling")) { ARM_Options.optimizeTranslationByProfiling = Boolean.parseBoolean(value); - } else if (key.equalsIgnoreCase("flagBehaviour")) { - ARM_Options.flagBehaviour = ARM_Options.FlagBehaviour.valueOf(value); + } else if (key.equalsIgnoreCase("flagEvaluation")) { + ARM_Options.flagEvaluation = ARM_Options.FlagBehaviour.valueOf(value); + } else if (key.equalsIgnoreCase("inlining")) { + ARM_Options.inlining = ARM_Options.InliningBehaviour.valueOf(value); } else { throw new Error("Unknown ARM option: " + key); Modified: src/org/binarytranslator/Main.java =================================================================== --- src/org/binarytranslator/Main.java 2007-08-08 10:22:45 UTC (rev 162) +++ src/org/binarytranslator/Main.java 2007-08-11 11:28:50 UTC (rev 163) @@ -105,7 +105,7 @@ //on SUN's VM, only the interpreter has been tested if (DBT_Options.buildForSunVM) { - DBT_Options.executionController = ExecutionController.Type.StagedEmulation; + DBT_Options.executionController = ExecutionController.Type.Interpreter; } //load a previously saved branch profile from file, if the user requested it Modified: src/org/binarytranslator/arch/arm/decoder/ARM2IR.java =================================================================== --- src/org/binarytranslator/arch/arm/decoder/ARM2IR.java 2007-08-08 10:22:45 UTC (rev 162) +++ src/org/binarytranslator/arch/arm/decoder/ARM2IR.java 2007-08-11 11:28:50 UTC (rev 163) @@ -9,6 +9,7 @@ import org.binarytranslator.arch.arm.os.process.ARM_ProcessSpace; import org.binarytranslator.arch.arm.os.process.ARM_Registers; import org.binarytranslator.arch.arm.os.process.ARM_Registers.OperatingMode; +import org.binarytranslator.generic.branchprofile.BranchProfile.BranchType; import org.binarytranslator.generic.decoder.CodeTranslator; import org.binarytranslator.generic.decoder.Laziness; import org.binarytranslator.vmInterface.DBT_Trace; @@ -143,17 +144,17 @@ super(context, trace); translator = new ARM_Translator((ARM_ProcessSpace)ps, this); - switch (ARM_Options.flagBehaviour) { - case ImmediateEvaluation: + switch (ARM_Options.flagEvaluation) { + case Immediate: flagBehavior = new ARM_ImmediateFlagBehavior(); break; - case LazyEvaluation: + case Lazy: flagBehavior = new ARM_LazyFlagBehavior(); break; default: - throw new RuntimeException("Unexpected flag behaviour: " + ARM_Options.flagBehaviour); + throw new RuntimeException("Unexpected flag behaviour: " + ARM_Options.flagEvaluation); } } @@ -409,7 +410,6 @@ @Override public void onFlagRead(Flag flag, ARM_Laziness lazy) { resolveFlag(flag, lazy); - } @Override @@ -463,6 +463,32 @@ return result; } + @Override + protected boolean inlineBranchInstruction(int targetPc, UnresolvedJumpInstruction jump) { + + switch (ARM_Options.inlining) + { + case Default: + return super.inlineBranchInstruction(targetPc, jump); + + case DynamicJumps: + if (jump.type == BranchType.INDIRECT_BRANCH) + return true; + else + return super.inlineBranchInstruction(targetPc, jump); + + case Functions: + if (jump.type == BranchType.CALL || jump.type == BranchType.RETURN) + return true; + else + return super.inlineBranchInstruction(targetPc, jump); + + default: + throw new RuntimeException("Unexpected inlining type."); + } + + } + /** * Returns a RegisterOperand that contains a reference to the currently used ARM_Registers instance. * Use this reference when calling functions on ARM_Registers. @@ -648,18 +674,20 @@ } public void appendLogicalFlags(ARM_Laziness lazy, OPT_Operand result) { + zeroUsed = negativeUsed = true; flagBehavior.appendLogicalFlags(lazy, result); } public void appendSubFlags(ARM_Laziness lazy, OPT_Operand result, OPT_Operand op1, OPT_Operand op2) { + zeroUsed = negativeUsed = carryUsed = overflowUsed = true; flagBehavior.appendSubFlags(lazy, result, op1, op2); } public void appendAddFlags(ARM_Laziness lazy, OPT_Operand result, OPT_Operand op1, OPT_Operand op2) { + zeroUsed = negativeUsed = carryUsed = overflowUsed = true; flagBehavior.appendAddFlags(lazy, result, op1, op2); } - - + @Override protected OPT_Register[] getUnusedRegisters() { Modified: src/org/binarytranslator/arch/arm/decoder/ARM_Instructions.java =================================================================== --- src/org/binarytranslator/arch/arm/decoder/ARM_Instructions.java 2007-08-08 10:22:45 UTC (rev 162) +++ src/org/binarytranslator/arch/arm/decoder/ARM_Instructions.java 2007-08-11 11:28:50 UTC (rev 163) @@ -1026,7 +1026,7 @@ public LongMultiply(int instr) { super(instr); - unsigned = Utils.getBit(instr, 22); + unsigned = !Utils.getBit(instr, 22); updateConditionCodes = Utils.getBit(instr, 20); accumulate = Utils.getBit(instr, 21); RdHigh = (byte) Utils.getBits(instr, 16, 19); Modified: src/org/binarytranslator/arch/arm/decoder/ARM_Interpreter.java =================================================================== --- src/org/binarytranslator/arch/arm/decoder/ARM_Interpreter.java 2007-08-08 10:22:45 UTC (rev 162) +++ src/org/binarytranslator/arch/arm/decoder/ARM_Interpreter.java 2007-08-11 11:28:50 UTC (rev 163) @@ -1375,8 +1375,8 @@ //get rid of the signs, if we're supposed to do unsigned multiplication if (i.unsigned) { - operand1 &= 0xFFFFFFFF; - operand2 &= 0xFFFFFFFF; + operand1 &= (long)0xFFFFFFFFL; + operand2 &= (long)0xFFFFFFFFL; } // calculate the result @@ -1385,7 +1385,7 @@ if (i.accumulate) { //treat the register as an unsigned value long operand = regs.get(i.getRdLow()); - operand &= 0xFFFFFFFF; + operand &= 0xFFFFFFFFL; result += operand; result += regs.get(i.getRdHigh()) << 32; Modified: src/org/binarytranslator/arch/arm/decoder/ARM_Options.java =================================================================== --- src/org/binarytranslator/arch/arm/decoder/ARM_Options.java 2007-08-08 10:22:45 UTC (rev 162) +++ src/org/binarytranslator/arch/arm/decoder/ARM_Options.java 2007-08-11 11:28:50 UTC (rev 163) @@ -3,10 +3,16 @@ public class ARM_Options { public enum FlagBehaviour { - LazyEvaluation, - ImmediateEvaluation + Lazy, + Immediate } + public enum InliningBehaviour { + Default, + Functions, + DynamicJumps + } + /** Set to true to enable a fastpath for the decoding of data processing instructions.. */ public final static boolean DATAPROCESSING_DECODER_FASTPATH = false; @@ -14,5 +20,7 @@ public static boolean optimizeTranslationByProfiling = false; /** This variable describes, if the translated program shall be optimized using lazy evaluation.*/ - public static FlagBehaviour flagBehaviour = FlagBehaviour.LazyEvaluation; + public static FlagBehaviour flagEvaluation = FlagBehaviour.Lazy; + + public static InliningBehaviour inlining = InliningBehaviour.Default; } Modified: src/org/binarytranslator/arch/arm/decoder/ARM_Translator.java =================================================================== --- src/org/binarytranslator/arch/arm/decoder/ARM_Translator.java 2007-08-08 10:22:45 UTC (rev 162) +++ src/org/binarytranslator/arch/arm/decoder/ARM_Translator.java 2007-08-11 11:28:50 UTC (rev 163) @@ -92,6 +92,9 @@ else instr = ARM_InstructionDecoder.ARM32.decode(instruction, translatorFactory); + if (DBT_Options.debugTranslation) + System.out.println("Translating instruction: " + ARM_Disassembler.disassemble(pc, ps).asString() + " at 0x" + Integer.toHexString(pc)); + if (instr.getCondition() != Condition.AL) { instr = new ConditionalDecorator(instr); } @@ -1327,24 +1330,27 @@ public void translate() { OPT_Operand operand1 = resolveOperand1(); - OPT_Operand operand2 = resolveOperand2(); + OPT_Operand originalOperand2 = resolveOperand2(); OPT_RegisterOperand result = getResultRegister(); OPT_BasicBlock addWithoutCarry = arm2ir.createBlockAfterCurrent(); OPT_BasicBlock addWithCarry = arm2ir.createBlockAfterCurrentNotInCFG(); + + OPT_RegisterOperand operand2 = arm2ir.getTempInt(0); + arm2ir.appendInstruction(Move.create(INT_MOVE, operand2, originalOperand2)); //Is the carry set at all? if not, just jump to addWithoutCarry - arm2ir.appendInstruction(Binary.create(INT_ADD, result, operand1, operand2)); arm2ir.appendInstruction(IfCmp.create(INT_IFCMP, arm2ir.getTempValidation(0), arm2ir.readCarryFlag(lazy), new OPT_IntConstantOperand(0), OPT_ConditionOperand.EQUAL(), addWithoutCarry.makeJumpTarget(), new OPT_BranchProfileOperand())); arm2ir.getCurrentBlock().insertOut(addWithCarry); //Yes, the carry flag is set. Pre-increase the result by one to account for the carry. arm2ir.setCurrentBlock(addWithCarry); - arm2ir.appendInstruction(Binary.create(INT_ADD, result.copyRO(), result.copy(), new OPT_IntConstantOperand(1))); + arm2ir.appendInstruction(Binary.create(INT_ADD, operand2.copyRO(), operand2.copy(), new OPT_IntConstantOperand(1))); addWithCarry.insertOut(addWithoutCarry); //Finally, add the second operands to the result arm2ir.setCurrentBlock(addWithoutCarry); + arm2ir.appendInstruction(Binary.create(INT_ADD, result, operand1, operand2.copy())); setAddResult(result, operand1, operand2); } } @@ -1358,24 +1364,27 @@ public void translate() { OPT_Operand operand1 = resolveOperand1(); - OPT_Operand operand2 = resolveOperand2(); + OPT_Operand originalOperand2 = resolveOperand2(); OPT_RegisterOperand result = getResultRegister(); OPT_BasicBlock subWithoutCarry = arm2ir.createBlockAfterCurrent(); OPT_BasicBlock subWithCarry = arm2ir.createBlockAfterCurrentNotInCFG(); + + OPT_RegisterOperand operand2 = arm2ir.getTempInt(0); + arm2ir.appendInstruction(Move.create(INT_MOVE, operand2, originalOperand2)); //Is the carry set? if yes, just jump to subWithoutCarry - arm2ir.appendInstruction(Binary.create(INT_SUB, result, operand1, operand2)); arm2ir.appendInstruction(IfCmp.create(INT_IFCMP, arm2ir.getTempValidation(0), arm2ir.readCarryFlag(lazy), new OPT_IntConstantOperand(1), OPT_ConditionOperand.EQUAL(), subWithoutCarry.makeJumpTarget(), new OPT_BranchProfileOperand())); arm2ir.getCurrentBlock().insertOut(subWithCarry); //No, the carry flag is not set. That means, we have to use the carry within the subtraction (weird arm logic). arm2ir.setCurrentBlock(subWithCarry); - arm2ir.appendInstruction(Binary.create(INT_SUB, result.copyRO(), result.copy(), new OPT_IntConstantOperand(1))); + arm2ir.appendInstruction(Binary.create(INT_ADD, operand2.copyRO(), operand2.copy(), new OPT_IntConstantOperand(1))); subWithCarry.insertOut(subWithoutCarry); //Finally, subtract the second operands from the result arm2ir.setCurrentBlock(subWithoutCarry); + arm2ir.appendInstruction(Binary.create(INT_SUB, result, operand1, operand2.copy())); setSubResult(result, operand1, operand2); } } @@ -1846,7 +1855,7 @@ } public int getSuccessor(int pc) { - if (i.offset.getType() == OperandWrapper.Type.Immediate) + if (i.offset.getType() == OperandWrapper.Type.Immediate && !i.link) return readPC() + i.getOffset().getImmediate(); else return -1; @@ -1993,8 +2002,8 @@ if (i.unsigned) { //treat the original ints as unsigned, so get rid of the signs for the longs - arm2ir.appendInstruction(Binary.create(LONG_AND, operand1.copyRO(), operand1.copy(), new OPT_LongConstantOperand(0xFFFFFFFF))); - arm2ir.appendInstruction(Binary.create(LONG_AND, operand2.copyRO(), operand2.copy(), new OPT_LongConstantOperand(0xFFFFFFFF))); + arm2ir.appendInstruction(Binary.create(LONG_AND, operand1.copyRO(), operand1.copy(), new OPT_LongConstantOperand(0xFFFFFFFFL))); + arm2ir.appendInstruction(Binary.create(LONG_AND, operand2.copyRO(), operand2.copy(), new OPT_LongConstantOperand(0xFFFFFFFFL))); } //multiply the two operands @@ -2005,7 +2014,7 @@ OPT_Operand operand3 = arm2ir.getRegister(i.getRdLow()); OPT_RegisterOperand tmp = arm2ir.getTempLong(0); arm2ir.appendInstruction(Unary.create(INT_2LONG, tmp, operand3)); - arm2ir.appendInstruction(Binary.create(LONG_AND, tmp.copyRO(), tmp.copy(), new OPT_LongConstantOperand(0xFFFFFFFF))); + arm2ir.appendInstruction(Binary.create(LONG_AND, tmp.copyRO(), tmp.copy(), new OPT_LongConstantOperand(0xFFFFFFFFL))); arm2ir.appendInstruction(Binary.create(LONG_ADD, result.copyRO(), result.copy(), tmp.copy())); operand3 = arm2ir.getRegister(i.getRdHigh()); @@ -2013,6 +2022,10 @@ arm2ir.appendInstruction(Binary.create(LONG_SHL, tmp.copyRO(), tmp.copy(), new OPT_IntConstantOperand(32))); arm2ir.appendInstruction(Binary.create(INT_ADD, result.copyRO(), result.copy(), operand3.copy())); } + + arm2ir.appendInstruction(Unary.create(LONG_2INT, arm2ir.getRegister(i.getRdLow()) ,result.copy())); + arm2ir.appendInstruction(Binary.create(LONG_SHR, result.copyRO(), result.copy(), new OPT_IntConstantOperand(32))); + arm2ir.appendInstruction(Unary.create(LONG_2INT, arm2ir.getRegister(i.getRdHigh()) ,result.copy())); if (i.updateConditionCodes) { //set the negative flag @@ -2054,10 +2067,10 @@ //do we have to transfer the saved or the current PSR? if (i.transferSavedPSR) { - call = createCallToRegisters("getSPSR", "()V", 0); + call = createCallToRegisters("getSPSR", "()I", 0); } else { - call = createCallToRegisters("getCPSR", "()V", 0); + call = createCallToRegisters("getCPSR", "()I", 0); } Call.setResult(call, psrValue); Modified: src/org/binarytranslator/generic/decoder/CodeTranslator.java =================================================================== --- src/org/binarytranslator/generic/decoder/CodeTranslator.java 2007-08-08 10:22:45 UTC (rev 162) +++ src/org/binarytranslator/generic/decoder/CodeTranslator.java 2007-08-11 11:28:50 UTC (rev 163) @@ -165,7 +165,7 @@ /** This class stores information about a jump instruction within the current trace, whose * target has not yet been resolved. */ - private final static class UnresolvedJumpInstruction { + protected final static class UnresolvedJumpInstruction { /** A reference to the jump instruction within the code. This is either a GOTO or SWITCH instruction. */ public final OPT_Instruction instruction; @@ -306,6 +306,10 @@ // Move currentBlock along currentBlock = nextBlock; } else { + + if (DBT_Options.debugTranslation) + System.out.println("Translating subtrace for 0x" + Integer.toHexString(pc)); + do { if (DBT.VerifyAssertions) DBT._assert(currentBlock.getNumberOfRealInstructions() == 0); @@ -351,6 +355,9 @@ break; } } while (pc != -1); + + if (DBT_Options.debugTranslation) + System.out.println("Done translating subtrace."); } } @@ -608,7 +615,7 @@ // serves more as a placeholder and might be mutated later on. appendInstruction(branch); UnresolvedJumpInstruction unresolvedJump = new UnresolvedJumpInstruction( - branch, (Laziness) targetLaziness.clone(), currentPC, targetPC, BranchType.CALL); + branch, (Laziness) targetLaziness.clone(), currentPC, targetPC, branchType); unresolvedDirectBranches.add(unresolvedJump); switch (branchType) { @@ -753,9 +760,17 @@ DBT_Trace compiledTrace = ps.codeCache.tryGet(targetPc); - return DBT_Options.singleInstrTranslation == false - && (compiledTrace == null || compiledTrace.getNumberOfInstructions() > 30) && !shallTraceStop() + boolean decision = DBT_Options.singleInstrTranslation == false + && (compiledTrace == null || compiledTrace.getNumberOfInstructions() < 20) && !shallTraceStop() && jump.type != BranchType.CALL && jump.type != BranchType.RETURN; + + if (DBT_Options.debugBranchResolution) { + String text = (!decision ? "Not inlining " : "Inlining "); + text += jump.type + " to 0x" + Integer.toHexString(targetPc); + System.out.println(text); + } + + return decision; } /** @@ -782,21 +797,19 @@ // precompiled target if (targetBB != null) return targetBB; - + + if (currentBlock.getNumberOfRealInstructions() != 0) { + currentBlock = createBlockAfterCurrentNotInCFG(); + } + if (!inlineBranchInstruction(targetPc, jump)) { - // Just exit the trace and continue at the target address in a new trace - if (currentBlock.getNumberOfRealInstructions() != 0) { - currentBlock = createBlockAfterCurrentNotInCFG(); - - if (DBT_Options.debugBranchResolution) - System.out.println("Resolving branch to next block."); - } - + //Just exit the trace and continue at the target address in a new trace targetBB = currentBlock; appendTraceExit(jump.lazyStateAtJump, new OPT_IntConstantOperand(targetPc)); registerMapping(targetPc, jump.lazyStateAtJump, targetBB); - } else { + } + else { // Otherwise we will translate the jump into the trace translateSubTrace((Laziness) jump.lazyStateAtJump.clone(), targetPc); targetBB = findMapping(targetPc, jump.lazyStateAtJump); @@ -1299,7 +1312,9 @@ */ public void appendInterpretedInstruction(int pc, Laziness lazy) { - resolveLaziness(lazy); + appendThrowBadInstruction(lazy, pc); + +/* resolveLaziness(lazy); spillAllRegisters(); // Prepare a local variable of type Interpreter @@ -1313,7 +1328,7 @@ VM_MethodReference getInterpreterMethodRef = (VM_MethodReference) VM_MemberReference .findOrCreate(psTref, VM_Atom .findOrCreateAsciiAtom("createInstructionInterpreter"), VM_Atom - .findOrCreateAsciiAtom("()A")); + .findOrCreateAsciiAtom("()Lorg.binarytranslator.generic.decoder.Interpreter;")); VM_Method getInterpreterMethod = getInterpreterMethodRef .resolveInterfaceMethod(); @@ -1345,7 +1360,7 @@ VM_MethodReference decodeMethodRef = (VM_MethodReference) VM_MemberReference .findOrCreate(interpreterTypeRef, VM_Atom .findOrCreateAsciiAtom("decode"), VM_Atom - .findOrCreateAsciiAtom("(I)A")); + .findOrCreateAsciiAtom("(I)Lorg.binarytranslator.generic.decoder.Interpreter.Instruction;")); VM_Method decodeMethod = decodeMethodRef.resolveInterfaceMethod(); methOp = OPT_MethodOperand.INTERFACE(decodeMethodRef, decodeMethod); @@ -1385,7 +1400,7 @@ appendCustomCall(s); // Fill all registers again following interpreted instruction - fillAllRegisters(); + fillAllRegisters();*/ } /** Get the method */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |