| Index: src/interpreter/bytecode-traits.h
|
| diff --git a/src/interpreter/bytecode-traits.h b/src/interpreter/bytecode-traits.h
|
| index b8136051bbb20eec6c127b9a21c2891742781eed..e966df2810a48fc198ddddc1241dda97026b2677 100644
|
| --- a/src/interpreter/bytecode-traits.h
|
| +++ b/src/interpreter/bytecode-traits.h
|
| @@ -16,17 +16,35 @@ namespace interpreter {
|
| // Template helpers to deduce the number of operands each bytecode has.
|
| #define OPERAND_TERM OperandType::kNone, OperandType::kNone, OperandType::kNone
|
|
|
| +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 {};
|
| +struct OperandTraits {
|
| + typedef OperandTypeInfoTraits<OperandTypeInfo::kNone> TypeInfo;
|
| +};
|
|
|
| -#define DECLARE_OPERAND_SIZE(Name, Size) \
|
| - template <> \
|
| - struct OperandTraits<OperandType::k##Name> { \
|
| - static const OperandSize kSizeType = Size; \
|
| - static const int kSize = static_cast<int>(Size); \
|
| +#define DECLARE_OPERAND_TYPE_TRAITS(Name, InfoType) \
|
| + template <> \
|
| + struct OperandTraits<OperandType::k##Name> { \
|
| + typedef OperandTypeInfoTraits<InfoType> TypeInfo; \
|
| };
|
| -OPERAND_TYPE_LIST(DECLARE_OPERAND_SIZE)
|
| -#undef DECLARE_OPERAND_SIZE
|
| +OPERAND_TYPE_LIST(DECLARE_OPERAND_TYPE_TRAITS)
|
| +#undef DECLARE_OPERAND_TYPE_TRAITS
|
|
|
| template <OperandType>
|
| struct RegisterOperandTraits {
|
| @@ -55,32 +73,19 @@ struct BytecodeTraits<operand_0, operand_1, operand_2, operand_3,
|
| return kOperands[i];
|
| }
|
|
|
| - static inline OperandSize GetOperandSize(int i) {
|
| - DCHECK(0 <= i && i < kOperandCount);
|
| - const OperandSize kOperandSizes[] =
|
| - {OperandTraits<operand_0>::kSizeType,
|
| - OperandTraits<operand_1>::kSizeType,
|
| - OperandTraits<operand_2>::kSizeType,
|
| - OperandTraits<operand_3>::kSizeType};
|
| - return kOperandSizes[i];
|
| - }
|
| -
|
| - static inline int GetOperandOffset(int i) {
|
| - DCHECK(0 <= i && i < kOperandCount);
|
| - const int kOffset0 = 1;
|
| - const int kOffset1 = kOffset0 + OperandTraits<operand_0>::kSize;
|
| - const int kOffset2 = kOffset1 + OperandTraits<operand_1>::kSize;
|
| - const int kOffset3 = kOffset2 + OperandTraits<operand_2>::kSize;
|
| - const int kOperandOffsets[] = {kOffset0, kOffset1, kOffset2, kOffset3};
|
| - return kOperandOffsets[i];
|
| - }
|
| -
|
| 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>::TypeInfo::kIsScalable |
|
| + OperandTraits<operand_1>::TypeInfo::kIsScalable |
|
| + OperandTraits<operand_2>::TypeInfo::kIsScalable |
|
| + OperandTraits<operand_3>::TypeInfo::kIsScalable);
|
| + }
|
| +
|
| static const int kOperandCount = 4;
|
| static const int kRegisterOperandCount =
|
| RegisterOperandTraits<operand_0>::kIsRegisterOperand +
|
| @@ -92,9 +97,6 @@ struct BytecodeTraits<operand_0, operand_1, operand_2, operand_3,
|
| (RegisterOperandTraits<operand_1>::kIsRegisterOperand << 1) +
|
| (RegisterOperandTraits<operand_2>::kIsRegisterOperand << 2) +
|
| (RegisterOperandTraits<operand_3>::kIsRegisterOperand << 3);
|
| - static const int kSize =
|
| - 1 + OperandTraits<operand_0>::kSize + OperandTraits<operand_1>::kSize +
|
| - OperandTraits<operand_2>::kSize + OperandTraits<operand_3>::kSize;
|
| };
|
|
|
| template <OperandType operand_0, OperandType operand_1, OperandType operand_2>
|
| @@ -105,29 +107,17 @@ struct BytecodeTraits<operand_0, operand_1, operand_2, OPERAND_TERM> {
|
| return kOperands[i];
|
| }
|
|
|
| - static inline OperandSize GetOperandSize(int i) {
|
| - DCHECK(0 <= i && i < kOperandCount);
|
| - const OperandSize kOperandSizes[] =
|
| - {OperandTraits<operand_0>::kSizeType,
|
| - OperandTraits<operand_1>::kSizeType,
|
| - OperandTraits<operand_2>::kSizeType};
|
| - return kOperandSizes[i];
|
| - }
|
| -
|
| - static inline int GetOperandOffset(int i) {
|
| - DCHECK(0 <= i && i < kOperandCount);
|
| - const int kOffset0 = 1;
|
| - const int kOffset1 = kOffset0 + OperandTraits<operand_0>::kSize;
|
| - const int kOffset2 = kOffset1 + OperandTraits<operand_1>::kSize;
|
| - const int kOperandOffsets[] = {kOffset0, kOffset1, kOffset2};
|
| - return kOperandOffsets[i];
|
| - }
|
| -
|
| 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>::TypeInfo::kIsScalable |
|
| + OperandTraits<operand_1>::TypeInfo::kIsScalable |
|
| + OperandTraits<operand_2>::TypeInfo::kIsScalable);
|
| + }
|
| +
|
| static const int kOperandCount = 3;
|
| static const int kRegisterOperandCount =
|
| RegisterOperandTraits<operand_0>::kIsRegisterOperand +
|
| @@ -137,9 +127,6 @@ struct BytecodeTraits<operand_0, operand_1, operand_2, OPERAND_TERM> {
|
| RegisterOperandTraits<operand_0>::kIsRegisterOperand +
|
| (RegisterOperandTraits<operand_1>::kIsRegisterOperand << 1) +
|
| (RegisterOperandTraits<operand_2>::kIsRegisterOperand << 2);
|
| - static const int kSize =
|
| - 1 + OperandTraits<operand_0>::kSize + OperandTraits<operand_1>::kSize +
|
| - OperandTraits<operand_2>::kSize;
|
| };
|
|
|
| template <OperandType operand_0, OperandType operand_1>
|
| @@ -150,27 +137,16 @@ struct BytecodeTraits<operand_0, operand_1, OPERAND_TERM> {
|
| return kOperands[i];
|
| }
|
|
|
| - static inline OperandSize GetOperandSize(int i) {
|
| - DCHECK(0 <= i && i < kOperandCount);
|
| - const OperandSize kOperandSizes[] =
|
| - {OperandTraits<operand_0>::kSizeType,
|
| - OperandTraits<operand_1>::kSizeType};
|
| - return kOperandSizes[i];
|
| - }
|
| -
|
| - static inline int GetOperandOffset(int i) {
|
| - DCHECK(0 <= i && i < kOperandCount);
|
| - const int kOffset0 = 1;
|
| - const int kOffset1 = kOffset0 + OperandTraits<operand_0>::kSize;
|
| - const int kOperandOffsets[] = {kOffset0, kOffset1};
|
| - return kOperandOffsets[i];
|
| - }
|
| -
|
| template <OperandType ot>
|
| static inline bool HasAnyOperandsOfType() {
|
| return operand_0 == ot || operand_1 == ot;
|
| }
|
|
|
| + static inline bool IsScalable() {
|
| + return (OperandTraits<operand_0>::TypeInfo::kIsScalable |
|
| + OperandTraits<operand_1>::TypeInfo::kIsScalable);
|
| + }
|
| +
|
| static const int kOperandCount = 2;
|
| static const int kRegisterOperandCount =
|
| RegisterOperandTraits<operand_0>::kIsRegisterOperand +
|
| @@ -178,8 +154,6 @@ struct BytecodeTraits<operand_0, operand_1, OPERAND_TERM> {
|
| static const int kRegisterOperandBitmap =
|
| RegisterOperandTraits<operand_0>::kIsRegisterOperand +
|
| (RegisterOperandTraits<operand_1>::kIsRegisterOperand << 1);
|
| - static const int kSize =
|
| - 1 + OperandTraits<operand_0>::kSize + OperandTraits<operand_1>::kSize;
|
| };
|
|
|
| template <OperandType operand_0>
|
| @@ -189,27 +163,20 @@ struct BytecodeTraits<operand_0, OPERAND_TERM> {
|
| return operand_0;
|
| }
|
|
|
| - static inline OperandSize GetOperandSize(int i) {
|
| - DCHECK(i == 0);
|
| - return OperandTraits<operand_0>::kSizeType;
|
| - }
|
| -
|
| - static inline int GetOperandOffset(int i) {
|
| - DCHECK(i == 0);
|
| - return 1;
|
| - }
|
| -
|
| template <OperandType ot>
|
| static inline bool HasAnyOperandsOfType() {
|
| return operand_0 == ot;
|
| }
|
|
|
| + static inline bool IsScalable() {
|
| + return OperandTraits<operand_0>::TypeInfo::kIsScalable;
|
| + }
|
| +
|
| static const int kOperandCount = 1;
|
| static const int kRegisterOperandCount =
|
| RegisterOperandTraits<operand_0>::kIsRegisterOperand;
|
| static const int kRegisterOperandBitmap =
|
| RegisterOperandTraits<operand_0>::kIsRegisterOperand;
|
| - static const int kSize = 1 + OperandTraits<operand_0>::kSize;
|
| };
|
|
|
| template <>
|
| @@ -219,27 +186,57 @@ struct BytecodeTraits<OperandType::kNone, OPERAND_TERM> {
|
| return OperandType::kNone;
|
| }
|
|
|
| - static inline OperandSize GetOperandSize(int i) {
|
| - UNREACHABLE();
|
| - return OperandSize::kNone;
|
| - }
|
| -
|
| - static inline int GetOperandOffset(int i) {
|
| - UNREACHABLE();
|
| - return 1;
|
| - }
|
| -
|
| template <OperandType ot>
|
| static inline bool HasAnyOperandsOfType() {
|
| return false;
|
| }
|
|
|
| + static inline bool IsScalable() { return false; }
|
| +
|
| static const int kOperandCount = 0;
|
| static const int kRegisterOperandCount = 0;
|
| static const int kRegisterOperandBitmap = 0;
|
| - static const int kSize = 1 + OperandTraits<OperandType::kNone>::kSize;
|
| };
|
|
|
| +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) {
|
| + 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; \
|
| + }
|
| + OPERAND_TYPE_LIST(CASE)
|
| +#undef CASE
|
| + }
|
| + UNREACHABLE();
|
| + return OperandSize::kNone;
|
| +}
|
| +
|
| } // namespace interpreter
|
| } // namespace internal
|
| } // namespace v8
|
|
|