blob: 6b081a741d8dc24b42c8eb8a95452c86a884aae6 [file] [log] [blame]
// 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_MAGLEV_MAGLEV_REGALLOC_DATA_H_
#define V8_MAGLEV_MAGLEV_REGALLOC_DATA_H_
#include "src/base/pointer-with-payload.h"
#include "src/codegen/register.h"
#include "src/compiler/backend/instruction.h"
namespace v8 {
namespace internal {
namespace maglev {
class ValueNode;
#define COUNT(V) +1
static constexpr int kAllocatableGeneralRegisterCount =
ALLOCATABLE_GENERAL_REGISTERS(COUNT);
#undef COUNT
#define COUNT(V) +1
static constexpr int kAllocatableDoubleRegisterCount =
ALLOCATABLE_DOUBLE_REGISTERS(COUNT);
#undef COUNT
template <typename T>
struct AllocatableRegisters;
template <>
struct AllocatableRegisters<Register> {
static constexpr RegList kRegisters = kAllocatableGeneralRegisters;
static constexpr int kCount = kAllocatableGeneralRegisterCount;
};
template <>
struct AllocatableRegisters<DoubleRegister> {
static constexpr DoubleRegList kRegisters = kAllocatableDoubleRegisters;
static constexpr int kCount = kAllocatableDoubleRegisterCount;
};
struct RegisterStateFlags {
// TODO(v8:7700): Use the good old Flags mechanism.
static constexpr int kIsMergeShift = 0;
static constexpr int kIsInitializedShift = 1;
const bool is_initialized = false;
const bool is_merge = false;
explicit constexpr operator uintptr_t() const {
return (is_initialized ? 1 << kIsInitializedShift : 0) |
(is_merge ? 1 << kIsMergeShift : 0);
}
constexpr explicit RegisterStateFlags(uintptr_t state)
: is_initialized((state & (1 << kIsInitializedShift)) != 0),
is_merge((state & (1 << kIsMergeShift)) != 0) {}
constexpr RegisterStateFlags(bool is_initialized, bool is_merge)
: is_initialized(is_initialized), is_merge(is_merge) {}
};
constexpr bool operator==(const RegisterStateFlags& left,
const RegisterStateFlags& right) {
return left.is_initialized == right.is_initialized &&
left.is_merge == right.is_merge;
}
typedef base::PointerWithPayload<void, RegisterStateFlags, 2> RegisterState;
struct RegisterMerge {
compiler::InstructionOperand* operands() {
return reinterpret_cast<compiler::InstructionOperand*>(this + 1);
}
compiler::InstructionOperand& operand(size_t i) { return operands()[i]; }
ValueNode* node;
};
inline bool LoadMergeState(RegisterState state, RegisterMerge** merge) {
DCHECK(state.GetPayload().is_initialized);
if (state.GetPayload().is_merge) {
*merge = static_cast<RegisterMerge*>(state.GetPointer());
return true;
}
*merge = nullptr;
return false;
}
inline bool LoadMergeState(RegisterState state, ValueNode** node,
RegisterMerge** merge) {
DCHECK(state.GetPayload().is_initialized);
if (LoadMergeState(state, merge)) {
*node = (*merge)->node;
return true;
}
*node = static_cast<ValueNode*>(state.GetPointer());
return false;
}
} // namespace maglev
} // namespace internal
} // namespace v8
#endif // V8_MAGLEV_MAGLEV_REGALLOC_DATA_H_