From: <mic...@us...> - 2007-05-17 16:31:40
|
Revision: 120 http://svn.sourceforge.net/pearcolator/?rev=120&view=rev Author: michael_baer Date: 2007-05-17 09:31:37 -0700 (Thu, 17 May 2007) Log Message: ----------- General changes to the dynamic translator: - Generalized & harmonized the set of functions used to build a trace - enabled the use of branch profiling for all ISAs - many code cleanups & refactorings ARM DBT changes: - Not returning from the trace on most branches - Using branch profiling - added support for more instruction types Modified Paths: -------------- src/org/binarytranslator/arch/arm/decoder/ARM2IR.java src/org/binarytranslator/arch/arm/decoder/ARM_Translator.java src/org/binarytranslator/arch/ppc/decoder/PPC2IR.java src/org/binarytranslator/arch/ppc/decoder/PPC_InstructionDecoder.java src/org/binarytranslator/arch/x86/decoder/X862IR.java src/org/binarytranslator/arch/x86/decoder/X86_DecodedOperand.java src/org/binarytranslator/arch/x86/decoder/X86_InstructionDecoder.java src/org/binarytranslator/arch/x86/decoder/X86_ModRM_Decoder.java src/org/binarytranslator/generic/branch/BranchLogic.java src/org/binarytranslator/generic/decoder/InstructionDecoder.java src/org/binarytranslator/generic/memory/CallBasedMemory.java src/org/binarytranslator/generic/memory/IntAddressedPreSwappedMemory.java src/org/binarytranslator/generic/memory/Memory.java src/org/binarytranslator/generic/os/process/ProcessSpace.java src/org/binarytranslator/vmInterface/DBT_Trace.java Added Paths: ----------- src/org/binarytranslator/generic/decoder/AbstractCodeTranslator.java src/org/binarytranslator/generic/os/abi/linux/filesystem/RemappingFilesystem.java Removed Paths: ------------- src/org/binarytranslator/generic/decoder/DecoderUtils.java src/org/binarytranslator/vmInterface/TranslationHelper.java Modified: src/org/binarytranslator/arch/arm/decoder/ARM2IR.java =================================================================== --- src/org/binarytranslator/arch/arm/decoder/ARM2IR.java 2007-05-16 18:16:21 UTC (rev 119) +++ src/org/binarytranslator/arch/arm/decoder/ARM2IR.java 2007-05-17 16:31:37 UTC (rev 120) @@ -7,7 +7,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.decoder.DecoderUtils; +import org.binarytranslator.generic.decoder.AbstractCodeTranslator; import org.binarytranslator.generic.decoder.Laziness; import org.jikesrvm.classloader.VM_Atom; import org.jikesrvm.classloader.VM_FieldReference; @@ -17,7 +17,7 @@ import org.jikesrvm.classloader.VM_TypeReference; import org.jikesrvm.compilers.opt.ir.*; -public class ARM2IR extends DecoderUtils implements OPT_HIRGenerator { +public class ARM2IR extends AbstractCodeTranslator implements OPT_HIRGenerator { /** Mapping of ARM registers to HIR registers */ private OPT_Register regMap[] = new OPT_Register[16]; @@ -128,7 +128,6 @@ if (DBT.VerifyAssertions) DBT._assert(registers_overflowFlag_Fref != null); } - public ARM2IR(OPT_GenerationContext context) { super(context); @@ -172,7 +171,7 @@ VM_FieldReference requestedMode_FieldReference = VM_FieldReference.findOrCreate(OperatingMode_TypeRef, VM_Atom.findOrCreateAsciiAtom(mode.name()), VM_Atom.findOrCreateAsciiAtom("Lorg/binarytranslator/arch/arm/os/process/ARM_Registers/OperatingMode;")).asFieldReference(); //Finally, use a getfield to grab the (static) member field - appendInstructionToCurrentBlock(GetField.create(GETFIELD, result, + appendInstruction(GetField.create(GETFIELD, result, null, new OPT_AddressConstantOperand(requestedMode_FieldReference .peekResolvedField().getOffset()), new OPT_LocationOperand( requestedMode_FieldReference), new OPT_TrueGuardOperand())); @@ -190,7 +189,7 @@ if (ps_registers == null) { ps_registersOp = gc.temps.makeTemp(registersTref); ps_registers = ps_registersOp.register; - appendInstructionToCurrentBlock(GetField.create(GETFIELD, ps_registersOp, + appendInstruction(GetField.create(GETFIELD, ps_registersOp, gc.makeLocal(1, psTref), new OPT_AddressConstantOperand(registersFref .peekResolvedField().getOffset()), new OPT_LocationOperand( registersFref), new OPT_TrueGuardOperand())); @@ -218,19 +217,19 @@ //store the carry flag OPT_RegisterOperand flag = new OPT_RegisterOperand(carryFlag, VM_TypeReference.Boolean); - appendInstructionToCurrentBlock(PutField.create(PUTFIELD, flag, ps_registersOp.copyRO(), new OPT_AddressConstantOperand(registers_carryFlag_Fref.peekResolvedField().getOffset()), new OPT_LocationOperand(registers_carryFlag_Fref), new OPT_TrueGuardOperand()) ); + appendInstruction(PutField.create(PUTFIELD, flag, ps_registersOp.copyRO(), new OPT_AddressConstantOperand(registers_carryFlag_Fref.peekResolvedField().getOffset()), new OPT_LocationOperand(registers_carryFlag_Fref), new OPT_TrueGuardOperand()) ); //store the negative flag flag = new OPT_RegisterOperand(negativeFlag, VM_TypeReference.Boolean); - appendInstructionToCurrentBlock(PutField.create(PUTFIELD, flag, ps_registersOp.copyRO(), new OPT_AddressConstantOperand(registers_negativeFlag_Fref.peekResolvedField().getOffset()), new OPT_LocationOperand(registers_negativeFlag_Fref), new OPT_TrueGuardOperand()) ); + appendInstruction(PutField.create(PUTFIELD, flag, ps_registersOp.copyRO(), new OPT_AddressConstantOperand(registers_negativeFlag_Fref.peekResolvedField().getOffset()), new OPT_LocationOperand(registers_negativeFlag_Fref), new OPT_TrueGuardOperand()) ); //store the zero flag flag = new OPT_RegisterOperand(zeroFlag, VM_TypeReference.Boolean); - appendInstructionToCurrentBlock(PutField.create(PUTFIELD, flag, ps_registersOp.copyRO(), new OPT_AddressConstantOperand(registers_zeroFlag_Fref.peekResolvedField().getOffset()), new OPT_LocationOperand(registers_zeroFlag_Fref), new OPT_TrueGuardOperand()) ); + appendInstruction(PutField.create(PUTFIELD, flag, ps_registersOp.copyRO(), new OPT_AddressConstantOperand(registers_zeroFlag_Fref.peekResolvedField().getOffset()), new OPT_LocationOperand(registers_zeroFlag_Fref), new OPT_TrueGuardOperand()) ); //store the overflow flag flag = new OPT_RegisterOperand(overflowFlag, VM_TypeReference.Boolean); - appendInstructionToCurrentBlock(PutField.create(PUTFIELD, flag, ps_registersOp.copyRO(), new OPT_AddressConstantOperand(registers_overflowFlag_Fref.peekResolvedField().getOffset()), new OPT_LocationOperand(registers_overflowFlag_Fref), new OPT_TrueGuardOperand()) ); + appendInstruction(PutField.create(PUTFIELD, flag, ps_registersOp.copyRO(), new OPT_AddressConstantOperand(registers_overflowFlag_Fref.peekResolvedField().getOffset()), new OPT_LocationOperand(registers_overflowFlag_Fref), new OPT_TrueGuardOperand()) ); } public void fillAllFlags() { @@ -247,19 +246,19 @@ //get the carry flag OPT_RegisterOperand flag = new OPT_RegisterOperand(carryFlag, VM_TypeReference.Boolean); - appendInstructionToCurrentBlock(GetField.create(GETFIELD, flag, ps_registersOp.copyRO(), new OPT_AddressConstantOperand(registers_carryFlag_Fref.peekResolvedField().getOffset()), new OPT_LocationOperand(registers_carryFlag_Fref), new OPT_TrueGuardOperand()) ); + appendInstruction(GetField.create(GETFIELD, flag, ps_registersOp.copyRO(), new OPT_AddressConstantOperand(registers_carryFlag_Fref.peekResolvedField().getOffset()), new OPT_LocationOperand(registers_carryFlag_Fref), new OPT_TrueGuardOperand()) ); //get the negative flag flag = new OPT_RegisterOperand(negativeFlag, VM_TypeReference.Boolean); - appendInstructionToCurrentBlock(GetField.create(GETFIELD, flag, ps_registersOp.copyRO(), new OPT_AddressConstantOperand(registers_negativeFlag_Fref.peekResolvedField().getOffset()), new OPT_LocationOperand(registers_negativeFlag_Fref), new OPT_TrueGuardOperand()) ); + appendInstruction(GetField.create(GETFIELD, flag, ps_registersOp.copyRO(), new OPT_AddressConstantOperand(registers_negativeFlag_Fref.peekResolvedField().getOffset()), new OPT_LocationOperand(registers_negativeFlag_Fref), new OPT_TrueGuardOperand()) ); //get the zero flag flag = new OPT_RegisterOperand(zeroFlag, VM_TypeReference.Boolean); - appendInstructionToCurrentBlock(GetField.create(GETFIELD, flag, ps_registersOp.copyRO(), new OPT_AddressConstantOperand(registers_zeroFlag_Fref.peekResolvedField().getOffset()), new OPT_LocationOperand(registers_zeroFlag_Fref), new OPT_TrueGuardOperand()) ); + appendInstruction(GetField.create(GETFIELD, flag, ps_registersOp.copyRO(), new OPT_AddressConstantOperand(registers_zeroFlag_Fref.peekResolvedField().getOffset()), new OPT_LocationOperand(registers_zeroFlag_Fref), new OPT_TrueGuardOperand()) ); //get the overflow flag flag = new OPT_RegisterOperand(overflowFlag, VM_TypeReference.Boolean); - appendInstructionToCurrentBlock(GetField.create(GETFIELD, flag, ps_registersOp.copyRO(), new OPT_AddressConstantOperand(registers_overflowFlag_Fref.peekResolvedField().getOffset()), new OPT_LocationOperand(registers_overflowFlag_Fref), new OPT_TrueGuardOperand()) ); + appendInstruction(GetField.create(GETFIELD, flag, ps_registersOp.copyRO(), new OPT_AddressConstantOperand(registers_overflowFlag_Fref.peekResolvedField().getOffset()), new OPT_LocationOperand(registers_overflowFlag_Fref), new OPT_TrueGuardOperand()) ); } @Override @@ -273,7 +272,7 @@ if (ps_registers_regs == null) { ps_registers_regsOp = gc.temps.makeTemp(registers_regs_Tref); - appendInstructionToCurrentBlock(GetField.create(GETFIELD, + appendInstruction(GetField.create(GETFIELD, ps_registers_regsOp, ps_registersOp.copyRO(), new OPT_AddressConstantOperand(registers_regs_Fref.peekResolvedField() .getOffset()), new OPT_LocationOperand(registers_regs_Fref), @@ -292,7 +291,7 @@ } else { regOp = new OPT_RegisterOperand(regMap[i], VM_TypeReference.Int); } - appendInstructionToCurrentBlock(ALoad.create(INT_ALOAD, regOp, + appendInstruction(ALoad.create(INT_ALOAD, regOp, ps_registers_regsOp.copyRO(), new OPT_IntConstantOperand(i), new OPT_LocationOperand(VM_TypeReference.Int), new OPT_TrueGuardOperand())); @@ -357,7 +356,7 @@ // never used if ((DBT_Options.singleInstrTranslation == false) || (regUsed[i] == true)) { - appendInstructionToCurrentBlock(AStore.create(INT_ASTORE, + appendInstruction(AStore.create(INT_ASTORE, new OPT_RegisterOperand(regMap[i], VM_TypeReference.Int), ps_registers_regsOp.copyRO(), new OPT_IntConstantOperand(i), new OPT_LocationOperand(VM_TypeReference.Int), @@ -423,23 +422,23 @@ Call.setAddress(s, new OPT_AddressConstantOperand(rotateRightMethod .getOffset())); - appendInstructionToCurrentBlock(s); + appendInstruction(s); } protected void appendBitTest(OPT_RegisterOperand target, OPT_Operand wordToTest, OPT_Operand bit) { if (DBT.VerifyAssertions) DBT._assert(wordToTest != target && bit != target); - appendInstructionToCurrentBlock(Binary.create(OPT_Operators.INT_SHL, target, new OPT_IntConstantOperand(1), bit)); - appendInstructionToCurrentBlock(Binary.create(OPT_Operators.INT_AND, target, wordToTest, target)); - appendInstructionToCurrentBlock(BooleanCmp.create(OPT_Operators.BOOLEAN_CMP_INT, target, target, new OPT_IntConstantOperand(0), OPT_ConditionOperand.NOT_EQUAL(), new OPT_BranchProfileOperand())); + appendInstruction(Binary.create(OPT_Operators.INT_SHL, target, new OPT_IntConstantOperand(1), bit)); + appendInstruction(Binary.create(OPT_Operators.INT_AND, target, wordToTest, target)); + appendInstruction(BooleanCmp.create(OPT_Operators.BOOLEAN_CMP_INT, target, target, new OPT_IntConstantOperand(0), OPT_ConditionOperand.NOT_EQUAL(), new OPT_BranchProfileOperand())); } protected void appendBitTest(OPT_RegisterOperand target, OPT_Operand wordToTest, int bit) { if (DBT.VerifyAssertions) DBT._assert(wordToTest != target); if (DBT.VerifyAssertions) DBT._assert(bit <= 31 && bit >= 0); - appendInstructionToCurrentBlock(Binary.create(OPT_Operators.INT_AND, target, wordToTest, new OPT_IntConstantOperand(1 << bit))); - appendInstructionToCurrentBlock(BooleanCmp.create(OPT_Operators.BOOLEAN_CMP_INT, target, target, new OPT_IntConstantOperand(0), OPT_ConditionOperand.NOT_EQUAL(), new OPT_BranchProfileOperand())); + appendInstruction(Binary.create(OPT_Operators.INT_AND, target, wordToTest, new OPT_IntConstantOperand(1 << bit))); + appendInstruction(BooleanCmp.create(OPT_Operators.BOOLEAN_CMP_INT, target, target, new OPT_IntConstantOperand(0), OPT_ConditionOperand.NOT_EQUAL(), new OPT_BranchProfileOperand())); } } Modified: src/org/binarytranslator/arch/arm/decoder/ARM_Translator.java =================================================================== --- src/org/binarytranslator/arch/arm/decoder/ARM_Translator.java 2007-05-16 18:16:21 UTC (rev 119) +++ src/org/binarytranslator/arch/arm/decoder/ARM_Translator.java 2007-05-17 16:31:37 UTC (rev 120) @@ -8,6 +8,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.branch.BranchLogic.BranchType; import org.jikesrvm.classloader.VM_Atom; import org.jikesrvm.classloader.VM_MemberReference; import org.jikesrvm.classloader.VM_Method; @@ -15,17 +16,18 @@ import org.jikesrvm.classloader.VM_TypeReference; import org.jikesrvm.compilers.opt.ir.*; -/** - */ public class ARM_Translator implements OPT_Operators { /** The process space that we're interpreting.*/ protected final ARM_ProcessSpace ps; + /** The ARM translation class. */ protected final ARM2IR arm2ir; + /** The current laziness state. */ protected ARM_Laziness lazy; + /** The current pc that we're translating. */ protected int pc; /** A "quick" pointer to the ARM registers within the process space*/ @@ -53,6 +55,19 @@ return instr.getSuccessor(pc); } + /** + * Creates an HIR instruction that will call method <code>methodName</code> in the current ARM registers class, + * which has the signature <code>signature</code> and takes <code>numParameters</code> parameters. + * + * @param methodName + * The name of the method to call. + * @param signature + * The method's signature + * @param numParameters + * The number of parameters the method takes. + * @return + * An HIR instruction that will call the given method. + */ private OPT_Instruction createCallToRegisters(String methodName, String signature, int numParameters) { VM_TypeReference RegistersType = VM_TypeReference @@ -79,19 +94,28 @@ return call; } + /** Some ARM instructions can use several addressing modes. Therefore, the ARM Decoder uses an + * {@link OperandWrapper}, that abstracts these differences. The <code>ResolvedOperand</code> class + * can be used to resolve an <code>OperandWrapper</code> into an actual HIR operand.*/ private abstract static class ResolvedOperand { + /** Stores the value that the operand resolves to. */ protected OPT_Operand value; + /** A backlink to the {@link ARM_Translator} class that is using this ResolvedOperand instance. */ protected ARM_Translator translator; - public static OPT_Operand resolveAndStoreShifterCarryOutToCarry( - ARM_Translator translator, OperandWrapper operand) { - - ResolvedOperand result = new ResolvedOperand_WithShifterCarryOut(translator, operand); - return result.getValue(); - } - + /** + * Call this function to create code that converts the <code>operand</code> into an + * HIR <code>OPT_Operand</code>. + * + * @param translator + * + * @param operand + * The operand that is to be converted. + * @return + * An HIR operand that represents the resolved operand. + */ public static OPT_Operand resolve(ARM_Translator translator, OperandWrapper operand) { ResolvedOperand result = new ResolvedOperand_WithoutShifterCarryOut( @@ -99,10 +123,30 @@ return result.getValue(); } + /** + * Works similar to {@link #resolve(ARM_Translator, OperandWrapper)}, but also calculates the + * shifter-carry-out that the ARM barell shifter would produce while resolving this operand. + * The shifter-carry-out is directly written into the <code>translator</code>'s carry flag. + * @param translator + * The translator instance within which the code for the said conversion is to be created. + * @param operand + * The operand that is to be converted. + * @return + * An HIR operand that represents the resolved operand. + */ + public static OPT_Operand resolveAndStoreShifterCarryOutToCarry( + ARM_Translator translator, OperandWrapper operand) { + + ResolvedOperand result = new ResolvedOperand_WithShifterCarryOut(translator, operand); + return result.getValue(); + } + public final OPT_Operand getValue() { return value; } + /** A subclass that resolves an {@link OperandWrapper} without calculating the shifter + * carry out produced by ARM's barrel shifter. */ private static class ResolvedOperand_WithoutShifterCarryOut extends ResolvedOperand { @@ -173,7 +217,7 @@ // the amount of shifting is determined by a register shiftAmount = translator.arm2ir.getRegister(operand.getShiftingRegister()); OPT_RegisterOperand shiftAmountAsByte = translator.arm2ir.getTempInt(7); - translator.arm2ir.appendInstructionToCurrentBlock(Binary.create(INT_AND, shiftAmountAsByte, shiftAmount, new OPT_IntConstantOperand(0xFF))); + translator.arm2ir.appendInstruction(Binary.create(INT_AND, shiftAmountAsByte, shiftAmount, new OPT_IntConstantOperand(0xFF))); shiftAmount = shiftAmountAsByte; } @@ -196,18 +240,18 @@ curBlock.deleteNormalOut(); curBlock.insertOut(block1); curBlock.insertOut(block2); - translator.arm2ir.appendInstructionToCurrentBlock(IfCmp.create(INT_IFCMP, validation, shiftAmount, new OPT_IntConstantOperand(32), OPT_ConditionOperand.GREATER_EQUAL(), block2.makeJumpTarget(), OPT_BranchProfileOperand.unlikely())); + translator.arm2ir.appendInstruction(IfCmp.create(INT_IFCMP, validation, shiftAmount, new OPT_IntConstantOperand(32), OPT_ConditionOperand.GREATER_EQUAL(), block2.makeJumpTarget(), OPT_BranchProfileOperand.unlikely())); //block 1 - normal case translator.arm2ir.setCurrentBlock(block1); block1.insertOut(nextBlock); - translator.arm2ir.appendInstructionToCurrentBlock(Binary.create(INT_SHR, resultRegister, shiftedOperand, shiftAmount)); - translator.arm2ir.appendInstructionToCurrentBlock(Goto.create(GOTO, nextBlock.makeJumpTarget())); + translator.arm2ir.appendInstruction(Binary.create(INT_SHR, resultRegister, shiftedOperand, shiftAmount)); + translator.arm2ir.appendInstruction(Goto.create(GOTO, nextBlock.makeJumpTarget())); //block 2 - shift >= 32 translator.arm2ir.setCurrentBlock(block2); block2.insertOut(nextBlock); - translator.arm2ir.appendInstructionToCurrentBlock(Binary.create( + translator.arm2ir.appendInstruction(Binary.create( INT_SHR, resultRegister, shiftedOperand, new OPT_IntConstantOperand(31))); break; @@ -218,24 +262,22 @@ block2 = translator.arm2ir.createBlockAfterCurrentNotInCFG(); block1 = translator.arm2ir.createBlockAfterCurrentNotInCFG(); - //current block curBlock.deleteNormalOut(); curBlock.insertOut(block1); curBlock.insertOut(block2); - translator.arm2ir.appendInstructionToCurrentBlock(IfCmp.create(INT_IFCMP, validation, shiftAmount, new OPT_IntConstantOperand(32), OPT_ConditionOperand.GREATER_EQUAL(), block2.makeJumpTarget(), OPT_BranchProfileOperand.unlikely())); + translator.arm2ir.appendInstruction(IfCmp.create(INT_IFCMP, validation, shiftAmount, new OPT_IntConstantOperand(32), OPT_ConditionOperand.GREATER_EQUAL(), block2.makeJumpTarget(), OPT_BranchProfileOperand.unlikely())); //block 1 - normal case translator.arm2ir.setCurrentBlock(block1); block1.insertOut(nextBlock); - translator.arm2ir.appendInstructionToCurrentBlock(Binary.create(INT_SHL, resultRegister, shiftedOperand, shiftAmount)); - translator.arm2ir.appendInstructionToCurrentBlock(Goto.create(GOTO, nextBlock.makeJumpTarget())); + translator.arm2ir.appendInstruction(Binary.create(INT_SHL, resultRegister, shiftedOperand, shiftAmount)); + translator.arm2ir.appendInstruction(Goto.create(GOTO, nextBlock.makeJumpTarget())); - //block 2 - shift >= 32 translator.arm2ir.setCurrentBlock(block2); block2.insertOut(nextBlock); - translator.arm2ir.appendInstructionToCurrentBlock(Move.create(INT_MOVE, resultRegister, new OPT_IntConstantOperand(0)) ); + translator.arm2ir.appendInstruction(Move.create(INT_MOVE, resultRegister, new OPT_IntConstantOperand(0)) ); break; case LSR: @@ -247,23 +289,22 @@ block2 = translator.arm2ir.createBlockAfterCurrentNotInCFG(); block1 = translator.arm2ir.createBlockAfterCurrentNotInCFG(); - //current block curBlock.deleteNormalOut(); curBlock.insertOut(block1); curBlock.insertOut(block2); - translator.arm2ir.appendInstructionToCurrentBlock(IfCmp.create(INT_IFCMP, validation, shiftAmount, new OPT_IntConstantOperand(32), OPT_ConditionOperand.GREATER_EQUAL(), block2.makeJumpTarget(), OPT_BranchProfileOperand.unlikely())); + translator.arm2ir.appendInstruction(IfCmp.create(INT_IFCMP, validation, shiftAmount, new OPT_IntConstantOperand(32), OPT_ConditionOperand.GREATER_EQUAL(), block2.makeJumpTarget(), OPT_BranchProfileOperand.unlikely())); //block 1 - normal case translator.arm2ir.setCurrentBlock(block1); block1.insertOut(nextBlock); - translator.arm2ir.appendInstructionToCurrentBlock(Binary.create(INT_USHR, resultRegister, shiftedOperand, shiftAmount)); - translator.arm2ir.appendInstructionToCurrentBlock(Goto.create(GOTO, nextBlock.makeJumpTarget())); + translator.arm2ir.appendInstruction(Binary.create(INT_USHR, resultRegister, shiftedOperand, shiftAmount)); + translator.arm2ir.appendInstruction(Goto.create(GOTO, nextBlock.makeJumpTarget())); //block 2 - shift >= 32 translator.arm2ir.setCurrentBlock(block2); block2.insertOut(nextBlock); - translator.arm2ir.appendInstructionToCurrentBlock(Move.create(INT_MOVE, resultRegister, new OPT_IntConstantOperand(0)) ); + translator.arm2ir.appendInstruction(Move.create(INT_MOVE, resultRegister, new OPT_IntConstantOperand(0)) ); break; case ROR: @@ -285,13 +326,13 @@ curBlock.deleteNormalOut(); curBlock.insertOut(nextBlock); curBlock.insertOut(block1); - translator.arm2ir.appendInstructionToCurrentBlock(Binary.create(INT_USHR, resultRegister, shiftedOperand, new OPT_IntConstantOperand(1))); - translator.arm2ir.appendInstructionToCurrentBlock(IfCmp.create(INT_IFCMP, translator.arm2ir.getTempValidation(0), translator.arm2ir.getCarryFlag(), new OPT_IntConstantOperand(1), OPT_ConditionOperand.NOT_EQUAL(), nextBlock.makeJumpTarget(), new OPT_BranchProfileOperand())); + translator.arm2ir.appendInstruction(Binary.create(INT_USHR, resultRegister, shiftedOperand, new OPT_IntConstantOperand(1))); + translator.arm2ir.appendInstruction(IfCmp.create(INT_IFCMP, translator.arm2ir.getTempValidation(0), translator.arm2ir.getCarryFlag(), new OPT_IntConstantOperand(1), OPT_ConditionOperand.NOT_EQUAL(), nextBlock.makeJumpTarget(), new OPT_BranchProfileOperand())); //Block 1 translator.arm2ir.setCurrentBlock(block1); block1.insertOut(nextBlock); - translator.arm2ir.appendInstructionToCurrentBlock(Binary.create(INT_OR, resultRegister, resultRegister, new OPT_IntConstantOperand(0x80000000))); + translator.arm2ir.appendInstruction(Binary.create(INT_OR, resultRegister, resultRegister, new OPT_IntConstantOperand(0x80000000))); break; default: @@ -303,7 +344,10 @@ return resultRegister; } } - + + /** + * This class resolves an {@link OperandWrapper} and also writes the shifter carry out, as + * produced by ARM's barrel shifter, into the Carry flag.*/ private static class ResolvedOperand_WithShifterCarryOut extends ResolvedOperand { @@ -323,7 +367,7 @@ OPT_Operand shifterCarryOut = new OPT_IntConstantOperand(((operand.getImmediate() & 0x80000000) != 0) ? 1 : 0); //otherwise there is no shifter carry out - translator.arm2ir.appendInstructionToCurrentBlock(Move.create(INT_MOVE, carryFlag, shifterCarryOut)); + translator.arm2ir.appendInstruction(Move.create(INT_MOVE, carryFlag, shifterCarryOut)); } return; @@ -386,7 +430,7 @@ // the amount of shifting is determined by a register shiftAmount = translator.arm2ir.getRegister(operand.getShiftingRegister()); OPT_RegisterOperand shiftAmountAsByte = translator.arm2ir.getTempInt(7); - translator.arm2ir.appendInstructionToCurrentBlock(Binary.create(INT_AND, shiftAmountAsByte, shiftAmount, new OPT_IntConstantOperand(0xFF))); + translator.arm2ir.appendInstruction(Binary.create(INT_AND, shiftAmountAsByte, shiftAmount, new OPT_IntConstantOperand(0xFF))); shiftAmount = shiftAmountAsByte; } @@ -409,33 +453,33 @@ curBlock.deleteNormalOut(); curBlock.insertOut(block1); curBlock.insertOut(block4); - translator.arm2ir.appendInstructionToCurrentBlock(IfCmp.create(INT_IFCMP, validation, shiftAmount, new OPT_IntConstantOperand(0), OPT_ConditionOperand.EQUAL(), block4.makeJumpTarget(), OPT_BranchProfileOperand.unlikely())); + translator.arm2ir.appendInstruction(IfCmp.create(INT_IFCMP, validation, shiftAmount, new OPT_IntConstantOperand(0), OPT_ConditionOperand.EQUAL(), block4.makeJumpTarget(), OPT_BranchProfileOperand.unlikely())); //block 1 - shift != 0 translator.arm2ir.setCurrentBlock(block1); block1.insertOut(block2); block1.insertOut(block3); - translator.arm2ir.appendInstructionToCurrentBlock(IfCmp.create(INT_IFCMP, validation, shiftAmount, new OPT_IntConstantOperand(32), OPT_ConditionOperand.GREATER_EQUAL(), block3.makeJumpTarget(), OPT_BranchProfileOperand.unlikely())); + translator.arm2ir.appendInstruction(IfCmp.create(INT_IFCMP, validation, shiftAmount, new OPT_IntConstantOperand(32), OPT_ConditionOperand.GREATER_EQUAL(), block3.makeJumpTarget(), OPT_BranchProfileOperand.unlikely())); //block 2 - shift < 32 && shift != 0 translator.arm2ir.setCurrentBlock(block2); block2.insertOut(nextBlock); - translator.arm2ir.appendInstructionToCurrentBlock(Binary.create(INT_SHR, resultRegister, shiftedOperand, shiftAmount) ); - translator.arm2ir.appendInstructionToCurrentBlock(Binary.create(INT_ADD, tmp, shiftAmount, new OPT_IntConstantOperand(-1)) ); + translator.arm2ir.appendInstruction(Binary.create(INT_SHR, resultRegister, shiftedOperand, shiftAmount) ); + translator.arm2ir.appendInstruction(Binary.create(INT_ADD, tmp, shiftAmount, new OPT_IntConstantOperand(-1)) ); translator.arm2ir.appendBitTest(getShifterCarryOutTarget(), shiftedOperand, tmp); - translator.arm2ir.appendInstructionToCurrentBlock(Goto.create(GOTO, nextBlock.makeJumpTarget())); + translator.arm2ir.appendInstruction(Goto.create(GOTO, nextBlock.makeJumpTarget())); //block 3 - shift >= 32 translator.arm2ir.setCurrentBlock(block3); block3.insertOut(nextBlock); translator.arm2ir.appendBitTest(getShifterCarryOutTarget(), shiftedOperand, 31); - translator.arm2ir.appendInstructionToCurrentBlock(Binary.create(INT_MUL, resultRegister, getShifterCarryOutTarget(), new OPT_IntConstantOperand(-1)) ); //creates either 0xFFFFFFFF if the bit is set, or 0 otherwise - translator.arm2ir.appendInstructionToCurrentBlock(Goto.create(GOTO, nextBlock.makeJumpTarget())); + translator.arm2ir.appendInstruction(Binary.create(INT_MUL, resultRegister, getShifterCarryOutTarget(), new OPT_IntConstantOperand(-1)) ); //creates either 0xFFFFFFFF if the bit is set, or 0 otherwise + translator.arm2ir.appendInstruction(Goto.create(GOTO, nextBlock.makeJumpTarget())); //block 4 - shift == 0 translator.arm2ir.setCurrentBlock(block4); block4.insertOut(nextBlock); - translator.arm2ir.appendInstructionToCurrentBlock(Move.create(INT_MOVE, resultRegister, shiftedOperand)); + translator.arm2ir.appendInstruction(Move.create(INT_MOVE, resultRegister, shiftedOperand)); break; case LSL: @@ -453,45 +497,45 @@ curBlock.deleteNormalOut(); curBlock.insertOut(block6); curBlock.insertOut(block1); - translator.arm2ir.appendInstructionToCurrentBlock(IfCmp.create(INT_IFCMP, validation, shiftAmount, new OPT_IntConstantOperand(0), OPT_ConditionOperand.EQUAL(), block6.makeJumpTarget(), OPT_BranchProfileOperand.unlikely())); + translator.arm2ir.appendInstruction(IfCmp.create(INT_IFCMP, validation, shiftAmount, new OPT_IntConstantOperand(0), OPT_ConditionOperand.EQUAL(), block6.makeJumpTarget(), OPT_BranchProfileOperand.unlikely())); //block 1 - shift != 0 translator.arm2ir.setCurrentBlock(block1); block1.insertOut(block2); block1.insertOut(block3); - translator.arm2ir.appendInstructionToCurrentBlock(IfCmp.create(INT_IFCMP, validation, shiftAmount, new OPT_IntConstantOperand(32), OPT_ConditionOperand.GREATER_EQUAL(), block3.makeJumpTarget(), OPT_BranchProfileOperand.unlikely())); + translator.arm2ir.appendInstruction(IfCmp.create(INT_IFCMP, validation, shiftAmount, new OPT_IntConstantOperand(32), OPT_ConditionOperand.GREATER_EQUAL(), block3.makeJumpTarget(), OPT_BranchProfileOperand.unlikely())); //block 2 - Shift != 0 && Shift < 32 translator.arm2ir.setCurrentBlock(block2); block2.insertOut(nextBlock); - translator.arm2ir.appendInstructionToCurrentBlock(Binary.create(INT_SUB, tmp, new OPT_IntConstantOperand(32), shiftAmount) ); + translator.arm2ir.appendInstruction(Binary.create(INT_SUB, tmp, new OPT_IntConstantOperand(32), shiftAmount) ); translator.arm2ir.appendBitTest(getShifterCarryOutTarget(), shiftedOperand, tmp); - translator.arm2ir.appendInstructionToCurrentBlock(Binary.create(INT_SHL, resultRegister, shiftedOperand, shiftAmount)); - translator.arm2ir.appendInstructionToCurrentBlock(Goto.create(GOTO, nextBlock.makeJumpTarget())); + translator.arm2ir.appendInstruction(Binary.create(INT_SHL, resultRegister, shiftedOperand, shiftAmount)); + translator.arm2ir.appendInstruction(Goto.create(GOTO, nextBlock.makeJumpTarget())); //block 3 - Shift >= 32 translator.arm2ir.setCurrentBlock(block3); - translator.arm2ir.appendInstructionToCurrentBlock(Move.create(INT_MOVE, resultRegister, new OPT_IntConstantOperand(0)) ); - translator.arm2ir.appendInstructionToCurrentBlock(IfCmp.create(INT_IFCMP, validation, shiftAmount, new OPT_IntConstantOperand(32), OPT_ConditionOperand.EQUAL(), block5.makeJumpTarget(), OPT_BranchProfileOperand.unlikely())); + translator.arm2ir.appendInstruction(Move.create(INT_MOVE, resultRegister, new OPT_IntConstantOperand(0)) ); + translator.arm2ir.appendInstruction(IfCmp.create(INT_IFCMP, validation, shiftAmount, new OPT_IntConstantOperand(32), OPT_ConditionOperand.EQUAL(), block5.makeJumpTarget(), OPT_BranchProfileOperand.unlikely())); block3.insertOut(block4); block3.insertOut(block5); //block 4 - Shift > 32 translator.arm2ir.setCurrentBlock(block4); block4.insertOut(nextBlock); - translator.arm2ir.appendInstructionToCurrentBlock(Move.create(INT_MOVE, getShifterCarryOutTarget(), new OPT_IntConstantOperand(0)) ); - translator.arm2ir.appendInstructionToCurrentBlock(Goto.create(GOTO, nextBlock.makeJumpTarget())); + translator.arm2ir.appendInstruction(Move.create(INT_MOVE, getShifterCarryOutTarget(), new OPT_IntConstantOperand(0)) ); + translator.arm2ir.appendInstruction(Goto.create(GOTO, nextBlock.makeJumpTarget())); //block 5 - Shift == 32 translator.arm2ir.setCurrentBlock(block5); block5.insertOut(nextBlock); translator.arm2ir.appendBitTest(getShifterCarryOutTarget(), shiftedOperand, 0); - translator.arm2ir.appendInstructionToCurrentBlock(Goto.create(GOTO, nextBlock.makeJumpTarget())); + translator.arm2ir.appendInstruction(Goto.create(GOTO, nextBlock.makeJumpTarget())); //block 6 - shift == 0 translator.arm2ir.setCurrentBlock(block6); block6.insertOut(nextBlock); - translator.arm2ir.appendInstructionToCurrentBlock(Move.create(INT_MOVE, resultRegister, shiftedOperand)); + translator.arm2ir.appendInstruction(Move.create(INT_MOVE, resultRegister, shiftedOperand)); break; case LSR: @@ -510,45 +554,45 @@ curBlock.deleteNormalOut(); curBlock.insertOut(block6); curBlock.insertOut(block1); - translator.arm2ir.appendInstructionToCurrentBlock(IfCmp.create(INT_IFCMP, validation, shiftAmount, new OPT_IntConstantOperand(0), OPT_ConditionOperand.EQUAL(), block6.makeJumpTarget(), OPT_BranchProfileOperand.unlikely())); + translator.arm2ir.appendInstruction(IfCmp.create(INT_IFCMP, validation, shiftAmount, new OPT_IntConstantOperand(0), OPT_ConditionOperand.EQUAL(), block6.makeJumpTarget(), OPT_BranchProfileOperand.unlikely())); //block 1 - shift != 0 translator.arm2ir.setCurrentBlock(block1); block1.insertOut(block2); block1.insertOut(block3); - translator.arm2ir.appendInstructionToCurrentBlock(IfCmp.create(INT_IFCMP, validation, shiftAmount, new OPT_IntConstantOperand(32), OPT_ConditionOperand.GREATER_EQUAL(), block3.makeJumpTarget(), OPT_BranchProfileOperand.unlikely())); + translator.arm2ir.appendInstruction(IfCmp.create(INT_IFCMP, validation, shiftAmount, new OPT_IntConstantOperand(32), OPT_ConditionOperand.GREATER_EQUAL(), block3.makeJumpTarget(), OPT_BranchProfileOperand.unlikely())); //block 2 - Shift != 0 && Shift < 32 translator.arm2ir.setCurrentBlock(block2); block2.insertOut(nextBlock); - translator.arm2ir.appendInstructionToCurrentBlock(Binary.create(INT_ADD, tmp, shiftAmount, new OPT_IntConstantOperand(-1))); + translator.arm2ir.appendInstruction(Binary.create(INT_ADD, tmp, shiftAmount, new OPT_IntConstantOperand(-1))); translator.arm2ir.appendBitTest(getShifterCarryOutTarget(), shiftedOperand, tmp); - translator.arm2ir.appendInstructionToCurrentBlock(Binary.create(INT_USHR, resultRegister, shiftedOperand, shiftAmount)); - translator.arm2ir.appendInstructionToCurrentBlock(Goto.create(GOTO, nextBlock.makeJumpTarget())); + translator.arm2ir.appendInstruction(Binary.create(INT_USHR, resultRegister, shiftedOperand, shiftAmount)); + translator.arm2ir.appendInstruction(Goto.create(GOTO, nextBlock.makeJumpTarget())); //block 3 - Shift >= 32 translator.arm2ir.setCurrentBlock(block3); - translator.arm2ir.appendInstructionToCurrentBlock(Move.create(INT_MOVE, resultRegister, new OPT_IntConstantOperand(0)) ); - translator.arm2ir.appendInstructionToCurrentBlock(IfCmp.create(INT_IFCMP, validation, shiftAmount, new OPT_IntConstantOperand(32), OPT_ConditionOperand.EQUAL(), block5.makeJumpTarget(), OPT_BranchProfileOperand.unlikely())); + translator.arm2ir.appendInstruction(Move.create(INT_MOVE, resultRegister, new OPT_IntConstantOperand(0)) ); + translator.arm2ir.appendInstruction(IfCmp.create(INT_IFCMP, validation, shiftAmount, new OPT_IntConstantOperand(32), OPT_ConditionOperand.EQUAL(), block5.makeJumpTarget(), OPT_BranchProfileOperand.unlikely())); block3.insertOut(block4); block3.insertOut(block5); //block 4 - Shift > 32 translator.arm2ir.setCurrentBlock(block4); block4.insertOut(nextBlock); - translator.arm2ir.appendInstructionToCurrentBlock(Move.create(INT_MOVE, getShifterCarryOutTarget(), new OPT_IntConstantOperand(0)) ); - translator.arm2ir.appendInstructionToCurrentBlock(Goto.create(GOTO, nextBlock.makeJumpTarget())); + translator.arm2ir.appendInstruction(Move.create(INT_MOVE, getShifterCarryOutTarget(), new OPT_IntConstantOperand(0)) ); + translator.arm2ir.appendInstruction(Goto.create(GOTO, nextBlock.makeJumpTarget())); //block 5 - Shift == 32 translator.arm2ir.setCurrentBlock(block5); block5.insertOut(nextBlock); translator.arm2ir.appendBitTest(getShifterCarryOutTarget(), shiftedOperand, 31); - translator.arm2ir.appendInstructionToCurrentBlock(Goto.create(GOTO, nextBlock.makeJumpTarget())); + translator.arm2ir.appendInstruction(Goto.create(GOTO, nextBlock.makeJumpTarget())); //block 6 - shift == 0 translator.arm2ir.setCurrentBlock(block6); block6.insertOut(nextBlock); - translator.arm2ir.appendInstructionToCurrentBlock(Move.create(INT_MOVE, resultRegister, shiftedOperand)); + translator.arm2ir.appendInstruction(Move.create(INT_MOVE, resultRegister, shiftedOperand)); break; case ROR: @@ -562,20 +606,20 @@ curBlock.deleteNormalOut(); curBlock.insertOut(block1); curBlock.insertOut(block2); - translator.arm2ir.appendInstructionToCurrentBlock(IfCmp.create(INT_IFCMP, validation, shiftAmount, new OPT_IntConstantOperand(0), OPT_ConditionOperand.EQUAL(), block2.makeJumpTarget(), OPT_BranchProfileOperand.unlikely())); + translator.arm2ir.appendInstruction(IfCmp.create(INT_IFCMP, validation, shiftAmount, new OPT_IntConstantOperand(0), OPT_ConditionOperand.EQUAL(), block2.makeJumpTarget(), OPT_BranchProfileOperand.unlikely())); //block 1 translator.arm2ir.setCurrentBlock(block1); block1.insertOut(nextBlock); translator.arm2ir.appendRotateRight(resultRegister, shiftedOperand, shiftAmount); - translator.arm2ir.appendInstructionToCurrentBlock(Binary.create(INT_ADD, tmp, shiftAmount, new OPT_IntConstantOperand(-1)) ); - translator.arm2ir.appendInstructionToCurrentBlock(Binary.create(INT_AND, tmp, tmp, new OPT_IntConstantOperand(0x1F)) ); + translator.arm2ir.appendInstruction(Binary.create(INT_ADD, tmp, shiftAmount, new OPT_IntConstantOperand(-1)) ); + translator.arm2ir.appendInstruction(Binary.create(INT_AND, tmp, tmp, new OPT_IntConstantOperand(0x1F)) ); translator.arm2ir.appendBitTest(getShifterCarryOutTarget(), shiftedOperand, tmp); - translator.arm2ir.appendInstructionToCurrentBlock(Goto.create(GOTO, nextBlock.makeJumpTarget())); + translator.arm2ir.appendInstruction(Goto.create(GOTO, nextBlock.makeJumpTarget())); //block 2 translator.arm2ir.setCurrentBlock(block2); - translator.arm2ir.appendInstructionToCurrentBlock(Move.create(INT_MOVE, resultRegister, shiftedOperand)); + translator.arm2ir.appendInstruction(Move.create(INT_MOVE, resultRegister, shiftedOperand)); break; case RRX: @@ -589,13 +633,13 @@ curBlock.deleteNormalOut(); curBlock.insertOut(block1); curBlock.insertOut(nextBlock); - translator.arm2ir.appendInstructionToCurrentBlock(Binary.create(INT_USHR, resultRegister, shiftedOperand, new OPT_IntConstantOperand(1))); - translator.arm2ir.appendInstructionToCurrentBlock(IfCmp.create(INT_IFCMP, translator.arm2ir.getTempValidation(0), translator.arm2ir.getCarryFlag(), new OPT_IntConstantOperand(1), OPT_ConditionOperand.NOT_EQUAL(), nextBlock.makeJumpTarget(), new OPT_BranchProfileOperand())); + translator.arm2ir.appendInstruction(Binary.create(INT_USHR, resultRegister, shiftedOperand, new OPT_IntConstantOperand(1))); + translator.arm2ir.appendInstruction(IfCmp.create(INT_IFCMP, translator.arm2ir.getTempValidation(0), translator.arm2ir.getCarryFlag(), new OPT_IntConstantOperand(1), OPT_ConditionOperand.NOT_EQUAL(), nextBlock.makeJumpTarget(), new OPT_BranchProfileOperand())); //Block 1 translator.arm2ir.setCurrentBlock(block1); block1.insertOut(nextBlock); - translator.arm2ir.appendInstructionToCurrentBlock(Binary.create(INT_OR, resultRegister, resultRegister, new OPT_IntConstantOperand(0x80000000))); + translator.arm2ir.appendInstruction(Binary.create(INT_OR, resultRegister, resultRegister, new OPT_IntConstantOperand(0x80000000))); //nextBlock translator.arm2ir.setCurrentBlock(nextBlock); @@ -640,29 +684,17 @@ public int getSuccessor(int pc) { //if this instruction is not a jump, then we can tell what the next instruction will be. - if (conditionalInstruction.getSuccessor(pc) == pc + 4) - return pc + 4; - else - return -1; + return pc + 4; } public void translate() { //conditionals are implemented easily: if the condition does not hold, then just //jump to the block following the conditional instruction - OPT_BasicBlock nextInstruction; - OPT_BasicBlock condBlock; - - if (getSuccessor(pc) != -1) { - nextInstruction = arm2ir.getNextBlock(); - condBlock = arm2ir.createBlockAfterCurrent(); - condBlock.insertOut(nextInstruction); - } - else { - nextInstruction = arm2ir.createBlockAfterCurrent(); - condBlock = arm2ir.createBlockAfterCurrent(); - } - + OPT_BasicBlock nextInstruction = arm2ir.getNextBlock(); + OPT_BasicBlock condBlock = arm2ir.createBlockAfterCurrent(); + arm2ir.getCurrentBlock().deleteNormalOut(); arm2ir.getCurrentBlock().insertOut(nextInstruction); + arm2ir.getCurrentBlock().insertOut(condBlock); switch (conditionalInstruction.getCondition()) { case AL: @@ -745,11 +777,6 @@ arm2ir.setCurrentBlock(condBlock); conditionalInstruction.translate(); - - if (getSuccessor(pc) == -1) { - arm2ir.setCurrentBlock(nextInstruction); - arm2ir.setReturnValueResolveLazinessAndBranchToFinish(lazy, new OPT_IntConstantOperand(pc+4)); - } } private void translateCondition(OPT_BasicBlock nextInstruction, OPT_Operand operand, OPT_ConditionOperand condition) { @@ -759,7 +786,7 @@ private void translateCondition(OPT_BasicBlock nextInstruction, OPT_Operand lhs, OPT_ConditionOperand condition, OPT_Operand rhs) { condition = condition.flipCode(); - arm2ir.appendInstructionToCurrentBlock(IfCmp.create(INT_IFCMP, arm2ir.getTempValidation(0), lhs, rhs, condition, nextInstruction.makeJumpTarget(), new OPT_BranchProfileOperand())); + arm2ir.appendInstruction(IfCmp.create(INT_IFCMP, arm2ir.getTempValidation(0), lhs, rhs, condition, nextInstruction.makeJumpTarget(), new OPT_BranchProfileOperand())); } private void translateCondition_HI(OPT_BasicBlock nextInstruction) { @@ -768,10 +795,10 @@ OPT_Operand zero = arm2ir.getZeroFlag(); OPT_RegisterOperand result = arm2ir.getGenerationContext().temps.makeTempBoolean(); - arm2ir.appendInstructionToCurrentBlock(BooleanCmp2.create(BOOLEAN_CMP2_INT_OR, result, carry, + arm2ir.appendInstruction(BooleanCmp2.create(BOOLEAN_CMP2_INT_OR, result, carry, new OPT_IntConstantOperand(0), OPT_ConditionOperand.EQUAL(), new OPT_BranchProfileOperand(), zero, new OPT_IntConstantOperand(1), OPT_ConditionOperand.EQUAL(), new OPT_BranchProfileOperand())); - arm2ir.appendInstructionToCurrentBlock(IfCmp.create(INT_IFCMP, arm2ir.getTempValidation(0), result, new OPT_IntConstantOperand(1), OPT_ConditionOperand.EQUAL(), nextInstruction.makeJumpTarget(), new OPT_BranchProfileOperand())); + arm2ir.appendInstruction(IfCmp.create(INT_IFCMP, arm2ir.getTempValidation(0), result, new OPT_IntConstantOperand(1), OPT_ConditionOperand.EQUAL(), nextInstruction.makeJumpTarget(), new OPT_BranchProfileOperand())); } private void translateCondition_LS(OPT_BasicBlock nextInstruction) { @@ -780,10 +807,10 @@ OPT_Operand zero = arm2ir.getZeroFlag(); OPT_RegisterOperand result = arm2ir.getGenerationContext().temps.makeTempBoolean(); - arm2ir.appendInstructionToCurrentBlock(BooleanCmp2.create(BOOLEAN_CMP2_INT_AND, result, carry, + arm2ir.appendInstruction(BooleanCmp2.create(BOOLEAN_CMP2_INT_AND, result, carry, new OPT_IntConstantOperand(1), OPT_ConditionOperand.EQUAL(), new OPT_BranchProfileOperand(), zero, new OPT_IntConstantOperand(0), OPT_ConditionOperand.EQUAL(), new OPT_BranchProfileOperand())); - arm2ir.appendInstructionToCurrentBlock(IfCmp.create(INT_IFCMP, arm2ir.getTempValidation(0), result, new OPT_IntConstantOperand(1), OPT_ConditionOperand.EQUAL(), nextInstruction.makeJumpTarget(), new OPT_BranchProfileOperand())); + arm2ir.appendInstruction(IfCmp.create(INT_IFCMP, arm2ir.getTempValidation(0), result, new OPT_IntConstantOperand(1), OPT_ConditionOperand.EQUAL(), nextInstruction.makeJumpTarget(), new OPT_BranchProfileOperand())); } private void translateCondition_GT(OPT_BasicBlock nextInstruction) { @@ -793,10 +820,10 @@ OPT_Operand zero = arm2ir.getZeroFlag(); OPT_RegisterOperand result = arm2ir.getGenerationContext().temps.makeTempBoolean(); - arm2ir.appendInstructionToCurrentBlock(BooleanCmp2.create(BOOLEAN_CMP2_INT_OR, result, negative, + arm2ir.appendInstruction(BooleanCmp2.create(BOOLEAN_CMP2_INT_OR, result, negative, overflow, OPT_ConditionOperand.NOT_EQUAL(), new OPT_BranchProfileOperand(), zero, new OPT_IntConstantOperand(1), OPT_ConditionOperand.EQUAL(), new OPT_BranchProfileOperand())); - arm2ir.appendInstructionToCurrentBlock(IfCmp.create(INT_IFCMP, arm2ir.getTempValidation(0), result, new OPT_IntConstantOperand(1), OPT_ConditionOperand.EQUAL(), nextInstruction.makeJumpTarget(), new OPT_BranchProfileOperand())); + arm2ir.appendInstruction(IfCmp.create(INT_IFCMP, arm2ir.getTempValidation(0), result, new OPT_IntConstantOperand(1), OPT_ConditionOperand.EQUAL(), nextInstruction.makeJumpTarget(), new OPT_BranchProfileOperand())); } private void translateCondition_LE(OPT_BasicBlock nextInstruction) { @@ -806,10 +833,10 @@ OPT_Operand zero = arm2ir.getZeroFlag(); OPT_RegisterOperand result = arm2ir.getGenerationContext().temps.makeTempBoolean(); - arm2ir.appendInstructionToCurrentBlock(BooleanCmp2.create(BOOLEAN_CMP2_INT_AND, result, negative, + arm2ir.appendInstruction(BooleanCmp2.create(BOOLEAN_CMP2_INT_AND, result, negative, overflow, OPT_ConditionOperand.EQUAL(), new OPT_BranchProfileOperand(), zero, new OPT_IntConstantOperand(0), OPT_ConditionOperand.EQUAL(), new OPT_BranchProfileOperand())); - arm2ir.appendInstructionToCurrentBlock(IfCmp.create(INT_IFCMP, arm2ir.getTempValidation(0), result, new OPT_IntConstantOperand(1), OPT_ConditionOperand.EQUAL(), nextInstruction.makeJumpTarget(), new OPT_BranchProfileOperand())); + arm2ir.appendInstruction(IfCmp.create(INT_IFCMP, arm2ir.getTempValidation(0), result, new OPT_IntConstantOperand(1), OPT_ConditionOperand.EQUAL(), nextInstruction.makeJumpTarget(), new OPT_BranchProfileOperand())); } public Condition getCondition() { @@ -854,7 +881,7 @@ public abstract void translate(); /** Sets the processor flags according to the result of adding <code>lhs</code> and <code>rhs</code>.*/ - protected final void setAddResult(OPT_Operand result, OPT_Operand lhs, OPT_Operand rhs) { + protected final void setAddResult(OPT_RegisterOperand result, OPT_Operand lhs, OPT_Operand rhs) { if (updateConditionCodes) { if (Rd != 15) { @@ -862,14 +889,20 @@ } else { OPT_Instruction s = createCallToRegisters("restoreSPSR2CPSR", "()V", 0); - arm2ir.appendInstructionToCurrentBlock(s); + arm2ir.appendInstruction(s); } } - arm2ir.appendInstructionToCurrentBlock(Move.create(INT_MOVE, arm2ir.getRegister(Rd), result) ); - - if (Rd == 15) - arm2ir.setReturnValueResolveLazinessAndBranchToFinish(lazy, result); + if (Rd == 15) { + + if (updateConditionCodes) + arm2ir.appendDynamicJump(result, lazy, BranchType.INDIRECT_BRANCH); + else + arm2ir.setReturnValueResolveLazinessAndBranchToFinish(lazy, result); + } + else { + arm2ir.appendInstruction(Move.create(INT_MOVE, arm2ir.getRegister(Rd), result) ); + } } /** @@ -883,24 +916,24 @@ */ protected final void setAddFlags(OPT_Operand result, OPT_Operand lhs, OPT_Operand rhs) { //set the carry flag - arm2ir.appendInstructionToCurrentBlock(BooleanCmp.create( + arm2ir.appendInstruction(BooleanCmp.create( BOOLEAN_CMP_INT, arm2ir.getCarryFlag(), lhs, rhs, OPT_ConditionOperand.CARRY_FROM_ADD(), new OPT_BranchProfileOperand())); //set the overflow flag - arm2ir.appendInstructionToCurrentBlock(BooleanCmp.create( + arm2ir.appendInstruction(BooleanCmp.create( BOOLEAN_CMP_INT, arm2ir.getOverflowFlag(), lhs, rhs, OPT_ConditionOperand.OVERFLOW_FROM_ADD(), OPT_BranchProfileOperand.unlikely())); //set the negative flag - arm2ir.appendInstructionToCurrentBlock(BooleanCmp.create( + arm2ir.appendInstruction(BooleanCmp.create( BOOLEAN_CMP_INT, arm2ir.getNegativeFlag(), result, new OPT_IntConstantOperand(0), OPT_ConditionOperand.LESS(), new OPT_BranchProfileOperand())); //set the zero flag - arm2ir.appendInstructionToCurrentBlock(BooleanCmp.create( + arm2ir.appendInstruction(BooleanCmp.create( BOOLEAN_CMP_INT, arm2ir.getZeroFlag(), result, new OPT_IntConstantOperand(0), OPT_ConditionOperand.EQUAL(), new OPT_BranchProfileOperand())); } /** Sets the processor flags according to the result of subtracting <code>rhs</code> from <code>lhs</code>.*/ - protected final void setSubResult(OPT_Operand result, OPT_Operand lhs, OPT_Operand rhs) { + protected final void setSubResult(OPT_RegisterOperand result, OPT_Operand lhs, OPT_Operand rhs) { if (updateConditionCodes) { if (Rd != 15) { @@ -908,14 +941,20 @@ } else { OPT_Instruction s = createCallToRegisters("restoreSPSR2CPSR", "()V", 0); - arm2ir.appendInstructionToCurrentBlock(s); + arm2ir.appendInstruction(s); } } - - arm2ir.appendInstructionToCurrentBlock(Move.create(INT_MOVE, arm2ir.getRegister(Rd), result) ); - - if (Rd == 15) - arm2ir.setReturnValueResolveLazinessAndBranchToFinish(lazy, result); + + if (Rd == 15) { + + if (updateConditionCodes) + arm2ir.appendDynamicJump(result, lazy, BranchType.INDIRECT_BRANCH); + else + arm2ir.setReturnValueResolveLazinessAndBranchToFinish(lazy, result); + } + else { + arm2ir.appendInstruction(Move.create(INT_MOVE, arm2ir.getRegister(Rd), result) ); + } } /** @@ -929,20 +968,20 @@ */ protected final void setSubFlags(OPT_Operand result, OPT_Operand lhs, OPT_Operand rhs) { //set the carry flag to not(Borrow) - arm2ir.appendInstructionToCurrentBlock(BooleanCmp.create( + arm2ir.appendInstruction(BooleanCmp.create( BOOLEAN_CMP_INT, arm2ir.getCarryFlag(), lhs, rhs, OPT_ConditionOperand.BORROW_FROM_SUB(), new OPT_BranchProfileOperand())); - arm2ir.appendInstructionToCurrentBlock(Unary.create(BOOLEAN_NOT, arm2ir.getCarryFlag(), arm2ir.getCarryFlag())); + arm2ir.appendInstruction(Unary.create(BOOLEAN_NOT, arm2ir.getCarryFlag(), arm2ir.getCarryFlag())); //set the overflow flag - arm2ir.appendInstructionToCurrentBlock(BooleanCmp.create( + arm2ir.appendInstruction(BooleanCmp.create( BOOLEAN_CMP_INT, arm2ir.getOverflowFlag(), lhs, rhs, OPT_ConditionOperand.OVERFLOW_FROM_SUB(), OPT_BranchProfileOperand.unlikely())); //set the negative flag - arm2ir.appendInstructionToCurrentBlock(BooleanCmp.create( + arm2ir.appendInstruction(BooleanCmp.create( BOOLEAN_CMP_INT, arm2ir.getNegativeFlag(), result, new OPT_IntConstantOperand(0), OPT_ConditionOperand.LESS(), new OPT_BranchProfileOperand())); //set the zero flag - arm2ir.appendInstructionToCurrentBlock(BooleanCmp.create( + arm2ir.appendInstruction(BooleanCmp.create( BOOLEAN_CMP_INT, arm2ir.getZeroFlag(), result, new OPT_IntConstantOperand(0), OPT_ConditionOperand.EQUAL(), new OPT_BranchProfileOperand())); } @@ -975,21 +1014,36 @@ } /** Sets the condition field for logical operations. */ - protected final void setLogicalResult(OPT_Operand result) { + protected final void setLogicalResult(OPT_RegisterOperand result) { if (updateConditionCodes) { if (Rd != 15) { setLogicalFlags(result); } else { OPT_Instruction s = createCallToRegisters("restoreSPSR2CPSR", "()V", 0); - arm2ir.appendInstructionToCurrentBlock(s); + arm2ir.appendInstruction(s); } } - arm2ir.appendInstructionToCurrentBlock(Move.create(INT_MOVE, arm2ir.getRegister(Rd), result) ); - if (Rd == 15) - arm2ir.setReturnValueResolveLazinessAndBranchToFinish(lazy, result); + + if (Rd == 15) { + if (updateConditionCodes) { + arm2ir.setReturnValueResolveLazinessAndBranchToFinish(lazy, result); + } + else { + BranchType branchType = BranchType.INDIRECT_BRANCH; + + //Mark "MOV pc, lr" instructions as returns + if (opcode == Opcode.MOV && operand2.getType() == OperandWrapper.Type.Register && operand2.getRegister() == ARM_Registers.LR) + branchType = BranchType.RETURN; + + arm2ir.appendDynamicJump(result, lazy, branchType); + } + } + else { + arm2ir.appendInstruction(Move.create(INT_MOVE, arm2ir.getRegister(Rd), result) ); + } } /** @@ -1001,11 +1055,11 @@ //the shifter carry out has already been set during the resolve-phase //set the negative flag - arm2ir.appendInstructionToCurrentBlock(BooleanCmp.create( + arm2ir.appendInstruction(BooleanCmp.create( BOOLEAN_CMP_INT, arm2ir.getNegativeFlag(), result, new OPT_IntConstantOperand(0), OPT_ConditionOperand.LESS(), new OPT_BranchProfileOperand())); //set the zero flag - arm2ir.appendInstructionToCurrentBlock(BooleanCmp.create( + arm2ir.appendInstruction(BooleanCmp.create( BOOLEAN_CMP_INT, arm2ir.getZeroFlag(), result, new OPT_IntConstantOperand(0), OPT_ConditionOperand.EQUAL(), new OPT_BranchProfileOperand())); } } @@ -1021,7 +1075,7 @@ public void translate() { OPT_RegisterOperand result = getResultRegister(); - arm2ir.appendInstructionToCurrentBlock(Binary.create(INT_AND, result, resolveOperand1(), resolveOperand2())); + arm2ir.appendInstruction(Binary.create(INT_AND, result, resolveOperand1(), resolveOperand2())); setLogicalResult(result); } @@ -1038,7 +1092,7 @@ public void translate() { OPT_RegisterOperand result = getResultRegister(); - arm2ir.appendInstructionToCurrentBlock(Binary.create(INT_XOR, result, resolveOperand1(), resolveOperand2())); + arm2ir.appendInstruction(Binary.create(INT_XOR, result, resolveOperand1(), resolveOperand2())); setLogicalResult(result); } @@ -1057,7 +1111,7 @@ OPT_Operand operand2 = resolveOperand2(); OPT_RegisterOperand result = getResultRegister(); - arm2ir.appendInstructionToCurrentBlock(Binary.create(INT_ADD, result, operand1, operand2)); + arm2ir.appendInstruction(Binary.create(INT_ADD, result, operand1, operand2)); setAddResult(result, operand1, operand2); } @@ -1076,7 +1130,7 @@ OPT_Operand operand2 = resolveOperand2(); OPT_RegisterOperand result = getResultRegister(); - arm2ir.appendInstructionToCurrentBlock(Binary.create(INT_SUB, result, operand1, operand2)); + arm2ir.appendInstruction(Binary.create(INT_SUB, result, operand1, operand2)); setSubResult(result, operand1, operand2); } @@ -1095,7 +1149,7 @@ OPT_Operand operand2 = resolveOperand2(); OPT_RegisterOperand result = getResultRegister(); - arm2ir.appendInstructionToCurrentBlock(Binary.create(INT_SUB, result, operand2, operand1)); + arm2ir.appendInstruction(Binary.create(INT_SUB, result, operand2, operand1)); setSubResult(result, operand2, operand1); } @@ -1121,13 +1175,13 @@ OPT_BasicBlock addWithCarry = arm2ir.createBlockAfterCurrentNotInCFG(); //Is the carry set at all? if not, just jump to addWithoutCarry - arm2ir.appendInstructionToCurrentBlock(Binary.create(INT_ADD, result, operand1, operand2)); - arm2ir.appendInstructionToCurrentBlock(IfCmp.create(INT_IFCMP, arm2ir.getTempValidation(0), arm2ir.getCarryFlag(), new OPT_IntConstantOperand(0), OPT_ConditionOperand.EQUAL(), addWithoutCarry.makeJumpTarget(), new OPT_BranchProfileOperand())); + arm2ir.appendInstruction(Binary.create(INT_ADD, result, operand1, operand2)); + arm2ir.appendInstruction(IfCmp.create(INT_IFCMP, arm2ir.getTempValidation(0), arm2ir.getCarryFlag(), 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.appendInstructionToCurrentBlock(Binary.create(INT_ADD, result, result, new OPT_IntConstantOperand(1))); + arm2ir.appendInstruction(Binary.create(INT_ADD, result, result, new OPT_IntConstantOperand(1))); addWithCarry.insertOut(addWithoutCarry); //Finally, add the second operands to the result @@ -1152,13 +1206,13 @@ OPT_BasicBlock subWithCarry = arm2ir.createBlockAfterCurrentNotInCFG(); //Is the carry set? if yes, just jump to subWithoutCarry - arm2ir.appendInstructionToCurrentBlock(Binary.create(INT_SUB, result, operand1, operand2)); - arm2... [truncated message content] |