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

/*
 * This file contains Arm-specific register allocation support.
 */

#include "../../CompilerUtility.h"
#include "../../CompilerIR.h"
#include "../..//Dataflow.h"
#include "ArmLIR.h"
#include "Codegen.h"
#include "../Ralloc.h"

namespace art {

/*
 * Placeholder routine until we do proper register allocation.
 */

typedef struct RefCounts {
    int count;
    int sReg;
    bool doubleStart;   // Starting vReg for a double
} RefCounts;

/* USE SSA names to count references of base Dalvik vRegs. */
STATIC void countRefs(CompilationUnit *cUnit, BasicBlock* bb,
                      RefCounts* coreCounts, RefCounts* fpCounts)
{
    MIR* mir;
    if (bb->blockType != kDalvikByteCode && bb->blockType != kEntryBlock &&
        bb->blockType != kExitBlock)
        return;

    for (mir = bb->firstMIRInsn; mir; mir = mir->next) {
        SSARepresentation *ssaRep = mir->ssaRep;
        if (ssaRep) {
            for (int i = 0; i < ssaRep->numDefs;) {
                RegLocation loc = cUnit->regLocation[ssaRep->defs[i]];
                RefCounts* counts = loc.fp ? fpCounts : coreCounts;
                int vReg = oatS2VReg(cUnit, ssaRep->defs[i]);
                if (loc.defined) {
                    counts[vReg].count++;
                }
                if (loc.wide) {
                    if (loc.defined) {
                        if (loc.fp) {
                            counts[vReg].doubleStart = true;
                        }
                        counts[vReg+1].count++;
                    }
                    i += 2;
                } else {
                    i++;
                }
            }
            for (int i = 0; i < ssaRep->numUses;) {
                RegLocation loc = cUnit->regLocation[ssaRep->uses[i]];
                RefCounts* counts = loc.fp ? fpCounts : coreCounts;
                int vReg = oatS2VReg(cUnit, ssaRep->uses[i]);
                if (loc.defined) {
                    counts[vReg].count++;
                }
                if (loc.wide) {
                    if (loc.defined) {
                        if (loc.fp) {
                            counts[vReg].doubleStart = true;
                        }
                        counts[vReg+1].count++;
                    }
                    i += 2;
                } else {
                    i++;
                }
            }
        }
    }
}

/* qsort callback function, sort descending */
STATIC int sortCounts(const void *val1, const void *val2)
{
    const RefCounts* op1 = (const RefCounts*)val1;
    const RefCounts* op2 = (const RefCounts*)val2;
    return (op1->count == op2->count) ? 0 : (op1->count < op2->count ? 1 : -1);
}

STATIC void dumpCounts(const RefCounts* arr, int size, const char* msg)
{
    LOG(INFO) << msg;
    for (int i = 0; i < size; i++) {
        LOG(INFO) << "sReg[" << arr[i].sReg << "]: " << arr[i].count;
    }
}

/*
 * Note: some portions of this code required even if the kPromoteRegs
 * optimization is disabled.
 */
extern void oatDoPromotion(CompilationUnit* cUnit)
{
    int numRegs = cUnit->numDalvikRegisters;

    /*
     * TUNING: is leaf?  Can't just use "hasInvoke" to determine as some
     * instructions might call out to C/assembly helper functions.  Until
     * machinery is in place, always spill lr.
     */
    cUnit->coreSpillMask |= (1 << rLR);
    cUnit->numCoreSpills++;
    /*
     * Simple hack for testing register allocation.  Just do a static
     * count of the uses of Dalvik registers.  Note that we examine
     * the SSA names, but count based on original Dalvik register name.
     * Count refs separately based on type in order to give allocation
     * preference to fp doubles - which must be allocated sequential
     * physical single fp registers started with an even-numbered
     * reg.
     */
    RefCounts *coreRegs = (RefCounts *)
          oatNew(sizeof(RefCounts) * numRegs, true, kAllocRegAlloc);
    RefCounts *fpRegs = (RefCounts *)
          oatNew(sizeof(RefCounts) * numRegs, true, kAllocRegAlloc);
    for (int i = 0; i < numRegs; i++) {
        coreRegs[i].sReg = fpRegs[i].sReg = i;
    }
    GrowableListIterator iterator;
    oatGrowableListIteratorInit(&cUnit->blockList, &iterator);
    while (true) {
        BasicBlock* bb;
        bb = (BasicBlock*)oatGrowableListIteratorNext(&iterator);
        if (bb == NULL) break;
        countRefs(cUnit, bb, coreRegs, fpRegs);
    }

    /*
     * Ideally, we'd allocate doubles starting with an even-numbered
     * register.  Bias the counts to try to allocate any vreg that's
     * used as the start of a pair first.
     */
    for (int i = 0; i < numRegs; i++) {
        if (fpRegs[i].doubleStart) {
            fpRegs[i].count *= 2;
        }
    }

    // Sort the count arrays
    qsort(coreRegs, numRegs, sizeof(RefCounts), sortCounts);
    qsort(fpRegs, numRegs, sizeof(RefCounts), sortCounts);

    if (cUnit->printMe) {
        dumpCounts(coreRegs, numRegs, "Core regs after sort");
        dumpCounts(fpRegs, numRegs, "Fp regs after sort");
    }

    if (!(cUnit->disableOpt & (1 << kPromoteRegs))) {
        // Promote fpRegs
        for (int i = 0; (fpRegs[i].count > 0) && (i < numRegs); i++) {
            if (cUnit->promotionMap[fpRegs[i].sReg].fpLocation != kLocPhysReg) {
                if (fpRegs[i].sReg >= cUnit->numRegs) {
                    // don't promote arg regs
                    continue;
                }
                int reg = oatAllocPreservedFPReg(cUnit, fpRegs[i].sReg,
                    fpRegs[i].doubleStart);
                if (reg < 0) {
                    break;  // No more left
                }
            }
        }

        // Promote core regs
        for (int i = 0; (coreRegs[i].count > 0) && i < numRegs; i++) {
            if (cUnit->promotionMap[coreRegs[i].sReg].coreLocation !=
                    kLocPhysReg) {
                if (coreRegs[i].sReg >= cUnit->numRegs) {
                    // don't promote arg regs
                    continue;
                }
                int reg = oatAllocPreservedCoreReg(cUnit, coreRegs[i].sReg);
                if (reg < 0) {
                   break;  // No more left
                }
            }
        }
    }

    // Now, update SSA names to new home locations
    for (int i = 0; i < cUnit->numSSARegs; i++) {
        RegLocation *curr = &cUnit->regLocation[i];
        int baseVReg = oatS2VReg(cUnit, curr->sRegLow);
        if (!curr->wide) {
            if (curr->fp) {
                if (cUnit->promotionMap[baseVReg].fpLocation == kLocPhysReg) {
                    curr->location = kLocPhysReg;
                    curr->lowReg = cUnit->promotionMap[baseVReg].fpReg;
                    curr->home = true;
                }
            } else {
                if (cUnit->promotionMap[baseVReg].coreLocation == kLocPhysReg) {
                    curr->location = kLocPhysReg;
                    curr->lowReg = cUnit->promotionMap[baseVReg].coreReg;
                    curr->home = true;
                }
            }
            curr->highReg = INVALID_REG;
        } else {
            if (curr->highWord) {
                continue;
            }
            if (curr->fp) {
                if ((cUnit->promotionMap[baseVReg].fpLocation == kLocPhysReg) &&
                    (cUnit->promotionMap[baseVReg+1].fpLocation ==
                    kLocPhysReg)) {
                    int lowReg = cUnit->promotionMap[baseVReg].fpReg;
                    int highReg = cUnit->promotionMap[baseVReg+1].fpReg;
                    // Doubles require pair of singles starting at even reg
                    if (((lowReg & 0x1) == 0) && ((lowReg + 1) == highReg)) {
                        curr->location = kLocPhysReg;
                        curr->lowReg = lowReg;
                        curr->highReg = highReg;
                        curr->home = true;
                    }
                }
            } else {
                if ((cUnit->promotionMap[baseVReg].coreLocation == kLocPhysReg)
                     && (cUnit->promotionMap[baseVReg+1].coreLocation ==
                     kLocPhysReg)) {
                    curr->location = kLocPhysReg;
                    curr->lowReg = cUnit->promotionMap[baseVReg].coreReg;
                    curr->highReg = cUnit->promotionMap[baseVReg+1].coreReg;
                    curr->home = true;
                }
            }
        }
    }
}

/* Returns sp-relative offset in bytes for a VReg */
extern int oatVRegOffset(CompilationUnit* cUnit, int vReg)
{
    return (vReg < cUnit->numRegs) ? cUnit->regsOffset + (vReg << 2) :
            cUnit->insOffset + ((vReg - cUnit->numRegs) << 2);
}

/* Returns sp-relative offset in bytes for a SReg */
extern int oatSRegOffset(CompilationUnit* cUnit, int sReg)
{
    return oatVRegOffset(cUnit, oatS2VReg(cUnit, sReg));
}


/* Return sp-relative offset in bytes using Method* */
extern int oatVRegOffset(const DexFile::CodeItem* code_item,
                         uint32_t core_spills, uint32_t fp_spills,
                         size_t frame_size, int reg)
{
    int numIns = code_item->ins_size_;
    int numRegs = code_item->registers_size_ - numIns;
    int numOuts = code_item->outs_size_;
    int numSpills = __builtin_popcount(core_spills) +
                    __builtin_popcount(fp_spills);
    int numPadding = (STACK_ALIGN_WORDS -
        (numSpills + numRegs + numOuts + 2)) & (STACK_ALIGN_WORDS-1);
    int regsOffset = (numOuts + numPadding + 1) * 4;
    int insOffset = frame_size + 4;
    return (reg < numRegs) ? regsOffset + (reg << 2) :
           insOffset + ((reg - numRegs) << 2);
}

/* Clobber all regs that might be used by an external C call */
extern void oatClobberCalleeSave(CompilationUnit *cUnit)
{
    oatClobber(cUnit, r0);
    oatClobber(cUnit, r1);
    oatClobber(cUnit, r2);
    oatClobber(cUnit, r3);
    oatClobber(cUnit, r12);
    oatClobber(cUnit, r14lr);
}

extern RegLocation oatGetReturnWide(CompilationUnit* cUnit)
{
    RegLocation res = LOC_C_RETURN_WIDE;
    oatClobber(cUnit, r0);
    oatClobber(cUnit, r1);
    oatMarkInUse(cUnit, r0);
    oatMarkInUse(cUnit, r1);
    oatMarkPair(cUnit, res.lowReg, res.highReg);
    return res;
}

extern RegLocation oatGetReturnWideAlt(CompilationUnit* cUnit)
{
    RegLocation res = LOC_C_RETURN_WIDE;
    res.lowReg = r2;
    res.highReg = r3;
    oatClobber(cUnit, r2);
    oatClobber(cUnit, r3);
    oatMarkInUse(cUnit, r2);
    oatMarkInUse(cUnit, r3);
    oatMarkPair(cUnit, res.lowReg, res.highReg);
    return res;
}

extern RegLocation oatGetReturn(CompilationUnit* cUnit)
{
    RegLocation res = LOC_C_RETURN;
    oatClobber(cUnit, r0);
    oatMarkInUse(cUnit, r0);
    return res;
}

extern RegLocation oatGetReturnAlt(CompilationUnit* cUnit)
{
    RegLocation res = LOC_C_RETURN;
    res.lowReg = r1;
    oatClobber(cUnit, r1);
    oatMarkInUse(cUnit, r1);
    return res;
}

extern RegisterInfo* oatGetRegInfo(CompilationUnit* cUnit, int reg)
{
    return FPREG(reg) ? &cUnit->regPool->FPRegs[reg & FP_REG_MASK]
                      : &cUnit->regPool->coreRegs[reg];
}

}  // namespace art
