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

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__
