exec_context.hh revision 14297
12817Sksewell@umich.edu/* 22817Sksewell@umich.edu * Copyright (c) 2014-2018 ARM Limited 32817Sksewell@umich.edu * All rights reserved 42817Sksewell@umich.edu * 52817Sksewell@umich.edu * The license below extends only to copyright in the software and shall 62817Sksewell@umich.edu * not be construed as granting a license to any other intellectual 72817Sksewell@umich.edu * property including but not limited to intellectual property relating 82817Sksewell@umich.edu * to a hardware implementation of the functionality of the software 92817Sksewell@umich.edu * licensed hereunder. You may use the software subject to the license 102817Sksewell@umich.edu * terms below provided that you ensure that this notice is replicated 112817Sksewell@umich.edu * unmodified and in its entirety in all distributions of the software, 122817Sksewell@umich.edu * modified or unmodified, in source code or in binary form. 132817Sksewell@umich.edu * 142817Sksewell@umich.edu * Copyright (c) 2002-2005 The Regents of The University of Michigan 152817Sksewell@umich.edu * All rights reserved. 162817Sksewell@umich.edu * 172817Sksewell@umich.edu * Redistribution and use in source and binary forms, with or without 182817Sksewell@umich.edu * modification, are permitted provided that the following conditions are 192817Sksewell@umich.edu * met: redistributions of source code must retain the above copyright 202817Sksewell@umich.edu * notice, this list of conditions and the following disclaimer; 212817Sksewell@umich.edu * redistributions in binary form must reproduce the above copyright 222817Sksewell@umich.edu * notice, this list of conditions and the following disclaimer in the 232817Sksewell@umich.edu * documentation and/or other materials provided with the distribution; 242817Sksewell@umich.edu * neither the name of the copyright holders nor the names of its 252817Sksewell@umich.edu * contributors may be used to endorse or promote products derived from 262817Sksewell@umich.edu * this software without specific prior written permission. 272817Sksewell@umich.edu * 282817Sksewell@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 294202Sbinkertn@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 302817Sksewell@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 312817Sksewell@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 322817Sksewell@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 334202Sbinkertn@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 342817Sksewell@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 355192Ssaidi@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 365192Ssaidi@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 375192Ssaidi@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 385192Ssaidi@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 395192Ssaidi@eecs.umich.edu * 405192Ssaidi@eecs.umich.edu * Authors: Kevin Lim 415192Ssaidi@eecs.umich.edu * Andreas Sandberg 425192Ssaidi@eecs.umich.edu * Mitch Hayenga 435192Ssaidi@eecs.umich.edu */ 445192Ssaidi@eecs.umich.edu 454202Sbinkertn@umich.edu#ifndef __CPU_SIMPLE_EXEC_CONTEXT_HH__ 464486Sbinkertn@umich.edu#define __CPU_SIMPLE_EXEC_CONTEXT_HH__ 474486Sbinkertn@umich.edu 484486Sbinkertn@umich.edu#include "arch/registers.hh" 494486Sbinkertn@umich.edu#include "base/types.hh" 504202Sbinkertn@umich.edu#include "config/the_isa.hh" 514202Sbinkertn@umich.edu#include "cpu/base.hh" 524202Sbinkertn@umich.edu#include "cpu/exec_context.hh" 534202Sbinkertn@umich.edu#include "cpu/reg_class.hh" 544202Sbinkertn@umich.edu#include "cpu/simple/base.hh" 554202Sbinkertn@umich.edu#include "cpu/static_inst_fwd.hh" 564202Sbinkertn@umich.edu#include "cpu/translation.hh" 574202Sbinkertn@umich.edu#include "mem/request.hh" 584202Sbinkertn@umich.edu 594202Sbinkertn@umich.educlass BaseSimpleCPU; 604202Sbinkertn@umich.edu 614202Sbinkertn@umich.educlass SimpleExecContext : public ExecContext { 624202Sbinkertn@umich.edu protected: 634202Sbinkertn@umich.edu using VecRegContainer = TheISA::VecRegContainer; 644202Sbinkertn@umich.edu using VecElem = TheISA::VecElem; 654202Sbinkertn@umich.edu 664202Sbinkertn@umich.edu public: 674202Sbinkertn@umich.edu BaseSimpleCPU *cpu; 682817Sksewell@umich.edu SimpleThread* thread; 695192Ssaidi@eecs.umich.edu 705192Ssaidi@eecs.umich.edu // This is the offset from the current pc that fetch should be performed 715192Ssaidi@eecs.umich.edu Addr fetchOffset; 725192Ssaidi@eecs.umich.edu // This flag says to stay at the current pc. This is useful for 735192Ssaidi@eecs.umich.edu // instructions which go beyond MachInst boundaries. 745192Ssaidi@eecs.umich.edu bool stayAtPC; 755192Ssaidi@eecs.umich.edu 765192Ssaidi@eecs.umich.edu // Branch prediction 775192Ssaidi@eecs.umich.edu TheISA::PCState predPC; 785192Ssaidi@eecs.umich.edu 795192Ssaidi@eecs.umich.edu /** PER-THREAD STATS */ 805192Ssaidi@eecs.umich.edu 815192Ssaidi@eecs.umich.edu // Number of simulated instructions 825192Ssaidi@eecs.umich.edu Counter numInst; 835192Ssaidi@eecs.umich.edu Stats::Scalar numInsts; 844202Sbinkertn@umich.edu Counter numOp; 854202Sbinkertn@umich.edu Stats::Scalar numOps; 864202Sbinkertn@umich.edu 874202Sbinkertn@umich.edu // Number of integer alu accesses 884202Sbinkertn@umich.edu Stats::Scalar numIntAluAccesses; 894202Sbinkertn@umich.edu 904202Sbinkertn@umich.edu // Number of float alu accesses 914202Sbinkertn@umich.edu Stats::Scalar numFpAluAccesses; 924202Sbinkertn@umich.edu 934202Sbinkertn@umich.edu // Number of vector alu accesses 944202Sbinkertn@umich.edu Stats::Scalar numVecAluAccesses; 954202Sbinkertn@umich.edu 964202Sbinkertn@umich.edu // Number of function calls/returns 974202Sbinkertn@umich.edu Stats::Scalar numCallsReturns; 984202Sbinkertn@umich.edu 994202Sbinkertn@umich.edu // Conditional control instructions; 1004202Sbinkertn@umich.edu Stats::Scalar numCondCtrlInsts; 1012817Sksewell@umich.edu 1024202Sbinkertn@umich.edu // Number of int instructions 1034497Sbinkertn@umich.edu Stats::Scalar numIntInsts; 1044202Sbinkertn@umich.edu 105 // Number of float instructions 106 Stats::Scalar numFpInsts; 107 108 // Number of vector instructions 109 Stats::Scalar numVecInsts; 110 111 // Number of integer register file accesses 112 Stats::Scalar numIntRegReads; 113 Stats::Scalar numIntRegWrites; 114 115 // Number of float register file accesses 116 Stats::Scalar numFpRegReads; 117 Stats::Scalar numFpRegWrites; 118 119 // Number of vector register file accesses 120 mutable Stats::Scalar numVecRegReads; 121 Stats::Scalar numVecRegWrites; 122 123 // Number of predicate register file accesses 124 mutable Stats::Scalar numVecPredRegReads; 125 Stats::Scalar numVecPredRegWrites; 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 RegVal 178 readIntRegOperand(const StaticInst *si, int idx) override 179 { 180 numIntRegReads++; 181 const RegId& reg = si->srcRegIdx(idx); 182 assert(reg.isIntReg()); 183 return thread->readIntReg(reg.index()); 184 } 185 186 /** Sets an integer register to a value. */ 187 void 188 setIntRegOperand(const StaticInst *si, int idx, RegVal val) override 189 { 190 numIntRegWrites++; 191 const RegId& reg = si->destRegIdx(idx); 192 assert(reg.isIntReg()); 193 thread->setIntReg(reg.index(), val); 194 } 195 196 /** Reads a floating point register in its binary format, instead 197 * of by value. */ 198 RegVal 199 readFloatRegOperandBits(const StaticInst *si, int idx) override 200 { 201 numFpRegReads++; 202 const RegId& reg = si->srcRegIdx(idx); 203 assert(reg.isFloatReg()); 204 return thread->readFloatReg(reg.index()); 205 } 206 207 /** Sets the bits of a floating point register of single width 208 * to a binary value. */ 209 void 210 setFloatRegOperandBits(const StaticInst *si, int idx, RegVal val) override 211 { 212 numFpRegWrites++; 213 const RegId& reg = si->destRegIdx(idx); 214 assert(reg.isFloatReg()); 215 thread->setFloatReg(reg.index(), val); 216 } 217 218 /** Reads a vector register. */ 219 const VecRegContainer & 220 readVecRegOperand(const StaticInst *si, int idx) const override 221 { 222 numVecRegReads++; 223 const RegId& reg = si->srcRegIdx(idx); 224 assert(reg.isVecReg()); 225 return thread->readVecReg(reg); 226 } 227 228 /** Reads a vector register for modification. */ 229 VecRegContainer & 230 getWritableVecRegOperand(const StaticInst *si, int idx) override 231 { 232 numVecRegWrites++; 233 const RegId& reg = si->destRegIdx(idx); 234 assert(reg.isVecReg()); 235 return thread->getWritableVecReg(reg); 236 } 237 238 /** Sets a vector register to a value. */ 239 void 240 setVecRegOperand(const StaticInst *si, int idx, 241 const VecRegContainer& val) override 242 { 243 numVecRegWrites++; 244 const RegId& reg = si->destRegIdx(idx); 245 assert(reg.isVecReg()); 246 thread->setVecReg(reg, val); 247 } 248 249 /** Vector Register Lane Interfaces. */ 250 /** @{ */ 251 /** Reads source vector lane. */ 252 template <typename VecElem> 253 VecLaneT<VecElem, true> 254 readVecLaneOperand(const StaticInst *si, int idx) const 255 { 256 numVecRegReads++; 257 const RegId& reg = si->srcRegIdx(idx); 258 assert(reg.isVecReg()); 259 return thread->readVecLane<VecElem>(reg); 260 } 261 /** Reads source vector 8bit operand. */ 262 virtual ConstVecLane8 263 readVec8BitLaneOperand(const StaticInst *si, int idx) const 264 override 265 { return readVecLaneOperand<uint8_t>(si, idx); } 266 267 /** Reads source vector 16bit operand. */ 268 virtual ConstVecLane16 269 readVec16BitLaneOperand(const StaticInst *si, int idx) const 270 override 271 { return readVecLaneOperand<uint16_t>(si, idx); } 272 273 /** Reads source vector 32bit operand. */ 274 virtual ConstVecLane32 275 readVec32BitLaneOperand(const StaticInst *si, int idx) const 276 override 277 { return readVecLaneOperand<uint32_t>(si, idx); } 278 279 /** Reads source vector 64bit operand. */ 280 virtual ConstVecLane64 281 readVec64BitLaneOperand(const StaticInst *si, int idx) const 282 override 283 { return readVecLaneOperand<uint64_t>(si, idx); } 284 285 /** Write a lane of the destination vector operand. */ 286 template <typename LD> 287 void 288 setVecLaneOperandT(const StaticInst *si, int idx, 289 const LD& val) 290 { 291 numVecRegWrites++; 292 const RegId& reg = si->destRegIdx(idx); 293 assert(reg.isVecReg()); 294 return thread->setVecLane(reg, val); 295 } 296 /** Write a lane of the destination vector operand. */ 297 virtual void 298 setVecLaneOperand(const StaticInst *si, int idx, 299 const LaneData<LaneSize::Byte>& val) override 300 { return setVecLaneOperandT(si, idx, val); } 301 /** Write a lane of the destination vector operand. */ 302 virtual void 303 setVecLaneOperand(const StaticInst *si, int idx, 304 const LaneData<LaneSize::TwoByte>& val) override 305 { return setVecLaneOperandT(si, idx, val); } 306 /** Write a lane of the destination vector operand. */ 307 virtual void 308 setVecLaneOperand(const StaticInst *si, int idx, 309 const LaneData<LaneSize::FourByte>& val) override 310 { return setVecLaneOperandT(si, idx, val); } 311 /** Write a lane of the destination vector operand. */ 312 virtual void 313 setVecLaneOperand(const StaticInst *si, int idx, 314 const LaneData<LaneSize::EightByte>& val) override 315 { return setVecLaneOperandT(si, idx, val); } 316 /** @} */ 317 318 /** Reads an element of a vector register. */ 319 VecElem 320 readVecElemOperand(const StaticInst *si, int idx) const override 321 { 322 numVecRegReads++; 323 const RegId& reg = si->srcRegIdx(idx); 324 assert(reg.isVecElem()); 325 return thread->readVecElem(reg); 326 } 327 328 /** Sets an element of a vector register to a value. */ 329 void 330 setVecElemOperand(const StaticInst *si, int idx, 331 const VecElem val) override 332 { 333 numVecRegWrites++; 334 const RegId& reg = si->destRegIdx(idx); 335 assert(reg.isVecElem()); 336 thread->setVecElem(reg, val); 337 } 338 339 const VecPredRegContainer& 340 readVecPredRegOperand(const StaticInst *si, int idx) const override 341 { 342 numVecPredRegReads++; 343 const RegId& reg = si->srcRegIdx(idx); 344 assert(reg.isVecPredReg()); 345 return thread->readVecPredReg(reg); 346 } 347 348 VecPredRegContainer& 349 getWritableVecPredRegOperand(const StaticInst *si, int idx) override 350 { 351 numVecPredRegWrites++; 352 const RegId& reg = si->destRegIdx(idx); 353 assert(reg.isVecPredReg()); 354 return thread->getWritableVecPredReg(reg); 355 } 356 357 void 358 setVecPredRegOperand(const StaticInst *si, int idx, 359 const VecPredRegContainer& val) override 360 { 361 numVecPredRegWrites++; 362 const RegId& reg = si->destRegIdx(idx); 363 assert(reg.isVecPredReg()); 364 thread->setVecPredReg(reg, val); 365 } 366 367 RegVal 368 readCCRegOperand(const StaticInst *si, int idx) override 369 { 370 numCCRegReads++; 371 const RegId& reg = si->srcRegIdx(idx); 372 assert(reg.isCCReg()); 373 return thread->readCCReg(reg.index()); 374 } 375 376 void 377 setCCRegOperand(const StaticInst *si, int idx, RegVal val) override 378 { 379 numCCRegWrites++; 380 const RegId& reg = si->destRegIdx(idx); 381 assert(reg.isCCReg()); 382 thread->setCCReg(reg.index(), val); 383 } 384 385 RegVal 386 readMiscRegOperand(const StaticInst *si, int idx) override 387 { 388 numIntRegReads++; 389 const RegId& reg = si->srcRegIdx(idx); 390 assert(reg.isMiscReg()); 391 return thread->readMiscReg(reg.index()); 392 } 393 394 void 395 setMiscRegOperand(const StaticInst *si, int idx, RegVal val) override 396 { 397 numIntRegWrites++; 398 const RegId& reg = si->destRegIdx(idx); 399 assert(reg.isMiscReg()); 400 thread->setMiscReg(reg.index(), val); 401 } 402 403 /** 404 * Reads a miscellaneous register, handling any architectural 405 * side effects due to reading that register. 406 */ 407 RegVal 408 readMiscReg(int misc_reg) override 409 { 410 numIntRegReads++; 411 return thread->readMiscReg(misc_reg); 412 } 413 414 /** 415 * Sets a miscellaneous register, handling any architectural 416 * side effects due to writing that register. 417 */ 418 void 419 setMiscReg(int misc_reg, RegVal val) override 420 { 421 numIntRegWrites++; 422 thread->setMiscReg(misc_reg, val); 423 } 424 425 PCState 426 pcState() const override 427 { 428 return thread->pcState(); 429 } 430 431 void 432 pcState(const PCState &val) override 433 { 434 thread->pcState(val); 435 } 436 437 Fault 438 readMem(Addr addr, uint8_t *data, unsigned int size, 439 Request::Flags flags, 440 const std::vector<bool>& byteEnable = std::vector<bool>()) 441 override 442 { 443 return cpu->readMem(addr, data, size, flags, byteEnable); 444 } 445 446 Fault 447 initiateMemRead(Addr addr, unsigned int size, 448 Request::Flags flags, 449 const std::vector<bool>& byteEnable = std::vector<bool>()) 450 override 451 { 452 return cpu->initiateMemRead(addr, size, flags, byteEnable); 453 } 454 455 Fault 456 writeMem(uint8_t *data, unsigned int size, Addr addr, 457 Request::Flags flags, uint64_t *res, 458 const std::vector<bool>& byteEnable = std::vector<bool>()) 459 override 460 { 461 assert(byteEnable.empty() || byteEnable.size() == size); 462 return cpu->writeMem(data, size, addr, flags, res, byteEnable); 463 } 464 465 Fault amoMem(Addr addr, uint8_t *data, unsigned int size, 466 Request::Flags flags, AtomicOpFunctorPtr amo_op) override 467 { 468 return cpu->amoMem(addr, data, size, flags, std::move(amo_op)); 469 } 470 471 Fault initiateMemAMO(Addr addr, unsigned int size, 472 Request::Flags flags, 473 AtomicOpFunctorPtr amo_op) override 474 { 475 return cpu->initiateMemAMO(addr, size, flags, std::move(amo_op)); 476 } 477 478 /** 479 * Sets the number of consecutive store conditional failures. 480 */ 481 void 482 setStCondFailures(unsigned int sc_failures) override 483 { 484 thread->setStCondFailures(sc_failures); 485 } 486 487 /** 488 * Returns the number of consecutive store conditional failures. 489 */ 490 unsigned int 491 readStCondFailures() const override 492 { 493 return thread->readStCondFailures(); 494 } 495 496 /** 497 * Executes a syscall specified by the callnum. 498 */ 499 void 500 syscall(int64_t callnum, Fault *fault) override 501 { 502 if (FullSystem) 503 panic("Syscall emulation isn't available in FS mode."); 504 505 thread->syscall(callnum, fault); 506 } 507 508 /** Returns a pointer to the ThreadContext. */ 509 ThreadContext *tcBase() override { return thread->getTC(); } 510 511 bool 512 readPredicate() const override 513 { 514 return thread->readPredicate(); 515 } 516 517 void 518 setPredicate(bool val) override 519 { 520 thread->setPredicate(val); 521 522 if (cpu->traceData) { 523 cpu->traceData->setPredicate(val); 524 } 525 } 526 527 bool 528 readMemAccPredicate() const override 529 { 530 return thread->readMemAccPredicate(); 531 } 532 533 void 534 setMemAccPredicate(bool val) override 535 { 536 thread->setMemAccPredicate(val); 537 } 538 539 /** 540 * Invalidate a page in the DTLB <i>and</i> ITLB. 541 */ 542 void 543 demapPage(Addr vaddr, uint64_t asn) override 544 { 545 thread->demapPage(vaddr, asn); 546 } 547 548 void 549 armMonitor(Addr address) override 550 { 551 cpu->armMonitor(thread->threadId(), address); 552 } 553 554 bool 555 mwait(PacketPtr pkt) override 556 { 557 return cpu->mwait(thread->threadId(), pkt); 558 } 559 560 void 561 mwaitAtomic(ThreadContext *tc) override 562 { 563 cpu->mwaitAtomic(thread->threadId(), tc, thread->dtb); 564 } 565 566 AddressMonitor * 567 getAddrMonitor() override 568 { 569 return cpu->getCpuAddrMonitor(thread->threadId()); 570 } 571}; 572 573#endif // __CPU_EXEC_CONTEXT_HH__ 574