Methods Summary |
---|
protected static int | argIndex(DalvInsn insn)Helper method to extract the callout-argument index from an
appropriate instruction.
int arg = ((CstInteger) ((CstInsn) insn).getConstant()).getValue();
if (arg < 0) {
throw new IllegalArgumentException("bogus insn");
}
return arg;
|
protected static java.lang.String | branchComment(DalvInsn insn)Helper method to return the comment for a branch.
TargetInsn ti = (TargetInsn) insn;
int offset = ti.getTargetOffset();
return (offset == (short) offset) ? Hex.s2(offset) : Hex.s4(offset);
|
public boolean | branchFits(TargetInsn insn)Returns whether or not the given instruction's branch offset will
fit in this instance's format. This always returns {@code false}
for formats that don't include a branch offset.
The default implementation of this method always returns
{@code false}. Subclasses must override this method if they
include branch offsets.
return false;
|
protected static java.lang.String | branchString(DalvInsn insn)Helper method to return a branch address string.
TargetInsn ti = (TargetInsn) insn;
int address = ti.getTargetAddress();
return (address == (char) address) ? Hex.u2(address) : Hex.u4(address);
|
public abstract int | codeSize()Gets the code size of instructions that use this format. The
size is a number of 16-bit code units, not bytes. This should
throw an exception if this format is of variable size.
|
protected static short | codeUnit(int low, int high)Helper method to combine two bytes into a code unit.
if ((low & 0xff) != low) {
throw new IllegalArgumentException("low out of range 0..255");
}
if ((high & 0xff) != high) {
throw new IllegalArgumentException("high out of range 0..255");
}
return (short) (low | (high << 8));
|
protected static short | codeUnit(int n0, int n1, int n2, int n3)Helper method to combine four nibbles into a code unit.
if ((n0 & 0xf) != n0) {
throw new IllegalArgumentException("n0 out of range 0..15");
}
if ((n1 & 0xf) != n1) {
throw new IllegalArgumentException("n1 out of range 0..15");
}
if ((n2 & 0xf) != n2) {
throw new IllegalArgumentException("n2 out of range 0..15");
}
if ((n3 & 0xf) != n3) {
throw new IllegalArgumentException("n3 out of range 0..15");
}
return (short) (n0 | (n1 << 4) | (n2 << 8) | (n3 << 12));
|
public java.util.BitSet | compatibleRegs(DalvInsn insn)Returns which of a given instruction's registers will fit in
this instance's format.
The default implementation of this method always returns
an empty BitSet. Subclasses must override this method if they
have registers.
return new BitSet();
|
protected static java.lang.String | cstComment(DalvInsn insn)Helper method to return an instruction comment for a constant.
CstInsn ci = (CstInsn) insn;
if (! ci.hasIndex()) {
return "";
}
StringBuilder sb = new StringBuilder(20);
int index = ci.getIndex();
sb.append(ci.getConstant().typeName());
sb.append('@");
if (index < 65536) {
sb.append(Hex.u2(index));
} else {
sb.append(Hex.u4(index));
}
return sb.toString();
|
protected static java.lang.String | cstString(DalvInsn insn)Helper method to return the constant string for a {@link CstInsn}
in human form.
CstInsn ci = (CstInsn) insn;
Constant cst = ci.getConstant();
return cst instanceof CstString ? ((CstString) cst).toQuoted() : cst.toHuman();
|
public abstract java.lang.String | insnArgString(DalvInsn insn)Returns the string form of the arguments to the given instruction.
The instruction must be of this instance's format. If the instruction
has no arguments, then the result should be {@code ""}, not
{@code null}.
Subclasses must override this method.
|
public abstract java.lang.String | insnCommentString(DalvInsn insn, boolean noteIndices)Returns the associated comment for the given instruction, if any.
The instruction must be of this instance's format. If the instruction
has no comment, then the result should be {@code ""}, not
{@code null}.
Subclasses must override this method.
|
public abstract boolean | isCompatible(DalvInsn insn)Returns whether or not the given instruction's arguments will
fit in this instance's format. This includes such things as
counting register arguments, checking register ranges, and
making sure that additional arguments are of appropriate types
and are in-range. If this format has a branch target but the
instruction's branch offset is unknown, this method will simply
not check the offset.
Subclasses must override this method.
|
protected static boolean | isRegListSequential(com.android.dx.rop.code.RegisterSpecList list)Helper method to determine if a list of registers are sequential,
including degenerate cases for empty or single-element lists.
int sz = list.size();
if (sz < 2) {
return true;
}
int first = list.get(0).getReg();
int next = first;
for (int i = 0; i < sz; i++) {
RegisterSpec one = list.get(i);
if (one.getReg() != next) {
return false;
}
next += one.getCategory();
}
return true;
|
public final java.lang.String | listingString(DalvInsn insn, boolean noteIndices)Returns the string form, suitable for inclusion in a listing
dump, of the given instruction. The instruction must be of this
instance's format for proper operation.
String op = insn.getOpcode().getName();
String arg = insnArgString(insn);
String comment = insnCommentString(insn, noteIndices);
StringBuilder sb = new StringBuilder(100);
sb.append(op);
if (arg.length() != 0) {
sb.append(' ");
sb.append(arg);
}
if (comment.length() != 0) {
sb.append(" // ");
sb.append(comment);
}
return sb.toString();
|
protected static java.lang.String | literalBitsComment(com.android.dx.rop.cst.CstLiteralBits value, int width)Helper method to return a literal bits comment string.
StringBuffer sb = new StringBuffer(20);
sb.append("#");
long bits;
if (value instanceof CstLiteral64) {
bits = ((CstLiteral64) value).getLongBits();
} else {
bits = value.getIntBits();
}
switch (width) {
case 4: sb.append(Hex.uNibble((int) bits)); break;
case 8: sb.append(Hex.u1((int) bits)); break;
case 16: sb.append(Hex.u2((int) bits)); break;
case 32: sb.append(Hex.u4((int) bits)); break;
case 64: sb.append(Hex.u8(bits)); break;
default: {
throw new RuntimeException("shouldn't happen");
}
}
return sb.toString();
|
protected static java.lang.String | literalBitsString(com.android.dx.rop.cst.CstLiteralBits value)Helper method to return a literal bits argument string.
StringBuffer sb = new StringBuffer(100);
sb.append('#");
if (value instanceof CstKnownNull) {
sb.append("null");
} else {
sb.append(value.typeName());
sb.append(' ");
sb.append(value.toHuman());
}
return sb.toString();
|
protected static int | makeByte(int low, int high)Helper method to combine two nibbles into a byte.
if ((low & 0xf) != low) {
throw new IllegalArgumentException("low out of range 0..15");
}
if ((high & 0xf) != high) {
throw new IllegalArgumentException("high out of range 0..15");
}
return low | (high << 4);
|
protected static short | opcodeUnit(DalvInsn insn, int arg)Helper method to combine an opcode and a second byte of data into
the appropriate form for emitting into a code buffer.
if ((arg & 0xff) != arg) {
throw new IllegalArgumentException("arg out of range 0..255");
}
int opcode = insn.getOpcode().getOpcode();
if ((opcode & 0xff) != opcode) {
throw new IllegalArgumentException("opcode out of range 0..255");
}
return (short) (opcode | (arg << 8));
|
protected static short | opcodeUnit(DalvInsn insn)Helper method to get an extended (16-bit) opcode out of an
instruction, returning it as a code unit. The opcode
must be an extended opcode.
int opcode = insn.getOpcode().getOpcode();
if ((opcode < 0x100) || (opcode > 0xffff)) {
throw new IllegalArgumentException("opcode out of range 0..65535");
}
return (short) opcode;
|
protected static java.lang.String | regListString(com.android.dx.rop.code.RegisterSpecList list)Helper method to return a register list string.
int sz = list.size();
StringBuffer sb = new StringBuffer(sz * 5 + 2);
sb.append('{");
for (int i = 0; i < sz; i++) {
if (i != 0) {
sb.append(", ");
}
sb.append(list.get(i).regString());
}
sb.append('}");
return sb.toString();
|
protected static java.lang.String | regRangeString(com.android.dx.rop.code.RegisterSpecList list)Helper method to return a register range string.
int size = list.size();
StringBuilder sb = new StringBuilder(30);
sb.append("{");
switch (size) {
case 0: {
// Nothing to do.
break;
}
case 1: {
sb.append(list.get(0).regString());
break;
}
default: {
RegisterSpec lastReg = list.get(size - 1);
if (lastReg.getCategory() == 2) {
/*
* Add one to properly represent a list-final
* category-2 register.
*/
lastReg = lastReg.withOffset(1);
}
sb.append(list.get(0).regString());
sb.append("..");
sb.append(lastReg.regString());
}
}
sb.append("}");
return sb.toString();
|
protected static boolean | signedFitsInByte(int value)Helper method to determine if a signed int value fits in a byte.
return (byte) value == value;
|
protected static boolean | signedFitsInNibble(int value)Helper method to determine if a signed int value fits in a nibble.
return (value >= -8) && (value <= 7);
|
protected static boolean | signedFitsInShort(int value)Helper method to determine if a signed int value fits in a short.
return (short) value == value;
|
protected static boolean | unsignedFitsInByte(int value)Helper method to determine if an unsigned int value fits in a byte.
return value == (value & 0xff);
|
protected static boolean | unsignedFitsInNibble(int value)Helper method to determine if an unsigned int value fits in a nibble.
return value == (value & 0xf);
|
protected static boolean | unsignedFitsInShort(int value)Helper method to determine if an unsigned int value fits in a short.
return value == (value & 0xffff);
|
protected static void | write(com.android.dx.util.AnnotatedOutput out, short c0)Writes one code unit to the given output destination.
out.writeShort(c0);
|
protected static void | write(com.android.dx.util.AnnotatedOutput out, short c0, short c1)Writes two code units to the given output destination.
out.writeShort(c0);
out.writeShort(c1);
|
protected static void | write(com.android.dx.util.AnnotatedOutput out, short c0, short c1, short c2)Writes three code units to the given output destination.
out.writeShort(c0);
out.writeShort(c1);
out.writeShort(c2);
|
protected static void | write(com.android.dx.util.AnnotatedOutput out, short c0, short c1, short c2, short c3)Writes four code units to the given output destination.
out.writeShort(c0);
out.writeShort(c1);
out.writeShort(c2);
out.writeShort(c3);
|
protected static void | write(com.android.dx.util.AnnotatedOutput out, short c0, short c1, short c2, short c3, short c4)Writes five code units to the given output destination.
out.writeShort(c0);
out.writeShort(c1);
out.writeShort(c2);
out.writeShort(c3);
out.writeShort(c4);
|
protected static void | write(com.android.dx.util.AnnotatedOutput out, short c0, int c1c2)Writes three code units to the given output destination, where the
second and third are represented as single int and emitted
in little-endian order.
write(out, c0, (short) c1c2, (short) (c1c2 >> 16));
|
protected static void | write(com.android.dx.util.AnnotatedOutput out, short c0, int c1c2, short c3)Writes four code units to the given output destination, where the
second and third are represented as single int and emitted
in little-endian order.
write(out, c0, (short) c1c2, (short) (c1c2 >> 16), c3);
|
protected static void | write(com.android.dx.util.AnnotatedOutput out, short c0, int c1c2, short c3, short c4)Writes five code units to the given output destination, where the
second and third are represented as single int and emitted
in little-endian order.
write(out, c0, (short) c1c2, (short) (c1c2 >> 16), c3, c4);
|
protected static void | write(com.android.dx.util.AnnotatedOutput out, short c0, long c1c2c3c4)Writes five code units to the given output destination, where the
second through fifth are represented as single long
and emitted in little-endian order.
write(out, c0, (short) c1c2c3c4, (short) (c1c2c3c4 >> 16),
(short) (c1c2c3c4 >> 32), (short) (c1c2c3c4 >> 48));
|
public abstract void | writeTo(com.android.dx.util.AnnotatedOutput out, DalvInsn insn)Writes the code units for the given instruction to the given
output destination. The instruction must be of this instance's format.
Subclasses must override this method.
|