/*
 * Copyright (c) 2003-2005 The Regents of The University of Michigan
 * 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.
 */

/**
 * @file
 * Defines global host-dependent types:
 * Counter, Tick, and (indirectly) {int,uint}{8,16,32,64}_t.
 */

#ifndef __BASE_TYPES_HH__
#define __BASE_TYPES_HH__

#include <inttypes.h>

#include <cassert>
#include <memory>
#include <ostream>
#include <stdexcept>

#include "base/refcnt.hh"
/* Hide the fact that this enum is generated by Python */
#include "enums/ByteOrder.hh"

/** uint64_t constant */
#define ULL(N)          ((uint64_t)N##ULL)
/** int64_t constant */
#define LL(N)           ((int64_t)N##LL)

/** Statistics counter type.  Not much excuse for not using a 64-bit
 * integer here, but if you're desperate and only run short
 * simulations you could make this 32 bits.
 */
typedef int64_t Counter;

/**
 * Tick count type.
 */
typedef uint64_t Tick;

const Tick MaxTick = ULL(0xffffffffffffffff);

/**
 * Cycles is a wrapper class for representing cycle counts, i.e. a
 * relative difference between two points in time, expressed in a
 * number of clock cycles.
 *
 * The Cycles wrapper class is a type-safe alternative to a
 * typedef, aiming to avoid unintentional mixing of cycles and ticks
 * in the code base.
 *
 * Note that there is no overloading of the bool operator as the
 * compiler is allowed to turn booleans into integers and this causes
 * a whole range of issues in a handful locations. The solution to
 * this problem would be to use the safe bool idiom, but for now we
 * make do without the test and use the more elaborate comparison >
 * Cycles(0).
 */
class Cycles
{

  private:

    /** Member holding the actual value. */
    uint64_t c;

  public:

    /** Explicit constructor assigning a value. */
    explicit constexpr Cycles(uint64_t _c) : c(_c) { }

    /** Default constructor for parameter classes. */
    Cycles() : c(0) { }

    /** Converting back to the value type. */
    constexpr operator uint64_t() const { return c; }

    /** Prefix increment operator. */
    Cycles& operator++()
    { ++c; return *this; }

    /** Prefix decrement operator. Is only temporarily used in the O3 CPU. */
    Cycles& operator--()
    { assert(c != 0); --c; return *this; }

    /** In-place addition of cycles. */
    Cycles& operator+=(const Cycles& cc)
    { c += cc.c; return *this; }

    /** Greater than comparison used for > Cycles(0). */
    constexpr bool operator>(const Cycles& cc) const
    { return c > cc.c; }

    constexpr Cycles operator +(const Cycles& b) const
    { return Cycles(c + b.c); }

    constexpr Cycles operator -(const Cycles& b) const
    {
        return c >= b.c ? Cycles(c - b.c) :
            throw std::invalid_argument("RHS cycle value larger than LHS");
    }

    constexpr Cycles operator <<(const int32_t shift) const
    { return Cycles(c << shift); }

    constexpr Cycles operator >>(const int32_t shift) const
    { return Cycles(c >> shift); }

    friend std::ostream& operator<<(std::ostream &out, const Cycles & cycles);
};

/**
 * Address type
 * This will probably be moved somewhere else in the near future.
 * This should be at least as big as the biggest address width in use
 * in the system, which will probably be 64 bits.
 */
typedef uint64_t Addr;

typedef uint16_t MicroPC;

static const MicroPC MicroPCRomBit = 1 << (sizeof(MicroPC) * 8 - 1);

static inline MicroPC
romMicroPC(MicroPC upc)
{
    return upc | MicroPCRomBit;
}

static inline MicroPC
normalMicroPC(MicroPC upc)
{
    return upc & ~MicroPCRomBit;
}

static inline bool
isRomMicroPC(MicroPC upc)
{
    return MicroPCRomBit & upc;
}

const Addr MaxAddr = (Addr)-1;

typedef uint64_t RegVal;

static inline uint32_t
floatToBits32(float val)
{
    union
    {
        float f;
        uint32_t i;
    } u;
    u.f = val;
    return u.i;
}

static inline uint64_t
floatToBits64(double val)
{
    union
    {
        double f;
        uint64_t i;
    } u;
    u.f = val;
    return u.i;
}

static inline uint64_t floatToBits(double val) { return floatToBits64(val); }
static inline uint32_t floatToBits(float val) { return floatToBits32(val); }

static inline float
bitsToFloat32(uint32_t val)
{
    union
    {
        float f;
        uint32_t i;
    } u;
    u.i = val;
    return u.f;
}

static inline double
bitsToFloat64(uint64_t val)
{
    union
    {
        double f;
        uint64_t i;
    } u;
    u.i = val;
    return u.f;
}

static inline double bitsToFloat(uint64_t val) { return bitsToFloat64(val); }
static inline float bitsToFloat(uint32_t val) { return bitsToFloat32(val); }

/**
 * Thread index/ID type
 */
typedef int16_t ThreadID;
const ThreadID InvalidThreadID = (ThreadID)-1;

/** Globally unique thread context ID */
typedef int ContextID;
const ContextID InvalidContextID = (ContextID)-1;

/**
 * Port index/ID type, and a symbolic name for an invalid port id.
 */
typedef int16_t PortID;
const PortID InvalidPortID = (PortID)-1;

class FaultBase;
typedef std::shared_ptr<FaultBase> Fault;

// Rather than creating a shared_ptr instance and assigning it nullptr,
// we just create an alias.
constexpr decltype(nullptr) NoFault = nullptr;

#endif // __BASE_TYPES_HH__
