summaryrefslogtreecommitdiff
path: root/src/cpu/exetrace.cc
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2006-11-20 18:09:55 -0500
committerGabe Black <gblack@eecs.umich.edu>2006-11-20 18:09:55 -0500
commitc1aeb7229ea44dbc7215b59c73747bee0f1b1572 (patch)
tree494e04f14fce72290b947acf6c182dd770ba6622 /src/cpu/exetrace.cc
parentb4a31cb8b554056fa48ad3986c4f011b8d312306 (diff)
downloadgem5-c1aeb7229ea44dbc7215b59c73747bee0f1b1572.tar.xz
Add in checks of more Legion based state, and put in more sophisticated formatting functions.
--HG-- extra : convert_revision : e3aa5919a6480aa01924c832a86fa1e8ddf5ba0d
Diffstat (limited to 'src/cpu/exetrace.cc')
-rw-r--r--src/cpu/exetrace.cc272
1 files changed, 260 insertions, 12 deletions
diff --git a/src/cpu/exetrace.cc b/src/cpu/exetrace.cc
index a2e6d2d33..0e4425acc 100644
--- a/src/cpu/exetrace.cc
+++ b/src/cpu/exetrace.cc
@@ -66,6 +66,56 @@ SharedData *shared_data = NULL;
// Methods for the InstRecord object
//
+#if THE_ISA == SPARC_ISA
+
+inline char * genCenteredLabel(int length, char * buffer, char * label)
+{
+ int labelLength = strlen(label);
+ assert(labelLength <= length);
+ int leftPad = (length - labelLength) / 2;
+ int rightPad = length - leftPad - labelLength;
+ char format[64];
+ sprintf(format, "%%%ds%%s%%%ds", leftPad, rightPad);
+ sprintf(buffer, format, "", label, "");
+ return buffer;
+}
+
+inline void printRegPair(ostream & os, char const * title, uint64_t a, uint64_t b)
+{
+ ccprintf(os, " %16s | %#018x %s %#-018x \n",
+ title, a, (a == b) ? "|" : "X", b);
+}
+
+inline void printColumnLabels(ostream & os)
+{
+ static char * regLabel = genCenteredLabel(16, new char[17], "Register");
+ static char * m5Label = genCenteredLabel(18, new char[18], "M5");
+ static char * legionLabel = genCenteredLabel(18, new char[18], "Legion");
+ ccprintf(os, " %s | %s | %s \n", regLabel, m5Label, legionLabel);
+ ccprintf(os, "--------------------+-----------------------+-----------------------\n");
+}
+
+inline void printSectionHeader(ostream & os, char * name)
+{
+ char sectionString[70];
+ genCenteredLabel(69, sectionString, name);
+ ccprintf(os, "====================================================================\n");
+ ccprintf(os, "%69s\n", sectionString);
+ ccprintf(os, "====================================================================\n");
+}
+
+inline void printLevelHeader(ostream & os, int level)
+{
+ char sectionString[70];
+ char levelName[70];
+ sprintf(levelName, "Trap stack level %d", level);
+ genCenteredLabel(69, sectionString, levelName);
+ ccprintf(os, "====================================================================\n");
+ ccprintf(os, "%69s\n", sectionString);
+ ccprintf(os, "====================================================================\n");
+}
+
+#endif
void
Trace::InstRecord::dump(ostream &outs)
@@ -237,14 +287,34 @@ Trace::InstRecord::dump(ostream &outs)
bool diffPC = false;
bool diffInst = false;
bool diffRegs = false;
+ bool diffTpc = false;
+ bool diffTnpc = false;
+ bool diffTstate = false;
+ bool diffTt = false;
+ bool diffTba = false;
+ bool diffHpstate = false;
+ bool diffHtstate = false;
+ bool diffHtba = false;
+ bool diffPstate = false;
+ bool diffY = false;
+ bool diffCcr = false;
+ bool diffTl = false;
+ bool diffGl = false;
+ bool diffAsi = false;
+ bool diffPil = false;
+ bool diffCwp = false;
+ bool diffCansave = false;
+ bool diffCanrestore = false;
+ bool diffOtherwin = false;
+ bool diffCleanwin = false;
Addr m5Pc, lgnPc;
if(!staticInst->isMicroOp() || staticInst->isLastMicroOp()) {
while (!compared) {
- m5Pc = PC & TheISA::PAddrImplMask;
- lgnPc = shared_data->pc & TheISA::PAddrImplMask;
if (shared_data->flags == OWN_M5) {
+ m5Pc = PC & TheISA::PAddrImplMask;
+ lgnPc = shared_data->pc & TheISA::PAddrImplMask;
if (lgnPc != m5Pc)
diffPC = true;
if (shared_data->instruction !=
@@ -256,8 +326,71 @@ Trace::InstRecord::dump(ostream &outs)
diffRegs = true;
}
}
-
- if (diffPC || diffInst || diffRegs ) {
+ uint64_t oldTl = thread->readMiscReg(MISCREG_TL);
+ if (oldTl != shared_data->tl)
+ diffTl = true;
+ for (int i = 1; i <= MaxTL; i++) {
+ thread->setMiscReg(MISCREG_TL, i);
+ if (thread->readMiscReg(MISCREG_TPC) !=
+ shared_data->tpc[i])
+ diffTpc = true;
+ if (thread->readMiscReg(MISCREG_TNPC) !=
+ shared_data->tnpc[i])
+ diffTnpc = true;
+ if (thread->readMiscReg(MISCREG_TSTATE) !=
+ shared_data->tstate[i])
+ diffTstate = true;
+ if (thread->readMiscReg(MISCREG_TT) !=
+ shared_data->tt[i])
+ diffTt = true;
+ if (thread->readMiscReg(MISCREG_HTSTATE) !=
+ shared_data->htstate[i])
+ diffHtstate = true;
+ }
+ thread->setMiscReg(MISCREG_TL, oldTl);
+
+ if(shared_data->tba != thread->readMiscReg(MISCREG_TBA))
+ diffTba = true;
+ //When the hpstate register is read by an instruction,
+ //legion has bit 11 set. When it's in storage, it doesn't.
+ //Since we don't directly support seperate interpretations
+ //of the registers like that, the bit is always set to 1 and
+ //we just don't compare it. It's not supposed to matter
+ //anyway.
+ if((shared_data->hpstate | (1 << 11)) != thread->readMiscReg(MISCREG_HPSTATE))
+ diffHpstate = true;
+ if(shared_data->htba != thread->readMiscReg(MISCREG_HTBA))
+ diffHtba = true;
+ if(shared_data->pstate != thread->readMiscReg(MISCREG_PSTATE))
+ diffPstate = true;
+ if(shared_data->y != thread->readMiscReg(MISCREG_Y))
+ diffY = true;
+ if(shared_data->ccr != thread->readMiscReg(MISCREG_CCR))
+ diffCcr = true;
+ if(shared_data->gl != thread->readMiscReg(MISCREG_GL))
+ diffGl = true;
+ if(shared_data->asi != thread->readMiscReg(MISCREG_ASI))
+ diffAsi = true;
+ if(shared_data->pil != thread->readMiscReg(MISCREG_PIL))
+ diffPil = true;
+ if(shared_data->cwp != thread->readMiscReg(MISCREG_CWP))
+ diffCwp = true;
+ if(shared_data->cansave != thread->readMiscReg(MISCREG_CANSAVE))
+ diffCansave = true;
+ if(shared_data->canrestore !=
+ thread->readMiscReg(MISCREG_CANRESTORE))
+ diffCanrestore = true;
+ if(shared_data->otherwin != thread->readMiscReg(MISCREG_OTHERWIN))
+ diffOtherwin = true;
+ if(shared_data->cleanwin != thread->readMiscReg(MISCREG_CLEANWIN))
+ diffCleanwin = true;
+
+ if (diffPC || diffInst || diffRegs || diffTpc || diffTnpc ||
+ diffTstate || diffTt || diffHpstate ||
+ diffHtstate || diffHtba || diffPstate || diffY ||
+ diffCcr || diffTl || diffGl || diffAsi || diffPil ||
+ diffCwp || diffCansave || diffCanrestore ||
+ diffOtherwin || diffCleanwin) {
outs << "Differences found between M5 and Legion:";
if (diffPC)
outs << " [PC]";
@@ -265,6 +398,44 @@ Trace::InstRecord::dump(ostream &outs)
outs << " [Instruction]";
if (diffRegs)
outs << " [IntRegs]";
+ if (diffTpc)
+ outs << " [Tpc]";
+ if (diffTnpc)
+ outs << " [Tnpc]";
+ if (diffTstate)
+ outs << " [Tstate]";
+ if (diffTt)
+ outs << " [Tt]";
+ if (diffHpstate)
+ outs << " [Hpstate]";
+ if (diffHtstate)
+ outs << " [Htstate]";
+ if (diffHtba)
+ outs << " [Htba]";
+ if (diffPstate)
+ outs << " [Pstate]";
+ if (diffY)
+ outs << " [Y]";
+ if (diffCcr)
+ outs << " [Ccr]";
+ if (diffTl)
+ outs << " [Tl]";
+ if (diffGl)
+ outs << " [Gl]";
+ if (diffAsi)
+ outs << " [Asi]";
+ if (diffPil)
+ outs << " [Pil]";
+ if (diffCwp)
+ outs << " [Cwp]";
+ if (diffCansave)
+ outs << " [Cansave]";
+ if (diffCanrestore)
+ outs << " [Canrestore]";
+ if (diffOtherwin)
+ outs << " [Otherwin]";
+ if (diffCleanwin)
+ outs << " [Cleanwin]";
outs << endl << endl;
outs << right << setfill(' ') << setw(15)
@@ -280,29 +451,106 @@ Trace::InstRecord::dump(ostream &outs)
<< staticInst->disassemble(m5Pc, debugSymbolTable)
<< endl;
- StaticInstPtr legionInst = StaticInst::decode(makeExtMI(shared_data->instruction, thread));
+ StaticInstPtr legionInst =
+ StaticInst::decode(makeExtMI(shared_data->instruction,
+ thread));
outs << setfill(' ') << setw(15)
<< " Legion Inst: "
<< "0x" << setw(8) << setfill('0') << hex
<< shared_data->instruction
<< legionInst->disassemble(lgnPc, debugSymbolTable)
- << endl;
-
+ << endl << endl;
+
+ printSectionHeader(outs, "General State");
+ printColumnLabels(outs);
+ printRegPair(outs, "HPstate",
+ thread->readMiscReg(MISCREG_HPSTATE),
+ shared_data->hpstate | (1 << 11));
+ printRegPair(outs, "Htba",
+ thread->readMiscReg(MISCREG_HTBA),
+ shared_data->htba);
+ printRegPair(outs, "Pstate",
+ thread->readMiscReg(MISCREG_PSTATE),
+ shared_data->pstate);
+ printRegPair(outs, "Y",
+ thread->readMiscReg(MISCREG_Y),
+ shared_data->y);
+ printRegPair(outs, "Ccr",
+ thread->readMiscReg(MISCREG_CCR),
+ shared_data->ccr);
+ printRegPair(outs, "Tl",
+ thread->readMiscReg(MISCREG_TL),
+ shared_data->tl);
+ printRegPair(outs, "Gl",
+ thread->readMiscReg(MISCREG_GL),
+ shared_data->gl);
+ printRegPair(outs, "Asi",
+ thread->readMiscReg(MISCREG_ASI),
+ shared_data->asi);
+ printRegPair(outs, "Pil",
+ thread->readMiscReg(MISCREG_PIL),
+ shared_data->pil);
+ printRegPair(outs, "Cwp",
+ thread->readMiscReg(MISCREG_CWP),
+ shared_data->cwp);
+ printRegPair(outs, "Cansave",
+ thread->readMiscReg(MISCREG_CANSAVE),
+ shared_data->cansave);
+ printRegPair(outs, "Canrestore",
+ thread->readMiscReg(MISCREG_CANRESTORE),
+ shared_data->canrestore);
+ printRegPair(outs, "Otherwin",
+ thread->readMiscReg(MISCREG_OTHERWIN),
+ shared_data->otherwin);
+ printRegPair(outs, "Cleanwin",
+ thread->readMiscReg(MISCREG_CLEANWIN),
+ shared_data->cleanwin);
+ outs << endl;
+ for (int i = 1; i <= MaxTL; i++) {
+ printLevelHeader(outs, i);
+ printColumnLabels(outs);
+ thread->setMiscReg(MISCREG_TL, i);
+ printRegPair(outs, "Tpc",
+ thread->readMiscReg(MISCREG_TPC),
+ shared_data->tpc[i]);
+ printRegPair(outs, "Tnpc",
+ thread->readMiscReg(MISCREG_TNPC),
+ shared_data->tnpc[i]);
+ printRegPair(outs, "Tstate",
+ thread->readMiscReg(MISCREG_TSTATE),
+ shared_data->tstate[i]);
+ printRegPair(outs, "Tt",
+ thread->readMiscReg(MISCREG_TT),
+ shared_data->tt[i]);
+ printRegPair(outs, "Htstate",
+ thread->readMiscReg(MISCREG_HTSTATE),
+ shared_data->htstate[i]);
+ }
+ thread->setMiscReg(MISCREG_TL, oldTl);
outs << endl;
+ printSectionHeader(outs, "General Purpose Registers");
static const char * regtypes[4] = {"%g", "%o", "%l", "%i"};
for(int y = 0; y < 4; y++)
{
for(int x = 0; x < 8; x++)
{
- outs << regtypes[y] << x << " " ;
- outs << "0x" << hex << setw(16) << thread->readIntReg(y*8+x);
- if (thread->readIntReg(y*8 + x) != shared_data->intregs[y*8+x])
+ char label[8];
+ sprintf(label, "%s%d", regtypes[y], x);
+ printRegPair(outs, label,
+ thread->readIntReg(y*8+x),
+ shared_data->intregs[y*8+x]);
+ /*outs << regtypes[y] << x << " " ;
+ outs << "0x" << hex << setw(16)
+ << thread->readIntReg(y*8+x);
+ if (thread->readIntReg(y*8 + x)
+ != shared_data->intregs[y*8+x])
outs << " X ";
else
outs << " | ";
- outs << "0x" << setw(16) << hex << shared_data->intregs[y*8+x]
- << endl;
+ outs << "0x" << setw(16) << hex
+ << shared_data->intregs[y*8+x]
+ << endl;*/
}
}
fatal("Differences found between Legion and M5\n");