Index: src/interpreter/bytecode-traits.h |
diff --git a/src/interpreter/bytecode-traits.h b/src/interpreter/bytecode-traits.h |
index f71598cbef94808cb8a7a6a3dcba60422dd5b41e..672a687faf0f7cddabea7314190cb6f3ff6140fc 100644 |
--- a/src/interpreter/bytecode-traits.h |
+++ b/src/interpreter/bytecode-traits.h |
@@ -5,7 +5,7 @@ |
#ifndef V8_INTERPRETER_BYTECODE_TRAITS_H_ |
#define V8_INTERPRETER_BYTECODE_TRAITS_H_ |
-#include "src/interpreter/bytecode-operands.h" |
+#include "src/interpreter/bytecodes.h" |
namespace v8 { |
namespace internal { |
@@ -65,88 +65,208 @@ |
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 <OperandType> |
+struct RegisterOperandTraits { |
+ static const int kIsRegisterOperand = 0; |
+}; |
+ |
+#define DECLARE_REGISTER_OPERAND(Name, _) \ |
+ template <> \ |
+ struct RegisterOperandTraits<OperandType::k##Name> { \ |
+ static const int kIsRegisterOperand = 1; \ |
+ }; |
+REGISTER_OPERAND_TYPE_LIST(DECLARE_REGISTER_OPERAND) |
+#undef DECLARE_REGISTER_OPERAND |
+ |
+template <AccumulatorUse, OperandType...> |
+struct BytecodeTraits {}; |
+ |
+template <AccumulatorUse accumulator_use, OperandType operand_0, |
+ OperandType operand_1, OperandType operand_2, OperandType operand_3> |
+struct BytecodeTraits<accumulator_use, operand_0, operand_1, operand_2, |
+ operand_3> { |
+ static const OperandType* GetOperandTypes() { |
+ static const OperandType operand_types[] = {operand_0, operand_1, operand_2, |
+ operand_3, OperandType::kNone}; |
+ return operand_types; |
+ } |
+ |
+ static const OperandTypeInfo* GetOperandTypeInfos() { |
+ static const OperandTypeInfo operand_type_infos[] = { |
+ OperandTraits<operand_0>::kOperandTypeInfo, |
+ OperandTraits<operand_1>::kOperandTypeInfo, |
+ OperandTraits<operand_2>::kOperandTypeInfo, |
+ OperandTraits<operand_3>::kOperandTypeInfo, OperandTypeInfo::kNone}; |
+ return operand_type_infos; |
+ } |
+ |
+ template <OperandType ot> |
+ static inline bool HasAnyOperandsOfType() { |
+ return operand_0 == ot || operand_1 == ot || operand_2 == ot || |
+ operand_3 == ot; |
+ } |
+ |
+ static inline bool IsScalable() { |
+ return (OperandTraits<operand_0>::TypeInfoTraits::kIsScalable | |
+ OperandTraits<operand_1>::TypeInfoTraits::kIsScalable | |
+ OperandTraits<operand_2>::TypeInfoTraits::kIsScalable | |
+ OperandTraits<operand_3>::TypeInfoTraits::kIsScalable); |
+ } |
+ |
+ static const AccumulatorUse kAccumulatorUse = accumulator_use; |
+ static const int kOperandCount = 4; |
+ static const int kRegisterOperandCount = |
+ RegisterOperandTraits<operand_0>::kIsRegisterOperand + |
+ RegisterOperandTraits<operand_1>::kIsRegisterOperand + |
+ RegisterOperandTraits<operand_2>::kIsRegisterOperand + |
+ RegisterOperandTraits<operand_3>::kIsRegisterOperand; |
+}; |
+ |
+template <AccumulatorUse accumulator_use, OperandType operand_0, |
+ OperandType operand_1, OperandType operand_2> |
+struct BytecodeTraits<accumulator_use, operand_0, operand_1, operand_2> { |
+ static const OperandType* GetOperandTypes() { |
+ static const OperandType operand_types[] = {operand_0, operand_1, operand_2, |
+ OperandType::kNone}; |
+ return operand_types; |
+ } |
+ |
+ static const OperandTypeInfo* GetOperandTypeInfos() { |
+ static const OperandTypeInfo operand_type_infos[] = { |
+ OperandTraits<operand_0>::kOperandTypeInfo, |
+ OperandTraits<operand_1>::kOperandTypeInfo, |
+ OperandTraits<operand_2>::kOperandTypeInfo, OperandTypeInfo::kNone}; |
+ return operand_type_infos; |
+ } |
+ |
+ template <OperandType ot> |
+ static inline bool HasAnyOperandsOfType() { |
+ return operand_0 == ot || operand_1 == ot || operand_2 == ot; |
+ } |
+ |
+ static inline bool IsScalable() { |
+ return (OperandTraits<operand_0>::TypeInfoTraits::kIsScalable | |
+ OperandTraits<operand_1>::TypeInfoTraits::kIsScalable | |
+ OperandTraits<operand_2>::TypeInfoTraits::kIsScalable); |
+ } |
+ |
+ static const AccumulatorUse kAccumulatorUse = accumulator_use; |
+ static const int kOperandCount = 3; |
+ static const int kRegisterOperandCount = |
+ RegisterOperandTraits<operand_0>::kIsRegisterOperand + |
+ RegisterOperandTraits<operand_1>::kIsRegisterOperand + |
+ RegisterOperandTraits<operand_2>::kIsRegisterOperand; |
+}; |
+ |
+template <AccumulatorUse accumulator_use, OperandType operand_0, |
+ OperandType operand_1> |
+struct BytecodeTraits<accumulator_use, operand_0, operand_1> { |
+ static const OperandType* GetOperandTypes() { |
+ static const OperandType operand_types[] = {operand_0, operand_1, |
+ OperandType::kNone}; |
+ return operand_types; |
+ } |
+ |
+ static const OperandTypeInfo* GetOperandTypeInfos() { |
+ static const OperandTypeInfo operand_type_infos[] = { |
+ OperandTraits<operand_0>::kOperandTypeInfo, |
+ OperandTraits<operand_1>::kOperandTypeInfo, OperandTypeInfo::kNone}; |
+ return operand_type_infos; |
+ } |
+ |
+ template <OperandType ot> |
+ static inline bool HasAnyOperandsOfType() { |
+ return operand_0 == ot || operand_1 == ot; |
+ } |
+ |
+ static inline bool IsScalable() { |
+ return (OperandTraits<operand_0>::TypeInfoTraits::kIsScalable | |
+ OperandTraits<operand_1>::TypeInfoTraits::kIsScalable); |
+ } |
+ |
+ static const AccumulatorUse kAccumulatorUse = accumulator_use; |
+ static const int kOperandCount = 2; |
+ static const int kRegisterOperandCount = |
+ RegisterOperandTraits<operand_0>::kIsRegisterOperand + |
+ RegisterOperandTraits<operand_1>::kIsRegisterOperand; |
+}; |
+ |
+template <AccumulatorUse accumulator_use, OperandType operand_0> |
+struct BytecodeTraits<accumulator_use, operand_0> { |
+ static const OperandType* GetOperandTypes() { |
+ static const OperandType operand_types[] = {operand_0, OperandType::kNone}; |
+ return operand_types; |
+ } |
+ |
+ static const OperandTypeInfo* GetOperandTypeInfos() { |
+ static const OperandTypeInfo operand_type_infos[] = { |
+ OperandTraits<operand_0>::kOperandTypeInfo, OperandTypeInfo::kNone}; |
+ return operand_type_infos; |
+ } |
+ |
+ template <OperandType ot> |
+ static inline bool HasAnyOperandsOfType() { |
+ return operand_0 == ot; |
+ } |
+ |
+ static inline bool IsScalable() { |
+ return OperandTraits<operand_0>::TypeInfoTraits::kIsScalable; |
+ } |
+ |
+ static const AccumulatorUse kAccumulatorUse = accumulator_use; |
+ static const int kOperandCount = 1; |
+ static const int kRegisterOperandCount = |
+ RegisterOperandTraits<operand_0>::kIsRegisterOperand; |
+}; |
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 OperandType* GetOperandTypes() { |
+ static const OperandType operand_types[] = {OperandType::kNone}; |
+ return operand_types; |
+ } |
+ |
+ static const OperandTypeInfo* GetOperandTypeInfos() { |
+ static const OperandTypeInfo operand_type_infos[] = { |
+ OperandTypeInfo::kNone}; |
+ return operand_type_infos; |
+ } |
+ |
+ template <OperandType ot> |
+ static inline bool HasAnyOperandsOfType() { |
+ return false; |
+ } |
+ |
+ static inline bool IsScalable() { return false; } |
+ |
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}; |
+ static const int kRegisterOperandCount = 0; |
+}; |
+ |
+static OperandSize ScaledOperandSize(OperandType operand_type, |
+ OperandScale operand_scale) { |
+ STATIC_ASSERT(static_cast<int>(OperandScale::kQuadruple) == 4 && |
+ OperandScale::kLast == OperandScale::kQuadruple); |
+ int index = static_cast<int>(operand_scale) >> 1; |
+ switch (operand_type) { |
+#define CASE(Name, TypeInfo) \ |
+ case OperandType::k##Name: { \ |
+ static const OperandSize kOperandSizes[] = { \ |
+ OperandScaler<OperandType::k##Name, \ |
+ OperandScale::kSingle>::kOperandSize, \ |
+ OperandScaler<OperandType::k##Name, \ |
+ OperandScale::kDouble>::kOperandSize, \ |
+ OperandScaler<OperandType::k##Name, \ |
+ OperandScale::kQuadruple>::kOperandSize}; \ |
+ return kOperandSizes[index]; \ |
+ } |
+ OPERAND_TYPE_LIST(CASE) |
+#undef CASE |
+ } |
+ UNREACHABLE(); |
+ return OperandSize::kNone; |
+} |
} // namespace interpreter |
} // namespace internal |