arch,cpu: Stop using << and to_number for VecReg serialization.

Override ParseParam<>::parse and ShowParam<>::parse directly. This will
allow using a different format for serializing and displaying registers.

Also get rid of the print() methods. When any cprintf based mechanism is
used (like DPRINTF), the underlying mechanism will use << to output the
value. Since we already override <<, there's no reason to wrap that in a
method which calls csprintf which calls << anyway.

Change-Id: Id65b9a657507f2f2cdf9673fd961cfeb0590f48c
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/41994
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Maintainer: Giacomo Travaglini <giacomo.travaglini@arm.com>
This commit is contained in:
Gabe Black
2021-02-25 05:24:56 -08:00
parent b6ae52f3ae
commit 454ffc5eb2
3 changed files with 38 additions and 44 deletions

View File

@@ -97,14 +97,13 @@
#define __ARCH_GENERIC_VEC_REG_HH__
#include <array>
#include <cassert>
#include <iostream>
#include <string>
#include <type_traits>
#include <vector>
#include "base/cprintf.hh"
#include "base/logging.hh"
#include "sim/serialize_handlers.hh"
constexpr unsigned MaxVecRegLenInBytes = 4096;
@@ -175,8 +174,6 @@ class VecRegT
return os;
}
const std::string print() const { return csprintf("%s", *this); }
/**
* Cast to VecRegContainer&
* It is useful to get the reference to the container for ISA tricks,
@@ -211,12 +208,6 @@ class VecRegContainer
public:
VecRegContainer() {}
VecRegContainer(const VecRegContainer &) = default;
/* This is required for de-serialisation. */
VecRegContainer(const std::vector<uint8_t>& that)
{
assert(that.size() >= SIZE);
std::memcpy(container.data(), &that[0], SIZE);
}
/** Zero the container. */
void zero() { memset(container.data(), 0, SIZE); }
@@ -239,17 +230,6 @@ class VecRegContainer
std::memcpy(container.data(), that.data(), SIZE);
return *this;
}
/** From vector<uint8_t>.
* This is required for de-serialisation.
* */
MyClass&
operator=(const std::vector<uint8_t>& that)
{
assert(that.size() >= SIZE);
std::memcpy(container.data(), that.data(), SIZE);
return *this;
}
/** @} */
/** Equality operator.
@@ -272,7 +252,6 @@ class VecRegContainer
return !operator==(that);
}
const std::string print() const { return csprintf("%s", *this); }
/** Get pointer to bytes. */
template <typename Ret>
const Ret* raw_ptr() const { return (const Ret*)container.data(); }
@@ -313,19 +292,20 @@ class VecRegContainer
return VecRegT<VecElem, NumElems, false>(*this);
}
/** @} */
/**
* Output operator.
* Used for serialization.
*/
friend std::ostream&
operator<<(std::ostream& os, const MyClass& v)
{
for (auto& b: v.container) {
os << csprintf("%02x", b);
ccprintf(os, "%02x", b);
}
return os;
}
/** @} */
/**
* Used for serialization.
*/
friend ShowParam<MyClass>;
};
/**
@@ -333,20 +313,34 @@ class VecRegContainer
*/
/** @{ */
template <size_t Sz>
inline bool
to_number(const std::string& value, VecRegContainer<Sz>& v)
struct ParseParam<VecRegContainer<Sz>>
{
fatal_if(value.size() > 2 * VecRegContainer<Sz>::size(),
"Vector register value overflow at unserialize");
static bool
parse(const std::string &str, VecRegContainer<Sz> &value)
{
fatal_if(str.size() > 2 * Sz,
"Vector register value overflow at unserialize");
for (int i = 0; i < VecRegContainer<Sz>::size(); i++) {
uint8_t b = 0;
if (2 * i < value.size())
b = stoul(value.substr(i * 2, 2), nullptr, 16);
v.template raw_ptr<uint8_t>()[i] = b;
for (int i = 0; i < Sz; i++) {
uint8_t b = 0;
if (2 * i < value.size())
b = stoul(str.substr(i * 2, 2), nullptr, 16);
value.template raw_ptr<uint8_t>()[i] = b;
}
return true;
}
return true;
}
};
template <size_t Sz>
struct ShowParam<VecRegContainer<Sz>>
{
static void
show(std::ostream &os, const VecRegContainer<Sz> &value)
{
for (auto& b: value.container)
ccprintf(os, "%02x", b);
}
};
/** @} */
/**

View File

@@ -203,7 +203,7 @@ class PhysRegFile
DPRINTF(IEW, "RegFile: Access to vector register %i, has "
"data %s\n", int(phys_reg->index()),
vectorRegFile[phys_reg->index()].print());
vectorRegFile[phys_reg->index()]);
return vectorRegFile[phys_reg->index()];
}
@@ -296,7 +296,7 @@ class PhysRegFile
assert(phys_reg->isVectorPhysReg());
DPRINTF(IEW, "RegFile: Setting vector register %i to %s\n",
int(phys_reg->index()), val.print());
int(phys_reg->index()), val);
vectorRegFile[phys_reg->index()] = val;
}

View File

@@ -295,7 +295,7 @@ class SimpleThread : public ThreadState, public ThreadContext
assert(flatIndex < TheISA::NumVecRegs);
const TheISA::VecRegContainer& regVal = readVecRegFlat(flatIndex);
DPRINTF(VecRegs, "Reading vector reg %d (%d) as %s.\n",
reg.index(), flatIndex, regVal.print());
reg.index(), flatIndex, regVal);
return regVal;
}
@@ -306,7 +306,7 @@ class SimpleThread : public ThreadState, public ThreadContext
assert(flatIndex < TheISA::NumVecRegs);
TheISA::VecRegContainer& regVal = getWritableVecRegFlat(flatIndex);
DPRINTF(VecRegs, "Reading vector reg %d (%d) as %s for modify.\n",
reg.index(), flatIndex, regVal.print());
reg.index(), flatIndex, regVal);
return regVal;
}
@@ -389,7 +389,7 @@ class SimpleThread : public ThreadState, public ThreadContext
assert(flatIndex < TheISA::NumVecRegs);
setVecRegFlat(flatIndex, val);
DPRINTF(VecRegs, "Setting vector reg %d (%d) to %s.\n",
reg.index(), flatIndex, val.print());
reg.index(), flatIndex, val);
}
void