summaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
authorGiacomo Gabrielli <giacomo.gabrielli@arm.com>2018-10-16 16:04:08 +0100
committerGiacomo Gabrielli <giacomo.gabrielli@arm.com>2019-01-30 16:57:54 +0000
commit25474167e5b247d1b91fbf802c5b396a63ae705e (patch)
treeb509597b23d792734f55c33b8125eebfbd9cd3a5 /src/arch
parentc6f5db8743f19b02a38146d9cf2a829883387008 (diff)
downloadgem5-25474167e5b247d1b91fbf802c5b396a63ae705e.tar.xz
arch,cpu: Add vector predicate registers
Latest-gen. vector/SIMD extensions, including the Arm Scalable Vector Extension (SVE), introduce the notion of a predicate register file. This changeset adds this feature across architectures and CPU models. Change-Id: Iebcadbad89c0a582ff8b1b70de353305db603946 Signed-off-by: Giacomo Gabrielli <giacomo.gabrielli@arm.com> Reviewed-on: https://gem5-review.googlesource.com/c/13715 Maintainer: Andreas Sandberg <andreas.sandberg@arm.com> Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/SConscript6
-rw-r--r--src/arch/alpha/isa.hh6
-rw-r--r--src/arch/alpha/registers.hh27
-rw-r--r--src/arch/arm/isa.hh10
-rw-r--r--src/arch/arm/registers.hh15
-rw-r--r--src/arch/generic/vec_pred_reg.hh404
-rw-r--r--src/arch/generic/vec_reg.hh14
-rwxr-xr-xsrc/arch/isa_parser.py94
-rw-r--r--src/arch/mips/isa.hh6
-rw-r--r--src/arch/mips/registers.hh27
-rw-r--r--src/arch/null/registers.hh23
-rw-r--r--src/arch/power/isa.hh6
-rw-r--r--src/arch/power/registers.hh27
-rw-r--r--src/arch/riscv/isa.hh1
-rw-r--r--src/arch/riscv/registers.hh29
-rw-r--r--src/arch/sparc/isa.hh6
-rw-r--r--src/arch/sparc/registers.hh27
-rw-r--r--src/arch/x86/isa.hh6
-rw-r--r--src/arch/x86/registers.hh28
19 files changed, 700 insertions, 62 deletions
diff --git a/src/arch/SConscript b/src/arch/SConscript
index 5ea7a6a75..ed583aa5a 100644
--- a/src/arch/SConscript
+++ b/src/arch/SConscript
@@ -1,6 +1,6 @@
# -*- mode:python -*-
-# Copyright (c) 2016 ARM Limited
+# Copyright (c) 2016-2017 ARM Limited
# All rights reserved.
#
# The license below extends only to copyright in the software and shall
@@ -226,6 +226,8 @@ Export('ISADesc')
DebugFlag('IntRegs')
DebugFlag('FloatRegs')
DebugFlag('VecRegs')
+DebugFlag('VecPredRegs')
DebugFlag('CCRegs')
DebugFlag('MiscRegs')
-CompoundFlag('Registers', [ 'IntRegs', 'FloatRegs', 'CCRegs', 'MiscRegs' ])
+CompoundFlag('Registers', [ 'IntRegs', 'FloatRegs', 'VecRegs', 'VecPredRegs',
+ 'CCRegs', 'MiscRegs' ])
diff --git a/src/arch/alpha/isa.hh b/src/arch/alpha/isa.hh
index 54e12022a..2b183f0e3 100644
--- a/src/arch/alpha/isa.hh
+++ b/src/arch/alpha/isa.hh
@@ -121,6 +121,12 @@ namespace AlphaISA
return reg;
}
+ int
+ flattenVecPredIndex(int reg) const
+ {
+ return reg;
+ }
+
// dummy
int
flattenCCIndex(int reg) const
diff --git a/src/arch/alpha/registers.hh b/src/arch/alpha/registers.hh
index 6c71320b6..218390597 100644
--- a/src/arch/alpha/registers.hh
+++ b/src/arch/alpha/registers.hh
@@ -34,6 +34,7 @@
#include "arch/alpha/generated/max_inst_regs.hh"
#include "arch/alpha/ipr.hh"
#include "arch/generic/types.hh"
+#include "arch/generic/vec_pred_reg.hh"
#include "arch/generic/vec_reg.hh"
#include "base/types.hh"
@@ -56,14 +57,20 @@ typedef RegVal MiscReg;
// dummy typedef since we don't have CC regs
typedef uint8_t CCReg;
-// dummy typedefs since we don't have vector regs
-constexpr unsigned NumVecElemPerVecReg = 2;
-using VecElem = uint32_t;
-using VecReg = ::VecRegT<VecElem, NumVecElemPerVecReg, false>;
-using ConstVecReg = ::VecRegT<VecElem, NumVecElemPerVecReg, true>;
-using VecRegContainer = VecReg::Container;
-// This has to be one to prevent warnings that are treated as errors
-constexpr unsigned NumVecRegs = 1;
+// Not applicable to Alpha
+using VecElem = ::DummyVecElem;
+using VecReg = ::DummyVecReg;
+using ConstVecReg = ::DummyConstVecReg;
+using VecRegContainer = ::DummyVecRegContainer;
+constexpr unsigned NumVecElemPerVecReg = ::DummyNumVecElemPerVecReg;
+constexpr size_t VecRegSizeBytes = ::DummyVecRegSizeBytes;
+
+// Not applicable to Alpha
+using VecPredReg = ::DummyVecPredReg;
+using ConstVecPredReg = ::DummyConstVecPredReg;
+using VecPredRegContainer = ::DummyVecPredRegContainer;
+constexpr size_t VecPredRegSizeBits = ::DummyVecPredRegSizeBits;
+constexpr bool VecPredRegHasPackedRepr = ::DummyVecPredRegHasPackedRepr;
enum MiscRegIndex
{
@@ -96,6 +103,10 @@ const int NumFloatArchRegs = 32;
const int NumIntRegs = NumIntArchRegs + NumPALShadowRegs;
const int NumFloatRegs = NumFloatArchRegs;
+const int NumVecRegs = 1; // Not applicable to Alpha
+ // (1 to prevent warnings)
+const int NumVecPredRegs = 1; // Not applicable to Alpha
+ // (1 to prevent warnings)
const int NumCCRegs = 0;
const int NumMiscRegs = NUM_MISCREGS;
diff --git a/src/arch/arm/isa.hh b/src/arch/arm/isa.hh
index a3e89b544..b98610bfc 100644
--- a/src/arch/arm/isa.hh
+++ b/src/arch/arm/isa.hh
@@ -446,6 +446,9 @@ namespace ArmISA
case VecElemClass:
return RegId(VecElemClass, flattenVecElemIndex(regId.index()),
regId.elemIndex());
+ case VecPredRegClass:
+ return RegId(VecPredRegClass,
+ flattenVecPredIndex(regId.index()));
case CCRegClass:
return RegId(CCRegClass, flattenCCIndex(regId.index()));
case MiscRegClass:
@@ -508,6 +511,13 @@ namespace ArmISA
}
int
+ flattenVecPredIndex(int reg) const
+ {
+ assert(reg >= 0);
+ return reg;
+ }
+
+ int
flattenCCIndex(int reg) const
{
assert(reg >= 0);
diff --git a/src/arch/arm/registers.hh b/src/arch/arm/registers.hh
index 8346f454b..8960f9f92 100644
--- a/src/arch/arm/registers.hh
+++ b/src/arch/arm/registers.hh
@@ -47,6 +47,8 @@
#include "arch/arm/generated/max_inst_regs.hh"
#include "arch/arm/intregs.hh"
#include "arch/arm/miscregs.hh"
+#include "arch/arm/types.hh"
+#include "arch/generic/vec_pred_reg.hh"
#include "arch/generic/vec_reg.hh"
namespace ArmISA {
@@ -66,6 +68,15 @@ using VecReg = ::VecRegT<VecElem, NumVecElemPerVecReg, false>;
using ConstVecReg = ::VecRegT<VecElem, NumVecElemPerVecReg, true>;
using VecRegContainer = VecReg::Container;
+constexpr size_t VecRegSizeBytes = NumVecElemPerVecReg * sizeof(VecElem);
+
+// Dummy typedefs
+using VecPredReg = ::DummyVecPredReg;
+using ConstVecPredReg = ::DummyConstVecPredReg;
+using VecPredRegContainer = ::DummyVecPredRegContainer;
+constexpr size_t VecPredRegSizeBits = ::DummyVecPredRegSizeBits;
+constexpr bool VecPredRegHasPackedRepr = ::DummyVecPredRegHasPackedRepr;
+
// condition code register; must be at least 32 bits for FpCondCodes
typedef uint64_t CCReg;
@@ -82,12 +93,14 @@ const int NumVecSpecialRegs = 8;
const int NumIntRegs = NUM_INTREGS;
const int NumFloatRegs = NumFloatV8ArchRegs + NumFloatSpecialRegs;
const int NumVecRegs = NumVecV8ArchRegs + NumVecSpecialRegs;
+const int NumVecPredRegs = 1;
const int NumCCRegs = NUM_CCREGS;
const int NumMiscRegs = NUM_MISCREGS;
#define ISA_HAS_CC_REGS
-const int TotalNumRegs = NumIntRegs + NumFloatRegs + NumVecRegs + NumMiscRegs;
+const int TotalNumRegs = NumIntRegs + NumFloatRegs + NumVecRegs +
+ NumVecPredRegs + NumMiscRegs;
// semantically meaningful register indices
const int ReturnValueReg = 0;
diff --git a/src/arch/generic/vec_pred_reg.hh b/src/arch/generic/vec_pred_reg.hh
new file mode 100644
index 000000000..9ff9915ef
--- /dev/null
+++ b/src/arch/generic/vec_pred_reg.hh
@@ -0,0 +1,404 @@
+// Copyright (c) 2017 ARM Limited
+// All rights reserved
+//
+// The license below extends only to copyright in the software and shall
+// not be construed as granting a license to any other intellectual
+// property including but not limited to intellectual property relating
+// to a hardware implementation of the functionality of the software
+// licensed hereunder. You may use the software subject to the license
+// terms below provided that you ensure that this notice is replicated
+// unmodified and in its entirety in all distributions of the software,
+// modified or unmodified, in source code or in binary form.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met: redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer;
+// redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution;
+// neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Authors: Giacomo Gabrielli
+// Rekai Gonzalez
+// Javier Setoain
+
+#ifndef __ARCH_GENERIC_VEC_PRED_REG_HH__
+#define __ARCH_GENERIC_VEC_PRED_REG_HH__
+
+#include <array>
+#include <cassert>
+#include <vector>
+
+#include "arch/generic/vec_reg.hh"
+#include "base/cprintf.hh"
+
+template <size_t NumBits, bool Packed>
+class VecPredRegContainer;
+
+/// Predicate register view.
+///
+/// This generic class implements the View in an MVC pattern, similarly to
+/// @see VecRegT. Since predicates are mainly used in conjunction with vectors
+/// to specify which lanes are active in a vector operation, the class is
+/// templated on the vector element type to simplify ISA definitions.
+/// @tparam VecElem Type of the vector elements.
+/// @tparam NumElems Number of vector elements making up the view.
+/// @tparam Packed True if the predicate register relies on a packed
+/// representation, i.e. adjacent bits refer to different vector elements
+/// irrespective of the vector element size (e.g. this is the case for
+/// AVX-512). If false, the predicate register relies on an unpacked
+/// representation, where each bit refers to the corresponding byte in a vector
+/// register (e.g. this is the case for ARM SVE).
+/// @tparam Const True if the underlying container can be modified through
+/// the view.
+template <typename VecElem, size_t NumElems, bool Packed, bool Const>
+class VecPredRegT
+{
+ protected:
+ /// Size of the register in bits.
+ static constexpr size_t NUM_BITS = Packed ? NumElems :
+ sizeof(VecElem) * NumElems;
+
+ public:
+ /// Container type alias.
+ using Container = typename std::conditional<
+ Const,
+ const VecPredRegContainer<NUM_BITS, Packed>,
+ VecPredRegContainer<NUM_BITS, Packed>>::type;
+
+ protected:
+ // Alias for this type
+ using MyClass = VecPredRegT<VecElem, NumElems, Packed, Const>;
+ /// Container corresponding to this view.
+ Container& container;
+
+ public:
+ VecPredRegT(Container& c) : container(c) {}
+
+ /// Reset the register to an all-false value.
+ template<bool Condition = !Const>
+ typename std::enable_if<Condition, void>::type
+ reset() { container.reset(); }
+
+ /// Reset the register to an all-true value.
+ template<bool Condition = !Const>
+ typename std::enable_if<Condition, void>::type
+ set() { container.set(); }
+
+ template<bool Condition = !Const>
+ typename std::enable_if<Condition, MyClass&>::type
+ operator=(const MyClass& that)
+ {
+ container = that.container;
+ return *this;
+ }
+
+ const bool&
+ operator[](size_t idx) const
+ {
+ return container[idx * (Packed ? 1 : sizeof(VecElem))];
+ }
+
+ template<bool Condition = !Const>
+ typename std::enable_if<Condition, bool&>::type
+ operator[](size_t idx)
+ {
+ return container[idx * (Packed ? 1 : sizeof(VecElem))];
+ }
+
+ /// Return an element of the predicate register as it appears
+ /// in the raw (untyped) internal representation
+ uint8_t
+ get_raw(size_t idx) const
+ {
+ return container.get_bits(idx * (Packed ? 1 : sizeof(VecElem)),
+ (Packed ? 1 : sizeof(VecElem)));
+ }
+
+ /// Write a raw value in an element of the predicate register
+ template<bool Condition = !Const>
+ typename std::enable_if<Condition, void>::type
+ set_raw(size_t idx, uint8_t val)
+ {
+ container.set_bits(idx * (Packed ? 1 : sizeof(VecElem)),
+ (Packed ? 1 : sizeof(VecElem)), val);
+ }
+
+ /// Equality operator, required to compare thread contexts.
+ template<typename VE2, size_t NE2, bool P2, bool C2>
+ bool
+ operator==(const VecPredRegT<VE2, NE2, P2, C2>& that) const
+ {
+ return container == that.container;
+ }
+
+ /// Inequality operator, required to compare thread contexts.
+ template<typename VE2, size_t NE2, bool P2, bool C2>
+ bool
+ operator!=(const VecPredRegT<VE2, NE2, P2, C2>& that) const
+ {
+ return !operator==(that);
+ }
+
+ friend std::ostream&
+ operator<<(std::ostream& os, const MyClass& p)
+ {
+ // 0-sized is not allowed
+ os << '[' << p.container[0];
+ for (int i = 0; i < p.NUM_BITS; ++i) {
+ os << " " << (p.container[i] ? 1 : 0);
+ }
+ os << ']';
+ return os;
+ }
+
+ /// Returns a string representation of the register content.
+ const std::string print() const { return csprintf("%s", *this); }
+
+ /// Returns true if the first active element of the register is true.
+ /// @param mask Input mask used to filter the predicates to be tested.
+ /// @param actual_num_elems Actual number of vector elements considered for
+ /// the test (corresponding to the current vector length).
+ template <bool MC>
+ bool
+ firstActive(const VecPredRegT<VecElem, NumElems, Packed, MC>& mask,
+ size_t actual_num_elems) const
+ {
+ assert(actual_num_elems <= NumElems);
+ for (int i = 0; i < actual_num_elems; ++i) {
+ if (mask[i]) {
+ return (*this)[i];
+ }
+ }
+ return false;
+ }
+
+ /// Returns true if there are no active elements in the register.
+ /// @param mask Input mask used to filter the predicates to be tested.
+ /// @param actual_num_elems Actual number of vector elements considered for
+ /// the test (corresponding to the current vector length).
+ template <bool MC>
+ bool
+ noneActive(const VecPredRegT<VecElem, NumElems, Packed, MC>& mask,
+ size_t actual_num_elems) const
+ {
+ assert(actual_num_elems <= NumElems);
+ for (int i = 0; i < actual_num_elems; ++i) {
+ if (mask[i] && operator[](i)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /// Returns true if the last active element of the register is true.
+ /// @param mask Input mask used to filter the predicates to be tested.
+ /// @param actual_num_elems Actual number of vector elements considered for
+ /// the test (corresponding to the current vector length).
+ template <bool MC>
+ bool
+ lastActive(const VecPredRegT<VecElem, NumElems, Packed, MC>& mask,
+ size_t actual_num_elems) const
+ {
+ assert(actual_num_elems <= NumElems);
+ for (int i = actual_num_elems - 1; i >= 0; --i) {
+ if (mask[i]) {
+ return operator[](i);
+ }
+ }
+ return false;
+ }
+};
+
+/// Generic predicate register container.
+///
+/// This generic class implements the Model in an MVC pattern, similarly to
+/// @see VecRegContainer.
+/// @tparam NumBits Size of the container in bits.
+/// @tparam Packed See @VecRegT.
+template <size_t NumBits, bool Packed>
+class VecPredRegContainer
+{
+ static_assert(NumBits > 0,
+ "Size of a predicate register must be > 0");
+
+ public:
+ static constexpr size_t NUM_BITS = NumBits;
+ using Container = std::array<bool, NumBits>;
+
+ private:
+ Container container;
+ // Alias for this type
+ using MyClass = VecPredRegContainer<NumBits, Packed>;
+
+ public:
+ VecPredRegContainer() {}
+
+ MyClass&
+ operator=(const MyClass& that)
+ {
+ if (&that == this)
+ return *this;
+ container = that.container;
+ return *this;
+ }
+
+ /// Required for de-serialization.
+ MyClass&
+ operator=(const std::vector<uint8_t>& that)
+ {
+ assert(that.size() == NUM_BITS);
+ std::copy(that.begin(), that.end(), container.begin());
+ return *this;
+ }
+
+ /// Resets the predicate register to an all-false register.
+ void
+ reset()
+ {
+ container.fill(false);
+ }
+
+ /// Sets the predicate register to an all-true value.
+ void
+ set()
+ {
+ container.fill(true);
+ }
+
+ /// Equality operator, required to compare thread contexts.
+ template<size_t N2, bool P2>
+ inline bool
+ operator==(const VecPredRegContainer<N2, P2>& that) const
+ {
+ return NumBits == N2 && Packed == P2 && container == that.container;
+ }
+
+ /// Inequality operator, required to compare thread contexts.
+ template<size_t N2, bool P2>
+ bool
+ operator!=(const VecPredRegContainer<N2, P2>& that) const
+ {
+ return !operator==(that);
+ }
+
+ /// Returns a reference to a specific element of the internal container.
+ bool& operator[](size_t idx) { return container[idx]; }
+
+ /// Returns a const reference to a specific element of the internal
+ /// container.
+ const bool& operator[](size_t idx) const { return container[idx]; }
+
+ /// Returns a subset of bits starting from a specific element in the
+ /// container.
+ uint8_t
+ get_bits(size_t idx, uint8_t nbits) const
+ {
+ assert(nbits > 0 && nbits <= 8 && (idx + nbits - 1) < NumBits);
+ uint8_t v = 0;
+ idx = idx + nbits - 1;
+ for (int i = 0; i < nbits; ++i, --idx) {
+ v <<= 1;
+ v |= container[idx];
+ }
+ return v;
+ }
+
+ /// Set a subset of bits starting from a specific element in the
+ /// container.
+ void
+ set_bits(size_t idx, uint8_t nbits, uint8_t bval)
+ {
+ assert(nbits > 0 && nbits <= 8 && (idx + nbits - 1) < NumBits);
+ for (int i = 0; i < nbits; ++i, ++idx) {
+ container[idx] = bval & 1;
+ bval >>= 1;
+ }
+ }
+
+ /// Returns a string representation of the register content.
+ const std::string print() const { return csprintf("%s", *this); }
+
+ friend std::ostream&
+ operator<<(std::ostream& os, const MyClass& v)
+ {
+ for (auto b: v.container) {
+ os << csprintf("%d", b);
+ }
+ return os;
+ }
+
+ /// Create a view of this container.
+ ///
+ /// If NumElems is provided, the size of the container is bounds-checked,
+ /// otherwise the size is inferred from the container size.
+ /// @tparam VecElem Type of the vector elements.
+ /// @tparam NumElems Number of vector elements making up the view.
+ /// @{
+ template <typename VecElem,
+ size_t NumElems = (Packed ? NumBits : NumBits / sizeof(VecElem))>
+ VecPredRegT<VecElem, NumElems, Packed, true> as() const
+ {
+ static_assert((Packed && NumElems <= NumBits) ||
+ (!Packed &&
+ NumBits % sizeof(VecElem) == 0 &&
+ sizeof(VecElem) * NumElems <= NumBits),
+ "Container size incompatible with view size");
+ return VecPredRegT<VecElem, NumElems, Packed, true>(*this);
+ }
+
+ template <typename VecElem,
+ size_t NumElems = (Packed ? NumBits : NumBits / sizeof(VecElem))>
+ VecPredRegT<VecElem, NumElems, Packed, false> as()
+ {
+ static_assert((Packed && NumElems <= NumBits) ||
+ (!Packed &&
+ NumBits % sizeof(VecElem) == 0 &&
+ sizeof(VecElem) * NumElems <= NumBits),
+ "Container size incompatible with view size");
+ return VecPredRegT<VecElem, NumElems, Packed, false>(*this);
+ }
+ /// @}
+};
+
+/// Helper functions used for serialization/de-serialization
+template <size_t NumBits, bool Packed>
+inline bool
+to_number(const std::string& value, VecPredRegContainer<NumBits, Packed>& p)
+{
+ int i = 0;
+ for (const auto& c: value) {
+ p[i] = (c == '1');
+ }
+ return true;
+}
+
+/// Dummy type aliases and constants for architectures that do not implement
+/// vector predicate registers.
+/// @{
+constexpr bool DummyVecPredRegHasPackedRepr = false;
+using DummyVecPredReg = VecPredRegT<DummyVecElem, DummyNumVecElemPerVecReg,
+ DummyVecPredRegHasPackedRepr, false>;
+using DummyConstVecPredReg = VecPredRegT<DummyVecElem,
+ DummyNumVecElemPerVecReg,
+ DummyVecPredRegHasPackedRepr, true>;
+using DummyVecPredRegContainer = DummyVecPredReg::Container;
+constexpr size_t DummyVecPredRegSizeBits = 8;
+/// @}
+
+#endif // __ARCH_GENERIC_VEC_PRED_REG_HH__
diff --git a/src/arch/generic/vec_reg.hh b/src/arch/generic/vec_reg.hh
index 7145af4cf..f26a8c8ad 100644
--- a/src/arch/generic/vec_reg.hh
+++ b/src/arch/generic/vec_reg.hh
@@ -648,4 +648,18 @@ to_number(const std::string& value, VecRegContainer<Sz>& v)
}
/** @} */
+/**
+ * Dummy type aliases and constants for architectures that do not implement
+ * vector registers.
+ */
+/** @{ */
+using DummyVecElem = uint32_t;
+constexpr unsigned DummyNumVecElemPerVecReg = 2;
+using DummyVecReg = VecRegT<DummyVecElem, DummyNumVecElemPerVecReg, false>;
+using DummyConstVecReg = VecRegT<DummyVecElem, DummyNumVecElemPerVecReg, true>;
+using DummyVecRegContainer = DummyVecReg::Container;
+constexpr size_t DummyVecRegSizeBytes = DummyNumVecElemPerVecReg *
+ sizeof(DummyVecElem);
+/** @} */
+
#endif /* __ARCH_GENERIC_VEC_REG_HH__ */
diff --git a/src/arch/isa_parser.py b/src/arch/isa_parser.py
index 755f966eb..16004c009 100755
--- a/src/arch/isa_parser.py
+++ b/src/arch/isa_parser.py
@@ -490,6 +490,9 @@ class Operand(object):
def isVecElem(self):
return 0
+ def isVecPredReg(self):
+ return 0
+
def isPCState(self):
return 0
@@ -795,10 +798,9 @@ class VecRegOperand(Operand):
wb = '''
if (traceData) {
- warn_once("Vectors not supported yet in tracedata");
- /*traceData->setData(final_val);*/
+ traceData->setData(tmp_d%d);
}
- '''
+ ''' % self.dest_reg_idx
return wb
def finalize(self, predRead, predWrite):
@@ -860,6 +862,88 @@ class VecElemOperand(Operand):
return c_write
+class VecPredRegOperand(Operand):
+ reg_class = 'VecPredRegClass'
+
+ def __init__(self, parser, full_name, ext, is_src, is_dest):
+ Operand.__init__(self, parser, full_name, ext, is_src, is_dest)
+ self.parser = parser
+
+ def isReg(self):
+ return 1
+
+ def isVecPredReg(self):
+ return 1
+
+ def makeDecl(self):
+ return ''
+
+ def makeConstructor(self, predRead, predWrite):
+ c_src = ''
+ c_dest = ''
+
+ if self.is_src:
+ c_src = src_reg_constructor % (self.reg_class, self.reg_spec)
+
+ if self.is_dest:
+ c_dest = dst_reg_constructor % (self.reg_class, self.reg_spec)
+ c_dest += '\n\t_numVecPredDestRegs++;'
+
+ return c_src + c_dest
+
+ def makeRead(self, predRead):
+ func = 'readVecPredRegOperand'
+ if self.read_code != None:
+ return self.buildReadCode(func)
+
+ if predRead:
+ rindex = '_sourceIndex++'
+ else:
+ rindex = '%d' % self.src_reg_idx
+
+ c_read = '\t\t%s& tmp_s%s = xc->%s(this, %s);\n' % (
+ 'const TheISA::VecPredRegContainer', rindex, func, rindex)
+ if self.ext:
+ c_read += '\t\tauto %s = tmp_s%s.as<%s>();\n' % (
+ self.base_name, rindex,
+ self.parser.operandTypeMap[self.ext])
+ return c_read
+
+ def makeReadW(self, predWrite):
+ func = 'getWritableVecPredRegOperand'
+ if self.read_code != None:
+ return self.buildReadCode(func)
+
+ if predWrite:
+ rindex = '_destIndex++'
+ else:
+ rindex = '%d' % self.dest_reg_idx
+
+ c_readw = '\t\t%s& tmp_d%s = xc->%s(this, %s);\n' % (
+ 'TheISA::VecPredRegContainer', rindex, func, rindex)
+ if self.ext:
+ c_readw += '\t\tauto %s = tmp_d%s.as<%s>();\n' % (
+ self.base_name, rindex,
+ self.parser.operandTypeMap[self.ext])
+ return c_readw
+
+ def makeWrite(self, predWrite):
+ func = 'setVecPredRegOperand'
+ if self.write_code != None:
+ return self.buildWriteCode(func)
+
+ wb = '''
+ if (traceData) {
+ traceData->setData(tmp_d%d);
+ }
+ ''' % self.dest_reg_idx
+ return wb
+
+ def finalize(self, predRead, predWrite):
+ super(VecPredRegOperand, self).finalize(predRead, predWrite)
+ if self.is_dest:
+ self.op_rd = self.makeReadW(predWrite) + self.op_rd
+
class CCRegOperand(Operand):
reg_class = 'CCRegClass'
@@ -1113,6 +1197,7 @@ class OperandList(object):
self.numFPDestRegs = 0
self.numIntDestRegs = 0
self.numVecDestRegs = 0
+ self.numVecPredDestRegs = 0
self.numCCDestRegs = 0
self.numMiscDestRegs = 0
self.memOperand = None
@@ -1136,6 +1221,8 @@ class OperandList(object):
self.numIntDestRegs += 1
elif op_desc.isVecReg():
self.numVecDestRegs += 1
+ elif op_desc.isVecPredReg():
+ self.numVecPredDestRegs += 1
elif op_desc.isCCReg():
self.numCCDestRegs += 1
elif op_desc.isControlReg():
@@ -1344,6 +1431,7 @@ class InstObjParams(object):
header += '\n\t_numFPDestRegs = 0;'
header += '\n\t_numVecDestRegs = 0;'
header += '\n\t_numVecElemDestRegs = 0;'
+ header += '\n\t_numVecPredDestRegs = 0;'
header += '\n\t_numIntDestRegs = 0;'
header += '\n\t_numCCDestRegs = 0;'
diff --git a/src/arch/mips/isa.hh b/src/arch/mips/isa.hh
index ffcb3f1dc..cea2d5412 100644
--- a/src/arch/mips/isa.hh
+++ b/src/arch/mips/isa.hh
@@ -165,6 +165,12 @@ namespace MipsISA
return reg;
}
+ int
+ flattenVecPredIndex(int reg) const
+ {
+ return reg;
+ }
+
// dummy
int
flattenCCIndex(int reg) const
diff --git a/src/arch/mips/registers.hh b/src/arch/mips/registers.hh
index 6f7097b08..633199c94 100644
--- a/src/arch/mips/registers.hh
+++ b/src/arch/mips/registers.hh
@@ -32,6 +32,7 @@
#ifndef __ARCH_MIPS_REGISTERS_HH__
#define __ARCH_MIPS_REGISTERS_HH__
+#include "arch/generic/vec_pred_reg.hh"
#include "arch/generic/vec_reg.hh"
#include "arch/mips/generated/max_inst_regs.hh"
#include "base/logging.hh"
@@ -55,6 +56,10 @@ const int NumFloatSpecialRegs = 5;
const int MaxShadowRegSets = 16; // Maximum number of shadow register sets
const int NumIntRegs = NumIntArchRegs + NumIntSpecialRegs; //HI & LO Regs
const int NumFloatRegs = NumFloatArchRegs + NumFloatSpecialRegs;//
+const int NumVecRegs = 1; // Not applicable to MIPS
+ // (1 to prevent warnings)
+const int NumVecPredRegs = 1; // Not applicable to MIPS
+ // (1 to prevent warnings)
const int NumCCRegs = 0;
const uint32_t MIPS32_QNAN = 0x7fbfffff;
@@ -289,14 +294,20 @@ typedef RegVal MiscReg;
// dummy typedef since we don't have CC regs
typedef uint8_t CCReg;
-// dummy typedefs since we don't have vector regs
-constexpr unsigned NumVecElemPerVecReg = 2;
-using VecElem = uint32_t;
-using VecReg = ::VecRegT<VecElem, NumVecElemPerVecReg, false>;
-using ConstVecReg = ::VecRegT<VecElem, NumVecElemPerVecReg, true>;
-using VecRegContainer = VecReg::Container;
-// This has to be one to prevent warnings that are treated as errors
-constexpr unsigned NumVecRegs = 1;
+// 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;
+
+// Not applicable to MIPS
+using VecPredReg = ::DummyVecPredReg;
+using ConstVecPredReg = ::DummyConstVecPredReg;
+using VecPredRegContainer = ::DummyVecPredRegContainer;
+constexpr size_t VecPredRegSizeBits = ::DummyVecPredRegSizeBits;
+constexpr bool VecPredRegHasPackedRepr = ::DummyVecPredRegHasPackedRepr;
} // namespace MipsISA
diff --git a/src/arch/null/registers.hh b/src/arch/null/registers.hh
index fb815af4a..ff9e0cda6 100644
--- a/src/arch/null/registers.hh
+++ b/src/arch/null/registers.hh
@@ -40,6 +40,7 @@
#ifndef __ARCH_NULL_REGISTERS_HH__
#define __ARCH_NULL_REGISTERS_HH__
+#include "arch/generic/vec_pred_reg.hh"
#include "arch/generic/vec_reg.hh"
#include "arch/types.hh"
#include "base/types.hh"
@@ -52,14 +53,20 @@ typedef uint8_t CCReg;
typedef RegVal MiscReg;
const RegIndex ZeroReg = 0;
-// dummy typedefs since we don't have vector regs
-constexpr unsigned NumVecElemPerVecReg = 2;
-using VecElem = uint32_t;
-using VecReg = ::VecRegT<VecElem, NumVecElemPerVecReg, false>;
-using ConstVecReg = ::VecRegT<VecElem, NumVecElemPerVecReg, true>;
-using VecRegContainer = VecReg::Container;
-// This has to be one to prevent warnings that are treated as errors
-constexpr unsigned NumVecRegs = 1;
+// 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;
+
+// Not applicable to null
+using VecPredReg = ::DummyVecPredReg;
+using ConstVecPredReg = ::DummyConstVecPredReg;
+using VecPredRegContainer = ::DummyVecPredRegContainer;
+constexpr size_t VecPredRegSizeBits = ::DummyVecPredRegSizeBits;
+constexpr bool VecPredRegHasPackedRepr = ::DummyVecPredRegHasPackedRepr;
}
diff --git a/src/arch/power/isa.hh b/src/arch/power/isa.hh
index 4e9fdb00a..3f26f57de 100644
--- a/src/arch/power/isa.hh
+++ b/src/arch/power/isa.hh
@@ -113,6 +113,12 @@ class ISA : public SimObject
return reg;
}
+ int
+ flattenVecPredIndex(int reg) const
+ {
+ return reg;
+ }
+
// dummy
int
flattenCCIndex(int reg) const
diff --git a/src/arch/power/registers.hh b/src/arch/power/registers.hh
index 989b4c52a..e8de218e7 100644
--- a/src/arch/power/registers.hh
+++ b/src/arch/power/registers.hh
@@ -31,6 +31,7 @@
#ifndef __ARCH_POWER_REGISTERS_HH__
#define __ARCH_POWER_REGISTERS_HH__
+#include "arch/generic/vec_pred_reg.hh"
#include "arch/generic/vec_reg.hh"
#include "arch/power/generated/max_inst_regs.hh"
#include "arch/power/miscregs.hh"
@@ -54,14 +55,20 @@ typedef RegVal MiscReg;
// dummy typedef since we don't have CC regs
typedef uint8_t CCReg;
-// dummy typedefs since we don't have vector regs
-constexpr unsigned NumVecElemPerVecReg = 2;
-using VecElem = uint32_t;
-using VecReg = ::VecRegT<VecElem, NumVecElemPerVecReg, false>;
-using ConstVecReg = ::VecRegT<VecElem, NumVecElemPerVecReg, true>;
-using VecRegContainer = VecReg::Container;
-// This has to be one to prevent warnings that are treated as errors
-constexpr unsigned NumVecRegs = 1;
+// 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;
+
+// Not applicable to Power
+using VecPredReg = ::DummyVecPredReg;
+using ConstVecPredReg = ::DummyConstVecPredReg;
+using VecPredRegContainer = ::DummyVecPredRegContainer;
+constexpr size_t VecPredRegSizeBits = ::DummyVecPredRegSizeBits;
+constexpr bool VecPredRegHasPackedRepr = ::DummyVecPredRegHasPackedRepr;
// Constants Related to the number of registers
const int NumIntArchRegs = 32;
@@ -75,6 +82,10 @@ const int NumInternalProcRegs = 0;
const int NumIntRegs = NumIntArchRegs + NumIntSpecialRegs;
const int NumFloatRegs = NumFloatArchRegs + NumFloatSpecialRegs;
+const int NumVecRegs = 1; // Not applicable to Power
+ // (1 to prevent warnings)
+const int NumVecPredRegs = 1; // Not applicable to Power
+ // (1 to prevent warnings)
const int NumCCRegs = 0;
const int NumMiscRegs = NUM_MISCREGS;
diff --git a/src/arch/riscv/isa.hh b/src/arch/riscv/isa.hh
index 2602f6dde..0107f8e92 100644
--- a/src/arch/riscv/isa.hh
+++ b/src/arch/riscv/isa.hh
@@ -84,6 +84,7 @@ class ISA : public SimObject
int flattenFloatIndex(int reg) const { return reg; }
int flattenVecIndex(int reg) const { return reg; }
int flattenVecElemIndex(int reg) const { return reg; }
+ int flattenVecPredIndex(int reg) const { return reg; }
int flattenCCIndex(int reg) const { return reg; }
int flattenMiscIndex(int reg) const { return reg; }
diff --git a/src/arch/riscv/registers.hh b/src/arch/riscv/registers.hh
index 2de154e22..a67274221 100644
--- a/src/arch/riscv/registers.hh
+++ b/src/arch/riscv/registers.hh
@@ -52,6 +52,7 @@
#include <vector>
#include "arch/generic/types.hh"
+#include "arch/generic/vec_pred_reg.hh"
#include "arch/generic/vec_reg.hh"
#include "arch/isa_traits.hh"
#include "arch/riscv/generated/max_inst_regs.hh"
@@ -68,19 +69,31 @@ typedef RegVal FloatRegBits;
typedef uint8_t CCReg; // Not applicable to Riscv
typedef RegVal MiscReg;
-// dummy typedefs since we don't have vector regs
-const unsigned NumVecElemPerVecReg = 2;
-using VecElem = uint32_t;
-using VecReg = ::VecRegT<VecElem, NumVecElemPerVecReg, false>;
-using ConstVecReg = ::VecRegT<VecElem, NumVecElemPerVecReg, true>;
-using VecRegContainer = VecReg::Container;
+// 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;
+
+// Not applicable to RISC-V
+using VecPredReg = ::DummyVecPredReg;
+using ConstVecPredReg = ::DummyConstVecPredReg;
+using VecPredRegContainer = ::DummyVecPredRegContainer;
+constexpr size_t VecPredRegSizeBits = ::DummyVecPredRegSizeBits;
+constexpr bool VecPredRegHasPackedRepr = ::DummyVecPredRegHasPackedRepr;
const int NumIntArchRegs = 32;
const int NumMicroIntRegs = 1;
const int NumIntRegs = NumIntArchRegs + NumMicroIntRegs;
const int NumFloatRegs = 32;
-// This has to be one to prevent warnings that are treated as errors
-const unsigned NumVecRegs = 1;
+
+const unsigned NumVecRegs = 1; // Not applicable to RISC-V
+ // (1 to prevent warnings)
+const int NumVecPredRegs = 1; // Not applicable to RISC-V
+ // (1 to prevent warnings)
+
const int NumCCRegs = 0;
// Semantically meaningful register indices
diff --git a/src/arch/sparc/isa.hh b/src/arch/sparc/isa.hh
index 8ad729862..6cda32038 100644
--- a/src/arch/sparc/isa.hh
+++ b/src/arch/sparc/isa.hh
@@ -234,6 +234,12 @@ class ISA : public SimObject
return reg;
}
+ int
+ flattenVecPredIndex(int reg) const
+ {
+ return reg;
+ }
+
// dummy
int
flattenCCIndex(int reg) const
diff --git a/src/arch/sparc/registers.hh b/src/arch/sparc/registers.hh
index 5f12b98cb..d9b182e7f 100644
--- a/src/arch/sparc/registers.hh
+++ b/src/arch/sparc/registers.hh
@@ -32,6 +32,7 @@
#ifndef __ARCH_SPARC_REGISTERS_HH__
#define __ARCH_SPARC_REGISTERS_HH__
+#include "arch/generic/vec_pred_reg.hh"
#include "arch/generic/vec_reg.hh"
#include "arch/sparc/generated/max_inst_regs.hh"
#include "arch/sparc/miscregs.hh"
@@ -48,14 +49,20 @@ using SparcISAInst::MaxMiscDestRegs;
// dummy typedef since we don't have CC regs
typedef uint8_t CCReg;
-// dummy typedefs since we don't have vector regs
-constexpr unsigned NumVecElemPerVecReg = 2;
-using VecElem = uint32_t;
-using VecReg = ::VecRegT<VecElem, NumVecElemPerVecReg, false>;
-using ConstVecReg = ::VecRegT<VecElem, NumVecElemPerVecReg, true>;
-using VecRegContainer = VecReg::Container;
-// This has to be one to prevent warnings that are treated as errors
-constexpr unsigned NumVecRegs = 1;
+// 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;
+
+// Not applicable to SPARC
+using VecPredReg = ::DummyVecPredReg;
+using ConstVecPredReg = ::DummyConstVecPredReg;
+using VecPredRegContainer = ::DummyVecPredRegContainer;
+constexpr size_t VecPredRegSizeBits = ::DummyVecPredRegSizeBits;
+constexpr bool VecPredRegHasPackedRepr = ::DummyVecPredRegHasPackedRepr;
// semantically meaningful register indices
const int ZeroReg = 0; // architecturally meaningful
@@ -70,6 +77,10 @@ const int SyscallPseudoReturnReg = 9;
const int NumIntArchRegs = 32;
const int NumIntRegs = (MaxGL + 1) * 8 + NWindows * 16 + NumMicroIntRegs;
+const int NumVecRegs = 1; // Not applicable to SPARC
+ // (1 to prevent warnings)
+const int NumVecPredRegs = 1; // Not applicable to SPARC
+ // (1 to prevent warnings)
const int NumCCRegs = 0;
const int TotalNumRegs = NumIntRegs + NumFloatRegs + NumMiscRegs;
diff --git a/src/arch/x86/isa.hh b/src/arch/x86/isa.hh
index b61face09..7ad464643 100644
--- a/src/arch/x86/isa.hh
+++ b/src/arch/x86/isa.hh
@@ -117,6 +117,12 @@ namespace X86ISA
}
int
+ flattenVecPredIndex(int reg) const
+ {
+ return reg;
+ }
+
+ int
flattenCCIndex(int reg) const
{
return reg;
diff --git a/src/arch/x86/registers.hh b/src/arch/x86/registers.hh
index 509f7a111..893822263 100644
--- a/src/arch/x86/registers.hh
+++ b/src/arch/x86/registers.hh
@@ -41,6 +41,7 @@
#ifndef __ARCH_X86_REGISTERS_HH__
#define __ARCH_X86_REGISTERS_HH__
+#include "arch/generic/vec_pred_reg.hh"
#include "arch/generic/vec_reg.hh"
#include "arch/x86/generated/max_inst_regs.hh"
#include "arch/x86/regs/int.hh"
@@ -77,6 +78,11 @@ enum DependenceTags {
Max_Reg_Index = Misc_Reg_Base + NumMiscRegs
};
+const int NumVecRegs = 1; // Not applicable to x86
+ // (1 to prevent warnings)
+const int NumVecPredRegs = 1; // Not applicable to x86
+ // (1 to prevent warnings)
+
// semantically meaningful register indices
//There is no such register in X86
const int ZeroReg = NUM_INTREGS;
@@ -94,14 +100,20 @@ typedef RegVal IntReg;
typedef uint64_t CCReg;
typedef RegVal MiscReg;
-// dummy typedefs since we don't have vector regs
-constexpr unsigned NumVecElemPerVecReg = 2;
-using VecElem = uint32_t;
-using VecReg = ::VecRegT<VecElem, NumVecElemPerVecReg, false>;
-using ConstVecReg = ::VecRegT<VecElem, NumVecElemPerVecReg, true>;
-using VecRegContainer = VecReg::Container;
-// This has to be one to prevent warnings that are treated as errors
-constexpr unsigned NumVecRegs = 1;
+// 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;
+
+// Not applicable to x86
+using VecPredReg = ::DummyVecPredReg;
+using ConstVecPredReg = ::DummyConstVecPredReg;
+using VecPredRegContainer = ::DummyVecPredRegContainer;
+constexpr size_t VecPredRegSizeBits = ::DummyVecPredRegSizeBits;
+constexpr bool VecPredRegHasPackedRepr = ::DummyVecPredRegHasPackedRepr;
//These floating point types are correct for mmx, but not
//technically for x87 (80 bits) or at all for xmm (128 bits)