/* * ========== Copyright Header Begin ========================================== * * OpenSPARC T2 Processor File: trconv.H * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES. * * The above named program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public * License version 2 as published by the Free Software Foundation. * * The above named program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * ========== Copyright Header End ============================================ */ // ========== Copyright Header Begin ========================================== // // OpenSPARC T2 Processor File: trconv.H // Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES. // // The above named program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public // License version 2 as published by the Free Software Foundation. // // The above named program is distributed in the hope that it will be // useful, but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // General Public License for more details. // // You should have received a copy of the GNU General Public // License along with this work; if not, write to the Free Software // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. // // ========== Copyright Header End ============================================ // File: trconv.H // // Description: Part of trconv library file, trconv.o, for printing and // converting execution traces // // How to add another RST record type to trconv: // // This file, trconv.H, is the main file supporting the class // definitions of each trace record type. It includes a global struct // "gbl" containing variables used throughout trconv, including the // counts of each record type. Also here is the base class "Trace" // containing the pure virtual functions you will need to define in // your new derived class. // // To create a new derived class, copy one of the existing classes, // and modify it accordingly. RSTF_Traceinfo is a simple example; // RSTF_Instr is a more elaborate example. // // All RST traces are first processed by RSTF_Union. In // RSTF_Union the rtype of each RST record is examined, and the // corresponding class member function is called. The protected member // function RSTF_Union::get_rst_type() determines to RST rtype and // returns a pointer to the corresponding RST class. // // Finally in init_globals(char *argv[]) in trconv.C, initialize // the new counter variable to 0. And in print_counts(FILE* outfp) in // trconv.C add an fprintf(stdout, ...) statement to print the count // of the new record type. // // Cross you fingers, recompile (ignore the warnings about "master is // defined but not used" and various member functions being "too large // and will not be expanded inline", they're normal), and run... #pragma ident "@(#) trconv.H 1.19: 11/06/07 11:35:08 @(#)" #include #include #include #include #include #include #include #define RSTF_NOADDR -1 #include "rstf/rstf.h" #include "rstf/rstf_deprecated.h" #if defined(ARCH_AMD64) #include "rstf/rstf_convert.h" #endif #include "MISC.h" #include "ITYPES.h" #define MAX_CPUID (1024) #define NUM_VERIFY (8) #define PSTATE_AM (0x8) extern char switch_error_string[]; enum { NONE = 0, RTF99, SHADE5, SHADE6x32, SHADE6x64, MASTER64, RST }; typedef struct { // format options int fromtype; // -from FX int totype; // -to FX // selection options uint64_t maxRecs; // -n N uint64_t maxInstrs; // -n Ni uint64_t skipRecs; // -s N uint64_t skipInstrs; // -s Ni uint64_t frompc; // -pc=pc1[,pc2] // -frompc ? uint64_t topc; // // -topc ? uint64_t fromea; // -ea=ea1[,ea2] // -fromea ? uint64_t toea; // // -toea ? char cpu[MAX_CPUID + 1]; // -cpu= uint16_t pstate[MAX_CPUID + 1]; // monitor pstate.am per cpu // printing options bool record; // -a bool disassembly; // -d bool verbose; // -x bool showIdx; // -nid bool countOnly; // -c #ifdef _PRINT_PA bool printPA; // -pa #endif // _PRINT_PA #ifdef _VALUE_TRACE bool valueTrace; // -vt #endif // _VALUE_TRACE FILE* msgfp; // -msg ? bool show_syms; symbol_table_t symbol_table; // verification options bool verify; // -nv bool checkError; // -e bool fast; // -fast // rst options bool onlyIns; // -i bool reorderIns; // -ic bool noIns; // -ni bool reorderNoIns; // -nic bool branch; // -branch (-nobranch?) bool pc_pavadiff; // -pc_pavadiff (-nopc_pavadiff?) bool ea_pavadiff; // -ea_pavadiff (-noea_pavadiff?) // patching options bool clean; // -patchcleanrst bool genIHash; // -patchihash // output options FILE* infp; // [input-file] FILE* outfp; // -stdout || -o // convenient variables char* progname; char* infile; int fromsize; int tosize; bool checkIHash; uint64_t icount, rcount; // instr count & total record count. uint64_t skipInstrsRecs; // rst-related bool rstf_pre212; // rst types uint64_t headercount, // instrcount, ---> use icount //asicount, traceinfocount, // ASI_T == TRACEINFO_T, TRACEINFO_T is to replace ASI_T tlbcount, threadcount, pregcount, trapcount, trapexitcount, trappinginstrcount, cpucount, dmacount, snoopcount, tsb_access_count, rfs_section_header_count, bpwarming_count, cachewarming_count, delimcount, // combination of leftdelim & rightdelim physaddrcount, pavadiffcount, //nullrec??? // null record, can be ignored filemarkercount, //hwinfocount, recnumcount, stringcount, // combination of strdesc & strcont statuscount, patchcount, regvalcount, memval64count, memval128count, bustracecount, processcount, timesynccount, devidstrcount, zerocount, unknowncount; #ifdef _PRINT_PA bool ea_pavadiff_valid[MAX_INSTR_CPUID]; uint64_t ea_pavadiff_value[MAX_INSTR_CPUID]; bool pc_pavadiff_valid[MAX_INSTR_CPUID]; uint64_t pc_pavadiff_value[MAX_INSTR_CPUID]; #endif // _PRINT_PA std::map devid2string; } Globals_T; extern Globals_T gbl; extern char usage_string[]; void usage(char progName[]); void parse_args(int argc, char *argv[], bool debug = false); void init_globals(char *argv[]); int format2int(const char str[]); int format2size(int format); bool streqprefix(const char* a, const char* b); bool streq(const char* a, const char* b); void get_pc_range(char* pc_str); void get_range(char* str, uint64_t *from, uint64_t* to); void get_cpu_range(char* pc_str); bool in_range(const uint64_t x, const uint64_t a, const uint64_t b); void print_counts(FILE* outfp); // base class for all trace structs class Trace { public: // increments global record and instruction counts virtual void count() { gbl.rcount++; gbl.icount++; } // prints record fields without disassembly of instruction records virtual void print_rec(uint64_t idx) = 0; // prints record disassenbly virtual void print_dasm(uint64_t idx) { print_rec(idx); } // Trace::print_dasm() // prints verbose record disassembly virtual void print_verb(uint64_t idx) { print_rec(idx); } // Trace::print_verb() // converts record type to Tmaster64 virtual void convert_to_master() { // not converted } // Trace::convert_to_master() // converts master to record type virtual void convert_from_master(Tmaster64* master) { Tmaster64* useless = master; // not converted } // Trace::convert_from_master() // sets ihash field to correct value for instruction records virtual void gen_ihash() { // not generated } // Trace::gen_ihash() // verifies ihash value of instruction records; // returns 1 on error, 0 otherwise virtual int check_ihash_error() { return 0; } // Trace::check_ihash_error() // verifies pc values of instruction records; prints message on error virtual void verify() { // not verified } // Trace::verify() // returns RSTF_NOADDR for non-instruction, non-trap types virtual uint64_t get_pc() { return RSTF_NOADDR; } // Trace::get_pc() // returns RSTF_NOADDR for non-instruction types virtual uint64_t get_ea() { return RSTF_NOADDR; } // Trace::get_ea() // returns ihash value in trace record virtual int get_ihash() { return 0; } // Trace::get_ihash() // increments trace pointer to next trace record in trace buffer virtual void inc_tr() = 0; // sets trace pointer to ptr; optionally sets tr_orig to ptr also virtual void set_tr(void* ptr, bool set_orig = true) = 0; // resets trace pointer to tr_orig virtual void reset_tr() = 0; // returns pointer to static protected data member this_master virtual Tmaster64* get_master() { return &this_master; } // Trace::get_master() // used for piping to and from rst trace types virtual rstf_unionT* copy_from_rst() { // do nothing (except for RSTF_Union::copy_from_rst() ) return NULL; } // used for piping to and from rst trace types virtual void copy_to_rst(rstf_unionT* from) { rstf_unionT* useless = from; // do nothing (except for RSTF_Union::copy_to_rst() ) } // used to verify branch targets in RSTF disassembly printouts int check_branch_ea(uint64_t dis_ea, uint64_t tr_ea) { if (dis_ea != tr_ea) { if ((dis_ea ^ tr_ea) != (0xffffffff00000000ull)) { fprintf(stderr, "trconv: warning: branch target != effective address " "(Rec #%llu: 0x%llx != 0x%llx)\n", gbl.rcount - 1, dis_ea, tr_ea); return 1; } } return 0; } virtual int getCpuID() { return -1; } protected: // static data member, shared by all derived classes static Tmaster64 this_master; }; // Trace //====================================================================== //====================================================================== class RSTF_Header : public Trace { public: virtual void count() { gbl.rcount++; gbl.headercount++; if (tr->majorVer*1000 + tr->minorVer <= 2011) { gbl.rstf_pre212 = true; } } virtual void print_rec(uint64_t idx) { if (gbl.showIdx) { fprintf(gbl.outfp , "%6lld ", idx); } fprintf(gbl.outfp, "header : majorVer=%d minorVer=%d %s", tr->majorVer, tr->minorVer, tr->header_str); fprintf(gbl.outfp, "\n"); } // RSTF_Header::print_rec() virtual void inc_tr() { tr++; } // RSTF_Header::inc_tr() virtual void set_tr(void* ptr, bool set_orig = true) { tr = (rstf_headerT*) ptr; if (set_orig) { tr_orig = tr; } } // RSTF_Header::set_tr() virtual void reset_tr() { tr = tr_orig; } // RSTF_Header::reset_tr() protected: rstf_headerT* tr; rstf_headerT* tr_orig; }; // RSTF_Header //====================================================================== //====================================================================== class RSTF_Instr : public Trace { public: virtual void count() { gbl.rcount++; gbl.icount++; if (gbl.clean == true) { if (!tr->ea_valid){ tr->ea_va = RSTF_NOADDR; } } } // RSTF_Instr::count() virtual void print_dasm(uint64_t idx) { char dis_string[80]; uint64_t ea_va = -1; int cpuid = getCpuID(); sprintDiss(dis_string, tr->instr, tr->pc_va); int ihash = spix_sparc_iop(SPIX_SPARC_V9, &tr->instr); // if (ih_isbranch(tr->ihash) || tr->ihash == SPIX_SPARC_IOP_CALL) { if (ih_isbranch(ihash) || ihash == SPIX_SPARC_IOP_CALL) { if (gbl.branch && tr->bt) { ea_va = getCtiEa(tr->instr, ihash, tr->pc_va); if (gbl.pstate[cpuid] & PSTATE_AM) { ea_va &= 0xffffffff; } if (!tr->an) { check_branch_ea(ea_va, tr->ea_va); } } } if (gbl.showIdx) { fprintf(gbl.outfp , "%6lld ", idx); } fprintf(gbl.outfp, "instr : cpuid=%d ", cpuid); if (tr->hpriv) { fprintf(gbl.outfp, "h "); } else if (tr->pr) { fprintf(gbl.outfp, "p "); } else { fprintf(gbl.outfp, "u "); } fprintf(gbl.outfp, "[0x%016llx] ", tr->pc_va); if (gbl.show_syms) { char *symbol; uint64_t offset; if (gbl.symbol_table.search_symbol_table(tr->pc_va, symbol, offset)) { fprintf(gbl.outfp, "(%s+0x%llx) ", symbol, offset); } else { fprintf(gbl.outfp, "(???+???) ", symbol, offset); } } fprintf(gbl.outfp, "%-32s", dis_string); if (ih_iscti(ihash)) { if (tr->bt) { fprintf(gbl.outfp, "T "); } else { fprintf(gbl.outfp, "N "); } } else { fprintf(gbl.outfp, " "); } #ifdef _PRINT_PA if (gbl.printPA) { if (!tr->an) { if (tr->ea_valid) { fprintf(gbl.outfp, "v[0x%016llx] ", tr->ea_va); if ((ih_isload(ihash) || ih_isstore(ihash)) && tr->tr == 0) { if (gbl.ea_pavadiff_valid[cpuid]) { fprintf(gbl.outfp, "p[0x%016llx] ", tr->ea_va + gbl.ea_pavadiff_value[cpuid]); } } else { if (gbl.pc_pavadiff_valid[cpuid]) { fprintf(gbl.outfp, "p[0x%016llx] ", tr->ea_va + gbl.pc_pavadiff_value[cpuid]); } } } else if (tr->bt) { // so it must be a branch...(?) fprintf(gbl.outfp, "<0x%016llx> ", tr->ea_va); } } } else #endif //_PRINT_PA { if (!tr->an) { if (tr->ea_valid) { fprintf(gbl.outfp, "[0x%016llx] ", tr->ea_va); } else if (tr->bt) { // so it must be a branch...(?) fprintf(gbl.outfp, "<0x%016llx> ", tr->ea_va); } } } if (tr->an) { fprintf(gbl.outfp, "an "); } if (tr->tr) { fprintf(gbl.outfp, "tr "); } fprintf(gbl.outfp, "\n"); } // RSTF_Instr::print_dasm() virtual void print_rec(uint64_t idx) { if (gbl.showIdx) { fprintf(gbl.outfp, "%6lld ", idx); } // int ihash = spix_sparc_iop(SPIX_SPARC_V9, &tr->instr); fprintf(gbl.outfp, "instr : cpuid=%d ", gbl.rstf_pre212? tr->cpuid: rstf_instrT_get_cpuid(tr)); fprintf(gbl.outfp, "pc=0x%016llx ", tr->pc_va); fprintf(gbl.outfp, "instr=0x%08x ", tr->instr); // fprintf(gbl.outfp, "ihash=%-3d ", ihash); fprintf(gbl.outfp, "hpriv=%d ", tr->hpriv); fprintf(gbl.outfp, "pr=%d ", tr->pr); fprintf(gbl.outfp, "bt=%d ", tr->bt); fprintf(gbl.outfp, "ea=0x%016llx ", tr->ea_va); fprintf(gbl.outfp, "ev=%d ", tr->ea_valid); fprintf(gbl.outfp, "an=%d ", tr->an); fprintf(gbl.outfp, "tr=%d ", tr->tr); fprintf(gbl.outfp, "\n"); } // RSTF_Instr::print_rec() virtual void print_verb(uint64_t idx) { char dis_string[80]; uint64_t ea_va = -1; int cpuid = gbl.rstf_pre212? tr->cpuid: rstf_instrT_get_cpuid(tr); sprintDiss(dis_string, tr->instr, tr->pc_va); int ihash = spix_sparc_iop(SPIX_SPARC_V9, &tr->instr); if (ih_isbranch(ihash) || ihash == SPIX_SPARC_IOP_CALL) { if (gbl.branch && tr->bt) { ea_va = getCtiEa(tr->instr, ihash, tr->pc_va); if (gbl.pstate[cpuid] & PSTATE_AM) { ea_va &= 0xffffffff; } if (!tr->an) { check_branch_ea(ea_va, tr->ea_va); } } } if (gbl.showIdx) { fprintf(gbl.outfp , "%6lld ", idx); } fprintf(gbl.outfp, "instr : cpuid=%d ", cpuid); if (tr->hpriv) { fprintf(gbl.outfp, "h "); } else if (tr->pr) { fprintf(gbl.outfp, "p "); } else { fprintf(gbl.outfp, "u "); } fprintf(gbl.outfp, "[0x%016llx] ", tr->pc_va); fprintf(gbl.outfp, "%-32s", dis_string); fprintf(gbl.outfp, "(0x%08x) ", tr->instr); fprintf(gbl.outfp, "%3d ", ihash); if (ih_iscti(ihash)) { if (tr->bt) { fprintf(gbl.outfp, "T "); } else { fprintf(gbl.outfp, "N "); } } else { fprintf(gbl.outfp, " "); } #ifdef _PRINT_PA if (gbl.printPA) { fprintf(gbl.outfp, "v[0x%016llx]", tr->ea_va); if (!tr->ea_valid) { fprintf(gbl.outfp, "x "); } else { fprintf(gbl.outfp, " "); } if ((ih_isload(ihash) || ih_isstore(ihash)) && tr->tr == 0) { if (gbl.ea_pavadiff_valid[cpuid]) { fprintf(gbl.outfp, "p[0x%016llx] ", tr->ea_va + gbl.ea_pavadiff_value[cpuid]); } } else { if (gbl.pc_pavadiff_valid[cpuid]) { fprintf(gbl.outfp, "p[0x%016llx] ", tr->ea_va + gbl.pc_pavadiff_value[cpuid]); } } } else #endif // _PRINT_PA { fprintf(gbl.outfp, "[0x%016llx]", tr->ea_va); if (!tr->ea_valid) { fprintf(gbl.outfp, "x "); } else { fprintf(gbl.outfp, " "); } } if (tr->an) { fprintf(gbl.outfp, "an "); } if (tr->tr) { fprintf(gbl.outfp, "tr "); } fprintf(gbl.outfp, "\n"); } // RSTF_Instr::print_verb() virtual void convert_to_master() { this_master.tr_pc_va = tr->pc_va; this_master.tr_ea_va = tr->ea_va ; this_master.tr_tid = 0; this_master.tr_ih = spix_sparc_iop(SPIX_SPARC_V9, &tr->instr); this_master.tr_reserved0 = 0; this_master.tr_taken = tr->bt; this_master.tr_annulled = tr->an; this_master.tr_i = tr->instr; this_master.tr_reserved1 = 0; this_master.tr_pc_pa = 0; this_master.tr_ea_pa = 0; this_master.tr_context = 0; //this_master.tr_traceinfo = 0; this_master.tr_got_trap = tr->tr; this_master.tr_privmode = tr->pr; this_master.tr_va_valid = tr->ea_valid; } // RSTF_Instr::convert_to_master() virtual void convert_from_master(Tmaster64* master) { tr->rtype = INSTR_T; tr->notused = 0; tr->ea_valid = master->tr_va_valid; tr->tr = master->tr_got_trap; tr->pr = master->tr_privmode; tr->bt = master->tr_taken; tr->an = master->tr_annulled; // tr->ihash = master->tr_ih; tr->instr = master->tr_i; tr->pc_va = master->tr_pc_va; tr->ea_va = master->tr_ea_va; } // RSTF_Instr::convert_from_master() virtual void gen_ihash() { // tr->ihash = getIHash(tr->instr); } // RSTF_Instr::gen_ihash() virtual int check_ihash_error() { #if 0 if (tr->ihash != getIHash(tr->instr)) { return 1; } #endif return 0; } // RSTF_Instr::check_ihash_error() virtual void verify() { rstf_instrT* vtr = tr - NUM_VERIFY; int i; for (i = 0; i < NUM_VERIFY - 1; i++) { if (vtr[i].rtype == INSTR_T) { if (vtr[i].pc_va % 4 != 0 && RSTF_IS_BADADDR(vtr[i].pc_va) == 0) { fprintf(stderr, "trconv: Error: Incorrect pc value in input file.\n"); set_tr(&vtr[i], false); print_verb(gbl.rcount - NUM_VERIFY + i); //exit(2); } } } } // RSTF_Instr::verify() virtual uint64_t get_pc() { return tr->pc_va; } // RSTF_Instr::get_pc() virtual uint64_t get_ea() { if (tr->ea_valid) { return tr->ea_va; } return RSTF_NOADDR; } // RSTF_Instr::get_ea() virtual int get_ihash() { return spix_sparc_iop(SPIX_SPARC_V9, &tr->instr); } // RSTF_Instr::get_ihash() virtual void inc_tr() { tr++; } // RSTF_Instr::inc_tr() virtual void set_tr(void* ptr, bool set_orig = true) { tr = (rstf_instrT*) ptr; if (set_orig) { tr_orig = tr; } } // RSTF_Instr::set_tr() virtual void reset_tr() { tr = tr_orig; } // RSTF_Instr::reset_tr() virtual int getCpuID() { return gbl.rstf_pre212? tr->cpuid: rstf_instrT_get_cpuid(tr); } protected: rstf_instrT* tr; rstf_instrT* tr_orig; }; // RSTF_Instr #if 0 // deprecated //====================================================================== //====================================================================== // ASI_T is deprecated, is replaced by TRACEINFO_T with the same enum value. class RSTF_Asi : public Trace { public: virtual void count() { gbl.rcount++; gbl.asicount++; } virtual void print_rec(uint64_t idx) { if (gbl.showIdx) { fprintf(gbl.outfp , "%6lld ", idx); } //FIXME should use rstf_traceinfoT, but it is not done yet, stay tune. fprintf(gbl.outfp, "asi : rtype=%d asi=%d", tr->rtype, tr->asi); fprintf(gbl.outfp, "\n"); } // RSTF_Asi::print_rec() virtual void inc_tr() { tr++; } // RSTF_Asi::inc_tr() virtual void set_tr(void* ptr, bool set_orig = true) { tr = (rstf_asiT*) ptr; if (set_orig) { tr_orig = tr; } } // RSTF_Asi::set_tr() virtual void reset_tr() { tr = tr_orig; } // RSTF_Asi::reset_tr() protected: rstf_asiT* tr; rstf_asiT* tr_orig; }; // RSTF_Asi #endif //====================================================================== //====================================================================== class RSTF_Traceinfo : public Trace { public: virtual void count() { gbl.rcount++; gbl.traceinfocount++; } virtual void print_rec(uint64_t idx) { if (gbl.showIdx) { fprintf(gbl.outfp , "%6lld ", idx); } switch(ti_level->rtype2) { case RSTT2_NLEVEL_T: { time_t t = ti_level->time64; fprintf(gbl.outfp, "trinfo : LEVEL=%d time=%s", ti_level->level, ctime(&t)); } break; case RSTT2_CPUINFO_T: fprintf(gbl.outfp, "trinfo : NCPUS=%d mincpuid=%d maxcpuid=%d\n", ti_cpuinfo->numcpus, ti_cpuinfo->min_cpu_id, ti_cpuinfo->max_cpu_id); break; case RSTT2_CPUIDINFO_T: fprintf(gbl.outfp, "trinfo : CPUIDS={ "); int i; for (i=0; i<10; i++) { fprintf(gbl.outfp, "%d,", ti_cpuid->cpuids[i]); } fprintf(gbl.outfp, "}\n"); break; default: fprintf(gbl.outfp, "Unknown TRACEINFO record\n"); } } // RSTF_Traceinfo::print_rec() virtual void inc_tr() { ti_level++; } // RSTF_Traceinfo::inc_tr() virtual void set_tr(void* ptr, bool set_orig = true) { ti_level = (rstf_traceinfo_levelT*) ptr; ti_cpuinfo = (rstf_cpuinfoT*) ptr; ti_cpuid = (rstf_cpuidinfoT*) ptr; if (set_orig) { tr_orig = ti_level; } } // RSTF_Traceinfo::set_tr() virtual void reset_tr() { ti_level = (rstf_traceinfo_levelT*) tr_orig; ti_cpuinfo = (rstf_cpuinfoT*) tr_orig; ti_cpuid = (rstf_cpuidinfoT*) tr_orig; } // RSTF_Traceinfo::reset_tr() protected: rstf_traceinfo_levelT* ti_level; rstf_cpuinfoT * ti_cpuinfo; rstf_cpuidinfoT * ti_cpuid; rstf_traceinfo_levelT* tr_orig; }; // RSTF_Traceinfo //====================================================================== //====================================================================== class RSTF_Tlb : public Trace { public: virtual void count() { gbl.rcount++; gbl.tlbcount++; } virtual void print_rec(uint64_t idx) { uint64_t pa; pa = tr->tte_data; pa &= (~ 0x1fffULL); pa &= 0x7ffffffffffULL; if (gbl.showIdx) { fprintf(gbl.outfp , "%6lld ", idx); } fprintf(gbl.outfp, "tlb : cpuid=%d demap=%d ", getCpuID(), tr->demap); fprintf(gbl.outfp, "type=%d ", tr->tlb_type); //fprintf(gbl.outfp, "valid=%d ", tr->valid); fprintf(gbl.outfp, "index=%-4d ", tr->tlb_index); fprintf(gbl.outfp, "no=%d ", tr->tlb_no); //fprintf(gbl.outfp, "state=0x%04x ", tr->state); //fprintf(gbl.outfp, "context=0x%04x ", tr->context); fprintf(gbl.outfp, "tag=0x%016llx ", tr->tte_tag); fprintf(gbl.outfp, "data=0x%016llx ", tr->tte_data); fprintf(gbl.outfp, "pa=0x%llx", pa); fprintf(gbl.outfp, "\n"); } // RSTF_Tlb::print_rec() virtual void inc_tr() { tr++; } // RSTF_Tlb::inc_tr() virtual void set_tr(void* ptr, bool set_orig = true) { tr = (rstf_tlbT*) ptr; if (set_orig) { tr_orig = tr; } } // RSTF_Tlb::set_tr() virtual void reset_tr() { tr = tr_orig; } // RSTF_Tlb::reset_tr() virtual int getCpuID() { return gbl.rstf_pre212? tr->cpuid: rstf_tlbT_get_cpuid(tr); } protected: rstf_tlbT* tr; rstf_tlbT* tr_orig; }; // RSTF_Tlb //====================================================================== //====================================================================== class RSTF_Thread : public Trace { public: virtual void count() { gbl.rcount++; gbl.threadcount++; } virtual void print_rec(uint64_t idx) { if (gbl.showIdx) { fprintf(gbl.outfp , "%6lld ", idx); } fprintf(gbl.outfp, "thread : rtype=%d", tr->rtype); //fprintf(gbl.outfp, "thread : rtype=%d newtid=%d newpid=%d", // tr->rtype, tr->newtid, tr->newpid); fprintf(gbl.outfp, "\n"); } // RSTF_Thread::print_rec() virtual void inc_tr() { tr++; } // RSTF_Thread::inc_tr() virtual void set_tr(void* ptr, bool set_orig = true) { tr = (rstf_threadT*) ptr; if (set_orig) { tr_orig = tr; } } // RSTF_Thread::set_tr() virtual void reset_tr() { tr = tr_orig; } // RSTF_Thread::reset_tr() protected: rstf_threadT* tr; rstf_threadT* tr_orig; }; // RSTF_Thread inline void decode_pstate_bits (FILE* const out, uint16_t pstate) { fprintf (out, "("); if ((pstate & 0x800) != 0) { // Cheetah specific fprintf(out, " IG"); } if ((pstate & 0x400) != 0) { // Cheetah specific fprintf(out, " MG"); } if ((pstate & 0x4) != 0) { fprintf(out, " PRIV"); } if ((pstate & 0x2) != 0) { fprintf(out, " IE"); } if ((pstate & 0x1) != 0) { fprintf(out, " AG"); } fprintf (out, ") "); } //====================================================================== //====================================================================== class RSTF_Trap : public Trace { public: virtual void count() { gbl.rcount++; gbl.trapcount++; } virtual void print_rec(uint64_t idx) { if (gbl.showIdx) { fprintf(gbl.outfp , "%6lld ", idx); } fprintf(gbl.outfp, "trap : cpuid=%d ", getCpuID()); fprintf(gbl.outfp, "async==%d ", tr->is_async); fprintf(gbl.outfp, "tl=%d ", tr->tl); fprintf(gbl.outfp, "ttype=0x%03x ", tr->ttype); switch (tr->ttype) { case 0x12: fprintf(gbl.outfp, "(unimplemented LDD instr) "); break; case 0x24: case 0x25: case 0x26: case 0x27: fprintf(gbl.outfp, "(clean window) "); break; case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47: case 0x48: case 0x49: case 0x4A: case 0x4B: case 0x4C: case 0x4D: case 0x4E: case 0x4F: fprintf(gbl.outfp, "(interrupt request lvl n) "); break; case 0x60: fprintf(gbl.outfp, "(interrupt request) "); break; case 0x64: case 0x65: case 0x66: case 0x67: fprintf(gbl.outfp, "(ITLB miss) "); break; case 0x68: case 0x69: case 0x6A: case 0x6B: fprintf(gbl.outfp, "(DTLB miss) "); break; case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87: case 0x88: case 0x89: case 0x8A: case 0x8B: case 0x8C: case 0x8D: case 0x8E: case 0x8F: case 0x90: case 0x91: case 0x92: case 0x93: case 0x94: case 0x95: case 0x96: case 0x97: case 0x98: case 0x99: case 0x9A: case 0x9B: case 0x9C: case 0x9D: case 0x9E: case 0x9F: fprintf(gbl.outfp, "(spill normal) "); break; case 0xA0: case 0xA1: case 0xA2: case 0xA3: case 0xA4: case 0xA5: case 0xA6: case 0xA7: case 0xA8: case 0xA9: case 0xAA: case 0xAB: case 0xAC: case 0xAD: case 0xAE: case 0xAF: case 0xB0: case 0xB1: case 0xB2: case 0xB3: case 0xB4: case 0xB5: case 0xB6: case 0xB7: case 0xB8: case 0xB9: case 0xBA: case 0xBB: case 0xBC: case 0xBD: case 0xBE: case 0xBF: fprintf(gbl.outfp, "(spill other) "); break; case 0xC0: case 0xC1: case 0xC2: case 0xC3: case 0xC4: case 0xC5: case 0xC6: case 0xC7: case 0xC8: case 0xC9: case 0xCA: case 0xCB: case 0xCC: case 0xCD: case 0xCE: case 0xCF: case 0xD0: case 0xD1: case 0xD2: case 0xD3: case 0xD4: case 0xD5: case 0xD6: case 0xD7: case 0xD8: case 0xD9: case 0xDA: case 0xDB: case 0xDC: case 0xDD: case 0xDE: case 0xDF: fprintf(gbl.outfp, "(fill normal) "); break; // 0x100 - 0x176 - Tcc instruction executed case 0x100: case 0x101: case 0x102: case 0x103: case 0x108: case 0x109: case 0x10a: case 0x10b: case 0x120: case 0x121: case 0x122: case 0x123: case 0x124: case 0x125: case 0x126: case 0x127: case 0x140: fprintf(gbl.outfp, "(tcc instr.) "); break; default: /* do nothing */ break; } fprintf(gbl.outfp, "pstate=0x%03x ", tr->pstate); decode_pstate_bits (gbl.outfp, tr->pstate); fprintf(gbl.outfp, "syscall=0x%04x ", tr->syscall); fprintf(gbl.outfp, "pc=0x%016llx ", tr->pc); fprintf(gbl.outfp, "npc=0x%016llx", tr->npc); fprintf(gbl.outfp, "\n"); } // RSTF_Trap::print_rec() virtual uint64_t get_pc() { return tr->pc; } // RSTF_Trap::get_pc() virtual void inc_tr() { tr++; } // RSTF_Trap::inc_tr() virtual void set_tr(void* ptr, bool set_orig = true) { tr = (rstf_trapT*) ptr; if (set_orig) { tr_orig = tr; } } // RSTF_Trap::set_tr() virtual void reset_tr() { tr = tr_orig; } // RSTF_Trap::reset_tr() virtual int getCpuID() { return gbl.rstf_pre212? tr->cpuid: rstf_trapT_get_cpuid(tr); } protected: rstf_trapT* tr; rstf_trapT* tr_orig; }; // RSTF_Trap //====================================================================== //====================================================================== class RSTF_Trapexit : public Trace { public: virtual void count() { gbl.rcount++; gbl.trapexitcount++; } virtual void print_rec(uint64_t idx) { if (gbl.showIdx) { fprintf(gbl.outfp , "%6lld ", idx); } fprintf(gbl.outfp, "trapexit: cpuid=%d tl=%d ", getCpuID(), tr->tl); fprintf(gbl.outfp, "tstate=%d ", tr->tstate); //fprintf(gbl.outfp, "pc=0x%016llx ", tr->pc); //fprintf(gbl.outfp, "npc=0x%016llx ", tr->npc); fprintf(gbl.outfp, "\n"); } // RSTF_Trapexit::print_rec() #if 0 virtual uint64_t get_pc() { return tr->pc; } // RSTF_Trapexit::get_pc() #endif virtual void inc_tr() { tr++; } // RSTF_Trapexit::inc_tr() virtual void set_tr(void* ptr, bool set_orig = true) { tr = (rstf_trapexitT*) ptr; if (set_orig) { tr_orig = tr; } } // RSTF_Trapexit::set_tr() virtual void reset_tr() { tr = tr_orig; } // RSTF_Trapexit::reset_tr() virtual int getCpuID() { return gbl.rstf_pre212? tr->cpuid: rstf_trapexitT_get_cpuid(tr); } protected: rstf_trapexitT* tr; rstf_trapexitT* tr_orig; }; // RSTF_Trapexit //====================================================================== //====================================================================== class RSTF_Regval : public Trace { public: virtual void count() { gbl.rcount++; gbl.regvalcount++; } #ifdef _VALUE_TRACE virtual void print_rec_valueTrace(uint64_t idx) { if (gbl.showIdx) { fprintf(gbl.outfp , "%6lld ", idx); } fprintf(gbl.outfp, "regval : "); fprintf(gbl.outfp, "cpuid=%d ", getCpuID()); // fprintf(gbl.outfp, "postInstr=%d ", tr->postInstr); for(long i=0; i<2; i++) { vtPrintReg(gbl.outfp, tr->regtype[i], tr->regid[i], tr->reg64[i], i); } fprintf(gbl.outfp, "\n"); } // RSTF_Regval::print_rec() #endif // _VALUE_TRACE virtual void print_rec_normal(uint64_t idx) { if (gbl.showIdx) { fprintf(gbl.outfp , "%6lld ", idx); } fprintf(gbl.outfp, "regval : "); fprintf(gbl.outfp, "cpuid=%d ", getCpuID()); fprintf(gbl.outfp, "postInstr=%d ", tr->postInstr); fprintf(gbl.outfp, "regtype[0]=%d ", tr->regtype[0]); fprintf(gbl.outfp, "regid[0]=%d ", tr->regid[0]); fprintf(gbl.outfp, "reg64[0]=0x%llx ", tr->reg64[0]); fprintf(gbl.outfp, "regtype[1]=%d ", tr->regtype[1]); fprintf(gbl.outfp, "regid[1]=%d ", tr->regid[1]); fprintf(gbl.outfp, "reg64[1]=0x%llx", tr->reg64[1]); fprintf(gbl.outfp, "\n"); //fprintf(gbl.outfp, "regnum=%d ", tr->regnum); //fprintf(gbl.outfp, "reg32=%d ", tr->reg32); } // RSTF_Regval::print_rec() virtual void print_rec(uint64_t idx) { #ifdef _VALUE_TRACE if (gbl.valueTrace) { print_rec_valueTrace(idx); } else #endif // _VALUE_TRACE { print_rec_normal(idx); } } virtual void inc_tr() { tr++; } // RSTF_Regval::inc_tr() virtual void set_tr(void* ptr, bool set_orig = true) { tr = (rstf_regvalT*) ptr; if (set_orig) { tr_orig = tr; } } // RSTF_Regval::set_tr() virtual void reset_tr() { tr = tr_orig; } // RSTF_Regval::reset_tr() virtual int getCpuID() { return gbl.rstf_pre212? tr->cpuid: rstf_regvalT_get_cpuid(tr); } protected: rstf_regvalT* tr; rstf_regvalT* tr_orig; #ifdef _VALUE_TRACE virtual void vtPrintIntRegName(FILE *outfp, long regid) { if (regid < 0 || regid >= 32) { fprintf(stderr, "trconv: warning: Register number %d should be <32 (Rec #%llu)\n", regid, gbl.rcount); } static char prefix[5] = "goli"; char toprint[3] = "g0"; toprint[0] = prefix[(regid/8)]; toprint[1] = '0' + (regid%8); fprintf(outfp, "%%%s ", toprint); } virtual void vtPrintFloatReg(FILE *outfp, long regid, uint64_t reg64, long i, char &isQuad, uint64_t &quadWord) { if (regid >= 0 && regid < 32) { // Single if(isQuad) { fprintf(stderr, "trconv: warning: quad register encountered (#%llu)\n", gbl.rcount); } float f = (float) reg64; fprintf(outfp, "(Reg %d: %%f%d = %f(0x%llx)) ", i, regid, f, reg64); } else if (regid < 64) { // Double if(isQuad) { fprintf(stderr, "trconv: warning: quad register encountered (#%llu)\n", gbl.rcount); } double d = (double) reg64; fprintf(outfp, "(Reg %d: %%d%d = %f(0x%llx)) ", i, ((regid - 32) * 2), d, reg64); } else { if (regid >= 80) { fprintf(stderr, "trconv: warning: regid = %d should have been <80 (Rec #%llu\n", regid, gbl.rcount); } if (i == 0) { isQuad = 1; quadWord = reg64; } else { if(isQuad) { fprintf(stderr, "trconv: warning: quad register encountered (#%llu)\n", gbl.rcount); } fprintf(outfp, "(Reg 0+1: %%q%d = 0x%016llx%016llx) ", i, ((regid - 64) * 4), quadWord, reg64); } } } virtual void vtPrintPrivReg(FILE *outfp, long regid) { switch (regid) { case RSTREG_TPC_R: fprintf(outfp, "%%tpc "); break; case RSTREG_TNPC_R: fprintf(outfp, "%%tnpc "); break; case RSTREG_TSTATE_R: fprintf(outfp, "%%tstate "); break; case RSTREG_TT_R: fprintf(outfp, "%%tt "); break; case RSTREG_TICK_R: fprintf(outfp, "%%tick "); break; case RSTREG_TBA_R: fprintf(outfp, "%%tba "); break; case RSTREG_PSTATE_R: fprintf(outfp, "%%pstate "); break; case RSTREG_TL_R: fprintf(outfp, "%%tl "); break; case RSTREG_PIL_R: fprintf(outfp, "%%pil "); break; case RSTREG_CWP_R: fprintf(outfp, "%%cwp "); break; case RSTREG_CANSAVE_R: fprintf(outfp, "%%cansave "); break; case RSTREG_CANRESTORE_R: fprintf(outfp, "%%canrestore "); break; case RSTREG_CLEANWIN_R: fprintf(outfp, "%%cleanwin "); break; case RSTREG_OTHERWIN_R: fprintf(outfp, "%%otherwin "); break; case RSTREG_WSTATE_R: fprintf(outfp, "%%wstate "); break; case RSTREG_FQ_R: fprintf(outfp, "%%fq "); break; case RSTREG_VERSION_R: fprintf(outfp, "%%ver "); break; case RSTREG_TPC_RBASE + 0: case RSTREG_TPC_RBASE + 1: case RSTREG_TPC_RBASE + 2: case RSTREG_TPC_RBASE + 3: case RSTREG_TPC_RBASE + 4: if (regid == RSTREG_TPC_RBASE){ // does not make sense to have trap level 0 fprintf(stderr, "trconv: warning: TPC should not be present for trap level 0 (#%llu) \n", gbl.rcount); } fprintf(outfp, "%%tpc[%d]", regid-RSTREG_TPC_RBASE); break; case RSTREG_TNPC_RBASE + 0: case RSTREG_TNPC_RBASE + 1: case RSTREG_TNPC_RBASE + 2: case RSTREG_TNPC_RBASE + 3: case RSTREG_TNPC_RBASE + 4: if (regid == RSTREG_TNPC_RBASE){ // does not make sense to have trap level 0 fprintf(stderr, "trconv: warning: TNPC should not be present for trap level 0 (#%llu) \n", gbl.rcount); } fprintf(outfp, "%%tnpc[%d]", regid-RSTREG_TNPC_RBASE); break; case RSTREG_TSTATE_RBASE + 0: case RSTREG_TSTATE_RBASE + 1: case RSTREG_TSTATE_RBASE + 2: case RSTREG_TSTATE_RBASE + 3: case RSTREG_TSTATE_RBASE + 4: if (regid == RSTREG_TSTATE_RBASE){ // does not make sense to have trap level 0 fprintf(stderr, "trconv: warning: TSTATE should not be present for trap level 0 (#%llu) \n", gbl.rcount); } fprintf(outfp, "%%tstate[%d]", regid-RSTREG_TSTATE_RBASE); break; case RSTREG_TT_RBASE + 0: case RSTREG_TT_RBASE + 1: case RSTREG_TT_RBASE + 2: case RSTREG_TT_RBASE + 3: case RSTREG_TT_RBASE + 4: if (regid == RSTREG_TT_RBASE){ // does not make sense to have trap level 0 fprintf(stderr, "trconv: warning: TT should not be present for trap level 0 (#%llu) \n", gbl.rcount); } fprintf(outfp, "%%tt[%d]", regid-RSTREG_TT_RBASE); break; default: fprintf(outfp, "%%unknownpr%d ", regid); // fprintf(stderr, "trconv: warning: Unknown priv regid %d (#%llu)", regid, gbl.rcount); break; } } virtual void vtPrintOtherReg(FILE *outfp, long regid) { switch (regid) { case RSTREG_Y_R: fprintf(outfp, "%%y "); break; case RSTREG_CC_R: fprintf(outfp, "%%cc "); break; case RSTREG_ASI_R: fprintf(outfp, "%%asi "); break; case RSTREG_TICK_R: fprintf(outfp, "%%tick "); break; case RSTREG_PC_R: fprintf(outfp, "%%pc "); break; case RSTREG_FPRS_R: fprintf(outfp, "%%fprs "); break; // case RSTREG_ASR_R: fprintf(outfp, "%%asr "); break; case RSTREG_ASR_PCR_R: fprintf(outfp, "%%pcr "); break; case RSTREG_ASR_PIC_R: fprintf(outfp, "%%pic "); break; case RSTREG_ASR_IEU_CTRL_R: fprintf(outfp, "%%ieu_ctrl "); break; case RSTREG_ASR_GSR_R: fprintf(outfp, "%%gsr "); break; case RSTREG_ASR_INTR_SET_R: fprintf(outfp, "%%intr_set "); break; case RSTREG_ASR_INTR_CLR_R: fprintf(outfp, "%%intr_clr "); break; case RSTREG_ASR_INTR_WRITE_R: fprintf(outfp, "%%intr_write "); break; case RSTREG_ASR_TICK_CMPR_R: fprintf(outfp, "%%tick_cmpr "); break; case RSTREG_ASR_STICK_REG_R: fprintf(outfp, "%%stick "); break; case RSTREG_ASR_STICK_CMPR_R: fprintf(outfp, "%%stick_cmpr "); break; case RSTREG_ASR_STICK_THR_STR_R: fprintf(outfp, "%%stick_thr_str "); break; case RSTREG_ASR_NPC_R: fprintf(outfp, "%%npc "); break; case RSTREG_ASR_FSR_R: fprintf(outfp, "%%fsr "); break; default: fprintf(outfp, "%%UnknownASR "); break; } } virtual void vtPrintReg(FILE *outfp, long regtype, long regid, uint64_t reg64, int i) { static char isQuad = 0; static uint64_t quadWord = 0x0; switch (regtype) { case RSTREG_INT_RT: if(isQuad) { fprintf(stderr, "trconv: warning: quad register encountered (#%llu)\n", gbl.rcount); } fprintf(outfp, "(Reg %d: ", i); vtPrintIntRegName(outfp, regid); fprintf(outfp, "= 0x%llx) ", reg64); break; case RSTREG_FLOAT_RT: vtPrintFloatReg(outfp, regid, reg64, i, isQuad, quadWord); break; case RSTREG_PRIV_RT: if(isQuad) { fprintf(stderr, "trconv: warning: quad register encountered (#%llu)\n", gbl.rcount); } fprintf(outfp, "(Reg %d: ", i); vtPrintPrivReg(outfp, regid); fprintf(outfp, "= 0x%llx) ", reg64); if (regid == RSTREG_PSTATE_R) decode_pstate_bits (outfp, reg64); break; case RSTREG_OTHER_RT: if(isQuad) { fprintf(stderr, "trconv: warning: quad register encountered (#%llu)\n", gbl.rcount); } fprintf(outfp, "(Reg %d: ", i); vtPrintOtherReg(outfp, regid); fprintf(outfp, "= 0x%llx) ", reg64); break; case RSTREG_UNUSED_RT: if(isQuad) { fprintf(stderr, "trconv: warning: quad register encountered (#%llu)\n", gbl.rcount); } // fprintf(outfp, "(Reg %d unused)", i); break; case RSTREG_CC_RT: fprintf(outfp, "(Reg %d: %%ccr=0x%02x) ", i, regid); break; case RSTREG_FCC_RT: fprintf(outfp, "(Reg %d: %%fcc=0x%02x) ", i, regid); break; case RSTREG_MMU_RT: if (regid == RSTREG_MMU_PCONTEXT) { fprintf(outfp, "(Reg %d: PContext=0x%02llx) ", i, reg64); } else if (regid == RSTREG_MMU_SCONTEXT) { fprintf(outfp, "(Reg %d: SContext=0x%02llx) ", i, reg64); } else { fprintf(stderr, "trconv: warning: (#%llu) (Reg %d: Unknown MMU RegID %d = 0x%02x)\n", gbl.rcount, i, regid, reg64); } break; case RSTREG_HPRIV_RT: switch(regid) { case RSTREG_HPR_HPSTATE: fprintf(outfp, "(Reg %d: %%hpstate=0x%llx) ", i, reg64); break; case RSTREG_HPR_HTSTATE: fprintf(outfp, "(Reg %d: %%htstate=0x%llx) ", i, reg64); break; case RSTREG_HPR_HINTP: fprintf(outfp, "(Reg %d: %%hintp=0x%llx) ", i, reg64); break; case RSTREG_HPR_HTBA: fprintf(outfp, "(Reg %d: %%htba=0x%llx) ", i, reg64); break; case RSTREG_HPR_HVER: fprintf(outfp, "(Reg %d: %%hver=0x%llx) ", i, reg64); break; case RSTREG_HPR_HSTICK_CMPR: fprintf(outfp, "(Reg %d: %%hstick_cmpr=0x%llx) ", i, reg64); break; default: fprintf(outfp, "(Reg %d: UnknownHPR%d = 0x%llx) ", i, regid, reg64); } break; default: fprintf(stderr, "trconv: warning: Unknown regtype %d for reg[%d] (#%llu)", regtype, i, gbl.rcount); break; } } #endif // _VALUE_TRACE }; // RSTF_Regval //====================================================================== //====================================================================== class RSTF_Cpu : public Trace { public: virtual void count() { gbl.rcount++; gbl.cpucount++; } virtual void print_rec(uint64_t idx) { if (gbl.showIdx) { fprintf(gbl.outfp , "%6lld ", idx); } fprintf(gbl.outfp, "cpu : cpuid=%d ", getCpuID()); fprintf(gbl.outfp, "timestamp=%llu", tr->timestamp); fprintf(gbl.outfp, "\n"); } // RSTF_Cpu::print_rec() virtual void inc_tr() { tr++; } // RSTF_Cpu::inc_tr() virtual void set_tr(void* ptr, bool set_orig = true) { tr = (rstf_cpuT*) ptr; if (set_orig) { tr_orig = tr; } } // RSTF_Cpu::set_tr() virtual void reset_tr() { tr = tr_orig; } // RSTF_Cpu::reset_tr() virtual int getCpuID() { return tr->cpu; } protected: rstf_cpuT* tr; rstf_cpuT* tr_orig; }; // RSTF_Cpu //====================================================================== //====================================================================== class RSTF_Process : public Trace { public: virtual void count() { gbl.rcount++; gbl.processcount++; } virtual void print_rec(uint64_t idx) { if (gbl.showIdx) { fprintf(gbl.outfp , "%6lld ", idx); } fprintf(gbl.outfp, "process : "); fprintf(gbl.outfp, "%d ", tr->oldpid); fprintf(gbl.outfp, "%d ", tr->newpid); fprintf(gbl.outfp, "%d ", tr->oldcontext); fprintf(gbl.outfp, "%d", tr->newcontext); fprintf(gbl.outfp, "\n"); } // RSTF_Process::print_rec() virtual void inc_tr() { tr++; } // RSTF_Process::inc_tr() virtual void set_tr(void* ptr, bool set_orig = true) { tr = (rstf_processT*) ptr; if (set_orig) { tr_orig = tr; } } // RSTF_Process::set_tr() virtual void reset_tr() { tr = tr_orig; } // RSTF_Process::reset_tr() protected: rstf_processT* tr; rstf_processT* tr_orig; }; // RSTF_Process //====================================================================== //====================================================================== class RSTF_Dma : public Trace { public: virtual void count() { gbl.rcount++; gbl.dmacount++; } virtual void print_rec(uint64_t idx) { if (gbl.showIdx) { fprintf(gbl.outfp , "%6lld ", idx); } fprintf(gbl.outfp, "dma : "); //fprintf(gbl.outfp, "rtype=%d ", tr->rtype); fprintf(gbl.outfp, "iswrite=%d ", tr->iswrite); fprintf(gbl.outfp, "start_pa=0x%016llx ", tr->start_pa); fprintf(gbl.outfp, "nbytes=%d ", tr->nbytes); if (tr->devid) { fprintf(gbl.outfp, "dev_id=%d ", tr->devid); std::string idstring = gbl.devid2string[tr->devid]; if (idstring.length() == 0) { idstring = "unknown"; } fprintf(gbl.outfp, "(%s)", idstring.c_str()); } fprintf(gbl.outfp, "\n"); } // RSTF_Dma::print_rec() virtual void inc_tr() { tr++; } // RSTF_Dma::inc_tr() virtual void set_tr(void* ptr, bool set_orig = true) { tr = (rstf_dmaT*) ptr; if (set_orig) { tr_orig = tr; } } // RSTF_Dma::set_tr() virtual void reset_tr() { tr = tr_orig; } // RSTF_Dma::reset_tr() protected: rstf_dmaT* tr; rstf_dmaT* tr_orig; }; // RSTF_Dma //====================================================================== //====================================================================== class RSTF_String : public Trace { public: virtual void count() { gbl.rcount++; gbl.stringcount++; } virtual void print_rec(uint64_t idx) { static char desc_string[800]; static char* desc_str = desc_string; char cont_string[32]; int i; if (tr->rtype == STRDESC_T) { if (gbl.showIdx) { fprintf(gbl.outfp , "%6lld ", idx); } for (i = 0; i < 23; i++) { if (tr->string[i] == 0) { break; } } if (i == 23) { fprintf(stderr, "trconv: warning: strdesc string not null terminated (#%llu)\n", gbl.rcount); } strncpy(desc_str, tr->string, 23); desc_str += 23; desc_str[0] = 0; fprintf(gbl.outfp, "strdesc : \"%s\"\n", desc_string); desc_str = desc_string; } else { strncpy(desc_str, tr->string, 23); desc_str += 23; desc_str[0] = 0; strncpy(cont_string, tr->string, 23); cont_string[23] = 0; if (gbl.fast) { if (gbl.showIdx) { fprintf(gbl.outfp , "%6lld ", idx); } fprintf(gbl.outfp, "strcont : \"%s\"\n", cont_string); } } } // RSTF_String::print_rec() virtual void inc_tr() { tr++; } // RSTF_String::inc_tr() virtual void set_tr(void* ptr, bool set_orig = true) { tr = (rstf_stringT*) ptr; if (set_orig) { tr_orig = tr; } } // RSTF_String::set_tr() virtual void reset_tr() { tr = tr_orig; } // RSTF_String::reset_tr() protected: rstf_stringT* tr; rstf_stringT* tr_orig; }; // RSTF_String //====================================================================== //====================================================================== class RSTF_Delim : public Trace { public: virtual void count() { gbl.rcount++; gbl.delimcount++; } virtual void print_rec(uint64_t idx) { if (gbl.showIdx) { fprintf(gbl.outfp , "%6lld ", idx); } if (tr->rtype == LEFTDELIM_T) { fprintf(gbl.outfp, "delimTl : "); } else { fprintf(gbl.outfp, "delimTr : "); } fprintf(gbl.outfp, "id=%d ", tr->id); fprintf(gbl.outfp, "what=%d ", tr->what); fprintf(gbl.outfp, "length=%d", tr->length); fprintf(gbl.outfp, "\n"); } // RSTF_Delim::print_rec() virtual void inc_tr() { tr++; } // RSTF_Delim::inc_tr() virtual void set_tr(void* ptr, bool set_orig = true) { tr = (rstf_delimT*) ptr; if (set_orig) { tr_orig = tr; } } // RSTF_Delim::set_tr() virtual void reset_tr() { tr = tr_orig; } // RSTF_Delim::reset_tr() protected: rstf_delimT* tr; rstf_delimT* tr_orig; }; // RSTF_Delim //====================================================================== //====================================================================== class RSTF_Preg : public Trace { public: virtual void count() { gbl.rcount++; gbl.pregcount++; } virtual void print_rec(uint64_t idx) { if (gbl.showIdx) { fprintf(gbl.outfp , "%6lld ", idx); } fprintf(gbl.outfp, "preg : cpuid=%d ", getCpuID()); fprintf(gbl.outfp, "asiReg=%d ", tr->asiReg); //fprintf(gbl.outfp, "last_context=%d ", tr->lastcontext); fprintf(gbl.outfp, "trap_lvl=0x%02x ", tr->traplevel); fprintf(gbl.outfp, "trap_type=0x%02x ", tr->traptype); fprintf(gbl.outfp, "pstate=0x%04x ", tr->pstate); decode_pstate_bits(gbl.outfp, tr->pstate); fprintf(gbl.outfp, "primA=%d ", tr->primA); fprintf(gbl.outfp, "secA=%d ", tr->secA); fprintf(gbl.outfp, "primD=%d ", tr->primD); fprintf(gbl.outfp, "secD=%d", tr->secD); fprintf(gbl.outfp, "\n"); } // RSTF_Preg::print_rec() virtual void inc_tr() { tr++; } // RSTF_Preg::inc_tr() virtual void set_tr(void* ptr, bool set_orig = true) { tr = (rstf_pregT*) ptr; if (set_orig) { tr_orig = tr; } } // RSTF_Preg::set_tr() virtual void reset_tr() { tr = tr_orig; } // RSTF_Preg::reset_tr() virtual int getCpuID() { return gbl.rstf_pre212? tr->cpuid: rstf_pregT_get_cpuid(tr); } protected: rstf_pregT* tr; rstf_pregT* tr_orig; }; // RSTF_Preg //====================================================================== //====================================================================== class RSTF_Physaddr : public Trace { public: virtual void count() { gbl.rcount++; gbl.physaddrcount++; } virtual void print_rec(uint64_t idx) { if (gbl.showIdx) { fprintf(gbl.outfp , "%6lld ", idx); } fprintf(gbl.outfp, "physadd : "); fprintf(gbl.outfp, "pc_pa=0x%08llx ", tr->pc_pa); if (tr->ea_valid) { fprintf(gbl.outfp, "ea_pa=0x%08llx ", tr->ea_pa); } else { fprintf(gbl.outfp, "((ea_pa=0x%08llx)) ", tr->ea_pa); } fprintf(gbl.outfp, "ea_valid=%d", tr->ea_valid); fprintf(gbl.outfp, "\n"); } // RSTF_Physaddr::print_rec() virtual void inc_tr() { tr++; } // RSTF_Physaddr::inc_tr() virtual void set_tr(void* ptr, bool set_orig = true) { tr = (rstf_physaddrT*) ptr; if (set_orig) { tr_orig = tr; } } // RSTF_Physaddr::set_tr() virtual void reset_tr() { tr = tr_orig; } // RSTF_Physaddr::reset_tr() protected: rstf_physaddrT* tr; rstf_physaddrT* tr_orig; }; // RSTF_Physaddr #define PAVADIFF_MASK (0x1fff) // lower 13 bits //====================================================================== //====================================================================== class RSTF_Pavadiff : public Trace { public: virtual void count() { static uint64_t prev_pc_pa_va = 0; gbl.rcount++; gbl.pavadiffcount++; if (gbl.pc_pavadiff) { if (tr->pc_pa_va != prev_pc_pa_va) { prev_pc_pa_va = tr->pc_pa_va; if (tr->pc_pa_va & PAVADIFF_MASK) { fprintf(gbl.msgfp, "trconv: warning: pc pa-va error " "(#%llu pc_pa_va=0x%llx not multiple of pagesize)\n", gbl.rcount - 1, tr->pc_pa_va); } } if (tr->ea_valid) { if (tr->ea_pa_va & PAVADIFF_MASK) { fprintf(gbl.msgfp, "trconv: warning: ea pa-va error " "(#%llu ea_pa_va=0x%llx not multiple of pagesize)\n", gbl.rcount - 1, tr->ea_pa_va); } } } } virtual void print_rec(uint64_t idx) { if (gbl.showIdx) { fprintf(gbl.outfp , "%6lld ", idx); } fprintf(gbl.outfp, "pavadiff: cpuid=%d ", getCpuID()); fprintf(gbl.outfp, "icontext=%d ", tr->icontext); fprintf(gbl.outfp, "dcontext=%d ", tr->dcontext); fprintf(gbl.outfp, "pc_pa_va=0x%016llx ", tr->pc_pa_va); if (tr->ea_valid) { fprintf(gbl.outfp, "ea_pa_va=0x%016llx ", tr->ea_pa_va); } else { fprintf(gbl.outfp, "((ea_pa_va=0x%016llx)) ", tr->ea_pa_va); } fprintf(gbl.outfp, "ea_valid=%d", tr->ea_valid); fprintf(gbl.outfp, "\n"); } // RSTF_Pavadiff::print_rec() virtual void inc_tr() { tr++; } // RSTF_Pavadiff::inc_tr() virtual void set_tr(void* ptr, bool set_orig = true) { tr = (rstf_pavadiffT*) ptr; if (set_orig) { tr_orig = tr; } } // RSTF_Pavadiff::set_tr() virtual void reset_tr() { tr = tr_orig; } // RSTF_Pavadiff::reset_tr() virtual int getCpuID() { return gbl.rstf_pre212? tr->cpuid: rstf_pavadiffT_get_cpuid(tr); } protected: rstf_pavadiffT* tr; rstf_pavadiffT* tr_orig; }; // RSTF_Pavadiff //====================================================================== //====================================================================== class RSTF_Filemarker : public Trace { public: virtual void count() { gbl.rcount++; gbl.filemarkercount++; } virtual void print_rec(uint64_t idx) { if (gbl.showIdx) { fprintf(gbl.outfp , "%6lld ", idx); } if (tr->recNum == 0) { // FILEMARKER_T fprintf(gbl.outfp, "filemark: "); fprintf(gbl.outfp, "recNum=%u ", tr->recNum); fprintf(gbl.outfp, "level=%u ", tr->level); fprintf(gbl.outfp, "incount=%llu ", tr->incount); fprintf(gbl.outfp, "outcount=%llu", tr->outcount); fprintf(gbl.outfp, "\n"); } else { // RECNUM_T rstf_recnumT *ttr = (rstf_recnumT *)tr; fprintf(gbl.outfp, "recnum : cpuid=%d ", gbl.rstf_pre212? tr->cpuID: rstf_filemarkerT_get_cpuid(tr)); fprintf(gbl.outfp, "recNum=%u ", ttr->recNum); fprintf(gbl.outfp, "level=%u ", ttr->level); fprintf(gbl.outfp, "level=%d ", ttr->recType); fprintf(gbl.outfp, "incount=%llu", ttr->incount); fprintf(gbl.outfp, "\n"); } } // RSTF_Filemarker::print_rec() virtual void inc_tr() { tr++; } // RSTF_Filemarker::inc_tr() virtual void set_tr(void* ptr, bool set_orig = true) { tr = (rstf_filemarkerT*) ptr; if (set_orig) { tr_orig = tr; } } // RSTF_Filemarker::set_tr() virtual void reset_tr() { tr = tr_orig; } // RSTF_Filemarker::reset_tr() protected: rstf_filemarkerT* tr; rstf_filemarkerT* tr_orig; }; // RSTF_Filemarker //====================================================================== //====================================================================== class RSTF_Status : public Trace { public: virtual void count() { gbl.rcount++; gbl.statuscount++; } virtual void print_rec(uint64_t idx) { if (gbl.showIdx) { fprintf(gbl.outfp , "%6lld ", idx); } fprintf(gbl.outfp, "status : "); fprintf(gbl.outfp, "status="); switch (tr->status) { case RST_EOF: fprintf(gbl.outfp, "RST_EOF\n"); break; case RST_ERROR: fprintf(gbl.outfp, "RST_ERROR\n"); break; case RST_STATUS_END: fprintf(gbl.outfp, "RST_STATUS_END\n"); break; default: fprintf(gbl.outfp, "Unknown status id: %d\n", tr->status); } } // RSTF_Status::print_rec() virtual void inc_tr() { tr++; } // RSTF_Status::inc_tr() virtual void set_tr(void* ptr, bool set_orig = true) { tr = (rstf_statusT*) ptr; if (set_orig) { tr_orig = tr; } } // RSTF_Status::set_tr() virtual void reset_tr() { tr = tr_orig; } // RSTF_Status::reset_tr() protected: rstf_statusT* tr; rstf_statusT* tr_orig; }; // RSTF_Status //====================================================================== //====================================================================== class RSTF_Patch : public Trace { public: virtual void count() { gbl.rcount++; gbl.patchcount++; } virtual void print_rec(uint64_t idx) { char text[16] = {0}; if (gbl.showIdx) { fprintf(gbl.outfp , "%6lld ", idx); } fprintf(gbl.outfp, "patch : "); fprintf(gbl.outfp, "isbegin=%d ", tr->isBegin); fprintf(gbl.outfp, "rewindrecs=%d ", tr->rewindrecs); fprintf(gbl.outfp, "id=%d ", tr->id); fprintf(gbl.outfp, "length=%d ", tr->length); fprintf(gbl.outfp, "descr=%s", memcpy(text, tr->descr, 8)); fprintf(gbl.outfp, "\n"); } // RSTF_Patch::print_rec() virtual void inc_tr() { tr++; } // RSTF_Patch::inc_tr() virtual void set_tr(void* ptr, bool set_orig = true) { tr = (rstf_patchT*) ptr; if (set_orig) { tr_orig = tr; } } // RSTF_Patch::set_tr() virtual void reset_tr() { tr = tr_orig; } // RSTF_Patch::reset_tr() protected: rstf_patchT* tr; rstf_patchT* tr_orig; }; // RSTF_Patch //====================================================================== //====================================================================== class RSTF_Hwinfo : public Trace { //FIXME nothing is defined yet, stay tune. }; // RSTF_Hwinfo //====================================================================== //====================================================================== class RSTF_Memval64 : public Trace { public: virtual void count() { gbl.rcount++; gbl.memval64count++; } virtual void print_rec(uint64_t idx) { if (gbl.showIdx) { fprintf(gbl.outfp , "%6lld ", idx); } fprintf(gbl.outfp, "mem64 : "); //fprintf(gbl.outfp, "128=%1d ", tr->ismemval128); fprintf(gbl.outfp, "isVA=%1d ", tr->addrisVA); //fprintf(gbl.outfp, "cont=%1d ", tr->isContRec); //fprintf(gbl.outfp, "zero5=%1d ", tr->zero5); fprintf(gbl.outfp, "cpuid=%d ", getCpuID()); fprintf(gbl.outfp, "sz=%d ", tr->size); fprintf(gbl.outfp, "addr=0x%016llx ", tr->addr); fprintf(gbl.outfp, "val=0x%llx ", tr->val); fprintf(gbl.outfp, "\n"); } // RSTF_Memval64::print_rec() virtual void inc_tr() { tr++; } // RSTF_Memval64::inc_tr() virtual void set_tr(void* ptr, bool set_orig = true) { tr = (rstf_memval64T*) ptr; if (set_orig) { tr_orig = tr; } } // RSTF_Memval64::set_tr() virtual void reset_tr() { tr = tr_orig; } // RSTF_Memval64::reset_tr() virtual int getCpuID() { return gbl.rstf_pre212? tr->cpuid: rstf_memval64T_get_cpuid(tr); } protected: rstf_memval64T* tr; rstf_memval64T* tr_orig; }; // RSTF_Memval64 //====================================================================== //====================================================================== class RSTF_Memval128 : public Trace { public: virtual void count() { gbl.rcount++; gbl.memval128count++; } virtual void print_rec(uint64_t idx) { if (gbl.showIdx) { fprintf(gbl.outfp , "%6lld ", idx); } fprintf(gbl.outfp, "mem128 : "); //fprintf(gbl.outfp, "128=%1d ", tr->ismemval128); fprintf(gbl.outfp, "isVA=%1d ", tr->addrisVA); fprintf(gbl.outfp, "cont=%1d ", tr->isContRec); //fprintf(gbl.outfp, "zero5=%1d ", tr->zero5); fprintf(gbl.outfp, "cpuid=%d ", getCpuID()); if (tr->isContRec == 0) { fprintf(gbl.outfp, "addr=0x%016llx ", makeAddr()); } fprintf(gbl.outfp, "val[0]=0x%llx ", tr->val[0]); fprintf(gbl.outfp, "val[1]=0x%llx ", tr->val[1]); fprintf(gbl.outfp, "\n"); } // RSTF_Memval128::print_rec() virtual void inc_tr() { tr++; } // RSTF_Memval128::inc_tr() virtual void set_tr(void* ptr, bool set_orig = true) { tr = (rstf_memval128T*) ptr; if (set_orig) { tr_orig = tr; } } // RSTF_Memval128::set_tr() virtual void reset_tr() { tr = tr_orig; } // RSTF_Memval128::reset_tr() virtual int getCpuID() { return gbl.rstf_pre212? tr->cpuid: rstf_memval128T_get_cpuid(tr); } protected: rstf_memval128T* tr; rstf_memval128T* tr_orig; uint64_t makeAddr() { int64_t addr = 0; int8_t* paddr = (int8_t*) &addr; if (tr->isContRec == 0) { paddr[0] = tr->addr36_43; addr >>= 20; addr |= (tr->addr04_35 << 4); } return (uint64_t) addr; } }; // RSTF_Memval128 //====================================================================== //====================================================================== class RSTF_Bustrace : public Trace { public: virtual void count() { gbl.rcount++; gbl.bustracecount++; } virtual void print_rec(uint64_t idx) { if (gbl.showIdx) { fprintf(gbl.outfp , "%6lld ", idx); } fprintf(gbl.outfp, "bustrace: "); fprintf(gbl.outfp, "dv=%1d ", tr->dirtyvictim); fprintf(gbl.outfp, "sh=%1d ", tr->shared); fprintf(gbl.outfp, "own=%1d ", tr->owned); fprintf(gbl.outfp, "mc=%1d ", tr->memcancel); //fprintf(gbl.outfp, "bt_type=%2d ", tr->bt_type); fprintf(gbl.outfp, "txType=%2d ", tr->txType); fprintf(gbl.outfp, "aid=%2d ", tr->agentid); fprintf(gbl.outfp, "tscale=%1d ", tr->nsScale); fprintf(gbl.outfp, "ts=%7d ", tr->timestamp); fprintf(gbl.outfp, "addr=0x%016llx ", tr->addr_pa); fprintf(gbl.outfp, "\n"); } // RSTF_Bustrace::print_rec() virtual void inc_tr() { tr++; } // RSTF_Bustrace::inc_tr() virtual void set_tr(void* ptr, bool set_orig = true) { tr = (rstf_bustraceT*) ptr; if (set_orig) { tr_orig = tr; } } // RSTF_Bustrace::set_tr() virtual void reset_tr() { tr = tr_orig; } // RSTF_Bustrace::reset_tr() protected: rstf_bustraceT* tr; rstf_bustraceT* tr_orig; }; // RSTF_Bustrace //====================================================================== //====================================================================== class RSTF_Snoop : public Trace { public: virtual void count() { gbl.rcount++; gbl.snoopcount++; } virtual void print_rec(uint64_t idx) { if (gbl.showIdx) { fprintf(gbl.outfp , "%6lld ", idx); } if (tr->device_type == DEVICE_CPU) { fprintf(gbl.outfp, "snoop : cpuid=%d ", tr->device_id); } else { fprintf(gbl.outfp, "snoop : unknown device=%d ", tr->device_id); } switch(tr->snoopreq) { case SNOOP_RTO: fprintf(gbl.outfp, "RTO "); break; case SNOOP_RTS: fprintf(gbl.outfp, "RTS "); break; default: fprintf(gbl.outfp, "Unknown snoop type "); break; } fprintf(gbl.outfp, "[0x%016llx]\n", tr->addr_pa); } // RSTF_Snoop::print_rec() virtual void inc_tr() { tr++; } // RSTF_Snoop::inc_tr() virtual void set_tr(void* ptr, bool set_orig = true) { tr = (rstf_snoopT*) ptr; if (set_orig) { tr_orig = tr; } } // RSTF_Snoop::set_tr() virtual void reset_tr() { tr = tr_orig; } // RSTF_Snoop::reset_tr() protected: rstf_snoopT* tr; rstf_snoopT* tr_orig; }; // RSTF_Snoop class RSTF_tsb_access : public Trace { public: virtual void count() { gbl.rcount++; gbl.tsb_access_count++; } virtual void print_rec(uint64_t idx) { if (gbl.showIdx) { fprintf(gbl.outfp, "%6lld ", idx); } fprintf(gbl.outfp, "tsbaccess: cpuid=%d ", getCpuID()); fprintf(gbl.outfp, "%s ", (tr->isdata? "DTSB": "ITSB")); fprintf(gbl.outfp, "pa=0x%016llx\n", tr->pa); } // RSTF_tsb_access::print_rec() virtual void inc_tr() { tr++; } virtual void set_tr(void * ptr, bool set_orig = true) { tr = (rstf_tsb_accessT*) ptr; if (set_orig) { tr_orig = tr; } } // RSTF_tsb_access::set_tr() virtual void reset_tr() { tr = tr_orig; } virtual int getCpuID() { return gbl.rstf_pre212? tr->cpuid: rstf_tsb_accessT_get_cpuid(tr); } protected: rstf_tsb_accessT * tr; rstf_tsb_accessT * tr_orig; }; // class RSTF_tsb_access : public Trace class RSTF_rfs_section_header : public Trace { public: virtual void count() { gbl.rcount++; gbl.rfs_section_header_count++; } virtual void print_rec(uint64_t idx) { if (gbl.showIdx) { fprintf(gbl.outfp, "%6lld ", idx); } fprintf(gbl.outfp, "rfs_section_header: "); switch(tr->section_type) { case RFS_CW_T: fprintf(gbl.outfp, "CacheWarming: "); break; case RFS_BT_T: fprintf(gbl.outfp, "BranchTrace: "); break; case RFS_RST_T: fprintf(gbl.outfp, "RST Trace: "); break; default: fprintf(gbl.outfp, "Unknown Type: "); break; } if (tr->n_records == rfs_unknown_nrecords) { fprintf(gbl.outfp, "All remaining records\n"); } else { fprintf(gbl.outfp, "%lld records\n", tr->n_records); } } virtual void inc_tr() { tr++; } // RSTF_Snoop::inc_tr() virtual void set_tr(void* ptr, bool set_orig = true) { tr = (rstf_rfs_section_headerT *) ptr; if (set_orig) { tr_orig = tr; } } virtual void reset_tr() { tr = tr_orig; } protected: rstf_rfs_section_headerT * tr; rstf_rfs_section_headerT * tr_orig; }; // class RSTF_rfs_section_header : public Trace class RSTF_bpwarming : public Trace { public: virtual void count() { gbl.rcount++; gbl.bpwarming_count++; } virtual void print_rec(uint64_t idx) { if (gbl.showIdx) { fprintf(gbl.outfp, "%6lld ", idx); } fprintf(gbl.outfp, "bpwarm : "); char dis_string[80]; sprintDiss(dis_string, tr->instr, tr->pc_va); fprintf(gbl.outfp, "cpuid=%d [0x%016llx] %08x %-32s %c [0x%016llx]", getCpuID(), tr->pc_va, tr->instr, dis_string, (tr->taken? 'T' : 'N'), tr->npc_va); } virtual void inc_tr() { tr++; } // RSTF_Snoop::inc_tr() virtual void set_tr(void* ptr, bool set_orig = true) { tr = (rstf_bpwarmingT *) ptr; if (set_orig) { tr_orig = tr; } } virtual void reset_tr() { tr = tr_orig; } virtual int getCpuID() { return gbl.rstf_pre212? tr->cpuid: rstf_bpwarmingT_get_cpuid(tr); } protected: rstf_bpwarmingT * tr; rstf_bpwarmingT * tr_orig; }; // class Rstf_bpwarming: public Trace class RSTF_cachewarming : public Trace { public: virtual void count() { gbl.rcount++; gbl.cachewarming_count++; } virtual void print_rec(uint64_t idx) { if (gbl.showIdx) { fprintf(gbl.outfp, "%6lld ", idx); } fprintf(gbl.outfp, "cachewarm: "); fprintf(gbl.outfp, "cpuid=%d ", getCpuID()); switch(tr->reftype) { case cw_reftype_I: fprintf(gbl.outfp, "ifetch "); break; case cw_reftype_R: fprintf(gbl.outfp, "load "); break; case cw_reftype_W: fprintf(gbl.outfp, "store "); break; case cw_reftype_PF_I: fprintf(gbl.outfp, "i-prefetch "); break; case cw_reftype_PF_D: fprintf(gbl.outfp, "d-prefetch "); break; case cw_reftype_DMA_R: fprintf(gbl.outfp, "dma-read "); break; case cw_reftype_DMA_W: fprintf(gbl.outfp, "dma-write "); break; default: fprintf(gbl.outfp, "unknown reftype "); break; } if (tr->reftype == cw_reftype_DMA_R || tr->reftype == cw_reftype_DMA_W) { fprintf(gbl.outfp, "pa=0x%016llx size=%08x\n", tr->pa, tr->refinfo.dma_size); } else { fprintf(gbl.outfp, "asi=%02x ", tr->refinfo.s.asi); fprintf(gbl.outfp, "va=0x%016llx pa=0x%016llx ", tr->va, tr->pa); if (tr->reftype == cw_reftype_PF_D) { fprintf(gbl.outfp, "fcn=%d\n", tr->refinfo.s.fcn); } else { fprintf(gbl.outfp, "\n"); } } } virtual void inc_tr() { tr++; } // RSTF_Snoop::inc_tr() virtual void set_tr(void* ptr, bool set_orig = true) { tr = (rstf_cachewarmingT *) ptr; if (set_orig) { tr_orig = tr; } } virtual void reset_tr() { tr = tr_orig; } virtual int getCpuID() { return gbl.rstf_pre212 ? tr->cpuid : rstf_cachewarmingT_get_cpuid(tr); } protected: rstf_cachewarmingT * tr; rstf_cachewarmingT * tr_orig; }; // class Rstf_cachewarming: public Trace class RSTF_Trapping_Instr : public Trace { public: virtual void count() { gbl.rcount++; gbl.trappinginstrcount++; } virtual void print_rec(uint64_t idx) { if (gbl.showIdx) { fprintf(gbl.outfp , "%6lld ", idx); } fprintf(gbl.outfp, "tr_instr : cpuid=%d", rstf_trapping_instrT_get_cpuid(tr)); if (tr->hpriv) fprintf(gbl.outfp, " h"); else if (tr->priv) fprintf(gbl.outfp, " p"); else fprintf(gbl.outfp, " u"); fprintf(gbl.outfp, " [0x%016llx] ", tr->pc_va); if (tr->iftrap) { fprintf(gbl.outfp, "ifetch_trap"); } else { fprintf(gbl.outfp, "%08x", tr->instr); // output decoded instr if (tr->ea_va_valid) { fprintf(gbl.outfp, " [%llx]", tr->ea_va); if (tr->ea_pa_valid) { fprintf(gbl.outfp, " ea_pa valid"); } else { fprintf(gbl.outfp, " ea_pa INVALID"); } } // if ea_va_valid } // tr->iftrap? fprintf(gbl.outfp, "\n"); } // RSTF_Trapexit::print_rec() #if 0 virtual uint64_t get_pc() { return tr->pc; } // RSTF_Trapexit::get_pc() #endif virtual void inc_tr() { tr++; } // RSTF_Trapexit::inc_tr() virtual void set_tr(void* ptr, bool set_orig = true) { tr = (rstf_trapping_instrT*) ptr; if (set_orig) { tr_orig = tr; } } // RSTF_Trapexit::set_tr() virtual void reset_tr() { tr = tr_orig; } // RSTF_Trapexit::reset_tr() virtual int getCpuID() { return gbl.rstf_pre212? tr->cpuid: rstf_trapping_instrT_get_cpuid(tr); } protected: rstf_trapping_instrT* tr; rstf_trapping_instrT* tr_orig; }; // RSTF_TRAPPING_INSTR_T //====================================================================== //====================================================================== class RSTF_Timesync : public Trace { public: virtual void count() { gbl.rcount++; gbl.timesynccount++; } virtual void print_rec(uint64_t idx) { if (gbl.showIdx) { fprintf(gbl.outfp , "%6lld ", idx); } fprintf(gbl.outfp, "timesync: cpuid=%d ", getCpuID()); fprintf(gbl.outfp, "seqnum=%llu ", tr->sequence_number); switch(tr->subtype) { case rstf_timesyncT_local: fprintf(gbl.outfp, "local"); break; case rstf_timesyncT_global: fprintf(gbl.outfp, "global"); break; default: fprintf(gbl.outfp, "unknown-sync-type"); break; } fprintf(gbl.outfp, "\n"); } // RSTF_Timesync::print_rec() virtual void inc_tr() { tr++; } // RSTF_TimeSync::inc_tr() virtual void set_tr(void* ptr, bool set_orig = true) { tr = (rstf_timesyncT*) ptr; if (set_orig) { tr_orig = tr; } } // RSTF_Timesync::set_tr() virtual void reset_tr() { tr = tr_orig; } // RSTF_Timesync::reset_tr() virtual int getCpuID() { return rstf_timesyncT_get_cpuid(tr); } protected: rstf_timesyncT* tr; rstf_timesyncT* tr_orig; }; // RSTF_Timesync //====================================================================== //====================================================================== class RSTF_Devidstr : public Trace { public: virtual void count() { gbl.rcount++; gbl.devidstrcount++; } virtual void print_rec(uint64_t idx) { static uint32_t id; static std::string idstring; char cstr[20]; if (gbl.showIdx) { fprintf(gbl.outfp , "%6lld ", idx); } if (tr->id != rstf_devidstr_continuation_id) { id = tr->id; } int i; for (i=0; i<19; i++) { if (tr->str[i] != '\0') { idstring += tr->str[i]; cstr[i] = tr->str[i]; } else { break; } } cstr[i] = 0; fprintf(gbl.outfp, "devidstr: id=%d \"%s\"\n", id, cstr); if (i < 19) { gbl.devid2string[tr->id] = idstring; idstring.clear(); } } // RSTF_Devidstr::print_rec() virtual void inc_tr() { tr++; } // RSTF_Devidstr::inc_tr() virtual void set_tr(void* ptr, bool set_orig = true) { tr = (rstf_devidstrT*) ptr; if (set_orig) { tr_orig = tr; } } // RSTF_Devidstr::set_tr() virtual void reset_tr() { tr = tr_orig; } // RSTF_Devidstr::reset_tr() protected: rstf_devidstrT* tr; rstf_devidstrT* tr_orig; }; // RSTF_Devidstr //====================================================================== //====================================================================== class RSTF_Zero : public Trace { public: virtual void count() { gbl.rcount++; gbl.zerocount++; } virtual void print_rec(uint64_t idx) { if (gbl.showIdx) { fprintf(gbl.outfp , "%6lld\t\tZero Record", idx); } } // RSTF_Zero::print_rec() virtual void inc_tr() { tr++; } // RSTF_Zero::inc_tr() virtual void set_tr(void* ptr, bool set_orig = true) { tr = (rstf_xxxT*) ptr; if (set_orig) { tr_orig = tr; } } // RSTF_Zero::set_tr() virtual void reset_tr() { tr = tr_orig; } // RSTF_Zero::reset_tr() protected: rstf_xxxT* tr; rstf_xxxT* tr_orig; }; // RSTF_Zero //====================================================================== //====================================================================== class RSTF_Unknown : public Trace { public: virtual void count() { gbl.rcount++; gbl.unknowncount++; } virtual void print_rec(uint64_t idx) { if (gbl.showIdx) { fprintf(gbl.outfp , "%6lld ", idx); } fprintf(gbl.outfp, "unknown : [Unsupported record type; rtype=%d]\n", tr->rtype); } // RSTF_Unknown::print_rec() virtual void inc_tr() { tr++; } // RSTF_Unknown::inc_tr() virtual void set_tr(void* ptr, bool set_orig = true) { tr = (rstf_protoT*) ptr; if (set_orig) { tr_orig = tr; } } // RSTF_Unknown::set_tr() virtual void reset_tr() { tr = tr_orig; } // RSTF_Unknown::reset_tr() protected: rstf_protoT* tr; rstf_protoT* tr_orig; }; // RSTF_Unknown //====================================================================== //====================================================================== class RSTF_Union : public Trace { public: virtual void count() { Trace* tr_trace; #if defined(ARCH_AMD64) rstf_convertT::b2l((rstf_uint8T *)tr); #endif tr_trace = get_rst_type(); if (tr_trace != NULL) { tr_trace->set_tr(tr, false); tr_trace->count(); } } // RSTF_Union::count() virtual void print_dasm(uint64_t idx) { Trace* tr_trace; print_header(); if (gbl.onlyIns) { if (tr->proto.rtype == INSTR_T) { tr_instr.set_tr(tr, false); tr_instr.print_dasm(idx); } } else { tr_trace = get_rst_type(); if (gbl.noIns && tr->proto.rtype == INSTR_T) { tr_trace = NULL; } if (tr_trace) { tr_trace->set_tr(tr, false); tr_trace->print_dasm(idx); } } } // RSTF_Union::print_dasm() virtual void print_rec(uint64_t idx) { Trace* tr_trace; print_header(); if (gbl.onlyIns) { if (tr->proto.rtype == INSTR_T) { tr_instr.set_tr(tr, false); tr_instr.print_rec(idx); } } else { tr_trace = get_rst_type(); if (gbl.noIns && tr->proto.rtype == INSTR_T) { tr_trace = NULL; } if (tr_trace) { tr_trace->set_tr(tr, false); tr_trace->print_rec(idx); } } } // RSTF_Union::print_rec() virtual void print_verb(uint64_t idx) { Trace* tr_trace; print_header(); if (gbl.onlyIns) { if (tr->proto.rtype == INSTR_T) { tr_instr.set_tr(tr, false); tr_instr.print_verb(idx); } } else { tr_trace = get_rst_type(); if (gbl.noIns && tr->proto.rtype == INSTR_T) { tr_trace = NULL; } if (tr_trace) { tr_trace->set_tr(tr, false); tr_trace->print_verb(idx); } } } // RSTF_Union::print_verb() virtual void convert_to_master() { if (tr->proto.rtype == INSTR_T) { tr_instr.set_tr(tr, false); tr_instr.convert_to_master(); } } // RSTF_Union::convert_to_master() virtual void convert_from_master(Tmaster64* master) { tr_instr.set_tr(tr, false); tr_instr.convert_from_master(master); } // RSTF_Union::convert_from_master() virtual void gen_ihash() { if (tr->proto.rtype == INSTR_T) { tr_instr.set_tr(tr, false); tr_instr.gen_ihash(); } } // RSTF_Union::gen_ihash() virtual int check_ihash_error() { if (tr->proto.rtype == INSTR_T) { tr_instr.set_tr(tr, false); return tr_instr.check_ihash_error(); } return 0; } // RSTF_Union::check_ihash_error() // check pc value of last NUM_VERIFY records in buffer virtual void verify() { tr_instr.set_tr(tr_orig, true); tr_instr.set_tr(tr, false); tr_instr.verify(); } // RSTF_Union::verify() virtual uint64_t get_pc() { switch (tr->proto.rtype) { case INSTR_T: return tr->instr.pc_va; case TRAP_T: return tr->trap.pc; #if 0 case TRAPEXIT_T: return tr->trapexit.pc; #endif } return RSTF_NOADDR; } // RSTF_Union::get_pc() virtual uint64_t get_ea() { if (tr->proto.rtype == INSTR_T) { if (tr->instr.ea_valid) { return tr->instr.ea_va; } } return RSTF_NOADDR; } // RSTF_Union::get_ea() virtual int get_ihash() { if (tr->proto.rtype == INSTR_T) { return spix_sparc_iop(SPIX_SPARC_V9, &tr->instr.instr); // return tr->instr.ihash; } return 0; } // RSTF_Union::get_ihash() virtual void inc_tr() { tr++; } // RSTF_Union::inc_tr() virtual void set_tr(void* ptr, bool set_orig = true) { tr = (rstf_unionT*) ptr; if (set_orig) { tr_orig = tr; } } // RSTF_Union::set_tr() virtual void reset_tr() { tr = tr_orig; } // RSTF_Union::reset_tr() virtual rstf_unionT* copy_from_rst() { return tr; } // RSTF_Union::copy_from_rst() virtual void copy_to_rst(rstf_unionT* from) { *tr = *from; } // RSTF_Union::copy_to_rst() virtual int getCpuID() { return get_rst_type()->getCpuID(); } protected: rstf_unionT* tr; rstf_unionT* tr_orig; RSTF_Header tr_header; RSTF_Instr tr_instr; //RSTF_Asi tr_asi; RSTF_Traceinfo tr_traceinfo; RSTF_Tlb tr_tlb; RSTF_Thread tr_thread; RSTF_Trap tr_trap; RSTF_Trapexit tr_trapexit; RSTF_Trapping_Instr tr_trapping_instr; RSTF_Bustrace tr_bustrace; RSTF_Regval tr_regval; RSTF_Memval64 tr_memval64; RSTF_Memval128 tr_memval128; RSTF_Cpu tr_cpu; RSTF_Process tr_process; RSTF_Dma tr_dma; RSTF_String tr_string; RSTF_Delim tr_delim; RSTF_Preg tr_preg; RSTF_Physaddr tr_physaddr; RSTF_Pavadiff tr_pavadiff; RSTF_Filemarker tr_filemarker; RSTF_Status tr_status; RSTF_Patch tr_patch; //RSTF_Hwinfo tr_hwinfo; //RSTF_Memval tr_memval; RSTF_Snoop tr_snoop; RSTF_tsb_access tr_tsb_access; RSTF_rfs_section_header tr_rfs_shdr; RSTF_bpwarming tr_bpwarming; RSTF_cachewarming tr_cachewarming; RSTF_Timesync tr_timesync; RSTF_Devidstr tr_devidstr; RSTF_Zero tr_zero; RSTF_Unknown tr_unknown; Trace* get_rst_type() { int cpuid = -1; switch (tr->proto.rtype) { case RSTHEADER_T: return &tr_header; case INSTR_T: return &tr_instr; //case ASI_T: // ASI is deprecated. ASI_T == TRACEINFO_T //return &tr_asi; case TRACEINFO_T: return &tr_traceinfo; case TLB_T: return &tr_tlb; case THREAD_T: return &tr_thread; case TRAP_T: return &tr_trap; case TRAPEXIT_T: return &tr_trapexit; case TRAPPING_INSTR_T: return & tr_trapping_instr; case BUSTRACE_T: return &tr_bustrace; case REGVAL_T: return &tr_regval; case MEMVAL_T: if (tr->memval64.ismemval128) { return &tr_memval128; } return &tr_memval64; case CPU_T: // CPU_T == TIMESTAMP_T return &tr_cpu; case PROCESS_T: return &tr_process; case DMA_T: return &tr_dma; case STRDESC_T: case STRCONT_T: return &tr_string; case LEFTDELIM_T: case RIGHTDELIM_T: return &tr_delim; case PREG_T: gbl.pstate[gbl.rstf_pre212? tr->preg.cpuid: rstf_pregT_get_cpuid(&tr->preg)] = tr->preg.pstate; return &tr_preg; case PHYSADDR_T: return &tr_physaddr; case PAVADIFF_T: #ifdef _PRINT_PA cpuid = gbl.rstf_pre212? tr->pavadiff.cpuid: rstf_pavadiffT_get_cpuid(&tr->pavadiff); if (tr->pavadiff.ea_valid) { gbl.ea_pavadiff_valid[cpuid] = true; gbl.ea_pavadiff_value[cpuid] = tr->pavadiff.ea_pa_va; } gbl.pc_pavadiff_value[cpuid] = tr->pavadiff.pc_pa_va; gbl.pc_pavadiff_valid[cpuid] = true; #endif return &tr_pavadiff; case FILEMARKER_T: // FILEMARKER_T == RECNUM_T return &tr_filemarker; case STATUS_T: return &tr_status; case PATCH_T: return &tr_patch; case HWINFO_T: //return &tr_hwinfo; return &tr_unknown; case SNOOP_T: return &tr_snoop; case TSB_ACCESS_T: return &tr_tsb_access; case RFS_SECTION_HEADER_T: return &tr_rfs_shdr; case RFS_BT_T: return & tr_bpwarming; case RFS_CW_T: return & tr_cachewarming; case TIMESYNC_T: return & tr_timesync; case DEVIDSTR_T: return & tr_devidstr; case RST_ZERO_T: return &tr_zero; default: return &tr_unknown; } } // RSTF_Union::get_rst_type() void print_header() { static bool prheader = true; if (prheader) { fprintf(gbl.outfp, "RST trace format (%s)\n", gbl.infile); fprintf(gbl.outfp, "================\n"); if (!gbl.noIns) { if (gbl.disassembly) { if (gbl.showIdx) { fprintf(gbl.outfp, " User/ Branch\n" " Rec # Type Priv PC Disassembly Taken EA \n"); } else { fprintf(gbl.outfp, " User/ Branch\n" "Type Priv PC Disassembly Taken EA \n"); } } else if (gbl.verbose) { if (gbl.showIdx) { fprintf(gbl.outfp, " User/ Br\n" " Rec # Type Priv PC Disassembly Instr Word IH Tk EA (x = invalid ea)\n"); } else { fprintf(gbl.outfp, " User/ Br\n" "Type Priv PC Disassembly Instr Word IH Tk EA (x = invalid ea)\n"); } } } prheader = false; } } // RSTF_Union::print_header() }; // RSTF_Union //====================================================================== //====================================================================== // Trtf99 and Tshade5 use Shade5 ihash values; // all other formats use the Shade6 ihash values. // class rtf99 : public Trace { public: virtual void print_dasm(uint64_t idx) { char dis_string[80]; sprintDiss(dis_string, tr->tr_i, tr->tr_pc); print_header(); if (gbl.showIdx) { fprintf(gbl.outfp , "%6lld ", idx); } fprintf(gbl.outfp, "[0x%08x] ", tr->tr_pc); fprintf(gbl.outfp, "%-32s", dis_string); fprintf(gbl.outfp, "[0x%08x] ", tr->tr_ea); fprintf(gbl.outfp, "0x%x", tr->tr_misc); fprintf(gbl.outfp, "\n"); } // rtf99::print_dasm() virtual void print_rec(uint64_t idx) { print_header(); if (gbl.showIdx) { fprintf(gbl.outfp , "%6lld ", idx); } fprintf(gbl.outfp, "[0x%08x] ", tr->tr_pc); fprintf(gbl.outfp, "(0x%08x) ", tr->tr_i); fprintf(gbl.outfp, "%3d ", tr->tr_ih); fprintf(gbl.outfp, "[0x%08x] ", tr->tr_ea); fprintf(gbl.outfp, "0x%x ", tr->tr_misc); fprintf(gbl.outfp, "\n"); } // rtf99::print_rec() virtual void print_verb(uint64_t idx) { char dis_string[80]; sprintDiss(dis_string, tr->tr_i, tr->tr_pc); print_header(); if (gbl.showIdx) { fprintf(gbl.outfp , "%6lld ", idx); } fprintf(gbl.outfp, "[0x%08x] ", tr->tr_pc); fprintf(gbl.outfp, "%-32s", dis_string); fprintf(gbl.outfp, "(0x%08x) ", tr->tr_i); fprintf(gbl.outfp, "%3d ", tr->tr_ih); fprintf(gbl.outfp, "[0x%08x] ", tr->tr_ea); fprintf(gbl.outfp, "0x%x", tr->tr_misc); fprintf(gbl.outfp, "\n"); } // rtf99::print_verb() virtual void convert_to_master() { this_master.tr_pc_va = tr->tr_pc; this_master.tr_ea_va = tr->tr_ea ; this_master.tr_tid = 0; this_master.tr_ih = tr->tr_ih; this_master.tr_reserved0 = 0; this_master.tr_taken = tr->tr_misc & 1; this_master.tr_annulled = (tr->tr_misc << 1) & 1; this_master.tr_iwstart = 0; this_master.tr_i = tr->tr_i; this_master.tr_reserved1 = 0; this_master.tr_pc_pa = 0; this_master.tr_ea_pa = 0; this_master.tr_context = 0; this_master.tr_asi = 0; this_master.tr_got_trap = 0; this_master.tr_asi_change = 0; this_master.tr_privmode = 0; } // rtf99::convert_to_master() virtual void convert_from_master(Tmaster64* master) { tr->tr_pc = (uint32_t)master->tr_pc_va; tr->tr_ea = (uint32_t)master->tr_ea_va; tr->tr_ih = master->tr_ih; tr->tr_misc = master->tr_taken + (master->tr_annulled >> 1); tr->tr_i = master->tr_i; } // rtf99::convert_from_master() virtual void gen_ihash() { tr->tr_ih = getIHash(tr->tr_i); } // tfr99::gen_ihash() virtual int check_ihash_error() { if (tr->tr_ih != getIHash(tr->tr_i)) { return 1; } return 0; } // rtf99::check_ihash_error() virtual void verify() { Trtf99 * vtr = tr - NUM_VERIFY; int i; for (i = 0; i < NUM_VERIFY - 1; i++) { if (vtr[i].tr_pc % 4 != 0 && RSTF_IS_BADADDR(vtr[i].tr_pc) == 0) { fprintf(stderr, "trconv: Error: Incorrect pc value in input file.\n"); set_tr(&vtr[i], false); print_verb(gbl.rcount - NUM_VERIFY + i); //exit(2); } } } // rtf99::verify() virtual uint64_t get_pc() { return tr->tr_pc; } // rtf99::get_pc() virtual uint64_t get_ea() { return tr->tr_ea; } // rtf99::get_ea() virtual int get_ihash() { return tr->tr_ih; } // rtf99::get_ihash() virtual void inc_tr() { tr++; } // rtf99::inc_tr() virtual void set_tr(void* ptr, bool set_orig = true) { tr = (Trtf99 *) ptr; if (set_orig) { tr_orig = tr; } } // rtf99::set_tr() virtual void reset_tr() { tr = tr_orig; } // rtf99::reset_tr() protected: Trtf99 * tr; Trtf99 * tr_orig; void print_header() { static bool prheader = false; if (!prheader) { fprintf(gbl.outfp, "rtf99 trace format (%s)\n", gbl.infile); fprintf(gbl.outfp, "====================\n"); if (gbl.record) { if (gbl.showIdx) { fprintf(gbl.outfp, " Rec # tr_pc tr_i " "tr_ih tr_ea misc\n"); } else { fprintf(gbl.outfp, " tr_pc tr_i " "tr_ih tr_ea misc\n"); } } else if (gbl.disassembly) { if (gbl.showIdx) { fprintf(gbl.outfp, " Rec # PC Disassembly" " EA Misc\n"); } else { fprintf(gbl.outfp, " PC Disassembly" " EA Misc\n"); } } else { if (gbl.showIdx) { fprintf(gbl.outfp, " Rec # PC Disassembly" " Instr Word IH EA\n"); } else { fprintf(gbl.outfp, " PC Disassembly" " Instr Word IH EA\n"); } } prheader = true; } } // rtf99::print_header() }; // rtf99 // Trtf99 and Tshade5 use Shade5 ihash values; // all other formats use the Shade6 ihash values. class Shade5 : public Trace { public: virtual void print_dasm(uint64_t idx) { char dis_string[80]; sprintDiss(dis_string, tr->tr_i, tr->tr_pc); print_header(); if (gbl.showIdx) { fprintf(gbl.outfp , "%6lld ", idx); } fprintf(gbl.outfp, "[0x%08x] ", tr->tr_pc); fprintf(gbl.outfp, "%-32s", dis_string); if (ih_iscti(tr->tr_ih)) { if (tr->tr_taken) { fprintf(gbl.outfp, "T "); } else { fprintf(gbl.outfp, "N "); } } else { fprintf(gbl.outfp, " "); } if (tr->tr_annulled) { fprintf(gbl.outfp, "an "); } else { fprintf(gbl.outfp, "[0x%08x] ", tr->tr_ea); } fprintf(gbl.outfp, "\n"); } // Shade5::print_dasm() virtual void print_rec(uint64_t idx) { print_header(); if (gbl.showIdx) { fprintf(gbl.outfp , "%6lld ", idx); } fprintf(gbl.outfp, "[0x%08x] ", tr->tr_pc); fprintf(gbl.outfp, "(0x%08x) ", tr->tr_i); fprintf(gbl.outfp, "%3d ", tr->tr_ih); if (ih_iscti(tr->tr_ih)) { if (tr->tr_taken) { fprintf(gbl.outfp, "T "); } else { fprintf(gbl.outfp, "N "); } } else { fprintf(gbl.outfp, " "); } fprintf(gbl.outfp, "[0x%08x] ", tr->tr_ea); fprintf(gbl.outfp, "%d ", tr->tr_annulled); fprintf(gbl.outfp, "\n"); } // Shade5::print_rec() virtual void print_verb(uint64_t idx) { char dis_string[80]; sprintDiss(dis_string, tr->tr_i, tr->tr_pc); print_header(); if (gbl.showIdx) { fprintf(gbl.outfp , "%6lld ", idx); } fprintf(gbl.outfp, "[0x%08x] ", tr->tr_pc); fprintf(gbl.outfp, "%-32s", dis_string); fprintf(gbl.outfp, "(0x%08x) ", tr->tr_i); fprintf(gbl.outfp, "%3d ", tr->tr_ih); if (ih_iscti(tr->tr_ih)) { if (tr->tr_taken) { fprintf(gbl.outfp, "T "); } else { fprintf(gbl.outfp, "N "); } } else { fprintf(gbl.outfp, " "); } fprintf(gbl.outfp, "[0x%08x] ", tr->tr_ea); if (tr->tr_annulled) { fprintf(gbl.outfp, "an "); } fprintf(gbl.outfp, "\n"); } // Shade5::print_verb() virtual void convert_to_master() { this_master.tr_pc_va = tr->tr_pc; this_master.tr_ea_va = tr->tr_ea ; this_master.tr_tid = 0; this_master.tr_ih = tr->tr_ih; this_master.tr_reserved0 = 0; this_master.tr_taken = tr->tr_taken; this_master.tr_annulled = tr->tr_annulled; this_master.tr_iwstart = 0; this_master.tr_i = tr->tr_i; this_master.tr_reserved1 = 0; this_master.tr_pc_pa = 0; this_master.tr_ea_pa = 0; this_master.tr_context = 0; this_master.tr_asi = 0; this_master.tr_got_trap = 0; this_master.tr_asi_change = 0; this_master.tr_privmode = 0; } // Shade5::convert_to_master() virtual void convert_from_master(Tmaster64* master) { tr->tr_pc = (uint32_t) master->tr_pc_va; tr->tr_ea = (uint32_t) master->tr_ea_va; tr->tr_ih = master->tr_ih; tr->tr_taken = master->tr_taken; tr->tr_annulled = master->tr_annulled; tr->tr_i = master->tr_i; } // Shade5::convert_from_master() virtual void gen_ihash() { tr->tr_ih = getIHash(tr->tr_i); } // Shade5::gen_ihash() virtual int check_ihash_error() { if (tr->tr_ih != getIHash(tr->tr_i)) { return 1; } return 0; } // Shade5::check_ihash_error() virtual void verify() { Tshade5* vtr = tr - NUM_VERIFY; int i; for (i = 0; i < NUM_VERIFY - 1; i++) { if (vtr[i].tr_pc % 4 != 0 && RSTF_IS_BADADDR(vtr[i].tr_pc) == 0) { fprintf(stderr, "trconv: Error: Incorrect pc value in input file.\n"); set_tr(&vtr[i], false); print_verb(gbl.rcount - NUM_VERIFY + i); //exit(2); } } } // Shade5::verify() virtual uint64_t get_pc() { return tr->tr_pc; } // Shade5::get_pc() virtual uint64_t get_ea() { return tr->tr_ea; } // Shade5::get_ea() virtual int get_ihash() { return tr->tr_ih; } // Shade5::get_ihash() virtual void inc_tr() { tr++; } // Shade5::inc_tr() virtual void set_tr(void* ptr, bool set_orig = true) { tr = (Tshade5*) ptr; if (set_orig) { tr_orig = tr; } } // Shade5::set_tr() virtual void reset_tr() { tr = tr_orig; } // Shade5::reset_tr() protected: Tshade5* tr; Tshade5* tr_orig; void print_header() { static bool prheader = true; if (prheader) { fprintf(gbl.outfp, "Shade5 trace format (%s)\n", gbl.infile); fprintf(gbl.outfp, "=====================\n"); if (gbl.record) { if (gbl.showIdx) { fprintf(gbl.outfp, " Rec # tr_pc tr_i " "tr_ih tr_ea an\n"); } else { fprintf(gbl.outfp, " tr_pc tr_i " "tr_ih tr_ea an\n"); } } else if (gbl.disassembly) { if (gbl.showIdx) { fprintf(gbl.outfp, " " " Br\n" " Rec # PC Disassembly" " Tk EA\n"); } else { fprintf(gbl.outfp, " " " Br\n" " PC Disassembly" " Tk EA\n"); } } else { if (gbl.showIdx) { fprintf(gbl.outfp, " " " Br\n" " Rec # PC Disassembly" " Instr Word IH Tk EA\n"); } else { fprintf(gbl.outfp, " " " Br\n" " PC Disassembly" " Instr Word IH Tk EA\n"); } } prheader = false; } } }; // Shade5 class Shade6x32 : public Trace { public: virtual void print_dasm(uint64_t idx) { char dis_string[80]; sprintDiss(dis_string, tr->tr_i, tr->tr_pc); print_header(); if (gbl.showIdx) { fprintf(gbl.outfp , "%6lld ", idx); } fprintf(gbl.outfp, "[0x%08x] ", tr->tr_pc); fprintf(gbl.outfp, "%-32s", dis_string); if (ih_iscti(tr->tr_ih)) { if (tr->tr_taken) { fprintf(gbl.outfp, "T "); } else { fprintf(gbl.outfp, "N "); } } else { fprintf(gbl.outfp, " "); } if (tr->tr_annulled) { fprintf(gbl.outfp, "an "); } else { fprintf(gbl.outfp, "[0x%08x] ", tr->tr_ea); } if (tr->tr_tid) { fprintf(gbl.outfp, "[0x%08x] ", tr->tr_tid); } if (tr->tr_iwstart) { fprintf(gbl.outfp, "wi "); } fprintf(gbl.outfp, "\n"); } // Shade6x32::print_dasm() virtual void print_rec(uint64_t idx) { print_header(); if (gbl.showIdx) { fprintf(gbl.outfp , "%6lld ", idx); } fprintf(gbl.outfp, "[0x%08x] ", tr->tr_pc); fprintf(gbl.outfp, "(0x%08x) ", tr->tr_i); fprintf(gbl.outfp, "%3d ", tr->tr_ih); if (ih_iscti(tr->tr_ih)) { if (tr->tr_taken) { fprintf(gbl.outfp, "T "); } else { fprintf(gbl.outfp, "N "); } } else { fprintf(gbl.outfp, " "); } fprintf(gbl.outfp, "[0x%08x] ", tr->tr_ea); fprintf(gbl.outfp, "%d ", tr->tr_annulled); fprintf(gbl.outfp, "%d ", tr->tr_iwstart); fprintf(gbl.outfp, "0x%08x ", tr->tr_tid); fprintf(gbl.outfp, "\n"); } // Shade6x32::print_rec() virtual void print_verb(uint64_t idx) { char dis_string[80]; sprintDiss(dis_string, tr->tr_i, tr->tr_pc); print_header(); if (gbl.showIdx) { fprintf(gbl.outfp , "%6lld ", idx); } fprintf(gbl.outfp, "[0x%08x] ", tr->tr_pc); fprintf(gbl.outfp, "%-32s", dis_string); fprintf(gbl.outfp, "(0x%08x) ", tr->tr_i); fprintf(gbl.outfp, "%3d ", tr->tr_ih); if (ih_iscti(tr->tr_ih)) { if (tr->tr_taken) { fprintf(gbl.outfp, "T "); } else { fprintf(gbl.outfp, "N "); } } else { fprintf(gbl.outfp, " "); } fprintf(gbl.outfp, "[0x%08x] ", tr->tr_ea); if (tr->tr_annulled) { fprintf(gbl.outfp, "an "); } if (tr->tr_tid) { fprintf(gbl.outfp, "[0x%08x] ", tr->tr_tid); } if (tr->tr_iwstart) { fprintf(gbl.outfp, "wi "); } fprintf(gbl.outfp, "\n"); } // Shade6x32::print_verb() virtual void convert_to_master() { this_master.tr_pc_va = tr->tr_pc; this_master.tr_ea_va = tr->tr_ea ; this_master.tr_tid = tr->tr_tid; this_master.tr_ih = tr->tr_ih; this_master.tr_reserved0 = tr->tr_shade_reserved0; this_master.tr_taken = tr->tr_taken; this_master.tr_annulled = tr->tr_annulled; this_master.tr_iwstart = tr->tr_iwstart; this_master.tr_i = tr->tr_i; this_master.tr_reserved1 = tr->tr_shade_reserved1; this_master.tr_pc_pa = 0; this_master.tr_ea_pa = 0; this_master.tr_context = 0; this_master.tr_asi = 0; this_master.tr_got_trap = 0; this_master.tr_asi_change = 0; this_master.tr_privmode = 0; } // Shade6x32::convert_to_master() virtual void convert_from_master(Tmaster64* master) { tr->tr_pc = (uint32_t)master->tr_pc_va; tr->tr_ea = (uint32_t)master->tr_ea_va ; tr->tr_tid = master->tr_tid; tr->tr_ih = master->tr_ih; tr->tr_ih = tr->tr_ih; tr->tr_shade_reserved0 = master->tr_reserved0; tr->tr_taken = master->tr_taken; tr->tr_annulled = master->tr_annulled; tr->tr_iwstart = master->tr_iwstart; tr->tr_i = master->tr_i; tr->tr_shade_reserved1 = master->tr_reserved1; } // Shade6x32::convert_from_master() virtual void gen_ihash() { tr->tr_ih = getIHash(tr->tr_i); } // Shade6x32::gen_ihash() virtual int check_ihash_error() { if (tr->tr_ih != getIHash(tr->tr_i)) { return 1; } return 0; } // Shade6x32::check_ihash_error() virtual void verify() { Tshade6x32* vtr = tr - NUM_VERIFY; int i; for (i = 0; i < NUM_VERIFY - 1; i++) { if (vtr[i].tr_pc % 4 != 0 && RSTF_IS_BADADDR(vtr[i].tr_pc) == 0) { fprintf(stderr, "trconv: Error: Incorrect pc value in input file.\n"); set_tr(&vtr[i], false); print_verb(gbl.rcount - NUM_VERIFY + i); //exit(2); } } } // Shade6x32::verify() virtual uint64_t get_pc() { return tr->tr_pc; } // Shade6x32::get_pc() virtual uint64_t get_ea() { return tr->tr_ea; } // Shade6x32::get_ea() virtual int get_ihash() { return tr->tr_ih; } // Shade6x32::get_ihash() virtual void inc_tr() { tr++; } // Shade6x32::inc_tr() virtual void set_tr(void* ptr, bool set_orig = true) { tr = (Tshade6x32*) ptr; if (set_orig) { tr_orig = tr; } } // Shade6x32::set_tr() virtual void reset_tr() { tr = tr_orig; } // Shade6x32::reset_tr() protected: Tshade6x32* tr; Tshade6x32* tr_orig; void print_header() { static bool prheader = true; if (prheader) { fprintf(gbl.outfp, "Shade6 (32bit) trace format (%s)\n", gbl.infile); fprintf(gbl.outfp, "=============================\n"); if (gbl.record) { if (gbl.showIdx) { fprintf(gbl.outfp, " Rec # tr_pc tr_i " "tr_ih tr_ea a w tr_tid\n"); } else { fprintf(gbl.outfp, " tr_pc tr_i " "tr_ih tr_ea a w tr_tid\n"); } } else if (gbl.disassembly) { if (gbl.showIdx) { fprintf(gbl.outfp, " " " Br\n" " Rec # PC Disassembly" " Tk EA\n"); } else { fprintf(gbl.outfp, " " " Br\n" " PC Disassembly" " Tk EA\n"); } } else { if (gbl.showIdx) { fprintf(gbl.outfp, " " " Br\n" " Rec # PC Disassembly" " Instr Word IH Tk EA\n"); } else { fprintf(gbl.outfp, " " " Br\n" " PC Disassembly" " Instr Word IH Tk EA\n"); } } prheader = false; } } }; // Shade6x32 class Shade6x64 : public Trace { public: virtual void print_dasm(uint64_t idx) { char dis_string[80]; sprintDiss(dis_string, tr->tr_i, tr->tr_pc); print_header(); if (gbl.showIdx) { fprintf(gbl.outfp , "%6lld ", idx); } fprintf(gbl.outfp, "[0x%016llx] ", tr->tr_pc); fprintf(gbl.outfp, "%-32s", dis_string); if (ih_iscti(tr->tr_ih)) { if (tr->tr_taken) { fprintf(gbl.outfp, "T "); } else { fprintf(gbl.outfp, "N "); } } else { fprintf(gbl.outfp, " "); } if (tr->tr_annulled) { fprintf(gbl.outfp, "an "); } else { fprintf(gbl.outfp, "[0x%016llx] ", tr->tr_ea); } if (tr->tr_tid) { fprintf(gbl.outfp, "[0x%08x] ", tr->tr_tid); } if (tr->tr_iwstart) { fprintf(gbl.outfp, "wi "); } fprintf(gbl.outfp, "\n"); } // Shade6x64::print_dasm() virtual void print_rec(uint64_t idx) { print_header(); if (gbl.showIdx) { fprintf(gbl.outfp , "%6lld ", idx); } fprintf(gbl.outfp, "[0x%016llx] ", tr->tr_pc); fprintf(gbl.outfp, "(0x%08x) ", tr->tr_i); fprintf(gbl.outfp, "%3d ", tr->tr_ih); if (ih_iscti(tr->tr_ih)) { if (tr->tr_taken) { fprintf(gbl.outfp, "T "); } else { fprintf(gbl.outfp, "N "); } } else { fprintf(gbl.outfp, " "); } fprintf(gbl.outfp, "[0x%016llx] ", tr->tr_ea); fprintf(gbl.outfp, "%d ", tr->tr_annulled); fprintf(gbl.outfp, "%d ", tr->tr_iwstart); fprintf(gbl.outfp, "0x%08x ", tr->tr_tid); fprintf(gbl.outfp, "\n"); } // Shade6x64::print_rec() virtual void print_verb(uint64_t idx) { char dis_string[80]; sprintDiss(dis_string, tr->tr_i, tr->tr_pc); print_header(); if (gbl.showIdx) { fprintf(gbl.outfp , "%6lld ", idx); } fprintf(gbl.outfp, "[0x%016llx] ", tr->tr_pc); fprintf(gbl.outfp, "%-32s", dis_string); fprintf(gbl.outfp, "(0x%08x) ", tr->tr_i); fprintf(gbl.outfp, "%3d ", tr->tr_ih); if (ih_iscti(tr->tr_ih)) { if (tr->tr_taken) { fprintf(gbl.outfp, "T "); } else { fprintf(gbl.outfp, "N "); } } else { fprintf(gbl.outfp, " "); } fprintf(gbl.outfp, "[0x%016llx] ", tr->tr_ea); if (tr->tr_annulled) { fprintf(gbl.outfp, "an "); } if (tr->tr_tid) { fprintf(gbl.outfp, "[0x%08x] ", tr->tr_tid); } if (tr->tr_iwstart) { fprintf(gbl.outfp, "wi "); } fprintf(gbl.outfp, "\n"); } // Shade6x64::print_verb() virtual void convert_to_master() { this_master.tr_pc_va = tr->tr_pc; this_master.tr_ea_va = tr->tr_ea ; this_master.tr_tid = tr->tr_tid; this_master.tr_ih = tr->tr_ih; this_master.tr_reserved0 = tr->tr_shade_reserved0; this_master.tr_taken = tr->tr_taken; this_master.tr_annulled = tr->tr_annulled; this_master.tr_iwstart = tr->tr_iwstart; this_master.tr_i = tr->tr_i; this_master.tr_reserved1 = tr->tr_shade_reserved1; this_master.tr_pc_pa = 0; this_master.tr_ea_pa = 0; this_master.tr_context = 0; this_master.tr_asi = 0; this_master.tr_got_trap = 0; this_master.tr_asi_change = 0; this_master.tr_privmode = 0; } // Shade6x64::convert_to_master() virtual void convert_from_master(Tmaster64* master) { tr->tr_pc = master->tr_pc_va; tr->tr_ea = master->tr_ea_va ; tr->tr_tid = master->tr_tid; tr->tr_ih = master->tr_ih; tr->tr_shade_reserved0 = master->tr_reserved0; tr->tr_taken = master->tr_taken; tr->tr_annulled = master->tr_annulled; tr->tr_iwstart = master->tr_iwstart; tr->tr_i = master->tr_i; tr->tr_shade_reserved1 = master->tr_reserved1; } // Shade6x64::convert_from_master() virtual void gen_ihash() { tr->tr_ih = getIHash(tr->tr_i); } // Shade6x64::gen_ihash() virtual int check_ihash_error() { if (tr->tr_ih != getIHash(tr->tr_i)) { return 1; } return 0; } // Shade6x64::check_ihash_error() virtual void verify() { Tshade6x64* vtr = tr - NUM_VERIFY; int i; for (i = 0; i < NUM_VERIFY - 1; i++) { if (vtr[i].tr_pc % 4 != 0 && RSTF_IS_BADADDR(vtr[i].tr_pc) == 0) { fprintf(stderr, "trconv: Error: Incorrect pc value in input file.\n"); set_tr(&vtr[i], false); print_verb(gbl.rcount - NUM_VERIFY + i); //exit(2); } } } // Shade6x64::verify() virtual uint64_t get_pc() { return tr->tr_pc; } // Shade6x64::get_pc() virtual uint64_t get_ea() { return tr->tr_ea; } // Shade6x64::get_ea() virtual int get_ihash() { return tr->tr_ih; } // Shade6x64::get_ihash() virtual void inc_tr() { tr++; } // Shade6x64::inc_tr() virtual void set_tr(void* ptr, bool set_orig = true) { tr = (Tshade6x64*) ptr; if (set_orig) { tr_orig = tr; } } // Shade6x64::set_tr() virtual void reset_tr() { tr = tr_orig; } // Shade6x64::reset_tr() protected: Tshade6x64* tr; Tshade6x64* tr_orig; void print_header() { static bool prheader = true; if (prheader) { fprintf(gbl.outfp, "Shade6 (64bit) trace format (%s)\n", gbl.infile); fprintf(gbl.outfp, "=============================\n"); if (gbl.record) { if (gbl.showIdx) { fprintf(gbl.outfp, " Rec # tr_pc tr_i " "tr_ih tr_ea a w tr_tid\n"); } else { fprintf(gbl.outfp, " tr_pc tr_i " "tr_ih tr_ea a w tr_tid\n"); } } else if (gbl.disassembly) { if (gbl.showIdx) { fprintf(gbl.outfp, " " " Br\n" " Rec # PC Disassembly" " Tk EA\n"); } else { fprintf(gbl.outfp, " " " Br\n" " PC Disassembly" " Tk EA\n"); } } else { if (gbl.showIdx) { fprintf(gbl.outfp, " " " Br\n" " Rec # PC Disassembly" " Instr Word IH Tk EA\n"); } else { fprintf(gbl.outfp, " " " Br\n" " PC Disassembly" " Instr Word IH Tk EA\n"); } } prheader = false; } } // Shade6x64::print_header() }; // Shade6x64 class Master : public Trace { public: virtual void print_dasm(uint64_t idx) { char dis_string[80]; sprintDiss(dis_string, tr->tr_i, tr->tr_pc_va); print_header(); if (gbl.showIdx) { fprintf(gbl.outfp , "%6lld ", idx); } if (tr->tr_privmode) { fprintf(gbl.outfp, "p "); } else { fprintf(gbl.outfp, "u "); } fprintf(gbl.outfp, "[0x%016llx] ", tr->tr_pc_va); fprintf(gbl.outfp, "%-32s", dis_string); if (ih_iscti(tr->tr_ih)) { if (tr->tr_taken) { fprintf(gbl.outfp, "T "); } else { fprintf(gbl.outfp, "N "); } } else { fprintf(gbl.outfp, " "); } if (tr->tr_va_valid && !tr->tr_annulled) { fprintf(gbl.outfp, "[0x%016llx]", tr->tr_ea_va); } if (tr->tr_annulled) { fprintf(gbl.outfp, "an "); } if (tr->tr_got_trap) { fprintf(gbl.outfp, "tr "); } if (tr->tr_asi_change) { fprintf(gbl.outfp, "asi "); } if (tr->tr_iwstart) { fprintf(gbl.outfp, "wi "); } fprintf(gbl.outfp, "\n"); } // Master::print_dasm() virtual void print_rec(uint64_t idx) { print_header(); if (gbl.showIdx) { fprintf(gbl.outfp , "%6lld ", idx); } fprintf(gbl.outfp, " [0x%016llx] ", tr->tr_pc_va); fprintf(gbl.outfp, "[0x%016llx] ", tr->tr_pc_pa); fprintf(gbl.outfp, "(0x%08x) ", tr->tr_i); if (tr->tr_privmode) { fprintf(gbl.outfp, " p "); } else { fprintf(gbl.outfp, " u "); } fprintf(gbl.outfp, "%3d ", tr->tr_ih); if (ih_iscti(tr->tr_ih)) { if (tr->tr_taken) { fprintf(gbl.outfp, "T "); } else { fprintf(gbl.outfp, "N "); } } else { fprintf(gbl.outfp, " "); } fprintf(gbl.outfp, "[0x%016llx] ", tr->tr_ea_va); fprintf(gbl.outfp, "<0x%016llx> ", tr->tr_ea_pa); fprintf(gbl.outfp, "%d ", tr->tr_va_valid); fprintf(gbl.outfp, " %d ", tr->tr_annulled); fprintf(gbl.outfp, " %d ", tr->tr_got_trap); fprintf(gbl.outfp, " %d ", tr->tr_asi_change); fprintf(gbl.outfp, "0x%04x", tr->tr_tid); fprintf(gbl.outfp, " %d ", tr->tr_context); fprintf(gbl.outfp, " %d ", tr->tr_asi); fprintf(gbl.outfp, " %d ", tr->tr_iwstart); fprintf(gbl.outfp, "\n"); } // Master::print_rec virtual void print_verb(uint64_t idx) { char dis_string[80]; sprintDiss(dis_string, tr->tr_i, tr->tr_pc_va); print_header(); if (gbl.showIdx) { fprintf(gbl.outfp , "%6lld ", idx); } if (tr->tr_privmode) { fprintf(gbl.outfp, "p "); } else { fprintf(gbl.outfp, "u "); } fprintf(gbl.outfp, "[0x%016llx] ", tr->tr_pc_va); fprintf(gbl.outfp, "<0x%016llx> ", tr->tr_pc_pa); fprintf(gbl.outfp, "%-32s", dis_string); fprintf(gbl.outfp, "(0x%08x) ", tr->tr_i); fprintf(gbl.outfp, "%3d ", tr->tr_ih); if (ih_iscti(tr->tr_ih)) { if (tr->tr_taken) { fprintf(gbl.outfp, "T "); } else { fprintf(gbl.outfp, "N "); } } else { fprintf(gbl.outfp, " "); } fprintf(gbl.outfp, "[0x%016llx]", tr->tr_ea_va); if (!tr->tr_va_valid) { fprintf(gbl.outfp, "x "); } else { fprintf(gbl.outfp, " "); } fprintf(gbl.outfp, "<0x%016llx> ", tr->tr_ea_pa); if (tr->tr_annulled) { fprintf(gbl.outfp, "an "); } if (tr->tr_got_trap) { fprintf(gbl.outfp, "tr "); } if (tr->tr_asi_change) { fprintf(gbl.outfp, "asi "); } if (tr->tr_iwstart) { fprintf(gbl.outfp, "wi "); } fprintf(gbl.outfp, "\n"); } // Master::print_verb() virtual void convert_to_master() { this_master = *tr; } // Master::convert_to_master virtual void convert_from_master(Tmaster64* master) { *tr = *master; } // Master::convert_from_master() virtual void gen_ihash() { tr->tr_ih = getIHash(tr->tr_i); } // Master::gen_ihash() virtual int check_ihash_error() { if (tr->tr_ih != getIHash(tr->tr_i)) { return 1; } return 0; } // Master::check_ihash_error() virtual void verify() { Tmaster64* vtr = tr - NUM_VERIFY; int i; for (i = 0; i < NUM_VERIFY - 1; i++) { if (vtr[i].tr_pc_va % 4 != 0 && RSTF_IS_BADADDR(vtr[i].tr_pc_va) == 0) { fprintf(stderr, "trconv: Error: Incorrect pc value in input file.\n"); set_tr(&vtr[i], false); print_verb(gbl.rcount - NUM_VERIFY + i); //exit(2); } } } // Master::verify() virtual uint64_t get_pc() { return tr->tr_pc_va; } // Master::get_pc() virtual uint64_t get_ea() { return tr->tr_ea_va; } // Master::get_ea() virtual int get_ihash() { return tr->tr_ih; } // Master::get_ihash() virtual void inc_tr() { tr++; } // Master::inc_tr() virtual void set_tr(void* ptr, bool set_orig = true) { tr = (Tmaster64*) ptr; if (set_orig) { tr_orig = tr; } } // Master::set_tr() virtual void reset_tr() { tr = tr_orig; } // Master::reset_tr() protected: Tmaster64* tr; Tmaster64* tr_orig; void print_header() { static bool prheader = true; if (prheader) { fprintf(gbl.outfp, "Master trace format (%s)\n", gbl.infile); fprintf(gbl.outfp, "===================\n"); if (gbl.record) { if (gbl.showIdx) { fprintf(gbl.outfp, " Rec # tr_pc_va tr_pc_pa " "tr_i tr_ih tr_ea_va tr_ea_pa " " va an gt ac tid cx a iw\n"); } else { fprintf(gbl.outfp, " tr_pc_va tr_pc_pa " "tr_i tr_ih tr_ea_va tr_ea_pa " " va an gt ac tid cx a iw\n"); } } else if (gbl.disassembly) { if (gbl.showIdx) { fprintf(gbl.outfp, " Usr/ " " Br\n" " Rec # Pr PC Disassembly" " Tk EA\n"); } else { fprintf(gbl.outfp, "Usr/ " " Br\n" "Pr PC Disassembly" " Tk EA\n"); } } else { if (gbl.showIdx) { fprintf(gbl.outfp, " Usr/ " " " " Br\n" " Rec # Pr PC (virtual) PC (physical)" " Disassembly " "Instr Word IH" " Tk EA (virtual, x=inv) EA (physical)\n"); } else { fprintf(gbl.outfp, "Usr/ " " " " Br\n" "Pr PC (virtual) PC (physical)" " Disassembly " "Instr Word IH" " Tk EA (virtual, x=inv) EA (physical)\n"); } } prheader = false; } // Master::print_header() } }; // Master