|
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.
|