1/* 2 * Copyright (c) 2011-2012, 2016-2018 ARM Limited 3 * Copyright (c) 2013 Advanced Micro Devices, Inc. 4 * All rights reserved 5 * 6 * The license below extends only to copyright in the software and shall 7 * not be construed as granting a license to any other intellectual 8 * property including but not limited to intellectual property relating --- 69 unchanged lines hidden (view full) --- 78 namespace Kernel { 79 class Statistics; 80 } 81} 82 83/** 84 * The SimpleThread object provides a combination of the ThreadState 85 * object and the ThreadContext interface. It implements the |
86 * ThreadContext interface and adds to the ThreadState object by adding all |
87 * the objects needed for simple functional execution, including a 88 * simple architectural register file, and pointers to the ITB and DTB 89 * in full system mode. For CPU models that do not need more advanced 90 * ways to hold state (i.e. a separate physical register file, or 91 * separate fetch and commit PC's), this SimpleThread class provides 92 * all the necessary state for full architecture-level functional 93 * simulation. See the AtomicSimpleCPU or TimingSimpleCPU for 94 * examples. 95 */ 96 |
97class SimpleThread : public ThreadState, public ThreadContext |
98{ 99 protected: 100 typedef TheISA::MachInst MachInst; 101 using VecRegContainer = TheISA::VecRegContainer; 102 using VecElem = TheISA::VecElem; 103 using VecPredRegContainer = TheISA::VecPredRegContainer; 104 public: 105 typedef ThreadContext::Status Status; --- 11 unchanged lines hidden (view full) --- 117 TheISA::PCState _pcState; 118 119 /** Did this instruction execute or is it predicated false */ 120 bool predicate; 121 122 public: 123 std::string name() const 124 { |
125 return csprintf("%s.[tid:%i]", baseCpu->name(), threadId()); |
126 } 127 |
128 System *system; 129 130 BaseTLB *itb; 131 BaseTLB *dtb; 132 133 TheISA::Decoder decoder; 134 135 // constructor: initialize SimpleThread from given process structure 136 // FS 137 SimpleThread(BaseCPU *_cpu, int _thread_num, System *_system, 138 BaseTLB *_itb, BaseTLB *_dtb, TheISA::ISA *_isa, 139 bool use_kernel_stats = true); 140 // SE 141 SimpleThread(BaseCPU *_cpu, int _thread_num, System *_system, 142 Process *_process, BaseTLB *_itb, BaseTLB *_dtb, 143 TheISA::ISA *_isa); 144 |
145 virtual ~SimpleThread() {} |
146 |
147 void takeOverFrom(ThreadContext *oldContext) override; |
148 |
149 void regStats(const std::string &name) override; |
150 151 void copyState(ThreadContext *oldContext); 152 153 void serialize(CheckpointOut &cp) const override; 154 void unserialize(CheckpointIn &cp) override; 155 void startup(); 156 157 /*************************************************************** 158 * SimpleThread functions to provide CPU with access to various 159 * state. 160 **************************************************************/ 161 162 /** Returns the pointer to this SimpleThread's ThreadContext. Used 163 * when a ThreadContext must be passed to objects outside of the 164 * CPU. 165 */ |
166 ThreadContext *getTC() { return this; } |
167 168 void demapPage(Addr vaddr, uint64_t asn) 169 { 170 itb->demapPage(vaddr, asn); 171 dtb->demapPage(vaddr, asn); 172 } 173 174 void demapInstPage(Addr vaddr, uint64_t asn) 175 { 176 itb->demapPage(vaddr, asn); 177 } 178 179 void demapDataPage(Addr vaddr, uint64_t asn) 180 { 181 dtb->demapPage(vaddr, asn); 182 } 183 |
184 void dumpFuncProfile() override; |
185 186 Fault hwrei(); 187 188 bool simPalCheck(int palFunc); 189 190 /******************************************* 191 * ThreadContext interface functions. 192 ******************************************/ 193 |
194 BaseCPU *getCpuPtr() override { return baseCpu; } |
195 |
196 int cpuId() const override { return ThreadState::cpuId(); } 197 uint32_t socketId() const override { return ThreadState::socketId(); } 198 int threadId() const override { return ThreadState::threadId(); } 199 void setThreadId(int id) override { ThreadState::setThreadId(id); } 200 ContextID contextId() const override { return ThreadState::contextId(); } 201 void setContextId(ContextID id) override { ThreadState::setContextId(id); } |
202 |
203 BaseTLB *getITBPtr() override { return itb; } |
204 |
205 BaseTLB *getDTBPtr() override { return dtb; } |
206 |
207 CheckerCPU *getCheckerCpuPtr() override { return NULL; } |
208 |
209 TheISA::ISA *getIsaPtr() override { return isa; } |
210 |
211 TheISA::Decoder *getDecoderPtr() override { return &decoder; } |
212 |
213 System *getSystemPtr() override { return system; } |
214 |
215 TheISA::Kernel::Statistics * 216 getKernelStats() 217 { 218 return ThreadState::getKernelStats(); 219 } |
220 |
221 PortProxy &getPhysProxy() { return ThreadState::getPhysProxy(); } 222 FSTranslatingPortProxy & 223 getVirtProxy() 224 { 225 return ThreadState::getVirtProxy(); 226 } 227 228 void initMemProxies(ThreadContext *tc) { ThreadState::initMemProxies(tc); } 229 SETranslatingPortProxy & 230 getMemProxy() 231 { 232 return ThreadState::getMemProxy(); 233 } 234 235 Process *getProcessPtr() { return ThreadState::getProcessPtr(); } 236 void setProcessPtr(Process *p) override { ThreadState::setProcessPtr(p); } 237 238 Status status() const override { return _status; } 239 240 void setStatus(Status newStatus) override { _status = newStatus; } 241 |
242 /// Set the status to Active. |
243 void activate() override; |
244 245 /// Set the status to Suspended. |
246 void suspend() override; |
247 248 /// Set the status to Halted. |
249 void halt() override; |
250 |
251 EndQuiesceEvent * 252 getQuiesceEvent() override 253 { 254 return ThreadState::getQuiesceEvent(); 255 } |
256 |
257 Tick 258 readLastActivate() override |
259 { |
260 return ThreadState::readLastActivate(); 261 } 262 Tick 263 readLastSuspend() override 264 { 265 return ThreadState::readLastSuspend(); 266 } 267 268 void profileClear() override { ThreadState::profileClear(); } 269 void profileSample() override { ThreadState::profileSample(); } 270 271 void copyArchRegs(ThreadContext *tc) override; 272 273 void clearArchRegs() override 274 { |
275 _pcState = 0; 276 memset(intRegs, 0, sizeof(intRegs)); 277 memset(floatRegs, 0, sizeof(floatRegs)); 278 for (int i = 0; i < TheISA::NumVecRegs; i++) { 279 vecRegs[i].zero(); 280 } 281 for (int i = 0; i < TheISA::NumVecPredRegs; i++) { 282 vecPredRegs[i].reset(); 283 } 284#ifdef ISA_HAS_CC_REGS 285 memset(ccRegs, 0, sizeof(ccRegs)); 286#endif 287 isa->clear(); 288 } 289 290 // 291 // New accessors for new decoder. 292 // 293 RegVal |
294 readIntReg(RegIndex reg_idx) const override |
295 { 296 int flatIndex = isa->flattenIntIndex(reg_idx); 297 assert(flatIndex < TheISA::NumIntRegs); 298 uint64_t regVal(readIntRegFlat(flatIndex)); 299 DPRINTF(IntRegs, "Reading int reg %d (%d) as %#x.\n", 300 reg_idx, flatIndex, regVal); 301 return regVal; 302 } 303 304 RegVal |
305 readFloatReg(RegIndex reg_idx) const override |
306 { 307 int flatIndex = isa->flattenFloatIndex(reg_idx); 308 assert(flatIndex < TheISA::NumFloatRegs); 309 RegVal regVal(readFloatRegFlat(flatIndex)); 310 DPRINTF(FloatRegs, "Reading float reg %d (%d) bits as %#x.\n", 311 reg_idx, flatIndex, regVal); 312 return regVal; 313 } 314 315 const VecRegContainer& |
316 readVecReg(const RegId& reg) const override |
317 { 318 int flatIndex = isa->flattenVecIndex(reg.index()); 319 assert(flatIndex < TheISA::NumVecRegs); 320 const VecRegContainer& regVal = readVecRegFlat(flatIndex); 321 DPRINTF(VecRegs, "Reading vector reg %d (%d) as %s.\n", 322 reg.index(), flatIndex, regVal.print()); 323 return regVal; 324 } 325 326 VecRegContainer& |
327 getWritableVecReg(const RegId& reg) override |
328 { 329 int flatIndex = isa->flattenVecIndex(reg.index()); 330 assert(flatIndex < TheISA::NumVecRegs); 331 VecRegContainer& regVal = getWritableVecRegFlat(flatIndex); 332 DPRINTF(VecRegs, "Reading vector reg %d (%d) as %s for modify.\n", 333 reg.index(), flatIndex, regVal.print()); 334 return regVal; 335 } --- 10 unchanged lines hidden (view full) --- 346 auto regVal = readVecLaneFlat<T>(flatIndex, reg.elemIndex()); 347 DPRINTF(VecRegs, "Reading vector lane %d (%d)[%d] as %lx.\n", 348 reg.index(), flatIndex, reg.elemIndex(), regVal); 349 return regVal; 350 } 351 352 /** Reads source vector 8bit operand. */ 353 virtual ConstVecLane8 |
354 readVec8BitLaneReg(const RegId ®) const override 355 { 356 return readVecLane<uint8_t>(reg); 357 } |
358 359 /** Reads source vector 16bit operand. */ 360 virtual ConstVecLane16 |
361 readVec16BitLaneReg(const RegId ®) const override 362 { 363 return readVecLane<uint16_t>(reg); 364 } |
365 366 /** Reads source vector 32bit operand. */ 367 virtual ConstVecLane32 |
368 readVec32BitLaneReg(const RegId ®) const override 369 { 370 return readVecLane<uint32_t>(reg); 371 } |
372 373 /** Reads source vector 64bit operand. */ 374 virtual ConstVecLane64 |
375 readVec64BitLaneReg(const RegId ®) const override 376 { 377 return readVecLane<uint64_t>(reg); 378 } |
379 380 /** Write a lane of the destination vector register. */ 381 template <typename LD> |
382 void 383 setVecLaneT(const RegId ®, const LD &val) |
384 { 385 int flatIndex = isa->flattenVecIndex(reg.index()); 386 assert(flatIndex < TheISA::NumVecRegs); 387 setVecLaneFlat(flatIndex, reg.elemIndex(), val); 388 DPRINTF(VecRegs, "Reading vector lane %d (%d)[%d] to %lx.\n", 389 reg.index(), flatIndex, reg.elemIndex(), val); 390 } |
391 virtual void 392 setVecLane(const RegId ®, const LaneData<LaneSize::Byte> &val) override 393 { 394 return setVecLaneT(reg, val); 395 } 396 virtual void 397 setVecLane(const RegId ®, 398 const LaneData<LaneSize::TwoByte> &val) override 399 { 400 return setVecLaneT(reg, val); 401 } 402 virtual void 403 setVecLane(const RegId ®, 404 const LaneData<LaneSize::FourByte> &val) override 405 { 406 return setVecLaneT(reg, val); 407 } 408 virtual void 409 setVecLane(const RegId ®, 410 const LaneData<LaneSize::EightByte> &val) override 411 { 412 return setVecLaneT(reg, val); 413 } |
414 /** @} */ 415 |
416 const VecElem & 417 readVecElem(const RegId ®) const override |
418 { 419 int flatIndex = isa->flattenVecElemIndex(reg.index()); 420 assert(flatIndex < TheISA::NumVecRegs); 421 const VecElem& regVal = readVecElemFlat(flatIndex, reg.elemIndex()); 422 DPRINTF(VecRegs, "Reading element %d of vector reg %d (%d) as" 423 " %#x.\n", reg.elemIndex(), reg.index(), flatIndex, regVal); 424 return regVal; 425 } 426 |
427 const VecPredRegContainer & 428 readVecPredReg(const RegId ®) const override |
429 { 430 int flatIndex = isa->flattenVecPredIndex(reg.index()); 431 assert(flatIndex < TheISA::NumVecPredRegs); 432 const VecPredRegContainer& regVal = readVecPredRegFlat(flatIndex); 433 DPRINTF(VecPredRegs, "Reading predicate reg %d (%d) as %s.\n", 434 reg.index(), flatIndex, regVal.print()); 435 return regVal; 436 } 437 |
438 VecPredRegContainer & 439 getWritableVecPredReg(const RegId ®) override |
440 { 441 int flatIndex = isa->flattenVecPredIndex(reg.index()); 442 assert(flatIndex < TheISA::NumVecPredRegs); 443 VecPredRegContainer& regVal = getWritableVecPredRegFlat(flatIndex); 444 DPRINTF(VecPredRegs, 445 "Reading predicate reg %d (%d) as %s for modify.\n", 446 reg.index(), flatIndex, regVal.print()); 447 return regVal; 448 } 449 450 RegVal |
451 readCCReg(RegIndex reg_idx) const override |
452 { 453#ifdef ISA_HAS_CC_REGS 454 int flatIndex = isa->flattenCCIndex(reg_idx); 455 assert(0 <= flatIndex); 456 assert(flatIndex < TheISA::NumCCRegs); 457 uint64_t regVal(readCCRegFlat(flatIndex)); 458 DPRINTF(CCRegs, "Reading CC reg %d (%d) as %#x.\n", 459 reg_idx, flatIndex, regVal); 460 return regVal; 461#else 462 panic("Tried to read a CC register."); 463 return 0; 464#endif 465 } 466 467 void |
468 setIntReg(RegIndex reg_idx, RegVal val) override |
469 { 470 int flatIndex = isa->flattenIntIndex(reg_idx); 471 assert(flatIndex < TheISA::NumIntRegs); 472 DPRINTF(IntRegs, "Setting int reg %d (%d) to %#x.\n", 473 reg_idx, flatIndex, val); 474 setIntRegFlat(flatIndex, val); 475 } 476 477 void |
478 setFloatReg(RegIndex reg_idx, RegVal val) override |
479 { 480 int flatIndex = isa->flattenFloatIndex(reg_idx); 481 assert(flatIndex < TheISA::NumFloatRegs); 482 // XXX: Fix array out of bounds compiler error for gem5.fast 483 // when checkercpu enabled 484 if (flatIndex < TheISA::NumFloatRegs) 485 setFloatRegFlat(flatIndex, val); 486 DPRINTF(FloatRegs, "Setting float reg %d (%d) bits to %#x.\n", 487 reg_idx, flatIndex, val); 488 } 489 490 void |
491 setVecReg(const RegId ®, const VecRegContainer &val) override |
492 { 493 int flatIndex = isa->flattenVecIndex(reg.index()); 494 assert(flatIndex < TheISA::NumVecRegs); 495 setVecRegFlat(flatIndex, val); 496 DPRINTF(VecRegs, "Setting vector reg %d (%d) to %s.\n", 497 reg.index(), flatIndex, val.print()); 498 } 499 500 void |
501 setVecElem(const RegId ®, const VecElem &val) override |
502 { 503 int flatIndex = isa->flattenVecElemIndex(reg.index()); 504 assert(flatIndex < TheISA::NumVecRegs); 505 setVecElemFlat(flatIndex, reg.elemIndex(), val); 506 DPRINTF(VecRegs, "Setting element %d of vector reg %d (%d) to" 507 " %#x.\n", reg.elemIndex(), reg.index(), flatIndex, val); 508 } 509 510 void |
511 setVecPredReg(const RegId ®, const VecPredRegContainer &val) override |
512 { 513 int flatIndex = isa->flattenVecPredIndex(reg.index()); 514 assert(flatIndex < TheISA::NumVecPredRegs); 515 setVecPredRegFlat(flatIndex, val); 516 DPRINTF(VecPredRegs, "Setting predicate reg %d (%d) to %s.\n", 517 reg.index(), flatIndex, val.print()); 518 } 519 520 void |
521 setCCReg(RegIndex reg_idx, RegVal val) override |
522 { 523#ifdef ISA_HAS_CC_REGS 524 int flatIndex = isa->flattenCCIndex(reg_idx); 525 assert(flatIndex < TheISA::NumCCRegs); 526 DPRINTF(CCRegs, "Setting CC reg %d (%d) to %#x.\n", 527 reg_idx, flatIndex, val); 528 setCCRegFlat(flatIndex, val); 529#else 530 panic("Tried to set a CC register."); 531#endif 532 } 533 |
534 TheISA::PCState pcState() const override { return _pcState; } 535 void pcState(const TheISA::PCState &val) override { _pcState = val; } |
536 537 void |
538 pcStateNoRecord(const TheISA::PCState &val) override |
539 { 540 _pcState = val; 541 } 542 |
543 Addr instAddr() const override { return _pcState.instAddr(); } 544 Addr nextInstAddr() const override { return _pcState.nextInstAddr(); } 545 MicroPC microPC() const override { return _pcState.microPC(); } 546 bool readPredicate() const { return predicate; } 547 void setPredicate(bool val) { predicate = val; } |
548 |
549 RegVal 550 readMiscRegNoEffect(RegIndex misc_reg) const override |
551 { |
552 return isa->readMiscRegNoEffect(misc_reg); |
553 } 554 |
555 RegVal 556 readMiscReg(RegIndex misc_reg) override |
557 { |
558 return isa->readMiscReg(misc_reg, this); |
559 } 560 561 void |
562 setMiscRegNoEffect(RegIndex misc_reg, RegVal val) override |
563 { |
564 return isa->setMiscRegNoEffect(misc_reg, val); |
565 } 566 |
567 void 568 setMiscReg(RegIndex misc_reg, RegVal val) override |
569 { |
570 return isa->setMiscReg(misc_reg, val, this); |
571 } 572 |
573 RegId 574 flattenRegId(const RegId& regId) const override |
575 { |
576 return isa->flattenRegId(regId); |
577 } 578 |
579 unsigned readStCondFailures() const override { return storeCondFailures; } |
580 |
581 void 582 setStCondFailures(unsigned sc_failures) override |
583 { |
584 storeCondFailures = sc_failures; |
585 } 586 |
587 Counter 588 readFuncExeInst() const override |
589 { |
590 return ThreadState::readFuncExeInst(); |
591 } 592 593 void |
594 syscall(int64_t callnum, Fault *fault) override |
595 { |
596 process->syscall(callnum, this, fault); |
597 } 598 |
599 RegVal readIntRegFlat(RegIndex idx) const override { return intRegs[idx]; } |
600 void |
601 setIntRegFlat(RegIndex idx, RegVal val) override |
602 { |
603 intRegs[idx] = val; |
604 } 605 |
606 RegVal 607 readFloatRegFlat(RegIndex idx) const override |
608 { |
609 return floatRegs[idx]; |
610 } |
611 void |
612 setFloatRegFlat(RegIndex idx, RegVal val) override |
613 { |
614 floatRegs[idx] = val; |
615 } 616 |
617 const VecRegContainer & |
618 readVecRegFlat(RegIndex reg) const override |
619 { 620 return vecRegs[reg]; 621 } 622 623 VecRegContainer & |
624 getWritableVecRegFlat(RegIndex reg) override |
625 { 626 return vecRegs[reg]; 627 } 628 629 void |
630 setVecRegFlat(RegIndex reg, const VecRegContainer &val) override |
631 { 632 vecRegs[reg] = val; 633 } 634 635 template <typename T> 636 VecLaneT<T, true> |
637 readVecLaneFlat(RegIndex reg, int lId) const |
638 { 639 return vecRegs[reg].laneView<T>(lId); 640 } 641 642 template <typename LD> 643 void |
644 setVecLaneFlat(RegIndex reg, int lId, const LD &val) |
645 { 646 vecRegs[reg].laneView<typename LD::UnderlyingType>(lId) = val; 647 } 648 649 const VecElem & |
650 readVecElemFlat(RegIndex reg, const ElemIndex &elemIndex) const override |
651 { 652 return vecRegs[reg].as<TheISA::VecElem>()[elemIndex]; 653 } 654 655 void |
656 setVecElemFlat(RegIndex reg, const ElemIndex &elemIndex, 657 const VecElem &val) override |
658 { 659 vecRegs[reg].as<TheISA::VecElem>()[elemIndex] = val; 660 } 661 |
662 const VecPredRegContainer & 663 readVecPredRegFlat(RegIndex reg) const override |
664 { 665 return vecPredRegs[reg]; 666 } 667 |
668 VecPredRegContainer & 669 getWritableVecPredRegFlat(RegIndex reg) override |
670 { 671 return vecPredRegs[reg]; 672 } 673 |
674 void 675 setVecPredRegFlat(RegIndex reg, const VecPredRegContainer &val) override |
676 { 677 vecPredRegs[reg] = val; 678 } 679 680#ifdef ISA_HAS_CC_REGS |
681 RegVal readCCRegFlat(RegIndex idx) const override { return ccRegs[idx]; } 682 void setCCRegFlat(RegIndex idx, RegVal val) override { ccRegs[idx] = val; } |
683#else |
684 RegVal 685 readCCRegFlat(RegIndex idx) const override 686 { 687 panic("readCCRegFlat w/no CC regs!\n"); 688 } |
689 |
690 void 691 setCCRegFlat(RegIndex idx, RegVal val) override 692 { 693 panic("setCCRegFlat w/no CC regs!\n"); 694 } |
695#endif 696}; 697 698 699#endif // __CPU_CPU_EXEC_CONTEXT_HH__ |