arch, cpu: Architectural Register structural indexing
Replace the unified register mapping with a structure associating a class and an index. It is now much easier to know which class of register the index is referring to. Also, when adding a new class there is no need to modify existing ones. Change-Id: I55b3ac80763702aa2cd3ed2cbff0a75ef7620373 Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com> [ Fix RISCV build issues ] Signed-off-by: Andreas Sandberg <andreas.sandberg@arm.com> Reviewed-on: https://gem5-review.googlesource.com/2700
This commit is contained in:
committed by
Andreas Sandberg
parent
864f87f9c5
commit
5e8287d2e2
@@ -130,7 +130,7 @@ output decoder {{
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -149,7 +149,7 @@ output decoder {{
|
||||
|
||||
#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];
|
||||
|
||||
@@ -220,13 +220,6 @@ output header {{
|
||||
{
|
||||
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)
|
||||
@@ -236,7 +229,7 @@ output header {{
|
||||
|
||||
/// 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;
|
||||
@@ -251,13 +244,13 @@ output header {{
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
|
||||
#include "arch/alpha/generated/max_inst_regs.hh"
|
||||
#include "arch/alpha/ipr.hh"
|
||||
#include "arch/generic/types.hh"
|
||||
#include "base/types.hh"
|
||||
|
||||
namespace AlphaISA {
|
||||
@@ -43,7 +44,6 @@ using AlphaISAInst::MaxInstDestRegs;
|
||||
// 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
|
||||
@@ -100,16 +100,6 @@ const int NumMiscRegs = NUM_MISCREGS;
|
||||
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__
|
||||
|
||||
@@ -95,7 +95,7 @@ BranchReg64::generateDisassembly(
|
||||
{
|
||||
std::stringstream ss;
|
||||
printMnemonic(ss, "", false);
|
||||
printReg(ss, op1);
|
||||
printIntReg(ss, op1);
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ BranchRet64::generateDisassembly(
|
||||
std::stringstream ss;
|
||||
printMnemonic(ss, "", false);
|
||||
if (op1 != INTREG_X30)
|
||||
printReg(ss, op1);
|
||||
printIntReg(ss, op1);
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
@@ -125,7 +125,7 @@ BranchImmReg64::generateDisassembly(
|
||||
{
|
||||
std::stringstream ss;
|
||||
printMnemonic(ss, "", false);
|
||||
printReg(ss, op1);
|
||||
printIntReg(ss, op1);
|
||||
ccprintf(ss, ", ");
|
||||
printTarget(ss, pc + imm, symtab);
|
||||
return ss.str();
|
||||
@@ -137,7 +137,7 @@ BranchImmImmReg64::generateDisassembly(
|
||||
{
|
||||
std::stringstream ss;
|
||||
printMnemonic(ss, "", false);
|
||||
printReg(ss, op1);
|
||||
printIntReg(ss, op1);
|
||||
ccprintf(ss, ", #%#x, ", imm1);
|
||||
printTarget(ss, pc + imm2, symtab);
|
||||
return ss.str();
|
||||
|
||||
@@ -56,7 +56,7 @@ DataXImmOnlyOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
std::stringstream ss;
|
||||
printMnemonic(ss, "", false);
|
||||
printReg(ss, dest);
|
||||
printIntReg(ss, dest);
|
||||
ccprintf(ss, ", #%d", imm);
|
||||
return ss.str();
|
||||
}
|
||||
@@ -84,9 +84,9 @@ DataX1RegOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
std::stringstream ss;
|
||||
printMnemonic(ss, "", false);
|
||||
printReg(ss, dest);
|
||||
printIntReg(ss, dest);
|
||||
ccprintf(ss, ", ");
|
||||
printReg(ss, op1);
|
||||
printIntReg(ss, op1);
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
@@ -95,9 +95,9 @@ DataX1RegImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
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();
|
||||
}
|
||||
@@ -107,9 +107,9 @@ DataX1Reg2ImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
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();
|
||||
}
|
||||
@@ -119,11 +119,11 @@ DataX2RegOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -132,11 +132,11 @@ DataX2RegImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
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();
|
||||
}
|
||||
@@ -146,13 +146,13 @@ DataX3RegOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -162,7 +162,7 @@ DataXCondCompImmOp::generateDisassembly(
|
||||
{
|
||||
std::stringstream ss;
|
||||
printMnemonic(ss, "", false);
|
||||
printReg(ss, op1);
|
||||
printIntReg(ss, op1);
|
||||
ccprintf(ss, ", #%d, #%d", imm, defCc);
|
||||
ccprintf(ss, ", ");
|
||||
printCondition(ss, condCode, true);
|
||||
@@ -175,9 +175,9 @@ DataXCondCompRegOp::generateDisassembly(
|
||||
{
|
||||
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);
|
||||
@@ -190,11 +190,11 @@ DataXCondSelOp::generateDisassembly(
|
||||
{
|
||||
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();
|
||||
|
||||
@@ -1525,9 +1525,9 @@ MicroIntImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
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();
|
||||
@@ -1538,9 +1538,9 @@ MicroIntImmXOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
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();
|
||||
@@ -1560,9 +1560,9 @@ MicroIntRegXOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
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();
|
||||
}
|
||||
@@ -1572,9 +1572,9 @@ MicroIntMov::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
std::stringstream ss;
|
||||
printMnemonic(ss);
|
||||
printReg(ss, ura);
|
||||
printIntReg(ss, ura);
|
||||
ss << ", ";
|
||||
printReg(ss, urb);
|
||||
printIntReg(ss, urb);
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
@@ -1583,11 +1583,11 @@ MicroIntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -1597,11 +1597,11 @@ MicroMemOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
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 << "]";
|
||||
@@ -1613,11 +1613,11 @@ MicroMemPairOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
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 << "]";
|
||||
|
||||
@@ -54,7 +54,7 @@ MemoryReg::printOffset(std::ostream &os) const
|
||||
{
|
||||
if (!add)
|
||||
os << "-";
|
||||
printReg(os, index);
|
||||
printIntReg(os, index);
|
||||
if (shiftType != LSL || shiftAmt != 0) {
|
||||
switch (shiftType) {
|
||||
case LSL:
|
||||
@@ -82,11 +82,11 @@ Swap::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
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();
|
||||
}
|
||||
@@ -109,7 +109,7 @@ RfeOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
printMnemonic(ss, "ib");
|
||||
break;
|
||||
}
|
||||
printReg(ss, base);
|
||||
printIntReg(ss, base);
|
||||
if (wb) {
|
||||
ss << "!";
|
||||
}
|
||||
@@ -134,7 +134,7 @@ SrsOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
printMnemonic(ss, "ib");
|
||||
break;
|
||||
}
|
||||
printReg(ss, INTREG_SP);
|
||||
printIntReg(ss, INTREG_SP);
|
||||
if (wb) {
|
||||
ss << "!";
|
||||
}
|
||||
@@ -180,7 +180,7 @@ Memory::printInst(std::ostream &os, AddrMode addrMode) const
|
||||
printMnemonic(os);
|
||||
printDest(os);
|
||||
os << ", [";
|
||||
printReg(os, base);
|
||||
printIntReg(os, base);
|
||||
if (addrMode != AddrMd_PostIndex) {
|
||||
os << ", ";
|
||||
printOffset(os);
|
||||
|
||||
@@ -211,7 +211,7 @@ class Memory : public MightBeMicro
|
||||
virtual void
|
||||
printDest(std::ostream &os) const
|
||||
{
|
||||
printReg(os, dest);
|
||||
printIntReg(os, dest);
|
||||
}
|
||||
|
||||
void printInst(std::ostream &os, AddrMode addrMode) const;
|
||||
@@ -253,7 +253,7 @@ class MemoryExImm : public MemoryImm
|
||||
void
|
||||
printDest(std::ostream &os) const
|
||||
{
|
||||
printReg(os, result);
|
||||
printIntReg(os, result);
|
||||
os << ", ";
|
||||
MemoryImm::printDest(os);
|
||||
}
|
||||
@@ -277,7 +277,7 @@ class MemoryDImm : public MemoryImm
|
||||
{
|
||||
MemoryImm::printDest(os);
|
||||
os << ", ";
|
||||
printReg(os, dest2);
|
||||
printIntReg(os, dest2);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -296,7 +296,7 @@ class MemoryExDImm : public MemoryDImm
|
||||
void
|
||||
printDest(std::ostream &os) const
|
||||
{
|
||||
printReg(os, result);
|
||||
printIntReg(os, result);
|
||||
os << ", ";
|
||||
MemoryDImm::printDest(os);
|
||||
}
|
||||
@@ -341,7 +341,7 @@ class MemoryDReg : public MemoryReg
|
||||
{
|
||||
MemoryReg::printDest(os);
|
||||
os << ", ";
|
||||
printReg(os, dest2);
|
||||
printIntReg(os, dest2);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ SysDC64::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
std::stringstream ss;
|
||||
printMnemonic(ss, "", false);
|
||||
ccprintf(ss, ", [");
|
||||
printReg(ss, base);
|
||||
printIntReg(ss, base);
|
||||
ccprintf(ss, "]");
|
||||
return ss.str();
|
||||
}
|
||||
@@ -65,9 +65,9 @@ void
|
||||
Memory64::startDisassembly(std::ostream &os) const
|
||||
{
|
||||
printMnemonic(os, "", false);
|
||||
printReg(os, dest);
|
||||
printIntReg(os, dest);
|
||||
ccprintf(os, ", [");
|
||||
printReg(os, base);
|
||||
printIntReg(os, base);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -100,11 +100,11 @@ MemoryDImm64::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
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, "]");
|
||||
@@ -116,13 +116,13 @@ MemoryDImmEx64::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
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, "]");
|
||||
@@ -173,11 +173,11 @@ MemoryEx64::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
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();
|
||||
}
|
||||
@@ -187,7 +187,7 @@ MemoryLiteral64::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
std::stringstream ss;
|
||||
printMnemonic(ss, "", false);
|
||||
printReg(ss, dest);
|
||||
printIntReg(ss, dest);
|
||||
ccprintf(ss, ", #%d", pc + imm);
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
@@ -47,21 +47,20 @@ MrsOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
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;
|
||||
@@ -80,17 +79,16 @@ MsrBase::printMsrBase(std::ostream &os) const
|
||||
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 {
|
||||
@@ -142,7 +140,7 @@ MsrRegOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
std::stringstream ss;
|
||||
printMsrBase(ss);
|
||||
ss << ", ";
|
||||
printReg(ss, op1);
|
||||
printIntReg(ss, op1);
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
@@ -151,11 +149,11 @@ MrrcOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -164,11 +162,11 @@ McrrOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -186,7 +184,7 @@ RegImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
std::stringstream ss;
|
||||
printMnemonic(ss);
|
||||
printReg(ss, dest);
|
||||
printIntReg(ss, dest);
|
||||
ccprintf(ss, ", #%d", imm);
|
||||
return ss.str();
|
||||
}
|
||||
@@ -196,9 +194,9 @@ RegRegOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
std::stringstream ss;
|
||||
printMnemonic(ss);
|
||||
printReg(ss, dest);
|
||||
printIntReg(ss, dest);
|
||||
ss << ", ";
|
||||
printReg(ss, op1);
|
||||
printIntReg(ss, op1);
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
@@ -207,11 +205,11 @@ RegRegRegImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
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();
|
||||
}
|
||||
@@ -221,13 +219,13 @@ RegRegRegRegOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -236,11 +234,11 @@ RegRegRegOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -249,9 +247,9 @@ RegRegImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
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();
|
||||
}
|
||||
@@ -261,9 +259,9 @@ MiscRegRegImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
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();
|
||||
}
|
||||
@@ -273,9 +271,9 @@ RegMiscRegImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
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();
|
||||
}
|
||||
@@ -285,7 +283,7 @@ RegImmImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
std::stringstream ss;
|
||||
printMnemonic(ss);
|
||||
printReg(ss, dest);
|
||||
printIntReg(ss, dest);
|
||||
ccprintf(ss, ", #%d, #%d", imm1, imm2);
|
||||
return ss.str();
|
||||
}
|
||||
@@ -295,9 +293,9 @@ RegRegImmImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
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();
|
||||
}
|
||||
@@ -307,9 +305,9 @@ RegImmRegOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
std::stringstream ss;
|
||||
printMnemonic(ss);
|
||||
printReg(ss, dest);
|
||||
printIntReg(ss, dest);
|
||||
ccprintf(ss, ", #%d, ", imm);
|
||||
printReg(ss, op1);
|
||||
printIntReg(ss, op1);
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
@@ -318,10 +316,10 @@ RegImmRegShiftOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
@@ -44,9 +44,9 @@ RegRegImmImmOp64::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
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();
|
||||
}
|
||||
@@ -57,11 +57,11 @@ RegRegRegImmOp64::generateDisassembly(
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -291,54 +291,56 @@ ArmStaticInst::shift_carry_rs(uint32_t base, uint32_t shamt,
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
ArmStaticInst::printIntReg(std::ostream &os, RegIndex reg_idx) const
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ArmStaticInst::printReg(std::ostream &os, int reg) const
|
||||
ArmStaticInst::printFloatReg(std::ostream &os, RegIndex reg_idx) const
|
||||
{
|
||||
RegIndex rel_reg;
|
||||
ccprintf(os, "f%d", reg_idx);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
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::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
|
||||
@@ -471,7 +473,7 @@ ArmStaticInst::printShiftOperand(std::ostream &os,
|
||||
bool firstOp = false;
|
||||
|
||||
if (rm != INTREG_ZERO) {
|
||||
printReg(os, rm);
|
||||
printIntReg(os, rm);
|
||||
}
|
||||
|
||||
bool done = false;
|
||||
@@ -520,7 +522,7 @@ ArmStaticInst::printShiftOperand(std::ostream &os,
|
||||
if (immShift)
|
||||
os << "#" << shiftAmt;
|
||||
else
|
||||
printReg(os, rs);
|
||||
printIntReg(os, rs);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -531,7 +533,7 @@ ArmStaticInst::printExtendOperand(bool firstOperand, std::ostream &os,
|
||||
{
|
||||
if (!firstOperand)
|
||||
ccprintf(os, ", ");
|
||||
printReg(os, rm);
|
||||
printIntReg(os, rm);
|
||||
if (type == UXTX && shiftAmt == 0)
|
||||
return;
|
||||
switch (type) {
|
||||
@@ -568,7 +570,7 @@ ArmStaticInst::printDataInst(std::ostream &os, bool withImm,
|
||||
// Destination
|
||||
if (rd != INTREG_ZERO) {
|
||||
firstOp = false;
|
||||
printReg(os, rd);
|
||||
printIntReg(os, rd);
|
||||
}
|
||||
|
||||
// Source 1.
|
||||
@@ -576,7 +578,7 @@ ArmStaticInst::printDataInst(std::ostream &os, bool withImm,
|
||||
if (!firstOp)
|
||||
os << ", ";
|
||||
firstOp = false;
|
||||
printReg(os, rn);
|
||||
printIntReg(os, rn);
|
||||
}
|
||||
|
||||
if (!firstOp)
|
||||
|
||||
@@ -155,7 +155,10 @@ class ArmStaticInst : public StaticInst
|
||||
|
||||
/// 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,
|
||||
|
||||
@@ -51,9 +51,9 @@ FpCondCompRegOp::generateDisassembly(
|
||||
{
|
||||
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);
|
||||
@@ -66,11 +66,11 @@ FpCondSelOp::generateDisassembly(
|
||||
{
|
||||
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();
|
||||
@@ -81,9 +81,9 @@ FpRegRegOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ FpRegImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
std::stringstream ss;
|
||||
printMnemonic(ss);
|
||||
printReg(ss, dest + FP_Reg_Base);
|
||||
printFloatReg(ss, dest);
|
||||
ccprintf(ss, ", #%d", imm);
|
||||
return ss.str();
|
||||
}
|
||||
@@ -102,9 +102,9 @@ FpRegRegImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
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();
|
||||
}
|
||||
@@ -114,11 +114,11 @@ FpRegRegRegOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -129,11 +129,11 @@ FpRegRegRegCondOp::generateDisassembly(Addr pc, const SymbolTable *symtab)
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -142,13 +142,13 @@ FpRegRegRegRegOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -157,11 +157,11 @@ FpRegRegRegImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -58,8 +58,6 @@ const int MaxInstSrcRegs = ArmISAInst::MaxInstDestRegs +
|
||||
using ArmISAInst::MaxInstDestRegs;
|
||||
using ArmISAInst::MaxMiscDestRegs;
|
||||
|
||||
typedef uint16_t RegIndex;
|
||||
|
||||
typedef uint64_t IntReg;
|
||||
|
||||
// floating point register file entry type
|
||||
@@ -109,12 +107,6 @@ const int SyscallNumReg = ReturnValueReg;
|
||||
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;
|
||||
|
||||
@@ -37,6 +37,9 @@
|
||||
#include "base/types.hh"
|
||||
#include "sim/serialize.hh"
|
||||
|
||||
// Logical register index type.
|
||||
typedef uint16_t RegIndex;
|
||||
|
||||
namespace GenericISA
|
||||
{
|
||||
|
||||
|
||||
@@ -520,7 +520,14 @@ class Operand(object):
|
||||
# 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
|
||||
|
||||
@@ -532,14 +539,13 @@ class IntRegOperand(Operand):
|
||||
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}' % \
|
||||
@@ -592,6 +598,8 @@ class IntRegOperand(Operand):
|
||||
return wb
|
||||
|
||||
class FloatRegOperand(Operand):
|
||||
reg_class = 'FloatRegClass'
|
||||
|
||||
def isReg(self):
|
||||
return 1
|
||||
|
||||
@@ -603,13 +611,10 @@ class FloatRegOperand(Operand):
|
||||
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
|
||||
@@ -654,6 +659,8 @@ class FloatRegOperand(Operand):
|
||||
return wb
|
||||
|
||||
class CCRegOperand(Operand):
|
||||
reg_class = 'CCRegClass'
|
||||
|
||||
def isReg(self):
|
||||
return 1
|
||||
|
||||
@@ -665,16 +672,13 @@ class CCRegOperand(Operand):
|
||||
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}' % \
|
||||
@@ -727,6 +731,8 @@ class CCRegOperand(Operand):
|
||||
return wb
|
||||
|
||||
class ControlRegOperand(Operand):
|
||||
reg_class = 'MiscRegClass'
|
||||
|
||||
def isReg(self):
|
||||
return 1
|
||||
|
||||
@@ -738,14 +744,10 @@ class ControlRegOperand(Operand):
|
||||
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
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ output header {{
|
||||
|
||||
/// 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;
|
||||
|
||||
@@ -70,13 +70,13 @@ output header {{
|
||||
//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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -384,44 +384,86 @@ decode OPCODE_HI default Unknown::unknown() {
|
||||
// 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) |
|
||||
@@ -450,56 +492,62 @@ decode OPCODE_HI default Unknown::unknown() {
|
||||
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({{
|
||||
@@ -534,7 +582,8 @@ decode OPCODE_HI default Unknown::unknown() {
|
||||
"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();
|
||||
}
|
||||
|
||||
@@ -257,9 +257,9 @@ output decoder {{
|
||||
|
||||
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]);
|
||||
}
|
||||
|
||||
@@ -272,9 +272,9 @@ output decoder {{
|
||||
|
||||
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]);
|
||||
}
|
||||
|
||||
@@ -287,9 +287,9 @@ output decoder {{
|
||||
|
||||
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]);
|
||||
}
|
||||
|
||||
|
||||
@@ -102,7 +102,8 @@ output exec {{
|
||||
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);
|
||||
|
||||
@@ -113,24 +113,25 @@ forkThread(TC *tc, Fault &fault, int Rd_bits, int Rs, int Rt)
|
||||
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);
|
||||
@@ -149,7 +150,7 @@ forkThread(TC *tc, Fault &fault, int Rd_bits, int Rs, int Rt)
|
||||
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
|
||||
@@ -185,13 +186,13 @@ yieldThread(TC *tc, Fault &fault, int src_reg, uint32_t yield_mask)
|
||||
|
||||
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 &&
|
||||
|
||||
@@ -275,16 +275,8 @@ enum MiscRegIndex{
|
||||
|
||||
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
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#ifndef __ARCH_NULL_REGISTERS_HH__
|
||||
#define __ARCH_NULL_REGISTERS_HH__
|
||||
|
||||
#include "arch/types.hh"
|
||||
#include "base/types.hh"
|
||||
|
||||
namespace NullISA {
|
||||
@@ -49,6 +50,7 @@ typedef uint32_t FloatRegBits;
|
||||
typedef float FloatReg;
|
||||
typedef uint8_t CCReg;
|
||||
typedef uint64_t MiscReg;
|
||||
const RegIndex ZeroReg = 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -153,7 +153,7 @@ BranchNonPCRelCond::generateDisassembly(Addr pc,
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -36,19 +36,17 @@
|
||||
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;
|
||||
|
||||
@@ -59,7 +59,7 @@ class PowerStaticInst : public StaticInst
|
||||
/// 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;
|
||||
|
||||
@@ -43,8 +43,6 @@ using PowerISAInst::MaxInstDestRegs;
|
||||
// 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
|
||||
@@ -87,12 +85,6 @@ const int SyscallNumReg = 0;
|
||||
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;
|
||||
|
||||
@@ -51,7 +51,7 @@ output header {{
|
||||
{}
|
||||
|
||||
std::string
|
||||
regName(RegIndex reg) const;
|
||||
regName(RegId reg) const;
|
||||
|
||||
virtual std::string
|
||||
generateDisassembly(Addr pc, const SymbolTable *symtab) const = 0;
|
||||
@@ -68,12 +68,15 @@ output header {{
|
||||
//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);
|
||||
}
|
||||
}
|
||||
}};
|
||||
|
||||
@@ -210,7 +210,7 @@ output decoder {{
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
#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"
|
||||
@@ -60,7 +61,6 @@ using RiscvISAInst::MaxInstSrcRegs;
|
||||
using RiscvISAInst::MaxInstDestRegs;
|
||||
const int MaxMiscDestRegs = 1;
|
||||
|
||||
typedef uint_fast16_t RegIndex;
|
||||
typedef uint64_t IntReg;
|
||||
typedef uint64_t FloatRegBits;
|
||||
typedef double FloatReg;
|
||||
@@ -74,12 +74,6 @@ const int NumFloatRegs = 32;
|
||||
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;
|
||||
|
||||
@@ -105,12 +105,12 @@ output header {{
|
||||
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;
|
||||
};
|
||||
@@ -251,7 +251,7 @@ output decoder {{
|
||||
}
|
||||
|
||||
void SparcStaticInst::printRegArray(std::ostream &os,
|
||||
const RegIndex indexArray[], int num) const
|
||||
const RegId indexArray[], int num) const
|
||||
{
|
||||
if (num <= 0)
|
||||
return;
|
||||
@@ -283,35 +283,36 @@ output decoder {{
|
||||
}
|
||||
|
||||
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;
|
||||
@@ -335,10 +336,10 @@ output decoder {{
|
||||
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;
|
||||
@@ -430,7 +431,7 @@ output decoder {{
|
||||
ccprintf(os, "%%fsr");
|
||||
break;
|
||||
default:
|
||||
ccprintf(os, "%%ctrl%d", reg - Misc_Reg_Base);
|
||||
ccprintf(os, "%%ctrl%d", reg_idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,7 +155,7 @@ output decoder {{
|
||||
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, ", ");
|
||||
@@ -170,7 +170,7 @@ output decoder {{
|
||||
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 {
|
||||
|
||||
@@ -84,7 +84,7 @@ output decoder {{
|
||||
ccprintf(response, ", ");
|
||||
}
|
||||
ccprintf(response, "[");
|
||||
if (_srcRegIdx[!store ? 0 : 1] != 0) {
|
||||
if (_srcRegIdx[!store ? 0 : 1].regIdx != 0) {
|
||||
printSrcReg(response, !store ? 0 : 1);
|
||||
ccprintf(response, " + ");
|
||||
}
|
||||
@@ -111,7 +111,7 @@ output decoder {{
|
||||
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, " + ");
|
||||
}
|
||||
|
||||
@@ -155,7 +155,7 @@ output decoder {{
|
||||
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, ", ");
|
||||
}
|
||||
@@ -175,7 +175,7 @@ output decoder {{
|
||||
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, ", ");
|
||||
}
|
||||
|
||||
@@ -59,8 +59,6 @@ typedef union
|
||||
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
|
||||
@@ -78,14 +76,6 @@ const int NumCCRegs = 0;
|
||||
|
||||
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
|
||||
|
||||
@@ -66,7 +66,7 @@ namespace X86ISA
|
||||
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)
|
||||
{}
|
||||
/*
|
||||
|
||||
@@ -75,12 +75,12 @@ namespace X86ISA
|
||||
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 =
|
||||
@@ -110,7 +110,7 @@ namespace X86ISA
|
||||
_scale, _index, _base, _disp, _segment,
|
||||
_dataSize, _addressSize, _memFlags,
|
||||
__opClass),
|
||||
data(_data.idx)
|
||||
data(_data.regIdx)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -143,8 +143,8 @@ namespace X86ISA
|
||||
_scale, _index, _base, _disp, _segment,
|
||||
_dataSize, _addressSize, _memFlags,
|
||||
__opClass),
|
||||
dataLow(_dataLow.idx),
|
||||
dataHi(_dataHi.idx)
|
||||
dataLow(_dataLow.regIdx),
|
||||
dataHi(_dataHi.regIdx)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace X86ISA
|
||||
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)
|
||||
{}
|
||||
|
||||
@@ -102,7 +102,7 @@ namespace X86ISA
|
||||
MediaOpBase(_machInst, mnem, _instMnem, setFlags,
|
||||
_src1, _dest, _srcSize, _destSize, _ext,
|
||||
__opClass),
|
||||
src2(_src2.idx)
|
||||
src2(_src2.regIdx)
|
||||
{}
|
||||
|
||||
std::string generateDisassembly(Addr pc,
|
||||
|
||||
@@ -64,7 +64,7 @@ namespace X86ISA
|
||||
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;
|
||||
@@ -90,7 +90,7 @@ namespace X86ISA
|
||||
RegOpBase(_machInst, mnem, _instMnem, setFlags,
|
||||
_src1, _dest, _dataSize, _ext,
|
||||
__opClass),
|
||||
src2(_src2.idx)
|
||||
src2(_src2.regIdx)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -120,7 +120,7 @@ namespace X86ISA
|
||||
}
|
||||
|
||||
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] =
|
||||
@@ -132,20 +132,20 @@ namespace X86ISA
|
||||
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;
|
||||
@@ -195,41 +195,41 @@ namespace X86ISA
|
||||
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;
|
||||
}
|
||||
@@ -250,14 +250,14 @@ namespace X86ISA
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,11 +51,27 @@ namespace X86ISA
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -81,7 +97,7 @@ namespace X86ISA
|
||||
|
||||
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,
|
||||
@@ -91,7 +107,7 @@ namespace X86ISA
|
||||
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;
|
||||
@@ -122,7 +138,7 @@ namespace X86ISA
|
||||
{
|
||||
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)
|
||||
{
|
||||
@@ -143,7 +159,7 @@ namespace X86ISA
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -95,7 +95,7 @@ def template MicroLimmOpConstructor {{
|
||||
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;
|
||||
|
||||
@@ -143,13 +143,19 @@ let {{
|
||||
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
|
||||
@@ -182,8 +188,11 @@ let {{
|
||||
# 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"
|
||||
@@ -195,8 +204,11 @@ let {{
|
||||
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
|
||||
@@ -222,8 +234,11 @@ let {{
|
||||
# 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"
|
||||
|
||||
@@ -105,8 +105,6 @@ typedef union
|
||||
MiscReg ctrlReg;
|
||||
} AnyReg;
|
||||
|
||||
typedef uint16_t RegIndex;
|
||||
|
||||
} // namespace X86ISA
|
||||
|
||||
#endif // __ARCH_X86_REGFILE_HH__
|
||||
|
||||
@@ -82,9 +82,6 @@ class BaseDynInst : public ExecContext, public RefCounted
|
||||
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;
|
||||
@@ -265,7 +262,7 @@ class BaseDynInst : public ExecContext, public RefCounted
|
||||
/** 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.
|
||||
@@ -386,7 +383,7 @@ class BaseDynInst : public ExecContext, public RefCounted
|
||||
/** 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];
|
||||
}
|
||||
@@ -422,7 +419,7 @@ class BaseDynInst : public ExecContext, public RefCounted
|
||||
/** 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;
|
||||
}
|
||||
@@ -604,10 +601,10 @@ class BaseDynInst : public ExecContext, public RefCounted
|
||||
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>
|
||||
|
||||
@@ -213,26 +213,31 @@ class CheckerCPU : public BaseCPU, public ExecContext
|
||||
|
||||
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>
|
||||
@@ -246,30 +251,35 @@ class CheckerCPU : public BaseCPU, public ExecContext
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -317,25 +327,27 @@ class CheckerCPU : public BaseCPU, public ExecContext
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
@@ -595,41 +595,40 @@ Checker<Impl>::copyResult(DynInstPtr &inst, uint64_t mismatch_val,
|
||||
// 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...
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#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"
|
||||
@@ -286,9 +287,9 @@ class ExecContext {
|
||||
*/
|
||||
|
||||
#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
|
||||
|
||||
|
||||
@@ -133,15 +133,15 @@ operator <<(std::ostream &os, const MinorDynInst &inst)
|
||||
/** 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
|
||||
@@ -153,17 +153,17 @@ printRegName(std::ostream &os, TheISA::RegIndex reg)
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -219,7 +219,7 @@ class MinorDynInst : public RefCounted
|
||||
/** 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;
|
||||
|
||||
@@ -124,43 +124,51 @@ class ExecContext : public ::ExecContext
|
||||
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
|
||||
@@ -208,16 +216,18 @@ class ExecContext : public ::ExecContext
|
||||
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
|
||||
@@ -269,15 +279,17 @@ class ExecContext : public ::ExecContext
|
||||
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
|
||||
@@ -308,37 +320,46 @@ class ExecContext : public ::ExecContext
|
||||
|
||||
/* 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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -48,28 +48,27 @@ namespace Minor
|
||||
{
|
||||
|
||||
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:
|
||||
@@ -82,32 +81,28 @@ Scoreboard::findIndex(RegIndex reg, Index &scoreboard_index)
|
||||
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
|
||||
@@ -124,8 +119,8 @@ Scoreboard::markupInstDests(MinorDynInstPtr inst, Cycles retire_time,
|
||||
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)) {
|
||||
@@ -148,7 +143,7 @@ Scoreboard::markupInstDests(MinorDynInstPtr inst, Cycles retire_time,
|
||||
*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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -166,7 +161,7 @@ Scoreboard::execSeqNumToWaitFor(MinorDynInstPtr inst,
|
||||
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;
|
||||
|
||||
@@ -195,7 +190,7 @@ Scoreboard::clearInstDests(MinorDynInstPtr inst, bool clear_unpredictable)
|
||||
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)) {
|
||||
@@ -252,7 +247,7 @@ Scoreboard::canInstIssue(MinorDynInstPtr inst,
|
||||
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;
|
||||
|
||||
|
||||
@@ -67,9 +67,6 @@ class Scoreboard : public Named
|
||||
* [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;
|
||||
|
||||
@@ -109,7 +106,7 @@ class Scoreboard : public Named
|
||||
/** 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
|
||||
|
||||
@@ -788,29 +788,27 @@ FullO3CPU<Impl>::insertThread(ThreadID tid)
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -845,24 +843,25 @@ FullO3CPU<Impl>::removeThread(ThreadID tid)
|
||||
// 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);
|
||||
}
|
||||
|
||||
@@ -67,15 +67,13 @@ class BaseO3DynInst : public BaseDynInst<Impl>
|
||||
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 {
|
||||
@@ -172,9 +170,9 @@ class BaseO3DynInst : public BaseDynInst<Impl>
|
||||
*/
|
||||
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
|
||||
@@ -183,8 +181,9 @@ class BaseO3DynInst : public BaseDynInst<Impl>
|
||||
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. */
|
||||
@@ -209,9 +208,9 @@ class BaseO3DynInst : public BaseDynInst<Impl>
|
||||
|
||||
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));
|
||||
@@ -301,13 +300,13 @@ class BaseO3DynInst : public BaseDynInst<Impl>
|
||||
}
|
||||
|
||||
#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");
|
||||
}
|
||||
|
||||
@@ -110,11 +110,11 @@ BaseO3DynInst<Impl>::initVars()
|
||||
// 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();
|
||||
|
||||
@@ -262,15 +262,15 @@ ElasticTrace::updateRegDep(const DynInstPtr &dyn_inst)
|
||||
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(),
|
||||
|
||||
@@ -85,9 +85,6 @@ class DefaultRename
|
||||
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
|
||||
@@ -301,7 +298,7 @@ class DefaultRename
|
||||
* 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)
|
||||
@@ -311,7 +308,7 @@ class DefaultRename
|
||||
/** 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. */
|
||||
|
||||
@@ -1011,42 +1011,41 @@ DefaultRename<Impl>::renameSrcRegs(DynInstPtr &inst, ThreadID tid)
|
||||
// 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);
|
||||
|
||||
@@ -1075,49 +1074,45 @@ DefaultRename<Impl>::renameDestRegs(DynInstPtr &inst, ThreadID tid)
|
||||
|
||||
// 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.
|
||||
@@ -1431,8 +1426,10 @@ DefaultRename<Impl>::dumpHistory()
|
||||
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++;
|
||||
|
||||
@@ -104,79 +104,73 @@ UnifiedRenameMap::init(PhysRegFile *_regFile,
|
||||
|
||||
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,10 +68,6 @@
|
||||
*/
|
||||
class SimpleRenameMap
|
||||
{
|
||||
public:
|
||||
|
||||
typedef TheISA::RegIndex RegIndex;
|
||||
|
||||
private:
|
||||
|
||||
/** The acutal arch-to-phys register map */
|
||||
@@ -152,9 +148,9 @@ class SimpleRenameMap
|
||||
/**
|
||||
* 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
|
||||
{
|
||||
@@ -179,7 +175,6 @@ class UnifiedRenameMap
|
||||
SimpleRenameMap ccMap;
|
||||
|
||||
public:
|
||||
typedef TheISA::RegIndex RegIndex;
|
||||
|
||||
typedef SimpleRenameMap::RenameInfo RenameInfo;
|
||||
|
||||
@@ -197,17 +192,17 @@ class UnifiedRenameMap
|
||||
|
||||
/**
|
||||
* 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)
|
||||
@@ -218,7 +213,7 @@ class UnifiedRenameMap
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
@@ -229,7 +224,7 @@ class UnifiedRenameMap
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
@@ -240,7 +235,7 @@ class UnifiedRenameMap
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
@@ -256,15 +251,15 @@ class UnifiedRenameMap
|
||||
|
||||
/**
|
||||
* 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
|
||||
@@ -275,7 +270,7 @@ class UnifiedRenameMap
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
@@ -286,7 +281,7 @@ class UnifiedRenameMap
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
@@ -311,15 +306,15 @@ class UnifiedRenameMap
|
||||
/**
|
||||
* 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)
|
||||
@@ -329,7 +324,7 @@ class UnifiedRenameMap
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
@@ -339,7 +334,7 @@ class UnifiedRenameMap
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
|
||||
@@ -60,8 +60,6 @@ struct DerivO3CPUParams;
|
||||
template <class Impl>
|
||||
class ROB
|
||||
{
|
||||
protected:
|
||||
typedef TheISA::RegIndex RegIndex;
|
||||
public:
|
||||
//Typedefs from the Impl.
|
||||
typedef typename Impl::O3CPU O3CPU;
|
||||
|
||||
@@ -36,3 +36,5 @@ const char *RegClassStrings[] = {
|
||||
"CCRegClass",
|
||||
"MiscRegClass"
|
||||
};
|
||||
|
||||
const RegId RegId::zeroReg = RegId(IntRegClass, TheISA::ZeroReg);
|
||||
|
||||
@@ -1,4 +1,16 @@
|
||||
/*
|
||||
* 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
|
||||
*.
|
||||
@@ -26,6 +38,7 @@
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors: Steve Reinhardt
|
||||
* Nathanael Premillieu
|
||||
*/
|
||||
|
||||
#ifndef __CPU__REG_CLASS_HH__
|
||||
@@ -34,6 +47,7 @@
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
|
||||
#include "arch/generic/types.hh"
|
||||
#include "arch/registers.hh"
|
||||
#include "config/the_isa.hh"
|
||||
|
||||
@@ -50,50 +64,49 @@ enum RegClass {
|
||||
/// 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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__
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
#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"
|
||||
@@ -164,22 +165,27 @@ class SimpleExecContext : public ExecContext {
|
||||
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
|
||||
@@ -187,8 +193,9 @@ class SimpleExecContext : public ExecContext {
|
||||
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. */
|
||||
@@ -196,8 +203,9 @@ class SimpleExecContext : public ExecContext {
|
||||
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
|
||||
@@ -206,37 +214,42 @@ class SimpleExecContext : public ExecContext {
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -398,14 +411,14 @@ class SimpleExecContext : public ExecContext {
|
||||
}
|
||||
|
||||
#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 "
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#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"
|
||||
@@ -70,8 +71,6 @@ class StaticInst : public RefCounted, public StaticInstFlags
|
||||
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
|
||||
@@ -185,11 +184,11 @@ class StaticInst : public RefCounted, public StaticInstFlags
|
||||
|
||||
/// 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
|
||||
@@ -220,9 +219,9 @@ class StaticInst : public RefCounted, public StaticInstFlags
|
||||
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()
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
#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.
|
||||
@@ -255,13 +256,13 @@ class ThreadContext
|
||||
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)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ TimingExprEvalContext::TimingExprEvalContext(const StaticInstPtr &inst_,
|
||||
|
||||
uint64_t TimingExprSrcReg::eval(TimingExprEvalContext &context)
|
||||
{
|
||||
return context.inst->srcRegIdx(index);
|
||||
return context.inst->srcRegIdx(index).regIdx;
|
||||
}
|
||||
|
||||
uint64_t TimingExprReadIntReg::eval(TimingExprEvalContext &context)
|
||||
|
||||
Reference in New Issue
Block a user