simple_thread.hh revision 13693:85fa3a41014b
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 9 * to a hardware implementation of the functionality of the software 10 * licensed hereunder. You may use the software subject to the license 11 * terms below provided that you ensure that this notice is replicated 12 * unmodified and in its entirety in all distributions of the software, 13 * modified or unmodified, in source code or in binary form. 14 * 15 * Copyright (c) 2001-2006 The Regents of The University of Michigan 16 * All rights reserved. 17 * 18 * Redistribution and use in source and binary forms, with or without 19 * modification, are permitted provided that the following conditions are 20 * met: redistributions of source code must retain the above copyright 21 * notice, this list of conditions and the following disclaimer; 22 * redistributions in binary form must reproduce the above copyright 23 * notice, this list of conditions and the following disclaimer in the 24 * documentation and/or other materials provided with the distribution; 25 * neither the name of the copyright holders nor the names of its 26 * contributors may be used to endorse or promote products derived from 27 * this software without specific prior written permission. 28 * 29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 32 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 33 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 34 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 35 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 36 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 37 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 38 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 39 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 40 * 41 * Authors: Steve Reinhardt 42 * Nathan Binkert 43 */ 44 45#ifndef __CPU_SIMPLE_THREAD_HH__ 46#define __CPU_SIMPLE_THREAD_HH__ 47 48#include "arch/decoder.hh" 49#include "arch/generic/tlb.hh" 50#include "arch/isa.hh" 51#include "arch/isa_traits.hh" 52#include "arch/registers.hh" 53#include "arch/types.hh" 54#include "base/types.hh" 55#include "config/the_isa.hh" 56#include "cpu/thread_context.hh" 57#include "cpu/thread_state.hh" 58#include "debug/CCRegs.hh" 59#include "debug/FloatRegs.hh" 60#include "debug/IntRegs.hh" 61#include "debug/VecPredRegs.hh" 62#include "debug/VecRegs.hh" 63#include "mem/page_table.hh" 64#include "mem/request.hh" 65#include "sim/byteswap.hh" 66#include "sim/eventq.hh" 67#include "sim/process.hh" 68#include "sim/serialize.hh" 69#include "sim/system.hh" 70 71class BaseCPU; 72class CheckerCPU; 73 74class FunctionProfile; 75class ProfileNode; 76 77namespace TheISA { 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 so that a ProxyThreadContext class can be 87 * made using SimpleThread as the template parameter (see 88 * thread_context.hh). It adds to the ThreadState object by adding all 89 * the objects needed for simple functional execution, including a 90 * simple architectural register file, and pointers to the ITB and DTB 91 * in full system mode. For CPU models that do not need more advanced 92 * ways to hold state (i.e. a separate physical register file, or 93 * separate fetch and commit PC's), this SimpleThread class provides 94 * all the necessary state for full architecture-level functional 95 * simulation. See the AtomicSimpleCPU or TimingSimpleCPU for 96 * examples. 97 */ 98 99class SimpleThread : public ThreadState 100{ 101 protected: 102 typedef TheISA::MachInst MachInst; 103 using VecRegContainer = TheISA::VecRegContainer; 104 using VecElem = TheISA::VecElem; 105 using VecPredRegContainer = TheISA::VecPredRegContainer; 106 public: 107 typedef ThreadContext::Status Status; 108 109 protected: 110 RegVal floatRegs[TheISA::NumFloatRegs]; 111 RegVal intRegs[TheISA::NumIntRegs]; 112 VecRegContainer vecRegs[TheISA::NumVecRegs]; 113 VecPredRegContainer vecPredRegs[TheISA::NumVecPredRegs]; 114#ifdef ISA_HAS_CC_REGS 115 RegVal ccRegs[TheISA::NumCCRegs]; 116#endif 117 TheISA::ISA *const isa; // one "instance" of the current ISA. 118 119 TheISA::PCState _pcState; 120 121 /** Did this instruction execute or is it predicated false */ 122 bool predicate; 123 124 public: 125 std::string name() const 126 { 127 return csprintf("%s.[tid:%i]", baseCpu->name(), tc->threadId()); 128 } 129 130 ProxyThreadContext<SimpleThread> *tc; 131 132 System *system; 133 134 BaseTLB *itb; 135 BaseTLB *dtb; 136 137 TheISA::Decoder decoder; 138 139 // constructor: initialize SimpleThread from given process structure 140 // FS 141 SimpleThread(BaseCPU *_cpu, int _thread_num, System *_system, 142 BaseTLB *_itb, BaseTLB *_dtb, TheISA::ISA *_isa, 143 bool use_kernel_stats = true); 144 // SE 145 SimpleThread(BaseCPU *_cpu, int _thread_num, System *_system, 146 Process *_process, BaseTLB *_itb, BaseTLB *_dtb, 147 TheISA::ISA *_isa); 148 149 virtual ~SimpleThread(); 150 151 virtual void takeOverFrom(ThreadContext *oldContext); 152 153 void regStats(const std::string &name); 154 155 void copyState(ThreadContext *oldContext); 156 157 void serialize(CheckpointOut &cp) const override; 158 void unserialize(CheckpointIn &cp) override; 159 void startup(); 160 161 /*************************************************************** 162 * SimpleThread functions to provide CPU with access to various 163 * state. 164 **************************************************************/ 165 166 /** Returns the pointer to this SimpleThread's ThreadContext. Used 167 * when a ThreadContext must be passed to objects outside of the 168 * CPU. 169 */ 170 ThreadContext *getTC() { return tc; } 171 172 void demapPage(Addr vaddr, uint64_t asn) 173 { 174 itb->demapPage(vaddr, asn); 175 dtb->demapPage(vaddr, asn); 176 } 177 178 void demapInstPage(Addr vaddr, uint64_t asn) 179 { 180 itb->demapPage(vaddr, asn); 181 } 182 183 void demapDataPage(Addr vaddr, uint64_t asn) 184 { 185 dtb->demapPage(vaddr, asn); 186 } 187 188 void dumpFuncProfile(); 189 190 Fault hwrei(); 191 192 bool simPalCheck(int palFunc); 193 194 /******************************************* 195 * ThreadContext interface functions. 196 ******************************************/ 197 198 BaseCPU *getCpuPtr() { return baseCpu; } 199 200 BaseTLB *getITBPtr() { return itb; } 201 202 BaseTLB *getDTBPtr() { return dtb; } 203 204 CheckerCPU *getCheckerCpuPtr() { return NULL; } 205 206 TheISA::ISA *getIsaPtr() { return isa; } 207 208 TheISA::Decoder *getDecoderPtr() { return &decoder; } 209 210 System *getSystemPtr() { return system; } 211 212 Status status() const { return _status; } 213 214 void setStatus(Status newStatus) { _status = newStatus; } 215 216 /// Set the status to Active. 217 void activate(); 218 219 /// Set the status to Suspended. 220 void suspend(); 221 222 /// Set the status to Halted. 223 void halt(); 224 225 void copyArchRegs(ThreadContext *tc); 226 227 void clearArchRegs() 228 { 229 _pcState = 0; 230 memset(intRegs, 0, sizeof(intRegs)); 231 memset(floatRegs, 0, sizeof(floatRegs)); 232 for (int i = 0; i < TheISA::NumVecRegs; i++) { 233 vecRegs[i].zero(); 234 } 235 for (int i = 0; i < TheISA::NumVecPredRegs; i++) { 236 vecPredRegs[i].reset(); 237 } 238#ifdef ISA_HAS_CC_REGS 239 memset(ccRegs, 0, sizeof(ccRegs)); 240#endif 241 isa->clear(); 242 } 243 244 // 245 // New accessors for new decoder. 246 // 247 RegVal 248 readIntReg(int reg_idx) 249 { 250 int flatIndex = isa->flattenIntIndex(reg_idx); 251 assert(flatIndex < TheISA::NumIntRegs); 252 uint64_t regVal(readIntRegFlat(flatIndex)); 253 DPRINTF(IntRegs, "Reading int reg %d (%d) as %#x.\n", 254 reg_idx, flatIndex, regVal); 255 return regVal; 256 } 257 258 RegVal 259 readFloatReg(int reg_idx) 260 { 261 int flatIndex = isa->flattenFloatIndex(reg_idx); 262 assert(flatIndex < TheISA::NumFloatRegs); 263 RegVal regVal(readFloatRegFlat(flatIndex)); 264 DPRINTF(FloatRegs, "Reading float reg %d (%d) bits as %#x.\n", 265 reg_idx, flatIndex, regVal); 266 return regVal; 267 } 268 269 const VecRegContainer& 270 readVecReg(const RegId& reg) const 271 { 272 int flatIndex = isa->flattenVecIndex(reg.index()); 273 assert(flatIndex < TheISA::NumVecRegs); 274 const VecRegContainer& regVal = readVecRegFlat(flatIndex); 275 DPRINTF(VecRegs, "Reading vector reg %d (%d) as %s.\n", 276 reg.index(), flatIndex, regVal.print()); 277 return regVal; 278 } 279 280 VecRegContainer& 281 getWritableVecReg(const RegId& reg) 282 { 283 int flatIndex = isa->flattenVecIndex(reg.index()); 284 assert(flatIndex < TheISA::NumVecRegs); 285 VecRegContainer& regVal = getWritableVecRegFlat(flatIndex); 286 DPRINTF(VecRegs, "Reading vector reg %d (%d) as %s for modify.\n", 287 reg.index(), flatIndex, regVal.print()); 288 return regVal; 289 } 290 291 /** Vector Register Lane Interfaces. */ 292 /** @{ */ 293 /** Reads source vector <T> operand. */ 294 template <typename T> 295 VecLaneT<T, true> 296 readVecLane(const RegId& reg) const 297 { 298 int flatIndex = isa->flattenVecIndex(reg.index()); 299 assert(flatIndex < TheISA::NumVecRegs); 300 auto regVal = readVecLaneFlat<T>(flatIndex, reg.elemIndex()); 301 DPRINTF(VecRegs, "Reading vector lane %d (%d)[%d] as %lx.\n", 302 reg.index(), flatIndex, reg.elemIndex(), regVal); 303 return regVal; 304 } 305 306 /** Reads source vector 8bit operand. */ 307 virtual ConstVecLane8 308 readVec8BitLaneReg(const RegId& reg) const 309 { return readVecLane<uint8_t>(reg); } 310 311 /** Reads source vector 16bit operand. */ 312 virtual ConstVecLane16 313 readVec16BitLaneReg(const RegId& reg) const 314 { return readVecLane<uint16_t>(reg); } 315 316 /** Reads source vector 32bit operand. */ 317 virtual ConstVecLane32 318 readVec32BitLaneReg(const RegId& reg) const 319 { return readVecLane<uint32_t>(reg); } 320 321 /** Reads source vector 64bit operand. */ 322 virtual ConstVecLane64 323 readVec64BitLaneReg(const RegId& reg) const 324 { return readVecLane<uint64_t>(reg); } 325 326 /** Write a lane of the destination vector register. */ 327 template <typename LD> 328 void setVecLaneT(const RegId& reg, const LD& val) 329 { 330 int flatIndex = isa->flattenVecIndex(reg.index()); 331 assert(flatIndex < TheISA::NumVecRegs); 332 setVecLaneFlat(flatIndex, reg.elemIndex(), val); 333 DPRINTF(VecRegs, "Reading vector lane %d (%d)[%d] to %lx.\n", 334 reg.index(), flatIndex, reg.elemIndex(), val); 335 } 336 virtual void setVecLane(const RegId& reg, 337 const LaneData<LaneSize::Byte>& val) 338 { return setVecLaneT(reg, val); } 339 virtual void setVecLane(const RegId& reg, 340 const LaneData<LaneSize::TwoByte>& val) 341 { return setVecLaneT(reg, val); } 342 virtual void setVecLane(const RegId& reg, 343 const LaneData<LaneSize::FourByte>& val) 344 { return setVecLaneT(reg, val); } 345 virtual void setVecLane(const RegId& reg, 346 const LaneData<LaneSize::EightByte>& val) 347 { return setVecLaneT(reg, val); } 348 /** @} */ 349 350 const VecElem& readVecElem(const RegId& reg) const 351 { 352 int flatIndex = isa->flattenVecElemIndex(reg.index()); 353 assert(flatIndex < TheISA::NumVecRegs); 354 const VecElem& regVal = readVecElemFlat(flatIndex, reg.elemIndex()); 355 DPRINTF(VecRegs, "Reading element %d of vector reg %d (%d) as" 356 " %#x.\n", reg.elemIndex(), reg.index(), flatIndex, regVal); 357 return regVal; 358 } 359 360 const VecPredRegContainer& 361 readVecPredReg(const RegId& reg) const 362 { 363 int flatIndex = isa->flattenVecPredIndex(reg.index()); 364 assert(flatIndex < TheISA::NumVecPredRegs); 365 const VecPredRegContainer& regVal = readVecPredRegFlat(flatIndex); 366 DPRINTF(VecPredRegs, "Reading predicate reg %d (%d) as %s.\n", 367 reg.index(), flatIndex, regVal.print()); 368 return regVal; 369 } 370 371 VecPredRegContainer& 372 getWritableVecPredReg(const RegId& reg) 373 { 374 int flatIndex = isa->flattenVecPredIndex(reg.index()); 375 assert(flatIndex < TheISA::NumVecPredRegs); 376 VecPredRegContainer& regVal = getWritableVecPredRegFlat(flatIndex); 377 DPRINTF(VecPredRegs, 378 "Reading predicate reg %d (%d) as %s for modify.\n", 379 reg.index(), flatIndex, regVal.print()); 380 return regVal; 381 } 382 383 RegVal 384 readCCReg(int reg_idx) 385 { 386#ifdef ISA_HAS_CC_REGS 387 int flatIndex = isa->flattenCCIndex(reg_idx); 388 assert(0 <= flatIndex); 389 assert(flatIndex < TheISA::NumCCRegs); 390 uint64_t regVal(readCCRegFlat(flatIndex)); 391 DPRINTF(CCRegs, "Reading CC reg %d (%d) as %#x.\n", 392 reg_idx, flatIndex, regVal); 393 return regVal; 394#else 395 panic("Tried to read a CC register."); 396 return 0; 397#endif 398 } 399 400 void 401 setIntReg(int reg_idx, RegVal val) 402 { 403 int flatIndex = isa->flattenIntIndex(reg_idx); 404 assert(flatIndex < TheISA::NumIntRegs); 405 DPRINTF(IntRegs, "Setting int reg %d (%d) to %#x.\n", 406 reg_idx, flatIndex, val); 407 setIntRegFlat(flatIndex, val); 408 } 409 410 void 411 setFloatReg(int reg_idx, RegVal val) 412 { 413 int flatIndex = isa->flattenFloatIndex(reg_idx); 414 assert(flatIndex < TheISA::NumFloatRegs); 415 // XXX: Fix array out of bounds compiler error for gem5.fast 416 // when checkercpu enabled 417 if (flatIndex < TheISA::NumFloatRegs) 418 setFloatRegFlat(flatIndex, val); 419 DPRINTF(FloatRegs, "Setting float reg %d (%d) bits to %#x.\n", 420 reg_idx, flatIndex, val); 421 } 422 423 void 424 setVecReg(const RegId& reg, const VecRegContainer& val) 425 { 426 int flatIndex = isa->flattenVecIndex(reg.index()); 427 assert(flatIndex < TheISA::NumVecRegs); 428 setVecRegFlat(flatIndex, val); 429 DPRINTF(VecRegs, "Setting vector reg %d (%d) to %s.\n", 430 reg.index(), flatIndex, val.print()); 431 } 432 433 void 434 setVecElem(const RegId& reg, const VecElem& val) 435 { 436 int flatIndex = isa->flattenVecElemIndex(reg.index()); 437 assert(flatIndex < TheISA::NumVecRegs); 438 setVecElemFlat(flatIndex, reg.elemIndex(), val); 439 DPRINTF(VecRegs, "Setting element %d of vector reg %d (%d) to" 440 " %#x.\n", reg.elemIndex(), reg.index(), flatIndex, val); 441 } 442 443 void 444 setVecPredReg(const RegId& reg, const VecPredRegContainer& val) 445 { 446 int flatIndex = isa->flattenVecPredIndex(reg.index()); 447 assert(flatIndex < TheISA::NumVecPredRegs); 448 setVecPredRegFlat(flatIndex, val); 449 DPRINTF(VecPredRegs, "Setting predicate reg %d (%d) to %s.\n", 450 reg.index(), flatIndex, val.print()); 451 } 452 453 void 454 setCCReg(int reg_idx, RegVal val) 455 { 456#ifdef ISA_HAS_CC_REGS 457 int flatIndex = isa->flattenCCIndex(reg_idx); 458 assert(flatIndex < TheISA::NumCCRegs); 459 DPRINTF(CCRegs, "Setting CC reg %d (%d) to %#x.\n", 460 reg_idx, flatIndex, val); 461 setCCRegFlat(flatIndex, val); 462#else 463 panic("Tried to set a CC register."); 464#endif 465 } 466 467 TheISA::PCState 468 pcState() 469 { 470 return _pcState; 471 } 472 473 void 474 pcState(const TheISA::PCState &val) 475 { 476 _pcState = val; 477 } 478 479 void 480 pcStateNoRecord(const TheISA::PCState &val) 481 { 482 _pcState = val; 483 } 484 485 Addr 486 instAddr() 487 { 488 return _pcState.instAddr(); 489 } 490 491 Addr 492 nextInstAddr() 493 { 494 return _pcState.nextInstAddr(); 495 } 496 497 void 498 setNPC(Addr val) 499 { 500 _pcState.setNPC(val); 501 } 502 503 MicroPC 504 microPC() 505 { 506 return _pcState.microPC(); 507 } 508 509 bool readPredicate() 510 { 511 return predicate; 512 } 513 514 void setPredicate(bool val) 515 { 516 predicate = val; 517 } 518 519 RegVal 520 readMiscRegNoEffect(int misc_reg, ThreadID tid=0) const 521 { 522 return isa->readMiscRegNoEffect(misc_reg); 523 } 524 525 RegVal 526 readMiscReg(int misc_reg, ThreadID tid=0) 527 { 528 return isa->readMiscReg(misc_reg, tc); 529 } 530 531 void 532 setMiscRegNoEffect(int misc_reg, RegVal val, ThreadID tid = 0) 533 { 534 return isa->setMiscRegNoEffect(misc_reg, val); 535 } 536 537 void 538 setMiscReg(int misc_reg, RegVal val, ThreadID tid = 0) 539 { 540 return isa->setMiscReg(misc_reg, val, tc); 541 } 542 543 RegId 544 flattenRegId(const RegId& regId) const 545 { 546 return isa->flattenRegId(regId); 547 } 548 549 unsigned readStCondFailures() { return storeCondFailures; } 550 551 void setStCondFailures(unsigned sc_failures) 552 { storeCondFailures = sc_failures; } 553 554 void 555 syscall(int64_t callnum, Fault *fault) 556 { 557 process->syscall(callnum, tc, fault); 558 } 559 560 RegVal readIntRegFlat(int idx) { return intRegs[idx]; } 561 void setIntRegFlat(int idx, RegVal val) { intRegs[idx] = val; } 562 563 RegVal readFloatRegFlat(int idx) { return floatRegs[idx]; } 564 void setFloatRegFlat(int idx, RegVal val) { floatRegs[idx] = val; } 565 566 const VecRegContainer & 567 readVecRegFlat(const RegIndex& reg) const 568 { 569 return vecRegs[reg]; 570 } 571 572 VecRegContainer & 573 getWritableVecRegFlat(const RegIndex& reg) 574 { 575 return vecRegs[reg]; 576 } 577 578 void 579 setVecRegFlat(const RegIndex& reg, const VecRegContainer& val) 580 { 581 vecRegs[reg] = val; 582 } 583 584 template <typename T> 585 VecLaneT<T, true> 586 readVecLaneFlat(const RegIndex& reg, int lId) const 587 { 588 return vecRegs[reg].laneView<T>(lId); 589 } 590 591 template <typename LD> 592 void 593 setVecLaneFlat(const RegIndex& reg, int lId, const LD& val) 594 { 595 vecRegs[reg].laneView<typename LD::UnderlyingType>(lId) = val; 596 } 597 598 const VecElem & 599 readVecElemFlat(const RegIndex& reg, const ElemIndex& elemIndex) const 600 { 601 return vecRegs[reg].as<TheISA::VecElem>()[elemIndex]; 602 } 603 604 void 605 setVecElemFlat(const RegIndex& reg, const ElemIndex& elemIndex, 606 const VecElem val) 607 { 608 vecRegs[reg].as<TheISA::VecElem>()[elemIndex] = val; 609 } 610 611 const VecPredRegContainer& readVecPredRegFlat(const RegIndex& reg) const 612 { 613 return vecPredRegs[reg]; 614 } 615 616 VecPredRegContainer& getWritableVecPredRegFlat(const RegIndex& reg) 617 { 618 return vecPredRegs[reg]; 619 } 620 621 void setVecPredRegFlat(const RegIndex& reg, const VecPredRegContainer& val) 622 { 623 vecPredRegs[reg] = val; 624 } 625 626#ifdef ISA_HAS_CC_REGS 627 RegVal readCCRegFlat(int idx) { return ccRegs[idx]; } 628 void setCCRegFlat(int idx, RegVal val) { ccRegs[idx] = val; } 629#else 630 RegVal readCCRegFlat(int idx) 631 { panic("readCCRegFlat w/no CC regs!\n"); } 632 633 void setCCRegFlat(int idx, RegVal val) 634 { panic("setCCRegFlat w/no CC regs!\n"); } 635#endif 636}; 637 638 639#endif // __CPU_CPU_EXEC_CONTEXT_HH__ 640