diff --git a/src/cpu/checker/cpu_impl.hh b/src/cpu/checker/cpu_impl.hh index 638a7371b1..9d5c260d0e 100644 --- a/src/cpu/checker/cpu_impl.hh +++ b/src/cpu/checker/cpu_impl.hh @@ -471,7 +471,6 @@ Checker::validateExecution(const DynInstPtr &inst) int idx = -1; bool result_mismatch = false; bool scalar_mismatch = false; - bool vector_mismatch = false; if (inst->isUnverifiable()) { // Unverifiable instructions assume they were executed @@ -488,10 +487,7 @@ Checker::validateExecution(const DynInstPtr &inst) if (checker_val != inst_val) { result_mismatch = true; idx = i; - scalar_mismatch = checker_val.isScalar(); - vector_mismatch = checker_val.isVector(); - panic_if(!(scalar_mismatch || vector_mismatch), - "Unknown type of result\n"); + scalar_mismatch = checker_val.is(); } } } // Checker CPU checks all the saved results in the dyninst passed by @@ -504,8 +500,8 @@ Checker::validateExecution(const DynInstPtr &inst) 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()); + curTick(), idx, inst_val.asNoAssert(), + checker_val.as()); } // It's useful to verify load values from memory, but in MP @@ -590,28 +586,22 @@ Checker::copyResult( const RegId& idx = inst->destRegIdx(start_idx); switch (idx.classValue()) { case IntRegClass: - panic_if(!mismatch_val.isScalar(), "Unexpected type of result"); - thread->setIntReg(idx.index(), mismatch_val.asInteger()); + thread->setIntReg(idx.index(), mismatch_val.as()); break; case FloatRegClass: - panic_if(!mismatch_val.isScalar(), "Unexpected type of result"); - thread->setFloatReg(idx.index(), mismatch_val.asInteger()); + thread->setFloatReg(idx.index(), mismatch_val.as()); break; case VecRegClass: - panic_if(!mismatch_val.isVector(), "Unexpected type of result"); - thread->setVecReg(idx, mismatch_val.asVector()); + thread->setVecReg(idx, mismatch_val.as()); break; case VecElemClass: - panic_if(!mismatch_val.isScalar(), "Unexpected type of result"); - thread->setVecElem(idx, mismatch_val.asInteger()); + thread->setVecElem(idx, mismatch_val.as()); break; case CCRegClass: - panic_if(!mismatch_val.isScalar(), "Unexpected type of result"); - thread->setCCReg(idx.index(), mismatch_val.asInteger()); + thread->setCCReg(idx.index(), mismatch_val.as()); break; case MiscRegClass: - panic_if(!mismatch_val.isScalar(), "Unexpected type of result"); - thread->setMiscReg(idx.index(), mismatch_val.asInteger()); + thread->setMiscReg(idx.index(), mismatch_val.as()); break; default: panic("Unknown register class: %d", (int)idx.classValue()); @@ -624,27 +614,21 @@ Checker::copyResult( res = inst->popResult(); switch (idx.classValue()) { case IntRegClass: - panic_if(!res.isScalar(), "Unexpected type of result"); - thread->setIntReg(idx.index(), res.asInteger()); + thread->setIntReg(idx.index(), res.as()); break; case FloatRegClass: - panic_if(!res.isScalar(), "Unexpected type of result"); - thread->setFloatReg(idx.index(), res.asInteger()); + thread->setFloatReg(idx.index(), res.as()); break; case VecRegClass: - panic_if(!res.isVector(), "Unexpected type of result"); - thread->setVecReg(idx, res.asVector()); + thread->setVecReg(idx, res.as()); break; case VecElemClass: - panic_if(!res.isScalar(), "Unexpected type of result"); - thread->setVecElem(idx, res.asInteger()); + thread->setVecElem(idx, res.as()); break; case CCRegClass: - panic_if(!res.isScalar(), "Unexpected type of result"); - thread->setCCReg(idx.index(), res.asInteger()); + thread->setCCReg(idx.index(), res.as()); 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(), 0); break; diff --git a/src/cpu/inst_res.hh b/src/cpu/inst_res.hh index c9507ba2ef..fd84cb6c85 100644 --- a/src/cpu/inst_res.hh +++ b/src/cpu/inst_res.hh @@ -41,7 +41,6 @@ #include #include -#include "arch/vecregs.hh" #include "base/logging.hh" #include "base/types.hh" @@ -88,6 +87,10 @@ class InstResult { static_assert(!std::is_pointer_v, "InstResult shouldn't point to external data."); + // Floating point values should be converted to/from ints using + // floatToBits and bitsToFloat, and not stored in InstResult directly. + static_assert(!std::is_floating_point_v, + "Floating point values should be converted to/from ints."); } // Convert floating point values to integers. @@ -127,23 +130,21 @@ class InstResult /** Checks */ /** @{ */ - /** Is this a scalar result?. */ + + template bool - isScalar() const + is() const { - return result.type() == typeid(RegVal); + static_assert(!std::is_floating_point_v, + "Floating point values should be converted to/from ints."); + return result.type() == typeid(T); } - /** Is this a vector result?. */ - bool - isVector() const + + template + std::enable_if_t && !std::is_same_v, bool> + is() const { - return result.type() == typeid(TheISA::VecRegContainer); - } - /** Is this a predicate result?. */ - bool - isPred() const - { - return result.type() == typeid(TheISA::VecPredRegContainer); + return is(); } /** Is this a valid result?. */ @@ -152,37 +153,33 @@ class InstResult /** Explicit cast-like operations. */ /** @{ */ - RegVal - asInteger() const + template + T + as() const { - panic_if(!isScalar(), "Converting non-scalar to scalar!!"); - return std::any_cast(result); + assert(is()); + return std::any_cast(result); + } + + template + std::enable_if_t && !std::is_same_v, + RegVal> + as() const + { + return as(); } /** Cast to integer without checking type. * This is required to have the o3 cpu checker happy, as it * compares results as integers without being fully aware of * their nature. */ - RegVal - asIntegerNoAssert() const + template + T + asNoAssert() const { - if (!isScalar()) - return 0; - return std::any_cast(result); - } - - TheISA::VecRegContainer - asVector() const - { - panic_if(!isVector(), "Converting scalar (or invalid) to vector!!"); - return std::any_cast(result); - } - - TheISA::VecPredRegContainer - asPred() const - { - panic_if(!isPred(), "Converting scalar (or invalid) to predicate!!"); - return std::any_cast(result); + if (!is()) + return T{}; + return as(); } /** @} */