cpu_impl.hh

来自「M5,一个功能强大的多处理器系统模拟器.很多针对处理器架构,性能的研究都使用它作」· HH 代码 · 共 484 行 · 第 1/2 页

HH
484
字号
            newPC = thread->readPC();            DPRINTF(Checker, "Fault, PC is now %#x\n", newPC);#endif        } else {#if THE_ISA != MIPS_ISA            // go to the next instruction            thread->setPC(thread->readNextPC());            thread->setNextPC(thread->readNextPC() + sizeof(MachInst));#else            // go to the next instruction            thread->setPC(thread->readNextPC());            thread->setNextPC(thread->readNextNPC());            thread->setNextNPC(thread->readNextNPC() + sizeof(MachInst));#endif        }#if FULL_SYSTEM        // @todo: Determine if these should happen only if the        // instruction hasn't faulted.  In the SimpleCPU case this may        // not be true, but in the O3 or Ozone case this may be true.        Addr oldpc;        int count = 0;        do {            oldpc = thread->readPC();            system->pcEventQueue.service(tc);            count++;        } while (oldpc != thread->readPC());        if (count > 1) {            willChangePC = true;            newPC = thread->readPC();            DPRINTF(Checker, "PC Event, PC is now %#x\n", newPC);        }#endif        // @todo:  Optionally can check all registers. (Or just those        // that have been modified).        validateState();        if (memReq) {            delete memReq;            memReq = NULL;        }        // Continue verifying instructions if there's another completed        // instruction waiting to be verified.        if (instList.empty()) {            break;        } else if (instList.front()->isCompleted()) {            inst = instList.front();            instList.pop_front();        } else {            break;        }    }    unverifiedInst = NULL;}template <class DynInstPtr>voidChecker<DynInstPtr>::switchOut(){    instList.clear();}template <class DynInstPtr>voidChecker<DynInstPtr>::takeOverFrom(BaseCPU *oldCPU){}template <class DynInstPtr>voidChecker<DynInstPtr>::validateInst(DynInstPtr &inst){    if (inst->readPC() != thread->readPC()) {        warn("%lli: PCs do not match! Inst: %#x, checker: %#x",             curTick, inst->readPC(), thread->readPC());        if (changedPC) {            warn("%lli: Changed PCs recently, may not be an error",                 curTick);        } else {            handleError(inst);        }    }    MachInst mi = static_cast<MachInst>(inst->staticInst->machInst);    if (mi != machInst) {        warn("%lli: Binary instructions do not match! Inst: %#x, "             "checker: %#x",             curTick, mi, machInst);        handleError(inst);    }}template <class DynInstPtr>voidChecker<DynInstPtr>::validateExecution(DynInstPtr &inst){    bool result_mismatch = false;    if (inst->numDestRegs()) {        // @todo: Support more destination registers.        if (inst->isUnverifiable()) {            // Unverifiable instructions assume they were executed            // properly by the CPU. Grab the result from the            // instruction and write it to the register.            copyResult(inst);        } else if (result.integer != inst->readIntResult()) {            result_mismatch = true;        }    }    if (result_mismatch) {        warn("%lli: Instruction results do not match! (Values may not "             "actually be integers) Inst: %#x, checker: %#x",             curTick, inst->readIntResult(), result.integer);        // It's useful to verify load values from memory, but in MP        // systems the value obtained at execute may be different than        // the value obtained at completion.  Similarly DMA can        // present the same problem on even UP systems.  Thus there is        // the option to only warn on loads having a result error.        if (inst->isLoad() && warnOnlyOnLoadError) {            copyResult(inst);        } else {            handleError(inst);        }    }    if (inst->readNextPC() != thread->readNextPC()) {        warn("%lli: Instruction next PCs do not match! Inst: %#x, "             "checker: %#x",             curTick, inst->readNextPC(), thread->readNextPC());        handleError(inst);    }    // Checking side effect registers can be difficult if they are not    // checked simultaneously with the execution of the instruction.    // This is because other valid instructions may have modified    // these registers in the meantime, and their values are not    // stored within the DynInst.    while (!miscRegIdxs.empty()) {        int misc_reg_idx = miscRegIdxs.front();        miscRegIdxs.pop();        if (inst->tcBase()->readMiscRegNoEffect(misc_reg_idx) !=            thread->readMiscRegNoEffect(misc_reg_idx)) {            warn("%lli: Misc reg idx %i (side effect) does not match! "                 "Inst: %#x, checker: %#x",                 curTick, misc_reg_idx,                 inst->tcBase()->readMiscRegNoEffect(misc_reg_idx),                 thread->readMiscRegNoEffect(misc_reg_idx));            handleError(inst);        }    }}template <class DynInstPtr>voidChecker<DynInstPtr>::validateState(){    if (updateThisCycle) {        warn("%lli: Instruction PC %#x results didn't match up, copying all "             "registers from main CPU", curTick, unverifiedInst->readPC());        // Heavy-weight copying of all registers        thread->copyArchRegs(unverifiedInst->tcBase());        // Also advance the PC.  Hopefully no PC-based events happened.#if THE_ISA != MIPS_ISA        // go to the next instruction        thread->setPC(thread->readNextPC());        thread->setNextPC(thread->readNextPC() + sizeof(MachInst));#else        // go to the next instruction        thread->setPC(thread->readNextPC());        thread->setNextPC(thread->readNextNPC());        thread->setNextNPC(thread->readNextNPC() + sizeof(MachInst));#endif        updateThisCycle = false;    }}template <class DynInstPtr>voidChecker<DynInstPtr>::copyResult(DynInstPtr &inst){    RegIndex idx = inst->destRegIdx(0);    if (idx < TheISA::FP_Base_DepTag) {        thread->setIntReg(idx, inst->readIntResult());    } else if (idx < TheISA::Fpcr_DepTag) {        thread->setFloatRegBits(idx, inst->readIntResult());    } else {        thread->setMiscRegNoEffect(idx, inst->readIntResult());    }}template <class DynInstPtr>voidChecker<DynInstPtr>::dumpAndExit(DynInstPtr &inst){    cprintf("Error detected, instruction information:\n");    cprintf("PC:%#x, nextPC:%#x\n[sn:%lli]\n[tid:%i]\n"            "Completed:%i\n",            inst->readPC(),            inst->readNextPC(),            inst->seqNum,            inst->threadNumber,            inst->isCompleted());    inst->dump();    CheckerCPU::dumpAndExit();}template <class DynInstPtr>voidChecker<DynInstPtr>::dumpInsts(){    int num = 0;    InstListIt inst_list_it = --(instList.end());    cprintf("Inst list size: %i\n", instList.size());    while (inst_list_it != instList.end())    {        cprintf("Instruction:%i\n",                num);        cprintf("PC:%#x\n[sn:%lli]\n[tid:%i]\n"                "Completed:%i\n",                (*inst_list_it)->readPC(),                (*inst_list_it)->seqNum,                (*inst_list_it)->threadNumber,                (*inst_list_it)->isCompleted());        cprintf("\n");        inst_list_it--;        ++num;    }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?