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

#include "Dalvik.h"
#include "CompilerInternals.h"

namespace art {

static const char* gOpKindNames[kOpInvalid + 1] = {
  "OpMov",
  "OpMvn",
  "OpCmp",
  "OpLsl",
  "OpLsr",
  "OpAsr",
  "OpRor",
  "OpNot",
  "OpAnd",
  "OpOr",
  "OpXor",
  "OpNeg",
  "OpAdd",
  "OpAdc",
  "OpSub",
  "OpSbc",
  "OpRsub",
  "OpMul",
  "OpDiv",
  "OpRem",
  "OpBic",
  "OpCmn",
  "OpTst",
  "OpBkpt",
  "OpBlx",
  "OpPush",
  "OpPop",
  "Op2Char",
  "Op2Short",
  "Op2Byte",
  "OpCondBr",
  "OpUncondBr",
  "OpBx",
  "OpInvalid",
};

std::ostream& operator<<(std::ostream& os, const OpKind& kind) {
  if (kind >= kOpMov && kind <= kOpInvalid) {
    os << gOpKindNames[kind];
  } else {
    os << "Unknown Op " << static_cast<int>(kind);
  }
  return os;
}

/* Allocate a new basic block */
BasicBlock* oatNewBB(CompilationUnit* cUnit, BBType blockType, int blockId)
{
  BasicBlock* bb = (BasicBlock* )oatNew(cUnit, sizeof(BasicBlock), true,
                                        kAllocBB);
  bb->blockType = blockType;
  bb->id = blockId;
  bb->predecessors = (GrowableList*) oatNew(cUnit, sizeof(GrowableList),
                                            false, kAllocPredecessors);
  oatInitGrowableList(cUnit, bb->predecessors,
                      (blockType == kExitBlock) ? 2048 : 2,
                      kListPredecessors);
  return bb;
}

/* Insert an MIR instruction to the end of a basic block */
void oatAppendMIR(BasicBlock* bb, MIR* mir)
{
  if (bb->firstMIRInsn == NULL) {
    DCHECK(bb->lastMIRInsn == NULL);
    bb->lastMIRInsn = bb->firstMIRInsn = mir;
    mir->prev = mir->next = NULL;
  } else {
    bb->lastMIRInsn->next = mir;
    mir->prev = bb->lastMIRInsn;
    mir->next = NULL;
    bb->lastMIRInsn = mir;
  }
}

/* Insert an MIR instruction to the head of a basic block */
void oatPrependMIR(BasicBlock* bb, MIR* mir)
{
  if (bb->firstMIRInsn == NULL) {
    DCHECK(bb->lastMIRInsn == NULL);
    bb->lastMIRInsn = bb->firstMIRInsn = mir;
    mir->prev = mir->next = NULL;
  } else {
    bb->firstMIRInsn->prev = mir;
    mir->next = bb->firstMIRInsn;
    mir->prev = NULL;
    bb->firstMIRInsn = mir;
  }
}

/* Insert a MIR instruction after the specified MIR */
void oatInsertMIRAfter(BasicBlock* bb, MIR* currentMIR, MIR* newMIR)
{
  newMIR->prev = currentMIR;
  newMIR->next = currentMIR->next;
  currentMIR->next = newMIR;

  if (newMIR->next) {
    /* Is not the last MIR in the block */
    newMIR->next->prev = newMIR;
  } else {
    /* Is the last MIR in the block */
    bb->lastMIRInsn = newMIR;
  }
}

/*
 * Append an LIR instruction to the LIR list maintained by a compilation
 * unit
 */
void oatAppendLIR(CompilationUnit *cUnit, LIR* lir)
{
  if (cUnit->firstLIRInsn == NULL) {
    DCHECK(cUnit->lastLIRInsn == NULL);
     cUnit->lastLIRInsn = cUnit->firstLIRInsn = lir;
    lir->prev = lir->next = NULL;
  } else {
    cUnit->lastLIRInsn->next = lir;
    lir->prev = cUnit->lastLIRInsn;
    lir->next = NULL;
    cUnit->lastLIRInsn = lir;
  }
}

/*
 * Insert an LIR instruction before the current instruction, which cannot be the
 * first instruction.
 *
 * prevLIR <-> newLIR <-> currentLIR
 */
void oatInsertLIRBefore(LIR* currentLIR, LIR* newLIR)
{
  DCHECK(currentLIR->prev != NULL);
  LIR *prevLIR = currentLIR->prev;

  prevLIR->next = newLIR;
  newLIR->prev = prevLIR;
  newLIR->next = currentLIR;
  currentLIR->prev = newLIR;
}

/*
 * Insert an LIR instruction after the current instruction, which cannot be the
 * first instruction.
 *
 * currentLIR -> newLIR -> oldNext
 */
void oatInsertLIRAfter(LIR* currentLIR, LIR* newLIR)
{
  newLIR->prev = currentLIR;
  newLIR->next = currentLIR->next;
  currentLIR->next = newLIR;
  newLIR->next->prev = newLIR;
}

}  // namespace art
