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