exec_context.hh revision 13611
12SN/A/* 210292SAndreas.Sandberg@ARM.com * Copyright (c) 2014-2017 ARM Limited 310292SAndreas.Sandberg@ARM.com * All rights reserved 410292SAndreas.Sandberg@ARM.com * 510292SAndreas.Sandberg@ARM.com * The license below extends only to copyright in the software and shall 610292SAndreas.Sandberg@ARM.com * not be construed as granting a license to any other intellectual 710292SAndreas.Sandberg@ARM.com * property including but not limited to intellectual property relating 810292SAndreas.Sandberg@ARM.com * to a hardware implementation of the functionality of the software 910292SAndreas.Sandberg@ARM.com * licensed hereunder. You may use the software subject to the license 1010292SAndreas.Sandberg@ARM.com * terms below provided that you ensure that this notice is replicated 1110292SAndreas.Sandberg@ARM.com * unmodified and in its entirety in all distributions of the software, 1210292SAndreas.Sandberg@ARM.com * modified or unmodified, in source code or in binary form. 1310292SAndreas.Sandberg@ARM.com * 144039Sbinkertn@umich.edu * Copyright (c) 2002-2005 The Regents of The University of Michigan 152SN/A * All rights reserved. 162SN/A * 172SN/A * Redistribution and use in source and binary forms, with or without 182SN/A * modification, are permitted provided that the following conditions are 192SN/A * met: redistributions of source code must retain the above copyright 202SN/A * notice, this list of conditions and the following disclaimer; 212SN/A * redistributions in binary form must reproduce the above copyright 222SN/A * notice, this list of conditions and the following disclaimer in the 232SN/A * documentation and/or other materials provided with the distribution; 242SN/A * neither the name of the copyright holders nor the names of its 252SN/A * contributors may be used to endorse or promote products derived from 262SN/A * this software without specific prior written permission. 272SN/A * 282SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 292SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 302SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 312SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 322SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 332SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 342SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 352SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 362SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 372SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 382SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 392665Ssaidi@eecs.umich.edu * 402665Ssaidi@eecs.umich.edu * Authors: Kevin Lim 412665Ssaidi@eecs.umich.edu * Andreas Sandberg 422SN/A * Mitch Hayenga 432SN/A */ 441354SN/A 451354SN/A#ifndef __CPU_SIMPLE_EXEC_CONTEXT_HH__ 462SN/A#define __CPU_SIMPLE_EXEC_CONTEXT_HH__ 474046Sbinkertn@umich.edu 482SN/A#include "arch/registers.hh" 4956SN/A#include "base/types.hh" 508232Snate@binkert.org#include "config/the_isa.hh" 511031SN/A#include "cpu/base.hh" 526214Snate@binkert.org#include "cpu/exec_context.hh" 534167Sbinkertn@umich.edu#include "cpu/reg_class.hh" 542SN/A#include "cpu/simple/base.hh" 552SN/A#include "cpu/static_inst_fwd.hh" 562SN/A#include "cpu/translation.hh" 578232Snate@binkert.org#include "mem/request.hh" 588232Snate@binkert.org 598232Snate@binkert.orgclass BaseSimpleCPU; 604046Sbinkertn@umich.edu 614046Sbinkertn@umich.educlass SimpleExecContext : public ExecContext { 622SN/A protected: 634046Sbinkertn@umich.edu typedef TheISA::CCReg CCReg; 644046Sbinkertn@umich.edu using VecRegContainer = TheISA::VecRegContainer; 654046Sbinkertn@umich.edu using VecElem = TheISA::VecElem; 662SN/A 674046Sbinkertn@umich.edu public: 684046Sbinkertn@umich.edu BaseSimpleCPU *cpu; 692SN/A SimpleThread* thread; 7010292SAndreas.Sandberg@ARM.com 7110292SAndreas.Sandberg@ARM.com // This is the offset from the current pc that fetch should be performed 7210292SAndreas.Sandberg@ARM.com Addr fetchOffset; 7310292SAndreas.Sandberg@ARM.com // This flag says to stay at the current pc. This is useful for 7410292SAndreas.Sandberg@ARM.com // instructions which go beyond MachInst boundaries. 7510292SAndreas.Sandberg@ARM.com bool stayAtPC; 7610292SAndreas.Sandberg@ARM.com 7710292SAndreas.Sandberg@ARM.com // Branch prediction 7810292SAndreas.Sandberg@ARM.com TheISA::PCState predPC; 7910292SAndreas.Sandberg@ARM.com 8010292SAndreas.Sandberg@ARM.com /** PER-THREAD STATS */ 8110292SAndreas.Sandberg@ARM.com 8210292SAndreas.Sandberg@ARM.com // Number of simulated instructions 8310292SAndreas.Sandberg@ARM.com Counter numInst; 844046Sbinkertn@umich.edu Stats::Scalar numInsts; 852SN/A Counter numOp; 867811Ssteve.reinhardt@amd.com Stats::Scalar numOps; 874039Sbinkertn@umich.edu 881070SN/A // Number of integer alu accesses 891070SN/A Stats::Scalar numIntAluAccesses; 901070SN/A 911070SN/A // Number of float alu accesses 921070SN/A Stats::Scalar numFpAluAccesses; 931070SN/A 941070SN/A // Number of vector alu accesses 951070SN/A Stats::Scalar numVecAluAccesses; 961070SN/A 972SN/A // Number of function calls/returns 982SN/A Stats::Scalar numCallsReturns; 9910259SAndrew.Bardsley@arm.com 10010259SAndrew.Bardsley@arm.com // Conditional control instructions; 10110259SAndrew.Bardsley@arm.com Stats::Scalar numCondCtrlInsts; 10210259SAndrew.Bardsley@arm.com 10310259SAndrew.Bardsley@arm.com // Number of int instructions 10410259SAndrew.Bardsley@arm.com Stats::Scalar numIntInsts; 10510259SAndrew.Bardsley@arm.com 10610259SAndrew.Bardsley@arm.com // Number of float instructions 10710259SAndrew.Bardsley@arm.com Stats::Scalar numFpInsts; 10810259SAndrew.Bardsley@arm.com 10910259SAndrew.Bardsley@arm.com // Number of vector instructions 11010259SAndrew.Bardsley@arm.com Stats::Scalar numVecInsts; 11110259SAndrew.Bardsley@arm.com 11210259SAndrew.Bardsley@arm.com // Number of integer register file accesses 1132SN/A Stats::Scalar numIntRegReads; 1142SN/A Stats::Scalar numIntRegWrites; 1152SN/A 1162SN/A // Number of float register file accesses 1172SN/A Stats::Scalar numFpRegReads; 1182SN/A Stats::Scalar numFpRegWrites; 1192SN/A 1202SN/A // Number of vector register file accesses 1212SN/A mutable Stats::Scalar numVecRegReads; 1222SN/A Stats::Scalar numVecRegWrites; 1232SN/A 1242SN/A // Number of predicate register file accesses 1258232Snate@binkert.org mutable Stats::Scalar numVecPredRegReads; 1262SN/A Stats::Scalar numVecPredRegWrites; 1274041Sbinkertn@umich.edu 1288232Snate@binkert.org // Number of condition code register file accesses 1294041Sbinkertn@umich.edu Stats::Scalar numCCRegReads; 1307823Ssteve.reinhardt@amd.com Stats::Scalar numCCRegWrites; 1312SN/A 1322SN/A // Number of simulated memory references 1334041Sbinkertn@umich.edu Stats::Scalar numMemRefs; 1348232Snate@binkert.org Stats::Scalar numLoadInsts; 1354041Sbinkertn@umich.edu Stats::Scalar numStoreInsts; 1367823Ssteve.reinhardt@amd.com 1372SN/A // Number of idle cycles 1382SN/A Stats::Formula numIdleCycles; 1398232Snate@binkert.org 1408232Snate@binkert.org // Number of busy cycles 1415806Ssaidi@eecs.umich.edu Stats::Formula numBusyCycles; 1428232Snate@binkert.org 1435806Ssaidi@eecs.umich.edu // Number of simulated loads 1445806Ssaidi@eecs.umich.edu Counter numLoad; 1454041Sbinkertn@umich.edu 1468232Snate@binkert.org // Number of idle cycles 1474041Sbinkertn@umich.edu Stats::Average notIdleFraction; 1484041Sbinkertn@umich.edu Stats::Formula idleFraction; 1492SN/A 1502SN/A // Number of cycles stalled for I-cache responses 1514046Sbinkertn@umich.edu Stats::Scalar icacheStallCycles; 1527823Ssteve.reinhardt@amd.com Counter lastIcacheStall; 1534046Sbinkertn@umich.edu 1544046Sbinkertn@umich.edu // Number of cycles stalled for D-cache responses 1554041Sbinkertn@umich.edu Stats::Scalar dcacheStallCycles; 1567823Ssteve.reinhardt@amd.com Counter lastDcacheStall; 1572SN/A 1582SN/A /// @{ 1594041Sbinkertn@umich.edu /// Total number of branches fetched 1604041Sbinkertn@umich.edu Stats::Scalar numBranches; 161507SN/A /// Number of branches predicted as taken 162507SN/A Stats::Scalar numPredictedBranches; 1632SN/A /// Number of misprediced branches 1642SN/A Stats::Scalar numBranchMispred; 1652SN/A /// @} 1664046Sbinkertn@umich.edu 1674041Sbinkertn@umich.edu // Instruction mix histogram by OpClass 1685806Ssaidi@eecs.umich.edu Stats::Vector statExecutedInstType; 1694041Sbinkertn@umich.edu 1704046Sbinkertn@umich.edu public: 1714041Sbinkertn@umich.edu /** Constructor */ 1724041Sbinkertn@umich.edu SimpleExecContext(BaseSimpleCPU* _cpu, SimpleThread* _thread) 1732SN/A : cpu(_cpu), thread(_thread), fetchOffset(0), stayAtPC(false), 1745543Ssaidi@eecs.umich.edu numInst(0), numOp(0), numLoad(0), lastIcacheStall(0), lastDcacheStall(0) 1752SN/A { } 1761354SN/A 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->readFloatReg(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->setFloatReg(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