exetrace.cc (3987:b9434f1d25fa) exetrace.cc (3989:6ce62f2fdeb4)
1/*
2 * Copyright (c) 2001-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Steve Reinhardt
29 * Lisa Hsu
30 * Nathan Binkert
31 * Steve Raasch
32 */
33
34#include <fstream>
35#include <iomanip>
36#include <sys/ipc.h>
37#include <sys/shm.h>
38
39#include "arch/regfile.hh"
40#include "arch/utility.hh"
41#include "base/loader/symtab.hh"
42#include "config/full_system.hh"
43#include "cpu/base.hh"
44#include "cpu/exetrace.hh"
45#include "cpu/static_inst.hh"
46#include "sim/param.hh"
47#include "sim/system.hh"
48
49#if FULL_SYSTEM
50#include "arch/tlb.hh"
51#endif
52
53//XXX This is temporary
54#include "arch/isa_specific.hh"
55#include "cpu/m5legion_interface.h"
56
57using namespace std;
58using namespace TheISA;
59
60#if THE_ISA == SPARC_ISA && FULL_SYSTEM
61static int diffcount = 0;
62static bool wasMicro = false;
63#endif
64
65namespace Trace {
66SharedData *shared_data = NULL;
67}
68
69////////////////////////////////////////////////////////////////////////
70//
71// Methods for the InstRecord object
72//
73
74#if THE_ISA == SPARC_ISA
75
76inline char * genCenteredLabel(int length, char * buffer, char * label)
77{
78 int labelLength = strlen(label);
79 assert(labelLength <= length);
80 int leftPad = (length - labelLength) / 2;
81 int rightPad = length - leftPad - labelLength;
82 char format[64];
83 sprintf(format, "%%%ds%%s%%%ds", leftPad, rightPad);
84 sprintf(buffer, format, "", label, "");
85 return buffer;
86}
87
88inline void printRegPair(ostream & os, char const * title, uint64_t a, uint64_t b)
89{
90 ccprintf(os, " %16s | %#018x %s %#-018x \n",
91 title, a, (a == b) ? "|" : "X", b);
92}
93
94inline void printColumnLabels(ostream & os)
95{
96 static char * regLabel = genCenteredLabel(16, new char[17], "Register");
97 static char * m5Label = genCenteredLabel(18, new char[18], "M5");
98 static char * legionLabel = genCenteredLabel(18, new char[18], "Legion");
99 ccprintf(os, " %s | %s | %s \n", regLabel, m5Label, legionLabel);
100 ccprintf(os, "--------------------+-----------------------+-----------------------\n");
101}
102
103inline void printSectionHeader(ostream & os, char * name)
104{
105 char sectionString[70];
106 genCenteredLabel(69, sectionString, name);
107 ccprintf(os, "====================================================================\n");
108 ccprintf(os, "%69s\n", sectionString);
109 ccprintf(os, "====================================================================\n");
110}
111
112inline void printLevelHeader(ostream & os, int level)
113{
114 char sectionString[70];
115 char levelName[70];
116 sprintf(levelName, "Trap stack level %d", level);
117 genCenteredLabel(69, sectionString, levelName);
118 ccprintf(os, "====================================================================\n");
119 ccprintf(os, "%69s\n", sectionString);
120 ccprintf(os, "====================================================================\n");
121}
122
123#endif
124
125void
126Trace::InstRecord::dump(ostream &outs)
127{
128 DPRINTF(Sparc, "Instruction: %#X\n", staticInst->machInst);
129 if (flags[PRINT_REG_DELTA])
130 {
131#if THE_ISA == SPARC_ISA
132 //Don't print what happens for each micro-op, just print out
133 //once at the last op, and for regular instructions.
134 if(!staticInst->isMicroOp() || staticInst->isLastMicroOp())
135 {
136 static uint64_t regs[32] = {
137 0, 0, 0, 0, 0, 0, 0, 0,
138 0, 0, 0, 0, 0, 0, 0, 0,
139 0, 0, 0, 0, 0, 0, 0, 0,
140 0, 0, 0, 0, 0, 0, 0, 0};
141 static uint64_t ccr = 0;
142 static uint64_t y = 0;
143 static uint64_t floats[32];
144 uint64_t newVal;
145 static const char * prefixes[4] = {"G", "O", "L", "I"};
146
147 outs << hex;
148 outs << "PC = " << thread->readNextPC();
149 outs << " NPC = " << thread->readNextNPC();
150 newVal = thread->readIntReg(SparcISA::NumIntArchRegs + 2);
151 //newVal = thread->readMiscReg(SparcISA::MISCREG_CCR);
152 if(newVal != ccr)
153 {
154 outs << " CCR = " << newVal;
155 ccr = newVal;
156 }
157 newVal = thread->readIntReg(SparcISA::NumIntArchRegs + 1);
158 //newVal = thread->readMiscReg(SparcISA::MISCREG_Y);
159 if(newVal != y)
160 {
161 outs << " Y = " << newVal;
162 y = newVal;
163 }
164 for(int y = 0; y < 4; y++)
165 {
166 for(int x = 0; x < 8; x++)
167 {
168 int index = x + 8 * y;
169 newVal = thread->readIntReg(index);
170 if(regs[index] != newVal)
171 {
172 outs << " " << prefixes[y] << dec << x << " = " << hex << newVal;
173 regs[index] = newVal;
174 }
175 }
176 }
177 for(int y = 0; y < 32; y++)
178 {
179 newVal = thread->readFloatRegBits(2 * y, 64);
180 if(floats[y] != newVal)
181 {
182 outs << " F" << dec << (2 * y) << " = " << hex << newVal;
183 floats[y] = newVal;
184 }
185 }
186 outs << dec << endl;
187 }
188#endif
189 }
190 else if (flags[INTEL_FORMAT]) {
191#if FULL_SYSTEM
192 bool is_trace_system = (thread->getCpuPtr()->system->name() == trace_system);
193#else
194 bool is_trace_system = true;
195#endif
196 if (is_trace_system) {
197 ccprintf(outs, "%7d ) ", cycle);
198 outs << "0x" << hex << PC << ":\t";
199 if (staticInst->isLoad()) {
200 outs << "<RD 0x" << hex << addr;
201 outs << ">";
202 } else if (staticInst->isStore()) {
203 outs << "<WR 0x" << hex << addr;
204 outs << ">";
205 }
206 outs << endl;
207 }
208 } else {
209 if (flags[PRINT_CYCLE])
210 ccprintf(outs, "%7d: ", cycle);
211
212 outs << thread->getCpuPtr()->name() << " ";
213
214 if (flags[TRACE_MISSPEC])
215 outs << (misspeculating ? "-" : "+") << " ";
216
217 if (flags[PRINT_THREAD_NUM])
218 outs << "T" << thread->getThreadNum() << " : ";
219
220
221 std::string sym_str;
222 Addr sym_addr;
223 if (debugSymbolTable
224 && debugSymbolTable->findNearestSymbol(PC, sym_str, sym_addr)
225 && flags[PC_SYMBOL]) {
226 if (PC != sym_addr)
227 sym_str += csprintf("+%d", PC - sym_addr);
228 outs << "@" << sym_str << " : ";
229 }
230 else {
231 outs << "0x" << hex << PC << " : ";
232 }
233
234 //
235 // Print decoded instruction
236 //
237
238#if defined(__GNUC__) && (__GNUC__ < 3)
239 // There's a bug in gcc 2.x library that prevents setw()
240 // from working properly on strings
241 string mc(staticInst->disassemble(PC, debugSymbolTable));
242 while (mc.length() < 26)
243 mc += " ";
244 outs << mc;
245#else
246 outs << setw(26) << left << staticInst->disassemble(PC, debugSymbolTable);
247#endif
248
249 outs << " : ";
250
251 if (flags[PRINT_OP_CLASS]) {
252 outs << opClassStrings[staticInst->opClass()] << " : ";
253 }
254
255 if (flags[PRINT_RESULT_DATA] && data_status != DataInvalid) {
256 outs << " D=";
257#if 0
258 if (data_status == DataDouble)
259 ccprintf(outs, "%f", data.as_double);
260 else
261 ccprintf(outs, "%#018x", data.as_int);
262#else
263 ccprintf(outs, "%#018x", data.as_int);
264#endif
265 }
266
267 if (flags[PRINT_EFF_ADDR] && addr_valid)
268 outs << " A=0x" << hex << addr;
269
270 if (flags[PRINT_INT_REGS] && regs_valid) {
271 for (int i = 0; i < TheISA::NumIntRegs;)
272 for (int j = i + 1; i <= j; i++)
273 ccprintf(outs, "r%02d = %#018x%s", i,
274 iregs->regs.readReg(i),
275 ((i == j) ? "\n" : " "));
276 outs << "\n";
277 }
278
279 if (flags[PRINT_FETCH_SEQ] && fetch_seq_valid)
280 outs << " FetchSeq=" << dec << fetch_seq;
281
282 if (flags[PRINT_CP_SEQ] && cp_seq_valid)
283 outs << " CPSeq=" << dec << cp_seq;
284
285 //
286 // End of line...
287 //
288 outs << endl;
289 }
290#if THE_ISA == SPARC_ISA && FULL_SYSTEM
291 // Compare
292 if (flags[LEGION_LOCKSTEP])
293 {
294 bool compared = false;
295 bool diffPC = false;
296 bool diffCC = false;
297 bool diffInst = false;
298 bool diffIntRegs = false;
299 bool diffFpRegs = false;
300 bool diffTpc = false;
301 bool diffTnpc = false;
302 bool diffTstate = false;
303 bool diffTt = false;
304 bool diffTba = false;
305 bool diffHpstate = false;
306 bool diffHtstate = false;
307 bool diffHtba = false;
308 bool diffPstate = false;
309 bool diffY = false;
310 bool diffCcr = false;
311 bool diffTl = false;
312 bool diffGl = false;
313 bool diffAsi = false;
314 bool diffPil = false;
315 bool diffCwp = false;
316 bool diffCansave = false;
317 bool diffCanrestore = false;
318 bool diffOtherwin = false;
319 bool diffCleanwin = false;
320 bool diffTlb = false;
321 Addr m5Pc, lgnPc;
322
323 // We took a trap on a micro-op...
324 if (wasMicro && !staticInst->isMicroOp())
325 {
326 // let's skip comparing this cycle
327 while (!compared)
328 if (shared_data->flags == OWN_M5) {
329 shared_data->flags = OWN_LEGION;
330 compared = true;
331 }
332 compared = false;
333 wasMicro = false;
334 }
335
336 if (staticInst->isLastMicroOp())
337 wasMicro = false;
338 else if (staticInst->isMicroOp())
339 wasMicro = true;
340
341
342 if(!staticInst->isMicroOp() || staticInst->isLastMicroOp()) {
343 while (!compared) {
344 if (shared_data->flags == OWN_M5) {
345 m5Pc = PC & TheISA::PAddrImplMask;
346 if (bits(shared_data->pstate,3,3)) {
347 m5Pc &= mask(32);
348 }
349 lgnPc = shared_data->pc & TheISA::PAddrImplMask;
350 if (lgnPc != m5Pc)
351 diffPC = true;
352
353 if (shared_data->cycle_count !=
354 thread->getCpuPtr()->instCount())
355 diffCC = true;
356
357 if (shared_data->instruction !=
358 (SparcISA::MachInst)staticInst->machInst) {
359 diffInst = true;
360 }
1/*
2 * Copyright (c) 2001-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Steve Reinhardt
29 * Lisa Hsu
30 * Nathan Binkert
31 * Steve Raasch
32 */
33
34#include <fstream>
35#include <iomanip>
36#include <sys/ipc.h>
37#include <sys/shm.h>
38
39#include "arch/regfile.hh"
40#include "arch/utility.hh"
41#include "base/loader/symtab.hh"
42#include "config/full_system.hh"
43#include "cpu/base.hh"
44#include "cpu/exetrace.hh"
45#include "cpu/static_inst.hh"
46#include "sim/param.hh"
47#include "sim/system.hh"
48
49#if FULL_SYSTEM
50#include "arch/tlb.hh"
51#endif
52
53//XXX This is temporary
54#include "arch/isa_specific.hh"
55#include "cpu/m5legion_interface.h"
56
57using namespace std;
58using namespace TheISA;
59
60#if THE_ISA == SPARC_ISA && FULL_SYSTEM
61static int diffcount = 0;
62static bool wasMicro = false;
63#endif
64
65namespace Trace {
66SharedData *shared_data = NULL;
67}
68
69////////////////////////////////////////////////////////////////////////
70//
71// Methods for the InstRecord object
72//
73
74#if THE_ISA == SPARC_ISA
75
76inline char * genCenteredLabel(int length, char * buffer, char * label)
77{
78 int labelLength = strlen(label);
79 assert(labelLength <= length);
80 int leftPad = (length - labelLength) / 2;
81 int rightPad = length - leftPad - labelLength;
82 char format[64];
83 sprintf(format, "%%%ds%%s%%%ds", leftPad, rightPad);
84 sprintf(buffer, format, "", label, "");
85 return buffer;
86}
87
88inline void printRegPair(ostream & os, char const * title, uint64_t a, uint64_t b)
89{
90 ccprintf(os, " %16s | %#018x %s %#-018x \n",
91 title, a, (a == b) ? "|" : "X", b);
92}
93
94inline void printColumnLabels(ostream & os)
95{
96 static char * regLabel = genCenteredLabel(16, new char[17], "Register");
97 static char * m5Label = genCenteredLabel(18, new char[18], "M5");
98 static char * legionLabel = genCenteredLabel(18, new char[18], "Legion");
99 ccprintf(os, " %s | %s | %s \n", regLabel, m5Label, legionLabel);
100 ccprintf(os, "--------------------+-----------------------+-----------------------\n");
101}
102
103inline void printSectionHeader(ostream & os, char * name)
104{
105 char sectionString[70];
106 genCenteredLabel(69, sectionString, name);
107 ccprintf(os, "====================================================================\n");
108 ccprintf(os, "%69s\n", sectionString);
109 ccprintf(os, "====================================================================\n");
110}
111
112inline void printLevelHeader(ostream & os, int level)
113{
114 char sectionString[70];
115 char levelName[70];
116 sprintf(levelName, "Trap stack level %d", level);
117 genCenteredLabel(69, sectionString, levelName);
118 ccprintf(os, "====================================================================\n");
119 ccprintf(os, "%69s\n", sectionString);
120 ccprintf(os, "====================================================================\n");
121}
122
123#endif
124
125void
126Trace::InstRecord::dump(ostream &outs)
127{
128 DPRINTF(Sparc, "Instruction: %#X\n", staticInst->machInst);
129 if (flags[PRINT_REG_DELTA])
130 {
131#if THE_ISA == SPARC_ISA
132 //Don't print what happens for each micro-op, just print out
133 //once at the last op, and for regular instructions.
134 if(!staticInst->isMicroOp() || staticInst->isLastMicroOp())
135 {
136 static uint64_t regs[32] = {
137 0, 0, 0, 0, 0, 0, 0, 0,
138 0, 0, 0, 0, 0, 0, 0, 0,
139 0, 0, 0, 0, 0, 0, 0, 0,
140 0, 0, 0, 0, 0, 0, 0, 0};
141 static uint64_t ccr = 0;
142 static uint64_t y = 0;
143 static uint64_t floats[32];
144 uint64_t newVal;
145 static const char * prefixes[4] = {"G", "O", "L", "I"};
146
147 outs << hex;
148 outs << "PC = " << thread->readNextPC();
149 outs << " NPC = " << thread->readNextNPC();
150 newVal = thread->readIntReg(SparcISA::NumIntArchRegs + 2);
151 //newVal = thread->readMiscReg(SparcISA::MISCREG_CCR);
152 if(newVal != ccr)
153 {
154 outs << " CCR = " << newVal;
155 ccr = newVal;
156 }
157 newVal = thread->readIntReg(SparcISA::NumIntArchRegs + 1);
158 //newVal = thread->readMiscReg(SparcISA::MISCREG_Y);
159 if(newVal != y)
160 {
161 outs << " Y = " << newVal;
162 y = newVal;
163 }
164 for(int y = 0; y < 4; y++)
165 {
166 for(int x = 0; x < 8; x++)
167 {
168 int index = x + 8 * y;
169 newVal = thread->readIntReg(index);
170 if(regs[index] != newVal)
171 {
172 outs << " " << prefixes[y] << dec << x << " = " << hex << newVal;
173 regs[index] = newVal;
174 }
175 }
176 }
177 for(int y = 0; y < 32; y++)
178 {
179 newVal = thread->readFloatRegBits(2 * y, 64);
180 if(floats[y] != newVal)
181 {
182 outs << " F" << dec << (2 * y) << " = " << hex << newVal;
183 floats[y] = newVal;
184 }
185 }
186 outs << dec << endl;
187 }
188#endif
189 }
190 else if (flags[INTEL_FORMAT]) {
191#if FULL_SYSTEM
192 bool is_trace_system = (thread->getCpuPtr()->system->name() == trace_system);
193#else
194 bool is_trace_system = true;
195#endif
196 if (is_trace_system) {
197 ccprintf(outs, "%7d ) ", cycle);
198 outs << "0x" << hex << PC << ":\t";
199 if (staticInst->isLoad()) {
200 outs << "<RD 0x" << hex << addr;
201 outs << ">";
202 } else if (staticInst->isStore()) {
203 outs << "<WR 0x" << hex << addr;
204 outs << ">";
205 }
206 outs << endl;
207 }
208 } else {
209 if (flags[PRINT_CYCLE])
210 ccprintf(outs, "%7d: ", cycle);
211
212 outs << thread->getCpuPtr()->name() << " ";
213
214 if (flags[TRACE_MISSPEC])
215 outs << (misspeculating ? "-" : "+") << " ";
216
217 if (flags[PRINT_THREAD_NUM])
218 outs << "T" << thread->getThreadNum() << " : ";
219
220
221 std::string sym_str;
222 Addr sym_addr;
223 if (debugSymbolTable
224 && debugSymbolTable->findNearestSymbol(PC, sym_str, sym_addr)
225 && flags[PC_SYMBOL]) {
226 if (PC != sym_addr)
227 sym_str += csprintf("+%d", PC - sym_addr);
228 outs << "@" << sym_str << " : ";
229 }
230 else {
231 outs << "0x" << hex << PC << " : ";
232 }
233
234 //
235 // Print decoded instruction
236 //
237
238#if defined(__GNUC__) && (__GNUC__ < 3)
239 // There's a bug in gcc 2.x library that prevents setw()
240 // from working properly on strings
241 string mc(staticInst->disassemble(PC, debugSymbolTable));
242 while (mc.length() < 26)
243 mc += " ";
244 outs << mc;
245#else
246 outs << setw(26) << left << staticInst->disassemble(PC, debugSymbolTable);
247#endif
248
249 outs << " : ";
250
251 if (flags[PRINT_OP_CLASS]) {
252 outs << opClassStrings[staticInst->opClass()] << " : ";
253 }
254
255 if (flags[PRINT_RESULT_DATA] && data_status != DataInvalid) {
256 outs << " D=";
257#if 0
258 if (data_status == DataDouble)
259 ccprintf(outs, "%f", data.as_double);
260 else
261 ccprintf(outs, "%#018x", data.as_int);
262#else
263 ccprintf(outs, "%#018x", data.as_int);
264#endif
265 }
266
267 if (flags[PRINT_EFF_ADDR] && addr_valid)
268 outs << " A=0x" << hex << addr;
269
270 if (flags[PRINT_INT_REGS] && regs_valid) {
271 for (int i = 0; i < TheISA::NumIntRegs;)
272 for (int j = i + 1; i <= j; i++)
273 ccprintf(outs, "r%02d = %#018x%s", i,
274 iregs->regs.readReg(i),
275 ((i == j) ? "\n" : " "));
276 outs << "\n";
277 }
278
279 if (flags[PRINT_FETCH_SEQ] && fetch_seq_valid)
280 outs << " FetchSeq=" << dec << fetch_seq;
281
282 if (flags[PRINT_CP_SEQ] && cp_seq_valid)
283 outs << " CPSeq=" << dec << cp_seq;
284
285 //
286 // End of line...
287 //
288 outs << endl;
289 }
290#if THE_ISA == SPARC_ISA && FULL_SYSTEM
291 // Compare
292 if (flags[LEGION_LOCKSTEP])
293 {
294 bool compared = false;
295 bool diffPC = false;
296 bool diffCC = false;
297 bool diffInst = false;
298 bool diffIntRegs = false;
299 bool diffFpRegs = false;
300 bool diffTpc = false;
301 bool diffTnpc = false;
302 bool diffTstate = false;
303 bool diffTt = false;
304 bool diffTba = false;
305 bool diffHpstate = false;
306 bool diffHtstate = false;
307 bool diffHtba = false;
308 bool diffPstate = false;
309 bool diffY = false;
310 bool diffCcr = false;
311 bool diffTl = false;
312 bool diffGl = false;
313 bool diffAsi = false;
314 bool diffPil = false;
315 bool diffCwp = false;
316 bool diffCansave = false;
317 bool diffCanrestore = false;
318 bool diffOtherwin = false;
319 bool diffCleanwin = false;
320 bool diffTlb = false;
321 Addr m5Pc, lgnPc;
322
323 // We took a trap on a micro-op...
324 if (wasMicro && !staticInst->isMicroOp())
325 {
326 // let's skip comparing this cycle
327 while (!compared)
328 if (shared_data->flags == OWN_M5) {
329 shared_data->flags = OWN_LEGION;
330 compared = true;
331 }
332 compared = false;
333 wasMicro = false;
334 }
335
336 if (staticInst->isLastMicroOp())
337 wasMicro = false;
338 else if (staticInst->isMicroOp())
339 wasMicro = true;
340
341
342 if(!staticInst->isMicroOp() || staticInst->isLastMicroOp()) {
343 while (!compared) {
344 if (shared_data->flags == OWN_M5) {
345 m5Pc = PC & TheISA::PAddrImplMask;
346 if (bits(shared_data->pstate,3,3)) {
347 m5Pc &= mask(32);
348 }
349 lgnPc = shared_data->pc & TheISA::PAddrImplMask;
350 if (lgnPc != m5Pc)
351 diffPC = true;
352
353 if (shared_data->cycle_count !=
354 thread->getCpuPtr()->instCount())
355 diffCC = true;
356
357 if (shared_data->instruction !=
358 (SparcISA::MachInst)staticInst->machInst) {
359 diffInst = true;
360 }
361 for (int i = 0; i < TheISA::NumIntArchRegs; i++) {
361 // assume we have %g0 working correctly
362 for (int i = 1; i < TheISA::NumIntArchRegs; i++) {
362 if (thread->readIntReg(i) != shared_data->intregs[i]) {
363 diffIntRegs = true;
364 }
365 }
366 for (int i = 0; i < TheISA::NumFloatRegs/2; i++) {
367 if (thread->readFloatRegBits(i*2,FloatRegFile::DoubleWidth) != shared_data->fpregs[i]) {
368 diffFpRegs = true;
369 }
370 }
371 uint64_t oldTl = thread->readMiscReg(MISCREG_TL);
372 if (oldTl != shared_data->tl)
373 diffTl = true;
374 for (int i = 1; i <= MaxTL; i++) {
375 thread->setMiscReg(MISCREG_TL, i);
376 if (thread->readMiscReg(MISCREG_TPC) !=
377 shared_data->tpc[i-1])
378 diffTpc = true;
379 if (thread->readMiscReg(MISCREG_TNPC) !=
380 shared_data->tnpc[i-1])
381 diffTnpc = true;
382 if (thread->readMiscReg(MISCREG_TSTATE) !=
383 shared_data->tstate[i-1])
384 diffTstate = true;
385 if (thread->readMiscReg(MISCREG_TT) !=
386 shared_data->tt[i-1])
387 diffTt = true;
388 if (thread->readMiscReg(MISCREG_HTSTATE) !=
389 shared_data->htstate[i-1])
390 diffHtstate = true;
391 }
392 thread->setMiscReg(MISCREG_TL, oldTl);
393
394 if(shared_data->tba != thread->readMiscReg(MISCREG_TBA))
395 diffTba = true;
396 //When the hpstate register is read by an instruction,
397 //legion has bit 11 set. When it's in storage, it doesn't.
398 //Since we don't directly support seperate interpretations
399 //of the registers like that, the bit is always set to 1 and
400 //we just don't compare it. It's not supposed to matter
401 //anyway.
402 if((shared_data->hpstate | (1 << 11)) != thread->readMiscReg(MISCREG_HPSTATE))
403 diffHpstate = true;
404 if(shared_data->htba != thread->readMiscReg(MISCREG_HTBA))
405 diffHtba = true;
406 if(shared_data->pstate != thread->readMiscReg(MISCREG_PSTATE))
407 diffPstate = true;
408 //if(shared_data->y != thread->readMiscReg(MISCREG_Y))
409 if(shared_data->y !=
410 thread->readIntReg(NumIntArchRegs + 1))
411 diffY = true;
412 //if(shared_data->ccr != thread->readMiscReg(MISCREG_CCR))
413 if(shared_data->ccr !=
414 thread->readIntReg(NumIntArchRegs + 2))
415 diffCcr = true;
416 if(shared_data->gl != thread->readMiscReg(MISCREG_GL))
417 diffGl = true;
418 if(shared_data->asi != thread->readMiscReg(MISCREG_ASI))
419 diffAsi = true;
420 if(shared_data->pil != thread->readMiscReg(MISCREG_PIL))
421 diffPil = true;
422 if(shared_data->cwp != thread->readMiscReg(MISCREG_CWP))
423 diffCwp = true;
424 //if(shared_data->cansave != thread->readMiscReg(MISCREG_CANSAVE))
425 if(shared_data->cansave !=
426 thread->readIntReg(NumIntArchRegs + 3))
427 diffCansave = true;
428 //if(shared_data->canrestore !=
429 // thread->readMiscReg(MISCREG_CANRESTORE))
430 if(shared_data->canrestore !=
363 if (thread->readIntReg(i) != shared_data->intregs[i]) {
364 diffIntRegs = true;
365 }
366 }
367 for (int i = 0; i < TheISA::NumFloatRegs/2; i++) {
368 if (thread->readFloatRegBits(i*2,FloatRegFile::DoubleWidth) != shared_data->fpregs[i]) {
369 diffFpRegs = true;
370 }
371 }
372 uint64_t oldTl = thread->readMiscReg(MISCREG_TL);
373 if (oldTl != shared_data->tl)
374 diffTl = true;
375 for (int i = 1; i <= MaxTL; i++) {
376 thread->setMiscReg(MISCREG_TL, i);
377 if (thread->readMiscReg(MISCREG_TPC) !=
378 shared_data->tpc[i-1])
379 diffTpc = true;
380 if (thread->readMiscReg(MISCREG_TNPC) !=
381 shared_data->tnpc[i-1])
382 diffTnpc = true;
383 if (thread->readMiscReg(MISCREG_TSTATE) !=
384 shared_data->tstate[i-1])
385 diffTstate = true;
386 if (thread->readMiscReg(MISCREG_TT) !=
387 shared_data->tt[i-1])
388 diffTt = true;
389 if (thread->readMiscReg(MISCREG_HTSTATE) !=
390 shared_data->htstate[i-1])
391 diffHtstate = true;
392 }
393 thread->setMiscReg(MISCREG_TL, oldTl);
394
395 if(shared_data->tba != thread->readMiscReg(MISCREG_TBA))
396 diffTba = true;
397 //When the hpstate register is read by an instruction,
398 //legion has bit 11 set. When it's in storage, it doesn't.
399 //Since we don't directly support seperate interpretations
400 //of the registers like that, the bit is always set to 1 and
401 //we just don't compare it. It's not supposed to matter
402 //anyway.
403 if((shared_data->hpstate | (1 << 11)) != thread->readMiscReg(MISCREG_HPSTATE))
404 diffHpstate = true;
405 if(shared_data->htba != thread->readMiscReg(MISCREG_HTBA))
406 diffHtba = true;
407 if(shared_data->pstate != thread->readMiscReg(MISCREG_PSTATE))
408 diffPstate = true;
409 //if(shared_data->y != thread->readMiscReg(MISCREG_Y))
410 if(shared_data->y !=
411 thread->readIntReg(NumIntArchRegs + 1))
412 diffY = true;
413 //if(shared_data->ccr != thread->readMiscReg(MISCREG_CCR))
414 if(shared_data->ccr !=
415 thread->readIntReg(NumIntArchRegs + 2))
416 diffCcr = true;
417 if(shared_data->gl != thread->readMiscReg(MISCREG_GL))
418 diffGl = true;
419 if(shared_data->asi != thread->readMiscReg(MISCREG_ASI))
420 diffAsi = true;
421 if(shared_data->pil != thread->readMiscReg(MISCREG_PIL))
422 diffPil = true;
423 if(shared_data->cwp != thread->readMiscReg(MISCREG_CWP))
424 diffCwp = true;
425 //if(shared_data->cansave != thread->readMiscReg(MISCREG_CANSAVE))
426 if(shared_data->cansave !=
427 thread->readIntReg(NumIntArchRegs + 3))
428 diffCansave = true;
429 //if(shared_data->canrestore !=
430 // thread->readMiscReg(MISCREG_CANRESTORE))
431 if(shared_data->canrestore !=
431 thread->readMiscReg(NumIntArchRegs + 4))
432 thread->readIntReg(NumIntArchRegs + 4))
432 diffCanrestore = true;
433 //if(shared_data->otherwin != thread->readMiscReg(MISCREG_OTHERWIN))
434 if(shared_data->otherwin !=
433 diffCanrestore = true;
434 //if(shared_data->otherwin != thread->readMiscReg(MISCREG_OTHERWIN))
435 if(shared_data->otherwin !=
435 thread->readIntReg(NumIntArchRegs + 5))
436 thread->readIntReg(NumIntArchRegs + 6))
436 diffOtherwin = true;
437 //if(shared_data->cleanwin != thread->readMiscReg(MISCREG_CLEANWIN))
438 if(shared_data->cleanwin !=
437 diffOtherwin = true;
438 //if(shared_data->cleanwin != thread->readMiscReg(MISCREG_CLEANWIN))
439 if(shared_data->cleanwin !=
439 thread->readMiscReg(NumIntArchRegs + 6))
440 thread->readIntReg(NumIntArchRegs + 5))
440 diffCleanwin = true;
441
442 for (int i = 0; i < 64; i++) {
443 if (shared_data->itb[i] != thread->getITBPtr()->TteRead(i))
444 diffTlb = true;
445 if (shared_data->dtb[i] != thread->getDTBPtr()->TteRead(i))
446 diffTlb = true;
447 }
448
449 if ((diffPC || diffCC || diffInst || diffIntRegs ||
450 diffFpRegs || diffTpc || diffTnpc || diffTstate ||
451 diffTt || diffHpstate || diffHtstate || diffHtba ||
452 diffPstate || diffY || diffCcr || diffTl || diffGl ||
453 diffAsi || diffPil || diffCwp || diffCansave ||
454 diffCanrestore || diffOtherwin || diffCleanwin || diffTlb)
455 && !((staticInst->machInst & 0xC1F80000) == 0x81D00000)
456 && !(((staticInst->machInst & 0xC0000000) == 0xC0000000)
457 && shared_data->tl == thread->readMiscReg(MISCREG_TL) + 1)
458 ) {
459
460 outs << "Differences found between M5 and Legion:";
461 if (diffPC)
462 outs << " [PC]";
463 if (diffCC)
464 outs << " [CC]";
465 if (diffInst)
466 outs << " [Instruction]";
467 if (diffIntRegs)
468 outs << " [IntRegs]";
469 if (diffFpRegs)
470 outs << " [FpRegs]";
471 if (diffTpc)
472 outs << " [Tpc]";
473 if (diffTnpc)
474 outs << " [Tnpc]";
475 if (diffTstate)
476 outs << " [Tstate]";
477 if (diffTt)
478 outs << " [Tt]";
479 if (diffHpstate)
480 outs << " [Hpstate]";
481 if (diffHtstate)
482 outs << " [Htstate]";
483 if (diffHtba)
484 outs << " [Htba]";
485 if (diffPstate)
486 outs << " [Pstate]";
487 if (diffY)
488 outs << " [Y]";
489 if (diffCcr)
490 outs << " [Ccr]";
491 if (diffTl)
492 outs << " [Tl]";
493 if (diffGl)
494 outs << " [Gl]";
495 if (diffAsi)
496 outs << " [Asi]";
497 if (diffPil)
498 outs << " [Pil]";
499 if (diffCwp)
500 outs << " [Cwp]";
501 if (diffCansave)
502 outs << " [Cansave]";
503 if (diffCanrestore)
504 outs << " [Canrestore]";
505 if (diffOtherwin)
506 outs << " [Otherwin]";
507 if (diffCleanwin)
508 outs << " [Cleanwin]";
509 if (diffTlb)
510 outs << " [Tlb]";
511 outs << endl << endl;
512
513 outs << right << setfill(' ') << setw(15)
514 << "M5 PC: " << "0x"<< setw(16) << setfill('0')
515 << hex << m5Pc << endl;
516 outs << setfill(' ') << setw(15)
517 << "Legion PC: " << "0x"<< setw(16) << setfill('0') << hex
518 << lgnPc << endl << endl;
519
520 outs << right << setfill(' ') << setw(15)
521 << "M5 CC: " << "0x"<< setw(16) << setfill('0')
522 << hex << thread->getCpuPtr()->instCount() << endl;
523 outs << setfill(' ') << setw(15)
524 << "Legion CC: " << "0x"<< setw(16) << setfill('0') << hex
525 << shared_data->cycle_count << endl << endl;
526
527 outs << setfill(' ') << setw(15)
528 << "M5 Inst: " << "0x"<< setw(8)
529 << setfill('0') << hex << staticInst->machInst
530 << staticInst->disassemble(m5Pc, debugSymbolTable)
531 << endl;
532
533 StaticInstPtr legionInst =
534 StaticInst::decode(makeExtMI(shared_data->instruction,
535 thread));
536 outs << setfill(' ') << setw(15)
537 << " Legion Inst: "
538 << "0x" << setw(8) << setfill('0') << hex
539 << shared_data->instruction
540 << legionInst->disassemble(lgnPc, debugSymbolTable)
541 << endl << endl;
542
543 printSectionHeader(outs, "General State");
544 printColumnLabels(outs);
545 printRegPair(outs, "HPstate",
546 thread->readMiscReg(MISCREG_HPSTATE),
547 shared_data->hpstate | (1 << 11));
548 printRegPair(outs, "Htba",
549 thread->readMiscReg(MISCREG_HTBA),
550 shared_data->htba);
551 printRegPair(outs, "Pstate",
552 thread->readMiscReg(MISCREG_PSTATE),
553 shared_data->pstate);
554 printRegPair(outs, "Y",
555 //thread->readMiscReg(MISCREG_Y),
441 diffCleanwin = true;
442
443 for (int i = 0; i < 64; i++) {
444 if (shared_data->itb[i] != thread->getITBPtr()->TteRead(i))
445 diffTlb = true;
446 if (shared_data->dtb[i] != thread->getDTBPtr()->TteRead(i))
447 diffTlb = true;
448 }
449
450 if ((diffPC || diffCC || diffInst || diffIntRegs ||
451 diffFpRegs || diffTpc || diffTnpc || diffTstate ||
452 diffTt || diffHpstate || diffHtstate || diffHtba ||
453 diffPstate || diffY || diffCcr || diffTl || diffGl ||
454 diffAsi || diffPil || diffCwp || diffCansave ||
455 diffCanrestore || diffOtherwin || diffCleanwin || diffTlb)
456 && !((staticInst->machInst & 0xC1F80000) == 0x81D00000)
457 && !(((staticInst->machInst & 0xC0000000) == 0xC0000000)
458 && shared_data->tl == thread->readMiscReg(MISCREG_TL) + 1)
459 ) {
460
461 outs << "Differences found between M5 and Legion:";
462 if (diffPC)
463 outs << " [PC]";
464 if (diffCC)
465 outs << " [CC]";
466 if (diffInst)
467 outs << " [Instruction]";
468 if (diffIntRegs)
469 outs << " [IntRegs]";
470 if (diffFpRegs)
471 outs << " [FpRegs]";
472 if (diffTpc)
473 outs << " [Tpc]";
474 if (diffTnpc)
475 outs << " [Tnpc]";
476 if (diffTstate)
477 outs << " [Tstate]";
478 if (diffTt)
479 outs << " [Tt]";
480 if (diffHpstate)
481 outs << " [Hpstate]";
482 if (diffHtstate)
483 outs << " [Htstate]";
484 if (diffHtba)
485 outs << " [Htba]";
486 if (diffPstate)
487 outs << " [Pstate]";
488 if (diffY)
489 outs << " [Y]";
490 if (diffCcr)
491 outs << " [Ccr]";
492 if (diffTl)
493 outs << " [Tl]";
494 if (diffGl)
495 outs << " [Gl]";
496 if (diffAsi)
497 outs << " [Asi]";
498 if (diffPil)
499 outs << " [Pil]";
500 if (diffCwp)
501 outs << " [Cwp]";
502 if (diffCansave)
503 outs << " [Cansave]";
504 if (diffCanrestore)
505 outs << " [Canrestore]";
506 if (diffOtherwin)
507 outs << " [Otherwin]";
508 if (diffCleanwin)
509 outs << " [Cleanwin]";
510 if (diffTlb)
511 outs << " [Tlb]";
512 outs << endl << endl;
513
514 outs << right << setfill(' ') << setw(15)
515 << "M5 PC: " << "0x"<< setw(16) << setfill('0')
516 << hex << m5Pc << endl;
517 outs << setfill(' ') << setw(15)
518 << "Legion PC: " << "0x"<< setw(16) << setfill('0') << hex
519 << lgnPc << endl << endl;
520
521 outs << right << setfill(' ') << setw(15)
522 << "M5 CC: " << "0x"<< setw(16) << setfill('0')
523 << hex << thread->getCpuPtr()->instCount() << endl;
524 outs << setfill(' ') << setw(15)
525 << "Legion CC: " << "0x"<< setw(16) << setfill('0') << hex
526 << shared_data->cycle_count << endl << endl;
527
528 outs << setfill(' ') << setw(15)
529 << "M5 Inst: " << "0x"<< setw(8)
530 << setfill('0') << hex << staticInst->machInst
531 << staticInst->disassemble(m5Pc, debugSymbolTable)
532 << endl;
533
534 StaticInstPtr legionInst =
535 StaticInst::decode(makeExtMI(shared_data->instruction,
536 thread));
537 outs << setfill(' ') << setw(15)
538 << " Legion Inst: "
539 << "0x" << setw(8) << setfill('0') << hex
540 << shared_data->instruction
541 << legionInst->disassemble(lgnPc, debugSymbolTable)
542 << endl << endl;
543
544 printSectionHeader(outs, "General State");
545 printColumnLabels(outs);
546 printRegPair(outs, "HPstate",
547 thread->readMiscReg(MISCREG_HPSTATE),
548 shared_data->hpstate | (1 << 11));
549 printRegPair(outs, "Htba",
550 thread->readMiscReg(MISCREG_HTBA),
551 shared_data->htba);
552 printRegPair(outs, "Pstate",
553 thread->readMiscReg(MISCREG_PSTATE),
554 shared_data->pstate);
555 printRegPair(outs, "Y",
556 //thread->readMiscReg(MISCREG_Y),
556 thread->readMiscReg(NumIntArchRegs + 1),
557 thread->readIntReg(NumIntArchRegs + 1),
557 shared_data->y);
558 printRegPair(outs, "Ccr",
559 //thread->readMiscReg(MISCREG_CCR),
558 shared_data->y);
559 printRegPair(outs, "Ccr",
560 //thread->readMiscReg(MISCREG_CCR),
560 thread->readMiscReg(NumIntArchRegs + 2),
561 thread->readIntReg(NumIntArchRegs + 2),
561 shared_data->ccr);
562 printRegPair(outs, "Tl",
563 thread->readMiscReg(MISCREG_TL),
564 shared_data->tl);
565 printRegPair(outs, "Gl",
566 thread->readMiscReg(MISCREG_GL),
567 shared_data->gl);
568 printRegPair(outs, "Asi",
569 thread->readMiscReg(MISCREG_ASI),
570 shared_data->asi);
571 printRegPair(outs, "Pil",
572 thread->readMiscReg(MISCREG_PIL),
573 shared_data->pil);
574 printRegPair(outs, "Cwp",
575 thread->readMiscReg(MISCREG_CWP),
576 shared_data->cwp);
577 printRegPair(outs, "Cansave",
578 //thread->readMiscReg(MISCREG_CANSAVE),
579 thread->readIntReg(NumIntArchRegs + 3),
580 shared_data->cansave);
581 printRegPair(outs, "Canrestore",
582 //thread->readMiscReg(MISCREG_CANRESTORE),
583 thread->readIntReg(NumIntArchRegs + 4),
584 shared_data->canrestore);
585 printRegPair(outs, "Otherwin",
586 //thread->readMiscReg(MISCREG_OTHERWIN),
562 shared_data->ccr);
563 printRegPair(outs, "Tl",
564 thread->readMiscReg(MISCREG_TL),
565 shared_data->tl);
566 printRegPair(outs, "Gl",
567 thread->readMiscReg(MISCREG_GL),
568 shared_data->gl);
569 printRegPair(outs, "Asi",
570 thread->readMiscReg(MISCREG_ASI),
571 shared_data->asi);
572 printRegPair(outs, "Pil",
573 thread->readMiscReg(MISCREG_PIL),
574 shared_data->pil);
575 printRegPair(outs, "Cwp",
576 thread->readMiscReg(MISCREG_CWP),
577 shared_data->cwp);
578 printRegPair(outs, "Cansave",
579 //thread->readMiscReg(MISCREG_CANSAVE),
580 thread->readIntReg(NumIntArchRegs + 3),
581 shared_data->cansave);
582 printRegPair(outs, "Canrestore",
583 //thread->readMiscReg(MISCREG_CANRESTORE),
584 thread->readIntReg(NumIntArchRegs + 4),
585 shared_data->canrestore);
586 printRegPair(outs, "Otherwin",
587 //thread->readMiscReg(MISCREG_OTHERWIN),
587 thread->readIntReg(NumIntArchRegs + 5),
588 thread->readIntReg(NumIntArchRegs + 6),
588 shared_data->otherwin);
589 printRegPair(outs, "Cleanwin",
590 //thread->readMiscReg(MISCREG_CLEANWIN),
589 shared_data->otherwin);
590 printRegPair(outs, "Cleanwin",
591 //thread->readMiscReg(MISCREG_CLEANWIN),
591 thread->readIntReg(NumIntArchRegs + 6),
592 thread->readIntReg(NumIntArchRegs + 5),
592 shared_data->cleanwin);
593 outs << endl;
594 for (int i = 1; i <= MaxTL; i++) {
595 printLevelHeader(outs, i);
596 printColumnLabels(outs);
597 thread->setMiscReg(MISCREG_TL, i);
598 printRegPair(outs, "Tpc",
599 thread->readMiscReg(MISCREG_TPC),
600 shared_data->tpc[i-1]);
601 printRegPair(outs, "Tnpc",
602 thread->readMiscReg(MISCREG_TNPC),
603 shared_data->tnpc[i-1]);
604 printRegPair(outs, "Tstate",
605 thread->readMiscReg(MISCREG_TSTATE),
606 shared_data->tstate[i-1]);
607 printRegPair(outs, "Tt",
608 thread->readMiscReg(MISCREG_TT),
609 shared_data->tt[i-1]);
610 printRegPair(outs, "Htstate",
611 thread->readMiscReg(MISCREG_HTSTATE),
612 shared_data->htstate[i-1]);
613 }
614 thread->setMiscReg(MISCREG_TL, oldTl);
615 outs << endl;
616
617 printSectionHeader(outs, "General Purpose Registers");
618 static const char * regtypes[4] = {"%g", "%o", "%l", "%i"};
619 for(int y = 0; y < 4; y++) {
620 for(int x = 0; x < 8; x++) {
621 char label[8];
622 sprintf(label, "%s%d", regtypes[y], x);
623 printRegPair(outs, label,
624 thread->readIntReg(y*8+x),
625 shared_data->intregs[y*8+x]);
626 }
627 }
628 if (diffFpRegs) {
629 for (int x = 0; x < 32; x++) {
630 char label[8];
631 sprintf(label, "%%f%d", x);
632 printRegPair(outs, label,
633 thread->readFloatRegBits(x,FloatRegFile::DoubleWidth),
634 shared_data->fpregs[x]);
635 }
636 }
637 if (diffTlb) {
638 printColumnLabels(outs);
639 char label[8];
640 for (int x = 0; x < 64; x++) {
641 if (shared_data->itb[x] != ULL(0xFFFFFFFFFFFFFFFF) ||
642 thread->getITBPtr()->TteRead(x) != ULL(0xFFFFFFFFFFFFFFFF)) {
643 sprintf(label, "I-TLB:%02d", x);
644 printRegPair(outs, label, thread->getITBPtr()->TteRead(x),
645 shared_data->itb[x]);
646 }
647 }
648 for (int x = 0; x < 64; x++) {
649 if (shared_data->dtb[x] != ULL(0xFFFFFFFFFFFFFFFF) ||
650 thread->getDTBPtr()->TteRead(x) != ULL(0xFFFFFFFFFFFFFFFF)) {
651 sprintf(label, "D-TLB:%02d", x);
652 printRegPair(outs, label, thread->getDTBPtr()->TteRead(x),
653 shared_data->dtb[x]);
654 }
655 }
656 thread->getITBPtr()->dumpAll();
657 thread->getDTBPtr()->dumpAll();
658 }
659
660 diffcount++;
661 if (diffcount > 2)
662 fatal("Differences found between Legion and M5\n");
663 } else
664 diffcount = 0;
665
666 compared = true;
667 shared_data->flags = OWN_LEGION;
668 }
669 } // while
670 } // if not microop
671 }
672#endif
673}
674
675
676vector<bool> Trace::InstRecord::flags(NUM_BITS);
677string Trace::InstRecord::trace_system;
678
679////////////////////////////////////////////////////////////////////////
680//
681// Parameter space for per-cycle execution address tracing options.
682// Derive from ParamContext so we can override checkParams() function.
683//
684class ExecutionTraceParamContext : public ParamContext
685{
686 public:
687 ExecutionTraceParamContext(const string &_iniSection)
688 : ParamContext(_iniSection)
689 {
690 }
691
692 void checkParams(); // defined at bottom of file
693};
694
695ExecutionTraceParamContext exeTraceParams("exetrace");
696
697Param<bool> exe_trace_spec(&exeTraceParams, "speculative",
698 "capture speculative instructions", true);
699
700Param<bool> exe_trace_print_cycle(&exeTraceParams, "print_cycle",
701 "print cycle number", true);
702Param<bool> exe_trace_print_opclass(&exeTraceParams, "print_opclass",
703 "print op class", true);
704Param<bool> exe_trace_print_thread(&exeTraceParams, "print_thread",
705 "print thread number", true);
706Param<bool> exe_trace_print_effaddr(&exeTraceParams, "print_effaddr",
707 "print effective address", true);
708Param<bool> exe_trace_print_data(&exeTraceParams, "print_data",
709 "print result data", true);
710Param<bool> exe_trace_print_iregs(&exeTraceParams, "print_iregs",
711 "print all integer regs", false);
712Param<bool> exe_trace_print_fetchseq(&exeTraceParams, "print_fetchseq",
713 "print fetch sequence number", false);
714Param<bool> exe_trace_print_cp_seq(&exeTraceParams, "print_cpseq",
715 "print correct-path sequence number", false);
716Param<bool> exe_trace_print_reg_delta(&exeTraceParams, "print_reg_delta",
717 "print which registers changed to what", false);
718Param<bool> exe_trace_pc_symbol(&exeTraceParams, "pc_symbol",
719 "Use symbols for the PC if available", true);
720Param<bool> exe_trace_intel_format(&exeTraceParams, "intel_format",
721 "print trace in intel compatible format", false);
722Param<bool> exe_trace_legion_lockstep(&exeTraceParams, "legion_lockstep",
723 "Compare sim state to legion state every cycle",
724 false);
725Param<string> exe_trace_system(&exeTraceParams, "trace_system",
726 "print trace of which system (client or server)",
727 "client");
728
729
730//
731// Helper function for ExecutionTraceParamContext::checkParams() just
732// to get us into the InstRecord namespace
733//
734void
735Trace::InstRecord::setParams()
736{
737 flags[TRACE_MISSPEC] = exe_trace_spec;
738
739 flags[PRINT_CYCLE] = exe_trace_print_cycle;
740 flags[PRINT_OP_CLASS] = exe_trace_print_opclass;
741 flags[PRINT_THREAD_NUM] = exe_trace_print_thread;
742 flags[PRINT_RESULT_DATA] = exe_trace_print_effaddr;
743 flags[PRINT_EFF_ADDR] = exe_trace_print_data;
744 flags[PRINT_INT_REGS] = exe_trace_print_iregs;
745 flags[PRINT_FETCH_SEQ] = exe_trace_print_fetchseq;
746 flags[PRINT_CP_SEQ] = exe_trace_print_cp_seq;
747 flags[PRINT_REG_DELTA] = exe_trace_print_reg_delta;
748 flags[PC_SYMBOL] = exe_trace_pc_symbol;
749 flags[INTEL_FORMAT] = exe_trace_intel_format;
750 flags[LEGION_LOCKSTEP] = exe_trace_legion_lockstep;
751 trace_system = exe_trace_system;
752
753 // If were going to be in lockstep with Legion
754 // Setup shared memory, and get otherwise ready
755 if (flags[LEGION_LOCKSTEP]) {
756 int shmfd = shmget('M' << 24 | getuid(), sizeof(SharedData), 0777);
757 if (shmfd < 0)
758 fatal("Couldn't get shared memory fd. Is Legion running?");
759
760 shared_data = (SharedData*)shmat(shmfd, NULL, SHM_RND);
761 if (shared_data == (SharedData*)-1)
762 fatal("Couldn't allocate shared memory");
763
764 if (shared_data->flags != OWN_M5)
765 fatal("Shared memory has invalid owner");
766
767 if (shared_data->version != VERSION)
768 fatal("Shared Data is wrong version! M5: %d Legion: %d", VERSION,
769 shared_data->version);
770
771 // step legion forward one cycle so we can get register values
772 shared_data->flags = OWN_LEGION;
773 }
774}
775
776void
777ExecutionTraceParamContext::checkParams()
778{
779 Trace::InstRecord::setParams();
780}
781
593 shared_data->cleanwin);
594 outs << endl;
595 for (int i = 1; i <= MaxTL; i++) {
596 printLevelHeader(outs, i);
597 printColumnLabels(outs);
598 thread->setMiscReg(MISCREG_TL, i);
599 printRegPair(outs, "Tpc",
600 thread->readMiscReg(MISCREG_TPC),
601 shared_data->tpc[i-1]);
602 printRegPair(outs, "Tnpc",
603 thread->readMiscReg(MISCREG_TNPC),
604 shared_data->tnpc[i-1]);
605 printRegPair(outs, "Tstate",
606 thread->readMiscReg(MISCREG_TSTATE),
607 shared_data->tstate[i-1]);
608 printRegPair(outs, "Tt",
609 thread->readMiscReg(MISCREG_TT),
610 shared_data->tt[i-1]);
611 printRegPair(outs, "Htstate",
612 thread->readMiscReg(MISCREG_HTSTATE),
613 shared_data->htstate[i-1]);
614 }
615 thread->setMiscReg(MISCREG_TL, oldTl);
616 outs << endl;
617
618 printSectionHeader(outs, "General Purpose Registers");
619 static const char * regtypes[4] = {"%g", "%o", "%l", "%i"};
620 for(int y = 0; y < 4; y++) {
621 for(int x = 0; x < 8; x++) {
622 char label[8];
623 sprintf(label, "%s%d", regtypes[y], x);
624 printRegPair(outs, label,
625 thread->readIntReg(y*8+x),
626 shared_data->intregs[y*8+x]);
627 }
628 }
629 if (diffFpRegs) {
630 for (int x = 0; x < 32; x++) {
631 char label[8];
632 sprintf(label, "%%f%d", x);
633 printRegPair(outs, label,
634 thread->readFloatRegBits(x,FloatRegFile::DoubleWidth),
635 shared_data->fpregs[x]);
636 }
637 }
638 if (diffTlb) {
639 printColumnLabels(outs);
640 char label[8];
641 for (int x = 0; x < 64; x++) {
642 if (shared_data->itb[x] != ULL(0xFFFFFFFFFFFFFFFF) ||
643 thread->getITBPtr()->TteRead(x) != ULL(0xFFFFFFFFFFFFFFFF)) {
644 sprintf(label, "I-TLB:%02d", x);
645 printRegPair(outs, label, thread->getITBPtr()->TteRead(x),
646 shared_data->itb[x]);
647 }
648 }
649 for (int x = 0; x < 64; x++) {
650 if (shared_data->dtb[x] != ULL(0xFFFFFFFFFFFFFFFF) ||
651 thread->getDTBPtr()->TteRead(x) != ULL(0xFFFFFFFFFFFFFFFF)) {
652 sprintf(label, "D-TLB:%02d", x);
653 printRegPair(outs, label, thread->getDTBPtr()->TteRead(x),
654 shared_data->dtb[x]);
655 }
656 }
657 thread->getITBPtr()->dumpAll();
658 thread->getDTBPtr()->dumpAll();
659 }
660
661 diffcount++;
662 if (diffcount > 2)
663 fatal("Differences found between Legion and M5\n");
664 } else
665 diffcount = 0;
666
667 compared = true;
668 shared_data->flags = OWN_LEGION;
669 }
670 } // while
671 } // if not microop
672 }
673#endif
674}
675
676
677vector<bool> Trace::InstRecord::flags(NUM_BITS);
678string Trace::InstRecord::trace_system;
679
680////////////////////////////////////////////////////////////////////////
681//
682// Parameter space for per-cycle execution address tracing options.
683// Derive from ParamContext so we can override checkParams() function.
684//
685class ExecutionTraceParamContext : public ParamContext
686{
687 public:
688 ExecutionTraceParamContext(const string &_iniSection)
689 : ParamContext(_iniSection)
690 {
691 }
692
693 void checkParams(); // defined at bottom of file
694};
695
696ExecutionTraceParamContext exeTraceParams("exetrace");
697
698Param<bool> exe_trace_spec(&exeTraceParams, "speculative",
699 "capture speculative instructions", true);
700
701Param<bool> exe_trace_print_cycle(&exeTraceParams, "print_cycle",
702 "print cycle number", true);
703Param<bool> exe_trace_print_opclass(&exeTraceParams, "print_opclass",
704 "print op class", true);
705Param<bool> exe_trace_print_thread(&exeTraceParams, "print_thread",
706 "print thread number", true);
707Param<bool> exe_trace_print_effaddr(&exeTraceParams, "print_effaddr",
708 "print effective address", true);
709Param<bool> exe_trace_print_data(&exeTraceParams, "print_data",
710 "print result data", true);
711Param<bool> exe_trace_print_iregs(&exeTraceParams, "print_iregs",
712 "print all integer regs", false);
713Param<bool> exe_trace_print_fetchseq(&exeTraceParams, "print_fetchseq",
714 "print fetch sequence number", false);
715Param<bool> exe_trace_print_cp_seq(&exeTraceParams, "print_cpseq",
716 "print correct-path sequence number", false);
717Param<bool> exe_trace_print_reg_delta(&exeTraceParams, "print_reg_delta",
718 "print which registers changed to what", false);
719Param<bool> exe_trace_pc_symbol(&exeTraceParams, "pc_symbol",
720 "Use symbols for the PC if available", true);
721Param<bool> exe_trace_intel_format(&exeTraceParams, "intel_format",
722 "print trace in intel compatible format", false);
723Param<bool> exe_trace_legion_lockstep(&exeTraceParams, "legion_lockstep",
724 "Compare sim state to legion state every cycle",
725 false);
726Param<string> exe_trace_system(&exeTraceParams, "trace_system",
727 "print trace of which system (client or server)",
728 "client");
729
730
731//
732// Helper function for ExecutionTraceParamContext::checkParams() just
733// to get us into the InstRecord namespace
734//
735void
736Trace::InstRecord::setParams()
737{
738 flags[TRACE_MISSPEC] = exe_trace_spec;
739
740 flags[PRINT_CYCLE] = exe_trace_print_cycle;
741 flags[PRINT_OP_CLASS] = exe_trace_print_opclass;
742 flags[PRINT_THREAD_NUM] = exe_trace_print_thread;
743 flags[PRINT_RESULT_DATA] = exe_trace_print_effaddr;
744 flags[PRINT_EFF_ADDR] = exe_trace_print_data;
745 flags[PRINT_INT_REGS] = exe_trace_print_iregs;
746 flags[PRINT_FETCH_SEQ] = exe_trace_print_fetchseq;
747 flags[PRINT_CP_SEQ] = exe_trace_print_cp_seq;
748 flags[PRINT_REG_DELTA] = exe_trace_print_reg_delta;
749 flags[PC_SYMBOL] = exe_trace_pc_symbol;
750 flags[INTEL_FORMAT] = exe_trace_intel_format;
751 flags[LEGION_LOCKSTEP] = exe_trace_legion_lockstep;
752 trace_system = exe_trace_system;
753
754 // If were going to be in lockstep with Legion
755 // Setup shared memory, and get otherwise ready
756 if (flags[LEGION_LOCKSTEP]) {
757 int shmfd = shmget('M' << 24 | getuid(), sizeof(SharedData), 0777);
758 if (shmfd < 0)
759 fatal("Couldn't get shared memory fd. Is Legion running?");
760
761 shared_data = (SharedData*)shmat(shmfd, NULL, SHM_RND);
762 if (shared_data == (SharedData*)-1)
763 fatal("Couldn't allocate shared memory");
764
765 if (shared_data->flags != OWN_M5)
766 fatal("Shared memory has invalid owner");
767
768 if (shared_data->version != VERSION)
769 fatal("Shared Data is wrong version! M5: %d Legion: %d", VERSION,
770 shared_data->version);
771
772 // step legion forward one cycle so we can get register values
773 shared_data->flags = OWN_LEGION;
774 }
775}
776
777void
778ExecutionTraceParamContext::checkParams()
779{
780 Trace::InstRecord::setParams();
781}
782