Java Code Examples for com.android.dx.rop.code.RegisterSpec#getCategory()

The following examples show how to use com.android.dx.rop.code.RegisterSpec#getCategory() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: FirstFitLocalCombiningAllocator.java    From J2ME-Loader with Apache License 2.0 6 votes vote down vote up
/**
 * Maps all non-parameter, non-local variable registers.
 */
private void handleNormalUnassociated() {
    int szSsaRegs = ssaMeth.getRegCount();

    for (int ssaReg = 0; ssaReg < szSsaRegs; ssaReg++) {
        if (ssaRegsMapped.get(ssaReg)) {
            // We already did this one
            continue;
        }

        RegisterSpec ssaSpec = getDefinitionSpecForSsaReg(ssaReg);

        if (ssaSpec == null) continue;

        int category = ssaSpec.getCategory();
        // Find a rop reg that does not interfere
        int ropReg = findNextUnreservedRopReg(paramRangeEnd, category);
        while (!canMapReg(ssaSpec, ropReg)) {
            ropReg = findNextUnreservedRopReg(ropReg + 1, category);
        }

        addMapping(ssaSpec, ropReg);
    }
}
 
Example 2
Source File: DalvInsn.java    From J2ME-Loader with Apache License 2.0 6 votes vote down vote up
/**
 * Makes a move instruction, appropriate and ideal for the given arguments.
 *
 * @param position {@code non-null;} source position information
 * @param dest {@code non-null;} destination register
 * @param src {@code non-null;} source register
 * @return {@code non-null;} an appropriately-constructed instance
 */
public static SimpleInsn makeMove(SourcePosition position,
        RegisterSpec dest, RegisterSpec src) {
    boolean category1 = dest.getCategory() == 1;
    boolean reference = dest.getType().isReference();
    int destReg = dest.getReg();
    int srcReg = src.getReg();
    Dop opcode;

    if ((srcReg | destReg) < 16) {
        opcode = reference ? Dops.MOVE_OBJECT :
            (category1 ? Dops.MOVE : Dops.MOVE_WIDE);
    } else if (destReg < 256) {
        opcode = reference ? Dops.MOVE_OBJECT_FROM16 :
            (category1 ? Dops.MOVE_FROM16 : Dops.MOVE_WIDE_FROM16);
    } else {
        opcode = reference ? Dops.MOVE_OBJECT_16 :
            (category1 ? Dops.MOVE_16 : Dops.MOVE_WIDE_16);
    }

    return new SimpleInsn(opcode, position,
                          RegisterSpecList.make(dest, src));
}
 
Example 3
Source File: HighRegisterPrefix.java    From Box with Apache License 2.0 6 votes vote down vote up
/** {@inheritDoc} */
@Override
protected String listingString0(boolean noteIndices) {
    RegisterSpecList registers = getRegisters();
    int sz = registers.size();
    StringBuilder sb = new StringBuilder(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();
}
 
Example 4
Source File: DalvInsn.java    From Box with Apache License 2.0 6 votes vote down vote up
/**
 * Makes a move instruction, appropriate and ideal for the given arguments.
 *
 * @param position {@code non-null;} source position information
 * @param dest {@code non-null;} destination register
 * @param src {@code non-null;} source register
 * @return {@code non-null;} an appropriately-constructed instance
 */
public static SimpleInsn makeMove(SourcePosition position,
        RegisterSpec dest, RegisterSpec src) {
    boolean category1 = dest.getCategory() == 1;
    boolean reference = dest.getType().isReference();
    int destReg = dest.getReg();
    int srcReg = src.getReg();
    Dop opcode;

    if ((srcReg | destReg) < 16) {
        opcode = reference ? Dops.MOVE_OBJECT :
            (category1 ? Dops.MOVE : Dops.MOVE_WIDE);
    } else if (destReg < 256) {
        opcode = reference ? Dops.MOVE_OBJECT_FROM16 :
            (category1 ? Dops.MOVE_FROM16 : Dops.MOVE_WIDE_FROM16);
    } else {
        opcode = reference ? Dops.MOVE_OBJECT_16 :
            (category1 ? Dops.MOVE_16 : Dops.MOVE_WIDE_16);
    }

    return new SimpleInsn(opcode, position,
                          RegisterSpecList.make(dest, src));
}
 
Example 5
Source File: FirstFitLocalCombiningAllocator.java    From Box with Apache License 2.0 6 votes vote down vote up
/**
 * Adds a mapping from an SSA register to a rop register.
 * {@link #canMapReg} should have already been called.
 *
 * @param ssaSpec {@code non-null;} SSA register to map from
 * @param ropReg {@code >=0;} rop register to map to
 */
private void addMapping(RegisterSpec ssaSpec, int ropReg) {
    int ssaReg = ssaSpec.getReg();

    // An assertion.
    if (ssaRegsMapped.get(ssaReg) || !canMapReg(ssaSpec, ropReg)) {
        throw new RuntimeException(
                "attempt to add invalid register mapping");
    }

    if (DEBUG) {
        System.out.printf("Add mapping s%d -> v%d c:%d\n",
                ssaSpec.getReg(), ropReg, ssaSpec.getCategory());
    }

    int category = ssaSpec.getCategory();
    mapper.addMapping(ssaSpec.getReg(), ropReg, category);
    ssaRegsMapped.set(ssaReg);
    usedRopRegs.set(ropReg, ropReg + category);
}
 
Example 6
Source File: InsnFormat.java    From Box with Apache License 2.0 6 votes vote down vote up
/**
 * 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;
}
 
Example 7
Source File: DalvInsn.java    From buck with Apache License 2.0 6 votes vote down vote up
/**
 * Makes a move instruction, appropriate and ideal for the given arguments.
 *
 * @param position {@code non-null;} source position information
 * @param dest {@code non-null;} destination register
 * @param src {@code non-null;} source register
 * @return {@code non-null;} an appropriately-constructed instance
 */
public static SimpleInsn makeMove(SourcePosition position,
        RegisterSpec dest, RegisterSpec src) {
    boolean category1 = dest.getCategory() == 1;
    boolean reference = dest.getType().isReference();
    int destReg = dest.getReg();
    int srcReg = src.getReg();
    Dop opcode;

    if ((srcReg | destReg) < 16) {
        opcode = reference ? Dops.MOVE_OBJECT :
            (category1 ? Dops.MOVE : Dops.MOVE_WIDE);
    } else if (destReg < 256) {
        opcode = reference ? Dops.MOVE_OBJECT_FROM16 :
            (category1 ? Dops.MOVE_FROM16 : Dops.MOVE_WIDE_FROM16);
    } else {
        opcode = reference ? Dops.MOVE_OBJECT_16 :
            (category1 ? Dops.MOVE_16 : Dops.MOVE_WIDE_16);
    }

    return new SimpleInsn(opcode, position,
                          RegisterSpecList.make(dest, src));
}
 
Example 8
Source File: Form45cc.java    From J2ME-Loader with Apache License 2.0 5 votes vote down vote up
/**
 * 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;
}
 
Example 9
Source File: FirstFitLocalCombiningAllocator.java    From J2ME-Loader with Apache License 2.0 5 votes vote down vote up
/**
 * Tries to map an SSA register to a rop register.
 *
 * @param ssaSpec {@code non-null;} SSA register
 * @param ropReg {@code >=0;} rop register
 * @param maxAllowedCategory {@code 1..2;} the maximum category
 * that the SSA register is allowed to be
 * @return {@code true} if map succeeded, {@code false} if not
 */
private boolean tryMapReg(RegisterSpec ssaSpec, int ropReg,
        int maxAllowedCategory) {
    if (ssaSpec.getCategory() <= maxAllowedCategory
            && !ssaRegsMapped.get(ssaSpec.getReg())
            && canMapReg(ssaSpec, ropReg)) {
        addMapping(ssaSpec, ropReg);
        return true;
    }

    return false;
}
 
Example 10
Source File: Form35c.java    From J2ME-Loader with Apache License 2.0 5 votes vote down vote up
/**
 * 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;
}
 
Example 11
Source File: FirstFitLocalCombiningAllocator.java    From Box with Apache License 2.0 5 votes vote down vote up
/**
 * Tries to map an SSA register to a rop register.
 *
 * @param ssaSpec {@code non-null;} SSA register
 * @param ropReg {@code >=0;} rop register
 * @param maxAllowedCategory {@code 1..2;} the maximum category
 * that the SSA register is allowed to be
 * @return {@code true} if map succeeded, {@code false} if not
 */
private boolean tryMapReg(RegisterSpec ssaSpec, int ropReg,
        int maxAllowedCategory) {
    if (ssaSpec.getCategory() <= maxAllowedCategory
            && !ssaRegsMapped.get(ssaSpec.getReg())
            && canMapReg(ssaSpec, ropReg)) {
        addMapping(ssaSpec, ropReg);
        return true;
    }

    return false;
}
 
Example 12
Source File: Form35c.java    From J2ME-Loader with Apache License 2.0 5 votes vote down vote up
/**
 * 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;
}
 
Example 13
Source File: Form35c.java    From Box with Apache License 2.0 5 votes vote down vote up
/**
 * 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;
}
 
Example 14
Source File: Form45cc.java    From Box with Apache License 2.0 5 votes vote down vote up
/**
 * 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;
}
 
Example 15
Source File: Form45cc.java    From Box with Apache License 2.0 5 votes vote down vote up
/**
 * 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;
}
 
Example 16
Source File: FirstFitLocalCombiningAllocator.java    From Box with Apache License 2.0 4 votes vote down vote up
/**
 * Maps the source registers of the specified instruction such that they
 * will fall in a contiguous range in rop form. Moves are inserted as
 * necessary to allow the range to be allocated.
 *
 * @param insn {@code non-null;} insn whos sources to process
 */
private void adjustAndMapSourceRangeRange(NormalSsaInsn insn) {
    int newRegStart = findRangeAndAdjust(insn);

    RegisterSpecList sources = insn.getSources();
    int szSources = sources.size();
    int nextRopReg = newRegStart;

    for (int i = 0; i < szSources; i++) {
        RegisterSpec source = sources.get(i);
        int sourceReg = source.getReg();
        int category = source.getCategory();
        int curRopReg = nextRopReg;
        nextRopReg += category;

        if (ssaRegsMapped.get(sourceReg)) {
            continue;
        }

        LocalItem localItem = getLocalItemForReg(sourceReg);
        addMapping(source, curRopReg);

        if (localItem != null) {
            markReserved(curRopReg, category);
            ArrayList<RegisterSpec> similarRegisters
                    = localVariables.get(localItem);

            int szSimilar = similarRegisters.size();

            /*
             * Try to map all SSA registers also associated with
             * this local.
             */
            for (int j = 0; j < szSimilar; j++) {
                RegisterSpec similarSpec = similarRegisters.get(j);
                int similarReg = similarSpec.getReg();

                // Don't map anything that's also a source.
                if (-1 != sources.indexOfRegister(similarReg)) {
                    continue;
                }

                // Registers left unmapped will get handled later.
                tryMapReg(similarSpec, curRopReg, category);
            }
        }
    }
}
 
Example 17
Source File: SsaBasicBlock.java    From Box with Apache License 2.0 3 votes vote down vote up
/**
 * Sets the register as used in a bitset, taking into account its
 * category/width.
 *
 * @param regsUsed set, indexed by register number
 * @param rs register to mark as used
 */
private static void setRegsUsed (BitSet regsUsed, RegisterSpec rs) {
    regsUsed.set(rs.getReg());
    if (rs.getCategory() > 1) {
        regsUsed.set(rs.getReg() + 1);
    }
}
 
Example 18
Source File: SsaBasicBlock.java    From buck with Apache License 2.0 3 votes vote down vote up
/**
 * Checks to see if the register is used in a bitset, taking
 * into account its category/width.
 *
 * @param regsUsed set, indexed by register number
 * @param rs register to mark as used
 * @return true if register is fully or partially (for the case of wide
 * registers) used.
 */
private static boolean checkRegUsed (BitSet regsUsed, RegisterSpec rs) {
    int reg = rs.getReg();
    int category = rs.getCategory();

    return regsUsed.get(reg)
            || (category == 2 ? regsUsed.get(reg + 1) : false);
}
 
Example 19
Source File: FirstFitLocalCombiningAllocator.java    From Box with Apache License 2.0 2 votes vote down vote up
/**
 * Checks to see if {@code ssaSpec} can be mapped to
 * {@code ropReg}. Checks interference graph and ensures
 * the range does not cross the parameter range.
 *
 * @param ssaSpec {@code non-null;} SSA spec
 * @param ropReg prosepctive new-namespace reg
 * @return {@code true} if mapping is possible
 */
private boolean canMapReg(RegisterSpec ssaSpec, int ropReg) {
    int category = ssaSpec.getCategory();
    return !(spansParamRange(ropReg, category)
            || mapper.interferes(ssaSpec, ropReg));
}
 
Example 20
Source File: FirstFitLocalCombiningAllocator.java    From Box with Apache License 2.0 2 votes vote down vote up
/**
 * Checks to see if {@code ssaSpec} can be mapped to
 * {@code ropReg}. Checks interference graph and ensures
 * the range does not cross the parameter range.
 *
 * @param ssaSpec {@code non-null;} SSA spec
 * @param ropReg prosepctive new-namespace reg
 * @return {@code true} if mapping is possible
 */
private boolean canMapReg(RegisterSpec ssaSpec, int ropReg) {
    int category = ssaSpec.getCategory();
    return !(spansParamRange(ropReg, category)
            || mapper.interferes(ssaSpec, ropReg));
}