/*
 * 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 x86-specific codegen factory support.
 * It is included by
 *
 *        Codegen-$(TARGET_ARCH_VARIANT).c
 *
 */

namespace art {

bool genAddLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
                RegLocation rlSrc1, RegLocation rlSrc2)
{
    UNIMPLEMENTED(WARNING) << "genAddLong";
#if 0
    rlSrc1 = loadValueWide(cUnit, rlSrc1, kCoreReg);
    rlSrc2 = loadValueWide(cUnit, rlSrc2, kCoreReg);
    RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
    /*
     *  [v1 v0] =  [a1 a0] + [a3 a2];
     *    addu v0,a2,a0
     *    addu t1,a3,a1
     *    sltu v1,v0,a2
     *    addu v1,v1,t1
     */

    opRegRegReg(cUnit, kOpAdd, rlResult.lowReg, rlSrc2.lowReg, rlSrc1.lowReg);
    int tReg = oatAllocTemp(cUnit);
    opRegRegReg(cUnit, kOpAdd, tReg, rlSrc2.highReg, rlSrc1.highReg);
    newLIR3(cUnit, kX86Sltu, rlResult.highReg, rlResult.lowReg, rlSrc2.lowReg);
    opRegRegReg(cUnit, kOpAdd, rlResult.highReg, rlResult.highReg, tReg);
    oatFreeTemp(cUnit, tReg);
    storeValueWide(cUnit, rlDest, rlResult);
#endif
    return false;
}

bool genSubLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
                RegLocation rlSrc1, RegLocation rlSrc2)
{
    UNIMPLEMENTED(WARNING) << "genSubLong";
#if 0
    rlSrc1 = loadValueWide(cUnit, rlSrc1, kCoreReg);
    rlSrc2 = loadValueWide(cUnit, rlSrc2, kCoreReg);
    RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
    /*
     *  [v1 v0] =  [a1 a0] - [a3 a2];
     *    subu    v0,a0,a2
     *    subu    v1,a1,a3
     *    sltu    t1,a0,v0
     *    subu    v1,v1,t1
     */

    opRegRegReg(cUnit, kOpSub, rlResult.lowReg, rlSrc1.lowReg, rlSrc2.lowReg);
    opRegRegReg(cUnit, kOpSub, rlResult.highReg, rlSrc1.highReg, rlSrc2.highReg);
    int tReg = oatAllocTemp(cUnit);
    newLIR3(cUnit, kX86Sltu, tReg, rlSrc1.lowReg, rlResult.lowReg);
    opRegRegReg(cUnit, kOpSub, rlResult.highReg, rlResult.highReg, tReg);
    oatFreeTemp(cUnit, tReg);
    storeValueWide(cUnit, rlDest, rlResult);
#endif
    return false;
}

bool genNegLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
                RegLocation rlSrc)
{
    UNIMPLEMENTED(WARNING) << "genNegLong";
#if 0
    rlSrc = loadValueWide(cUnit, rlSrc, kCoreReg);
    RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
    /*
     *  [v1 v0] =  -[a1 a0]
     *    negu    v0,a0
     *    negu    v1,a1
     *    sltu    t1,r_zero
     *    subu    v1,v1,t1
     */

    opRegReg(cUnit, kOpNeg, rlResult.lowReg, rlSrc.lowReg);
    opRegReg(cUnit, kOpNeg, rlResult.highReg, rlSrc.highReg);
    int tReg = oatAllocTemp(cUnit);
    newLIR3(cUnit, kX86Sltu, tReg, r_ZERO, rlResult.lowReg);
    opRegRegReg(cUnit, kOpSub, rlResult.highReg, rlResult.highReg, tReg);
    oatFreeTemp(cUnit, tReg);
    storeValueWide(cUnit, rlDest, rlResult);
#endif
    return false;
}

void genDebuggerUpdate(CompilationUnit* cUnit, int32_t offset);

/*
 * In the Arm code a it is typical to use the link register
 * to hold the target address.  However, for X86 we must
 * ensure that all branch instructions can be restarted if
 * there is a trap in the shadow.  Allocate a temp register.
 */
int loadHelper(CompilationUnit* cUnit, int offset)
{
    UNIMPLEMENTED(WARNING);
    return 0;
#if 0
    int tReg = oatAllocTemp(cUnit);
    loadWordDisp(cUnit, rSELF, offset, tReg);
    return tReg;
#endif
}

void spillCoreRegs(CompilationUnit* cUnit)
{
    if (cUnit->numCoreSpills == 0) {
        return;
    }
    uint32_t mask = cUnit->coreSpillMask;
    int offset = cUnit->frameSize - 4;
    for (int reg = 0; mask; mask >>= 1, reg++) {
        if (mask & 0x1) {
            offset -= 4;
            storeWordDisp(cUnit, rSP, offset, reg);
        }
    }
}

void unSpillCoreRegs(CompilationUnit* cUnit)
{
    if (cUnit->numCoreSpills == 0) {
        return;
    }
    uint32_t mask = cUnit->coreSpillMask;
    int offset = cUnit->frameSize - 4;
    for (int reg = 0; mask; mask >>= 1, reg++) {
        if (mask & 0x1) {
            offset -= 4;
            loadWordDisp(cUnit, rSP, offset, reg);
        }
    }
}

void opRegThreadMem(CompilationUnit* cUnit, OpKind op, int rDest, int threadOffset) {
  X86OpCode opcode = kX86Bkpt;
  switch (op) {
    case kOpCmp: opcode = kX86Cmp32RT;  break;
    default:
      LOG(FATAL) << "Bad opcode: " << op;
      break;
  }
  DCHECK((EncodingMap[opcode].flags & IS_BINARY_OP) != 0);
  newLIR2(cUnit, opcode, rDest, threadOffset);
}

void genEntrySequence(CompilationUnit* cUnit, BasicBlock* bb)
{
    /*
     * On entry, rARG0, rARG1, rARG2 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 no spare temps.
     */
    oatLockTemp(cUnit, rARG0);
    oatLockTemp(cUnit, rARG1);
    oatLockTemp(cUnit, rARG2);

    /* Build frame, return address already on stack */
    opRegImm(cUnit, kOpSub, rSP, cUnit->frameSize - 4);

    /*
     * 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 <
                              Thread::kStackOverflowReservedBytes));
    newLIR0(cUnit, kPseudoMethodEntry);
    /* Spill core callee saves */
    spillCoreRegs(cUnit);
    /* NOTE: promotion of FP regs currently unsupported, thus no FP spill */
    DCHECK_EQ(cUnit->numFPSpills, 0);
    if (!skipOverflowCheck) {
        // cmp rSP, fs:[stack_end_]; jcc throw_launchpad
        LIR* tgt = rawLIR(cUnit, 0, kPseudoThrowTarget, kThrowStackOverflow, 0, 0, 0, 0);
        opRegThreadMem(cUnit, kOpCmp, rSP, Thread::StackEndOffset().Int32Value());
        opCondBranch(cUnit, kCondUlt, tgt);
        // Remember branch target - will process later
        oatInsertGrowableList(cUnit, &cUnit->throwLaunchpads, (intptr_t)tgt);
    }
    /* Spill Method* */
    storeBaseDisp(cUnit, rSP, 0, rARG0, kWord);
    flushIns(cUnit);

    if (cUnit->genDebugger) {
        // Refresh update debugger callout
        UNIMPLEMENTED(WARNING) << "genDebugger";
#if 0
        loadWordDisp(cUnit, rSELF,
                     OFFSETOF_MEMBER(Thread, pUpdateDebuggerFromCode), rSUSPEND);
        genDebuggerUpdate(cUnit, DEBUGGER_METHOD_ENTRY);
#endif
    }

    oatFreeTemp(cUnit, rARG0);
    oatFreeTemp(cUnit, rARG1);
    oatFreeTemp(cUnit, rARG2);
}

void genExitSequence(CompilationUnit* cUnit, BasicBlock* bb) {
  /*
   * In the exit path, rRET0/rRET1 are live - make sure they aren't
   * allocated by the register utilities as temps.
   */
  oatLockTemp(cUnit, rRET0);
  oatLockTemp(cUnit, rRET1);

  newLIR0(cUnit, kPseudoMethodExit);
  /* If we're compiling for the debugger, generate an update callout */
  if (cUnit->genDebugger) {
    genDebuggerUpdate(cUnit, DEBUGGER_METHOD_EXIT);
  }
  unSpillCoreRegs(cUnit);
  /* Remove frame except for return address */
  opRegImm(cUnit, kOpAdd, rSP, cUnit->frameSize - 4);
  newLIR0(cUnit, kX86Ret);
}

/*
 * 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) {
  LIR* thisLIR;

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

    /* Branch to the next instruction */
    if (thisLIR->opcode == kX86Jmp) {
      LIR* nextLIR = thisLIR;

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

        /*
         * Is the branch target the next instruction?
         */
        if (nextLIR == (LIR*) thisLIR->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 = (LIR*) cUnit->lastLIRInsn))
          break;
      }
    }
  }
}


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

    for (i = 0; i < kX86Last; 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();
}

}  // namespace art
