Methods Summary |
---|
protected abstract java.lang.String | argString()Gets the string form for any arguments to this instance. Subclasses
must override this.
|
public abstract int | codeSize()Gets the size of this instruction, in 16-bit code units.
|
public com.android.dx.dex.code.DalvInsn | expandedPrefix(java.util.BitSet compatRegs)Gets the instruction prefix required, if any, to use in an expanded
version of this instance. Will not generate moves for registers
marked compatible to the format by the given BitSet.
RegisterSpecList regs = registers;
boolean firstBit = compatRegs.get(0);
if (hasResult()) compatRegs.set(0);
regs = regs.subset(compatRegs);
if (hasResult()) compatRegs.set(0, firstBit);
if (regs.size() == 0) return null;
return new HighRegisterPrefix(position, regs);
|
public com.android.dx.dex.code.DalvInsn | expandedSuffix(java.util.BitSet compatRegs)Gets the instruction suffix required, if any, to use in an expanded
version of this instance. Will not generate a move for a register
marked compatible to the format by the given BitSet.
if (hasResult() && !compatRegs.get(0)) {
RegisterSpec r = registers.get(0);
return makeMove(position, r, r.withReg(0));
} else {
return null;
}
|
public com.android.dx.dex.code.DalvInsn | expandedVersion(java.util.BitSet compatRegs)Gets the instruction that is equivalent to this one, except that
it replaces incompatible registers with sequential registers
starting at {@code 0} (storing the result, if any, in register
{@code 0} as well). The sequence of instructions from
{@link #expandedPrefix} and {@link #expandedSuffix} (if non-null)
surrounding the result of a call to this method are the expanded
transformation of this instance, and it is guaranteed that the
number of low registers used will be the number returned by
{@link #getMinimumRegisterRequirement}.
RegisterSpecList regs =
registers.withExpandedRegisters(0, hasResult(), compatRegs);
return withRegisters(regs);
|
public final int | getAddress()Gets the output address of this instruction, if it is known. This throws
a {@code RuntimeException} if it has not yet been set.
if (address < 0) {
throw new RuntimeException("address not yet known");
}
return address;
|
public com.android.dx.dex.code.DalvInsn | getLowRegVersion()Gets the instruction that is equivalent to this one, except that
it uses sequential registers starting at {@code 0} (storing
the result, if any, in register {@code 0} as well).
RegisterSpecList regs =
registers.withExpandedRegisters(0, hasResult(), null);
return withRegisters(regs);
|
public final int | getMinimumRegisterRequirement(java.util.BitSet compatRegs)Gets the minimum distinct registers required for this instruction.
Uses the given BitSet to determine which registers require
replacement, and ignores registers that are already compatible.
This assumes that the result (if any) can share registers with the
sources (if any), that each source register is unique, and that
(to be explicit here) category-2 values take up two consecutive
registers.
boolean hasResult = hasResult();
int regSz = registers.size();
int resultRequirement = 0;
int sourceRequirement = 0;
if (hasResult && !compatRegs.get(0)) {
resultRequirement = registers.get(0).getCategory();
}
for (int i = hasResult ? 1 : 0; i < regSz; i++) {
if (!compatRegs.get(i)) {
sourceRequirement += registers.get(i).getCategory();
}
}
return Math.max(sourceRequirement, resultRequirement);
|
public final int | getNextAddress()Gets the address immediately after this instance. This is only
calculable if this instance's address is known, and it is equal
to the address plus the length of the instruction format of this
instance's opcode.
return getAddress() + codeSize();
|
public final Dop | getOpcode()Gets the opcode.
return opcode;
|
public final com.android.dx.rop.code.SourcePosition | getPosition()Gets the source position.
return position;
|
public final com.android.dx.rop.code.RegisterSpecList | getRegisters()Gets the register list for this instruction.
return registers;
|
public final boolean | hasAddress()Gets whether the address of this instruction is known.
return (address >= 0);
|
public final boolean | hasResult()Returns whether this instance's opcode uses a result register.
This method is a convenient shorthand for
{@code getOpcode().hasResult()}.
return opcode.hasResult();
|
public final java.lang.String | identifierString()Gets the short identifier for this instruction. This is its
address, if assigned, or its identity hashcode if not.
if (address != -1) {
return String.format("%04x", address);
}
return Hex.u4(System.identityHashCode(this));
|
public final java.lang.String | listingString(java.lang.String prefix, int width, boolean noteIndices)Returns the string form of this instance suitable for inclusion in
a human-oriented listing dump. This method will return {@code null}
if this instance should not appear in a listing.
String insnPerSe = listingString0(noteIndices);
if (insnPerSe == null) {
return null;
}
String addr = prefix + identifierString() + ": ";
int w1 = addr.length();
int w2 = (width == 0) ? insnPerSe.length() : (width - w1);
return TwoColumnOutput.toString(addr, w1, "", insnPerSe, w2);
|
protected abstract java.lang.String | listingString0(boolean noteIndices)Helper for {@link #listingString}, which returns the string
form of this instance suitable for inclusion in a
human-oriented listing dump, not including the instruction
address and without respect for any output formatting. This
method should return {@code null} if this instance should
not appear in a listing.
|
public static SimpleInsn | makeMove(com.android.dx.rop.code.SourcePosition position, com.android.dx.rop.code.RegisterSpec dest, com.android.dx.rop.code.RegisterSpec src)Makes a move instruction, appropriate and ideal for the given arguments.
boolean category1 = dest.getCategory() == 1;
boolean reference = dest.getType().isReference();
int destReg = dest.getReg();
int srcReg = src.getReg();
Dop opcode;
if ((srcReg | destReg) < 16) {
opcode = reference ? Dops.MOVE_OBJECT :
(category1 ? Dops.MOVE : Dops.MOVE_WIDE);
} else if (destReg < 256) {
opcode = reference ? Dops.MOVE_OBJECT_FROM16 :
(category1 ? Dops.MOVE_FROM16 : Dops.MOVE_WIDE_FROM16);
} else {
opcode = reference ? Dops.MOVE_OBJECT_16 :
(category1 ? Dops.MOVE_16 : Dops.MOVE_WIDE_16);
}
return new SimpleInsn(opcode, position,
RegisterSpecList.make(dest, src));
|
public final void | setAddress(int address)Sets the output address.
if (address < 0) {
throw new IllegalArgumentException("address < 0");
}
this.address = address;
|
public final java.lang.String | toString(){@inheritDoc}
StringBuffer sb = new StringBuffer(100);
sb.append(identifierString());
sb.append(' ");
sb.append(position);
sb.append(": ");
sb.append(opcode.getName());
boolean needComma = false;
if (registers.size() != 0) {
sb.append(registers.toHuman(" ", ", ", null));
needComma = true;
}
String extra = argString();
if (extra != null) {
if (needComma) {
sb.append(',");
}
sb.append(' ");
sb.append(extra);
}
return sb.toString();
|
public com.android.dx.dex.code.DalvInsn | withMapper(com.android.dx.ssa.RegisterMapper mapper)Returns an instance that is just like this one, except that the
register list is mapped by using {@code mapper}.
return withRegisters(mapper.map(getRegisters()));
|
public abstract com.android.dx.dex.code.DalvInsn | withOpcode(Dop opcode)Returns an instance that is just like this one, except that its
opcode is replaced by the one given, and its address is reset.
|
public abstract com.android.dx.dex.code.DalvInsn | withRegisterOffset(int delta)Returns an instance that is just like this one, except that all
register references have been offset by the given delta, and its
address is reset.
|
public abstract com.android.dx.dex.code.DalvInsn | withRegisters(com.android.dx.rop.code.RegisterSpecList registers)Returns an instance that is just like this one, except that the
register list is replaced by the given one, and its address is
reset.
|
public abstract void | writeTo(com.android.dx.util.AnnotatedOutput out)Writes this instance to the given output. This method should
never annotate the output.
|