/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "object_utils.h"

#define DISPLAY_MISSING_TARGETS (cUnit->enableDebug & \
    (1 << kDebugDisplayMissingTargets))

STATIC const RegLocation badLoc = {kLocDalvikFrame, 0, 0, 0, 0, 0, 0, INVALID_REG,
                                   INVALID_REG, INVALID_SREG};

/* Mark register usage state and return long retloc */
STATIC RegLocation getRetLocWide(CompilationUnit* cUnit)
{
    RegLocation res = LOC_DALVIK_RETURN_VAL_WIDE;
    oatLockTemp(cUnit, res.lowReg);
    oatLockTemp(cUnit, res.highReg);
    oatMarkPair(cUnit, res.lowReg, res.highReg);
    return res;
}

STATIC RegLocation getRetLoc(CompilationUnit* cUnit)
{
    RegLocation res = LOC_DALVIK_RETURN_VAL;
    oatLockTemp(cUnit, res.lowReg);
    return res;
}

/*
 * Let helper function take care of everything.  Will call
 * Array::AllocFromCode(type_idx, method, count);
 * Note: AllocFromCode will handle checks for errNegativeArraySize.
 */
STATIC void genNewArray(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
                        RegLocation rlSrc)
{
    oatFlushAllRegs(cUnit);    /* Everything to home location */
    uint32_t type_idx = mir->dalvikInsn.vC;
    if (cUnit->compiler->CanAccessTypeWithoutChecks(cUnit->method_idx,
                                                    cUnit->dex_cache,
                                                    *cUnit->dex_file,
                                                    type_idx)) {
        loadWordDisp(cUnit, rSELF,
                     OFFSETOF_MEMBER(Thread, pAllocArrayFromCode), rLR);
    } else {
        UNIMPLEMENTED(WARNING) << "Need to check access of '"
                               << PrettyMethod(cUnit->method_idx, *cUnit->dex_file)
                               << "' to unresolved type " << type_idx;
        loadWordDisp(cUnit, rSELF,
                     OFFSETOF_MEMBER(Thread, pAllocArrayFromCode), rLR);
    }
    loadCurrMethodDirect(cUnit, r1);              // arg1 <- Method*
    loadConstant(cUnit, r0, type_idx);            // arg0 <- type_id
    loadValueDirectFixed(cUnit, rlSrc, r2);       // arg2 <- count
    callRuntimeHelper(cUnit, rLR);
    RegLocation rlResult = oatGetReturn(cUnit);
    storeValue(cUnit, rlDest, rlResult);
}

/*
 * Similar to genNewArray, but with post-allocation initialization.
 * Verifier guarantees we're dealing with an array class.  Current
 * code throws runtime exception "bad Filled array req" for 'D' and 'J'.
 * Current code also throws internal unimp if not 'L', '[' or 'I'.
 */
STATIC void genFilledNewArray(CompilationUnit* cUnit, MIR* mir, bool isRange)
{
    DecodedInstruction* dInsn = &mir->dalvikInsn;
    int elems = dInsn->vA;
    int typeId = dInsn->vB;
    oatFlushAllRegs(cUnit);    /* Everything to home location */
    loadWordDisp(cUnit, rSELF,
                 OFFSETOF_MEMBER(Thread, pCheckAndAllocArrayFromCode), rLR);
    if (!cUnit->compiler->CanAccessTypeWithoutChecks(cUnit->method_idx,
                                                     cUnit->dex_cache,
                                                     *cUnit->dex_file,
                                                     typeId)) {
        UNIMPLEMENTED(WARNING) << "Need to check access of '"
            << PrettyMethod(cUnit->method_idx, *cUnit->dex_file)
            << "' to unresolved type " << typeId;
    }
    loadCurrMethodDirect(cUnit, r1);              // arg1 <- Method*
    loadConstant(cUnit, r0, typeId);              // arg0 <- type_id
    loadConstant(cUnit, r2, elems);               // arg2 <- count
    callRuntimeHelper(cUnit, rLR);
    /*
     * NOTE: the implicit target for OP_FILLED_NEW_ARRAY is the
     * return region.  Because AllocFromCode placed the new array
     * in r0, we'll just lock it into place.  When debugger support is
     * added, it may be necessary to additionally copy all return
     * values to a home location in thread-local storage
     */
    oatLockTemp(cUnit, r0);

    // Having a range of 0 is legal
    if (isRange && (dInsn->vA > 0)) {
        /*
         * Bit of ugliness here.  We're going generate a mem copy loop
         * on the register range, but it is possible that some regs
         * in the range have been promoted.  This is unlikely, but
         * before generating the copy, we'll just force a flush
         * of any regs in the source range that have been promoted to
         * home location.
         */
        for (unsigned int i = 0; i < dInsn->vA; i++) {
            RegLocation loc = oatUpdateLoc(cUnit,
                oatGetSrc(cUnit, mir, i));
            if (loc.location == kLocPhysReg) {
                storeBaseDisp(cUnit, rSP, oatSRegOffset(cUnit, loc.sRegLow),
                              loc.lowReg, kWord);
            }
        }
        /*
         * TUNING note: generated code here could be much improved, but
         * this is an uncommon operation and isn't especially performance
         * critical.
         */
        int rSrc = oatAllocTemp(cUnit);
        int rDst = oatAllocTemp(cUnit);
        int rIdx = oatAllocTemp(cUnit);
        int rVal = rLR;  // Using a lot of temps, rLR is known free here
        // Set up source pointer
        RegLocation rlFirst = oatGetSrc(cUnit, mir, 0);
        opRegRegImm(cUnit, kOpAdd, rSrc, rSP,
                    oatSRegOffset(cUnit, rlFirst.sRegLow));
        // Set up the target pointer
        opRegRegImm(cUnit, kOpAdd, rDst, r0,
                    Array::DataOffset().Int32Value());
        // Set up the loop counter (known to be > 0)
        loadConstant(cUnit, rIdx, dInsn->vA - 1);
        // Generate the copy loop.  Going backwards for convenience
        ArmLIR* target = newLIR0(cUnit, kArmPseudoTargetLabel);
        target->defMask = ENCODE_ALL;
        // Copy next element
        loadBaseIndexed(cUnit, rSrc, rIdx, rVal, 2, kWord);
        storeBaseIndexed(cUnit, rDst, rIdx, rVal, 2, kWord);
        // Use setflags encoding here
        newLIR3(cUnit, kThumb2SubsRRI12, rIdx, rIdx, 1);
        ArmLIR* branch = opCondBranch(cUnit, kArmCondGe);
        branch->generic.target = (LIR*)target;
    } else if (!isRange) {
        // TUNING: interleave
        for (unsigned int i = 0; i < dInsn->vA; i++) {
            RegLocation rlArg = loadValue(cUnit,
                oatGetSrc(cUnit, mir, i), kCoreReg);
            storeBaseDisp(cUnit, r0,
                          Array::DataOffset().Int32Value() +
                          i * 4, rlArg.lowReg, kWord);
            // If the loadValue caused a temp to be allocated, free it
            if (oatIsTemp(cUnit, rlArg.lowReg)) {
                oatFreeTemp(cUnit, rlArg.lowReg);
            }
        }
    }
}

Field* FindFieldWithResolvedStaticStorage(CompilationUnit* cUnit,
                                          const uint32_t fieldIdx,
                                          uint32_t& resolvedTypeIdx) {
    Field* field = cUnit->class_linker->ResolveField(*cUnit->dex_file,
                                                     fieldIdx,
                                                     cUnit->dex_cache,
                                                     cUnit->class_loader,
                                                     true);
    if (field == NULL) {
        Thread* thread = Thread::Current();
        if (thread->IsExceptionPending()) {  // clear any exception left by resolve field
            thread->ClearException();
        }
        return NULL;
    }
    const art::DexFile::FieldId& field_id = cUnit->dex_file->GetFieldId(fieldIdx);
    int type_idx = field_id.class_idx_;
    Class* klass = cUnit->dex_cache->GetResolvedTypes()->Get(type_idx);
    // Check if storage class is the same as class referred to by type idx.
    // They may not be if the FieldId refers a subclass, but storage is in super
    if (field->GetDeclaringClass() == klass) {
        resolvedTypeIdx = type_idx;
        return field;
    }
    // See if we can find a dex reference for the storage class.
    // we may not if the dex file never references the super class,
    // but usually it will.
    std::string descriptor(art::FieldHelper(field).GetDeclaringClassDescriptor());
    const art::DexFile::StringId* string_id =
        cUnit->dex_file->FindStringId(descriptor);
    if (string_id == NULL) {
        return NULL;  // descriptor not found, resort to slow path
    }
    const art::DexFile::TypeId* type_id =
        cUnit->dex_file->FindTypeId(cUnit->dex_file->GetIndexForStringId(*string_id));
    if (type_id == NULL) {
        return NULL;  // type id not found, resort to slow path
    }
    resolvedTypeIdx = cUnit->dex_file->GetIndexForTypeId(*type_id);
    return field;
}

STATIC void genSput(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc)
{
    bool isObject = ((mir->dalvikInsn.opcode == OP_SPUT_OBJECT) ||
                     (mir->dalvikInsn.opcode == OP_SPUT_OBJECT_VOLATILE));
    int fieldIdx = mir->dalvikInsn.vB;
    uint32_t typeIdx;
    Field* field = FindFieldWithResolvedStaticStorage(cUnit, fieldIdx, typeIdx);
    oatFlushAllRegs(cUnit);
    if (SLOW_FIELD_PATH || field == NULL) {
        // Slow path
        warnIfUnresolved(cUnit, fieldIdx, field);
        int funcOffset = isObject ? OFFSETOF_MEMBER(Thread, pSetObjStatic)
                                  : OFFSETOF_MEMBER(Thread, pSet32Static);
        loadWordDisp(cUnit, rSELF, funcOffset, rLR);
        loadConstant(cUnit, r0, mir->dalvikInsn.vB);
        loadCurrMethodDirect(cUnit, r1);
        loadValueDirect(cUnit, rlSrc, r2);
        callRuntimeHelper(cUnit, rLR);
    } else {
        // fast path
        int fieldOffset = field->GetOffset().Int32Value();
        // Using fixed register to sync with slow path
        int rMethod = r1;
        oatLockTemp(cUnit, rMethod);
        loadCurrMethodDirect(cUnit, rMethod);
        int rBase = r0;
        oatLockTemp(cUnit, rBase);
        loadWordDisp(cUnit, rMethod,
            Method::DexCacheInitializedStaticStorageOffset().Int32Value(),
            rBase);
        loadWordDisp(cUnit, rBase, art::Array::DataOffset().Int32Value() +
                      sizeof(int32_t*)* typeIdx, rBase);
        // TUNING: fast path should fall through
        // TUNING: Try a conditional skip here, might be faster
        ArmLIR* branchOver = genCmpImmBranch(cUnit, kArmCondNe, rBase, 0);
        loadWordDisp(cUnit, rSELF,
                     OFFSETOF_MEMBER(Thread, pInitializeStaticStorage), rLR);
        loadConstant(cUnit, r0, typeIdx);
        callRuntimeHelper(cUnit, rLR);
        ArmLIR* skipTarget = newLIR0(cUnit, kArmPseudoTargetLabel);
        skipTarget->defMask = ENCODE_ALL;
        branchOver->generic.target = (LIR*)skipTarget;
        rlSrc = oatGetSrc(cUnit, mir, 0);
        rlSrc = loadValue(cUnit, rlSrc, kAnyReg);
#if ANDROID_SMP != 0
        if (field->IsVolatile()) {
            oatGenMemBarrier(cUnit, kST);
        }
#endif
        storeWordDisp(cUnit, rBase, fieldOffset, rlSrc.lowReg);
#if ANDROID_SMP != 0
        if (field->IsVolatile()) {
            oatGenMemBarrier(cUnit, kSY);
        }
#endif
        if (isObject) {
            markGCCard(cUnit, rlSrc.lowReg, rBase);
        }
        oatFreeTemp(cUnit, rBase);
    }
}

STATIC void genSputWide(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc)
{
    int fieldIdx = mir->dalvikInsn.vB;
    uint32_t typeIdx;
    Field* field = FindFieldWithResolvedStaticStorage(cUnit, fieldIdx, typeIdx);
    oatFlushAllRegs(cUnit);
#if ANDROID_SMP != 0
    bool isVolatile = (field == NULL) || field->IsVolatile();
#else
    bool isVolatile = false;
#endif
    if (SLOW_FIELD_PATH || field == NULL || isVolatile) {
        warnIfUnresolved(cUnit, fieldIdx, field);
        loadWordDisp(cUnit, rSELF, OFFSETOF_MEMBER(Thread, pSet64Static), rLR);
        loadConstant(cUnit, r0, mir->dalvikInsn.vB);
        loadCurrMethodDirect(cUnit, r1);
        loadValueDirectWideFixed(cUnit, rlSrc, r2, r3);
        callRuntimeHelper(cUnit, rLR);
    } else {
        // fast path
        int fieldOffset = field->GetOffset().Int32Value();
        // Using fixed register to sync with slow path
        int rMethod = r1;
        oatLockTemp(cUnit, rMethod);
        loadCurrMethodDirect(cUnit, r1);
        int rBase = r0;
        oatLockTemp(cUnit, rBase);
        loadWordDisp(cUnit, rMethod,
            Method::DexCacheInitializedStaticStorageOffset().Int32Value(),
            rBase);
        loadWordDisp(cUnit, rBase, art::Array::DataOffset().Int32Value() +
                      sizeof(int32_t*)* typeIdx, rBase);
        // TUNING: fast path should fall through
        ArmLIR* branchOver = genCmpImmBranch(cUnit, kArmCondNe, rBase, 0);
        loadWordDisp(cUnit, rSELF,
                     OFFSETOF_MEMBER(Thread, pInitializeStaticStorage), rLR);
        loadConstant(cUnit, r0, typeIdx);
        callRuntimeHelper(cUnit, rLR);
        ArmLIR* skipTarget = newLIR0(cUnit, kArmPseudoTargetLabel);
        skipTarget->defMask = ENCODE_ALL;
        branchOver->generic.target = (LIR*)skipTarget;
        rlSrc = oatGetSrcWide(cUnit, mir, 0, 1);
        rlSrc = loadValueWide(cUnit, rlSrc, kAnyReg);
        storeBaseDispWide(cUnit, rBase, fieldOffset, rlSrc.lowReg,
                          rlSrc.highReg);
        oatFreeTemp(cUnit, rBase);
    }
}


STATIC void genSgetWide(CompilationUnit* cUnit, MIR* mir,
                 RegLocation rlResult, RegLocation rlDest)
{
    int fieldIdx = mir->dalvikInsn.vB;
    uint32_t typeIdx;
    Field* field = FindFieldWithResolvedStaticStorage(cUnit, fieldIdx, typeIdx);
#if ANDROID_SMP != 0
    bool isVolatile = (field == NULL) || field->IsVolatile();
#else
    bool isVolatile = false;
#endif
    oatFlushAllRegs(cUnit);
    if (SLOW_FIELD_PATH || field == NULL || isVolatile) {
        warnIfUnresolved(cUnit, fieldIdx, field);
        loadWordDisp(cUnit, rSELF, OFFSETOF_MEMBER(Thread, pGet64Static), rLR);
        loadConstant(cUnit, r0, mir->dalvikInsn.vB);
        loadCurrMethodDirect(cUnit, r1);
        callRuntimeHelper(cUnit, rLR);
        RegLocation rlResult = oatGetReturnWide(cUnit);
        storeValueWide(cUnit, rlDest, rlResult);
    } else {
        // Fast path
        int fieldOffset = field->GetOffset().Int32Value();
        // Using fixed register to sync with slow path
        int rMethod = r1;
        oatLockTemp(cUnit, rMethod);
        loadCurrMethodDirect(cUnit, rMethod);
        int rBase = r0;
        oatLockTemp(cUnit, rBase);
        loadWordDisp(cUnit, rMethod,
            Method::DexCacheInitializedStaticStorageOffset().Int32Value(),
            rBase);
        loadWordDisp(cUnit, rBase, art::Array::DataOffset().Int32Value() +
                      sizeof(int32_t*)* typeIdx, rBase);
        // TUNING: fast path should fall through
        ArmLIR* branchOver = genCmpImmBranch(cUnit, kArmCondNe, rBase, 0);
        loadWordDisp(cUnit, rSELF,
                     OFFSETOF_MEMBER(Thread, pInitializeStaticStorage), rLR);
        loadConstant(cUnit, r0, typeIdx);
        callRuntimeHelper(cUnit, rLR);
        ArmLIR* skipTarget = newLIR0(cUnit, kArmPseudoTargetLabel);
        skipTarget->defMask = ENCODE_ALL;
        branchOver->generic.target = (LIR*)skipTarget;
        rlDest = oatGetDestWide(cUnit, mir, 0, 1);
        RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
        loadBaseDispWide(cUnit, NULL, rBase, fieldOffset, rlResult.lowReg,
                         rlResult.highReg, INVALID_SREG);
        oatFreeTemp(cUnit, rBase);
        storeValueWide(cUnit, rlDest, rlResult);
    }
}

STATIC void genSget(CompilationUnit* cUnit, MIR* mir,
             RegLocation rlResult, RegLocation rlDest)
{
    int fieldIdx = mir->dalvikInsn.vB;
    uint32_t typeIdx;
    Field* field = FindFieldWithResolvedStaticStorage(cUnit, fieldIdx, typeIdx);
    bool isObject = ((mir->dalvikInsn.opcode == OP_SGET_OBJECT) ||
                     (mir->dalvikInsn.opcode == OP_SGET_OBJECT_VOLATILE));
    oatFlushAllRegs(cUnit);
    if (SLOW_FIELD_PATH || field == NULL) {
        // Slow path
        warnIfUnresolved(cUnit, fieldIdx, field);
        int funcOffset = isObject ? OFFSETOF_MEMBER(Thread, pGetObjStatic)
                                  : OFFSETOF_MEMBER(Thread, pGet32Static);
        loadWordDisp(cUnit, rSELF, funcOffset, rLR);
        loadConstant(cUnit, r0, mir->dalvikInsn.vB);
        loadCurrMethodDirect(cUnit, r1);
        callRuntimeHelper(cUnit, rLR);
        RegLocation rlResult = oatGetReturn(cUnit);
        storeValue(cUnit, rlDest, rlResult);
    } else {
        // Fast path
        int fieldOffset = field->GetOffset().Int32Value();
        // Using fixed register to sync with slow path
        int rMethod = r1;
        oatLockTemp(cUnit, rMethod);
        loadCurrMethodDirect(cUnit, rMethod);
        int rBase = r0;
        oatLockTemp(cUnit, rBase);
        loadWordDisp(cUnit, rMethod,
            Method::DexCacheInitializedStaticStorageOffset().Int32Value(),
            rBase);
        loadWordDisp(cUnit, rBase, art::Array::DataOffset().Int32Value() +
                      sizeof(int32_t*)* typeIdx, rBase);
        // TUNING: fast path should fall through
        ArmLIR* branchOver = genCmpImmBranch(cUnit, kArmCondNe, rBase, 0);
        loadWordDisp(cUnit, rSELF,
                     OFFSETOF_MEMBER(Thread, pInitializeStaticStorage), rLR);
        loadConstant(cUnit, r0, typeIdx);
        callRuntimeHelper(cUnit, rLR);
        ArmLIR* skipTarget = newLIR0(cUnit, kArmPseudoTargetLabel);
        skipTarget->defMask = ENCODE_ALL;
        branchOver->generic.target = (LIR*)skipTarget;
        rlDest = oatGetDest(cUnit, mir, 0);
        rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
#if ANDROID_SMP != 0
        if (field->IsVolatile()) {
            oatGenMemBarrier(cUnit, kSY);
        }
#endif
        loadWordDisp(cUnit, rBase, fieldOffset, rlResult.lowReg);
        oatFreeTemp(cUnit, rBase);
        storeValue(cUnit, rlDest, rlResult);
    }
}

typedef int (*NextCallInsn)(CompilationUnit*, MIR*, DecodedInstruction*, int,
                            ArmLIR*);

/*
 * Bit of a hack here - in leiu of a real scheduling pass,
 * emit the next instruction in static & direct invoke sequences.
 */
STATIC int nextSDCallInsn(CompilationUnit* cUnit, MIR* mir,
                        DecodedInstruction* dInsn, int state,
                        ArmLIR* rollback)
{
    DCHECK(rollback == NULL);
    uint32_t idx = dInsn->vB;
    switch(state) {
        case 0:  // Get the current Method* [sets r0]
            loadCurrMethodDirect(cUnit, r0);
            break;
        case 1:  // Get method->code_and_direct_methods_
            loadWordDisp(cUnit, r0,
                Method::GetDexCacheCodeAndDirectMethodsOffset().Int32Value(),
                r0);
            break;
        case 2:  // Grab target method* and target code_
            loadWordDisp(cUnit, r0,
                art::CodeAndDirectMethods::CodeOffsetInBytes(idx), rLR);
            loadWordDisp(cUnit, r0,
                art::CodeAndDirectMethods::MethodOffsetInBytes(idx), r0);
            break;
        default:
            return -1;
    }
    return state + 1;
}

/*
 * Bit of a hack here - in leiu of a real scheduling pass,
 * emit the next instruction in a virtual invoke sequence.
 * We can use rLR as a temp prior to target address loading
 * Note also that we'll load the first argument ("this") into
 * r1 here rather than the standard loadArgRegs.
 */
STATIC int nextVCallInsn(CompilationUnit* cUnit, MIR* mir,
                        DecodedInstruction* dInsn, int state,
                        ArmLIR* rollback)
{
    DCHECK(rollback == NULL);
    RegLocation rlArg;
    /*
     * This is the fast path in which the target virtual method is
     * fully resolved at compile time.
     */
    Method* baseMethod = cUnit->class_linker->ResolveMethod(*cUnit->dex_file,
                                                            dInsn->vB,
                                                            cUnit->dex_cache,
                                                            cUnit->class_loader,
                                                            false);
    CHECK(baseMethod != NULL);
    uint32_t target_idx = baseMethod->GetMethodIndex();
    switch(state) {
        case 0:  // Get "this" [set r1]
            rlArg = oatGetSrc(cUnit, mir, 0);
            loadValueDirectFixed(cUnit, rlArg, r1);
            break;
        case 1: // Is "this" null? [use r1]
            genNullCheck(cUnit, oatSSASrc(mir,0), r1, mir);
            // get this->klass_ [use r1, set rLR]
            loadWordDisp(cUnit, r1, Object::ClassOffset().Int32Value(), rLR);
            break;
        case 2: // Get this->klass_->vtable [usr rLR, set rLR]
            loadWordDisp(cUnit, rLR, Class::VTableOffset().Int32Value(), rLR);
            break;
        case 3: // Get target method [use rLR, set r0]
            loadWordDisp(cUnit, rLR, (target_idx * 4) +
                         art::Array::DataOffset().Int32Value(), r0);
            break;
        case 4: // Get the target compiled code address [uses r0, sets rLR]
            loadWordDisp(cUnit, r0, Method::GetCodeOffset().Int32Value(), rLR);
            break;
        default:
            return -1;
    }
    return state + 1;
}

STATIC int nextVCallInsnSP(CompilationUnit* cUnit, MIR* mir,
                           DecodedInstruction* dInsn, int state,
                           ArmLIR* rollback)
{
    RegLocation rlArg;
    ArmLIR* skipBranch;
    ArmLIR* skipTarget;
    /*
     * This handles the case in which the base method is not fully
     * resolved at compile time.  We must generate code to test
     * for resolution a run time, bail to the slow path if not to
     * fill in all the tables.  In the latter case, we'll restart at
     * at the beginning of the sequence.
     */
    switch(state) {
        case 0:  // Get the current Method* [sets r0]
            loadCurrMethodDirect(cUnit, r0);
            break;
        case 1: // Get method->dex_cache_resolved_methods_
            loadWordDisp(cUnit, r0,
                Method::GetDexCacheResolvedMethodsOffset().Int32Value(), rLR);
            break;
        case 2: // method->dex_cache_resolved_methods_->Get(method_idx)
            loadWordDisp(cUnit, rLR, (dInsn->vB * 4) +
                         art::Array::DataOffset().Int32Value(), rLR);
            break;
        case 3: // Resolved?
            skipBranch = genCmpImmBranch(cUnit, kArmCondNe, rLR, 0);
            // Slowest path, bail to helper, rollback and retry
            loadWordDisp(cUnit, rSELF,
                         OFFSETOF_MEMBER(Thread, pResolveMethodFromCode), rLR);
            loadConstant(cUnit, r1, dInsn->vB);
            loadConstant(cUnit, r2, false);
            callRuntimeHelper(cUnit, rLR);
            genUnconditionalBranch(cUnit, rollback);
            // Resume normal slow path
            skipTarget = newLIR0(cUnit, kArmPseudoTargetLabel);
            skipTarget->defMask = ENCODE_ALL;
            skipBranch->generic.target = (LIR*)skipTarget;
            // Get base_method->method_index [usr rLR, set r0]
            loadBaseDisp(cUnit, mir, rLR,
                         Method::GetMethodIndexOffset().Int32Value(), r0,
                         kUnsignedHalf, INVALID_SREG);
            // Load "this" [set r1]
            rlArg = oatGetSrc(cUnit, mir, 0);
            loadValueDirectFixed(cUnit, rlArg, r1);
            break;
        case 4:
            // Is "this" null? [use r1]
            genNullCheck(cUnit, oatSSASrc(mir,0), r1, mir);
            // get this->clazz [use r1, set rLR]
            loadWordDisp(cUnit, r1, Object::ClassOffset().Int32Value(), rLR);
            break;
        case 5:
            // get this->klass_->vtable_ [usr rLR, set rLR]
            loadWordDisp(cUnit, rLR, Class::VTableOffset().Int32Value(), rLR);
            DCHECK_EQ((art::Array::DataOffset().Int32Value() & 0x3), 0);
            // In load shadow fold vtable_ object header size into method_index_
            opRegImm(cUnit, kOpAdd, r0,
                     art::Array::DataOffset().Int32Value() / 4);
            // Get target Method*
            loadBaseIndexed(cUnit, rLR, r0, r0, 2, kWord);
            break;
        case 6: // Get the target compiled code address [uses r0, sets rLR]
            loadWordDisp(cUnit, r0, Method::GetCodeOffset().Int32Value(), rLR);
            break;
        default:
            return -1;
    }
    return state + 1;
}

STATIC int loadArgRegs(CompilationUnit* cUnit, MIR* mir,
                          DecodedInstruction* dInsn, int callState,
                          NextCallInsn nextCallInsn, ArmLIR* rollback,
                          bool skipThis)
{
    int nextReg = r1;
    int nextArg = 0;
    if (skipThis) {
        nextReg++;
        nextArg++;
    }
    for (; (nextReg <= r3) && (nextArg < mir->ssaRep->numUses); nextReg++) {
        RegLocation rlArg = oatGetRawSrc(cUnit, mir, nextArg++);
        rlArg = oatUpdateRawLoc(cUnit, rlArg);
        if (rlArg.wide && (nextReg <= r2)) {
            loadValueDirectWideFixed(cUnit, rlArg, nextReg, nextReg + 1);
            nextReg++;
            nextArg++;
        } else {
            rlArg.wide = false;
            loadValueDirectFixed(cUnit, rlArg, nextReg);
        }
        callState = nextCallInsn(cUnit, mir, dInsn, callState, rollback);
    }
    return callState;
}

// Interleave launch code for INVOKE_INTERFACE.
STATIC int nextInterfaceCallInsn(CompilationUnit* cUnit, MIR* mir,
                                 DecodedInstruction* dInsn, int state,
                                 ArmLIR* rollback)
{
    DCHECK(rollback == NULL);
    switch(state) {
        case 0: // Load trampoline target
            loadWordDisp(cUnit, rSELF,
                         OFFSETOF_MEMBER(Thread, pInvokeInterfaceTrampoline),
                         rLR);
            // Load r0 with method index
            loadConstant(cUnit, r0, dInsn->vB);
            break;
        default:
            return -1;
    }
    return state + 1;
}

/*
 * Interleave launch code for INVOKE_SUPER.  See comments
 * for nextVCallIns.
 */
STATIC int nextSuperCallInsn(CompilationUnit* cUnit, MIR* mir,
                             DecodedInstruction* dInsn, int state,
                             ArmLIR* rollback)
{
    DCHECK(rollback == NULL);
    RegLocation rlArg;
    /*
     * This is the fast path in which the target virtual method is
     * fully resolved at compile time.  Note also that this path assumes
     * that the check to verify that the target method index falls
     * within the size of the super's vtable has been done at compile-time.
     */
    art::ClassLinker* class_linker = art::Runtime::Current()->GetClassLinker();
    Method* baseMethod = class_linker->ResolveMethod(*cUnit->dex_file,
                                                     dInsn->vB,
                                                     cUnit->dex_cache,
                                                     cUnit->class_loader,
                                                     false);
    CHECK(baseMethod != NULL);
    Class* declaring_class = cUnit->dex_cache->GetResolvedTypes()
        ->Get(cUnit->dex_file->GetMethodId(cUnit->method_idx).class_idx_);
    Class* superClass = (declaring_class != NULL)
        ? declaring_class->GetSuperClass() : NULL;
    CHECK(superClass != NULL);
    int32_t target_idx = baseMethod->GetMethodIndex();
    CHECK(superClass->GetVTable()->GetLength() > target_idx);
    Method* targetMethod = superClass->GetVTable()->Get(target_idx);
    CHECK(targetMethod != NULL);
    switch(state) {
        case 0: // Get current Method* [set r0]
            loadCurrMethodDirect(cUnit, r0);
            // Load "this" [set r1]
            rlArg = oatGetSrc(cUnit, mir, 0);
            loadValueDirectFixed(cUnit, rlArg, r1);
            // Get method->declaring_class_ [use r0, set rLR]
            loadWordDisp(cUnit, r0, Method::DeclaringClassOffset().Int32Value(),
                         rLR);
            // Is "this" null? [use r1]
            genNullCheck(cUnit, oatSSASrc(mir,0), r1, mir);
            break;
        case 1: // Get method->declaring_class_->super_class [usr rLR, set rLR]
            loadWordDisp(cUnit, rLR, Class::SuperClassOffset().Int32Value(),
                         rLR);
            break;
        case 2: // Get ...->super_class_->vtable [u/s rLR]
            loadWordDisp(cUnit, rLR, Class::VTableOffset().Int32Value(), rLR);
            break;
        case 3: // Get target method [use rLR, set r0]
            loadWordDisp(cUnit, rLR, (target_idx * 4) +
                         art::Array::DataOffset().Int32Value(), r0);
            break;
        case 4: // Get the target compiled code address [uses r0, sets rLR]
            loadWordDisp(cUnit, r0, Method::GetCodeOffset().Int32Value(), rLR);
            break;
        default:
            return -1;
    }
    return state + 1;
}

/* Slow-path version of nextSuperCallInsn */
STATIC int nextSuperCallInsnSP(CompilationUnit* cUnit, MIR* mir,
                               DecodedInstruction* dInsn, int state,
                               ArmLIR* rollback)
{
    RegLocation rlArg;
    ArmLIR* skipBranch;
    ArmLIR* skipTarget;
    int tReg;
    /*
     * This handles the case in which the base method is not fully
     * resolved at compile time.  We must generate code to test
     * for resolution a run time, bail to the slow path if not to
     * fill in all the tables.  In the latter case, we'll restart at
     * at the beginning of the sequence.
     */
    switch(state) {
        case 0:  // Get the current Method* [sets r0]
            loadCurrMethodDirect(cUnit, r0);
            break;
        case 1: // Get method->dex_cache_resolved_methods_ [uses r0, set rLR]
            loadWordDisp(cUnit, r0,
                Method::GetDexCacheResolvedMethodsOffset().Int32Value(), rLR);
            break;
        case 2: // method->dex_cache_resolved_methods_->Get(meth_idx) [u/s rLR]
            loadWordDisp(cUnit, rLR, (dInsn->vB * 4) +
                         art::Array::DataOffset().Int32Value(), rLR);
            break;
        case 3: // Resolved?
            skipBranch = genCmpImmBranch(cUnit, kArmCondNe, rLR, 0);
            // Slowest path, bail to helper, rollback and retry
            loadWordDisp(cUnit, rSELF,
                         OFFSETOF_MEMBER(Thread, pResolveMethodFromCode), rLR);
            loadConstant(cUnit, r1, dInsn->vB);
            loadConstant(cUnit, r2, true);
            callRuntimeHelper(cUnit, rLR);
            genUnconditionalBranch(cUnit, rollback);
            // Resume normal slow path
            skipTarget = newLIR0(cUnit, kArmPseudoTargetLabel);
            skipTarget->defMask = ENCODE_ALL;
            skipBranch->generic.target = (LIR*)skipTarget;
            // Get base_method->method_index [usr rLR, set rLR]
            loadBaseDisp(cUnit, mir, rLR,
                         Method::GetMethodIndexOffset().Int32Value(), rLR,
                         kUnsignedHalf, INVALID_SREG);
            // Load "this" [set r1]
            rlArg = oatGetSrc(cUnit, mir, 0);
            loadValueDirectFixed(cUnit, rlArg, r1);
            // Load curMethod->declaring_class_ [uses r0, sets r0]
            loadWordDisp(cUnit, r0, Method::DeclaringClassOffset().Int32Value(),
                         r0);
            // Null this?
            genNullCheck(cUnit, oatSSASrc(mir,0), r1, mir);
            // Get method->declaring_class_->super_class [usr r0, set r0]
            loadWordDisp(cUnit, r0, Class::SuperClassOffset().Int32Value(), r0);
            break;
        case 4: // Get ...->super_class_->vtable [u/s r0]
            loadWordDisp(cUnit, r0, Class::VTableOffset().Int32Value(), r0);
            if (!(mir->optimizationFlags & MIR_IGNORE_RANGE_CHECK)) {
                // Range check, throw NSM on failure
                tReg = oatAllocTemp(cUnit);
                loadWordDisp(cUnit, r0, art::Array::LengthOffset().Int32Value(),
                             tReg);
                genRegRegCheck(cUnit, kArmCondCs, tReg, rLR, mir,
                               kArmThrowNoSuchMethod);
                oatFreeTemp(cUnit, tReg);
            }
            // Adjust vtable_ base past object header
            opRegImm(cUnit, kOpAdd, r0, art::Array::DataOffset().Int32Value());
            // Get target Method*
            loadBaseIndexed(cUnit, r0, rLR, r0, 2, kWord);
            break;
        case 5: // Get the target compiled code address [uses r0, sets rLR]
            loadWordDisp(cUnit, r0, Method::GetCodeOffset().Int32Value(), rLR);
            break;
        default:
            return -1;
    }
    return state + 1;
}

/*
 * Load up to 5 arguments, the first three of which will be in
 * r1 .. r3.  On entry r0 contains the current method pointer,
 * and as part of the load sequence, it must be replaced with
 * the target method pointer.  Note, this may also be called
 * for "range" variants if the number of arguments is 5 or fewer.
 */
STATIC int genDalvikArgsNoRange(CompilationUnit* cUnit, MIR* mir,
                                DecodedInstruction* dInsn, int callState,
                                ArmLIR** pcrLabel, bool isRange,
                                NextCallInsn nextCallInsn, ArmLIR* rollback,
                                bool skipThis)
{
    RegLocation rlArg;

    /* If no arguments, just return */
    if (dInsn->vA == 0)
        return callState;

    callState = nextCallInsn(cUnit, mir, dInsn, callState, rollback);

    DCHECK_LE(dInsn->vA, 5U);
    if (dInsn->vA > 3) {
        uint32_t nextUse = 3;
        //Detect special case of wide arg spanning arg3/arg4
        RegLocation rlUse0 = oatGetRawSrc(cUnit, mir, 0);
        RegLocation rlUse1 = oatGetRawSrc(cUnit, mir, 1);
        RegLocation rlUse2 = oatGetRawSrc(cUnit, mir, 2);
        if (((!rlUse0.wide && !rlUse1.wide) || rlUse0.wide) &&
            rlUse2.wide) {
            int reg;
            // Wide spans, we need the 2nd half of uses[2].
            rlArg = oatUpdateLocWide(cUnit, rlUse2);
            if (rlArg.location == kLocPhysReg) {
                reg = rlArg.highReg;
            } else {
                // r2 & r3 can safely be used here
                reg = r3;
                loadWordDisp(cUnit, rSP,
                             oatSRegOffset(cUnit, rlArg.sRegLow) + 4, reg);
                callState = nextCallInsn(cUnit, mir, dInsn, callState,
                                         rollback);
            }
            storeBaseDisp(cUnit, rSP, (nextUse + 1) * 4, reg, kWord);
            storeBaseDisp(cUnit, rSP, 16 /* (3+1)*4 */, reg, kWord);
            callState = nextCallInsn(cUnit, mir, dInsn, callState, rollback);
            nextUse++;
        }
        // Loop through the rest
        while (nextUse < dInsn->vA) {
            int lowReg;
            int highReg;
            rlArg = oatGetRawSrc(cUnit, mir, nextUse);
            rlArg = oatUpdateRawLoc(cUnit, rlArg);
            if (rlArg.location == kLocPhysReg) {
                lowReg = rlArg.lowReg;
                highReg = rlArg.highReg;
            } else {
                lowReg = r2;
                highReg = r3;
                if (rlArg.wide) {
                    loadValueDirectWideFixed(cUnit, rlArg, lowReg, highReg);
                } else {
                    loadValueDirectFixed(cUnit, rlArg, lowReg);
                }
                callState = nextCallInsn(cUnit, mir, dInsn, callState,
                                         rollback);
            }
            int outsOffset = (nextUse + 1) * 4;
            if (rlArg.wide) {
                storeBaseDispWide(cUnit, rSP, outsOffset, lowReg, highReg);
                nextUse += 2;
            } else {
                storeWordDisp(cUnit, rSP, outsOffset, lowReg);
                nextUse++;
            }
            callState = nextCallInsn(cUnit, mir, dInsn, callState, rollback);
        }
    }

    callState = loadArgRegs(cUnit, mir, dInsn, callState, nextCallInsn,
                            rollback, skipThis);

    if (pcrLabel) {
        *pcrLabel = genNullCheck(cUnit, oatSSASrc(mir,0), r1, mir);
    }
    return callState;
}

/*
 * May have 0+ arguments (also used for jumbo).  Note that
 * source virtual registers may be in physical registers, so may
 * need to be flushed to home location before copying.  This
 * applies to arg3 and above (see below).
 *
 * Two general strategies:
 *    If < 20 arguments
 *       Pass args 3-18 using vldm/vstm block copy
 *       Pass arg0, arg1 & arg2 in r1-r3
 *    If 20+ arguments
 *       Pass args arg19+ using memcpy block copy
 *       Pass arg0, arg1 & arg2 in r1-r3
 *
 */
STATIC int genDalvikArgsRange(CompilationUnit* cUnit, MIR* mir,
                              DecodedInstruction* dInsn, int callState,
                              ArmLIR** pcrLabel, NextCallInsn nextCallInsn,
                              ArmLIR* rollback, bool skipThis)
{
    int firstArg = dInsn->vC;
    int numArgs = dInsn->vA;

    // If we can treat it as non-range (Jumbo ops will use range form)
    if (numArgs <= 5)
        return genDalvikArgsNoRange(cUnit, mir, dInsn, callState, pcrLabel,
                                    true, nextCallInsn, rollback, skipThis);
    /*
     * Make sure range list doesn't span the break between in normal
     * Dalvik vRegs and the ins.
     */
    int highestArg = oatGetSrc(cUnit, mir, numArgs-1).sRegLow;
    int boundaryReg = cUnit->numDalvikRegisters - cUnit->numIns;
    if ((firstArg < boundaryReg) && (highestArg >= boundaryReg)) {
        LOG(FATAL) << "Argument list spanned locals & args";
    }

    /*
     * First load the non-register arguments.  Both forms expect all
     * of the source arguments to be in their home frame location, so
     * scan the sReg names and flush any that have been promoted to
     * frame backing storage.
     */
    // Scan the rest of the args - if in physReg flush to memory
    for (int nextArg = 0; nextArg < numArgs;) {
        RegLocation loc = oatGetRawSrc(cUnit, mir, nextArg);
        if (loc.wide) {
            loc = oatUpdateLocWide(cUnit, loc);
            if ((nextArg >= 2) && (loc.location == kLocPhysReg)) {
                storeBaseDispWide(cUnit, rSP,
                                  oatSRegOffset(cUnit, loc.sRegLow),
                                  loc.lowReg, loc.highReg);
            }
            nextArg += 2;
        } else {
            loc = oatUpdateLoc(cUnit, loc);
            if ((nextArg >= 3) && (loc.location == kLocPhysReg)) {
                storeBaseDisp(cUnit, rSP, oatSRegOffset(cUnit, loc.sRegLow),
                              loc.lowReg, kWord);
            }
            nextArg++;
        }
    }

    int startOffset = oatSRegOffset(cUnit,
        cUnit->regLocation[mir->ssaRep->uses[3]].sRegLow);
    int outsOffset = 4 /* Method* */ + (3 * 4);
    if (numArgs >= 20) {
        // Generate memcpy
        opRegRegImm(cUnit, kOpAdd, r0, rSP, outsOffset);
        opRegRegImm(cUnit, kOpAdd, r1, rSP, startOffset);
        loadWordDisp(cUnit, rSELF, OFFSETOF_MEMBER(Thread, pMemcpy), rLR);
        loadConstant(cUnit, r2, (numArgs - 3) * 4);
        callRuntimeHelper(cUnit, rLR);
        // Restore Method*
        loadCurrMethodDirect(cUnit, r0);
    } else {
        // Use vldm/vstm pair using r3 as a temp
        int regsLeft = std::min(numArgs - 3, 16);
        callState = nextCallInsn(cUnit, mir, dInsn, callState, rollback);
        opRegRegImm(cUnit, kOpAdd, r3, rSP, startOffset);
        ArmLIR* ld = newLIR3(cUnit, kThumb2Vldms, r3, fr0, regsLeft);
        //TUNING: loosen barrier
        ld->defMask = ENCODE_ALL;
        setMemRefType(ld, true /* isLoad */, kDalvikReg);
        callState = nextCallInsn(cUnit, mir, dInsn, callState, rollback);
        opRegRegImm(cUnit, kOpAdd, r3, rSP, 4 /* Method* */ + (3 * 4));
        callState = nextCallInsn(cUnit, mir, dInsn, callState, rollback);
        ArmLIR* st = newLIR3(cUnit, kThumb2Vstms, r3, fr0, regsLeft);
        setMemRefType(st, false /* isLoad */, kDalvikReg);
        st->defMask = ENCODE_ALL;
        callState = nextCallInsn(cUnit, mir, dInsn, callState, rollback);
    }

    callState = loadArgRegs(cUnit, mir, dInsn, callState, nextCallInsn,
                            rollback, skipThis);

    callState = nextCallInsn(cUnit, mir, dInsn, callState, rollback);
    if (pcrLabel) {
        *pcrLabel = genNullCheck(cUnit, oatSSASrc(mir,0), r1, mir);
    }
    return callState;
}

// Debugging routine - if null target, branch to DebugMe
STATIC void genShowTarget(CompilationUnit* cUnit)
{
    ArmLIR* branchOver = genCmpImmBranch(cUnit, kArmCondNe, rLR, 0);
    loadWordDisp(cUnit, rSELF,
                 OFFSETOF_MEMBER(Thread, pDebugMe), rLR);
    ArmLIR* target = newLIR0(cUnit, kArmPseudoTargetLabel);
    target->defMask = -1;
    branchOver->generic.target = (LIR*)target;
}

STATIC void genInvokeStaticDirect(CompilationUnit* cUnit, MIR* mir,
                                  bool direct, bool range)
{
    DecodedInstruction* dInsn = &mir->dalvikInsn;
    int callState = 0;
    ArmLIR* nullCk;
    ArmLIR** pNullCk = direct ? &nullCk : NULL;
    NextCallInsn nextCallInsn = nextSDCallInsn;
    oatFlushAllRegs(cUnit);    /* Everything to home location */

    // Explicit register usage
    oatLockCallTemps(cUnit);

    // Is this the special "Ljava/lang/Object;.<init>:()V" case?
    if (mir->dalvikInsn.opcode == OP_INVOKE_DIRECT) {
        int idx = mir->dalvikInsn.vB;
        Method* target = cUnit->dex_cache->GetResolvedMethods()->Get(idx);
        if (target) {
            if (PrettyMethod(target) == "java.lang.Object.<init>()V") {
                RegLocation rlArg = oatGetSrc(cUnit, mir, 0);
                loadValueDirectFixed(cUnit, rlArg, r0);
                loadWordDisp(cUnit, rSELF,
                         OFFSETOF_MEMBER(Thread, pObjectInit), rLR);
                genNullCheck(cUnit, oatSSASrc(mir,0), r0, mir);
                opReg(cUnit, kOpBlx, rLR);
                oatClobberCalleeSave(cUnit);
                return;
            }
        }
    }

    if (range) {
        callState = genDalvikArgsRange(cUnit, mir, dInsn, callState, pNullCk,
                                       nextCallInsn, NULL, false);
    } else {
        callState = genDalvikArgsNoRange(cUnit, mir, dInsn, callState, pNullCk,
                                         false, nextCallInsn, NULL, false);
    }
    // Finish up any of the call sequence not interleaved in arg loading
    while (callState >= 0) {
        callState = nextCallInsn(cUnit, mir, dInsn, callState, NULL);
    }
    if (DISPLAY_MISSING_TARGETS) {
        genShowTarget(cUnit);
    }
    opReg(cUnit, kOpBlx, rLR);
    oatClobberCalleeSave(cUnit);
}

/*
 * All invoke-interface calls bounce off of art_invoke_interface_trampoline,
 * which will locate the target and continue on via a tail call.
 */
STATIC void genInvokeInterface(CompilationUnit* cUnit, MIR* mir)
{
    DecodedInstruction* dInsn = &mir->dalvikInsn;
    int callState = 0;
    ArmLIR* nullCk;
    oatFlushAllRegs(cUnit);    /* Everything to home location */

    // Explicit register usage
    oatLockCallTemps(cUnit);
    /* Note: must call nextInterfaceCallInsn() prior to 1st argument load */
    callState = nextInterfaceCallInsn(cUnit, mir, dInsn, callState, NULL);
    if (mir->dalvikInsn.opcode == OP_INVOKE_INTERFACE)
        callState = genDalvikArgsNoRange(cUnit, mir, dInsn, callState, &nullCk,
                                         false, nextInterfaceCallInsn, NULL,
                                         false);
    else
        callState = genDalvikArgsRange(cUnit, mir, dInsn, callState, &nullCk,
                                       nextInterfaceCallInsn, NULL, false);
    // Finish up any of the call sequence not interleaved in arg loading
    while (callState >= 0) {
        callState = nextInterfaceCallInsn(cUnit, mir, dInsn, callState, NULL);
    }
    if (DISPLAY_MISSING_TARGETS) {
        genShowTarget(cUnit);
    }
    opReg(cUnit, kOpBlx, rLR);
    oatClobberCalleeSave(cUnit);
}

STATIC void genInvokeSuper(CompilationUnit* cUnit, MIR* mir)
{
    DecodedInstruction* dInsn = &mir->dalvikInsn;
    int callState = 0;
    ArmLIR* rollback;
    art::ClassLinker* class_linker = art::Runtime::Current()->GetClassLinker();
    Method* baseMethod = class_linker->ResolveMethod(*cUnit->dex_file,
                                                     dInsn->vB,
                                                     cUnit->dex_cache,
                                                     cUnit->class_loader,
                                                     false);
    NextCallInsn nextCallInsn;
    bool fastPath = true;
    oatFlushAllRegs(cUnit);    /* Everything to home location */

    // Explicit register usage
    oatLockCallTemps(cUnit);

    // For testing, force call to artResolveMethodFromCode & ignore result
    if (EXERCISE_RESOLVE_METHOD) {
        loadCurrMethodDirect(cUnit, r0);
        loadWordDisp(cUnit, rSELF,
                     OFFSETOF_MEMBER(Thread, pResolveMethodFromCode), rLR);
        loadConstant(cUnit, r1, dInsn->vB);
        loadConstant(cUnit, r2, true);
        callRuntimeHelper(cUnit, rLR);
    }

    if (SLOW_INVOKE_PATH || baseMethod == NULL) {
        Thread* thread = Thread::Current();
        if (thread->IsExceptionPending()) {  // clear any exception left by resolve method
            thread->ClearException();
        }
        fastPath = false;
    } else {
        Class* declaring_class = cUnit->dex_cache->GetResolvedTypes()
            ->Get(cUnit->dex_file->GetMethodId(cUnit->method_idx).class_idx_);
        Class* superClass = (declaring_class != NULL)
            ? declaring_class->GetSuperClass() : NULL;
        if (superClass == NULL) {
            fastPath = false;
        } else {
            int32_t target_idx = baseMethod->GetMethodIndex();
            if (superClass->GetVTable()->GetLength() <= target_idx) {
                fastPath = false;
            } else {
                fastPath = (superClass->GetVTable()->Get(target_idx) != NULL);
            }
        }
    }
    if (fastPath) {
        nextCallInsn = nextSuperCallInsn;
        rollback = NULL;
    } else {
        nextCallInsn = nextSuperCallInsnSP;
        rollback = newLIR0(cUnit, kArmPseudoTargetLabel);
        rollback->defMask = -1;
    }
    if (mir->dalvikInsn.opcode == OP_INVOKE_SUPER)
        callState = genDalvikArgsNoRange(cUnit, mir, dInsn, callState, NULL,
                                         false, nextCallInsn, rollback, true);
    else
        callState = genDalvikArgsRange(cUnit, mir, dInsn, callState, NULL,
                                       nextCallInsn, rollback, true);
    // Finish up any of the call sequence not interleaved in arg loading
    while (callState >= 0) {
        callState = nextCallInsn(cUnit, mir, dInsn, callState, rollback);
    }
    if (DISPLAY_MISSING_TARGETS) {
        genShowTarget(cUnit);
    }
    opReg(cUnit, kOpBlx, rLR);
    oatClobberCalleeSave(cUnit);
}

STATIC void genInvokeVirtual(CompilationUnit* cUnit, MIR* mir)
{
    DecodedInstruction* dInsn = &mir->dalvikInsn;
    int callState = 0;
    ArmLIR* rollback;
    art::ClassLinker* class_linker = art::Runtime::Current()->GetClassLinker();
    Method* method = class_linker->ResolveMethod(*cUnit->dex_file,
                                                 dInsn->vB,
                                                 cUnit->dex_cache,
                                                 cUnit->class_loader,
                                                 false);
    NextCallInsn nextCallInsn;
    oatFlushAllRegs(cUnit);    /* Everything to home location */
    // Explicit register usage
    oatLockCallTemps(cUnit);

    // For testing, force call to artResolveMethodFromCode & ignore result
    if (EXERCISE_RESOLVE_METHOD) {
        loadCurrMethodDirect(cUnit, r0);
        loadWordDisp(cUnit, rSELF,
                     OFFSETOF_MEMBER(Thread, pResolveMethodFromCode), rLR);
        loadConstant(cUnit, r1, dInsn->vB);
        loadConstant(cUnit, r2, false);
        callRuntimeHelper(cUnit, rLR);
    }

    if (SLOW_INVOKE_PATH || method == NULL) {
        Thread* thread = Thread::Current();
        if (thread->IsExceptionPending()) {  // clear any exception left by resolve method
            thread->ClearException();
        }
        // Slow path
        nextCallInsn = nextVCallInsnSP;
        // If we need a slow-path callout, we'll restart here
        rollback = newLIR0(cUnit, kArmPseudoTargetLabel);
        rollback->defMask = -1;
    } else {
        // Fast path
        nextCallInsn = nextVCallInsn;
        rollback = NULL;
    }
    if (mir->dalvikInsn.opcode == OP_INVOKE_VIRTUAL)
        callState = genDalvikArgsNoRange(cUnit, mir, dInsn, callState, NULL,
                                         false, nextCallInsn, rollback, true);
    else
        callState = genDalvikArgsRange(cUnit, mir, dInsn, callState, NULL,
                                       nextCallInsn, rollback, true);
    // Finish up any of the call sequence not interleaved in arg loading
    while (callState >= 0) {
        callState = nextCallInsn(cUnit, mir, dInsn, callState, rollback);
    }
    if (DISPLAY_MISSING_TARGETS) {
        genShowTarget(cUnit);
    }
    opReg(cUnit, kOpBlx, rLR);
    oatClobberCalleeSave(cUnit);
}

STATIC bool compileDalvikInstruction(CompilationUnit* cUnit, MIR* mir,
                                     BasicBlock* bb, ArmLIR* labelList)
{
    bool res = false;   // Assume success
    RegLocation rlSrc[3];
    RegLocation rlDest = badLoc;
    RegLocation rlResult = badLoc;
    Opcode opcode = mir->dalvikInsn.opcode;

    /* Prep Src and Dest locations */
    int nextSreg = 0;
    int nextLoc = 0;
    int attrs = oatDataFlowAttributes[opcode];
    rlSrc[0] = rlSrc[1] = rlSrc[2] = badLoc;
    if (attrs & DF_UA) {
        rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
        nextSreg++;
    } else if (attrs & DF_UA_WIDE) {
        rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg,
                                                 nextSreg + 1);
        nextSreg+= 2;
    }
    if (attrs & DF_UB) {
        rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
        nextSreg++;
    } else if (attrs & DF_UB_WIDE) {
        rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg,
                                                 nextSreg + 1);
        nextSreg+= 2;
    }
    if (attrs & DF_UC) {
        rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
    } else if (attrs & DF_UC_WIDE) {
        rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg,
                                                 nextSreg + 1);
    }
    if (attrs & DF_DA) {
        rlDest = oatGetDest(cUnit, mir, 0);
    } else if (attrs & DF_DA_WIDE) {
        rlDest = oatGetDestWide(cUnit, mir, 0, 1);
    }

    switch(opcode) {
        case OP_NOP:
            break;

        case OP_MOVE_EXCEPTION:
            int exOffset;
            int resetReg;
            exOffset = Thread::ExceptionOffset().Int32Value();
            resetReg = oatAllocTemp(cUnit);
            rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
            loadWordDisp(cUnit, rSELF, exOffset, rlResult.lowReg);
            loadConstant(cUnit, resetReg, 0);
            storeWordDisp(cUnit, rSELF, exOffset, resetReg);
            storeValue(cUnit, rlDest, rlResult);
            break;

        case OP_RETURN_VOID:
            genSuspendTest(cUnit, mir);
            break;

        case OP_RETURN:
        case OP_RETURN_OBJECT:
            genSuspendTest(cUnit, mir);
            storeValue(cUnit, getRetLoc(cUnit), rlSrc[0]);
            break;

        case OP_RETURN_WIDE:
            genSuspendTest(cUnit, mir);
            storeValueWide(cUnit, getRetLocWide(cUnit), rlSrc[0]);
            break;

        case OP_MOVE_RESULT_WIDE:
            if (mir->optimizationFlags & MIR_INLINED)
                break;  // Nop - combined w/ previous invoke
            storeValueWide(cUnit, rlDest, getRetLocWide(cUnit));
            break;

        case OP_MOVE_RESULT:
        case OP_MOVE_RESULT_OBJECT:
            if (mir->optimizationFlags & MIR_INLINED)
                break;  // Nop - combined w/ previous invoke
            storeValue(cUnit, rlDest, getRetLoc(cUnit));
            break;

        case OP_MOVE:
        case OP_MOVE_OBJECT:
        case OP_MOVE_16:
        case OP_MOVE_OBJECT_16:
        case OP_MOVE_FROM16:
        case OP_MOVE_OBJECT_FROM16:
            storeValue(cUnit, rlDest, rlSrc[0]);
            break;

        case OP_MOVE_WIDE:
        case OP_MOVE_WIDE_16:
        case OP_MOVE_WIDE_FROM16:
            storeValueWide(cUnit, rlDest, rlSrc[0]);
            break;

        case OP_CONST:
        case OP_CONST_4:
        case OP_CONST_16:
            rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
            loadConstantNoClobber(cUnit, rlResult.lowReg, mir->dalvikInsn.vB);
            storeValue(cUnit, rlDest, rlResult);
            break;

        case OP_CONST_HIGH16:
            rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
            loadConstantNoClobber(cUnit, rlResult.lowReg,
                                  mir->dalvikInsn.vB << 16);
            storeValue(cUnit, rlDest, rlResult);
            break;

        case OP_CONST_WIDE_16:
        case OP_CONST_WIDE_32:
            rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
            loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
                                  mir->dalvikInsn.vB,
                                  (mir->dalvikInsn.vB & 0x80000000) ? -1 : 0);
            storeValueWide(cUnit, rlDest, rlResult);
            break;

        case OP_CONST_WIDE:
            rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
            loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
                          mir->dalvikInsn.vB_wide & 0xffffffff,
                          (mir->dalvikInsn.vB_wide >> 32) & 0xffffffff);
            storeValueWide(cUnit, rlDest, rlResult);
            break;

        case OP_CONST_WIDE_HIGH16:
            rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
            loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
                                  0, mir->dalvikInsn.vB << 16);
            storeValueWide(cUnit, rlDest, rlResult);
            break;

        case OP_MONITOR_ENTER:
            genMonitorEnter(cUnit, mir, rlSrc[0]);
            break;

        case OP_MONITOR_EXIT:
            genMonitorExit(cUnit, mir, rlSrc[0]);
            break;

        case OP_CHECK_CAST:
            genCheckCast(cUnit, mir, rlSrc[0]);
            break;

        case OP_INSTANCE_OF:
            genInstanceof(cUnit, mir, rlDest, rlSrc[0]);
            break;

        case OP_NEW_INSTANCE:
            genNewInstance(cUnit, mir, rlDest);
            break;

        case OP_THROW:
            genThrow(cUnit, mir, rlSrc[0]);
            break;

        case OP_THROW_VERIFICATION_ERROR:
            loadWordDisp(cUnit, rSELF,
                OFFSETOF_MEMBER(Thread, pThrowVerificationErrorFromCode), rLR);
            loadConstant(cUnit, r0, mir->dalvikInsn.vA);
            loadConstant(cUnit, r1, mir->dalvikInsn.vB);
            callRuntimeHelper(cUnit, rLR);
            break;

        case OP_ARRAY_LENGTH:
            int lenOffset;
            lenOffset = Array::LengthOffset().Int32Value();
            rlSrc[0] = loadValue(cUnit, rlSrc[0], kCoreReg);
            genNullCheck(cUnit, rlSrc[0].sRegLow, rlSrc[0].lowReg, mir);
            rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
            loadWordDisp(cUnit, rlSrc[0].lowReg, lenOffset,
                         rlResult.lowReg);
            storeValue(cUnit, rlDest, rlResult);
            break;

        case OP_CONST_STRING:
        case OP_CONST_STRING_JUMBO:
            genConstString(cUnit, mir, rlDest, rlSrc[0]);
            break;

        case OP_CONST_CLASS:
            genConstClass(cUnit, mir, rlDest, rlSrc[0]);
            break;

        case OP_FILL_ARRAY_DATA:
            genFillArrayData(cUnit, mir, rlSrc[0]);
            break;

        case OP_FILLED_NEW_ARRAY:
            genFilledNewArray(cUnit, mir, false /* not range */);
            break;

        case OP_FILLED_NEW_ARRAY_RANGE:
            genFilledNewArray(cUnit, mir, true /* range */);
            break;

        case OP_NEW_ARRAY:
            genNewArray(cUnit, mir, rlDest, rlSrc[0]);
            break;

        case OP_GOTO:
        case OP_GOTO_16:
        case OP_GOTO_32:
            if (bb->taken->startOffset <= mir->offset) {
                genSuspendTest(cUnit, mir);
            }
            genUnconditionalBranch(cUnit, &labelList[bb->taken->id]);
            break;

        case OP_PACKED_SWITCH:
            genPackedSwitch(cUnit, mir, rlSrc[0]);
            break;

        case OP_SPARSE_SWITCH:
            genSparseSwitch(cUnit, mir, rlSrc[0]);
            break;

        case OP_CMPL_FLOAT:
        case OP_CMPG_FLOAT:
        case OP_CMPL_DOUBLE:
        case OP_CMPG_DOUBLE:
            res = genCmpFP(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
            break;

        case OP_CMP_LONG:
            genCmpLong(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
            break;

        case OP_IF_EQ:
        case OP_IF_NE:
        case OP_IF_LT:
        case OP_IF_GE:
        case OP_IF_GT:
        case OP_IF_LE: {
            bool backwardBranch;
            ArmConditionCode cond;
            backwardBranch = (bb->taken->startOffset <= mir->offset);
            if (backwardBranch) {
                genSuspendTest(cUnit, mir);
            }
            rlSrc[0] = loadValue(cUnit, rlSrc[0], kCoreReg);
            rlSrc[1] = loadValue(cUnit, rlSrc[1], kCoreReg);
            opRegReg(cUnit, kOpCmp, rlSrc[0].lowReg, rlSrc[1].lowReg);
            switch(opcode) {
                case OP_IF_EQ:
                    cond = kArmCondEq;
                    break;
                case OP_IF_NE:
                    cond = kArmCondNe;
                    break;
                case OP_IF_LT:
                    cond = kArmCondLt;
                    break;
                case OP_IF_GE:
                    cond = kArmCondGe;
                    break;
                case OP_IF_GT:
                    cond = kArmCondGt;
                    break;
                case OP_IF_LE:
                    cond = kArmCondLe;
                    break;
                default:
                    cond = (ArmConditionCode)0;
                    LOG(FATAL) << "Unexpected opcode " << (int)opcode;
            }
            genConditionalBranch(cUnit, cond, &labelList[bb->taken->id]);
            genUnconditionalBranch(cUnit, &labelList[bb->fallThrough->id]);
            break;
            }

        case OP_IF_EQZ:
        case OP_IF_NEZ:
        case OP_IF_LTZ:
        case OP_IF_GEZ:
        case OP_IF_GTZ:
        case OP_IF_LEZ: {
            bool backwardBranch;
            ArmConditionCode cond;
            backwardBranch = (bb->taken->startOffset <= mir->offset);
            if (backwardBranch) {
                genSuspendTest(cUnit, mir);
            }
            rlSrc[0] = loadValue(cUnit, rlSrc[0], kCoreReg);
            opRegImm(cUnit, kOpCmp, rlSrc[0].lowReg, 0);
            switch(opcode) {
                case OP_IF_EQZ:
                    cond = kArmCondEq;
                    break;
                case OP_IF_NEZ:
                    cond = kArmCondNe;
                    break;
                case OP_IF_LTZ:
                    cond = kArmCondLt;
                    break;
                case OP_IF_GEZ:
                    cond = kArmCondGe;
                    break;
                case OP_IF_GTZ:
                    cond = kArmCondGt;
                    break;
                case OP_IF_LEZ:
                    cond = kArmCondLe;
                    break;
                default:
                    cond = (ArmConditionCode)0;
                    LOG(FATAL) << "Unexpected opcode " << (int)opcode;
            }
            genConditionalBranch(cUnit, cond, &labelList[bb->taken->id]);
            genUnconditionalBranch(cUnit, &labelList[bb->fallThrough->id]);
            break;
            }

      case OP_AGET_WIDE:
            genArrayGet(cUnit, mir, kLong, rlSrc[0], rlSrc[1], rlDest, 3);
            break;
        case OP_AGET:
        case OP_AGET_OBJECT:
            genArrayGet(cUnit, mir, kWord, rlSrc[0], rlSrc[1], rlDest, 2);
            break;
        case OP_AGET_BOOLEAN:
            genArrayGet(cUnit, mir, kUnsignedByte, rlSrc[0], rlSrc[1],
                        rlDest, 0);
            break;
        case OP_AGET_BYTE:
            genArrayGet(cUnit, mir, kSignedByte, rlSrc[0], rlSrc[1], rlDest, 0);
            break;
        case OP_AGET_CHAR:
            genArrayGet(cUnit, mir, kUnsignedHalf, rlSrc[0], rlSrc[1],
                        rlDest, 1);
            break;
        case OP_AGET_SHORT:
            genArrayGet(cUnit, mir, kSignedHalf, rlSrc[0], rlSrc[1], rlDest, 1);
            break;
        case OP_APUT_WIDE:
            genArrayPut(cUnit, mir, kLong, rlSrc[1], rlSrc[2], rlSrc[0], 3);
            break;
        case OP_APUT:
            genArrayPut(cUnit, mir, kWord, rlSrc[1], rlSrc[2], rlSrc[0], 2);
            break;
        case OP_APUT_OBJECT:
            genArrayObjPut(cUnit, mir, rlSrc[1], rlSrc[2], rlSrc[0], 2);
            break;
        case OP_APUT_SHORT:
        case OP_APUT_CHAR:
            genArrayPut(cUnit, mir, kUnsignedHalf, rlSrc[1], rlSrc[2],
                        rlSrc[0], 1);
            break;
        case OP_APUT_BYTE:
        case OP_APUT_BOOLEAN:
            genArrayPut(cUnit, mir, kUnsignedByte, rlSrc[1], rlSrc[2],
                        rlSrc[0], 0);
            break;

        case OP_IGET_WIDE:
        case OP_IGET_WIDE_VOLATILE:
            genIGetWide(cUnit, mir, rlDest, rlSrc[0]);
            break;

        case OP_IGET:
        case OP_IGET_VOLATILE:
        case OP_IGET_OBJECT:
        case OP_IGET_OBJECT_VOLATILE:
            genIGet(cUnit, mir, kWord, rlDest, rlSrc[0]);
            break;

        case OP_IGET_BOOLEAN:
        case OP_IGET_BYTE:
            genIGet(cUnit, mir, kUnsignedByte, rlDest, rlSrc[0]);
            break;

        case OP_IGET_CHAR:
            genIGet(cUnit, mir, kUnsignedHalf, rlDest, rlSrc[0]);
            break;

        case OP_IGET_SHORT:
            genIGet(cUnit, mir, kSignedHalf, rlDest, rlSrc[0]);
            break;

        case OP_IPUT_WIDE:
        case OP_IPUT_WIDE_VOLATILE:
            genIPutWide(cUnit, mir, rlSrc[0], rlSrc[1]);
            break;

        case OP_IPUT_OBJECT:
        case OP_IPUT_OBJECT_VOLATILE:
            genIPut(cUnit, mir, kWord, rlSrc[0], rlSrc[1], true);
            break;

        case OP_IPUT:
        case OP_IPUT_VOLATILE:
            genIPut(cUnit, mir, kWord, rlSrc[0], rlSrc[1], false);
            break;

        case OP_IPUT_BOOLEAN:
        case OP_IPUT_BYTE:
            genIPut(cUnit, mir, kUnsignedByte, rlSrc[0], rlSrc[1], false);
            break;

        case OP_IPUT_CHAR:
            genIPut(cUnit, mir, kUnsignedHalf, rlSrc[0], rlSrc[1], false);
            break;

        case OP_IPUT_SHORT:
            genIPut(cUnit, mir, kSignedHalf, rlSrc[0], rlSrc[1], false);
            break;

        case OP_SGET:
        case OP_SGET_OBJECT:
        case OP_SGET_BOOLEAN:
        case OP_SGET_BYTE:
        case OP_SGET_CHAR:
        case OP_SGET_SHORT:
            genSget(cUnit, mir, rlResult, rlDest);
            break;

        case OP_SGET_WIDE:
            genSgetWide(cUnit, mir, rlResult, rlDest);
            break;

        case OP_SPUT:
        case OP_SPUT_OBJECT:
        case OP_SPUT_BOOLEAN:
        case OP_SPUT_BYTE:
        case OP_SPUT_CHAR:
        case OP_SPUT_SHORT:
            genSput(cUnit, mir, rlSrc[0]);
            break;

        case OP_SPUT_WIDE:
            genSputWide(cUnit, mir, rlSrc[0]);
            break;

        case OP_INVOKE_STATIC_RANGE:
            genInvokeStaticDirect(cUnit, mir, false /*direct*/,
                                  true /*range*/);
            break;
        case OP_INVOKE_STATIC:
            genInvokeStaticDirect(cUnit, mir, false /*direct*/,
                                  false /*range*/);
            break;

        case OP_INVOKE_DIRECT:
            genInvokeStaticDirect(cUnit, mir, true /*direct*/,
                                  false /*range*/);
            break;
        case OP_INVOKE_DIRECT_RANGE:
            genInvokeStaticDirect(cUnit, mir, true /*direct*/,
                                  true /*range*/);
            break;

        case OP_INVOKE_VIRTUAL:
        case OP_INVOKE_VIRTUAL_RANGE:
            genInvokeVirtual(cUnit, mir);
            break;

        case OP_INVOKE_SUPER:
        case OP_INVOKE_SUPER_RANGE:
            genInvokeSuper(cUnit, mir);
            break;

        case OP_INVOKE_INTERFACE:
        case OP_INVOKE_INTERFACE_RANGE:
            genInvokeInterface(cUnit, mir);
            break;

        case OP_NEG_INT:
        case OP_NOT_INT:
            res = genArithOpInt(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
            break;

        case OP_NEG_LONG:
        case OP_NOT_LONG:
            res = genArithOpLong(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
            break;

        case OP_NEG_FLOAT:
            res = genArithOpFloat(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
            break;

        case OP_NEG_DOUBLE:
            res = genArithOpDouble(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
            break;

        case OP_INT_TO_LONG:
            rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
            if (rlSrc[0].location == kLocPhysReg) {
                genRegCopy(cUnit, rlResult.lowReg, rlSrc[0].lowReg);
            } else {
                loadValueDirect(cUnit, rlSrc[0], rlResult.lowReg);
            }
            opRegRegImm(cUnit, kOpAsr, rlResult.highReg,
                        rlResult.lowReg, 31);
            storeValueWide(cUnit, rlDest, rlResult);
            break;

        case OP_LONG_TO_INT:
            rlSrc[0] = oatUpdateLocWide(cUnit, rlSrc[0]);
            rlSrc[0] = oatWideToNarrow(cUnit, rlSrc[0]);
            storeValue(cUnit, rlDest, rlSrc[0]);
            break;

        case OP_INT_TO_BYTE:
            rlSrc[0] = loadValue(cUnit, rlSrc[0], kCoreReg);
            rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
            opRegReg(cUnit, kOp2Byte, rlResult.lowReg, rlSrc[0].lowReg);
            storeValue(cUnit, rlDest, rlResult);
            break;

        case OP_INT_TO_SHORT:
            rlSrc[0] = loadValue(cUnit, rlSrc[0], kCoreReg);
            rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
            opRegReg(cUnit, kOp2Short, rlResult.lowReg, rlSrc[0].lowReg);
            storeValue(cUnit, rlDest, rlResult);
            break;

        case OP_INT_TO_CHAR:
            rlSrc[0] = loadValue(cUnit, rlSrc[0], kCoreReg);
            rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
            opRegReg(cUnit, kOp2Char, rlResult.lowReg, rlSrc[0].lowReg);
            storeValue(cUnit, rlDest, rlResult);
            break;

        case OP_INT_TO_FLOAT:
        case OP_INT_TO_DOUBLE:
        case OP_LONG_TO_FLOAT:
        case OP_LONG_TO_DOUBLE:
        case OP_FLOAT_TO_INT:
        case OP_FLOAT_TO_LONG:
        case OP_FLOAT_TO_DOUBLE:
        case OP_DOUBLE_TO_INT:
        case OP_DOUBLE_TO_LONG:
        case OP_DOUBLE_TO_FLOAT:
            genConversion(cUnit, mir);
            break;

        case OP_ADD_INT:
        case OP_SUB_INT:
        case OP_MUL_INT:
        case OP_DIV_INT:
        case OP_REM_INT:
        case OP_AND_INT:
        case OP_OR_INT:
        case OP_XOR_INT:
        case OP_SHL_INT:
        case OP_SHR_INT:
        case OP_USHR_INT:
        case OP_ADD_INT_2ADDR:
        case OP_SUB_INT_2ADDR:
        case OP_MUL_INT_2ADDR:
        case OP_DIV_INT_2ADDR:
        case OP_REM_INT_2ADDR:
        case OP_AND_INT_2ADDR:
        case OP_OR_INT_2ADDR:
        case OP_XOR_INT_2ADDR:
        case OP_SHL_INT_2ADDR:
        case OP_SHR_INT_2ADDR:
        case OP_USHR_INT_2ADDR:
            genArithOpInt(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
            break;

        case OP_ADD_LONG:
        case OP_SUB_LONG:
        case OP_MUL_LONG:
        case OP_DIV_LONG:
        case OP_REM_LONG:
        case OP_AND_LONG:
        case OP_OR_LONG:
        case OP_XOR_LONG:
        case OP_ADD_LONG_2ADDR:
        case OP_SUB_LONG_2ADDR:
        case OP_MUL_LONG_2ADDR:
        case OP_DIV_LONG_2ADDR:
        case OP_REM_LONG_2ADDR:
        case OP_AND_LONG_2ADDR:
        case OP_OR_LONG_2ADDR:
        case OP_XOR_LONG_2ADDR:
            genArithOpLong(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
            break;

        case OP_SHL_LONG:
        case OP_SHR_LONG:
        case OP_USHR_LONG:
        case OP_SHL_LONG_2ADDR:
        case OP_SHR_LONG_2ADDR:
        case OP_USHR_LONG_2ADDR:
            genShiftOpLong(cUnit,mir, rlDest, rlSrc[0], rlSrc[1]);
            break;

        case OP_ADD_FLOAT:
        case OP_SUB_FLOAT:
        case OP_MUL_FLOAT:
        case OP_DIV_FLOAT:
        case OP_REM_FLOAT:
        case OP_ADD_FLOAT_2ADDR:
        case OP_SUB_FLOAT_2ADDR:
        case OP_MUL_FLOAT_2ADDR:
        case OP_DIV_FLOAT_2ADDR:
        case OP_REM_FLOAT_2ADDR:
            genArithOpFloat(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
            break;

        case OP_ADD_DOUBLE:
        case OP_SUB_DOUBLE:
        case OP_MUL_DOUBLE:
        case OP_DIV_DOUBLE:
        case OP_REM_DOUBLE:
        case OP_ADD_DOUBLE_2ADDR:
        case OP_SUB_DOUBLE_2ADDR:
        case OP_MUL_DOUBLE_2ADDR:
        case OP_DIV_DOUBLE_2ADDR:
        case OP_REM_DOUBLE_2ADDR:
            genArithOpDouble(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
            break;

        case OP_RSUB_INT:
        case OP_ADD_INT_LIT16:
        case OP_MUL_INT_LIT16:
        case OP_DIV_INT_LIT16:
        case OP_REM_INT_LIT16:
        case OP_AND_INT_LIT16:
        case OP_OR_INT_LIT16:
        case OP_XOR_INT_LIT16:
        case OP_ADD_INT_LIT8:
        case OP_RSUB_INT_LIT8:
        case OP_MUL_INT_LIT8:
        case OP_DIV_INT_LIT8:
        case OP_REM_INT_LIT8:
        case OP_AND_INT_LIT8:
        case OP_OR_INT_LIT8:
        case OP_XOR_INT_LIT8:
        case OP_SHL_INT_LIT8:
        case OP_SHR_INT_LIT8:
        case OP_USHR_INT_LIT8:
            genArithOpIntLit(cUnit, mir, rlDest, rlSrc[0], mir->dalvikInsn.vC);
            break;

        default:
            res = true;
    }
    return res;
}

STATIC const char* extendedMIROpNames[kMirOpLast - kMirOpFirst] = {
    "kMirOpPhi",
    "kMirOpNullNRangeUpCheck",
    "kMirOpNullNRangeDownCheck",
    "kMirOpLowerBound",
    "kMirOpPunt",
    "kMirOpCheckInlinePrediction",
};

/* Extended MIR instructions like PHI */
STATIC void handleExtendedMethodMIR(CompilationUnit* cUnit, MIR* mir)
{
    int opOffset = mir->dalvikInsn.opcode - kMirOpFirst;
    char* msg = (char*)oatNew(strlen(extendedMIROpNames[opOffset]) + 1, false);
    strcpy(msg, extendedMIROpNames[opOffset]);
    ArmLIR* op = newLIR1(cUnit, kArmPseudoExtended, (int) msg);

    switch ((ExtendedMIROpcode)mir->dalvikInsn.opcode) {
        case kMirOpPhi: {
            char* ssaString = oatGetSSAString(cUnit, mir->ssaRep);
            op->flags.isNop = true;
            newLIR1(cUnit, kArmPseudoSSARep, (int) ssaString);
            break;
        }
        default:
            break;
    }
}

/*
 * If there are any ins passed in registers that have not been promoted
 * to a callee-save register, flush them to the frame.  Perform intial
 * assignment of promoted arguments.
 */
STATIC void flushIns(CompilationUnit* cUnit)
{
    if (cUnit->numIns == 0)
        return;
    int firstArgReg = r1;
    int lastArgReg = r3;
    int startVReg = cUnit->numDalvikRegisters - cUnit->numIns;
    /*
     * Arguments passed in registers should be flushed
     * to their backing locations in the frame for now.
     * Also, we need to do initial assignment for promoted
     * arguments.  NOTE: an older version of dx had an issue
     * in which it would reuse static method argument registers.
     * This could result in the same Dalvik virtual register
     * being promoted to both core and fp regs.  In those
     * cases, copy argument to both.  This will be uncommon
     * enough that it isn't worth attempting to optimize.
     */
    for (int i = 0; i < cUnit->numIns; i++) {
        PromotionMap vMap = cUnit->promotionMap[startVReg + i];
        if (i <= (lastArgReg - firstArgReg)) {
            // If arriving in register
            if (vMap.coreLocation == kLocPhysReg) {
                genRegCopy(cUnit, vMap.coreReg, firstArgReg + i);
            }
            if (vMap.fpLocation == kLocPhysReg) {
                genRegCopy(cUnit, vMap.fpReg, firstArgReg + i);
            }
            // Also put a copy in memory in case we're partially promoted
            storeBaseDisp(cUnit, rSP, oatSRegOffset(cUnit, startVReg + i),
                          firstArgReg + i, kWord);
        } else {
            // If arriving in frame & promoted
            if (vMap.coreLocation == kLocPhysReg) {
                loadWordDisp(cUnit, rSP, oatSRegOffset(cUnit, startVReg + i),
                             vMap.coreReg);
            }
            if (vMap.fpLocation == kLocPhysReg) {
                loadWordDisp(cUnit, rSP, oatSRegOffset(cUnit, startVReg + i),
                             vMap.fpReg);
            }
        }
    }
}

/* 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;
    oatAppendLIR(cUnit, (LIR*) &labelList[blockId]);

    /* Reset local optimization data on block boundaries */
    oatResetRegPool(cUnit);
    oatClobberAllRegs(cUnit);
    oatResetDefTracking(cUnit);

    ArmLIR* headLIR = NULL;

    int spillCount = cUnit->numCoreSpills + cUnit->numFPSpills;
    if (bb->blockType == kEntryBlock) {
        /*
         * On entry, r0, r1, r2 & r3 are live.  Let the register allocation
         * mechanism know so it doesn't try to use any of them when
         * expanding the frame or flushing.  This leaves the utility
         * code with a single temp: r12.  This should be enough.
         */
        oatLockTemp(cUnit, r0);
        oatLockTemp(cUnit, r1);
        oatLockTemp(cUnit, r2);
        oatLockTemp(cUnit, r3);

        /*
         * We can safely skip the stack overflow check if we're
         * a leaf *and* our frame size < fudge factor.
         */
        bool skipOverflowCheck = ((cUnit->attrs & METHOD_IS_LEAF) &&
                                  ((size_t)cUnit->frameSize <
                                  art::Thread::kStackOverflowReservedBytes));
        newLIR0(cUnit, kArmPseudoMethodEntry);
        if (!skipOverflowCheck) {
            /* Load stack limit */
            loadWordDisp(cUnit, rSELF,
                         art::Thread::StackEndOffset().Int32Value(), r12);
        }
        /* Spill core callee saves */
        newLIR1(cUnit, kThumb2Push, cUnit->coreSpillMask);
        /* Need to spill any FP regs? */
        if (cUnit->numFPSpills) {
            /*
             * NOTE: fp spills are a little different from core spills in that
             * they are pushed as a contiguous block.  When promoting from
             * the fp set, we must allocate all singles from s16..highest-promoted
             */
            newLIR1(cUnit, kThumb2VPushCS, cUnit->numFPSpills);
        }
        if (!skipOverflowCheck) {
            opRegRegImm(cUnit, kOpSub, rLR, rSP,
                        cUnit->frameSize - (spillCount * 4));
            genRegRegCheck(cUnit, kArmCondCc, rLR, r12, NULL,
                           kArmThrowStackOverflow);
            genRegCopy(cUnit, rSP, rLR);         // Establish stack
        } else {
            opRegImm(cUnit, kOpSub, rSP,
                     cUnit->frameSize - (spillCount * 4));
        }
        storeBaseDisp(cUnit, rSP, 0, r0, kWord);
        flushIns(cUnit);
        oatFreeTemp(cUnit, r0);
        oatFreeTemp(cUnit, r1);
        oatFreeTemp(cUnit, r2);
        oatFreeTemp(cUnit, r3);
    } else if (bb->blockType == kExitBlock) {
        newLIR0(cUnit, kArmPseudoMethodExit);
        opRegImm(cUnit, kOpAdd, rSP, cUnit->frameSize - (spillCount * 4));
        /* Need to restore any FP callee saves? */
        if (cUnit->numFPSpills) {
            newLIR1(cUnit, kThumb2VPopCS, cUnit->numFPSpills);
        }
        if (cUnit->coreSpillMask & (1 << rLR)) {
            /* Unspill rLR to rPC */
            cUnit->coreSpillMask &= ~(1 << rLR);
            cUnit->coreSpillMask |= (1 << rPC);
        }
        newLIR1(cUnit, kThumb2Pop, cUnit->coreSpillMask);
        if (!(cUnit->coreSpillMask & (1 << rPC))) {
            /* We didn't pop to rPC, so must do a bv rLR */
            newLIR1(cUnit, kThumbBx, rLR);
        }
    }

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

        oatResetRegPool(cUnit);
        if (cUnit->disableOpt & (1 << kTrackLiveTemps)) {
            oatClobberAllRegs(cUnit);
        }

        if (cUnit->disableOpt & (1 << kSuppressLoads)) {
            oatResetDefTracking(cUnit);
        }

        if ((int)mir->dalvikInsn.opcode >= (int)kMirOpFirst) {
            handleExtendedMethodMIR(cUnit, mir);
            continue;
        }

        cUnit->currentDalvikOffset = mir->offset;

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

        ArmLIR* boundaryLIR;

        /* Mark the beginning of a Dalvik instruction for line tracking */
        boundaryLIR = newLIR1(cUnit, kArmPseudoDalvikByteCodeBoundary,
                             (int) oatGetDalvikDisassembly(
                             &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 = oatGetSSAString(cUnit, mir->ssaRep);
            newLIR1(cUnit, kArmPseudoSSARep, (int) ssaString);
        }

        bool notHandled = compileDalvikInstruction(cUnit, mir, bb, labelList);

        if (notHandled) {
            char buf[100];
            snprintf(buf, 100, "%#06x: Opcode %#x (%s) / Fmt %d not handled",
                 mir->offset,
                 dalvikOpcode, dexGetOpcodeName(dalvikOpcode),
                 dalvikFormat);
            LOG(FATAL) << buf;
        }
    }

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

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

/*
 * Nop any unconditional branches that go to the next instruction.
 * Note: new redundant branches may be inserted later, and we'll
 * use a check in final instruction assembly to nop those out.
 */
void removeRedundantBranches(CompilationUnit* cUnit)
{
    ArmLIR* thisLIR;

    for (thisLIR = (ArmLIR*) cUnit->firstLIRInsn;
         thisLIR != (ArmLIR*) cUnit->lastLIRInsn;
         thisLIR = NEXT_LIR(thisLIR)) {

        /* Branch to the next instruction */
        if ((thisLIR->opcode == kThumbBUncond) ||
            (thisLIR->opcode == kThumb2BUncond)) {
            ArmLIR* nextLIR = thisLIR;

            while (true) {
                nextLIR = NEXT_LIR(nextLIR);

                /*
                 * Is the branch target the next instruction?
                 */
                if (nextLIR == (ArmLIR*) thisLIR->generic.target) {
                    thisLIR->flags.isNop = true;
                    break;
                }

                /*
                 * Found real useful stuff between the branch and the target.
                 * Need to explicitly check the lastLIRInsn here because it
                 * might be the last real instruction.
                 */
                if (!isPseudoOpcode(nextLIR->opcode) ||
                    (nextLIR = (ArmLIR*) cUnit->lastLIRInsn))
                    break;
            }
        }
    }
}

STATIC void handleSuspendLaunchpads(CompilationUnit *cUnit)
{
    ArmLIR** suspendLabel =
        (ArmLIR **) cUnit->suspendLaunchpads.elemList;
    int numElems = cUnit->suspendLaunchpads.numUsed;

    for (int i = 0; i < numElems; i++) {
        /* TUNING: move suspend count load into helper */
        ArmLIR* lab = suspendLabel[i];
        ArmLIR* resumeLab = (ArmLIR*)lab->operands[0];
        cUnit->currentDalvikOffset = lab->operands[1];
        oatAppendLIR(cUnit, (LIR *)lab);
        loadWordDisp(cUnit, rSELF,
                     OFFSETOF_MEMBER(Thread, pTestSuspendFromCode), rLR);
        loadWordDisp(cUnit, rSELF,
            art::Thread::SuspendCountOffset().Int32Value(), rSUSPEND);
        opReg(cUnit, kOpBlx, rLR);
        genUnconditionalBranch(cUnit, resumeLab);
    }
}

STATIC void handleThrowLaunchpads(CompilationUnit *cUnit)
{
    ArmLIR** throwLabel =
        (ArmLIR **) cUnit->throwLaunchpads.elemList;
    int numElems = cUnit->throwLaunchpads.numUsed;
    int i;

    for (i = 0; i < numElems; i++) {
        ArmLIR* lab = throwLabel[i];
        cUnit->currentDalvikOffset = lab->operands[1];
        oatAppendLIR(cUnit, (LIR *)lab);
        int funcOffset = 0;
        int v1 = lab->operands[2];
        int v2 = lab->operands[3];
        switch(lab->operands[0]) {
            case kArmThrowNullPointer:
                funcOffset = OFFSETOF_MEMBER(Thread, pThrowNullPointerFromCode);
                break;
            case kArmThrowArrayBounds:
                if (v2 != r0) {
                    genRegCopy(cUnit, r0, v1);
                    genRegCopy(cUnit, r1, v2);
                } else {
                    if (v1 == r1) {
                        genRegCopy(cUnit, r12, v1);
                        genRegCopy(cUnit, r1, v2);
                        genRegCopy(cUnit, r0, r12);
                    } else {
                        genRegCopy(cUnit, r1, v2);
                        genRegCopy(cUnit, r0, v1);
                    }
                }
                funcOffset = OFFSETOF_MEMBER(Thread, pThrowArrayBoundsFromCode);
                break;
            case kArmThrowDivZero:
                funcOffset = OFFSETOF_MEMBER(Thread, pThrowDivZeroFromCode);
                break;
            case kArmThrowVerificationError:
                loadConstant(cUnit, r0, v1);
                loadConstant(cUnit, r1, v2);
                funcOffset =
                    OFFSETOF_MEMBER(Thread, pThrowVerificationErrorFromCode);
                break;
            case kArmThrowNegArraySize:
                genRegCopy(cUnit, r0, v1);
                funcOffset =
                    OFFSETOF_MEMBER(Thread, pThrowNegArraySizeFromCode);
                break;
            case kArmThrowNoSuchMethod:
                genRegCopy(cUnit, r0, v2);
                funcOffset =
                    OFFSETOF_MEMBER(Thread, pThrowNoSuchMethodFromCode);
                break;
            case kArmThrowStackOverflow:
                funcOffset =
                    OFFSETOF_MEMBER(Thread, pThrowStackOverflowFromCode);
                // Restore stack alignment
                opRegImm(cUnit, kOpAdd, rSP,
                         (cUnit->numCoreSpills + cUnit->numFPSpills) * 4);
                break;
            default:
                LOG(FATAL) << "Unexpected throw kind: " << lab->operands[0];
        }
        loadWordDisp(cUnit, rSELF, funcOffset, rLR);
        callRuntimeHelper(cUnit, rLR);
    }
}

void oatMethodMIR2LIR(CompilationUnit* cUnit)
{
    /* Used to hold the labels of each block */
    cUnit->blockLabelList =
        (void *) oatNew(sizeof(ArmLIR) * cUnit->numBlocks, true);

    oatDataFlowAnalysisDispatcher(cUnit, methodBlockCodeGen,
                                  kPreOrderDFSTraversal, false /* Iterative */);
    handleSuspendLaunchpads(cUnit);

    handleThrowLaunchpads(cUnit);

    removeRedundantBranches(cUnit);
}

/* Common initialization routine for an architecture family */
bool oatArchInit()
{
    int i;

    for (i = 0; i < kArmLast; i++) {
        if (EncodingMap[i].opcode != i) {
            LOG(FATAL) << "Encoding order for " << EncodingMap[i].name <<
               " is wrong: expecting " << i << ", seeing " <<
               (int)EncodingMap[i].opcode;
        }
    }

    return oatArchVariantInit();
}

/* Needed by the Assembler */
void oatSetupResourceMasks(ArmLIR* lir)
{
    setupResourceMasks(lir);
}

/* Needed by the ld/st optmizatons */
ArmLIR* oatRegCopyNoInsert(CompilationUnit* cUnit, int rDest, int rSrc)
{
    return genRegCopyNoInsert(cUnit, rDest, rSrc);
}

/* Needed by the register allocator */
ArmLIR* oatRegCopy(CompilationUnit* cUnit, int rDest, int rSrc)
{
    return genRegCopy(cUnit, rDest, rSrc);
}

/* Needed by the register allocator */
void oatRegCopyWide(CompilationUnit* cUnit, int destLo, int destHi,
                            int srcLo, int srcHi)
{
    genRegCopyWide(cUnit, destLo, destHi, srcLo, srcHi);
}

void oatFlushRegImpl(CompilationUnit* cUnit, int rBase,
                             int displacement, int rSrc, OpSize size)
{
    storeBaseDisp(cUnit, rBase, displacement, rSrc, size);
}

void oatFlushRegWideImpl(CompilationUnit* cUnit, int rBase,
                                 int displacement, int rSrcLo, int rSrcHi)
{
    storeBaseDispWide(cUnit, rBase, displacement, rSrcLo, rSrcHi);
}
