From: <mic...@us...> - 2007-04-13 15:01:40
|
Revision: 38 http://svn.sourceforge.net/pearcolator/?rev=38&view=rev Author: michael_baer Date: 2007-04-13 08:01:40 -0700 (Fri, 13 Apr 2007) Log Message: ----------- Added Support for half-word and signed data transfers. Added initial version of an ARM instruction decoder. Modified Paths: -------------- src/org/binarytranslator/arch/arm/decoder/ARM_InstructionDecoders.java src/org/binarytranslator/arch/arm/decoder/ARM_InstructionVisitor.java Added Paths: ----------- src/org/binarytranslator/arch/arm/decoder/ARM_InstructionDecoder.java src/org/binarytranslator/arch/arm/decoder/ARM_InstructionFactory.java Added: src/org/binarytranslator/arch/arm/decoder/ARM_InstructionDecoder.java =================================================================== --- src/org/binarytranslator/arch/arm/decoder/ARM_InstructionDecoder.java (rev 0) +++ src/org/binarytranslator/arch/arm/decoder/ARM_InstructionDecoder.java 2007-04-13 15:01:40 UTC (rev 38) @@ -0,0 +1,211 @@ +package org.binarytranslator.arch.arm.decoder; + +import org.binarytranslator.DBT; + +/** + * This class decodes an ARM instruction and uses a user-supplied ARM_InstructionFactory to create a class + * that represents the given instruction. + * + * I'm not happy with the structure of this module, but looking at the opcode map of the ARM, it's hard to + * provide a structured way of decoding primary and secondary opcodes efficiently. This class first looks at + * bits 25-27 and tries to decode as much from these as possible, using the decode_xxx functions. However, + * sometimes bits have to be checked in quite a non-systematic fashion to really catch all the cases that + * have been squeezed into newer ARM architectures. + * + * @author Michael Baer + * + */ +public class ARM_InstructionDecoder { + + /** + * Checks if a bit is set within a word. + * @param word + * The word that is being examined. + * @param bit + * The number of the bit that is to be checked, starting from zero. + * @return + * True, if the given bit is set within the word, false otherwise. + */ + private static final boolean getBit(int word, int bit) { + if (DBT.VerifyAssertions) + DBT._assert(bit >= 0 && bit <= 31); + return (word & (1 << bit)) != 0; + } + + public static <T> T decode(int instr, ARM_InstructionFactory<T> factory) { + if (getBit(instr, 27)) { + return decode_1xx(instr, factory); + } + else { + return decode_0xx(instr, factory); + } + } + + private static <T> T decode_0xx(int instr, ARM_InstructionFactory<T> factory) { + if ((instr & 0xF0000000) == 0xF0000000) { + return factory.createUndefinedInstruction(instr); + } + + if (getBit(instr, 26)) { + //opcode: 01 + if (getBit(instr, 25) && getBit(instr, 4)) + return factory.createUndefinedInstruction(instr); + else + return factory.createSingleDataTransfer(instr); + } + else { + //opcode: 00 + return decode_00x(instr, factory); + } + } + + private static <T> T decode_1xx(int instr, ARM_InstructionFactory<T> factory) { + if (getBit(instr, 26)) { + //opcode: 11 + return decode_11x( instr, factory); + } + else { + //opcode: 10 + return decode_10x(instr, factory); + } + } + + private static <T> T decode_00x(int instr, ARM_InstructionFactory<T> factory) { + if (getBit(instr, 25)) + return decode_001(instr, factory); + else + return decode_000(instr, factory); + } + + private static <T> T decode_10x(int instr, ARM_InstructionFactory<T> factory) { + if (getBit(instr, 25)) { + //opcode: 101 + if ((instr & 0xF0000000) == 0xF0000000) + return factory.createBranchExchange(instr); + else + return factory.createBranch(instr); + } + else { + //opcode: 100 + if ((instr & 0xF0000000) == 0xF0000000) + return factory.createUndefinedInstruction(instr); + else + return factory.createBlockDataTransfer(instr); + } + } + + private static <T> T decode_000(int instr, ARM_InstructionFactory<T> factory) { + //opcode: 000 + if (getBit(instr, 24) && !getBit(instr, 23) && !getBit(instr, 20)) { + //opcode: 00010xx0 - those are the new instructions, which the ARM ref. manual calls "misc. instructions" + return decode_00010xx0(instr, factory); + } + else { + if (getBit(instr, 4) == false || getBit(instr, 7) == false) + return factory.createDataProcessing(instr); + + return decode_multiplies_extra_load_stores(instr, factory); + } + } + + private static <T> T decode_001(int instr, ARM_InstructionFactory<T> factory) { + //opcode: 001 + if (!getBit(instr, 24) || getBit(instr, 23) || getBit(instr, 20)) { + return factory.createDataProcessing(instr); + } + + if (getBit(instr, 21)) + return factory.createMoveToStatusRegister(instr); + else + return factory.createUndefinedInstruction(instr); + } + + private static <T> T decode_11x(int instr, ARM_InstructionFactory<T> factory) { + + if (getBit(instr, 25) == false) { + //opcode: 110 + return factory.createCoprocessorDataTransfer(instr); + } + + //opcode: 111 + if (getBit(instr, 24)) { + //opcode: 1111 + if ((instr & 0xF0000000) == 0xF0000000) + return factory.createUndefinedInstruction(instr); + else + return factory.createSoftwareInterrupt(instr); + } + else { + //opcode: 1110 + if (getBit(instr, 4)) { + return factory.createCoprocessorDataTransfer(instr); + } + else { + return factory.createCoprocessorRegisterTransfer(instr); + } + } + } + /** Decodes instructions with the opcode 00010xx0 - those are the new instructions, which + * the ARM ref. manual calls "misc. instructions". + * + * @see Page A3-4 in the ARM Reference Manual (ARM DDI 0100 E) / 2000 + */ + private static <T> T decode_00010xx0(int instr, ARM_InstructionFactory<T> factory) { + // + if (getBit(instr, 6) || getBit(instr, 7)) { + //enhanced DSP multiplications, DSP add/subtracts and software breakpoints + //we might want to support these in the future, so when in debug mode, catch if any program actually uses them + if (DBT.VerifyAssertions) DBT._assert(false); + return factory.createUndefinedInstruction(instr); + } + else { + //bit 6 and 7 are clear + if (getBit(instr, 4)) { + if (getBit(instr, 22)) + return factory.createCountLeadingZeros(instr); + else + return factory.createBranchExchange(instr); + } + else { + if (getBit(instr, 21)) + return factory.createMoveToStatusRegister(instr); + else + return factory.createMoveFromStatusRegister(instr); + } + } + } + + /** This might appear even more weird, but I didn't design the ARM ISA. This function decodes + * all the operations defined on p. A3-3 in the ARM reference manual from 2000 (ARM DDI 0100 E). + * + * @see ARM Reference Manual (ARM DDI 0100 E) / 2000 + */ + private static <T> T decode_multiplies_extra_load_stores(int instr, ARM_InstructionFactory<T> factory) { + //Here, we already know that bits 4 and 7 are set, while bit 25-27 are clear + if (getBit(instr, 6)) { + //load/store signed half-word or two words + if (getBit(instr, 20)) + return factory.createSingleDataTransfer(instr); + else + return factory.createUndefinedInstruction(instr); //two words immediate offset + } + else { + if (getBit(instr, 5)) { + //load/store half-word + return factory.createSingleDataTransfer(instr); + } + else { + //Multiply, multiply long or Swap + if (getBit(instr, 24)) { + return factory.createSwap(instr); + } + else { + if (getBit(instr, 23)) + return factory.createLongMultiply(instr); + else + return factory.createIntMultiply(instr); + } + } + } + } +} Modified: src/org/binarytranslator/arch/arm/decoder/ARM_InstructionDecoders.java =================================================================== --- src/org/binarytranslator/arch/arm/decoder/ARM_InstructionDecoders.java 2007-04-13 11:16:14 UTC (rev 37) +++ src/org/binarytranslator/arch/arm/decoder/ARM_InstructionDecoders.java 2007-04-13 15:01:40 UTC (rev 38) @@ -2,6 +2,19 @@ import org.binarytranslator.DBT; +/** + * In the ARM decoder model, the decoding and usage (translating/interpreting/disassembling) of instructions + * is strictly separated. This class provides a namespace for all decoder classes. A decoder works like a + * mask than can be put upon a binary instruction to look at the different fields within that instruction. + * + * Application might derive from these decoders to implement instruction-specific functionality. + * Then, implement a version of the generic {@link ARM_InstructionFactory} interface, which returns + * your derived classes and pass it to the {@link ARM_InstructionDecoder} to let it create instances of + * your class from binary instructions. + * + * @author Michael Baer + * + */ public class ARM_InstructionDecoders { /** @@ -13,7 +26,7 @@ * @return * True, if the given bit is set within the word, false otherwise. */ - public static final boolean getBit(int word, int bit) { + private static final boolean getBit(int word, int bit) { if (DBT.VerifyAssertions) DBT._assert(bit >= 0 && bit <= 31); return (word & (1 << bit)) != 0; @@ -31,7 +44,7 @@ * @return * A zero-based version of the bit sequence. */ - public static final int getBits(int word, int from, int to) { + private static final int getBits(int word, int from, int to) { if (DBT.VerifyAssertions) DBT._assert(from < to && from >= 0 && to <= 31); return (word & ((1 << (to + 1)) - 1)) >> from; @@ -136,17 +149,17 @@ } /** Returns true, if the condition codes shall be updated by the result of this operation. */ - public boolean updateConditionCodes() { + public final boolean updateConditionCodes() { return updateConditionCodes; } /** Returns true, if this is the accumulate version of the instruction. */ - public boolean accumulate() { + public final boolean accumulate() { return accumulate; } /** Returns the register number of the Rs operand register. */ - public byte getRs() { + public final byte getRs() { return Rs; } } @@ -172,7 +185,7 @@ } /** Returns the coprocessor that shall process this instruction */ - public byte getCoprocessorNumber() { + public final byte getCoprocessorNumber() { return cpNum; } } @@ -180,6 +193,7 @@ /** Represents an operand, which might either be an immediate value, a register (shifted by an immediate) or a register shifted by a register. */ public abstract static class OperandWrapper { + /** Describes the type of the operand. */ public enum Type { Immediate, Register, @@ -187,6 +201,7 @@ RegisterShiftedRegister, } + /** Describes a type of shift, in case the operand is supposed to be shifted. */ public enum ShiftType { LogicalLeft, LogicalRight, @@ -236,6 +251,7 @@ } } + /** Returns the type of the operand that this class is actually representing. */ public abstract Type getType(); /** Returns the immediate, which is the 2nd operand of this instruction. Make sure that hasImmediate is true before calling this. */ @@ -263,8 +279,10 @@ throw new RuntimeException("Invalid call on an operand wrapper."); } + /** Represents an immediate value operand. */ protected static class ImmediateOperand extends OperandWrapper { + /** @see #getImmediate() */ protected final int immediate; protected ImmediateOperand(int immediate) { @@ -282,8 +300,10 @@ } } + /** Represents a register operand. */ protected static class RegisterOperand extends OperandWrapper { + /** @see #getRegister() */ protected final byte register; protected RegisterOperand(byte register) { @@ -301,9 +321,13 @@ } } + /** Represents an operand, which is a register shifted by an immediate value. */ protected static class RegisterShiftImmediateOperand extends RegisterOperand { + /** @see #getShiftType() */ protected final ShiftType shiftType; + + /** @see #getShiftAmount() */ protected final byte shiftAmount; protected RegisterShiftImmediateOperand(byte register, ShiftType shift, byte shiftAmount) { @@ -321,11 +345,20 @@ public byte getShiftAmount() { return shiftAmount; } + + @Override + public ShiftType getShiftType() { + return shiftType; + } } + /** Returns an operand, which is a register shifted by a register. */ protected static class RegisterShiftRegisterOperand extends RegisterOperand { + /** @see #getShiftType() */ protected final ShiftType shiftType; + + /** @see #getShiftingRegister() */ protected final byte shiftingRegister; protected RegisterShiftRegisterOperand(byte shiftedRegister, ShiftType shift, byte shiftingRegister) { @@ -343,11 +376,16 @@ public byte getShiftingRegister() { return shiftingRegister; } + + @Override + public ShiftType getShiftType() { + return shiftType; + } } } /** Represents a Data Processing instruction. */ - public final static class DataProcessing extends + public static class DataProcessing extends TwoRegistersTemplate { /** @see #hasSetConditionCodes() */ @@ -372,25 +410,20 @@ } /** Returns the opcode, that specifies the data processing operation, which is to be performed. */ - public byte getOpcode() { + public final byte getOpcode() { return opcode; } /** Returns true if the condition codes shall be set by this operation, false otherwise. */ - public boolean updateConditionCodes() { + public final boolean updateConditionCodes() { return updateConditionCodes; } /** Returns the 2nd operand of this data processing instruction. */ - public OperandWrapper getOperand2() { + public final OperandWrapper getOperand2() { return operand2; } - /** Checks if <code>instr</code> is a valid bit representation of this instruction. */ - public static boolean conforms(int instr) { - return getBits(instr, 26, 27) == 0; - } - @Override public void visit(ARM_InstructionVisitor visitor) { visitor.visit(this); @@ -398,17 +431,26 @@ } /** Represents a LDR/SDR instruction. */ - public final static class SingleDataTransfer extends + public static class SingleDataTransfer extends TwoRegistersTemplate { + + public enum TransferSize { + Byte, + HalfWord, + Word + } /** @see #preIndexing() */ protected final boolean preIndexing; /** @see #positiveOffset() */ protected final boolean positiveOffset; + + /** @see #signExtend() */ + protected final boolean signExtend; - /** @see #byteTransfer() */ - protected final boolean byteTransfer; + /** @see #getSize() */ + protected final TransferSize size; /** @see #writeBack() */ protected final boolean writeBack; @@ -416,58 +458,88 @@ /** @see #isLoad() */ protected final boolean isLoad; - /** @see #getOperand2() */ - protected final OperandWrapper operand2; + /** @see #getOffset() */ + protected final OperandWrapper offset; public SingleDataTransfer(int instr) { super(instr); preIndexing = getBit(instr, 24); positiveOffset = getBit(instr, 23); - byteTransfer = getBit(instr, 22); writeBack = getBit(instr, 21); isLoad = getBit(instr, 20); - if (getBit(instr, 25)) - operand2 = OperandWrapper.createImmediate(instr & 0xFF); - else - operand2 = OperandWrapper.decodeShiftedRegister(instr); + if (getBit(instr, 26)) { + //this is an unsigned byte or word transfer + signExtend = false; + + if (getBit(instr, 22)) + size = TransferSize.Byte; + else + size = TransferSize.Word; + + if (getBit(instr, 25)) + offset = OperandWrapper.createImmediate(instr & 0xFF); + else + offset = OperandWrapper.decodeShiftedRegister(instr); + } + else { + //this is a byte or half-word transfer + if (getBit(instr, 5)) + size = TransferSize.HalfWord; + else + size = TransferSize.Byte; + + signExtend = getBit(instr, 6); + + if (getBit(instr, 22)) { + //immediate offset + offset = OperandWrapper.createImmediate((getBits(instr, 8, 11) << 4) | (instr & 0xF)); + } + else { + //register offset + offset = OperandWrapper.createRegister((byte)(instr & 0xF)); + } + + //The decoder should make sure that we're never being called with this combination + if (DBT.VerifyAssertions) DBT._assert(!signExtend || isLoad); + } } + + /** Returns true, if the loaded/stored value shall be signed-extended.*/ + public final boolean signExtend() { + return signExtend; + } - /** Returns true, if a single byte is to be transfered or false if an int shall be transfered. */ - public boolean isByteTransfer() { - return byteTransfer; + /** Returns the number of bytes that have to be transferred. */ + public final TransferSize getSize() { + return size; } /** True if this is a LDM instruction, false if it is a STM instruction. */ - public boolean isLoad() { + public final boolean isLoad() { return isLoad; } /** Returns true, if the offset from the base register (see {@link #getRn()} is positive, false if it is negative. */ - public boolean positiveOffset() { + public final boolean positiveOffset() { return positiveOffset; } /** True if the base register shall be changed before the transfer, otherwise changed it after the transfer. */ - public boolean preIndexing() { + public final boolean preIndexing() { return preIndexing; } /** True if the incremented base register shall be persisted after this instruction. */ - public boolean writeBack() { + public final boolean writeBack() { return writeBack; } - /** Returns the 2nd operand of this data processing instruction. */ - public OperandWrapper getOperand2() { - return operand2; + /** Returns the offset operand for this data processing instruction. */ + public final OperandWrapper getOffset() { + return offset; } - - /** Checks if <code>instr</code> is a valid bit representation of this instruction. */ - public static boolean conforms(int instr) { - return getBits(instr, 26, 27) == 1; - } @Override public void visit(ARM_InstructionVisitor visitor) { @@ -476,17 +548,12 @@ } /** Represents a normal (not long) multiply instruction. */ - public final static class Multiply extends MultiplyTemplate { + public static class IntMultiply extends MultiplyTemplate { - protected Multiply(int instr) { + protected IntMultiply(int instr) { super(instr); } - /** Checks if <code>instr</code> is a valid bit representation of this instruction type. */ - public static boolean conforms(int instr) { - return getBits(instr, 22, 27) == 0 && getBits(instr, 4, 7) == 9; - } - @Override public void visit(ARM_InstructionVisitor visitor) { visitor.visit(this); @@ -494,7 +561,7 @@ } /** Represents a long multiply instruction. */ - public final static class LongMultiply extends MultiplyTemplate { + public static class LongMultiply extends MultiplyTemplate { /** @see #isUnsigned() */ protected final boolean unsigned; @@ -506,25 +573,20 @@ } /** Long multiplication stores its result in two registers. This function gets the register which receives the high int. */ - public byte getRdHigh() { + public final byte getRdHigh() { return Rd; } /** Long multiplication stores its result in two registers. This function gets the register which receives the low int. */ - public byte getRdLow() { + public final byte getRdLow() { return Rn; } /** Returns true, if this is an unsigned multiplication or false if it is a signed multiplication. */ - public boolean isUnsigned() { + public final boolean isUnsigned() { return unsigned; } - /** Checks if <code>instr</code> is a valid bit representation of this instruction type. */ - public static boolean conforms(int instr) { - return getBits(instr, 23, 27) == 1 && getBits(instr, 4, 7) == 9; - } - @Override public void visit(ARM_InstructionVisitor visitor) { visitor.visit(this); @@ -532,7 +594,7 @@ } /** Represents a SWP/SWPB instruction. */ - public final static class Swap extends ThreeRegistersTemplate { + public static class Swap extends ThreeRegistersTemplate { /** @see #swapByte() */ protected final boolean swapByte; @@ -543,16 +605,10 @@ } /** Returns true, if a byte shall be swapped or false, if an int (32 bit) shall be swapped. */ - public boolean swapByte() { + public final boolean swapByte() { return swapByte; } - /** Checks if <code>instr</code> is a valid bit representation of this instruction type. */ - public static boolean conforms(int instr) { - return getBits(instr, 23, 27) == 2 && getBits(instr, 20, 21) == 0 - && getBits(instr, 4, 11) == 9; - } - @Override public void visit(ARM_InstructionVisitor visitor) { visitor.visit(this); @@ -560,7 +616,7 @@ } /** Represents a LDM/STM instruction. */ - public final static class BlockDataTransfer extends Basic { + public static class BlockDataTransfer extends Basic { /** @see #preIndexing() */ protected final boolean preIndexing; @@ -595,13 +651,8 @@ registerList = instr; } - /** Checks if <code>instr</code> is a valid bit representation of this instruction. */ - public static boolean conforms(int instr) { - return getBits(instr, 25, 27) == 4; - } - /** @return True if register r should be transferred using this instruction. */ - public boolean transferRegister(int r) { + public final boolean transferRegister(int r) { if (DBT.VerifyAssertions) DBT._assert(r >= 0 && r < 16); @@ -609,32 +660,32 @@ } /** True if the base register shall be changed before each single transfer, otherwise changed it after each transfer. */ - public boolean preIndexing() { + public final boolean preIndexing() { return preIndexing; } /** True if the base register shall be incremented, false if it should be decremented. */ - public boolean incrementBase() { + public final boolean incrementBase() { return incrementBase; } /** Force user mode during this instruction? */ - public boolean forceUser() { + public final boolean forceUser() { return forceUser; } /** True if the incremented base register shall be persisted after this instruction. */ - public boolean writeBack() { + public final boolean writeBack() { return writeBack; } /** True if this is a LDM instruction, false if it is a STM instruction. */ - public boolean isLoad() { + public final boolean isLoad() { return isLoad; } /** The number of the register which will provides the base address for this LDM/STM instruction. */ - public byte getBaseRegister() { + public final byte getBaseRegister() { return baseRegister; } @@ -645,7 +696,7 @@ } /** Represents a SWI instruction*/ - public final static class SoftwareInterrupt extends Basic { + public static class SoftwareInterrupt extends Basic { /** @see #getInterruptNumber() */ protected final int interruptNumber; @@ -656,15 +707,10 @@ } /** Returns the interrupt that is being called. The value is taken from the instruction's comment field. */ - public int getInterruptNumber() { + public final int getInterruptNumber() { return interruptNumber; } - /** Checks if <code>instr</code> is a valid bit representation of this instruction. */ - public static boolean conforms(int instr) { - return getBits(instr, 24, 27) == 15; - } - @Override public void visit(ARM_InstructionVisitor visitor) { visitor.visit(this); @@ -672,7 +718,7 @@ } /** Represents a branch instruction. */ - public final static class Branch extends Basic { + public static class Branch extends Basic { /** @see #isBranchAndLink() */ protected final boolean link; @@ -687,20 +733,15 @@ } /** Should the current PC be put into the lr? */ - public boolean isBranchAndLink() { + public final boolean isBranchAndLink() { return link; } /** The offset of the target address to the PC */ - public int getOffset() { + public final int getOffset() { return offset; } - /** Checks if <code>instr</code> is a valid bit representation of this instruction. */ - public static boolean conforms(int instr) { - return getBits(instr, 25, 27) == 5; - } - @Override public void visit(ARM_InstructionVisitor visitor) { visitor.visit(this); @@ -708,7 +749,7 @@ } /** Represents a BX instruction set */ - public final static class BranchExchange extends Basic { + public static class BranchExchange extends Basic { /** @see #getRn() */ protected final OperandWrapper target; @@ -739,16 +780,10 @@ } /** Returns, whether the return address for this jump shall be put into the lr. */ - public boolean link() { + public final boolean link() { return link; } - /** Checks if <code>instr</code> is a valid bit representation of this instruction. */ - public static boolean conforms(int instr) { - return getBits(instr, 25, 31) == 0x7D // BLX(1) - || (getBits(instr, 20, 27) == 0x12 && getBits(instr, 6, 7) == 0); //BLX(2) && BX - } - @Override public void visit(ARM_InstructionVisitor visitor) { visitor.visit(this); @@ -756,7 +791,7 @@ } /** Represents a LDC/STC instruction. */ - public static final class CoprocessorDataTransfer extends CoprocessorTemplate { + public static class CoprocessorDataTransfer extends CoprocessorTemplate { /** @see #getOffset() */ protected final int offset; @@ -788,44 +823,39 @@ } /** Returns the number of the register, which contains the base address for this data transfer.*/ - public byte getBaseRegister() { + public final byte getBaseRegister() { return Rn; } /** Returns the transfer register on the coprocessor. */ - public byte getCoprocessorRegister() { + public final byte getCoprocessorRegister() { return Rd; } /** True if this is a LDC instruction, false if it is a STC instruction. */ - public boolean isLoad() { + public final boolean isLoad() { return isLoad; } /** Returns the offset that should be added to the base register. Note that the offset may be negative. */ - public int getOffset() { + public final int getOffset() { return offset; } /** True if the changed base register shall be persisted after this instruction. */ - public boolean writeBack() { + public final boolean writeBack() { return writeBack; } /** True if the base register shall be changed before the transfer, otherwise changed it after the transfer. */ - public boolean preIndexing() { + public final boolean preIndexing() { return preIndexing; } /** Returns true, if the flag which indicates a large transfer is set. The meaning of "large transfer" is dependend on the coprocessor.*/ - public boolean largeTransfer() { + public final boolean largeTransfer() { return largeTransfer; } - - /** Checks if <code>instr</code> is a valid bit representation of this instruction type. */ - public static boolean conforms(int instr) { - return getBits(instr, 25, 27) == 6; - } @Override public void visit(ARM_InstructionVisitor visitor) { @@ -834,7 +864,7 @@ } /** Represents a CDP instruction. */ - public final static class CoprocessorDataProcessing extends CoprocessorTemplate { + public static class CoprocessorDataProcessing extends CoprocessorTemplate { /** @see #getOpcode() */ protected final byte opcode; @@ -854,34 +884,29 @@ } /** Returns the destination register of this operation. This register is a coprocessor register. */ - public byte getCoprocessorRd() { + public final byte getCoprocessorRd() { return Rd; } /** Returns the first operand register of this operation. This register is a coprocessor register. */ - public byte getCoprocessorRn() { + public final byte getCoprocessorRn() { return Rn; } /** Returns the second operand register of this operation. This register is a coprocessor register. */ - public byte getCoprocessorRm() { + public final byte getCoprocessorRm() { return cpRm; } /** The instruction contains three bits that may be used to control the details of the operation. This info is only of significance to the coprocessor. */ - public byte getCoprocessorInfo() { + public final byte getCoprocessorInfo() { return cpInfo; } /** Returns the opcode, that identifies the operation that shall be performed on the coprocessor. This vlaue is only of significance to the coprocessor. */ - public byte getOpcode() { + public final byte getOpcode() { return opcode; } - - /** Checks if <code>instr</code> is a valid bit representation of this instruction type. */ - public static boolean conforms(int instr) { - return getBits(instr, 24, 27) == 14 && !getBit(instr, 4); - } @Override public void visit(ARM_InstructionVisitor visitor) { @@ -890,7 +915,7 @@ } /** Represents a MRC/MCR instruction. */ - public final static class CoprocessorRegisterTransfer extends CoprocessorTemplate { + public static class CoprocessorRegisterTransfer extends CoprocessorTemplate { /** @see #getOpcode() */ protected final byte opcode; @@ -914,39 +939,34 @@ } /** Returns true if this operation is a load from a coprocessor or false if it is a store to coprocessor. */ - public boolean isLoadFromCP() { + public final boolean isLoadFromCP() { return isLoad; } /** Returns the destination register of this operation.*/ - public byte getRd() { + public final byte getRd() { return Rd; } /** Returns the first operand register of this operation. This register is a coprocessor register. */ - public byte getCoprocessorRn() { + public final byte getCoprocessorRn() { return Rn; } /** Returns the second operand register of this operation. This register is a coprocessor register. */ - public byte getCoprocessorRm() { + public final byte getCoprocessorRm() { return cpRm; } /** The instruction contains three bits that may be used to control the details of the operation. This info is only of significance to the coprocessor. */ - public byte getCoprocessorInfo() { + public final byte getCoprocessorInfo() { return cpInfo; } /** Returns the opcode, that identifies the operation that shall be performed on the coprocessor. This vlaue is only of significance to the coprocessor. */ - public byte getOpcode() { + public final byte getOpcode() { return opcode; } - - /** Checks if <code>instr</code> is a valid bit representation of this instruction type. */ - public static boolean conforms(int instr) { - return getBits(instr, 24, 27) == 14 && getBit(instr, 4); - } @Override public void visit(ARM_InstructionVisitor visitor) { @@ -955,7 +975,7 @@ } /** Represents a MRS instruction. */ - public final static class TransferFromStatusRegister extends Basic { + public static class MoveFromStatusRegister extends Basic { /** @see #getRd() */ protected final byte Rd; @@ -963,7 +983,7 @@ /** @see #transferSavedPSR() */ protected final boolean transferSavedPSR; - public TransferFromStatusRegister(int instr) { + public MoveFromStatusRegister(int instr) { super(instr); Rd = (byte) getBits(instr, 12, 15); @@ -971,19 +991,14 @@ } /** Returns the number of the destination register. */ - public byte getRd() { + public final byte getRd() { return Rd; } /** Identifies the PSR that is to be transferred: true for the SPSR, false for the CPSR. */ - public boolean transferSavedPSR() { + public final boolean transferSavedPSR() { return transferSavedPSR; } - - /** Checks if <code>instr</code> is a valid bit representation of this instruction type. */ - public static boolean conforms(int instr) { - return getBits(instr, 23, 27) == 2 && getBits(instr, 16, 21) == 0 && (instr & 0xFFF) == 0; - } @Override public void visit(ARM_InstructionVisitor visitor) { @@ -992,7 +1007,7 @@ } /** Represents a MSR instruction. */ - public final static class TransferToStatusRegister extends Basic { + public static class MoveToStatusRegister extends Basic { /** @see #transferControlField() */ protected final boolean transferControl; @@ -1012,7 +1027,7 @@ /** @see #getSourceOperand() */ protected final OperandWrapper sourceOperand; - public TransferToStatusRegister(int instr) { + public MoveToStatusRegister(int instr) { super(instr); transferControl = getBit(instr, 16); @@ -1029,39 +1044,34 @@ } /** Identifies the PSR that is to be transferred: true for the SPSR, false for the CPSR. */ - public boolean transferSavedPSR() { + public final boolean transferSavedPSR() { return transferSavedPSR; } /** Returns true if the control field of the PSR shall be overwritten. */ - public boolean transferControlField() { + public final boolean transferControlField() { return transferControl; } /** Returns true if the extension field of the PSR shall be overwritten. */ - public boolean transferExtensionField() { + public final boolean transferExtensionField() { return transferExtension; } /** Returns true if the status field of the PSR shall be overwritten. */ - public boolean transferStatusField() { + public final boolean transferStatusField() { return transferStatus; } /** Returns true if the flag field of the PSR shall be overwritten. */ - public boolean transferFlagField() { + public final boolean transferFlagField() { return transferFlags; } /** Returns the operand, which is to be transfered into the status register. */ - public OperandWrapper getSourceOperand() { + public final OperandWrapper getSourceOperand() { return sourceOperand; } - - /** Checks if <code>instr</code> is a valid bit representation of this instruction type. */ - public static boolean conforms(int instr) { - return getBits(instr, 26, 27) == 0 && getBits(instr, 23, 24) == 2 && getBits(instr, 12, 15) == 0; - } @Override public void visit(ARM_InstructionVisitor visitor) { @@ -1070,7 +1080,7 @@ } /** Represents a CLZ instruction. */ - public final static class CountLeadingZeros extends Basic { + public static class CountLeadingZeros extends Basic { /** @see #getRm() */ protected final byte Rm; @@ -1086,19 +1096,14 @@ } /** Returns the source register for this operation. */ - public byte getRm() { + public final byte getRm() { return Rm; } /** Returns the destination register for this operation. */ - public byte getRd() { + public final byte getRd() { return Rd; } - - /** Checks if <code>instr</code> is a valid bit representation of this instruction type. */ - public static boolean conforms(int instr) { - return getBits(instr, 16, 27) == 0x16F && getBits(instr, 4, 11) == 0xF1; - } @Override public void visit(ARM_InstructionVisitor visitor) { Added: src/org/binarytranslator/arch/arm/decoder/ARM_InstructionFactory.java =================================================================== --- src/org/binarytranslator/arch/arm/decoder/ARM_InstructionFactory.java (rev 0) +++ src/org/binarytranslator/arch/arm/decoder/ARM_InstructionFactory.java 2007-04-13 15:01:40 UTC (rev 38) @@ -0,0 +1,20 @@ +package org.binarytranslator.arch.arm.decoder; + +public interface ARM_InstructionFactory<T> { + T createDataProcessing(int instr); + T createSingleDataTransfer(int instr); + T createBlockDataTransfer(int instr); + T createIntMultiply(int instr); + T createLongMultiply(int instr); + T createSwap(int instr); + T createSoftwareInterrupt(int instr); + T createBranch(int instr); + T createBranchExchange(int instr); + T createCoprocessorDataTransfer(int instr); + T createCoprocessorDataProcessing(int instr); + T createCoprocessorRegisterTransfer(int instr); + T createMoveFromStatusRegister(int instr); + T createMoveToStatusRegister(int instr); + T createCountLeadingZeros(int instr); + T createUndefinedInstruction(int instr); +} Modified: src/org/binarytranslator/arch/arm/decoder/ARM_InstructionVisitor.java =================================================================== --- src/org/binarytranslator/arch/arm/decoder/ARM_InstructionVisitor.java 2007-04-13 11:16:14 UTC (rev 37) +++ src/org/binarytranslator/arch/arm/decoder/ARM_InstructionVisitor.java 2007-04-13 15:01:40 UTC (rev 38) @@ -1,27 +1,13 @@ package org.binarytranslator.arch.arm.decoder; -import org.binarytranslator.arch.arm.decoder.ARM_InstructionDecoders.BlockDataTransfer; -import org.binarytranslator.arch.arm.decoder.ARM_InstructionDecoders.Branch; -import org.binarytranslator.arch.arm.decoder.ARM_InstructionDecoders.BranchExchange; -import org.binarytranslator.arch.arm.decoder.ARM_InstructionDecoders.CoprocessorDataProcessing; -import org.binarytranslator.arch.arm.decoder.ARM_InstructionDecoders.CoprocessorDataTransfer; -import org.binarytranslator.arch.arm.decoder.ARM_InstructionDecoders.CoprocessorRegisterTransfer; -import org.binarytranslator.arch.arm.decoder.ARM_InstructionDecoders.CountLeadingZeros; -import org.binarytranslator.arch.arm.decoder.ARM_InstructionDecoders.DataProcessing; -import org.binarytranslator.arch.arm.decoder.ARM_InstructionDecoders.LongMultiply; -import org.binarytranslator.arch.arm.decoder.ARM_InstructionDecoders.Multiply; -import org.binarytranslator.arch.arm.decoder.ARM_InstructionDecoders.SingleDataTransfer; -import org.binarytranslator.arch.arm.decoder.ARM_InstructionDecoders.SoftwareInterrupt; -import org.binarytranslator.arch.arm.decoder.ARM_InstructionDecoders.Swap; -import org.binarytranslator.arch.arm.decoder.ARM_InstructionDecoders.TransferFromStatusRegister; -import org.binarytranslator.arch.arm.decoder.ARM_InstructionDecoders.TransferToStatusRegister; +import org.binarytranslator.arch.arm.decoder.ARM_InstructionDecoders.*; /** An interface that supports iterating over ARM instructions using the visitor pattern. */ public interface ARM_InstructionVisitor { void visit(DataProcessing processing); void visit(SingleDataTransfer transfer); - void visit(Multiply multiply); + void visit(IntMultiply multiply); void visit(LongMultiply multiply); void visit(Swap swap); void visit(BlockDataTransfer transfer); @@ -31,7 +17,7 @@ void visit(CoprocessorDataTransfer transfer); void visit(CoprocessorDataProcessing processing); void visit(CoprocessorRegisterTransfer transfer); - void visit(TransferFromStatusRegister register); - void visit(TransferToStatusRegister register); + void visit(MoveFromStatusRegister register); + void visit(MoveToStatusRegister register); void visit(CountLeadingZeros zeros); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |