1/* 2 * Copyright (c) 2011 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 --- 477 unchanged lines hidden (view full) --- 486 uint64_t inst_val; 487 int idx = -1; 488 bool result_mismatch = false; 489 490 if (inst->isUnverifiable()) { 491 // Unverifiable instructions assume they were executed 492 // properly by the CPU. Grab the result from the 493 // instruction and write it to the register. |
494 copyResult(inst, 0, idx); |
495 } else if (inst->numDestRegs() > 0 && !result.empty()) { 496 DPRINTF(Checker, "Dest regs %d, number of checker dest regs %d\n", 497 inst->numDestRegs(), result.size()); 498 for (int i = 0; i < inst->numDestRegs() && !result.empty(); i++) { 499 result.front().get(checker_val); 500 result.pop(); 501 inst_val = 0; 502 inst->template popResult<uint64_t>(inst_val); --- 17 unchanged lines hidden (view full) --- 520 // It's useful to verify load values from memory, but in MP 521 // systems the value obtained at execute may be different than 522 // the value obtained at completion. Similarly DMA can 523 // present the same problem on even UP systems. Thus there is 524 // the option to only warn on loads having a result error. 525 // The load/store queue in Detailed CPU can also cause problems 526 // if load/store forwarding is allowed. 527 if (inst->isLoad() && warnOnlyOnLoadError) { |
528 copyResult(inst, inst_val, idx); |
529 } else { 530 handleError(inst); 531 } 532 } 533 534 if (inst->nextInstAddr() != thread->nextInstAddr()) { 535 warn("%lli: Instruction next PCs do not match! Inst: %#x, " 536 "checker: %#x", --- 48 unchanged lines hidden (view full) --- 585 // Also advance the PC. Hopefully no PC-based events happened. 586 advancePC(NoFault); 587 updateThisCycle = false; 588 } 589} 590 591template <class Impl> 592void |
593Checker<Impl>::copyResult(DynInstPtr &inst, uint64_t mismatch_val, |
594 int start_idx) 595{ 596 // We've already popped one dest off the queue, 597 // so do the fix-up then start with the next dest reg; 598 if (start_idx >= 0) { 599 RegIndex idx = inst->destRegIdx(start_idx); 600 switch (regIdxToClass(idx)) { 601 case IntRegClass: |
602 thread->setIntReg(idx, mismatch_val); |
603 break; 604 case FloatRegClass: |
605 thread->setFloatRegBits(idx - TheISA::FP_Reg_Base, mismatch_val); |
606 break; 607 case CCRegClass: |
608 thread->setCCReg(idx - TheISA::CC_Reg_Base, mismatch_val); |
609 break; |
610 case MiscRegClass: 611 thread->setMiscReg(idx - TheISA::Misc_Reg_Base, |
612 mismatch_val); |
613 break; 614 } 615 } |
616 start_idx++; |
617 uint64_t res = 0; |
618 for (int i = start_idx; i < inst->numDestRegs(); i++) { 619 RegIndex idx = inst->destRegIdx(i); |
620 inst->template popResult<uint64_t>(res); |
621 switch (regIdxToClass(idx)) { |
622 case IntRegClass: 623 thread->setIntReg(idx, res); 624 break; 625 case FloatRegClass: 626 thread->setFloatRegBits(idx - TheISA::FP_Reg_Base, res); 627 break; 628 case CCRegClass: 629 thread->setCCReg(idx - TheISA::CC_Reg_Base, res); 630 break; 631 case MiscRegClass: 632 // Try to get the proper misc register index for ARM here... 633 thread->setMiscReg(idx - TheISA::Misc_Reg_Base, res); 634 break; |
635 // else Register is out of range... 636 } 637 } 638} 639 640template <class Impl> 641void 642Checker<Impl>::dumpAndExit(DynInstPtr &inst) --- 44 unchanged lines hidden --- |