v8/src/reglist.h
Clemens Hammacher fd306a0658 Allow constexpr RegList construction from Registers
Before, the standard way to create a RegList was either:
RegList list = (1 << 0) | (1 << 1) | ...
or
RegList list = rax.bit() | rdx.bit() | ...

The first way allows to make the RegList constexpr, but needs comments
to document which registers you are referring to, and it has no checks
that all bits you set on the RegList actually belong to valid registers.
The second one uses the symbolic names, hence is much more readable and
makes it harder to construct invalid RegLists. It's not constexpr
though, since the {bit()} method on the register types is not constexpr.

This CL adds a constexpr accessor to get the code and bit of a
constexpr Register, and adds a helper method to create a constexpr
RegList like this:
constexpr RegList list = Register::ListOf<rax, rdx, rdi>();

This new method is used in a number of places to test its
applicability. Other uses of the old pattern remain and can be cleaned
up later.

R=tebbi@chromium.org

Change-Id: Ie7b1d6342dc5f316dcfedd0363b3540ad5e7f413
Reviewed-on: https://chromium-review.googlesource.com/728026
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48887}
2017-10-24 17:30:11 +00:00

48 lines
1.3 KiB
C++

// Copyright 2017 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_REGLIST_H_
#define V8_REGLIST_H_
#include <cstdint>
#include "src/base/bits.h"
#include "src/base/template-utils.h"
namespace v8 {
namespace internal {
// Register configurations.
#if V8_TARGET_ARCH_ARM64
typedef uint64_t RegList;
#else
typedef uint32_t RegList;
#endif
// Get the number of registers in a given register list.
constexpr int NumRegs(RegList list) {
return base::bits::CountPopulation(list);
}
// Combine two RegLists by building the union of the contained registers.
// Implemented as a Functor to pass it to base::fold even on gcc < 5 (see
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52892).
// TODO(clemensh): Remove this once we require gcc >= 5.0.
struct CombineRegListsFunctor {
constexpr RegList operator()(RegList list1, RegList list2) const {
return list1 | list2;
}
};
// Combine several RegLists by building the union of the contained registers.
template <typename... RegLists>
constexpr RegList CombineRegLists(RegLists... lists) {
return base::fold(CombineRegListsFunctor{}, 0, lists...);
}
} // namespace internal
} // namespace v8
#endif // V8_REGLIST_H_