From abf6b8b7b641648e2b26157fd3876c8c41670141 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 9 Aug 2021 02:41:05 -0700 Subject: [PATCH] cpu: Generalize the vec reg types out of InstResult. Use templates to delegate knowing what these types are to whatever is using InstResult. This will need to be even more generalized at these call sights so that we don't just push around the dependencies, but that will have to be handled later. Change-Id: I45915d70ea06caed06f0ccf356f9e2e1acbd6c61 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/49131 Reviewed-by: Yu-hsin Wang Maintainer: Gabe Black Tested-by: kokoro --- src/cpu/checker/cpu_impl.hh | 44 ++++++++--------------- src/cpu/inst_res.hh | 71 ++++++++++++++++++------------------- 2 files changed, 48 insertions(+), 67 deletions(-) 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(); } /** @} */