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/bytecode-operands.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 <OperandType> | 68 template <int... values> |
69 struct RegisterOperandTraits { | 69 struct SumHelper; |
70 static const int kIsRegisterOperand = 0; | 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; |
71 }; | 77 }; |
72 | 78 |
73 #define DECLARE_REGISTER_OPERAND(Name, _) \ | 79 template <AccumulatorUse accumulator_use, OperandType... operands> |
74 template <> \ | 80 struct BytecodeTraits { |
75 struct RegisterOperandTraits<OperandType::k##Name> { \ | 81 static const OperandType kOperandTypes[]; |
76 static const int kIsRegisterOperand = 1; \ | 82 static const OperandTypeInfo kOperandTypeInfos[]; |
77 }; | 83 static const OperandSize kSingleScaleOperandSizes[]; |
78 REGISTER_OPERAND_TYPE_LIST(DECLARE_REGISTER_OPERAND) | 84 static const OperandSize kDoubleScaleOperandSizes[]; |
79 #undef DECLARE_REGISTER_OPERAND | 85 static const OperandSize kQuadrupleScaleOperandSizes[]; |
80 | 86 static const int kSingleScaleSize = SumHelper< |
81 template <AccumulatorUse, OperandType...> | 87 1, OperandScaler<operands, OperandScale::kSingle>::kSize...>::kValue; |
82 struct BytecodeTraits {}; | 88 static const int kDoubleScaleSize = SumHelper< |
83 | 89 1, OperandScaler<operands, OperandScale::kDouble>::kSize...>::kValue; |
84 template <AccumulatorUse accumulator_use, OperandType operand_0, | 90 static const int kQuadrupleScaleSize = SumHelper< |
85 OperandType operand_1, OperandType operand_2, OperandType operand_3> | 91 1, OperandScaler<operands, OperandScale::kQuadruple>::kSize...>::kValue; |
86 struct BytecodeTraits<accumulator_use, operand_0, operand_1, operand_2, | |
87 operand_3> { | |
88 static const OperandType* GetOperandTypes() { | |
89 static const OperandType operand_types[] = {operand_0, operand_1, operand_2, | |
90 operand_3, OperandType::kNone}; | |
91 return operand_types; | |
92 } | |
93 | |
94 static const OperandTypeInfo* GetOperandTypeInfos() { | |
95 static const OperandTypeInfo operand_type_infos[] = { | |
96 OperandTraits<operand_0>::kOperandTypeInfo, | |
97 OperandTraits<operand_1>::kOperandTypeInfo, | |
98 OperandTraits<operand_2>::kOperandTypeInfo, | |
99 OperandTraits<operand_3>::kOperandTypeInfo, OperandTypeInfo::kNone}; | |
100 return operand_type_infos; | |
101 } | |
102 | |
103 template <OperandType ot> | |
104 static inline bool HasAnyOperandsOfType() { | |
105 return operand_0 == ot || operand_1 == ot || operand_2 == ot || | |
106 operand_3 == ot; | |
107 } | |
108 | |
109 static inline bool IsScalable() { | |
110 return (OperandTraits<operand_0>::TypeInfoTraits::kIsScalable | | |
111 OperandTraits<operand_1>::TypeInfoTraits::kIsScalable | | |
112 OperandTraits<operand_2>::TypeInfoTraits::kIsScalable | | |
113 OperandTraits<operand_3>::TypeInfoTraits::kIsScalable); | |
114 } | |
115 | |
116 static const AccumulatorUse kAccumulatorUse = accumulator_use; | 92 static const AccumulatorUse kAccumulatorUse = accumulator_use; |
117 static const int kOperandCount = 4; | 93 static const int kOperandCount = sizeof...(operands); |
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 }; | 94 }; |
124 | 95 |
125 template <AccumulatorUse accumulator_use, OperandType operand_0, | 96 template <AccumulatorUse accumulator_use, OperandType... operands> |
126 OperandType operand_1, OperandType operand_2> | 97 STATIC_CONST_MEMBER_DEFINITION const OperandType |
127 struct BytecodeTraits<accumulator_use, operand_0, operand_1, operand_2> { | 98 BytecodeTraits<accumulator_use, operands...>::kOperandTypes[] = { |
128 static const OperandType* GetOperandTypes() { | 99 operands...}; |
129 static const OperandType operand_types[] = {operand_0, operand_1, operand_2, | 100 template <AccumulatorUse accumulator_use, OperandType... operands> |
130 OperandType::kNone}; | 101 STATIC_CONST_MEMBER_DEFINITION const OperandTypeInfo |
131 return operand_types; | 102 BytecodeTraits<accumulator_use, operands...>::kOperandTypeInfos[] = { |
132 } | 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...}; |
133 | 116 |
134 static const OperandTypeInfo* GetOperandTypeInfos() { | 117 template <AccumulatorUse accumulator_use> |
135 static const OperandTypeInfo operand_type_infos[] = { | 118 struct BytecodeTraits<accumulator_use> { |
136 OperandTraits<operand_0>::kOperandTypeInfo, | 119 static const OperandType kOperandTypes[]; |
137 OperandTraits<operand_1>::kOperandTypeInfo, | 120 static const OperandTypeInfo kOperandTypeInfos[]; |
138 OperandTraits<operand_2>::kOperandTypeInfo, OperandTypeInfo::kNone}; | 121 static const OperandSize kSingleScaleOperandSizes[]; |
139 return operand_type_infos; | 122 static const OperandSize kDoubleScaleOperandSizes[]; |
140 } | 123 static const OperandSize kQuadrupleScaleOperandSizes[]; |
141 | 124 static const int kSingleScaleSize = 1; |
142 template <OperandType ot> | 125 static const int kDoubleScaleSize = 1; |
143 static inline bool HasAnyOperandsOfType() { | 126 static const int kQuadrupleScaleSize = 1; |
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; | 127 static const AccumulatorUse kAccumulatorUse = accumulator_use; |
154 static const int kOperandCount = 3; | 128 static const int kOperandCount = 0; |
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 }; | 129 }; |
221 | 130 |
222 template <AccumulatorUse accumulator_use> | 131 template <AccumulatorUse accumulator_use> |
223 struct BytecodeTraits<accumulator_use> { | 132 STATIC_CONST_MEMBER_DEFINITION const OperandType |
224 static const OperandType* GetOperandTypes() { | 133 BytecodeTraits<accumulator_use>::kOperandTypes[] = {OperandType::kNone}; |
225 static const OperandType operand_types[] = {OperandType::kNone}; | 134 template <AccumulatorUse accumulator_use> |
226 return operand_types; | 135 STATIC_CONST_MEMBER_DEFINITION const OperandTypeInfo |
227 } | 136 BytecodeTraits<accumulator_use>::kOperandTypeInfos[] = { |
228 | |
229 static const OperandTypeInfo* GetOperandTypeInfos() { | |
230 static const OperandTypeInfo operand_type_infos[] = { | |
231 OperandTypeInfo::kNone}; | 137 OperandTypeInfo::kNone}; |
232 return operand_type_infos; | 138 template <AccumulatorUse accumulator_use> |
233 } | 139 STATIC_CONST_MEMBER_DEFINITION const OperandSize |
234 | 140 BytecodeTraits<accumulator_use>::kSingleScaleOperandSizes[] = { |
235 template <OperandType ot> | 141 OperandSize::kNone}; |
236 static inline bool HasAnyOperandsOfType() { | 142 template <AccumulatorUse accumulator_use> |
237 return false; | 143 STATIC_CONST_MEMBER_DEFINITION const OperandSize |
238 } | 144 BytecodeTraits<accumulator_use>::kDoubleScaleOperandSizes[] = { |
239 | 145 OperandSize::kNone}; |
240 static inline bool IsScalable() { return false; } | 146 template <AccumulatorUse accumulator_use> |
241 | 147 STATIC_CONST_MEMBER_DEFINITION const OperandSize |
242 static const AccumulatorUse kAccumulatorUse = accumulator_use; | 148 BytecodeTraits<accumulator_use>::kQuadrupleScaleOperandSizes[] = { |
243 static const int kOperandCount = 0; | 149 OperandSize::kNone}; |
244 static const int kRegisterOperandCount = 0; | |
245 }; | |
246 | |
247 static OperandSize ScaledOperandSize(OperandType operand_type, | |
248 OperandScale operand_scale) { | |
249 STATIC_ASSERT(static_cast<int>(OperandScale::kQuadruple) == 4 && | |
250 OperandScale::kLast == OperandScale::kQuadruple); | |
251 int index = static_cast<int>(operand_scale) >> 1; | |
252 switch (operand_type) { | |
253 #define CASE(Name, TypeInfo) \ | |
254 case OperandType::k##Name: { \ | |
255 static const OperandSize kOperandSizes[] = { \ | |
256 OperandScaler<OperandType::k##Name, \ | |
257 OperandScale::kSingle>::kOperandSize, \ | |
258 OperandScaler<OperandType::k##Name, \ | |
259 OperandScale::kDouble>::kOperandSize, \ | |
260 OperandScaler<OperandType::k##Name, \ | |
261 OperandScale::kQuadruple>::kOperandSize}; \ | |
262 return kOperandSizes[index]; \ | |
263 } | |
264 OPERAND_TYPE_LIST(CASE) | |
265 #undef CASE | |
266 } | |
267 UNREACHABLE(); | |
268 return OperandSize::kNone; | |
269 } | |
270 | 150 |
271 } // namespace interpreter | 151 } // namespace interpreter |
272 } // namespace internal | 152 } // namespace internal |
273 } // namespace v8 | 153 } // namespace v8 |
274 | 154 |
275 #endif // V8_INTERPRETER_BYTECODE_TRAITS_H_ | 155 #endif // V8_INTERPRETER_BYTECODE_TRAITS_H_ |
OLD | NEW |