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

/*
 * This file contains target-independent codegen and support, and is
 * included by:
 *
 *        $(TARGET_ARCH)/Codegen-$(TARGET_ARCH_VARIANT).c
 *
 * which combines this common code with specific support found in the
 * applicable directories below this one.
 *
 */

/*
 * Load an immediate value into a fixed or temp register.  Target
 * register is clobbered, and marked inUse.
 */
LIR* loadConstant(CompilationUnit* cUnit, int rDest, int value)
{
  if (oatIsTemp(cUnit, rDest)) {
    oatClobber(cUnit, rDest);
    oatMarkInUse(cUnit, rDest);
  }
  return loadConstantNoClobber(cUnit, rDest, value);
}

/* Load a word at base + displacement.  Displacement must be word multiple */
LIR* loadWordDisp(CompilationUnit* cUnit, int rBase, int displacement,
                  int rDest)
{
  return loadBaseDisp(cUnit, rBase, displacement, rDest, kWord,
                      INVALID_SREG);
}

LIR* storeWordDisp(CompilationUnit* cUnit, int rBase, int displacement,
                   int rSrc)
{
  return storeBaseDisp(cUnit, rBase, displacement, rSrc, kWord);
}

/*
 * Load a Dalvik register into a physical register.  Take care when
 * using this routine, as it doesn't perform any bookkeeping regarding
 * register liveness.  That is the responsibility of the caller.
 */
void loadValueDirect(CompilationUnit* cUnit, RegLocation rlSrc, int rDest)
{
  rlSrc = oatUpdateLoc(cUnit, rlSrc);
  if (rlSrc.location == kLocPhysReg) {
    opRegCopy(cUnit, rDest, rlSrc.lowReg);
  } else {
    DCHECK((rlSrc.location == kLocDalvikFrame) ||
           (rlSrc.location == kLocCompilerTemp));
    loadWordDisp(cUnit, rSP, oatSRegOffset(cUnit, rlSrc.sRegLow), rDest);
  }
}

/*
 * Similar to loadValueDirect, but clobbers and allocates the target
 * register.  Should be used when loading to a fixed register (for example,
 * loading arguments to an out of line call.
 */
void loadValueDirectFixed(CompilationUnit* cUnit, RegLocation rlSrc, int rDest)
{
  oatClobber(cUnit, rDest);
  oatMarkInUse(cUnit, rDest);
  loadValueDirect(cUnit, rlSrc, rDest);
}

/*
 * Load a Dalvik register pair into a physical register[s].  Take care when
 * using this routine, as it doesn't perform any bookkeeping regarding
 * register liveness.  That is the responsibility of the caller.
 */
void loadValueDirectWide(CompilationUnit* cUnit, RegLocation rlSrc, int regLo,
             int regHi)
{
  rlSrc = oatUpdateLocWide(cUnit, rlSrc);
  if (rlSrc.location == kLocPhysReg) {
    opRegCopyWide(cUnit, regLo, regHi, rlSrc.lowReg, rlSrc.highReg);
  } else {
    DCHECK((rlSrc.location == kLocDalvikFrame) ||
           (rlSrc.location == kLocCompilerTemp));
    loadBaseDispWide(cUnit, rSP, oatSRegOffset(cUnit, rlSrc.sRegLow),
                     regLo, regHi, INVALID_SREG);
  }
}

/*
 * Similar to loadValueDirect, but clobbers and allocates the target
 * registers.  Should be used when loading to a fixed registers (for example,
 * loading arguments to an out of line call.
 */
void loadValueDirectWideFixed(CompilationUnit* cUnit, RegLocation rlSrc,
                              int regLo, int regHi)
{
  oatClobber(cUnit, regLo);
  oatClobber(cUnit, regHi);
  oatMarkInUse(cUnit, regLo);
  oatMarkInUse(cUnit, regHi);
  loadValueDirectWide(cUnit, rlSrc, regLo, regHi);
}

RegLocation loadValue(CompilationUnit* cUnit, RegLocation rlSrc,
                      RegisterClass opKind)
{
  rlSrc = oatEvalLoc(cUnit, rlSrc, opKind, false);
  if (rlSrc.location != kLocPhysReg) {
    DCHECK((rlSrc.location == kLocDalvikFrame) ||
           (rlSrc.location == kLocCompilerTemp));
    loadValueDirect(cUnit, rlSrc, rlSrc.lowReg);
    rlSrc.location = kLocPhysReg;
    oatMarkLive(cUnit, rlSrc.lowReg, rlSrc.sRegLow);
  }
  return rlSrc;
}

void storeValue(CompilationUnit* cUnit, RegLocation rlDest, RegLocation rlSrc)
{
#ifndef NDEBUG
  /*
   * Sanity checking - should never try to store to the same
   * ssa name during the compilation of a single instruction
   * without an intervening oatClobberSReg().
   */
  DCHECK((cUnit->liveSReg == INVALID_SREG) ||
         (rlDest.sRegLow != cUnit->liveSReg));
  cUnit->liveSReg = rlDest.sRegLow;
#endif
  LIR* defStart;
  LIR* defEnd;
  DCHECK(!rlDest.wide);
  DCHECK(!rlSrc.wide);
  rlSrc = oatUpdateLoc(cUnit, rlSrc);
  rlDest = oatUpdateLoc(cUnit, rlDest);
  if (rlSrc.location == kLocPhysReg) {
    if (oatIsLive(cUnit, rlSrc.lowReg) ||
      oatIsPromoted(cUnit, rlSrc.lowReg) ||
      (rlDest.location == kLocPhysReg)) {
      // Src is live/promoted or Dest has assigned reg.
      rlDest = oatEvalLoc(cUnit, rlDest, kAnyReg, false);
      opRegCopy(cUnit, rlDest.lowReg, rlSrc.lowReg);
    } else {
      // Just re-assign the registers.  Dest gets Src's regs
      rlDest.lowReg = rlSrc.lowReg;
      oatClobber(cUnit, rlSrc.lowReg);
    }
  } else {
    // Load Src either into promoted Dest or temps allocated for Dest
    rlDest = oatEvalLoc(cUnit, rlDest, kAnyReg, false);
    loadValueDirect(cUnit, rlSrc, rlDest.lowReg);
  }

  // Dest is now live and dirty (until/if we flush it to home location)
  oatMarkLive(cUnit, rlDest.lowReg, rlDest.sRegLow);
  oatMarkDirty(cUnit, rlDest);


  oatResetDefLoc(cUnit, rlDest);
  if (oatIsDirty(cUnit, rlDest.lowReg) &&
      oatLiveOut(cUnit, rlDest.sRegLow)) {
    defStart = (LIR* )cUnit->lastLIRInsn;
    storeBaseDisp(cUnit, rSP, oatSRegOffset(cUnit, rlDest.sRegLow),
                  rlDest.lowReg, kWord);
    oatMarkClean(cUnit, rlDest);
    defEnd = (LIR* )cUnit->lastLIRInsn;
    oatMarkDef(cUnit, rlDest, defStart, defEnd);
  }
}

RegLocation loadValueWide(CompilationUnit* cUnit, RegLocation rlSrc,
              RegisterClass opKind)
{
  DCHECK(rlSrc.wide);
  rlSrc = oatEvalLoc(cUnit, rlSrc, opKind, false);
  if (rlSrc.location != kLocPhysReg) {
    DCHECK((rlSrc.location == kLocDalvikFrame) ||
        (rlSrc.location == kLocCompilerTemp));
    loadValueDirectWide(cUnit, rlSrc, rlSrc.lowReg, rlSrc.highReg);
    rlSrc.location = kLocPhysReg;
    oatMarkLive(cUnit, rlSrc.lowReg, rlSrc.sRegLow);
    oatMarkLive(cUnit, rlSrc.highReg,
                oatSRegHi(rlSrc.sRegLow));
  }
  return rlSrc;
}

void storeValueWide(CompilationUnit* cUnit, RegLocation rlDest,
          RegLocation rlSrc)
{
#ifndef NDEBUG
  /*
   * Sanity checking - should never try to store to the same
   * ssa name during the compilation of a single instruction
   * without an intervening oatClobberSReg().
   */
  DCHECK((cUnit->liveSReg == INVALID_SREG) ||
      (rlDest.sRegLow != cUnit->liveSReg));
  cUnit->liveSReg = rlDest.sRegLow;
#endif
  LIR* defStart;
  LIR* defEnd;
  DCHECK_EQ(FPREG(rlSrc.lowReg), FPREG(rlSrc.highReg));
  DCHECK(rlDest.wide);
  DCHECK(rlSrc.wide);
  if (rlSrc.location == kLocPhysReg) {
    if (oatIsLive(cUnit, rlSrc.lowReg) ||
        oatIsLive(cUnit, rlSrc.highReg) ||
        oatIsPromoted(cUnit, rlSrc.lowReg) ||
        oatIsPromoted(cUnit, rlSrc.highReg) ||
        (rlDest.location == kLocPhysReg)) {
      // Src is live or promoted or Dest has assigned reg.
      rlDest = oatEvalLoc(cUnit, rlDest, kAnyReg, false);
      opRegCopyWide(cUnit, rlDest.lowReg, rlDest.highReg,
                    rlSrc.lowReg, rlSrc.highReg);
    } else {
      // Just re-assign the registers.  Dest gets Src's regs
      rlDest.lowReg = rlSrc.lowReg;
      rlDest.highReg = rlSrc.highReg;
      oatClobber(cUnit, rlSrc.lowReg);
      oatClobber(cUnit, rlSrc.highReg);
    }
  } else {
    // Load Src either into promoted Dest or temps allocated for Dest
    rlDest = oatEvalLoc(cUnit, rlDest, kAnyReg, false);
    loadValueDirectWide(cUnit, rlSrc, rlDest.lowReg, rlDest.highReg);
  }

  // Dest is now live and dirty (until/if we flush it to home location)
  oatMarkLive(cUnit, rlDest.lowReg, rlDest.sRegLow);
  oatMarkLive(cUnit, rlDest.highReg, oatSRegHi(rlDest.sRegLow));
  oatMarkDirty(cUnit, rlDest);
  oatMarkPair(cUnit, rlDest.lowReg, rlDest.highReg);


  oatResetDefLocWide(cUnit, rlDest);
  if ((oatIsDirty(cUnit, rlDest.lowReg) ||
      oatIsDirty(cUnit, rlDest.highReg)) &&
      (oatLiveOut(cUnit, rlDest.sRegLow) ||
      oatLiveOut(cUnit, oatSRegHi(rlDest.sRegLow)))) {
    defStart = (LIR*)cUnit->lastLIRInsn;
    DCHECK_EQ((SRegToVReg(cUnit, rlDest.sRegLow)+1),
              SRegToVReg(cUnit, oatSRegHi(rlDest.sRegLow)));
    storeBaseDispWide(cUnit, rSP, oatSRegOffset(cUnit, rlDest.sRegLow),
                      rlDest.lowReg, rlDest.highReg);
    oatMarkClean(cUnit, rlDest);
    defEnd = (LIR*)cUnit->lastLIRInsn;
    oatMarkDefWide(cUnit, rlDest, defStart, defEnd);
  }
}

/*
 * Mark garbage collection card. Skip if the value we're storing is null.
 */
void markGCCard(CompilationUnit* cUnit, int valReg, int tgtAddrReg)
{
  int regCardBase = oatAllocTemp(cUnit);
  int regCardNo = oatAllocTemp(cUnit);
  LIR* branchOver = opCmpImmBranch(cUnit, kCondEq, valReg, 0, NULL);
#if !defined(TARGET_X86)
  loadWordDisp(cUnit, rSELF, Thread::CardTableOffset().Int32Value(),
               regCardBase);
#else
  newLIR2(cUnit, kX86Mov32RT, regCardBase,
          Thread::CardTableOffset().Int32Value());
#endif
  opRegRegImm(cUnit, kOpLsr, regCardNo, tgtAddrReg, GC_CARD_SHIFT);
  storeBaseIndexed(cUnit, regCardBase, regCardNo, regCardBase, 0,
                   kUnsignedByte);
  LIR* target = newLIR0(cUnit, kPseudoTargetLabel);
  branchOver->target = (LIR*)target;
  oatFreeTemp(cUnit, regCardBase);
  oatFreeTemp(cUnit, regCardNo);
}

/* Utilities to load the current Method* */
void loadCurrMethodDirect(CompilationUnit *cUnit, int rTgt)
{
  loadValueDirectFixed(cUnit, cUnit->methodLoc, rTgt);
}

RegLocation loadCurrMethod(CompilationUnit *cUnit)
{
  return loadValue(cUnit, cUnit->methodLoc, kCoreReg);
}

bool methodStarInReg(CompilationUnit* cUnit)
{
   return (cUnit->methodLoc.location == kLocPhysReg);
}


}  // namespace art
