Gabe Black has uploaded this change for review. (
https://gem5-review.googlesource.com/c/public/gem5/+/41995 )
Change subject: arch,cpu,gpu-compute: Further simplify VecRegContainer.
......................................................................
arch,cpu,gpu-compute: Further simplify VecRegContainer.
Get rid of VecRegT, and a few redundant or unused methods.
Change-Id: I6c88c40653e1939fe74b8ffb847ef50ab8064670
---
M src/arch/arm/isa.cc
M src/arch/arm/isa.hh
M src/arch/arm/isa/templates/sve_mem.isa
M src/arch/arm/nativetrace.cc
M src/arch/arm/registers.hh
M src/arch/gcn3/operand.hh
M src/arch/gcn3/registers.hh
M src/arch/generic/vec_reg.hh
M src/arch/mips/registers.hh
M src/arch/null/registers.hh
M src/arch/power/registers.hh
M src/arch/riscv/registers.hh
M src/arch/sparc/registers.hh
M src/arch/x86/registers.hh
M src/cpu/o3/rename_map.cc
M src/gpu-compute/wavefront.cc
16 files changed, 58 insertions(+), 191 deletions(-)
diff --git a/src/arch/arm/isa.cc b/src/arch/arm/isa.cc
index c7f82e0..c86cd17 100644
--- a/src/arch/arm/isa.cc
+++ b/src/arch/arm/isa.cc
@@ -2348,15 +2348,6 @@
}
void
-ISA::zeroSveVecRegUpperPart(VecRegContainer &vc, unsigned eCount)
-{
- auto vv = vc.as<uint64_t>();
- for (int i = 2; i < eCount; ++i) {
- vv[i] = 0;
- }
-}
-
-void
ISA::serialize(CheckpointOut &cp) const
{
DPRINTF(Checkpoint, "Serializing Arm Misc Registers\n");
diff --git a/src/arch/arm/isa.hh b/src/arch/arm/isa.hh
index 7888229..62979fc 100644
--- a/src/arch/arm/isa.hh
+++ b/src/arch/arm/isa.hh
@@ -852,8 +852,16 @@
unsigned getCurSveVecLenInBitsAtReset() const { return sveVL *
128; }
- static void zeroSveVecRegUpperPart(VecRegContainer &vc,
- unsigned eCount);
+ template <typename Elem>
+ static void
+ zeroSveVecRegUpperPart(Elem *v, unsigned eCount)
+ {
+ static_assert(sizeof(Elem) <= sizeof(uint64_t));
+ eCount *= (sizeof(uint64_t) / sizeof(Elem));
+ for (int i = 16 / sizeof(Elem); i < eCount; ++i) {
+ v[i] = 0;
+ }
+ }
void serialize(CheckpointOut &cp) const override;
void unserialize(CheckpointIn &cp) override;
diff --git a/src/arch/arm/isa/templates/sve_mem.isa
b/src/arch/arm/isa/templates/sve_mem.isa
index f635870..9b1ab84 100644
--- a/src/arch/arm/isa/templates/sve_mem.isa
+++ b/src/arch/arm/isa/templates/sve_mem.isa
@@ -170,7 +170,7 @@
%(rden_code)s;
- fault = readMemAtomic(xc, EA, memData.raw_ptr<uint8_t>(),
+ fault = readMemAtomic(xc, EA, memData.as<uint8_t>(),
memAccessSize, this->memAccessFlags, rdEn);
%(fault_code)s;
@@ -228,7 +228,7 @@
auto memDataView = memData.as<MemElemType>();
if (xc->readMemAccPredicate()) {
- memcpy(memData.raw_ptr<uint8_t>(), pkt->getPtr<uint8_t>(),
+ memcpy(memData.as<uint8_t>(), pkt->getPtr<uint8_t>(),
pkt->getSize());
}
@@ -265,7 +265,7 @@
}
if (fault == NoFault) {
- fault = writeMemAtomic(xc, memData.raw_ptr<uint8_t>(),
+ fault = writeMemAtomic(xc, memData.as<uint8_t>(),
EA, memAccessSize, this->memAccessFlags, nullptr, wrEn);
}
@@ -303,7 +303,7 @@
}
if (fault == NoFault) {
- fault = writeMemTiming(xc, memData.raw_ptr<uint8_t>(),
+ fault = writeMemTiming(xc, memData.as<uint8_t>(),
EA, memAccessSize, this->memAccessFlags, nullptr, wrEn);
}
@@ -1001,7 +1001,7 @@
auto memDataView = memData.as<Element>();
if (fault == NoFault) {
- fault = readMemAtomic(xc, EA, memData.raw_ptr<uint8_t>(),
+ fault = readMemAtomic(xc, EA, memData.as<uint8_t>(),
memAccessSize, this->memAccessFlags,
std::vector<bool>(memAccessSize, true));
%(memacc_code)s;
@@ -1059,7 +1059,7 @@
ArmISA::VecRegContainer memData;
auto memDataView = memData.as<Element>();
- memcpy(memData.raw_ptr<uint8_t>(), pkt->getPtr<uint8_t>(),
+ memcpy(memData.as<uint8_t>(), pkt->getPtr<uint8_t>(),
pkt->getSize());
if (fault == NoFault) {
@@ -1100,7 +1100,7 @@
}
if (fault == NoFault) {
- fault = writeMemAtomic(xc, memData.raw_ptr<uint8_t>(),
+ fault = writeMemAtomic(xc, memData.as<uint8_t>(),
EA, memAccessSize, this->memAccessFlags, nullptr, wrEn);
}
@@ -1138,7 +1138,7 @@
}
if (fault == NoFault) {
- fault = writeMemTiming(xc, memData.raw_ptr<uint8_t>(),
+ fault = writeMemTiming(xc, memData.as<uint8_t>(),
EA, memAccessSize, this->memAccessFlags, nullptr, wrEn);
}
diff --git a/src/arch/arm/nativetrace.cc b/src/arch/arm/nativetrace.cc
index 7075adb..f37ee4d 100644
--- a/src/arch/arm/nativetrace.cc
+++ b/src/arch/arm/nativetrace.cc
@@ -126,8 +126,7 @@
changed[STATE_CPSR] = (newState[STATE_CPSR] != oldState[STATE_CPSR]);
for (int i = 0; i < NumVecV7ArchRegs; i++) {
- auto vec(tc->readVecReg(RegId(VecRegClass,i))
- .as<uint64_t, MaxSveVecLenInDWords>());
+ auto *vec = tc->readVecReg(RegId(VecRegClass,i)).as<uint64_t>();
newState[STATE_F0 + 2*i] = vec[0];
newState[STATE_F0 + 2*i + 1] = vec[1];
}
diff --git a/src/arch/arm/registers.hh b/src/arch/arm/registers.hh
index 0955906..62fb0d3 100644
--- a/src/arch/arm/registers.hh
+++ b/src/arch/arm/registers.hh
@@ -58,9 +58,8 @@
constexpr unsigned NumVecElemPerVecReg = MaxSveVecLenInWords;
using VecElem = uint32_t;
-using VecReg = ::VecRegT<VecElem, NumVecElemPerVecReg, false>;
-using ConstVecReg = ::VecRegT<VecElem, NumVecElemPerVecReg, true>;
-using VecRegContainer = VecReg::Container;
+using VecRegContainer =
+ ::VecRegContainer<NumVecElemPerVecReg * sizeof(VecElem)>;
using VecPredReg = ::VecPredRegT<VecElem, NumVecElemPerVecReg,
VecPredRegHasPackedRepr, false>;
diff --git a/src/arch/gcn3/operand.hh b/src/arch/gcn3/operand.hh
index 39d3d13..4256941 100644
--- a/src/arch/gcn3/operand.hh
+++ b/src/arch/gcn3/operand.hh
@@ -326,12 +326,8 @@
scRegData.read();
}
- using VecRegCont = typename std::conditional<NumDwords == 2,
- VecRegContainerU64, typename
std::conditional<sizeof(DataType)
- == sizeof(VecElemU16), VecRegContainerU16,
- typename std::conditional<sizeof(DataType)
- == sizeof(VecElemU8), VecRegContainerU8,
- VecRegContainerU32>::type>::type>::type;
+ using VecRegCont =
+ VecRegContainer<sizeof(DataType) * NumVecElemPerVecReg>;
/**
* whether this operand a scalar or not.
diff --git a/src/arch/gcn3/registers.hh b/src/arch/gcn3/registers.hh
index 7ad9b1f..4f5d031 100644
--- a/src/arch/gcn3/registers.hh
+++ b/src/arch/gcn3/registers.hh
@@ -168,33 +168,8 @@
typedef int64_t VecElemI64;
typedef double VecElemF64;
- // typedefs for the various sizes/types of vector regs
- using VecRegU8 = ::VecRegT<VecElemU8, NumVecElemPerVecReg, false>;
- using VecRegI8 = ::VecRegT<VecElemI8, NumVecElemPerVecReg, false>;
- using VecRegU16 = ::VecRegT<VecElemU16, NumVecElemPerVecReg, false>;
- using VecRegI16 = ::VecRegT<VecElemI16, NumVecElemPerVecReg, false>;
- using VecRegU32 = ::VecRegT<VecElemU32, NumVecElemPerVecReg, false>;
- using VecRegI32 = ::VecRegT<VecElemI32, NumVecElemPerVecReg, false>;
- using VecRegF32 = ::VecRegT<VecElemF32, NumVecElemPerVecReg, false>;
- using VecRegU64 = ::VecRegT<VecElemU64, NumVecElemPerVecReg, false>;
- using VecRegI64 = ::VecRegT<VecElemI64, NumVecElemPerVecReg, false>;
- using VecRegF64 = ::VecRegT<VecElemF64, NumVecElemPerVecReg, false>;
- // non-writeable versions of vector regs
- using ConstVecRegU8 = ::VecRegT<VecElemU8, NumVecElemPerVecReg, true>;
- using ConstVecRegI8 = ::VecRegT<VecElemI8, NumVecElemPerVecReg, true>;
- using ConstVecRegU16 = ::VecRegT<VecElemU16, NumVecElemPerVecReg,
true>;
- using ConstVecRegI16 = ::VecRegT<VecElemI16, NumVecElemPerVecReg,
true>;
- using ConstVecRegU32 = ::VecRegT<VecElemU32, NumVecElemPerVecReg,
true>;
- using ConstVecRegI32 = ::VecRegT<VecElemI32, NumVecElemPerVecReg,
true>;
- using ConstVecRegF32 = ::VecRegT<VecElemF32, NumVecElemPerVecReg,
true>;
- using ConstVecRegU64 = ::VecRegT<VecElemU64, NumVecElemPerVecReg,
true>;
- using ConstVecRegI64 = ::VecRegT<VecElemI64, NumVecElemPerVecReg,
true>;
- using ConstVecRegF64 = ::VecRegT<VecElemF64, NumVecElemPerVecReg,
true>;
-
- using VecRegContainerU8 = VecRegU8::Container;
- using VecRegContainerU16 = VecRegU16::Container;
- using VecRegContainerU32 = VecRegU32::Container;
- using VecRegContainerU64 = VecRegU64::Container;
+ using VecRegContainerU32 =
+ VecRegContainer<sizeof(VecElemU32) * NumVecElemPerVecReg>;
struct StatusReg
{
diff --git a/src/arch/generic/vec_reg.hh b/src/arch/generic/vec_reg.hh
index 48cd4bd..1f0df1c 100644
--- a/src/arch/generic/vec_reg.hh
+++ b/src/arch/generic/vec_reg.hh
@@ -97,9 +97,9 @@
#define __ARCH_GENERIC_VEC_REG_HH__
#include <array>
+#include <cstdint>
#include <iostream>
#include <string>
-#include <type_traits>
#include "base/cprintf.hh"
#include "base/logging.hh"
@@ -107,81 +107,6 @@
constexpr unsigned MaxVecRegLenInBytes = 4096;
-template <size_t Sz>
-class VecRegContainer;
-
-/** Vector Register Abstraction
- * This generic class is a view in a particularization of MVC, to vector
- * registers. There is a VecRegContainer that implements the model, and
- * contains the data. To that model we can interpose different
instantiations
- * of VecRegT to view the container as a vector of NumElems elems of type
- * VecElem.
- * @tparam VecElem Type of each element of the vector.
- * @tparam NumElems Amount of components of the vector.
- * @tparam Const Indicate if the underlying container can be modified
through
- * the view.
- */
-template <typename VecElem, size_t NumElems, bool Const>
-class VecRegT
-{
- private:
- /** Size of the register in bytes. */
- static constexpr inline size_t
- size()
- {
- return sizeof(VecElem) * NumElems;
- }
-
- public:
- /** Container type alias. */
- using Container = typename std::conditional<Const,
- const
VecRegContainer<size()>,
-
VecRegContainer<size()>>::type;
- private:
- /** My type alias. */
- using MyClass = VecRegT<VecElem, NumElems, Const>;
- /** Reference to container. */
- Container& container;
-
- public:
- /** Constructor. */
- VecRegT(Container& cnt) : container(cnt) {};
-
- /** Index operator. */
- const VecElem &
- operator[](size_t idx) const
- {
- return container.template raw_ptr<VecElem>()[idx];
- }
-
- /** Index operator. */
- template<bool Condition = !Const>
- typename std::enable_if_t<Condition, VecElem&>
- operator[](size_t idx)
- {
- return container.template raw_ptr<VecElem>()[idx];
- }
-
- /** Output stream operator. */
- friend std::ostream&
- operator<<(std::ostream& os, const MyClass& vr)
- {
- /* 0-sized is not allowed */
- os << "[" << std::hex << (uint32_t)vr[0];
- for (uint32_t e = 1; e < vr.size(); e++)
- os << " " << std::hex << (uint32_t)vr[e];
- os << ']';
- return os;
- }
-
- /**
- * Cast to VecRegContainer&
- * It is useful to get the reference to the container for ISA tricks,
- * because casting to reference prevents unnecessary copies.
- */
- operator Container&() { return container; }
-};
-
/**
* Vector Register Abstraction
* This generic class is the model in a particularization of MVC, to vector
@@ -203,7 +128,6 @@
private:
// 16-byte aligned to support 128bit element view
alignas(16) Container container;
- using MyClass = VecRegContainer<SIZE>;
public:
VecRegContainer() {}
@@ -215,19 +139,11 @@
/** Assignment operators. */
/** @{ */
/** From VecRegContainer */
- MyClass&
- operator=(const MyClass& that)
+ VecRegContainer<SIZE>&
+ operator=(const VecRegContainer<SIZE>& that)
{
- if (&that == this)
- return *this;
- return *this = that.container;
- }
-
- /** From appropriately sized uint8_t[]. */
- MyClass&
- operator=(const Container& that)
- {
- std::memcpy(container.data(), that.data(), SIZE);
+ if (&that != this)
+ std::memcpy(container.data(), that.container.data(), SIZE);
return *this;
}
/** @} */
@@ -252,13 +168,6 @@
return !operator==(that);
}
- /** Get pointer to bytes. */
- template <typename Ret>
- const Ret* raw_ptr() const { return (const Ret*)container.data(); }
-
- template <typename Ret>
- Ret* raw_ptr() { return (Ret*)container.data(); }
-
/**
* View interposers.
* Create a view of this container as a vector of VecElems with an
@@ -270,34 +179,37 @@
* @tparam NumElem Amount of elements in the view.
*/
/** @{ */
- template <typename VecElem, size_t NumElems=(SIZE / sizeof(VecElem))>
- VecRegT<VecElem, NumElems, true>
- as() const
- {
- static_assert(SIZE % sizeof(VecElem) == 0,
- "VecElem does not evenly divide the register size");
- static_assert(sizeof(VecElem) * NumElems <= SIZE,
- "Viewing VecReg as something bigger than it is");
- return VecRegT<VecElem, NumElems, true>(*this);
- }
-
- template <typename VecElem, size_t NumElems=(SIZE / sizeof(VecElem))>
- VecRegT<VecElem, NumElems, false>
+ template <typename VecElem>
+ VecElem *
as()
{
static_assert(SIZE % sizeof(VecElem) == 0,
"VecElem does not evenly divide the register size");
- static_assert(sizeof(VecElem) * NumElems <= SIZE,
- "Viewing VecReg as something bigger than it is");
- return VecRegT<VecElem, NumElems, false>(*this);
+ return (VecElem *)container.data();
+ }
+
+ template <typename VecElem>
+ const VecElem *
+ as() const
+ {
+ static_assert(SIZE % sizeof(VecElem) == 0,
+ "VecElem does not evenly divide the register size");
+ return (VecElem *)container.data();
}
friend std::ostream&
- operator<<(std::ostream& os, const MyClass& v)
+ operator<<(std::ostream& os, const VecRegContainer<SIZE>& v)
{
+ // When printing for human consumption, break into 4 byte chunks.
+ ccprintf(os, "[");
+ size_t count = 0;
for (auto& b: v.container) {
+ if (count && (count % 4) == 0)
+ os << " ";
ccprintf(os, "%02x", b);
+ count++;
}
+ ccprintf(os, "]");
return os;
}
@@ -305,7 +217,7 @@
/**
* Used for serialization.
*/
- friend ShowParam<MyClass>;
+ friend ShowParam<VecRegContainer<SIZE>>;
};
/**
@@ -325,7 +237,7 @@
uint8_t b = 0;
if (2 * i < value.size())
b = stoul(s.substr(i * 2, 2), nullptr, 16);
- value.template raw_ptr<uint8_t>()[i] = b;
+ value.template as<uint8_t>()[i] = b;
}
return true;
}
@@ -350,9 +262,8 @@
/** @{ */
using DummyVecElem = uint32_t;
constexpr unsigned DummyNumVecElemPerVecReg = 2;
-using DummyVecReg = VecRegT<DummyVecElem, DummyNumVecElemPerVecReg, false>;
-using DummyConstVecReg = VecRegT<DummyVecElem, DummyNumVecElemPerVecReg,
true>;
-using DummyVecRegContainer = DummyVecReg::Container;
+using DummyVecRegContainer =
+ VecRegContainer<DummyNumVecElemPerVecReg * sizeof(DummyVecElem)>;
constexpr size_t DummyVecRegSizeBytes = DummyNumVecElemPerVecReg *
sizeof(DummyVecElem);
/** @} */
diff --git a/src/arch/mips/registers.hh b/src/arch/mips/registers.hh
index a9d2661..18c0d58 100644
--- a/src/arch/mips/registers.hh
+++ b/src/arch/mips/registers.hh
@@ -270,8 +270,6 @@
// Not applicable to MIPS
using VecElem = ::DummyVecElem;
-using VecReg = ::DummyVecReg;
-using ConstVecReg = ::DummyConstVecReg;
using VecRegContainer = ::DummyVecRegContainer;
constexpr unsigned NumVecElemPerVecReg = ::DummyNumVecElemPerVecReg;
constexpr size_t VecRegSizeBytes = ::DummyVecRegSizeBytes;
diff --git a/src/arch/null/registers.hh b/src/arch/null/registers.hh
index 3e96472..d56a6a7 100644
--- a/src/arch/null/registers.hh
+++ b/src/arch/null/registers.hh
@@ -49,8 +49,6 @@
// Not applicable to null
using VecElem = ::DummyVecElem;
-using VecReg = ::DummyVecReg;
-using ConstVecReg = ::DummyConstVecReg;
using VecRegContainer = ::DummyVecRegContainer;
constexpr unsigned NumVecElemPerVecReg = ::DummyNumVecElemPerVecReg;
constexpr size_t VecRegSizeBytes = ::DummyVecRegSizeBytes;
diff --git a/src/arch/power/registers.hh b/src/arch/power/registers.hh
index 2a1aea5..5fc2200 100644
--- a/src/arch/power/registers.hh
+++ b/src/arch/power/registers.hh
@@ -39,8 +39,6 @@
// Not applicable to Power
using VecElem = ::DummyVecElem;
-using VecReg = ::DummyVecReg;
-using ConstVecReg = ::DummyConstVecReg;
using VecRegContainer = ::DummyVecRegContainer;
constexpr unsigned NumVecElemPerVecReg = ::DummyNumVecElemPerVecReg;
constexpr size_t VecRegSizeBytes = ::DummyVecRegSizeBytes;
diff --git a/src/arch/riscv/registers.hh b/src/arch/riscv/registers.hh
index 862259f..e7f3e11 100644
--- a/src/arch/riscv/registers.hh
+++ b/src/arch/riscv/registers.hh
@@ -93,8 +93,6 @@
// Not applicable to RISC-V
using VecElem = ::DummyVecElem;
-using VecReg = ::DummyVecReg;
-using ConstVecReg = ::DummyConstVecReg;
using VecRegContainer = ::DummyVecRegContainer;
constexpr unsigned NumVecElemPerVecReg = ::DummyNumVecElemPerVecReg;
constexpr size_t VecRegSizeBytes = ::DummyVecRegSizeBytes;
diff --git a/src/arch/sparc/registers.hh b/src/arch/sparc/registers.hh
index 0602176..aa263a9 100644
--- a/src/arch/sparc/registers.hh
+++ b/src/arch/sparc/registers.hh
@@ -40,8 +40,6 @@
// Not applicable to SPARC
using VecElem = ::DummyVecElem;
-using VecReg = ::DummyVecReg;
-using ConstVecReg = ::DummyConstVecReg;
using VecRegContainer = ::DummyVecRegContainer;
constexpr unsigned NumVecElemPerVecReg = ::DummyNumVecElemPerVecReg;
constexpr size_t VecRegSizeBytes = ::DummyVecRegSizeBytes;
diff --git a/src/arch/x86/registers.hh b/src/arch/x86/registers.hh
index a29f1b8..769f6da 100644
--- a/src/arch/x86/registers.hh
+++ b/src/arch/x86/registers.hh
@@ -83,8 +83,6 @@
// Not applicable to x86
using VecElem = ::DummyVecElem;
-using VecReg = ::DummyVecReg;
-using ConstVecReg = ::DummyConstVecReg;
using VecRegContainer = ::DummyVecRegContainer;
constexpr unsigned NumVecElemPerVecReg = ::DummyNumVecElemPerVecReg;
constexpr size_t VecRegSizeBytes = ::DummyVecRegSizeBytes;
diff --git a/src/cpu/o3/rename_map.cc b/src/cpu/o3/rename_map.cc
index cda9924..0edafcf 100644
--- a/src/cpu/o3/rename_map.cc
+++ b/src/cpu/o3/rename_map.cc
@@ -200,7 +200,7 @@
*/
TheISA::VecRegContainer new_RF[TheISA::NumVecRegs];
for (uint32_t i = 0; i < TheISA::NumVecRegs; i++) {
- TheISA::VecReg dst = new_RF[i].as<TheISA::VecElem>();
+ TheISA::VecElem *dst = new_RF[i].as<TheISA::VecElem>();
for (uint32_t l = 0; l < TheISA::NumVecElemPerVecReg; l++) {
RegId s_rid(VecElemClass, i, l);
PhysRegIdPtr s_prid = vecElemMap.lookup(s_rid);
diff --git a/src/gpu-compute/wavefront.cc b/src/gpu-compute/wavefront.cc
index e442e2a..c5a6d24 100644
--- a/src/gpu-compute/wavefront.cc
+++ b/src/gpu-compute/wavefront.cc
@@ -453,7 +453,7 @@
{
physVgprIdx = computeUnit->registerManager
->mapVgpr(this, regInitIdx);
- TheGpuISA::VecRegU32 vgpr_x
+ TheGpuISA::VecElemU32 *vgpr_x
= raw_vgpr.as<TheGpuISA::VecElemU32>();
for (int lane = 0; lane < workItemId[0].size();
++lane) {
@@ -469,7 +469,7 @@
{
physVgprIdx = computeUnit->registerManager
->mapVgpr(this, regInitIdx);
- TheGpuISA::VecRegU32 vgpr_y
+ TheGpuISA::VecElemU32 *vgpr_y
= raw_vgpr.as<TheGpuISA::VecElemU32>();
for (int lane = 0; lane < workItemId[1].size();
++lane) {
@@ -485,7 +485,7 @@
{
physVgprIdx = computeUnit->registerManager->
mapVgpr(this, regInitIdx);
- TheGpuISA::VecRegU32 vgpr_z
+ TheGpuISA::VecElemU32 *vgpr_z
= raw_vgpr.as<TheGpuISA::VecElemU32>();
for (int lane = 0; lane < workItemId[2].size();
++lane) {
--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/41995
To unsubscribe, or for help writing mail filters, visit
https://gem5-review.googlesource.com/settings
Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: I6c88c40653e1939fe74b8ffb847ef50ab8064670
Gerrit-Change-Number: 41995
Gerrit-PatchSet: 1
Gerrit-Owner: Gabe Black <gabe.bl...@gmail.com>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list -- gem5-dev@gem5.org
To unsubscribe send an email to gem5-dev-le...@gem5.org
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s