blob: 50c15cdbc1b7cd1d7cb1a3d6e7e8416cbbdf1e49 [file] [log] [blame]
// Copyright 2015 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_INTERPRETER_BYTECODE_TRAITS_H_
#define V8_INTERPRETER_BYTECODE_TRAITS_H_
#include "src/interpreter/bytecode-operands.h"
namespace v8 {
namespace internal {
namespace interpreter {
template <OperandTypeInfo>
struct OperandTypeInfoTraits;
#define DECLARE_OPERAND_TYPE_INFO(Name, Scalable, Unsigned, BaseSize) \
template <> \
struct OperandTypeInfoTraits<OperandTypeInfo::k##Name> { \
static constexpr bool kIsScalable = Scalable; \
static constexpr bool kIsUnsigned = Unsigned; \
static constexpr OperandSize kUnscaledSize = BaseSize; \
};
OPERAND_TYPE_INFO_LIST(DECLARE_OPERAND_TYPE_INFO)
#undef DECLARE_OPERAND_TYPE_INFO
template <OperandType>
struct OperandTraits;
#define DECLARE_OPERAND_TYPE_TRAITS(Name, InfoType) \
template <> \
struct OperandTraits<OperandType::k##Name> { \
using TypeInfoTraits = OperandTypeInfoTraits<InfoType>; \
static constexpr OperandTypeInfo kOperandTypeInfo = InfoType; \
};
OPERAND_TYPE_LIST(DECLARE_OPERAND_TYPE_TRAITS)
#undef DECLARE_OPERAND_TYPE_TRAITS
template <OperandType operand_type, OperandScale operand_scale>
struct OperandScaler {
static constexpr int kSize =
static_cast<int>(
OperandTraits<operand_type>::TypeInfoTraits::kUnscaledSize) *
(OperandTraits<operand_type>::TypeInfoTraits::kIsScalable
? static_cast<int>(operand_scale)
: 1);
static constexpr OperandSize kOperandSize = static_cast<OperandSize>(kSize);
};
template <ImplicitRegisterUse implicit_register_use, OperandType... operands>
struct BytecodeTraits {
static constexpr OperandType kOperandTypes[] = {operands...};
static constexpr OperandTypeInfo kOperandTypeInfos[] = {
OperandTraits<operands>::kOperandTypeInfo...};
static constexpr OperandSize kSingleScaleOperandSizes[] = {
OperandScaler<operands, OperandScale::kSingle>::kOperandSize...};
static constexpr OperandSize kDoubleScaleOperandSizes[] = {
OperandScaler<operands, OperandScale::kDouble>::kOperandSize...};
static constexpr OperandSize kQuadrupleScaleOperandSizes[] = {
OperandScaler<operands, OperandScale::kQuadruple>::kOperandSize...};
template <OperandScale scale>
static constexpr auto CalculateOperandOffsets() {
std::array<int, sizeof...(operands) + 1> result{};
int offset = 1;
int i = 0;
(((result[i++] = offset),
(offset += OperandScaler<operands, scale>::kSize)),
...);
return result;
}
static constexpr auto kSingleScaleOperandOffsets =
CalculateOperandOffsets<OperandScale::kSingle>();
static constexpr auto kDoubleScaleOperandOffsets =
CalculateOperandOffsets<OperandScale::kDouble>();
static constexpr auto kQuadrupleScaleOperandOffsets =
CalculateOperandOffsets<OperandScale::kQuadruple>();
static constexpr int kSingleScaleSize =
(1 + ... + OperandScaler<operands, OperandScale::kSingle>::kSize);
static constexpr int kDoubleScaleSize =
(1 + ... + OperandScaler<operands, OperandScale::kDouble>::kSize);
static constexpr int kQuadrupleScaleSize =
(1 + ... + OperandScaler<operands, OperandScale::kQuadruple>::kSize);
static constexpr ImplicitRegisterUse kImplicitRegisterUse =
implicit_register_use;
static constexpr int kOperandCount = sizeof...(operands);
};
template <ImplicitRegisterUse implicit_register_use>
struct BytecodeTraits<implicit_register_use> {
static constexpr OperandType* kOperandTypes = nullptr;
static constexpr OperandTypeInfo* kOperandTypeInfos = nullptr;
static constexpr OperandSize* kSingleScaleOperandSizes = nullptr;
static constexpr OperandSize* kDoubleScaleOperandSizes = nullptr;
static constexpr OperandSize* kQuadrupleScaleOperandSizes = nullptr;
static constexpr auto kSingleScaleOperandOffsets = std::array<int, 0>{};
static constexpr auto kDoubleScaleOperandOffsets = std::array<int, 0>{};
static constexpr auto kQuadrupleScaleOperandOffsets = std::array<int, 0>{};
static constexpr int kSingleScaleSize = 1;
static constexpr int kDoubleScaleSize = 1;
static constexpr int kQuadrupleScaleSize = 1;
static constexpr ImplicitRegisterUse kImplicitRegisterUse =
implicit_register_use;
static constexpr int kOperandCount = 0;
};
} // namespace interpreter
} // namespace internal
} // namespace v8
#endif // V8_INTERPRETER_BYTECODE_TRAITS_H_