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