2 * Copyright (c) 2017-2019 ARM Limited
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.
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.
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.
37 * Authors: Giacomo Travaglini
41 * @file: The file contains the informations used to generate records
42 * for the pre-ARMv8 cores.
45 #ifndef __ARCH_ARM_TRACERS_TARMAC_RECORD_HH__
46 #define __ARCH_ARM_TRACERS_TARMAC_RECORD_HH__
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"
61 * Returns the string representation of the instruction set being
62 * currently run according to the Tarmac format.
64 * @param isetstate: enum variable (ISetState) specifying an ARM
66 * @return instruction set in string format.
69 iSetStateToStr(TarmacBaseRecord::ISetState isetstate);
72 * Returns the string representation of the ARM Operating Mode
73 * (CPSR.M[3:0] field) according to the Tarmac format.
75 * @param opMode: ARM operating mode.
76 * @return operating mode in string format.
79 opModeToStr(ArmISA::OperatingMode opMode);
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:
91 class TarmacTracerRecord : public TarmacBaseRecord
94 /** Instruction Entry */
95 struct TraceInstEntry: public InstEntry, Printable
97 TraceInstEntry(const TarmacContext& tarmCtx, bool predicate);
99 virtual void print(std::ostream& outs,
101 const std::string &prefix = "") const override;
104 /** Number of instructions being traced */
105 static uint64_t instCount;
107 /** True if instruction is executed in secure mode */
111 * 16 for 16-bit Thumb Instruction
112 * 32 otherwise (ARM and BigThumb)
117 /** Register Entry */
118 struct TraceRegEntry: public RegEntry, Printable
121 TraceRegEntry(const TarmacContext& tarmCtx, const RegId& reg);
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.
132 void update(const TarmacContext& tarmCtx);
134 virtual void print(std::ostream& outs,
136 const std::string &prefix = "") const override;
139 /** Register update functions. */
141 updateMisc(const TarmacContext& tarmCtx, RegIndex regRelIdx);
144 updateCC(const TarmacContext& tarmCtx, RegIndex regRelIdx);
147 updateFloat(const TarmacContext& tarmCtx, RegIndex regRelIdx);
150 updateInt(const TarmacContext& tarmCtx, RegIndex regRelIdx);
153 updateVec(const TarmacContext& tarmCtx, RegIndex regRelIdx) {};
156 updatePred(const TarmacContext& tarmCtx, RegIndex regRelIdx) {};
159 /** True if register entry is valid */
161 /** Register class */
163 /** Register arch number */
165 /** Register name to be printed */
170 struct TraceMemEntry: public MemEntry, Printable
173 TraceMemEntry(const TarmacContext& tarmCtx,
174 uint8_t _size, Addr _addr, uint64_t _data);
176 virtual void print(std::ostream& outs,
178 const std::string &prefix = "") const override;
181 /** True if memory access is a load */
186 TarmacTracerRecord(Tick _when, ThreadContext *_thread,
187 const StaticInstPtr _staticInst, ArmISA::PCState _pc,
188 TarmacTracer& _tracer,
189 const StaticInstPtr _macroStaticInst = NULL);
191 virtual void dump() override;
193 using InstPtr = std::unique_ptr<TraceInstEntry>;
194 using MemPtr = std::unique_ptr<TraceMemEntry>;
195 using RegPtr = std::unique_ptr<TraceRegEntry>;
198 /** Generates an Entry for the executed instruction. */
199 virtual void addInstEntry(std::vector<InstPtr>& queue,
200 const TarmacContext& ptr);
202 /** Generates an Entry for every triggered memory access */
203 virtual void addMemEntry(std::vector<MemPtr>& queue,
204 const TarmacContext& ptr);
206 /** Generate an Entry for every register being written. */
207 virtual void addRegEntry(std::vector<RegPtr>& queue,
208 const TarmacContext& ptr);
211 /** Generate and update a register entry. */
212 template<typename RegEntry>
214 genRegister(const TarmacContext& tarmCtx, const RegId& reg)
216 RegEntry single_reg(tarmCtx, reg);
217 single_reg.update(tarmCtx);
222 template<typename RegEntry>
224 mergeCCEntry(std::vector<RegPtr>& queue, const TarmacContext& tarmCtx)
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); }
232 if (it != queue.end()) {
233 // Remove all CC Entries.
234 queue.erase(it, queue.end());
236 auto is_cpsr = [] (RegPtr& reg) ->bool
238 return (reg->regClass == MiscRegClass) &&
239 (reg->regRel == ArmISA::MISCREG_CPSR);
242 // Looking for the presence of a CPSR register entry.
243 auto cpsr_it = std::find_if(
244 queue.begin(), queue.end(), is_cpsr
247 // If CPSR entry not present, generate one
248 if (cpsr_it == queue.end()) {
249 RegId reg(MiscRegClass, ArmISA::MISCREG_CPSR);
251 m5::make_unique<RegEntry>(
252 genRegister<RegEntry>(tarmCtx, reg))
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);
265 /** Reference to tracer */
266 TarmacTracer& tracer;
271 #endif // __ARCH_ARM_TRACERS_TARMAC_RECORD_HH__