1 // Copyright 2015 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef V8_INTERPRETER_BYTECODE_TRAITS_H_ 6 #define V8_INTERPRETER_BYTECODE_TRAITS_H_ 7 8 #include "src/interpreter/bytecode-operands.h" 9 10 namespace v8 { 11 namespace internal { 12 namespace interpreter { 13 14 template <OperandTypeInfo> 15 struct OperandTypeInfoTraits { 16 static const bool kIsScalable = false; 17 static const bool kIsUnsigned = false; 18 static const OperandSize kUnscaledSize = OperandSize::kNone; 19 }; 20 21 #define DECLARE_OPERAND_TYPE_INFO(Name, Scalable, Unsigned, BaseSize) \ 22 template <> \ 23 struct OperandTypeInfoTraits<OperandTypeInfo::k##Name> { \ 24 static const bool kIsScalable = Scalable; \ 25 static const bool kIsUnsigned = Unsigned; \ 26 static const OperandSize kUnscaledSize = BaseSize; \ 27 }; 28 OPERAND_TYPE_INFO_LIST(DECLARE_OPERAND_TYPE_INFO) 29 #undef DECLARE_OPERAND_TYPE_INFO 30 31 template <OperandType> 32 struct OperandTraits { 33 using TypeInfoTraits = OperandTypeInfoTraits<OperandTypeInfo::kNone>; 34 static const OperandTypeInfo kOperandTypeInfo = OperandTypeInfo::kNone; 35 }; 36 37 #define DECLARE_OPERAND_TYPE_TRAITS(Name, InfoType) \ 38 template <> \ 39 struct OperandTraits<OperandType::k##Name> { \ 40 using TypeInfoTraits = OperandTypeInfoTraits<InfoType>; \ 41 static const OperandTypeInfo kOperandTypeInfo = InfoType; \ 42 }; 43 OPERAND_TYPE_LIST(DECLARE_OPERAND_TYPE_TRAITS) 44 #undef DECLARE_OPERAND_TYPE_TRAITS 45 46 template <OperandType operand_type, OperandScale operand_scale> 47 struct OperandScaler { 48 template <bool, OperandSize, OperandScale> 49 struct Helper { 50 static const int kSize = 0; 51 }; 52 template <OperandSize size, OperandScale scale> 53 struct Helper<false, size, scale> { 54 static const int kSize = static_cast<int>(size); 55 }; 56 template <OperandSize size, OperandScale scale> 57 struct Helper<true, size, scale> { 58 static const int kSize = static_cast<int>(size) * static_cast<int>(scale); 59 }; 60 61 static const int kSize = 62 Helper<OperandTraits<operand_type>::TypeInfoTraits::kIsScalable, 63 OperandTraits<operand_type>::TypeInfoTraits::kUnscaledSize, 64 operand_scale>::kSize; 65 static const OperandSize kOperandSize = static_cast<OperandSize>(kSize); 66 }; 67 68 template <int... values> 69 struct SumHelper; 70 template <int value> 71 struct SumHelper<value> { 72 static const int kValue = value; 73 }; 74 template <int value, int... values> 75 struct SumHelper<value, values...> { 76 static const int kValue = value + SumHelper<values...>::kValue; 77 }; 78 79 template <AccumulatorUse accumulator_use, OperandType... operands> 80 struct BytecodeTraits { 81 static const OperandType kOperandTypes[]; 82 static const OperandTypeInfo kOperandTypeInfos[]; 83 static const OperandSize kSingleScaleOperandSizes[]; 84 static const OperandSize kDoubleScaleOperandSizes[]; 85 static const OperandSize kQuadrupleScaleOperandSizes[]; 86 static const int kSingleScaleSize = SumHelper< 87 1, OperandScaler<operands, OperandScale::kSingle>::kSize...>::kValue; 88 static const int kDoubleScaleSize = SumHelper< 89 1, OperandScaler<operands, OperandScale::kDouble>::kSize...>::kValue; 90 static const int kQuadrupleScaleSize = SumHelper< 91 1, OperandScaler<operands, OperandScale::kQuadruple>::kSize...>::kValue; 92 static const AccumulatorUse kAccumulatorUse = accumulator_use; 93 static const int kOperandCount = sizeof...(operands); 94 }; 95 96 template <AccumulatorUse accumulator_use, OperandType... operands> 97 STATIC_CONST_MEMBER_DEFINITION const OperandType 98 BytecodeTraits<accumulator_use, operands...>::kOperandTypes[] = { 99 operands...}; 100 template <AccumulatorUse accumulator_use, OperandType... operands> 101 STATIC_CONST_MEMBER_DEFINITION const OperandTypeInfo 102 BytecodeTraits<accumulator_use, operands...>::kOperandTypeInfos[] = { 103 OperandTraits<operands>::kOperandTypeInfo...}; 104 template <AccumulatorUse accumulator_use, OperandType... operands> 105 STATIC_CONST_MEMBER_DEFINITION const OperandSize 106 BytecodeTraits<accumulator_use, operands...>::kSingleScaleOperandSizes[] = { 107 OperandScaler<operands, OperandScale::kSingle>::kOperandSize...}; 108 template <AccumulatorUse accumulator_use, OperandType... operands> 109 STATIC_CONST_MEMBER_DEFINITION const OperandSize 110 BytecodeTraits<accumulator_use, operands...>::kDoubleScaleOperandSizes[] = { 111 OperandScaler<operands, OperandScale::kDouble>::kOperandSize...}; 112 template <AccumulatorUse accumulator_use, OperandType... operands> 113 STATIC_CONST_MEMBER_DEFINITION const OperandSize BytecodeTraits< 114 accumulator_use, operands...>::kQuadrupleScaleOperandSizes[] = { 115 OperandScaler<operands, OperandScale::kQuadruple>::kOperandSize...}; 116 117 template <AccumulatorUse accumulator_use> 118 struct BytecodeTraits<accumulator_use> { 119 static const OperandType kOperandTypes[]; 120 static const OperandTypeInfo kOperandTypeInfos[]; 121 static const OperandSize kSingleScaleOperandSizes[]; 122 static const OperandSize kDoubleScaleOperandSizes[]; 123 static const OperandSize kQuadrupleScaleOperandSizes[]; 124 static const int kSingleScaleSize = 1; 125 static const int kDoubleScaleSize = 1; 126 static const int kQuadrupleScaleSize = 1; 127 static const AccumulatorUse kAccumulatorUse = accumulator_use; 128 static const int kOperandCount = 0; 129 }; 130 131 template <AccumulatorUse accumulator_use> 132 STATIC_CONST_MEMBER_DEFINITION const OperandType 133 BytecodeTraits<accumulator_use>::kOperandTypes[] = {OperandType::kNone}; 134 template <AccumulatorUse accumulator_use> 135 STATIC_CONST_MEMBER_DEFINITION const OperandTypeInfo 136 BytecodeTraits<accumulator_use>::kOperandTypeInfos[] = { 137 OperandTypeInfo::kNone}; 138 template <AccumulatorUse accumulator_use> 139 STATIC_CONST_MEMBER_DEFINITION const OperandSize 140 BytecodeTraits<accumulator_use>::kSingleScaleOperandSizes[] = { 141 OperandSize::kNone}; 142 template <AccumulatorUse accumulator_use> 143 STATIC_CONST_MEMBER_DEFINITION const OperandSize 144 BytecodeTraits<accumulator_use>::kDoubleScaleOperandSizes[] = { 145 OperandSize::kNone}; 146 template <AccumulatorUse accumulator_use> 147 STATIC_CONST_MEMBER_DEFINITION const OperandSize 148 BytecodeTraits<accumulator_use>::kQuadrupleScaleOperandSizes[] = { 149 OperandSize::kNone}; 150 151 } // namespace interpreter 152 } // namespace internal 153 } // namespace v8 154 155 #endif // V8_INTERPRETER_BYTECODE_TRAITS_H_ 156