Search in sources :

Example 1 with RegisterSpec

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);
}
Also used : Rop(com.android.dx.rop.code.Rop) ThrowingCstInsn(com.android.dx.rop.code.ThrowingCstInsn) Constant(com.android.dx.rop.cst.Constant) CstType(com.android.dx.rop.cst.CstType) CstFieldRef(com.android.dx.rop.cst.CstFieldRef) CstString(com.android.dx.rop.cst.CstString) RegisterSpec(com.android.dx.rop.code.RegisterSpec)

Example 2 with RegisterSpec

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;
}
Also used : RegisterSpec(com.android.dx.rop.code.RegisterSpec)

Example 3 with RegisterSpec

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;
}
Also used : RegisterSpecList(com.android.dx.rop.code.RegisterSpecList) RegisterSpec(com.android.dx.rop.code.RegisterSpec)

Example 4 with RegisterSpec

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();
}
Also used : RegisterSpecList(com.android.dx.rop.code.RegisterSpecList) RegisterSpec(com.android.dx.rop.code.RegisterSpec)

Example 5 with RegisterSpec

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;
}
Also used : RegisterSpec(com.android.dx.rop.code.RegisterSpec)

Aggregations

RegisterSpec (com.android.dx.rop.code.RegisterSpec)135 RegisterSpecList (com.android.dx.rop.code.RegisterSpecList)50 PlainInsn (com.android.dx.rop.code.PlainInsn)24 Constant (com.android.dx.rop.cst.Constant)20 TypedConstant (com.android.dx.rop.cst.TypedConstant)16 TypeBearer (com.android.dx.rop.type.TypeBearer)16 ArrayList (java.util.ArrayList)16 Insn (com.android.dx.rop.code.Insn)14 PlainCstInsn (com.android.dx.rop.code.PlainCstInsn)14 Rop (com.android.dx.rop.code.Rop)14 ThrowingCstInsn (com.android.dx.rop.code.ThrowingCstInsn)14 CstType (com.android.dx.rop.cst.CstType)14 BitSet (java.util.BitSet)11 LocalItem (com.android.dx.rop.code.LocalItem)10 RegisterSpecSet (com.android.dx.rop.code.RegisterSpecSet)10 ThrowingInsn (com.android.dx.rop.code.ThrowingInsn)10 CstString (com.android.dx.rop.cst.CstString)10 HashSet (java.util.HashSet)10 SourcePosition (com.android.dx.rop.code.SourcePosition)8 CstFieldRef (com.android.dx.rop.cst.CstFieldRef)8