The Sparta Modeling Framework
Loading...
Searching...
No Matches
RegisterSet.hpp
1// <RegisterSet> -*- C++ -*-
2
3#pragma once
4
5#include <cstdint>
6#include <iostream>
7#include <ios>
8#include <unordered_map>
9#include <functional>
10#include <memory>
11#include <string>
12#include <utility>
13#include <vector>
14
15#include "sparta/functional/Register.hpp"
16#include "sparta/functional/RegisterBankTable.hpp"
21#include "sparta/functional/ArchData.hpp"
22#include "sparta/utils/StringManager.hpp"
23
24namespace sparta {
25
26class RegisterSet;
27
38{
39public:
53 {
59
66 const char *name;
67
74
80 const char *group;
81
88
93 const char *desc;
94
95 }; // Definition
96
99};
100
101inline bool operator==(const RegisterProxyBase::Definition &a,
103{
104 if (a.id != b.id) {
105 return false;
106 }
107 if (!utils::strcmp_with_null(a.name, b.name)) {
108 return false;
109 }
110 if (a.group_num != b.group_num) {
111 return false;
112 }
113 if (!utils::strcmp_with_null(a.group, b.group)) {
114 return false;
115 }
116 if (a.group_idx != b.group_idx) {
117 return false;
118 }
119 if (!utils::strcmp_with_null(a.desc, b.desc)) {
120 return false;
121 }
122
123 return true;
124}
125
126inline bool operator!=(const RegisterProxyBase::Definition &a,
127 const RegisterProxyBase::Definition &b)
128{
129 return !(a == b);
130}
131
142{
143public:
147 RegisterProxy() = delete;
148
153
157 RegisterProxy(const RegisterProxy &) = delete;
158
164
172 : rs_(*reg.getParentAs<RegisterSet>())
173 , reg_inv_(&reg)
174 , group_num_(Register::GROUP_NUM_NONE)
175 , group_idx_(Register::GROUP_IDX_NONE)
176 , reg_name_(reg.getNamePtr())
177 {
179 reg_inv_ != nullptr,
180 "reg argument of RegisterProxy constructor must not be nullptr")
181 }
182
196 Register::group_num_type group_num,
197 Register::group_idx_type group_idx,
198 const std::string *managed_name)
199 : rs_(rs)
200 , reg_inv_(nullptr)
201 , group_num_(group_num)
202 , group_idx_(group_idx)
203 , reg_name_(managed_name)
204 {
206 "group_num argument of RegisterProxy constructor must not "
207 "be GROUP_NUM_NONE");
209 "group_idx argument of RegisterProxy constructor must not "
210 "be GROUP_IDX_NONE");
211 sparta_assert(reg_name_ != nullptr, "managed_name argument of "
212 "RegisterProxy constructor must not "
213 "be nullptr");
214 sparta_assert(StringManager::getStringManager().isInterned(managed_name),
215 "managed_name argument of RegisterProxy constructor must "
216 "be a string managed by the StringManager singleton");
217 }
218
223 {
224 }
225
229 std::string stringize() const;
230
238
246
251
252private:
256 RegisterSet &rs_;
257
262 RegisterBase *reg_inv_;
263
267 typename RegisterBase::group_num_type group_num_;
268
272 typename RegisterBase::group_idx_type group_idx_;
273
277 const std::string *reg_name_;
278}; // class RegisterProxy
279
419class RegisterSet : public TreeNode
420{
421public:
422
429 static const ArchData::offset_type ARCH_DATA_LINE_SIZE = 512;
430
432 using RegisterVector = typename RegisterBankTable<RegisterBase>::RegisterVector;
433
438 using GroupVector = typename RegisterBankTable<RegisterBase>::RegisterVector;
439
443 typedef std::unordered_map<std::string, std::unique_ptr<RegisterProxy>> RegisterProxyMap;
444
449 typedef std::function<
452 const std::string *name_ptr)>
454
458 template <typename RegisterT>
460 {
461 };
462
478 template <typename RegisterT>
480 const RegisterBase::Definition *defs,
481 const RegisterProxyBase::Definition *proxy_defs,
484 : TreeNode("regs",
487 "Register set")
488 , adata_(this,
490 ArchData::DEFAULT_INITIAL_FILL,
491 ArchData::DEFAULT_INITIAL_FILL_SIZE,
492 false) // Cannot delete lines
493 , cur_bank_fxn_(cbfxn)
494 {
495 (void)tag;
496
497 if(parent){
498 setExpectedParent_(parent);
499 }
500
501 // Add all registers
502 const auto *rdef = defs;
503 if (rdef != nullptr) {
504 while (rdef->name != nullptr) {
505 addRegister_<RegisterT>(rdef);
506 ++rdef;
507 }
508 }
509
510 // Add all proxies
511 const auto *pdef = proxy_defs;
512 if (pdef != nullptr) {
513 while (pdef->name != nullptr) {
514 addProxy_(pdef);
515 ++pdef;
516 }
517 }
518
519 // Perform the layout. At this point, no further registers can be added.
520 adata_.layout();
521
522 if (parent) {
523 parent->addChild(this);
524 }
525 }
526
530 template <typename RegisterT>
532 const RegisterBase::Definition *defs,
534 : RegisterSet(parent, defs, nullptr, nullptr, tag)
535 {
536 // Handled in delegated consturctor
537 }
538
539 template <typename RegisterT = Register>
540 static std::unique_ptr<RegisterSet>
541 create(TreeNode *parent,
542 const RegisterBase::Definition *defs,
543 const RegisterProxyBase::Definition *proxy_defs,
545 {
546 return std::unique_ptr<RegisterSet>(new RegisterSet(
547 parent, defs, proxy_defs, cbfxn, RegisterTypeTag<RegisterT>()));
548 }
549
550 template <typename RegisterT = Register>
551 static std::unique_ptr<RegisterSet>
552 create(TreeNode *parent, const RegisterBase::Definition *defs)
553 {
554 return std::unique_ptr<RegisterSet>(new RegisterSet(
555 parent, defs, RegisterTypeTag<RegisterT>()));
556 }
557
564 {
565 for (auto r : owned_regs_) {
566 delete r;
567 }
568 }
569
573 void reset() {
574 for (uint32_t i=0; i<regs_.size(); i++) {
575 regs_[i]->reset();
576 }
577 }
578
597 banks_.setMinimumBankIndex(min_idx);
598 }
599
603 uint32_t getNumRegisters() const { return regs_.size(); }
604
610 {
611 return banks_.getNumBanks();
612 }
613
618 {
619 return banks_.getNumGroups();
620 }
621
627 const RegisterVector& getRegisters() const { return regs_; }
628
629 // Overload of TreeNode::stringize
630 virtual std::string stringize(bool pretty=false) const override {
631 (void) pretty;
632 std::stringstream ss;
633 ss << '<' << getLocation() << ' ' << regs_.size() << " regs>";
634 return ss.str();
635 }
636
640 void dumpBanks(std::ostream& out) const {
641 banks_.dump(out);
642 }
643
653 RegisterBase *getRegister(const std::string &name)
654 {
655 return getChildAs<RegisterBase>(name);
656 }
657
671 RegisterProxy &getRegisterProxy(const std::string &name)
672 {
673 auto rpi = reg_proxies_.find(name);
674 if(rpi != reg_proxies_.end()){
675 return *(rpi->second.get());
676 }
677 auto r = getChildAs<RegisterBase>(name, false);
678 if(!r){
679 throw SpartaException("Could not get register proxy from ") << getLocation()
680 << " named \"" << name << "\" because there was no existing proxy and no "
681 "register with this name.";
682 }
683 reg_proxies_[name] =
684 typename RegisterProxyMap::mapped_type(new RegisterProxy(*r));
685 return *reg_proxies_[name];
686 }
687
701 RegisterBase::group_idx_type group_idx) const noexcept
702 {
703 return banks_.canLookupRegister(group_num, group_idx, RegisterBase::BANK_IDX_DEFAULT);
704 }
705
714 RegisterBase::bank_idx_type bank_idx) const noexcept
715 {
716 return banks_.canLookupRegister(group_num, group_idx, bank_idx);
717 }
718
751 {
752 const auto &rm = banks_[RegisterBase::BANK_IDX_DEFAULT][group_num];
753 const auto idx_count = rm.count(group_idx);
754 if (idx_count==1) {
755 sparta_assert(rm.at(group_idx) != nullptr);
756 }
757 return (idx_count==1 ? rm.at(group_idx) : nullptr);
758 }
759
769 {
770 const auto &rm = banks_[bank_idx][group_num];
771 const auto idx_count = rm.count(group_idx);
772 if (idx_count==1) {
773 sparta_assert(rm.at(group_idx) != nullptr);
774 }
775 return (idx_count==1 ? rm.at(group_idx) : nullptr);
776 }
777
792 {
793 return banks_.getRegister(group_num, group_idx, RegisterBase::BANK_IDX_DEFAULT);
794 }
795
805 {
806 return banks_.getRegister(group_num, group_idx, bank_idx);
807 }
808
817 uint32_t getGroupSize(RegisterBase::group_num_type group_num) noexcept
818 {
819 return banks_.getGroupSize(group_num, RegisterBase::BANK_IDX_DEFAULT);
820 }
821
831 {
832 return banks_.getGroupSize(group_num, bank_num);
833 }
834
851 const std::string *name_ptr) const
852 {
853 if (cur_bank_fxn_ == nullptr) {
855 }
856 return cur_bank_fxn_(group_num, group_idx, name_ptr);
857 }
858
859private:
868 virtual void onAddingChild_(TreeNode *child) override
869 {
870 auto reg = dynamic_cast<RegisterBase *>(child);
871 if (nullptr == reg) {
872 throw SpartaException("Cannot add TreeNode child at ")
873 << child << " which is not a Register to RegisterSet "
874 << getLocation();
875 }
876
877 // Add register to regs_ list for tracking.
878 regs_.push_back(reg);
879 }
880
894 template <typename RegisterT>
895 void addRegister_(const RegisterBase::Definition *rdef)
896 {
897 sparta_assert(false == adata_.isLaidOut());// Cannot addRegister_ after the ArchData has been layed out
898 sparta_assert(reg_proxies_.size() == 0); // Cannot addRegister_ once a proxy has been added
899 auto r = new RegisterT(nullptr, *rdef, &adata_);
900
901 // Attempt to insert the register into the bank table
902 banks_.addRegister(r); // Throws if unable to add
903
904 // Finally add register as child after it is validated
905 this->addChild(r);
906 owned_regs_.push_back(r);
907 }
908
909
918 void addProxy_(const RegisterProxyBase::Definition *pdef)
919 {
920 sparta_assert(pdef,
921 "Attempted to add a RegisterProxy to RegisterSet " << getLocation()
922 << " with a null proxy definition");
923
924 // Check fields of the definition
925 sparta_assert(pdef->name,
926 "Attempted to add a RegisterProxy to RegisterSet " << getLocation()
927 << " with a null proxy name");
928 sparta_assert(pdef->desc,
929 "Attempted to add a RegisterProxy to RegisterSet " << getLocation()
930 << " named \"" << pdef->name << "\" with a null proxy description");
931 sparta_assert(pdef->group_num != Register::GROUP_NUM_NONE,
932 "Attempted to add a RegisterProxy to RegisterSet " << getLocation()
933 << " named \"" << pdef->name << "\" with a group number of "
934 "GROUP_NUM_NONE. RegisterProxy definitions must have a valid group number");
935 sparta_assert(pdef->group_idx != Register::GROUP_IDX_NONE,
936 "Attempted to add a RegisterProxy to RegisterSet " << getLocation()
937 << " named \"" << pdef->name << "\" with a group number of "
938 "GROUP_NUM_NONE. RegisterProxy definitions must have a valid group number");
939
940 // Check ID conflicts with other proxies and registers
941 for(auto& reg : regs_){
942 sparta_assert(reg->getID() != pdef->id,
943 "Attempted to add a RegisterProxy to RegisterSet " << getLocation()
944 << " named \"" << pdef->name << "\" with an ID of " << pdef->id
945 << " which is already usd by Register " << reg);
946 }
947
948 // Check for a register with the same name
949 auto reg_samename = getChildAs<RegisterBase>(pdef->name, false);
950 sparta_assert(reg_samename == nullptr,
951 "Attempted to add a RegisterProxy to RegisterSet " << getLocation()
952 << " named \"" << pdef->name << "\" but there is already a normal "
953 "Register with the same name: " << reg_samename->getLocation());
954
955 // Check for an existing proxy
956 auto rpi = reg_proxies_.find(pdef->name);
957 if(rpi != reg_proxies_.end()){
958 throw SpartaException("A RegisterProxy in ") << getLocation()
959 << " named \"" << pdef->name << "\" already exists";
960 }
961
965
966 uint32_t matches = 0;
967 for(uint32_t b = 0; b < banks_.getNumBanks(); b++){
968 if(banks_.canLookupRegister(pdef->group_num, pdef->group_idx, b)){
969 auto r = banks_.lookupRegister(pdef->group_num, pdef->group_idx, b);
970
971 // Sanity check lookup
972 sparta_assert(r);
973 sparta_assert(r->getGroupNum() == pdef->group_num);
974 sparta_assert(r->getGroupIdx() == pdef->group_idx);
975
976 // Ensure that the group name matches
977 sparta_assert(r->getGroupName() == pdef->group,
978 "Attempted to add a RegisterProxy to RegisterSet "
979 << getLocation() << " named \"" << pdef->name << "\" which matched "
980 "the group number and group index with " << *r << " but the "
981 "proxy had an incorrect group name \"" << pdef->group << "\"");
982
983 matches++;
984 }
985 }
986
987 // Ensure that one register matches
988 sparta_assert(matches > 0,
989 "Attempted to add a RegisterProxy to RegisterSet "
990 << getLocation() << " named \"" << pdef->name << "\" with group num "
991 << pdef->group_num << " and group idx " << pdef->group_idx << " which did "
992 "not match any known registers");
993
994 // Finally add the proxy
995 auto rp = new RegisterProxy(*this,
996 pdef->group_num,
997 pdef->group_idx,
999 reg_proxies_[pdef->name] = typename RegisterProxyMap::mapped_type(rp); // Takes ownership of memory
1000 }
1001
1006 ArchData adata_;
1007
1012 RegisterVector owned_regs_;
1013
1018 RegisterVector regs_;
1019
1023 RegisterBankTable<RegisterBase> banks_;
1024
1028 RegisterProxyMap reg_proxies_;
1029
1033 CurrentBankFunction cur_bank_fxn_;
1034
1035}; // class RegisterSet
1036
1040inline std::string RegisterProxy::stringize() const
1041{
1042 std::stringstream ss;
1043 ss << "<RegisterProxy to ";
1044 if (reg_inv_) {
1045 ss << reg_inv_;
1046 } else {
1047 ss << "name: \"" << reg_name_ << "\" group: " << group_num_
1048 << " idx: " << group_idx_;
1049 }
1050 ss << " within " << rs_.getLocation() << ">";
1051 return ss.str();
1052}
1053
1055{
1056 if (reg_inv_ != nullptr) {
1057 return reg_inv_;
1058 }
1059
1060 auto bank_idx = rs_.getCurrentBank(group_num_, group_idx_, reg_name_);
1061 return rs_.getRegister(group_num_, group_idx_, bank_idx);
1062}
1063
1065{
1066 if (reg_inv_ != nullptr) {
1067 return reg_inv_;
1068 }
1069
1070 auto bank_idx = rs_.getCurrentBank(group_num_, group_idx_, reg_name_);
1071 if (!rs_.canLookupRegister(group_num_, group_idx_, bank_idx)) {
1072 return nullptr;
1073 }
1074 return rs_.lookupRegister(group_num_, group_idx_, bank_idx);
1075}
1076
1078{
1079 return rs_;
1080}
1081
1082} // namespace sparta
1083
1085inline std::ostream &operator<<(std::ostream &o, const sparta::RegisterProxy &rp)
1086{
1087 o << rp.stringize();
1088 return o;
1089}
1090
1092inline std::ostream &operator<<(std::ostream &o, const sparta::RegisterProxy *rp)
1093{
1094 if (nullptr == rp) {
1095 o << "null";
1096 } else {
1097 o << rp->stringize();
1098 }
1099 return o;
1100}
1101
1103inline std::ostream& operator<<(std::ostream& o, const sparta::RegisterSet &rs)
1104{
1105 o << rs.stringize();
1106 return o;
1107}
1108
1110inline std::ostream &operator<<(std::ostream &o, const sparta::RegisterSet *rs)
1111{
1112 if(nullptr == rs){
1113 o << "null";
1114 }else{
1115 o << rs->stringize();
1116 }
1117 return o;
1118}
Set of macros for Sparta assertions. Caught by the framework.
#define sparta_assert(...)
Simple variadic assertion that will throw a sparta_exception if the condition fails.
Exception class for all of Sparta.
Cool string utilities.
Basic Node framework in sparta device tree composite pattern.
Contains a set of contiguous line of architectural data which can be referred to by any architected o...
Definition ArchData.hpp:39
bool isLaidOut() const
Has this ArchData been laid out yet.
void layout()
Organizes the Segments into overlapping regions as needed, eventually calling ArchDataSegment::place ...
Definition ArchData.hpp:586
void addRegister(RegisterT *r)
Adds a register to this table unless it is not a member of a group (See Register::getGroupNum.
void dump(std::ostream &out, bool detailed=false) const
Dump this register bank table to an out stream. Banks will be columns and group num/id will be rows.
void setMinimumBankIndex(Register::bank_idx_type min_idx)
Sets the minimum bank index for this register set, overriding the default of BANK_IDX_DEFAULT.
RegisterT::group_idx_type getNumGroups() const
Gets the number of register groups added to this table regardless of banks.
uint32_t getGroupSize(typename RegisterT::group_num_type group_num, typename RegisterT::bank_idx_type bank_num)
Gets the number of registers in a group by its group num and bank.
RegisterT * getRegister(typename RegisterT::group_num_type group_num, typename RegisterT::group_idx_type group_idx, typename RegisterT::bank_idx_type bank_idx)
Gets a Register by group number and group index and throws an exception if it cannot be found.
RegisterT::bank_idx_type getNumBanks() const
Gets the total number of banks instantiated (even if they contain have no actual registers accessible...
Base class to represents an architected register of any size that is a power of 2 and greater than 0 ...
Definition Register.hpp:63
DataView::ident_type ident_type
Identifier to distinguish from other registers in the same RegisterSet.
Definition Register.hpp:72
uint32_t bank_idx_type
Numeric bank identifier for bank lookup.
Definition Register.hpp:98
static constexpr bank_idx_type BANK_IDX_DEFAULT
Default index for bank when no bank is specified. A bank having this index will always exist.
Definition Register.hpp:127
TreeNode::group_idx_type group_idx_type
TreeNode group index.
Definition Register.hpp:92
uint32_t group_num_type
Numeric group identifier for register lookup.
Definition Register.hpp:87
static constexpr group_num_type GROUP_NUM_NONE
Represents no group much like sparta::TreeNode::GROUP_NAME_NONE.
Definition Register.hpp:684
static const Definition DEFINITION_END
Entry indicating the end of a sparta::Register::Definition array.
Represents an interface to a pseudo-"Register" of a fixed size which indirectly references other regi...
RegisterProxy(RegisterBase &reg)
Concrete Register Constructor. The "current register" of this proxy never changes.
RegisterProxy & operator=(const RegisterProxy &)=delete
Assignment Operator deleted to assure persistence of any proxy's group information and RegisterSet.
RegisterBase * tryGetCurrentRegister() const
Attempt to get the current register being pointed to by this proxy based on simulation state.
std::string stringize() const
Form a string representing this proxy.
RegisterProxy(const RegisterProxy &)=delete
Not Copy Constructable.
RegisterBase * getCurrentRegister() const
Gets the current register being pointed to by this proxy based on simulation state.
RegisterSet & getContainingRegisterSet() const
Gets the RegisterSet which this proxy accesses.
RegisterProxy(RegisterSet &rs, Register::group_num_type group_num, Register::group_idx_type group_idx, const std::string *managed_name)
Actual Proxy Contruction. Proxies all registers having a specific group_num and group_idx in a single...
RegisterProxy(RegisterProxy &&)=delete
Move construction not allowed.
RegisterProxy()=delete
RegisterProxy disabled.
~RegisterProxy()
Destructor.
Holds and can create a set of Register objects having various names and groups.
std::function< Register::bank_idx_type(RegisterBase::group_num_type, RegisterBase::group_idx_type, const std::string *name_ptr)> CurrentBankFunction
Function object type for holding a callback for querying the owning simulator about the current bank.
RegisterBase * getRegister(const std::string &name)
Retrieves a concrete register child that is a Register with the given dotted path.
static const ArchData::offset_type ARCH_DATA_LINE_SIZE
Size of an ArchData line for Registers (bytes) Must be large enough to fit the largest register in a ...
void dumpBanks(std::ostream &out) const
Dumps the table of banks and registers.
RegisterBase::bank_idx_type getCurrentBank(RegisterBase::group_num_type group_num, RegisterBase::group_idx_type group_idx, const std::string *name_ptr) const
Determine the current bank for this register set based on the context of time simulator.
RegisterProxy & getRegisterProxy(const std::string &name)
Retrieves a register proxy based on the given name. RegisterProxies are an indirection layer that dir...
RegisterBase * getRegister(RegisterBase::group_num_type group_num, RegisterBase::group_idx_type group_idx)
Gets a Register by group number and group index and throws an exception if it cannot be found.
const RegisterVector & getRegisters() const
Gets the vector of Registers contained by this set.
bool canLookupRegister(RegisterBase::group_num_type group_num, RegisterBase::group_idx_type group_idx, RegisterBase::bank_idx_type bank_idx) const noexcept
Alternate canLookupRegister with additional bank field.
std::unordered_map< std::string, std::unique_ptr< RegisterProxy > > RegisterProxyMap
Map of strings to self-deleting RegisterProxy instances.
RegisterSet(TreeNode *parent, const RegisterBase::Definition *defs, RegisterTypeTag< RegisterT > tag)
Constructor with no current-bank query function.
bool canLookupRegister(RegisterBase::group_num_type group_num, RegisterBase::group_idx_type group_idx) const noexcept
Determines if a register exists with the given group number and index.
RegisterBase::bank_idx_type getNumBanks() const
Returns the number of banks created (empty banks are automatically created between sprarse bank indic...
uint32_t getGroupSize(RegisterBase::group_num_type group_num, RegisterBase::bank_idx_type bank_num)
Alternate getGroupSize with additional bank field.
RegisterBase * getRegister(RegisterBase::group_num_type group_num, RegisterBase::group_idx_type group_idx, RegisterBase::bank_idx_type bank_idx)
Alternate getRegister with additional bank field.
typename RegisterBankTable< RegisterBase >::RegisterVector GroupVector
Vector of RegisterVectors used for lookup by numeric group number of type Register::Definition::group...
uint32_t getNumRegisters() const
Gets the number of counters in this Set.
void reset()
Reset all registers in this set to default values.
void setMinimumBankIndex(RegisterBase::bank_idx_type min_idx)
Sets the minimum bank index for this register set, overriding the default of Register::BANK_IDX_DEFAU...
RegisterBase * lookupRegister(RegisterBase::group_num_type group_num, RegisterBase::group_idx_type group_idx, RegisterBase::bank_idx_type bank_idx)
Alternate lookupRegister with additional bank field.
RegisterBase * lookupRegister(RegisterBase::group_num_type group_num, RegisterBase::group_idx_type group_idx)
Quickly looks up a register by its number and index with bounds checking.
RegisterBase::group_idx_type getNumGroups() const
Returns the number of groups in this register set.
RegisterSet(TreeNode *parent, const RegisterBase::Definition *defs, const RegisterProxyBase::Definition *proxy_defs, CurrentBankFunction cbfxn, RegisterTypeTag< RegisterT > tag)
Constructor.
typename RegisterBankTable< RegisterBase >::RegisterVector RegisterVector
Type for holding registers.
virtual std::string stringize(bool pretty=false) const override
Create a string representation of this node.
~RegisterSet()
Destructor.
uint32_t getGroupSize(RegisterBase::group_num_type group_num) noexcept
Gets the number of Registers in a group by its group num.
An implementation of a RegisterBase.
Used to construct and throw a standard C++ exception. Inherits from std::exception.
static StringManager & getStringManager()
Returns the StringManager singleton.
std::string * internString(const std::string &s)
Stores a string in shared space within this manager unless it is already stored.
Node in a composite tree representing a sparta Tree item.
Definition TreeNode.hpp:205
static const group_idx_type GROUP_IDX_NONE
GroupIndex indicating that a node has no group index because it belongs to no group.
Definition TreeNode.hpp:303
std::string getLocation() const override final
static constexpr char GROUP_NAME_BUILTIN[]
Reserved name for built-in nodes.
Definition TreeNode.hpp:370
TreeNode()=delete
Not default-constructable.
void addChild(TreeNode *child, bool inherit_phase=true)
Adds a TreeNode to this node as a child.
void setExpectedParent_(const TreeNode *parent)
Tracks a node as an expected parent without actually adding this node as a child. This is used almost...
Macros for handling exponential backoff.
std::ostream & operator<<(std::ostream &o, const SimulationInfo &info)
ostream insertion operator for SimulationInfo
Describes an architected Register.
Definition Register.hpp:548
Describes a register Proxy.
const Register::group_idx_type group_idx
Group index by which the a Register will be looked up when this RegisterProxy is accessed.
const Register::group_num_type group_num
Group number by which the a Register will be looked up when this RegisterProxy is accessed.
const char * desc
Description of this proxy as if it were a Register. Must NOT be NULL.
const Register::ident_type id
ID. Must be unique within all registers and register proxies within a register set.
const char * group
String name of group in which this register resides (e.g. gpr). Must NOT be NULL. This is the same as...
const char * name
String identifier for this register proxy. This name must be unique from all other RegisterProxies in...