mem-cache: Add multiple eviction stats
[gem5.git] / src / arch / arm / tracers / tarmac_record.hh
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
40 /**
41 * @file: The file contains the informations used to generate records
42 * for the pre-ARMv8 cores.
43 */
44
45 #ifndef __ARCH_ARM_TRACERS_TARMAC_RECORD_HH__
46 #define __ARCH_ARM_TRACERS_TARMAC_RECORD_HH__
47
48 #include "arch/arm/tracers/tarmac_base.hh"
49 #include "base/printable.hh"
50 #include "config/the_isa.hh"
51 #include "cpu/reg_class.hh"
52 #include "cpu/static_inst.hh"
53
54 namespace Trace {
55
56 class TarmacContext;
57
58 class TarmacTracer;
59
60 /**
61 * Returns the string representation of the instruction set being
62 * currently run according to the Tarmac format.
63 *
64 * @param isetstate: enum variable (ISetState) specifying an ARM
65 * instruction set.
66 * @return instruction set in string format.
67 */
68 std::string
69 iSetStateToStr(TarmacBaseRecord::ISetState isetstate);
70
71 /**
72 * Returns the string representation of the ARM Operating Mode
73 * (CPSR.M[3:0] field) according to the Tarmac format.
74 *
75 * @param opMode: ARM operating mode.
76 * @return operating mode in string format.
77 */
78 std::string
79 opModeToStr(ArmISA::OperatingMode opMode);
80
81 /**
82 * TarmacTracer Record:
83 * Record generated by the TarmacTracer for every executed instruction.
84 * The record is composed by a set of entries, matching the tracing
85 * capabilities provided by the Tarmac specifications:
86 *
87 * - Instruction Entry
88 * - Register Entry
89 * - Memory Entry
90 */
91 class TarmacTracerRecord : public TarmacBaseRecord
92 {
93 public:
94 /** Instruction Entry */
95 struct TraceInstEntry: public InstEntry, Printable
96 {
97 TraceInstEntry(const TarmacContext& tarmCtx, bool predicate);
98
99 virtual void print(std::ostream& outs,
100 int verbosity = 0,
101 const std::string &prefix = "") const override;
102
103 protected:
104 /** Number of instructions being traced */
105 static uint64_t instCount;
106
107 /** True if instruction is executed in secure mode */
108 bool secureMode;
109 /**
110 * Instruction size:
111 * 16 for 16-bit Thumb Instruction
112 * 32 otherwise (ARM and BigThumb)
113 */
114 uint8_t instSize;
115 };
116
117 /** Register Entry */
118 struct TraceRegEntry: public RegEntry, Printable
119 {
120 public:
121 TraceRegEntry(const TarmacContext& tarmCtx, const RegId& reg);
122
123 /**
124 * This updates the register entry using the update table. It is
125 * a required step after the register entry generation.
126 * If unupdated, the entry will be marked as invalid.
127 * The entry update cannot be done automatically at TraceRegEntry
128 * construction: the entries are extended by consequent Tarmac
129 * Tracer versions (like V8), and virtual functions should
130 * be avoided during construction.
131 */
132 void update(const TarmacContext& tarmCtx);
133
134 virtual void print(std::ostream& outs,
135 int verbosity = 0,
136 const std::string &prefix = "") const override;
137
138 protected:
139 /** Register update functions. */
140 virtual void
141 updateMisc(const TarmacContext& tarmCtx, RegIndex regRelIdx);
142
143 virtual void
144 updateCC(const TarmacContext& tarmCtx, RegIndex regRelIdx);
145
146 virtual void
147 updateFloat(const TarmacContext& tarmCtx, RegIndex regRelIdx);
148
149 virtual void
150 updateInt(const TarmacContext& tarmCtx, RegIndex regRelIdx);
151
152 virtual void
153 updateVec(const TarmacContext& tarmCtx, RegIndex regRelIdx) {};
154
155 virtual void
156 updatePred(const TarmacContext& tarmCtx, RegIndex regRelIdx) {};
157
158 public:
159 /** True if register entry is valid */
160 bool regValid;
161 /** Register class */
162 RegClass regClass;
163 /** Register arch number */
164 RegIndex regRel;
165 /** Register name to be printed */
166 std::string regName;
167 };
168
169 /** Memory Entry */
170 struct TraceMemEntry: public MemEntry, Printable
171 {
172 public:
173 TraceMemEntry(const TarmacContext& tarmCtx,
174 uint8_t _size, Addr _addr, uint64_t _data);
175
176 virtual void print(std::ostream& outs,
177 int verbosity = 0,
178 const std::string &prefix = "") const override;
179
180 protected:
181 /** True if memory access is a load */
182 bool loadAccess;
183 };
184
185 public:
186 TarmacTracerRecord(Tick _when, ThreadContext *_thread,
187 const StaticInstPtr _staticInst, ArmISA::PCState _pc,
188 TarmacTracer& _tracer,
189 const StaticInstPtr _macroStaticInst = NULL);
190
191 virtual void dump() override;
192
193 using InstPtr = std::unique_ptr<TraceInstEntry>;
194 using MemPtr = std::unique_ptr<TraceMemEntry>;
195 using RegPtr = std::unique_ptr<TraceRegEntry>;
196
197 protected:
198 /** Generates an Entry for the executed instruction. */
199 virtual void addInstEntry(std::vector<InstPtr>& queue,
200 const TarmacContext& ptr);
201
202 /** Generates an Entry for every triggered memory access */
203 virtual void addMemEntry(std::vector<MemPtr>& queue,
204 const TarmacContext& ptr);
205
206 /** Generate an Entry for every register being written. */
207 virtual void addRegEntry(std::vector<RegPtr>& queue,
208 const TarmacContext& ptr);
209
210 protected:
211 /** Generate and update a register entry. */
212 template<typename RegEntry>
213 RegEntry
214 genRegister(const TarmacContext& tarmCtx, const RegId& reg)
215 {
216 RegEntry single_reg(tarmCtx, reg);
217 single_reg.update(tarmCtx);
218
219 return single_reg;
220 }
221
222 template<typename RegEntry>
223 void
224 mergeCCEntry(std::vector<RegPtr>& queue, const TarmacContext& tarmCtx)
225 {
226 // Find all CC Entries and move them at the end of the queue
227 auto it = std::remove_if(
228 queue.begin(), queue.end(),
229 [] (RegPtr& reg) ->bool { return (reg->regClass == CCRegClass); }
230 );
231
232 if (it != queue.end()) {
233 // Remove all CC Entries.
234 queue.erase(it, queue.end());
235
236 auto is_cpsr = [] (RegPtr& reg) ->bool
237 {
238 return (reg->regClass == MiscRegClass) &&
239 (reg->regRel == ArmISA::MISCREG_CPSR);
240 };
241
242 // Looking for the presence of a CPSR register entry.
243 auto cpsr_it = std::find_if(
244 queue.begin(), queue.end(), is_cpsr
245 );
246
247 // If CPSR entry not present, generate one
248 if (cpsr_it == queue.end()) {
249 RegId reg(MiscRegClass, ArmISA::MISCREG_CPSR);
250 queue.push_back(
251 m5::make_unique<RegEntry>(
252 genRegister<RegEntry>(tarmCtx, reg))
253 );
254 }
255 }
256 }
257
258 /** Flush queues to the trace output */
259 template<typename Queue>
260 void flushQueues(Queue& queue);
261 template<typename Queue, typename... Args>
262 void flushQueues(Queue& queue, Args & ... args);
263
264 protected:
265 /** Reference to tracer */
266 TarmacTracer& tracer;
267 };
268
269 } // namespace Trace
270
271 #endif // __ARCH_ARM_TRACERS_TARMAC_RECORD_HH__