exec_context.hh revision 12104
1/* 2 * Copyright (c) 2014-2015 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 * Copyright (c) 2002-2005 The Regents of The University of Michigan 15 * All rights reserved. 16 * 17 * Redistribution and use in source and binary forms, with or without 18 * modification, are permitted provided that the following conditions are 19 * met: redistributions of source code must retain the above copyright 20 * notice, this list of conditions and the following disclaimer; 21 * redistributions in binary form must reproduce the above copyright 22 * notice, this list of conditions and the following disclaimer in the 23 * documentation and/or other materials provided with the distribution; 24 * neither the name of the copyright holders nor the names of its 25 * contributors may be used to endorse or promote products derived from 26 * this software without specific prior written permission. 27 * 28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 39 * 40 * Authors: Kevin Lim 41 * Andreas Sandberg 42 * Mitch Hayenga 43 */ 44 45#ifndef __CPU_SIMPLE_EXEC_CONTEXT_HH__ 46#define __CPU_SIMPLE_EXEC_CONTEXT_HH__ 47 48#include "arch/registers.hh" 49#include "base/types.hh" 50#include "config/the_isa.hh" 51#include "cpu/base.hh" 52#include "cpu/exec_context.hh" 53#include "cpu/reg_class.hh" 54#include "cpu/simple/base.hh" 55#include "cpu/static_inst_fwd.hh" 56#include "cpu/translation.hh" 57#include "mem/request.hh" 58 59class BaseSimpleCPU; 60 61class SimpleExecContext : public ExecContext { 62 protected: 63 typedef TheISA::MiscReg MiscReg; 64 typedef TheISA::FloatReg FloatReg; 65 typedef TheISA::FloatRegBits FloatRegBits; 66 typedef TheISA::CCReg CCReg; 67 68 public: 69 BaseSimpleCPU *cpu; 70 SimpleThread* thread; 71 72 // This is the offset from the current pc that fetch should be performed 73 Addr fetchOffset; 74 // This flag says to stay at the current pc. This is useful for 75 // instructions which go beyond MachInst boundaries. 76 bool stayAtPC; 77 78 // Branch prediction 79 TheISA::PCState predPC; 80 81 /** PER-THREAD STATS */ 82 83 // Number of simulated instructions 84 Counter numInst; 85 Stats::Scalar numInsts; 86 Counter numOp; 87 Stats::Scalar numOps; 88 89 // Number of integer alu accesses 90 Stats::Scalar numIntAluAccesses; 91 92 // Number of float alu accesses 93 Stats::Scalar numFpAluAccesses; 94 95 // Number of function calls/returns 96 Stats::Scalar numCallsReturns; 97 98 // Conditional control instructions; 99 Stats::Scalar numCondCtrlInsts; 100 101 // Number of int instructions 102 Stats::Scalar numIntInsts; 103 104 // Number of float instructions 105 Stats::Scalar numFpInsts; 106 107 // Number of integer register file accesses 108 Stats::Scalar numIntRegReads; 109 Stats::Scalar numIntRegWrites; 110 111 // Number of float register file accesses 112 Stats::Scalar numFpRegReads; 113 Stats::Scalar numFpRegWrites; 114 115 // Number of condition code register file accesses 116 Stats::Scalar numCCRegReads; 117 Stats::Scalar numCCRegWrites; 118 119 // Number of simulated memory references 120 Stats::Scalar numMemRefs; 121 Stats::Scalar numLoadInsts; 122 Stats::Scalar numStoreInsts; 123 124 // Number of idle cycles 125 Stats::Formula numIdleCycles; 126 127 // Number of busy cycles 128 Stats::Formula numBusyCycles; 129 130 // Number of simulated loads 131 Counter numLoad; 132 133 // Number of idle cycles 134 Stats::Average notIdleFraction; 135 Stats::Formula idleFraction; 136 137 // Number of cycles stalled for I-cache responses 138 Stats::Scalar icacheStallCycles; 139 Counter lastIcacheStall; 140 141 // Number of cycles stalled for D-cache responses 142 Stats::Scalar dcacheStallCycles; 143 Counter lastDcacheStall; 144 145 /// @{ 146 /// Total number of branches fetched 147 Stats::Scalar numBranches; 148 /// Number of branches predicted as taken 149 Stats::Scalar numPredictedBranches; 150 /// Number of misprediced branches 151 Stats::Scalar numBranchMispred; 152 /// @} 153 154 // Instruction mix histogram by OpClass 155 Stats::Vector statExecutedInstType; 156 157 public: 158 /** Constructor */ 159 SimpleExecContext(BaseSimpleCPU* _cpu, SimpleThread* _thread) 160 : cpu(_cpu), thread(_thread), fetchOffset(0), stayAtPC(false), 161 numInst(0), numOp(0), numLoad(0), lastIcacheStall(0), lastDcacheStall(0) 162 { } 163 164 /** Reads an integer register. */ 165 IntReg readIntRegOperand(const StaticInst *si, int idx) override 166 { 167 numIntRegReads++; 168 RegId reg = si->srcRegIdx(idx); 169 assert(reg.regClass == IntRegClass); 170 return thread->readIntReg(reg.regIdx); 171 } 172 173 /** Sets an integer register to a value. */ 174 void setIntRegOperand(const StaticInst *si, int idx, IntReg val) override 175 { 176 numIntRegWrites++; 177 RegId reg = si->destRegIdx(idx); 178 assert(reg.regClass == IntRegClass); 179 thread->setIntReg(reg.regIdx, val); 180 } 181 182 /** Reads a floating point register of single register width. */ 183 FloatReg readFloatRegOperand(const StaticInst *si, int idx) override 184 { 185 numFpRegReads++; 186 RegId reg = si->srcRegIdx(idx); 187 assert(reg.regClass == FloatRegClass); 188 return thread->readFloatReg(reg.regIdx); 189 } 190 191 /** Reads a floating point register in its binary format, instead 192 * of by value. */ 193 FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx) override 194 { 195 numFpRegReads++; 196 RegId reg = si->srcRegIdx(idx); 197 assert(reg.regClass == FloatRegClass); 198 return thread->readFloatRegBits(reg.regIdx); 199 } 200 201 /** Sets a floating point register of single width to a value. */ 202 void setFloatRegOperand(const StaticInst *si, int idx, 203 FloatReg val) override 204 { 205 numFpRegWrites++; 206 RegId reg = si->destRegIdx(idx); 207 assert(reg.regClass == FloatRegClass); 208 thread->setFloatReg(reg.regIdx, val); 209 } 210 211 /** Sets the bits of a floating point register of single width 212 * to a binary value. */ 213 void setFloatRegOperandBits(const StaticInst *si, int idx, 214 FloatRegBits val) override 215 { 216 numFpRegWrites++; 217 RegId reg = si->destRegIdx(idx); 218 assert(reg.regClass == FloatRegClass); 219 thread->setFloatRegBits(reg.regIdx, val); 220 } 221 222 CCReg readCCRegOperand(const StaticInst *si, int idx) override 223 { 224 numCCRegReads++; 225 RegId reg = si->srcRegIdx(idx); 226 assert(reg.regClass == CCRegClass); 227 return thread->readCCReg(reg.regIdx); 228 } 229 230 void setCCRegOperand(const StaticInst *si, int idx, CCReg val) override 231 { 232 numCCRegWrites++; 233 RegId reg = si->destRegIdx(idx); 234 assert(reg.regClass == CCRegClass); 235 thread->setCCReg(reg.regIdx, val); 236 } 237 238 MiscReg readMiscRegOperand(const StaticInst *si, int idx) override 239 { 240 numIntRegReads++; 241 RegId reg = si->srcRegIdx(idx); 242 assert(reg.regClass == MiscRegClass); 243 return thread->readMiscReg(reg.regIdx); 244 } 245 246 void setMiscRegOperand(const StaticInst *si, int idx, 247 const MiscReg &val) override 248 { 249 numIntRegWrites++; 250 RegId reg = si->destRegIdx(idx); 251 assert(reg.regClass == MiscRegClass); 252 thread->setMiscReg(reg.regIdx, val); 253 } 254 255 /** 256 * Reads a miscellaneous register, handling any architectural 257 * side effects due to reading that register. 258 */ 259 MiscReg readMiscReg(int misc_reg) override 260 { 261 numIntRegReads++; 262 return thread->readMiscReg(misc_reg); 263 } 264 265 /** 266 * Sets a miscellaneous register, handling any architectural 267 * side effects due to writing that register. 268 */ 269 void setMiscReg(int misc_reg, const MiscReg &val) override 270 { 271 numIntRegWrites++; 272 thread->setMiscReg(misc_reg, val); 273 } 274 275 PCState pcState() const override 276 { 277 return thread->pcState(); 278 } 279 280 void pcState(const PCState &val) override 281 { 282 thread->pcState(val); 283 } 284 285 286 /** 287 * Record the effective address of the instruction. 288 * 289 * @note Only valid for memory ops. 290 */ 291 void setEA(Addr EA) override 292 { panic("BaseSimpleCPU::setEA() not implemented\n"); } 293 294 /** 295 * Get the effective address of the instruction. 296 * 297 * @note Only valid for memory ops. 298 */ 299 Addr getEA() const override 300 { panic("BaseSimpleCPU::getEA() not implemented\n"); } 301 302 Fault readMem(Addr addr, uint8_t *data, unsigned int size, 303 Request::Flags flags) override 304 { 305 return cpu->readMem(addr, data, size, flags); 306 } 307 308 Fault initiateMemRead(Addr addr, unsigned int size, 309 Request::Flags flags) override 310 { 311 return cpu->initiateMemRead(addr, size, flags); 312 } 313 314 Fault writeMem(uint8_t *data, unsigned int size, Addr addr, 315 Request::Flags flags, uint64_t *res) override 316 { 317 return cpu->writeMem(data, size, addr, flags, res); 318 } 319 320 /** 321 * Sets the number of consecutive store conditional failures. 322 */ 323 void setStCondFailures(unsigned int sc_failures) override 324 { 325 thread->setStCondFailures(sc_failures); 326 } 327 328 /** 329 * Returns the number of consecutive store conditional failures. 330 */ 331 unsigned int readStCondFailures() const override 332 { 333 return thread->readStCondFailures(); 334 } 335 336 /** 337 * Executes a syscall specified by the callnum. 338 */ 339 void syscall(int64_t callnum, Fault *fault) override 340 { 341 if (FullSystem) 342 panic("Syscall emulation isn't available in FS mode."); 343 344 thread->syscall(callnum, fault); 345 } 346 347 /** Returns a pointer to the ThreadContext. */ 348 ThreadContext *tcBase() override 349 { 350 return thread->getTC(); 351 } 352 353 /** 354 * Somewhat Alpha-specific function that handles returning from an 355 * error or interrupt. 356 */ 357 Fault hwrei() override 358 { 359 return thread->hwrei(); 360 } 361 362 /** 363 * Check for special simulator handling of specific PAL calls. If 364 * return value is false, actual PAL call will be suppressed. 365 */ 366 bool simPalCheck(int palFunc) override 367 { 368 return thread->simPalCheck(palFunc); 369 } 370 371 bool readPredicate() override 372 { 373 return thread->readPredicate(); 374 } 375 376 void setPredicate(bool val) override 377 { 378 thread->setPredicate(val); 379 380 if (cpu->traceData) { 381 cpu->traceData->setPredicate(val); 382 } 383 } 384 385 /** 386 * Invalidate a page in the DTLB <i>and</i> ITLB. 387 */ 388 void demapPage(Addr vaddr, uint64_t asn) override 389 { 390 thread->demapPage(vaddr, asn); 391 } 392 393 void armMonitor(Addr address) override 394 { 395 cpu->armMonitor(thread->threadId(), address); 396 } 397 398 bool mwait(PacketPtr pkt) override 399 { 400 return cpu->mwait(thread->threadId(), pkt); 401 } 402 403 void mwaitAtomic(ThreadContext *tc) override 404 { 405 cpu->mwaitAtomic(thread->threadId(), tc, thread->dtb); 406 } 407 408 AddressMonitor *getAddrMonitor() override 409 { 410 return cpu->getCpuAddrMonitor(thread->threadId()); 411 } 412 413#if THE_ISA == MIPS_ISA 414 MiscReg readRegOtherThread(RegId reg, ThreadID tid = InvalidThreadID) 415 override 416 { 417 panic("Simple CPU models do not support multithreaded " 418 "register access."); 419 } 420 421 void setRegOtherThread(RegId reg, MiscReg val, 422 ThreadID tid = InvalidThreadID) override 423 { 424 panic("Simple CPU models do not support multithreaded " 425 "register access."); 426 } 427 428#endif 429 430}; 431 432#endif // __CPU_EXEC_CONTEXT_HH__ 433