use of com.android.dx.rop.code.RegisterSpec in project buck by facebook.
the class RopToDop method dopFor.
/**
* Returns the dalvik opcode appropriate for the given register-based
* instruction.
*
* @param insn {@code non-null;} the original instruction
* @return the corresponding dalvik opcode; one of the constants in
* {@link Dops}
*/
public static Dop dopFor(Insn insn) {
Rop rop = insn.getOpcode();
/*
* First, just try looking up the rop in the MAP of easy
* cases.
*/
Dop result = MAP.get(rop);
if (result != null) {
return result;
}
switch(rop.getOpcode()) {
case RegOps.MOVE_EXCEPTION:
return Dops.MOVE_EXCEPTION;
case RegOps.INVOKE_STATIC:
return Dops.INVOKE_STATIC;
case RegOps.INVOKE_VIRTUAL:
return Dops.INVOKE_VIRTUAL;
case RegOps.INVOKE_SUPER:
return Dops.INVOKE_SUPER;
case RegOps.INVOKE_DIRECT:
return Dops.INVOKE_DIRECT;
case RegOps.INVOKE_INTERFACE:
return Dops.INVOKE_INTERFACE;
case RegOps.NEW_ARRAY:
return Dops.NEW_ARRAY;
case RegOps.FILLED_NEW_ARRAY:
return Dops.FILLED_NEW_ARRAY;
case RegOps.FILL_ARRAY_DATA:
return Dops.FILL_ARRAY_DATA;
case RegOps.MOVE_RESULT:
{
RegisterSpec resultReg = insn.getResult();
if (resultReg == null) {
return Dops.NOP;
} else {
switch(resultReg.getBasicType()) {
case Type.BT_INT:
case Type.BT_FLOAT:
case Type.BT_BOOLEAN:
case Type.BT_BYTE:
case Type.BT_CHAR:
case Type.BT_SHORT:
return Dops.MOVE_RESULT;
case Type.BT_LONG:
case Type.BT_DOUBLE:
return Dops.MOVE_RESULT_WIDE;
case Type.BT_OBJECT:
return Dops.MOVE_RESULT_OBJECT;
default:
{
throw new RuntimeException("Unexpected basic type");
}
}
}
}
case RegOps.GET_FIELD:
{
CstFieldRef ref = (CstFieldRef) ((ThrowingCstInsn) insn).getConstant();
int basicType = ref.getBasicType();
switch(basicType) {
case Type.BT_BOOLEAN:
return Dops.IGET_BOOLEAN;
case Type.BT_BYTE:
return Dops.IGET_BYTE;
case Type.BT_CHAR:
return Dops.IGET_CHAR;
case Type.BT_SHORT:
return Dops.IGET_SHORT;
case Type.BT_INT:
return Dops.IGET;
}
break;
}
case RegOps.PUT_FIELD:
{
CstFieldRef ref = (CstFieldRef) ((ThrowingCstInsn) insn).getConstant();
int basicType = ref.getBasicType();
switch(basicType) {
case Type.BT_BOOLEAN:
return Dops.IPUT_BOOLEAN;
case Type.BT_BYTE:
return Dops.IPUT_BYTE;
case Type.BT_CHAR:
return Dops.IPUT_CHAR;
case Type.BT_SHORT:
return Dops.IPUT_SHORT;
case Type.BT_INT:
return Dops.IPUT;
}
break;
}
case RegOps.GET_STATIC:
{
CstFieldRef ref = (CstFieldRef) ((ThrowingCstInsn) insn).getConstant();
int basicType = ref.getBasicType();
switch(basicType) {
case Type.BT_BOOLEAN:
return Dops.SGET_BOOLEAN;
case Type.BT_BYTE:
return Dops.SGET_BYTE;
case Type.BT_CHAR:
return Dops.SGET_CHAR;
case Type.BT_SHORT:
return Dops.SGET_SHORT;
case Type.BT_INT:
return Dops.SGET;
}
break;
}
case RegOps.PUT_STATIC:
{
CstFieldRef ref = (CstFieldRef) ((ThrowingCstInsn) insn).getConstant();
int basicType = ref.getBasicType();
switch(basicType) {
case Type.BT_BOOLEAN:
return Dops.SPUT_BOOLEAN;
case Type.BT_BYTE:
return Dops.SPUT_BYTE;
case Type.BT_CHAR:
return Dops.SPUT_CHAR;
case Type.BT_SHORT:
return Dops.SPUT_SHORT;
case Type.BT_INT:
return Dops.SPUT;
}
break;
}
case RegOps.CONST:
{
Constant cst = ((ThrowingCstInsn) insn).getConstant();
if (cst instanceof CstType) {
return Dops.CONST_CLASS;
} else if (cst instanceof CstString) {
return Dops.CONST_STRING;
}
break;
}
}
throw new RuntimeException("unknown rop: " + rop);
}
use of com.android.dx.rop.code.RegisterSpec in project buck by facebook.
the class Form35c method wordCount.
/**
* Gets the number of words required for the given register list, where
* category-2 values count as two words. Return {@code -1} if the
* list requires more than five words or contains registers that need
* more than a nibble to identify them.
*
* @param regs {@code non-null;} the register list in question
* @return {@code >= -1;} the number of words required, or {@code -1}
* if the list couldn't possibly fit in this format
*/
private static int wordCount(RegisterSpecList regs) {
int sz = regs.size();
if (sz > MAX_NUM_OPS) {
// It can't possibly fit.
return -1;
}
int result = 0;
for (int i = 0; i < sz; i++) {
RegisterSpec one = regs.get(i);
result += one.getCategory();
/*
* The check below adds (category - 1) to the register, to
* account for the fact that the second half of a
* category-2 register has to be represented explicitly in
* the result.
*/
if (!unsignedFitsInNibble(one.getReg() + one.getCategory() - 1)) {
return -1;
}
}
return (result <= MAX_NUM_OPS) ? result : -1;
}
use of com.android.dx.rop.code.RegisterSpec in project buck by facebook.
the class Form35c method explicitize.
/**
* Returns a register list which is equivalent to the given one,
* except that it splits category-2 registers into two explicit
* entries. This returns the original list if no modification is
* required
*
* @param orig {@code non-null;} the original list
* @return {@code non-null;} the list with the described transformation
*/
private static RegisterSpecList explicitize(RegisterSpecList orig) {
int wordCount = wordCount(orig);
int sz = orig.size();
if (wordCount == sz) {
return orig;
}
RegisterSpecList result = new RegisterSpecList(wordCount);
int wordAt = 0;
for (int i = 0; i < sz; i++) {
RegisterSpec one = orig.get(i);
result.set(wordAt, one);
if (one.getCategory() == 2) {
result.set(wordAt + 1, RegisterSpec.make(one.getReg() + 1, Type.VOID));
wordAt += 2;
} else {
wordAt++;
}
}
result.setImmutable();
return result;
}
use of com.android.dx.rop.code.RegisterSpec in project buck by facebook.
the class HighRegisterPrefix method listingString0.
/** {@inheritDoc} */
@Override
protected String listingString0(boolean noteIndices) {
RegisterSpecList registers = getRegisters();
int sz = registers.size();
StringBuffer sb = new StringBuffer(100);
for (int i = 0, outAt = 0; i < sz; i++) {
RegisterSpec src = registers.get(i);
SimpleInsn insn = moveInsnFor(src, outAt);
if (i != 0) {
sb.append('\n');
}
sb.append(insn.listingString0(noteIndices));
outAt += src.getCategory();
}
return sb.toString();
}
use of com.android.dx.rop.code.RegisterSpec in project buck by facebook.
the class InsnFormat method isRegListSequential.
/**
* Helper method to determine if a list of registers are sequential,
* including degenerate cases for empty or single-element lists.
*
* @param list {@code non-null;} the list of registers
* @return {@code true} iff the list is sequentially ordered
*/
protected static boolean isRegListSequential(RegisterSpecList list) {
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;
}
Aggregations