gem5  v19.0.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
tarmac_record.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017-2019 ARM Limited
3  * All rights reserved
4  *
5  * The license below extends only to copyright in the software and shall
6  * not be construed as granting a license to any other intellectual
7  * property including but not limited to intellectual property relating
8  * to a hardware implementation of the functionality of the software
9  * licensed hereunder. You may use the software subject to the license
10  * terms below provided that you ensure that this notice is replicated
11  * unmodified and in its entirety in all distributions of the software,
12  * modified or unmodified, in source code or in binary form.
13  *
14  * Redistribution and use in source and binary forms, with or without
15  * modification, are permitted provided that the following conditions are
16  * met: redistributions of source code must retain the above copyright
17  * notice, this list of conditions and the following disclaimer;
18  * redistributions in binary form must reproduce the above copyright
19  * notice, this list of conditions and the following disclaimer in the
20  * documentation and/or other materials provided with the distribution;
21  * neither the name of the copyright holders nor the names of its
22  * contributors may be used to endorse or promote products derived from
23  * this software without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36  *
37  * Authors: Giacomo Travaglini
38  */
39 
41 
43 #include "tarmac_tracer.hh"
44 
45 namespace Trace {
46 
47 // TARMAC Instruction Record static variables
49 
50 std::string
52 {
53  switch (isetstate) {
55  return "A";
57  return "T";
59  return "O";
60  default:
61  return "Unsupported";
62  }
63 }
64 
65 std::string
67 {
68  switch (opMode) {
69  case MODE_EL0T:
70  return "EL0t";
71  case MODE_EL1T:
72  return "EL1t";
73  case MODE_EL1H:
74  return "EL1h";
75  case MODE_EL2T:
76  return "EL2t";
77  case MODE_EL2H:
78  return "EL2h";
79  case MODE_EL3T:
80  return "EL3t";
81  case MODE_EL3H:
82  return "EL3h";
83  case MODE_USER:
84  return "usr";
85  case MODE_FIQ:
86  return "fiq";
87  case MODE_IRQ:
88  return "irq";
89  case MODE_SVC:
90  return "svc";
91  case MODE_MON:
92  return "mon";
93  case MODE_ABORT:
94  return "abt";
95  case MODE_HYP:
96  return "hyp";
97  case MODE_UNDEFINED:
98  return "und";
99  case MODE_SYSTEM:
100  return "sys";
101  default:
102  return "Unsupported";
103  }
104 }
105 
106 // TarmacTracerRecord ctor
108  const StaticInstPtr _staticInst,
109  PCState _pc,
110  TarmacTracer& _tracer,
111  const StaticInstPtr _macroStaticInst)
112  : TarmacBaseRecord(_when, _thread, _staticInst,
113  _pc, _macroStaticInst),
114  tracer(_tracer)
115 {
116 }
117 
119  const TarmacContext& tarmCtx,
120  bool predicate)
121  : InstEntry(tarmCtx.thread, tarmCtx.pc, tarmCtx.staticInst, predicate)
122 {
123  secureMode = inSecureState(tarmCtx.thread);
124 
125  auto arm_inst = static_cast<const ArmStaticInst*>(
126  tarmCtx.staticInst.get()
127  );
128 
129  // Get the instruction size as a number of bits:
130  // (multiply byte size by 8)
131  instSize = (arm_inst->instSize() << 3);
132 
133  // Mask the opcode using the instruction size: the
134  // opcode field will otherwise be 32 bit wide even
135  // for 16bit (Thumb) instruction.
136  opcode = arm_inst->encoding();
137 
138  // Update the instruction count: number of executed
139  // instructions.
140  instCount++;
141 }
142 
144  const TarmacContext& tarmCtx,
145  uint8_t _size, Addr _addr, uint64_t _data)
146  : MemEntry(_size, _addr, _data),
147  loadAccess(tarmCtx.staticInst->isLoad())
148 {
149 }
150 
152  const TarmacContext& tarmCtx,
153  const RegId& reg)
154  : RegEntry(tarmCtx.pc),
155  regValid(false),
156  regClass(reg.classValue()),
157  regRel(reg.index())
158 {
159 }
160 
161 void
163  const TarmacContext& tarmCtx
164 )
165 {
166  // Fill the register entry data, according to register
167  // class.
168  switch (regClass) {
169  case CCRegClass:
170  updateCC(tarmCtx, regRel);
171  break;
172  case FloatRegClass:
173  updateFloat(tarmCtx, regRel);
174  break;
175  case IntRegClass:
176  updateInt(tarmCtx, regRel);
177  break;
178  case MiscRegClass:
179  updateMisc(tarmCtx, regRel);
180  break;
181  case VecRegClass:
182  updateVec(tarmCtx, regRel);
183  break;
184  case VecPredRegClass:
185  updatePred(tarmCtx, regRel);
186  break;
187  default:
188  // If unsupported format, do nothing: non updating
189  // the register will prevent it to be printed.
190  break;
191  }
192 }
193 
194 void
196  const TarmacContext& tarmCtx,
197  RegIndex regRelIdx
198 )
199 {
200  auto thread = tarmCtx.thread;
201 
202  regValid = true;
203  regName = miscRegName[regRelIdx];
204  values[Lo] = thread->readMiscRegNoEffect(regRelIdx);
205 
206  // If it is the CPSR:
207  // update the value of the CPSR register and add
208  // the CC flags on top of the value
209  if (regRelIdx == MISCREG_CPSR) {
211  cpsr.nz = thread->readCCReg(CCREG_NZ);
212  cpsr.c = thread->readCCReg(CCREG_C);
213  cpsr.v = thread->readCCReg(CCREG_V);
214  cpsr.ge = thread->readCCReg(CCREG_GE);
215 
216  // update the entry value
217  values[Lo] = cpsr;
218  }
219 }
220 
221 void
223  const TarmacContext& tarmCtx,
224  RegIndex regRelIdx
225 )
226 {
227  auto thread = tarmCtx.thread;
228 
229  regValid = true;
230  regName = ccRegName[regRelIdx];
231  values[Lo] = thread->readCCReg(regRelIdx);
232 }
233 
234 void
236  const TarmacContext& tarmCtx,
237  RegIndex regRelIdx
238 )
239 {
240  auto thread = tarmCtx.thread;
241 
242  regValid = true;
243  regName = "f" + std::to_string(regRelIdx);
244  values[Lo] = bitsToFloat32(thread->readFloatReg(regRelIdx));
245 }
246 
247 void
249  const TarmacContext& tarmCtx,
250  RegIndex regRelIdx
251 )
252 {
253  auto thread = tarmCtx.thread;
254 
255  // Reading operating mode from CPSR.
256  // This is needed when printing the register name in case
257  // of banked register (e.g. lr_svc)
259  OperatingMode mode = (OperatingMode)(uint8_t)cpsr.mode;
260 
261  std::string reg_suffix;
262  if (mode != MODE_USER) {
263  reg_suffix = "_" + opModeToStr(mode);
264  }
265 
266  regValid = true;
267  switch (regRelIdx) {
268  case PCReg:
269  regName = "pc";
270  break;
271  case StackPointerReg:
272  regName = "sp" + reg_suffix ;
273  break;
274  case FramePointerReg:
275  regName = "fp" + reg_suffix;
276  break;
277  case ReturnAddressReg:
278  regName = "lr" + reg_suffix;
279  break;
280  default:
281  regName = "r" + std::to_string(regRelIdx);
282  break;
283  }
284  values[Lo] = thread->readIntReg(regRelIdx);
285 }
286 
287 void
289  const TarmacContext& tarmCtx)
290 {
291  // Generate an instruction entry in the record and
292  // add it to the Instruction Queue
293  queue.push_back(
294  m5::make_unique<TraceInstEntry>(tarmCtx, predicate)
295  );
296 }
297 
298 void
300  const TarmacContext& tarmCtx)
301 {
302  // Generate a memory entry in the record if the record
303  // implies a valid memory access, and add it to the
304  // Memory Queue
305  if (getMemValid()) {
306  queue.push_back(
307  m5::make_unique<TraceMemEntry>(tarmCtx,
308  static_cast<uint8_t>(getSize()),
309  getAddr(), getIntData())
310  );
311  }
312 }
313 
314 void
316  const TarmacContext& tarmCtx)
317 {
318  // Generate an entry for every ARM register being
319  // written by the current instruction
320  for (auto reg = 0; reg < staticInst->numDestRegs(); ++reg) {
321 
322  RegId reg_id = staticInst->destRegIdx(reg);
323 
324  // Creating a single register change entry
325  auto single_reg = genRegister<TraceRegEntry>(tarmCtx, reg_id);
326 
327  // Copying the entry and adding it to the "list"
328  // of entries to be dumped to trace.
329  queue.push_back(
330  m5::make_unique<TraceRegEntry>(single_reg)
331  );
332  }
333 
334  // Gem5 is treating CPSR flags as separate registers (CC registers),
335  // in contrast with Tarmac specification: we need to merge the gem5 CC
336  // entries altogether with the CPSR register and produce a single entry.
337  mergeCCEntry<TraceRegEntry>(queue, tarmCtx);
338 }
339 
340 void
342 {
343  // Generate and print all the record's entries.
344  auto &instQueue = tracer.instQueue;
345  auto &memQueue = tracer.memQueue;
346  auto &regQueue = tracer.regQueue;
347 
348  const TarmacContext tarmCtx(
349  thread,
351  pc
352  );
353 
354  if (!staticInst->isMicroop()) {
355  // Current instruction is NOT a micro-instruction:
356  // Generate Tarmac entries and dump them immediately
357 
358  // Generate Tarmac entries and add them to the respective
359  // queues.
360  addInstEntry(instQueue, tarmCtx);
361  addMemEntry(memQueue, tarmCtx);
362  addRegEntry(regQueue, tarmCtx);
363 
364  // Flush (print) any queued entry.
365  flushQueues(instQueue, memQueue, regQueue);
366 
367  } else {
368  // Current instruction is a micro-instruction:
369  // save micro entries into dedicated queues and flush them
370  // into the tracefile only when the MACRO-instruction
371  // has completed.
372 
373  if (staticInst->isFirstMicroop()) {
374  addInstEntry(instQueue, tarmCtx);
375  }
376 
377  addRegEntry(regQueue, tarmCtx);
378  addMemEntry(memQueue, tarmCtx);
379 
380  if (staticInst->isLastMicroop()) {
381  // Flush (print) any queued entry.
382  flushQueues(instQueue, memQueue, regQueue);
383  }
384  }
385 }
386 
387 template<typename Queue>
388 void
390 {
391  std::ostream &outs = Trace::output();
392 
393  for (const auto &single_entry : queue) {
394  single_entry->print(outs);
395  }
396 
397  queue.clear();
398 }
399 
400 template<typename Queue, typename... Args>
401 void
402 TarmacTracerRecord::flushQueues(Queue& queue, Args & ... args)
403 {
404  flushQueues(queue);
405  flushQueues(args...);
406 }
407 
408 void
410  std::ostream& outs,
411  int verbosity,
412  const std::string &prefix) const
413 {
414  // Pad the opcode
415  std::string opcode_str = csprintf("%0*x", instSize >> 2, opcode);
416 
417  // Print the instruction record formatted according
418  // to the Tarmac specification
419  ccprintf(outs, "%s clk %s (%u) %08x %s %s %s_%s : %s\n",
420  curTick(), /* Tick time */
421  taken? "IT" : "IS", /* Instruction taken/skipped */
422  instCount, /* Instruction count */
423  addr, /* Instruction address */
424  opcode_str, /* Instruction opcode */
425  iSetStateToStr(isetstate), /* Instruction Set */
426  opModeToStr(mode), /* Exception level */
427  secureMode? "s" : "ns", /* Security */
428  disassemble); /* Instruction disass */
429 }
430 
431 void
433  std::ostream& outs,
434  int verbosity,
435  const std::string &prefix) const
436 {
437  // Print the memory record formatted according
438  // to the Tarmac specification
439  ccprintf(outs, "%s clk M%s%d %08x %0*x\n",
440  curTick(), /* Tick time */
441  loadAccess? "R" : "W", /* Access type */
442  size, /* Access size */
443  addr, /* Memory address */
444  size*2, /* Padding with access size */
445  data); /* Memory data */
446 }
447 
448 void
450  std::ostream& outs,
451  int verbosity,
452  const std::string &prefix) const
453 {
454  // Print the register record formatted according
455  // to the Tarmac specification
456  if (regValid)
457  ccprintf(outs, "%s clk R %s %08x\n",
458  curTick(), /* Tick time */
459  regName, /* Register name */
460  values[Lo]); /* Register value */
461 }
462 
463 } // namespace Trace
void ccprintf(cp::Print &print)
Definition: cprintf.hh:131
TraceMemEntry(const TarmacContext &tarmCtx, uint8_t _size, Addr _addr, uint64_t _data)
TarmacTracer & tracer
Reference to tracer.
TraceInstEntry(const TarmacContext &tarmCtx, bool predicate)
TheISA::PCState pc
Definition: insttracer.hh:69
Bitfield< 30, 0 > index
Bitfield< 5, 3 > reg
Definition: types.hh:89
std::string regName
Register name to be printed.
Floating-point register.
Definition: reg_class.hh:58
ISetState
ARM instruction set state.
Definition: tarmac_base.hh:77
Tarmac Tracer: this tracer generates a new Tarmac Record for every instruction being executed in gem5...
bool predicate
is the predicate for execution this inst true or false (not execed)?
Definition: insttracer.hh:147
uint64_t getIntData() const
Definition: insttracer.hh:238
std::vector< InstPtr > instQueue
Collection of heterogeneous printable entries: could be representing either instructions, register or memory entries.
Addr getSize() const
Definition: insttracer.hh:234
std::string opModeToStr(OperatingMode opMode)
Returns the string representation of the ARM Operating Mode (CPSR.M[3:0] field) according to the Tarm...
std::vector< uint64_t > values
Definition: tarmac_base.hh:116
virtual RegVal readIntReg(RegIndex reg_idx) const =0
Control (misc) register.
Definition: reg_class.hh:65
This object type is encapsulating the informations needed by a Tarmac record to generate it&#39;s own ent...
virtual void updateMisc(const TarmacContext &tarmCtx, RegIndex regRelIdx)
Register update functions.
ThreadContext * thread
Definition: insttracer.hh:65
TarmacTracerRecord(Tick _when, ThreadContext *_thread, const StaticInstPtr _staticInst, ArmISA::PCState _pc, TarmacTracer &_tracer, const StaticInstPtr _macroStaticInst=NULL)
int8_t numDestRegs() const
Number of destination registers.
Definition: static_inst.hh:135
bool secureMode
True if instruction is executed in secure mode.
Addr size
The size of the memory request.
Definition: insttracer.hh:84
OperatingMode
Definition: types.hh:592
static uint64_t instCount
Number of instructions being traced.
uint8_t instSize
Instruction size: 16 for 16-bit Thumb Instruction 32 otherwise (ARM and BigThumb) ...
static float bitsToFloat32(uint32_t val)
Definition: types.hh:198
virtual void updateFloat(const TarmacContext &tarmCtx, RegIndex regRelIdx)
const char *const miscRegName[]
Definition: miscregs.hh:1021
virtual void addMemEntry(std::vector< MemPtr > &queue, const TarmacContext &ptr)
Generates an Entry for every triggered memory access.
Bitfield< 4, 0 > mode
void flushQueues(Queue &queue)
Flush queues to the trace output.
virtual RegVal readCCReg(RegIndex reg_idx) const =0
ThreadContext is the external interface to all thread state for anything outside of the CPU...
A high-level queue interface, to be used by both the MSHR queue and the write buffer.
Definition: queue.hh:70
std::vector< RegPtr > regQueue
RegIndex regRel
Register arch number.
const RegIndex ReturnAddressReg
Definition: registers.hh:80
TARMAC instruction trace record.
Definition: tarmac_base.hh:84
virtual void updateVec(const TarmacContext &tarmCtx, RegIndex regRelIdx)
virtual void print(std::ostream &outs, int verbosity=0, const std::string &prefix="") const override
std::vector< MemPtr > memQueue
Tick curTick()
The current simulated tick.
Definition: core.hh:47
std::string csprintf(const char *format, const Args &...args)
Definition: cprintf.hh:162
virtual RegVal readFloatReg(RegIndex reg_idx) const =0
uint16_t RegIndex
Definition: types.hh:42
virtual void print(std::ostream &outs, int verbosity=0, const std::string &prefix="") const override
uint64_t Tick
Tick count type.
Definition: types.hh:63
const char *const ccRegName[NUM_CCREGS]
Definition: ccregs.hh:55
bool regValid(Addr daddr)
Definition: sinicreg.hh:226
const int PCReg
Definition: registers.hh:118
virtual void addRegEntry(std::vector< RegPtr > &queue, const TarmacContext &ptr)
Generate an Entry for every register being written.
Condition-code register.
Definition: reg_class.hh:64
StaticInstPtr macroStaticInst
Definition: insttracer.hh:70
const RegIndex StackPointerReg
Definition: registers.hh:77
union Trace::InstRecord::@120 data
virtual void print(std::ostream &outs, int verbosity=0, const std::string &prefix="") const override
std::ostream & output()
Get the ostream from the current global logger.
Definition: trace.cc:81
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
void update(const TarmacContext &tarmCtx)
This updates the register entry using the update table.
bool isFirstMicroop() const
Definition: static_inst.hh:200
TraceRegEntry(const TarmacContext &tarmCtx, const RegId &reg)
bool regValid
True if register entry is valid.
TARMAC register trace record.
Definition: tarmac_base.hh:101
const StaticInstPtr staticInst
virtual RegVal readMiscRegNoEffect(RegIndex misc_reg) const =0
TARMAC memory access trace record (stores only).
Definition: tarmac_base.hh:120
std::string iSetStateToStr(TarmacBaseRecord::ISetState isetstate)
Returns the string representation of the instruction set being currently run according to the Tarmac ...
GenericISA::SimplePCState< MachInst > PCState
Definition: types.hh:43
Bitfield< 24, 21 > opcode
Definition: types.hh:102
Addr getAddr() const
Definition: insttracer.hh:233
bool getMemValid() const
Definition: insttracer.hh:236
virtual void updateInt(const TarmacContext &tarmCtx, RegIndex regRelIdx)
StaticInstPtr staticInst
Definition: insttracer.hh:68
const RegIndex FramePointerReg
Definition: registers.hh:82
const RegId & destRegIdx(int i) const
Return logical index (architectural reg num) of i&#39;th destination reg.
Definition: static_inst.hh:216
Register ID: describe an architectural register with its class and index.
Definition: reg_class.hh:79
Integer register.
Definition: reg_class.hh:57
virtual void updateCC(const TarmacContext &tarmCtx, RegIndex regRelIdx)
virtual void updatePred(const TarmacContext &tarmCtx, RegIndex regRelIdx)
Vector Register.
Definition: reg_class.hh:60
bool inSecureState(ThreadContext *tc)
Definition: utility.cc:195
virtual void dump() override
virtual void addInstEntry(std::vector< InstPtr > &queue, const TarmacContext &ptr)
Generates an Entry for the executed instruction.
T * get() const
Directly access the pointer itself without taking a reference.
Definition: refcnt.hh:221
ThreadContext * thread
Addr addr
The address that was accessed.
Definition: insttracer.hh:83
bool isMicroop() const
Definition: static_inst.hh:197
const std::string to_string(sc_enc enc)
Definition: sc_fxdefs.cc:60
bool isLastMicroop() const
Definition: static_inst.hh:199

Generated on Fri Feb 28 2020 16:26:57 for gem5 by doxygen 1.8.13