diff --git a/src/core/sal/CPU.cc b/src/core/sal/CPU.cc index e701e062..2315fa92 100644 --- a/src/core/sal/CPU.cc +++ b/src/core/sal/CPU.cc @@ -1,15 +1,19 @@ +#include #include "CPU.hpp" namespace fail { -void CPUArchitecture::m_addRegister(Register* reg) +void CPUArchitecture::m_addRegister(Register* reg, RegisterType type) { - assert(!reg->isAssigned() && "FATAL ERROR: The register is already assigned!"); - m_Registers.push_back(reg); + // We may be called multiple times with the same register, if it needs to + // reside in multiple subsets. + if (std::find(m_Registers.begin(), m_Registers.end(), reg) == m_Registers.end()) { + m_Registers.push_back(reg); + } - UniformRegisterSet* urs = getRegisterSetOfType(reg->getType()); - if (urs == NULL) { - urs = new UniformRegisterSet(reg->getType()); + UniformRegisterSet* urs = getRegisterSetOfType(type); + if (!urs) { + urs = new UniformRegisterSet(type); m_RegisterSubsets.push_back(urs); } urs->m_add(reg); @@ -34,7 +38,7 @@ UniformRegisterSet* CPUArchitecture::getRegisterSetOfType(RegisterType t) const if ((*it)->getType() == t) return *it; } - return NULL; + return 0; } } // end-of-namespace: fail diff --git a/src/core/sal/CPU.hpp b/src/core/sal/CPU.hpp index 27a14135..65ff9d3e 100644 --- a/src/core/sal/CPU.hpp +++ b/src/core/sal/CPU.hpp @@ -73,7 +73,7 @@ protected: * @param reg a pointer to the register object to be added * @see getType() */ - void m_addRegister(Register* reg); + void m_addRegister(Register* reg, RegisterType type = RT_NONE); }; } // end-of-namespace: fail diff --git a/src/core/sal/Register.cc b/src/core/sal/Register.cc index 2e1bfac2..bf9f4e36 100644 --- a/src/core/sal/Register.cc +++ b/src/core/sal/Register.cc @@ -10,11 +10,8 @@ Register* UniformRegisterSet::getRegister(size_t i) const void UniformRegisterSet::m_add(Register* preg) { - assert(!preg->m_Assigned && - "FATAL ERROR: The register has already been assigned."); + assert(std::find(m_Regs.begin(), m_Regs.end(), preg) == m_Regs.end()); m_Regs.push_back(preg); - preg->m_Assigned = true; - preg->m_Index = m_Regs.size()-1; // the index within the vector (set) } } // end-of-namespace: fail diff --git a/src/core/sal/Register.hpp b/src/core/sal/Register.hpp index f349237e..96ff6505 100644 --- a/src/core/sal/Register.hpp +++ b/src/core/sal/Register.hpp @@ -19,10 +19,11 @@ namespace fail { * specific to a simulator/architecture. */ enum RegisterType { - RT_GP, //!< general purpose - RT_FP, //!< floating point register - RT_IP, //!< program counter / instruction pointer - RT_ST //!< status register + RT_NONE, //!< no classification + RT_GP, //!< general purpose + RT_FP, //!< floating point register + RT_IP, //!< program counter / instruction pointer + RT_ST //!< status register }; /** @@ -33,13 +34,8 @@ enum RegisterType { */ class Register { protected: - RegisterType m_Type; //!< the type of this register regwidth_t m_Width; //!< the register width unsigned int m_Id; //!< the unique id of this register - //! \c true if register has already been assigned, \c false otherwise - bool m_Assigned; - //! The index in it's register set if assigned (\c -1 otherwise) - size_t m_Index; std::string m_Name; //!< The (optional) name, maybe empty friend class UniformRegisterSet; public: @@ -49,14 +45,8 @@ public: * @param t the type of the register to be constructed * @param w the width of the register in bits */ - Register(unsigned int id, RegisterType t, regwidth_t w) - : m_Type(t), m_Width(w), m_Id(id), m_Assigned(false), - m_Index(static_cast(-1)) { } - /** - * Returns the (fixed) type of this register. - * @return the type of this register - */ - RegisterType getType() const { return m_Type; } + Register(unsigned int id, regwidth_t w) + : m_Width(w), m_Id(id) { } /** * Returns the (fixed) width of this register. * @return the width in bits @@ -72,20 +62,6 @@ public: * @return the textual register description */ const std::string& getName() const { return m_Name; } - /** - * Retrieves the unique index within it's assigned register set. - * If the register has not been assigned, \c (size_t)-1 will be - * returned. - * @return the register index or -1 if not assigned - * @see isAssigned() - */ - size_t getIndex() const { return m_Index; } - /** - * Checks whether this register has already been assigned. On - * creation the register isn't initially assigned. - * @return \c true if assigned, \c false otherwise - */ - bool isAssigned() const { return m_Assigned; } /** * Returns the unique id of this register. * @return the unique id diff --git a/src/core/sal/arm/ArmArchitecture.cc b/src/core/sal/arm/ArmArchitecture.cc index 4121ef8a..a17f28a4 100644 --- a/src/core/sal/arm/ArmArchitecture.cc +++ b/src/core/sal/arm/ArmArchitecture.cc @@ -10,19 +10,19 @@ ArmArchitecture::ArmArchitecture() // 16x 32-Bit GP Registers for (int i = 0; i < 16; i++) { if (i != RI_IP) { // IP will be added separately (see below) - Register *reg = new Register(i, RT_GP, 32); + Register *reg = new Register(i, 32); // Build and set the register name: std::stringstream sstr; sstr << "R" << i+1; reg->setName(sstr.str().c_str()); - m_addRegister(reg); + m_addRegister(reg, RT_GP); } } // Instruction Pointer: - Register *reg = new Register(RI_IP, RT_IP, 32); + Register *reg = new Register(RI_IP, 32); reg->setName("IP"); - m_addRegister(reg); + m_addRegister(reg, RT_IP); } ArmArchitecture::~ArmArchitecture() diff --git a/src/core/sal/x86/X86Architecture.cc b/src/core/sal/x86/X86Architecture.cc index e8587e69..97ff6e2d 100644 --- a/src/core/sal/x86/X86Architecture.cc +++ b/src/core/sal/x86/X86Architecture.cc @@ -13,34 +13,34 @@ X86Architecture::X86Architecture() const std::string names[] = { "RAX", "RCX", "RDX", "RBX", "RSP", "RBP", "RSI", "RDI", "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15" }; for (unsigned short i = 0; i < 16; i++) { - Register* pReg = new Register(i, RT_GP, 64); + Register* pReg = new Register(i, 64); pReg->setName(names[i]); - m_addRegister(pReg); + m_addRegister(pReg, RT_GP); } #else // -- 32 bit register -- const std::string names[] = { "EAX", "ECX", "EDX", "EBX", "ESP", "EBP", "ESI", "EDI" }; for (unsigned short i = 0; i < 8; i++) { - Register* pReg = new Register(i, RT_GP, 32); + Register* pReg = new Register(i, 32); pReg->setName(names[i]); - m_addRegister(pReg); + m_addRegister(pReg, RT_GP); } #endif // SIM_SUPPORT_64 // ------------------------------------- // Add the program counter (PC) register: #ifdef SIM_SUPPORT_64 - Register* pPCReg = new Register(RID_PC, RT_IP, 64); + Register* pPCReg = new Register(RID_PC, 64); pPCReg->setName("RIP"); #else - Register* pPCReg = new Register(RID_PC, RT_IP, 32); + Register* pPCReg = new Register(RID_PC, 32); pPCReg->setName("EIP"); #endif // SIM_SUPPORT_64 - m_addRegister(pPCReg); + m_addRegister(pPCReg, RT_IP); // ------------------------------------- // Add the status register (EFLAGS): - Register* pFlagReg = new Register(RID_FLAGS, RT_ST, 32); + Register* pFlagReg = new Register(RID_FLAGS, 32); pFlagReg->setName("EFLAGS"); - m_addRegister(pFlagReg); + m_addRegister(pFlagReg, RT_ST); } X86Architecture::~X86Architecture()