exec_context.hh revision 13500:6e0a2a7c6d8c
1/* 2 * Copyright (c) 2014-2016 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 using VecRegContainer = TheISA::VecRegContainer; 68 using VecElem = TheISA::VecElem; 69 70 public: 71 BaseSimpleCPU *cpu; 72 SimpleThread* thread; 73 74 // This is the offset from the current pc that fetch should be performed 75 Addr fetchOffset; 76 // This flag says to stay at the current pc. This is useful for 77 // instructions which go beyond MachInst boundaries. 78 bool stayAtPC; 79 80 // Branch prediction 81 TheISA::PCState predPC; 82 83 /** PER-THREAD STATS */ 84 85 // Number of simulated instructions 86 Counter numInst; 87 Stats::Scalar numInsts; 88 Counter numOp; 89 Stats::Scalar numOps; 90 91 // Number of integer alu accesses 92 Stats::Scalar numIntAluAccesses; 93 94 // Number of float alu accesses 95 Stats::Scalar numFpAluAccesses; 96 97 // Number of vector alu accesses 98 Stats::Scalar numVecAluAccesses; 99 100 // Number of function calls/returns 101 Stats::Scalar numCallsReturns; 102 103 // Conditional control instructions; 104 Stats::Scalar numCondCtrlInsts; 105 106 // Number of int instructions 107 Stats::Scalar numIntInsts; 108 109 // Number of float instructions 110 Stats::Scalar numFpInsts; 111 112 // Number of vector instructions 113 Stats::Scalar numVecInsts; 114 115 // Number of integer register file accesses 116 Stats::Scalar numIntRegReads; 117 Stats::Scalar numIntRegWrites; 118 119 // Number of float register file accesses 120 Stats::Scalar numFpRegReads; 121 Stats::Scalar numFpRegWrites; 122 123 // Number of vector register file accesses 124 mutable Stats::Scalar numVecRegReads; 125 Stats::Scalar numVecRegWrites; 126 127 // Number of condition code register file accesses 128 Stats::Scalar numCCRegReads; 129 Stats::Scalar numCCRegWrites; 130 131 // Number of simulated memory references 132 Stats::Scalar numMemRefs; 133 Stats::Scalar numLoadInsts; 134 Stats::Scalar numStoreInsts; 135 136 // Number of idle cycles 137 Stats::Formula numIdleCycles; 138 139 // Number of busy cycles 140 Stats::Formula numBusyCycles; 141 142 // Number of simulated loads 143 Counter numLoad; 144 145 // Number of idle cycles 146 Stats::Average notIdleFraction; 147 Stats::Formula idleFraction; 148 149 // Number of cycles stalled for I-cache responses 150 Stats::Scalar icacheStallCycles; 151 Counter lastIcacheStall; 152 153 // Number of cycles stalled for D-cache responses 154 Stats::Scalar dcacheStallCycles; 155 Counter lastDcacheStall; 156 157 /// @{ 158 /// Total number of branches fetched 159 Stats::Scalar numBranches; 160 /// Number of branches predicted as taken 161 Stats::Scalar numPredictedBranches; 162 /// Number of misprediced branches 163 Stats::Scalar numBranchMispred; 164 /// @} 165 166 // Instruction mix histogram by OpClass 167 Stats::Vector statExecutedInstType; 168 169 public: 170 /** Constructor */ 171 SimpleExecContext(BaseSimpleCPU* _cpu, SimpleThread* _thread) 172 : cpu(_cpu), thread(_thread), fetchOffset(0), stayAtPC(false), 173 numInst(0), numOp(0), numLoad(0), lastIcacheStall(0), lastDcacheStall(0) 174 { } 175 176 /** Reads an integer register. */ 177 IntReg readIntRegOperand(const StaticInst *si, int idx) override 178 { 179 numIntRegReads++; 180 const RegId& reg = si->srcRegIdx(idx); 181 assert(reg.isIntReg()); 182 return thread->readIntReg(reg.index()); 183 } 184 185 /** Sets an integer register to a value. */ 186 void setIntRegOperand(const StaticInst *si, int idx, IntReg val) override 187 { 188 numIntRegWrites++; 189 const RegId& reg = si->destRegIdx(idx); 190 assert(reg.isIntReg()); 191 thread->setIntReg(reg.index(), val); 192 } 193 194 /** Reads a floating point register in its binary format, instead 195 * of by value. */ 196 FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx) override 197 { 198 numFpRegReads++; 199 const RegId& reg = si->srcRegIdx(idx); 200 assert(reg.isFloatReg()); 201 return thread->readFloatRegBits(reg.index()); 202 } 203 204 /** Sets the bits of a floating point register of single width 205 * to a binary value. */ 206 void setFloatRegOperandBits(const StaticInst *si, int idx, 207 FloatRegBits val) override 208 { 209 numFpRegWrites++; 210 const RegId& reg = si->destRegIdx(idx); 211 assert(reg.isFloatReg()); 212 thread->setFloatRegBits(reg.index(), val); 213 } 214 215 /** Reads a vector register. */ 216 const VecRegContainer& 217 readVecRegOperand(const StaticInst *si, int idx) const override 218 { 219 numVecRegReads++; 220 const RegId& reg = si->srcRegIdx(idx); 221 assert(reg.isVecReg()); 222 return thread->readVecReg(reg); 223 } 224 225 /** Reads a vector register for modification. */ 226 VecRegContainer& 227 getWritableVecRegOperand(const StaticInst *si, int idx) override 228 { 229 numVecRegWrites++; 230 const RegId& reg = si->destRegIdx(idx); 231 assert(reg.isVecReg()); 232 return thread->getWritableVecReg(reg); 233 } 234 235 /** Sets a vector register to a value. */ 236 void setVecRegOperand(const StaticInst *si, int idx, 237 const VecRegContainer& val) override 238 { 239 numVecRegWrites++; 240 const RegId& reg = si->destRegIdx(idx); 241 assert(reg.isVecReg()); 242 thread->setVecReg(reg, val); 243 } 244 245 /** Vector Register Lane Interfaces. */ 246 /** @{ */ 247 /** Reads source vector lane. */ 248 template <typename VecElem> 249 VecLaneT<VecElem, true> 250 readVecLaneOperand(const StaticInst *si, int idx) const 251 { 252 numVecRegReads++; 253 const RegId& reg = si->srcRegIdx(idx); 254 assert(reg.isVecReg()); 255 return thread->readVecLane<VecElem>(reg); 256 } 257 /** Reads source vector 8bit operand. */ 258 virtual ConstVecLane8 259 readVec8BitLaneOperand(const StaticInst *si, int idx) const 260 override 261 { return readVecLaneOperand<uint8_t>(si, idx); } 262 263 /** Reads source vector 16bit operand. */ 264 virtual ConstVecLane16 265 readVec16BitLaneOperand(const StaticInst *si, int idx) const 266 override 267 { return readVecLaneOperand<uint16_t>(si, idx); } 268 269 /** Reads source vector 32bit operand. */ 270 virtual ConstVecLane32 271 readVec32BitLaneOperand(const StaticInst *si, int idx) const 272 override 273 { return readVecLaneOperand<uint32_t>(si, idx); } 274 275 /** Reads source vector 64bit operand. */ 276 virtual ConstVecLane64 277 readVec64BitLaneOperand(const StaticInst *si, int idx) const 278 override 279 { return readVecLaneOperand<uint64_t>(si, idx); } 280 281 /** Write a lane of the destination vector operand. */ 282 template <typename LD> 283 void 284 setVecLaneOperandT(const StaticInst *si, int idx, 285 const LD& val) 286 { 287 numVecRegWrites++; 288 const RegId& reg = si->destRegIdx(idx); 289 assert(reg.isVecReg()); 290 return thread->setVecLane(reg, val); 291 } 292 /** Write a lane of the destination vector operand. */ 293 virtual void 294 setVecLaneOperand(const StaticInst *si, int idx, 295 const LaneData<LaneSize::Byte>& val) override 296 { return setVecLaneOperandT(si, idx, val); } 297 /** Write a lane of the destination vector operand. */ 298 virtual void 299 setVecLaneOperand(const StaticInst *si, int idx, 300 const LaneData<LaneSize::TwoByte>& val) override 301 { return setVecLaneOperandT(si, idx, val); } 302 /** Write a lane of the destination vector operand. */ 303 virtual void 304 setVecLaneOperand(const StaticInst *si, int idx, 305 const LaneData<LaneSize::FourByte>& val) override 306 { return setVecLaneOperandT(si, idx, val); } 307 /** Write a lane of the destination vector operand. */ 308 virtual void 309 setVecLaneOperand(const StaticInst *si, int idx, 310 const LaneData<LaneSize::EightByte>& val) override 311 { return setVecLaneOperandT(si, idx, val); } 312 /** @} */ 313 314 /** Reads an element of a vector register. */ 315 VecElem readVecElemOperand(const StaticInst *si, int idx) const override 316 { 317 numVecRegReads++; 318 const RegId& reg = si->destRegIdx(idx); 319 assert(reg.isVecElem()); 320 return thread->readVecElem(reg); 321 } 322 323 /** Sets an element of a vector register to a value. */ 324 void setVecElemOperand(const StaticInst *si, int idx, 325 const VecElem val) override 326 { 327 numVecRegWrites++; 328 const RegId& reg = si->destRegIdx(idx); 329 assert(reg.isVecElem()); 330 thread->setVecElem(reg, val); 331 } 332 333 CCReg readCCRegOperand(const StaticInst *si, int idx) override 334 { 335 numCCRegReads++; 336 const RegId& reg = si->srcRegIdx(idx); 337 assert(reg.isCCReg()); 338 return thread->readCCReg(reg.index()); 339 } 340 341 void setCCRegOperand(const StaticInst *si, int idx, CCReg val) override 342 { 343 numCCRegWrites++; 344 const RegId& reg = si->destRegIdx(idx); 345 assert(reg.isCCReg()); 346 thread->setCCReg(reg.index(), val); 347 } 348 349 MiscReg readMiscRegOperand(const StaticInst *si, int idx) override 350 { 351 numIntRegReads++; 352 const RegId& reg = si->srcRegIdx(idx); 353 assert(reg.isMiscReg()); 354 return thread->readMiscReg(reg.index()); 355 } 356 357 void setMiscRegOperand(const StaticInst *si, int idx, 358 const MiscReg &val) override 359 { 360 numIntRegWrites++; 361 const RegId& reg = si->destRegIdx(idx); 362 assert(reg.isMiscReg()); 363 thread->setMiscReg(reg.index(), val); 364 } 365 366 /** 367 * Reads a miscellaneous register, handling any architectural 368 * side effects due to reading that register. 369 */ 370 MiscReg readMiscReg(int misc_reg) override 371 { 372 numIntRegReads++; 373 return thread->readMiscReg(misc_reg); 374 } 375 376 /** 377 * Sets a miscellaneous register, handling any architectural 378 * side effects due to writing that register. 379 */ 380 void setMiscReg(int misc_reg, const MiscReg &val) override 381 { 382 numIntRegWrites++; 383 thread->setMiscReg(misc_reg, val); 384 } 385 386 PCState pcState() const override 387 { 388 return thread->pcState(); 389 } 390 391 void pcState(const PCState &val) override 392 { 393 thread->pcState(val); 394 } 395 396 397 Fault readMem(Addr addr, uint8_t *data, unsigned int size, 398 Request::Flags flags) override 399 { 400 return cpu->readMem(addr, data, size, flags); 401 } 402 403 Fault initiateMemRead(Addr addr, unsigned int size, 404 Request::Flags flags) override 405 { 406 return cpu->initiateMemRead(addr, size, flags); 407 } 408 409 Fault writeMem(uint8_t *data, unsigned int size, Addr addr, 410 Request::Flags flags, uint64_t *res) override 411 { 412 return cpu->writeMem(data, size, addr, flags, res); 413 } 414 415 /** 416 * Sets the number of consecutive store conditional failures. 417 */ 418 void setStCondFailures(unsigned int sc_failures) override 419 { 420 thread->setStCondFailures(sc_failures); 421 } 422 423 /** 424 * Returns the number of consecutive store conditional failures. 425 */ 426 unsigned int readStCondFailures() const override 427 { 428 return thread->readStCondFailures(); 429 } 430 431 /** 432 * Executes a syscall specified by the callnum. 433 */ 434 void syscall(int64_t callnum, Fault *fault) override 435 { 436 if (FullSystem) 437 panic("Syscall emulation isn't available in FS mode."); 438 439 thread->syscall(callnum, fault); 440 } 441 442 /** Returns a pointer to the ThreadContext. */ 443 ThreadContext *tcBase() override 444 { 445 return thread->getTC(); 446 } 447 448 /** 449 * Somewhat Alpha-specific function that handles returning from an 450 * error or interrupt. 451 */ 452 Fault hwrei() override 453 { 454 return thread->hwrei(); 455 } 456 457 /** 458 * Check for special simulator handling of specific PAL calls. If 459 * return value is false, actual PAL call will be suppressed. 460 */ 461 bool simPalCheck(int palFunc) override 462 { 463 return thread->simPalCheck(palFunc); 464 } 465 466 bool readPredicate() const override 467 { 468 return thread->readPredicate(); 469 } 470 471 void setPredicate(bool val) override 472 { 473 thread->setPredicate(val); 474 475 if (cpu->traceData) { 476 cpu->traceData->setPredicate(val); 477 } 478 } 479 480 /** 481 * Invalidate a page in the DTLB <i>and</i> ITLB. 482 */ 483 void demapPage(Addr vaddr, uint64_t asn) override 484 { 485 thread->demapPage(vaddr, asn); 486 } 487 488 void armMonitor(Addr address) override 489 { 490 cpu->armMonitor(thread->threadId(), address); 491 } 492 493 bool mwait(PacketPtr pkt) override 494 { 495 return cpu->mwait(thread->threadId(), pkt); 496 } 497 498 void mwaitAtomic(ThreadContext *tc) override 499 { 500 cpu->mwaitAtomic(thread->threadId(), tc, thread->dtb); 501 } 502 503 AddressMonitor *getAddrMonitor() override 504 { 505 return cpu->getCpuAddrMonitor(thread->threadId()); 506 } 507 508#if THE_ISA == MIPS_ISA 509 MiscReg readRegOtherThread(const RegId& reg, 510 ThreadID tid = InvalidThreadID) 511 override 512 { 513 panic("Simple CPU models do not support multithreaded " 514 "register access."); 515 } 516 517 void setRegOtherThread(const RegId& reg, MiscReg val, 518 ThreadID tid = InvalidThreadID) override 519 { 520 panic("Simple CPU models do not support multithreaded " 521 "register access."); 522 } 523 524#endif 525 526}; 527 528#endif // __CPU_EXEC_CONTEXT_HH__ 529