sal: allow register sets to overlap

This allows a register to be a member of multiple UniformRegisterSets.
Needed to architecture-specifically store, e.g., a list of registers to
record in traces.

Change-Id: Ia5d20768540efe252a84df967d43e569f107da3a
This commit is contained in:
Horst Schirmeier
2013-08-23 10:39:30 +02:00
parent ff1ceeddac
commit 52723a874e
6 changed files with 33 additions and 56 deletions

View File

@ -1,15 +1,19 @@
#include <algorithm>
#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

View File

@ -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

View File

@ -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

View File

@ -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<size_t>(-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

View File

@ -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()

View File

@ -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()