From: <mic...@us...> - 2007-05-10 15:21:58
|
Revision: 111 http://svn.sourceforge.net/pearcolator/?rev=111&view=rev Author: michael_baer Date: 2007-05-10 08:21:58 -0700 (Thu, 10 May 2007) Log Message: ----------- - fixed various problems in ARM's DBT part - fixed an interpreter bug, where LSL and ROR by 32 would produce a wrong result Modified Paths: -------------- src/org/binarytranslator/arch/arm/decoder/ARM2IR.java src/org/binarytranslator/arch/arm/decoder/ARM_Interpreter.java src/org/binarytranslator/arch/arm/decoder/ARM_Translator.java src/org/binarytranslator/arch/arm/os/process/ARM_ProcessSpace.java src/org/binarytranslator/arch/arm/os/process/image/ARM_ImageProcessSpace.java src/org/binarytranslator/generic/decoder/DecoderUtils.java src/org/binarytranslator/generic/memory/AutoMappingMemory.java src/org/binarytranslator/generic/memory/DebugMemory.java Modified: src/org/binarytranslator/arch/arm/decoder/ARM2IR.java =================================================================== --- src/org/binarytranslator/arch/arm/decoder/ARM2IR.java 2007-05-09 17:28:51 UTC (rev 110) +++ src/org/binarytranslator/arch/arm/decoder/ARM2IR.java 2007-05-10 15:21:58 UTC (rev 111) @@ -20,10 +20,22 @@ public class ARM2IR extends DecoderUtils implements OPT_HIRGenerator { /** Mapping of ARM registers to HIR registers */ - protected OPT_Register regMap[] = new OPT_Register[16]; + private OPT_Register regMap[] = new OPT_Register[16]; + /** The ARM carry flag. */ + private OPT_Register carryFlag; + + /** The ARM zero flag. */ + private OPT_Register zeroFlag; + + /** The ARM negative flag. */ + private OPT_Register negativeFlag; + + /** The ARM overflow flag. */ + private OPT_Register overflowFlag; + /** Set to true for each register that is in use during the current trace */ - protected boolean regUsed[] = new boolean[16]; + private boolean regUsed[] = new boolean[16]; /** Type reference to the ARM process space */ private static final VM_TypeReference psTref; @@ -38,15 +50,29 @@ private static final VM_FieldReference registers_regs_Fref; /** A type reference to the ARM registers array within the ARM_Registers class */ - private static final VM_TypeReference registers_regs_Tref; + private static final VM_TypeReference registers_regs_Tref; + /** A field reference to the carry flag within the ARM registers. */ + private static final VM_FieldReference registers_carryFlag_Fref; + + /** A field reference to the zero flag within the ARM registers. */ + private static final VM_FieldReference registers_zeroFlag_Fref; + + /** A field reference to the negative flag within the ARM registers. */ + private static final VM_FieldReference registers_negativeFlag_Fref; + + /** A field reference to the overflow flag within the ARM registers. */ + private static final VM_FieldReference registers_overflowFlag_Fref; + /** A register holding a reference to ps.registers */ private OPT_Register ps_registers; /** A register holding a reference to ps.registers.regs */ private OPT_Register ps_registers_regs; - + /** The class performing the actual translation of the bytecode. */ + private final ARM_Translator translator; + static { psTref = VM_TypeReference.findOrCreate(ARM_ProcessSpace.class); @@ -73,11 +99,40 @@ registers_regs_Tref = registers_regs_Fref.getFieldContentsType(); if (DBT.VerifyAssertions) DBT._assert(registers_regs_Tref != null); + + registers_carryFlag_Fref = VM_MemberReference + .findOrCreate(registersTref, + VM_Atom.findOrCreateAsciiAtom("flagCarry"), + VM_Atom.findOrCreateAsciiAtom("Z")).asFieldReference(); + + if (DBT.VerifyAssertions) DBT._assert(registers_carryFlag_Fref != null); + + registers_zeroFlag_Fref = VM_MemberReference + .findOrCreate(registersTref, + VM_Atom.findOrCreateAsciiAtom("flagZero"), + VM_Atom.findOrCreateAsciiAtom("Z")).asFieldReference(); + + if (DBT.VerifyAssertions) DBT._assert(registers_zeroFlag_Fref != null); + + registers_negativeFlag_Fref = VM_MemberReference + .findOrCreate(registersTref, + VM_Atom.findOrCreateAsciiAtom("flagNegative"), + VM_Atom.findOrCreateAsciiAtom("Z")).asFieldReference(); + + if (DBT.VerifyAssertions) DBT._assert(registers_negativeFlag_Fref != null); + + registers_overflowFlag_Fref = VM_MemberReference + .findOrCreate(registersTref, + VM_Atom.findOrCreateAsciiAtom("flagOverflow"), + VM_Atom.findOrCreateAsciiAtom("Z")).asFieldReference(); + + if (DBT.VerifyAssertions) DBT._assert(registers_overflowFlag_Fref != null); } public ARM2IR(OPT_GenerationContext context) { super(context); + translator = new ARM_Translator((ARM_ProcessSpace)ps, this); } @Override @@ -132,7 +187,7 @@ public OPT_RegisterOperand getArmRegistersReference() { OPT_RegisterOperand ps_registersOp; - if (ps_registers != null) { + if (ps_registers == null) { ps_registersOp = gc.temps.makeTemp(registersTref); ps_registers = ps_registersOp.register; appendInstructionToCurrentBlock(GetField.create(GETFIELD, ps_registersOp, @@ -154,14 +209,49 @@ //first resolve the current lazy state (i.e. calculate the values of registers that are not yet resolved) resolveLaziness(lazyState); + } + + private void spillAllFlags() { + + OPT_RegisterOperand ps_registersOp = getArmRegistersReference(); - //TODO: Implement - throw new RuntimeException("Not yet implemented"); + //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()) ); + + //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()) ); + + //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()) ); + + //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()) ); } public void fillAllFlags() { - //TODO: Implement - throw new RuntimeException("Not yet implemented"); + + //get an operand that contains a reference to the current ps.registers field. + OPT_RegisterOperand ps_registersOp = getArmRegistersReference(); + + //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()) ); + + //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()) ); + + //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()) ); + + //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()) ); } @Override @@ -199,6 +289,9 @@ new OPT_LocationOperand(VM_TypeReference.Int), new OPT_TrueGuardOperand())); } + + //fill all flags from the process space + fillAllFlags(); } public OPT_RegisterOperand getRegister(int r) { @@ -207,26 +300,21 @@ } public OPT_RegisterOperand getCarryFlag() { - //TODO: Implement - throw new RuntimeException("Not yet implemented"); + return new OPT_RegisterOperand(carryFlag, VM_TypeReference.Boolean); } public OPT_RegisterOperand getZeroFlag() { - //TODO: Implement - throw new RuntimeException("Not yet implemented"); + return new OPT_RegisterOperand(zeroFlag, VM_TypeReference.Boolean); } public OPT_RegisterOperand getNegativeFlag() { - //TODO: Implement - throw new RuntimeException("Not yet implemented"); + return new OPT_RegisterOperand(negativeFlag, VM_TypeReference.Boolean); } public OPT_RegisterOperand getOverflowFlag() { - //TODO: Implement - throw new RuntimeException("Not yet implemented"); + return new OPT_RegisterOperand(overflowFlag, VM_TypeReference.Boolean); } - @Override protected OPT_Register[] getUnusedRegisters() { @@ -268,13 +356,17 @@ new OPT_TrueGuardOperand())); } } + + //spill all flags to the process space + spillAllFlags(); } @Override protected int translateInstruction(Laziness lazy, int pc) { - return 0xEBADC0DE; - //ARM_InstructionDecoder.translateInstruction(this, - // (ARM_ProcessSpace) ps, (ARM_Laziness) lazy, pc); + System.out.println("Translating address: 0x" + Integer.toHexString(pc)); + System.out.println("Instruction: " + ARM_Disassembler.disassemble(pc, ps)); + + return translator.translateInstruction(pc, (ARM_Laziness)lazy); } /** Modified: src/org/binarytranslator/arch/arm/decoder/ARM_Interpreter.java =================================================================== --- src/org/binarytranslator/arch/arm/decoder/ARM_Interpreter.java 2007-05-09 17:28:51 UTC (rev 110) +++ src/org/binarytranslator/arch/arm/decoder/ARM_Interpreter.java 2007-05-10 15:21:58 UTC (rev 111) @@ -272,7 +272,7 @@ } if (shiftAmount == 32) { - shifterCarryOut = Utils.getBit(value, 31); + shifterCarryOut = (value & 0x1) != 0; return 0; } @@ -311,7 +311,7 @@ return value; } else { - shifterCarryOut = Utils.getBit(value, shiftAmount & 0x1F); + shifterCarryOut = Utils.getBit(value, (shiftAmount-1) & 0x1F); return Integer.rotateRight(value, shiftAmount); } Modified: src/org/binarytranslator/arch/arm/decoder/ARM_Translator.java =================================================================== --- src/org/binarytranslator/arch/arm/decoder/ARM_Translator.java 2007-05-09 17:28:51 UTC (rev 110) +++ src/org/binarytranslator/arch/arm/decoder/ARM_Translator.java 2007-05-10 15:21:58 UTC (rev 111) @@ -30,12 +30,29 @@ /** A "quick" pointer to the ARM registers within the process space*/ protected final ARM_Registers regs = null; + + private final ARM_InstructionDecoder.ARM_InstructionFactory<ARM_Instruction> translatorFactory = new TranslatorFactory(); public ARM_Translator(ARM_ProcessSpace ps, ARM2IR arm2ir) { this.ps = ps; this.arm2ir = arm2ir; } + public int translateInstruction(int pc, ARM_Laziness lazy) { + this.pc = pc; + this.lazy = lazy; + + int instruction = ps.memory.loadInstruction32(pc); + ARM_Instruction instr = ARM_InstructionDecoder.decode(instruction, translatorFactory); + + if (instr.getCondition() != Condition.AL) { + instr = new ConditionalDecorator(instr); + } + + instr.translate(); + return instr.getSuccessor(pc); + } + private OPT_Instruction createCallToRegisters(String methodName, String signature, int numParameters) { VM_TypeReference RegistersType = VM_TypeReference @@ -69,9 +86,11 @@ protected ARM_Translator translator; - public static ResolvedOperand resolveAndStoreShifterCarryOutToCarry( + public static OPT_Operand resolveAndStoreShifterCarryOutToCarry( ARM_Translator translator, OperandWrapper operand) { - throw new RuntimeException("Not yet implemented"); + + ResolvedOperand result = new ResolvedOperand_WithShifterCarryOut(translator, operand); + return result.getValue(); } public static OPT_Operand resolve(ARM_Translator translator, @@ -167,96 +186,36 @@ .getShiftingRegister()); } - OPT_BasicBlock currentBlock = translator.arm2ir.getCurrentBlock(); - OPT_BasicBlock nextBlock = translator.arm2ir.getNextBlock(); - - OPT_BasicBlock ifBlock; - OPT_BasicBlock elseBlock; - OPT_RegisterOperand resultRegister = getTempInt(); switch (operand.getShiftType()) { case ASR: /* - * if (shiftAmout >= 32) { value = shiftedOperand >> 31; shiftedOperand >> 1; } - * else - * value = shiftedOperand >> shiftAmount; + * shiftedOperand >> shiftAmount; */ - ifBlock = translator.arm2ir.createBlockAfterCurrentNotInCFG(); - elseBlock = translator.arm2ir.createBlockAfterCurrent(); - ifBlock.insertOut(nextBlock); - translator.arm2ir.appendInstructionToCurrentBlock(IfCmp.create( - INT_IFCMP, getTempValidation(), shiftAmount, - new OPT_IntConstantOperand(32), OPT_ConditionOperand - .GREATER_EQUAL(), ifBlock.makeJumpTarget(), - OPT_BranchProfileOperand.unlikely())); - currentBlock.insertOut(ifBlock); - - //shift - translator.arm2ir.setCurrentBlock(ifBlock); translator.arm2ir.appendInstructionToCurrentBlock(Binary.create( - INT_SHR, resultRegister, shiftedOperand, - new OPT_IntConstantOperand(31))); - translator.arm2ir.appendInstructionToCurrentBlock(Binary.create( - INT_SHR, resultRegister, shiftedOperand, - new OPT_IntConstantOperand(1))); - - translator.arm2ir.setCurrentBlock(elseBlock); - translator.arm2ir.appendInstructionToCurrentBlock(Binary.create( INT_SHR, resultRegister, shiftedOperand, shiftAmount)); - break; + return resultRegister; case LSL: /* - * if (shiftAmout >= 32) { value = 0; else value = shiftedOperand << - * shiftAmount; + * value = shiftedOperand << shiftAmount; */ - ifBlock = translator.arm2ir.createBlockAfterCurrentNotInCFG(); - elseBlock = translator.arm2ir.createBlockAfterCurrent(); - ifBlock.insertOut(nextBlock); - translator.arm2ir.appendInstructionToCurrentBlock(IfCmp.create( - INT_IFCMP, getTempValidation(), shiftAmount, - new OPT_IntConstantOperand(32), OPT_ConditionOperand - .GREATER_EQUAL(), ifBlock.makeJumpTarget(), - OPT_BranchProfileOperand.unlikely())); - currentBlock.insertOut(ifBlock); - - translator.arm2ir.setCurrentBlock(ifBlock); - translator.arm2ir.appendInstructionToCurrentBlock(Unary.create( - INT_MOVE, resultRegister, new OPT_IntConstantOperand(0))); - - translator.arm2ir.setCurrentBlock(elseBlock); translator.arm2ir.appendInstructionToCurrentBlock(Binary.create( INT_SHL, resultRegister, shiftedOperand, shiftAmount)); + return resultRegister; - break; - case LSR: /* - * if (shiftAmout >= 32) { value = 0; else value = shiftedOperand >>> - * shiftAmount; + * value = shiftedOperand >>> shiftAmount; + */ - ifBlock = translator.arm2ir.createBlockAfterCurrentNotInCFG(); - elseBlock = translator.arm2ir.createBlockAfterCurrent(); - ifBlock.insertOut(nextBlock); - translator.arm2ir.appendInstructionToCurrentBlock(IfCmp.create( - INT_IFCMP, getTempValidation(), shiftAmount, - new OPT_IntConstantOperand(32), OPT_ConditionOperand - .GREATER_EQUAL(), ifBlock.makeJumpTarget(), - OPT_BranchProfileOperand.unlikely())); - currentBlock.insertOut(ifBlock); - - translator.arm2ir.setCurrentBlock(ifBlock); - translator.arm2ir.appendInstructionToCurrentBlock(Unary.create( - INT_MOVE, resultRegister, new OPT_IntConstantOperand(0))); - - translator.arm2ir.setCurrentBlock(elseBlock); translator.arm2ir.appendInstructionToCurrentBlock(Binary.create( INT_USHR, resultRegister, shiftedOperand, shiftAmount)); - break; + return resultRegister; case ROR: /* @@ -267,8 +226,8 @@ case RRX: /* - * if (regs.isCarrySet()) return (resultRegister >> 1) | 0x80000000; - * else return resultRegister >>> 1; + * value = resultRegister >>> 1; + * if (regs.isCarrySet()) value |= 0x80000000; */ // resultRegister = resultRegister >>> 1 @@ -276,28 +235,34 @@ INT_USHR_ACC, resultRegister, new OPT_IntConstantOperand(1))); //conditionally, set resultRegister = resultRegister | 0x80000000; - ifBlock = translator.arm2ir.createBlockAfterCurrentNotInCFG(); - ifBlock.insertOut(nextBlock); + OPT_BasicBlock curBlock = translator.arm2ir.getCurrentBlock(); + + OPT_BasicBlock nextBlock = translator.arm2ir.getNextBlock(); + OPT_BasicBlock block1 = translator.arm2ir.createBlockAfterCurrentNotInCFG(); + + //Current block + curBlock.insertOut(block1); translator.arm2ir.appendInstructionToCurrentBlock(IfCmp.create( INT_IFCMP, getTempValidation(), translator.arm2ir.getCarryFlag(), new OPT_IntConstantOperand(1), OPT_ConditionOperand - .EQUAL(), ifBlock.makeJumpTarget(), - OPT_BranchProfileOperand.unlikely())); - currentBlock.insertOut(ifBlock); + .EQUAL(), block1.makeJumpTarget(), + new OPT_BranchProfileOperand())); + + //Block 1 + translator.arm2ir.setCurrentBlock(block1); + block1.insertOut(nextBlock); - translator.arm2ir.setCurrentBlock(ifBlock); translator.arm2ir.appendInstructionToCurrentBlock(Unary.create( INT_OR_ACC, resultRegister, new OPT_IntConstantOperand(0x80000000))); + + translator.arm2ir.setCurrentBlock(nextBlock); + translator.arm2ir.setNextBlock(translator.arm2ir.createBlockAfterCurrent()); + return resultRegister; - break; - default: throw new RuntimeException("Unexpected shift type: " + operand.getShiftType()); } - - translator.arm2ir.setCurrentBlock(nextBlock); - return resultRegister; } } @@ -356,21 +321,9 @@ } } - /** - * Translates a bit test, where bit <code>shifterResultBit</code> is tested within <code>value</code> and the result - * is put into the carry flag If <code>shifterResultBit</code> is less than 0, the carry is not changed. - * - */ - private void translateShifterCarryOut(OPT_Operand value, OPT_Operand shifterResultBit) { - - OPT_RegisterOperand carryFlag = translator.arm2ir.getCarryFlag(); - - - OPT_RegisterOperand tmp = getTempInt(); - translator.arm2ir.appendInstructionToCurrentBlock(Binary.create(INT_ADD, - tmp, shifterResultBit, new OPT_IntConstantOperand(1))); - translator.arm2ir.appendInstructionToCurrentBlock(BooleanCmp.create( - BOOLEAN_CMP_INT, carryFlag, value, tmp.copyRO(), OPT_ConditionOperand.BIT_TEST(), new OPT_BranchProfileOperand())); + /** Returns the register that receives the shifte carry out*/ + private OPT_RegisterOperand getShifterCarryOutTarget() { + return translator.arm2ir.getCarryFlag(); } /** @@ -402,140 +355,185 @@ .getShiftingRegister()); } - OPT_BasicBlock currentBlock = translator.arm2ir.getCurrentBlock(); + OPT_RegisterOperand resultRegister = getTempInt(); + OPT_BasicBlock nextBlock = translator.arm2ir.getNextBlock(); + OPT_BasicBlock curBlock = translator.arm2ir.getCurrentBlock(); + OPT_BasicBlock block1, block2, block3; + + OPT_RegisterOperand validation1 = translator.arm2ir.getTempValidation(9); + OPT_RegisterOperand validation2 = translator.arm2ir.getTempValidation(8); + + OPT_RegisterOperand tmp = translator.arm2ir.getTempInt(9); - OPT_BasicBlock ifBlock; - OPT_BasicBlock elseBlock; - - OPT_RegisterOperand resultRegister = getTempInt(); - switch (operand.getShiftType()) { case ASR: /* - * if (shiftAmout >= 32) { value = shiftedOperand >> 31; shiftedOperand >> 1; } - * else - * value = shiftedOperand >> shiftAmount; + * shiftedOperand >> shiftAmount; + * + * if (shiftAmount != 0) { + * shiftAmount = MIN(shiftAmount, 32); + * carry = shiftedOperand[shiftAmount] + * } */ - ifBlock = translator.arm2ir.createBlockAfterCurrentNotInCFG(); - ifBlock.insertOut(nextBlock); - elseBlock = translator.arm2ir.createBlockAfterCurrent(); - - translator.arm2ir.appendInstructionToCurrentBlock(IfCmp.create( - INT_IFCMP, getTempValidation(), shiftAmount, - new OPT_IntConstantOperand(32), OPT_ConditionOperand - .GREATER_EQUAL(), ifBlock.makeJumpTarget(), - new OPT_BranchProfileOperand())); - currentBlock.insertOut(ifBlock); - - //shift twice to simulate arithmetic shift-right by 32 - //circumvents java doing (shiftAmount MOD 32). - translator.arm2ir.setCurrentBlock(ifBlock); translator.arm2ir.appendInstructionToCurrentBlock(Binary.create( - INT_SHR, resultRegister, shiftedOperand, - new OPT_IntConstantOperand(31))); - translator.arm2ir.appendInstructionToCurrentBlock(Binary.create( - INT_SHR, resultRegister, shiftedOperand, - new OPT_IntConstantOperand(1))); - - translator.arm2ir.setCurrentBlock(elseBlock); - translator.arm2ir.appendInstructionToCurrentBlock(Binary.create( INT_SHR, resultRegister, shiftedOperand, shiftAmount)); - translateShifterCarryOut(resultRegister, shiftAmount); + + block3 = translator.arm2ir.createBlockAfterCurrentNotInCFG(); + block2 = translator.arm2ir.createBlockAfterCurrentNotInCFG(); + block1 = translator.arm2ir.createBlockAfterCurrentNotInCFG(); + + //current block + curBlock.insertOut(block1); + translator.arm2ir.appendInstructionToCurrentBlock(IfCmp.create(INT_IFCMP, validation1, shiftAmount, new OPT_IntConstantOperand(0), OPT_ConditionOperand.EQUAL(), nextBlock.makeJumpTarget(), OPT_BranchProfileOperand.unlikely())); + + //block 1 + translator.arm2ir.setCurrentBlock(block1); + block1.insertOut(block2); + block1.insertOut(block3); + translator.arm2ir.appendInstructionToCurrentBlock(IfCmp.create(INT_IFCMP, validation2, shiftAmount, new OPT_IntConstantOperand(32), OPT_ConditionOperand.GREATER(), block3.makeJumpTarget(), OPT_BranchProfileOperand.unlikely())); + + //block 2 + translator.arm2ir.setCurrentBlock(block2); + block2.insertOut(nextBlock); + translator.arm2ir.appendInstructionToCurrentBlock(BooleanCmp.create(BOOLEAN_CMP_INT, getShifterCarryOutTarget(), shiftedOperand, shiftAmount, OPT_ConditionOperand.BIT_TEST(), new OPT_BranchProfileOperand()) ); + + //block 3 + translator.arm2ir.setCurrentBlock(block3); + block3.insertOut(nextBlock); + translator.arm2ir.appendInstructionToCurrentBlock(BooleanCmp.create(BOOLEAN_CMP_INT, getShifterCarryOutTarget(), shiftedOperand, new OPT_IntConstantOperand(32), OPT_ConditionOperand.BIT_TEST(), new OPT_BranchProfileOperand()) ); + break; case LSL: /* - * if (shiftAmout >= 32) { value = 0; else value = shiftedOperand << - * shiftAmount; + * value = shiftedOperand << shiftAmount; */ - ifBlock = translator.arm2ir.createBlockAfterCurrentNotInCFG(); - elseBlock = translator.arm2ir.createBlockAfterCurrent(); - ifBlock.insertOut(nextBlock); - translator.arm2ir.appendInstructionToCurrentBlock(IfCmp.create( - INT_IFCMP, getTempValidation(), shiftAmount, - new OPT_IntConstantOperand(32), OPT_ConditionOperand - .GREATER_EQUAL(), ifBlock.makeJumpTarget(), - OPT_BranchProfileOperand.unlikely())); - currentBlock.insertOut(ifBlock); - - translator.arm2ir.setCurrentBlock(ifBlock); - translator.arm2ir.appendInstructionToCurrentBlock(Unary.create( - INT_MOVE, resultRegister, new OPT_IntConstantOperand(0))); - - translator.arm2ir.setCurrentBlock(elseBlock); translator.arm2ir.appendInstructionToCurrentBlock(Binary.create( INT_SHL, resultRegister, shiftedOperand, shiftAmount)); + + block3 = translator.arm2ir.createBlockAfterCurrentNotInCFG(); + block2 = translator.arm2ir.createBlockAfterCurrentNotInCFG(); + block1 = translator.arm2ir.createBlockAfterCurrentNotInCFG(); + + //current block + curBlock.insertOut(block1); + translator.arm2ir.appendInstructionToCurrentBlock(IfCmp.create(INT_IFCMP, validation1, shiftAmount, new OPT_IntConstantOperand(0), OPT_ConditionOperand.EQUAL(), nextBlock.makeJumpTarget(), OPT_BranchProfileOperand.unlikely())); + + //block 1 + translator.arm2ir.setCurrentBlock(block1); + block1.insertOut(block2); + block1.insertOut(block3); + translator.arm2ir.appendInstructionToCurrentBlock(IfCmp.create(INT_IFCMP, validation2, shiftAmount, new OPT_IntConstantOperand(32), OPT_ConditionOperand.GREATER(), block3.makeJumpTarget(), OPT_BranchProfileOperand.unlikely())); + + //block 2 + translator.arm2ir.setCurrentBlock(block2); + block2.insertOut(nextBlock); + translator.arm2ir.appendInstructionToCurrentBlock( Binary.create(INT_SUB, tmp, new OPT_IntConstantOperand(32), shiftAmount) ); + translator.arm2ir.appendInstructionToCurrentBlock(BooleanCmp.create(BOOLEAN_CMP_INT, getShifterCarryOutTarget(), shiftedOperand, tmp, OPT_ConditionOperand.BIT_TEST(), new OPT_BranchProfileOperand()) ); + + //block 3 + translator.arm2ir.setCurrentBlock(block3); + block3.insertOut(nextBlock); + translator.arm2ir.appendInstructionToCurrentBlock( Move.create(INT_MOVE, getShifterCarryOutTarget(), new OPT_IntConstantOperand(0)) ); break; case LSR: /* - * if (shiftAmout >= 32) { value = 0; else value = shiftedOperand >>> - * shiftAmount; + * value = shiftedOperand >>> shiftAmount; + */ - ifBlock = translator.arm2ir.createBlockAfterCurrentNotInCFG(); - elseBlock = translator.arm2ir.createBlockAfterCurrent(); - ifBlock.insertOut(nextBlock); - translator.arm2ir.appendInstructionToCurrentBlock(IfCmp.create( - INT_IFCMP, getTempValidation(), shiftAmount, - new OPT_IntConstantOperand(32), OPT_ConditionOperand - .GREATER_EQUAL(), ifBlock.makeJumpTarget(), - OPT_BranchProfileOperand.unlikely())); - currentBlock.insertOut(ifBlock); - - translator.arm2ir.setCurrentBlock(ifBlock); - translator.arm2ir.appendInstructionToCurrentBlock(Unary.create( - INT_MOVE, resultRegister, new OPT_IntConstantOperand(0))); - - translator.arm2ir.setCurrentBlock(elseBlock); translator.arm2ir.appendInstructionToCurrentBlock(Binary.create( INT_USHR, resultRegister, shiftedOperand, shiftAmount)); + block3 = translator.arm2ir.createBlockAfterCurrentNotInCFG(); + block2 = translator.arm2ir.createBlockAfterCurrentNotInCFG(); + block1 = translator.arm2ir.createBlockAfterCurrentNotInCFG(); + + //current block + curBlock.insertOut(block1); + translator.arm2ir.appendInstructionToCurrentBlock(IfCmp.create(INT_IFCMP, validation1, shiftAmount, new OPT_IntConstantOperand(0), OPT_ConditionOperand.EQUAL(), nextBlock.makeJumpTarget(), OPT_BranchProfileOperand.unlikely())); + + //block 1 + translator.arm2ir.setCurrentBlock(block1); + block1.insertOut(block2); + block1.insertOut(block3); + translator.arm2ir.appendInstructionToCurrentBlock(IfCmp.create(INT_IFCMP, validation2, shiftAmount, new OPT_IntConstantOperand(32), OPT_ConditionOperand.GREATER(), block3.makeJumpTarget(), OPT_BranchProfileOperand.unlikely())); + + //block 2 + translator.arm2ir.setCurrentBlock(block2); + block2.insertOut(nextBlock); + translator.arm2ir.appendInstructionToCurrentBlock(BooleanCmp.create(BOOLEAN_CMP_INT, getShifterCarryOutTarget(), shiftedOperand, shiftAmount, OPT_ConditionOperand.BIT_TEST(), new OPT_BranchProfileOperand()) ); + + //block 3 + translator.arm2ir.setCurrentBlock(block3); + block3.insertOut(nextBlock); + translator.arm2ir.appendInstructionToCurrentBlock( Move.create(INT_MOVE, getShifterCarryOutTarget(), new OPT_IntConstantOperand(0)) ); + break; case ROR: /* * return Integer.rotateRight(value, shiftAmount); */ - translator.arm2ir.appendRotateRight(resultRegister, shiftedOperand, - shiftAmount); - return resultRegister; + translator.arm2ir.appendRotateRight(resultRegister, shiftedOperand, shiftAmount); + + block1 = translator.arm2ir.createBlockAfterCurrentNotInCFG(); + + //current block + curBlock.insertOut(block1); + translator.arm2ir.appendInstructionToCurrentBlock(IfCmp.create(INT_IFCMP, validation1, shiftAmount, new OPT_IntConstantOperand(0), OPT_ConditionOperand.EQUAL(), nextBlock.makeJumpTarget(), OPT_BranchProfileOperand.unlikely())); + + //block 1 + translator.arm2ir.setCurrentBlock(block1); + block1.insertOut(nextBlock); + translator.arm2ir.appendInstructionToCurrentBlock( Binary.create(INT_SUB, tmp, shiftAmount, new OPT_IntConstantOperand(1)) ); + translator.arm2ir.appendInstructionToCurrentBlock( Binary.create(INT_AND, tmp, shiftAmount, new OPT_IntConstantOperand(0x1F)) ); + translator.arm2ir.appendInstructionToCurrentBlock(BooleanCmp.create(BOOLEAN_CMP_INT, getShifterCarryOutTarget(), shiftedOperand, tmp, OPT_ConditionOperand.BIT_TEST(), new OPT_BranchProfileOperand()) ); + + break; case RRX: /* - * if (regs.isCarrySet()) return (resultRegister >> 1) | 0x80000000; - * else return resultRegister >>> 1; + * value = resultRegister >>> 1; + * if (regs.isCarrySet()) value |= 0x80000000; */ // resultRegister = resultRegister >>> 1 translator.arm2ir.appendInstructionToCurrentBlock(Unary.create( INT_USHR_ACC, resultRegister, new OPT_IntConstantOperand(1))); + translator.arm2ir.appendInstructionToCurrentBlock(BooleanCmp.create(BOOLEAN_CMP_INT, getShifterCarryOutTarget(), shiftedOperand, new OPT_IntConstantOperand(1), OPT_ConditionOperand.BIT_TEST(), new OPT_BranchProfileOperand()) ); - ifBlock = translator.arm2ir.createBlockAfterCurrentNotInCFG(); - ifBlock.insertOut(nextBlock); + //conditionally, set resultRegister = resultRegister | 0x80000000; + block1 = translator.arm2ir.createBlockAfterCurrentNotInCFG(); + + //Current block + curBlock.insertOut(block1); translator.arm2ir.appendInstructionToCurrentBlock(IfCmp.create( INT_IFCMP, getTempValidation(), translator.arm2ir.getCarryFlag(), new OPT_IntConstantOperand(1), OPT_ConditionOperand - .EQUAL(), ifBlock.makeJumpTarget(), - OPT_BranchProfileOperand.unlikely())); - currentBlock.insertOut(ifBlock); + .EQUAL(), block1.makeJumpTarget(), + new OPT_BranchProfileOperand())); + + //Block 1 + translator.arm2ir.setCurrentBlock(block1); + block1.insertOut(nextBlock); - translator.arm2ir.setCurrentBlock(ifBlock); translator.arm2ir.appendInstructionToCurrentBlock(Unary.create( - INT_AND_ACC, resultRegister, new OPT_IntConstantOperand( - 0x80000000))); - + INT_OR_ACC, resultRegister, new OPT_IntConstantOperand(0x80000000))); + break; default: throw new RuntimeException("Unexpected shift type: " + operand.getShiftType()); } - + translator.arm2ir.setCurrentBlock(nextBlock); + translator.arm2ir.setNextBlock( translator.arm2ir.createBlockAfterCurrent() ); return resultRegister; } } @@ -564,6 +562,9 @@ /** performs the actual translation.*/ void translate(); + + /** Return the instruction following this one or -1, if that is not yet known. */ + int getSuccessor(int pc); } /** All ARM instructions that are supposed to be executed conditionally @@ -579,6 +580,14 @@ conditionalInstruction = i; } + 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; + } + public void translate() { //conditionals are implemented easily: if the condition does not hold, then just //jump to the block following the conditional instruction @@ -880,8 +889,7 @@ protected OPT_Operand resolveOperand2() { if (updateConditionCodes) { - ResolvedOperand resolvedOperand2 = ResolvedOperand.resolveAndStoreShifterCarryOutToCarry(ARM_Translator.this, operand2); - return resolvedOperand2.getValue(); + return ResolvedOperand.resolveAndStoreShifterCarryOutToCarry(ARM_Translator.this, operand2); } else { return super.resolveOperand2(); @@ -2032,9 +2040,9 @@ } - /** This class will create instances of the different interpreter instructions. It is being "controlled" by + /** This class will create instances of the different translated instructions. It is being "controlled" by * the ARM_InstructionDecoder, which uses an abstract factory pattern to decode an instruction. */ - private class InterpreterFactory implements + private class TranslatorFactory implements ARM_InstructionFactory<ARM_Instruction> { public ARM_Instruction createDataProcessing(int instr) { Modified: src/org/binarytranslator/arch/arm/os/process/ARM_ProcessSpace.java =================================================================== --- src/org/binarytranslator/arch/arm/os/process/ARM_ProcessSpace.java 2007-05-09 17:28:51 UTC (rev 110) +++ src/org/binarytranslator/arch/arm/os/process/ARM_ProcessSpace.java 2007-05-10 15:21:58 UTC (rev 111) @@ -2,6 +2,7 @@ import java.io.IOException; import org.binarytranslator.DBT_Options; +import org.binarytranslator.arch.arm.decoder.ARM2IR; import org.binarytranslator.arch.arm.decoder.ARM_Interpreter; import org.binarytranslator.arch.arm.os.process.image.ARM_ImageProcessSpace; import org.binarytranslator.arch.arm.os.process.linux.ARM_LinuxProcessSpace; @@ -47,8 +48,7 @@ * @return a HIR generator */ public OPT_HIRGenerator createHIRGenerator(OPT_GenerationContext context) { - System.out.println("Executing instr: " + memory.load32(0)); - throw new RuntimeException("Not yet implemented"); + return new ARM2IR(context); } /** Modified: src/org/binarytranslator/arch/arm/os/process/image/ARM_ImageProcessSpace.java =================================================================== --- src/org/binarytranslator/arch/arm/os/process/image/ARM_ImageProcessSpace.java 2007-05-09 17:28:51 UTC (rev 110) +++ src/org/binarytranslator/arch/arm/os/process/image/ARM_ImageProcessSpace.java 2007-05-10 15:21:58 UTC (rev 111) @@ -9,8 +9,6 @@ import org.binarytranslator.generic.execution.GdbController.GdbTarget; import org.binarytranslator.generic.memory.AutoMappingMemory; import org.binarytranslator.generic.os.loader.Loader; -import org.jikesrvm.compilers.opt.ir.OPT_GenerationContext; -import org.jikesrvm.compilers.opt.ir.OPT_HIRGenerator; public class ARM_ImageProcessSpace extends ARM_ProcessSpace { @@ -22,12 +20,6 @@ //make sure that pages of memory are automatically mapped in as they are requested. memory = new AutoMappingMemory(memory); } - - @Override - public OPT_HIRGenerator createHIRGenerator(OPT_GenerationContext context) - { - throw new UnsupportedOperationException("Not yet implemented."); - } @Override public void doSysCall() { @@ -37,9 +29,7 @@ ARM_Instructions.Instruction instr = ARM_InstructionDecoder.decode(instruction); if (DBT.VerifyAssertions) { - if (!(instr instanceof ARM_Instructions.SoftwareInterrupt)) { - throw new Error("The current instruction is not a valid system call."); - } + DBT._assert(instr instanceof ARM_Instructions.SoftwareInterrupt); } //Thumb system calls start from 0, while ARM calls start from 0x900000. Modified: src/org/binarytranslator/generic/decoder/DecoderUtils.java =================================================================== --- src/org/binarytranslator/generic/decoder/DecoderUtils.java 2007-05-09 17:28:51 UTC (rev 110) +++ src/org/binarytranslator/generic/decoder/DecoderUtils.java 2007-05-10 15:21:58 UTC (rev 111) @@ -447,6 +447,7 @@ * @return the next block */ public OPT_BasicBlock getNextBlock() { + return nextBlock; } Modified: src/org/binarytranslator/generic/memory/AutoMappingMemory.java =================================================================== --- src/org/binarytranslator/generic/memory/AutoMappingMemory.java 2007-05-09 17:28:51 UTC (rev 110) +++ src/org/binarytranslator/generic/memory/AutoMappingMemory.java 2007-05-10 15:21:58 UTC (rev 111) @@ -2,8 +2,6 @@ import java.io.RandomAccessFile; -import org.binarytranslator.vmInterface.TranslationHelper; -import org.jikesrvm.classloader.VM_MethodReference; /** * A memory implementation that will automatically map pages into memory, as soon @@ -31,10 +29,6 @@ return mem.equals(arg0); } - public VM_MethodReference getMethodRef(int callAddress) { - return mem.getMethodRef(callAddress); - } - public int getPageSize() { return mem.getPageSize(); } @@ -43,10 +37,6 @@ return mem.hashCode(); } - public void initTranslate(TranslationHelper helper) { - mem.initTranslate(helper); - } - public boolean isMapped(int addr) { return mem.isMapped(addr); } Modified: src/org/binarytranslator/generic/memory/DebugMemory.java =================================================================== --- src/org/binarytranslator/generic/memory/DebugMemory.java 2007-05-09 17:28:51 UTC (rev 110) +++ src/org/binarytranslator/generic/memory/DebugMemory.java 2007-05-10 15:21:58 UTC (rev 111) @@ -470,7 +470,7 @@ * @return the result */ public int load32(int addr) { - return (loadSigned8(addr + 3) << 24) | (loadUnsigned8(addr + 2) << 16) + return (loadUnsigned8(addr + 3) << 24) | (loadUnsigned8(addr + 2) << 16) | (loadUnsigned8(addr + 1) << 8) | loadUnsigned8(addr); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |