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 ---