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 const std::string& name = "regs")
485 : TreeNode(name,
488 "Register set")
489 , adata_(this,
491 ArchData::DEFAULT_INITIAL_FILL,
492 ArchData::DEFAULT_INITIAL_FILL_SIZE,
493 false) // Cannot delete lines
494 , cur_bank_fxn_(cbfxn)
495 {
496 (void)tag;
497
498 if(parent){
499 setExpectedParent_(parent);
500 }
501
502 // Add all registers
503 const auto *rdef = defs;
504 if (rdef != nullptr) {
505 while (rdef->name != nullptr) {
506 addRegister_<RegisterT>(rdef);
507 ++rdef;
508 }
509 }
510
511 // Add all proxies
512 const auto *pdef = proxy_defs;
513 if (pdef != nullptr) {
514 while (pdef->name != nullptr) {
515 addProxy_(pdef);
516 ++pdef;
517 }
518 }
519
520 // Perform the layout. At this point, no further registers can be added.
521 adata_.layout();
522
523 if (parent) {
524 parent->addChild(this);
525 }
526 }
527
531 template <typename RegisterT>
533 const RegisterBase::Definition *defs,
535 const std::string& name = "regs")
536 : RegisterSet(parent, defs, nullptr, nullptr, tag, name)
537 {
538 // Handled in delegated consturctor
539 }
540
541 template <typename RegisterT = Register>
542 static std::unique_ptr<RegisterSet>
543 create(TreeNode *parent,
544 const RegisterBase::Definition *defs,
545 const RegisterProxyBase::Definition *proxy_defs,
547 const std::string& name = "regs")
548 {
549 return std::unique_ptr<RegisterSet>(new RegisterSet(
550 parent, defs, proxy_defs, cbfxn, RegisterTypeTag<RegisterT>(), name));
551 }
552
553 template <typename RegisterT = Register>
554 static std::unique_ptr<RegisterSet>
555 create(TreeNode *parent, const RegisterBase::Definition *defs, const std::string& name = "regs")
556 {
557 return std::unique_ptr<RegisterSet>(new RegisterSet(
558 parent, defs, RegisterTypeTag<RegisterT>(), name));
559 }
560
567 {
568 for (auto r : owned_regs_) {
569 delete r;
570 }
571 }
572
576 void reset() {
577 for (uint32_t i=0; i<regs_.size(); i++) {
578 regs_[i]->reset();
579 }
580 }
581
600 banks_.setMinimumBankIndex(min_idx);
601 }
602
606 uint32_t getNumRegisters() const { return regs_.size(); }
607
613 {
614 return banks_.getNumBanks();
615 }
616
621 {
622 return banks_.getNumGroups();
623 }
624
630 const RegisterVector& getRegisters() const { return regs_; }
631
632 // Overload of TreeNode::stringize
633 virtual std::string stringize(bool pretty=false) const override {
634 (void) pretty;
635 std::stringstream ss;
636 ss << '<' << getLocation() << ' ' << regs_.size() << " regs>";
637 return ss.str();
638 }
639
643 void dumpBanks(std::ostream& out) const {
644 banks_.dump(out);
645 }
646
656 RegisterBase *getRegister(const std::string &name)
657 {
658 return getChildAs<RegisterBase>(name);
659 }
660
674 RegisterProxy &getRegisterProxy(const std::string &name)
675 {
676 auto rpi = reg_proxies_.find(name);
677 if(rpi != reg_proxies_.end()){
678 return *(rpi->second.get());
679 }
680 auto r = getChildAs<RegisterBase>(name, false);
681 if(!r){
682 throw SpartaException("Could not get register proxy from ") << getLocation()
683 << " named \"" << name << "\" because there was no existing proxy and no "
684 "register with this name.";
685 }
686 reg_proxies_[name] =
687 typename RegisterProxyMap::mapped_type(new RegisterProxy(*r));
688 return *reg_proxies_[name];
689 }
690
704 RegisterBase::group_idx_type group_idx) const noexcept
705 {
706 return banks_.canLookupRegister(group_num, group_idx, RegisterBase::BANK_IDX_DEFAULT);
707 }
708
717 RegisterBase::bank_idx_type bank_idx) const noexcept
718 {
719 return banks_.canLookupRegister(group_num, group_idx, bank_idx);
720 }
721
754 {
755 const auto &rm = banks_[RegisterBase::BANK_IDX_DEFAULT][group_num];
756 const auto idx_count = rm.count(group_idx);
757 if (idx_count==1) {
758 sparta_assert(rm.at(group_idx) != nullptr);
759 }
760 return (idx_count==1 ? rm.at(group_idx) : nullptr);
761 }
762
772 {
773 const auto &rm = banks_[bank_idx][group_num];
774 const auto idx_count = rm.count(group_idx);
775 if (idx_count==1) {
776 sparta_assert(rm.at(group_idx) != nullptr);
777 }
778 return (idx_count==1 ? rm.at(group_idx) : nullptr);
779 }
780
795 {
796 return banks_.getRegister(group_num, group_idx, RegisterBase::BANK_IDX_DEFAULT);
797 }
798
808 {
809 return banks_.getRegister(group_num, group_idx, bank_idx);
810 }
811
820 uint32_t getGroupSize(RegisterBase::group_num_type group_num) noexcept
821 {
822 return banks_.getGroupSize(group_num, RegisterBase::BANK_IDX_DEFAULT);
823 }
824
834 {
835 return banks_.getGroupSize(group_num, bank_num);
836 }
837
854 const std::string *name_ptr) const
855 {
856 if (cur_bank_fxn_ == nullptr) {
858 }
859 return cur_bank_fxn_(group_num, group_idx, name_ptr);
860 }
861
862private:
871 virtual void onAddingChild_(TreeNode *child) override
872 {
873 auto reg = dynamic_cast<RegisterBase *>(child);
874 if (nullptr == reg) {
875 throw SpartaException("Cannot add TreeNode child at ")
876 << child << " which is not a Register to RegisterSet "
877 << getLocation();
878 }
879
880 // Add register to regs_ list for tracking.
881 regs_.push_back(reg);
882 }
883
897 template <typename RegisterT>
898 void addRegister_(const RegisterBase::Definition *rdef)
899 {
900 sparta_assert(false == adata_.isLaidOut());// Cannot addRegister_ after the ArchData has been layed out
901 sparta_assert(reg_proxies_.size() == 0); // Cannot addRegister_ once a proxy has been added
902 auto r = new RegisterT(nullptr, *rdef, &adata_);
903
904 // Attempt to insert the register into the bank table
905 banks_.addRegister(r); // Throws if unable to add
906
907 // Finally add register as child after it is validated
908 this->addChild(r);
909 owned_regs_.push_back(r);
910 }
911
912
921 void addProxy_(const RegisterProxyBase::Definition *pdef)
922 {
923 sparta_assert(pdef,
924 "Attempted to add a RegisterProxy to RegisterSet " << getLocation()
925 << " with a null proxy definition");
926
927 // Check fields of the definition
928 sparta_assert(pdef->name,
929 "Attempted to add a RegisterProxy to RegisterSet " << getLocation()
930 << " with a null proxy name");
931 sparta_assert(pdef->desc,
932 "Attempted to add a RegisterProxy to RegisterSet " << getLocation()
933 << " named \"" << pdef->name << "\" with a null proxy description");
934 sparta_assert(pdef->group_num != Register::GROUP_NUM_NONE,
935 "Attempted to add a RegisterProxy to RegisterSet " << getLocation()
936 << " named \"" << pdef->name << "\" with a group number of "
937 "GROUP_NUM_NONE. RegisterProxy definitions must have a valid group number");
938 sparta_assert(pdef->group_idx != Register::GROUP_IDX_NONE,
939 "Attempted to add a RegisterProxy to RegisterSet " << getLocation()
940 << " named \"" << pdef->name << "\" with a group number of "
941 "GROUP_NUM_NONE. RegisterProxy definitions must have a valid group number");
942
943 // Check ID conflicts with other proxies and registers
944 for(auto& reg : regs_){
945 sparta_assert(reg->getID() != pdef->id,
946 "Attempted to add a RegisterProxy to RegisterSet " << getLocation()
947 << " named \"" << pdef->name << "\" with an ID of " << pdef->id
948 << " which is already usd by Register " << reg);
949 }
950
951 // Check for a register with the same name
952 auto reg_samename = getChildAs<RegisterBase>(pdef->name, false);
953 sparta_assert(reg_samename == nullptr,
954 "Attempted to add a RegisterProxy to RegisterSet " << getLocation()
955 << " named \"" << pdef->name << "\" but there is already a normal "
956 "Register with the same name: " << reg_samename->getLocation());
957
958 // Check for an existing proxy
959 auto rpi = reg_proxies_.find(pdef->name);
960 if(rpi != reg_proxies_.end()){
961 throw SpartaException("A RegisterProxy in ") << getLocation()
962 << " named \"" << pdef->name << "\" already exists";
963 }
964
968
969 uint32_t matches = 0;
970 for(uint32_t b = 0; b < banks_.getNumBanks(); b++){
971 if(banks_.canLookupRegister(pdef->group_num, pdef->group_idx, b)){
972 auto r = banks_.lookupRegister(pdef->group_num, pdef->group_idx, b);
973
974 // Sanity check lookup
975 sparta_assert(r);
976 sparta_assert(r->getGroupNum() == pdef->group_num);
977 sparta_assert(r->getGroupIdx() == pdef->group_idx);
978
979 // Ensure that the group name matches
980 sparta_assert(r->getGroupName() == pdef->group,
981 "Attempted to add a RegisterProxy to RegisterSet "
982 << getLocation() << " named \"" << pdef->name << "\" which matched "
983 "the group number and group index with " << *r << " but the "
984 "proxy had an incorrect group name \"" << pdef->group << "\"");
985
986 matches++;
987 }
988 }
989
990 // Ensure that one register matches
991 sparta_assert(matches > 0,
992 "Attempted to add a RegisterProxy to RegisterSet "
993 << getLocation() << " named \"" << pdef->name << "\" with group num "
994 << pdef->group_num << " and group idx " << pdef->group_idx << " which did "
995 "not match any known registers");
996
997 // Finally add the proxy
998 auto rp = new RegisterProxy(*this,
999 pdef->group_num,
1000 pdef->group_idx,
1002 reg_proxies_[pdef->name] = typename RegisterProxyMap::mapped_type(rp); // Takes ownership of memory
1003 }
1004
1009 ArchData adata_;
1010
1015 RegisterVector owned_regs_;
1016
1021 RegisterVector regs_;
1022
1026 RegisterBankTable<RegisterBase> banks_;
1027
1031 RegisterProxyMap reg_proxies_;
1032
1036 CurrentBankFunction cur_bank_fxn_;
1037
1038}; // class RegisterSet
1039
1043inline std::string RegisterProxy::stringize() const
1044{
1045 std::stringstream ss;
1046 ss << "<RegisterProxy to ";
1047 if (reg_inv_) {
1048 ss << reg_inv_;
1049 } else {
1050 ss << "name: \"" << reg_name_ << "\" group: " << group_num_
1051 << " idx: " << group_idx_;
1052 }
1053 ss << " within " << rs_.getLocation() << ">";
1054 return ss.str();
1055}
1056
1058{
1059 if (reg_inv_ != nullptr) {
1060 return reg_inv_;
1061 }
1062
1063 auto bank_idx = rs_.getCurrentBank(group_num_, group_idx_, reg_name_);
1064 return rs_.getRegister(group_num_, group_idx_, bank_idx);
1065}
1066
1068{
1069 if (reg_inv_ != nullptr) {
1070 return reg_inv_;
1071 }
1072
1073 auto bank_idx = rs_.getCurrentBank(group_num_, group_idx_, reg_name_);
1074 if (!rs_.canLookupRegister(group_num_, group_idx_, bank_idx)) {
1075 return nullptr;
1076 }
1077 return rs_.lookupRegister(group_num_, group_idx_, bank_idx);
1078}
1079
1081{
1082 return rs_;
1083}
1084
1085} // namespace sparta
1086
1088inline std::ostream &operator<<(std::ostream &o, const sparta::RegisterProxy &rp)
1089{
1090 o << rp.stringize();
1091 return o;
1092}
1093
1095inline std::ostream &operator<<(std::ostream &o, const sparta::RegisterProxy *rp)
1096{
1097 if (nullptr == rp) {
1098 o << "null";
1099 } else {
1100 o << rp->stringize();
1101 }
1102 return o;
1103}
1104
1106inline std::ostream& operator<<(std::ostream& o, const sparta::RegisterSet &rs)
1107{
1108 o << rs.stringize();
1109 return o;
1110}
1111
1113inline std::ostream &operator<<(std::ostream &o, const sparta::RegisterSet *rs)
1114{
1115 if(nullptr == rs){
1116 o << "null";
1117 }else{
1118 o << rs->stringize();
1119 }
1120 return o;
1121}
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.
RegisterSet(TreeNode *parent, const RegisterBase::Definition *defs, RegisterTypeTag< RegisterT > tag, const std::string &name="regs")
Constructor with no current-bank query function.
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.
RegisterSet(TreeNode *parent, const RegisterBase::Definition *defs, const RegisterProxyBase::Definition *proxy_defs, CurrentBankFunction cbfxn, RegisterTypeTag< RegisterT > tag, const std::string &name="regs")
Constructor.
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.
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.
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...