Search in sources :

Example 61 with RegisterSpecList

use of com.android.dx.rop.code.RegisterSpecList in project J2ME-Loader by nikita36078.

the class NormalSsaInsn method changeOneSource.

/**
 * Changes one of the insn's sources. New source should be of same type
 * and category.
 *
 * @param index {@code >=0;} index of source to change
 * @param newSpec spec for new source
 */
public final void changeOneSource(int index, RegisterSpec newSpec) {
    RegisterSpecList origSources = insn.getSources();
    int sz = origSources.size();
    RegisterSpecList newSources = new RegisterSpecList(sz);
    for (int i = 0; i < sz; i++) {
        newSources.set(i, i == index ? newSpec : origSources.get(i));
    }
    newSources.setImmutable();
    RegisterSpec origSpec = origSources.get(index);
    if (origSpec.getReg() != newSpec.getReg()) {
        /*
             * If the register remains unchanged, we're only changing
             * the type or local var name so don't update use list
             */
        getBlock().getParent().onSourceChanged(this, origSpec, newSpec);
    }
    insn = insn.withNewRegisters(getResult(), newSources);
}
Also used : RegisterSpecList(com.android.dx.rop.code.RegisterSpecList) RegisterSpec(com.android.dx.rop.code.RegisterSpec)

Example 62 with RegisterSpecList

use of com.android.dx.rop.code.RegisterSpecList in project J2ME-Loader by nikita36078.

the class NormalSsaInsn method setNewSources.

/**
 * Changes the source list of the insn. New source list should be the
 * same size and consist of sources of identical types.
 *
 * @param newSources non-null new sources list.
 */
public final void setNewSources(RegisterSpecList newSources) {
    RegisterSpecList origSources = insn.getSources();
    if (origSources.size() != newSources.size()) {
        throw new RuntimeException("Sources counts don't match");
    }
    insn = insn.withNewRegisters(getResult(), newSources);
}
Also used : RegisterSpecList(com.android.dx.rop.code.RegisterSpecList)

Example 63 with RegisterSpecList

use of com.android.dx.rop.code.RegisterSpecList in project J2ME-Loader by nikita36078.

the class PhiInsn method getSources.

/**
 * Gets sources. Constructed lazily from phi operand data structures and
 * then cached.
 *
 * @return {@code non-null;} sources list
 */
@Override
public RegisterSpecList getSources() {
    if (sources != null) {
        return sources;
    }
    if (operands.size() == 0) {
        // How'd this happen? A phi insn with no operand?
        return RegisterSpecList.EMPTY;
    }
    int szSources = operands.size();
    sources = new RegisterSpecList(szSources);
    for (int i = 0; i < szSources; i++) {
        Operand o = operands.get(i);
        sources.set(i, o.regSpec);
    }
    sources.setImmutable();
    return sources;
}
Also used : RegisterSpecList(com.android.dx.rop.code.RegisterSpecList)

Example 64 with RegisterSpecList

use of com.android.dx.rop.code.RegisterSpecList in project J2ME-Loader by nikita36078.

the class SCCP method replaceConstants.

/**
 * Replaces TypeBearers in source register specs with constant type
 * bearers if possible. These are then referenced in later optimization
 * steps.
 */
private void replaceConstants() {
    for (int reg = 0; reg < regCount; reg++) {
        if (latticeValues[reg] != CONSTANT) {
            continue;
        }
        if (!(latticeConstants[reg] instanceof TypedConstant)) {
            // We can't do much with these
            continue;
        }
        SsaInsn defn = ssaMeth.getDefinitionForRegister(reg);
        TypeBearer typeBearer = defn.getResult().getTypeBearer();
        if (typeBearer.isConstant()) {
            /*
                 * The definition was a constant already.
                 * The uses should be as well.
                 */
            continue;
        }
        // Update the destination RegisterSpec with the constant value
        RegisterSpec dest = defn.getResult();
        RegisterSpec newDest = dest.withType((TypedConstant) latticeConstants[reg]);
        defn.setResult(newDest);
        /*
             * Update the sources RegisterSpec's of all non-move uses.
             * These will be used in later steps.
             */
        for (SsaInsn insn : ssaMeth.getUseListForRegister(reg)) {
            if (insn.isPhiOrMove()) {
                continue;
            }
            NormalSsaInsn nInsn = (NormalSsaInsn) insn;
            RegisterSpecList sources = insn.getSources();
            int index = sources.indexOfRegister(reg);
            RegisterSpec spec = sources.get(index);
            RegisterSpec newSpec = spec.withType((TypedConstant) latticeConstants[reg]);
            nInsn.changeOneSource(index, newSpec);
        }
    }
}
Also used : TypedConstant(com.android.dx.rop.cst.TypedConstant) TypeBearer(com.android.dx.rop.type.TypeBearer) RegisterSpecList(com.android.dx.rop.code.RegisterSpecList) RegisterSpec(com.android.dx.rop.code.RegisterSpec)

Example 65 with RegisterSpecList

use of com.android.dx.rop.code.RegisterSpecList in project J2ME-Loader by nikita36078.

the class SCCP method simulateMath.

/**
 * Simulates math insns, if possible.
 *
 * @param insn non-null insn to simulate
 * @param resultType basic type of the result
 * @return constant result or null if not simulatable.
 */
private Constant simulateMath(SsaInsn insn, int resultType) {
    Insn ropInsn = insn.getOriginalRopInsn();
    int opcode = insn.getOpcode().getOpcode();
    RegisterSpecList sources = insn.getSources();
    int regA = sources.get(0).getReg();
    Constant cA;
    Constant cB;
    if (latticeValues[regA] != CONSTANT) {
        cA = null;
    } else {
        cA = latticeConstants[regA];
    }
    if (sources.size() == 1) {
        CstInsn cstInsn = (CstInsn) ropInsn;
        cB = cstInsn.getConstant();
    } else {
        /* sources.size() == 2 */
        int regB = sources.get(1).getReg();
        if (latticeValues[regB] != CONSTANT) {
            cB = null;
        } else {
            cB = latticeConstants[regB];
        }
    }
    if (cA == null || cB == null) {
        // TODO handle a constant of 0 with MUL or AND
        return null;
    }
    switch(resultType) {
        case Type.BT_INT:
            int vR;
            boolean skip = false;
            int vA = ((CstInteger) cA).getValue();
            int vB = ((CstInteger) cB).getValue();
            switch(opcode) {
                case RegOps.ADD:
                    vR = vA + vB;
                    break;
                case RegOps.SUB:
                    // 1 source for reverse sub, 2 sources for regular sub
                    if (sources.size() == 1) {
                        vR = vB - vA;
                    } else {
                        vR = vA - vB;
                    }
                    break;
                case RegOps.MUL:
                    vR = vA * vB;
                    break;
                case RegOps.DIV:
                    if (vB == 0) {
                        skip = true;
                        // just to hide a warning
                        vR = 0;
                    } else {
                        vR = vA / vB;
                    }
                    break;
                case RegOps.AND:
                    vR = vA & vB;
                    break;
                case RegOps.OR:
                    vR = vA | vB;
                    break;
                case RegOps.XOR:
                    vR = vA ^ vB;
                    break;
                case RegOps.SHL:
                    vR = vA << vB;
                    break;
                case RegOps.SHR:
                    vR = vA >> vB;
                    break;
                case RegOps.USHR:
                    vR = vA >>> vB;
                    break;
                case RegOps.REM:
                    if (vB == 0) {
                        skip = true;
                        // just to hide a warning
                        vR = 0;
                    } else {
                        vR = vA % vB;
                    }
                    break;
                default:
                    throw new RuntimeException("Unexpected op");
            }
            return skip ? null : CstInteger.make(vR);
        default:
            // not yet supported
            return null;
    }
}
Also used : CstInsn(com.android.dx.rop.code.CstInsn) Insn(com.android.dx.rop.code.Insn) PlainInsn(com.android.dx.rop.code.PlainInsn) CstInsn(com.android.dx.rop.code.CstInsn) Constant(com.android.dx.rop.cst.Constant) TypedConstant(com.android.dx.rop.cst.TypedConstant) CstInteger(com.android.dx.rop.cst.CstInteger) RegisterSpecList(com.android.dx.rop.code.RegisterSpecList)

Aggregations

RegisterSpecList (com.android.dx.rop.code.RegisterSpecList)202 RegisterSpec (com.android.dx.rop.code.RegisterSpec)50 BitSet (java.util.BitSet)45 CstLiteralBits (com.android.dx.rop.cst.CstLiteralBits)42 Constant (com.android.dx.rop.cst.Constant)36 CstInsn (com.android.dx.dex.code.CstInsn)34 PlainInsn (com.android.dx.rop.code.PlainInsn)18 CstType (com.android.dx.rop.cst.CstType)12 TargetInsn (com.android.dx.dex.code.TargetInsn)10 Insn (com.android.dx.rop.code.Insn)10 TypedConstant (com.android.dx.rop.cst.TypedConstant)10 PlainCstInsn (com.android.dx.rop.code.PlainCstInsn)8 Rop (com.android.dx.rop.code.Rop)8 CstFieldRef (com.android.dx.rop.cst.CstFieldRef)8 CstMethodRef (com.android.dx.rop.cst.CstMethodRef)8 TypeBearer (com.android.dx.rop.type.TypeBearer)8 ThrowingCstInsn (com.android.dx.rop.code.ThrowingCstInsn)6 ThrowingInsn (com.android.dx.rop.code.ThrowingInsn)6 CstInteger (com.android.dx.rop.cst.CstInteger)6 MultiCstInsn (com.android.dx.dex.code.MultiCstInsn)4