exetrace.cc (3903:f005d99d790a) exetrace.cc (3928:9486450f013f)
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->readMiscReg(SparcISA::MISCREG_CCR);
151 if(newVal != ccr)
152 {
153 outs << " CCR = " << newVal;
154 ccr = newVal;
155 }
156 newVal = thread->readMiscReg(SparcISA::MISCREG_Y);
157 if(newVal != y)
158 {
159 outs << " Y = " << newVal;
160 y = newVal;
161 }
162 for(int y = 0; y < 4; y++)
163 {
164 for(int x = 0; x < 8; x++)
165 {
166 int index = x + 8 * y;
167 newVal = thread->readIntReg(index);
168 if(regs[index] != newVal)
169 {
170 outs << " " << prefixes[y] << dec << x << " = " << hex << newVal;
171 regs[index] = newVal;
172 }
173 }
174 }
175 for(int y = 0; y < 32; y++)
176 {
177 newVal = thread->readFloatRegBits(2 * y, 64);
178 if(floats[y] != newVal)
179 {
180 outs << " F" << dec << (2 * y) << " = " << hex << newVal;
181 floats[y] = newVal;
182 }
183 }
184 outs << dec << endl;
185 }
186#endif
187 }
188 else if (flags[INTEL_FORMAT]) {
189#if FULL_SYSTEM
190 bool is_trace_system = (thread->getCpuPtr()->system->name() == trace_system);
191#else
192 bool is_trace_system = true;
193#endif
194 if (is_trace_system) {
195 ccprintf(outs, "%7d ) ", cycle);
196 outs << "0x" << hex << PC << ":\t";
197 if (staticInst->isLoad()) {
198 outs << "<RD 0x" << hex << addr;
199 outs << ">";
200 } else if (staticInst->isStore()) {
201 outs << "<WR 0x" << hex << addr;
202 outs << ">";
203 }
204 outs << endl;
205 }
206 } else {
207 if (flags[PRINT_CYCLE])
208 ccprintf(outs, "%7d: ", cycle);
209
210 outs << thread->getCpuPtr()->name() << " ";
211
212 if (flags[TRACE_MISSPEC])
213 outs << (misspeculating ? "-" : "+") << " ";
214
215 if (flags[PRINT_THREAD_NUM])
216 outs << "T" << thread->getThreadNum() << " : ";
217
218
219 std::string sym_str;
220 Addr sym_addr;
221 if (debugSymbolTable
222 && debugSymbolTable->findNearestSymbol(PC, sym_str, sym_addr)
223 && flags[PC_SYMBOL]) {
224 if (PC != sym_addr)
225 sym_str += csprintf("+%d", PC - sym_addr);
226 outs << "@" << sym_str << " : ";
227 }
228 else {
229 outs << "0x" << hex << PC << " : ";
230 }
231
232 //
233 // Print decoded instruction
234 //
235
236#if defined(__GNUC__) && (__GNUC__ < 3)
237 // There's a bug in gcc 2.x library that prevents setw()
238 // from working properly on strings
239 string mc(staticInst->disassemble(PC, debugSymbolTable));
240 while (mc.length() < 26)
241 mc += " ";
242 outs << mc;
243#else
244 outs << setw(26) << left << staticInst->disassemble(PC, debugSymbolTable);
245#endif
246
247 outs << " : ";
248
249 if (flags[PRINT_OP_CLASS]) {
250 outs << opClassStrings[staticInst->opClass()] << " : ";
251 }
252
253 if (flags[PRINT_RESULT_DATA] && data_status != DataInvalid) {
254 outs << " D=";
255#if 0
256 if (data_status == DataDouble)
257 ccprintf(outs, "%f", data.as_double);
258 else
259 ccprintf(outs, "%#018x", data.as_int);
260#else
261 ccprintf(outs, "%#018x", data.as_int);
262#endif
263 }
264
265 if (flags[PRINT_EFF_ADDR] && addr_valid)
266 outs << " A=0x" << hex << addr;
267
268 if (flags[PRINT_INT_REGS] && regs_valid) {
269 for (int i = 0; i < TheISA::NumIntRegs;)
270 for (int j = i + 1; i <= j; i++)
271 ccprintf(outs, "r%02d = %#018x%s", i,
272 iregs->regs.readReg(i),
273 ((i == j) ? "\n" : " "));
274 outs << "\n";
275 }
276
277 if (flags[PRINT_FETCH_SEQ] && fetch_seq_valid)
278 outs << " FetchSeq=" << dec << fetch_seq;
279
280 if (flags[PRINT_CP_SEQ] && cp_seq_valid)
281 outs << " CPSeq=" << dec << cp_seq;
282
283 //
284 // End of line...
285 //
286 outs << endl;
287 }
288#if THE_ISA == SPARC_ISA && FULL_SYSTEM
289 // Compare
290 if (flags[LEGION_LOCKSTEP])
291 {
292 bool compared = false;
293 bool diffPC = false;
294 bool diffCC = false;
295 bool diffInst = false;
296 bool diffRegs = false;
297 bool diffTpc = false;
298 bool diffTnpc = false;
299 bool diffTstate = false;
300 bool diffTt = false;
301 bool diffTba = false;
302 bool diffHpstate = false;
303 bool diffHtstate = false;
304 bool diffHtba = false;
305 bool diffPstate = false;
306 bool diffY = false;
307 bool diffCcr = false;
308 bool diffTl = false;
309 bool diffGl = false;
310 bool diffAsi = false;
311 bool diffPil = false;
312 bool diffCwp = false;
313 bool diffCansave = false;
314 bool diffCanrestore = false;
315 bool diffOtherwin = false;
316 bool diffCleanwin = false;
317 bool diffTlb = false;
318 Addr m5Pc, lgnPc;
319
320 // We took a trap on a micro-op...
321 if (wasMicro && !staticInst->isMicroOp())
322 {
323 // let's skip comparing this cycle
324 while (!compared)
325 if (shared_data->flags == OWN_M5) {
326 shared_data->flags = OWN_LEGION;
327 compared = true;
328 }
329 compared = false;
330 wasMicro = false;
331 }
332
333 if (staticInst->isLastMicroOp())
334 wasMicro = false;
335 else if (staticInst->isMicroOp())
336 wasMicro = true;
337
338
339 if(!staticInst->isMicroOp() || staticInst->isLastMicroOp()) {
340 while (!compared) {
341 if (shared_data->flags == OWN_M5) {
342 m5Pc = PC & TheISA::PAddrImplMask;
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->readMiscReg(SparcISA::MISCREG_CCR);
151 if(newVal != ccr)
152 {
153 outs << " CCR = " << newVal;
154 ccr = newVal;
155 }
156 newVal = thread->readMiscReg(SparcISA::MISCREG_Y);
157 if(newVal != y)
158 {
159 outs << " Y = " << newVal;
160 y = newVal;
161 }
162 for(int y = 0; y < 4; y++)
163 {
164 for(int x = 0; x < 8; x++)
165 {
166 int index = x + 8 * y;
167 newVal = thread->readIntReg(index);
168 if(regs[index] != newVal)
169 {
170 outs << " " << prefixes[y] << dec << x << " = " << hex << newVal;
171 regs[index] = newVal;
172 }
173 }
174 }
175 for(int y = 0; y < 32; y++)
176 {
177 newVal = thread->readFloatRegBits(2 * y, 64);
178 if(floats[y] != newVal)
179 {
180 outs << " F" << dec << (2 * y) << " = " << hex << newVal;
181 floats[y] = newVal;
182 }
183 }
184 outs << dec << endl;
185 }
186#endif
187 }
188 else if (flags[INTEL_FORMAT]) {
189#if FULL_SYSTEM
190 bool is_trace_system = (thread->getCpuPtr()->system->name() == trace_system);
191#else
192 bool is_trace_system = true;
193#endif
194 if (is_trace_system) {
195 ccprintf(outs, "%7d ) ", cycle);
196 outs << "0x" << hex << PC << ":\t";
197 if (staticInst->isLoad()) {
198 outs << "<RD 0x" << hex << addr;
199 outs << ">";
200 } else if (staticInst->isStore()) {
201 outs << "<WR 0x" << hex << addr;
202 outs << ">";
203 }
204 outs << endl;
205 }
206 } else {
207 if (flags[PRINT_CYCLE])
208 ccprintf(outs, "%7d: ", cycle);
209
210 outs << thread->getCpuPtr()->name() << " ";
211
212 if (flags[TRACE_MISSPEC])
213 outs << (misspeculating ? "-" : "+") << " ";
214
215 if (flags[PRINT_THREAD_NUM])
216 outs << "T" << thread->getThreadNum() << " : ";
217
218
219 std::string sym_str;
220 Addr sym_addr;
221 if (debugSymbolTable
222 && debugSymbolTable->findNearestSymbol(PC, sym_str, sym_addr)
223 && flags[PC_SYMBOL]) {
224 if (PC != sym_addr)
225 sym_str += csprintf("+%d", PC - sym_addr);
226 outs << "@" << sym_str << " : ";
227 }
228 else {
229 outs << "0x" << hex << PC << " : ";
230 }
231
232 //
233 // Print decoded instruction
234 //
235
236#if defined(__GNUC__) && (__GNUC__ < 3)
237 // There's a bug in gcc 2.x library that prevents setw()
238 // from working properly on strings
239 string mc(staticInst->disassemble(PC, debugSymbolTable));
240 while (mc.length() < 26)
241 mc += " ";
242 outs << mc;
243#else
244 outs << setw(26) << left << staticInst->disassemble(PC, debugSymbolTable);
245#endif
246
247 outs << " : ";
248
249 if (flags[PRINT_OP_CLASS]) {
250 outs << opClassStrings[staticInst->opClass()] << " : ";
251 }
252
253 if (flags[PRINT_RESULT_DATA] && data_status != DataInvalid) {
254 outs << " D=";
255#if 0
256 if (data_status == DataDouble)
257 ccprintf(outs, "%f", data.as_double);
258 else
259 ccprintf(outs, "%#018x", data.as_int);
260#else
261 ccprintf(outs, "%#018x", data.as_int);
262#endif
263 }
264
265 if (flags[PRINT_EFF_ADDR] && addr_valid)
266 outs << " A=0x" << hex << addr;
267
268 if (flags[PRINT_INT_REGS] && regs_valid) {
269 for (int i = 0; i < TheISA::NumIntRegs;)
270 for (int j = i + 1; i <= j; i++)
271 ccprintf(outs, "r%02d = %#018x%s", i,
272 iregs->regs.readReg(i),
273 ((i == j) ? "\n" : " "));
274 outs << "\n";
275 }
276
277 if (flags[PRINT_FETCH_SEQ] && fetch_seq_valid)
278 outs << " FetchSeq=" << dec << fetch_seq;
279
280 if (flags[PRINT_CP_SEQ] && cp_seq_valid)
281 outs << " CPSeq=" << dec << cp_seq;
282
283 //
284 // End of line...
285 //
286 outs << endl;
287 }
288#if THE_ISA == SPARC_ISA && FULL_SYSTEM
289 // Compare
290 if (flags[LEGION_LOCKSTEP])
291 {
292 bool compared = false;
293 bool diffPC = false;
294 bool diffCC = false;
295 bool diffInst = false;
296 bool diffRegs = false;
297 bool diffTpc = false;
298 bool diffTnpc = false;
299 bool diffTstate = false;
300 bool diffTt = false;
301 bool diffTba = false;
302 bool diffHpstate = false;
303 bool diffHtstate = false;
304 bool diffHtba = false;
305 bool diffPstate = false;
306 bool diffY = false;
307 bool diffCcr = false;
308 bool diffTl = false;
309 bool diffGl = false;
310 bool diffAsi = false;
311 bool diffPil = false;
312 bool diffCwp = false;
313 bool diffCansave = false;
314 bool diffCanrestore = false;
315 bool diffOtherwin = false;
316 bool diffCleanwin = false;
317 bool diffTlb = false;
318 Addr m5Pc, lgnPc;
319
320 // We took a trap on a micro-op...
321 if (wasMicro && !staticInst->isMicroOp())
322 {
323 // let's skip comparing this cycle
324 while (!compared)
325 if (shared_data->flags == OWN_M5) {
326 shared_data->flags = OWN_LEGION;
327 compared = true;
328 }
329 compared = false;
330 wasMicro = false;
331 }
332
333 if (staticInst->isLastMicroOp())
334 wasMicro = false;
335 else if (staticInst->isMicroOp())
336 wasMicro = true;
337
338
339 if(!staticInst->isMicroOp() || staticInst->isLastMicroOp()) {
340 while (!compared) {
341 if (shared_data->flags == OWN_M5) {
342 m5Pc = PC & TheISA::PAddrImplMask;
343 if (bits(shared_data->pstate,3,3)) {
344 m5Pc &= mask(32);
345 }
343 lgnPc = shared_data->pc & TheISA::PAddrImplMask;
344 if (lgnPc != m5Pc)
345 diffPC = true;
346
347 if (shared_data->cycle_count !=
348 thread->getCpuPtr()->instCount())
349 diffCC = true;
350
351 if (shared_data->instruction !=
352 (SparcISA::MachInst)staticInst->machInst) {
353 diffInst = true;
354 }
355 for (int i = 0; i < TheISA::NumIntArchRegs; i++) {
356 if (thread->readIntReg(i) != shared_data->intregs[i]) {
357 diffRegs = true;
358 }
359 }
360 uint64_t oldTl = thread->readMiscReg(MISCREG_TL);
361 if (oldTl != shared_data->tl)
362 diffTl = true;
363 for (int i = 1; i <= MaxTL; i++) {
364 thread->setMiscReg(MISCREG_TL, i);
365 if (thread->readMiscReg(MISCREG_TPC) !=
366 shared_data->tpc[i-1])
367 diffTpc = true;
368 if (thread->readMiscReg(MISCREG_TNPC) !=
369 shared_data->tnpc[i-1])
370 diffTnpc = true;
371 if (thread->readMiscReg(MISCREG_TSTATE) !=
372 shared_data->tstate[i-1])
373 diffTstate = true;
374 if (thread->readMiscReg(MISCREG_TT) !=
375 shared_data->tt[i-1])
376 diffTt = true;
377 if (thread->readMiscReg(MISCREG_HTSTATE) !=
378 shared_data->htstate[i-1])
379 diffHtstate = true;
380 }
381 thread->setMiscReg(MISCREG_TL, oldTl);
382
383 if(shared_data->tba != thread->readMiscReg(MISCREG_TBA))
384 diffTba = true;
385 //When the hpstate register is read by an instruction,
386 //legion has bit 11 set. When it's in storage, it doesn't.
387 //Since we don't directly support seperate interpretations
388 //of the registers like that, the bit is always set to 1 and
389 //we just don't compare it. It's not supposed to matter
390 //anyway.
391 if((shared_data->hpstate | (1 << 11)) != thread->readMiscReg(MISCREG_HPSTATE))
392 diffHpstate = true;
393 if(shared_data->htba != thread->readMiscReg(MISCREG_HTBA))
394 diffHtba = true;
395 if(shared_data->pstate != thread->readMiscReg(MISCREG_PSTATE))
396 diffPstate = true;
397 if(shared_data->y != thread->readMiscReg(MISCREG_Y))
398 diffY = true;
399 if(shared_data->ccr != thread->readMiscReg(MISCREG_CCR))
400 diffCcr = true;
401 if(shared_data->gl != thread->readMiscReg(MISCREG_GL))
402 diffGl = true;
403 if(shared_data->asi != thread->readMiscReg(MISCREG_ASI))
404 diffAsi = true;
405 if(shared_data->pil != thread->readMiscReg(MISCREG_PIL))
406 diffPil = true;
407 if(shared_data->cwp != thread->readMiscReg(MISCREG_CWP))
408 diffCwp = true;
409 if(shared_data->cansave != thread->readMiscReg(MISCREG_CANSAVE))
410 diffCansave = true;
411 if(shared_data->canrestore !=
412 thread->readMiscReg(MISCREG_CANRESTORE))
413 diffCanrestore = true;
414 if(shared_data->otherwin != thread->readMiscReg(MISCREG_OTHERWIN))
415 diffOtherwin = true;
416 if(shared_data->cleanwin != thread->readMiscReg(MISCREG_CLEANWIN))
417 diffCleanwin = true;
418
419 for (int i = 0; i < 64; i++) {
420 if (shared_data->itb[i] != thread->getITBPtr()->TteRead(i))
421 diffTlb = true;
422 if (shared_data->dtb[i] != thread->getDTBPtr()->TteRead(i))
423 diffTlb = true;
424 }
425
426 if ((diffPC || diffCC || diffInst || diffRegs || diffTpc ||
427 diffTnpc || diffTstate || diffTt || diffHpstate ||
428 diffHtstate || diffHtba || diffPstate || diffY ||
429 diffCcr || diffTl || diffGl || diffAsi || diffPil ||
430 diffCwp || diffCansave || diffCanrestore ||
431 diffOtherwin || diffCleanwin || diffTlb)
432 && !((staticInst->machInst & 0xC1F80000) == 0x81D00000)
433 && !(((staticInst->machInst & 0xC0000000) == 0xC0000000)
434 && shared_data->tl == thread->readMiscReg(MISCREG_TL) + 1)
435 ) {
436
437 outs << "Differences found between M5 and Legion:";
438 if (diffPC)
439 outs << " [PC]";
440 if (diffCC)
441 outs << " [CC]";
442 if (diffInst)
443 outs << " [Instruction]";
444 if (diffRegs)
445 outs << " [IntRegs]";
446 if (diffTpc)
447 outs << " [Tpc]";
448 if (diffTnpc)
449 outs << " [Tnpc]";
450 if (diffTstate)
451 outs << " [Tstate]";
452 if (diffTt)
453 outs << " [Tt]";
454 if (diffHpstate)
455 outs << " [Hpstate]";
456 if (diffHtstate)
457 outs << " [Htstate]";
458 if (diffHtba)
459 outs << " [Htba]";
460 if (diffPstate)
461 outs << " [Pstate]";
462 if (diffY)
463 outs << " [Y]";
464 if (diffCcr)
465 outs << " [Ccr]";
466 if (diffTl)
467 outs << " [Tl]";
468 if (diffGl)
469 outs << " [Gl]";
470 if (diffAsi)
471 outs << " [Asi]";
472 if (diffPil)
473 outs << " [Pil]";
474 if (diffCwp)
475 outs << " [Cwp]";
476 if (diffCansave)
477 outs << " [Cansave]";
478 if (diffCanrestore)
479 outs << " [Canrestore]";
480 if (diffOtherwin)
481 outs << " [Otherwin]";
482 if (diffCleanwin)
483 outs << " [Cleanwin]";
484 if (diffTlb)
485 outs << " [Tlb]";
486 outs << endl << endl;
487
488 outs << right << setfill(' ') << setw(15)
489 << "M5 PC: " << "0x"<< setw(16) << setfill('0')
490 << hex << m5Pc << endl;
491 outs << setfill(' ') << setw(15)
492 << "Legion PC: " << "0x"<< setw(16) << setfill('0') << hex
493 << lgnPc << endl << endl;
494
495 outs << right << setfill(' ') << setw(15)
496 << "M5 CC: " << "0x"<< setw(16) << setfill('0')
497 << hex << thread->getCpuPtr()->instCount() << endl;
498 outs << setfill(' ') << setw(15)
499 << "Legion CC: " << "0x"<< setw(16) << setfill('0') << hex
500 << shared_data->cycle_count << endl << endl;
501
502 outs << setfill(' ') << setw(15)
503 << "M5 Inst: " << "0x"<< setw(8)
504 << setfill('0') << hex << staticInst->machInst
505 << staticInst->disassemble(m5Pc, debugSymbolTable)
506 << endl;
507
508 StaticInstPtr legionInst =
509 StaticInst::decode(makeExtMI(shared_data->instruction,
510 thread));
511 outs << setfill(' ') << setw(15)
512 << " Legion Inst: "
513 << "0x" << setw(8) << setfill('0') << hex
514 << shared_data->instruction
515 << legionInst->disassemble(lgnPc, debugSymbolTable)
516 << endl << endl;
517
518 printSectionHeader(outs, "General State");
519 printColumnLabels(outs);
520 printRegPair(outs, "HPstate",
521 thread->readMiscReg(MISCREG_HPSTATE),
522 shared_data->hpstate | (1 << 11));
523 printRegPair(outs, "Htba",
524 thread->readMiscReg(MISCREG_HTBA),
525 shared_data->htba);
526 printRegPair(outs, "Pstate",
527 thread->readMiscReg(MISCREG_PSTATE),
528 shared_data->pstate);
529 printRegPair(outs, "Y",
530 thread->readMiscReg(MISCREG_Y),
531 shared_data->y);
532 printRegPair(outs, "Ccr",
533 thread->readMiscReg(MISCREG_CCR),
534 shared_data->ccr);
535 printRegPair(outs, "Tl",
536 thread->readMiscReg(MISCREG_TL),
537 shared_data->tl);
538 printRegPair(outs, "Gl",
539 thread->readMiscReg(MISCREG_GL),
540 shared_data->gl);
541 printRegPair(outs, "Asi",
542 thread->readMiscReg(MISCREG_ASI),
543 shared_data->asi);
544 printRegPair(outs, "Pil",
545 thread->readMiscReg(MISCREG_PIL),
546 shared_data->pil);
547 printRegPair(outs, "Cwp",
548 thread->readMiscReg(MISCREG_CWP),
549 shared_data->cwp);
550 printRegPair(outs, "Cansave",
551 thread->readMiscReg(MISCREG_CANSAVE),
552 shared_data->cansave);
553 printRegPair(outs, "Canrestore",
554 thread->readMiscReg(MISCREG_CANRESTORE),
555 shared_data->canrestore);
556 printRegPair(outs, "Otherwin",
557 thread->readMiscReg(MISCREG_OTHERWIN),
558 shared_data->otherwin);
559 printRegPair(outs, "Cleanwin",
560 thread->readMiscReg(MISCREG_CLEANWIN),
561 shared_data->cleanwin);
562 outs << endl;
563 for (int i = 1; i <= MaxTL; i++) {
564 printLevelHeader(outs, i);
565 printColumnLabels(outs);
566 thread->setMiscReg(MISCREG_TL, i);
567 printRegPair(outs, "Tpc",
568 thread->readMiscReg(MISCREG_TPC),
569 shared_data->tpc[i-1]);
570 printRegPair(outs, "Tnpc",
571 thread->readMiscReg(MISCREG_TNPC),
572 shared_data->tnpc[i-1]);
573 printRegPair(outs, "Tstate",
574 thread->readMiscReg(MISCREG_TSTATE),
575 shared_data->tstate[i-1]);
576 printRegPair(outs, "Tt",
577 thread->readMiscReg(MISCREG_TT),
578 shared_data->tt[i-1]);
579 printRegPair(outs, "Htstate",
580 thread->readMiscReg(MISCREG_HTSTATE),
581 shared_data->htstate[i-1]);
582 }
583 thread->setMiscReg(MISCREG_TL, oldTl);
584 outs << endl;
585
586 printSectionHeader(outs, "General Purpose Registers");
587 static const char * regtypes[4] = {"%g", "%o", "%l", "%i"};
588 for(int y = 0; y < 4; y++)
589 {
590 for(int x = 0; x < 8; x++)
591 {
592 char label[8];
593 sprintf(label, "%s%d", regtypes[y], x);
594 printRegPair(outs, label,
595 thread->readIntReg(y*8+x),
596 shared_data->intregs[y*8+x]);
597 /*outs << regtypes[y] << x << " " ;
598 outs << "0x" << hex << setw(16)
599 << thread->readIntReg(y*8+x);
600 if (thread->readIntReg(y*8 + x)
601 != shared_data->intregs[y*8+x])
602 outs << " X ";
603 else
604 outs << " | ";
605 outs << "0x" << setw(16) << hex
606 << shared_data->intregs[y*8+x]
607 << endl;*/
608 }
609 }
610 if (diffTlb) {
611 printColumnLabels(outs);
612 char label[8];
613 for (int x = 0; x < 64; x++) {
614 if (shared_data->itb[x] != ULL(0xFFFFFFFFFFFFFFFF) ||
615 thread->getITBPtr()->TteRead(x) != ULL(0xFFFFFFFFFFFFFFFF)) {
616 sprintf(label, "I-TLB:%02d", x);
617 printRegPair(outs, label, thread->getITBPtr()->TteRead(x),
618 shared_data->itb[x]);
619 }
620 }
621 for (int x = 0; x < 64; x++) {
622 if (shared_data->dtb[x] != ULL(0xFFFFFFFFFFFFFFFF) ||
623 thread->getDTBPtr()->TteRead(x) != ULL(0xFFFFFFFFFFFFFFFF)) {
624 sprintf(label, "D-TLB:%02d", x);
625 printRegPair(outs, label, thread->getDTBPtr()->TteRead(x),
626 shared_data->dtb[x]);
627 }
628 }
629 thread->getITBPtr()->dumpAll();
630 thread->getDTBPtr()->dumpAll();
631 }
632
633 diffcount++;
634 if (diffcount > 2)
635 fatal("Differences found between Legion and M5\n");
636 } else
637 diffcount = 0;
638
639 compared = true;
640 shared_data->flags = OWN_LEGION;
641 }
642 } // while
643 } // if not microop
644 }
645#endif
646}
647
648
649vector<bool> Trace::InstRecord::flags(NUM_BITS);
650string Trace::InstRecord::trace_system;
651
652////////////////////////////////////////////////////////////////////////
653//
654// Parameter space for per-cycle execution address tracing options.
655// Derive from ParamContext so we can override checkParams() function.
656//
657class ExecutionTraceParamContext : public ParamContext
658{
659 public:
660 ExecutionTraceParamContext(const string &_iniSection)
661 : ParamContext(_iniSection)
662 {
663 }
664
665 void checkParams(); // defined at bottom of file
666};
667
668ExecutionTraceParamContext exeTraceParams("exetrace");
669
670Param<bool> exe_trace_spec(&exeTraceParams, "speculative",
671 "capture speculative instructions", true);
672
673Param<bool> exe_trace_print_cycle(&exeTraceParams, "print_cycle",
674 "print cycle number", true);
675Param<bool> exe_trace_print_opclass(&exeTraceParams, "print_opclass",
676 "print op class", true);
677Param<bool> exe_trace_print_thread(&exeTraceParams, "print_thread",
678 "print thread number", true);
679Param<bool> exe_trace_print_effaddr(&exeTraceParams, "print_effaddr",
680 "print effective address", true);
681Param<bool> exe_trace_print_data(&exeTraceParams, "print_data",
682 "print result data", true);
683Param<bool> exe_trace_print_iregs(&exeTraceParams, "print_iregs",
684 "print all integer regs", false);
685Param<bool> exe_trace_print_fetchseq(&exeTraceParams, "print_fetchseq",
686 "print fetch sequence number", false);
687Param<bool> exe_trace_print_cp_seq(&exeTraceParams, "print_cpseq",
688 "print correct-path sequence number", false);
689Param<bool> exe_trace_print_reg_delta(&exeTraceParams, "print_reg_delta",
690 "print which registers changed to what", false);
691Param<bool> exe_trace_pc_symbol(&exeTraceParams, "pc_symbol",
692 "Use symbols for the PC if available", true);
693Param<bool> exe_trace_intel_format(&exeTraceParams, "intel_format",
694 "print trace in intel compatible format", false);
695Param<bool> exe_trace_legion_lockstep(&exeTraceParams, "legion_lockstep",
696 "Compare sim state to legion state every cycle",
697 false);
698Param<string> exe_trace_system(&exeTraceParams, "trace_system",
699 "print trace of which system (client or server)",
700 "client");
701
702
703//
704// Helper function for ExecutionTraceParamContext::checkParams() just
705// to get us into the InstRecord namespace
706//
707void
708Trace::InstRecord::setParams()
709{
710 flags[TRACE_MISSPEC] = exe_trace_spec;
711
712 flags[PRINT_CYCLE] = exe_trace_print_cycle;
713 flags[PRINT_OP_CLASS] = exe_trace_print_opclass;
714 flags[PRINT_THREAD_NUM] = exe_trace_print_thread;
715 flags[PRINT_RESULT_DATA] = exe_trace_print_effaddr;
716 flags[PRINT_EFF_ADDR] = exe_trace_print_data;
717 flags[PRINT_INT_REGS] = exe_trace_print_iregs;
718 flags[PRINT_FETCH_SEQ] = exe_trace_print_fetchseq;
719 flags[PRINT_CP_SEQ] = exe_trace_print_cp_seq;
720 flags[PRINT_REG_DELTA] = exe_trace_print_reg_delta;
721 flags[PC_SYMBOL] = exe_trace_pc_symbol;
722 flags[INTEL_FORMAT] = exe_trace_intel_format;
723 flags[LEGION_LOCKSTEP] = exe_trace_legion_lockstep;
724 trace_system = exe_trace_system;
725
726 // If were going to be in lockstep with Legion
727 // Setup shared memory, and get otherwise ready
728 if (flags[LEGION_LOCKSTEP]) {
729 int shmfd = shmget('M' << 24 | getuid(), sizeof(SharedData), 0777);
730 if (shmfd < 0)
731 fatal("Couldn't get shared memory fd. Is Legion running?");
732
733 shared_data = (SharedData*)shmat(shmfd, NULL, SHM_RND);
734 if (shared_data == (SharedData*)-1)
735 fatal("Couldn't allocate shared memory");
736
737 if (shared_data->flags != OWN_M5)
738 fatal("Shared memory has invalid owner");
739
740 if (shared_data->version != VERSION)
741 fatal("Shared Data is wrong version! M5: %d Legion: %d", VERSION,
742 shared_data->version);
743
744 // step legion forward one cycle so we can get register values
745 shared_data->flags = OWN_LEGION;
746 }
747}
748
749void
750ExecutionTraceParamContext::checkParams()
751{
752 Trace::InstRecord::setParams();
753}
754
346 lgnPc = shared_data->pc & TheISA::PAddrImplMask;
347 if (lgnPc != m5Pc)
348 diffPC = true;
349
350 if (shared_data->cycle_count !=
351 thread->getCpuPtr()->instCount())
352 diffCC = true;
353
354 if (shared_data->instruction !=
355 (SparcISA::MachInst)staticInst->machInst) {
356 diffInst = true;
357 }
358 for (int i = 0; i < TheISA::NumIntArchRegs; i++) {
359 if (thread->readIntReg(i) != shared_data->intregs[i]) {
360 diffRegs = true;
361 }
362 }
363 uint64_t oldTl = thread->readMiscReg(MISCREG_TL);
364 if (oldTl != shared_data->tl)
365 diffTl = true;
366 for (int i = 1; i <= MaxTL; i++) {
367 thread->setMiscReg(MISCREG_TL, i);
368 if (thread->readMiscReg(MISCREG_TPC) !=
369 shared_data->tpc[i-1])
370 diffTpc = true;
371 if (thread->readMiscReg(MISCREG_TNPC) !=
372 shared_data->tnpc[i-1])
373 diffTnpc = true;
374 if (thread->readMiscReg(MISCREG_TSTATE) !=
375 shared_data->tstate[i-1])
376 diffTstate = true;
377 if (thread->readMiscReg(MISCREG_TT) !=
378 shared_data->tt[i-1])
379 diffTt = true;
380 if (thread->readMiscReg(MISCREG_HTSTATE) !=
381 shared_data->htstate[i-1])
382 diffHtstate = true;
383 }
384 thread->setMiscReg(MISCREG_TL, oldTl);
385
386 if(shared_data->tba != thread->readMiscReg(MISCREG_TBA))
387 diffTba = true;
388 //When the hpstate register is read by an instruction,
389 //legion has bit 11 set. When it's in storage, it doesn't.
390 //Since we don't directly support seperate interpretations
391 //of the registers like that, the bit is always set to 1 and
392 //we just don't compare it. It's not supposed to matter
393 //anyway.
394 if((shared_data->hpstate | (1 << 11)) != thread->readMiscReg(MISCREG_HPSTATE))
395 diffHpstate = true;
396 if(shared_data->htba != thread->readMiscReg(MISCREG_HTBA))
397 diffHtba = true;
398 if(shared_data->pstate != thread->readMiscReg(MISCREG_PSTATE))
399 diffPstate = true;
400 if(shared_data->y != thread->readMiscReg(MISCREG_Y))
401 diffY = true;
402 if(shared_data->ccr != thread->readMiscReg(MISCREG_CCR))
403 diffCcr = true;
404 if(shared_data->gl != thread->readMiscReg(MISCREG_GL))
405 diffGl = true;
406 if(shared_data->asi != thread->readMiscReg(MISCREG_ASI))
407 diffAsi = true;
408 if(shared_data->pil != thread->readMiscReg(MISCREG_PIL))
409 diffPil = true;
410 if(shared_data->cwp != thread->readMiscReg(MISCREG_CWP))
411 diffCwp = true;
412 if(shared_data->cansave != thread->readMiscReg(MISCREG_CANSAVE))
413 diffCansave = true;
414 if(shared_data->canrestore !=
415 thread->readMiscReg(MISCREG_CANRESTORE))
416 diffCanrestore = true;
417 if(shared_data->otherwin != thread->readMiscReg(MISCREG_OTHERWIN))
418 diffOtherwin = true;
419 if(shared_data->cleanwin != thread->readMiscReg(MISCREG_CLEANWIN))
420 diffCleanwin = true;
421
422 for (int i = 0; i < 64; i++) {
423 if (shared_data->itb[i] != thread->getITBPtr()->TteRead(i))
424 diffTlb = true;
425 if (shared_data->dtb[i] != thread->getDTBPtr()->TteRead(i))
426 diffTlb = true;
427 }
428
429 if ((diffPC || diffCC || diffInst || diffRegs || diffTpc ||
430 diffTnpc || diffTstate || diffTt || diffHpstate ||
431 diffHtstate || diffHtba || diffPstate || diffY ||
432 diffCcr || diffTl || diffGl || diffAsi || diffPil ||
433 diffCwp || diffCansave || diffCanrestore ||
434 diffOtherwin || diffCleanwin || diffTlb)
435 && !((staticInst->machInst & 0xC1F80000) == 0x81D00000)
436 && !(((staticInst->machInst & 0xC0000000) == 0xC0000000)
437 && shared_data->tl == thread->readMiscReg(MISCREG_TL) + 1)
438 ) {
439
440 outs << "Differences found between M5 and Legion:";
441 if (diffPC)
442 outs << " [PC]";
443 if (diffCC)
444 outs << " [CC]";
445 if (diffInst)
446 outs << " [Instruction]";
447 if (diffRegs)
448 outs << " [IntRegs]";
449 if (diffTpc)
450 outs << " [Tpc]";
451 if (diffTnpc)
452 outs << " [Tnpc]";
453 if (diffTstate)
454 outs << " [Tstate]";
455 if (diffTt)
456 outs << " [Tt]";
457 if (diffHpstate)
458 outs << " [Hpstate]";
459 if (diffHtstate)
460 outs << " [Htstate]";
461 if (diffHtba)
462 outs << " [Htba]";
463 if (diffPstate)
464 outs << " [Pstate]";
465 if (diffY)
466 outs << " [Y]";
467 if (diffCcr)
468 outs << " [Ccr]";
469 if (diffTl)
470 outs << " [Tl]";
471 if (diffGl)
472 outs << " [Gl]";
473 if (diffAsi)
474 outs << " [Asi]";
475 if (diffPil)
476 outs << " [Pil]";
477 if (diffCwp)
478 outs << " [Cwp]";
479 if (diffCansave)
480 outs << " [Cansave]";
481 if (diffCanrestore)
482 outs << " [Canrestore]";
483 if (diffOtherwin)
484 outs << " [Otherwin]";
485 if (diffCleanwin)
486 outs << " [Cleanwin]";
487 if (diffTlb)
488 outs << " [Tlb]";
489 outs << endl << endl;
490
491 outs << right << setfill(' ') << setw(15)
492 << "M5 PC: " << "0x"<< setw(16) << setfill('0')
493 << hex << m5Pc << endl;
494 outs << setfill(' ') << setw(15)
495 << "Legion PC: " << "0x"<< setw(16) << setfill('0') << hex
496 << lgnPc << endl << endl;
497
498 outs << right << setfill(' ') << setw(15)
499 << "M5 CC: " << "0x"<< setw(16) << setfill('0')
500 << hex << thread->getCpuPtr()->instCount() << endl;
501 outs << setfill(' ') << setw(15)
502 << "Legion CC: " << "0x"<< setw(16) << setfill('0') << hex
503 << shared_data->cycle_count << endl << endl;
504
505 outs << setfill(' ') << setw(15)
506 << "M5 Inst: " << "0x"<< setw(8)
507 << setfill('0') << hex << staticInst->machInst
508 << staticInst->disassemble(m5Pc, debugSymbolTable)
509 << endl;
510
511 StaticInstPtr legionInst =
512 StaticInst::decode(makeExtMI(shared_data->instruction,
513 thread));
514 outs << setfill(' ') << setw(15)
515 << " Legion Inst: "
516 << "0x" << setw(8) << setfill('0') << hex
517 << shared_data->instruction
518 << legionInst->disassemble(lgnPc, debugSymbolTable)
519 << endl << endl;
520
521 printSectionHeader(outs, "General State");
522 printColumnLabels(outs);
523 printRegPair(outs, "HPstate",
524 thread->readMiscReg(MISCREG_HPSTATE),
525 shared_data->hpstate | (1 << 11));
526 printRegPair(outs, "Htba",
527 thread->readMiscReg(MISCREG_HTBA),
528 shared_data->htba);
529 printRegPair(outs, "Pstate",
530 thread->readMiscReg(MISCREG_PSTATE),
531 shared_data->pstate);
532 printRegPair(outs, "Y",
533 thread->readMiscReg(MISCREG_Y),
534 shared_data->y);
535 printRegPair(outs, "Ccr",
536 thread->readMiscReg(MISCREG_CCR),
537 shared_data->ccr);
538 printRegPair(outs, "Tl",
539 thread->readMiscReg(MISCREG_TL),
540 shared_data->tl);
541 printRegPair(outs, "Gl",
542 thread->readMiscReg(MISCREG_GL),
543 shared_data->gl);
544 printRegPair(outs, "Asi",
545 thread->readMiscReg(MISCREG_ASI),
546 shared_data->asi);
547 printRegPair(outs, "Pil",
548 thread->readMiscReg(MISCREG_PIL),
549 shared_data->pil);
550 printRegPair(outs, "Cwp",
551 thread->readMiscReg(MISCREG_CWP),
552 shared_data->cwp);
553 printRegPair(outs, "Cansave",
554 thread->readMiscReg(MISCREG_CANSAVE),
555 shared_data->cansave);
556 printRegPair(outs, "Canrestore",
557 thread->readMiscReg(MISCREG_CANRESTORE),
558 shared_data->canrestore);
559 printRegPair(outs, "Otherwin",
560 thread->readMiscReg(MISCREG_OTHERWIN),
561 shared_data->otherwin);
562 printRegPair(outs, "Cleanwin",
563 thread->readMiscReg(MISCREG_CLEANWIN),
564 shared_data->cleanwin);
565 outs << endl;
566 for (int i = 1; i <= MaxTL; i++) {
567 printLevelHeader(outs, i);
568 printColumnLabels(outs);
569 thread->setMiscReg(MISCREG_TL, i);
570 printRegPair(outs, "Tpc",
571 thread->readMiscReg(MISCREG_TPC),
572 shared_data->tpc[i-1]);
573 printRegPair(outs, "Tnpc",
574 thread->readMiscReg(MISCREG_TNPC),
575 shared_data->tnpc[i-1]);
576 printRegPair(outs, "Tstate",
577 thread->readMiscReg(MISCREG_TSTATE),
578 shared_data->tstate[i-1]);
579 printRegPair(outs, "Tt",
580 thread->readMiscReg(MISCREG_TT),
581 shared_data->tt[i-1]);
582 printRegPair(outs, "Htstate",
583 thread->readMiscReg(MISCREG_HTSTATE),
584 shared_data->htstate[i-1]);
585 }
586 thread->setMiscReg(MISCREG_TL, oldTl);
587 outs << endl;
588
589 printSectionHeader(outs, "General Purpose Registers");
590 static const char * regtypes[4] = {"%g", "%o", "%l", "%i"};
591 for(int y = 0; y < 4; y++)
592 {
593 for(int x = 0; x < 8; x++)
594 {
595 char label[8];
596 sprintf(label, "%s%d", regtypes[y], x);
597 printRegPair(outs, label,
598 thread->readIntReg(y*8+x),
599 shared_data->intregs[y*8+x]);
600 /*outs << regtypes[y] << x << " " ;
601 outs << "0x" << hex << setw(16)
602 << thread->readIntReg(y*8+x);
603 if (thread->readIntReg(y*8 + x)
604 != shared_data->intregs[y*8+x])
605 outs << " X ";
606 else
607 outs << " | ";
608 outs << "0x" << setw(16) << hex
609 << shared_data->intregs[y*8+x]
610 << endl;*/
611 }
612 }
613 if (diffTlb) {
614 printColumnLabels(outs);
615 char label[8];
616 for (int x = 0; x < 64; x++) {
617 if (shared_data->itb[x] != ULL(0xFFFFFFFFFFFFFFFF) ||
618 thread->getITBPtr()->TteRead(x) != ULL(0xFFFFFFFFFFFFFFFF)) {
619 sprintf(label, "I-TLB:%02d", x);
620 printRegPair(outs, label, thread->getITBPtr()->TteRead(x),
621 shared_data->itb[x]);
622 }
623 }
624 for (int x = 0; x < 64; x++) {
625 if (shared_data->dtb[x] != ULL(0xFFFFFFFFFFFFFFFF) ||
626 thread->getDTBPtr()->TteRead(x) != ULL(0xFFFFFFFFFFFFFFFF)) {
627 sprintf(label, "D-TLB:%02d", x);
628 printRegPair(outs, label, thread->getDTBPtr()->TteRead(x),
629 shared_data->dtb[x]);
630 }
631 }
632 thread->getITBPtr()->dumpAll();
633 thread->getDTBPtr()->dumpAll();
634 }
635
636 diffcount++;
637 if (diffcount > 2)
638 fatal("Differences found between Legion and M5\n");
639 } else
640 diffcount = 0;
641
642 compared = true;
643 shared_data->flags = OWN_LEGION;
644 }
645 } // while
646 } // if not microop
647 }
648#endif
649}
650
651
652vector<bool> Trace::InstRecord::flags(NUM_BITS);
653string Trace::InstRecord::trace_system;
654
655////////////////////////////////////////////////////////////////////////
656//
657// Parameter space for per-cycle execution address tracing options.
658// Derive from ParamContext so we can override checkParams() function.
659//
660class ExecutionTraceParamContext : public ParamContext
661{
662 public:
663 ExecutionTraceParamContext(const string &_iniSection)
664 : ParamContext(_iniSection)
665 {
666 }
667
668 void checkParams(); // defined at bottom of file
669};
670
671ExecutionTraceParamContext exeTraceParams("exetrace");
672
673Param<bool> exe_trace_spec(&exeTraceParams, "speculative",
674 "capture speculative instructions", true);
675
676Param<bool> exe_trace_print_cycle(&exeTraceParams, "print_cycle",
677 "print cycle number", true);
678Param<bool> exe_trace_print_opclass(&exeTraceParams, "print_opclass",
679 "print op class", true);
680Param<bool> exe_trace_print_thread(&exeTraceParams, "print_thread",
681 "print thread number", true);
682Param<bool> exe_trace_print_effaddr(&exeTraceParams, "print_effaddr",
683 "print effective address", true);
684Param<bool> exe_trace_print_data(&exeTraceParams, "print_data",
685 "print result data", true);
686Param<bool> exe_trace_print_iregs(&exeTraceParams, "print_iregs",
687 "print all integer regs", false);
688Param<bool> exe_trace_print_fetchseq(&exeTraceParams, "print_fetchseq",
689 "print fetch sequence number", false);
690Param<bool> exe_trace_print_cp_seq(&exeTraceParams, "print_cpseq",
691 "print correct-path sequence number", false);
692Param<bool> exe_trace_print_reg_delta(&exeTraceParams, "print_reg_delta",
693 "print which registers changed to what", false);
694Param<bool> exe_trace_pc_symbol(&exeTraceParams, "pc_symbol",
695 "Use symbols for the PC if available", true);
696Param<bool> exe_trace_intel_format(&exeTraceParams, "intel_format",
697 "print trace in intel compatible format", false);
698Param<bool> exe_trace_legion_lockstep(&exeTraceParams, "legion_lockstep",
699 "Compare sim state to legion state every cycle",
700 false);
701Param<string> exe_trace_system(&exeTraceParams, "trace_system",
702 "print trace of which system (client or server)",
703 "client");
704
705
706//
707// Helper function for ExecutionTraceParamContext::checkParams() just
708// to get us into the InstRecord namespace
709//
710void
711Trace::InstRecord::setParams()
712{
713 flags[TRACE_MISSPEC] = exe_trace_spec;
714
715 flags[PRINT_CYCLE] = exe_trace_print_cycle;
716 flags[PRINT_OP_CLASS] = exe_trace_print_opclass;
717 flags[PRINT_THREAD_NUM] = exe_trace_print_thread;
718 flags[PRINT_RESULT_DATA] = exe_trace_print_effaddr;
719 flags[PRINT_EFF_ADDR] = exe_trace_print_data;
720 flags[PRINT_INT_REGS] = exe_trace_print_iregs;
721 flags[PRINT_FETCH_SEQ] = exe_trace_print_fetchseq;
722 flags[PRINT_CP_SEQ] = exe_trace_print_cp_seq;
723 flags[PRINT_REG_DELTA] = exe_trace_print_reg_delta;
724 flags[PC_SYMBOL] = exe_trace_pc_symbol;
725 flags[INTEL_FORMAT] = exe_trace_intel_format;
726 flags[LEGION_LOCKSTEP] = exe_trace_legion_lockstep;
727 trace_system = exe_trace_system;
728
729 // If were going to be in lockstep with Legion
730 // Setup shared memory, and get otherwise ready
731 if (flags[LEGION_LOCKSTEP]) {
732 int shmfd = shmget('M' << 24 | getuid(), sizeof(SharedData), 0777);
733 if (shmfd < 0)
734 fatal("Couldn't get shared memory fd. Is Legion running?");
735
736 shared_data = (SharedData*)shmat(shmfd, NULL, SHM_RND);
737 if (shared_data == (SharedData*)-1)
738 fatal("Couldn't allocate shared memory");
739
740 if (shared_data->flags != OWN_M5)
741 fatal("Shared memory has invalid owner");
742
743 if (shared_data->version != VERSION)
744 fatal("Shared Data is wrong version! M5: %d Legion: %d", VERSION,
745 shared_data->version);
746
747 // step legion forward one cycle so we can get register values
748 shared_data->flags = OWN_LEGION;
749 }
750}
751
752void
753ExecutionTraceParamContext::checkParams()
754{
755 Trace::InstRecord::setParams();
756}
757