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