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