diff options
author | Giacomo Gabrielli <giacomo.gabrielli@arm.com> | 2018-10-16 16:04:08 +0100 |
---|---|---|
committer | Giacomo Gabrielli <giacomo.gabrielli@arm.com> | 2019-01-30 16:57:54 +0000 |
commit | 25474167e5b247d1b91fbf802c5b396a63ae705e (patch) | |
tree | b509597b23d792734f55c33b8125eebfbd9cd3a5 /src/arch | |
parent | c6f5db8743f19b02a38146d9cf2a829883387008 (diff) | |
download | gem5-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/SConscript | 6 | ||||
-rw-r--r-- | src/arch/alpha/isa.hh | 6 | ||||
-rw-r--r-- | src/arch/alpha/registers.hh | 27 | ||||
-rw-r--r-- | src/arch/arm/isa.hh | 10 | ||||
-rw-r--r-- | src/arch/arm/registers.hh | 15 | ||||
-rw-r--r-- | src/arch/generic/vec_pred_reg.hh | 404 | ||||
-rw-r--r-- | src/arch/generic/vec_reg.hh | 14 | ||||
-rwxr-xr-x | src/arch/isa_parser.py | 94 | ||||
-rw-r--r-- | src/arch/mips/isa.hh | 6 | ||||
-rw-r--r-- | src/arch/mips/registers.hh | 27 | ||||
-rw-r--r-- | src/arch/null/registers.hh | 23 | ||||
-rw-r--r-- | src/arch/power/isa.hh | 6 | ||||
-rw-r--r-- | src/arch/power/registers.hh | 27 | ||||
-rw-r--r-- | src/arch/riscv/isa.hh | 1 | ||||
-rw-r--r-- | src/arch/riscv/registers.hh | 29 | ||||
-rw-r--r-- | src/arch/sparc/isa.hh | 6 | ||||
-rw-r--r-- | src/arch/sparc/registers.hh | 27 | ||||
-rw-r--r-- | src/arch/x86/isa.hh | 6 | ||||
-rw-r--r-- | src/arch/x86/registers.hh | 28 |
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) |