if (!myMnemonic.compare("or") && srcRegIdx(0) == srcRegIdx(1)) {
myMnemonic = "mr";
printSecondSrc = false;
- } else if (!myMnemonic.compare("mtlr") || !myMnemonic.compare("cmpi")) {
+ } else if (!myMnemonic.compare("mtcrf") ||
+ !myMnemonic.compare("mtxer") ||
+ !myMnemonic.compare("mtlr") ||
+ !myMnemonic.compare("mtctr") ||
+ !myMnemonic.compare("cmpi")) {
printDest = false;
- } else if (!myMnemonic.compare("mflr")) {
+ } else if (!myMnemonic.compare("mfcr") ||
+ !myMnemonic.compare("mfxer") ||
+ !myMnemonic.compare("mflr") ||
+ !myMnemonic.compare("mfctr")) {
printSrcs = false;
}
#include "arch/power/types.hh"
#include "base/logging.hh"
#include "cpu/reg_class.hh"
+#include "debug/MiscRegs.hh"
#include "sim/sim_object.hh"
struct PowerISAParams;
RegVal
readMiscRegNoEffect(int misc_reg) const
{
- fatal("Power does not currently have any misc regs defined\n");
- return dummy;
+ assert(misc_reg < NumMiscRegs);
+ int flatIndex = flattenMiscIndex(misc_reg);
+ auto val = miscRegs[flatIndex];
+ DPRINTF(MiscRegs, "Reading misc reg %d (%s) as %#x.\n", misc_reg,
+ miscRegName[flatIndex], val);
+ return val;
}
RegVal
readMiscReg(int misc_reg)
{
- fatal("Power does not currently have any misc regs defined\n");
- return dummy;
+ return readMiscRegNoEffect(misc_reg);
}
void
setMiscRegNoEffect(int misc_reg, RegVal val)
{
- fatal("Power does not currently have any misc regs defined\n");
+ assert(misc_reg < NumMiscRegs);
+ int flatIndex = flattenMiscIndex(misc_reg);
+ DPRINTF(MiscRegs, "Setting misc reg %d (%s) to %#x.\n", misc_reg,
+ miscRegName[flatIndex], val);
+ miscRegs[flatIndex] = val;
}
void
setMiscReg(int misc_reg, RegVal val)
{
- fatal("Power does not currently have any misc regs defined\n");
+ return setMiscRegNoEffect(misc_reg, val);
}
- RegId flattenRegId(const RegId& regId) const { return regId; }
+ RegId
+ flattenRegId(const RegId& regId) const
+ {
+ switch (regId.classValue()) {
+ case IntRegClass:
+ return RegId(IntRegClass, flattenIntIndex(regId.index()));
+ case FloatRegClass:
+ return RegId(FloatRegClass, flattenFloatIndex(regId.index()));
+ case VecRegClass:
+ return RegId(VecRegClass, flattenVecIndex(regId.index()));
+ case VecElemClass:
+ return RegId(VecElemClass, flattenVecElemIndex(regId.index()),
+ regId.elemIndex());
+ case VecPredRegClass:
+ return RegId(VecPredRegClass,
+ flattenVecPredIndex(regId.index()));
+ case CCRegClass:
+ return RegId(CCRegClass, flattenCCIndex(regId.index()));
+ case MiscRegClass:
+ return RegId(MiscRegClass, flattenMiscIndex(regId.index()));
+ }
+
+ return RegId();
+ }
int
flattenIntIndex(int reg) const
'NIA': ('PCState', 'ud', 'npc', (None, None, 'IsControl'), 9),
# Control registers
- 'CR': ('IntReg', 'uw', 'INTREG_CR', 'IsInteger', 9),
- 'LR': ('IntReg', 'ud', 'INTREG_LR', 'IsInteger', 9),
- 'CTR': ('IntReg', 'ud', 'INTREG_CTR', 'IsInteger', 9),
- 'XER': ('IntReg', 'uw', 'INTREG_XER', 'IsInteger', 9),
+ 'CR': ('ControlReg', 'uw', 'MISCREG_CR', 'IsInteger', 9),
+ 'XER': ('ControlReg', 'uw', 'MISCREG_XER', 'IsInteger', 9),
+ 'LR': ('ControlReg', 'ud', 'MISCREG_LR', 'IsInteger', 9),
+ 'CTR': ('ControlReg', 'ud', 'MISCREG_CTR', 'IsInteger', 9),
- # Setting as IntReg so things are stored as an integer, not double
- 'FPSCR': ('IntReg', 'uw', 'INTREG_FPSCR', 'IsFloating', 9),
+ # Setting as ControlReg so things are stored as an integer, not double
+ 'FPSCR': ('ControlReg', 'uw', 'MISCREG_FPSCR', 'IsFloating', 9),
# Registers for linked loads and stores
'Rsv': ('IntReg', 'uw', 'INTREG_RSV', 'IsInteger', 9),
{
enum MiscRegIndex {
- NUM_MISCREGS = 0
+ MISCREG_CR,
+ MISCREG_FPSCR,
+ MISCREG_XER,
+ MISCREG_LR,
+ MISCREG_CTR,
+ NUM_MISCREGS
};
const char * const miscRegName[NUM_MISCREGS] = {
+ "CR",
+ "FPSCR",
+ "XER",
+ "LR",
+ "CTR",
};
BitUnion32(Cr)
// Constants Related to the number of registers
const int NumIntArchRegs = 32;
-// CR, XER, LR, CTR, FPSCR, RSV, RSV-LEN, RSV-ADDR
+// RSV, RSV-LEN, RSV-ADDR
// and zero register, which doesn't actually exist but needs a number
-const int NumIntSpecialRegs = 9;
+const int NumIntSpecialRegs = 4;
const int NumFloatArchRegs = 32;
const int NumIntRegs = NumIntArchRegs + NumIntSpecialRegs;
const int ZeroReg = NumIntRegs - 1;
enum MiscIntRegNums {
- INTREG_CR = NumIntArchRegs,
- INTREG_XER,
- INTREG_LR,
- INTREG_CTR,
- INTREG_FPSCR,
- INTREG_RSV,
+ INTREG_RSV = NumIntArchRegs,
INTREG_RSV_LEN,
INTREG_RSV_ADDR
};
r.pc = htobe((uint32_t)context->pcState().pc());
r.msr = 0; // Is MSR modeled?
- r.cr = htobe((uint32_t)context->readIntReg(INTREG_CR));
- r.lr = htobe((uint32_t)context->readIntReg(INTREG_LR));
- r.ctr = htobe((uint32_t)context->readIntReg(INTREG_CTR));
- r.xer = htobe((uint32_t)context->readIntReg(INTREG_XER));
+ r.cr = htobe((uint32_t)context->readMiscReg(MISCREG_CR));
+ r.lr = htobe((uint32_t)context->readMiscReg(MISCREG_LR));
+ r.ctr = htobe((uint32_t)context->readMiscReg(MISCREG_CTR));
+ r.xer = htobe((uint32_t)context->readMiscReg(MISCREG_XER));
}
void
context->pcState(betoh(r.pc));
// Is MSR modeled?
- context->setIntReg(INTREG_CR, betoh(r.cr));
- context->setIntReg(INTREG_LR, betoh(r.lr));
- context->setIntReg(INTREG_CTR, betoh(r.ctr));
- context->setIntReg(INTREG_XER, betoh(r.xer));
+ context->setMiscReg(MISCREG_CR, betoh(r.cr));
+ context->setMiscReg(MISCREG_LR, betoh(r.lr));
+ context->setMiscReg(MISCREG_CTR, betoh(r.ctr));
+ context->setMiscReg(MISCREG_XER, betoh(r.xer));
}
BaseGdbRegCache*
if (ret.suppressed() || ret.needsRetry())
return;
- PowerISA::Cr cr = tc->readIntReg(PowerISA::INTREG_CR);
+ PowerISA::Cr cr = tc->readIntReg(PowerISA::MISCREG_CR);
if (ret.successful()) {
cr.cr0.so = 0;
} else {
cr.cr0.so = 1;
}
- tc->setIntReg(PowerISA::INTREG_CR, cr);
+ tc->setIntReg(PowerISA::MISCREG_CR, cr);
tc->setIntReg(PowerISA::ReturnValueReg, ret.encodedValue());
}
};