From 5595a77da2524b6a1a2efd722553c3666788f06d Mon Sep 17 00:00:00 2001 From: Finn Wilkinson Date: Wed, 7 Feb 2024 09:30:34 +0000 Subject: [PATCH 1/9] Moved ExecutionInfo to abstract Instruction class. --- src/include/simeng/Instruction.hh | 13 +++++++++++++ src/include/simeng/arch/aarch64/Architecture.hh | 10 ++++++---- src/include/simeng/arch/aarch64/Instruction.hh | 13 ------------- src/include/simeng/arch/riscv/Architecture.hh | 8 ++++---- src/include/simeng/arch/riscv/Instruction.hh | 15 +-------------- src/lib/arch/aarch64/Architecture.cc | 3 +-- src/lib/arch/riscv/Architecture.cc | 11 +++++------ src/lib/arch/riscv/Instruction.cc | 2 +- 8 files changed, 31 insertions(+), 44 deletions(-) diff --git a/src/include/simeng/Instruction.hh b/src/include/simeng/Instruction.hh index 0b326f0ee5..426e28b4b7 100644 --- a/src/include/simeng/Instruction.hh +++ b/src/include/simeng/Instruction.hh @@ -13,6 +13,19 @@ using InstructionException = short; namespace simeng { +/** A struct holding user-defined execution information for an + * instruction. */ +struct ExecutionInfo { + /** The latency for the instruction. */ + uint16_t latency = 1; + + /** The execution throughput for the instruction. */ + uint16_t stallCycles = 1; + + /** The ports that support the instruction. */ + std::vector ports = {}; +}; + /** An abstract instruction definition. * Each supported ISA should provide a derived implementation of this class. */ class Instruction { diff --git a/src/include/simeng/arch/aarch64/Architecture.hh b/src/include/simeng/arch/aarch64/Architecture.hh index 6a46482e8e..37763d7fe6 100644 --- a/src/include/simeng/arch/aarch64/Architecture.hh +++ b/src/include/simeng/arch/aarch64/Architecture.hh @@ -20,7 +20,9 @@ class Architecture : public arch::Architecture { public: Architecture(kernel::Linux& kernel, ryml::ConstNodeRef config = config::SimInfo::getConfig()); + ~Architecture(); + /** Pre-decode instruction memory into a macro-op of `Instruction` * instances. Returns the number of bytes consumed to produce it (always 4), * and writes into the supplied macro-op vector. */ @@ -46,6 +48,10 @@ class Architecture : public arch::Architecture { /** Returns the maximum size of a valid instruction in bytes. */ uint8_t getMaxInstructionSize() const override; + /** Updates System registers of any system-based timers. */ + void updateSystemTimerRegisters(RegisterFileSet* regFile, + const uint64_t iterations) const override; + /** Returns the current vector length set by the provided configuration. */ uint64_t getVectorLength() const; @@ -53,10 +59,6 @@ class Architecture : public arch::Architecture { * configuration. */ uint64_t getStreamingVectorLength() const; - /** Updates System registers of any system-based timers. */ - void updateSystemTimerRegisters(RegisterFileSet* regFile, - const uint64_t iterations) const override; - /** Retrieve an ExecutionInfo object for the requested instruction. If a * opcode-based override has been defined for the latency and/or * port information, return that instead of the group-defined execution diff --git a/src/include/simeng/arch/aarch64/Instruction.hh b/src/include/simeng/arch/aarch64/Instruction.hh index ddefb0ceb6..01224b3a72 100644 --- a/src/include/simeng/arch/aarch64/Instruction.hh +++ b/src/include/simeng/arch/aarch64/Instruction.hh @@ -176,19 +176,6 @@ const uint8_t MATRIX = 5; const Register ZERO_REGISTER = {GENERAL, (uint16_t)-1}; } // namespace RegisterType -/** A struct holding user-defined execution information for a aarch64 - * instruction. */ -struct ExecutionInfo { - /** The latency for the instruction. */ - uint16_t latency = 1; - - /** The execution throughput for the instruction. */ - uint16_t stallCycles = 1; - - /** The ports that support the instruction. */ - std::vector ports = {}; -}; - /** The various exceptions that can be raised by an individual instruction. */ enum class InstructionException { None = 0, diff --git a/src/include/simeng/arch/riscv/Architecture.hh b/src/include/simeng/arch/riscv/Architecture.hh index c78498a3f8..de0291dac7 100644 --- a/src/include/simeng/arch/riscv/Architecture.hh +++ b/src/include/simeng/arch/riscv/Architecture.hh @@ -49,11 +49,11 @@ class Architecture : public arch::Architecture { const uint64_t iterations) const override; private: - /** Retrieve an executionInfo object for the requested instruction. If a + /** Retrieve an ExecutionInfo object for the requested instruction. If a * opcode-based override has been defined for the latency and/or * port information, return that instead of the group-defined execution * information. */ - executionInfo getExecutionInfo(Instruction& insn) const; + ExecutionInfo getExecutionInfo(Instruction& insn) const; /** A decoding cache, mapping an instruction word to a previously decoded * instruction. Instructions are added to the cache as they're decoded, to @@ -69,11 +69,11 @@ class Architecture : public arch::Architecture { /** A map to hold the relationship between aarch64 instruction groups and * user-defined execution information. */ - std::unordered_map groupExecutionInfo_; + std::unordered_map groupExecutionInfo_; /** A map to hold the relationship between aarch64 instruction opcode and * user-defined execution information. */ - std::unordered_map opcodeExecutionInfo_; + std::unordered_map opcodeExecutionInfo_; /** A Capstone decoding library handle, for decoding instructions. */ csh capstoneHandle_; diff --git a/src/include/simeng/arch/riscv/Instruction.hh b/src/include/simeng/arch/riscv/Instruction.hh index d769fa7f69..93a90799ce 100644 --- a/src/include/simeng/arch/riscv/Instruction.hh +++ b/src/include/simeng/arch/riscv/Instruction.hh @@ -28,19 +28,6 @@ const uint8_t SYSTEM = 2; const Register ZERO_REGISTER = {GENERAL, (uint16_t)0}; } // namespace RegisterType -/** A struct holding user-defined execution information for a aarch64 - * instruction. */ -struct executionInfo { - /** The latency for the instruction. */ - uint16_t latency = 1; - - /** The execution throughput for the instruction. */ - uint16_t stallCycles = 1; - - /** The ports that support the instruction. */ - std::vector ports = {}; -}; - /** The various exceptions that can be raised by an individual instruction. */ enum class InstructionException { None = 0, @@ -158,7 +145,7 @@ class Instruction : public simeng::Instruction { /** Set this instruction's execution information including it's execution * latency and throughput, and the set of ports which support it. */ - void setExecutionInfo(const executionInfo& info); + void setExecutionInfo(const ExecutionInfo& info); /** Get this instruction's supported set of ports. */ const std::vector& getSupportedPorts() override; diff --git a/src/lib/arch/aarch64/Architecture.cc b/src/lib/arch/aarch64/Architecture.cc index abb02f0d14..d60476e5e6 100644 --- a/src/lib/arch/aarch64/Architecture.cc +++ b/src/lib/arch/aarch64/Architecture.cc @@ -130,8 +130,7 @@ Architecture::Architecture(kernel::Linux& kernel, ryml::ConstNodeRef config) // If latency information hasn't been defined, set to zero as to inform // later access to use group defined latencies instead uint16_t opcode = opcode_node[j].as(); - opcodeExecutionInfo_.try_emplace( - opcode, simeng::arch::aarch64::ExecutionInfo{0, 0, {}}); + opcodeExecutionInfo_.try_emplace(opcode, ExecutionInfo{0, 0, {}}); opcodeExecutionInfo_[opcode].ports.push_back(static_cast(i)); } } diff --git a/src/lib/arch/riscv/Architecture.cc b/src/lib/arch/riscv/Architecture.cc index 81e720118a..c330d699fd 100644 --- a/src/lib/arch/riscv/Architecture.cc +++ b/src/lib/arch/riscv/Architecture.cc @@ -40,7 +40,7 @@ Architecture::Architecture(kernel::Linux& kernel, ryml::ConstNodeRef config) RegisterType::SYSTEM, static_cast(getSystemRegisterTag(RISCV_SYSREG_CYCLE))}; - // Instantiate an executionInfo entry for each group in the InstructionGroup + // Instantiate an ExecutionInfo entry for each group in the InstructionGroup // namespace. for (int i = 0; i < NUM_GROUPS; i++) { groupExecutionInfo_[i] = {1, 1, {}}; @@ -131,8 +131,7 @@ Architecture::Architecture(kernel::Linux& kernel, ryml::ConstNodeRef config) // If latency information hasn't been defined, set to zero as to inform // later access to use group defined latencies instead uint16_t opcode = opcode_node[j].as(); - opcodeExecutionInfo_.try_emplace( - opcode, simeng::arch::riscv::executionInfo{0, 0, {}}); + opcodeExecutionInfo_.try_emplace(opcode, ExecutionInfo{0, 0, {}}); opcodeExecutionInfo_[opcode].ports.push_back(static_cast(i)); } } @@ -210,13 +209,13 @@ uint8_t Architecture::predecode(const void* ptr, uint16_t bytesAvailable, return 4; } -executionInfo Architecture::getExecutionInfo(Instruction& insn) const { +ExecutionInfo Architecture::getExecutionInfo(Instruction& insn) const { // Assume no opcode-based override - executionInfo exeInfo = groupExecutionInfo_.at(insn.getGroup()); + ExecutionInfo exeInfo = groupExecutionInfo_.at(insn.getGroup()); if (opcodeExecutionInfo_.find(insn.getMetadata().opcode) != opcodeExecutionInfo_.end()) { // Replace with overrided values - executionInfo overrideInfo = + ExecutionInfo overrideInfo = opcodeExecutionInfo_.at(insn.getMetadata().opcode); if (overrideInfo.latency != 0) exeInfo.latency = overrideInfo.latency; if (overrideInfo.stallCycles != 0) diff --git a/src/lib/arch/riscv/Instruction.cc b/src/lib/arch/riscv/Instruction.cc index cccba60b86..fdf6ce680d 100644 --- a/src/lib/arch/riscv/Instruction.cc +++ b/src/lib/arch/riscv/Instruction.cc @@ -149,7 +149,7 @@ uint16_t Instruction::getGroup() const { return base + 2; // Default return is {Data type}_SIMPLE_ARTH } -void Instruction::setExecutionInfo(const executionInfo& info) { +void Instruction::setExecutionInfo(const ExecutionInfo& info) { if (isLoad_ || isStore_) { lsqExecutionLatency_ = info.latency; } else { From 664d569a014cc93c75e398bade69c4003479e36f Mon Sep 17 00:00:00 2001 From: Finn Wilkinson Date: Wed, 7 Feb 2024 10:53:53 +0000 Subject: [PATCH 2/9] Made all static member variables in Architecture mutable, and moved common variables to base class. --- src/include/simeng/arch/Architecture.hh | 28 ++++++++++++ .../simeng/arch/aarch64/Architecture.hh | 44 +++++++------------ src/include/simeng/arch/riscv/Architecture.hh | 28 +++--------- src/lib/arch/aarch64/Architecture.cc | 38 ++++++++-------- src/lib/arch/riscv/Architecture.cc | 15 +++---- test/unit/MockArchitecture.hh | 2 + test/unit/aarch64/ArchitectureTest.cc | 19 -------- test/unit/aarch64/InstructionTest.cc | 1 - test/unit/pipeline/FetchUnitTest.cc | 5 +++ test/unit/riscv/InstructionTest.cc | 1 - 10 files changed, 82 insertions(+), 99 deletions(-) diff --git a/src/include/simeng/arch/Architecture.hh b/src/include/simeng/arch/Architecture.hh index f7f163815c..1eb2133a46 100644 --- a/src/include/simeng/arch/Architecture.hh +++ b/src/include/simeng/arch/Architecture.hh @@ -7,6 +7,7 @@ #include "simeng/Core.hh" #include "simeng/Instruction.hh" #include "simeng/MemoryInterface.hh" +#include "simeng/kernel/Linux.hh" namespace simeng { @@ -59,6 +60,8 @@ class ExceptionHandler { * ISA should provide a derived implementation of this class. */ class Architecture { public: + Architecture(kernel::Linux& kernel) : linux_(kernel) {} + virtual ~Architecture(){}; /** Attempt to pre-decode from `bytesAvailable` bytes of instruction memory. @@ -90,6 +93,31 @@ class Architecture { /** Updates System registers of any system-based timers. */ virtual void updateSystemTimerRegisters(RegisterFileSet* regFile, const uint64_t iterations) const = 0; + + protected: + /** A Capstone decoding library handle, for decoding instructions. */ + csh capstoneHandle_; + + /** A reference to a Linux kernel object to forward syscalls to. */ + kernel::Linux& linux_; + + /** A mapping from system register encoding to a zero-indexed tag. */ + std::unordered_map systemRegisterMap_; + + /** A map to hold the relationship between instruction groups and + * user-defined execution information. */ + std::unordered_map groupExecutionInfo_; + + /** A map to hold the relationship between instruction opcode and + * user-defined execution information. */ + std::unordered_map opcodeExecutionInfo_; + + private: + /** Retrieve an ExecutionInfo object for the requested instruction. If a + * opcode-based override has been defined for the latency and/or + * port information, return that instead of the group-defined execution + * information. */ + virtual ExecutionInfo getExecutionInfo(const Instruction& insn) const = 0; }; } // namespace arch diff --git a/src/include/simeng/arch/aarch64/Architecture.hh b/src/include/simeng/arch/aarch64/Architecture.hh index 37763d7fe6..30b8c8b395 100644 --- a/src/include/simeng/arch/aarch64/Architecture.hh +++ b/src/include/simeng/arch/aarch64/Architecture.hh @@ -7,7 +7,6 @@ #include "simeng/arch/Architecture.hh" #include "simeng/arch/aarch64/ExceptionHandler.hh" #include "simeng/arch/aarch64/MicroDecoder.hh" -#include "simeng/kernel/Linux.hh" using csh = size_t; @@ -59,12 +58,6 @@ class Architecture : public arch::Architecture { * configuration. */ uint64_t getStreamingVectorLength() const; - /** Retrieve an ExecutionInfo object for the requested instruction. If a - * opcode-based override has been defined for the latency and/or - * port information, return that instead of the group-defined execution - * information. */ - ExecutionInfo getExecutionInfo(Instruction& insn) const; - /** Returns the current value of SVCRval_. */ uint64_t getSVCRval() const; @@ -72,34 +65,22 @@ class Architecture : public arch::Architecture { void setSVCRval(const uint64_t newVal) const; private: + /** Retrieve an ExecutionInfo object for the requested instruction. If a + * opcode-based override has been defined for the latency and/or + * port information, return that instead of the group-defined execution + * information. */ + virtual ExecutionInfo getExecutionInfo( + const simeng::Instruction& insn) const override; + /** A decoding cache, mapping an instruction word to a previously decoded * instruction. Instructions are added to the cache as they're decoded, to * reduce the overhead of future decoding. */ - static std::unordered_map decodeCache_; + mutable std::unordered_map decodeCache_; + /** A decoding metadata cache, mapping an instruction word to a previously * decoded instruction metadata bundle. Metadata is added to the cache as it's * decoded, to reduce the overhead of future decoding. */ - static std::forward_list metadataCache_; - - /** A copy of the value of the SVCR system register. */ - static uint64_t SVCRval_; - - /** A mapping from system register encoding to a zero-indexed tag. */ - std::unordered_map systemRegisterMap_; - - /** A map to hold the relationship between aarch64 instruction groups and - * user-defined execution information. */ - std::unordered_map groupExecutionInfo_; - - /** A map to hold the relationship between aarch64 instruction opcode and - * user-defined execution information. */ - std::unordered_map opcodeExecutionInfo_; - - /** A Capstone decoding library handle, for decoding instructions. */ - csh capstoneHandle_; - - /** A reference to a Linux kernel object to forward syscalls to. */ - kernel::Linux& linux_; + mutable std::forward_list metadataCache_; /** A reference to a micro decoder object to split macro operations. */ std::unique_ptr microDecoder_; @@ -110,6 +91,9 @@ class Architecture : public arch::Architecture { /** The streaming vector length used by the SME extension in bits. */ uint64_t SVL_; + /** A copy of the value of the SVCR system register. */ + mutable uint64_t SVCRval_; + /** System Register of Virtual Counter Timer. */ simeng::Register VCTreg_; @@ -119,6 +103,8 @@ class Architecture : public arch::Architecture { /** Modulo component used to define the frequency at which the VCT is updated. */ double vctModulo_; + + friend class MicroDecoder; }; } // namespace aarch64 diff --git a/src/include/simeng/arch/riscv/Architecture.hh b/src/include/simeng/arch/riscv/Architecture.hh index de0291dac7..60391af59a 100644 --- a/src/include/simeng/arch/riscv/Architecture.hh +++ b/src/include/simeng/arch/riscv/Architecture.hh @@ -6,7 +6,6 @@ #include "simeng/arch/Architecture.hh" #include "simeng/arch/riscv/ExceptionHandler.hh" #include "simeng/arch/riscv/Instruction.hh" -#include "simeng/kernel/Linux.hh" using csh = size_t; @@ -19,7 +18,9 @@ class Architecture : public arch::Architecture { public: Architecture(kernel::Linux& kernel, ryml::ConstNodeRef config = config::SimInfo::getConfig()); + ~Architecture(); + /** Pre-decode instruction memory into a macro-op of `Instruction` * instances. Returns the number of bytes consumed to produce it (always 4), * and writes into the supplied macro-op vector. */ @@ -53,33 +54,18 @@ class Architecture : public arch::Architecture { * opcode-based override has been defined for the latency and/or * port information, return that instead of the group-defined execution * information. */ - ExecutionInfo getExecutionInfo(Instruction& insn) const; + ExecutionInfo getExecutionInfo( + const simeng::Instruction& insn) const override; /** A decoding cache, mapping an instruction word to a previously decoded * instruction. Instructions are added to the cache as they're decoded, to * reduce the overhead of future decoding. */ - static std::unordered_map decodeCache_; + mutable std::unordered_map decodeCache_; + /** A decoding metadata cache, mapping an instruction word to a previously * decoded instruction metadata bundle. Metadata is added to the cache as it's * decoded, to reduce the overhead of future decoding. */ - static std::forward_list metadataCache_; - - /** A mapping from system register encoding to a zero-indexed tag. */ - std::unordered_map systemRegisterMap_; - - /** A map to hold the relationship between aarch64 instruction groups and - * user-defined execution information. */ - std::unordered_map groupExecutionInfo_; - - /** A map to hold the relationship between aarch64 instruction opcode and - * user-defined execution information. */ - std::unordered_map opcodeExecutionInfo_; - - /** A Capstone decoding library handle, for decoding instructions. */ - csh capstoneHandle_; - - /** A reference to a Linux kernel object to forward syscalls to. */ - kernel::Linux& linux_; + mutable std::forward_list metadataCache_; /** System Register of Processor Cycle Counter. */ simeng::Register cycleSystemReg_; diff --git a/src/lib/arch/aarch64/Architecture.cc b/src/lib/arch/aarch64/Architecture.cc index d60476e5e6..638136addc 100644 --- a/src/lib/arch/aarch64/Architecture.cc +++ b/src/lib/arch/aarch64/Architecture.cc @@ -7,17 +7,13 @@ namespace simeng { namespace arch { namespace aarch64 { -std::unordered_map Architecture::decodeCache_; -std::forward_list Architecture::metadataCache_; -uint64_t Architecture::SVCRval_; - Architecture::Architecture(kernel::Linux& kernel, ryml::ConstNodeRef config) - : linux_(kernel), - microDecoder_(std::make_unique()), - VL_(config["Core"]["Vector-Length"].as()), - SVL_(config["Core"]["Streaming-Vector-Length"].as()), - vctModulo_((config["Core"]["Clock-Frequency-GHz"].as() * 1e9) / - (config["Core"]["Timer-Frequency-MHz"].as() * 1e6)) { + : arch::Architecture(kernel) { + microDecoder_ = std::make_unique(); + VL_ = config["Core"]["Vector-Length"].as(); + SVL_ = config["Core"]["Streaming-Vector-Length"].as(); + vctModulo_ = (config["Core"]["Clock-Frequency-GHz"].as() * 1e9) / + (config["Core"]["Timer-Frequency-MHz"].as() * 1e6); if (cs_open(CS_ARCH_ARM64, CS_MODE_ARM, &capstoneHandle_) != CS_ERR_OK) { std::cerr << "[SimEng:Architecture] Could not create capstone handle" << std::endl; @@ -40,8 +36,8 @@ Architecture::Architecture(kernel::Linux& kernel, ryml::ConstNodeRef config) RegisterType::SYSTEM, static_cast(getSystemRegisterTag(ARM64_SYSREG_PMCCNTR_EL0))}; - // Instantiate an ExecutionInfo entry for each group in the InstructionGroup - // namespace. + // Instantiate an ExecutionInfo entry for each group in the + // InstructionGroup namespace. for (int i = 0; i < NUM_GROUPS; i++) { groupExecutionInfo_[i] = {1, 1, {}}; } @@ -56,8 +52,8 @@ Architecture::Architecture(kernel::Linux& kernel, ryml::ConstNodeRef config) uint16_t group = port_node["Instruction-Group-Nums"][j].as(); groupExecutionInfo_[group].latency = latency; groupExecutionInfo_[group].stallCycles = throughput; - // Set zero inheritance distance for latency assignment as it's explicitly - // defined + // Set zero inheritance distance for latency assignment as it's + // explicitly defined inheritanceDistance[group] = 0; // Add inherited support for those appropriate groups std::queue groups; @@ -127,8 +123,8 @@ Architecture::Architecture(kernel::Linux& kernel, ryml::ConstNodeRef config) ryml::ConstNodeRef opcode_node = config["Ports"][i]["Instruction-Opcode-Support"]; for (size_t j = 0; j < opcode_node.num_children(); j++) { - // If latency information hasn't been defined, set to zero as to inform - // later access to use group defined latencies instead + // If latency information hasn't been defined, set to zero as to + // inform later access to use group defined latencies instead uint16_t opcode = opcode_node[j].as(); opcodeExecutionInfo_.try_emplace(opcode, ExecutionInfo{0, 0, {}}); opcodeExecutionInfo_[opcode].ports.push_back(static_cast(i)); @@ -211,14 +207,16 @@ uint8_t Architecture::predecode(const void* ptr, uint16_t bytesAvailable, return 4; } -ExecutionInfo Architecture::getExecutionInfo(Instruction& insn) const { +ExecutionInfo Architecture::getExecutionInfo( + const simeng::Instruction& insn) const { + auto insn_new = reinterpret_cast(insn); // Assume no opcode-based override - ExecutionInfo exeInfo = groupExecutionInfo_.at(insn.getGroup()); - if (opcodeExecutionInfo_.find(insn.getMetadata().opcode) != + ExecutionInfo exeInfo = groupExecutionInfo_.at(insn_new.getGroup()); + if (opcodeExecutionInfo_.find(insn_new.getMetadata().opcode) != opcodeExecutionInfo_.end()) { // Replace with overrided values ExecutionInfo overrideInfo = - opcodeExecutionInfo_.at(insn.getMetadata().opcode); + opcodeExecutionInfo_.at(insn_new.getMetadata().opcode); if (overrideInfo.latency != 0) exeInfo.latency = overrideInfo.latency; if (overrideInfo.stallCycles != 0) exeInfo.stallCycles = overrideInfo.stallCycles; diff --git a/src/lib/arch/riscv/Architecture.cc b/src/lib/arch/riscv/Architecture.cc index c330d699fd..fcd616fb99 100644 --- a/src/lib/arch/riscv/Architecture.cc +++ b/src/lib/arch/riscv/Architecture.cc @@ -11,11 +11,8 @@ namespace simeng { namespace arch { namespace riscv { -std::unordered_map Architecture::decodeCache_; -std::forward_list Architecture::metadataCache_; - Architecture::Architecture(kernel::Linux& kernel, ryml::ConstNodeRef config) - : linux_(kernel) { + : arch::Architecture(kernel) { // Set initial rounding mode for F/D extensions // TODO set fcsr accordingly when Zicsr extension supported fesetround(FE_TONEAREST); @@ -209,14 +206,16 @@ uint8_t Architecture::predecode(const void* ptr, uint16_t bytesAvailable, return 4; } -ExecutionInfo Architecture::getExecutionInfo(Instruction& insn) const { +ExecutionInfo Architecture::getExecutionInfo( + const simeng::Instruction& insn) const { + auto insn_new = reinterpret_cast(insn); // Assume no opcode-based override - ExecutionInfo exeInfo = groupExecutionInfo_.at(insn.getGroup()); - if (opcodeExecutionInfo_.find(insn.getMetadata().opcode) != + ExecutionInfo exeInfo = groupExecutionInfo_.at(insn_new.getGroup()); + if (opcodeExecutionInfo_.find(insn_new.getMetadata().opcode) != opcodeExecutionInfo_.end()) { // Replace with overrided values ExecutionInfo overrideInfo = - opcodeExecutionInfo_.at(insn.getMetadata().opcode); + opcodeExecutionInfo_.at(insn_new.getMetadata().opcode); if (overrideInfo.latency != 0) exeInfo.latency = overrideInfo.latency; if (overrideInfo.stallCycles != 0) exeInfo.stallCycles = overrideInfo.stallCycles; diff --git a/test/unit/MockArchitecture.hh b/test/unit/MockArchitecture.hh index 7795571f2f..fac0582f13 100644 --- a/test/unit/MockArchitecture.hh +++ b/test/unit/MockArchitecture.hh @@ -8,6 +8,7 @@ namespace simeng { /** Mock implementation of the `Architecture` interface. */ class MockArchitecture : public arch::Architecture { public: + MockArchitecture(kernel::Linux& kernel) : arch::Architecture(kernel) {} MOCK_CONST_METHOD4(predecode, uint8_t(const void* ptr, uint16_t bytesAvailable, uint64_t instructionAddress, MacroOp& output)); @@ -21,6 +22,7 @@ class MockArchitecture : public arch::Architecture { MOCK_CONST_METHOD0(getMaxInstructionSize, uint8_t()); MOCK_CONST_METHOD2(updateSystemTimerRegisters, void(RegisterFileSet* regFile, const uint64_t iterations)); + MOCK_CONST_METHOD1(getExecutionInfo, ExecutionInfo(const Instruction& insn)); }; } // namespace simeng diff --git a/test/unit/aarch64/ArchitectureTest.cc b/test/unit/aarch64/ArchitectureTest.cc index 29238dd4dc..163eec59ec 100644 --- a/test/unit/aarch64/ArchitectureTest.cc +++ b/test/unit/aarch64/ArchitectureTest.cc @@ -214,25 +214,6 @@ TEST_F(AArch64ArchitectureTest, updateSystemTimerRegisters) { } } -TEST_F(AArch64ArchitectureTest, getExecutionInfo) { - MacroOp insn; - uint64_t bytes = arch->predecode(validInstrBytes.data(), - validInstrBytes.size(), 0x4, insn); - // Insn[0] = fdivr z1.s, p0/m, z1.s, z0.s - Instruction* aarch64Insn = reinterpret_cast(insn[0].get()); - EXPECT_EQ(bytes, 4); - EXPECT_EQ(aarch64Insn->getInstructionAddress(), 0x4); - EXPECT_EQ(aarch64Insn->exceptionEncountered(), false); - - ExecutionInfo info = arch->getExecutionInfo(*aarch64Insn); - - // Latencies and Port numbers from a64fx.yaml - EXPECT_EQ(info.latency, 98); - EXPECT_EQ(info.stallCycles, 98); - std::vector ports = {0}; - EXPECT_EQ(info.ports, ports); -} - TEST_F(AArch64ArchitectureTest, get_set_SVCRVal) { EXPECT_EQ(arch->getSVCRval(), 0); arch->setSVCRval(3); diff --git a/test/unit/aarch64/InstructionTest.cc b/test/unit/aarch64/InstructionTest.cc index 20dddcca18..1613262588 100644 --- a/test/unit/aarch64/InstructionTest.cc +++ b/test/unit/aarch64/InstructionTest.cc @@ -1,5 +1,4 @@ #include "../ConfigInit.hh" -#include "../MockArchitecture.hh" #include "arch/aarch64/InstructionMetadata.hh" #include "gmock/gmock.h" #include "simeng/arch/aarch64/Instruction.hh" diff --git a/test/unit/pipeline/FetchUnitTest.cc b/test/unit/pipeline/FetchUnitTest.cc index f404029640..2a523479e9 100644 --- a/test/unit/pipeline/FetchUnitTest.cc +++ b/test/unit/pipeline/FetchUnitTest.cc @@ -6,6 +6,7 @@ #include "gtest/gtest.h" #include "simeng/Instruction.hh" #include "simeng/arch/Architecture.hh" +#include "simeng/kernel/Linux.hh" #include "simeng/pipeline/FetchUnit.hh" #include "simeng/pipeline/PipelineBuffer.hh" @@ -29,6 +30,9 @@ class PipelineFetchUnitTest : public testing::Test { public: PipelineFetchUnitTest() : output(1, {}), + linux(config::SimInfo::getConfig()["CPU-Info"]["Special-File-Dir-Path"] + .as()), + isa(linux), fetchBuffer({{0, 16}, 0, 0}), completedReads(&fetchBuffer, 1), fetchUnit(output, memory, 1024, 0, blockSize, isa, predictor), @@ -45,6 +49,7 @@ class PipelineFetchUnitTest : public testing::Test { PipelineBuffer output; MockMemoryInterface memory; + kernel::Linux linux; MockArchitecture isa; MockBranchPredictor predictor; diff --git a/test/unit/riscv/InstructionTest.cc b/test/unit/riscv/InstructionTest.cc index 37580c4f80..baf8073402 100644 --- a/test/unit/riscv/InstructionTest.cc +++ b/test/unit/riscv/InstructionTest.cc @@ -1,5 +1,4 @@ #include "../ConfigInit.hh" -#include "../MockArchitecture.hh" #include "arch/riscv/InstructionMetadata.hh" #include "gmock/gmock.h" #include "simeng/arch/riscv/Instruction.hh" From 65bdece1447b4fed6ca64813fd70a2b1f1f125ea Mon Sep 17 00:00:00 2001 From: Finn Wilkinson Date: Wed, 7 Feb 2024 11:04:34 +0000 Subject: [PATCH 3/9] removed getExecutionInfo() from base architecture class. --- src/include/simeng/arch/Architecture.hh | 7 ------- .../simeng/arch/aarch64/Architecture.hh | 15 ++++++--------- src/include/simeng/arch/riscv/Architecture.hh | 3 +-- src/lib/arch/aarch64/Architecture.cc | 10 ++++------ src/lib/arch/riscv/Architecture.cc | 10 ++++------ test/unit/MockArchitecture.hh | 1 - test/unit/aarch64/ArchitectureTest.cc | 19 +++++++++++++++++++ 7 files changed, 34 insertions(+), 31 deletions(-) diff --git a/src/include/simeng/arch/Architecture.hh b/src/include/simeng/arch/Architecture.hh index 1eb2133a46..02b293bf25 100644 --- a/src/include/simeng/arch/Architecture.hh +++ b/src/include/simeng/arch/Architecture.hh @@ -111,13 +111,6 @@ class Architecture { /** A map to hold the relationship between instruction opcode and * user-defined execution information. */ std::unordered_map opcodeExecutionInfo_; - - private: - /** Retrieve an ExecutionInfo object for the requested instruction. If a - * opcode-based override has been defined for the latency and/or - * port information, return that instead of the group-defined execution - * information. */ - virtual ExecutionInfo getExecutionInfo(const Instruction& insn) const = 0; }; } // namespace arch diff --git a/src/include/simeng/arch/aarch64/Architecture.hh b/src/include/simeng/arch/aarch64/Architecture.hh index 30b8c8b395..bbae36d5c1 100644 --- a/src/include/simeng/arch/aarch64/Architecture.hh +++ b/src/include/simeng/arch/aarch64/Architecture.hh @@ -29,6 +29,12 @@ class Architecture : public arch::Architecture { uint64_t instructionAddress, MacroOp& output) const override; + /** Retrieve an ExecutionInfo object for the requested instruction. If a + * opcode-based override has been defined for the latency and/or + * port information, return that instead of the group-defined execution + * information. */ + virtual ExecutionInfo getExecutionInfo(const Instruction& insn) const; + /** Returns a zero-indexed register tag for a system register encoding. * Returns -1 in the case that the system register has no mapping. */ int32_t getSystemRegisterTag(uint16_t reg) const override; @@ -65,13 +71,6 @@ class Architecture : public arch::Architecture { void setSVCRval(const uint64_t newVal) const; private: - /** Retrieve an ExecutionInfo object for the requested instruction. If a - * opcode-based override has been defined for the latency and/or - * port information, return that instead of the group-defined execution - * information. */ - virtual ExecutionInfo getExecutionInfo( - const simeng::Instruction& insn) const override; - /** A decoding cache, mapping an instruction word to a previously decoded * instruction. Instructions are added to the cache as they're decoded, to * reduce the overhead of future decoding. */ @@ -103,8 +102,6 @@ class Architecture : public arch::Architecture { /** Modulo component used to define the frequency at which the VCT is updated. */ double vctModulo_; - - friend class MicroDecoder; }; } // namespace aarch64 diff --git a/src/include/simeng/arch/riscv/Architecture.hh b/src/include/simeng/arch/riscv/Architecture.hh index 60391af59a..2e45be7cfa 100644 --- a/src/include/simeng/arch/riscv/Architecture.hh +++ b/src/include/simeng/arch/riscv/Architecture.hh @@ -54,8 +54,7 @@ class Architecture : public arch::Architecture { * opcode-based override has been defined for the latency and/or * port information, return that instead of the group-defined execution * information. */ - ExecutionInfo getExecutionInfo( - const simeng::Instruction& insn) const override; + ExecutionInfo getExecutionInfo(const Instruction& insn) const; /** A decoding cache, mapping an instruction word to a previously decoded * instruction. Instructions are added to the cache as they're decoded, to diff --git a/src/lib/arch/aarch64/Architecture.cc b/src/lib/arch/aarch64/Architecture.cc index 638136addc..04b2a4909c 100644 --- a/src/lib/arch/aarch64/Architecture.cc +++ b/src/lib/arch/aarch64/Architecture.cc @@ -207,16 +207,14 @@ uint8_t Architecture::predecode(const void* ptr, uint16_t bytesAvailable, return 4; } -ExecutionInfo Architecture::getExecutionInfo( - const simeng::Instruction& insn) const { - auto insn_new = reinterpret_cast(insn); +ExecutionInfo Architecture::getExecutionInfo(const Instruction& insn) const { // Assume no opcode-based override - ExecutionInfo exeInfo = groupExecutionInfo_.at(insn_new.getGroup()); - if (opcodeExecutionInfo_.find(insn_new.getMetadata().opcode) != + ExecutionInfo exeInfo = groupExecutionInfo_.at(insn.getGroup()); + if (opcodeExecutionInfo_.find(insn.getMetadata().opcode) != opcodeExecutionInfo_.end()) { // Replace with overrided values ExecutionInfo overrideInfo = - opcodeExecutionInfo_.at(insn_new.getMetadata().opcode); + opcodeExecutionInfo_.at(insn.getMetadata().opcode); if (overrideInfo.latency != 0) exeInfo.latency = overrideInfo.latency; if (overrideInfo.stallCycles != 0) exeInfo.stallCycles = overrideInfo.stallCycles; diff --git a/src/lib/arch/riscv/Architecture.cc b/src/lib/arch/riscv/Architecture.cc index fcd616fb99..0c03d46de6 100644 --- a/src/lib/arch/riscv/Architecture.cc +++ b/src/lib/arch/riscv/Architecture.cc @@ -206,16 +206,14 @@ uint8_t Architecture::predecode(const void* ptr, uint16_t bytesAvailable, return 4; } -ExecutionInfo Architecture::getExecutionInfo( - const simeng::Instruction& insn) const { - auto insn_new = reinterpret_cast(insn); +ExecutionInfo Architecture::getExecutionInfo(const Instruction& insn) const { // Assume no opcode-based override - ExecutionInfo exeInfo = groupExecutionInfo_.at(insn_new.getGroup()); - if (opcodeExecutionInfo_.find(insn_new.getMetadata().opcode) != + ExecutionInfo exeInfo = groupExecutionInfo_.at(insn.getGroup()); + if (opcodeExecutionInfo_.find(insn.getMetadata().opcode) != opcodeExecutionInfo_.end()) { // Replace with overrided values ExecutionInfo overrideInfo = - opcodeExecutionInfo_.at(insn_new.getMetadata().opcode); + opcodeExecutionInfo_.at(insn.getMetadata().opcode); if (overrideInfo.latency != 0) exeInfo.latency = overrideInfo.latency; if (overrideInfo.stallCycles != 0) exeInfo.stallCycles = overrideInfo.stallCycles; diff --git a/test/unit/MockArchitecture.hh b/test/unit/MockArchitecture.hh index fac0582f13..fb26a60b91 100644 --- a/test/unit/MockArchitecture.hh +++ b/test/unit/MockArchitecture.hh @@ -22,7 +22,6 @@ class MockArchitecture : public arch::Architecture { MOCK_CONST_METHOD0(getMaxInstructionSize, uint8_t()); MOCK_CONST_METHOD2(updateSystemTimerRegisters, void(RegisterFileSet* regFile, const uint64_t iterations)); - MOCK_CONST_METHOD1(getExecutionInfo, ExecutionInfo(const Instruction& insn)); }; } // namespace simeng diff --git a/test/unit/aarch64/ArchitectureTest.cc b/test/unit/aarch64/ArchitectureTest.cc index 163eec59ec..29238dd4dc 100644 --- a/test/unit/aarch64/ArchitectureTest.cc +++ b/test/unit/aarch64/ArchitectureTest.cc @@ -214,6 +214,25 @@ TEST_F(AArch64ArchitectureTest, updateSystemTimerRegisters) { } } +TEST_F(AArch64ArchitectureTest, getExecutionInfo) { + MacroOp insn; + uint64_t bytes = arch->predecode(validInstrBytes.data(), + validInstrBytes.size(), 0x4, insn); + // Insn[0] = fdivr z1.s, p0/m, z1.s, z0.s + Instruction* aarch64Insn = reinterpret_cast(insn[0].get()); + EXPECT_EQ(bytes, 4); + EXPECT_EQ(aarch64Insn->getInstructionAddress(), 0x4); + EXPECT_EQ(aarch64Insn->exceptionEncountered(), false); + + ExecutionInfo info = arch->getExecutionInfo(*aarch64Insn); + + // Latencies and Port numbers from a64fx.yaml + EXPECT_EQ(info.latency, 98); + EXPECT_EQ(info.stallCycles, 98); + std::vector ports = {0}; + EXPECT_EQ(info.ports, ports); +} + TEST_F(AArch64ArchitectureTest, get_set_SVCRVal) { EXPECT_EQ(arch->getSVCRval(), 0); arch->setSVCRval(3); From fd37bc57863186fc7dde0d1c8cbfdafae8edc493 Mon Sep 17 00:00:00 2001 From: Finn Wilkinson Date: Wed, 7 Feb 2024 11:14:34 +0000 Subject: [PATCH 4/9] Ensured .hh and .cc function ordering matches for aarch64 and riscv architecture classes. --- .../simeng/arch/aarch64/Architecture.hh | 12 ++--- src/lib/arch/aarch64/Architecture.cc | 52 ++++++++++--------- src/lib/arch/riscv/Architecture.cc | 45 ++++++++-------- 3 files changed, 56 insertions(+), 53 deletions(-) diff --git a/src/include/simeng/arch/aarch64/Architecture.hh b/src/include/simeng/arch/aarch64/Architecture.hh index bbae36d5c1..4b27569230 100644 --- a/src/include/simeng/arch/aarch64/Architecture.hh +++ b/src/include/simeng/arch/aarch64/Architecture.hh @@ -29,12 +29,6 @@ class Architecture : public arch::Architecture { uint64_t instructionAddress, MacroOp& output) const override; - /** Retrieve an ExecutionInfo object for the requested instruction. If a - * opcode-based override has been defined for the latency and/or - * port information, return that instead of the group-defined execution - * information. */ - virtual ExecutionInfo getExecutionInfo(const Instruction& insn) const; - /** Returns a zero-indexed register tag for a system register encoding. * Returns -1 in the case that the system register has no mapping. */ int32_t getSystemRegisterTag(uint16_t reg) const override; @@ -57,6 +51,12 @@ class Architecture : public arch::Architecture { void updateSystemTimerRegisters(RegisterFileSet* regFile, const uint64_t iterations) const override; + /** Retrieve an ExecutionInfo object for the requested instruction. If a + * opcode-based override has been defined for the latency and/or + * port information, return that instead of the group-defined execution + * information. */ + virtual ExecutionInfo getExecutionInfo(const Instruction& insn) const; + /** Returns the current vector length set by the provided configuration. */ uint64_t getVectorLength() const; diff --git a/src/lib/arch/aarch64/Architecture.cc b/src/lib/arch/aarch64/Architecture.cc index 04b2a4909c..fb746c0a65 100644 --- a/src/lib/arch/aarch64/Architecture.cc +++ b/src/lib/arch/aarch64/Architecture.cc @@ -132,6 +132,7 @@ Architecture::Architecture(kernel::Linux& kernel, ryml::ConstNodeRef config) } } } + Architecture::~Architecture() { cs_close(&capstoneHandle_); decodeCache_.clear(); @@ -207,27 +208,6 @@ uint8_t Architecture::predecode(const void* ptr, uint16_t bytesAvailable, return 4; } -ExecutionInfo Architecture::getExecutionInfo(const Instruction& insn) const { - // Assume no opcode-based override - ExecutionInfo exeInfo = groupExecutionInfo_.at(insn.getGroup()); - if (opcodeExecutionInfo_.find(insn.getMetadata().opcode) != - opcodeExecutionInfo_.end()) { - // Replace with overrided values - ExecutionInfo overrideInfo = - opcodeExecutionInfo_.at(insn.getMetadata().opcode); - if (overrideInfo.latency != 0) exeInfo.latency = overrideInfo.latency; - if (overrideInfo.stallCycles != 0) - exeInfo.stallCycles = overrideInfo.stallCycles; - if (overrideInfo.ports.size()) exeInfo.ports = overrideInfo.ports; - } - return exeInfo; -} - -std::shared_ptr Architecture::handleException( - const std::shared_ptr& instruction, const Core& core, - MemoryInterface& memory) const { - return std::make_shared(instruction, core, memory, linux_); -} int32_t Architecture::getSystemRegisterTag(uint16_t reg) const { // Check below is done for speculative instructions that may be passed into // the function but will not be executed. If such invalid speculative @@ -236,6 +216,12 @@ int32_t Architecture::getSystemRegisterTag(uint16_t reg) const { return systemRegisterMap_.at(reg); } +std::shared_ptr Architecture::handleException( + const std::shared_ptr& instruction, const Core& core, + MemoryInterface& memory) const { + return std::make_shared(instruction, core, memory, linux_); +} + ProcessStateChange Architecture::getInitialState() const { ProcessStateChange changes; // Set ProcessStateChange type @@ -259,10 +245,6 @@ ProcessStateChange Architecture::getInitialState() const { uint8_t Architecture::getMaxInstructionSize() const { return 4; } -uint64_t Architecture::getVectorLength() const { return VL_; } - -uint64_t Architecture::getStreamingVectorLength() const { return SVL_; } - void Architecture::updateSystemTimerRegisters(RegisterFileSet* regFile, const uint64_t iterations) const { // Update the Processor Cycle Counter to total cycles completed. @@ -273,6 +255,26 @@ void Architecture::updateSystemTimerRegisters(RegisterFileSet* regFile, } } +ExecutionInfo Architecture::getExecutionInfo(const Instruction& insn) const { + // Assume no opcode-based override + ExecutionInfo exeInfo = groupExecutionInfo_.at(insn.getGroup()); + if (opcodeExecutionInfo_.find(insn.getMetadata().opcode) != + opcodeExecutionInfo_.end()) { + // Replace with overrided values + ExecutionInfo overrideInfo = + opcodeExecutionInfo_.at(insn.getMetadata().opcode); + if (overrideInfo.latency != 0) exeInfo.latency = overrideInfo.latency; + if (overrideInfo.stallCycles != 0) + exeInfo.stallCycles = overrideInfo.stallCycles; + if (overrideInfo.ports.size()) exeInfo.ports = overrideInfo.ports; + } + return exeInfo; +} + +uint64_t Architecture::getVectorLength() const { return VL_; } + +uint64_t Architecture::getStreamingVectorLength() const { return SVL_; } + /** The SVCR value is stored in Architecture to allow the value to be * retrieved within execution pipeline. This prevents adding an implicit * operand to every SME instruction; reducing the amount of complexity when diff --git a/src/lib/arch/riscv/Architecture.cc b/src/lib/arch/riscv/Architecture.cc index 0c03d46de6..5a98934dd3 100644 --- a/src/lib/arch/riscv/Architecture.cc +++ b/src/lib/arch/riscv/Architecture.cc @@ -134,6 +134,7 @@ Architecture::Architecture(kernel::Linux& kernel, ryml::ConstNodeRef config) } } } + Architecture::~Architecture() { cs_close(&capstoneHandle_); decodeCache_.clear(); @@ -206,28 +207,6 @@ uint8_t Architecture::predecode(const void* ptr, uint16_t bytesAvailable, return 4; } -ExecutionInfo Architecture::getExecutionInfo(const Instruction& insn) const { - // Assume no opcode-based override - ExecutionInfo exeInfo = groupExecutionInfo_.at(insn.getGroup()); - if (opcodeExecutionInfo_.find(insn.getMetadata().opcode) != - opcodeExecutionInfo_.end()) { - // Replace with overrided values - ExecutionInfo overrideInfo = - opcodeExecutionInfo_.at(insn.getMetadata().opcode); - if (overrideInfo.latency != 0) exeInfo.latency = overrideInfo.latency; - if (overrideInfo.stallCycles != 0) - exeInfo.stallCycles = overrideInfo.stallCycles; - if (overrideInfo.ports.size()) exeInfo.ports = overrideInfo.ports; - } - return exeInfo; -} - -std::shared_ptr Architecture::handleException( - const std::shared_ptr& instruction, const Core& core, - MemoryInterface& memory) const { - return std::make_shared(instruction, core, memory, linux_); -} - int32_t Architecture::getSystemRegisterTag(uint16_t reg) const { // Check below is done for speculative instructions that may be passed into // the function but will not be executed. If such invalid speculative @@ -236,6 +215,12 @@ int32_t Architecture::getSystemRegisterTag(uint16_t reg) const { return systemRegisterMap_.at(reg); } +std::shared_ptr Architecture::handleException( + const std::shared_ptr& instruction, const Core& core, + MemoryInterface& memory) const { + return std::make_shared(instruction, core, memory, linux_); +} + ProcessStateChange Architecture::getInitialState() const { ProcessStateChange changes; // Set ProcessStateChange type @@ -256,6 +241,22 @@ void Architecture::updateSystemTimerRegisters(RegisterFileSet* regFile, regFile->set(cycleSystemReg_, iterations); } +ExecutionInfo Architecture::getExecutionInfo(const Instruction& insn) const { + // Assume no opcode-based override + ExecutionInfo exeInfo = groupExecutionInfo_.at(insn.getGroup()); + if (opcodeExecutionInfo_.find(insn.getMetadata().opcode) != + opcodeExecutionInfo_.end()) { + // Replace with overrided values + ExecutionInfo overrideInfo = + opcodeExecutionInfo_.at(insn.getMetadata().opcode); + if (overrideInfo.latency != 0) exeInfo.latency = overrideInfo.latency; + if (overrideInfo.stallCycles != 0) + exeInfo.stallCycles = overrideInfo.stallCycles; + if (overrideInfo.ports.size()) exeInfo.ports = overrideInfo.ports; + } + return exeInfo; +} + } // namespace riscv } // namespace arch } // namespace simeng From f480b7b3fa9e7a0a278725310c995e9e2d653ed2 Mon Sep 17 00:00:00 2001 From: Finn Wilkinson Date: Wed, 7 Feb 2024 11:37:36 +0000 Subject: [PATCH 5/9] Added underscores to member vairables which were missing them. --- src/lib/arch/aarch64/Architecture.cc | 8 +------- src/lib/arch/riscv/Architecture.cc | 7 +------ 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/src/lib/arch/aarch64/Architecture.cc b/src/lib/arch/aarch64/Architecture.cc index fb746c0a65..b4fc298fb3 100644 --- a/src/lib/arch/aarch64/Architecture.cc +++ b/src/lib/arch/aarch64/Architecture.cc @@ -133,13 +133,7 @@ Architecture::Architecture(kernel::Linux& kernel, ryml::ConstNodeRef config) } } -Architecture::~Architecture() { - cs_close(&capstoneHandle_); - decodeCache_.clear(); - metadataCache_.clear(); - groupExecutionInfo_.clear(); - SVCRval_ = 0; -} +Architecture::~Architecture() { cs_close(&capstoneHandle_); } uint8_t Architecture::predecode(const void* ptr, uint16_t bytesAvailable, uint64_t instructionAddress, diff --git a/src/lib/arch/riscv/Architecture.cc b/src/lib/arch/riscv/Architecture.cc index 5a98934dd3..01bce46fed 100644 --- a/src/lib/arch/riscv/Architecture.cc +++ b/src/lib/arch/riscv/Architecture.cc @@ -135,12 +135,7 @@ Architecture::Architecture(kernel::Linux& kernel, ryml::ConstNodeRef config) } } -Architecture::~Architecture() { - cs_close(&capstoneHandle_); - decodeCache_.clear(); - metadataCache_.clear(); - groupExecutionInfo_.clear(); -} +Architecture::~Architecture() { cs_close(&capstoneHandle_); } uint8_t Architecture::predecode(const void* ptr, uint16_t bytesAvailable, uint64_t instructionAddress, From 7a93fb6c356416f3ff468ebf66d8366d441104a7 Mon Sep 17 00:00:00 2001 From: Finn Wilkinson Date: Thu, 8 Feb 2024 11:48:05 +0000 Subject: [PATCH 6/9] Fix for failing SVCR test. --- src/include/simeng/arch/aarch64/Architecture.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/include/simeng/arch/aarch64/Architecture.hh b/src/include/simeng/arch/aarch64/Architecture.hh index 4b27569230..cfba757341 100644 --- a/src/include/simeng/arch/aarch64/Architecture.hh +++ b/src/include/simeng/arch/aarch64/Architecture.hh @@ -91,7 +91,7 @@ class Architecture : public arch::Architecture { uint64_t SVL_; /** A copy of the value of the SVCR system register. */ - mutable uint64_t SVCRval_; + mutable uint64_t SVCRval_ = 0; /** System Register of Virtual Counter Timer. */ simeng::Register VCTreg_; From 4acc294a0c70c62e27994a223ef066eba1c688f0 Mon Sep 17 00:00:00 2001 From: Finn Wilkinson Date: Thu, 8 Feb 2024 14:29:01 +0000 Subject: [PATCH 7/9] re-added initialiser list to aarch64 arch class. --- src/lib/arch/aarch64/Architecture.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/lib/arch/aarch64/Architecture.cc b/src/lib/arch/aarch64/Architecture.cc index b4fc298fb3..9de2742594 100644 --- a/src/lib/arch/aarch64/Architecture.cc +++ b/src/lib/arch/aarch64/Architecture.cc @@ -8,12 +8,12 @@ namespace arch { namespace aarch64 { Architecture::Architecture(kernel::Linux& kernel, ryml::ConstNodeRef config) - : arch::Architecture(kernel) { - microDecoder_ = std::make_unique(); - VL_ = config["Core"]["Vector-Length"].as(); - SVL_ = config["Core"]["Streaming-Vector-Length"].as(); - vctModulo_ = (config["Core"]["Clock-Frequency-GHz"].as() * 1e9) / - (config["Core"]["Timer-Frequency-MHz"].as() * 1e6); + : arch::Architecture(kernel), + microDecoder_(std::make_unique()), + VL_(config["Core"]["Vector-Length"].as()), + SVL_(config["Core"]["Streaming-Vector-Length"].as()), + vctModulo_((config["Core"]["Clock-Frequency-GHz"].as() * 1e9) / + (config["Core"]["Timer-Frequency-MHz"].as() * 1e6)) { if (cs_open(CS_ARCH_ARM64, CS_MODE_ARM, &capstoneHandle_) != CS_ERR_OK) { std::cerr << "[SimEng:Architecture] Could not create capstone handle" << std::endl; From 17f05f89e084e18b774ea5a92706cab925d0db57 Mon Sep 17 00:00:00 2001 From: Finn Wilkinson Date: Thu, 8 Feb 2024 16:54:37 +0000 Subject: [PATCH 8/9] Removed un-needed header. --- test/unit/pipeline/FetchUnitTest.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/pipeline/FetchUnitTest.cc b/test/unit/pipeline/FetchUnitTest.cc index 2a523479e9..ae82d77f93 100644 --- a/test/unit/pipeline/FetchUnitTest.cc +++ b/test/unit/pipeline/FetchUnitTest.cc @@ -6,7 +6,7 @@ #include "gtest/gtest.h" #include "simeng/Instruction.hh" #include "simeng/arch/Architecture.hh" -#include "simeng/kernel/Linux.hh" +// #include "simeng/kernel/Linux.hh" #include "simeng/pipeline/FetchUnit.hh" #include "simeng/pipeline/PipelineBuffer.hh" From 3208192ceccfeadd40f66dd1f0e33bb129ee37ee Mon Sep 17 00:00:00 2001 From: Finn Wilkinson Date: Thu, 8 Feb 2024 17:20:49 +0000 Subject: [PATCH 9/9] Removed commented out header. --- test/unit/pipeline/FetchUnitTest.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/test/unit/pipeline/FetchUnitTest.cc b/test/unit/pipeline/FetchUnitTest.cc index ae82d77f93..5ef3e23ed3 100644 --- a/test/unit/pipeline/FetchUnitTest.cc +++ b/test/unit/pipeline/FetchUnitTest.cc @@ -6,7 +6,6 @@ #include "gtest/gtest.h" #include "simeng/Instruction.hh" #include "simeng/arch/Architecture.hh" -// #include "simeng/kernel/Linux.hh" #include "simeng/pipeline/FetchUnit.hh" #include "simeng/pipeline/PipelineBuffer.hh"