Search in sources :

Example 6 with RegisterSpec

use of com.android.dx.rop.code.RegisterSpec in project buck by facebook.

the class OutputFinisher method hasLocalInfo.

/**
     * Helper for {@link #add} which scrutinizes a single
     * instruction for local variable information.
     *
     * @param insn {@code non-null;} instruction to scrutinize
     * @return {@code true} iff the instruction refers to any
     * named locals
     */
private static boolean hasLocalInfo(DalvInsn insn) {
    if (insn instanceof LocalSnapshot) {
        RegisterSpecSet specs = ((LocalSnapshot) insn).getLocals();
        int size = specs.size();
        for (int i = 0; i < size; i++) {
            if (hasLocalInfo(specs.get(i))) {
                return true;
            }
        }
    } else if (insn instanceof LocalStart) {
        RegisterSpec spec = ((LocalStart) insn).getLocal();
        if (hasLocalInfo(spec)) {
            return true;
        }
    }
    return false;
}
Also used : RegisterSpecSet(com.android.dx.rop.code.RegisterSpecSet) RegisterSpec(com.android.dx.rop.code.RegisterSpec)

Example 7 with RegisterSpec

use of com.android.dx.rop.code.RegisterSpec in project buck by facebook.

the class OutputFinisher method align64bits.

private void align64bits(Dop[] opcodes) {
    while (true) {
        int notAligned64bitRegAccess = 0;
        int aligned64bitRegAccess = 0;
        int notAligned64bitParamAccess = 0;
        int aligned64bitParamAccess = 0;
        int lastParameter = unreservedRegCount + reservedCount + reservedParameterCount;
        int firstParameter = lastParameter - paramSize;
        // Collects the number of time that 64-bit registers are accessed aligned or not.
        for (DalvInsn insn : insns) {
            RegisterSpecList regs = insn.getRegisters();
            for (int usedRegIdx = 0; usedRegIdx < regs.size(); usedRegIdx++) {
                RegisterSpec reg = regs.get(usedRegIdx);
                if (reg.isCategory2()) {
                    boolean isParameter = reg.getReg() >= firstParameter;
                    if (reg.isEvenRegister()) {
                        if (isParameter) {
                            aligned64bitParamAccess++;
                        } else {
                            aligned64bitRegAccess++;
                        }
                    } else {
                        if (isParameter) {
                            notAligned64bitParamAccess++;
                        } else {
                            notAligned64bitRegAccess++;
                        }
                    }
                }
            }
        }
        if (notAligned64bitParamAccess > aligned64bitParamAccess && notAligned64bitRegAccess > aligned64bitRegAccess) {
            addReservedRegisters(1);
        } else if (notAligned64bitParamAccess > aligned64bitParamAccess) {
            addReservedParameters(1);
        } else if (notAligned64bitRegAccess > aligned64bitRegAccess) {
            addReservedRegisters(1);
            // so the number of aligned become the number of unaligned.
            if (paramSize != 0 && aligned64bitParamAccess > notAligned64bitParamAccess) {
                addReservedParameters(1);
            }
        } else {
            break;
        }
        if (!reserveRegisters(opcodes)) {
            break;
        }
    }
}
Also used : RegisterSpecList(com.android.dx.rop.code.RegisterSpecList) RegisterSpec(com.android.dx.rop.code.RegisterSpec)

Example 8 with RegisterSpec

use of com.android.dx.rop.code.RegisterSpec in project buck by facebook.

the class Form21c method isCompatible.

/** {@inheritDoc} */
@Override
public boolean isCompatible(DalvInsn insn) {
    if (!(insn instanceof CstInsn)) {
        return false;
    }
    RegisterSpecList regs = insn.getRegisters();
    RegisterSpec reg;
    switch(regs.size()) {
        case 1:
            {
                reg = regs.get(0);
                break;
            }
        case 2:
            {
                /*
                 * This format is allowed for ops that are effectively
                 * 2-arg but where the two args are identical.
                 */
                reg = regs.get(0);
                if (reg.getReg() != regs.get(1).getReg()) {
                    return false;
                }
                break;
            }
        default:
            {
                return false;
            }
    }
    if (!unsignedFitsInByte(reg.getReg())) {
        return false;
    }
    CstInsn ci = (CstInsn) insn;
    int cpi = ci.getIndex();
    Constant cst = ci.getConstant();
    if (!unsignedFitsInShort(cpi)) {
        return false;
    }
    return (cst instanceof CstType) || (cst instanceof CstFieldRef) || (cst instanceof CstString);
}
Also used : CstInsn(com.android.dx.dex.code.CstInsn) 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) RegisterSpecList(com.android.dx.rop.code.RegisterSpecList) RegisterSpec(com.android.dx.rop.code.RegisterSpec)

Example 9 with RegisterSpec

use of com.android.dx.rop.code.RegisterSpec in project buck by facebook.

the class Form31c method isCompatible.

/** {@inheritDoc} */
@Override
public boolean isCompatible(DalvInsn insn) {
    if (!(insn instanceof CstInsn)) {
        return false;
    }
    RegisterSpecList regs = insn.getRegisters();
    RegisterSpec reg;
    switch(regs.size()) {
        case 1:
            {
                reg = regs.get(0);
                break;
            }
        case 2:
            {
                /*
                 * This format is allowed for ops that are effectively
                 * 2-arg but where the two args are identical.
                 */
                reg = regs.get(0);
                if (reg.getReg() != regs.get(1).getReg()) {
                    return false;
                }
                break;
            }
        default:
            {
                return false;
            }
    }
    if (!unsignedFitsInByte(reg.getReg())) {
        return false;
    }
    CstInsn ci = (CstInsn) insn;
    Constant cst = ci.getConstant();
    return (cst instanceof CstType) || (cst instanceof CstFieldRef) || (cst instanceof CstString);
}
Also used : CstInsn(com.android.dx.dex.code.CstInsn) 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) RegisterSpecList(com.android.dx.rop.code.RegisterSpecList) RegisterSpec(com.android.dx.rop.code.RegisterSpec)

Example 10 with RegisterSpec

use of com.android.dx.rop.code.RegisterSpec in project buck by facebook.

the class Ropper method addReturnBlock.

/**
     * Constructs and adds the return block, if necessary. The return
     * block merely contains an appropriate {@code return}
     * instruction.
     */
private void addReturnBlock() {
    Rop returnOp = machine.getReturnOp();
    if (returnOp == null) {
        /*
             * The method being converted never returns normally, so there's
             * no need for a return block.
             */
        return;
    }
    SourcePosition returnPos = machine.getReturnPosition();
    int label = getSpecialLabel(RETURN);
    if (isSynchronized()) {
        InsnList insns = new InsnList(1);
        Insn insn = new ThrowingInsn(Rops.MONITOR_EXIT, returnPos, RegisterSpecList.make(getSynchReg()), StdTypeList.EMPTY);
        insns.set(0, insn);
        insns.setImmutable();
        int nextLabel = getSpecialLabel(SYNCH_RETURN);
        BasicBlock bb = new BasicBlock(label, insns, IntList.makeImmutable(nextLabel), nextLabel);
        addBlock(bb, IntList.EMPTY);
        label = nextLabel;
    }
    InsnList insns = new InsnList(1);
    TypeList sourceTypes = returnOp.getSources();
    RegisterSpecList sources;
    if (sourceTypes.size() == 0) {
        sources = RegisterSpecList.EMPTY;
    } else {
        RegisterSpec source = RegisterSpec.make(0, sourceTypes.getType(0));
        sources = RegisterSpecList.make(source);
    }
    Insn insn = new PlainInsn(returnOp, returnPos, null, sources);
    insns.set(0, insn);
    insns.setImmutable();
    BasicBlock bb = new BasicBlock(label, insns, IntList.EMPTY, -1);
    addBlock(bb, IntList.EMPTY);
}
Also used : PlainInsn(com.android.dx.rop.code.PlainInsn) Rop(com.android.dx.rop.code.Rop) ThrowingCstInsn(com.android.dx.rop.code.ThrowingCstInsn) ThrowingInsn(com.android.dx.rop.code.ThrowingInsn) PlainInsn(com.android.dx.rop.code.PlainInsn) Insn(com.android.dx.rop.code.Insn) PlainCstInsn(com.android.dx.rop.code.PlainCstInsn) SourcePosition(com.android.dx.rop.code.SourcePosition) BasicBlock(com.android.dx.rop.code.BasicBlock) InsnList(com.android.dx.rop.code.InsnList) ThrowingInsn(com.android.dx.rop.code.ThrowingInsn) RegisterSpecList(com.android.dx.rop.code.RegisterSpecList) TypeList(com.android.dx.rop.type.TypeList) StdTypeList(com.android.dx.rop.type.StdTypeList) 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