Merge zizzer:/bk/newmem
[gem5.git] / src / cpu / exetrace.cc
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 <errno.h>
35 #include <fstream>
36 #include <iomanip>
37 #include <sys/ipc.h>
38 #include <sys/shm.h>
39
40 #include "arch/predecoder.hh"
41 #include "arch/regfile.hh"
42 #include "arch/utility.hh"
43 #include "base/loader/symtab.hh"
44 #include "base/socket.hh"
45 #include "config/full_system.hh"
46 #include "cpu/base.hh"
47 #include "cpu/exetrace.hh"
48 #include "cpu/static_inst.hh"
49 #include "sim/param.hh"
50 #include "sim/system.hh"
51
52 #if FULL_SYSTEM
53 #include "arch/tlb.hh"
54 #endif
55
56 //XXX This is temporary
57 #include "arch/isa_specific.hh"
58 #include "cpu/m5legion_interface.h"
59
60 using namespace std;
61 using namespace TheISA;
62
63 #if THE_ISA == SPARC_ISA && FULL_SYSTEM
64 static int diffcount = 0;
65 static bool wasMicro = false;
66 #endif
67
68 namespace Trace {
69 SharedData *shared_data = NULL;
70 ListenSocket *cosim_listener = NULL;
71
72 void
73 setupSharedData()
74 {
75 int shmfd = shmget('M' << 24 | getuid(), sizeof(SharedData), 0777);
76 if (shmfd < 0)
77 fatal("Couldn't get shared memory fd. Is Legion running?");
78
79 shared_data = (SharedData*)shmat(shmfd, NULL, SHM_RND);
80 if (shared_data == (SharedData*)-1)
81 fatal("Couldn't allocate shared memory");
82
83 if (shared_data->flags != OWN_M5)
84 fatal("Shared memory has invalid owner");
85
86 if (shared_data->version != VERSION)
87 fatal("Shared Data is wrong version! M5: %d Legion: %d", VERSION,
88 shared_data->version);
89
90 // step legion forward one cycle so we can get register values
91 shared_data->flags = OWN_LEGION;
92 }
93
94 ////////////////////////////////////////////////////////////////////////
95 //
96 // Methods for the InstRecord object
97 //
98
99 #if THE_ISA == SPARC_ISA
100
101 inline char * genCenteredLabel(int length, char * buffer, char * label)
102 {
103 int labelLength = strlen(label);
104 assert(labelLength <= length);
105 int leftPad = (length - labelLength) / 2;
106 int rightPad = length - leftPad - labelLength;
107 char format[64];
108 sprintf(format, "%%%ds%%s%%%ds", leftPad, rightPad);
109 sprintf(buffer, format, "", label, "");
110 return buffer;
111 }
112
113 inline void printRegPair(ostream & os, char const * title, uint64_t a, uint64_t b)
114 {
115 ccprintf(os, " %16s | %#018x %s %#-018x \n",
116 title, a, (a == b) ? "|" : "X", b);
117 }
118
119 inline void printColumnLabels(ostream & os)
120 {
121 static char * regLabel = genCenteredLabel(16, new char[17], "Register");
122 static char * m5Label = genCenteredLabel(18, new char[18], "M5");
123 static char * legionLabel = genCenteredLabel(18, new char[18], "Legion");
124 ccprintf(os, " %s | %s | %s \n", regLabel, m5Label, legionLabel);
125 ccprintf(os, "--------------------+-----------------------+-----------------------\n");
126 }
127
128 inline void printSectionHeader(ostream & os, char * name)
129 {
130 char sectionString[70];
131 genCenteredLabel(69, sectionString, name);
132 ccprintf(os, "====================================================================\n");
133 ccprintf(os, "%69s\n", sectionString);
134 ccprintf(os, "====================================================================\n");
135 }
136
137 inline void printLevelHeader(ostream & os, int level)
138 {
139 char sectionString[70];
140 char levelName[70];
141 sprintf(levelName, "Trap stack level %d", level);
142 genCenteredLabel(69, sectionString, levelName);
143 ccprintf(os, "====================================================================\n");
144 ccprintf(os, "%69s\n", sectionString);
145 ccprintf(os, "====================================================================\n");
146 }
147
148 #endif
149
150 void
151 Trace::InstRecord::dump()
152 {
153 ostream &outs = Trace::output();
154
155 DPRINTF(Sparc, "Instruction: %#X\n", staticInst->machInst);
156 bool diff = true;
157 if (IsOn(ExecRegDelta))
158 {
159 diff = false;
160 #ifndef NDEBUG
161 #if THE_ISA == SPARC_ISA
162 static int fd = 0;
163 //Don't print what happens for each micro-op, just print out
164 //once at the last op, and for regular instructions.
165 if(!staticInst->isMicroOp() || staticInst->isLastMicroOp())
166 {
167 if(!cosim_listener)
168 {
169 int port = 8000;
170 cosim_listener = new ListenSocket();
171 while(!cosim_listener->listen(port, true))
172 {
173 DPRINTF(GDBMisc, "Can't bind port %d\n", port);
174 port++;
175 }
176 ccprintf(cerr, "Listening for cosimulator on port %d\n", port);
177 fd = cosim_listener->accept();
178 }
179 char prefix[] = "goli";
180 for(int p = 0; p < 4; p++)
181 {
182 for(int i = 0; i < 8; i++)
183 {
184 uint64_t regVal;
185 int res = read(fd, &regVal, sizeof(regVal));
186 if(res < 0)
187 panic("First read call failed! %s\n", strerror(errno));
188 regVal = TheISA::gtoh(regVal);
189 uint64_t realRegVal = thread->readIntReg(p * 8 + i);
190 if((regVal & 0xffffffffULL) != (realRegVal & 0xffffffffULL))
191 {
192 DPRINTF(ExecRegDelta, "Register %s%d should be %#x but is %#x.\n", prefix[p], i, regVal, realRegVal);
193 diff = true;
194 }
195 //ccprintf(outs, "%s%d m5 = %#x statetrace = %#x\n", prefix[p], i, realRegVal, regVal);
196 }
197 }
198 /*for(int f = 0; f <= 62; f+=2)
199 {
200 uint64_t regVal;
201 int res = read(fd, &regVal, sizeof(regVal));
202 if(res < 0)
203 panic("First read call failed! %s\n", strerror(errno));
204 regVal = TheISA::gtoh(regVal);
205 uint64_t realRegVal = thread->readFloatRegBits(f, 64);
206 if(regVal != realRegVal)
207 {
208 DPRINTF(ExecRegDelta, "Register f%d should be %#x but is %#x.\n", f, regVal, realRegVal);
209 }
210 }*/
211 uint64_t regVal;
212 int res = read(fd, &regVal, sizeof(regVal));
213 if(res < 0)
214 panic("First read call failed! %s\n", strerror(errno));
215 regVal = TheISA::gtoh(regVal);
216 uint64_t realRegVal = thread->readNextPC();
217 if(regVal != realRegVal)
218 {
219 DPRINTF(ExecRegDelta, "Register pc should be %#x but is %#x.\n", regVal, realRegVal);
220 diff = true;
221 }
222 res = read(fd, &regVal, sizeof(regVal));
223 if(res < 0)
224 panic("First read call failed! %s\n", strerror(errno));
225 regVal = TheISA::gtoh(regVal);
226 realRegVal = thread->readNextNPC();
227 if(regVal != realRegVal)
228 {
229 DPRINTF(ExecRegDelta, "Register npc should be %#x but is %#x.\n", regVal, realRegVal);
230 diff = true;
231 }
232 res = read(fd, &regVal, sizeof(regVal));
233 if(res < 0)
234 panic("First read call failed! %s\n", strerror(errno));
235 regVal = TheISA::gtoh(regVal);
236 realRegVal = thread->readIntReg(SparcISA::NumIntArchRegs + 2);
237 if((regVal & 0xF) != (realRegVal & 0xF))
238 {
239 DPRINTF(ExecRegDelta, "Register ccr should be %#x but is %#x.\n", regVal, realRegVal);
240 diff = true;
241 }
242 }
243 #endif
244 #endif
245 #if 0 //THE_ISA == SPARC_ISA
246 //Don't print what happens for each micro-op, just print out
247 //once at the last op, and for regular instructions.
248 if(!staticInst->isMicroOp() || staticInst->isLastMicroOp())
249 {
250 static uint64_t regs[32] = {
251 0, 0, 0, 0, 0, 0, 0, 0,
252 0, 0, 0, 0, 0, 0, 0, 0,
253 0, 0, 0, 0, 0, 0, 0, 0,
254 0, 0, 0, 0, 0, 0, 0, 0};
255 static uint64_t ccr = 0;
256 static uint64_t y = 0;
257 static uint64_t floats[32];
258 uint64_t newVal;
259 static const char * prefixes[4] = {"G", "O", "L", "I"};
260
261 outs << hex;
262 outs << "PC = " << thread->readNextPC();
263 outs << " NPC = " << thread->readNextNPC();
264 newVal = thread->readIntReg(SparcISA::NumIntArchRegs + 2);
265 //newVal = thread->readMiscRegNoEffect(SparcISA::MISCREG_CCR);
266 if(newVal != ccr)
267 {
268 outs << " CCR = " << newVal;
269 ccr = newVal;
270 }
271 newVal = thread->readIntReg(SparcISA::NumIntArchRegs + 1);
272 //newVal = thread->readMiscRegNoEffect(SparcISA::MISCREG_Y);
273 if(newVal != y)
274 {
275 outs << " Y = " << newVal;
276 y = newVal;
277 }
278 for(int y = 0; y < 4; y++)
279 {
280 for(int x = 0; x < 8; x++)
281 {
282 int index = x + 8 * y;
283 newVal = thread->readIntReg(index);
284 if(regs[index] != newVal)
285 {
286 outs << " " << prefixes[y] << dec << x << " = " << hex << newVal;
287 regs[index] = newVal;
288 }
289 }
290 }
291 for(int y = 0; y < 32; y++)
292 {
293 newVal = thread->readFloatRegBits(2 * y, 64);
294 if(floats[y] != newVal)
295 {
296 outs << " F" << dec << (2 * y) << " = " << hex << newVal;
297 floats[y] = newVal;
298 }
299 }
300 outs << dec << endl;
301 }
302 #endif
303 }
304 if(!diff) {
305 } else if (IsOn(ExecIntel)) {
306 ccprintf(outs, "%7d ) ", when);
307 outs << "0x" << hex << PC << ":\t";
308 if (staticInst->isLoad()) {
309 ccprintf(outs, "<RD %#x>", addr);
310 } else if (staticInst->isStore()) {
311 ccprintf(outs, "<WR %#x>", addr);
312 }
313 outs << endl;
314 } else {
315 if (IsOn(ExecTicks))
316 ccprintf(outs, "%7d: ", when);
317
318 outs << thread->getCpuPtr()->name() << " ";
319
320 if (IsOn(ExecSpeculative))
321 outs << (misspeculating ? "-" : "+") << " ";
322
323 if (IsOn(ExecThread))
324 outs << "T" << thread->getThreadNum() << " : ";
325
326
327 std::string sym_str;
328 Addr sym_addr;
329 if (debugSymbolTable
330 && debugSymbolTable->findNearestSymbol(PC, sym_str, sym_addr)
331 && IsOn(ExecSymbol)) {
332 if (PC != sym_addr)
333 sym_str += csprintf("+%d", PC - sym_addr);
334 outs << "@" << sym_str << " : ";
335 }
336 else {
337 outs << "0x" << hex << PC << " : ";
338 }
339
340 //
341 // Print decoded instruction
342 //
343
344 #if defined(__GNUC__) && (__GNUC__ < 3)
345 // There's a bug in gcc 2.x library that prevents setw()
346 // from working properly on strings
347 string mc(staticInst->disassemble(PC, debugSymbolTable));
348 while (mc.length() < 26)
349 mc += " ";
350 outs << mc;
351 #else
352 outs << setw(26) << left << staticInst->disassemble(PC, debugSymbolTable);
353 #endif
354
355 outs << " : ";
356
357 if (IsOn(ExecOpClass)) {
358 outs << opClassStrings[staticInst->opClass()] << " : ";
359 }
360
361 if (IsOn(ExecResult) && data_status != DataInvalid) {
362 outs << " D=";
363 #if 0
364 if (data_status == DataDouble)
365 ccprintf(outs, "%f", data.as_double);
366 else
367 ccprintf(outs, "%#018x", data.as_int);
368 #else
369 ccprintf(outs, "%#018x", data.as_int);
370 #endif
371 }
372
373 if (IsOn(ExecEffAddr) && addr_valid)
374 outs << " A=0x" << hex << addr;
375
376 if (IsOn(ExecIntRegs) && regs_valid) {
377 for (int i = 0; i < TheISA::NumIntRegs;)
378 for (int j = i + 1; i <= j; i++)
379 ccprintf(outs, "r%02d = %#018x%s", i,
380 iregs->regs.readReg(i),
381 ((i == j) ? "\n" : " "));
382 outs << "\n";
383 }
384
385 if (IsOn(ExecFetchSeq) && fetch_seq_valid)
386 outs << " FetchSeq=" << dec << fetch_seq;
387
388 if (IsOn(ExecCPSeq) && cp_seq_valid)
389 outs << " CPSeq=" << dec << cp_seq;
390
391 //
392 // End of line...
393 //
394 outs << endl;
395 }
396 #if THE_ISA == SPARC_ISA && FULL_SYSTEM
397 static TheISA::Predecoder predecoder(NULL);
398 // Compare
399 if (IsOn(ExecLegion))
400 {
401 bool compared = false;
402 bool diffPC = false;
403 bool diffCC = false;
404 bool diffInst = false;
405 bool diffIntRegs = false;
406 bool diffFpRegs = false;
407 bool diffTpc = false;
408 bool diffTnpc = false;
409 bool diffTstate = false;
410 bool diffTt = false;
411 bool diffTba = false;
412 bool diffHpstate = false;
413 bool diffHtstate = false;
414 bool diffHtba = false;
415 bool diffPstate = false;
416 bool diffY = false;
417 bool diffFsr = false;
418 bool diffCcr = false;
419 bool diffTl = false;
420 bool diffGl = false;
421 bool diffAsi = false;
422 bool diffPil = false;
423 bool diffCwp = false;
424 bool diffCansave = false;
425 bool diffCanrestore = false;
426 bool diffOtherwin = false;
427 bool diffCleanwin = false;
428 bool diffTlb = false;
429 Addr m5Pc, lgnPc;
430
431 if (!shared_data)
432 setupSharedData();
433
434 // We took a trap on a micro-op...
435 if (wasMicro && !staticInst->isMicroOp())
436 {
437 // let's skip comparing this tick
438 while (!compared)
439 if (shared_data->flags == OWN_M5) {
440 shared_data->flags = OWN_LEGION;
441 compared = true;
442 }
443 compared = false;
444 wasMicro = false;
445 }
446
447 if (staticInst->isLastMicroOp())
448 wasMicro = false;
449 else if (staticInst->isMicroOp())
450 wasMicro = true;
451
452
453 if(!staticInst->isMicroOp() || staticInst->isLastMicroOp()) {
454 while (!compared) {
455 if (shared_data->flags == OWN_M5) {
456 m5Pc = PC & TheISA::PAddrImplMask;
457 if (bits(shared_data->pstate,3,3)) {
458 m5Pc &= mask(32);
459 }
460 lgnPc = shared_data->pc & TheISA::PAddrImplMask;
461 if (lgnPc != m5Pc)
462 diffPC = true;
463
464 if (shared_data->cycle_count !=
465 thread->getCpuPtr()->instCount())
466 diffCC = true;
467
468 if (shared_data->instruction !=
469 (SparcISA::MachInst)staticInst->machInst) {
470 diffInst = true;
471 }
472 // assume we have %g0 working correctly
473 for (int i = 1; i < TheISA::NumIntArchRegs; i++) {
474 if (thread->readIntReg(i) != shared_data->intregs[i]) {
475 diffIntRegs = true;
476 }
477 }
478 for (int i = 0; i < TheISA::NumFloatRegs/2; i++) {
479 if (thread->readFloatRegBits(i*2,FloatRegFile::DoubleWidth) != shared_data->fpregs[i]) {
480 diffFpRegs = true;
481 }
482 }
483 uint64_t oldTl = thread->readMiscRegNoEffect(MISCREG_TL);
484 if (oldTl != shared_data->tl)
485 diffTl = true;
486 for (int i = 1; i <= MaxTL; i++) {
487 thread->setMiscRegNoEffect(MISCREG_TL, i);
488 if (thread->readMiscRegNoEffect(MISCREG_TPC) !=
489 shared_data->tpc[i-1])
490 diffTpc = true;
491 if (thread->readMiscRegNoEffect(MISCREG_TNPC) !=
492 shared_data->tnpc[i-1])
493 diffTnpc = true;
494 if (thread->readMiscRegNoEffect(MISCREG_TSTATE) !=
495 shared_data->tstate[i-1])
496 diffTstate = true;
497 if (thread->readMiscRegNoEffect(MISCREG_TT) !=
498 shared_data->tt[i-1])
499 diffTt = true;
500 if (thread->readMiscRegNoEffect(MISCREG_HTSTATE) !=
501 shared_data->htstate[i-1])
502 diffHtstate = true;
503 }
504 thread->setMiscRegNoEffect(MISCREG_TL, oldTl);
505
506 if(shared_data->tba != thread->readMiscRegNoEffect(MISCREG_TBA))
507 diffTba = true;
508 //When the hpstate register is read by an instruction,
509 //legion has bit 11 set. When it's in storage, it doesn't.
510 //Since we don't directly support seperate interpretations
511 //of the registers like that, the bit is always set to 1 and
512 //we just don't compare it. It's not supposed to matter
513 //anyway.
514 if((shared_data->hpstate | (1 << 11)) != thread->readMiscRegNoEffect(MISCREG_HPSTATE))
515 diffHpstate = true;
516 if(shared_data->htba != thread->readMiscRegNoEffect(MISCREG_HTBA))
517 diffHtba = true;
518 if(shared_data->pstate != thread->readMiscRegNoEffect(MISCREG_PSTATE))
519 diffPstate = true;
520 //if(shared_data->y != thread->readMiscRegNoEffect(MISCREG_Y))
521 if(shared_data->y !=
522 thread->readIntReg(NumIntArchRegs + 1))
523 diffY = true;
524 if(shared_data->fsr != thread->readMiscRegNoEffect(MISCREG_FSR)) {
525 diffFsr = true;
526 if (mbits(shared_data->fsr, 63,10) ==
527 mbits(thread->readMiscRegNoEffect(MISCREG_FSR), 63,10)) {
528 thread->setMiscRegNoEffect(MISCREG_FSR, shared_data->fsr);
529 diffFsr = false;
530 }
531 }
532 //if(shared_data->ccr != thread->readMiscRegNoEffect(MISCREG_CCR))
533 if(shared_data->ccr !=
534 thread->readIntReg(NumIntArchRegs + 2))
535 diffCcr = true;
536 if(shared_data->gl != thread->readMiscRegNoEffect(MISCREG_GL))
537 diffGl = true;
538 if(shared_data->asi != thread->readMiscRegNoEffect(MISCREG_ASI))
539 diffAsi = true;
540 if(shared_data->pil != thread->readMiscRegNoEffect(MISCREG_PIL))
541 diffPil = true;
542 if(shared_data->cwp != thread->readMiscRegNoEffect(MISCREG_CWP))
543 diffCwp = true;
544 //if(shared_data->cansave != thread->readMiscRegNoEffect(MISCREG_CANSAVE))
545 if(shared_data->cansave !=
546 thread->readIntReg(NumIntArchRegs + 3))
547 diffCansave = true;
548 //if(shared_data->canrestore !=
549 // thread->readMiscRegNoEffect(MISCREG_CANRESTORE))
550 if(shared_data->canrestore !=
551 thread->readIntReg(NumIntArchRegs + 4))
552 diffCanrestore = true;
553 //if(shared_data->otherwin != thread->readMiscRegNoEffect(MISCREG_OTHERWIN))
554 if(shared_data->otherwin !=
555 thread->readIntReg(NumIntArchRegs + 6))
556 diffOtherwin = true;
557 //if(shared_data->cleanwin != thread->readMiscRegNoEffect(MISCREG_CLEANWIN))
558 if(shared_data->cleanwin !=
559 thread->readIntReg(NumIntArchRegs + 5))
560 diffCleanwin = true;
561
562 for (int i = 0; i < 64; i++) {
563 if (shared_data->itb[i] != thread->getITBPtr()->TteRead(i))
564 diffTlb = true;
565 if (shared_data->dtb[i] != thread->getDTBPtr()->TteRead(i))
566 diffTlb = true;
567 }
568
569 if (diffPC || diffCC || diffInst || diffIntRegs ||
570 diffFpRegs || diffTpc || diffTnpc || diffTstate ||
571 diffTt || diffHpstate || diffHtstate || diffHtba ||
572 diffPstate || diffY || diffCcr || diffTl || diffFsr ||
573 diffGl || diffAsi || diffPil || diffCwp || diffCansave ||
574 diffCanrestore || diffOtherwin || diffCleanwin || diffTlb)
575 {
576
577 outs << "Differences found between M5 and Legion:";
578 if (diffPC)
579 outs << " [PC]";
580 if (diffCC)
581 outs << " [CC]";
582 if (diffInst)
583 outs << " [Instruction]";
584 if (diffIntRegs)
585 outs << " [IntRegs]";
586 if (diffFpRegs)
587 outs << " [FpRegs]";
588 if (diffTpc)
589 outs << " [Tpc]";
590 if (diffTnpc)
591 outs << " [Tnpc]";
592 if (diffTstate)
593 outs << " [Tstate]";
594 if (diffTt)
595 outs << " [Tt]";
596 if (diffHpstate)
597 outs << " [Hpstate]";
598 if (diffHtstate)
599 outs << " [Htstate]";
600 if (diffHtba)
601 outs << " [Htba]";
602 if (diffPstate)
603 outs << " [Pstate]";
604 if (diffY)
605 outs << " [Y]";
606 if (diffFsr)
607 outs << " [FSR]";
608 if (diffCcr)
609 outs << " [Ccr]";
610 if (diffTl)
611 outs << " [Tl]";
612 if (diffGl)
613 outs << " [Gl]";
614 if (diffAsi)
615 outs << " [Asi]";
616 if (diffPil)
617 outs << " [Pil]";
618 if (diffCwp)
619 outs << " [Cwp]";
620 if (diffCansave)
621 outs << " [Cansave]";
622 if (diffCanrestore)
623 outs << " [Canrestore]";
624 if (diffOtherwin)
625 outs << " [Otherwin]";
626 if (diffCleanwin)
627 outs << " [Cleanwin]";
628 if (diffTlb)
629 outs << " [Tlb]";
630 outs << endl << endl;
631
632 outs << right << setfill(' ') << setw(15)
633 << "M5 PC: " << "0x"<< setw(16) << setfill('0')
634 << hex << m5Pc << endl;
635 outs << setfill(' ') << setw(15)
636 << "Legion PC: " << "0x"<< setw(16) << setfill('0') << hex
637 << lgnPc << endl << endl;
638
639 outs << right << setfill(' ') << setw(15)
640 << "M5 CC: " << "0x"<< setw(16) << setfill('0')
641 << hex << thread->getCpuPtr()->instCount() << endl;
642 outs << setfill(' ') << setw(15)
643 << "Legion CC: " << "0x"<< setw(16) << setfill('0') << hex
644 << shared_data->cycle_count << endl << endl;
645
646 outs << setfill(' ') << setw(15)
647 << "M5 Inst: " << "0x"<< setw(8)
648 << setfill('0') << hex << staticInst->machInst
649 << staticInst->disassemble(m5Pc, debugSymbolTable)
650 << endl;
651
652 predecoder.setTC(thread);
653 predecoder.moreBytes(m5Pc, 0, shared_data->instruction);
654
655 assert(predecoder.extMachInstRead());
656
657 StaticInstPtr legionInst =
658 StaticInst::decode(predecoder.getExtMachInst());
659 outs << setfill(' ') << setw(15)
660 << " Legion Inst: "
661 << "0x" << setw(8) << setfill('0') << hex
662 << shared_data->instruction
663 << legionInst->disassemble(lgnPc, debugSymbolTable)
664 << endl << endl;
665
666 printSectionHeader(outs, "General State");
667 printColumnLabels(outs);
668 printRegPair(outs, "HPstate",
669 thread->readMiscRegNoEffect(MISCREG_HPSTATE),
670 shared_data->hpstate | (1 << 11));
671 printRegPair(outs, "Htba",
672 thread->readMiscRegNoEffect(MISCREG_HTBA),
673 shared_data->htba);
674 printRegPair(outs, "Pstate",
675 thread->readMiscRegNoEffect(MISCREG_PSTATE),
676 shared_data->pstate);
677 printRegPair(outs, "Y",
678 //thread->readMiscRegNoEffect(MISCREG_Y),
679 thread->readIntReg(NumIntArchRegs + 1),
680 shared_data->y);
681 printRegPair(outs, "FSR",
682 thread->readMiscRegNoEffect(MISCREG_FSR),
683 shared_data->fsr);
684 printRegPair(outs, "Ccr",
685 //thread->readMiscRegNoEffect(MISCREG_CCR),
686 thread->readIntReg(NumIntArchRegs + 2),
687 shared_data->ccr);
688 printRegPair(outs, "Tl",
689 thread->readMiscRegNoEffect(MISCREG_TL),
690 shared_data->tl);
691 printRegPair(outs, "Gl",
692 thread->readMiscRegNoEffect(MISCREG_GL),
693 shared_data->gl);
694 printRegPair(outs, "Asi",
695 thread->readMiscRegNoEffect(MISCREG_ASI),
696 shared_data->asi);
697 printRegPair(outs, "Pil",
698 thread->readMiscRegNoEffect(MISCREG_PIL),
699 shared_data->pil);
700 printRegPair(outs, "Cwp",
701 thread->readMiscRegNoEffect(MISCREG_CWP),
702 shared_data->cwp);
703 printRegPair(outs, "Cansave",
704 //thread->readMiscRegNoEffect(MISCREG_CANSAVE),
705 thread->readIntReg(NumIntArchRegs + 3),
706 shared_data->cansave);
707 printRegPair(outs, "Canrestore",
708 //thread->readMiscRegNoEffect(MISCREG_CANRESTORE),
709 thread->readIntReg(NumIntArchRegs + 4),
710 shared_data->canrestore);
711 printRegPair(outs, "Otherwin",
712 //thread->readMiscRegNoEffect(MISCREG_OTHERWIN),
713 thread->readIntReg(NumIntArchRegs + 6),
714 shared_data->otherwin);
715 printRegPair(outs, "Cleanwin",
716 //thread->readMiscRegNoEffect(MISCREG_CLEANWIN),
717 thread->readIntReg(NumIntArchRegs + 5),
718 shared_data->cleanwin);
719 outs << endl;
720 for (int i = 1; i <= MaxTL; i++) {
721 printLevelHeader(outs, i);
722 printColumnLabels(outs);
723 thread->setMiscRegNoEffect(MISCREG_TL, i);
724 printRegPair(outs, "Tpc",
725 thread->readMiscRegNoEffect(MISCREG_TPC),
726 shared_data->tpc[i-1]);
727 printRegPair(outs, "Tnpc",
728 thread->readMiscRegNoEffect(MISCREG_TNPC),
729 shared_data->tnpc[i-1]);
730 printRegPair(outs, "Tstate",
731 thread->readMiscRegNoEffect(MISCREG_TSTATE),
732 shared_data->tstate[i-1]);
733 printRegPair(outs, "Tt",
734 thread->readMiscRegNoEffect(MISCREG_TT),
735 shared_data->tt[i-1]);
736 printRegPair(outs, "Htstate",
737 thread->readMiscRegNoEffect(MISCREG_HTSTATE),
738 shared_data->htstate[i-1]);
739 }
740 thread->setMiscRegNoEffect(MISCREG_TL, oldTl);
741 outs << endl;
742
743 printSectionHeader(outs, "General Purpose Registers");
744 static const char * regtypes[4] = {"%g", "%o", "%l", "%i"};
745 for(int y = 0; y < 4; y++) {
746 for(int x = 0; x < 8; x++) {
747 char label[8];
748 sprintf(label, "%s%d", regtypes[y], x);
749 printRegPair(outs, label,
750 thread->readIntReg(y*8+x),
751 shared_data->intregs[y*8+x]);
752 }
753 }
754 if (diffFpRegs) {
755 for (int x = 0; x < 32; x++) {
756 char label[8];
757 sprintf(label, "%%f%d", x);
758 printRegPair(outs, label,
759 thread->readFloatRegBits(x*2,FloatRegFile::DoubleWidth),
760 shared_data->fpregs[x]);
761 }
762 }
763 if (diffTlb) {
764 printColumnLabels(outs);
765 char label[8];
766 for (int x = 0; x < 64; x++) {
767 if (shared_data->itb[x] != ULL(0xFFFFFFFFFFFFFFFF) ||
768 thread->getITBPtr()->TteRead(x) != ULL(0xFFFFFFFFFFFFFFFF)) {
769 sprintf(label, "I-TLB:%02d", x);
770 printRegPair(outs, label, thread->getITBPtr()->TteRead(x),
771 shared_data->itb[x]);
772 }
773 }
774 for (int x = 0; x < 64; x++) {
775 if (shared_data->dtb[x] != ULL(0xFFFFFFFFFFFFFFFF) ||
776 thread->getDTBPtr()->TteRead(x) != ULL(0xFFFFFFFFFFFFFFFF)) {
777 sprintf(label, "D-TLB:%02d", x);
778 printRegPair(outs, label, thread->getDTBPtr()->TteRead(x),
779 shared_data->dtb[x]);
780 }
781 }
782 thread->getITBPtr()->dumpAll();
783 thread->getDTBPtr()->dumpAll();
784 }
785
786 diffcount++;
787 if (diffcount > 3)
788 fatal("Differences found between Legion and M5\n");
789 } else
790 diffcount = 0;
791
792 compared = true;
793 shared_data->flags = OWN_LEGION;
794 }
795 } // while
796 } // if not microop
797 }
798 #endif
799 }
800
801 /* namespace Trace */ }