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 <yuhsingw@google.com> Maintainer: Gabe Black <gabe.black@gmail.com> Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
@@ -471,7 +471,6 @@ Checker<DynInstPtr>::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<DynInstPtr>::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<RegVal>();
|
||||
}
|
||||
}
|
||||
} // Checker CPU checks all the saved results in the dyninst passed by
|
||||
@@ -504,8 +500,8 @@ Checker<DynInstPtr>::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<RegVal>(),
|
||||
checker_val.as<RegVal>());
|
||||
}
|
||||
|
||||
// It's useful to verify load values from memory, but in MP
|
||||
@@ -590,28 +586,22 @@ Checker<DynInstPtr>::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<RegVal>());
|
||||
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<RegVal>());
|
||||
break;
|
||||
case VecRegClass:
|
||||
panic_if(!mismatch_val.isVector(), "Unexpected type of result");
|
||||
thread->setVecReg(idx, mismatch_val.asVector());
|
||||
thread->setVecReg(idx, mismatch_val.as<TheISA::VecRegContainer>());
|
||||
break;
|
||||
case VecElemClass:
|
||||
panic_if(!mismatch_val.isScalar(), "Unexpected type of result");
|
||||
thread->setVecElem(idx, mismatch_val.asInteger());
|
||||
thread->setVecElem(idx, mismatch_val.as<RegVal>());
|
||||
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<RegVal>());
|
||||
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<RegVal>());
|
||||
break;
|
||||
default:
|
||||
panic("Unknown register class: %d", (int)idx.classValue());
|
||||
@@ -624,27 +614,21 @@ Checker<DynInstPtr>::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<RegVal>());
|
||||
break;
|
||||
case FloatRegClass:
|
||||
panic_if(!res.isScalar(), "Unexpected type of result");
|
||||
thread->setFloatReg(idx.index(), res.asInteger());
|
||||
thread->setFloatReg(idx.index(), res.as<RegVal>());
|
||||
break;
|
||||
case VecRegClass:
|
||||
panic_if(!res.isVector(), "Unexpected type of result");
|
||||
thread->setVecReg(idx, res.asVector());
|
||||
thread->setVecReg(idx, res.as<TheISA::VecRegContainer>());
|
||||
break;
|
||||
case VecElemClass:
|
||||
panic_if(!res.isScalar(), "Unexpected type of result");
|
||||
thread->setVecElem(idx, res.asInteger());
|
||||
thread->setVecElem(idx, res.as<RegVal>());
|
||||
break;
|
||||
case CCRegClass:
|
||||
panic_if(!res.isScalar(), "Unexpected type of result");
|
||||
thread->setCCReg(idx.index(), res.asInteger());
|
||||
thread->setCCReg(idx.index(), res.as<RegVal>());
|
||||
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;
|
||||
|
||||
@@ -41,7 +41,6 @@
|
||||
#include <any>
|
||||
#include <type_traits>
|
||||
|
||||
#include "arch/vecregs.hh"
|
||||
#include "base/logging.hh"
|
||||
#include "base/types.hh"
|
||||
|
||||
@@ -88,6 +87,10 @@ class InstResult
|
||||
{
|
||||
static_assert(!std::is_pointer_v<T>,
|
||||
"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<T>,
|
||||
"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 <typename T>
|
||||
bool
|
||||
isScalar() const
|
||||
is() const
|
||||
{
|
||||
return result.type() == typeid(RegVal);
|
||||
static_assert(!std::is_floating_point_v<T>,
|
||||
"Floating point values should be converted to/from ints.");
|
||||
return result.type() == typeid(T);
|
||||
}
|
||||
/** Is this a vector result?. */
|
||||
bool
|
||||
isVector() const
|
||||
|
||||
template <typename T>
|
||||
std::enable_if_t<std::is_integral_v<T> && !std::is_same_v<T, RegVal>, 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<RegVal>();
|
||||
}
|
||||
|
||||
/** Is this a valid result?. */
|
||||
@@ -152,37 +153,33 @@ class InstResult
|
||||
|
||||
/** Explicit cast-like operations. */
|
||||
/** @{ */
|
||||
RegVal
|
||||
asInteger() const
|
||||
template <typename T>
|
||||
T
|
||||
as() const
|
||||
{
|
||||
panic_if(!isScalar(), "Converting non-scalar to scalar!!");
|
||||
return std::any_cast<RegVal>(result);
|
||||
assert(is<T>());
|
||||
return std::any_cast<T>(result);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::enable_if_t<std::is_integral_v<T> && !std::is_same_v<T, RegVal>,
|
||||
RegVal>
|
||||
as() const
|
||||
{
|
||||
return as<RegVal>();
|
||||
}
|
||||
|
||||
/** 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 <typename T>
|
||||
T
|
||||
asNoAssert() const
|
||||
{
|
||||
if (!isScalar())
|
||||
return 0;
|
||||
return std::any_cast<RegVal>(result);
|
||||
}
|
||||
|
||||
TheISA::VecRegContainer
|
||||
asVector() const
|
||||
{
|
||||
panic_if(!isVector(), "Converting scalar (or invalid) to vector!!");
|
||||
return std::any_cast<TheISA::VecRegContainer>(result);
|
||||
}
|
||||
|
||||
TheISA::VecPredRegContainer
|
||||
asPred() const
|
||||
{
|
||||
panic_if(!isPred(), "Converting scalar (or invalid) to predicate!!");
|
||||
return std::any_cast<TheISA::VecPredRegContainer>(result);
|
||||
if (!is<T>())
|
||||
return T{};
|
||||
return as<T>();
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
Reference in New Issue
Block a user