12SN/A/*
21762SN/A * Copyright (c) 2003-2005 The Regents of The University of Michigan
32SN/A * All rights reserved.
42SN/A *
52SN/A * Redistribution and use in source and binary forms, with or without
62SN/A * modification, are permitted provided that the following conditions are
72SN/A * met: redistributions of source code must retain the above copyright
82SN/A * notice, this list of conditions and the following disclaimer;
92SN/A * redistributions in binary form must reproduce the above copyright
102SN/A * notice, this list of conditions and the following disclaimer in the
112SN/A * documentation and/or other materials provided with the distribution;
122SN/A * neither the name of the copyright holders nor the names of its
132SN/A * contributors may be used to endorse or promote products derived from
142SN/A * this software without specific prior written permission.
152SN/A *
162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665SN/A *
282665SN/A * Authors: Nathan Binkert
292SN/A */
302SN/A
312SN/A/**
322SN/A * @file
336214Snate@binkert.org * Defines global host-dependent types:
342SN/A * Counter, Tick, and (indirectly) {int,uint}{8,16,32,64}_t.
352SN/A */
362SN/A
376214Snate@binkert.org#ifndef __BASE_TYPES_HH__
386214Snate@binkert.org#define __BASE_TYPES_HH__
392SN/A
402SN/A#include <inttypes.h>
412SN/A
429180Sandreas.hansson@arm.com#include <cassert>
4310474Sandreas.hansson@arm.com#include <memory>
449500Snilay@cs.wisc.edu#include <ostream>
4511004SAndreas.Sandberg@ARM.com#include <stdexcept>
469180Sandreas.hansson@arm.com
4710276SAndreas.Sandberg@ARM.com#include "base/refcnt.hh"
4810276SAndreas.Sandberg@ARM.com
492SN/A/** uint64_t constant */
505543SN/A#define ULL(N)          ((uint64_t)N##ULL)
512SN/A/** int64_t constant */
525543SN/A#define LL(N)           ((int64_t)N##LL)
532SN/A
542SN/A/** Statistics counter type.  Not much excuse for not using a 64-bit
552SN/A * integer here, but if you're desperate and only run short
562SN/A * simulations you could make this 32 bits.
572SN/A */
582SN/Atypedef int64_t Counter;
592SN/A
602SN/A/**
619158Sandreas.hansson@arm.com * Tick count type.
622SN/A */
639158Sandreas.hansson@arm.comtypedef uint64_t Tick;
642SN/A
659158Sandreas.hansson@arm.comconst Tick MaxTick = ULL(0xffffffffffffffff);
662667SN/A
672130SN/A/**
689180Sandreas.hansson@arm.com * Cycles is a wrapper class for representing cycle counts, i.e. a
699180Sandreas.hansson@arm.com * relative difference between two points in time, expressed in a
709180Sandreas.hansson@arm.com * number of clock cycles.
719180Sandreas.hansson@arm.com *
729180Sandreas.hansson@arm.com * The Cycles wrapper class is a type-safe alternative to a
739180Sandreas.hansson@arm.com * typedef, aiming to avoid unintentional mixing of cycles and ticks
749180Sandreas.hansson@arm.com * in the code base.
759180Sandreas.hansson@arm.com *
7611990Sandreas.sandberg@arm.com * Note that there is no overloading of the bool operator as the
779180Sandreas.hansson@arm.com * compiler is allowed to turn booleans into integers and this causes
789180Sandreas.hansson@arm.com * a whole range of issues in a handful locations. The solution to
799180Sandreas.hansson@arm.com * this problem would be to use the safe bool idiom, but for now we
809180Sandreas.hansson@arm.com * make do without the test and use the more elaborate comparison >
819180Sandreas.hansson@arm.com * Cycles(0).
829180Sandreas.hansson@arm.com */
839180Sandreas.hansson@arm.comclass Cycles
849180Sandreas.hansson@arm.com{
859180Sandreas.hansson@arm.com
869180Sandreas.hansson@arm.com  private:
879180Sandreas.hansson@arm.com
889180Sandreas.hansson@arm.com    /** Member holding the actual value. */
899180Sandreas.hansson@arm.com    uint64_t c;
909180Sandreas.hansson@arm.com
919180Sandreas.hansson@arm.com  public:
929180Sandreas.hansson@arm.com
939180Sandreas.hansson@arm.com    /** Explicit constructor assigning a value. */
9411004SAndreas.Sandberg@ARM.com    explicit constexpr Cycles(uint64_t _c) : c(_c) { }
959180Sandreas.hansson@arm.com
969184Sandreas.hansson@arm.com    /** Default constructor for parameter classes. */
979184Sandreas.hansson@arm.com    Cycles() : c(0) { }
989184Sandreas.hansson@arm.com
999180Sandreas.hansson@arm.com    /** Converting back to the value type. */
10011004SAndreas.Sandberg@ARM.com    constexpr operator uint64_t() const { return c; }
1019180Sandreas.hansson@arm.com
1029180Sandreas.hansson@arm.com    /** Prefix increment operator. */
1039180Sandreas.hansson@arm.com    Cycles& operator++()
1049180Sandreas.hansson@arm.com    { ++c; return *this; }
1059180Sandreas.hansson@arm.com
1069180Sandreas.hansson@arm.com    /** Prefix decrement operator. Is only temporarily used in the O3 CPU. */
1079180Sandreas.hansson@arm.com    Cycles& operator--()
1089180Sandreas.hansson@arm.com    { assert(c != 0); --c; return *this; }
1099180Sandreas.hansson@arm.com
1109180Sandreas.hansson@arm.com    /** In-place addition of cycles. */
11111004SAndreas.Sandberg@ARM.com    Cycles& operator+=(const Cycles& cc)
1129180Sandreas.hansson@arm.com    { c += cc.c; return *this; }
1139180Sandreas.hansson@arm.com
1149180Sandreas.hansson@arm.com    /** Greater than comparison used for > Cycles(0). */
11511004SAndreas.Sandberg@ARM.com    constexpr bool operator>(const Cycles& cc) const
1169180Sandreas.hansson@arm.com    { return c > cc.c; }
1179180Sandreas.hansson@arm.com
11811004SAndreas.Sandberg@ARM.com    constexpr Cycles operator +(const Cycles& b) const
1199498Snilay@cs.wisc.edu    { return Cycles(c + b.c); }
1209498Snilay@cs.wisc.edu
12111004SAndreas.Sandberg@ARM.com    constexpr Cycles operator -(const Cycles& b) const
12211004SAndreas.Sandberg@ARM.com    {
12311004SAndreas.Sandberg@ARM.com        return c >= b.c ? Cycles(c - b.c) :
12411004SAndreas.Sandberg@ARM.com            throw std::invalid_argument("RHS cycle value larger than LHS");
12511004SAndreas.Sandberg@ARM.com    }
1269498Snilay@cs.wisc.edu
12711004SAndreas.Sandberg@ARM.com    constexpr Cycles operator <<(const int32_t shift) const
1289498Snilay@cs.wisc.edu    { return Cycles(c << shift); }
1299498Snilay@cs.wisc.edu
13011004SAndreas.Sandberg@ARM.com    constexpr Cycles operator >>(const int32_t shift) const
1319498Snilay@cs.wisc.edu    { return Cycles(c >> shift); }
1329498Snilay@cs.wisc.edu
1339500Snilay@cs.wisc.edu    friend std::ostream& operator<<(std::ostream &out, const Cycles & cycles);
1349180Sandreas.hansson@arm.com};
1359180Sandreas.hansson@arm.com
1369180Sandreas.hansson@arm.com/**
1372130SN/A * Address type
1382130SN/A * This will probably be moved somewhere else in the near future.
1392130SN/A * This should be at least as big as the biggest address width in use
1402130SN/A * in the system, which will probably be 64 bits.
1412130SN/A */
1422130SN/Atypedef uint64_t Addr;
1432130SN/A
1447720Sgblack@eecs.umich.edutypedef uint16_t MicroPC;
1457720Sgblack@eecs.umich.edu
1467720Sgblack@eecs.umich.edustatic const MicroPC MicroPCRomBit = 1 << (sizeof(MicroPC) * 8 - 1);
1477720Sgblack@eecs.umich.edu
1487720Sgblack@eecs.umich.edustatic inline MicroPC
1497720Sgblack@eecs.umich.eduromMicroPC(MicroPC upc)
1507720Sgblack@eecs.umich.edu{
1517720Sgblack@eecs.umich.edu    return upc | MicroPCRomBit;
1527720Sgblack@eecs.umich.edu}
1537720Sgblack@eecs.umich.edu
1547720Sgblack@eecs.umich.edustatic inline MicroPC
1557720Sgblack@eecs.umich.edunormalMicroPC(MicroPC upc)
1567720Sgblack@eecs.umich.edu{
1577720Sgblack@eecs.umich.edu    return upc & ~MicroPCRomBit;
1587720Sgblack@eecs.umich.edu}
1597720Sgblack@eecs.umich.edu
1607720Sgblack@eecs.umich.edustatic inline bool
1617720Sgblack@eecs.umich.eduisRomMicroPC(MicroPC upc)
1627720Sgblack@eecs.umich.edu{
1637720Sgblack@eecs.umich.edu    return MicroPCRomBit & upc;
1647720Sgblack@eecs.umich.edu}
1657720Sgblack@eecs.umich.edu
1662438SN/Aconst Addr MaxAddr = (Addr)-1;
1672438SN/A
16813385Sgabeblack@google.comtypedef uint64_t RegVal;
16913385Sgabeblack@google.com
17013446Sgabeblack@google.comstatic inline uint32_t
17113446Sgabeblack@google.comfloatToBits32(float val)
17213446Sgabeblack@google.com{
17313446Sgabeblack@google.com    union
17413446Sgabeblack@google.com    {
17513446Sgabeblack@google.com        float f;
17613446Sgabeblack@google.com        uint32_t i;
17713446Sgabeblack@google.com    } u;
17813446Sgabeblack@google.com    u.f = val;
17913446Sgabeblack@google.com    return u.i;
18013446Sgabeblack@google.com}
18113446Sgabeblack@google.com
18213446Sgabeblack@google.comstatic inline uint64_t
18313446Sgabeblack@google.comfloatToBits64(double val)
18413446Sgabeblack@google.com{
18513446Sgabeblack@google.com    union
18613446Sgabeblack@google.com    {
18713446Sgabeblack@google.com        double f;
18813446Sgabeblack@google.com        uint64_t i;
18913446Sgabeblack@google.com    } u;
19013446Sgabeblack@google.com    u.f = val;
19113446Sgabeblack@google.com    return u.i;
19213446Sgabeblack@google.com}
19313446Sgabeblack@google.com
19413446Sgabeblack@google.comstatic inline uint64_t floatToBits(double val) { return floatToBits64(val); }
19513446Sgabeblack@google.comstatic inline uint32_t floatToBits(float val) { return floatToBits32(val); }
19613446Sgabeblack@google.com
19713446Sgabeblack@google.comstatic inline float
19813446Sgabeblack@google.combitsToFloat32(uint32_t val)
19913446Sgabeblack@google.com{
20013446Sgabeblack@google.com    union
20113446Sgabeblack@google.com    {
20213446Sgabeblack@google.com        float f;
20313446Sgabeblack@google.com        uint32_t i;
20413446Sgabeblack@google.com    } u;
20513446Sgabeblack@google.com    u.i = val;
20613446Sgabeblack@google.com    return u.f;
20713446Sgabeblack@google.com}
20813446Sgabeblack@google.com
20913446Sgabeblack@google.comstatic inline double
21013446Sgabeblack@google.combitsToFloat64(uint64_t val)
21113446Sgabeblack@google.com{
21213446Sgabeblack@google.com    union
21313446Sgabeblack@google.com    {
21413446Sgabeblack@google.com        double f;
21513446Sgabeblack@google.com        uint64_t i;
21613446Sgabeblack@google.com    } u;
21713446Sgabeblack@google.com    u.i = val;
21813446Sgabeblack@google.com    return u.f;
21913446Sgabeblack@google.com}
22013446Sgabeblack@google.com
22113446Sgabeblack@google.comstatic inline double bitsToFloat(uint64_t val) { return bitsToFloat64(val); }
22213446Sgabeblack@google.comstatic inline float bitsToFloat(uint32_t val) { return bitsToFloat32(val); }
22313446Sgabeblack@google.com
2246221Snate@binkert.org/**
2256221Snate@binkert.org * Thread index/ID type
2266221Snate@binkert.org */
2276221Snate@binkert.orgtypedef int16_t ThreadID;
2286221Snate@binkert.orgconst ThreadID InvalidThreadID = (ThreadID)-1;
2296221Snate@binkert.org
23011005Sandreas.sandberg@arm.com/** Globally unique thread context ID */
23111005Sandreas.sandberg@arm.comtypedef int ContextID;
23211005Sandreas.sandberg@arm.comconst ContextID InvalidContextID = (ContextID)-1;
23311005Sandreas.sandberg@arm.com
2349031Sandreas.hansson@arm.com/**
2359031Sandreas.hansson@arm.com * Port index/ID type, and a symbolic name for an invalid port id.
2369031Sandreas.hansson@arm.com */
2379031Sandreas.hansson@arm.comtypedef int16_t PortID;
2389031Sandreas.hansson@arm.comconst PortID InvalidPortID = (PortID)-1;
2399031Sandreas.hansson@arm.com
2407678Sgblack@eecs.umich.educlass FaultBase;
24110474Sandreas.hansson@arm.comtypedef std::shared_ptr<FaultBase> Fault;
24210474Sandreas.hansson@arm.com
24310474Sandreas.hansson@arm.com// Rather than creating a shared_ptr instance and assigning it nullptr,
24410474Sandreas.hansson@arm.com// we just create an alias.
24510474Sandreas.hansson@arm.comconstexpr decltype(nullptr) NoFault = nullptr;
2467678Sgblack@eecs.umich.edu
24711306Santhony.gutierrez@amd.comstruct AtomicOpFunctor
24811306Santhony.gutierrez@amd.com{
24911306Santhony.gutierrez@amd.com    virtual void operator()(uint8_t *p) = 0;
25012766Sqtt2@cornell.edu    virtual AtomicOpFunctor* clone() = 0;
25111306Santhony.gutierrez@amd.com    virtual ~AtomicOpFunctor() {}
25211306Santhony.gutierrez@amd.com};
25311306Santhony.gutierrez@amd.com
25411306Santhony.gutierrez@amd.comtemplate <class T>
25511306Santhony.gutierrez@amd.comstruct TypedAtomicOpFunctor : public AtomicOpFunctor
25611306Santhony.gutierrez@amd.com{
25711306Santhony.gutierrez@amd.com    void operator()(uint8_t *p) { execute((T *)p); }
25812766Sqtt2@cornell.edu    virtual AtomicOpFunctor* clone() = 0;
25911306Santhony.gutierrez@amd.com    virtual void execute(T * p) = 0;
26011306Santhony.gutierrez@amd.com};
26111306Santhony.gutierrez@amd.com
26214297Sjordi.vaquero@metempsy.comtypedef std::unique_ptr<AtomicOpFunctor> AtomicOpFunctorPtr;
26314297Sjordi.vaquero@metempsy.com
26410839Sandreas.sandberg@arm.comenum ByteOrder {
26510839Sandreas.sandberg@arm.com    BigEndianByteOrder,
26610839Sandreas.sandberg@arm.com    LittleEndianByteOrder
26710839Sandreas.sandberg@arm.com};
26810839Sandreas.sandberg@arm.com
2696214Snate@binkert.org#endif // __BASE_TYPES_HH__
270