| 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/bytecodes.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 // TODO(rmcilroy): consider simplifying this to avoid the template magic. | |
| 15 | |
| 16 // Template helpers to deduce the number of operands each bytecode has. | |
| 17 #define OPERAND_TERM OperandType::kNone, OperandType::kNone, OperandType::kNone | |
| 18 | |
| 19 template <OperandTypeInfo> | 14 template <OperandTypeInfo> |
| 20 struct OperandTypeInfoTraits { | 15 struct OperandTypeInfoTraits { |
| 21 static const bool kIsScalable = false; | 16 static const bool kIsScalable = false; |
| 22 static const bool kIsUnsigned = false; | 17 static const bool kIsUnsigned = false; |
| 23 static const OperandSize kUnscaledSize = OperandSize::kNone; | 18 static const OperandSize kUnscaledSize = OperandSize::kNone; |
| 24 }; | 19 }; |
| 25 | 20 |
| 26 #define DECLARE_OPERAND_TYPE_INFO(Name, Scalable, Unsigned, BaseSize) \ | 21 #define DECLARE_OPERAND_TYPE_INFO(Name, Scalable, Unsigned, BaseSize) \ |
| 27 template <> \ | 22 template <> \ |
| 28 struct OperandTypeInfoTraits<OperandTypeInfo::k##Name> { \ | 23 struct OperandTypeInfoTraits<OperandTypeInfo::k##Name> { \ |
| (...skipping 23 matching lines...) Expand all Loading... |
| 52 }; | 47 }; |
| 53 | 48 |
| 54 #define DECLARE_REGISTER_OPERAND(Name, _) \ | 49 #define DECLARE_REGISTER_OPERAND(Name, _) \ |
| 55 template <> \ | 50 template <> \ |
| 56 struct RegisterOperandTraits<OperandType::k##Name> { \ | 51 struct RegisterOperandTraits<OperandType::k##Name> { \ |
| 57 static const int kIsRegisterOperand = 1; \ | 52 static const int kIsRegisterOperand = 1; \ |
| 58 }; | 53 }; |
| 59 REGISTER_OPERAND_TYPE_LIST(DECLARE_REGISTER_OPERAND) | 54 REGISTER_OPERAND_TYPE_LIST(DECLARE_REGISTER_OPERAND) |
| 60 #undef DECLARE_REGISTER_OPERAND | 55 #undef DECLARE_REGISTER_OPERAND |
| 61 | 56 |
| 62 template <OperandType... Args> | 57 template <AccumulatorUse, OperandType...> |
| 63 struct BytecodeTraits {}; | 58 struct BytecodeTraits {}; |
| 64 | 59 |
| 65 template <OperandType operand_0, OperandType operand_1, OperandType operand_2, | 60 template <AccumulatorUse accumulator_use, OperandType operand_0, |
| 66 OperandType operand_3> | 61 OperandType operand_1, OperandType operand_2, OperandType operand_3> |
| 67 struct BytecodeTraits<operand_0, operand_1, operand_2, operand_3, | 62 struct BytecodeTraits<accumulator_use, operand_0, operand_1, operand_2, |
| 68 OPERAND_TERM> { | 63 operand_3> { |
| 69 static OperandType GetOperandType(int i) { | 64 static OperandType GetOperandType(int i) { |
| 70 DCHECK(0 <= i && i < kOperandCount); | 65 DCHECK(0 <= i && i < kOperandCount); |
| 71 const OperandType kOperands[] = {operand_0, operand_1, operand_2, | 66 const OperandType kOperands[] = {operand_0, operand_1, operand_2, |
| 72 operand_3}; | 67 operand_3}; |
| 73 return kOperands[i]; | 68 return kOperands[i]; |
| 74 } | 69 } |
| 75 | 70 |
| 76 template <OperandType ot> | 71 template <OperandType ot> |
| 77 static inline bool HasAnyOperandsOfType() { | 72 static inline bool HasAnyOperandsOfType() { |
| 78 return operand_0 == ot || operand_1 == ot || operand_2 == ot || | 73 return operand_0 == ot || operand_1 == ot || operand_2 == ot || |
| 79 operand_3 == ot; | 74 operand_3 == ot; |
| 80 } | 75 } |
| 81 | 76 |
| 82 static inline bool IsScalable() { | 77 static inline bool IsScalable() { |
| 83 return (OperandTraits<operand_0>::TypeInfo::kIsScalable | | 78 return (OperandTraits<operand_0>::TypeInfo::kIsScalable | |
| 84 OperandTraits<operand_1>::TypeInfo::kIsScalable | | 79 OperandTraits<operand_1>::TypeInfo::kIsScalable | |
| 85 OperandTraits<operand_2>::TypeInfo::kIsScalable | | 80 OperandTraits<operand_2>::TypeInfo::kIsScalable | |
| 86 OperandTraits<operand_3>::TypeInfo::kIsScalable); | 81 OperandTraits<operand_3>::TypeInfo::kIsScalable); |
| 87 } | 82 } |
| 88 | 83 |
| 84 static const AccumulatorUse kAccumulatorUse = accumulator_use; |
| 89 static const int kOperandCount = 4; | 85 static const int kOperandCount = 4; |
| 90 static const int kRegisterOperandCount = | 86 static const int kRegisterOperandCount = |
| 91 RegisterOperandTraits<operand_0>::kIsRegisterOperand + | 87 RegisterOperandTraits<operand_0>::kIsRegisterOperand + |
| 92 RegisterOperandTraits<operand_1>::kIsRegisterOperand + | 88 RegisterOperandTraits<operand_1>::kIsRegisterOperand + |
| 93 RegisterOperandTraits<operand_2>::kIsRegisterOperand + | 89 RegisterOperandTraits<operand_2>::kIsRegisterOperand + |
| 94 RegisterOperandTraits<operand_3>::kIsRegisterOperand; | 90 RegisterOperandTraits<operand_3>::kIsRegisterOperand; |
| 95 static const int kRegisterOperandBitmap = | 91 static const int kRegisterOperandBitmap = |
| 96 RegisterOperandTraits<operand_0>::kIsRegisterOperand + | 92 RegisterOperandTraits<operand_0>::kIsRegisterOperand + |
| 97 (RegisterOperandTraits<operand_1>::kIsRegisterOperand << 1) + | 93 (RegisterOperandTraits<operand_1>::kIsRegisterOperand << 1) + |
| 98 (RegisterOperandTraits<operand_2>::kIsRegisterOperand << 2) + | 94 (RegisterOperandTraits<operand_2>::kIsRegisterOperand << 2) + |
| 99 (RegisterOperandTraits<operand_3>::kIsRegisterOperand << 3); | 95 (RegisterOperandTraits<operand_3>::kIsRegisterOperand << 3); |
| 100 }; | 96 }; |
| 101 | 97 |
| 102 template <OperandType operand_0, OperandType operand_1, OperandType operand_2> | 98 template <AccumulatorUse accumulator_use, OperandType operand_0, |
| 103 struct BytecodeTraits<operand_0, operand_1, operand_2, OPERAND_TERM> { | 99 OperandType operand_1, OperandType operand_2> |
| 100 struct BytecodeTraits<accumulator_use, operand_0, operand_1, operand_2> { |
| 104 static inline OperandType GetOperandType(int i) { | 101 static inline OperandType GetOperandType(int i) { |
| 105 DCHECK(0 <= i && i <= 2); | 102 DCHECK(0 <= i && i <= 2); |
| 106 const OperandType kOperands[] = {operand_0, operand_1, operand_2}; | 103 const OperandType kOperands[] = {operand_0, operand_1, operand_2}; |
| 107 return kOperands[i]; | 104 return kOperands[i]; |
| 108 } | 105 } |
| 109 | 106 |
| 110 template <OperandType ot> | 107 template <OperandType ot> |
| 111 static inline bool HasAnyOperandsOfType() { | 108 static inline bool HasAnyOperandsOfType() { |
| 112 return operand_0 == ot || operand_1 == ot || operand_2 == ot; | 109 return operand_0 == ot || operand_1 == ot || operand_2 == ot; |
| 113 } | 110 } |
| 114 | 111 |
| 115 static inline bool IsScalable() { | 112 static inline bool IsScalable() { |
| 116 return (OperandTraits<operand_0>::TypeInfo::kIsScalable | | 113 return (OperandTraits<operand_0>::TypeInfo::kIsScalable | |
| 117 OperandTraits<operand_1>::TypeInfo::kIsScalable | | 114 OperandTraits<operand_1>::TypeInfo::kIsScalable | |
| 118 OperandTraits<operand_2>::TypeInfo::kIsScalable); | 115 OperandTraits<operand_2>::TypeInfo::kIsScalable); |
| 119 } | 116 } |
| 120 | 117 |
| 118 static const AccumulatorUse kAccumulatorUse = accumulator_use; |
| 121 static const int kOperandCount = 3; | 119 static const int kOperandCount = 3; |
| 122 static const int kRegisterOperandCount = | 120 static const int kRegisterOperandCount = |
| 123 RegisterOperandTraits<operand_0>::kIsRegisterOperand + | 121 RegisterOperandTraits<operand_0>::kIsRegisterOperand + |
| 124 RegisterOperandTraits<operand_1>::kIsRegisterOperand + | 122 RegisterOperandTraits<operand_1>::kIsRegisterOperand + |
| 125 RegisterOperandTraits<operand_2>::kIsRegisterOperand; | 123 RegisterOperandTraits<operand_2>::kIsRegisterOperand; |
| 126 static const int kRegisterOperandBitmap = | 124 static const int kRegisterOperandBitmap = |
| 127 RegisterOperandTraits<operand_0>::kIsRegisterOperand + | 125 RegisterOperandTraits<operand_0>::kIsRegisterOperand + |
| 128 (RegisterOperandTraits<operand_1>::kIsRegisterOperand << 1) + | 126 (RegisterOperandTraits<operand_1>::kIsRegisterOperand << 1) + |
| 129 (RegisterOperandTraits<operand_2>::kIsRegisterOperand << 2); | 127 (RegisterOperandTraits<operand_2>::kIsRegisterOperand << 2); |
| 130 }; | 128 }; |
| 131 | 129 |
| 132 template <OperandType operand_0, OperandType operand_1> | 130 template <AccumulatorUse accumulator_use, OperandType operand_0, |
| 133 struct BytecodeTraits<operand_0, operand_1, OPERAND_TERM> { | 131 OperandType operand_1> |
| 132 struct BytecodeTraits<accumulator_use, operand_0, operand_1> { |
| 134 static inline OperandType GetOperandType(int i) { | 133 static inline OperandType GetOperandType(int i) { |
| 135 DCHECK(0 <= i && i < kOperandCount); | 134 DCHECK(0 <= i && i < kOperandCount); |
| 136 const OperandType kOperands[] = {operand_0, operand_1}; | 135 const OperandType kOperands[] = {operand_0, operand_1}; |
| 137 return kOperands[i]; | 136 return kOperands[i]; |
| 138 } | 137 } |
| 139 | 138 |
| 140 template <OperandType ot> | 139 template <OperandType ot> |
| 141 static inline bool HasAnyOperandsOfType() { | 140 static inline bool HasAnyOperandsOfType() { |
| 142 return operand_0 == ot || operand_1 == ot; | 141 return operand_0 == ot || operand_1 == ot; |
| 143 } | 142 } |
| 144 | 143 |
| 145 static inline bool IsScalable() { | 144 static inline bool IsScalable() { |
| 146 return (OperandTraits<operand_0>::TypeInfo::kIsScalable | | 145 return (OperandTraits<operand_0>::TypeInfo::kIsScalable | |
| 147 OperandTraits<operand_1>::TypeInfo::kIsScalable); | 146 OperandTraits<operand_1>::TypeInfo::kIsScalable); |
| 148 } | 147 } |
| 149 | 148 |
| 149 static const AccumulatorUse kAccumulatorUse = accumulator_use; |
| 150 static const int kOperandCount = 2; | 150 static const int kOperandCount = 2; |
| 151 static const int kRegisterOperandCount = | 151 static const int kRegisterOperandCount = |
| 152 RegisterOperandTraits<operand_0>::kIsRegisterOperand + | 152 RegisterOperandTraits<operand_0>::kIsRegisterOperand + |
| 153 RegisterOperandTraits<operand_1>::kIsRegisterOperand; | 153 RegisterOperandTraits<operand_1>::kIsRegisterOperand; |
| 154 static const int kRegisterOperandBitmap = | 154 static const int kRegisterOperandBitmap = |
| 155 RegisterOperandTraits<operand_0>::kIsRegisterOperand + | 155 RegisterOperandTraits<operand_0>::kIsRegisterOperand + |
| 156 (RegisterOperandTraits<operand_1>::kIsRegisterOperand << 1); | 156 (RegisterOperandTraits<operand_1>::kIsRegisterOperand << 1); |
| 157 }; | 157 }; |
| 158 | 158 |
| 159 template <OperandType operand_0> | 159 template <AccumulatorUse accumulator_use, OperandType operand_0> |
| 160 struct BytecodeTraits<operand_0, OPERAND_TERM> { | 160 struct BytecodeTraits<accumulator_use, operand_0> { |
| 161 static inline OperandType GetOperandType(int i) { | 161 static inline OperandType GetOperandType(int i) { |
| 162 DCHECK(i == 0); | 162 DCHECK(i == 0); |
| 163 return operand_0; | 163 return operand_0; |
| 164 } | 164 } |
| 165 | 165 |
| 166 template <OperandType ot> | 166 template <OperandType ot> |
| 167 static inline bool HasAnyOperandsOfType() { | 167 static inline bool HasAnyOperandsOfType() { |
| 168 return operand_0 == ot; | 168 return operand_0 == ot; |
| 169 } | 169 } |
| 170 | 170 |
| 171 static inline bool IsScalable() { | 171 static inline bool IsScalable() { |
| 172 return OperandTraits<operand_0>::TypeInfo::kIsScalable; | 172 return OperandTraits<operand_0>::TypeInfo::kIsScalable; |
| 173 } | 173 } |
| 174 | 174 |
| 175 static const AccumulatorUse kAccumulatorUse = accumulator_use; |
| 175 static const int kOperandCount = 1; | 176 static const int kOperandCount = 1; |
| 176 static const int kRegisterOperandCount = | 177 static const int kRegisterOperandCount = |
| 177 RegisterOperandTraits<operand_0>::kIsRegisterOperand; | 178 RegisterOperandTraits<operand_0>::kIsRegisterOperand; |
| 178 static const int kRegisterOperandBitmap = | 179 static const int kRegisterOperandBitmap = |
| 179 RegisterOperandTraits<operand_0>::kIsRegisterOperand; | 180 RegisterOperandTraits<operand_0>::kIsRegisterOperand; |
| 180 }; | 181 }; |
| 181 | 182 |
| 182 template <> | 183 template <AccumulatorUse accumulator_use> |
| 183 struct BytecodeTraits<OperandType::kNone, OPERAND_TERM> { | 184 struct BytecodeTraits<accumulator_use> { |
| 184 static inline OperandType GetOperandType(int i) { | 185 static inline OperandType GetOperandType(int i) { |
| 185 UNREACHABLE(); | 186 UNREACHABLE(); |
| 186 return OperandType::kNone; | 187 return OperandType::kNone; |
| 187 } | 188 } |
| 188 | 189 |
| 189 template <OperandType ot> | 190 template <OperandType ot> |
| 190 static inline bool HasAnyOperandsOfType() { | 191 static inline bool HasAnyOperandsOfType() { |
| 191 return false; | 192 return false; |
| 192 } | 193 } |
| 193 | 194 |
| 194 static inline bool IsScalable() { return false; } | 195 static inline bool IsScalable() { return false; } |
| 195 | 196 |
| 197 static const AccumulatorUse kAccumulatorUse = accumulator_use; |
| 196 static const int kOperandCount = 0; | 198 static const int kOperandCount = 0; |
| 197 static const int kRegisterOperandCount = 0; | 199 static const int kRegisterOperandCount = 0; |
| 198 static const int kRegisterOperandBitmap = 0; | 200 static const int kRegisterOperandBitmap = 0; |
| 199 }; | 201 }; |
| 200 | 202 |
| 201 template <bool> | 203 template <bool> |
| 202 struct OperandScaler { | 204 struct OperandScaler { |
| 203 static int Multiply(int size, int operand_scale) { return 0; } | 205 static int Multiply(int size, int operand_scale) { return 0; } |
| 204 }; | 206 }; |
| 205 | 207 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 235 } | 237 } |
| 236 UNREACHABLE(); | 238 UNREACHABLE(); |
| 237 return OperandSize::kNone; | 239 return OperandSize::kNone; |
| 238 } | 240 } |
| 239 | 241 |
| 240 } // namespace interpreter | 242 } // namespace interpreter |
| 241 } // namespace internal | 243 } // namespace internal |
| 242 } // namespace v8 | 244 } // namespace v8 |
| 243 | 245 |
| 244 #endif // V8_INTERPRETER_BYTECODE_TRAITS_H_ | 246 #endif // V8_INTERPRETER_BYTECODE_TRAITS_H_ |
| OLD | NEW |