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 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 final int | getMinimumRegisterRequirement()Gets the minimum distinct registers required for this instruction.
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 = hasResult ? registers.get(0).getCategory() : 0;
int sourceRequirement = 0;
for (int i = hasResult ? 1 : 0; i < regSz; 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.dexgen.rop.code.SourcePosition | getPosition()Gets the source position.
return position;
|
public final com.android.dexgen.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 com.android.dexgen.dex.code.DalvInsn | hrPrefix()Gets the instruction prefix required, if any, to use in a high
register transformed version of this instance.
RegisterSpecList regs = registers;
int sz = regs.size();
if (hasResult()) {
if (sz == 1) {
return null;
}
regs = regs.withoutFirst();
} else if (sz == 0) {
return null;
}
return new HighRegisterPrefix(position, regs);
|
public com.android.dexgen.dex.code.DalvInsn | hrSuffix()Gets the instruction suffix required, if any, to use in a high
register transformed version of this instance.
if (hasResult()) {
RegisterSpec r = registers.get(0);
return makeMove(position, r, r.withReg(0));
} else {
return null;
}
|
public com.android.dexgen.dex.code.DalvInsn | hrVersion()Gets the instruction that is equivalent to this one, except that
uses sequential registers starting at {@code 0} (storing
the result, if any, in register {@code 0} as well). The
sequence of instructions from {@link #hrPrefix} and {@link
#hrSuffix} (if non-null) surrounding the result of a call to
this method are the high register 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.withSequentialRegisters(0, hasResult());
return withRegisters(regs);
|
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.dexgen.rop.code.SourcePosition position, com.android.dexgen.rop.code.RegisterSpec dest, com.android.dexgen.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 abstract com.android.dexgen.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.dexgen.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.dexgen.dex.code.DalvInsn | withRegisters(com.android.dexgen.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.dexgen.util.AnnotatedOutput out)Writes this instance to the given output. This method should
never annotate the output.
|