/*
 * 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 <limits>
#include <memory>
#include <ostream>
#include <stdexcept>

namespace gem5
{

/** 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 = 0xffffffffffffffffULL;

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

using RegVal = uint64_t;

// Logical register index type.
using RegIndex = uint16_t;

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

/** ElemIndex value that indicates that the register is not a vector. */
static const ElemIndex IllegalElemIndex =
    std::numeric_limits<ElemIndex>::max();

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;

} // namespace gem5

#endif // __BASE_TYPES_HH__
