gem5  v20.0.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
tarmac_record_v8.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 "arch/arm/tlb.hh"
43 
44 namespace Trace {
45 
47  const TarmacContext& tarmCtx,
48  bool predicate)
49  : TraceInstEntry(tarmCtx, predicate),
50  TraceEntryV8(tarmCtx.tarmacCpuName()),
51  paddr(0),
52  paddrValid(false)
53 {
54  const auto thread = tarmCtx.thread;
55 
56  // Evaluate physical address
57  ArmISA::TLB* dtb = static_cast<TLB*>(thread->getDTBPtr());
59 }
60 
62  const TarmacContext& tarmCtx,
63  uint8_t _size, Addr _addr, uint64_t _data)
64  : TraceMemEntry(tarmCtx, _size, _addr, _data),
65  TraceEntryV8(tarmCtx.tarmacCpuName()),
66  paddr(_addr)
67 {
68  const auto thread = tarmCtx.thread;
69 
70  // Evaluate physical address
71  ArmISA::TLB* dtb = static_cast<TLB*>(thread->getDTBPtr());
73 }
74 
76  const TarmacContext& tarmCtx,
77  const RegId& reg)
78  : TraceRegEntry(tarmCtx, reg),
79  TraceEntryV8(tarmCtx.tarmacCpuName()),
80  regWidth(64)
81 {
82 }
83 
84 void
86  const TarmacContext& tarmCtx,
87  RegIndex regRelIdx
88 )
89 {
90  // Do not trace pseudo register accesses: invalid
91  // register entry.
92  if (regRelIdx > NUM_ARCH_INTREGS) {
93  regValid = false;
94  return;
95  }
96 
97  TraceRegEntry::updateInt(tarmCtx, regRelIdx);
98 
99  if ((regRelIdx != PCReg) || (regRelIdx != StackPointerReg) ||
100  (regRelIdx != FramePointerReg) || (regRelIdx != ReturnAddressReg)) {
101 
102  const auto* arm_inst = static_cast<const ArmStaticInst*>(
103  tarmCtx.staticInst.get()
104  );
105 
106  regWidth = (arm_inst->getIntWidth());
107  if (regWidth == 32) {
108  regName = "W" + std::to_string(regRelIdx);
109  } else {
110  regName = "X" + std::to_string(regRelIdx);
111  }
112  }
113 }
114 
115 void
117  const TarmacContext& tarmCtx,
118  RegIndex regRelIdx
119 )
120 {
121  TraceRegEntry::updateMisc(tarmCtx, regRelIdx);
122  // System registers are 32bit wide
123  regWidth = 32;
124 }
125 
126 void
128  const TarmacContext& tarmCtx,
129  RegIndex regRelIdx
130 )
131 {
132  auto thread = tarmCtx.thread;
133  const auto& vec_container = thread->readVecReg(
134  RegId(regClass, regRelIdx));
135  auto vv = vec_container.as<VecElem>();
136 
137  regWidth = ArmStaticInst::getCurSveVecLenInBits(thread);
138  auto num_elements = regWidth / (sizeof(VecElem) * 8);
139 
140  // Resize vector of values
141  values.resize(num_elements);
142 
143  for (auto i = 0; i < num_elements; i++) {
144  values[i] = vv[i];
145  }
146 
147  regValid = true;
148  regName = "Z" + std::to_string(regRelIdx);
149 }
150 
151 void
153  const TarmacContext& tarmCtx,
154  RegIndex regRelIdx
155 )
156 {
157  auto thread = tarmCtx.thread;
158  const auto& pred_container = thread->readVecPredReg(
159  RegId(regClass, regRelIdx));
160 
161  // Predicate registers are always 1/8 the size of related vector
162  // registers. (getCurSveVecLenInBits(thread) / 8)
163  regWidth = ArmStaticInst::getCurSveVecLenInBits(thread) / 8;
164  auto num_elements = regWidth / 16;
165 
166  // Resize vector of values
167  values.resize(num_elements);
168 
169  // Get a copy of pred_container as a vector of half-words
170  auto vv = pred_container.as<uint16_t>();
171  for (auto i = 0; i < num_elements; i++) {
172  values[i] = vv[i];
173  }
174 
175  regValid = true;
176  regName = "P" + std::to_string(regRelIdx);
177 }
178 
179 void
181  const TarmacContext& tarmCtx)
182 {
183  // Generate an instruction entry in the record and
184  // add it to the Instruction Queue
185  queue.push_back(
186  m5::make_unique<TraceInstEntryV8>(tarmCtx, predicate)
187  );
188 }
189 
190 void
192  const TarmacContext& tarmCtx)
193 {
194  // Generate a memory entry in the record if the record
195  // implies a valid memory access, and add it to the
196  // Memory Queue
197  if (getMemValid()) {
198  queue.push_back(
199  m5::make_unique<TraceMemEntryV8>(tarmCtx,
200  static_cast<uint8_t>(getSize()),
201  getAddr(), getIntData())
202  );
203  }
204 }
205 
206 void
208  const TarmacContext& tarmCtx)
209 {
210  // Generate an entry for every ARM register being
211  // written by the current instruction
212  for (auto reg = 0; reg < staticInst->numDestRegs(); ++reg) {
213 
214  RegId reg_id = staticInst->destRegIdx(reg);
215 
216  // Creating a single register change entry
217  auto single_reg = genRegister<TraceRegEntryV8>(tarmCtx, reg_id);
218 
219  // Copying the entry and adding it to the "list"
220  // of entries to be dumped to trace.
221  queue.push_back(
222  m5::make_unique<TraceRegEntryV8>(single_reg)
223  );
224  }
225 
226  // Gem5 is treating CPSR flags as separate registers (CC registers),
227  // in contrast with Tarmac specification: we need to merge the gem5 CC
228  // entries altogether with the CPSR register and produce a single entry.
229  mergeCCEntry<TraceRegEntryV8>(queue, tarmCtx);
230 }
231 
232 void
234  std::ostream& outs,
235  int verbosity,
236  const std::string &prefix) const
237 {
238  // If there is a valid vaddr->paddr translation, print the
239  // physical address, otherwise print the virtual address only.
240  std::string paddr_str = paddrValid? csprintf(":%012x",paddr) :
241  std::string();
242 
243  // Pad the opcode.
244  std::string opcode_str = csprintf("%0*x", instSize >> 2, opcode);
245 
246  // Print the instruction record formatted according
247  // to the Tarmac specification
248  ccprintf(outs, "%s clk %s %s (%u) %08x%s %s %s %s_%s : %s\n",
249  curTick(), /* Tick time */
250  cpuName, /* Cpu name */
251  taken? "IT" : "IS", /* Instruction taken/skipped */
252  instCount, /* Instruction count */
253  addr, /* Instruction virt address */
254  paddr_str, /* Instruction phys address */
255  opcode_str, /* Instruction opcode */
256  iSetStateToStr(isetstate), /* Instruction Set */
257  opModeToStr(mode), /* Exception level */
258  secureMode? "s" : "ns", /* Security */
259  disassemble); /* Instruction disass */
260 }
261 
262 void
264  std::ostream& outs,
265  int verbosity,
266  const std::string &prefix) const
267 {
268  // Print the memory record formatted according
269  // to the Tarmac specification
270  ccprintf(outs, "%s clk %s M%s%d %08x:%012x %0*x\n",
271  curTick(), /* Tick time */
272  cpuName, /* Cpu name */
273  loadAccess? "R" : "W", /* Access type */
274  size, /* Access size */
275  addr, /* Virt Memory address */
276  paddr, /* Phys Memory address */
277  size*2, /* Padding with access size */
278  data); /* Memory data */
279 }
280 
281 void
283  std::ostream& outs,
284  int verbosity,
285  const std::string &prefix) const
286 {
287  // Print the register record formatted according
288  // to the Tarmac specification
289  if (regValid) {
290  ccprintf(outs, "%s clk %s R %s %s\n",
291  curTick(), /* Tick time */
292  cpuName, /* Cpu name */
293  regName, /* Register name */
294  formatReg()); /* Register value */
295  }
296 }
297 
298 std::string
300 {
301  if (regWidth <= 64) {
302  // Register width is < 64 bit (scalar register).
303  return csprintf("%0*x", regWidth / 4, values[Lo]);
304  } else {
305 
306  // Register width is > 64 bit (vector). Iterate over every vector
307  // element. Since the vector values are stored in Little Endian, print
308  // starting from the last element.
309  std::string reg_val;
310  for (auto it = values.rbegin(); it != values.rend(); it++) {
311  reg_val += csprintf("%0*x_",
312  static_cast<int>(sizeof(VecElem) * 2), *it);
313  }
314 
315  // Remove trailing underscore
316  reg_val.pop_back();
317 
318  return reg_val;
319  }
320 }
321 
322 } // namespace Trace
void ccprintf(cp::Print &print)
Definition: cprintf.hh:127
Bitfield< 5, 3 > reg
Definition: types.hh:87
void updateVec(const TarmacContext &tarmCtx, RegIndex regRelIdx) override
bool predicate
is the predicate for execution this inst true or false (not execed)?
Definition: insttracer.hh:144
Bitfield< 7 > i
uint64_t getIntData() const
Definition: insttracer.hh:235
Addr getSize() const
Definition: insttracer.hh:231
virtual BaseTLB * getDTBPtr()=0
TraceInstEntryV8(const TarmacContext &tarmCtx, bool predicate)
std::string opModeToStr(OperatingMode opMode)
Returns the string representation of the ARM Operating Mode (CPSR.M[3:0] field) according to the Tarm...
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 print(std::ostream &outs, int verbosity=0, const std::string &prefix="") const override
virtual void updateMisc(const TarmacContext &tarmCtx, RegIndex regRelIdx)
Register update functions.
ThreadContext * thread
Definition: insttracer.hh:62
int8_t numDestRegs() const
Number of destination registers.
Definition: static_inst.hh:137
Addr size
The size of the memory request.
Definition: insttracer.hh:81
Bitfield< 4, 0 > mode
uint32_t VecElem
Definition: registers.hh:68
void updateInt(const TarmacContext &tarmCtx, RegIndex regRelIdx) override
std::string formatReg() const
Returning a string which contains the formatted register value: transformed in hex, 0 padded or/and split in chunks separated by underscores in case of vector register.
virtual const VecRegContainer & readVecReg(const RegId &reg) const =0
virtual void print(std::ostream &outs, int verbosity=0, const std::string &prefix="") const override
TraceRegEntryV8(const TarmacContext &tarmCtx, const RegId &reg)
virtual const VecPredRegContainer & readVecPredReg(const RegId &reg) const =0
Tick curTick()
The current simulated tick.
Definition: core.hh:44
std::string csprintf(const char *format, const Args &...args)
Definition: cprintf.hh:158
uint16_t RegIndex
Definition: types.hh:40
const int ReturnAddressReg
Definition: registers.hh:115
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
bool translateFunctional(ThreadContext *tc, Addr vaddr, Addr &paddr)
Do a functional lookup on the TLB (for debugging) and don&#39;t modify any internal state.
Definition: tlb.cc:115
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:140
VecRegT< VecElem, NumElems, true > as() const
View interposers.
Definition: vec_reg.hh:386
void updatePred(const TarmacContext &tarmCtx, RegIndex regRelIdx) override
const StaticInstPtr staticInst
General data shared by all v8 entries.
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
void addInstEntry(std::vector< InstPtr > &queue, const TarmacContext &ptr)
Generates an Entry for the executed instruction.
bool getMemValid() const
Definition: insttracer.hh:233
virtual void updateInt(const TarmacContext &tarmCtx, RegIndex regRelIdx)
StaticInstPtr staticInst
Definition: insttracer.hh:65
uint16_t regWidth
Size in bits of arch register.
const RegId & destRegIdx(int i) const
Return logical index (architectural reg num) of i&#39;th destination reg.
Definition: static_inst.hh:218
TraceMemEntryV8(const TarmacContext &tarmCtx, uint8_t _size, Addr _addr, uint64_t _data)
Register ID: describe an architectural register with its class and index.
Definition: reg_class.hh:75
virtual void print(std::ostream &outs, int verbosity=0, const std::string &prefix="") const override
void updateMisc(const TarmacContext &tarmCtx, RegIndex regRelIdx) override
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
const std::string to_string(sc_enc enc)
Definition: sc_fxdefs.cc:60
void addMemEntry(std::vector< MemPtr > &queue, const TarmacContext &ptr)
Generates an Entry for every memory access triggered.
void addRegEntry(std::vector< RegPtr > &queue, const TarmacContext &ptr)
Generate a Record for every register being written.

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