gem5  v20.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 
39 
41 #include "tarmac_tracer.hh"
42 
43 namespace Trace {
44 
45 // TARMAC Instruction Record static variables
47 
48 std::string
50 {
51  switch (isetstate) {
53  return "A";
55  return "T";
57  return "O";
58  default:
59  return "Unsupported";
60  }
61 }
62 
63 std::string
65 {
66  switch (opMode) {
67  case MODE_EL0T:
68  return "EL0t";
69  case MODE_EL1T:
70  return "EL1t";
71  case MODE_EL1H:
72  return "EL1h";
73  case MODE_EL2T:
74  return "EL2t";
75  case MODE_EL2H:
76  return "EL2h";
77  case MODE_EL3T:
78  return "EL3t";
79  case MODE_EL3H:
80  return "EL3h";
81  case MODE_USER:
82  return "usr";
83  case MODE_FIQ:
84  return "fiq";
85  case MODE_IRQ:
86  return "irq";
87  case MODE_SVC:
88  return "svc";
89  case MODE_MON:
90  return "mon";
91  case MODE_ABORT:
92  return "abt";
93  case MODE_HYP:
94  return "hyp";
95  case MODE_UNDEFINED:
96  return "und";
97  case MODE_SYSTEM:
98  return "sys";
99  default:
100  return "Unsupported";
101  }
102 }
103 
104 // TarmacTracerRecord ctor
106  const StaticInstPtr _staticInst,
107  PCState _pc,
108  TarmacTracer& _tracer,
109  const StaticInstPtr _macroStaticInst)
110  : TarmacBaseRecord(_when, _thread, _staticInst,
111  _pc, _macroStaticInst),
112  tracer(_tracer)
113 {
114 }
115 
117  const TarmacContext& tarmCtx,
118  bool predicate)
119  : InstEntry(tarmCtx.thread, tarmCtx.pc, tarmCtx.staticInst, predicate)
120 {
121  secureMode = inSecureState(tarmCtx.thread);
122 
123  auto arm_inst = static_cast<const ArmStaticInst*>(
124  tarmCtx.staticInst.get()
125  );
126 
127  // Get the instruction size as a number of bits:
128  // (multiply byte size by 8)
129  instSize = (arm_inst->instSize() << 3);
130 
131  // Mask the opcode using the instruction size: the
132  // opcode field will otherwise be 32 bit wide even
133  // for 16bit (Thumb) instruction.
134  opcode = arm_inst->encoding();
135 
136  // Update the instruction count: number of executed
137  // instructions.
138  instCount++;
139 }
140 
142  const TarmacContext& tarmCtx,
143  uint8_t _size, Addr _addr, uint64_t _data)
144  : MemEntry(_size, _addr, _data),
145  loadAccess(tarmCtx.staticInst->isLoad())
146 {
147 }
148 
150  const TarmacContext& tarmCtx,
151  const RegId& reg)
152  : RegEntry(tarmCtx.pc),
153  regValid(false),
154  regClass(reg.classValue()),
155  regRel(reg.index())
156 {
157 }
158 
159 void
161  const TarmacContext& tarmCtx
162 )
163 {
164  // Fill the register entry data, according to register
165  // class.
166  switch (regClass) {
167  case CCRegClass:
168  updateCC(tarmCtx, regRel);
169  break;
170  case FloatRegClass:
171  updateFloat(tarmCtx, regRel);
172  break;
173  case IntRegClass:
174  updateInt(tarmCtx, regRel);
175  break;
176  case MiscRegClass:
177  updateMisc(tarmCtx, regRel);
178  break;
179  case VecRegClass:
180  updateVec(tarmCtx, regRel);
181  break;
182  case VecPredRegClass:
183  updatePred(tarmCtx, regRel);
184  break;
185  default:
186  // If unsupported format, do nothing: non updating
187  // the register will prevent it to be printed.
188  break;
189  }
190 }
191 
192 void
194  const TarmacContext& tarmCtx,
195  RegIndex regRelIdx
196 )
197 {
198  auto thread = tarmCtx.thread;
199 
200  regValid = true;
201  regName = miscRegName[regRelIdx];
202  values[Lo] = thread->readMiscRegNoEffect(regRelIdx);
203 
204  // If it is the CPSR:
205  // update the value of the CPSR register and add
206  // the CC flags on top of the value
207  if (regRelIdx == MISCREG_CPSR) {
209  cpsr.nz = thread->readCCReg(CCREG_NZ);
210  cpsr.c = thread->readCCReg(CCREG_C);
211  cpsr.v = thread->readCCReg(CCREG_V);
212  cpsr.ge = thread->readCCReg(CCREG_GE);
213 
214  // update the entry value
215  values[Lo] = cpsr;
216  }
217 }
218 
219 void
221  const TarmacContext& tarmCtx,
222  RegIndex regRelIdx
223 )
224 {
225  auto thread = tarmCtx.thread;
226 
227  regValid = true;
228  regName = ccRegName[regRelIdx];
229  values[Lo] = thread->readCCReg(regRelIdx);
230 }
231 
232 void
234  const TarmacContext& tarmCtx,
235  RegIndex regRelIdx
236 )
237 {
238  auto thread = tarmCtx.thread;
239 
240  regValid = true;
241  regName = "f" + std::to_string(regRelIdx);
242  values[Lo] = bitsToFloat32(thread->readFloatReg(regRelIdx));
243 }
244 
245 void
247  const TarmacContext& tarmCtx,
248  RegIndex regRelIdx
249 )
250 {
251  auto thread = tarmCtx.thread;
252 
253  // Reading operating mode from CPSR.
254  // This is needed when printing the register name in case
255  // of banked register (e.g. lr_svc)
257  OperatingMode mode = (OperatingMode)(uint8_t)cpsr.mode;
258 
259  std::string reg_suffix;
260  if (mode != MODE_USER) {
261  reg_suffix = "_" + opModeToStr(mode);
262  }
263 
264  regValid = true;
265  switch (regRelIdx) {
266  case PCReg:
267  regName = "pc";
268  break;
269  case StackPointerReg:
270  regName = "sp" + reg_suffix ;
271  break;
272  case FramePointerReg:
273  regName = "fp" + reg_suffix;
274  break;
275  case ReturnAddressReg:
276  regName = "lr" + reg_suffix;
277  break;
278  default:
279  regName = "r" + std::to_string(regRelIdx);
280  break;
281  }
282  values[Lo] = thread->readIntReg(regRelIdx);
283 }
284 
285 void
287  const TarmacContext& tarmCtx)
288 {
289  // Generate an instruction entry in the record and
290  // add it to the Instruction Queue
291  queue.push_back(
292  m5::make_unique<TraceInstEntry>(tarmCtx, predicate)
293  );
294 }
295 
296 void
298  const TarmacContext& tarmCtx)
299 {
300  // Generate a memory entry in the record if the record
301  // implies a valid memory access, and add it to the
302  // Memory Queue
303  if (getMemValid()) {
304  queue.push_back(
305  m5::make_unique<TraceMemEntry>(tarmCtx,
306  static_cast<uint8_t>(getSize()),
307  getAddr(), getIntData())
308  );
309  }
310 }
311 
312 void
314  const TarmacContext& tarmCtx)
315 {
316  // Generate an entry for every ARM register being
317  // written by the current instruction
318  for (auto reg = 0; reg < staticInst->numDestRegs(); ++reg) {
319 
320  RegId reg_id = staticInst->destRegIdx(reg);
321 
322  // Creating a single register change entry
323  auto single_reg = genRegister<TraceRegEntry>(tarmCtx, reg_id);
324 
325  // Copying the entry and adding it to the "list"
326  // of entries to be dumped to trace.
327  queue.push_back(
328  m5::make_unique<TraceRegEntry>(single_reg)
329  );
330  }
331 
332  // Gem5 is treating CPSR flags as separate registers (CC registers),
333  // in contrast with Tarmac specification: we need to merge the gem5 CC
334  // entries altogether with the CPSR register and produce a single entry.
335  mergeCCEntry<TraceRegEntry>(queue, tarmCtx);
336 }
337 
338 void
340 {
341  // Generate and print all the record's entries.
342  auto &instQueue = tracer.instQueue;
343  auto &memQueue = tracer.memQueue;
344  auto &regQueue = tracer.regQueue;
345 
346  const TarmacContext tarmCtx(
347  thread,
349  pc
350  );
351 
352  if (!staticInst->isMicroop()) {
353  // Current instruction is NOT a micro-instruction:
354  // Generate Tarmac entries and dump them immediately
355 
356  // Generate Tarmac entries and add them to the respective
357  // queues.
358  addInstEntry(instQueue, tarmCtx);
359  addMemEntry(memQueue, tarmCtx);
360  addRegEntry(regQueue, tarmCtx);
361 
362  // Flush (print) any queued entry.
363  flushQueues(instQueue, memQueue, regQueue);
364 
365  } else {
366  // Current instruction is a micro-instruction:
367  // save micro entries into dedicated queues and flush them
368  // into the tracefile only when the MACRO-instruction
369  // has completed.
370 
371  if (staticInst->isFirstMicroop()) {
372  addInstEntry(instQueue, tarmCtx);
373  }
374 
375  addRegEntry(regQueue, tarmCtx);
376  addMemEntry(memQueue, tarmCtx);
377 
378  if (staticInst->isLastMicroop()) {
379  // Flush (print) any queued entry.
380  flushQueues(instQueue, memQueue, regQueue);
381  }
382  }
383 }
384 
385 template<typename Queue>
386 void
388 {
389  std::ostream &outs = Trace::output();
390 
391  for (const auto &single_entry : queue) {
392  single_entry->print(outs);
393  }
394 
395  queue.clear();
396 }
397 
398 template<typename Queue, typename... Args>
399 void
400 TarmacTracerRecord::flushQueues(Queue& queue, Args & ... args)
401 {
402  flushQueues(queue);
403  flushQueues(args...);
404 }
405 
406 void
408  std::ostream& outs,
409  int verbosity,
410  const std::string &prefix) const
411 {
412  // Pad the opcode
413  std::string opcode_str = csprintf("%0*x", instSize >> 2, opcode);
414 
415  // Print the instruction record formatted according
416  // to the Tarmac specification
417  ccprintf(outs, "%s clk %s (%u) %08x %s %s %s_%s : %s\n",
418  curTick(), /* Tick time */
419  taken? "IT" : "IS", /* Instruction taken/skipped */
420  instCount, /* Instruction count */
421  addr, /* Instruction address */
422  opcode_str, /* Instruction opcode */
423  iSetStateToStr(isetstate), /* Instruction Set */
424  opModeToStr(mode), /* Exception level */
425  secureMode? "s" : "ns", /* Security */
426  disassemble); /* Instruction disass */
427 }
428 
429 void
431  std::ostream& outs,
432  int verbosity,
433  const std::string &prefix) const
434 {
435  // Print the memory record formatted according
436  // to the Tarmac specification
437  ccprintf(outs, "%s clk M%s%d %08x %0*x\n",
438  curTick(), /* Tick time */
439  loadAccess? "R" : "W", /* Access type */
440  size, /* Access size */
441  addr, /* Memory address */
442  size*2, /* Padding with access size */
443  data); /* Memory data */
444 }
445 
446 void
448  std::ostream& outs,
449  int verbosity,
450  const std::string &prefix) const
451 {
452  // Print the register record formatted according
453  // to the Tarmac specification
454  if (regValid)
455  ccprintf(outs, "%s clk R %s %08x\n",
456  curTick(), /* Tick time */
457  regName, /* Register name */
458  values[Lo]); /* Register value */
459 }
460 
461 } // namespace Trace
void ccprintf(cp::Print &print)
Definition: cprintf.hh:127
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:66
Bitfield< 30, 0 > index
Bitfield< 5, 3 > reg
Definition: types.hh:87
std::string regName
Register name to be printed.
Floating-point register.
Definition: reg_class.hh:54
ISetState
ARM instruction set state.
Definition: tarmac_base.hh:74
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:144
uint64_t getIntData() const
Definition: insttracer.hh:235
std::vector< InstPtr > instQueue
Collection of heterogeneous printable entries: could be representing either instructions, register or memory entries.
Addr getSize() const
Definition: insttracer.hh:231
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:113
virtual RegVal readIntReg(RegIndex reg_idx) const =0
Control (misc) register.
Definition: reg_class.hh:61
This object type is encapsulating the informations needed by a Tarmac record to generate it&#39;s own ent...
union Trace::InstRecord::@115 data
virtual void updateMisc(const TarmacContext &tarmCtx, RegIndex regRelIdx)
Register update functions.
ThreadContext * thread
Definition: insttracer.hh:62
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:137
bool secureMode
True if instruction is executed in secure mode.
Addr size
The size of the memory request.
Definition: insttracer.hh:81
OperatingMode
Definition: types.hh:590
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:196
virtual void updateFloat(const TarmacContext &tarmCtx, RegIndex regRelIdx)
const char *const miscRegName[]
Definition: miscregs.hh:1033
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:66
std::vector< RegPtr > regQueue
RegIndex regRel
Register arch number.
TARMAC instruction trace record.
Definition: tarmac_base.hh:81
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:44
std::string csprintf(const char *format, const Args &...args)
Definition: cprintf.hh:158
virtual RegVal readFloatReg(RegIndex reg_idx) const =0
uint16_t RegIndex
Definition: types.hh:40
const int ReturnAddressReg
Definition: registers.hh:115
virtual void print(std::ostream &outs, int verbosity=0, const std::string &prefix="") const override
uint64_t Tick
Tick count type.
Definition: types.hh:61
const char *const ccRegName[NUM_CCREGS]
Definition: ccregs.hh:54
bool regValid(Addr daddr)
Definition: sinicreg.hh:224
const int PCReg
Definition: registers.hh:116
const int StackPointerReg
Definition: registers.hh:114
const int FramePointerReg
Definition: registers.hh:113
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:60
StaticInstPtr macroStaticInst
Definition: insttracer.hh:67
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:77
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:140
void update(const TarmacContext &tarmCtx)
This updates the register entry using the update table.
bool isFirstMicroop() const
Definition: static_inst.hh:202
TraceRegEntry(const TarmacContext &tarmCtx, const RegId &reg)
bool regValid
True if register entry is valid.
TARMAC register trace record.
Definition: tarmac_base.hh:98
const StaticInstPtr staticInst
virtual RegVal readMiscRegNoEffect(RegIndex misc_reg) const =0
TARMAC memory access trace record (stores only).
Definition: tarmac_base.hh:117
std::string iSetStateToStr(TarmacBaseRecord::ISetState isetstate)
Returns the string representation of the instruction set being currently run according to the Tarmac ...
Bitfield< 24, 21 > opcode
Definition: types.hh:100
Addr getAddr() const
Definition: insttracer.hh:230
bool getMemValid() const
Definition: insttracer.hh:233
virtual void updateInt(const TarmacContext &tarmCtx, RegIndex regRelIdx)
StaticInstPtr staticInst
Definition: insttracer.hh:65
const RegId & destRegIdx(int i) const
Return logical index (architectural reg num) of i&#39;th destination reg.
Definition: static_inst.hh:218
Register ID: describe an architectural register with its class and index.
Definition: reg_class.hh:75
Integer register.
Definition: reg_class.hh:53
virtual void updateCC(const TarmacContext &tarmCtx, RegIndex regRelIdx)
virtual void updatePred(const TarmacContext &tarmCtx, RegIndex regRelIdx)
Vector Register.
Definition: reg_class.hh:56
bool inSecureState(ThreadContext *tc)
Definition: utility.cc:174
virtual void dump() override
virtual void addInstEntry(std::vector< InstPtr > &queue, const TarmacContext &ptr)
Generates an Entry for the executed instruction.
GenericISA::DelaySlotPCState< MachInst > PCState
Definition: types.hh:41
T * get() const
Directly access the pointer itself without taking a reference.
Definition: refcnt.hh:219
ThreadContext * thread
Addr addr
The address that was accessed.
Definition: insttracer.hh:80
bool isMicroop() const
Definition: static_inst.hh:199
const std::string to_string(sc_enc enc)
Definition: sc_fxdefs.cc:60
bool isLastMicroop() const
Definition: static_inst.hh:201

Generated on Thu May 28 2020 16:11:03 for gem5 by doxygen 1.8.13