diff options
Diffstat (limited to 'src/cpu/checker')
-rw-r--r-- | src/cpu/checker/cpu.hh | 36 | ||||
-rw-r--r-- | src/cpu/checker/cpu_impl.hh | 55 |
2 files changed, 48 insertions, 43 deletions
diff --git a/src/cpu/checker/cpu.hh b/src/cpu/checker/cpu.hh index 304caaa85..6571d034a 100644 --- a/src/cpu/checker/cpu.hh +++ b/src/cpu/checker/cpu.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011 ARM Limited + * Copyright (c) 2011, 2016 ARM Limited * Copyright (c) 2013 Advanced Micro Devices, Inc. * All rights reserved * @@ -53,6 +53,7 @@ #include "cpu/base.hh" #include "cpu/base_dyn_inst.hh" #include "cpu/exec_context.hh" +#include "cpu/inst_res.hh" #include "cpu/pc_event.hh" #include "cpu/simple_thread.hh" #include "cpu/static_inst.hh" @@ -143,18 +144,9 @@ class CheckerCPU : public BaseCPU, public ExecContext Addr dbg_vtophys(Addr addr); - union Result { - uint64_t integer; - double dbl; - void set(uint64_t i) { integer = i; } - void set(double d) { dbl = d; } - void get(uint64_t& i) { i = integer; } - void get(double& d) { d = dbl; } - }; - // ISAs like ARM can have multiple destination registers to check, // keep them all in a std::queue - std::queue<Result> result; + std::queue<InstResult> result; // Pointer to the one memory request. RequestPtr memReq; @@ -240,12 +232,11 @@ class CheckerCPU : public BaseCPU, public ExecContext return thread->readCCReg(reg.index()); } - template <class T> - void setResult(T t) + template<typename T> + void setScalarResult(T&& t) { - Result instRes; - instRes.set(t); - result.push(instRes); + result.push(InstResult(std::forward<T>(t), + InstResult::ResultType::Scalar)); } void setIntRegOperand(const StaticInst *si, int idx, @@ -254,7 +245,7 @@ class CheckerCPU : public BaseCPU, public ExecContext const RegId& reg = si->destRegIdx(idx); assert(reg.isIntReg()); thread->setIntReg(reg.index(), val); - setResult<uint64_t>(val); + setScalarResult(val); } void setFloatRegOperand(const StaticInst *si, int idx, @@ -263,7 +254,7 @@ class CheckerCPU : public BaseCPU, public ExecContext const RegId& reg = si->destRegIdx(idx); assert(reg.isFloatReg()); thread->setFloatReg(reg.index(), val); - setResult<double>(val); + setScalarResult(val); } void setFloatRegOperandBits(const StaticInst *si, int idx, @@ -272,7 +263,7 @@ class CheckerCPU : public BaseCPU, public ExecContext const RegId& reg = si->destRegIdx(idx); assert(reg.isFloatReg()); thread->setFloatRegBits(reg.index(), val); - setResult<uint64_t>(val); + setScalarResult(val); } void setCCRegOperand(const StaticInst *si, int idx, CCReg val) override @@ -280,7 +271,7 @@ class CheckerCPU : public BaseCPU, public ExecContext const RegId& reg = si->destRegIdx(idx); assert(reg.isCCReg()); thread->setCCReg(reg.index(), val); - setResult<uint64_t>(val); + setScalarResult((uint64_t)val); } bool readPredicate() override { return thread->readPredicate(); } @@ -422,7 +413,7 @@ class CheckerCPU : public BaseCPU, public ExecContext ThreadContext *tcBase() override { return tc; } SimpleThread *threadBase() { return thread; } - Result unverifiedResult; + InstResult unverifiedResult; Request *unverifiedReq; uint8_t *unverifiedMemData; @@ -464,7 +455,8 @@ class Checker : public CheckerCPU void validateExecution(DynInstPtr &inst); void validateState(); - void copyResult(DynInstPtr &inst, uint64_t mismatch_val, int start_idx); + void copyResult(DynInstPtr &inst, const InstResult& mismatch_val, + int start_idx); void handlePendingInt(); private: diff --git a/src/cpu/checker/cpu_impl.hh b/src/cpu/checker/cpu_impl.hh index 0c90590c7..ed86aec84 100644 --- a/src/cpu/checker/cpu_impl.hh +++ b/src/cpu/checker/cpu_impl.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011 ARM Limited + * Copyright (c) 2011, 2016 ARM Limited * Copyright (c) 2013 Advanced Micro Devices, Inc. * All rights reserved * @@ -481,27 +481,29 @@ template <class Impl> void Checker<Impl>::validateExecution(DynInstPtr &inst) { - uint64_t checker_val; - uint64_t inst_val; + InstResult checker_val; + InstResult inst_val; int idx = -1; bool result_mismatch = false; + bool scalar_mismatch = false; 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, 0, idx); + copyResult(inst, InstResult(0ul, InstResult::ResultType::Scalar), idx); } else if (inst->numDestRegs() > 0 && !result.empty()) { DPRINTF(Checker, "Dest regs %d, number of checker dest regs %d\n", inst->numDestRegs(), result.size()); for (int i = 0; i < inst->numDestRegs() && !result.empty(); i++) { - result.front().get(checker_val); + checker_val = result.front(); result.pop(); - inst_val = 0; - inst->template popResult<uint64_t>(inst_val); + inst_val = inst->popResult( + InstResult(0ul, InstResult::ResultType::Scalar)); if (checker_val != inst_val) { result_mismatch = true; idx = i; + scalar_mismatch = true; break; } } @@ -512,9 +514,12 @@ Checker<Impl>::validateExecution(DynInstPtr &inst) // this is ok and not a bug. May be worthwhile to try and correct this. if (result_mismatch) { - warn("%lli: Instruction results do not match! (Values may not " - "actually be integers) Inst: %#x, checker: %#x", - curTick(), inst_val, checker_val); + if (scalar_mismatch) { + warn("%lli: Instruction results (%i) do not match! (Values may" + " not actually be integers) Inst: %#x, checker: %#x", + curTick(), idx, inst_val.asIntegerNoAssert(), + checker_val.asInteger()); + } // It's useful to verify load values from memory, but in MP // systems the value obtained at execute may be different than @@ -589,7 +594,7 @@ Checker<Impl>::validateState() template <class Impl> void -Checker<Impl>::copyResult(DynInstPtr &inst, uint64_t mismatch_val, +Checker<Impl>::copyResult(DynInstPtr &inst, const InstResult& mismatch_val, int start_idx) { // We've already popped one dest off the queue, @@ -598,37 +603,45 @@ Checker<Impl>::copyResult(DynInstPtr &inst, uint64_t mismatch_val, const RegId& idx = inst->destRegIdx(start_idx); switch (idx.classValue()) { case IntRegClass: - thread->setIntReg(idx.index(), mismatch_val); + panic_if(!mismatch_val.isScalar(), "Unexpected type of result"); + thread->setIntReg(idx.index(), mismatch_val.asInteger()); break; case FloatRegClass: - thread->setFloatRegBits(idx.index(), mismatch_val); + panic_if(!mismatch_val.isScalar(), "Unexpected type of result"); + thread->setFloatRegBits(idx.index(), mismatch_val.asInteger()); break; case CCRegClass: - thread->setCCReg(idx.index(), mismatch_val); + panic_if(!mismatch_val.isScalar(), "Unexpected type of result"); + thread->setCCReg(idx.index(), mismatch_val.asInteger()); break; case MiscRegClass: - thread->setMiscReg(idx.index(), mismatch_val); + panic_if(!mismatch_val.isScalar(), "Unexpected type of result"); + thread->setMiscReg(idx.index(), mismatch_val.asInteger()); break; } } start_idx++; - uint64_t res = 0; + InstResult res; for (int i = start_idx; i < inst->numDestRegs(); i++) { const RegId& idx = inst->destRegIdx(i); - inst->template popResult<uint64_t>(res); + res = inst->popResult(); switch (idx.classValue()) { case IntRegClass: - thread->setIntReg(idx.index(), res); + panic_if(!res.isScalar(), "Unexpected type of result"); + thread->setIntReg(idx.index(), res.asInteger()); break; case FloatRegClass: - thread->setFloatRegBits(idx.index(), res); + panic_if(!res.isScalar(), "Unexpected type of result"); + thread->setFloatRegBits(idx.index(), res.asInteger()); break; case CCRegClass: - thread->setCCReg(idx.index(), res); + panic_if(!res.isScalar(), "Unexpected type of result"); + thread->setCCReg(idx.index(), res.asInteger()); break; case MiscRegClass: + panic_if(res.isValid(), "MiscReg expecting invalid result"); // Try to get the proper misc register index for ARM here... - thread->setMiscReg(idx.index(), res); + thread->setMiscReg(idx.index(), 0); break; // else Register is out of range... } |