| 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
|
|
|