Deleted Added
sdiff udiff text old ( 3975:10fa2125f19e ) new ( 3980:9bcb2a2e9bb8 )
full compact
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 diffRegs = false;
299 bool diffTpc = false;
300 bool diffTnpc = false;
301 bool diffTstate = false;
302 bool diffTt = false;
303 bool diffTba = false;
304 bool diffHpstate = false;
305 bool diffHtstate = false;
306 bool diffHtba = false;
307 bool diffPstate = false;
308 bool diffY = false;
309 bool diffCcr = false;
310 bool diffTl = false;
311 bool diffGl = false;
312 bool diffAsi = false;
313 bool diffPil = false;
314 bool diffCwp = false;
315 bool diffCansave = false;
316 bool diffCanrestore = false;
317 bool diffOtherwin = false;
318 bool diffCleanwin = false;
319 bool diffTlb = false;
320 Addr m5Pc, lgnPc;
321
322 // We took a trap on a micro-op...
323 if (wasMicro && !staticInst->isMicroOp())
324 {
325 // let's skip comparing this cycle
326 while (!compared)
327 if (shared_data->flags == OWN_M5) {
328 shared_data->flags = OWN_LEGION;
329 compared = true;
330 }
331 compared = false;
332 wasMicro = false;
333 }
334
335 if (staticInst->isLastMicroOp())
336 wasMicro = false;
337 else if (staticInst->isMicroOp())
338 wasMicro = true;
339
340
341 if(!staticInst->isMicroOp() || staticInst->isLastMicroOp()) {
342 while (!compared) {
343 if (shared_data->flags == OWN_M5) {
344 m5Pc = PC & TheISA::PAddrImplMask;
345 if (bits(shared_data->pstate,3,3)) {
346 m5Pc &= mask(32);
347 }
348 lgnPc = shared_data->pc & TheISA::PAddrImplMask;
349 if (lgnPc != m5Pc)
350 diffPC = true;
351
352 if (shared_data->cycle_count !=
353 thread->getCpuPtr()->instCount())
354 diffCC = true;
355
356 if (shared_data->instruction !=
357 (SparcISA::MachInst)staticInst->machInst) {
358 diffInst = true;
359 }
360 for (int i = 0; i < TheISA::NumIntArchRegs; i++) {
361 if (thread->readIntReg(i) != shared_data->intregs[i]) {
362 diffRegs = true;
363 }
364 }
365 uint64_t oldTl = thread->readMiscReg(MISCREG_TL);
366 if (oldTl != shared_data->tl)
367 diffTl = true;
368 for (int i = 1; i <= MaxTL; i++) {
369 thread->setMiscReg(MISCREG_TL, i);
370 if (thread->readMiscReg(MISCREG_TPC) !=
371 shared_data->tpc[i-1])
372 diffTpc = true;
373 if (thread->readMiscReg(MISCREG_TNPC) !=
374 shared_data->tnpc[i-1])
375 diffTnpc = true;
376 if (thread->readMiscReg(MISCREG_TSTATE) !=
377 shared_data->tstate[i-1])
378 diffTstate = true;
379 if (thread->readMiscReg(MISCREG_TT) !=
380 shared_data->tt[i-1])
381 diffTt = true;
382 if (thread->readMiscReg(MISCREG_HTSTATE) !=
383 shared_data->htstate[i-1])
384 diffHtstate = true;
385 }
386 thread->setMiscReg(MISCREG_TL, oldTl);
387
388 if(shared_data->tba != thread->readMiscReg(MISCREG_TBA))
389 diffTba = true;
390 //When the hpstate register is read by an instruction,
391 //legion has bit 11 set. When it's in storage, it doesn't.
392 //Since we don't directly support seperate interpretations
393 //of the registers like that, the bit is always set to 1 and
394 //we just don't compare it. It's not supposed to matter
395 //anyway.
396 if((shared_data->hpstate | (1 << 11)) != thread->readMiscReg(MISCREG_HPSTATE))
397 diffHpstate = true;
398 if(shared_data->htba != thread->readMiscReg(MISCREG_HTBA))
399 diffHtba = true;
400 if(shared_data->pstate != thread->readMiscReg(MISCREG_PSTATE))
401 diffPstate = true;
402 //if(shared_data->y != thread->readMiscReg(MISCREG_Y))
403 if(shared_data->y !=
404 thread->readIntReg(NumIntArchRegs + 1))
405 diffY = true;
406 //if(shared_data->ccr != thread->readMiscReg(MISCREG_CCR))
407 if(shared_data->ccr !=
408 thread->readIntReg(NumIntArchRegs + 2))
409 diffCcr = true;
410 if(shared_data->gl != thread->readMiscReg(MISCREG_GL))
411 diffGl = true;
412 if(shared_data->asi != thread->readMiscReg(MISCREG_ASI))
413 diffAsi = true;
414 if(shared_data->pil != thread->readMiscReg(MISCREG_PIL))
415 diffPil = true;
416 if(shared_data->cwp != thread->readMiscReg(MISCREG_CWP))
417 diffCwp = true;
418 //if(shared_data->cansave != thread->readMiscReg(MISCREG_CANSAVE))
419 if(shared_data->cansave !=
420 thread->readIntReg(NumIntArchRegs + 3))
421 diffCansave = true;
422 //if(shared_data->canrestore !=
423 // thread->readMiscReg(MISCREG_CANRESTORE))
424 if(shared_data->canrestore !=
425 thread->readMiscReg(NumIntArchRegs + 4))
426 diffCanrestore = true;
427 //if(shared_data->otherwin != thread->readMiscReg(MISCREG_OTHERWIN))
428 if(shared_data->otherwin !=
429 thread->readIntReg(NumIntArchRegs + 5))
430 diffOtherwin = true;
431 //if(shared_data->cleanwin != thread->readMiscReg(MISCREG_CLEANWIN))
432 if(shared_data->cleanwin !=
433 thread->readMiscReg(NumIntArchRegs + 6))
434 diffCleanwin = true;
435
436 for (int i = 0; i < 64; i++) {
437 if (shared_data->itb[i] != thread->getITBPtr()->TteRead(i))
438 diffTlb = true;
439 if (shared_data->dtb[i] != thread->getDTBPtr()->TteRead(i))
440 diffTlb = true;
441 }
442
443 if ((diffPC || diffCC || diffInst || diffRegs || diffTpc ||
444 diffTnpc || diffTstate || diffTt || diffHpstate ||
445 diffHtstate || diffHtba || diffPstate || diffY ||
446 diffCcr || diffTl || diffGl || diffAsi || diffPil ||
447 diffCwp || diffCansave || diffCanrestore ||
448 diffOtherwin || diffCleanwin || diffTlb)
449 && !((staticInst->machInst & 0xC1F80000) == 0x81D00000)
450 && !(((staticInst->machInst & 0xC0000000) == 0xC0000000)
451 && shared_data->tl == thread->readMiscReg(MISCREG_TL) + 1)
452 ) {
453
454 outs << "Differences found between M5 and Legion:";
455 if (diffPC)
456 outs << " [PC]";
457 if (diffCC)
458 outs << " [CC]";
459 if (diffInst)
460 outs << " [Instruction]";
461 if (diffRegs)
462 outs << " [IntRegs]";
463 if (diffTpc)
464 outs << " [Tpc]";
465 if (diffTnpc)
466 outs << " [Tnpc]";
467 if (diffTstate)
468 outs << " [Tstate]";
469 if (diffTt)
470 outs << " [Tt]";
471 if (diffHpstate)
472 outs << " [Hpstate]";
473 if (diffHtstate)
474 outs << " [Htstate]";
475 if (diffHtba)
476 outs << " [Htba]";
477 if (diffPstate)
478 outs << " [Pstate]";
479 if (diffY)
480 outs << " [Y]";
481 if (diffCcr)
482 outs << " [Ccr]";
483 if (diffTl)
484 outs << " [Tl]";
485 if (diffGl)
486 outs << " [Gl]";
487 if (diffAsi)
488 outs << " [Asi]";
489 if (diffPil)
490 outs << " [Pil]";
491 if (diffCwp)
492 outs << " [Cwp]";
493 if (diffCansave)
494 outs << " [Cansave]";
495 if (diffCanrestore)
496 outs << " [Canrestore]";
497 if (diffOtherwin)
498 outs << " [Otherwin]";
499 if (diffCleanwin)
500 outs << " [Cleanwin]";
501 if (diffTlb)
502 outs << " [Tlb]";
503 outs << endl << endl;
504
505 outs << right << setfill(' ') << setw(15)
506 << "M5 PC: " << "0x"<< setw(16) << setfill('0')
507 << hex << m5Pc << endl;
508 outs << setfill(' ') << setw(15)
509 << "Legion PC: " << "0x"<< setw(16) << setfill('0') << hex
510 << lgnPc << endl << endl;
511
512 outs << right << setfill(' ') << setw(15)
513 << "M5 CC: " << "0x"<< setw(16) << setfill('0')
514 << hex << thread->getCpuPtr()->instCount() << endl;
515 outs << setfill(' ') << setw(15)
516 << "Legion CC: " << "0x"<< setw(16) << setfill('0') << hex
517 << shared_data->cycle_count << endl << endl;
518
519 outs << setfill(' ') << setw(15)
520 << "M5 Inst: " << "0x"<< setw(8)
521 << setfill('0') << hex << staticInst->machInst
522 << staticInst->disassemble(m5Pc, debugSymbolTable)
523 << endl;
524
525 StaticInstPtr legionInst =
526 StaticInst::decode(makeExtMI(shared_data->instruction,
527 thread));
528 outs << setfill(' ') << setw(15)
529 << " Legion Inst: "
530 << "0x" << setw(8) << setfill('0') << hex
531 << shared_data->instruction
532 << legionInst->disassemble(lgnPc, debugSymbolTable)
533 << endl << endl;
534
535 printSectionHeader(outs, "General State");
536 printColumnLabels(outs);
537 printRegPair(outs, "HPstate",
538 thread->readMiscReg(MISCREG_HPSTATE),
539 shared_data->hpstate | (1 << 11));
540 printRegPair(outs, "Htba",
541 thread->readMiscReg(MISCREG_HTBA),
542 shared_data->htba);
543 printRegPair(outs, "Pstate",
544 thread->readMiscReg(MISCREG_PSTATE),
545 shared_data->pstate);
546 printRegPair(outs, "Y",
547 //thread->readMiscReg(MISCREG_Y),
548 thread->readMiscReg(NumIntArchRegs + 1),
549 shared_data->y);
550 printRegPair(outs, "Ccr",
551 //thread->readMiscReg(MISCREG_CCR),
552 thread->readMiscReg(NumIntArchRegs + 2),
553 shared_data->ccr);
554 printRegPair(outs, "Tl",
555 thread->readMiscReg(MISCREG_TL),
556 shared_data->tl);
557 printRegPair(outs, "Gl",
558 thread->readMiscReg(MISCREG_GL),
559 shared_data->gl);
560 printRegPair(outs, "Asi",
561 thread->readMiscReg(MISCREG_ASI),
562 shared_data->asi);
563 printRegPair(outs, "Pil",
564 thread->readMiscReg(MISCREG_PIL),
565 shared_data->pil);
566 printRegPair(outs, "Cwp",
567 thread->readMiscReg(MISCREG_CWP),
568 shared_data->cwp);
569 printRegPair(outs, "Cansave",
570 //thread->readMiscReg(MISCREG_CANSAVE),
571 thread->readIntReg(NumIntArchRegs + 3),
572 shared_data->cansave);
573 printRegPair(outs, "Canrestore",
574 //thread->readMiscReg(MISCREG_CANRESTORE),
575 thread->readIntReg(NumIntArchRegs + 4),
576 shared_data->canrestore);
577 printRegPair(outs, "Otherwin",
578 //thread->readMiscReg(MISCREG_OTHERWIN),
579 thread->readIntReg(NumIntArchRegs + 5),
580 shared_data->otherwin);
581 printRegPair(outs, "Cleanwin",
582 //thread->readMiscReg(MISCREG_CLEANWIN),
583 thread->readIntReg(NumIntArchRegs + 6),
584 shared_data->cleanwin);
585 outs << endl;
586 for (int i = 1; i <= MaxTL; i++) {
587 printLevelHeader(outs, i);
588 printColumnLabels(outs);
589 thread->setMiscReg(MISCREG_TL, i);
590 printRegPair(outs, "Tpc",
591 thread->readMiscReg(MISCREG_TPC),
592 shared_data->tpc[i-1]);
593 printRegPair(outs, "Tnpc",
594 thread->readMiscReg(MISCREG_TNPC),
595 shared_data->tnpc[i-1]);
596 printRegPair(outs, "Tstate",
597 thread->readMiscReg(MISCREG_TSTATE),
598 shared_data->tstate[i-1]);
599 printRegPair(outs, "Tt",
600 thread->readMiscReg(MISCREG_TT),
601 shared_data->tt[i-1]);
602 printRegPair(outs, "Htstate",
603 thread->readMiscReg(MISCREG_HTSTATE),
604 shared_data->htstate[i-1]);
605 }
606 thread->setMiscReg(MISCREG_TL, oldTl);
607 outs << endl;
608
609 printSectionHeader(outs, "General Purpose Registers");
610 static const char * regtypes[4] = {"%g", "%o", "%l", "%i"};
611 for(int y = 0; y < 4; y++)
612 {
613 for(int x = 0; x < 8; x++)
614 {
615 char label[8];
616 sprintf(label, "%s%d", regtypes[y], x);
617 printRegPair(outs, label,
618 thread->readIntReg(y*8+x),
619 shared_data->intregs[y*8+x]);
620 /*outs << regtypes[y] << x << " " ;
621 outs << "0x" << hex << setw(16)
622 << thread->readIntReg(y*8+x);
623 if (thread->readIntReg(y*8 + x)
624 != shared_data->intregs[y*8+x])
625 outs << " X ";
626 else
627 outs << " | ";
628 outs << "0x" << setw(16) << hex
629 << shared_data->intregs[y*8+x]
630 << endl;*/
631 }
632 }
633 if (diffTlb) {
634 printColumnLabels(outs);
635 char label[8];
636 for (int x = 0; x < 64; x++) {
637 if (shared_data->itb[x] != ULL(0xFFFFFFFFFFFFFFFF) ||
638 thread->getITBPtr()->TteRead(x) != ULL(0xFFFFFFFFFFFFFFFF)) {
639 sprintf(label, "I-TLB:%02d", x);
640 printRegPair(outs, label, thread->getITBPtr()->TteRead(x),
641 shared_data->itb[x]);
642 }
643 }
644 for (int x = 0; x < 64; x++) {
645 if (shared_data->dtb[x] != ULL(0xFFFFFFFFFFFFFFFF) ||
646 thread->getDTBPtr()->TteRead(x) != ULL(0xFFFFFFFFFFFFFFFF)) {
647 sprintf(label, "D-TLB:%02d", x);
648 printRegPair(outs, label, thread->getDTBPtr()->TteRead(x),
649 shared_data->dtb[x]);
650 }
651 }
652 thread->getITBPtr()->dumpAll();
653 thread->getDTBPtr()->dumpAll();
654 }
655
656 diffcount++;
657 if (diffcount > 2)
658 fatal("Differences found between Legion and M5\n");
659 } else
660 diffcount = 0;
661
662 compared = true;
663 shared_data->flags = OWN_LEGION;
664 }
665 } // while
666 } // if not microop
667 }
668#endif
669}
670
671
672vector<bool> Trace::InstRecord::flags(NUM_BITS);
673string Trace::InstRecord::trace_system;
674
675////////////////////////////////////////////////////////////////////////
676//
677// Parameter space for per-cycle execution address tracing options.
678// Derive from ParamContext so we can override checkParams() function.
679//
680class ExecutionTraceParamContext : public ParamContext
681{
682 public:
683 ExecutionTraceParamContext(const string &_iniSection)
684 : ParamContext(_iniSection)
685 {
686 }
687
688 void checkParams(); // defined at bottom of file
689};
690
691ExecutionTraceParamContext exeTraceParams("exetrace");
692
693Param<bool> exe_trace_spec(&exeTraceParams, "speculative",
694 "capture speculative instructions", true);
695
696Param<bool> exe_trace_print_cycle(&exeTraceParams, "print_cycle",
697 "print cycle number", true);
698Param<bool> exe_trace_print_opclass(&exeTraceParams, "print_opclass",
699 "print op class", true);
700Param<bool> exe_trace_print_thread(&exeTraceParams, "print_thread",
701 "print thread number", true);
702Param<bool> exe_trace_print_effaddr(&exeTraceParams, "print_effaddr",
703 "print effective address", true);
704Param<bool> exe_trace_print_data(&exeTraceParams, "print_data",
705 "print result data", true);
706Param<bool> exe_trace_print_iregs(&exeTraceParams, "print_iregs",
707 "print all integer regs", false);
708Param<bool> exe_trace_print_fetchseq(&exeTraceParams, "print_fetchseq",
709 "print fetch sequence number", false);
710Param<bool> exe_trace_print_cp_seq(&exeTraceParams, "print_cpseq",
711 "print correct-path sequence number", false);
712Param<bool> exe_trace_print_reg_delta(&exeTraceParams, "print_reg_delta",
713 "print which registers changed to what", false);
714Param<bool> exe_trace_pc_symbol(&exeTraceParams, "pc_symbol",
715 "Use symbols for the PC if available", true);
716Param<bool> exe_trace_intel_format(&exeTraceParams, "intel_format",
717 "print trace in intel compatible format", false);
718Param<bool> exe_trace_legion_lockstep(&exeTraceParams, "legion_lockstep",
719 "Compare sim state to legion state every cycle",
720 false);
721Param<string> exe_trace_system(&exeTraceParams, "trace_system",
722 "print trace of which system (client or server)",
723 "client");
724
725
726//
727// Helper function for ExecutionTraceParamContext::checkParams() just
728// to get us into the InstRecord namespace
729//
730void
731Trace::InstRecord::setParams()
732{
733 flags[TRACE_MISSPEC] = exe_trace_spec;
734
735 flags[PRINT_CYCLE] = exe_trace_print_cycle;
736 flags[PRINT_OP_CLASS] = exe_trace_print_opclass;
737 flags[PRINT_THREAD_NUM] = exe_trace_print_thread;
738 flags[PRINT_RESULT_DATA] = exe_trace_print_effaddr;
739 flags[PRINT_EFF_ADDR] = exe_trace_print_data;
740 flags[PRINT_INT_REGS] = exe_trace_print_iregs;
741 flags[PRINT_FETCH_SEQ] = exe_trace_print_fetchseq;
742 flags[PRINT_CP_SEQ] = exe_trace_print_cp_seq;
743 flags[PRINT_REG_DELTA] = exe_trace_print_reg_delta;
744 flags[PC_SYMBOL] = exe_trace_pc_symbol;
745 flags[INTEL_FORMAT] = exe_trace_intel_format;
746 flags[LEGION_LOCKSTEP] = exe_trace_legion_lockstep;
747 trace_system = exe_trace_system;
748
749 // If were going to be in lockstep with Legion
750 // Setup shared memory, and get otherwise ready
751 if (flags[LEGION_LOCKSTEP]) {
752 int shmfd = shmget('M' << 24 | getuid(), sizeof(SharedData), 0777);
753 if (shmfd < 0)
754 fatal("Couldn't get shared memory fd. Is Legion running?");
755
756 shared_data = (SharedData*)shmat(shmfd, NULL, SHM_RND);
757 if (shared_data == (SharedData*)-1)
758 fatal("Couldn't allocate shared memory");
759
760 if (shared_data->flags != OWN_M5)
761 fatal("Shared memory has invalid owner");
762
763 if (shared_data->version != VERSION)
764 fatal("Shared Data is wrong version! M5: %d Legion: %d", VERSION,
765 shared_data->version);
766
767 // step legion forward one cycle so we can get register values
768 shared_data->flags = OWN_LEGION;
769 }
770}
771
772void
773ExecutionTraceParamContext::checkParams()
774{
775 Trace::InstRecord::setParams();
776}
777