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