cpu_impl.hh (12106:7784fac1b159) | cpu_impl.hh (12107:998b4c54ee51) |
---|---|
1/* | 1/* |
2 * Copyright (c) 2011 ARM Limited | 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 9 * to a hardware implementation of the functionality of the software 10 * licensed hereunder. You may use the software subject to the license --- 465 unchanged lines hidden (view full) --- 476 curStaticInst->getName(), inst->staticInst->getName()); 477 } 478} 479 480template <class Impl> 481void 482Checker<Impl>::validateExecution(DynInstPtr &inst) 483{ | 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 --- 465 unchanged lines hidden (view full) --- 476 curStaticInst->getName(), inst->staticInst->getName()); 477 } 478} 479 480template <class Impl> 481void 482Checker<Impl>::validateExecution(DynInstPtr &inst) 483{ |
484 uint64_t checker_val; 485 uint64_t inst_val; | 484 InstResult checker_val; 485 InstResult inst_val; |
486 int idx = -1; 487 bool result_mismatch = false; | 486 int idx = -1; 487 bool result_mismatch = false; |
488 bool scalar_mismatch = false; |
|
488 489 if (inst->isUnverifiable()) { 490 // Unverifiable instructions assume they were executed 491 // properly by the CPU. Grab the result from the 492 // instruction and write it to the register. | 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. |
493 copyResult(inst, 0, idx); | 494 copyResult(inst, InstResult(0ul, InstResult::ResultType::Scalar), idx); |
494 } else if (inst->numDestRegs() > 0 && !result.empty()) { 495 DPRINTF(Checker, "Dest regs %d, number of checker dest regs %d\n", 496 inst->numDestRegs(), result.size()); 497 for (int i = 0; i < inst->numDestRegs() && !result.empty(); i++) { | 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++) { |
498 result.front().get(checker_val); | 499 checker_val = result.front(); |
499 result.pop(); | 500 result.pop(); |
500 inst_val = 0; 501 inst->template popResult<uint64_t>(inst_val); | 501 inst_val = inst->popResult( 502 InstResult(0ul, InstResult::ResultType::Scalar)); |
502 if (checker_val != inst_val) { 503 result_mismatch = true; 504 idx = i; | 503 if (checker_val != inst_val) { 504 result_mismatch = true; 505 idx = i; |
506 scalar_mismatch = true; |
|
505 break; 506 } 507 } 508 } // Checker CPU checks all the saved results in the dyninst passed by 509 // the cpu model being checked against the saved results present in 510 // the static inst executed in the Checker. Sometimes the number 511 // of saved results differs between the dyninst and static inst, but 512 // this is ok and not a bug. May be worthwhile to try and correct this. 513 514 if (result_mismatch) { | 507 break; 508 } 509 } 510 } // Checker CPU checks all the saved results in the dyninst passed by 511 // the cpu model being checked against the saved results present in 512 // the static inst executed in the Checker. Sometimes the number 513 // of saved results differs between the dyninst and static inst, but 514 // this is ok and not a bug. May be worthwhile to try and correct this. 515 516 if (result_mismatch) { |
515 warn("%lli: Instruction results do not match! (Values may not " 516 "actually be integers) Inst: %#x, checker: %#x", 517 curTick(), inst_val, checker_val); | 517 if (scalar_mismatch) { 518 warn("%lli: Instruction results (%i) do not match! (Values may" 519 " not actually be integers) Inst: %#x, checker: %#x", 520 curTick(), idx, inst_val.asIntegerNoAssert(), 521 checker_val.asInteger()); 522 } |
518 519 // It's useful to verify load values from memory, but in MP 520 // systems the value obtained at execute may be different than 521 // the value obtained at completion. Similarly DMA can 522 // present the same problem on even UP systems. Thus there is 523 // the option to only warn on loads having a result error. 524 // The load/store queue in Detailed CPU can also cause problems 525 // if load/store forwarding is allowed. --- 58 unchanged lines hidden (view full) --- 584 // Also advance the PC. Hopefully no PC-based events happened. 585 advancePC(NoFault); 586 updateThisCycle = false; 587 } 588} 589 590template <class Impl> 591void | 523 524 // It's useful to verify load values from memory, but in MP 525 // systems the value obtained at execute may be different than 526 // the value obtained at completion. Similarly DMA can 527 // present the same problem on even UP systems. Thus there is 528 // the option to only warn on loads having a result error. 529 // The load/store queue in Detailed CPU can also cause problems 530 // if load/store forwarding is allowed. --- 58 unchanged lines hidden (view full) --- 589 // Also advance the PC. Hopefully no PC-based events happened. 590 advancePC(NoFault); 591 updateThisCycle = false; 592 } 593} 594 595template <class Impl> 596void |
592Checker<Impl>::copyResult(DynInstPtr &inst, uint64_t mismatch_val, | 597Checker<Impl>::copyResult(DynInstPtr &inst, const InstResult& mismatch_val, |
593 int start_idx) 594{ 595 // We've already popped one dest off the queue, 596 // so do the fix-up then start with the next dest reg; 597 if (start_idx >= 0) { 598 const RegId& idx = inst->destRegIdx(start_idx); 599 switch (idx.classValue()) { 600 case IntRegClass: | 598 int start_idx) 599{ 600 // We've already popped one dest off the queue, 601 // so do the fix-up then start with the next dest reg; 602 if (start_idx >= 0) { 603 const RegId& idx = inst->destRegIdx(start_idx); 604 switch (idx.classValue()) { 605 case IntRegClass: |
601 thread->setIntReg(idx.index(), mismatch_val); | 606 panic_if(!mismatch_val.isScalar(), "Unexpected type of result"); 607 thread->setIntReg(idx.index(), mismatch_val.asInteger()); |
602 break; 603 case FloatRegClass: | 608 break; 609 case FloatRegClass: |
604 thread->setFloatRegBits(idx.index(), mismatch_val); | 610 panic_if(!mismatch_val.isScalar(), "Unexpected type of result"); 611 thread->setFloatRegBits(idx.index(), mismatch_val.asInteger()); |
605 break; 606 case CCRegClass: | 612 break; 613 case CCRegClass: |
607 thread->setCCReg(idx.index(), mismatch_val); | 614 panic_if(!mismatch_val.isScalar(), "Unexpected type of result"); 615 thread->setCCReg(idx.index(), mismatch_val.asInteger()); |
608 break; 609 case MiscRegClass: | 616 break; 617 case MiscRegClass: |
610 thread->setMiscReg(idx.index(), mismatch_val); | 618 panic_if(!mismatch_val.isScalar(), "Unexpected type of result"); 619 thread->setMiscReg(idx.index(), mismatch_val.asInteger()); |
611 break; 612 } 613 } 614 start_idx++; | 620 break; 621 } 622 } 623 start_idx++; |
615 uint64_t res = 0; | 624 InstResult res; |
616 for (int i = start_idx; i < inst->numDestRegs(); i++) { 617 const RegId& idx = inst->destRegIdx(i); | 625 for (int i = start_idx; i < inst->numDestRegs(); i++) { 626 const RegId& idx = inst->destRegIdx(i); |
618 inst->template popResult<uint64_t>(res); | 627 res = inst->popResult(); |
619 switch (idx.classValue()) { 620 case IntRegClass: | 628 switch (idx.classValue()) { 629 case IntRegClass: |
621 thread->setIntReg(idx.index(), res); | 630 panic_if(!res.isScalar(), "Unexpected type of result"); 631 thread->setIntReg(idx.index(), res.asInteger()); |
622 break; 623 case FloatRegClass: | 632 break; 633 case FloatRegClass: |
624 thread->setFloatRegBits(idx.index(), res); | 634 panic_if(!res.isScalar(), "Unexpected type of result"); 635 thread->setFloatRegBits(idx.index(), res.asInteger()); |
625 break; 626 case CCRegClass: | 636 break; 637 case CCRegClass: |
627 thread->setCCReg(idx.index(), res); | 638 panic_if(!res.isScalar(), "Unexpected type of result"); 639 thread->setCCReg(idx.index(), res.asInteger()); |
628 break; 629 case MiscRegClass: | 640 break; 641 case MiscRegClass: |
642 panic_if(res.isValid(), "MiscReg expecting invalid result"); |
|
630 // Try to get the proper misc register index for ARM here... | 643 // Try to get the proper misc register index for ARM here... |
631 thread->setMiscReg(idx.index(), res); | 644 thread->setMiscReg(idx.index(), 0); |
632 break; 633 // else Register is out of range... 634 } 635 } 636} 637 638template <class Impl> 639void --- 45 unchanged lines hidden --- | 645 break; 646 // else Register is out of range... 647 } 648 } 649} 650 651template <class Impl> 652void --- 45 unchanged lines hidden --- |