Example #1
0
/* Create the PC reconstruction slot if not already done */
static ArmLIR *genCheckCommon(CompilationUnit *cUnit, int dOffset,
                              ArmLIR *branch,
                              ArmLIR *pcrLabel)
{
    /* Forget all def info (because we might rollback here.  Bug #2367397 */
    dvmCompilerResetDefTracking(cUnit);

    /* Set up the place holder to reconstruct this Dalvik PC */
    if (pcrLabel == NULL) {
        int dPC = (int) (cUnit->method->insns + dOffset);
        pcrLabel = (ArmLIR *) dvmCompilerNew(sizeof(ArmLIR), true);
        pcrLabel->opcode = kArmPseudoPCReconstructionCell;
        pcrLabel->operands[0] = dPC;
        pcrLabel->operands[1] = dOffset;
        /* Insert the place holder to the growable list */
        dvmInsertGrowableList(&cUnit->pcReconstructionList,
                              (intptr_t) pcrLabel);
    }
    /* Branch to the PC reconstruction code */
    branch->generic.target = (LIR *) pcrLabel;

    /* Clear the conservative flags for branches that punt to the interpreter */
    relaxBranchMasks(branch);

    return pcrLabel;
}
/* Handle the content in each basic block */
static bool methodBlockCodeGen(CompilationUnit *cUnit, BasicBlock *bb)
{
    MIR *mir;
    ArmLIR *labelList = (ArmLIR *) cUnit->blockLabelList;
    int blockId = bb->id;

    cUnit->curBlock = bb;
    labelList[blockId].operands[0] = bb->startOffset;

    /* Insert the block label */
    labelList[blockId].opcode = kArmPseudoNormalBlockLabel;
    dvmCompilerAppendLIR(cUnit, (LIR *) &labelList[blockId]);

    dvmCompilerClobberAllRegs(cUnit);
    dvmCompilerResetNullCheck(cUnit);

    ArmLIR *headLIR = NULL;

    if (bb->blockType == kEntryBlock) {
        /* r0 = callsitePC */
        opImm(cUnit, kOpPush, (1 << r0 | 1 << r1 | 1 << r5FP | 1 << r14lr));
        opRegImm(cUnit, kOpSub, r5FP,
                 sizeof(StackSaveArea) + cUnit->method->registersSize * 4);

    } else if (bb->blockType == kExitBlock) {
        /* No need to pop r0 and r1 */
        opRegImm(cUnit, kOpAdd, r13sp, 8);
        opImm(cUnit, kOpPop, (1 << r5FP | 1 << r15pc));
    }

    for (mir = bb->firstMIRInsn; mir; mir = mir->next) {

        dvmCompilerResetRegPool(cUnit);
        if (gDvmJit.disableOpt & (1 << kTrackLiveTemps)) {
            dvmCompilerClobberAllRegs(cUnit);
        }

        if (gDvmJit.disableOpt & (1 << kSuppressLoads)) {
            dvmCompilerResetDefTracking(cUnit);
        }

        Opcode dalvikOpcode = mir->dalvikInsn.opcode;
        InstructionFormat dalvikFormat =
            dexGetFormatFromOpcode(dalvikOpcode);

        ArmLIR *boundaryLIR;

        /*
         * Don't generate the boundary LIR unless we are debugging this
         * trace or we need a scheduling barrier.
         */
        if (headLIR == NULL || cUnit->printMe == true) {
            boundaryLIR =
                newLIR2(cUnit, kArmPseudoDalvikByteCodeBoundary,
                        mir->offset,
                        (int) dvmCompilerGetDalvikDisassembly(
                            &mir->dalvikInsn, ""));
            /* Remember the first LIR for this block */
            if (headLIR == NULL) {
                headLIR = boundaryLIR;
                /* Set the first boundaryLIR as a scheduling barrier */
                headLIR->defMask = ENCODE_ALL;
            }
        }

        /* Don't generate the SSA annotation unless verbose mode is on */
        if (cUnit->printMe && mir->ssaRep) {
            char *ssaString = dvmCompilerGetSSAString(cUnit, mir->ssaRep);
            newLIR1(cUnit, kArmPseudoSSARep, (int) ssaString);
        }

        bool notHandled;
        switch (dalvikFormat) {
            case kFmt10t:
            case kFmt20t:
            case kFmt30t:
                notHandled = handleMethodFmt10t_Fmt20t_Fmt30t(cUnit, mir, bb,
                                                              labelList);
                break;
            case kFmt10x:
                notHandled = handleMethodFmt10x(cUnit, mir);
                break;
            case kFmt11n:
            case kFmt31i:
                notHandled = handleMethodFmt11n_Fmt31i(cUnit, mir);
                break;
            case kFmt11x:
                notHandled = handleMethodFmt11x(cUnit, mir, bb, labelList);
                break;
            case kFmt12x:
                notHandled = handleMethodFmt12x(cUnit, mir);
                break;
            case kFmt20bc:
                notHandled = handleMethodFmt20bc(cUnit, mir);
                break;
            case kFmt21c:
            case kFmt31c:
                notHandled = handleMethodFmt21c_Fmt31c(cUnit, mir);
                break;
            case kFmt21h:
                notHandled = handleMethodFmt21h(cUnit, mir);
                break;
            case kFmt21s:
                notHandled = handleMethodFmt21s(cUnit, mir);
                break;
            case kFmt21t:
                notHandled = handleMethodFmt21t(cUnit, mir, bb, labelList);
                break;
            case kFmt22b:
            case kFmt22s:
                notHandled = handleMethodFmt22b_Fmt22s(cUnit, mir);
                break;
            case kFmt22c:
                notHandled = handleMethodFmt22c(cUnit, mir);
                break;
            case kFmt22cs:
                notHandled = handleMethodFmt22cs(cUnit, mir);
                break;
            case kFmt22t:
                notHandled = handleMethodFmt22t(cUnit, mir, bb, labelList);
                break;
            case kFmt22x:
            case kFmt32x:
                notHandled = handleMethodFmt22x_Fmt32x(cUnit, mir);
                break;
            case kFmt23x:
                notHandled = handleMethodFmt23x(cUnit, mir);
                break;
            case kFmt31t:
                notHandled = handleMethodFmt31t(cUnit, mir);
                break;
            case kFmt3rc:
            case kFmt35c:
                notHandled = handleMethodFmt35c_3rc(cUnit, mir, bb, labelList);
                break;
            case kFmt3rms:
            case kFmt35ms:
                notHandled = handleMethodFmt35ms_3rms(cUnit, mir, bb,
                                                      labelList);
                break;
            case kFmt35mi:
            case kFmt3rmi:
                notHandled = handleMethodExecuteInline(cUnit, mir);
                break;
            case kFmt51l:
                notHandled = handleMethodFmt51l(cUnit, mir);
                break;
            default:
                notHandled = true;
                break;
        }

        /* FIXME - to be implemented */
        if (notHandled == true && dalvikOpcode >= kNumPackedOpcodes) {
            notHandled = false;
        }

        if (notHandled) {
            ALOGE("%#06x: Opcode %#x (%s) / Fmt %d not handled",
                 mir->offset,
                 dalvikOpcode, dexGetOpcodeName(dalvikOpcode),
                 dalvikFormat);
            dvmCompilerAbort(cUnit);
            break;
        }
    }

    if (headLIR) {
        /*
         * Eliminate redundant loads/stores and delay stores into later
         * slots
         */
        dvmCompilerApplyLocalOptimizations(cUnit, (LIR *) headLIR,
                                           cUnit->lastLIRInsn);

        /*
         * Generate an unconditional branch to the fallthrough block.
         */
        if (bb->fallThrough) {
            genUnconditionalBranch(cUnit,
                                   &labelList[bb->fallThrough->id]);
        }
    }
    return false;
}