| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef V8_INTERPRETER_BYTECODE_TRAITS_H_ | 5 #ifndef V8_INTERPRETER_BYTECODE_TRAITS_H_ |
| 6 #define V8_INTERPRETER_BYTECODE_TRAITS_H_ | 6 #define V8_INTERPRETER_BYTECODE_TRAITS_H_ |
| 7 | 7 |
| 8 #include "src/interpreter/bytecode-operands.h" | 8 #include "src/interpreter/bytecodes.h" |
| 9 | 9 |
| 10 namespace v8 { | 10 namespace v8 { |
| 11 namespace internal { | 11 namespace internal { |
| 12 namespace interpreter { | 12 namespace interpreter { |
| 13 | 13 |
| 14 template <OperandTypeInfo> | 14 template <OperandTypeInfo> |
| 15 struct OperandTypeInfoTraits { | 15 struct OperandTypeInfoTraits { |
| 16 static const bool kIsScalable = false; | 16 static const bool kIsScalable = false; |
| 17 static const bool kIsUnsigned = false; | 17 static const bool kIsUnsigned = false; |
| 18 static const OperandSize kUnscaledSize = OperandSize::kNone; | 18 static const OperandSize kUnscaledSize = OperandSize::kNone; |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 58 static const int kSize = static_cast<int>(size) * static_cast<int>(scale); | 58 static const int kSize = static_cast<int>(size) * static_cast<int>(scale); |
| 59 }; | 59 }; |
| 60 | 60 |
| 61 static const int kSize = | 61 static const int kSize = |
| 62 Helper<OperandTraits<operand_type>::TypeInfoTraits::kIsScalable, | 62 Helper<OperandTraits<operand_type>::TypeInfoTraits::kIsScalable, |
| 63 OperandTraits<operand_type>::TypeInfoTraits::kUnscaledSize, | 63 OperandTraits<operand_type>::TypeInfoTraits::kUnscaledSize, |
| 64 operand_scale>::kSize; | 64 operand_scale>::kSize; |
| 65 static const OperandSize kOperandSize = static_cast<OperandSize>(kSize); | 65 static const OperandSize kOperandSize = static_cast<OperandSize>(kSize); |
| 66 }; | 66 }; |
| 67 | 67 |
| 68 template <int... values> | 68 template <OperandType> |
| 69 struct SumHelper; | 69 struct RegisterOperandTraits { |
| 70 template <int value> | 70 static const int kIsRegisterOperand = 0; |
| 71 struct SumHelper<value> { | 71 }; |
| 72 static const int kValue = value; | 72 |
| 73 }; | 73 #define DECLARE_REGISTER_OPERAND(Name, _) \ |
| 74 template <int value, int... values> | 74 template <> \ |
| 75 struct SumHelper<value, values...> { | 75 struct RegisterOperandTraits<OperandType::k##Name> { \ |
| 76 static const int kValue = value + SumHelper<values...>::kValue; | 76 static const int kIsRegisterOperand = 1; \ |
| 77 }; | 77 }; |
| 78 | 78 REGISTER_OPERAND_TYPE_LIST(DECLARE_REGISTER_OPERAND) |
| 79 template <AccumulatorUse accumulator_use, OperandType... operands> | 79 #undef DECLARE_REGISTER_OPERAND |
| 80 struct BytecodeTraits { | 80 |
| 81 static const OperandType kOperandTypes[]; | 81 template <AccumulatorUse, OperandType...> |
| 82 static const OperandTypeInfo kOperandTypeInfos[]; | 82 struct BytecodeTraits {}; |
| 83 static const OperandSize kSingleScaleOperandSizes[]; | 83 |
| 84 static const OperandSize kDoubleScaleOperandSizes[]; | 84 template <AccumulatorUse accumulator_use, OperandType operand_0, |
| 85 static const OperandSize kQuadrupleScaleOperandSizes[]; | 85 OperandType operand_1, OperandType operand_2, OperandType operand_3> |
| 86 static const int kSingleScaleSize = SumHelper< | 86 struct BytecodeTraits<accumulator_use, operand_0, operand_1, operand_2, |
| 87 1, OperandScaler<operands, OperandScale::kSingle>::kSize...>::kValue; | 87 operand_3> { |
| 88 static const int kDoubleScaleSize = SumHelper< | 88 static const OperandType* GetOperandTypes() { |
| 89 1, OperandScaler<operands, OperandScale::kDouble>::kSize...>::kValue; | 89 static const OperandType operand_types[] = {operand_0, operand_1, operand_2, |
| 90 static const int kQuadrupleScaleSize = SumHelper< | 90 operand_3, OperandType::kNone}; |
| 91 1, OperandScaler<operands, OperandScale::kQuadruple>::kSize...>::kValue; | 91 return operand_types; |
| 92 static const AccumulatorUse kAccumulatorUse = accumulator_use; | 92 } |
| 93 static const int kOperandCount = sizeof...(operands); | 93 |
| 94 }; | 94 static const OperandTypeInfo* GetOperandTypeInfos() { |
| 95 | 95 static const OperandTypeInfo operand_type_infos[] = { |
| 96 template <AccumulatorUse accumulator_use, OperandType... operands> | 96 OperandTraits<operand_0>::kOperandTypeInfo, |
| 97 STATIC_CONST_MEMBER_DEFINITION const OperandType | 97 OperandTraits<operand_1>::kOperandTypeInfo, |
| 98 BytecodeTraits<accumulator_use, operands...>::kOperandTypes[] = { | 98 OperandTraits<operand_2>::kOperandTypeInfo, |
| 99 operands...}; | 99 OperandTraits<operand_3>::kOperandTypeInfo, OperandTypeInfo::kNone}; |
| 100 template <AccumulatorUse accumulator_use, OperandType... operands> | 100 return operand_type_infos; |
| 101 STATIC_CONST_MEMBER_DEFINITION const OperandTypeInfo | 101 } |
| 102 BytecodeTraits<accumulator_use, operands...>::kOperandTypeInfos[] = { | 102 |
| 103 OperandTraits<operands>::kOperandTypeInfo...}; | 103 template <OperandType ot> |
| 104 template <AccumulatorUse accumulator_use, OperandType... operands> | 104 static inline bool HasAnyOperandsOfType() { |
| 105 STATIC_CONST_MEMBER_DEFINITION const OperandSize | 105 return operand_0 == ot || operand_1 == ot || operand_2 == ot || |
| 106 BytecodeTraits<accumulator_use, operands...>::kSingleScaleOperandSizes[] = { | 106 operand_3 == ot; |
| 107 OperandScaler<operands, OperandScale::kSingle>::kOperandSize...}; | 107 } |
| 108 template <AccumulatorUse accumulator_use, OperandType... operands> | 108 |
| 109 STATIC_CONST_MEMBER_DEFINITION const OperandSize | 109 static inline bool IsScalable() { |
| 110 BytecodeTraits<accumulator_use, operands...>::kDoubleScaleOperandSizes[] = { | 110 return (OperandTraits<operand_0>::TypeInfoTraits::kIsScalable | |
| 111 OperandScaler<operands, OperandScale::kDouble>::kOperandSize...}; | 111 OperandTraits<operand_1>::TypeInfoTraits::kIsScalable | |
| 112 template <AccumulatorUse accumulator_use, OperandType... operands> | 112 OperandTraits<operand_2>::TypeInfoTraits::kIsScalable | |
| 113 STATIC_CONST_MEMBER_DEFINITION const OperandSize BytecodeTraits< | 113 OperandTraits<operand_3>::TypeInfoTraits::kIsScalable); |
| 114 accumulator_use, operands...>::kQuadrupleScaleOperandSizes[] = { | 114 } |
| 115 OperandScaler<operands, OperandScale::kQuadruple>::kOperandSize...}; | 115 |
| 116 static const AccumulatorUse kAccumulatorUse = accumulator_use; |
| 117 static const int kOperandCount = 4; |
| 118 static const int kRegisterOperandCount = |
| 119 RegisterOperandTraits<operand_0>::kIsRegisterOperand + |
| 120 RegisterOperandTraits<operand_1>::kIsRegisterOperand + |
| 121 RegisterOperandTraits<operand_2>::kIsRegisterOperand + |
| 122 RegisterOperandTraits<operand_3>::kIsRegisterOperand; |
| 123 }; |
| 124 |
| 125 template <AccumulatorUse accumulator_use, OperandType operand_0, |
| 126 OperandType operand_1, OperandType operand_2> |
| 127 struct BytecodeTraits<accumulator_use, operand_0, operand_1, operand_2> { |
| 128 static const OperandType* GetOperandTypes() { |
| 129 static const OperandType operand_types[] = {operand_0, operand_1, operand_2, |
| 130 OperandType::kNone}; |
| 131 return operand_types; |
| 132 } |
| 133 |
| 134 static const OperandTypeInfo* GetOperandTypeInfos() { |
| 135 static const OperandTypeInfo operand_type_infos[] = { |
| 136 OperandTraits<operand_0>::kOperandTypeInfo, |
| 137 OperandTraits<operand_1>::kOperandTypeInfo, |
| 138 OperandTraits<operand_2>::kOperandTypeInfo, OperandTypeInfo::kNone}; |
| 139 return operand_type_infos; |
| 140 } |
| 141 |
| 142 template <OperandType ot> |
| 143 static inline bool HasAnyOperandsOfType() { |
| 144 return operand_0 == ot || operand_1 == ot || operand_2 == ot; |
| 145 } |
| 146 |
| 147 static inline bool IsScalable() { |
| 148 return (OperandTraits<operand_0>::TypeInfoTraits::kIsScalable | |
| 149 OperandTraits<operand_1>::TypeInfoTraits::kIsScalable | |
| 150 OperandTraits<operand_2>::TypeInfoTraits::kIsScalable); |
| 151 } |
| 152 |
| 153 static const AccumulatorUse kAccumulatorUse = accumulator_use; |
| 154 static const int kOperandCount = 3; |
| 155 static const int kRegisterOperandCount = |
| 156 RegisterOperandTraits<operand_0>::kIsRegisterOperand + |
| 157 RegisterOperandTraits<operand_1>::kIsRegisterOperand + |
| 158 RegisterOperandTraits<operand_2>::kIsRegisterOperand; |
| 159 }; |
| 160 |
| 161 template <AccumulatorUse accumulator_use, OperandType operand_0, |
| 162 OperandType operand_1> |
| 163 struct BytecodeTraits<accumulator_use, operand_0, operand_1> { |
| 164 static const OperandType* GetOperandTypes() { |
| 165 static const OperandType operand_types[] = {operand_0, operand_1, |
| 166 OperandType::kNone}; |
| 167 return operand_types; |
| 168 } |
| 169 |
| 170 static const OperandTypeInfo* GetOperandTypeInfos() { |
| 171 static const OperandTypeInfo operand_type_infos[] = { |
| 172 OperandTraits<operand_0>::kOperandTypeInfo, |
| 173 OperandTraits<operand_1>::kOperandTypeInfo, OperandTypeInfo::kNone}; |
| 174 return operand_type_infos; |
| 175 } |
| 176 |
| 177 template <OperandType ot> |
| 178 static inline bool HasAnyOperandsOfType() { |
| 179 return operand_0 == ot || operand_1 == ot; |
| 180 } |
| 181 |
| 182 static inline bool IsScalable() { |
| 183 return (OperandTraits<operand_0>::TypeInfoTraits::kIsScalable | |
| 184 OperandTraits<operand_1>::TypeInfoTraits::kIsScalable); |
| 185 } |
| 186 |
| 187 static const AccumulatorUse kAccumulatorUse = accumulator_use; |
| 188 static const int kOperandCount = 2; |
| 189 static const int kRegisterOperandCount = |
| 190 RegisterOperandTraits<operand_0>::kIsRegisterOperand + |
| 191 RegisterOperandTraits<operand_1>::kIsRegisterOperand; |
| 192 }; |
| 193 |
| 194 template <AccumulatorUse accumulator_use, OperandType operand_0> |
| 195 struct BytecodeTraits<accumulator_use, operand_0> { |
| 196 static const OperandType* GetOperandTypes() { |
| 197 static const OperandType operand_types[] = {operand_0, OperandType::kNone}; |
| 198 return operand_types; |
| 199 } |
| 200 |
| 201 static const OperandTypeInfo* GetOperandTypeInfos() { |
| 202 static const OperandTypeInfo operand_type_infos[] = { |
| 203 OperandTraits<operand_0>::kOperandTypeInfo, OperandTypeInfo::kNone}; |
| 204 return operand_type_infos; |
| 205 } |
| 206 |
| 207 template <OperandType ot> |
| 208 static inline bool HasAnyOperandsOfType() { |
| 209 return operand_0 == ot; |
| 210 } |
| 211 |
| 212 static inline bool IsScalable() { |
| 213 return OperandTraits<operand_0>::TypeInfoTraits::kIsScalable; |
| 214 } |
| 215 |
| 216 static const AccumulatorUse kAccumulatorUse = accumulator_use; |
| 217 static const int kOperandCount = 1; |
| 218 static const int kRegisterOperandCount = |
| 219 RegisterOperandTraits<operand_0>::kIsRegisterOperand; |
| 220 }; |
| 116 | 221 |
| 117 template <AccumulatorUse accumulator_use> | 222 template <AccumulatorUse accumulator_use> |
| 118 struct BytecodeTraits<accumulator_use> { | 223 struct BytecodeTraits<accumulator_use> { |
| 119 static const OperandType kOperandTypes[]; | 224 static const OperandType* GetOperandTypes() { |
| 120 static const OperandTypeInfo kOperandTypeInfos[]; | 225 static const OperandType operand_types[] = {OperandType::kNone}; |
| 121 static const OperandSize kSingleScaleOperandSizes[]; | 226 return operand_types; |
| 122 static const OperandSize kDoubleScaleOperandSizes[]; | 227 } |
| 123 static const OperandSize kQuadrupleScaleOperandSizes[]; | 228 |
| 124 static const int kSingleScaleSize = 1; | 229 static const OperandTypeInfo* GetOperandTypeInfos() { |
| 125 static const int kDoubleScaleSize = 1; | 230 static const OperandTypeInfo operand_type_infos[] = { |
| 126 static const int kQuadrupleScaleSize = 1; | 231 OperandTypeInfo::kNone}; |
| 232 return operand_type_infos; |
| 233 } |
| 234 |
| 235 template <OperandType ot> |
| 236 static inline bool HasAnyOperandsOfType() { |
| 237 return false; |
| 238 } |
| 239 |
| 240 static inline bool IsScalable() { return false; } |
| 241 |
| 127 static const AccumulatorUse kAccumulatorUse = accumulator_use; | 242 static const AccumulatorUse kAccumulatorUse = accumulator_use; |
| 128 static const int kOperandCount = 0; | 243 static const int kOperandCount = 0; |
| 129 }; | 244 static const int kRegisterOperandCount = 0; |
| 130 | 245 }; |
| 131 template <AccumulatorUse accumulator_use> | 246 |
| 132 STATIC_CONST_MEMBER_DEFINITION const OperandType | 247 static OperandSize ScaledOperandSize(OperandType operand_type, |
| 133 BytecodeTraits<accumulator_use>::kOperandTypes[] = {OperandType::kNone}; | 248 OperandScale operand_scale) { |
| 134 template <AccumulatorUse accumulator_use> | 249 STATIC_ASSERT(static_cast<int>(OperandScale::kQuadruple) == 4 && |
| 135 STATIC_CONST_MEMBER_DEFINITION const OperandTypeInfo | 250 OperandScale::kLast == OperandScale::kQuadruple); |
| 136 BytecodeTraits<accumulator_use>::kOperandTypeInfos[] = { | 251 int index = static_cast<int>(operand_scale) >> 1; |
| 137 OperandTypeInfo::kNone}; | 252 switch (operand_type) { |
| 138 template <AccumulatorUse accumulator_use> | 253 #define CASE(Name, TypeInfo) \ |
| 139 STATIC_CONST_MEMBER_DEFINITION const OperandSize | 254 case OperandType::k##Name: { \ |
| 140 BytecodeTraits<accumulator_use>::kSingleScaleOperandSizes[] = { | 255 static const OperandSize kOperandSizes[] = { \ |
| 141 OperandSize::kNone}; | 256 OperandScaler<OperandType::k##Name, \ |
| 142 template <AccumulatorUse accumulator_use> | 257 OperandScale::kSingle>::kOperandSize, \ |
| 143 STATIC_CONST_MEMBER_DEFINITION const OperandSize | 258 OperandScaler<OperandType::k##Name, \ |
| 144 BytecodeTraits<accumulator_use>::kDoubleScaleOperandSizes[] = { | 259 OperandScale::kDouble>::kOperandSize, \ |
| 145 OperandSize::kNone}; | 260 OperandScaler<OperandType::k##Name, \ |
| 146 template <AccumulatorUse accumulator_use> | 261 OperandScale::kQuadruple>::kOperandSize}; \ |
| 147 STATIC_CONST_MEMBER_DEFINITION const OperandSize | 262 return kOperandSizes[index]; \ |
| 148 BytecodeTraits<accumulator_use>::kQuadrupleScaleOperandSizes[] = { | 263 } |
| 149 OperandSize::kNone}; | 264 OPERAND_TYPE_LIST(CASE) |
| 265 #undef CASE |
| 266 } |
| 267 UNREACHABLE(); |
| 268 return OperandSize::kNone; |
| 269 } |
| 150 | 270 |
| 151 } // namespace interpreter | 271 } // namespace interpreter |
| 152 } // namespace internal | 272 } // namespace internal |
| 153 } // namespace v8 | 273 } // namespace v8 |
| 154 | 274 |
| 155 #endif // V8_INTERPRETER_BYTECODE_TRAITS_H_ | 275 #endif // V8_INTERPRETER_BYTECODE_TRAITS_H_ |
| OLD | NEW |