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