cpu.hh (13500:6e0a2a7c6d8c) | cpu.hh (13557:fc33e6048b25) |
---|---|
1/* 2 * Copyright (c) 2011, 2016 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 --- 74 unchanged lines hidden (view full) --- 83 * Checker's state through any ThreadContext accesses. This allows the 84 * checker to be able to correctly verify instructions, even with 85 * external accesses to the ThreadContext that change state. 86 */ 87class CheckerCPU : public BaseCPU, public ExecContext 88{ 89 protected: 90 typedef TheISA::MachInst MachInst; | 1/* 2 * Copyright (c) 2011, 2016 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 --- 74 unchanged lines hidden (view full) --- 83 * Checker's state through any ThreadContext accesses. This allows the 84 * checker to be able to correctly verify instructions, even with 85 * external accesses to the ThreadContext that change state. 86 */ 87class CheckerCPU : public BaseCPU, public ExecContext 88{ 89 protected: 90 typedef TheISA::MachInst MachInst; |
91 typedef TheISA::FloatReg FloatReg; 92 typedef TheISA::FloatRegBits FloatRegBits; 93 typedef TheISA::MiscReg MiscReg; | |
94 using VecRegContainer = TheISA::VecRegContainer; 95 96 /** id attached to all issued requests */ 97 MasterID masterId; 98 public: 99 void init() override; 100 101 typedef CheckerCPUParams Params; --- 82 unchanged lines hidden (view full) --- 184 // renaming. We find the architectural register index by indexing 185 // into the instruction's own operand index table. Note that a 186 // raw pointer to the StaticInst is provided instead of a 187 // ref-counted StaticInstPtr to redice overhead. This is fine as 188 // long as these methods don't copy the pointer into any long-term 189 // storage (which is pretty hard to imagine they would have reason 190 // to do). 191 | 91 using VecRegContainer = TheISA::VecRegContainer; 92 93 /** id attached to all issued requests */ 94 MasterID masterId; 95 public: 96 void init() override; 97 98 typedef CheckerCPUParams Params; --- 82 unchanged lines hidden (view full) --- 181 // renaming. We find the architectural register index by indexing 182 // into the instruction's own operand index table. Note that a 183 // raw pointer to the StaticInst is provided instead of a 184 // ref-counted StaticInstPtr to redice overhead. This is fine as 185 // long as these methods don't copy the pointer into any long-term 186 // storage (which is pretty hard to imagine they would have reason 187 // to do). 188 |
192 IntReg readIntRegOperand(const StaticInst *si, int idx) override | 189 RegVal 190 readIntRegOperand(const StaticInst *si, int idx) override |
193 { 194 const RegId& reg = si->srcRegIdx(idx); 195 assert(reg.isIntReg()); 196 return thread->readIntReg(reg.index()); 197 } 198 | 191 { 192 const RegId& reg = si->srcRegIdx(idx); 193 assert(reg.isIntReg()); 194 return thread->readIntReg(reg.index()); 195 } 196 |
199 FloatRegBits readFloatRegOperandBits(const StaticInst *si, 200 int idx) override | 197 RegVal 198 readFloatRegOperandBits(const StaticInst *si, int idx) override |
201 { 202 const RegId& reg = si->srcRegIdx(idx); 203 assert(reg.isFloatReg()); 204 return thread->readFloatRegBits(reg.index()); 205 } 206 207 /** 208 * Read source vector register operand. 209 */ | 199 { 200 const RegId& reg = si->srcRegIdx(idx); 201 assert(reg.isFloatReg()); 202 return thread->readFloatRegBits(reg.index()); 203 } 204 205 /** 206 * Read source vector register operand. 207 */ |
210 const VecRegContainer& readVecRegOperand(const StaticInst *si, 211 int idx) const override | 208 const VecRegContainer & 209 readVecRegOperand(const StaticInst *si, int idx) const override |
212 { 213 const RegId& reg = si->srcRegIdx(idx); 214 assert(reg.isVecReg()); 215 return thread->readVecReg(reg); 216 } 217 218 /** 219 * Read destination vector register operand for modification. 220 */ | 210 { 211 const RegId& reg = si->srcRegIdx(idx); 212 assert(reg.isVecReg()); 213 return thread->readVecReg(reg); 214 } 215 216 /** 217 * Read destination vector register operand for modification. 218 */ |
221 VecRegContainer& getWritableVecRegOperand(const StaticInst *si, 222 int idx) override | 219 VecRegContainer & 220 getWritableVecRegOperand(const StaticInst *si, int idx) override |
223 { 224 const RegId& reg = si->destRegIdx(idx); 225 assert(reg.isVecReg()); 226 return thread->getWritableVecReg(reg); 227 } 228 229 /** Vector Register Lane Interfaces. */ 230 /** @{ */ 231 /** Reads source vector 8bit operand. */ 232 virtual ConstVecLane8 | 221 { 222 const RegId& reg = si->destRegIdx(idx); 223 assert(reg.isVecReg()); 224 return thread->getWritableVecReg(reg); 225 } 226 227 /** Vector Register Lane Interfaces. */ 228 /** @{ */ 229 /** Reads source vector 8bit operand. */ 230 virtual ConstVecLane8 |
233 readVec8BitLaneOperand(const StaticInst *si, int idx) const 234 override | 231 readVec8BitLaneOperand(const StaticInst *si, int idx) const override |
235 { 236 const RegId& reg = si->destRegIdx(idx); 237 assert(reg.isVecReg()); 238 return thread->readVec8BitLaneReg(reg); 239 } 240 241 /** Reads source vector 16bit operand. */ 242 virtual ConstVecLane16 | 232 { 233 const RegId& reg = si->destRegIdx(idx); 234 assert(reg.isVecReg()); 235 return thread->readVec8BitLaneReg(reg); 236 } 237 238 /** Reads source vector 16bit operand. */ 239 virtual ConstVecLane16 |
243 readVec16BitLaneOperand(const StaticInst *si, int idx) const 244 override | 240 readVec16BitLaneOperand(const StaticInst *si, int idx) const override |
245 { 246 const RegId& reg = si->destRegIdx(idx); 247 assert(reg.isVecReg()); 248 return thread->readVec16BitLaneReg(reg); 249 } 250 251 /** Reads source vector 32bit operand. */ 252 virtual ConstVecLane32 | 241 { 242 const RegId& reg = si->destRegIdx(idx); 243 assert(reg.isVecReg()); 244 return thread->readVec16BitLaneReg(reg); 245 } 246 247 /** Reads source vector 32bit operand. */ 248 virtual ConstVecLane32 |
253 readVec32BitLaneOperand(const StaticInst *si, int idx) const 254 override | 249 readVec32BitLaneOperand(const StaticInst *si, int idx) const override |
255 { 256 const RegId& reg = si->destRegIdx(idx); 257 assert(reg.isVecReg()); 258 return thread->readVec32BitLaneReg(reg); 259 } 260 261 /** Reads source vector 64bit operand. */ 262 virtual ConstVecLane64 | 250 { 251 const RegId& reg = si->destRegIdx(idx); 252 assert(reg.isVecReg()); 253 return thread->readVec32BitLaneReg(reg); 254 } 255 256 /** Reads source vector 64bit operand. */ 257 virtual ConstVecLane64 |
263 readVec64BitLaneOperand(const StaticInst *si, int idx) const 264 override | 258 readVec64BitLaneOperand(const StaticInst *si, int idx) const override |
265 { 266 const RegId& reg = si->destRegIdx(idx); 267 assert(reg.isVecReg()); 268 return thread->readVec64BitLaneReg(reg); 269 } 270 271 /** Write a lane of the destination vector operand. */ 272 template <typename LD> --- 25 unchanged lines hidden (view full) --- 298 virtual void 299 setVecLaneOperand(const StaticInst *si, int idx, 300 const LaneData<LaneSize::EightByte>& val) override 301 { 302 setVecLaneOperandT(si, idx, val); 303 } 304 /** @} */ 305 | 259 { 260 const RegId& reg = si->destRegIdx(idx); 261 assert(reg.isVecReg()); 262 return thread->readVec64BitLaneReg(reg); 263 } 264 265 /** Write a lane of the destination vector operand. */ 266 template <typename LD> --- 25 unchanged lines hidden (view full) --- 292 virtual void 293 setVecLaneOperand(const StaticInst *si, int idx, 294 const LaneData<LaneSize::EightByte>& val) override 295 { 296 setVecLaneOperandT(si, idx, val); 297 } 298 /** @} */ 299 |
306 VecElem readVecElemOperand(const StaticInst *si, int idx) const override | 300 VecElem 301 readVecElemOperand(const StaticInst *si, int idx) const override |
307 { 308 const RegId& reg = si->srcRegIdx(idx); 309 return thread->readVecElem(reg); 310 } 311 | 302 { 303 const RegId& reg = si->srcRegIdx(idx); 304 return thread->readVecElem(reg); 305 } 306 |
312 CCReg readCCRegOperand(const StaticInst *si, int idx) override | 307 CCReg 308 readCCRegOperand(const StaticInst *si, int idx) override |
313 { 314 const RegId& reg = si->srcRegIdx(idx); 315 assert(reg.isCCReg()); 316 return thread->readCCReg(reg.index()); 317 } 318 319 template<typename T> | 309 { 310 const RegId& reg = si->srcRegIdx(idx); 311 assert(reg.isCCReg()); 312 return thread->readCCReg(reg.index()); 313 } 314 315 template<typename T> |
320 void setScalarResult(T&& t) | 316 void 317 setScalarResult(T&& t) |
321 { 322 result.push(InstResult(std::forward<T>(t), | 318 { 319 result.push(InstResult(std::forward<T>(t), |
323 InstResult::ResultType::Scalar)); | 320 InstResult::ResultType::Scalar)); |
324 } 325 326 template<typename T> | 321 } 322 323 template<typename T> |
327 void setVecResult(T&& t) | 324 void 325 setVecResult(T&& t) |
328 { 329 result.push(InstResult(std::forward<T>(t), | 326 { 327 result.push(InstResult(std::forward<T>(t), |
330 InstResult::ResultType::VecReg)); | 328 InstResult::ResultType::VecReg)); |
331 } 332 333 template<typename T> | 329 } 330 331 template<typename T> |
334 void setVecElemResult(T&& t) | 332 void 333 setVecElemResult(T&& t) |
335 { 336 result.push(InstResult(std::forward<T>(t), | 334 { 335 result.push(InstResult(std::forward<T>(t), |
337 InstResult::ResultType::VecElem)); | 336 InstResult::ResultType::VecElem)); |
338 } 339 | 337 } 338 |
340 void setIntRegOperand(const StaticInst *si, int idx, 341 IntReg val) override | 339 void 340 setIntRegOperand(const StaticInst *si, int idx, RegVal val) override |
342 { 343 const RegId& reg = si->destRegIdx(idx); 344 assert(reg.isIntReg()); 345 thread->setIntReg(reg.index(), val); 346 setScalarResult(val); 347 } 348 | 341 { 342 const RegId& reg = si->destRegIdx(idx); 343 assert(reg.isIntReg()); 344 thread->setIntReg(reg.index(), val); 345 setScalarResult(val); 346 } 347 |
349 void setFloatRegOperandBits(const StaticInst *si, int idx, 350 FloatRegBits val) override | 348 void 349 setFloatRegOperandBits(const StaticInst *si, int idx, RegVal val) override |
351 { 352 const RegId& reg = si->destRegIdx(idx); 353 assert(reg.isFloatReg()); 354 thread->setFloatRegBits(reg.index(), val); 355 setScalarResult(val); 356 } 357 | 350 { 351 const RegId& reg = si->destRegIdx(idx); 352 assert(reg.isFloatReg()); 353 thread->setFloatRegBits(reg.index(), val); 354 setScalarResult(val); 355 } 356 |
358 void setCCRegOperand(const StaticInst *si, int idx, CCReg val) override | 357 void 358 setCCRegOperand(const StaticInst *si, int idx, CCReg val) override |
359 { 360 const RegId& reg = si->destRegIdx(idx); 361 assert(reg.isCCReg()); 362 thread->setCCReg(reg.index(), val); 363 setScalarResult((uint64_t)val); 364 } 365 | 359 { 360 const RegId& reg = si->destRegIdx(idx); 361 assert(reg.isCCReg()); 362 thread->setCCReg(reg.index(), val); 363 setScalarResult((uint64_t)val); 364 } 365 |
366 void setVecRegOperand(const StaticInst *si, int idx, 367 const VecRegContainer& val) override | 366 void 367 setVecRegOperand(const StaticInst *si, int idx, 368 const VecRegContainer& val) override |
368 { 369 const RegId& reg = si->destRegIdx(idx); 370 assert(reg.isVecReg()); 371 thread->setVecReg(reg, val); 372 setVecResult(val); 373 } 374 | 369 { 370 const RegId& reg = si->destRegIdx(idx); 371 assert(reg.isVecReg()); 372 thread->setVecReg(reg, val); 373 setVecResult(val); 374 } 375 |
375 void setVecElemOperand(const StaticInst *si, int idx, 376 const VecElem val) override | 376 void 377 setVecElemOperand(const StaticInst *si, int idx, 378 const VecElem val) override |
377 { 378 const RegId& reg = si->destRegIdx(idx); 379 assert(reg.isVecElem()); 380 thread->setVecElem(reg, val); 381 setVecElemResult(val); 382 } 383 384 bool readPredicate() const override { return thread->readPredicate(); } 385 | 379 { 380 const RegId& reg = si->destRegIdx(idx); 381 assert(reg.isVecElem()); 382 thread->setVecElem(reg, val); 383 setVecElemResult(val); 384 } 385 386 bool readPredicate() const override { return thread->readPredicate(); } 387 |
386 void setPredicate(bool val) override | 388 void 389 setPredicate(bool val) override |
387 { 388 thread->setPredicate(val); 389 } 390 391 TheISA::PCState pcState() const override { return thread->pcState(); } | 390 { 391 thread->setPredicate(val); 392 } 393 394 TheISA::PCState pcState() const override { return thread->pcState(); } |
392 void pcState(const TheISA::PCState &val) override | 395 void 396 pcState(const TheISA::PCState &val) override |
393 { 394 DPRINTF(Checker, "Changing PC to %s, old PC %s.\n", 395 val, thread->pcState()); 396 thread->pcState(val); 397 } 398 Addr instAddr() { return thread->instAddr(); } 399 Addr nextInstAddr() { return thread->nextInstAddr(); } 400 MicroPC microPC() { return thread->microPC(); } 401 ////////////////////////////////////////// 402 | 397 { 398 DPRINTF(Checker, "Changing PC to %s, old PC %s.\n", 399 val, thread->pcState()); 400 thread->pcState(val); 401 } 402 Addr instAddr() { return thread->instAddr(); } 403 Addr nextInstAddr() { return thread->nextInstAddr(); } 404 MicroPC microPC() { return thread->microPC(); } 405 ////////////////////////////////////////// 406 |
403 MiscReg readMiscRegNoEffect(int misc_reg) const | 407 RegVal 408 readMiscRegNoEffect(int misc_reg) const |
404 { 405 return thread->readMiscRegNoEffect(misc_reg); 406 } 407 | 409 { 410 return thread->readMiscRegNoEffect(misc_reg); 411 } 412 |
408 MiscReg readMiscReg(int misc_reg) override | 413 RegVal 414 readMiscReg(int misc_reg) override |
409 { 410 return thread->readMiscReg(misc_reg); 411 } 412 | 415 { 416 return thread->readMiscReg(misc_reg); 417 } 418 |
413 void setMiscRegNoEffect(int misc_reg, const MiscReg &val) | 419 void 420 setMiscRegNoEffect(int misc_reg, const RegVal &val) |
414 { | 421 { |
415 DPRINTF(Checker, "Setting misc reg %d with no effect to check later\n", misc_reg); | 422 DPRINTF(Checker, "Setting misc reg %d with no effect to check later\n", 423 misc_reg); |
416 miscRegIdxs.push(misc_reg); 417 return thread->setMiscRegNoEffect(misc_reg, val); 418 } 419 | 424 miscRegIdxs.push(misc_reg); 425 return thread->setMiscRegNoEffect(misc_reg, val); 426 } 427 |
420 void setMiscReg(int misc_reg, const MiscReg &val) override | 428 void 429 setMiscReg(int misc_reg, const RegVal &val) override |
421 { | 430 { |
422 DPRINTF(Checker, "Setting misc reg %d with effect to check later\n", misc_reg); | 431 DPRINTF(Checker, "Setting misc reg %d with effect to check later\n", 432 misc_reg); |
423 miscRegIdxs.push(misc_reg); 424 return thread->setMiscReg(misc_reg, val); 425 } 426 | 433 miscRegIdxs.push(misc_reg); 434 return thread->setMiscReg(misc_reg, val); 435 } 436 |
427 MiscReg readMiscRegOperand(const StaticInst *si, int idx) override | 437 RegVal 438 readMiscRegOperand(const StaticInst *si, int idx) override |
428 { 429 const RegId& reg = si->srcRegIdx(idx); 430 assert(reg.isMiscReg()); 431 return thread->readMiscReg(reg.index()); 432 } 433 | 439 { 440 const RegId& reg = si->srcRegIdx(idx); 441 assert(reg.isMiscReg()); 442 return thread->readMiscReg(reg.index()); 443 } 444 |
434 void setMiscRegOperand(const StaticInst *si, int idx, 435 const MiscReg &val) override | 445 void 446 setMiscRegOperand(const StaticInst *si, int idx, 447 const RegVal &val) override |
436 { 437 const RegId& reg = si->destRegIdx(idx); 438 assert(reg.isMiscReg()); 439 return this->setMiscReg(reg.index(), val); 440 } 441 442#if THE_ISA == MIPS_ISA | 448 { 449 const RegId& reg = si->destRegIdx(idx); 450 assert(reg.isMiscReg()); 451 return this->setMiscReg(reg.index(), val); 452 } 453 454#if THE_ISA == MIPS_ISA |
443 MiscReg readRegOtherThread(const RegId& misc_reg, ThreadID tid) override | 455 RegVal 456 readRegOtherThread(const RegId &misc_reg, ThreadID tid) override |
444 { 445 panic("MIPS MT not defined for CheckerCPU.\n"); 446 return 0; 447 } 448 | 457 { 458 panic("MIPS MT not defined for CheckerCPU.\n"); 459 return 0; 460 } 461 |
449 void setRegOtherThread(const RegId& misc_reg, MiscReg val, 450 ThreadID tid) override | 462 void 463 setRegOtherThread(const RegId& misc_reg, RegVal val, ThreadID tid) override |
451 { 452 panic("MIPS MT not defined for CheckerCPU.\n"); 453 } 454#endif 455 456 ///////////////////////////////////////// 457 | 464 { 465 panic("MIPS MT not defined for CheckerCPU.\n"); 466 } 467#endif 468 469 ///////////////////////////////////////// 470 |
458 void recordPCChange(const TheISA::PCState &val) | 471 void 472 recordPCChange(const TheISA::PCState &val) |
459 { 460 changedPC = true; 461 newPCState = val; 462 } 463 | 473 { 474 changedPC = true; 475 newPCState = val; 476 } 477 |
464 void demapPage(Addr vaddr, uint64_t asn) override | 478 void 479 demapPage(Addr vaddr, uint64_t asn) override |
465 { 466 this->itb->demapPage(vaddr, asn); 467 this->dtb->demapPage(vaddr, asn); 468 } 469 470 // monitor/mwait funtions | 480 { 481 this->itb->demapPage(vaddr, asn); 482 this->dtb->demapPage(vaddr, asn); 483 } 484 485 // monitor/mwait funtions |
471 void armMonitor(Addr address) override 472 { BaseCPU::armMonitor(0, address); } | 486 void armMonitor(Addr address) override { BaseCPU::armMonitor(0, address); } |
473 bool mwait(PacketPtr pkt) override { return BaseCPU::mwait(0, pkt); } 474 void mwaitAtomic(ThreadContext *tc) override 475 { return BaseCPU::mwaitAtomic(0, tc, thread->dtb); } 476 AddressMonitor *getAddrMonitor() override 477 { return BaseCPU::getCpuAddrMonitor(0); } 478 | 487 bool mwait(PacketPtr pkt) override { return BaseCPU::mwait(0, pkt); } 488 void mwaitAtomic(ThreadContext *tc) override 489 { return BaseCPU::mwaitAtomic(0, tc, thread->dtb); } 490 AddressMonitor *getAddrMonitor() override 491 { return BaseCPU::getCpuAddrMonitor(0); } 492 |
479 void demapInstPage(Addr vaddr, uint64_t asn) | 493 void 494 demapInstPage(Addr vaddr, uint64_t asn) |
480 { 481 this->itb->demapPage(vaddr, asn); 482 } 483 | 495 { 496 this->itb->demapPage(vaddr, asn); 497 } 498 |
484 void demapDataPage(Addr vaddr, uint64_t asn) | 499 void 500 demapDataPage(Addr vaddr, uint64_t asn) |
485 { 486 this->dtb->demapPage(vaddr, asn); 487 } 488 489 Fault readMem(Addr addr, uint8_t *data, unsigned size, 490 Request::Flags flags) override; 491 Fault writeMem(uint8_t *data, unsigned size, Addr addr, 492 Request::Flags flags, uint64_t *res) override; 493 | 501 { 502 this->dtb->demapPage(vaddr, asn); 503 } 504 505 Fault readMem(Addr addr, uint8_t *data, unsigned size, 506 Request::Flags flags) override; 507 Fault writeMem(uint8_t *data, unsigned size, Addr addr, 508 Request::Flags flags, uint64_t *res) override; 509 |
494 unsigned int readStCondFailures() const override { | 510 unsigned int 511 readStCondFailures() const override { |
495 return thread->readStCondFailures(); 496 } 497 | 512 return thread->readStCondFailures(); 513 } 514 |
498 void setStCondFailures(unsigned int sc_failures) override 499 {} | 515 void setStCondFailures(unsigned int sc_failures) override {} |
500 ///////////////////////////////////////////////////// 501 502 Fault hwrei() override { return thread->hwrei(); } 503 bool simPalCheck(int palFunc) override 504 { return thread->simPalCheck(palFunc); } 505 void wakeup(ThreadID tid) override { } 506 // Assume that the normal CPU's call to syscall was successful. 507 // The checker's state would have already been updated by the syscall. 508 void syscall(int64_t callnum, Fault *fault) override { } 509 | 516 ///////////////////////////////////////////////////// 517 518 Fault hwrei() override { return thread->hwrei(); } 519 bool simPalCheck(int palFunc) override 520 { return thread->simPalCheck(palFunc); } 521 void wakeup(ThreadID tid) override { } 522 // Assume that the normal CPU's call to syscall was successful. 523 // The checker's state would have already been updated by the syscall. 524 void syscall(int64_t callnum, Fault *fault) override { } 525 |
510 void handleError() | 526 void 527 handleError() |
511 { 512 if (exitOnError) 513 dumpAndExit(); 514 } 515 516 bool checkFlags(const RequestPtr &unverified_req, Addr vAddr, 517 Addr pAddr, int flags); 518 --- 73 unchanged lines hidden --- | 528 { 529 if (exitOnError) 530 dumpAndExit(); 531 } 532 533 bool checkFlags(const RequestPtr &unverified_req, Addr vAddr, 534 Addr pAddr, int flags); 535 --- 73 unchanged lines hidden --- |