cpu: Add an iterator type to RegClass.
This will enable it to be used in range based for loops, to iterate over all the RegIds which are part of a RegClass. This cleans up that sort of loop a bit, and also makes it less necessary to construct a RegId directly. Change-Id: Ia3c2aa5cf4d842465bd0948d174f51a1b92e5e3f Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/49780 Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com> Maintainer: Gabe Black <gabe.black@gmail.com> Maintainer: Giacomo Travaglini <giacomo.travaglini@arm.com> Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
@@ -42,6 +42,7 @@
|
||||
#define __CPU__REG_CLASS_HH__
|
||||
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
#include <string>
|
||||
|
||||
#include "base/cprintf.hh"
|
||||
@@ -78,6 +79,8 @@ class RegClassOps
|
||||
virtual std::string valString(const void *val, size_t size) const;
|
||||
};
|
||||
|
||||
class RegClassIterator;
|
||||
|
||||
class RegClass
|
||||
{
|
||||
private:
|
||||
@@ -120,6 +123,11 @@ class RegClass
|
||||
{
|
||||
return _ops->valString(val, regBytes());
|
||||
}
|
||||
|
||||
using iterator = RegClassIterator;
|
||||
|
||||
inline iterator begin() const;
|
||||
inline iterator end() const;
|
||||
};
|
||||
|
||||
/** Register ID: describe an architectural register with its class and index.
|
||||
@@ -136,6 +144,7 @@ class RegId
|
||||
int numPinnedWrites;
|
||||
|
||||
friend struct std::hash<RegId>;
|
||||
friend class RegClassIterator;
|
||||
|
||||
public:
|
||||
constexpr RegId() : RegId(InvalidRegClass, 0) {}
|
||||
@@ -210,6 +219,67 @@ class RegId
|
||||
}
|
||||
};
|
||||
|
||||
class RegClassIterator
|
||||
{
|
||||
private:
|
||||
RegId id;
|
||||
|
||||
RegClassIterator(const RegClass ®_class, RegIndex idx) :
|
||||
id(reg_class.type(), idx)
|
||||
{}
|
||||
|
||||
friend class RegClass;
|
||||
|
||||
public:
|
||||
using iterator_category = std::forward_iterator_tag;
|
||||
using difference_type = std::size_t;
|
||||
using value_type = const RegId;
|
||||
using pointer = value_type *;
|
||||
using reference = value_type &;
|
||||
|
||||
reference operator*() const { return id; }
|
||||
pointer operator->() { return &id; }
|
||||
|
||||
RegClassIterator &
|
||||
operator++()
|
||||
{
|
||||
id.regIdx++;
|
||||
return *this;
|
||||
}
|
||||
|
||||
RegClassIterator
|
||||
operator++(int)
|
||||
{
|
||||
auto tmp = *this;
|
||||
++(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
bool
|
||||
operator==(const RegClassIterator &other) const
|
||||
{
|
||||
return id == other.id;
|
||||
}
|
||||
|
||||
bool
|
||||
operator!=(const RegClassIterator &other) const
|
||||
{
|
||||
return id != other.id;
|
||||
}
|
||||
};
|
||||
|
||||
RegClassIterator
|
||||
RegClass::begin() const
|
||||
{
|
||||
return RegClassIterator(*this, 0);
|
||||
}
|
||||
|
||||
RegClassIterator
|
||||
RegClass::end() const
|
||||
{
|
||||
return RegClassIterator(*this, numRegs());
|
||||
}
|
||||
|
||||
template <typename ValueType>
|
||||
class TypedRegClassOps : public RegClassOps
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user