/*
 * Copyright (c) 2010 Gabe Black
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Gabe Black
 */

#ifndef __ARCH_GENERIC_TYPES_HH__
#define __ARCH_GENERIC_TYPES_HH__

#include <iostream>
#include <limits>

#include "base/trace.hh"
#include "base/types.hh"
#include "sim/serialize.hh"

// Logical register index type.
typedef uint16_t RegIndex;

/** Logical vector register elem index type. */
using ElemIndex = uint16_t;

/** ElemIndex value that indicates that the register is not a vector. */
#define ILLEGAL_ELEM_INDEX std::numeric_limits<ElemIndex>::max()

namespace GenericISA
{

// The guaranteed interface.
class PCStateBase : public Serializable
{
  protected:
    Addr _pc;
    Addr _npc;

    PCStateBase() : _pc(0), _npc(0) {}
    PCStateBase(Addr val) : _pc(0), _npc(0) { set(val); }

  public:
    /**
     * Returns the memory address the bytes of this instruction came from.
     *
     * @return Memory address of the current instruction's encoding.
     */
    Addr
    instAddr() const
    {
        return _pc;
    }

    /**
     * Returns the memory address the bytes of the next instruction came from.
     *
     * @return Memory address of the next instruction's encoding.
     */
    Addr
    nextInstAddr() const
    {
        return _npc;
    }

    /**
     * Returns the current micropc.
     *
     * @return The current micropc.
     */
    MicroPC
    microPC() const
    {
        return 0;
    }

    /**
     * Force this PC to reflect a particular value, resetting all its other
     * fields around it. This is useful for in place (re)initialization.
     *
     * @param val The value to set the PC to.
     */
    void set(Addr val);

    bool
    operator == (const PCStateBase &opc) const
    {
        return _pc == opc._pc && _npc == opc._npc;
    }

    bool
    operator != (const PCStateBase &opc) const
    {
        return !(*this == opc);
    }

    void
    serialize(CheckpointOut &cp) const override
    {
        SERIALIZE_SCALAR(_pc);
        SERIALIZE_SCALAR(_npc);
    }

    void
    unserialize(CheckpointIn &cp) override
    {
        UNSERIALIZE_SCALAR(_pc);
        UNSERIALIZE_SCALAR(_npc);
    }
};


/*
 * Different flavors of PC state. Only ISA specific code should rely on
 * any particular type of PC state being available. All other code should
 * use the interface above.
 */

// The most basic type of PC.
template <class MachInst>
class SimplePCState : public PCStateBase
{
  protected:
    typedef PCStateBase Base;

  public:

    Addr pc() const { return _pc; }
    void pc(Addr val) { _pc = val; }

    Addr npc() const { return _npc; }
    void npc(Addr val) { _npc = val; }

    void
    set(Addr val)
    {
        pc(val);
        npc(val + sizeof(MachInst));
    };

    void
    setNPC(Addr val)
    {
        npc(val);
    }

    SimplePCState() {}
    SimplePCState(Addr val) { set(val); }

    bool
    branching() const
    {
        return this->npc() != this->pc() + sizeof(MachInst);
    }

    // Advance the PC.
    void
    advance()
    {
        _pc = _npc;
        _npc += sizeof(MachInst);
    }
};

template <class MachInst>
std::ostream &
operator<<(std::ostream & os, const SimplePCState<MachInst> &pc)
{
    ccprintf(os, "(%#x=>%#x)", pc.pc(), pc.npc());
    return os;
}

// A PC and microcode PC.
template <class MachInst>
class UPCState : public SimplePCState<MachInst>
{
  protected:
    typedef SimplePCState<MachInst> Base;

    MicroPC _upc;
    MicroPC _nupc;

  public:

    MicroPC upc() const { return _upc; }
    void upc(MicroPC val) { _upc = val; }

    MicroPC nupc() const { return _nupc; }
    void nupc(MicroPC val) { _nupc = val; }

    MicroPC
    microPC() const
    {
        return _upc;
    }

    void
    set(Addr val)
    {
        Base::set(val);
        upc(0);
        nupc(1);
    }

    UPCState() : _upc(0), _nupc(0) {}
    UPCState(Addr val) : _upc(0), _nupc(0) { set(val); }

    bool
    branching() const
    {
        return this->npc() != this->pc() + sizeof(MachInst) ||
               this->nupc() != this->upc() + 1;
    }

    // Advance the upc within the instruction.
    void
    uAdvance()
    {
        _upc = _nupc;
        _nupc++;
    }

    // End the macroop by resetting the upc and advancing the regular pc.
    void
    uEnd()
    {
        this->advance();
        _upc = 0;
        _nupc = 1;
    }

    bool
    operator == (const UPCState<MachInst> &opc) const
    {
        return Base::_pc == opc._pc &&
               Base::_npc == opc._npc &&
               _upc == opc._upc && _nupc == opc._nupc;
    }

    bool
    operator != (const UPCState<MachInst> &opc) const
    {
        return !(*this == opc);
    }

    void
    serialize(CheckpointOut &cp) const override
    {
        Base::serialize(cp);
        SERIALIZE_SCALAR(_upc);
        SERIALIZE_SCALAR(_nupc);
    }

    void
    unserialize(CheckpointIn &cp) override
    {
        Base::unserialize(cp);
        UNSERIALIZE_SCALAR(_upc);
        UNSERIALIZE_SCALAR(_nupc);
    }
};

template <class MachInst>
std::ostream &
operator<<(std::ostream & os, const UPCState<MachInst> &pc)
{
    ccprintf(os, "(%#x=>%#x).(%d=>%d)",
            pc.pc(), pc.npc(), pc.upc(), pc.nupc());
    return os;
}

// A PC with a delay slot.
template <class MachInst>
class DelaySlotPCState : public SimplePCState<MachInst>
{
  protected:
    typedef SimplePCState<MachInst> Base;

    Addr _nnpc;

  public:

    Addr nnpc() const { return _nnpc; }
    void nnpc(Addr val) { _nnpc = val; }

    void
    set(Addr val)
    {
        Base::set(val);
        nnpc(val + 2 * sizeof(MachInst));
    }

    DelaySlotPCState() {}
    DelaySlotPCState(Addr val) { set(val); }

    bool
    branching() const
    {
        return !(this->nnpc() == this->npc() + sizeof(MachInst) &&
                 (this->npc() == this->pc() + sizeof(MachInst) ||
                  this->npc() == this->pc() + 2 * sizeof(MachInst)));
    }

    // Advance the PC.
    void
    advance()
    {
        Base::_pc = Base::_npc;
        Base::_npc = _nnpc;
        _nnpc += sizeof(MachInst);
    }

    bool
    operator == (const DelaySlotPCState<MachInst> &opc) const
    {
        return Base::_pc == opc._pc &&
               Base::_npc == opc._npc &&
               _nnpc == opc._nnpc;
    }

    bool
    operator != (const DelaySlotPCState<MachInst> &opc) const
    {
        return !(*this == opc);
    }

    void
    serialize(CheckpointOut &cp) const override
    {
        Base::serialize(cp);
        SERIALIZE_SCALAR(_nnpc);
    }

    void
    unserialize(CheckpointIn &cp) override
    {
        Base::unserialize(cp);
        UNSERIALIZE_SCALAR(_nnpc);
    }
};

template <class MachInst>
std::ostream &
operator<<(std::ostream & os, const DelaySlotPCState<MachInst> &pc)
{
    ccprintf(os, "(%#x=>%#x=>%#x)",
            pc.pc(), pc.npc(), pc.nnpc());
    return os;
}

// A PC with a delay slot and a microcode PC.
template <class MachInst>
class DelaySlotUPCState : public DelaySlotPCState<MachInst>
{
  protected:
    typedef DelaySlotPCState<MachInst> Base;

    MicroPC _upc;
    MicroPC _nupc;

  public:

    MicroPC upc() const { return _upc; }
    void upc(MicroPC val) { _upc = val; }

    MicroPC nupc() const { return _nupc; }
    void nupc(MicroPC val) { _nupc = val; }

    MicroPC
    microPC() const
    {
        return _upc;
    }

    void
    set(Addr val)
    {
        Base::set(val);
        upc(0);
        nupc(1);
    }

    DelaySlotUPCState() {}
    DelaySlotUPCState(Addr val) { set(val); }

    bool
    branching() const
    {
        return Base::branching() || this->nupc() != this->upc() + 1;
    }

    // Advance the upc within the instruction.
    void
    uAdvance()
    {
        _upc = _nupc;
        _nupc++;
    }

    // End the macroop by resetting the upc and advancing the regular pc.
    void
    uEnd()
    {
        this->advance();
        _upc = 0;
        _nupc = 1;
    }

    bool
    operator == (const DelaySlotUPCState<MachInst> &opc) const
    {
        return Base::_pc == opc._pc &&
               Base::_npc == opc._npc &&
               Base::_nnpc == opc._nnpc &&
               _upc == opc._upc && _nupc == opc._nupc;
    }

    bool
    operator != (const DelaySlotUPCState<MachInst> &opc) const
    {
        return !(*this == opc);
    }

    void
    serialize(CheckpointOut &cp) const override
    {
        Base::serialize(cp);
        SERIALIZE_SCALAR(_upc);
        SERIALIZE_SCALAR(_nupc);
    }

    void
    unserialize(CheckpointIn &cp) override
    {
        Base::unserialize(cp);
        UNSERIALIZE_SCALAR(_upc);
        UNSERIALIZE_SCALAR(_nupc);
    }
};

template <class MachInst>
std::ostream &
operator<<(std::ostream & os, const DelaySlotUPCState<MachInst> &pc)
{
    ccprintf(os, "(%#x=>%#x=>%#x).(%d=>%d)",
            pc.pc(), pc.npc(), pc.nnpc(), pc.upc(), pc.nupc());
    return os;
}

}

#endif
