예제 #1
0
파일: Factory.cpp 프로젝트: handgod/soma
/*
 * Load a class pointer value into a fixed or temp register.  Target
 * register is clobbered, and marked inUse.
 */
static ArmLIR *loadClassPointer(CompilationUnit *cUnit, int rDest, int value)
{
    ArmLIR *res;
    cUnit->hasClassLiterals = true;
    if (dvmCompilerIsTemp(cUnit, rDest)) {
        dvmCompilerClobber(cUnit, rDest);
        dvmCompilerMarkInUse(cUnit, rDest);
    }
    ArmLIR *dataTarget = scanLiteralPool(cUnit->classPointerList, value, 0);
    if (dataTarget == NULL) {
        dataTarget = addWordData(cUnit, &cUnit->classPointerList, value);
        /* Counts the number of class pointers in this translation */
        cUnit->numClassPointers++;
    }
    ArmLIR *loadPcRel = (ArmLIR *) dvmCompilerNew(sizeof(ArmLIR), true);
    loadPcRel->opcode = kThumbLdrPcRel;
    loadPcRel->generic.target = (LIR *) dataTarget;
    loadPcRel->operands[0] = rDest;
    setupResourceMasks(loadPcRel);
    setMemRefType(loadPcRel, true, kLiteral);
    loadPcRel->aliasInfo = dataTarget->operands[0];
    res = loadPcRel;
    dvmCompilerAppendLIR(cUnit, (LIR *) loadPcRel);
    return res;
}
예제 #2
0
/*
 * The following are building blocks to construct low-level IRs with 0 - 4
 * operands.
 */
static ArmLIR *newLIR0(CompilationUnit *cUnit, ArmOpcode opcode)
{
    ArmLIR *insn = (ArmLIR *) dvmCompilerNew(sizeof(ArmLIR), true);
    assert(isPseudoOpcode(opcode) || (getEncoding(opcode)->flags & NO_OPERAND));
    insn->opcode = opcode;
    setupResourceMasks(insn);
    dvmCompilerAppendLIR(cUnit, (LIR *) insn);
    return insn;
}
예제 #3
0
static ArmLIR *newLIR1(CompilationUnit *cUnit, ArmOpcode opcode,
                           int dest)
{
    ArmLIR *insn = (ArmLIR *) dvmCompilerNew(sizeof(ArmLIR), true);
    assert(isPseudoOpcode(opcode) || (getEncoding(opcode)->flags & IS_UNARY_OP));
    insn->opcode = opcode;
    insn->operands[0] = dest;
    setupResourceMasks(insn);
    dvmCompilerAppendLIR(cUnit, (LIR *) insn);
    return insn;
}
예제 #4
0
static ArmLIR *newLIR2(CompilationUnit *cUnit, ArmOpcode opcode,
                           int dest, int src1)
{
    ArmLIR *insn = (ArmLIR *) dvmCompilerNew(sizeof(ArmLIR), true);
    assert(isPseudoOpcode(opcode) ||
           (EncodingMap[opcode].flags & IS_BINARY_OP));
    insn->opcode = opcode;
    insn->operands[0] = dest;
    insn->operands[1] = src1;
    setupResourceMasks(insn);
    dvmCompilerAppendLIR(cUnit, (LIR *) insn);
    return insn;
}
예제 #5
0
파일: Factory.cpp 프로젝트: handgod/soma
/*
 * Load a immediate using a shortcut if possible; otherwise
 * grab from the per-translation literal pool.  If target is
 * a high register, build constant into a low register and copy.
 *
 * No additional register clobbering operation performed. Use this version when
 * 1) rDest is freshly returned from dvmCompilerAllocTemp or
 * 2) The codegen is under fixed register usage
 */
static ArmLIR *loadConstantNoClobber(CompilationUnit *cUnit, int rDest,
                                     int value)
{
    ArmLIR *res;
    int tDest = LOWREG(rDest) ? rDest : dvmCompilerAllocTemp(cUnit);
    /* See if the value can be constructed cheaply */
    if ((value >= 0) && (value <= 255)) {
        res = newLIR2(cUnit, kThumbMovImm, tDest, value);
        if (rDest != tDest) {
           opRegReg(cUnit, kOpMov, rDest, tDest);
           dvmCompilerFreeTemp(cUnit, tDest);
        }
        return res;
    } else if ((value & 0xFFFFFF00) == 0xFFFFFF00) {
        res = newLIR2(cUnit, kThumbMovImm, tDest, ~value);
        newLIR2(cUnit, kThumbMvn, tDest, tDest);
        if (rDest != tDest) {
           opRegReg(cUnit, kOpMov, rDest, tDest);
           dvmCompilerFreeTemp(cUnit, tDest);
        }
        return res;
    }
    /* No shortcut - go ahead and use literal pool */
    ArmLIR *dataTarget = scanLiteralPool(cUnit->literalList, value, 255);
    if (dataTarget == NULL) {
        dataTarget = addWordData(cUnit, &cUnit->literalList, value);
    }
    ArmLIR *loadPcRel = (ArmLIR *) dvmCompilerNew(sizeof(ArmLIR), true);
    loadPcRel->opcode = kThumbLdrPcRel;
    loadPcRel->generic.target = (LIR *) dataTarget;
    loadPcRel->operands[0] = tDest;
    setupResourceMasks(loadPcRel);
    setMemRefType(loadPcRel, true, kLiteral);
    loadPcRel->aliasInfo = dataTarget->operands[0];
    res = loadPcRel;
    dvmCompilerAppendLIR(cUnit, (LIR *) loadPcRel);

    /*
     * To save space in the constant pool, we use the ADD_RRI8 instruction to
     * add up to 255 to an existing constant value.
     */
    if (dataTarget->operands[0] != value) {
        newLIR2(cUnit, kThumbAddRI8, tDest, value - dataTarget->operands[0]);
    }
    if (rDest != tDest) {
       opRegReg(cUnit, kOpMov, rDest, tDest);
       dvmCompilerFreeTemp(cUnit, tDest);
    }
    return res;
}
예제 #6
0
static ArmLIR *newLIR4(CompilationUnit *cUnit, ArmOpcode opcode,
                       int dest, int src1, int src2, int info)
{
    ArmLIR *insn = (ArmLIR *) dvmCompilerNew(sizeof(ArmLIR), true);
    assert(isPseudoOpcode(opcode) ||
           (getEncoding(opcode)->flags & IS_QUAD_OP));
    insn->opcode = opcode;
    insn->operands[0] = dest;
    insn->operands[1] = src1;
    insn->operands[2] = src2;
    insn->operands[3] = info;
    setupResourceMasks(insn);
    dvmCompilerAppendLIR(cUnit, (LIR *) insn);
    return insn;
}
예제 #7
0
static ArmLIR *newLIR3(CompilationUnit *cUnit, ArmOpcode opcode,
                           int dest, int src1, int src2)
{
    ArmLIR *insn = (ArmLIR *) dvmCompilerNew(sizeof(ArmLIR), true);
    if (!(getEncoding(opcode)->flags & IS_TERTIARY_OP)) {
        ALOGE("Bad LIR3: %s[%d]",EncodingMap[opcode].name,opcode);
    }
    assert(isPseudoOpcode(opcode) ||
           (getEncoding(opcode)->flags & IS_TERTIARY_OP));
    insn->opcode = opcode;
    insn->operands[0] = dest;
    insn->operands[1] = src1;
    insn->operands[2] = src2;
    setupResourceMasks(insn);
    dvmCompilerAppendLIR(cUnit, (LIR *) insn);
    return insn;
}