tarmac_record.hh revision 13915
1/* 2 * Copyright (c) 2017-2018 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 54namespace Trace { 55 56class TarmacContext; 57 58class 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 */ 68std::string 69iSetStateToStr(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 */ 78std::string 79opModeToStr(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 */ 91class 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 public: 153 /** True if register entry is valid */ 154 bool regValid; 155 /** Register class */ 156 RegClass regClass; 157 /** Register arch number */ 158 RegIndex regRel; 159 /** Register name to be printed */ 160 std::string regName; 161 }; 162 163 /** Memory Entry */ 164 struct TraceMemEntry: public MemEntry, Printable 165 { 166 public: 167 TraceMemEntry(const TarmacContext& tarmCtx, 168 uint8_t _size, Addr _addr, uint64_t _data); 169 170 virtual void print(std::ostream& outs, 171 int verbosity = 0, 172 const std::string &prefix = "") const override; 173 174 protected: 175 /** True if memory access is a load */ 176 bool loadAccess; 177 }; 178 179 public: 180 TarmacTracerRecord(Tick _when, ThreadContext *_thread, 181 const StaticInstPtr _staticInst, ArmISA::PCState _pc, 182 TarmacTracer& _tracer, 183 const StaticInstPtr _macroStaticInst = NULL); 184 185 virtual void dump() override; 186 187 using InstPtr = std::unique_ptr<TraceInstEntry>; 188 using MemPtr = std::unique_ptr<TraceMemEntry>; 189 using RegPtr = std::unique_ptr<TraceRegEntry>; 190 191 protected: 192 /** Generates an Entry for the executed instruction. */ 193 virtual void addInstEntry(std::vector<InstPtr>& queue, 194 const TarmacContext& ptr); 195 196 /** Generates an Entry for every triggered memory access */ 197 virtual void addMemEntry(std::vector<MemPtr>& queue, 198 const TarmacContext& ptr); 199 200 /** Generate an Entry for every register being written. */ 201 virtual void addRegEntry(std::vector<RegPtr>& queue, 202 const TarmacContext& ptr); 203 204 protected: 205 /** Generate and update a register entry. */ 206 template<typename RegEntry> 207 RegEntry 208 genRegister(const TarmacContext& tarmCtx, const RegId& reg) 209 { 210 RegEntry single_reg(tarmCtx, reg); 211 single_reg.update(tarmCtx); 212 213 return single_reg; 214 } 215 216 template<typename RegEntry> 217 void 218 mergeCCEntry(std::vector<RegPtr>& queue, const TarmacContext& tarmCtx) 219 { 220 // Find all CC Entries and move them at the end of the queue 221 auto it = std::remove_if( 222 queue.begin(), queue.end(), 223 [] (RegPtr& reg) ->bool { return (reg->regClass == CCRegClass); } 224 ); 225 226 if (it != queue.end()) { 227 // Remove all CC Entries. 228 queue.erase(it, queue.end()); 229 230 auto is_cpsr = [] (RegPtr& reg) ->bool 231 { 232 return (reg->regClass == MiscRegClass) && 233 (reg->regRel == ArmISA::MISCREG_CPSR); 234 }; 235 236 // Looking for the presence of a CPSR register entry. 237 auto cpsr_it = std::find_if( 238 queue.begin(), queue.end(), is_cpsr 239 ); 240 241 // If CPSR entry not present, generate one 242 if (cpsr_it == queue.end()) { 243 RegId reg(MiscRegClass, ArmISA::MISCREG_CPSR); 244 queue.push_back( 245 m5::make_unique<RegEntry>( 246 genRegister<RegEntry>(tarmCtx, reg)) 247 ); 248 } 249 } 250 } 251 252 /** Flush queues to the trace output */ 253 template<typename Queue> 254 void flushQueues(Queue& queue); 255 template<typename Queue, typename... Args> 256 void flushQueues(Queue& queue, Args & ... args); 257 258 protected: 259 /** Reference to tracer */ 260 TarmacTracer& tracer; 261}; 262 263} // namespace Trace 264 265#endif // __ARCH_ARM_TRACERS_TARMAC_RECORD_HH__ 266