/*
 * Copyright (C) 2012 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 Mips-specific register allocation support.
 */

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

namespace art {

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

void oatAdjustSpillMask(CompilationUnit* cUnit)
{
    cUnit->coreSpillMask |= (1 << r_RA);
    cUnit->numCoreSpills++;
}

/*
 * Mark a callee-save fp register as promoted.  Note that
 * vpush/vpop uses contiguous register lists so we must
 * include any holes in the mask.  Associate holes with
 * Dalvik register INVALID_VREG (0xFFFFU).
 */
void oatMarkPreservedSingle(CompilationUnit* cUnit, int sReg, int reg)
{
    LOG(FATAL) << "No support yet for promoted FP regs";
}

void oatFlushRegWide(CompilationUnit* cUnit, int reg1, int reg2)
{
    RegisterInfo* info1 = oatGetRegInfo(cUnit, reg1);
    RegisterInfo* info2 = oatGetRegInfo(cUnit, reg2);
    DCHECK(info1 && info2 && info1->pair && info2->pair &&
           (info1->partner == info2->reg) &&
           (info2->partner == info1->reg));
    if ((info1->live && info1->dirty) || (info2->live && info2->dirty)) {
        if (!(info1->isTemp && info2->isTemp)) {
            /* Should not happen.  If it does, there's a problem in evalLoc */
            LOG(FATAL) << "Long half-temp, half-promoted";
        }

        info1->dirty = false;
        info2->dirty = false;
        if (oatS2VReg(cUnit, info2->sReg) <
            oatS2VReg(cUnit, info1->sReg))
            info1 = info2;
        int vReg = oatS2VReg(cUnit, info1->sReg);
        oatFlushRegWideImpl(cUnit, rSP,
                                    oatVRegOffset(cUnit, vReg),
                                    info1->reg, info1->partner);
    }
}

void oatFlushReg(CompilationUnit* cUnit, int reg)
{
    RegisterInfo* info = oatGetRegInfo(cUnit, reg);
    if (info->live && info->dirty) {
        info->dirty = false;
        int vReg = oatS2VReg(cUnit, info->sReg);
        oatFlushRegImpl(cUnit, rSP,
                                oatVRegOffset(cUnit, vReg),
                                reg, kWord);
    }
}

/* Give access to the target-dependent FP register encoding to common code */
bool oatIsFpReg(int reg) {
    return FPREG(reg);
}

uint32_t oatFpRegMask() {
    return FP_REG_MASK;
}

/* Clobber all regs that might be used by an external C call */
extern void oatClobberCalleeSave(CompilationUnit *cUnit)
{
    oatClobber(cUnit, r_ZERO);
    oatClobber(cUnit, r_AT);
    oatClobber(cUnit, r_V0);
    oatClobber(cUnit, r_V1);
    oatClobber(cUnit, r_A0);
    oatClobber(cUnit, r_A1);
    oatClobber(cUnit, r_A2);
    oatClobber(cUnit, r_A3);
    oatClobber(cUnit, r_T0);
    oatClobber(cUnit, r_T1);
    oatClobber(cUnit, r_T2);
    oatClobber(cUnit, r_T3);
    oatClobber(cUnit, r_T4);
    oatClobber(cUnit, r_T5);
    oatClobber(cUnit, r_T6);
    oatClobber(cUnit, r_T7);
    oatClobber(cUnit, r_T8);
    oatClobber(cUnit, r_T9);
    oatClobber(cUnit, r_K0);
    oatClobber(cUnit, r_K1);
    oatClobber(cUnit, r_GP);
    oatClobber(cUnit, r_FP);
    oatClobber(cUnit, r_RA);
    oatClobber(cUnit, r_F0);
    oatClobber(cUnit, r_F1);
    oatClobber(cUnit, r_F2);
    oatClobber(cUnit, r_F3);
    oatClobber(cUnit, r_F4);
    oatClobber(cUnit, r_F5);
    oatClobber(cUnit, r_F6);
    oatClobber(cUnit, r_F7);
    oatClobber(cUnit, r_F8);
    oatClobber(cUnit, r_F9);
    oatClobber(cUnit, r_F10);
    oatClobber(cUnit, r_F11);
    oatClobber(cUnit, r_F12);
    oatClobber(cUnit, r_F13);
    oatClobber(cUnit, r_F14);
    oatClobber(cUnit, r_F15);
}

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

extern RegLocation oatGetReturnAlt(CompilationUnit* cUnit)
{
    UNIMPLEMENTED(FATAL);
    RegLocation res = LOC_C_RETURN;
    return res;
}

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

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

/* To be used when explicitly managing register use */
extern void oatLockCallTemps(CompilationUnit* cUnit)
{
    oatLockTemp(cUnit, rARG0);
    oatLockTemp(cUnit, rARG1);
    oatLockTemp(cUnit, rARG2);
    oatLockTemp(cUnit, rARG3);
}

/* To be used when explicitly managing register use */
extern void oatFreeCallTemps(CompilationUnit* cUnit)
{
    oatFreeTemp(cUnit, rARG0);
    oatFreeTemp(cUnit, rARG1);
    oatFreeTemp(cUnit, rARG2);
    oatFreeTemp(cUnit, rARG3);
}

/* Convert an instruction to a NOP */
void oatNopLIR( LIR* lir)
{
    ((LIR*)lir)->flags.isNop = true;
}

}  // namespace art
