Index: src/interpreter/bytecode-traits.h |
diff --git a/src/interpreter/bytecode-traits.h b/src/interpreter/bytecode-traits.h |
index c724827356a3d020384386e7b875545c29f9b569..e7d14325037a44ce8757fc9ed07be47d85a8f00f 100644 |
--- a/src/interpreter/bytecode-traits.h |
+++ b/src/interpreter/bytecode-traits.h |
@@ -41,6 +41,28 @@ struct OperandTraits { |
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>::TypeInfo::kIsScalable, |
+ OperandTraits<operand_type>::TypeInfo::kUnscaledSize, |
+ operand_scale>::kSize; |
+ static const OperandSize kOperandSize = static_cast<OperandSize>(kSize); |
+}; |
+ |
template <OperandType> |
struct RegisterOperandTraits { |
static const int kIsRegisterOperand = 0; |
@@ -61,11 +83,30 @@ 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 OperandType GetOperandType(int i) { |
- DCHECK(0 <= i && i < kOperandCount); |
- const OperandType kOperands[] = {operand_0, operand_1, operand_2, |
- operand_3}; |
- return kOperands[i]; |
+ static const OperandType* GetOperandTypes() { |
+ static const OperandType operand_types[] = {operand_0, operand_1, operand_2, |
+ operand_3, OperandType::kNone}; |
+ return operand_types; |
+ } |
+ |
+ static OperandSize GetOperandSize(int i, OperandScale operand_scale) { |
+ switch (operand_scale) { |
+#define CASE(Name, _) \ |
+ case OperandScale::k##Name: { \ |
+ static const OperandSize kOperandSizes[] = { \ |
+ OperandScaler<operand_0, OperandScale::k##Name>::kOperandSize, \ |
+ OperandScaler<operand_1, OperandScale::k##Name>::kOperandSize, \ |
+ OperandScaler<operand_2, OperandScale::k##Name>::kOperandSize, \ |
+ OperandScaler<operand_3, OperandScale::k##Name>::kOperandSize, \ |
+ }; \ |
+ DCHECK_LT(static_cast<size_t>(i), arraysize(kOperandSizes)); \ |
+ return kOperandSizes[i]; \ |
+ } |
+ OPERAND_SCALE_LIST(CASE) |
+#undef CASE |
+ } |
+ UNREACHABLE(); |
+ return OperandSize::kNone; |
} |
template <OperandType ot> |
@@ -98,10 +139,29 @@ struct BytecodeTraits<accumulator_use, operand_0, operand_1, operand_2, |
template <AccumulatorUse accumulator_use, OperandType operand_0, |
OperandType operand_1, OperandType operand_2> |
struct BytecodeTraits<accumulator_use, operand_0, operand_1, operand_2> { |
- static inline OperandType GetOperandType(int i) { |
- DCHECK(0 <= i && i <= 2); |
- const OperandType kOperands[] = {operand_0, operand_1, operand_2}; |
- return kOperands[i]; |
+ static const OperandType* GetOperandTypes() { |
+ static const OperandType operand_types[] = {operand_0, operand_1, operand_2, |
+ OperandType::kNone}; |
+ return operand_types; |
+ } |
+ |
+ static OperandSize GetOperandSize(int i, OperandScale operand_scale) { |
+ switch (operand_scale) { |
+#define CASE(Name, _) \ |
+ case OperandScale::k##Name: { \ |
+ static const OperandSize kOperandSizes[] = { \ |
+ OperandScaler<operand_0, OperandScale::k##Name>::kOperandSize, \ |
+ OperandScaler<operand_1, OperandScale::k##Name>::kOperandSize, \ |
+ OperandScaler<operand_2, OperandScale::k##Name>::kOperandSize, \ |
+ }; \ |
+ DCHECK_LT(static_cast<size_t>(i), arraysize(kOperandSizes)); \ |
+ return kOperandSizes[i]; \ |
+ } |
+ OPERAND_SCALE_LIST(CASE) |
+#undef CASE |
+ } |
+ UNREACHABLE(); |
+ return OperandSize::kNone; |
} |
template <OperandType ot> |
@@ -130,10 +190,28 @@ struct BytecodeTraits<accumulator_use, operand_0, operand_1, operand_2> { |
template <AccumulatorUse accumulator_use, OperandType operand_0, |
OperandType operand_1> |
struct BytecodeTraits<accumulator_use, operand_0, operand_1> { |
- static inline OperandType GetOperandType(int i) { |
- DCHECK(0 <= i && i < kOperandCount); |
- const OperandType kOperands[] = {operand_0, operand_1}; |
- return kOperands[i]; |
+ static const OperandType* GetOperandTypes() { |
+ static const OperandType operand_types[] = {operand_0, operand_1, |
+ OperandType::kNone}; |
+ return operand_types; |
+ } |
+ |
+ static OperandSize GetOperandSize(int i, OperandScale operand_scale) { |
+ switch (operand_scale) { |
+#define CASE(Name, _) \ |
+ case OperandScale::k##Name: { \ |
+ static const OperandSize kOperandSizes[] = { \ |
+ OperandScaler<operand_0, OperandScale::k##Name>::kOperandSize, \ |
+ OperandScaler<operand_1, OperandScale::k##Name>::kOperandSize, \ |
+ }; \ |
+ DCHECK_LT(static_cast<size_t>(i), arraysize(kOperandSizes)); \ |
+ return kOperandSizes[i]; \ |
+ } |
+ OPERAND_SCALE_LIST(CASE) |
+#undef CASE |
+ } |
+ UNREACHABLE(); |
+ return OperandSize::kNone; |
} |
template <OperandType ot> |
@@ -158,9 +236,26 @@ struct BytecodeTraits<accumulator_use, operand_0, operand_1> { |
template <AccumulatorUse accumulator_use, OperandType operand_0> |
struct BytecodeTraits<accumulator_use, operand_0> { |
- static inline OperandType GetOperandType(int i) { |
- DCHECK(i == 0); |
- return operand_0; |
+ static const OperandType* GetOperandTypes() { |
+ static const OperandType operand_types[] = {operand_0, OperandType::kNone}; |
+ return operand_types; |
+ } |
+ |
+ static OperandSize GetOperandSize(int i, OperandScale operand_scale) { |
+ switch (operand_scale) { |
+#define CASE(Name, _) \ |
+ case OperandScale::k##Name: { \ |
+ static const OperandSize kOperandSizes[] = { \ |
+ OperandScaler<operand_0, OperandScale::k##Name>::kOperandSize, \ |
+ }; \ |
+ DCHECK_LT(static_cast<size_t>(i), arraysize(kOperandSizes)); \ |
+ return kOperandSizes[i]; \ |
+ } |
+ OPERAND_SCALE_LIST(CASE) |
+#undef CASE |
+ } |
+ UNREACHABLE(); |
+ return OperandSize::kNone; |
} |
template <OperandType ot> |
@@ -182,9 +277,14 @@ struct BytecodeTraits<accumulator_use, operand_0> { |
template <AccumulatorUse accumulator_use> |
struct BytecodeTraits<accumulator_use> { |
- static inline OperandType GetOperandType(int i) { |
+ static const OperandType* GetOperandTypes() { |
+ static const OperandType operand_types[] = {OperandType::kNone}; |
+ return operand_types; |
+ } |
+ |
+ static OperandSize GetOperandSize(int i, OperandScale operand_scale) { |
UNREACHABLE(); |
- return OperandType::kNone; |
+ return OperandSize::kNone; |
} |
template <OperandType ot> |
@@ -200,37 +300,22 @@ struct BytecodeTraits<accumulator_use> { |
static const int kRegisterOperandBitmap = 0; |
}; |
-template <bool> |
-struct OperandScaler { |
- static int Multiply(int size, int operand_scale) { return 0; } |
-}; |
- |
-template <> |
-struct OperandScaler<false> { |
- static int Multiply(int size, int operand_scale) { return size; } |
-}; |
- |
-template <> |
-struct OperandScaler<true> { |
- static int Multiply(int size, int operand_scale) { |
- return size * operand_scale; |
- } |
-}; |
- |
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: { \ |
- OperandSize base_size = OperandTypeInfoTraits<TypeInfo>::kUnscaledSize; \ |
- int size = \ |
- OperandScaler<OperandTypeInfoTraits<TypeInfo>::kIsScalable>::Multiply( \ |
- static_cast<int>(base_size), static_cast<int>(operand_scale)); \ |
- OperandSize operand_size = static_cast<OperandSize>(size); \ |
- DCHECK(operand_size == OperandSize::kByte || \ |
- operand_size == OperandSize::kShort || \ |
- operand_size == OperandSize::kQuad); \ |
- return operand_size; \ |
+#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 |