summaryrefslogtreecommitdiff
path: root/deps/v8/src/codegen/reglist-base.h
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/codegen/reglist-base.h')
-rw-r--r--deps/v8/src/codegen/reglist-base.h232
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_