Jump::branchTarget(ThreadContext *tc) const
{
PCState pc = tc->pcState();
- uint64_t Rb = tc->readIntReg(_srcRegIdx[0]);
+ uint64_t Rb = tc->readIntReg(_srcRegIdx[0].regIdx);
pc.set((Rb & ~3) | (pc.pc() & 1));
return pc;
}
#ifndef SS_COMPATIBLE_DISASSEMBLY
std::string suffix("");
- suffix += ((_destRegIdx[0] >= FP_Reg_Base)
+ suffix += ((_destRegIdx[0].regClass == FloatRegClass)
? fpTrappingModeSuffix[trappingMode]
: intTrappingModeSuffix[trappingMode]);
suffix += roundingModeSuffix[roundingMode];
{
protected:
- /// Make AlphaISA register dependence tags directly visible in
- /// this class and derived classes. Maybe these should really
- /// live here and not in the AlphaISA namespace.
- enum DependenceTags {
- FP_Reg_Base = AlphaISA::FP_Reg_Base
- };
-
/// Constructor.
AlphaStaticInst(const char *mnem, ExtMachInst _machInst,
OpClass __opClass)
/// Print a register name for disassembly given the unique
/// dependence tag number (FP or int).
- void printReg(std::ostream &os, int reg) const;
+ void printReg(std::ostream &os, RegId reg) const;
std::string
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
output decoder {{
void
- AlphaStaticInst::printReg(std::ostream &os, int reg) const
+ AlphaStaticInst::printReg(std::ostream &os, RegId reg) const
{
- if (reg < FP_Reg_Base) {
- ccprintf(os, "r%d", reg);
+ if (reg.regClass == IntRegClass) {
+ ccprintf(os, "r%d", reg.regIdx);
}
else {
- ccprintf(os, "f%d", reg - FP_Reg_Base);
+ ccprintf(os, "f%d", reg.regIdx);
}
}
#include "arch/alpha/generated/max_inst_regs.hh"
#include "arch/alpha/ipr.hh"
+#include "arch/generic/types.hh"
#include "base/types.hh"
namespace AlphaISA {
// Locked read/write flags are can't be detected by the ISA parser
const int MaxMiscDestRegs = AlphaISAInst::MaxMiscDestRegs + 1;
-typedef uint8_t RegIndex;
typedef uint64_t IntReg;
// floating point register file entry type
const int TotalNumRegs =
NumIntRegs + NumFloatRegs + NumMiscRegs;
-// These enumerate all the registers for dependence tracking.
-enum DependenceTags {
- // 0..31 are the integer regs 0..31
- // 32..63 are the FP regs 0..31, i.e. use (reg + FP_Reg_Base)
- FP_Reg_Base = NumIntRegs,
- CC_Reg_Base = FP_Reg_Base + NumFloatRegs,
- Misc_Reg_Base = CC_Reg_Base + NumCCRegs, // NumCCRegs == 0
- Max_Reg_Index = Misc_Reg_Base + NumMiscRegs + NumInternalProcRegs
-};
-
} // namespace AlphaISA
#endif // __ARCH_ALPHA_REGFILE_HH__
{
std::stringstream ss;
printMnemonic(ss, "", false);
- printReg(ss, op1);
+ printIntReg(ss, op1);
return ss.str();
}
std::stringstream ss;
printMnemonic(ss, "", false);
if (op1 != INTREG_X30)
- printReg(ss, op1);
+ printIntReg(ss, op1);
return ss.str();
}
{
std::stringstream ss;
printMnemonic(ss, "", false);
- printReg(ss, op1);
+ printIntReg(ss, op1);
ccprintf(ss, ", ");
printTarget(ss, pc + imm, symtab);
return ss.str();
{
std::stringstream ss;
printMnemonic(ss, "", false);
- printReg(ss, op1);
+ printIntReg(ss, op1);
ccprintf(ss, ", #%#x, ", imm1);
printTarget(ss, pc + imm2, symtab);
return ss.str();
{
std::stringstream ss;
printMnemonic(ss, "", false);
- printReg(ss, dest);
+ printIntReg(ss, dest);
ccprintf(ss, ", #%d", imm);
return ss.str();
}
{
std::stringstream ss;
printMnemonic(ss, "", false);
- printReg(ss, dest);
+ printIntReg(ss, dest);
ccprintf(ss, ", ");
- printReg(ss, op1);
+ printIntReg(ss, op1);
return ss.str();
}
{
std::stringstream ss;
printMnemonic(ss, "", false);
- printReg(ss, dest);
+ printIntReg(ss, dest);
ccprintf(ss, ", ");
- printReg(ss, op1);
+ printIntReg(ss, op1);
ccprintf(ss, ", #%d", imm);
return ss.str();
}
{
std::stringstream ss;
printMnemonic(ss, "", false);
- printReg(ss, dest);
+ printIntReg(ss, dest);
ccprintf(ss, ", ");
- printReg(ss, op1);
+ printIntReg(ss, op1);
ccprintf(ss, ", #%d, #%d", imm1, imm2);
return ss.str();
}
{
std::stringstream ss;
printMnemonic(ss, "", false);
- printReg(ss, dest);
+ printIntReg(ss, dest);
ccprintf(ss, ", ");
- printReg(ss, op1);
+ printIntReg(ss, op1);
ccprintf(ss, ", ");
- printReg(ss, op2);
+ printIntReg(ss, op2);
return ss.str();
}
{
std::stringstream ss;
printMnemonic(ss, "", false);
- printReg(ss, dest);
+ printIntReg(ss, dest);
ccprintf(ss, ", ");
- printReg(ss, op1);
+ printIntReg(ss, op1);
ccprintf(ss, ", ");
- printReg(ss, op2);
+ printIntReg(ss, op2);
ccprintf(ss, ", #%d", imm);
return ss.str();
}
{
std::stringstream ss;
printMnemonic(ss, "", false);
- printReg(ss, dest);
+ printIntReg(ss, dest);
ccprintf(ss, ", ");
- printReg(ss, op1);
+ printIntReg(ss, op1);
ccprintf(ss, ", ");
- printReg(ss, op2);
+ printIntReg(ss, op2);
ccprintf(ss, ", ");
- printReg(ss, op3);
+ printIntReg(ss, op3);
return ss.str();
}
{
std::stringstream ss;
printMnemonic(ss, "", false);
- printReg(ss, op1);
+ printIntReg(ss, op1);
ccprintf(ss, ", #%d, #%d", imm, defCc);
ccprintf(ss, ", ");
printCondition(ss, condCode, true);
{
std::stringstream ss;
printMnemonic(ss, "", false);
- printReg(ss, op1);
+ printIntReg(ss, op1);
ccprintf(ss, ", ");
- printReg(ss, op2);
+ printIntReg(ss, op2);
ccprintf(ss, ", #%d", defCc);
ccprintf(ss, ", ");
printCondition(ss, condCode, true);
{
std::stringstream ss;
printMnemonic(ss, "", false);
- printReg(ss, dest);
+ printIntReg(ss, dest);
ccprintf(ss, ", ");
- printReg(ss, op1);
+ printIntReg(ss, op1);
ccprintf(ss, ", ");
- printReg(ss, op2);
+ printIntReg(ss, op2);
ccprintf(ss, ", ");
printCondition(ss, condCode, true);
return ss.str();
{
std::stringstream ss;
printMnemonic(ss);
- printReg(ss, ura);
+ printIntReg(ss, ura);
ss << ", ";
- printReg(ss, urb);
+ printIntReg(ss, urb);
ss << ", ";
ccprintf(ss, "#%d", imm);
return ss.str();
{
std::stringstream ss;
printMnemonic(ss);
- printReg(ss, ura);
+ printIntReg(ss, ura);
ss << ", ";
- printReg(ss, urb);
+ printIntReg(ss, urb);
ss << ", ";
ccprintf(ss, "#%d", imm);
return ss.str();
{
std::stringstream ss;
printMnemonic(ss);
- printReg(ss, ura);
+ printIntReg(ss, ura);
ccprintf(ss, ", ");
- printReg(ss, urb);
+ printIntReg(ss, urb);
printExtendOperand(false, ss, (IntRegIndex)urc, type, shiftAmt);
return ss.str();
}
{
std::stringstream ss;
printMnemonic(ss);
- printReg(ss, ura);
+ printIntReg(ss, ura);
ss << ", ";
- printReg(ss, urb);
+ printIntReg(ss, urb);
return ss.str();
}
{
std::stringstream ss;
printMnemonic(ss);
- printReg(ss, ura);
+ printIntReg(ss, ura);
ss << ", ";
- printReg(ss, urb);
+ printIntReg(ss, urb);
ss << ", ";
- printReg(ss, urc);
+ printIntReg(ss, urc);
return ss.str();
}
std::stringstream ss;
printMnemonic(ss);
if (isFloating())
- printReg(ss, ura + FP_Reg_Base);
+ printFloatReg(ss, ura);
else
- printReg(ss, ura);
+ printIntReg(ss, ura);
ss << ", [";
- printReg(ss, urb);
+ printIntReg(ss, urb);
ss << ", ";
ccprintf(ss, "#%d", imm);
ss << "]";
{
std::stringstream ss;
printMnemonic(ss);
- printReg(ss, dest);
+ printIntReg(ss, dest);
ss << ",";
- printReg(ss, dest2);
+ printIntReg(ss, dest2);
ss << ", [";
- printReg(ss, urb);
+ printIntReg(ss, urb);
ss << ", ";
ccprintf(ss, "#%d", imm);
ss << "]";
{
if (!add)
os << "-";
- printReg(os, index);
+ printIntReg(os, index);
if (shiftType != LSL || shiftAmt != 0) {
switch (shiftType) {
case LSL:
{
stringstream ss;
printMnemonic(ss);
- printReg(ss, dest);
+ printIntReg(ss, dest);
ss << ", ";
- printReg(ss, op1);
+ printIntReg(ss, op1);
ss << ", [";
- printReg(ss, base);
+ printIntReg(ss, base);
ss << "]";
return ss.str();
}
printMnemonic(ss, "ib");
break;
}
- printReg(ss, base);
+ printIntReg(ss, base);
if (wb) {
ss << "!";
}
printMnemonic(ss, "ib");
break;
}
- printReg(ss, INTREG_SP);
+ printIntReg(ss, INTREG_SP);
if (wb) {
ss << "!";
}
printMnemonic(os);
printDest(os);
os << ", [";
- printReg(os, base);
+ printIntReg(os, base);
if (addrMode != AddrMd_PostIndex) {
os << ", ";
printOffset(os);
virtual void
printDest(std::ostream &os) const
{
- printReg(os, dest);
+ printIntReg(os, dest);
}
void printInst(std::ostream &os, AddrMode addrMode) const;
void
printDest(std::ostream &os) const
{
- printReg(os, result);
+ printIntReg(os, result);
os << ", ";
MemoryImm::printDest(os);
}
{
MemoryImm::printDest(os);
os << ", ";
- printReg(os, dest2);
+ printIntReg(os, dest2);
}
};
void
printDest(std::ostream &os) const
{
- printReg(os, result);
+ printIntReg(os, result);
os << ", ";
MemoryDImm::printDest(os);
}
{
MemoryReg::printDest(os);
os << ", ";
- printReg(os, dest2);
+ printIntReg(os, dest2);
}
};
std::stringstream ss;
printMnemonic(ss, "", false);
ccprintf(ss, ", [");
- printReg(ss, base);
+ printIntReg(ss, base);
ccprintf(ss, "]");
return ss.str();
}
Memory64::startDisassembly(std::ostream &os) const
{
printMnemonic(os, "", false);
- printReg(os, dest);
+ printIntReg(os, dest);
ccprintf(os, ", [");
- printReg(os, base);
+ printIntReg(os, base);
}
void
{
std::stringstream ss;
printMnemonic(ss, "", false);
- printReg(ss, dest);
+ printIntReg(ss, dest);
ccprintf(ss, ", ");
- printReg(ss, dest2);
+ printIntReg(ss, dest2);
ccprintf(ss, ", [");
- printReg(ss, base);
+ printIntReg(ss, base);
if (imm)
ccprintf(ss, ", #%d", imm);
ccprintf(ss, "]");
{
std::stringstream ss;
printMnemonic(ss, "", false);
- printReg(ss, result);
+ printIntReg(ss, result);
ccprintf(ss, ", ");
- printReg(ss, dest);
+ printIntReg(ss, dest);
ccprintf(ss, ", ");
- printReg(ss, dest2);
+ printIntReg(ss, dest2);
ccprintf(ss, ", [");
- printReg(ss, base);
+ printIntReg(ss, base);
if (imm)
ccprintf(ss, ", #%d", imm);
ccprintf(ss, "]");
{
std::stringstream ss;
printMnemonic(ss, "", false);
- printReg(ss, dest);
+ printIntReg(ss, dest);
ccprintf(ss, ", ");
- printReg(ss, result);
+ printIntReg(ss, result);
ccprintf(ss, ", [");
- printReg(ss, base);
+ printIntReg(ss, base);
ccprintf(ss, "]");
return ss.str();
}
{
std::stringstream ss;
printMnemonic(ss, "", false);
- printReg(ss, dest);
+ printIntReg(ss, dest);
ccprintf(ss, ", #%d", pc + imm);
return ss.str();
}
{
std::stringstream ss;
printMnemonic(ss);
- printReg(ss, dest);
+ printIntReg(ss, dest);
ss << ", ";
bool foundPsr = false;
for (unsigned i = 0; i < numSrcRegs(); i++) {
- RegIndex idx = srcRegIdx(i);
- RegIndex rel_idx;
- if (regIdxToClass(idx, &rel_idx) != MiscRegClass) {
+ RegId reg = srcRegIdx(i);
+ if (reg.regClass != MiscRegClass) {
continue;
}
- if (rel_idx == MISCREG_CPSR) {
+ if (reg.regIdx == MISCREG_CPSR) {
ss << "cpsr";
foundPsr = true;
break;
}
- if (rel_idx == MISCREG_SPSR) {
+ if (reg.regIdx == MISCREG_SPSR) {
ss << "spsr";
foundPsr = true;
break;
bool apsr = false;
bool foundPsr = false;
for (unsigned i = 0; i < numDestRegs(); i++) {
- int idx = destRegIdx(i);
- if (idx < Misc_Reg_Base) {
+ RegId reg = destRegIdx(i);
+ if (reg.regClass != MiscRegClass) {
continue;
}
- idx -= Misc_Reg_Base;
- if (idx == MISCREG_CPSR) {
+ if (reg.regIdx == MISCREG_CPSR) {
os << "cpsr_";
foundPsr = true;
break;
}
- if (idx == MISCREG_SPSR) {
+ if (reg.regIdx == MISCREG_SPSR) {
if (bits(byteMask, 1, 0)) {
os << "spsr_";
} else {
std::stringstream ss;
printMsrBase(ss);
ss << ", ";
- printReg(ss, op1);
+ printIntReg(ss, op1);
return ss.str();
}
{
std::stringstream ss;
printMnemonic(ss);
- printReg(ss, dest);
+ printIntReg(ss, dest);
ss << ", ";
- printReg(ss, dest2);
+ printIntReg(ss, dest2);
ss << ", ";
- printReg(ss, op1);
+ printIntReg(ss, op1);
return ss.str();
}
{
std::stringstream ss;
printMnemonic(ss);
- printReg(ss, dest);
+ printIntReg(ss, dest);
ss << ", ";
- printReg(ss, op1);
+ printIntReg(ss, op1);
ss << ", ";
- printReg(ss, op2);
+ printIntReg(ss, op2);
return ss.str();
}
{
std::stringstream ss;
printMnemonic(ss);
- printReg(ss, dest);
+ printIntReg(ss, dest);
ccprintf(ss, ", #%d", imm);
return ss.str();
}
{
std::stringstream ss;
printMnemonic(ss);
- printReg(ss, dest);
+ printIntReg(ss, dest);
ss << ", ";
- printReg(ss, op1);
+ printIntReg(ss, op1);
return ss.str();
}
{
std::stringstream ss;
printMnemonic(ss);
- printReg(ss, dest);
+ printIntReg(ss, dest);
ss << ", ";
- printReg(ss, op1);
+ printIntReg(ss, op1);
ss << ", ";
- printReg(ss, op2);
+ printIntReg(ss, op2);
ccprintf(ss, ", #%d", imm);
return ss.str();
}
{
std::stringstream ss;
printMnemonic(ss);
- printReg(ss, dest);
+ printIntReg(ss, dest);
ss << ", ";
- printReg(ss, op1);
+ printIntReg(ss, op1);
ss << ", ";
- printReg(ss, op2);
+ printIntReg(ss, op2);
ss << ", ";
- printReg(ss, op3);
+ printIntReg(ss, op3);
return ss.str();
}
{
std::stringstream ss;
printMnemonic(ss);
- printReg(ss, dest);
+ printIntReg(ss, dest);
ss << ", ";
- printReg(ss, op1);
+ printIntReg(ss, op1);
ss << ", ";
- printReg(ss, op2);
+ printIntReg(ss, op2);
return ss.str();
}
{
std::stringstream ss;
printMnemonic(ss);
- printReg(ss, dest);
+ printIntReg(ss, dest);
ss << ", ";
- printReg(ss, op1);
+ printIntReg(ss, op1);
ccprintf(ss, ", #%d", imm);
return ss.str();
}
{
std::stringstream ss;
printMnemonic(ss);
- printReg(ss, dest);
+ printIntReg(ss, dest);
ss << ", ";
- printReg(ss, op1);
+ printIntReg(ss, op1);
ccprintf(ss, ", #%d", imm);
return ss.str();
}
{
std::stringstream ss;
printMnemonic(ss);
- printReg(ss, dest);
+ printIntReg(ss, dest);
ss << ", ";
- printReg(ss, op1);
+ printIntReg(ss, op1);
ccprintf(ss, ", #%d", imm);
return ss.str();
}
{
std::stringstream ss;
printMnemonic(ss);
- printReg(ss, dest);
+ printIntReg(ss, dest);
ccprintf(ss, ", #%d, #%d", imm1, imm2);
return ss.str();
}
{
std::stringstream ss;
printMnemonic(ss);
- printReg(ss, dest);
+ printIntReg(ss, dest);
ss << ", ";
- printReg(ss, op1);
+ printIntReg(ss, op1);
ccprintf(ss, ", #%d, #%d", imm1, imm2);
return ss.str();
}
{
std::stringstream ss;
printMnemonic(ss);
- printReg(ss, dest);
+ printIntReg(ss, dest);
ccprintf(ss, ", #%d, ", imm);
- printReg(ss, op1);
+ printIntReg(ss, op1);
return ss.str();
}
{
std::stringstream ss;
printMnemonic(ss);
- printReg(ss, dest);
+ printIntReg(ss, dest);
ccprintf(ss, ", #%d, ", imm);
printShiftOperand(ss, op1, true, shiftAmt, INTREG_ZERO, shiftType);
- printReg(ss, op1);
+ printIntReg(ss, op1);
return ss.str();
}
{
std::stringstream ss;
printMnemonic(ss, "", false);
- printReg(ss, dest);
+ printIntReg(ss, dest);
ss << ", ";
- printReg(ss, op1);
+ printIntReg(ss, op1);
ccprintf(ss, ", #%d, #%d", imm1, imm2);
return ss.str();
}
{
std::stringstream ss;
printMnemonic(ss, "", false);
- printReg(ss, dest);
+ printIntReg(ss, dest);
ss << ", ";
- printReg(ss, op1);
+ printIntReg(ss, op1);
ss << ", ";
- printReg(ss, op2);
+ printIntReg(ss, op2);
ccprintf(ss, ", #%d", imm);
return ss.str();
}
return 0;
}
-
void
-ArmStaticInst::printReg(std::ostream &os, int reg) const
+ArmStaticInst::printIntReg(std::ostream &os, RegIndex reg_idx) const
{
- RegIndex rel_reg;
-
- switch (regIdxToClass(reg, &rel_reg)) {
- case IntRegClass:
- if (aarch64) {
- if (reg == INTREG_UREG0)
- ccprintf(os, "ureg0");
- else if (reg == INTREG_SPX)
- ccprintf(os, "%s%s", (intWidth == 32) ? "w" : "", "sp");
- else if (reg == INTREG_X31)
- ccprintf(os, "%szr", (intWidth == 32) ? "w" : "x");
- else
- ccprintf(os, "%s%d", (intWidth == 32) ? "w" : "x", reg);
- } else {
- switch (rel_reg) {
- case PCReg:
- ccprintf(os, "pc");
- break;
- case StackPointerReg:
- ccprintf(os, "sp");
- break;
- case FramePointerReg:
- ccprintf(os, "fp");
- break;
- case ReturnAddressReg:
- ccprintf(os, "lr");
- break;
- default:
- ccprintf(os, "r%d", reg);
- break;
- }
+ if (aarch64) {
+ if (reg_idx == INTREG_UREG0)
+ ccprintf(os, "ureg0");
+ else if (reg_idx == INTREG_SPX)
+ ccprintf(os, "%s%s", (intWidth == 32) ? "w" : "", "sp");
+ else if (reg_idx == INTREG_X31)
+ ccprintf(os, "%szr", (intWidth == 32) ? "w" : "x");
+ else
+ ccprintf(os, "%s%d", (intWidth == 32) ? "w" : "x", reg_idx);
+ } else {
+ switch (reg_idx) {
+ case PCReg:
+ ccprintf(os, "pc");
+ break;
+ case StackPointerReg:
+ ccprintf(os, "sp");
+ break;
+ case FramePointerReg:
+ ccprintf(os, "fp");
+ break;
+ case ReturnAddressReg:
+ ccprintf(os, "lr");
+ break;
+ default:
+ ccprintf(os, "r%d", reg_idx);
+ break;
}
- break;
- case FloatRegClass:
- ccprintf(os, "f%d", rel_reg);
- break;
- case MiscRegClass:
- assert(rel_reg < NUM_MISCREGS);
- ccprintf(os, "%s", ArmISA::miscRegName[rel_reg]);
- break;
- case CCRegClass:
- ccprintf(os, "cc_%s", ArmISA::ccRegName[rel_reg]);
- break;
}
}
+void
+ArmStaticInst::printFloatReg(std::ostream &os, RegIndex reg_idx) const
+{
+ ccprintf(os, "f%d", reg_idx);
+}
+
+void
+ArmStaticInst::printCCReg(std::ostream &os, RegIndex reg_idx) const
+{
+ ccprintf(os, "cc_%s", ArmISA::ccRegName[reg_idx]);
+}
+
+void
+ArmStaticInst::printMiscReg(std::ostream &os, RegIndex reg_idx) const
+{
+ assert(reg_idx < NUM_MISCREGS);
+ ccprintf(os, "%s", ArmISA::miscRegName[reg_idx]);
+}
+
void
ArmStaticInst::printMnemonic(std::ostream &os,
const std::string &suffix,
bool firstOp = false;
if (rm != INTREG_ZERO) {
- printReg(os, rm);
+ printIntReg(os, rm);
}
bool done = false;
if (immShift)
os << "#" << shiftAmt;
else
- printReg(os, rs);
+ printIntReg(os, rs);
}
}
{
if (!firstOperand)
ccprintf(os, ", ");
- printReg(os, rm);
+ printIntReg(os, rm);
if (type == UXTX && shiftAmt == 0)
return;
switch (type) {
// Destination
if (rd != INTREG_ZERO) {
firstOp = false;
- printReg(os, rd);
+ printIntReg(os, rd);
}
// Source 1.
if (!firstOp)
os << ", ";
firstOp = false;
- printReg(os, rn);
+ printIntReg(os, rn);
}
if (!firstOp)
/// Print a register name for disassembly given the unique
/// dependence tag number (FP or int).
- void printReg(std::ostream &os, int reg) const;
+ void printIntReg(std::ostream &os, RegIndex reg_idx) const;
+ void printFloatReg(std::ostream &os, RegIndex reg_idx) const;
+ void printCCReg(std::ostream &os, RegIndex reg_idx) const;
+ void printMiscReg(std::ostream &os, RegIndex reg_idx) const;
void printMnemonic(std::ostream &os,
const std::string &suffix = "",
bool withPred = true,
{
std::stringstream ss;
printMnemonic(ss, "", false);
- printReg(ss, op1);
+ printIntReg(ss, op1);
ccprintf(ss, ", ");
- printReg(ss, op2);
+ printIntReg(ss, op2);
ccprintf(ss, ", #%d", defCc);
ccprintf(ss, ", ");
printCondition(ss, condCode, true);
{
std::stringstream ss;
printMnemonic(ss, "", false);
- printReg(ss, dest);
+ printIntReg(ss, dest);
ccprintf(ss, ", ");
- printReg(ss, op1);
+ printIntReg(ss, op1);
ccprintf(ss, ", ");
- printReg(ss, op2);
+ printIntReg(ss, op2);
ccprintf(ss, ", ");
printCondition(ss, condCode, true);
return ss.str();
{
std::stringstream ss;
printMnemonic(ss);
- printReg(ss, dest + FP_Reg_Base);
+ printFloatReg(ss, dest);
ss << ", ";
- printReg(ss, op1 + FP_Reg_Base);
+ printFloatReg(ss, op1);
return ss.str();
}
{
std::stringstream ss;
printMnemonic(ss);
- printReg(ss, dest + FP_Reg_Base);
+ printFloatReg(ss, dest);
ccprintf(ss, ", #%d", imm);
return ss.str();
}
{
std::stringstream ss;
printMnemonic(ss);
- printReg(ss, dest + FP_Reg_Base);
+ printFloatReg(ss, dest);
ss << ", ";
- printReg(ss, op1 + FP_Reg_Base);
+ printFloatReg(ss, op1);
ccprintf(ss, ", #%d", imm);
return ss.str();
}
{
std::stringstream ss;
printMnemonic(ss);
- printReg(ss, dest + FP_Reg_Base);
+ printFloatReg(ss, dest);
ss << ", ";
- printReg(ss, op1 + FP_Reg_Base);
+ printFloatReg(ss, op1);
ss << ", ";
- printReg(ss, op2 + FP_Reg_Base);
+ printFloatReg(ss, op2);
return ss.str();
}
std::stringstream ss;
printMnemonic(ss);
printCondition(ss, cond);
- printReg(ss, dest + FP_Reg_Base);
+ printFloatReg(ss, dest);
ss << ", ";
- printReg(ss, op1 + FP_Reg_Base);
+ printFloatReg(ss, op1);
ss << ", ";
- printReg(ss, op2 + FP_Reg_Base);
+ printFloatReg(ss, op2);
return ss.str();
}
{
std::stringstream ss;
printMnemonic(ss);
- printReg(ss, dest + FP_Reg_Base);
+ printFloatReg(ss, dest);
ss << ", ";
- printReg(ss, op1 + FP_Reg_Base);
+ printFloatReg(ss, op1);
ss << ", ";
- printReg(ss, op2 + FP_Reg_Base);
+ printFloatReg(ss, op2);
ss << ", ";
- printReg(ss, op3 + FP_Reg_Base);
+ printFloatReg(ss, op3);
return ss.str();
}
{
std::stringstream ss;
printMnemonic(ss);
- printReg(ss, dest + FP_Reg_Base);
+ printFloatReg(ss, dest);
ss << ", ";
- printReg(ss, op1 + FP_Reg_Base);
+ printFloatReg(ss, op1);
ss << ", ";
- printReg(ss, op2 + FP_Reg_Base);
+ printFloatReg(ss, op2);
ccprintf(ss, ", #%d", imm);
return ss.str();
}
using ArmISAInst::MaxInstDestRegs;
using ArmISAInst::MaxMiscDestRegs;
-typedef uint16_t RegIndex;
-
typedef uint64_t IntReg;
// floating point register file entry type
const int SyscallPseudoReturnReg = ReturnValueReg;
const int SyscallSuccessReg = ReturnValueReg;
-// These help enumerate all the registers for dependence tracking.
-const int FP_Reg_Base = NumIntRegs * (MODE_MAXMODE + 1);
-const int CC_Reg_Base = FP_Reg_Base + NumFloatRegs;
-const int Misc_Reg_Base = CC_Reg_Base + NumCCRegs;
-const int Max_Reg_Index = Misc_Reg_Base + NumMiscRegs;
-
typedef union {
IntReg intreg;
FloatReg fpreg;
#include "base/types.hh"
#include "sim/serialize.hh"
+// Logical register index type.
+typedef uint16_t RegIndex;
+
namespace GenericISA
{
# to avoid 'uninitialized variable' errors from the compiler.
return self.ctype + ' ' + self.base_name + ' = 0;\n';
+
+src_reg_constructor = '\n\t_srcRegIdx[_numSrcRegs++] = RegId(%s, %s);'
+dst_reg_constructor = '\n\t_destRegIdx[_numDestRegs++] = RegId(%s, %s);'
+
+
class IntRegOperand(Operand):
+ reg_class = 'IntRegClass'
+
def isReg(self):
return 1
c_dest = ''
if self.is_src:
- c_src = '\n\t_srcRegIdx[_numSrcRegs++] = %s;' % (self.reg_spec)
+ c_src = src_reg_constructor % (self.reg_class, self.reg_spec)
if self.hasReadPred():
c_src = '\n\tif (%s) {%s\n\t}' % \
(self.read_predicate, c_src)
if self.is_dest:
- c_dest = '\n\t_destRegIdx[_numDestRegs++] = %s;' % \
- (self.reg_spec)
+ c_dest = dst_reg_constructor % (self.reg_class, self.reg_spec)
c_dest += '\n\t_numIntDestRegs++;'
if self.hasWritePred():
c_dest = '\n\tif (%s) {%s\n\t}' % \
return wb
class FloatRegOperand(Operand):
+ reg_class = 'FloatRegClass'
+
def isReg(self):
return 1
c_dest = ''
if self.is_src:
- c_src = '\n\t_srcRegIdx[_numSrcRegs++] = %s + FP_Reg_Base;' % \
- (self.reg_spec)
+ c_src = src_reg_constructor % (self.reg_class, self.reg_spec)
if self.is_dest:
- c_dest = \
- '\n\t_destRegIdx[_numDestRegs++] = %s + FP_Reg_Base;' % \
- (self.reg_spec)
+ c_dest = dst_reg_constructor % (self.reg_class, self.reg_spec)
c_dest += '\n\t_numFPDestRegs++;'
return c_src + c_dest
return wb
class CCRegOperand(Operand):
+ reg_class = 'CCRegClass'
+
def isReg(self):
return 1
c_dest = ''
if self.is_src:
- c_src = '\n\t_srcRegIdx[_numSrcRegs++] = %s + CC_Reg_Base;' % \
- (self.reg_spec)
+ c_src = src_reg_constructor % (self.reg_class, self.reg_spec)
if self.hasReadPred():
c_src = '\n\tif (%s) {%s\n\t}' % \
(self.read_predicate, c_src)
if self.is_dest:
- c_dest = \
- '\n\t_destRegIdx[_numDestRegs++] = %s + CC_Reg_Base;' % \
- (self.reg_spec)
+ c_dest = dst_reg_constructor % (self.reg_class, self.reg_spec)
c_dest += '\n\t_numCCDestRegs++;'
if self.hasWritePred():
c_dest = '\n\tif (%s) {%s\n\t}' % \
return wb
class ControlRegOperand(Operand):
+ reg_class = 'MiscRegClass'
+
def isReg(self):
return 1
c_dest = ''
if self.is_src:
- c_src = \
- '\n\t_srcRegIdx[_numSrcRegs++] = %s + Misc_Reg_Base;' % \
- (self.reg_spec)
+ c_src = src_reg_constructor % (self.reg_class, self.reg_spec)
if self.is_dest:
- c_dest = \
- '\n\t_destRegIdx[_numDestRegs++] = %s + Misc_Reg_Base;' % \
- (self.reg_spec)
+ c_dest = dst_reg_constructor % (self.reg_class, self.reg_spec)
return c_src + c_dest
/// Print a register name for disassembly given the unique
/// dependence tag number (FP or int).
- void printReg(std::ostream &os, int reg) const;
+ void printReg(std::ostream &os, RegId reg) const;
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
//Ouputs to decoder.cc
output decoder {{
- void MipsStaticInst::printReg(std::ostream &os, int reg) const
+ void MipsStaticInst::printReg(std::ostream &os, RegId reg) const
{
- if (reg < FP_Reg_Base) {
- ccprintf(os, "r%d", reg);
+ if (reg.regClass == IntRegClass) {
+ ccprintf(os, "r%d", reg.regIdx);
}
else {
- ccprintf(os, "f%d", reg - FP_Reg_Base);
+ ccprintf(os, "f%d", reg.regIdx);
}
}
// Decode MIPS MT MFTR instruction into sub-instructions
0x8: decode MT_U {
0x0: mftc0({{
- data = xc->readRegOtherThread((RT << 3 | SEL) +
- Misc_Reg_Base);
+ data = xc->readRegOtherThread(RegId(MiscRegClass,
+ (RT << 3 | SEL)));
}});
0x1: decode SEL {
0x0: mftgpr({{
- data = xc->readRegOtherThread(RT);
+ data = xc->readRegOtherThread(
+ RegId(IntRegClass, RT));
}});
0x1: decode RT {
- 0x0: mftlo_dsp0({{ data = xc->readRegOtherThread(INTREG_DSP_LO0); }});
- 0x1: mfthi_dsp0({{ data = xc->readRegOtherThread(INTREG_DSP_HI0); }});
- 0x2: mftacx_dsp0({{ data = xc->readRegOtherThread(INTREG_DSP_ACX0); }});
- 0x4: mftlo_dsp1({{ data = xc->readRegOtherThread(INTREG_DSP_LO1); }});
- 0x5: mfthi_dsp1({{ data = xc->readRegOtherThread(INTREG_DSP_HI1); }});
- 0x6: mftacx_dsp1({{ data = xc->readRegOtherThread(INTREG_DSP_ACX1); }});
- 0x8: mftlo_dsp2({{ data = xc->readRegOtherThread(INTREG_DSP_LO2); }});
- 0x9: mfthi_dsp2({{ data = xc->readRegOtherThread(INTREG_DSP_HI2); }});
- 0x10: mftacx_dsp2({{ data = xc->readRegOtherThread(INTREG_DSP_ACX2); }});
- 0x12: mftlo_dsp3({{ data = xc->readRegOtherThread(INTREG_DSP_LO3); }});
- 0x13: mfthi_dsp3({{ data = xc->readRegOtherThread(INTREG_DSP_HI3); }});
- 0x14: mftacx_dsp3({{ data = xc->readRegOtherThread(INTREG_DSP_ACX3); }});
- 0x16: mftdsp({{ data = xc->readRegOtherThread(INTREG_DSP_CONTROL); }});
+ 0x0: mftlo_dsp0({{
+ data = xc->readRegOtherThread(
+ RegId(IntRegClass, INTREG_DSP_LO0));
+ }});
+ 0x1: mfthi_dsp0({{
+ data = xc->readRegOtherThread(
+ RegId(IntRegClass, INTREG_DSP_HI0));
+ }});
+ 0x2: mftacx_dsp0({{
+ data = xc->readRegOtherThread(
+ RegId(IntRegClass, INTREG_DSP_ACX0));
+ }});
+ 0x4: mftlo_dsp1({{
+ data = xc->readRegOtherThread(
+ RegId(IntRegClass, INTREG_DSP_LO1));
+ }});
+ 0x5: mfthi_dsp1({{
+ data = xc->readRegOtherThread(
+ RegId(IntRegClass, INTREG_DSP_HI1));
+ }});
+ 0x6: mftacx_dsp1({{
+ data = xc->readRegOtherThread(
+ RegId(IntRegClass, INTREG_DSP_ACX1));
+ }});
+ 0x8: mftlo_dsp2({{
+ data = xc->readRegOtherThread(
+ RegId(IntRegClass, INTREG_DSP_LO2));
+ }});
+ 0x9: mfthi_dsp2({{
+ data = xc->readRegOtherThread(
+ RegId(IntRegClass, INTREG_DSP_HI2));
+ }});
+ 0x10: mftacx_dsp2({{
+ data = xc->readRegOtherThread(
+ RegId(IntRegClass, INTREG_DSP_ACX2));
+ }});
+ 0x12: mftlo_dsp3({{
+ data = xc->readRegOtherThread(
+ RegId(IntRegClass, INTREG_DSP_LO3));
+ }});
+ 0x13: mfthi_dsp3({{
+ data = xc->readRegOtherThread(
+ RegId(IntRegClass, INTREG_DSP_HI3));
+ }});
+ 0x14: mftacx_dsp3({{
+ data = xc->readRegOtherThread(
+ RegId(IntRegClass, INTREG_DSP_ACX3));
+ }});
+ 0x16: mftdsp({{
+ data = xc->readRegOtherThread(
+ RegId(IntRegClass, INTREG_DSP_CONTROL));
+ }});
default: CP0Unimpl::unknown();
}
0x2: decode MT_H {
- 0x0: mftc1({{ data = xc->readRegOtherThread(RT +
- FP_Reg_Base);
+ 0x0: mftc1({{
+ data = xc->readRegOtherThread(
+ RegId(FloatRegClass, RT));
}});
- 0x1: mfthc1({{ data = xc->readRegOtherThread(RT +
- FP_Reg_Base);
+ 0x1: mfthc1({{
+ data = xc->readRegOtherThread(
+ RegId(FloatRegClass, RT));
}});
}
0x3: cftc1({{
- uint32_t fcsr_val = xc->readRegOtherThread(FLOATREG_FCSR +
- FP_Reg_Base);
+ uint32_t fcsr_val = xc->readRegOtherThread(
+ RegId(FloatRegClass, FLOATREG_FCSR));
switch (RT) {
case 0:
- data = xc->readRegOtherThread(FLOATREG_FIR +
- Misc_Reg_Base);
+ data = xc->readRegOtherThread(
+ RegId(MiscRegClass, FLOATREG_FIR));
break;
case 25:
data = (fcsr_val & 0xFE000000 >> 24) |
format MT_MTTR {
// Decode MIPS MT MTTR instruction into sub-instructions
0xC: decode MT_U {
- 0x0: mttc0({{ xc->setRegOtherThread((RD << 3 | SEL) + Misc_Reg_Base,
- Rt);
+ 0x0: mttc0({{ xc->setRegOtherThread(
+ RegId(MiscRegClass, (RD << 3 | SEL)), Rt);
}});
0x1: decode SEL {
- 0x0: mttgpr({{ xc->setRegOtherThread(RD, Rt); }});
+ 0x0: mttgpr({{ xc->setRegOtherThread(
+ RegId(IntRegClass, RD), Rt);
+ }});
0x1: decode RT {
- 0x0: mttlo_dsp0({{ xc->setRegOtherThread(INTREG_DSP_LO0, Rt);
- }});
- 0x1: mtthi_dsp0({{ xc->setRegOtherThread(INTREG_DSP_HI0,
- Rt);
- }});
- 0x2: mttacx_dsp0({{ xc->setRegOtherThread(INTREG_DSP_ACX0,
- Rt);
- }});
- 0x4: mttlo_dsp1({{ xc->setRegOtherThread(INTREG_DSP_LO1,
- Rt);
- }});
- 0x5: mtthi_dsp1({{ xc->setRegOtherThread(INTREG_DSP_HI1,
- Rt);
- }});
- 0x6: mttacx_dsp1({{ xc->setRegOtherThread(INTREG_DSP_ACX1,
- Rt);
- }});
- 0x8: mttlo_dsp2({{ xc->setRegOtherThread(INTREG_DSP_LO2,
- Rt);
- }});
- 0x9: mtthi_dsp2({{ xc->setRegOtherThread(INTREG_DSP_HI2,
- Rt);
- }});
- 0x10: mttacx_dsp2({{ xc->setRegOtherThread(INTREG_DSP_ACX2,
- Rt);
- }});
- 0x12: mttlo_dsp3({{ xc->setRegOtherThread(INTREG_DSP_LO3,
- Rt);
- }});
- 0x13: mtthi_dsp3({{ xc->setRegOtherThread(INTREG_DSP_HI3,
- Rt);
- }});
- 0x14: mttacx_dsp3({{ xc->setRegOtherThread(INTREG_DSP_ACX3, Rt);
- }});
- 0x16: mttdsp({{ xc->setRegOtherThread(INTREG_DSP_CONTROL, Rt); }});
+ 0x0: mttlo_dsp0({{ xc->setRegOtherThread(
+ RegId(IntRegClass, INTREG_DSP_LO0), Rt);
+ }});
+ 0x1: mtthi_dsp0({{ xc->setRegOtherThread(
+ RegId(IntRegClass, INTREG_DSP_HI0), Rt);
+ }});
+ 0x2: mttacx_dsp0({{ xc->setRegOtherThread(
+ RegId(IntRegClass, INTREG_DSP_ACX0), Rt);
+ }});
+ 0x4: mttlo_dsp1({{ xc->setRegOtherThread(
+ RegId(IntRegClass, INTREG_DSP_LO1), Rt);
+ }});
+ 0x5: mtthi_dsp1({{ xc->setRegOtherThread(
+ RegId(IntRegClass, INTREG_DSP_HI1), Rt);
+ }});
+ 0x6: mttacx_dsp1({{ xc->setRegOtherThread(
+ RegId(IntRegClass, INTREG_DSP_ACX1), Rt);
+ }});
+ 0x8: mttlo_dsp2({{ xc->setRegOtherThread(
+ RegId(IntRegClass, INTREG_DSP_LO2), Rt);
+ }});
+ 0x9: mtthi_dsp2({{ xc->setRegOtherThread(
+ RegId(IntRegClass, INTREG_DSP_HI2), Rt);
+ }});
+ 0x10: mttacx_dsp2({{ xc->setRegOtherThread(
+ RegId(IntRegClass, INTREG_DSP_ACX2), Rt);
+ }});
+ 0x12: mttlo_dsp3({{ xc->setRegOtherThread(
+ RegId(IntRegClass, INTREG_DSP_LO3), Rt);
+ }});
+ 0x13: mtthi_dsp3({{ xc->setRegOtherThread(
+ RegId(IntRegClass, INTREG_DSP_HI3), Rt);
+ }});
+ 0x14: mttacx_dsp3({{ xc->setRegOtherThread(
+ RegId(IntRegClass, INTREG_DSP_ACX3), Rt);
+ }});
+ 0x16: mttdsp({{ xc->setRegOtherThread(
+ RegId(IntRegClass, INTREG_DSP_CONTROL), Rt);
+ }});
default: CP0Unimpl::unknown();
}
0x2: mttc1({{
- uint64_t data = xc->readRegOtherThread(RD +
- FP_Reg_Base);
+ uint64_t data = xc->readRegOtherThread(
+ RegId(FloatRegClass, RD));
data = insertBits(data, MT_H ? 63 : 31,
MT_H ? 32 : 0, Rt);
- xc->setRegOtherThread(RD + FP_Reg_Base,
+ xc->setRegOtherThread(RegId(FloatRegClass, RD),
data);
}});
0x3: cttc1({{
"Access to Floating Control "
"S""tatus Register", FS);
}
- xc->setRegOtherThread(FLOATREG_FCSR + FP_Reg_Base, data);
+ xc->setRegOtherThread(
+ RegId(FloatRegClass, FLOATREG_FCSR), data);
}});
default: CP0Unimpl::unknown();
}
ccprintf(ss, "%-10s ", mnemonic);
- if (_numDestRegs > 0 && _destRegIdx[0] < 32) {
+ if (_numDestRegs > 0 && _destRegIdx[0].regIdx < 32) {
printReg(ss, _destRegIdx[0]);
- } else if (_numSrcRegs > 0 && _srcRegIdx[0] < 32) {
+ } else if (_numSrcRegs > 0 && _srcRegIdx[0].regIdx < 32) {
printReg(ss, _srcRegIdx[0]);
}
ccprintf(ss, "%-10s ", mnemonic);
- if (_numDestRegs > 0 && _destRegIdx[0] < 32) {
+ if (_numDestRegs > 0 && _destRegIdx[0].regIdx < 32) {
printReg(ss, _destRegIdx[0]);
- } else if (_numSrcRegs > 0 && _srcRegIdx[0] < 32) {
+ } else if (_numSrcRegs > 0 && _srcRegIdx[0].regIdx < 32) {
printReg(ss, _srcRegIdx[0]);
}
ccprintf(ss, "%-10s ", mnemonic);
- if (_numDestRegs > 0 && _destRegIdx[0] < 32) {
+ if (_numDestRegs > 0 && _destRegIdx[0].regIdx < 32) {
printReg(ss, _destRegIdx[0]);
- } else if (_numSrcRegs > 0 && _srcRegIdx[0] < 32) {
+ } else if (_numSrcRegs > 0 && _srcRegIdx[0].regIdx < 32) {
printReg(ss, _srcRegIdx[0]);
}
MVPConf0Reg &mvp_conf0)
{
vpe_conf0 = xc->readMiscReg(MISCREG_VPE_CONF0);
- tc_bind_mt = xc->readRegOtherThread(MISCREG_TC_BIND + Misc_Reg_Base);
+ tc_bind_mt = xc->readRegOtherThread(RegId(MiscRegClass,
+ MISCREG_TC_BIND));
tc_bind = xc->readMiscReg(MISCREG_TC_BIND);
vpe_control = xc->readMiscReg(MISCREG_VPE_CONTROL);
mvp_conf0 = xc->readMiscReg(MISCREG_MVP_CONF0);
int success = 0;
for (ThreadID tid = 0; tid < num_threads && success == 0; tid++) {
TCBindReg tidTCBind =
- tc->readRegOtherThread(MISCREG_TC_BIND + Misc_Reg_Base, tid);
+ tc->readRegOtherThread(RegId(MiscRegClass, MISCREG_TC_BIND), tid);
TCBindReg tcBind = tc->readMiscRegNoEffect(MISCREG_TC_BIND);
if (tidTCBind.curVPE == tcBind.curVPE) {
TCStatusReg tidTCStatus =
- tc->readRegOtherThread(MISCREG_TC_STATUS +
- Misc_Reg_Base,tid);
+ tc->readRegOtherThread(RegId(MiscRegClass, MISCREG_TC_STATUS),
+ tid);
TCHaltReg tidTCHalt =
- tc->readRegOtherThread(MISCREG_TC_HALT + Misc_Reg_Base,tid);
+ tc->readRegOtherThread(RegId(MiscRegClass, MISCREG_TC_HALT),
+ tid);
if (tidTCStatus.da == 1 && tidTCHalt.h == 0 &&
tidTCStatus.a == 0 && success == 0) {
- tc->setRegOtherThread(MISCREG_TC_RESTART +
- Misc_Reg_Base, Rs, tid);
- tc->setRegOtherThread(Rd_bits, Rt, tid);
+ tc->setRegOtherThread(RegId(MiscRegClass, MISCREG_TC_RESTART),
+ Rs, tid);
+ tc->setRegOtherThread(RegId(IntRegClass, Rd_bits), Rt, tid);
StatusReg status = tc->readMiscReg(MISCREG_STATUS);
TCStatusReg tcStatus = tc->readMiscReg(MISCREG_TC_STATUS);
tidTCStatus.asid = tcStatus.asid;
// Write Status Register
- tc->setRegOtherThread(MISCREG_TC_STATUS + Misc_Reg_Base,
+ tc->setRegOtherThread(RegId(MiscRegClass, MISCREG_TC_STATUS),
tidTCStatus, tid);
// Mark As Successful Fork
for (ThreadID tid = 0; tid < num_threads; tid++) {
TCStatusReg tidTCStatus =
- tc->readRegOtherThread(MISCREG_TC_STATUS + Misc_Reg_Base,
+ tc->readRegOtherThread(RegId(MiscRegClass, MISCREG_TC_STATUS),
tid);
TCHaltReg tidTCHalt =
- tc->readRegOtherThread(MISCREG_TC_HALT + Misc_Reg_Base,
+ tc->readRegOtherThread(RegId(MiscRegClass, MISCREG_TC_HALT),
tid);
TCBindReg tidTCBind =
- tc->readRegOtherThread(MISCREG_TC_BIND + Misc_Reg_Base,
+ tc->readRegOtherThread(RegId(MiscRegClass, MISCREG_TC_BIND),
tid);
if (tidTCBind.curVPE == tcBind.curVPE &&
const int NumMiscRegs = MISCREG_NUMREGS;
-// These help enumerate all the registers for dependence tracking.
-const int FP_Reg_Base = NumIntRegs;
-const int CC_Reg_Base = FP_Reg_Base + NumFloatRegs;
-const int Misc_Reg_Base = CC_Reg_Base + NumCCRegs; // NumCCRegs == 0
-const int Max_Reg_Index = Misc_Reg_Base + NumMiscRegs;
-
const int TotalNumRegs = NumIntRegs + NumFloatRegs + NumMiscRegs;
-typedef uint16_t RegIndex;
-
typedef uint32_t IntReg;
// floating point register file entry type
#ifndef __ARCH_NULL_REGISTERS_HH__
#define __ARCH_NULL_REGISTERS_HH__
+#include "arch/types.hh"
#include "base/types.hh"
namespace NullISA {
typedef float FloatReg;
typedef uint8_t CCReg;
typedef uint64_t MiscReg;
+const RegIndex ZeroReg = 0;
}
PowerISA::PCState
BranchRegCond::branchTarget(ThreadContext *tc) const
{
- uint32_t regVal = tc->readIntReg(_srcRegIdx[_numSrcRegs - 1]);
+ uint32_t regVal = tc->readIntReg(_srcRegIdx[_numSrcRegs - 1].regIdx);
return regVal & 0xfffffffc;
}
using namespace PowerISA;
void
-PowerStaticInst::printReg(std::ostream &os, int reg) const
+PowerStaticInst::printReg(std::ostream &os, RegId reg) const
{
- RegIndex rel_reg;
-
- switch (regIdxToClass(reg, &rel_reg)) {
+ switch (reg.regClass) {
case IntRegClass:
- ccprintf(os, "r%d", rel_reg);
+ ccprintf(os, "r%d", reg.regIdx);
break;
case FloatRegClass:
- ccprintf(os, "f%d", rel_reg);
+ ccprintf(os, "f%d", reg.regIdx);
break;
case MiscRegClass:
- switch (rel_reg) {
+ switch (reg.regIdx) {
case 0: ccprintf(os, "cr"); break;
case 1: ccprintf(os, "xer"); break;
case 2: ccprintf(os, "lr"); break;
/// Print a register name for disassembly given the unique
/// dependence tag number (FP or int).
void
- printReg(std::ostream &os, int reg) const;
+ printReg(std::ostream &os, RegId reg) const;
std::string
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
// be detected by it. Manually add it here.
const int MaxMiscDestRegs = PowerISAInst::MaxMiscDestRegs + 1;
-typedef uint8_t RegIndex;
-
typedef uint64_t IntReg;
// Floating point register file entry type
const int SyscallPseudoReturnReg = 3;
const int SyscallSuccessReg = 3;
-// These help enumerate all the registers for dependence tracking.
-const int FP_Reg_Base = NumIntRegs;
-const int CC_Reg_Base = FP_Reg_Base + NumFloatRegs;
-const int Misc_Reg_Base = CC_Reg_Base + NumCCRegs; // NumCCRegs == 0
-const int Max_Reg_Index = Misc_Reg_Base + NumMiscRegs;
-
typedef union {
IntReg intreg;
FloatReg fpreg;
{}
std::string
- regName(RegIndex reg) const;
+ regName(RegId reg) const;
virtual std::string
generateDisassembly(Addr pc, const SymbolTable *symtab) const = 0;
//Ouputs to decoder.cc
output decoder {{
std::string
- RiscvStaticInst::regName(RegIndex reg) const
+ RiscvStaticInst::regName(RegId reg) const
{
- if (reg < FP_Reg_Base) {
- return std::string(RegisterNames[reg]);
- } else {
- return std::string("f") + std::to_string(reg - FP_Reg_Base);
+ switch (reg.regClass) {
+ case IntRegClass:
+ return std::string(RegisterNames[reg.regIdx]);
+ case FloatRegClass:
+ return std::string("f") + std::to_string(reg.regIdx);
+ default:
+ return csprintf("unknown[%i/%i]", reg.regClass, reg.regIdx);
}
}
}};
Jump::branchTarget(ThreadContext *tc) const
{
PCState pc = tc->pcState();
- IntReg Rs1 = tc->readIntReg(_srcRegIdx[0]);
+ IntReg Rs1 = tc->readIntReg(_srcRegIdx[0].regIdx);
pc.set((Rs1 + imm)&~0x1);
return pc;
}
#include <map>
#include <string>
+#include "arch/generic/types.hh"
#include "arch/isa_traits.hh"
#include "arch/riscv/generated/max_inst_regs.hh"
#include "base/types.hh"
using RiscvISAInst::MaxInstDestRegs;
const int MaxMiscDestRegs = 1;
-typedef uint_fast16_t RegIndex;
typedef uint64_t IntReg;
typedef uint64_t FloatRegBits;
typedef double FloatReg;
const int NumCCRegs = 0;
const int NumMiscRegs = 4096;
-// These help enumerate all the registers for dependence tracking.
-const int FP_Reg_Base = NumIntRegs;
-const int CC_Reg_Base = FP_Reg_Base + NumFloatRegs;
-const int Misc_Reg_Base = CC_Reg_Base + NumCCRegs;
-const int Max_Reg_Index = Misc_Reg_Base + NumMiscRegs;
-
// Semantically meaningful register indices
const int ZeroReg = 0;
const int ReturnAddrReg = 1;
std::string generateDisassembly(Addr pc,
const SymbolTable *symtab) const;
- void printReg(std::ostream &os, int reg) const;
+ void printReg(std::ostream &os, RegId reg) const;
void printSrcReg(std::ostream &os, int reg) const;
void printDestReg(std::ostream &os, int reg) const;
void printRegArray(std::ostream &os,
- const RegIndex indexArray[], int num) const;
+ const RegId indexArray[], int num) const;
void advancePC(SparcISA::PCState &pcState) const;
};
}
void SparcStaticInst::printRegArray(std::ostream &os,
- const RegIndex indexArray[], int num) const
+ const RegId indexArray[], int num) const
{
if (num <= 0)
return;
}
void
- SparcStaticInst::printReg(std::ostream &os, int reg) const
+ SparcStaticInst::printReg(std::ostream &os, RegId reg) const
{
const int MaxGlobal = 8;
const int MaxOutput = 16;
const int MaxLocal = 24;
const int MaxInput = 32;
const int MaxMicroReg = 40;
- if (reg < FP_Reg_Base) {
+ RegIndex reg_idx = reg.regIdx;
+ if (reg.regClass == IntRegClass) {
// If we used a register from the next or previous window,
// take out the offset.
- while (reg >= MaxMicroReg)
- reg -= MaxMicroReg;
- if (reg == FramePointerReg)
+ while (reg_idx >= MaxMicroReg)
+ reg_idx -= MaxMicroReg;
+ if (reg_idx == FramePointerReg)
ccprintf(os, "%%fp");
- else if (reg == StackPointerReg)
+ else if (reg_idx == StackPointerReg)
ccprintf(os, "%%sp");
- else if (reg < MaxGlobal)
- ccprintf(os, "%%g%d", reg);
- else if (reg < MaxOutput)
- ccprintf(os, "%%o%d", reg - MaxGlobal);
- else if (reg < MaxLocal)
- ccprintf(os, "%%l%d", reg - MaxOutput);
- else if (reg < MaxInput)
- ccprintf(os, "%%i%d", reg - MaxLocal);
- else if (reg < MaxMicroReg)
- ccprintf(os, "%%u%d", reg - MaxInput);
+ else if (reg_idx < MaxGlobal)
+ ccprintf(os, "%%g%d", reg_idx);
+ else if (reg_idx < MaxOutput)
+ ccprintf(os, "%%o%d", reg_idx - MaxGlobal);
+ else if (reg_idx < MaxLocal)
+ ccprintf(os, "%%l%d", reg_idx - MaxOutput);
+ else if (reg_idx < MaxInput)
+ ccprintf(os, "%%i%d", reg_idx - MaxLocal);
+ else if (reg_idx < MaxMicroReg)
+ ccprintf(os, "%%u%d", reg_idx - MaxInput);
// The fake int regs that are really control regs
else {
- switch (reg - MaxMicroReg) {
+ switch (reg_idx - MaxMicroReg) {
case 1:
ccprintf(os, "%%y");
break;
break;
}
}
- } else if (reg < Misc_Reg_Base) {
- ccprintf(os, "%%f%d", reg - FP_Reg_Base);
+ } else if (reg.regClass == FloatRegClass) {
+ ccprintf(os, "%%f%d", reg_idx);
} else {
- switch (reg - Misc_Reg_Base) {
+ switch (reg_idx) {
case MISCREG_ASI:
ccprintf(os, "%%asi");
break;
ccprintf(os, "%%fsr");
break;
default:
- ccprintf(os, "%%ctrl%d", reg - Misc_Reg_Base);
+ ccprintf(os, "%%ctrl%d", reg_idx);
}
}
}
IntOp::printPseudoOps(std::ostream &os, Addr pc,
const SymbolTable *symbab) const
{
- if (!std::strcmp(mnemonic, "or") && _srcRegIdx[0] == 0) {
+ if (!std::strcmp(mnemonic, "or") && _srcRegIdx[0].regIdx == 0) {
printMnemonic(os, "mov");
printSrcReg(os, 1);
ccprintf(os, ", ");
const SymbolTable *symbab) const
{
if (!std::strcmp(mnemonic, "or")) {
- if (_numSrcRegs > 0 && _srcRegIdx[0] == 0) {
+ if (_numSrcRegs > 0 && _srcRegIdx[0].regIdx == 0) {
if (imm == 0) {
printMnemonic(os, "clr");
} else {
ccprintf(response, ", ");
}
ccprintf(response, "[");
- if (_srcRegIdx[!store ? 0 : 1] != 0) {
+ if (_srcRegIdx[!store ? 0 : 1].regIdx != 0) {
printSrcReg(response, !store ? 0 : 1);
ccprintf(response, " + ");
}
ccprintf(response, ", ");
}
ccprintf(response, "[");
- if (_srcRegIdx[!save ? 0 : 1] != 0) {
+ if (_srcRegIdx[!save ? 0 : 1].regIdx != 0) {
printReg(response, _srcRegIdx[!save ? 0 : 1]);
ccprintf(response, " + ");
}
ccprintf(response, " ");
// If the first reg is %g0, don't print it.
// This improves readability
- if (_srcRegIdx[0] != 0) {
+ if (_srcRegIdx[0].regIdx != 0) {
printSrcReg(response, 0);
ccprintf(response, ", ");
}
ccprintf(response, " ");
// If the first reg is %g0, don't print it.
// This improves readability
- if (_srcRegIdx[0] != 0) {
+ if (_srcRegIdx[0].regIdx != 0) {
printSrcReg(response, 0);
ccprintf(response, ", ");
}
MiscReg ctrlreg;
} AnyReg;
-typedef uint16_t RegIndex;
-
// semantically meaningful register indices
const int ZeroReg = 0; // architecturally meaningful
// the rest of these depend on the ABI
const int TotalNumRegs = NumIntRegs + NumFloatRegs + NumMiscRegs;
-// These enumerate all the registers for dependence tracking.
-enum DependenceTags {
- FP_Reg_Base = NumIntRegs,
- CC_Reg_Base = FP_Reg_Base + NumFloatRegs,
- Misc_Reg_Base = CC_Reg_Base + NumCCRegs, // NumCCRegs == 0
- Max_Reg_Index = Misc_Reg_Base + NumMiscRegs,
-};
-
} // namespace SparcISA
#endif
OpClass __opClass) :
X86MicroopBase(_machInst, mnem, _instMnem, setFlags,
__opClass),
- src1(_src1.idx), src2(_src2.idx), dest(_dest.idx),
+ src1(_src1.regIdx), src2(_src2.regIdx), dest(_dest.regIdx),
dataSize(_dataSize), spm(_spm)
{}
/*
Request::FlagsType _memFlags,
OpClass __opClass) :
X86MicroopBase(_machInst, mnem, _instMnem, setFlags, __opClass),
- scale(_scale), index(_index.idx), base(_base.idx),
- disp(_disp), segment(_segment.idx),
+ scale(_scale), index(_index.regIdx), base(_base.regIdx),
+ disp(_disp), segment(_segment.regIdx),
dataSize(_dataSize), addressSize(_addressSize),
- memFlags(_memFlags | _segment.idx)
+ memFlags(_memFlags | _segment.regIdx)
{
- assert(_segment.idx < NUM_SEGMENTREGS);
+ assert(_segment.regIdx < NUM_SEGMENTREGS);
foldOBit =
(dataSize == 1 && !_machInst.rex.present) ? 1 << 6 : 0;
foldABit =
_scale, _index, _base, _disp, _segment,
_dataSize, _addressSize, _memFlags,
__opClass),
- data(_data.idx)
+ data(_data.regIdx)
{
}
_scale, _index, _base, _disp, _segment,
_dataSize, _addressSize, _memFlags,
__opClass),
- dataLow(_dataLow.idx),
- dataHi(_dataHi.idx)
+ dataLow(_dataLow.regIdx),
+ dataHi(_dataHi.regIdx)
{
}
OpClass __opClass) :
X86MicroopBase(_machInst, mnem, _instMnem, setFlags,
__opClass),
- src1(_src1.idx), dest(_dest.idx),
+ src1(_src1.regIdx), dest(_dest.regIdx),
srcSize(_srcSize), destSize(_destSize), ext(_ext)
{}
MediaOpBase(_machInst, mnem, _instMnem, setFlags,
_src1, _dest, _srcSize, _destSize, _ext,
__opClass),
- src2(_src2.idx)
+ src2(_src2.regIdx)
{}
std::string generateDisassembly(Addr pc,
OpClass __opClass) :
X86MicroopBase(_machInst, mnem, _instMnem, setFlags,
__opClass),
- src1(_src1.idx), dest(_dest.idx),
+ src1(_src1.regIdx), dest(_dest.regIdx),
dataSize(_dataSize), ext(_ext)
{
foldOBit = (dataSize == 1 && !_machInst.rex.present) ? 1 << 6 : 0;
RegOpBase(_machInst, mnem, _instMnem, setFlags,
_src1, _dest, _dataSize, _ext,
__opClass),
- src2(_src2.idx)
+ src2(_src2.regIdx)
{
}
}
void
- X86StaticInst::printReg(std::ostream &os, int reg, int size) const
+ X86StaticInst::printReg(std::ostream &os, RegId reg, int size) const
{
assert(size == 1 || size == 2 || size == 4 || size == 8);
static const char * abcdFormats[9] =
static const char * microFormats[9] =
{"", "t%db", "t%dw", "", "t%dd", "", "", "", "t%d"};
- RegIndex rel_reg;
+ RegIndex reg_idx = reg.regIdx;
- switch (regIdxToClass(reg, &rel_reg)) {
+ switch (reg.regClass) {
case IntRegClass: {
const char * suffix = "";
- bool fold = rel_reg & IntFoldBit;
- rel_reg &= ~IntFoldBit;
+ bool fold = reg_idx & IntFoldBit;
+ reg_idx &= ~IntFoldBit;
if (fold)
suffix = "h";
- else if (rel_reg < 8 && size == 1)
+ else if (reg_idx < 8 && size == 1)
suffix = "l";
- switch (rel_reg) {
+ switch (reg_idx) {
case INTREG_RAX:
ccprintf(os, abcdFormats[size], "a");
break;
ccprintf(os, longFormats[size], "15");
break;
default:
- ccprintf(os, microFormats[size], rel_reg - NUM_INTREGS);
+ ccprintf(os, microFormats[size], reg_idx - NUM_INTREGS);
}
ccprintf(os, suffix);
break;
}
case FloatRegClass: {
- if (rel_reg < NumMMXRegs) {
- ccprintf(os, "%%mmx%d", rel_reg);
+ if (reg_idx < NumMMXRegs) {
+ ccprintf(os, "%%mmx%d", reg_idx);
return;
}
- rel_reg -= NumMMXRegs;
- if (rel_reg < NumXMMRegs * 2) {
- ccprintf(os, "%%xmm%d_%s", rel_reg / 2,
- (rel_reg % 2) ? "high": "low");
+ reg_idx -= NumMMXRegs;
+ if (reg_idx < NumXMMRegs * 2) {
+ ccprintf(os, "%%xmm%d_%s", reg_idx / 2,
+ (reg_idx % 2) ? "high": "low");
return;
}
- rel_reg -= NumXMMRegs * 2;
- if (rel_reg < NumMicroFpRegs) {
- ccprintf(os, "%%ufp%d", rel_reg);
+ reg_idx -= NumXMMRegs * 2;
+ if (reg_idx < NumMicroFpRegs) {
+ ccprintf(os, "%%ufp%d", reg_idx);
return;
}
- rel_reg -= NumMicroFpRegs;
- ccprintf(os, "%%st(%d)", rel_reg);
+ reg_idx -= NumMicroFpRegs;
+ ccprintf(os, "%%st(%d)", reg_idx);
break;
}
case CCRegClass:
- ccprintf(os, "%%cc%d", rel_reg);
+ ccprintf(os, "%%cc%d", reg_idx);
break;
case MiscRegClass:
- switch (rel_reg) {
+ switch (reg_idx) {
default:
- ccprintf(os, "%%ctrl%d", rel_reg);
+ ccprintf(os, "%%ctrl%d", reg_idx);
}
break;
}
{
if (scale != 1)
ccprintf(os, "%d*", scale);
- printReg(os, index, addressSize);
+ printReg(os, InstRegIndex(index), addressSize);
someAddr = true;
}
if (base != ZeroReg)
{
if (someAddr)
os << " + ";
- printReg(os, base, addressSize);
+ printReg(os, InstRegIndex(base), addressSize);
someAddr = true;
}
}
* wrapper struct for these lets take advantage of the compiler's type
* checking.
*/
- struct InstRegIndex
+ struct InstRegIndex : public RegId
{
- RegIndex idx;
- explicit InstRegIndex(RegIndex _idx) : idx(_idx)
- {}
+ explicit InstRegIndex(RegIndex _idx) :
+ RegId(computeRegClass(_idx), _idx) {}
+
+ private:
+ // TODO: As X86 register index definition is highly built on the
+ // unified space concept, it is easier for the moment to rely on
+ // an helper function to compute the RegClass. It would be nice
+ // to fix those definition and get rid of this.
+ RegClass computeRegClass(RegIndex _idx) {
+ if (_idx < FP_Reg_Base) {
+ return IntRegClass;
+ } else if (_idx < CC_Reg_Base) {
+ return FloatRegClass;
+ } else if (_idx < Misc_Reg_Base) {
+ return CCRegClass;
+ } else {
+ return MiscRegClass;
+ }
+ }
};
/**
void printSegment(std::ostream &os, int segment) const;
- void printReg(std::ostream &os, int reg, int size) const;
+ void printReg(std::ostream &os, RegId reg, int size) const;
void printSrcReg(std::ostream &os, int reg, int size) const;
void printDestReg(std::ostream &os, int reg, int size) const;
void printMem(std::ostream &os, uint8_t segment,
inline uint64_t merge(uint64_t into, uint64_t val, int size) const
{
X86IntReg reg = into;
- if (_destRegIdx[0] & IntFoldBit)
+ if (_destRegIdx[0].regIdx & IntFoldBit)
{
reg.H = val;
return reg;
{
X86IntReg reg = from;
DPRINTF(X86, "Picking with size %d\n", size);
- if (_srcRegIdx[idx] & IntFoldBit)
+ if (_srcRegIdx[idx].regIdx & IntFoldBit)
return reg.H;
switch(size)
{
{
X86IntReg reg = from;
DPRINTF(X86, "Picking with size %d\n", size);
- if (_srcRegIdx[idx] & IntFoldBit)
+ if (_srcRegIdx[idx].regIdx & IntFoldBit)
return reg.SH;
switch(size)
{
InstRegIndex _dest, uint64_t _imm, uint8_t _dataSize) :
%(base_class)s(machInst, "%(mnemonic)s", instMnem,
setFlags, %(op_class)s),
- dest(_dest.idx), imm(_imm), dataSize(_dataSize)
+ dest(_dest.regIdx), imm(_imm), dataSize(_dataSize)
{
foldOBit = (dataSize == 1 && !machInst.rex.present) ? 1 << 6 : 0;
%(constructor)s;
regString = "INTREG_R%s" % opType.reg
env.addReg(regString)
env.addToDisassembly(
- "printReg(out, %s, regSize);\n" % regString)
+ "printReg(out, InstRegIndex(%s), regSize);\n" %
+ regString)
+
Name += "_R"
+
elif opType.tag == "B":
# This refers to registers whose index is encoded as part of the opcode
env.addToDisassembly(
- "printReg(out, %s, regSize);\n" % InstRegIndex)
+ "printReg(out, InstRegIndex(%s), regSize);\n" %
+ InstRegIndex)
+
Name += "_R"
+
env.addReg(InstRegIndex)
elif opType.tag == "M":
# This refers to memory. The macroop constructor sets up modrm
# Use the "reg" field of the ModRM byte to select the register
env.addReg(ModRMRegIndex)
env.addToDisassembly(
- "printReg(out, %s, regSize);\n" % ModRMRegIndex)
+ "printReg(out, InstRegIndex(%s), regSize);\n" %
+ ModRMRegIndex)
+
if opType.tag == "P":
+
Name += "_MMX"
elif opType.tag == "V":
Name += "_XMM"
regEnv = copy.copy(env)
regEnv.addReg(ModRMRMIndex)
regEnv.addToDisassembly(
- "printReg(out, %s, regSize);\n" % ModRMRMIndex)
+ "printReg(out, InstRegIndex(%s), regSize);\n" %
+ ModRMRMIndex)
+
# This refers to memory. The macroop constructor should set up
+
# modrm addressing.
memEnv = copy.copy(env)
memEnv.doModRM = True
# Non register modrm settings should cause an error
env.addReg(ModRMRMIndex)
env.addToDisassembly(
- "printReg(out, %s, regSize);\n" % ModRMRMIndex)
+ "printReg(out, InstRegIndex(%s), regSize);\n" %
+ ModRMRMIndex)
+
if opType.tag == "PR":
+
Name += "_MMX"
elif opType.tag == "VR":
Name += "_XMM"
MiscReg ctrlReg;
} AnyReg;
-typedef uint16_t RegIndex;
-
} // namespace X86ISA
#endif // __ARCH_X86_REGFILE_HH__
typedef typename Impl::CPUType ImplCPU;
typedef typename ImplCPU::ImplState ImplState;
- // Logical register index type.
- typedef TheISA::RegIndex RegIndex;
-
// The DynInstPtr type.
typedef typename Impl::DynInstPtr DynInstPtr;
typedef RefCountingPtr<BaseDynInst<Impl> > BaseDynInstPtr;
/** Flattened register index of the destination registers of this
* instruction.
*/
- std::array<TheISA::RegIndex, TheISA::MaxInstDestRegs> _flatDestRegIdx;
+ std::array<RegId, TheISA::MaxInstDestRegs> _flatDestRegIdx;
/** Physical register index of the destination registers of this
* instruction.
/** Returns the flattened register index of the i'th destination
* register.
*/
- TheISA::RegIndex flattenedDestRegIdx(int idx) const
+ RegId flattenedDestRegIdx(int idx) const
{
return _flatDestRegIdx[idx];
}
/** Flattens a destination architectural register index into a logical
* index.
*/
- void flattenDestReg(int idx, TheISA::RegIndex flattened_dest)
+ void flattenDestReg(int idx, RegId flattened_dest)
{
_flatDestRegIdx[idx] = flattened_dest;
}
int8_t numCCDestRegs() const { return staticInst->numCCDestRegs(); }
/** Returns the logical register index of the i'th destination register. */
- RegIndex destRegIdx(int i) const { return staticInst->destRegIdx(i); }
+ RegId destRegIdx(int i) const { return staticInst->destRegIdx(i); }
/** Returns the logical register index of the i'th source register. */
- RegIndex srcRegIdx(int i) const { return staticInst->srcRegIdx(i); }
+ RegId srcRegIdx(int i) const { return staticInst->srcRegIdx(i); }
/** Pops a result off the instResult queue */
template <class T>
IntReg readIntRegOperand(const StaticInst *si, int idx) override
{
- return thread->readIntReg(si->srcRegIdx(idx));
+ RegId reg = si->srcRegIdx(idx);
+ assert(reg.regClass == IntRegClass);
+ return thread->readIntReg(reg.regIdx);
}
FloatReg readFloatRegOperand(const StaticInst *si, int idx) override
{
- int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Reg_Base;
- return thread->readFloatReg(reg_idx);
+ RegId reg = si->srcRegIdx(idx);
+ assert(reg.regClass == FloatRegClass);
+ return thread->readFloatReg(reg.regIdx);
}
FloatRegBits readFloatRegOperandBits(const StaticInst *si,
int idx) override
{
- int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Reg_Base;
- return thread->readFloatRegBits(reg_idx);
+ RegId reg = si->srcRegIdx(idx);
+ assert(reg.regClass == FloatRegClass);
+ return thread->readFloatRegBits(reg.regIdx);
}
CCReg readCCRegOperand(const StaticInst *si, int idx) override
{
- int reg_idx = si->srcRegIdx(idx) - TheISA::CC_Reg_Base;
- return thread->readCCReg(reg_idx);
+ RegId reg = si->srcRegIdx(idx);
+ assert(reg.regClass == CCRegClass);
+ return thread->readCCReg(reg.regIdx);
}
template <class T>
void setIntRegOperand(const StaticInst *si, int idx,
IntReg val) override
{
- thread->setIntReg(si->destRegIdx(idx), val);
+ RegId reg = si->destRegIdx(idx);
+ assert(reg.regClass == IntRegClass);
+ thread->setIntReg(reg.regIdx, val);
setResult<uint64_t>(val);
}
void setFloatRegOperand(const StaticInst *si, int idx,
FloatReg val) override
{
- int reg_idx = si->destRegIdx(idx) - TheISA::FP_Reg_Base;
- thread->setFloatReg(reg_idx, val);
+ RegId reg = si->destRegIdx(idx);
+ assert(reg.regClass == FloatRegClass);
+ thread->setFloatReg(reg.regIdx, val);
setResult<double>(val);
}
void setFloatRegOperandBits(const StaticInst *si, int idx,
FloatRegBits val) override
{
- int reg_idx = si->destRegIdx(idx) - TheISA::FP_Reg_Base;
- thread->setFloatRegBits(reg_idx, val);
+ RegId reg = si->destRegIdx(idx);
+ assert(reg.regClass == FloatRegClass);
+ thread->setFloatRegBits(reg.regIdx, val);
setResult<uint64_t>(val);
}
void setCCRegOperand(const StaticInst *si, int idx, CCReg val) override
{
- int reg_idx = si->destRegIdx(idx) - TheISA::CC_Reg_Base;
- thread->setCCReg(reg_idx, val);
+ RegId reg = si->destRegIdx(idx);
+ assert(reg.regClass == CCRegClass);
+ thread->setCCReg(reg.regIdx, val);
setResult<uint64_t>(val);
}
MiscReg readMiscRegOperand(const StaticInst *si, int idx) override
{
- int reg_idx = si->srcRegIdx(idx) - TheISA::Misc_Reg_Base;
- return thread->readMiscReg(reg_idx);
+ RegId reg = si->srcRegIdx(idx);
+ assert(reg.regClass == MiscRegClass);
+ return thread->readMiscReg(reg.regIdx);
}
void setMiscRegOperand(const StaticInst *si, int idx,
const MiscReg &val) override
{
- int reg_idx = si->destRegIdx(idx) - TheISA::Misc_Reg_Base;
- return this->setMiscReg(reg_idx, val);
+ RegId reg = si->destRegIdx(idx);
+ assert(reg.regClass == MiscRegClass);
+ return this->setMiscReg(reg.regIdx, val);
}
#if THE_ISA == MIPS_ISA
- MiscReg readRegOtherThread(int misc_reg, ThreadID tid) override
+ MiscReg readRegOtherThread(RegId misc_reg, ThreadID tid) override
{
panic("MIPS MT not defined for CheckerCPU.\n");
return 0;
}
- void setRegOtherThread(int misc_reg, MiscReg val, ThreadID tid) override
+ void setRegOtherThread(RegId misc_reg, MiscReg val, ThreadID tid) override
{
panic("MIPS MT not defined for CheckerCPU.\n");
}
// We've already popped one dest off the queue,
// so do the fix-up then start with the next dest reg;
if (start_idx >= 0) {
- RegIndex idx = inst->destRegIdx(start_idx);
- switch (regIdxToClass(idx)) {
+ RegId idx = inst->destRegIdx(start_idx);
+ switch (idx.regClass) {
case IntRegClass:
- thread->setIntReg(idx, mismatch_val);
+ thread->setIntReg(idx.regIdx, mismatch_val);
break;
case FloatRegClass:
- thread->setFloatRegBits(idx - TheISA::FP_Reg_Base, mismatch_val);
+ thread->setFloatRegBits(idx.regIdx, mismatch_val);
break;
case CCRegClass:
- thread->setCCReg(idx - TheISA::CC_Reg_Base, mismatch_val);
+ thread->setCCReg(idx.regIdx, mismatch_val);
break;
case MiscRegClass:
- thread->setMiscReg(idx - TheISA::Misc_Reg_Base,
- mismatch_val);
+ thread->setMiscReg(idx.regIdx, mismatch_val);
break;
}
}
start_idx++;
uint64_t res = 0;
for (int i = start_idx; i < inst->numDestRegs(); i++) {
- RegIndex idx = inst->destRegIdx(i);
+ RegId idx = inst->destRegIdx(i);
inst->template popResult<uint64_t>(res);
- switch (regIdxToClass(idx)) {
+ switch (idx.regClass) {
case IntRegClass:
- thread->setIntReg(idx, res);
+ thread->setIntReg(idx.regIdx, res);
break;
case FloatRegClass:
- thread->setFloatRegBits(idx - TheISA::FP_Reg_Base, res);
+ thread->setFloatRegBits(idx.regIdx, res);
break;
case CCRegClass:
- thread->setCCReg(idx - TheISA::CC_Reg_Base, res);
+ thread->setCCReg(idx.regIdx, res);
break;
case MiscRegClass:
// Try to get the proper misc register index for ARM here...
- thread->setMiscReg(idx - TheISA::Misc_Reg_Base, res);
+ thread->setMiscReg(idx.regIdx, res);
break;
// else Register is out of range...
}
#include "base/types.hh"
#include "config/the_isa.hh"
#include "cpu/base.hh"
+#include "cpu/reg_class.hh"
#include "cpu/static_inst_fwd.hh"
#include "cpu/translation.hh"
#include "mem/request.hh"
*/
#if THE_ISA == MIPS_ISA
- virtual MiscReg readRegOtherThread(int regIdx,
+ virtual MiscReg readRegOtherThread(RegId reg,
ThreadID tid = InvalidThreadID) = 0;
- virtual void setRegOtherThread(int regIdx, MiscReg val,
+ virtual void setRegOtherThread(RegId reg, MiscReg val,
ThreadID tid = InvalidThreadID) = 0;
#endif
/** Print a register in the form r<n>, f<n>, m<n>(<name>), z for integer,
* float, misc and zero registers given an 'architectural register number' */
static void
-printRegName(std::ostream &os, TheISA::RegIndex reg)
+printRegName(std::ostream &os, RegId reg)
{
- RegClass reg_class = regIdxToClass(reg);
+ RegClass reg_class = reg.regClass;
switch (reg_class)
{
case MiscRegClass:
{
- TheISA::RegIndex misc_reg = reg - TheISA::Misc_Reg_Base;
+ RegIndex misc_reg = reg.regIdx;
/* This is an ugly test because not all archs. have miscRegName */
#if THE_ISA == ARM_ISA
}
break;
case FloatRegClass:
- os << 'f' << static_cast<unsigned int>(reg - TheISA::FP_Reg_Base);
+ os << 'f' << static_cast<unsigned int>(reg.regIdx);
break;
case IntRegClass:
- if (reg == TheISA::ZeroReg) {
+ if (reg.isZeroReg()) {
os << 'z';
} else {
- os << 'r' << static_cast<unsigned int>(reg);
+ os << 'r' << static_cast<unsigned int>(reg.regIdx);
}
break;
case CCRegClass:
- os << 'c' << static_cast<unsigned int>(reg - TheISA::CC_Reg_Base);
+ os << 'c' << static_cast<unsigned int>(reg.regIdx);
}
}
/** Flat register indices so that, when clearing the scoreboard, we
* have the same register indices as when the instruction was marked
* up */
- TheISA::RegIndex flatDestRegIdx[TheISA::MaxInstDestRegs];
+ RegId flatDestRegIdx[TheISA::MaxInstDestRegs];
/** Effective address as set by ExecContext::setEA */
Addr ea;
IntReg
readIntRegOperand(const StaticInst *si, int idx) override
{
- return thread.readIntReg(si->srcRegIdx(idx));
+ RegId reg = si->srcRegIdx(idx);
+ assert(reg.regClass == IntRegClass);
+ return thread.readIntReg(reg.regIdx);
}
TheISA::FloatReg
readFloatRegOperand(const StaticInst *si, int idx) override
{
- int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Reg_Base;
- return thread.readFloatReg(reg_idx);
+ RegId reg = si->srcRegIdx(idx);
+ assert(reg.regClass == FloatRegClass);
+ return thread.readFloatReg(reg.regIdx);
}
TheISA::FloatRegBits
readFloatRegOperandBits(const StaticInst *si, int idx) override
{
- int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Reg_Base;
- return thread.readFloatRegBits(reg_idx);
+ RegId reg = si->srcRegIdx(idx);
+ assert(reg.regClass == FloatRegClass);
+ return thread.readFloatRegBits(reg.regIdx);
}
void
setIntRegOperand(const StaticInst *si, int idx, IntReg val) override
{
- thread.setIntReg(si->destRegIdx(idx), val);
+ RegId reg = si->destRegIdx(idx);
+ assert(reg.regClass == IntRegClass);
+ thread.setIntReg(reg.regIdx, val);
}
void
setFloatRegOperand(const StaticInst *si, int idx,
TheISA::FloatReg val) override
{
- int reg_idx = si->destRegIdx(idx) - TheISA::FP_Reg_Base;
- thread.setFloatReg(reg_idx, val);
+ RegId reg = si->destRegIdx(idx);
+ assert(reg.regClass == FloatRegClass);
+ thread.setFloatReg(reg.regIdx, val);
}
void
setFloatRegOperandBits(const StaticInst *si, int idx,
TheISA::FloatRegBits val) override
{
- int reg_idx = si->destRegIdx(idx) - TheISA::FP_Reg_Base;
- thread.setFloatRegBits(reg_idx, val);
+ RegId reg = si->destRegIdx(idx);
+ assert(reg.regClass == FloatRegClass);
+ thread.setFloatRegBits(reg.regIdx, val);
}
bool
TheISA::MiscReg
readMiscRegOperand(const StaticInst *si, int idx) override
{
- int reg_idx = si->srcRegIdx(idx) - TheISA::Misc_Reg_Base;
- return thread.readMiscReg(reg_idx);
+ RegId reg = si->srcRegIdx(idx);
+ assert(reg.regClass == MiscRegClass);
+ return thread.readMiscReg(reg.regIdx);
}
void
setMiscRegOperand(const StaticInst *si, int idx,
const TheISA::MiscReg &val) override
{
- int reg_idx = si->destRegIdx(idx) - TheISA::Misc_Reg_Base;
- return thread.setMiscReg(reg_idx, val);
+ RegId reg = si->destRegIdx(idx);
+ assert(reg.regClass == MiscRegClass);
+ return thread.setMiscReg(reg.regIdx, val);
}
Fault
TheISA::CCReg
readCCRegOperand(const StaticInst *si, int idx) override
{
- int reg_idx = si->srcRegIdx(idx) - TheISA::CC_Reg_Base;
- return thread.readCCReg(reg_idx);
+ RegId reg = si->srcRegIdx(idx);
+ assert(reg.regClass == CCRegClass);
+ return thread.readCCReg(reg.regIdx);
}
void
setCCRegOperand(const StaticInst *si, int idx, TheISA::CCReg val) override
{
- int reg_idx = si->destRegIdx(idx) - TheISA::CC_Reg_Base;
- thread.setCCReg(reg_idx, val);
+ RegId reg = si->destRegIdx(idx);
+ assert(reg.regClass == CCRegClass);
+ thread.setCCReg(reg.regIdx, val);
}
void
/* MIPS: other thread register reading/writing */
uint64_t
- readRegOtherThread(int idx, ThreadID tid = InvalidThreadID)
+ readRegOtherThread(RegId reg, ThreadID tid = InvalidThreadID)
{
SimpleThread *other_thread = (tid == InvalidThreadID
? &thread : cpu.threads[tid]);
- if (idx < TheISA::FP_Reg_Base) { /* Integer */
- return other_thread->readIntReg(idx);
- } else if (idx < TheISA::Misc_Reg_Base) { /* Float */
- return other_thread->readFloatRegBits(idx
- - TheISA::FP_Reg_Base);
- } else { /* Misc */
- return other_thread->readMiscReg(idx
- - TheISA::Misc_Reg_Base);
+ switch(reg.regClass) {
+ case IntRegClass:
+ return other_thread->readIntReg(reg.regIdx);
+ break;
+ case FloatRegClass:
+ return other_thread->readFloatRegBits(reg.regIdx);
+ break;
+ case MiscRegClass:
+ return other_thread->readMiscReg(reg.regIdx);
+ default:
+ panic("Unexpected reg class! (%s)",
+ RegClassStrings[reg.regClass]);
+ return 0;
}
}
void
- setRegOtherThread(int idx, const TheISA::MiscReg &val,
+ setRegOtherThread(RegId reg, const TheISA::MiscReg &val,
ThreadID tid = InvalidThreadID)
{
SimpleThread *other_thread = (tid == InvalidThreadID
? &thread : cpu.threads[tid]);
- if (idx < TheISA::FP_Reg_Base) { /* Integer */
- return other_thread->setIntReg(idx, val);
- } else if (idx < TheISA::Misc_Reg_Base) { /* Float */
- return other_thread->setFloatRegBits(idx
- - TheISA::FP_Reg_Base, val);
- } else { /* Misc */
- return other_thread->setMiscReg(idx
- - TheISA::Misc_Reg_Base, val);
+ switch(reg.regClass) {
+ case IntRegClass:
+ return other_thread->setIntReg(reg.regIdx, val);
+ break;
+ case FloatRegClass:
+ return other_thread->setFloatRegBits(reg.regIdx, val);
+ break;
+ case MiscRegClass:
+ return other_thread->setMiscReg(reg.regIdx, val);
+ default:
+ panic("Unexpected reg class! (%s)",
+ RegClassStrings[reg.regClass]);
}
}
{
bool
-Scoreboard::findIndex(RegIndex reg, Index &scoreboard_index)
+Scoreboard::findIndex(RegId reg, Index &scoreboard_index)
{
- RegClass reg_class = regIdxToClass(reg);
bool ret = false;
- if (reg == TheISA::ZeroReg) {
+ if (reg.isZeroReg()) {
/* Don't bother with the zero register */
ret = false;
} else {
- switch (reg_class)
+ switch (reg.regClass)
{
case IntRegClass:
- scoreboard_index = reg;
+ scoreboard_index = reg.regIdx;
ret = true;
break;
case FloatRegClass:
scoreboard_index = TheISA::NumIntRegs + TheISA::NumCCRegs +
- reg - TheISA::FP_Reg_Base;
+ reg.regIdx;
ret = true;
break;
case CCRegClass:
- scoreboard_index = TheISA::NumIntRegs + reg - TheISA::FP_Reg_Base;
+ scoreboard_index = TheISA::NumIntRegs + reg.regIdx;
ret = true;
break;
case MiscRegClass:
return ret;
}
-/** Flatten a RegIndex, irrespective of what reg type it's pointing to */
-static TheISA::RegIndex
-flattenRegIndex(TheISA::RegIndex reg, ThreadContext *thread_context)
+/** Flatten a RegId, irrespective of what reg type it's pointing to */
+static RegId
+flattenRegIndex(RegId reg, ThreadContext *thread_context)
{
- RegClass reg_class = regIdxToClass(reg);
- TheISA::RegIndex ret = reg;
-
- switch (reg_class)
+ switch (reg.regClass)
{
case IntRegClass:
- ret = thread_context->flattenIntIndex(reg);
+ reg.regIdx = thread_context->flattenIntIndex(reg.regIdx);
break;
case FloatRegClass:
- ret = thread_context->flattenFloatIndex(reg);
+ reg.regIdx = thread_context->flattenFloatIndex(reg.regIdx);
break;
case CCRegClass:
- ret = thread_context->flattenCCIndex(reg);
+ reg.regIdx = thread_context->flattenCCIndex(reg.regIdx);
break;
case MiscRegClass:
/* Don't bother to flatten misc regs as we don't need them here */
/* return thread_context->flattenMiscIndex(reg); */
- ret = reg;
break;
}
- return ret;
+ return reg;
}
void
for (unsigned int dest_index = 0; dest_index < num_dests;
dest_index++)
{
- RegIndex reg = flattenRegIndex(
- staticInst->destRegIdx(dest_index), thread_context);
+ RegId reg = flattenRegIndex(
+ staticInst->destRegIdx(dest_index), thread_context);
Index index;
if (findIndex(reg, index)) {
*inst, index, numResults[index], returnCycle[index]);
} else {
/* Use ZeroReg to mark invalid/untracked dests */
- inst->flatDestRegIdx[dest_index] = TheISA::ZeroReg;
+ inst->flatDestRegIdx[dest_index] = RegId::zeroReg;
}
}
}
unsigned int num_srcs = staticInst->numSrcRegs();
for (unsigned int src_index = 0; src_index < num_srcs; src_index++) {
- RegIndex reg = flattenRegIndex(staticInst->srcRegIdx(src_index),
+ RegId reg = flattenRegIndex(staticInst->srcRegIdx(src_index),
thread_context);
unsigned short int index;
for (unsigned int dest_index = 0; dest_index < num_dests;
dest_index++)
{
- RegIndex reg = inst->flatDestRegIdx[dest_index];
+ RegId reg = inst->flatDestRegIdx[dest_index];
Index index;
if (findIndex(reg, index)) {
while (src_index < num_srcs && /* More registers */
ret /* Still possible */)
{
- RegIndex reg = flattenRegIndex(staticInst->srcRegIdx(src_index),
+ RegId reg = flattenRegIndex(staticInst->srcRegIdx(src_index),
thread_context);
unsigned short int index;
* [NumIntRegs+NumCCRegs, NumFloatRegs+NumIntRegs+NumCCRegs-1] */
const unsigned numRegs;
- /** Type to use for thread context registers */
- typedef TheISA::RegIndex RegIndex;
-
/** Type to use when indexing numResults */
typedef unsigned short int Index;
/** Sets scoreboard_index to the index into numResults of the
* given register index. Returns true if the given register
* is in the scoreboard and false if it isn't */
- bool findIndex(RegIndex reg, Index &scoreboard_index);
+ bool findIndex(RegId reg, Index &scoreboard_index);
/** Mark up an instruction's effects by incrementing
* numResults counts. If mark_unpredictable is true, the inst's
src_tc = tcBase(tid);
//Bind Int Regs to Rename Map
- for (int ireg = 0; ireg < TheISA::NumIntRegs; ireg++) {
- PhysRegIndex phys_reg = freeList.getIntReg();
- renameMap[tid].setEntry(ireg,phys_reg);
+ for (RegId reg_id(IntRegClass, 0); reg_id.regIdx < TheISA::NumIntRegs;
+ reg_id.regIdx++) {
+ PhysRegIndex phys_reg = freeList.getIntReg();
+ renameMap[tid].setEntry(reg_id, phys_reg);
scoreboard.setReg(phys_reg);
}
//Bind Float Regs to Rename Map
- int max_reg = TheISA::FP_Reg_Base + TheISA::NumFloatRegs;
- for (int freg = TheISA::FP_Reg_Base; freg < max_reg; freg++) {
+ for (RegId reg_id(FloatRegClass, 0); reg_id.regIdx < TheISA::NumFloatRegs;
+ reg_id.regIdx++) {
PhysRegIndex phys_reg = freeList.getFloatReg();
-
- renameMap[tid].setEntry(freg,phys_reg);
+ renameMap[tid].setEntry(reg_id, phys_reg);
scoreboard.setReg(phys_reg);
}
//Bind condition-code Regs to Rename Map
- max_reg = TheISA::CC_Reg_Base + TheISA::NumCCRegs;
- for (int creg = TheISA::CC_Reg_Base;
- creg < max_reg; creg++) {
+ for (RegId reg_id(CCRegClass, 0); reg_id.regIdx < TheISA::NumCCRegs;
+ reg_id.regIdx++) {
PhysRegIndex phys_reg = freeList.getCCReg();
-
- renameMap[tid].setEntry(creg,phys_reg);
+ renameMap[tid].setEntry(reg_id, phys_reg);
scoreboard.setReg(phys_reg);
}
// in SMT workloads.
// Unbind Int Regs from Rename Map
- for (int ireg = 0; ireg < TheISA::NumIntRegs; ireg++) {
- PhysRegIndex phys_reg = renameMap[tid].lookup(ireg);
+ for (RegId reg_id(IntRegClass, 0); reg_id.regIdx < TheISA::NumIntRegs;
+ reg_id.regIdx++) {
+ PhysRegIndex phys_reg = renameMap[tid].lookup(reg_id);
scoreboard.unsetReg(phys_reg);
freeList.addReg(phys_reg);
}
// Unbind Float Regs from Rename Map
- int max_reg = TheISA::FP_Reg_Base + TheISA::NumFloatRegs;
- for (int freg = TheISA::FP_Reg_Base; freg < max_reg; freg++) {
- PhysRegIndex phys_reg = renameMap[tid].lookup(freg);
+ for (RegId reg_id(FloatRegClass, 0); reg_id.regIdx < TheISA::NumFloatRegs;
+ reg_id.regIdx++) {
+ PhysRegIndex phys_reg = renameMap[tid].lookup(reg_id);
scoreboard.unsetReg(phys_reg);
freeList.addReg(phys_reg);
}
// Unbind condition-code Regs from Rename Map
- max_reg = TheISA::CC_Reg_Base + TheISA::NumCCRegs;
- for (int creg = TheISA::CC_Reg_Base; creg < max_reg; creg++) {
- PhysRegIndex phys_reg = renameMap[tid].lookup(creg);
+ for (RegId reg_id(CCRegClass, 0); reg_id.regIdx < TheISA::NumCCRegs;
+ reg_id.regIdx++) {
+ PhysRegIndex phys_reg = renameMap[tid].lookup(reg_id);
scoreboard.unsetReg(phys_reg);
freeList.addReg(phys_reg);
}
typedef TheISA::MachInst MachInst;
/** Extended machine instruction type. */
typedef TheISA::ExtMachInst ExtMachInst;
- /** Logical register index type. */
- typedef TheISA::RegIndex RegIndex;
- /** Integer register index type. */
+ /** Register types. */
typedef TheISA::IntReg IntReg;
typedef TheISA::FloatReg FloatReg;
typedef TheISA::FloatRegBits FloatRegBits;
typedef TheISA::CCReg CCReg;
- /** Misc register index type. */
+ /** Misc register type. */
typedef TheISA::MiscReg MiscReg;
enum {
*/
TheISA::MiscReg readMiscRegOperand(const StaticInst *si, int idx)
{
- return this->cpu->readMiscReg(
- si->srcRegIdx(idx) - TheISA::Misc_Reg_Base,
- this->threadNumber);
+ RegId reg = si->srcRegIdx(idx);
+ assert(reg.regClass == MiscRegClass);
+ return this->cpu->readMiscReg(reg.regIdx, this->threadNumber);
}
/** Sets a misc. register, including any side-effects the write
void setMiscRegOperand(const StaticInst *si, int idx,
const MiscReg &val)
{
- int misc_reg = si->destRegIdx(idx) - TheISA::Misc_Reg_Base;
- setMiscReg(misc_reg, val);
+ RegId reg = si->destRegIdx(idx);
+ assert(reg.regClass == MiscRegClass);
+ setMiscReg(reg.regIdx, val);
}
/** Called at the commit stage to update the misc. registers. */
for (int idx = 0; idx < this->numDestRegs(); idx++) {
PhysRegIndex prev_phys_reg = this->prevDestRegIdx(idx);
- TheISA::RegIndex original_dest_reg =
+ RegId original_dest_reg =
this->staticInst->destRegIdx(idx);
- switch (regIdxToClass(original_dest_reg)) {
+ switch (original_dest_reg.regClass) {
case IntRegClass:
this->setIntRegOperand(this->staticInst.get(), idx,
this->cpu->readIntReg(prev_phys_reg));
}
#if THE_ISA == MIPS_ISA
- MiscReg readRegOtherThread(int misc_reg, ThreadID tid)
+ MiscReg readRegOtherThread(RegId misc_reg, ThreadID tid)
{
panic("MIPS MT not defined for O3 CPU.\n");
return 0;
}
- void setRegOtherThread(int misc_reg, MiscReg val, ThreadID tid)
+ void setRegOtherThread(RegId misc_reg, MiscReg val, ThreadID tid)
{
panic("MIPS MT not defined for O3 CPU.\n");
}
// as the normal register entries. It will allow the IQ to work
// without any modifications.
for (int i = 0; i < this->staticInst->numDestRegs(); i++) {
- this->_destRegIdx[i] = this->staticInst->destRegIdx(i);
+ this->_destRegIdx[i] = this->staticInst->destRegIdx(i).regIdx;
}
for (int i = 0; i < this->staticInst->numSrcRegs(); i++) {
- this->_srcRegIdx[i] = this->staticInst->srcRegIdx(i);
+ this->_srcRegIdx[i] = this->staticInst->srcRegIdx(i).regIdx;
}
this->_readySrcRegIdx.reset();
for (int dest_idx = 0; dest_idx < max_regs; dest_idx++) {
// For data dependency tracking the register must be an int, float or
// CC register and not a Misc register.
- TheISA::RegIndex dest_reg = dyn_inst->destRegIdx(dest_idx);
- if (regIdxToClass(dest_reg) != MiscRegClass) {
- // Get the physical register index of the i'th destination register.
- dest_reg = dyn_inst->renamedDestRegIdx(dest_idx);
- if (dest_reg != TheISA::ZeroReg) {
- DPRINTFR(ElasticTrace, "[sn:%lli] Update map for dest reg %i\n",
- seq_num, dest_reg);
- physRegDepMap[dest_reg] = seq_num;
- }
+ RegId dest_reg = dyn_inst->destRegIdx(dest_idx);
+ if (dest_reg.isRenameable() &&
+ !dest_reg.isZeroReg()) {
+ // Get the physical register index of the i'th destination
+ // register.
+ PhysRegIndex phys_dest_reg = dyn_inst->renamedDestRegIdx(dest_idx);
+ DPRINTFR(ElasticTrace, "[sn:%lli] Update map for dest reg %i\n",
+ seq_num, dest_reg.regIdx);
+ physRegDepMap[phys_dest_reg] = seq_num;
}
}
maxPhysRegDepMapSize = std::max(physRegDepMap.size(),
typedef typename CPUPol::IEW IEW;
typedef typename CPUPol::Commit Commit;
- // Typedefs from the ISA.
- typedef TheISA::RegIndex RegIndex;
-
// A deque is used to queue the instructions. Barrier insts must
// be added to the front of the queue, which is the only reason for
// using a deque instead of a queue. (Most other stages use a
* register for that arch. register, and the new physical register.
*/
struct RenameHistory {
- RenameHistory(InstSeqNum _instSeqNum, RegIndex _archReg,
+ RenameHistory(InstSeqNum _instSeqNum, RegId _archReg,
PhysRegIndex _newPhysReg, PhysRegIndex _prevPhysReg)
: instSeqNum(_instSeqNum), archReg(_archReg),
newPhysReg(_newPhysReg), prevPhysReg(_prevPhysReg)
/** The sequence number of the instruction that renamed. */
InstSeqNum instSeqNum;
/** The architectural register index that was renamed. */
- RegIndex archReg;
+ RegId archReg;
/** The new physical register that the arch. register is renamed to. */
PhysRegIndex newPhysReg;
/** The old physical register that the arch. register was renamed to. */
// Get the architectual register numbers from the source and
// operands, and redirect them to the right physical register.
for (int src_idx = 0; src_idx < num_src_regs; src_idx++) {
- RegIndex src_reg = inst->srcRegIdx(src_idx);
- RegIndex rel_src_reg;
- RegIndex flat_rel_src_reg;
+ RegId src_reg = inst->srcRegIdx(src_idx);
+ RegIndex flat_src_reg;
PhysRegIndex renamed_reg;
- switch (regIdxToClass(src_reg, &rel_src_reg)) {
+ switch (src_reg.regClass) {
case IntRegClass:
- flat_rel_src_reg = tc->flattenIntIndex(rel_src_reg);
- renamed_reg = map->lookupInt(flat_rel_src_reg);
+ flat_src_reg = tc->flattenIntIndex(src_reg.regIdx);
+ renamed_reg = map->lookupInt(flat_src_reg);
intRenameLookups++;
break;
case FloatRegClass:
- flat_rel_src_reg = tc->flattenFloatIndex(rel_src_reg);
- renamed_reg = map->lookupFloat(flat_rel_src_reg);
+ flat_src_reg = tc->flattenFloatIndex(src_reg.regIdx);
+ renamed_reg = map->lookupFloat(flat_src_reg);
fpRenameLookups++;
break;
case CCRegClass:
- flat_rel_src_reg = tc->flattenCCIndex(rel_src_reg);
- renamed_reg = map->lookupCC(flat_rel_src_reg);
+ flat_src_reg = tc->flattenCCIndex(src_reg.regIdx);
+ renamed_reg = map->lookupCC(flat_src_reg);
break;
case MiscRegClass:
// misc regs don't get flattened
- flat_rel_src_reg = rel_src_reg;
- renamed_reg = map->lookupMisc(flat_rel_src_reg);
+ flat_src_reg = src_reg.regIdx;
+ renamed_reg = map->lookupMisc(flat_src_reg);
break;
default:
- panic("Reg index is out of bound: %d.", src_reg);
+ panic("Invalid register class: %d.", src_reg.regClass);
}
DPRINTF(Rename, "[tid:%u]: Looking up %s arch reg %i (flattened %i), "
- "got phys reg %i\n", tid, RegClassStrings[regIdxToClass(src_reg)],
- (int)src_reg, (int)flat_rel_src_reg, (int)renamed_reg);
+ "got phys reg %i\n", tid, RegClassStrings[src_reg.regClass],
+ (int)src_reg.regIdx, (int)flat_src_reg, (int)renamed_reg);
inst->renameSrcReg(src_idx, renamed_reg);
// Rename the destination registers.
for (int dest_idx = 0; dest_idx < num_dest_regs; dest_idx++) {
- RegIndex dest_reg = inst->destRegIdx(dest_idx);
- RegIndex rel_dest_reg;
- RegIndex flat_rel_dest_reg;
- RegIndex flat_uni_dest_reg;
+ RegId dest_reg = inst->destRegIdx(dest_idx);
+ RegIndex flat_dest_reg;
typename RenameMap::RenameInfo rename_result;
- switch (regIdxToClass(dest_reg, &rel_dest_reg)) {
+ switch (dest_reg.regClass) {
case IntRegClass:
- flat_rel_dest_reg = tc->flattenIntIndex(rel_dest_reg);
- rename_result = map->renameInt(flat_rel_dest_reg);
- flat_uni_dest_reg = flat_rel_dest_reg; // 1:1 mapping
+ flat_dest_reg = tc->flattenIntIndex(dest_reg.regIdx);
+ rename_result = map->renameInt(flat_dest_reg);
break;
case FloatRegClass:
- flat_rel_dest_reg = tc->flattenFloatIndex(rel_dest_reg);
- rename_result = map->renameFloat(flat_rel_dest_reg);
- flat_uni_dest_reg = flat_rel_dest_reg + TheISA::FP_Reg_Base;
+ flat_dest_reg = tc->flattenFloatIndex(dest_reg.regIdx);
+ rename_result = map->renameFloat(flat_dest_reg);
break;
case CCRegClass:
- flat_rel_dest_reg = tc->flattenCCIndex(rel_dest_reg);
- rename_result = map->renameCC(flat_rel_dest_reg);
- flat_uni_dest_reg = flat_rel_dest_reg + TheISA::CC_Reg_Base;
+ flat_dest_reg = tc->flattenCCIndex(dest_reg.regIdx);
+ rename_result = map->renameCC(flat_dest_reg);
break;
case MiscRegClass:
// misc regs don't get flattened
- flat_rel_dest_reg = rel_dest_reg;
- rename_result = map->renameMisc(flat_rel_dest_reg);
- flat_uni_dest_reg = flat_rel_dest_reg + TheISA::Misc_Reg_Base;
+ flat_dest_reg = dest_reg.regIdx;
+ rename_result = map->renameMisc(dest_reg.regIdx);
break;
default:
- panic("Reg index is out of bound: %d.", dest_reg);
+ panic("Invalid register class: %d.", dest_reg.regClass);
}
+ RegId flat_uni_dest_reg(dest_reg.regClass, flat_dest_reg);
+
inst->flattenDestReg(dest_idx, flat_uni_dest_reg);
// Mark Scoreboard entry as not ready
scoreboard->unsetReg(rename_result.first);
DPRINTF(Rename, "[tid:%u]: Renaming arch reg %i to physical "
- "reg %i.\n", tid, (int)flat_rel_dest_reg,
+ "reg %i.\n", tid, (int)flat_dest_reg,
(int)rename_result.first);
// Record the rename information so that a history can be kept.
buf_it = historyBuffer[tid].begin();
while (buf_it != historyBuffer[tid].end()) {
- cprintf("Seq num: %i\nArch reg: %i New phys reg: %i Old phys "
- "reg: %i\n", (*buf_it).instSeqNum, (int)(*buf_it).archReg,
+ cprintf("Seq num: %i\nArch reg[%s]: %i New phys reg: %i Old phys "
+ "reg: %i\n", (*buf_it).instSeqNum,
+ RegClassStrings[(*buf_it).archReg.regClass],
+ (*buf_it).archReg.regIdx,
(int)(*buf_it).newPhysReg, (int)(*buf_it).prevPhysReg);
buf_it++;
UnifiedRenameMap::RenameInfo
-UnifiedRenameMap::rename(RegIndex arch_reg)
+UnifiedRenameMap::rename(RegId arch_reg)
{
- RegIndex rel_arch_reg;
-
- switch (regIdxToClass(arch_reg, &rel_arch_reg)) {
+ switch (arch_reg.regClass) {
case IntRegClass:
- return renameInt(rel_arch_reg);
+ return renameInt(arch_reg.regIdx);
case FloatRegClass:
- return renameFloat(rel_arch_reg);
+ return renameFloat(arch_reg.regIdx);
case CCRegClass:
- return renameCC(rel_arch_reg);
+ return renameCC(arch_reg.regIdx);
case MiscRegClass:
- return renameMisc(rel_arch_reg);
+ return renameMisc(arch_reg.regIdx);
default:
panic("rename rename(): unknown reg class %s\n",
- RegClassStrings[regIdxToClass(arch_reg)]);
+ RegClassStrings[arch_reg.regClass]);
}
}
PhysRegIndex
-UnifiedRenameMap::lookup(RegIndex arch_reg) const
+UnifiedRenameMap::lookup(RegId arch_reg) const
{
- RegIndex rel_arch_reg;
-
- switch (regIdxToClass(arch_reg, &rel_arch_reg)) {
+ switch (arch_reg.regClass) {
case IntRegClass:
- return lookupInt(rel_arch_reg);
+ return lookupInt(arch_reg.regIdx);
case FloatRegClass:
- return lookupFloat(rel_arch_reg);
+ return lookupFloat(arch_reg.regIdx);
case CCRegClass:
- return lookupCC(rel_arch_reg);
+ return lookupCC(arch_reg.regIdx);
case MiscRegClass:
- return lookupMisc(rel_arch_reg);
+ return lookupMisc(arch_reg.regIdx);
default:
panic("rename lookup(): unknown reg class %s\n",
- RegClassStrings[regIdxToClass(arch_reg)]);
+ RegClassStrings[arch_reg.regClass]);
}
}
void
-UnifiedRenameMap::setEntry(RegIndex arch_reg, PhysRegIndex phys_reg)
+UnifiedRenameMap::setEntry(RegId arch_reg, PhysRegIndex phys_reg)
{
- RegIndex rel_arch_reg;
-
- switch (regIdxToClass(arch_reg, &rel_arch_reg)) {
+ switch (arch_reg.regClass) {
case IntRegClass:
- return setIntEntry(rel_arch_reg, phys_reg);
+ return setIntEntry(arch_reg.regIdx, phys_reg);
case FloatRegClass:
- return setFloatEntry(rel_arch_reg, phys_reg);
+ return setFloatEntry(arch_reg.regIdx, phys_reg);
case CCRegClass:
- return setCCEntry(rel_arch_reg, phys_reg);
+ return setCCEntry(arch_reg.regIdx, phys_reg);
case MiscRegClass:
// Misc registers do not actually rename, so don't change
// their mappings. We end up here when a commit or squash
// tries to update or undo a hardwired misc reg nmapping,
// which should always be setting it to what it already is.
- assert(phys_reg == lookupMisc(rel_arch_reg));
+ assert(phys_reg == lookupMisc(arch_reg.regIdx));
return;
default:
panic("rename setEntry(): unknown reg class %s\n",
- RegClassStrings[regIdxToClass(arch_reg)]);
+ RegClassStrings[arch_reg.regClass]);
}
}
*/
class SimpleRenameMap
{
- public:
-
- typedef TheISA::RegIndex RegIndex;
-
private:
/** The acutal arch-to-phys register map */
/**
* Unified register rename map for all classes of registers. Wraps a
* set of class-specific rename maps. Methods that do not specify a
- * register class (e.g., rename()) take unified register indices,
+ * register class (e.g., rename()) take register ids,
* while methods that do specify a register class (e.g., renameInt())
- * take relative register indices. See http://gem5.org/Register_Indexing.
+ * take register indices.
*/
class UnifiedRenameMap
{
SimpleRenameMap ccMap;
public:
- typedef TheISA::RegIndex RegIndex;
typedef SimpleRenameMap::RenameInfo RenameInfo;
/**
* Tell rename map to get a new free physical register to remap
- * the specified architectural register. This version takes a
- * unified flattened architectural register index and calls the
+ * the specified architectural register. This version takes a
+ * flattened architectural register id and calls the
* appropriate class-specific rename table.
- * @param arch_reg The unified architectural register index to remap.
+ * @param arch_reg The architectural register index to remap.
* @return A RenameInfo pair indicating both the new and previous
* physical registers.
*/
- RenameInfo rename(RegIndex arch_reg);
+ RenameInfo rename(RegId arch_reg);
/**
- * Perform rename() on an integer register, given a relative
+ * Perform rename() on an integer register, given a
* integer register index.
*/
RenameInfo renameInt(RegIndex rel_arch_reg)
}
/**
- * Perform rename() on a floating-point register, given a relative
+ * Perform rename() on a floating-point register, given a
* floating-point register index.
*/
RenameInfo renameFloat(RegIndex rel_arch_reg)
}
/**
- * Perform rename() on a condition-code register, given a relative
+ * Perform rename() on a condition-code register, given a
* condition-code register index.
*/
RenameInfo renameCC(RegIndex rel_arch_reg)
}
/**
- * Perform rename() on a misc register, given a relative
+ * Perform rename() on a misc register, given a
* misc register index.
*/
RenameInfo renameMisc(RegIndex rel_arch_reg)
/**
* Look up the physical register mapped to an architectural register.
- * This version takes a unified flattened architectural register index
+ * This version takes a flattened architectural register id
* and calls the appropriate class-specific rename table.
- * @param arch_reg The unified architectural register to look up.
+ * @param arch_reg The architectural register to look up.
* @return The physical register it is currently mapped to.
*/
- PhysRegIndex lookup(RegIndex arch_reg) const;
+ PhysRegIndex lookup(RegId arch_reg) const;
/**
- * Perform lookup() on an integer register, given a relative
+ * Perform lookup() on an integer register, given a
* integer register index.
*/
PhysRegIndex lookupInt(RegIndex rel_arch_reg) const
}
/**
- * Perform lookup() on a floating-point register, given a relative
+ * Perform lookup() on a floating-point register, given a
* floating-point register index.
*/
PhysRegIndex lookupFloat(RegIndex rel_arch_reg) const
}
/**
- * Perform lookup() on a condition-code register, given a relative
+ * Perform lookup() on a condition-code register, given a
* condition-code register index.
*/
PhysRegIndex lookupCC(RegIndex rel_arch_reg) const
/**
* Update rename map with a specific mapping. Generally used to
* roll back to old mappings on a squash. This version takes a
- * unified flattened architectural register index and calls the
+ * flattened architectural register id and calls the
* appropriate class-specific rename table.
- * @param arch_reg The unified architectural register to remap.
+ * @param arch_reg The architectural register to remap.
* @param phys_reg The physical register to remap it to.
*/
- void setEntry(RegIndex arch_reg, PhysRegIndex phys_reg);
+ void setEntry(RegId arch_reg, PhysRegIndex phys_reg);
/**
- * Perform setEntry() on an integer register, given a relative
+ * Perform setEntry() on an integer register, given a
* integer register index.
*/
void setIntEntry(RegIndex arch_reg, PhysRegIndex phys_reg)
}
/**
- * Perform setEntry() on a floating-point register, given a relative
+ * Perform setEntry() on a floating-point register, given a
* floating-point register index.
*/
void setFloatEntry(RegIndex arch_reg, PhysRegIndex phys_reg)
}
/**
- * Perform setEntry() on a condition-code register, given a relative
+ * Perform setEntry() on a condition-code register, given a
* condition-code register index.
*/
void setCCEntry(RegIndex arch_reg, PhysRegIndex phys_reg)
template <class Impl>
class ROB
{
- protected:
- typedef TheISA::RegIndex RegIndex;
public:
//Typedefs from the Impl.
typedef typename Impl::O3CPU O3CPU;
"CCRegClass",
"MiscRegClass"
};
+
+const RegId RegId::zeroReg = RegId(IntRegClass, TheISA::ZeroReg);
/*
+ * Copyright (c) 2016 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
* Copyright (c) 2013 Advanced Micro Devices, Inc.
* All rights reserved
*.
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Steve Reinhardt
+ * Nathanael Premillieu
*/
#ifndef __CPU__REG_CLASS_HH__
#include <cassert>
#include <cstddef>
+#include "arch/generic/types.hh"
#include "arch/registers.hh"
#include "config/the_isa.hh"
/// unhandled cases in some switch statements.
const int NumRegClasses = MiscRegClass + 1;
-/**
- * Map a 'unified' architectural register index to its register class.
- * The unified architectural register index space is used to represent
- * all architectural register identifiers in a single contiguous
- * index space. See http://gem5.org/Register_Indexing.
- *
- * @param reg_idx Unified-space register index
- * @param rel_reg_idx Optional output param pointer; if non-NULL, location
- * will be written with the relative register index for reg_idx
- *
- * @return Register class of reg_idx
- */
-inline
-RegClass regIdxToClass(TheISA::RegIndex reg_idx,
- TheISA::RegIndex *rel_reg_idx = NULL)
-{
- assert(reg_idx < TheISA::Max_Reg_Index);
- RegClass cl;
- int offset;
+/// Register ID: describe an architectural register with its class and index.
+/// This structure is used instead of just the register index to disambiguate
+/// between different classes of registers.
+/// For example, a integer register with index 3 is represented by
+/// Regid(IntRegClass, 3).
+struct RegId {
+ RegClass regClass;
+ RegIndex regIdx;
+ RegId() {};
+ RegId(RegClass reg_class, RegIndex reg_idx)
+ : regClass(reg_class), regIdx(reg_idx)
+ {}
- if (reg_idx < TheISA::FP_Reg_Base) {
- cl = IntRegClass;
- offset = 0;
- } else if (reg_idx < TheISA::CC_Reg_Base) {
- cl = FloatRegClass;
- offset = TheISA::FP_Reg_Base;
- } else if (reg_idx < TheISA::Misc_Reg_Base) {
- // if there are no CC regs, the ISA should set
- // CC_Reg_Base == Misc_Reg_Base so the if above
- // never succeeds
- cl = CCRegClass;
- offset = TheISA::CC_Reg_Base;
- } else {
- cl = MiscRegClass;
- offset = TheISA::Misc_Reg_Base;
+ bool operator==(const RegId& that) const {
+ return regClass == that.regClass && regIdx == that.regIdx;
}
- if (rel_reg_idx)
- *rel_reg_idx = reg_idx - offset;
- return cl;
-}
+ bool operator!=(const RegId& that) const {
+ return !(*this==that);
+ }
-/// Map enum values to strings for debugging
-extern const char *RegClassStrings[];
+ /**
+ * Returns true if this register is a zero register (needs to have a
+ * constant zero value throughout the execution)
+ */
+ bool isZeroReg() const
+ {
+ return (regIdx == TheISA::ZeroReg &&
+ (regClass == IntRegClass ||
+ (THE_ISA == ALPHA_ISA && regClass == FloatRegClass)));
+ }
+ /**
+ * Return true if this register can be renamed
+ */
+ bool isRenameable()
+ {
+ return regClass != MiscRegClass;
+ }
+ static const RegId zeroReg;
+};
+
+/// Map enum values to strings for debugging
+extern const char *RegClassStrings[];
#endif // __CPU__REG_CLASS_HH__
#include "config/the_isa.hh"
#include "cpu/base.hh"
#include "cpu/exec_context.hh"
+#include "cpu/reg_class.hh"
#include "cpu/simple/base.hh"
#include "cpu/static_inst_fwd.hh"
#include "cpu/translation.hh"
IntReg readIntRegOperand(const StaticInst *si, int idx) override
{
numIntRegReads++;
- return thread->readIntReg(si->srcRegIdx(idx));
+ RegId reg = si->srcRegIdx(idx);
+ assert(reg.regClass == IntRegClass);
+ return thread->readIntReg(reg.regIdx);
}
/** Sets an integer register to a value. */
void setIntRegOperand(const StaticInst *si, int idx, IntReg val) override
{
numIntRegWrites++;
- thread->setIntReg(si->destRegIdx(idx), val);
+ RegId reg = si->destRegIdx(idx);
+ assert(reg.regClass == IntRegClass);
+ thread->setIntReg(reg.regIdx, val);
}
/** Reads a floating point register of single register width. */
FloatReg readFloatRegOperand(const StaticInst *si, int idx) override
{
numFpRegReads++;
- int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Reg_Base;
- return thread->readFloatReg(reg_idx);
+ RegId reg = si->srcRegIdx(idx);
+ assert(reg.regClass == FloatRegClass);
+ return thread->readFloatReg(reg.regIdx);
}
/** Reads a floating point register in its binary format, instead
FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx) override
{
numFpRegReads++;
- int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Reg_Base;
- return thread->readFloatRegBits(reg_idx);
+ RegId reg = si->srcRegIdx(idx);
+ assert(reg.regClass == FloatRegClass);
+ return thread->readFloatRegBits(reg.regIdx);
}
/** Sets a floating point register of single width to a value. */
FloatReg val) override
{
numFpRegWrites++;
- int reg_idx = si->destRegIdx(idx) - TheISA::FP_Reg_Base;
- thread->setFloatReg(reg_idx, val);
+ RegId reg = si->destRegIdx(idx);
+ assert(reg.regClass == FloatRegClass);
+ thread->setFloatReg(reg.regIdx, val);
}
/** Sets the bits of a floating point register of single width
FloatRegBits val) override
{
numFpRegWrites++;
- int reg_idx = si->destRegIdx(idx) - TheISA::FP_Reg_Base;
- thread->setFloatRegBits(reg_idx, val);
+ RegId reg = si->destRegIdx(idx);
+ assert(reg.regClass == FloatRegClass);
+ thread->setFloatRegBits(reg.regIdx, val);
}
CCReg readCCRegOperand(const StaticInst *si, int idx) override
{
numCCRegReads++;
- int reg_idx = si->srcRegIdx(idx) - TheISA::CC_Reg_Base;
- return thread->readCCReg(reg_idx);
+ RegId reg = si->srcRegIdx(idx);
+ assert(reg.regClass == CCRegClass);
+ return thread->readCCReg(reg.regIdx);
}
void setCCRegOperand(const StaticInst *si, int idx, CCReg val) override
{
numCCRegWrites++;
- int reg_idx = si->destRegIdx(idx) - TheISA::CC_Reg_Base;
- thread->setCCReg(reg_idx, val);
+ RegId reg = si->destRegIdx(idx);
+ assert(reg.regClass == CCRegClass);
+ thread->setCCReg(reg.regIdx, val);
}
MiscReg readMiscRegOperand(const StaticInst *si, int idx) override
{
numIntRegReads++;
- int reg_idx = si->srcRegIdx(idx) - TheISA::Misc_Reg_Base;
- return thread->readMiscReg(reg_idx);
+ RegId reg = si->srcRegIdx(idx);
+ assert(reg.regClass == MiscRegClass);
+ return thread->readMiscReg(reg.regIdx);
}
void setMiscRegOperand(const StaticInst *si, int idx,
const MiscReg &val) override
{
numIntRegWrites++;
- int reg_idx = si->destRegIdx(idx) - TheISA::Misc_Reg_Base;
- thread->setMiscReg(reg_idx, val);
+ RegId reg = si->destRegIdx(idx);
+ assert(reg.regClass == MiscRegClass);
+ thread->setMiscReg(reg.regIdx, val);
}
/**
}
#if THE_ISA == MIPS_ISA
- MiscReg readRegOtherThread(int regIdx, ThreadID tid = InvalidThreadID)
+ MiscReg readRegOtherThread(RegId reg, ThreadID tid = InvalidThreadID)
override
{
panic("Simple CPU models do not support multithreaded "
"register access.");
}
- void setRegOtherThread(int regIdx, MiscReg val,
+ void setRegOtherThread(RegId reg, MiscReg val,
ThreadID tid = InvalidThreadID) override
{
panic("Simple CPU models do not support multithreaded "
#include "base/types.hh"
#include "config/the_isa.hh"
#include "cpu/op_class.hh"
+#include "cpu/reg_class.hh"
#include "cpu/static_inst_fwd.hh"
#include "cpu/thread_context.hh"
#include "enums/StaticInstFlags.hh"
public:
/// Binary extended machine instruction type.
typedef TheISA::ExtMachInst ExtMachInst;
- /// Logical register index type.
- typedef TheISA::RegIndex RegIndex;
enum {
MaxInstSrcRegs = TheISA::MaxInstSrcRegs, //< Max source regs
/// Return logical index (architectural reg num) of i'th destination reg.
/// Only the entries from 0 through numDestRegs()-1 are valid.
- RegIndex destRegIdx(int i) const { return _destRegIdx[i]; }
+ RegId destRegIdx(int i) const { return _destRegIdx[i]; }
/// Return logical index (architectural reg num) of i'th source reg.
/// Only the entries from 0 through numSrcRegs()-1 are valid.
- RegIndex srcRegIdx(int i) const { return _srcRegIdx[i]; }
+ RegId srcRegIdx(int i) const { return _srcRegIdx[i]; }
/// Pointer to a statically allocated "null" instruction object.
/// Used to give eaCompInst() and memAccInst() something to return
protected:
/// See destRegIdx().
- RegIndex _destRegIdx[MaxInstDestRegs];
+ RegId _destRegIdx[MaxInstDestRegs];
/// See srcRegIdx().
- RegIndex _srcRegIdx[MaxInstSrcRegs];
+ RegId _srcRegIdx[MaxInstSrcRegs];
/**
* Base mnemonic (e.g., "add"). Used by generateDisassembly()
#include "arch/types.hh"
#include "base/types.hh"
#include "config/the_isa.hh"
+#include "cpu/reg_class.hh"
// @todo: Figure out a more architecture independent way to obtain the ITB and
// DTB pointers.
virtual int flattenMiscIndex(int reg) = 0;
virtual uint64_t
- readRegOtherThread(int misc_reg, ThreadID tid)
+ readRegOtherThread(RegId misc_reg, ThreadID tid)
{
return 0;
}
virtual void
- setRegOtherThread(int misc_reg, const MiscReg &val, ThreadID tid)
+ setRegOtherThread(RegId misc_reg, const MiscReg &val, ThreadID tid)
{
}
uint64_t TimingExprSrcReg::eval(TimingExprEvalContext &context)
{
- return context.inst->srcRegIdx(index);
+ return context.inst->srcRegIdx(index).regIdx;
}
uint64_t TimingExprReadIntReg::eval(TimingExprEvalContext &context)