| // 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 { |
| static const bool kIsScalable = false; |
| static const bool kIsUnsigned = false; |
| static const OperandSize kUnscaledSize = OperandSize::kNone; |
| }; |
| |
| #define DECLARE_OPERAND_TYPE_INFO(Name, Scalable, Unsigned, BaseSize) \ |
| template <> \ |
| struct OperandTypeInfoTraits<OperandTypeInfo::k##Name> { \ |
| static const bool kIsScalable = Scalable; \ |
| static const bool kIsUnsigned = Unsigned; \ |
| static const OperandSize kUnscaledSize = BaseSize; \ |
| }; |
| OPERAND_TYPE_INFO_LIST(DECLARE_OPERAND_TYPE_INFO) |
| #undef DECLARE_OPERAND_TYPE_INFO |
| |
| template <OperandType> |
| struct OperandTraits { |
| using TypeInfoTraits = OperandTypeInfoTraits<OperandTypeInfo::kNone>; |
| static const OperandTypeInfo kOperandTypeInfo = OperandTypeInfo::kNone; |
| }; |
| |
| #define DECLARE_OPERAND_TYPE_TRAITS(Name, InfoType) \ |
| template <> \ |
| struct OperandTraits<OperandType::k##Name> { \ |
| using TypeInfoTraits = OperandTypeInfoTraits<InfoType>; \ |
| static const OperandTypeInfo kOperandTypeInfo = InfoType; \ |
| }; |
| OPERAND_TYPE_LIST(DECLARE_OPERAND_TYPE_TRAITS) |
| #undef DECLARE_OPERAND_TYPE_TRAITS |
| |
| template <OperandType operand_type, OperandScale operand_scale> |
| struct OperandScaler { |
| template <bool, OperandSize, OperandScale> |
| struct Helper { |
| static const int kSize = 0; |
| }; |
| template <OperandSize size, OperandScale scale> |
| struct Helper<false, size, scale> { |
| static const int kSize = static_cast<int>(size); |
| }; |
| template <OperandSize size, OperandScale scale> |
| struct Helper<true, size, scale> { |
| static const int kSize = static_cast<int>(size) * static_cast<int>(scale); |
| }; |
| |
| static const int kSize = |
| Helper<OperandTraits<operand_type>::TypeInfoTraits::kIsScalable, |
| OperandTraits<operand_type>::TypeInfoTraits::kUnscaledSize, |
| operand_scale>::kSize; |
| static const OperandSize kOperandSize = static_cast<OperandSize>(kSize); |
| }; |
| |
| template <int... values> |
| struct SumHelper; |
| template <int value> |
| struct SumHelper<value> { |
| static const int kValue = value; |
| }; |
| template <int value, int... values> |
| struct SumHelper<value, values...> { |
| static const int kValue = value + SumHelper<values...>::kValue; |
| }; |
| |
| template <AccumulatorUse accumulator_use, OperandType... operands> |
| struct BytecodeTraits { |
| static const OperandType kOperandTypes[]; |
| static const OperandTypeInfo kOperandTypeInfos[]; |
| static const OperandSize kSingleScaleOperandSizes[]; |
| static const OperandSize kDoubleScaleOperandSizes[]; |
| static const OperandSize kQuadrupleScaleOperandSizes[]; |
| static const int kSingleScaleSize = SumHelper< |
| 1, OperandScaler<operands, OperandScale::kSingle>::kSize...>::kValue; |
| static const int kDoubleScaleSize = SumHelper< |
| 1, OperandScaler<operands, OperandScale::kDouble>::kSize...>::kValue; |
| static const int kQuadrupleScaleSize = SumHelper< |
| 1, OperandScaler<operands, OperandScale::kQuadruple>::kSize...>::kValue; |
| static const AccumulatorUse kAccumulatorUse = accumulator_use; |
| static const int kOperandCount = sizeof...(operands); |
| }; |
| |
| template <AccumulatorUse accumulator_use, OperandType... operands> |
| STATIC_CONST_MEMBER_DEFINITION const OperandType |
| BytecodeTraits<accumulator_use, operands...>::kOperandTypes[] = { |
| operands...}; |
| template <AccumulatorUse accumulator_use, OperandType... operands> |
| STATIC_CONST_MEMBER_DEFINITION const OperandTypeInfo |
| BytecodeTraits<accumulator_use, operands...>::kOperandTypeInfos[] = { |
| OperandTraits<operands>::kOperandTypeInfo...}; |
| template <AccumulatorUse accumulator_use, OperandType... operands> |
| STATIC_CONST_MEMBER_DEFINITION const OperandSize |
| BytecodeTraits<accumulator_use, operands...>::kSingleScaleOperandSizes[] = { |
| OperandScaler<operands, OperandScale::kSingle>::kOperandSize...}; |
| template <AccumulatorUse accumulator_use, OperandType... operands> |
| STATIC_CONST_MEMBER_DEFINITION const OperandSize |
| BytecodeTraits<accumulator_use, operands...>::kDoubleScaleOperandSizes[] = { |
| OperandScaler<operands, OperandScale::kDouble>::kOperandSize...}; |
| template <AccumulatorUse accumulator_use, OperandType... operands> |
| STATIC_CONST_MEMBER_DEFINITION const OperandSize BytecodeTraits< |
| accumulator_use, operands...>::kQuadrupleScaleOperandSizes[] = { |
| OperandScaler<operands, OperandScale::kQuadruple>::kOperandSize...}; |
| |
| template <AccumulatorUse accumulator_use> |
| struct BytecodeTraits<accumulator_use> { |
| static const OperandType kOperandTypes[]; |
| static const OperandTypeInfo kOperandTypeInfos[]; |
| static const OperandSize kSingleScaleOperandSizes[]; |
| static const OperandSize kDoubleScaleOperandSizes[]; |
| static const OperandSize kQuadrupleScaleOperandSizes[]; |
| static const int kSingleScaleSize = 1; |
| static const int kDoubleScaleSize = 1; |
| static const int kQuadrupleScaleSize = 1; |
| static const AccumulatorUse kAccumulatorUse = accumulator_use; |
| static const int kOperandCount = 0; |
| }; |
| |
| template <AccumulatorUse accumulator_use> |
| STATIC_CONST_MEMBER_DEFINITION const OperandType |
| BytecodeTraits<accumulator_use>::kOperandTypes[] = {OperandType::kNone}; |
| template <AccumulatorUse accumulator_use> |
| STATIC_CONST_MEMBER_DEFINITION const OperandTypeInfo |
| BytecodeTraits<accumulator_use>::kOperandTypeInfos[] = { |
| OperandTypeInfo::kNone}; |
| template <AccumulatorUse accumulator_use> |
| STATIC_CONST_MEMBER_DEFINITION const OperandSize |
| BytecodeTraits<accumulator_use>::kSingleScaleOperandSizes[] = { |
| OperandSize::kNone}; |
| template <AccumulatorUse accumulator_use> |
| STATIC_CONST_MEMBER_DEFINITION const OperandSize |
| BytecodeTraits<accumulator_use>::kDoubleScaleOperandSizes[] = { |
| OperandSize::kNone}; |
| template <AccumulatorUse accumulator_use> |
| STATIC_CONST_MEMBER_DEFINITION const OperandSize |
| BytecodeTraits<accumulator_use>::kQuadrupleScaleOperandSizes[] = { |
| OperandSize::kNone}; |
| |
| } // namespace interpreter |
| } // namespace internal |
| } // namespace v8 |
| |
| #endif // V8_INTERPRETER_BYTECODE_TRAITS_H_ |