/*
 * 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);
  cUnit->blockIdMap.Put(blockId, blockId);
  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
