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

Generated on Tue Jun 18 2024 16:23:57 for gem5 by doxygen 1.11.0