exetrace.cc revision 3980:9bcb2a2e9bb8
12SN/A/* 29448SAndreas.Sandberg@ARM.com * Copyright (c) 2001-2005 The Regents of The University of Michigan 39920Syasuko.eckert@amd.com * All rights reserved. 47338SAli.Saidi@ARM.com * 57338SAli.Saidi@ARM.com * Redistribution and use in source and binary forms, with or without 67338SAli.Saidi@ARM.com * modification, are permitted provided that the following conditions are 77338SAli.Saidi@ARM.com * met: redistributions of source code must retain the above copyright 87338SAli.Saidi@ARM.com * notice, this list of conditions and the following disclaimer; 97338SAli.Saidi@ARM.com * redistributions in binary form must reproduce the above copyright 107338SAli.Saidi@ARM.com * notice, this list of conditions and the following disclaimer in the 117338SAli.Saidi@ARM.com * documentation and/or other materials provided with the distribution; 127338SAli.Saidi@ARM.com * neither the name of the copyright holders nor the names of its 137338SAli.Saidi@ARM.com * contributors may be used to endorse or promote products derived from 147338SAli.Saidi@ARM.com * this software without specific prior written permission. 151762SN/A * 162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272SN/A * 282SN/A * Authors: Steve Reinhardt 292SN/A * Lisa Hsu 302SN/A * Nathan Binkert 312SN/A * Steve Raasch 322SN/A */ 332SN/A 342SN/A#include <fstream> 352SN/A#include <iomanip> 362SN/A#include <sys/ipc.h> 372SN/A#include <sys/shm.h> 382SN/A 392SN/A#include "arch/regfile.hh" 402665Ssaidi@eecs.umich.edu#include "arch/utility.hh" 412665Ssaidi@eecs.umich.edu#include "base/loader/symtab.hh" 422SN/A#include "config/full_system.hh" 432SN/A#include "cpu/base.hh" 448779Sgblack@eecs.umich.edu#include "cpu/exetrace.hh" 458779Sgblack@eecs.umich.edu#include "cpu/static_inst.hh" 468779Sgblack@eecs.umich.edu#include "sim/param.hh" 472439SN/A#include "sim/system.hh" 488779Sgblack@eecs.umich.edu 498229Snate@binkert.org#if FULL_SYSTEM 506216Snate@binkert.org#include "arch/tlb.hh" 51146SN/A#endif 52146SN/A 53146SN/A//XXX This is temporary 54146SN/A#include "arch/isa_specific.hh" 55146SN/A#include "cpu/m5legion_interface.h" 566216Snate@binkert.org 576658Snate@binkert.orgusing namespace std; 588229Snate@binkert.orgusing namespace TheISA; 591717SN/A 608887Sgeoffrey.blake@arm.com#if THE_ISA == SPARC_ISA && FULL_SYSTEM 618887Sgeoffrey.blake@arm.comstatic int diffcount = 0; 62146SN/Astatic bool wasMicro = false; 6310061Sandreas@sandberg.pp.se#endif 641977SN/A 652683Sktlim@umich.edunamespace Trace { 661717SN/ASharedData *shared_data = NULL; 67146SN/A} 682683Sktlim@umich.edu 698232Snate@binkert.org//////////////////////////////////////////////////////////////////////// 708232Snate@binkert.org// 718232Snate@binkert.org// Methods for the InstRecord object 728779Sgblack@eecs.umich.edu// 733348Sbinkertn@umich.edu 746105Ssteve.reinhardt@amd.com#if THE_ISA == SPARC_ISA 756216Snate@binkert.org 762036SN/Ainline char * genCenteredLabel(int length, char * buffer, char * label) 77146SN/A{ 788817Sgblack@eecs.umich.edu int labelLength = strlen(label); 798793Sgblack@eecs.umich.edu assert(labelLength <= length); 8056SN/A int leftPad = (length - labelLength) / 2; 8156SN/A int rightPad = length - leftPad - labelLength; 82695SN/A char format[64]; 832901Ssaidi@eecs.umich.edu sprintf(format, "%%%ds%%s%%%ds", leftPad, rightPad); 842SN/A sprintf(buffer, format, "", label, ""); 852SN/A return buffer; 862449SN/A} 871355SN/A 885529Snate@binkert.orginline void printRegPair(ostream & os, char const * title, uint64_t a, uint64_t b) 8910061Sandreas@sandberg.pp.se{ 9010061Sandreas@sandberg.pp.se ccprintf(os, " %16s | %#018x %s %#-018x \n", 9110061Sandreas@sandberg.pp.se title, a, (a == b) ? "|" : "X", b); 92224SN/A} 938793Sgblack@eecs.umich.edu 949384SAndreas.Sandberg@arm.cominline void printColumnLabels(ostream & os) 959384SAndreas.Sandberg@arm.com{ 968793Sgblack@eecs.umich.edu static char * regLabel = genCenteredLabel(16, new char[17], "Register"); 978820Sgblack@eecs.umich.edu static char * m5Label = genCenteredLabel(18, new char[18], "M5"); 989384SAndreas.Sandberg@arm.com static char * legionLabel = genCenteredLabel(18, new char[18], "Legion"); 992SN/A ccprintf(os, " %s | %s | %s \n", regLabel, m5Label, legionLabel); 1006029Ssteve.reinhardt@amd.com ccprintf(os, "--------------------+-----------------------+-----------------------\n"); 1012672Sktlim@umich.edu} 1022683Sktlim@umich.edu 1032SN/Ainline void printSectionHeader(ostream & os, char * name) 1048733Sgeoffrey.blake@arm.com{ 1058733Sgeoffrey.blake@arm.com char sectionString[70]; 1068733Sgeoffrey.blake@arm.com genCenteredLabel(69, sectionString, name); 1078733Sgeoffrey.blake@arm.com ccprintf(os, "====================================================================\n"); 1088733Sgeoffrey.blake@arm.com ccprintf(os, "%69s\n", sectionString); 1098733Sgeoffrey.blake@arm.com ccprintf(os, "====================================================================\n"); 1108733Sgeoffrey.blake@arm.com} 1118733Sgeoffrey.blake@arm.com 1128733Sgeoffrey.blake@arm.cominline void printLevelHeader(ostream & os, int level) 1138733Sgeoffrey.blake@arm.com{ 1148733Sgeoffrey.blake@arm.com char sectionString[70]; 1152SN/A char levelName[70]; 116334SN/A sprintf(levelName, "Trap stack level %d", level); 1178834Satgutier@umich.edu genCenteredLabel(69, sectionString, levelName); 1188834Satgutier@umich.edu ccprintf(os, "====================================================================\n"); 119140SN/A ccprintf(os, "%69s\n", sectionString); 120334SN/A ccprintf(os, "====================================================================\n"); 1212SN/A} 1222SN/A 1232SN/A#endif 1242680Sktlim@umich.edu 1254377Sgblack@eecs.umich.eduvoid 1265169Ssaidi@eecs.umich.eduTrace::InstRecord::dump(ostream &outs) 1274377Sgblack@eecs.umich.edu{ 1284377Sgblack@eecs.umich.edu DPRINTF(Sparc, "Instruction: %#X\n", staticInst->machInst); 1292SN/A if (flags[PRINT_REG_DELTA]) 1302SN/A { 1312623SN/A#if THE_ISA == SPARC_ISA 1322SN/A //Don't print what happens for each micro-op, just print out 1332SN/A //once at the last op, and for regular instructions. 1342SN/A if(!staticInst->isMicroOp() || staticInst->isLastMicroOp()) 135180SN/A { 1368737Skoansin.tan@gmail.com static uint64_t regs[32] = { 137393SN/A 0, 0, 0, 0, 0, 0, 0, 0, 138393SN/A 0, 0, 0, 0, 0, 0, 0, 0, 139393SN/A 0, 0, 0, 0, 0, 0, 0, 0, 140393SN/A 0, 0, 0, 0, 0, 0, 0, 0}; 141384SN/A static uint64_t ccr = 0; 142384SN/A static uint64_t y = 0; 143393SN/A static uint64_t floats[32]; 1448737Skoansin.tan@gmail.com uint64_t newVal; 145393SN/A static const char * prefixes[4] = {"G", "O", "L", "I"}; 146393SN/A 147393SN/A outs << hex; 148393SN/A outs << "PC = " << thread->readNextPC(); 149384SN/A outs << " NPC = " << thread->readNextNPC(); 150189SN/A newVal = thread->readIntReg(SparcISA::NumIntArchRegs + 2); 151189SN/A //newVal = thread->readMiscReg(SparcISA::MISCREG_CCR); 1522623SN/A if(newVal != ccr) 1532SN/A { 154729SN/A outs << " CCR = " << newVal; 155334SN/A ccr = newVal; 1562SN/A } 1572SN/A newVal = thread->readIntReg(SparcISA::NumIntArchRegs + 1); 1582SN/A //newVal = thread->readMiscReg(SparcISA::MISCREG_Y); 1598834Satgutier@umich.edu if(newVal != y) 1608834Satgutier@umich.edu { 1618834Satgutier@umich.edu outs << " Y = " << newVal; 1628834Satgutier@umich.edu y = newVal; 1638834Satgutier@umich.edu } 1648834Satgutier@umich.edu for(int y = 0; y < 4; y++) 1658834Satgutier@umich.edu { 1662SN/A for(int x = 0; x < 8; x++) 1672SN/A { 1687897Shestness@cs.utexas.edu int index = x + 8 * y; 1697897Shestness@cs.utexas.edu newVal = thread->readIntReg(index); 1707897Shestness@cs.utexas.edu if(regs[index] != newVal) 1717897Shestness@cs.utexas.edu { 1727897Shestness@cs.utexas.edu outs << " " << prefixes[y] << dec << x << " = " << hex << newVal; 1737897Shestness@cs.utexas.edu regs[index] = newVal; 1747897Shestness@cs.utexas.edu } 1757897Shestness@cs.utexas.edu } 1767897Shestness@cs.utexas.edu } 1777897Shestness@cs.utexas.edu for(int y = 0; y < 32; y++) 1787897Shestness@cs.utexas.edu { 1797897Shestness@cs.utexas.edu newVal = thread->readFloatRegBits(2 * y, 64); 1807897Shestness@cs.utexas.edu if(floats[y] != newVal) 1817897Shestness@cs.utexas.edu { 1827897Shestness@cs.utexas.edu outs << " F" << dec << (2 * y) << " = " << hex << newVal; 1837897Shestness@cs.utexas.edu floats[y] = newVal; 1847897Shestness@cs.utexas.edu } 1857897Shestness@cs.utexas.edu } 1867897Shestness@cs.utexas.edu outs << dec << endl; 1877897Shestness@cs.utexas.edu } 1887897Shestness@cs.utexas.edu#endif 1897897Shestness@cs.utexas.edu } 1907897Shestness@cs.utexas.edu else if (flags[INTEL_FORMAT]) { 1917897Shestness@cs.utexas.edu#if FULL_SYSTEM 1927897Shestness@cs.utexas.edu bool is_trace_system = (thread->getCpuPtr()->system->name() == trace_system); 1937897Shestness@cs.utexas.edu#else 1947897Shestness@cs.utexas.edu bool is_trace_system = true; 1957897Shestness@cs.utexas.edu#endif 1967897Shestness@cs.utexas.edu if (is_trace_system) { 1977897Shestness@cs.utexas.edu ccprintf(outs, "%7d ) ", cycle); 1987897Shestness@cs.utexas.edu outs << "0x" << hex << PC << ":\t"; 1997897Shestness@cs.utexas.edu if (staticInst->isLoad()) { 2007897Shestness@cs.utexas.edu outs << "<RD 0x" << hex << addr; 2017897Shestness@cs.utexas.edu outs << ">"; 2027897Shestness@cs.utexas.edu } else if (staticInst->isStore()) { 2037897Shestness@cs.utexas.edu outs << "<WR 0x" << hex << addr; 2047897Shestness@cs.utexas.edu outs << ">"; 2057897Shestness@cs.utexas.edu } 2067897Shestness@cs.utexas.edu outs << endl; 2077897Shestness@cs.utexas.edu } 2087897Shestness@cs.utexas.edu } else { 2097897Shestness@cs.utexas.edu if (flags[PRINT_CYCLE]) 2107897Shestness@cs.utexas.edu ccprintf(outs, "%7d: ", cycle); 2117897Shestness@cs.utexas.edu 2127897Shestness@cs.utexas.edu outs << thread->getCpuPtr()->name() << " "; 2137897Shestness@cs.utexas.edu 2147897Shestness@cs.utexas.edu if (flags[TRACE_MISSPEC]) 2157897Shestness@cs.utexas.edu outs << (misspeculating ? "-" : "+") << " "; 2167897Shestness@cs.utexas.edu 2177897Shestness@cs.utexas.edu if (flags[PRINT_THREAD_NUM]) 2189920Syasuko.eckert@amd.com outs << "T" << thread->getThreadNum() << " : "; 2199920Syasuko.eckert@amd.com 2209920Syasuko.eckert@amd.com 2219920Syasuko.eckert@amd.com std::string sym_str; 2229920Syasuko.eckert@amd.com Addr sym_addr; 2239920Syasuko.eckert@amd.com if (debugSymbolTable 2249920Syasuko.eckert@amd.com && debugSymbolTable->findNearestSymbol(PC, sym_str, sym_addr) 2259920Syasuko.eckert@amd.com && flags[PC_SYMBOL]) { 2269920Syasuko.eckert@amd.com if (PC != sym_addr) 2279920Syasuko.eckert@amd.com sym_str += csprintf("+%d", PC - sym_addr); 2289920Syasuko.eckert@amd.com outs << "@" << sym_str << " : "; 2299920Syasuko.eckert@amd.com } 2302SN/A else { 2317897Shestness@cs.utexas.edu outs << "0x" << hex << PC << " : "; 2327897Shestness@cs.utexas.edu } 2337897Shestness@cs.utexas.edu 2347897Shestness@cs.utexas.edu // 2357897Shestness@cs.utexas.edu // Print decoded instruction 2367897Shestness@cs.utexas.edu // 2377897Shestness@cs.utexas.edu 2387897Shestness@cs.utexas.edu#if defined(__GNUC__) && (__GNUC__ < 3) 2397897Shestness@cs.utexas.edu // There's a bug in gcc 2.x library that prevents setw() 2407897Shestness@cs.utexas.edu // from working properly on strings 2417897Shestness@cs.utexas.edu string mc(staticInst->disassemble(PC, debugSymbolTable)); 2427897Shestness@cs.utexas.edu while (mc.length() < 26) 2432SN/A mc += " "; 2442SN/A outs << mc; 2451001SN/A#else 2461001SN/A outs << setw(26) << left << staticInst->disassemble(PC, debugSymbolTable); 2471001SN/A#endif 2481001SN/A 2491001SN/A outs << " : "; 2502SN/A 2512SN/A if (flags[PRINT_OP_CLASS]) { 2522SN/A outs << opClassStrings[staticInst->opClass()] << " : "; 2532SN/A } 2542SN/A 2557897Shestness@cs.utexas.edu if (flags[PRINT_RESULT_DATA] && data_status != DataInvalid) { 2567897Shestness@cs.utexas.edu outs << " D="; 2577897Shestness@cs.utexas.edu#if 0 2587897Shestness@cs.utexas.edu if (data_status == DataDouble) 2597897Shestness@cs.utexas.edu ccprintf(outs, "%f", data.as_double); 2607897Shestness@cs.utexas.edu else 2617897Shestness@cs.utexas.edu ccprintf(outs, "%#018x", data.as_int); 2627897Shestness@cs.utexas.edu#else 2637897Shestness@cs.utexas.edu ccprintf(outs, "%#018x", data.as_int); 2647897Shestness@cs.utexas.edu#endif 2652SN/A } 2662SN/A 2672SN/A if (flags[PRINT_EFF_ADDR] && addr_valid) 2682SN/A outs << " A=0x" << hex << addr; 2692SN/A 2702SN/A if (flags[PRINT_INT_REGS] && regs_valid) { 2712SN/A for (int i = 0; i < TheISA::NumIntRegs;) 2722SN/A for (int j = i + 1; i <= j; i++) 2732SN/A ccprintf(outs, "r%02d = %#018x%s", i, 2742SN/A iregs->regs.readReg(i), 2752SN/A ((i == j) ? "\n" : " ")); 2762SN/A outs << "\n"; 2772390SN/A } 2782390SN/A 2792390SN/A if (flags[PRINT_FETCH_SEQ] && fetch_seq_valid) 2802390SN/A outs << " FetchSeq=" << dec << fetch_seq; 2812390SN/A 2822390SN/A if (flags[PRINT_CP_SEQ] && cp_seq_valid) 2832390SN/A outs << " CPSeq=" << dec << cp_seq; 2842390SN/A 2852390SN/A // 2862390SN/A // End of line... 2872390SN/A // 2882390SN/A outs << endl; 28910193SCurtis.Dunham@arm.com } 29010193SCurtis.Dunham@arm.com#if THE_ISA == SPARC_ISA && FULL_SYSTEM 29110193SCurtis.Dunham@arm.com // Compare 29210193SCurtis.Dunham@arm.com if (flags[LEGION_LOCKSTEP]) 29310193SCurtis.Dunham@arm.com { 29410193SCurtis.Dunham@arm.com bool compared = false; 29510193SCurtis.Dunham@arm.com bool diffPC = false; 29610193SCurtis.Dunham@arm.com bool diffCC = false; 29710193SCurtis.Dunham@arm.com bool diffInst = false; 29810193SCurtis.Dunham@arm.com bool diffIntRegs = false; 299385SN/A bool diffFpRegs = false; 3007897Shestness@cs.utexas.edu bool diffTpc = false; 3017897Shestness@cs.utexas.edu bool diffTnpc = false; 30210061Sandreas@sandberg.pp.se bool diffTstate = false; 30310061Sandreas@sandberg.pp.se bool diffTt = false; 30410061Sandreas@sandberg.pp.se bool diffTba = false; 30510061Sandreas@sandberg.pp.se bool diffHpstate = false; 30610061Sandreas@sandberg.pp.se bool diffHtstate = false; 30710061Sandreas@sandberg.pp.se bool diffHtba = false; 30810061Sandreas@sandberg.pp.se bool diffPstate = false; 30910061Sandreas@sandberg.pp.se bool diffY = false; 31010061Sandreas@sandberg.pp.se bool diffCcr = false; 31110061Sandreas@sandberg.pp.se bool diffTl = false; 31210061Sandreas@sandberg.pp.se bool diffGl = false; 31310061Sandreas@sandberg.pp.se bool diffAsi = false; 31410061Sandreas@sandberg.pp.se bool diffPil = false; 31510061Sandreas@sandberg.pp.se bool diffCwp = false; 31610061Sandreas@sandberg.pp.se bool diffCansave = false; 3172SN/A bool diffCanrestore = false; 3182SN/A bool diffOtherwin = false; 3192SN/A bool diffCleanwin = false; 3202623SN/A bool diffTlb = false; 321334SN/A Addr m5Pc, lgnPc; 3222361SN/A 3235496Ssaidi@eecs.umich.edu // We took a trap on a micro-op... 324334SN/A if (wasMicro && !staticInst->isMicroOp()) 325334SN/A { 326334SN/A // let's skip comparing this cycle 3279448SAndreas.Sandberg@ARM.com while (!compared) 3282SN/A if (shared_data->flags == OWN_M5) { 3299448SAndreas.Sandberg@ARM.com shared_data->flags = OWN_LEGION; 3309448SAndreas.Sandberg@ARM.com compared = true; 3319448SAndreas.Sandberg@ARM.com } 3322683Sktlim@umich.edu compared = false; 3332SN/A wasMicro = false; 3342SN/A } 3352SN/A 3369448SAndreas.Sandberg@ARM.com if (staticInst->isLastMicroOp()) 3379448SAndreas.Sandberg@ARM.com wasMicro = false; 3382SN/A else if (staticInst->isMicroOp()) 3399448SAndreas.Sandberg@ARM.com wasMicro = true; 3409448SAndreas.Sandberg@ARM.com 3419448SAndreas.Sandberg@ARM.com 3422SN/A if(!staticInst->isMicroOp() || staticInst->isLastMicroOp()) { 3432SN/A while (!compared) { 3442SN/A if (shared_data->flags == OWN_M5) { 3456221Snate@binkert.org m5Pc = PC & TheISA::PAddrImplMask; 3462SN/A if (bits(shared_data->pstate,3,3)) { 3472SN/A m5Pc &= mask(32); 3482SN/A } 3492SN/A lgnPc = shared_data->pc & TheISA::PAddrImplMask; 3502623SN/A if (lgnPc != m5Pc) 3512SN/A diffPC = true; 3522680Sktlim@umich.edu 3532SN/A if (shared_data->cycle_count != 3542SN/A thread->getCpuPtr()->instCount()) 3552SN/A diffCC = true; 3565807Snate@binkert.org 3572SN/A if (shared_data->instruction != 3585807Snate@binkert.org (SparcISA::MachInst)staticInst->machInst) { 3595807Snate@binkert.org diffInst = true; 3602SN/A } 3615807Snate@binkert.org for (int i = 0; i < TheISA::NumIntArchRegs; i++) { 3625807Snate@binkert.org if (thread->readIntReg(i) != shared_data->intregs[i]) { 3632SN/A diffIntRegs = true; 3642SN/A } 3652SN/A } 3662623SN/A for (int i = 0; i < TheISA::NumFloatRegs/2; i++) { 3672SN/A if (thread->readFloatRegBits(i,FloatRegFile::DoubleWidth) != shared_data->fpregs[i]) { 3685704Snate@binkert.org diffFpRegs = true; 3695647Sgblack@eecs.umich.edu } 3702SN/A } 3713520Sgblack@eecs.umich.edu uint64_t oldTl = thread->readMiscReg(MISCREG_TL); 3727338SAli.Saidi@ARM.com if (oldTl != shared_data->tl) 3735647Sgblack@eecs.umich.edu diffTl = true; 3743520Sgblack@eecs.umich.edu for (int i = 1; i <= MaxTL; i++) { 3759023Sgblack@eecs.umich.edu thread->setMiscReg(MISCREG_TL, i); 3762SN/A if (thread->readMiscReg(MISCREG_TPC) != 3772SN/A shared_data->tpc[i-1]) 3782623SN/A diffTpc = true; 3792SN/A if (thread->readMiscReg(MISCREG_TNPC) != 3802623SN/A shared_data->tnpc[i-1]) 3815894Sgblack@eecs.umich.edu diffTnpc = true; 3822662Sstever@eecs.umich.edu if (thread->readMiscReg(MISCREG_TSTATE) != 3832623SN/A shared_data->tstate[i-1]) 3847720Sgblack@eecs.umich.edu diffTstate = true; 3854495Sacolyte@umich.edu if (thread->readMiscReg(MISCREG_TT) != 3862623SN/A shared_data->tt[i-1]) 3877720Sgblack@eecs.umich.edu diffTt = true; 3882623SN/A if (thread->readMiscReg(MISCREG_HTSTATE) != 3897720Sgblack@eecs.umich.edu shared_data->htstate[i-1]) 3908832SAli.Saidi@ARM.com diffHtstate = true; 3918832SAli.Saidi@ARM.com } 3922623SN/A thread->setMiscReg(MISCREG_TL, oldTl); 3932623SN/A 3942623SN/A if(shared_data->tba != thread->readMiscReg(MISCREG_TBA)) 3952623SN/A diffTba = true; 3962623SN/A //When the hpstate register is read by an instruction, 3972623SN/A //legion has bit 11 set. When it's in storage, it doesn't. 3982SN/A //Since we don't directly support seperate interpretations 3992683Sktlim@umich.edu //of the registers like that, the bit is always set to 1 and 4002427SN/A //we just don't compare it. It's not supposed to matter 4012683Sktlim@umich.edu //anyway. 4022427SN/A if((shared_data->hpstate | (1 << 11)) != thread->readMiscReg(MISCREG_HPSTATE)) 4032SN/A diffHpstate = true; 4042623SN/A if(shared_data->htba != thread->readMiscReg(MISCREG_HTBA)) 4052623SN/A diffHtba = true; 4067897Shestness@cs.utexas.edu if(shared_data->pstate != thread->readMiscReg(MISCREG_PSTATE)) 4072SN/A diffPstate = true; 4082623SN/A //if(shared_data->y != thread->readMiscReg(MISCREG_Y)) 4092623SN/A if(shared_data->y != 4104377Sgblack@eecs.umich.edu thread->readIntReg(NumIntArchRegs + 1)) 4117720Sgblack@eecs.umich.edu diffY = true; 4124377Sgblack@eecs.umich.edu //if(shared_data->ccr != thread->readMiscReg(MISCREG_CCR)) 4137720Sgblack@eecs.umich.edu if(shared_data->ccr != 4145665Sgblack@eecs.umich.edu thread->readIntReg(NumIntArchRegs + 2)) 4157720Sgblack@eecs.umich.edu diffCcr = true; 4167720Sgblack@eecs.umich.edu if(shared_data->gl != thread->readMiscReg(MISCREG_GL)) 4175665Sgblack@eecs.umich.edu diffGl = true; 4185665Sgblack@eecs.umich.edu if(shared_data->asi != thread->readMiscReg(MISCREG_ASI)) 4194181Sgblack@eecs.umich.edu diffAsi = true; 4204181Sgblack@eecs.umich.edu if(shared_data->pil != thread->readMiscReg(MISCREG_PIL)) 4219023Sgblack@eecs.umich.edu diffPil = true; 4229023Sgblack@eecs.umich.edu if(shared_data->cwp != thread->readMiscReg(MISCREG_CWP)) 4234181Sgblack@eecs.umich.edu diffCwp = true; 4244182Sgblack@eecs.umich.edu //if(shared_data->cansave != thread->readMiscReg(MISCREG_CANSAVE)) 4257720Sgblack@eecs.umich.edu if(shared_data->cansave != 4269023Sgblack@eecs.umich.edu thread->readIntReg(NumIntArchRegs + 3)) 4279023Sgblack@eecs.umich.edu diffCansave = true; 4284593Sgblack@eecs.umich.edu //if(shared_data->canrestore != 4299023Sgblack@eecs.umich.edu // thread->readMiscReg(MISCREG_CANRESTORE)) 4304377Sgblack@eecs.umich.edu if(shared_data->canrestore != 4319023Sgblack@eecs.umich.edu thread->readMiscReg(NumIntArchRegs + 4)) 4324377Sgblack@eecs.umich.edu diffCanrestore = true; 4339023Sgblack@eecs.umich.edu //if(shared_data->otherwin != thread->readMiscReg(MISCREG_OTHERWIN)) 4349023Sgblack@eecs.umich.edu if(shared_data->otherwin != 4354377Sgblack@eecs.umich.edu thread->readIntReg(NumIntArchRegs + 5)) 4367720Sgblack@eecs.umich.edu diffOtherwin = true; 4374377Sgblack@eecs.umich.edu //if(shared_data->cleanwin != thread->readMiscReg(MISCREG_CLEANWIN)) 4384377Sgblack@eecs.umich.edu if(shared_data->cleanwin != 4394377Sgblack@eecs.umich.edu thread->readMiscReg(NumIntArchRegs + 6)) 4404377Sgblack@eecs.umich.edu diffCleanwin = true; 4414181Sgblack@eecs.umich.edu 4424181Sgblack@eecs.umich.edu for (int i = 0; i < 64; i++) { 4434181Sgblack@eecs.umich.edu if (shared_data->itb[i] != thread->getITBPtr()->TteRead(i)) 4444539Sgblack@eecs.umich.edu diffTlb = true; 4453276Sgblack@eecs.umich.edu if (shared_data->dtb[i] != thread->getDTBPtr()->TteRead(i)) 4467720Sgblack@eecs.umich.edu diffTlb = true; 4473280Sgblack@eecs.umich.edu } 4483280Sgblack@eecs.umich.edu 4493276Sgblack@eecs.umich.edu if ((diffPC || diffCC || diffInst || diffIntRegs || 4503276Sgblack@eecs.umich.edu diffFpRegs || diffTpc || diffTnpc || diffTstate || 4513276Sgblack@eecs.umich.edu diffTt || diffHpstate || diffHtstate || diffHtba || 4527720Sgblack@eecs.umich.edu diffPstate || diffY || diffCcr || diffTl || diffGl || 4533276Sgblack@eecs.umich.edu diffAsi || diffPil || diffCwp || diffCansave || 4543276Sgblack@eecs.umich.edu diffCanrestore || diffOtherwin || diffCleanwin || diffTlb) 4554181Sgblack@eecs.umich.edu && !((staticInst->machInst & 0xC1F80000) == 0x81D00000) 4568955Sgblack@eecs.umich.edu && !(((staticInst->machInst & 0xC0000000) == 0xC0000000) 4574522Ssaidi@eecs.umich.edu && shared_data->tl == thread->readMiscReg(MISCREG_TL) + 1) 4587823Ssteve.reinhardt@amd.com ) { 4597720Sgblack@eecs.umich.edu 4602470SN/A outs << "Differences found between M5 and Legion:"; 4618955Sgblack@eecs.umich.edu if (diffPC) 4624181Sgblack@eecs.umich.edu outs << " [PC]"; 4634522Ssaidi@eecs.umich.edu if (diffCC) 4644181Sgblack@eecs.umich.edu outs << " [CC]"; 46510061Sandreas@sandberg.pp.se if (diffInst) 46610061Sandreas@sandberg.pp.se outs << " [Instruction]"; 46710061Sandreas@sandberg.pp.se if (diffIntRegs) 46810061Sandreas@sandberg.pp.se outs << " [IntRegs]"; 46910061Sandreas@sandberg.pp.se if (diffFpRegs) 47010061Sandreas@sandberg.pp.se outs << " [FpRegs]"; 47110061Sandreas@sandberg.pp.se if (diffTpc) 47210061Sandreas@sandberg.pp.se outs << " [Tpc]"; 47310061Sandreas@sandberg.pp.se if (diffTnpc) 47410061Sandreas@sandberg.pp.se outs << " [Tnpc]"; 47510061Sandreas@sandberg.pp.se if (diffTstate) 47610061Sandreas@sandberg.pp.se outs << " [Tstate]"; 47710061Sandreas@sandberg.pp.se if (diffTt) 4782623SN/A outs << " [Tt]"; 4792623SN/A if (diffHpstate) 4802623SN/A outs << " [Hpstate]"; 4812623SN/A if (diffHtstate) 4822623SN/A outs << " [Htstate]"; 4837720Sgblack@eecs.umich.edu if (diffHtba) 4847720Sgblack@eecs.umich.edu outs << " [Htba]"; 4857720Sgblack@eecs.umich.edu if (diffPstate) 4867720Sgblack@eecs.umich.edu outs << " [Pstate]"; 4878780Sgblack@eecs.umich.edu if (diffY) 4883577Sgblack@eecs.umich.edu outs << " [Y]"; 4897720Sgblack@eecs.umich.edu if (diffCcr) 4905086Sgblack@eecs.umich.edu outs << " [Ccr]"; 4912623SN/A if (diffTl) 4922683Sktlim@umich.edu outs << " [Tl]"; 4932623SN/A if (diffGl) 4942SN/A outs << " [Gl]"; 4952623SN/A if (diffAsi) 4962623SN/A outs << " [Asi]"; 4972SN/A if (diffPil) 4982SN/A outs << " [Pil]"; 4992623SN/A if (diffCwp) 5002623SN/A outs << " [Cwp]"; 5012623SN/A if (diffCansave) 5022623SN/A outs << " [Cansave]"; 5032SN/A if (diffCanrestore) 5045953Ssaidi@eecs.umich.edu outs << " [Canrestore]"; 5057720Sgblack@eecs.umich.edu if (diffOtherwin) 5065953Ssaidi@eecs.umich.edu outs << " [Otherwin]"; 5075953Ssaidi@eecs.umich.edu if (diffCleanwin) 50810061Sandreas@sandberg.pp.se outs << " [Cleanwin]"; 50910061Sandreas@sandberg.pp.se if (diffTlb) 51010061Sandreas@sandberg.pp.se outs << " [Tlb]"; 51110061Sandreas@sandberg.pp.se outs << endl << endl; 5127897Shestness@cs.utexas.edu 5137897Shestness@cs.utexas.edu outs << right << setfill(' ') << setw(15) 5147897Shestness@cs.utexas.edu << "M5 PC: " << "0x"<< setw(16) << setfill('0') 5157897Shestness@cs.utexas.edu << hex << m5Pc << endl; 5167897Shestness@cs.utexas.edu outs << setfill(' ') << setw(15) 5177897Shestness@cs.utexas.edu << "Legion PC: " << "0x"<< setw(16) << setfill('0') << hex 5187897Shestness@cs.utexas.edu << lgnPc << endl << endl; 5197897Shestness@cs.utexas.edu 5207897Shestness@cs.utexas.edu outs << right << setfill(' ') << setw(15) 5217897Shestness@cs.utexas.edu << "M5 CC: " << "0x"<< setw(16) << setfill('0') 5227897Shestness@cs.utexas.edu << hex << thread->getCpuPtr()->instCount() << endl; 5237897Shestness@cs.utexas.edu outs << setfill(' ') << setw(15) 5247897Shestness@cs.utexas.edu << "Legion CC: " << "0x"<< setw(16) << setfill('0') << hex 5257897Shestness@cs.utexas.edu << shared_data->cycle_count << endl << endl; 5267897Shestness@cs.utexas.edu 5277897Shestness@cs.utexas.edu outs << setfill(' ') << setw(15) 5287897Shestness@cs.utexas.edu << "M5 Inst: " << "0x"<< setw(8) 5297897Shestness@cs.utexas.edu << setfill('0') << hex << staticInst->machInst 5307897Shestness@cs.utexas.edu << staticInst->disassemble(m5Pc, debugSymbolTable) 5317897Shestness@cs.utexas.edu << endl; 5327897Shestness@cs.utexas.edu 5337897Shestness@cs.utexas.edu StaticInstPtr legionInst = 5347897Shestness@cs.utexas.edu StaticInst::decode(makeExtMI(shared_data->instruction, 5357897Shestness@cs.utexas.edu thread)); 5367897Shestness@cs.utexas.edu outs << setfill(' ') << setw(15) 5377897Shestness@cs.utexas.edu << " Legion Inst: " 5387897Shestness@cs.utexas.edu << "0x" << setw(8) << setfill('0') << hex 5397897Shestness@cs.utexas.edu << shared_data->instruction 5407897Shestness@cs.utexas.edu << legionInst->disassemble(lgnPc, debugSymbolTable) 5417897Shestness@cs.utexas.edu << endl << endl; 5427897Shestness@cs.utexas.edu 5437897Shestness@cs.utexas.edu printSectionHeader(outs, "General State"); 5447897Shestness@cs.utexas.edu printColumnLabels(outs); 54510193SCurtis.Dunham@arm.com printRegPair(outs, "HPstate", 54610193SCurtis.Dunham@arm.com thread->readMiscReg(MISCREG_HPSTATE), 5478780Sgblack@eecs.umich.edu shared_data->hpstate | (1 << 11)); 5488780Sgblack@eecs.umich.edu printRegPair(outs, "Htba", 5492644Sstever@eecs.umich.edu thread->readMiscReg(MISCREG_HTBA), 5502644Sstever@eecs.umich.edu shared_data->htba); 5514046Sbinkertn@umich.edu printRegPair(outs, "Pstate", 5524046Sbinkertn@umich.edu thread->readMiscReg(MISCREG_PSTATE), 5534046Sbinkertn@umich.edu shared_data->pstate); 5542644Sstever@eecs.umich.edu printRegPair(outs, "Y", 5552623SN/A //thread->readMiscReg(MISCREG_Y), 5562SN/A thread->readMiscReg(NumIntArchRegs + 1), 5572623SN/A shared_data->y); 5582623SN/A printRegPair(outs, "Ccr", 5592623SN/A //thread->readMiscReg(MISCREG_CCR), 56010061Sandreas@sandberg.pp.se thread->readMiscReg(NumIntArchRegs + 2), 56110061Sandreas@sandberg.pp.se shared_data->ccr); 5624377Sgblack@eecs.umich.edu printRegPair(outs, "Tl", 5634377Sgblack@eecs.umich.edu thread->readMiscReg(MISCREG_TL), 5642090SN/A shared_data->tl); 5653905Ssaidi@eecs.umich.edu printRegPair(outs, "Gl", 5667678Sgblack@eecs.umich.edu thread->readMiscReg(MISCREG_GL), 5679023Sgblack@eecs.umich.edu shared_data->gl); 5684377Sgblack@eecs.umich.edu printRegPair(outs, "Asi", 5697720Sgblack@eecs.umich.edu thread->readMiscReg(MISCREG_ASI), 5707720Sgblack@eecs.umich.edu shared_data->asi); 5717720Sgblack@eecs.umich.edu printRegPair(outs, "Pil", 5727720Sgblack@eecs.umich.edu thread->readMiscReg(MISCREG_PIL), 5737720Sgblack@eecs.umich.edu shared_data->pil); 5747720Sgblack@eecs.umich.edu printRegPair(outs, "Cwp", 5753276Sgblack@eecs.umich.edu thread->readMiscReg(MISCREG_CWP), 5762SN/A shared_data->cwp); 57710061Sandreas@sandberg.pp.se printRegPair(outs, "Cansave", 57810061Sandreas@sandberg.pp.se //thread->readMiscReg(MISCREG_CANSAVE), 57910061Sandreas@sandberg.pp.se thread->readIntReg(NumIntArchRegs + 3), 58010061Sandreas@sandberg.pp.se shared_data->cansave); 58110061Sandreas@sandberg.pp.se printRegPair(outs, "Canrestore", 58210061Sandreas@sandberg.pp.se //thread->readMiscReg(MISCREG_CANRESTORE), 58310061Sandreas@sandberg.pp.se thread->readIntReg(NumIntArchRegs + 4), 58410061Sandreas@sandberg.pp.se shared_data->canrestore); 58510061Sandreas@sandberg.pp.se printRegPair(outs, "Otherwin", 58610061Sandreas@sandberg.pp.se //thread->readMiscReg(MISCREG_OTHERWIN), 58710061Sandreas@sandberg.pp.se thread->readIntReg(NumIntArchRegs + 5), 58810061Sandreas@sandberg.pp.se shared_data->otherwin); 58910061Sandreas@sandberg.pp.se printRegPair(outs, "Cleanwin", 59010061Sandreas@sandberg.pp.se //thread->readMiscReg(MISCREG_CLEANWIN), 59110061Sandreas@sandberg.pp.se thread->readIntReg(NumIntArchRegs + 6), 59210061Sandreas@sandberg.pp.se shared_data->cleanwin); 59310061Sandreas@sandberg.pp.se outs << endl; 5942SN/A for (int i = 1; i <= MaxTL; i++) { 5952SN/A printLevelHeader(outs, i); 5969461Snilay@cs.wisc.edu printColumnLabels(outs); 5979461Snilay@cs.wisc.edu thread->setMiscReg(MISCREG_TL, i); 5989461Snilay@cs.wisc.edu printRegPair(outs, "Tpc", 5999461Snilay@cs.wisc.edu thread->readMiscReg(MISCREG_TPC), 6009461Snilay@cs.wisc.edu shared_data->tpc[i-1]); 6019461Snilay@cs.wisc.edu printRegPair(outs, "Tnpc", 602 thread->readMiscReg(MISCREG_TNPC), 603 shared_data->tnpc[i-1]); 604 printRegPair(outs, "Tstate", 605 thread->readMiscReg(MISCREG_TSTATE), 606 shared_data->tstate[i-1]); 607 printRegPair(outs, "Tt", 608 thread->readMiscReg(MISCREG_TT), 609 shared_data->tt[i-1]); 610 printRegPair(outs, "Htstate", 611 thread->readMiscReg(MISCREG_HTSTATE), 612 shared_data->htstate[i-1]); 613 } 614 thread->setMiscReg(MISCREG_TL, oldTl); 615 outs << endl; 616 617 printSectionHeader(outs, "General Purpose Registers"); 618 static const char * regtypes[4] = {"%g", "%o", "%l", "%i"}; 619 for(int y = 0; y < 4; y++) { 620 for(int x = 0; x < 8; x++) { 621 char label[8]; 622 sprintf(label, "%s%d", regtypes[y], x); 623 printRegPair(outs, label, 624 thread->readIntReg(y*8+x), 625 shared_data->intregs[y*8+x]); 626 } 627 } 628 if (diffFpRegs) { 629 for (int x = 0; x < 32; x++) { 630 char label[8]; 631 sprintf(label, "%%f%d", x); 632 printRegPair(outs, label, 633 thread->readFloatRegBits(x,FloatRegFile::DoubleWidth), 634 shared_data->fpregs[x]); 635 } 636 } 637 if (diffTlb) { 638 printColumnLabels(outs); 639 char label[8]; 640 for (int x = 0; x < 64; x++) { 641 if (shared_data->itb[x] != ULL(0xFFFFFFFFFFFFFFFF) || 642 thread->getITBPtr()->TteRead(x) != ULL(0xFFFFFFFFFFFFFFFF)) { 643 sprintf(label, "I-TLB:%02d", x); 644 printRegPair(outs, label, thread->getITBPtr()->TteRead(x), 645 shared_data->itb[x]); 646 } 647 } 648 for (int x = 0; x < 64; x++) { 649 if (shared_data->dtb[x] != ULL(0xFFFFFFFFFFFFFFFF) || 650 thread->getDTBPtr()->TteRead(x) != ULL(0xFFFFFFFFFFFFFFFF)) { 651 sprintf(label, "D-TLB:%02d", x); 652 printRegPair(outs, label, thread->getDTBPtr()->TteRead(x), 653 shared_data->dtb[x]); 654 } 655 } 656 thread->getITBPtr()->dumpAll(); 657 thread->getDTBPtr()->dumpAll(); 658 } 659 660 diffcount++; 661 if (diffcount > 2) 662 fatal("Differences found between Legion and M5\n"); 663 } else 664 diffcount = 0; 665 666 compared = true; 667 shared_data->flags = OWN_LEGION; 668 } 669 } // while 670 } // if not microop 671 } 672#endif 673} 674 675 676vector<bool> Trace::InstRecord::flags(NUM_BITS); 677string Trace::InstRecord::trace_system; 678 679//////////////////////////////////////////////////////////////////////// 680// 681// Parameter space for per-cycle execution address tracing options. 682// Derive from ParamContext so we can override checkParams() function. 683// 684class ExecutionTraceParamContext : public ParamContext 685{ 686 public: 687 ExecutionTraceParamContext(const string &_iniSection) 688 : ParamContext(_iniSection) 689 { 690 } 691 692 void checkParams(); // defined at bottom of file 693}; 694 695ExecutionTraceParamContext exeTraceParams("exetrace"); 696 697Param<bool> exe_trace_spec(&exeTraceParams, "speculative", 698 "capture speculative instructions", true); 699 700Param<bool> exe_trace_print_cycle(&exeTraceParams, "print_cycle", 701 "print cycle number", true); 702Param<bool> exe_trace_print_opclass(&exeTraceParams, "print_opclass", 703 "print op class", true); 704Param<bool> exe_trace_print_thread(&exeTraceParams, "print_thread", 705 "print thread number", true); 706Param<bool> exe_trace_print_effaddr(&exeTraceParams, "print_effaddr", 707 "print effective address", true); 708Param<bool> exe_trace_print_data(&exeTraceParams, "print_data", 709 "print result data", true); 710Param<bool> exe_trace_print_iregs(&exeTraceParams, "print_iregs", 711 "print all integer regs", false); 712Param<bool> exe_trace_print_fetchseq(&exeTraceParams, "print_fetchseq", 713 "print fetch sequence number", false); 714Param<bool> exe_trace_print_cp_seq(&exeTraceParams, "print_cpseq", 715 "print correct-path sequence number", false); 716Param<bool> exe_trace_print_reg_delta(&exeTraceParams, "print_reg_delta", 717 "print which registers changed to what", false); 718Param<bool> exe_trace_pc_symbol(&exeTraceParams, "pc_symbol", 719 "Use symbols for the PC if available", true); 720Param<bool> exe_trace_intel_format(&exeTraceParams, "intel_format", 721 "print trace in intel compatible format", false); 722Param<bool> exe_trace_legion_lockstep(&exeTraceParams, "legion_lockstep", 723 "Compare sim state to legion state every cycle", 724 false); 725Param<string> exe_trace_system(&exeTraceParams, "trace_system", 726 "print trace of which system (client or server)", 727 "client"); 728 729 730// 731// Helper function for ExecutionTraceParamContext::checkParams() just 732// to get us into the InstRecord namespace 733// 734void 735Trace::InstRecord::setParams() 736{ 737 flags[TRACE_MISSPEC] = exe_trace_spec; 738 739 flags[PRINT_CYCLE] = exe_trace_print_cycle; 740 flags[PRINT_OP_CLASS] = exe_trace_print_opclass; 741 flags[PRINT_THREAD_NUM] = exe_trace_print_thread; 742 flags[PRINT_RESULT_DATA] = exe_trace_print_effaddr; 743 flags[PRINT_EFF_ADDR] = exe_trace_print_data; 744 flags[PRINT_INT_REGS] = exe_trace_print_iregs; 745 flags[PRINT_FETCH_SEQ] = exe_trace_print_fetchseq; 746 flags[PRINT_CP_SEQ] = exe_trace_print_cp_seq; 747 flags[PRINT_REG_DELTA] = exe_trace_print_reg_delta; 748 flags[PC_SYMBOL] = exe_trace_pc_symbol; 749 flags[INTEL_FORMAT] = exe_trace_intel_format; 750 flags[LEGION_LOCKSTEP] = exe_trace_legion_lockstep; 751 trace_system = exe_trace_system; 752 753 // If were going to be in lockstep with Legion 754 // Setup shared memory, and get otherwise ready 755 if (flags[LEGION_LOCKSTEP]) { 756 int shmfd = shmget('M' << 24 | getuid(), sizeof(SharedData), 0777); 757 if (shmfd < 0) 758 fatal("Couldn't get shared memory fd. Is Legion running?"); 759 760 shared_data = (SharedData*)shmat(shmfd, NULL, SHM_RND); 761 if (shared_data == (SharedData*)-1) 762 fatal("Couldn't allocate shared memory"); 763 764 if (shared_data->flags != OWN_M5) 765 fatal("Shared memory has invalid owner"); 766 767 if (shared_data->version != VERSION) 768 fatal("Shared Data is wrong version! M5: %d Legion: %d", VERSION, 769 shared_data->version); 770 771 // step legion forward one cycle so we can get register values 772 shared_data->flags = OWN_LEGION; 773 } 774} 775 776void 777ExecutionTraceParamContext::checkParams() 778{ 779 Trace::InstRecord::setParams(); 780} 781 782