diff options
Diffstat (limited to 'deps/v8/src/codegen/reglist-base.h')
-rw-r--r-- | deps/v8/src/codegen/reglist-base.h | 232 |
1 files changed, 232 insertions, 0 deletions
diff --git a/deps/v8/src/codegen/reglist-base.h b/deps/v8/src/codegen/reglist-base.h new file mode 100644 index 0000000000..6fc67cd304 --- /dev/null +++ b/deps/v8/src/codegen/reglist-base.h @@ -0,0 +1,232 @@ +// Copyright 2022 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_CODEGEN_REGLIST_BASE_H_ +#define V8_CODEGEN_REGLIST_BASE_H_ + +#include <cstdint> +#include <initializer_list> + +#include "src/base/bits.h" +#include "src/base/iterator.h" +#include "src/base/template-utils.h" + +namespace v8 { +namespace internal { + +class Register; + +template <typename RegisterT> +class RegListBase { + using num_registers_sized_storage_t = typename std::conditional< + RegisterT::kNumRegisters <= 16, uint16_t, + typename std::conditional<RegisterT::kNumRegisters <= 32, uint32_t, + uint64_t>::type>::type; + STATIC_ASSERT(RegisterT::kNumRegisters <= 64); + + public: + class Iterator; + class ReverseIterator; + +#ifdef V8_TARGET_ARCH_ARM64 + // On ARM64 the sp register has the special value 63 (kSPRegInternalCode) + using storage_t = typename std::conditional< + std::is_same<RegisterT, v8::internal::Register>::value, uint64_t, + num_registers_sized_storage_t>::type; +#else + using storage_t = num_registers_sized_storage_t; +#endif + + constexpr RegListBase() = default; + constexpr RegListBase(std::initializer_list<RegisterT> regs) { + for (RegisterT reg : regs) { + set(reg); + } + } + + constexpr void set(RegisterT reg) { + if (!reg.is_valid()) return; + regs_ |= storage_t{1} << reg.code(); + } + + constexpr void clear(RegisterT reg) { + if (!reg.is_valid()) return; + regs_ &= ~(storage_t{1} << reg.code()); + } + + constexpr bool has(RegisterT reg) const { + if (!reg.is_valid()) return false; + return (regs_ & (storage_t{1} << reg.code())) != 0; + } + + constexpr void clear(RegListBase other) { regs_ &= ~other.regs_; } + + constexpr bool is_empty() const { return regs_ == 0; } + + constexpr unsigned Count() const { + return base::bits::CountPopulation(regs_); + } + + constexpr RegListBase operator&(const RegListBase other) const { + return RegListBase(regs_ & other.regs_); + } + + constexpr RegListBase operator|(const RegListBase other) const { + return RegListBase(regs_ | other.regs_); + } + + constexpr RegListBase operator^(const RegListBase other) const { + return RegListBase(regs_ ^ other.regs_); + } + + constexpr RegListBase operator-(const RegListBase other) const { + return RegListBase(regs_ & ~other.regs_); + } + + constexpr RegListBase operator|(const RegisterT reg) const { + return *this | RegListBase{reg}; + } + + constexpr RegListBase operator-(const RegisterT reg) const { + return *this - RegListBase{reg}; + } + + constexpr RegListBase& operator&=(const RegListBase other) { + regs_ &= other.regs_; + return *this; + } + + constexpr RegListBase& operator|=(const RegListBase other) { + regs_ |= other.regs_; + return *this; + } + + constexpr bool operator==(const RegListBase other) const { + return regs_ == other.regs_; + } + constexpr bool operator!=(const RegListBase other) const { + return regs_ != other.regs_; + } + + constexpr RegisterT first() const { + DCHECK(!is_empty()); + int first_code = base::bits::CountTrailingZerosNonZero(regs_); + return RegisterT::from_code(first_code); + } + + constexpr RegisterT last() const { + DCHECK(!is_empty()); + int last_code = + 8 * sizeof(regs_) - 1 - base::bits::CountLeadingZeros(regs_); + return RegisterT::from_code(last_code); + } + + constexpr RegisterT PopFirst() { + RegisterT reg = first(); + clear(reg); + return reg; + } + + constexpr storage_t bits() const { return regs_; } + + inline Iterator begin() const; + inline Iterator end() const; + + inline ReverseIterator rbegin() const; + inline ReverseIterator rend() const; + + static RegListBase FromBits(storage_t bits) { return RegListBase(bits); } + + template <storage_t bits> + static constexpr RegListBase FromBits() { + return RegListBase{bits}; + } + + private: + // Unchecked constructor. Only use for valid bits. + explicit constexpr RegListBase(storage_t bits) : regs_(bits) {} + + storage_t regs_ = 0; +}; + +template <typename RegisterT> +class RegListBase<RegisterT>::Iterator + : public base::iterator<std::forward_iterator_tag, RegisterT> { + public: + RegisterT operator*() { return remaining_.first(); } + Iterator& operator++() { + remaining_.clear(remaining_.first()); + return *this; + } + bool operator==(Iterator other) { return remaining_ == other.remaining_; } + bool operator!=(Iterator other) { return remaining_ != other.remaining_; } + + private: + explicit Iterator(RegListBase<RegisterT> remaining) : remaining_(remaining) {} + friend class RegListBase; + + RegListBase<RegisterT> remaining_; +}; + +template <typename RegisterT> +class RegListBase<RegisterT>::ReverseIterator + : public base::iterator<std::forward_iterator_tag, RegisterT> { + public: + RegisterT operator*() { return remaining_.last(); } + ReverseIterator& operator++() { + remaining_.clear(remaining_.last()); + return *this; + } + bool operator==(ReverseIterator other) { + return remaining_ == other.remaining_; + } + bool operator!=(ReverseIterator other) { + return remaining_ != other.remaining_; + } + + private: + explicit ReverseIterator(RegListBase<RegisterT> remaining) + : remaining_(remaining) {} + friend class RegListBase; + + RegListBase<RegisterT> remaining_; +}; + +template <typename RegisterT> +typename RegListBase<RegisterT>::Iterator RegListBase<RegisterT>::begin() + const { + return Iterator{*this}; +} +template <typename RegisterT> +typename RegListBase<RegisterT>::Iterator RegListBase<RegisterT>::end() const { + return Iterator{RegListBase<RegisterT>{}}; +} + +template <typename RegisterT> +typename RegListBase<RegisterT>::ReverseIterator +RegListBase<RegisterT>::rbegin() const { + return ReverseIterator{*this}; +} +template <typename RegisterT> +typename RegListBase<RegisterT>::ReverseIterator RegListBase<RegisterT>::rend() + const { + return ReverseIterator{RegListBase<RegisterT>{}}; +} + +template <typename RegisterT> +inline std::ostream& operator<<(std::ostream& os, + RegListBase<RegisterT> reglist) { + os << "{"; + for (bool first = true; !reglist.is_empty(); first = false) { + RegisterT reg = reglist.first(); + reglist.clear(reg); + os << (first ? "" : ", ") << reg; + } + return os << "}"; +} + +} // namespace internal +} // namespace v8 + +#endif // V8_CODEGEN_REGLIST_BASE_H_ |