/*
 * 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.
 */

namespace art {

void setMemRefType(LIR* lir, bool isLoad, int memType)
{
    u8 *maskPtr;
    u8 mask = ENCODE_MEM;;
    DCHECK(EncodingMap[lir->opcode].flags & (IS_LOAD | IS_STORE));
    if (isLoad) {
        maskPtr = &lir->useMask;
    } else {
        maskPtr = &lir->defMask;
    }
    /* Clear out the memref flags */
    *maskPtr &= ~mask;
    /* ..and then add back the one we need */
    switch (memType) {
        case kLiteral:
            DCHECK(isLoad);
            *maskPtr |= ENCODE_LITERAL;
            break;
        case kDalvikReg:
            *maskPtr |= ENCODE_DALVIK_REG;
            break;
        case kHeapRef:
            *maskPtr |= ENCODE_HEAP_REF;
            break;
        case kMustNotAlias:
            /* Currently only loads can be marked as kMustNotAlias */
            DCHECK(!(EncodingMap[lir->opcode].flags & IS_STORE));
            *maskPtr |= ENCODE_MUST_NOT_ALIAS;
            break;
        default:
            LOG(FATAL) << "Oat: invalid memref kind - " << memType;
    }
}

/*
 * Mark load/store instructions that access Dalvik registers through the stack.
 */
void annotateDalvikRegAccess(LIR* lir, int regId, bool isLoad, bool is64bit)
{
    setMemRefType(lir, isLoad, kDalvikReg);

    /*
     * Store the Dalvik register id in aliasInfo. Mark the MSB if it is a 64-bit
     * access.
     */
    lir->aliasInfo = regId;
    if (is64bit) {
        lir->aliasInfo |= 0x80000000;
    }
}

/*
 * Decode the register id.
 */
inline u8 getRegMaskCommon(int reg)
{
    u8 seed;
    int shift;
    int regId = reg & 0x1f;

    /*
     * Each double register is equal to a pair of single-precision FP registers
     */
    seed = DOUBLEREG(reg) ? 3 : 1;
    /* FP register starts at bit position 16 */
    shift = FPREG(reg) ? kFPReg0 : 0;
    /* Expand the double register id into single offset */
    shift += regId;
    return (seed << shift);
}

/*
 * Mark the corresponding bit(s).
 */
inline void setupRegMask(u8* mask, int reg)
{
    *mask |= getRegMaskCommon(reg);
}

/*
 * Set up the proper fields in the resource mask
 */
void setupResourceMasks(LIR* lir)
{
    int opcode = lir->opcode;
    int flags;

    if (opcode <= 0) {
        lir->useMask = lir->defMask = 0;
        return;
    }

    flags = EncodingMap[lir->opcode].flags;

    if (flags & NEEDS_FIXUP) {
        lir->flags.pcRelFixup = true;
    }

    /* Get the starting size of the instruction's template */
    lir->flags.size = oatGetInsnSize(lir);

    /* Set up the mask for resources that are updated */
    if (flags & (IS_LOAD | IS_STORE)) {
        /* Default to heap - will catch specialized classes later */
        setMemRefType(lir, flags & IS_LOAD, kHeapRef);
    }

    /*
     * Conservatively assume the branch here will call out a function that in
     * turn will trash everything.
     */
    if (flags & IS_BRANCH) {
        lir->defMask = lir->useMask = ENCODE_ALL;
        return;
    }

    if (flags & REG_DEF0) {
        setupRegMask(&lir->defMask, lir->operands[0]);
    }

    if (flags & REG_DEF1) {
        setupRegMask(&lir->defMask, lir->operands[1]);
    }

    if (flags & REG_DEF_SP) {
        lir->defMask |= ENCODE_REG_SP;
    }

#if !defined(TARGET_X86)
    if (flags & REG_DEF_LR) {
        lir->defMask |= ENCODE_REG_LR;
    }
#endif

    if (flags & REG_DEF_LIST0) {
        lir->defMask |= ENCODE_REG_LIST(lir->operands[0]);
    }

    if (flags & REG_DEF_LIST1) {
        lir->defMask |= ENCODE_REG_LIST(lir->operands[1]);
    }

#if defined(TARGET_ARM)
    if (flags & REG_DEF_FPCS_LIST0) {
        lir->defMask |= ENCODE_REG_FPCS_LIST(lir->operands[0]);
    }

    if (flags & REG_DEF_FPCS_LIST2) {
        for (int i = 0; i < lir->operands[2]; i++) {
            setupRegMask(&lir->defMask, lir->operands[1] + i);
        }
    }
#endif

    if (flags & SETS_CCODES) {
        lir->defMask |= ENCODE_CCODE;
    }

#if defined(TARGET_ARM)
    /* Conservatively treat the IT block */
    if (flags & IS_IT) {
        lir->defMask = ENCODE_ALL;
    }
#endif

    if (flags & (REG_USE0 | REG_USE1 | REG_USE2 | REG_USE3)) {
        int i;

        for (i = 0; i < 4; i++) {
            if (flags & (1 << (kRegUse0 + i))) {
                setupRegMask(&lir->useMask, lir->operands[i]);
            }
        }
    }

#if defined(TARGET_ARM)
    if (flags & REG_USE_PC) {
        lir->useMask |= ENCODE_REG_PC;
    }
#endif

    if (flags & REG_USE_SP) {
        lir->useMask |= ENCODE_REG_SP;
    }

    if (flags & REG_USE_LIST0) {
        lir->useMask |= ENCODE_REG_LIST(lir->operands[0]);
    }

    if (flags & REG_USE_LIST1) {
        lir->useMask |= ENCODE_REG_LIST(lir->operands[1]);
    }

#if defined(TARGET_ARM)
    if (flags & REG_USE_FPCS_LIST0) {
        lir->useMask |= ENCODE_REG_FPCS_LIST(lir->operands[0]);
    }

    if (flags & REG_USE_FPCS_LIST2) {
        for (int i = 0; i < lir->operands[2]; i++) {
            setupRegMask(&lir->useMask, lir->operands[1] + i);
        }
    }
#endif

    if (flags & USES_CCODES) {
        lir->useMask |= ENCODE_CCODE;
    }

#if defined(TARGET_ARM)
    /* Fixup for kThumbPush/lr and kThumbPop/pc */
    if (opcode == kThumbPush || opcode == kThumbPop) {
        u8 r8Mask = getRegMaskCommon(r8);
        if ((opcode == kThumbPush) && (lir->useMask & r8Mask)) {
            lir->useMask &= ~r8Mask;
            lir->useMask |= ENCODE_REG_LR;
        } else if ((opcode == kThumbPop) && (lir->defMask & r8Mask)) {
            lir->defMask &= ~r8Mask;
            lir->defMask |= ENCODE_REG_PC;
        }
    }
#endif
}

/*
 * Debugging macros
 */
#define DUMP_RESOURCE_MASK(X)
#define DUMP_SSA_REP(X)

/* Pretty-print a LIR instruction */
void oatDumpLIRInsn(CompilationUnit* cUnit, LIR* arg, unsigned char* baseAddr)
{
    LIR* lir = (LIR*) arg;
    int offset = lir->offset;
    int dest = lir->operands[0];
    const bool dumpNop = (cUnit->enableDebug & (1 << kDebugShowNops));

    /* Handle pseudo-ops individually, and all regular insns as a group */
    switch (lir->opcode) {
        case kPseudoMethodEntry:
            LOG(INFO) << "-------- method entry " <<
                PrettyMethod(cUnit->method_idx, *cUnit->dex_file);
            break;
        case kPseudoMethodExit:
            LOG(INFO) << "-------- Method_Exit";
            break;
        case kPseudoBarrier:
            LOG(INFO) << "-------- BARRIER";
            break;
        case kPseudoExtended:
            LOG(INFO) << "-------- " << (char* ) dest;
            break;
        case kPseudoSSARep:
            DUMP_SSA_REP(LOG(INFO) << "-------- kMirOpPhi: " <<  (char* ) dest);
            break;
        case kPseudoEntryBlock:
            LOG(INFO) << "-------- entry offset: 0x" << std::hex << dest;
            break;
        case kPseudoDalvikByteCodeBoundary:
            LOG(INFO) << "-------- dalvik offset: 0x" << std::hex <<
                 lir->dalvikOffset << " @ " << (char* )lir->operands[0];
            break;
        case kPseudoExitBlock:
            LOG(INFO) << "-------- exit offset: 0x" << std::hex << dest;
            break;
        case kPseudoPseudoAlign4:
            LOG(INFO) << (intptr_t)baseAddr + offset << " (0x" << std::hex <<
                offset << "): .align4";
            break;
        case kPseudoEHBlockLabel:
            LOG(INFO) << "Exception_Handling:";
            break;
        case kPseudoTargetLabel:
        case kPseudoNormalBlockLabel:
            LOG(INFO) << "L" << (void*)lir << ":";
            break;
        case kPseudoThrowTarget:
            LOG(INFO) << "LT" << (void*)lir << ":";
            break;
        case kPseudoIntrinsicRetry:
            LOG(INFO) << "IR" << (void*)lir << ":";
            break;
        case kPseudoSuspendTarget:
            LOG(INFO) << "LS" << (void*)lir << ":";
            break;
        case kPseudoCaseLabel:
            LOG(INFO) << "LC" << (void*)lir << ": Case target 0x" <<
                std::hex << lir->operands[0] << "|" << std::dec <<
                lir->operands[0];
            break;
        default:
            if (lir->flags.isNop && !dumpNop) {
                break;
            } else {
                std::string op_name(buildInsnString(EncodingMap[lir->opcode].name, lir, baseAddr));
                std::string op_operands(buildInsnString(EncodingMap[lir->opcode].fmt, lir, baseAddr));
                LOG(INFO) << StringPrintf("%05x: %-9s%s%s", (unsigned int)(baseAddr + offset),
                    op_name.c_str(), op_operands.c_str(), lir->flags.isNop ? "(nop)" : "");
            }
            break;
    }

    if (lir->useMask && (!lir->flags.isNop || dumpNop)) {
        DUMP_RESOURCE_MASK(oatDumpResourceMask((LIR* ) lir,
                                               lir->useMask, "use"));
    }
    if (lir->defMask && (!lir->flags.isNop || dumpNop)) {
        DUMP_RESOURCE_MASK(oatDumpResourceMask((LIR* ) lir,
                                               lir->defMask, "def"));
    }
}

void oatDumpPromotionMap(CompilationUnit *cUnit)
{
    int numRegs = cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
    for (int i = 0; i < numRegs; i++) {
        PromotionMap vRegMap = cUnit->promotionMap[i];
        std::string buf;
        if (vRegMap.fpLocation == kLocPhysReg) {
            StringAppendF(&buf, " : s%d", vRegMap.fpReg & FP_REG_MASK);
        }

        std::string buf3;
        if (i < cUnit->numDalvikRegisters) {
            StringAppendF(&buf3, "%02d", i);
        } else if (i == cUnit->methodSReg) {
            buf3 = "Method*";
        } else {
            StringAppendF(&buf3, "ct%d", i - cUnit->numDalvikRegisters);
        }

        LOG(INFO) << StringPrintf("V[%s] -> %s%d%s", buf3.c_str(),
                 vRegMap.coreLocation == kLocPhysReg ?
                 "r" : "SP+", vRegMap.coreLocation == kLocPhysReg ?
                 vRegMap.coreReg : oatSRegOffset(cUnit, i), buf.c_str());
    }
}

/* Dump instructions and constant pool contents */
void oatCodegenDump(CompilationUnit* cUnit)
{
    LOG(INFO) << "/*";
    LOG(INFO) << "Dumping LIR insns for "
        << PrettyMethod(cUnit->method_idx, *cUnit->dex_file);
    LIR* lirInsn;
    LIR* thisLIR;
    int insnsSize = cUnit->insnsSize;

    LOG(INFO) << "Regs (excluding ins) : " << cUnit->numRegs;
    LOG(INFO) << "Ins                  : " << cUnit->numIns;
    LOG(INFO) << "Outs                 : " << cUnit->numOuts;
    LOG(INFO) << "CoreSpills           : " << cUnit->numCoreSpills;
    LOG(INFO) << "FPSpills             : " << cUnit->numFPSpills;
    LOG(INFO) << "CompilerTemps        : " << cUnit->numCompilerTemps;
    LOG(INFO) << "Frame size           : " << cUnit->frameSize;
    LOG(INFO) << "code size is " << cUnit->totalSize <<
        " bytes, Dalvik size is " << insnsSize * 2;
    LOG(INFO) << "expansion factor: " <<
         (float)cUnit->totalSize / (float)(insnsSize * 2);
    oatDumpPromotionMap(cUnit);
    for (lirInsn = cUnit->firstLIRInsn; lirInsn; lirInsn = lirInsn->next) {
        oatDumpLIRInsn(cUnit, lirInsn, 0);
    }
    for (lirInsn = cUnit->classPointerList; lirInsn; lirInsn = lirInsn->next) {
        thisLIR = (LIR*) lirInsn;
        LOG(INFO) << StringPrintf("%x (%04x): .class (%s)",
            thisLIR->offset, thisLIR->offset,
            ((CallsiteInfo *) thisLIR->operands[0])->classDescriptor);
    }
    for (lirInsn = cUnit->literalList; lirInsn; lirInsn = lirInsn->next) {
        thisLIR = (LIR*) lirInsn;
        LOG(INFO) << StringPrintf("%x (%04x): .word (%#x)",
            thisLIR->offset, thisLIR->offset, thisLIR->operands[0]);
    }

    const DexFile::MethodId& method_id =
        cUnit->dex_file->GetMethodId(cUnit->method_idx);
    std::string signature(cUnit->dex_file->GetMethodSignature(method_id));
    std::string name(cUnit->dex_file->GetMethodName(method_id));
    std::string descriptor(cUnit->dex_file->GetMethodDeclaringClassDescriptor(method_id));

    // Dump mapping table
    if (cUnit->mappingTable.size() > 0) {
        std::string line(StringPrintf("\n    MappingTable %s%s_%s_mappingTable[%zu] = {",
            descriptor.c_str(), name.c_str(), signature.c_str(), cUnit->mappingTable.size()));
        std::replace(line.begin(), line.end(), ';', '_');
        LOG(INFO) << line;
        for (uint32_t i = 0; i < cUnit->mappingTable.size(); i+=2) {
            line = StringPrintf("        {0x%05x, 0x%04x},",
                cUnit->mappingTable[i], cUnit->mappingTable[i+1]);
            LOG(INFO) << line;
        }
        LOG(INFO) <<"    };\n\n";
    }
}


LIR* rawLIR(CompilationUnit* cUnit, int dalvikOffset, int opcode, int op0,
            int op1, int op2, int op3, int op4, LIR* target)
{
    LIR* insn = (LIR* ) oatNew(cUnit, sizeof(LIR), true, kAllocLIR);
    insn->dalvikOffset = dalvikOffset;
    insn->opcode = opcode;
    insn->operands[0] = op0;
    insn->operands[1] = op1;
    insn->operands[2] = op2;
    insn->operands[3] = op3;
    insn->operands[4] = op4;
    insn->target = target;
    oatSetupResourceMasks(insn);
    if (opcode == kPseudoTargetLabel) {
        // Always make labels scheduling barriers
        insn->defMask = ENCODE_ALL;
    }
    return insn;
}

/*
 * The following are building blocks to construct low-level IRs with 0 - 4
 * operands.
 */
LIR* newLIR0(CompilationUnit* cUnit, int opcode)
{
    DCHECK(isPseudoOpcode(opcode) || (EncodingMap[opcode].flags & NO_OPERAND))
                << EncodingMap[opcode].name << " " << (int)opcode << " "
                << PrettyMethod(cUnit->method_idx, *cUnit->dex_file) << " "
                << cUnit->currentDalvikOffset;
    LIR* insn = rawLIR(cUnit, cUnit->currentDalvikOffset, opcode);
    oatAppendLIR(cUnit, (LIR*) insn);
    return insn;
}

LIR* newLIR1(CompilationUnit* cUnit, int opcode,
                           int dest)
{
    DCHECK(isPseudoOpcode(opcode) || (EncodingMap[opcode].flags & IS_UNARY_OP))
                << EncodingMap[opcode].name << " " << (int)opcode << " "
                << PrettyMethod(cUnit->method_idx, *cUnit->dex_file) << " "
                << cUnit->currentDalvikOffset;
    LIR* insn = rawLIR(cUnit, cUnit->currentDalvikOffset, opcode, dest);
    oatAppendLIR(cUnit, (LIR*) insn);
    return insn;
}

LIR* newLIR2(CompilationUnit* cUnit, int opcode,
                           int dest, int src1)
{
    DCHECK(isPseudoOpcode(opcode) || (EncodingMap[opcode].flags & IS_BINARY_OP))
                << EncodingMap[opcode].name << " " << (int)opcode << " "
                << PrettyMethod(cUnit->method_idx, *cUnit->dex_file) << " "
                << cUnit->currentDalvikOffset;
    LIR* insn = rawLIR(cUnit, cUnit->currentDalvikOffset, opcode, dest, src1);
    oatAppendLIR(cUnit, (LIR*) insn);
    return insn;
}

LIR* newLIR3(CompilationUnit* cUnit, int opcode,
                           int dest, int src1, int src2)
{
    DCHECK(isPseudoOpcode(opcode) || (EncodingMap[opcode].flags & IS_TERTIARY_OP))
                << EncodingMap[opcode].name << " " << (int)opcode << " "
                << PrettyMethod(cUnit->method_idx, *cUnit->dex_file) << " "
                << cUnit->currentDalvikOffset;
    LIR* insn = rawLIR(cUnit, cUnit->currentDalvikOffset, opcode, dest, src1,
                       src2);
    oatAppendLIR(cUnit, (LIR*) insn);
    return insn;
}

LIR* newLIR4(CompilationUnit* cUnit, int opcode,
            int dest, int src1, int src2, int info)
{
    DCHECK(isPseudoOpcode(opcode) || (EncodingMap[opcode].flags & IS_QUAD_OP))
                << EncodingMap[opcode].name << " " << (int)opcode << " "
                << PrettyMethod(cUnit->method_idx, *cUnit->dex_file) << " "
                << cUnit->currentDalvikOffset;
    LIR* insn = rawLIR(cUnit, cUnit->currentDalvikOffset, opcode, dest, src1,
                       src2, info);
    oatAppendLIR(cUnit, (LIR*) insn);
    return insn;
}

LIR* newLIR5(CompilationUnit* cUnit, int opcode,
             int dest, int src1, int src2, int info1, int info2)
{
    DCHECK(isPseudoOpcode(opcode) || (EncodingMap[opcode].flags & IS_QUIN_OP))
                << EncodingMap[opcode].name << " " << (int)opcode << " "
                << PrettyMethod(cUnit->method_idx, *cUnit->dex_file) << " "
                << cUnit->currentDalvikOffset;
    LIR* insn = rawLIR(cUnit, cUnit->currentDalvikOffset, opcode, dest, src1,
                       src2, info1, info2);
    oatAppendLIR(cUnit, (LIR*) insn);
    return insn;
}

/*
 * Search the existing constants in the literal pool for an exact or close match
 * within specified delta (greater or equal to 0).
 */
LIR* scanLiteralPool(LIR* dataTarget, int value, unsigned int delta)
{
    while (dataTarget) {
        if (((unsigned) (value - ((LIR* ) dataTarget)->operands[0])) <=
            delta)
            return (LIR* ) dataTarget;
        dataTarget = dataTarget->next;
    }
    return NULL;
}

/* Search the existing constants in the literal pool for an exact wide match */
LIR* scanLiteralPoolWide(LIR* dataTarget, int valLo, int valHi)
{
    bool loMatch = false;
    LIR* loTarget = NULL;
    while (dataTarget) {
        if (loMatch && (((LIR*)dataTarget)->operands[0] == valHi)) {
            return (LIR*)loTarget;
        }
        loMatch = false;
        if (((LIR*)dataTarget)->operands[0] == valLo) {
            loMatch = true;
            loTarget = dataTarget;
        }
        dataTarget = dataTarget->next;
    }
    return NULL;
}

/*
 * The following are building blocks to insert constants into the pool or
 * instruction streams.
 */

/* Add a 32-bit constant either in the constant pool */
LIR* addWordData(CompilationUnit* cUnit, LIR* *constantListP, int value)
{
    /* Add the constant to the literal pool */
    if (constantListP) {
        LIR* newValue = (LIR* ) oatNew(cUnit, sizeof(LIR), true,
                                             kAllocData);
        newValue->operands[0] = value;
        newValue->next = *constantListP;
        *constantListP = (LIR*) newValue;
        return newValue;
    }
    return NULL;
}

/* Add a 64-bit constant to the constant pool or mixed with code */
LIR* addWideData(CompilationUnit* cUnit, LIR* *constantListP,
                           int valLo, int valHi)
{
    //FIXME: hard-coded little endian, need BE variant
    // Insert high word into list first
    addWordData(cUnit, constantListP, valHi);
    return addWordData(cUnit, constantListP, valLo);
}

void pushWord(std::vector<uint8_t>&buf, int data) {
    buf.push_back( data & 0xff);
    buf.push_back( (data >> 8) & 0xff);
    buf.push_back( (data >> 16) & 0xff);
    buf.push_back( (data >> 24) & 0xff);
}

void alignBuffer(std::vector<uint8_t>&buf, size_t offset) {
    while (buf.size() < offset) {
        buf.push_back(0);
    }
}

bool IsDirect(int invokeType) {
  InvokeType type = static_cast<InvokeType>(invokeType);
  return type == kStatic || type == kDirect;
}

/* Write the literal pool to the output stream */
void installLiteralPools(CompilationUnit* cUnit)
{
    alignBuffer(cUnit->codeBuffer, cUnit->dataOffset);
    LIR* dataLIR = cUnit->literalList;
    while (dataLIR != NULL) {
        pushWord(cUnit->codeBuffer, dataLIR->operands[0]);
        dataLIR = NEXT_LIR(dataLIR);
    }
    // Push code and method literals, record offsets for the compiler to patch.
    dataLIR = cUnit->codeLiteralList;
    if (dataLIR != NULL) {
        while (dataLIR != NULL) {
            uint32_t target = dataLIR->operands[0];
            cUnit->compiler->AddCodePatch(cUnit->dex_cache, cUnit->dex_file,
                                          cUnit->method_idx,
                                          cUnit->access_flags,
                                          target,
                                          IsDirect(dataLIR->operands[1]),
                                          cUnit->codeBuffer.size());
            const DexFile::MethodId& id = cUnit->dex_file->GetMethodId(target);
            // unique based on target to ensure code deduplication works
            uint32_t unique_patch_value = reinterpret_cast<uint32_t>(&id);
            pushWord(cUnit->codeBuffer, unique_patch_value);
            dataLIR = NEXT_LIR(dataLIR);
        }
        dataLIR = cUnit->methodLiteralList;
        while (dataLIR != NULL) {
            uint32_t target = dataLIR->operands[0];
            cUnit->compiler->AddMethodPatch(cUnit->dex_cache, cUnit->dex_file,
                                            cUnit->method_idx,
                                            cUnit->access_flags,
                                            target,
                                            IsDirect(dataLIR->operands[1]),
                                            cUnit->codeBuffer.size());
            const DexFile::MethodId& id = cUnit->dex_file->GetMethodId(target);
            // unique based on target to ensure code deduplication works
            uint32_t unique_patch_value = reinterpret_cast<uint32_t>(&id);
            pushWord(cUnit->codeBuffer, unique_patch_value);
            dataLIR = NEXT_LIR(dataLIR);
        }
    }

}

/* Write the switch tables to the output stream */
void installSwitchTables(CompilationUnit* cUnit)
{
    GrowableListIterator iterator;
    oatGrowableListIteratorInit(&cUnit->switchTables, &iterator);
    while (true) {
        SwitchTable* tabRec = (SwitchTable *) oatGrowableListIteratorNext(
             &iterator);
        if (tabRec == NULL) break;
        alignBuffer(cUnit->codeBuffer, tabRec->offset);
        /*
         * For Arm, our reference point is the address of the bx
         * instruction that does the launch, so we have to subtract
         * the auto pc-advance.  For other targets the reference point
         * is a label, so we can use the offset as-is.
         */
#if defined(TARGET_ARM)
        int bxOffset = tabRec->anchor->offset + 4;
#elif defined(TARGET_X86)
        int bxOffset = 0;
#else
        int bxOffset = tabRec->anchor->offset;
#endif
        if (cUnit->printMe) {
            LOG(INFO) << "Switch table for offset 0x" << std::hex << bxOffset;
        }
        if (tabRec->table[0] == Instruction::kSparseSwitchSignature) {
            int* keys = (int*)&(tabRec->table[2]);
            for (int elems = 0; elems < tabRec->table[1]; elems++) {
                int disp = tabRec->targets[elems]->offset - bxOffset;
                if (cUnit->printMe) {
                    LOG(INFO) << "    Case[" << elems << "] key: 0x" <<
                        std::hex << keys[elems] << ", disp: 0x" <<
                        std::hex << disp;
                }
                pushWord(cUnit->codeBuffer, keys[elems]);
                pushWord(cUnit->codeBuffer,
                    tabRec->targets[elems]->offset - bxOffset);
            }
        } else {
            DCHECK_EQ(static_cast<int>(tabRec->table[0]), static_cast<int>(Instruction::kPackedSwitchSignature));
            for (int elems = 0; elems < tabRec->table[1]; elems++) {
                int disp = tabRec->targets[elems]->offset - bxOffset;
                if (cUnit->printMe) {
                    LOG(INFO) << "    Case[" << elems << "] disp: 0x" <<
                        std::hex << disp;
                }
                pushWord(cUnit->codeBuffer,
                         tabRec->targets[elems]->offset - bxOffset);
            }
        }
    }
}

/* Write the fill array dta to the output stream */
void installFillArrayData(CompilationUnit* cUnit)
{
    GrowableListIterator iterator;
    oatGrowableListIteratorInit(&cUnit->fillArrayData, &iterator);
    while (true) {
        FillArrayData *tabRec = (FillArrayData *) oatGrowableListIteratorNext(
             &iterator);
        if (tabRec == NULL) break;
        alignBuffer(cUnit->codeBuffer, tabRec->offset);
        for (int i = 0; i < (tabRec->size + 1) / 2; i++) {
            cUnit->codeBuffer.push_back( tabRec->table[i] & 0xFF);
            cUnit->codeBuffer.push_back( (tabRec->table[i] >> 8) & 0xFF);
        }
    }
}

int assignLiteralOffsetCommon(LIR* lir, int offset)
{
    for (;lir != NULL; lir = lir->next) {
        lir->offset = offset;
        offset += 4;
    }
    return offset;
}

void createMappingTable(CompilationUnit* cUnit)
{
    LIR* tgtLIR;
    int currentDalvikOffset = -1;

    for (tgtLIR = (LIR *) cUnit->firstLIRInsn;
         tgtLIR;
         tgtLIR = NEXT_LIR(tgtLIR)) {
        if ((tgtLIR->opcode >= 0) && !tgtLIR->flags.isNop &&
            (currentDalvikOffset != tgtLIR->dalvikOffset)) {
            // Changed - need to emit a record
            cUnit->mappingTable.push_back(tgtLIR->offset);
            cUnit->mappingTable.push_back(tgtLIR->dalvikOffset);
            currentDalvikOffset = tgtLIR->dalvikOffset;
        }
    }
}

/* Determine the offset of each literal field */
int assignLiteralOffset(CompilationUnit* cUnit, int offset)
{
    offset = assignLiteralOffsetCommon(cUnit->literalList, offset);
    offset = assignLiteralOffsetCommon(cUnit->codeLiteralList, offset);
    offset = assignLiteralOffsetCommon(cUnit->methodLiteralList, offset);
    return offset;
}

int assignSwitchTablesOffset(CompilationUnit* cUnit, int offset)
{
    GrowableListIterator iterator;
    oatGrowableListIteratorInit(&cUnit->switchTables, &iterator);
    while (true) {
        SwitchTable *tabRec = (SwitchTable *) oatGrowableListIteratorNext(
             &iterator);
        if (tabRec == NULL) break;
        tabRec->offset = offset;
        if (tabRec->table[0] == Instruction::kSparseSwitchSignature) {
            offset += tabRec->table[1] * (sizeof(int) * 2);
        } else {
            DCHECK_EQ(static_cast<int>(tabRec->table[0]), static_cast<int>(Instruction::kPackedSwitchSignature));
            offset += tabRec->table[1] * sizeof(int);
        }
    }
    return offset;
}

int assignFillArrayDataOffset(CompilationUnit* cUnit, int offset)
{
    GrowableListIterator iterator;
    oatGrowableListIteratorInit(&cUnit->fillArrayData, &iterator);
    while (true) {
        FillArrayData *tabRec = (FillArrayData *) oatGrowableListIteratorNext(
             &iterator);
        if (tabRec == NULL) break;
        tabRec->offset = offset;
        offset += tabRec->size;
        // word align
        offset = (offset + 3) & ~3;
        }
    return offset;
}

/*
 * Walk the compilation unit and assign offsets to instructions
 * and literals and compute the total size of the compiled unit.
 */
void oatAssignOffsets(CompilationUnit* cUnit)
{
    int offset = oatAssignInsnOffsets(cUnit);

    /* Const values have to be word aligned */
    offset = (offset + 3) & ~3;

    /* Set up offsets for literals */
    cUnit->dataOffset = offset;

    offset = assignLiteralOffset(cUnit, offset);

    offset = assignSwitchTablesOffset(cUnit, offset);

    offset = assignFillArrayDataOffset(cUnit, offset);

    cUnit->totalSize = offset;
}

/*
 * Go over each instruction in the list and calculate the offset from the top
 * before sending them off to the assembler. If out-of-range branch distance is
 * seen rearrange the instructions a bit to correct it.
 */
void oatAssembleLIR(CompilationUnit* cUnit)
{
    oatAssignOffsets(cUnit);
    /*
     * Assemble here.  Note that we generate code with optimistic assumptions
     * and if found now to work, we'll have to redo the sequence and retry.
     */

    while (true) {
        AssemblerStatus res = oatAssembleInstructions(cUnit, 0);
        if (res == kSuccess) {
            break;
        } else {
            cUnit->assemblerRetries++;
            if (cUnit->assemblerRetries > MAX_ASSEMBLER_RETRIES) {
              oatCodegenDump(cUnit);
              LOG(FATAL) << "Assembler error - too many retries";
            }
            // Redo offsets and try again
            oatAssignOffsets(cUnit);
            cUnit->codeBuffer.clear();
        }
    }

    // Install literals
    installLiteralPools(cUnit);

    // Install switch tables
    installSwitchTables(cUnit);

    // Install fill array data
    installFillArrayData(cUnit);

    /*
     * Create the mapping table
     */
    createMappingTable(cUnit);
}

/*
 * Insert a kPseudoCaseLabel at the beginning of the Dalvik
 * offset vaddr.  This label will be used to fix up the case
 * branch table during the assembly phase.  Be sure to set
 * all resource flags on this to prevent code motion across
 * target boundaries.  KeyVal is just there for debugging.
 */
LIR* insertCaseLabel(CompilationUnit* cUnit, int vaddr, int keyVal)
{
    SafeMap<unsigned int, LIR*>::iterator it;
    it = cUnit->boundaryMap.find(vaddr);
    if (it == cUnit->boundaryMap.end()) {
        LOG(FATAL) << "Error: didn't find vaddr 0x" << std::hex << vaddr;
    }
    LIR* newLabel = (LIR*)oatNew(cUnit, sizeof(LIR), true, kAllocLIR);
    newLabel->dalvikOffset = vaddr;
    newLabel->opcode = kPseudoCaseLabel;
    newLabel->operands[0] = keyVal;
    oatInsertLIRAfter(it->second, (LIR*)newLabel);
    return newLabel;
}

void markPackedCaseLabels(CompilationUnit* cUnit, SwitchTable *tabRec)
{
    const u2* table = tabRec->table;
    int baseVaddr = tabRec->vaddr;
    int *targets = (int*)&table[4];
    int entries = table[1];
    int lowKey = s4FromSwitchData(&table[2]);
    for (int i = 0; i < entries; i++) {
        tabRec->targets[i] = insertCaseLabel(cUnit, baseVaddr + targets[i],
                                             i + lowKey);
    }
}

void markSparseCaseLabels(CompilationUnit* cUnit, SwitchTable *tabRec)
{
    const u2* table = tabRec->table;
    int baseVaddr = tabRec->vaddr;
    int entries = table[1];
    int* keys = (int*)&table[2];
    int* targets = &keys[entries];
    for (int i = 0; i < entries; i++) {
        tabRec->targets[i] = insertCaseLabel(cUnit, baseVaddr + targets[i],
                                             keys[i]);
    }
}

void oatProcessSwitchTables(CompilationUnit* cUnit)
{
    GrowableListIterator iterator;
    oatGrowableListIteratorInit(&cUnit->switchTables, &iterator);
    while (true) {
        SwitchTable *tabRec = (SwitchTable *) oatGrowableListIteratorNext(
             &iterator);
        if (tabRec == NULL) break;
        if (tabRec->table[0] == Instruction::kPackedSwitchSignature) {
            markPackedCaseLabels(cUnit, tabRec);
        } else if (tabRec->table[0] == Instruction::kSparseSwitchSignature) {
            markSparseCaseLabels(cUnit, tabRec);
        } else {
            LOG(FATAL) << "Invalid switch table";
        }
    }
}

//FIXME: Do we have endian issues here?

void dumpSparseSwitchTable(const u2* table)
    /*
     * Sparse switch data format:
     *  ushort ident = 0x0200   magic value
     *  ushort size             number of entries in the table; > 0
     *  int keys[size]          keys, sorted low-to-high; 32-bit aligned
     *  int targets[size]       branch targets, relative to switch opcode
     *
     * Total size is (2+size*4) 16-bit code units.
     */
{
    u2 ident = table[0];
    int entries = table[1];
    int* keys = (int*)&table[2];
    int* targets = &keys[entries];
    LOG(INFO) <<  "Sparse switch table - ident:0x" << std::hex << ident <<
       ", entries: " << std::dec << entries;
    for (int i = 0; i < entries; i++) {
        LOG(INFO) << "    Key[" << keys[i] << "] -> 0x" << std::hex <<
        targets[i];
    }
}

void dumpPackedSwitchTable(const u2* table)
    /*
     * Packed switch data format:
     *  ushort ident = 0x0100   magic value
     *  ushort size             number of entries in the table
     *  int first_key           first (and lowest) switch case value
     *  int targets[size]       branch targets, relative to switch opcode
     *
     * Total size is (4+size*2) 16-bit code units.
     */
{
    u2 ident = table[0];
    int* targets = (int*)&table[4];
    int entries = table[1];
    int lowKey = s4FromSwitchData(&table[2]);
    LOG(INFO) << "Packed switch table - ident:0x" << std::hex << ident <<
        ", entries: " << std::dec << entries << ", lowKey: " << lowKey;
    for (int i = 0; i < entries; i++) {
        LOG(INFO) << "    Key[" << (i + lowKey) << "] -> 0x" << std::hex <<
            targets[i];
    }
}


}  // namespace art
