From 3f88e2022c1a49dd0a62618fba4e8d11b220b6ea Mon Sep 17 00:00:00 2001 From: Nav Date: Thu, 25 Jul 2024 19:03:26 +0100 Subject: [PATCH] Refactored descriptor ID generation and added IDs to peripherals, register groups and registers --- src/Services/StringService.cpp | 15 ++++- src/Services/StringService.hpp | 24 ++++++- src/Targets/Microchip/AVR8/Avr8.cpp | 4 ++ src/Targets/RiscV/RiscV.cpp | 36 ++++++++++ src/Targets/TargetAddressSpaceDescriptor.cpp | 2 +- .../TargetDescriptionFile.cpp | 65 ++++++++++++------- .../TargetDescriptionFile.hpp | 14 ++-- src/Targets/TargetMemorySegmentDescriptor.cpp | 2 +- src/Targets/TargetPeripheralDescriptor.cpp | 11 +++- src/Targets/TargetPeripheralDescriptor.hpp | 10 ++- src/Targets/TargetRegisterDescriptor.cpp | 21 +++--- src/Targets/TargetRegisterDescriptor.hpp | 9 ++- src/Targets/TargetRegisterGroupDescriptor.cpp | 17 ++++- src/Targets/TargetRegisterGroupDescriptor.hpp | 13 +++- 14 files changed, 191 insertions(+), 52 deletions(-) diff --git a/src/Services/StringService.cpp b/src/Services/StringService.cpp index a906016a..41cfaba0 100644 --- a/src/Services/StringService.cpp +++ b/src/Services/StringService.cpp @@ -6,6 +6,8 @@ #include #include #include +#include +#include namespace Services { @@ -100,9 +102,16 @@ namespace Services return static_cast(StringService::toUint64(str, base)); } - std::size_t StringService::hash(const std::string& str) { - static const auto hash = std::hash{}; - return hash(str); + std::size_t StringService::generateUniqueInteger(const std::string& str) { + static auto mutex = std::mutex{}; + + static auto lastValue = std::size_t{0}; + static auto map = std::unordered_map{}; + + const auto lock = std::unique_lock{mutex}; + + const auto valueIt = map.find(str); + return valueIt != map.end() ? valueIt->second : map.emplace(str, ++lastValue).first->second; } std::vector StringService::split(std::string_view str, char delimiter) { diff --git a/src/Services/StringService.hpp b/src/Services/StringService.hpp index d5c16b2c..b1003de1 100644 --- a/src/Services/StringService.hpp +++ b/src/Services/StringService.hpp @@ -29,7 +29,29 @@ namespace Services static std::uint16_t toUint16(const std::string& str, int base = 0); static std::uint8_t toUint8(const std::string& str, int base = 0); - static std::size_t hash(const std::string& str); + /** + * Generates a unique integer from a given string. + * + * This function will return the same value for matching strings. + * That is: If strA == strB, then generateUniqueInteger(strA) == generateUniqueInteger(strB). + * + * This function does *not* return a hash of the string. We can't use hashes because they're not unique due to + * collisions. + * + * The returned value will only be unique for the duration of the current execution cycle. + * That means generateUniqueInteger(strA) != generateUniqueInteger(strA) if the functions are called within + * different execution cycles. + * + * The generated value isn't actually derived from the string itself. It's just an integer that we produce and + * keep record of, in a key-value store. See the implementation for more. + * + * The purpose of this function is to generate internal integer IDs for entities within Bloom, such as address + * spaces and memory segments. These IDs have no meaning to the user or any other external entity. + * + * @param str + * @return + */ + static std::size_t generateUniqueInteger(const std::string& str); static std::vector split(std::string_view str, char delimiter); }; diff --git a/src/Targets/Microchip/AVR8/Avr8.cpp b/src/Targets/Microchip/AVR8/Avr8.cpp index 27603d30..062571d2 100644 --- a/src/Targets/Microchip/AVR8/Avr8.cpp +++ b/src/Targets/Microchip/AVR8/Avr8.cpp @@ -290,8 +290,10 @@ namespace Targets::Microchip::Avr8 auto& gpRegisterGroup = gpPeripheral.registerGroupDescriptorsByKey.emplace( "gpr", TargetRegisterGroupDescriptor{ + "gpr", "gpr", "CPU General Purpose", + gpPeripheral.key, registerFileAddressSpace.key, std::nullopt, {}, @@ -306,6 +308,8 @@ namespace Targets::Microchip::Avr8 TargetRegisterDescriptor{ key, "R" + std::to_string(i), + gpRegisterGroup.absoluteKey, + gpPeripheral.key, registerFileAddressSpace.key, registerFileMemorySegment.startAddress + i, 1, diff --git a/src/Targets/RiscV/RiscV.cpp b/src/Targets/RiscV/RiscV.cpp index b0a15542..91902a79 100644 --- a/src/Targets/RiscV/RiscV.cpp +++ b/src/Targets/RiscV/RiscV.cpp @@ -462,8 +462,10 @@ namespace Targets::RiscV auto& gprGroup = cpuPeripheralDescriptor.registerGroupDescriptorsByKey.emplace( "gpr", TargetRegisterGroupDescriptor{ + "gpr", "gpr", "General Purpose Registers", + cpuPeripheralDescriptor.key, addressSpaceDescriptor.key, std::nullopt, {}, @@ -478,6 +480,8 @@ namespace Targets::RiscV TargetRegisterDescriptor{ key, "X" + std::to_string(i), + gprGroup.absoluteKey, + cpuPeripheralDescriptor.key, addressSpaceDescriptor.key, gprMemorySegmentDescriptor.addressRange.startAddress + i, 4, @@ -492,8 +496,10 @@ namespace Targets::RiscV auto& csrGroup = cpuPeripheralDescriptor.registerGroupDescriptorsByKey.emplace( "csr", TargetRegisterGroupDescriptor{ + "csr", "csr", "Control Status Registers", + cpuPeripheralDescriptor.key, addressSpaceDescriptor.key, std::nullopt, {}, @@ -506,6 +512,8 @@ namespace Targets::RiscV TargetRegisterDescriptor{ "marchid", "MARCHID", + csrGroup.absoluteKey, + cpuPeripheralDescriptor.key, addressSpaceDescriptor.key, csrMemorySegmentDescriptor.addressRange.startAddress + 0xF12, 4, @@ -521,6 +529,8 @@ namespace Targets::RiscV TargetRegisterDescriptor{ "mimpid", "MIMPID", + csrGroup.absoluteKey, + cpuPeripheralDescriptor.key, addressSpaceDescriptor.key, csrMemorySegmentDescriptor.addressRange.startAddress + 0xF13, 4, @@ -536,6 +546,8 @@ namespace Targets::RiscV TargetRegisterDescriptor{ "mstatus", "MSTATUS", + csrGroup.absoluteKey, + cpuPeripheralDescriptor.key, addressSpaceDescriptor.key, csrMemorySegmentDescriptor.addressRange.startAddress + 0x300, 4, @@ -551,6 +563,8 @@ namespace Targets::RiscV TargetRegisterDescriptor{ "misa", "MISA", + csrGroup.absoluteKey, + cpuPeripheralDescriptor.key, addressSpaceDescriptor.key, csrMemorySegmentDescriptor.addressRange.startAddress + 0x301, 4, @@ -566,6 +580,8 @@ namespace Targets::RiscV TargetRegisterDescriptor{ "mtvec", "MTVEC", + csrGroup.absoluteKey, + cpuPeripheralDescriptor.key, addressSpaceDescriptor.key, csrMemorySegmentDescriptor.addressRange.startAddress + 0x305, 4, @@ -581,6 +597,8 @@ namespace Targets::RiscV TargetRegisterDescriptor{ "mcounteren", "MCOUNTEREN", + csrGroup.absoluteKey, + cpuPeripheralDescriptor.key, addressSpaceDescriptor.key, csrMemorySegmentDescriptor.addressRange.startAddress + 0x306, 4, @@ -596,6 +614,8 @@ namespace Targets::RiscV TargetRegisterDescriptor{ "mscratch", "MSCRATCH", + csrGroup.absoluteKey, + cpuPeripheralDescriptor.key, addressSpaceDescriptor.key, csrMemorySegmentDescriptor.addressRange.startAddress + 0x340, 4, @@ -611,6 +631,8 @@ namespace Targets::RiscV TargetRegisterDescriptor{ "mepc", "MEPC", + csrGroup.absoluteKey, + cpuPeripheralDescriptor.key, addressSpaceDescriptor.key, csrMemorySegmentDescriptor.addressRange.startAddress + 0x341, 4, @@ -626,6 +648,8 @@ namespace Targets::RiscV TargetRegisterDescriptor{ "mcause", "MCAUSE", + csrGroup.absoluteKey, + cpuPeripheralDescriptor.key, addressSpaceDescriptor.key, csrMemorySegmentDescriptor.addressRange.startAddress + 0x342, 4, @@ -641,6 +665,8 @@ namespace Targets::RiscV TargetRegisterDescriptor{ "mtval", "MTVAL", + csrGroup.absoluteKey, + cpuPeripheralDescriptor.key, addressSpaceDescriptor.key, csrMemorySegmentDescriptor.addressRange.startAddress + 0x343, 4, @@ -656,6 +682,8 @@ namespace Targets::RiscV TargetRegisterDescriptor{ "mip", "MIP", + csrGroup.absoluteKey, + cpuPeripheralDescriptor.key, addressSpaceDescriptor.key, csrMemorySegmentDescriptor.addressRange.startAddress + 0x344, 4, @@ -671,6 +699,8 @@ namespace Targets::RiscV TargetRegisterDescriptor{ "dcsr", "DCSR", + csrGroup.absoluteKey, + cpuPeripheralDescriptor.key, addressSpaceDescriptor.key, csrMemorySegmentDescriptor.addressRange.startAddress + 0x7B0, 4, @@ -686,6 +716,8 @@ namespace Targets::RiscV TargetRegisterDescriptor{ "dpc", "DPC", + csrGroup.absoluteKey, + cpuPeripheralDescriptor.key, addressSpaceDescriptor.key, csrMemorySegmentDescriptor.addressRange.startAddress + 0x7B1, 4, @@ -701,6 +733,8 @@ namespace Targets::RiscV TargetRegisterDescriptor{ "dscratch0", "DSCRATCH0", + csrGroup.absoluteKey, + cpuPeripheralDescriptor.key, addressSpaceDescriptor.key, csrMemorySegmentDescriptor.addressRange.startAddress + 0x7B2, 4, @@ -716,6 +750,8 @@ namespace Targets::RiscV TargetRegisterDescriptor{ "dscratch1", "DSCRATCH1", + csrGroup.absoluteKey, + cpuPeripheralDescriptor.key, addressSpaceDescriptor.key, csrMemorySegmentDescriptor.addressRange.startAddress + 0x7B3, 4, diff --git a/src/Targets/TargetAddressSpaceDescriptor.cpp b/src/Targets/TargetAddressSpaceDescriptor.cpp index 83769400..e7c62c7b 100644 --- a/src/Targets/TargetAddressSpaceDescriptor.cpp +++ b/src/Targets/TargetAddressSpaceDescriptor.cpp @@ -102,6 +102,6 @@ namespace Targets } TargetAddressSpaceId TargetAddressSpaceDescriptor::generateId(const std::string& addressSpaceKey) { - return static_cast(Services::StringService::hash(addressSpaceKey)); + return static_cast(Services::StringService::generateUniqueInteger(addressSpaceKey)); } } diff --git a/src/Targets/TargetDescription/TargetDescriptionFile.cpp b/src/Targets/TargetDescription/TargetDescriptionFile.cpp index 4a230960..a73cb85e 100644 --- a/src/Targets/TargetDescription/TargetDescriptionFile.cpp +++ b/src/Targets/TargetDescription/TargetDescriptionFile.cpp @@ -925,13 +925,15 @@ namespace Targets::TargetDescription output.registerGroupDescriptorsByKey.emplace( key, TargetDescriptionFile::targetRegisterGroupDescriptorFromRegisterGroup( - registerGroupInstance.key, - registerGroupInstance.name, - registerGroupInstance.addressSpaceKey, - registerGroupInstance.description, peripheralModule.getRegisterGroup(registerGroupInstance.registerGroupKey), peripheralModule, - registerGroupInstance.offset + peripheral.key, + registerGroupInstance.addressSpaceKey, + registerGroupInstance.offset, + std::nullopt, + registerGroupInstance.description, + registerGroupInstance.key, + registerGroupInstance.name ) ); } @@ -955,17 +957,27 @@ namespace Targets::TargetDescription } TargetRegisterGroupDescriptor TargetDescriptionFile::targetRegisterGroupDescriptorFromRegisterGroup( - const std::string& key, - const std::string& name, - const std::string& addressSpaceKey, - const std::optional& description, const RegisterGroup& registerGroup, const Module& peripheralModule, - TargetMemoryAddress baseAddress + const std::string& peripheralKey, + const std::string& addressSpaceKey, + TargetMemoryAddress baseAddress, + const std::optional& parentGroupAbsoluteKey, + const std::optional& description, + const std::optional& keyOverride, + const std::optional& nameOverride ) { + const auto& key = keyOverride.has_value() ? *keyOverride : registerGroup.key; + const auto& name = nameOverride.has_value() ? *nameOverride : registerGroup.name; + const auto absoluteKey = parentGroupAbsoluteKey.has_value() + ? *parentGroupAbsoluteKey + "." + key + : key; + auto output = TargetRegisterGroupDescriptor{ key, + absoluteKey, name, + peripheralKey, addressSpaceKey, description, {}, @@ -976,29 +988,30 @@ namespace Targets::TargetDescription output.subgroupDescriptorsByKey.emplace( key, TargetDescriptionFile::targetRegisterGroupDescriptorFromRegisterGroup( - subgroup.key, - subgroup.name, - addressSpaceKey, - std::nullopt, - registerGroup, + subgroup, peripheralModule, - baseAddress + registerGroup.offset.value_or(0) + peripheralKey, + addressSpaceKey, + baseAddress + registerGroup.offset.value_or(0), + absoluteKey ) ); } for (const auto& [key, subgroupReference] : registerGroup.subgroupReferencesByKey) { - const auto& registerGroup = peripheralModule.getRegisterGroup(subgroupReference.registerGroupKey); + const auto& referencedGroup = peripheralModule.getRegisterGroup(subgroupReference.registerGroupKey); output.subgroupDescriptorsByKey.emplace( key, TargetDescriptionFile::targetRegisterGroupDescriptorFromRegisterGroup( - subgroupReference.key, - subgroupReference.name, - addressSpaceKey, - subgroupReference.description, - registerGroup, + referencedGroup, peripheralModule, - baseAddress + subgroupReference.offset + registerGroup.offset.value_or(0) + peripheralKey, + addressSpaceKey, + baseAddress + registerGroup.offset.value_or(0) + subgroupReference.offset, + absoluteKey, + subgroupReference.description, + subgroupReference.key, + subgroupReference.name ) ); } @@ -1008,6 +1021,8 @@ namespace Targets::TargetDescription key, TargetDescriptionFile::targetRegisterDescriptorFromRegister( reg, + absoluteKey, + peripheralKey, addressSpaceKey, baseAddress + registerGroup.offset.value_or(0) ) @@ -1019,12 +1034,16 @@ namespace Targets::TargetDescription TargetRegisterDescriptor TargetDescriptionFile::targetRegisterDescriptorFromRegister( const Register& reg, + const std::string& absoluteGroupKey, + const std::string& peripheralKey, const std::string& addressSpaceKey, TargetMemoryAddress baseAddress ) { auto output = TargetRegisterDescriptor{ reg.key, reg.name, + absoluteGroupKey, + peripheralKey, addressSpaceKey, baseAddress + reg.offset, reg.size, diff --git a/src/Targets/TargetDescription/TargetDescriptionFile.hpp b/src/Targets/TargetDescription/TargetDescriptionFile.hpp index ff9c31ed..c485daca 100644 --- a/src/Targets/TargetDescription/TargetDescriptionFile.hpp +++ b/src/Targets/TargetDescription/TargetDescriptionFile.hpp @@ -215,17 +215,21 @@ namespace Targets::TargetDescription static TargetPeripheralSignalDescriptor targetPeripheralSignalDescriptorFromSignal(const Signal& signal); static TargetRegisterGroupDescriptor targetRegisterGroupDescriptorFromRegisterGroup( - const std::string& key, - const std::string& name, - const std::string& addressSpaceKey, - const std::optional& description, const RegisterGroup& registerGroup, const Module& peripheralModule, - TargetMemoryAddress baseAddress + const std::string& peripheralKey, + const std::string& addressSpaceKey, + TargetMemoryAddress baseAddress, + const std::optional& parentGroupAbsoluteKey, + const std::optional& description = std::nullopt, + const std::optional& keyOverride = std::nullopt, + const std::optional& nameOverride = std::nullopt ); static TargetRegisterDescriptor targetRegisterDescriptorFromRegister( const Register& reg, + const std::string& absoluteGroupKey, + const std::string& peripheralKey, const std::string& addressSpaceKey, TargetMemoryAddress baseAddress ); diff --git a/src/Targets/TargetMemorySegmentDescriptor.cpp b/src/Targets/TargetMemorySegmentDescriptor.cpp index 45f6dd35..d0f6e66c 100644 --- a/src/Targets/TargetMemorySegmentDescriptor.cpp +++ b/src/Targets/TargetMemorySegmentDescriptor.cpp @@ -16,7 +16,7 @@ namespace Targets const TargetMemoryAccess& programmingModeAccess, std::optional pageSize ) - : id(static_cast(Services::StringService::hash(addressSpaceKey + key))) + : id(static_cast(Services::StringService::generateUniqueInteger(addressSpaceKey + key))) , key(key) , name(name) , type(type) diff --git a/src/Targets/TargetPeripheralDescriptor.cpp b/src/Targets/TargetPeripheralDescriptor.cpp index 9230a341..25687928 100644 --- a/src/Targets/TargetPeripheralDescriptor.cpp +++ b/src/Targets/TargetPeripheralDescriptor.cpp @@ -15,12 +15,21 @@ namespace Targets std::map>&& registerGroupDescriptorsByKey, std::vector&& signalDescriptors ) - : key(key) + : id(static_cast(Services::StringService::generateUniqueInteger(key))) + , key(key) , name(name) , registerGroupDescriptorsByKey(std::move(registerGroupDescriptorsByKey)) , signalDescriptors(std::move(signalDescriptors)) {} + bool TargetPeripheralDescriptor::operator == (const TargetPeripheralDescriptor& other) const { + return this->id == other.id; + } + + bool TargetPeripheralDescriptor::operator != (const TargetPeripheralDescriptor& other) const { + return !(*this == other); + } + std::optional< std::reference_wrapper > TargetPeripheralDescriptor::tryGetRegisterGroupDescriptor(std::string_view keyStr) const { diff --git a/src/Targets/TargetPeripheralDescriptor.hpp b/src/Targets/TargetPeripheralDescriptor.hpp index ba1ab0fa..d9199dd1 100644 --- a/src/Targets/TargetPeripheralDescriptor.hpp +++ b/src/Targets/TargetPeripheralDescriptor.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -13,10 +14,13 @@ namespace Targets { + using TargetPeripheralId = std::size_t; + struct TargetPeripheralDescriptor { public: - std::string key; + const TargetPeripheralId id; + const std::string key; std::string name; std::map> registerGroupDescriptorsByKey; std::vector signalDescriptors; @@ -32,7 +36,9 @@ namespace Targets TargetPeripheralDescriptor& operator = (const TargetPeripheralDescriptor& other) = delete; TargetPeripheralDescriptor(TargetPeripheralDescriptor&& other) noexcept = default; - TargetPeripheralDescriptor& operator = (TargetPeripheralDescriptor&& other) = default; + + bool operator == (const TargetPeripheralDescriptor& other) const; + bool operator != (const TargetPeripheralDescriptor& other) const; [[nodiscard]] std::optional< std::reference_wrapper diff --git a/src/Targets/TargetRegisterDescriptor.cpp b/src/Targets/TargetRegisterDescriptor.cpp index c6914afd..b55cca5b 100644 --- a/src/Targets/TargetRegisterDescriptor.cpp +++ b/src/Targets/TargetRegisterDescriptor.cpp @@ -1,6 +1,8 @@ #include "TargetRegisterDescriptor.hpp" +#include "src/Services/StringService.hpp" #include "TargetAddressSpaceDescriptor.hpp" + #include "src/Exceptions/InternalFatalErrorException.hpp" namespace Targets @@ -8,6 +10,8 @@ namespace Targets TargetRegisterDescriptor::TargetRegisterDescriptor( const std::string& key, const std::string& name, + const std::string& absoluteGroupKey, + const std::string& peripheralKey, const std::string& addressSpaceKey, TargetMemoryAddress startAddress, TargetMemorySize size, @@ -16,8 +20,11 @@ namespace Targets std::optional description, std::map&& bitFieldDescriptorsByKey ) - : key(key) + : id(Services::StringService::generateUniqueInteger(peripheralKey + absoluteGroupKey + key)) + , key(key) , name(name) + , absoluteGroupKey(absoluteGroupKey) + , peripheralKey(peripheralKey) , addressSpaceId(TargetAddressSpaceDescriptor::generateId(addressSpaceKey)) , addressSpaceKey(addressSpaceKey) , startAddress(startAddress) @@ -29,15 +36,7 @@ namespace Targets {} bool TargetRegisterDescriptor::operator == (const TargetRegisterDescriptor& other) const { - return this->key == other.key - && this->name == other.name - && this->addressSpaceKey == other.addressSpaceKey - && this->startAddress == other.startAddress - && this->size == other.size - && this->type == other.type - && this->access == other.access - && this->description == other.description - ; + return this->id == other.id; } bool TargetRegisterDescriptor::operator < (const TargetRegisterDescriptor& other) const { @@ -81,6 +80,8 @@ namespace Targets auto output = TargetRegisterDescriptor{ this->key, this->name, + this->absoluteGroupKey, + this->peripheralKey, this->addressSpaceKey, this->startAddress, this->size, diff --git a/src/Targets/TargetRegisterDescriptor.hpp b/src/Targets/TargetRegisterDescriptor.hpp index c8ec1db2..435b993f 100644 --- a/src/Targets/TargetRegisterDescriptor.hpp +++ b/src/Targets/TargetRegisterDescriptor.hpp @@ -15,6 +15,7 @@ namespace Targets { + using TargetRegisterId = std::size_t; using TargetRegisterDescriptorId = std::uint32_t; using TargetRegisterDescriptorIds = std::set; @@ -47,8 +48,11 @@ namespace Targets struct TargetRegisterDescriptor { public: - std::string key; + const TargetRegisterId id; + const std::string key; std::string name; + std::string absoluteGroupKey; + std::string peripheralKey; TargetAddressSpaceId addressSpaceId; std::string addressSpaceKey; TargetMemoryAddress startAddress; @@ -61,6 +65,8 @@ namespace Targets TargetRegisterDescriptor( const std::string& key, const std::string& name, + const std::string& absoluteGroupKey, + const std::string& peripheralKey, const std::string& addressSpaceKey, TargetMemoryAddress startAddress, TargetMemorySize size, @@ -74,7 +80,6 @@ namespace Targets TargetRegisterDescriptor& operator = (const TargetRegisterDescriptor& other) = delete; TargetRegisterDescriptor(TargetRegisterDescriptor&& other) noexcept = default; - TargetRegisterDescriptor& operator = (TargetRegisterDescriptor&& other) = default; bool operator == (const TargetRegisterDescriptor& other) const; bool operator < (const TargetRegisterDescriptor& other) const; diff --git a/src/Targets/TargetRegisterGroupDescriptor.cpp b/src/Targets/TargetRegisterGroupDescriptor.cpp index 01ee6ff3..b89a6f0e 100644 --- a/src/Targets/TargetRegisterGroupDescriptor.cpp +++ b/src/Targets/TargetRegisterGroupDescriptor.cpp @@ -10,20 +10,33 @@ namespace Targets { TargetRegisterGroupDescriptor::TargetRegisterGroupDescriptor( const std::string& key, + const std::string& absoluteKey, const std::string& name, + const std::string& peripheralKey, const std::string& addressSpaceKey, const std::optional& description, std::map>&& registerDescriptorsByKey, std::map>&& subgroupDescriptorsByKey ) - : key(key) + : id(Services::StringService::generateUniqueInteger(peripheralKey + absoluteKey)) + , key(key) + , absoluteKey(absoluteKey) , name(name) + , peripheralKey(peripheralKey) , addressSpaceKey(addressSpaceKey) , description(description) , registerDescriptorsByKey(std::move(registerDescriptorsByKey)) , subgroupDescriptorsByKey(std::move(subgroupDescriptorsByKey)) {} + bool TargetRegisterGroupDescriptor::operator == (const TargetRegisterGroupDescriptor& other) const { + return this->id == other.id; + } + + bool TargetRegisterGroupDescriptor::operator != (const TargetRegisterGroupDescriptor& other) const { + return !(*this == other); + } + TargetMemoryAddress TargetRegisterGroupDescriptor::startAddress() const { assert(!this->registerDescriptorsByKey.empty() || !this->subgroupDescriptorsByKey.empty()); @@ -140,7 +153,9 @@ namespace Targets TargetRegisterGroupDescriptor TargetRegisterGroupDescriptor::clone() const { auto output = TargetRegisterGroupDescriptor{ this->key, + this->absoluteKey, this->name, + this->peripheralKey, this->addressSpaceKey, this->description, {}, diff --git a/src/Targets/TargetRegisterGroupDescriptor.hpp b/src/Targets/TargetRegisterGroupDescriptor.hpp index bc37824a..7f292543 100644 --- a/src/Targets/TargetRegisterGroupDescriptor.hpp +++ b/src/Targets/TargetRegisterGroupDescriptor.hpp @@ -15,11 +15,16 @@ namespace Targets { + using TargetRegisterGroupId = std::size_t; + struct TargetRegisterGroupDescriptor { public: - std::string key; + const TargetRegisterGroupId id; + const std::string key; + const std::string absoluteKey; std::string name; + std::string peripheralKey; std::string addressSpaceKey; std::optional description; std::map> registerDescriptorsByKey; @@ -27,7 +32,9 @@ namespace Targets TargetRegisterGroupDescriptor( const std::string& key, + const std::string& absoluteKey, const std::string& name, + const std::string& peripheralKey, const std::string& addressSpaceKey, const std::optional& description, std::map>&& registerDescriptorsByKey, @@ -38,7 +45,9 @@ namespace Targets TargetRegisterGroupDescriptor& operator = (const TargetRegisterGroupDescriptor& other) = delete; TargetRegisterGroupDescriptor(TargetRegisterGroupDescriptor&& other) noexcept = default; - TargetRegisterGroupDescriptor& operator = (TargetRegisterGroupDescriptor&& other) = default; + + bool operator == (const TargetRegisterGroupDescriptor& other) const; + bool operator != (const TargetRegisterGroupDescriptor& other) const; /** * Calculates the start address of the register group.