X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fcpu%2Fexetrace.cc;h=bbde89c006b029971e4dfb19e871c2ea4b06ea4c;hb=db522eb930020a7a9caf1ea6e289fc81a0bcc842;hp=85df19348b4c7c51573a76177776fbf4b0d57478;hpb=49490b334af3bc145071a9a81f37012e7693af59;p=gem5.git diff --git a/src/cpu/exetrace.cc b/src/cpu/exetrace.cc index 85df19348..bbde89c00 100644 --- a/src/cpu/exetrace.cc +++ b/src/cpu/exetrace.cc @@ -31,772 +31,149 @@ * Steve Raasch */ -#include -#include +#include "cpu/exetrace.hh" + #include -#include -#include -#include "arch/predecoder.hh" -#include "arch/regfile.hh" +#include "arch/isa_traits.hh" #include "arch/utility.hh" #include "base/loader/symtab.hh" -#include "base/socket.hh" -#include "config/full_system.hh" +#include "config/the_isa.hh" #include "cpu/base.hh" -#include "cpu/exetrace.hh" #include "cpu/static_inst.hh" -#include "sim/param.hh" -#include "sim/system.hh" - -#if FULL_SYSTEM -#include "arch/tlb.hh" -#endif - -//XXX This is temporary -#include "arch/isa_specific.hh" -#include "cpu/m5legion_interface.h" +#include "cpu/thread_context.hh" +#include "debug/ExecAll.hh" +#include "enums/OpClass.hh" using namespace std; using namespace TheISA; -#if THE_ISA == SPARC_ISA && FULL_SYSTEM -static int diffcount = 0; -static bool wasMicro = false; -#endif - namespace Trace { -SharedData *shared_data = NULL; -ListenSocket *cosim_listener = NULL; void -setupSharedData() -{ - int shmfd = shmget('M' << 24 | getuid(), sizeof(SharedData), 0777); - if (shmfd < 0) - fatal("Couldn't get shared memory fd. Is Legion running?"); - - shared_data = (SharedData*)shmat(shmfd, NULL, SHM_RND); - if (shared_data == (SharedData*)-1) - fatal("Couldn't allocate shared memory"); - - if (shared_data->flags != OWN_M5) - fatal("Shared memory has invalid owner"); - - if (shared_data->version != VERSION) - fatal("Shared Data is wrong version! M5: %d Legion: %d", VERSION, - shared_data->version); - - // step legion forward one cycle so we can get register values - shared_data->flags = OWN_LEGION; -} - -//////////////////////////////////////////////////////////////////////// -// -// Methods for the InstRecord object -// - -#if THE_ISA == SPARC_ISA - -inline char * genCenteredLabel(int length, char * buffer, char * label) +ExeTracerRecord::dumpTicks(ostream &outs) { - 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; + ccprintf(outs, "%7d: ", when); } -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) +void +Trace::ExeTracerRecord::traceInst(const StaticInstPtr &inst, bool ran) { - 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"); -} + ostream &outs = Trace::output(); -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"); -} + if (!Debug::ExecUser || !Debug::ExecKernel) { + bool in_user_mode = TheISA::inUserMode(thread); + if (in_user_mode && !Debug::ExecUser) return; + if (!in_user_mode && !Debug::ExecKernel) return; + } -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"); -} + if (Debug::ExecTicks) + dumpTicks(outs); -#endif + outs << thread->getCpuPtr()->name() << " "; -void -Trace::InstRecord::dump() -{ - ostream &outs = Trace::output(); + if (Debug::ExecAsid) + outs << "A" << dec << TheISA::getExecutingAsid(thread) << " "; - DPRINTF(Sparc, "Instruction: %#X\n", staticInst->machInst); - bool diff = true; - if (IsOn(ExecRegDelta)) - { - diff = false; -#ifndef NDEBUG -#if THE_ISA == SPARC_ISA - static int fd = 0; - //Don't print what happens for each micro-op, just print out - //once at the last op, and for regular instructions. - if(!staticInst->isMicroop() || staticInst->isLastMicroop()) - { - if(!cosim_listener) - { - int port = 8000; - cosim_listener = new ListenSocket(); - while(!cosim_listener->listen(port, true)) - { - DPRINTF(GDBMisc, "Can't bind port %d\n", port); - port++; - } - ccprintf(cerr, "Listening for cosimulator on port %d\n", port); - fd = cosim_listener->accept(); - } - char prefix[] = "goli"; - for(int p = 0; p < 4; p++) - { - for(int i = 0; i < 8; i++) - { - uint64_t regVal; - int res = read(fd, ®Val, sizeof(regVal)); - if(res < 0) - panic("First read call failed! %s\n", strerror(errno)); - regVal = TheISA::gtoh(regVal); - uint64_t realRegVal = thread->readIntReg(p * 8 + i); - if((regVal & 0xffffffffULL) != (realRegVal & 0xffffffffULL)) - { - DPRINTF(ExecRegDelta, "Register %s%d should be %#x but is %#x.\n", prefix[p], i, regVal, realRegVal); - diff = true; - } - //ccprintf(outs, "%s%d m5 = %#x statetrace = %#x\n", prefix[p], i, realRegVal, regVal); - } - } - /*for(int f = 0; f <= 62; f+=2) - { - uint64_t regVal; - int res = read(fd, ®Val, sizeof(regVal)); - if(res < 0) - panic("First read call failed! %s\n", strerror(errno)); - regVal = TheISA::gtoh(regVal); - uint64_t realRegVal = thread->readFloatRegBits(f, 64); - if(regVal != realRegVal) - { - DPRINTF(ExecRegDelta, "Register f%d should be %#x but is %#x.\n", f, regVal, realRegVal); - } - }*/ - uint64_t regVal; - int res = read(fd, ®Val, sizeof(regVal)); - if(res < 0) - panic("First read call failed! %s\n", strerror(errno)); - regVal = TheISA::gtoh(regVal); - uint64_t realRegVal = thread->readNextPC(); - if(regVal != realRegVal) - { - DPRINTF(ExecRegDelta, "Register pc should be %#x but is %#x.\n", regVal, realRegVal); - diff = true; - } - res = read(fd, ®Val, sizeof(regVal)); - if(res < 0) - panic("First read call failed! %s\n", strerror(errno)); - regVal = TheISA::gtoh(regVal); - realRegVal = thread->readNextNPC(); - if(regVal != realRegVal) - { - DPRINTF(ExecRegDelta, "Register npc should be %#x but is %#x.\n", regVal, realRegVal); - diff = true; - } - res = read(fd, ®Val, sizeof(regVal)); - if(res < 0) - panic("First read call failed! %s\n", strerror(errno)); - regVal = TheISA::gtoh(regVal); - realRegVal = thread->readIntReg(SparcISA::NumIntArchRegs + 2); - if((regVal & 0xF) != (realRegVal & 0xF)) - { - DPRINTF(ExecRegDelta, "Register ccr should be %#x but is %#x.\n", regVal, realRegVal); - diff = true; - } - } -#endif -#endif -#if 0 //THE_ISA == SPARC_ISA - //Don't print what happens for each micro-op, just print out - //once at the last op, and for regular instructions. - if(!staticInst->isMicroop() || staticInst->isLastMicroop()) - { - static uint64_t regs[32] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0}; - static uint64_t ccr = 0; - static uint64_t y = 0; - static uint64_t floats[32]; - uint64_t newVal; - static const char * prefixes[4] = {"G", "O", "L", "I"}; + if (Debug::ExecThread) + outs << "T" << thread->threadId() << " : "; - outs << hex; - outs << "PC = " << thread->readNextPC(); - outs << " NPC = " << thread->readNextNPC(); - newVal = thread->readIntReg(SparcISA::NumIntArchRegs + 2); - //newVal = thread->readMiscRegNoEffect(SparcISA::MISCREG_CCR); - if(newVal != ccr) - { - outs << " CCR = " << newVal; - ccr = newVal; - } - newVal = thread->readIntReg(SparcISA::NumIntArchRegs + 1); - //newVal = thread->readMiscRegNoEffect(SparcISA::MISCREG_Y); - if(newVal != y) - { - outs << " Y = " << newVal; - y = newVal; - } - for(int y = 0; y < 4; y++) - { - for(int x = 0; x < 8; x++) - { - int index = x + 8 * y; - newVal = thread->readIntReg(index); - if(regs[index] != newVal) - { - outs << " " << prefixes[y] << dec << x << " = " << hex << newVal; - regs[index] = newVal; - } - } - } - for(int y = 0; y < 32; y++) - { - newVal = thread->readFloatRegBits(2 * y, 64); - if(floats[y] != newVal) - { - outs << " F" << dec << (2 * y) << " = " << hex << newVal; - floats[y] = newVal; - } - } - outs << dec << endl; - } -#endif + std::string sym_str; + Addr sym_addr; + Addr cur_pc = pc.instAddr(); + if (debugSymbolTable && Debug::ExecSymbol && + (!FullSystem || !inUserMode(thread)) && + debugSymbolTable->findNearestSymbol(cur_pc, sym_str, sym_addr)) { + if (cur_pc != sym_addr) + sym_str += csprintf("+%d",cur_pc - sym_addr); + outs << "@" << sym_str; + } else { + outs << "0x" << hex << cur_pc; } - if(!diff) { - } else if (IsOn(ExecIntel)) { - ccprintf(outs, "%7d ) ", when); - outs << "0x" << hex << PC << ":\t"; - if (staticInst->isLoad()) { - ccprintf(outs, "", addr); - } else if (staticInst->isStore()) { - ccprintf(outs, "", addr); - } - outs << endl; + + if (inst->isMicroop()) { + outs << "." << setw(2) << dec << pc.microPC(); } else { - if (IsOn(ExecTicks)) - ccprintf(outs, "%7d: ", when); + outs << " "; + } - outs << thread->getCpuPtr()->name() << " "; + outs << " : "; - if (IsOn(ExecSpeculative)) - outs << (misspeculating ? "-" : "+") << " "; + // + // Print decoded instruction + // - if (IsOn(ExecThread)) - outs << "T" << thread->getThreadNum() << " : "; + outs << setw(26) << left; + outs << inst->disassemble(cur_pc, debugSymbolTable); + if (ran) { + outs << " : "; - std::string sym_str; - Addr sym_addr; - if (debugSymbolTable - && debugSymbolTable->findNearestSymbol(PC, sym_str, sym_addr) - && IsOn(ExecSymbol)) { - if (PC != sym_addr) - sym_str += csprintf("+%d", PC - sym_addr); - outs << "@" << sym_str << " : "; + if (Debug::ExecOpClass) { + outs << Enums::OpClassStrings[inst->opClass()] << " : "; } - else { - outs << "0x" << hex << PC << " : "; - } - - // - // Print decoded instruction - // - -#if defined(__GNUC__) && (__GNUC__ < 3) - // There's a bug in gcc 2.x library that prevents setw() - // from working properly on strings - string mc(staticInst->disassemble(PC, debugSymbolTable)); - while (mc.length() < 26) - mc += " "; - outs << mc; -#else - outs << setw(26) << left << staticInst->disassemble(PC, debugSymbolTable); -#endif - - outs << " : "; - if (IsOn(ExecOpClass)) { - outs << opClassStrings[staticInst->opClass()] << " : "; + if (Debug::ExecResult && !predicate) { + outs << "Predicated False"; } - if (IsOn(ExecResult) && data_status != DataInvalid) { - outs << " D="; -#if 0 - if (data_status == DataDouble) - ccprintf(outs, "%f", data.as_double); - else - ccprintf(outs, "%#018x", data.as_int); -#else - ccprintf(outs, "%#018x", data.as_int); -#endif + if (Debug::ExecResult && data_status != DataInvalid) { + ccprintf(outs, " D=%#018x", data.as_int); } - if (IsOn(ExecEffAddr) && addr_valid) + if (Debug::ExecEffAddr && getMemValid()) outs << " A=0x" << hex << addr; - if (IsOn(ExecIntRegs) && regs_valid) { - for (int i = 0; i < TheISA::NumIntRegs;) - for (int j = i + 1; i <= j; i++) - ccprintf(outs, "r%02d = %#018x%s", i, - iregs->regs.readReg(i), - ((i == j) ? "\n" : " ")); - outs << "\n"; - } - - if (IsOn(ExecFetchSeq) && fetch_seq_valid) + if (Debug::ExecFetchSeq && fetch_seq_valid) outs << " FetchSeq=" << dec << fetch_seq; - if (IsOn(ExecCPSeq) && cp_seq_valid) + if (Debug::ExecCPSeq && cp_seq_valid) outs << " CPSeq=" << dec << cp_seq; - // - // End of line... - // - outs << endl; - } -#if THE_ISA == SPARC_ISA && FULL_SYSTEM - static TheISA::Predecoder predecoder(NULL); - // Compare - if (IsOn(ExecLegion)) - { - bool compared = false; - bool diffPC = false; - bool diffCC = false; - bool diffInst = false; - bool diffIntRegs = false; - bool diffFpRegs = 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 diffFsr = 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; - bool diffTlb = false; - Addr m5Pc, lgnPc; - - if (!shared_data) - setupSharedData(); - - // We took a trap on a micro-op... - if (wasMicro && !staticInst->isMicroop()) - { - // let's skip comparing this tick - while (!compared) - if (shared_data->flags == OWN_M5) { - shared_data->flags = OWN_LEGION; - compared = true; - } - compared = false; - wasMicro = false; + if (Debug::ExecFlags) { + outs << " flags=("; + inst->printFlags(outs, "|"); + outs << ")"; } + } - if (staticInst->isLastMicroop()) - wasMicro = false; - else if (staticInst->isMicroop()) - wasMicro = true; - - - if(!staticInst->isMicroop() || staticInst->isLastMicroop()) { - while (!compared) { - if (shared_data->flags == OWN_M5) { - m5Pc = PC & TheISA::PAddrImplMask; - if (bits(shared_data->pstate,3,3)) { - m5Pc &= mask(32); - } - lgnPc = shared_data->pc & TheISA::PAddrImplMask; - if (lgnPc != m5Pc) - diffPC = true; - - if (shared_data->cycle_count != - thread->getCpuPtr()->instCount()) - diffCC = true; - - if (shared_data->instruction != - (SparcISA::MachInst)staticInst->machInst) { - diffInst = true; - } - // assume we have %g0 working correctly - for (int i = 1; i < TheISA::NumIntArchRegs; i++) { - if (thread->readIntReg(i) != shared_data->intregs[i]) { - diffIntRegs = true; - } - } - for (int i = 0; i < TheISA::NumFloatRegs/2; i++) { - if (thread->readFloatRegBits(i*2,FloatRegFile::DoubleWidth) != shared_data->fpregs[i]) { - diffFpRegs = true; - } - } - uint64_t oldTl = thread->readMiscRegNoEffect(MISCREG_TL); - if (oldTl != shared_data->tl) - diffTl = true; - for (int i = 1; i <= MaxTL; i++) { - thread->setMiscRegNoEffect(MISCREG_TL, i); - if (thread->readMiscRegNoEffect(MISCREG_TPC) != - shared_data->tpc[i-1]) - diffTpc = true; - if (thread->readMiscRegNoEffect(MISCREG_TNPC) != - shared_data->tnpc[i-1]) - diffTnpc = true; - if (thread->readMiscRegNoEffect(MISCREG_TSTATE) != - shared_data->tstate[i-1]) - diffTstate = true; - if (thread->readMiscRegNoEffect(MISCREG_TT) != - shared_data->tt[i-1]) - diffTt = true; - if (thread->readMiscRegNoEffect(MISCREG_HTSTATE) != - shared_data->htstate[i-1]) - diffHtstate = true; - } - thread->setMiscRegNoEffect(MISCREG_TL, oldTl); - - if(shared_data->tba != thread->readMiscRegNoEffect(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->readMiscRegNoEffect(MISCREG_HPSTATE)) - diffHpstate = true; - if(shared_data->htba != thread->readMiscRegNoEffect(MISCREG_HTBA)) - diffHtba = true; - if(shared_data->pstate != thread->readMiscRegNoEffect(MISCREG_PSTATE)) - diffPstate = true; - //if(shared_data->y != thread->readMiscRegNoEffect(MISCREG_Y)) - if(shared_data->y != - thread->readIntReg(NumIntArchRegs + 1)) - diffY = true; - if(shared_data->fsr != thread->readMiscRegNoEffect(MISCREG_FSR)) { - diffFsr = true; - if (mbits(shared_data->fsr, 63,10) == - mbits(thread->readMiscRegNoEffect(MISCREG_FSR), 63,10)) { - thread->setMiscRegNoEffect(MISCREG_FSR, shared_data->fsr); - diffFsr = false; - } - } - //if(shared_data->ccr != thread->readMiscRegNoEffect(MISCREG_CCR)) - if(shared_data->ccr != - thread->readIntReg(NumIntArchRegs + 2)) - diffCcr = true; - if(shared_data->gl != thread->readMiscRegNoEffect(MISCREG_GL)) - diffGl = true; - if(shared_data->asi != thread->readMiscRegNoEffect(MISCREG_ASI)) - diffAsi = true; - if(shared_data->pil != thread->readMiscRegNoEffect(MISCREG_PIL)) - diffPil = true; - if(shared_data->cwp != thread->readMiscRegNoEffect(MISCREG_CWP)) - diffCwp = true; - //if(shared_data->cansave != thread->readMiscRegNoEffect(MISCREG_CANSAVE)) - if(shared_data->cansave != - thread->readIntReg(NumIntArchRegs + 3)) - diffCansave = true; - //if(shared_data->canrestore != - // thread->readMiscRegNoEffect(MISCREG_CANRESTORE)) - if(shared_data->canrestore != - thread->readIntReg(NumIntArchRegs + 4)) - diffCanrestore = true; - //if(shared_data->otherwin != thread->readMiscRegNoEffect(MISCREG_OTHERWIN)) - if(shared_data->otherwin != - thread->readIntReg(NumIntArchRegs + 6)) - diffOtherwin = true; - //if(shared_data->cleanwin != thread->readMiscRegNoEffect(MISCREG_CLEANWIN)) - if(shared_data->cleanwin != - thread->readIntReg(NumIntArchRegs + 5)) - diffCleanwin = true; - - for (int i = 0; i < 64; i++) { - if (shared_data->itb[i] != thread->getITBPtr()->TteRead(i)) - diffTlb = true; - if (shared_data->dtb[i] != thread->getDTBPtr()->TteRead(i)) - diffTlb = true; - } - - if (diffPC || diffCC || diffInst || diffIntRegs || - diffFpRegs || diffTpc || diffTnpc || diffTstate || - diffTt || diffHpstate || diffHtstate || diffHtba || - diffPstate || diffY || diffCcr || diffTl || diffFsr || - diffGl || diffAsi || diffPil || diffCwp || diffCansave || - diffCanrestore || diffOtherwin || diffCleanwin || diffTlb) - { - - outs << "Differences found between M5 and Legion:"; - if (diffPC) - outs << " [PC]"; - if (diffCC) - outs << " [CC]"; - if (diffInst) - outs << " [Instruction]"; - if (diffIntRegs) - outs << " [IntRegs]"; - if (diffFpRegs) - outs << " [FpRegs]"; - 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 (diffFsr) - outs << " [FSR]"; - 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]"; - if (diffTlb) - outs << " [Tlb]"; - outs << endl << endl; - - outs << right << setfill(' ') << setw(15) - << "M5 PC: " << "0x"<< setw(16) << setfill('0') - << hex << m5Pc << endl; - outs << setfill(' ') << setw(15) - << "Legion PC: " << "0x"<< setw(16) << setfill('0') << hex - << lgnPc << endl << endl; - - outs << right << setfill(' ') << setw(15) - << "M5 CC: " << "0x"<< setw(16) << setfill('0') - << hex << thread->getCpuPtr()->instCount() << endl; - outs << setfill(' ') << setw(15) - << "Legion CC: " << "0x"<< setw(16) << setfill('0') << hex - << shared_data->cycle_count << endl << endl; - - outs << setfill(' ') << setw(15) - << "M5 Inst: " << "0x"<< setw(8) - << setfill('0') << hex << staticInst->machInst - << staticInst->disassemble(m5Pc, debugSymbolTable) - << endl; - - predecoder.setTC(thread); - predecoder.moreBytes(m5Pc, m5Pc, - shared_data->instruction); - - assert(predecoder.extMachInstReady()); - - StaticInstPtr legionInst = - StaticInst::decode(predecoder.getExtMachInst(), lgnPc); - outs << setfill(' ') << setw(15) - << " Legion Inst: " - << "0x" << setw(8) << setfill('0') << hex - << shared_data->instruction - << legionInst->disassemble(lgnPc, debugSymbolTable) - << endl << endl; - - printSectionHeader(outs, "General State"); - printColumnLabels(outs); - printRegPair(outs, "HPstate", - thread->readMiscRegNoEffect(MISCREG_HPSTATE), - shared_data->hpstate | (1 << 11)); - printRegPair(outs, "Htba", - thread->readMiscRegNoEffect(MISCREG_HTBA), - shared_data->htba); - printRegPair(outs, "Pstate", - thread->readMiscRegNoEffect(MISCREG_PSTATE), - shared_data->pstate); - printRegPair(outs, "Y", - //thread->readMiscRegNoEffect(MISCREG_Y), - thread->readIntReg(NumIntArchRegs + 1), - shared_data->y); - printRegPair(outs, "FSR", - thread->readMiscRegNoEffect(MISCREG_FSR), - shared_data->fsr); - printRegPair(outs, "Ccr", - //thread->readMiscRegNoEffect(MISCREG_CCR), - thread->readIntReg(NumIntArchRegs + 2), - shared_data->ccr); - printRegPair(outs, "Tl", - thread->readMiscRegNoEffect(MISCREG_TL), - shared_data->tl); - printRegPair(outs, "Gl", - thread->readMiscRegNoEffect(MISCREG_GL), - shared_data->gl); - printRegPair(outs, "Asi", - thread->readMiscRegNoEffect(MISCREG_ASI), - shared_data->asi); - printRegPair(outs, "Pil", - thread->readMiscRegNoEffect(MISCREG_PIL), - shared_data->pil); - printRegPair(outs, "Cwp", - thread->readMiscRegNoEffect(MISCREG_CWP), - shared_data->cwp); - printRegPair(outs, "Cansave", - //thread->readMiscRegNoEffect(MISCREG_CANSAVE), - thread->readIntReg(NumIntArchRegs + 3), - shared_data->cansave); - printRegPair(outs, "Canrestore", - //thread->readMiscRegNoEffect(MISCREG_CANRESTORE), - thread->readIntReg(NumIntArchRegs + 4), - shared_data->canrestore); - printRegPair(outs, "Otherwin", - //thread->readMiscRegNoEffect(MISCREG_OTHERWIN), - thread->readIntReg(NumIntArchRegs + 6), - shared_data->otherwin); - printRegPair(outs, "Cleanwin", - //thread->readMiscRegNoEffect(MISCREG_CLEANWIN), - thread->readIntReg(NumIntArchRegs + 5), - shared_data->cleanwin); - outs << endl; - for (int i = 1; i <= MaxTL; i++) { - printLevelHeader(outs, i); - printColumnLabels(outs); - thread->setMiscRegNoEffect(MISCREG_TL, i); - printRegPair(outs, "Tpc", - thread->readMiscRegNoEffect(MISCREG_TPC), - shared_data->tpc[i-1]); - printRegPair(outs, "Tnpc", - thread->readMiscRegNoEffect(MISCREG_TNPC), - shared_data->tnpc[i-1]); - printRegPair(outs, "Tstate", - thread->readMiscRegNoEffect(MISCREG_TSTATE), - shared_data->tstate[i-1]); - printRegPair(outs, "Tt", - thread->readMiscRegNoEffect(MISCREG_TT), - shared_data->tt[i-1]); - printRegPair(outs, "Htstate", - thread->readMiscRegNoEffect(MISCREG_HTSTATE), - shared_data->htstate[i-1]); - } - thread->setMiscRegNoEffect(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++) { - char label[8]; - sprintf(label, "%s%d", regtypes[y], x); - printRegPair(outs, label, - thread->readIntReg(y*8+x), - shared_data->intregs[y*8+x]); - } - } - if (diffFpRegs) { - for (int x = 0; x < 32; x++) { - char label[8]; - sprintf(label, "%%f%d", x); - printRegPair(outs, label, - thread->readFloatRegBits(x*2,FloatRegFile::DoubleWidth), - shared_data->fpregs[x]); - } - } - if (diffTlb) { - printColumnLabels(outs); - char label[8]; - for (int x = 0; x < 64; x++) { - if (shared_data->itb[x] != ULL(0xFFFFFFFFFFFFFFFF) || - thread->getITBPtr()->TteRead(x) != ULL(0xFFFFFFFFFFFFFFFF)) { - sprintf(label, "I-TLB:%02d", x); - printRegPair(outs, label, thread->getITBPtr()->TteRead(x), - shared_data->itb[x]); - } - } - for (int x = 0; x < 64; x++) { - if (shared_data->dtb[x] != ULL(0xFFFFFFFFFFFFFFFF) || - thread->getDTBPtr()->TteRead(x) != ULL(0xFFFFFFFFFFFFFFFF)) { - sprintf(label, "D-TLB:%02d", x); - printRegPair(outs, label, thread->getDTBPtr()->TteRead(x), - shared_data->dtb[x]); - } - } - thread->getITBPtr()->dumpAll(); - thread->getDTBPtr()->dumpAll(); - } - - diffcount++; - if (diffcount > 3) - fatal("Differences found between Legion and M5\n"); - } else - diffcount = 0; + // + // End of line... + // + outs << endl; +} - compared = true; - shared_data->flags = OWN_LEGION; - } - } // while - } // if not microop +void +Trace::ExeTracerRecord::dump() +{ + /* + * The behavior this check tries to achieve is that if ExecMacro is on, + * the macroop will be printed. If it's on and microops are also on, it's + * printed before the microops start printing to give context. If the + * microops aren't printed, then it's printed only when the final microop + * finishes. Macroops then behave like regular instructions and don't + * complete/print when they fault. + */ + if (Debug::ExecMacro && staticInst->isMicroop() && + ((Debug::ExecMicro && + macroStaticInst && staticInst->isFirstMicroop()) || + (!Debug::ExecMicro && + macroStaticInst && staticInst->isLastMicroop()))) { + traceInst(macroStaticInst, false); + } + if (Debug::ExecMicro || !staticInst->isMicroop()) { + traceInst(staticInst, true); } -#endif } -/* namespace Trace */ } +} // namespace Trace + +//////////////////////////////////////////////////////////////////////// +// +// ExeTracer Simulation Object +// +Trace::ExeTracer * +ExeTracerParams::create() +{ + return new Trace::ExeTracer(this); +}