Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(125)

Side by Side Diff: src/interpreter/bytecode-traits.h

Issue 1947403002: [interpreter] Introduce bytecode generation pipeline. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/interpreter/bytecode-pipeline.cc ('k') | src/interpreter/bytecodes.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 {
(...skipping 23 matching lines...) Expand all
34 }; 34 };
35 35
36 #define DECLARE_OPERAND_TYPE_TRAITS(Name, InfoType) \ 36 #define DECLARE_OPERAND_TYPE_TRAITS(Name, InfoType) \
37 template <> \ 37 template <> \
38 struct OperandTraits<OperandType::k##Name> { \ 38 struct OperandTraits<OperandType::k##Name> { \
39 typedef OperandTypeInfoTraits<InfoType> TypeInfo; \ 39 typedef OperandTypeInfoTraits<InfoType> TypeInfo; \
40 }; 40 };
41 OPERAND_TYPE_LIST(DECLARE_OPERAND_TYPE_TRAITS) 41 OPERAND_TYPE_LIST(DECLARE_OPERAND_TYPE_TRAITS)
42 #undef DECLARE_OPERAND_TYPE_TRAITS 42 #undef DECLARE_OPERAND_TYPE_TRAITS
43 43
44 template <OperandType operand_type, OperandScale operand_scale>
45 struct OperandScaler {
46 template <bool, OperandSize, OperandScale>
47 struct Helper {
48 static const int kSize = 0;
49 };
50 template <OperandSize size, OperandScale scale>
51 struct Helper<false, size, scale> {
52 static const int kSize = static_cast<int>(size);
53 };
54 template <OperandSize size, OperandScale scale>
55 struct Helper<true, size, scale> {
56 static const int kSize = static_cast<int>(size) * static_cast<int>(scale);
57 };
58
59 static const int kSize =
60 Helper<OperandTraits<operand_type>::TypeInfo::kIsScalable,
61 OperandTraits<operand_type>::TypeInfo::kUnscaledSize,
62 operand_scale>::kSize;
63 static const OperandSize kOperandSize = static_cast<OperandSize>(kSize);
64 };
65
44 template <OperandType> 66 template <OperandType>
45 struct RegisterOperandTraits { 67 struct RegisterOperandTraits {
46 static const int kIsRegisterOperand = 0; 68 static const int kIsRegisterOperand = 0;
47 }; 69 };
48 70
49 #define DECLARE_REGISTER_OPERAND(Name, _) \ 71 #define DECLARE_REGISTER_OPERAND(Name, _) \
50 template <> \ 72 template <> \
51 struct RegisterOperandTraits<OperandType::k##Name> { \ 73 struct RegisterOperandTraits<OperandType::k##Name> { \
52 static const int kIsRegisterOperand = 1; \ 74 static const int kIsRegisterOperand = 1; \
53 }; 75 };
54 REGISTER_OPERAND_TYPE_LIST(DECLARE_REGISTER_OPERAND) 76 REGISTER_OPERAND_TYPE_LIST(DECLARE_REGISTER_OPERAND)
55 #undef DECLARE_REGISTER_OPERAND 77 #undef DECLARE_REGISTER_OPERAND
56 78
57 template <AccumulatorUse, OperandType...> 79 template <AccumulatorUse, OperandType...>
58 struct BytecodeTraits {}; 80 struct BytecodeTraits {};
59 81
60 template <AccumulatorUse accumulator_use, OperandType operand_0, 82 template <AccumulatorUse accumulator_use, OperandType operand_0,
61 OperandType operand_1, OperandType operand_2, OperandType operand_3> 83 OperandType operand_1, OperandType operand_2, OperandType operand_3>
62 struct BytecodeTraits<accumulator_use, operand_0, operand_1, operand_2, 84 struct BytecodeTraits<accumulator_use, operand_0, operand_1, operand_2,
63 operand_3> { 85 operand_3> {
64 static OperandType GetOperandType(int i) { 86 static const OperandType* GetOperandTypes() {
65 DCHECK(0 <= i && i < kOperandCount); 87 static const OperandType operand_types[] = {operand_0, operand_1, operand_2,
66 const OperandType kOperands[] = {operand_0, operand_1, operand_2, 88 operand_3, OperandType::kNone};
67 operand_3}; 89 return operand_types;
68 return kOperands[i]; 90 }
91
92 static OperandSize GetOperandSize(int i, OperandScale operand_scale) {
93 switch (operand_scale) {
94 #define CASE(Name, _) \
95 case OperandScale::k##Name: { \
96 static const OperandSize kOperandSizes[] = { \
97 OperandScaler<operand_0, OperandScale::k##Name>::kOperandSize, \
98 OperandScaler<operand_1, OperandScale::k##Name>::kOperandSize, \
99 OperandScaler<operand_2, OperandScale::k##Name>::kOperandSize, \
100 OperandScaler<operand_3, OperandScale::k##Name>::kOperandSize, \
101 }; \
102 DCHECK_LT(static_cast<size_t>(i), arraysize(kOperandSizes)); \
103 return kOperandSizes[i]; \
104 }
105 OPERAND_SCALE_LIST(CASE)
106 #undef CASE
107 }
108 UNREACHABLE();
109 return OperandSize::kNone;
69 } 110 }
70 111
71 template <OperandType ot> 112 template <OperandType ot>
72 static inline bool HasAnyOperandsOfType() { 113 static inline bool HasAnyOperandsOfType() {
73 return operand_0 == ot || operand_1 == ot || operand_2 == ot || 114 return operand_0 == ot || operand_1 == ot || operand_2 == ot ||
74 operand_3 == ot; 115 operand_3 == ot;
75 } 116 }
76 117
77 static inline bool IsScalable() { 118 static inline bool IsScalable() {
78 return (OperandTraits<operand_0>::TypeInfo::kIsScalable | 119 return (OperandTraits<operand_0>::TypeInfo::kIsScalable |
(...skipping 12 matching lines...) Expand all
91 static const int kRegisterOperandBitmap = 132 static const int kRegisterOperandBitmap =
92 RegisterOperandTraits<operand_0>::kIsRegisterOperand + 133 RegisterOperandTraits<operand_0>::kIsRegisterOperand +
93 (RegisterOperandTraits<operand_1>::kIsRegisterOperand << 1) + 134 (RegisterOperandTraits<operand_1>::kIsRegisterOperand << 1) +
94 (RegisterOperandTraits<operand_2>::kIsRegisterOperand << 2) + 135 (RegisterOperandTraits<operand_2>::kIsRegisterOperand << 2) +
95 (RegisterOperandTraits<operand_3>::kIsRegisterOperand << 3); 136 (RegisterOperandTraits<operand_3>::kIsRegisterOperand << 3);
96 }; 137 };
97 138
98 template <AccumulatorUse accumulator_use, OperandType operand_0, 139 template <AccumulatorUse accumulator_use, OperandType operand_0,
99 OperandType operand_1, OperandType operand_2> 140 OperandType operand_1, OperandType operand_2>
100 struct BytecodeTraits<accumulator_use, operand_0, operand_1, operand_2> { 141 struct BytecodeTraits<accumulator_use, operand_0, operand_1, operand_2> {
101 static inline OperandType GetOperandType(int i) { 142 static const OperandType* GetOperandTypes() {
102 DCHECK(0 <= i && i <= 2); 143 static const OperandType operand_types[] = {operand_0, operand_1, operand_2,
103 const OperandType kOperands[] = {operand_0, operand_1, operand_2}; 144 OperandType::kNone};
104 return kOperands[i]; 145 return operand_types;
146 }
147
148 static OperandSize GetOperandSize(int i, OperandScale operand_scale) {
149 switch (operand_scale) {
150 #define CASE(Name, _) \
151 case OperandScale::k##Name: { \
152 static const OperandSize kOperandSizes[] = { \
153 OperandScaler<operand_0, OperandScale::k##Name>::kOperandSize, \
154 OperandScaler<operand_1, OperandScale::k##Name>::kOperandSize, \
155 OperandScaler<operand_2, OperandScale::k##Name>::kOperandSize, \
156 }; \
157 DCHECK_LT(static_cast<size_t>(i), arraysize(kOperandSizes)); \
158 return kOperandSizes[i]; \
159 }
160 OPERAND_SCALE_LIST(CASE)
161 #undef CASE
162 }
163 UNREACHABLE();
164 return OperandSize::kNone;
105 } 165 }
106 166
107 template <OperandType ot> 167 template <OperandType ot>
108 static inline bool HasAnyOperandsOfType() { 168 static inline bool HasAnyOperandsOfType() {
109 return operand_0 == ot || operand_1 == ot || operand_2 == ot; 169 return operand_0 == ot || operand_1 == ot || operand_2 == ot;
110 } 170 }
111 171
112 static inline bool IsScalable() { 172 static inline bool IsScalable() {
113 return (OperandTraits<operand_0>::TypeInfo::kIsScalable | 173 return (OperandTraits<operand_0>::TypeInfo::kIsScalable |
114 OperandTraits<operand_1>::TypeInfo::kIsScalable | 174 OperandTraits<operand_1>::TypeInfo::kIsScalable |
115 OperandTraits<operand_2>::TypeInfo::kIsScalable); 175 OperandTraits<operand_2>::TypeInfo::kIsScalable);
116 } 176 }
117 177
118 static const AccumulatorUse kAccumulatorUse = accumulator_use; 178 static const AccumulatorUse kAccumulatorUse = accumulator_use;
119 static const int kOperandCount = 3; 179 static const int kOperandCount = 3;
120 static const int kRegisterOperandCount = 180 static const int kRegisterOperandCount =
121 RegisterOperandTraits<operand_0>::kIsRegisterOperand + 181 RegisterOperandTraits<operand_0>::kIsRegisterOperand +
122 RegisterOperandTraits<operand_1>::kIsRegisterOperand + 182 RegisterOperandTraits<operand_1>::kIsRegisterOperand +
123 RegisterOperandTraits<operand_2>::kIsRegisterOperand; 183 RegisterOperandTraits<operand_2>::kIsRegisterOperand;
124 static const int kRegisterOperandBitmap = 184 static const int kRegisterOperandBitmap =
125 RegisterOperandTraits<operand_0>::kIsRegisterOperand + 185 RegisterOperandTraits<operand_0>::kIsRegisterOperand +
126 (RegisterOperandTraits<operand_1>::kIsRegisterOperand << 1) + 186 (RegisterOperandTraits<operand_1>::kIsRegisterOperand << 1) +
127 (RegisterOperandTraits<operand_2>::kIsRegisterOperand << 2); 187 (RegisterOperandTraits<operand_2>::kIsRegisterOperand << 2);
128 }; 188 };
129 189
130 template <AccumulatorUse accumulator_use, OperandType operand_0, 190 template <AccumulatorUse accumulator_use, OperandType operand_0,
131 OperandType operand_1> 191 OperandType operand_1>
132 struct BytecodeTraits<accumulator_use, operand_0, operand_1> { 192 struct BytecodeTraits<accumulator_use, operand_0, operand_1> {
133 static inline OperandType GetOperandType(int i) { 193 static const OperandType* GetOperandTypes() {
134 DCHECK(0 <= i && i < kOperandCount); 194 static const OperandType operand_types[] = {operand_0, operand_1,
135 const OperandType kOperands[] = {operand_0, operand_1}; 195 OperandType::kNone};
136 return kOperands[i]; 196 return operand_types;
197 }
198
199 static OperandSize GetOperandSize(int i, OperandScale operand_scale) {
200 switch (operand_scale) {
201 #define CASE(Name, _) \
202 case OperandScale::k##Name: { \
203 static const OperandSize kOperandSizes[] = { \
204 OperandScaler<operand_0, OperandScale::k##Name>::kOperandSize, \
205 OperandScaler<operand_1, OperandScale::k##Name>::kOperandSize, \
206 }; \
207 DCHECK_LT(static_cast<size_t>(i), arraysize(kOperandSizes)); \
208 return kOperandSizes[i]; \
209 }
210 OPERAND_SCALE_LIST(CASE)
211 #undef CASE
212 }
213 UNREACHABLE();
214 return OperandSize::kNone;
137 } 215 }
138 216
139 template <OperandType ot> 217 template <OperandType ot>
140 static inline bool HasAnyOperandsOfType() { 218 static inline bool HasAnyOperandsOfType() {
141 return operand_0 == ot || operand_1 == ot; 219 return operand_0 == ot || operand_1 == ot;
142 } 220 }
143 221
144 static inline bool IsScalable() { 222 static inline bool IsScalable() {
145 return (OperandTraits<operand_0>::TypeInfo::kIsScalable | 223 return (OperandTraits<operand_0>::TypeInfo::kIsScalable |
146 OperandTraits<operand_1>::TypeInfo::kIsScalable); 224 OperandTraits<operand_1>::TypeInfo::kIsScalable);
147 } 225 }
148 226
149 static const AccumulatorUse kAccumulatorUse = accumulator_use; 227 static const AccumulatorUse kAccumulatorUse = accumulator_use;
150 static const int kOperandCount = 2; 228 static const int kOperandCount = 2;
151 static const int kRegisterOperandCount = 229 static const int kRegisterOperandCount =
152 RegisterOperandTraits<operand_0>::kIsRegisterOperand + 230 RegisterOperandTraits<operand_0>::kIsRegisterOperand +
153 RegisterOperandTraits<operand_1>::kIsRegisterOperand; 231 RegisterOperandTraits<operand_1>::kIsRegisterOperand;
154 static const int kRegisterOperandBitmap = 232 static const int kRegisterOperandBitmap =
155 RegisterOperandTraits<operand_0>::kIsRegisterOperand + 233 RegisterOperandTraits<operand_0>::kIsRegisterOperand +
156 (RegisterOperandTraits<operand_1>::kIsRegisterOperand << 1); 234 (RegisterOperandTraits<operand_1>::kIsRegisterOperand << 1);
157 }; 235 };
158 236
159 template <AccumulatorUse accumulator_use, OperandType operand_0> 237 template <AccumulatorUse accumulator_use, OperandType operand_0>
160 struct BytecodeTraits<accumulator_use, operand_0> { 238 struct BytecodeTraits<accumulator_use, operand_0> {
161 static inline OperandType GetOperandType(int i) { 239 static const OperandType* GetOperandTypes() {
162 DCHECK(i == 0); 240 static const OperandType operand_types[] = {operand_0, OperandType::kNone};
163 return operand_0; 241 return operand_types;
242 }
243
244 static OperandSize GetOperandSize(int i, OperandScale operand_scale) {
245 switch (operand_scale) {
246 #define CASE(Name, _) \
247 case OperandScale::k##Name: { \
248 static const OperandSize kOperandSizes[] = { \
249 OperandScaler<operand_0, OperandScale::k##Name>::kOperandSize, \
250 }; \
251 DCHECK_LT(static_cast<size_t>(i), arraysize(kOperandSizes)); \
252 return kOperandSizes[i]; \
253 }
254 OPERAND_SCALE_LIST(CASE)
255 #undef CASE
256 }
257 UNREACHABLE();
258 return OperandSize::kNone;
164 } 259 }
165 260
166 template <OperandType ot> 261 template <OperandType ot>
167 static inline bool HasAnyOperandsOfType() { 262 static inline bool HasAnyOperandsOfType() {
168 return operand_0 == ot; 263 return operand_0 == ot;
169 } 264 }
170 265
171 static inline bool IsScalable() { 266 static inline bool IsScalable() {
172 return OperandTraits<operand_0>::TypeInfo::kIsScalable; 267 return OperandTraits<operand_0>::TypeInfo::kIsScalable;
173 } 268 }
174 269
175 static const AccumulatorUse kAccumulatorUse = accumulator_use; 270 static const AccumulatorUse kAccumulatorUse = accumulator_use;
176 static const int kOperandCount = 1; 271 static const int kOperandCount = 1;
177 static const int kRegisterOperandCount = 272 static const int kRegisterOperandCount =
178 RegisterOperandTraits<operand_0>::kIsRegisterOperand; 273 RegisterOperandTraits<operand_0>::kIsRegisterOperand;
179 static const int kRegisterOperandBitmap = 274 static const int kRegisterOperandBitmap =
180 RegisterOperandTraits<operand_0>::kIsRegisterOperand; 275 RegisterOperandTraits<operand_0>::kIsRegisterOperand;
181 }; 276 };
182 277
183 template <AccumulatorUse accumulator_use> 278 template <AccumulatorUse accumulator_use>
184 struct BytecodeTraits<accumulator_use> { 279 struct BytecodeTraits<accumulator_use> {
185 static inline OperandType GetOperandType(int i) { 280 static const OperandType* GetOperandTypes() {
281 static const OperandType operand_types[] = {OperandType::kNone};
282 return operand_types;
283 }
284
285 static OperandSize GetOperandSize(int i, OperandScale operand_scale) {
186 UNREACHABLE(); 286 UNREACHABLE();
187 return OperandType::kNone; 287 return OperandSize::kNone;
188 } 288 }
189 289
190 template <OperandType ot> 290 template <OperandType ot>
191 static inline bool HasAnyOperandsOfType() { 291 static inline bool HasAnyOperandsOfType() {
192 return false; 292 return false;
193 } 293 }
194 294
195 static inline bool IsScalable() { return false; } 295 static inline bool IsScalable() { return false; }
196 296
197 static const AccumulatorUse kAccumulatorUse = accumulator_use; 297 static const AccumulatorUse kAccumulatorUse = accumulator_use;
198 static const int kOperandCount = 0; 298 static const int kOperandCount = 0;
199 static const int kRegisterOperandCount = 0; 299 static const int kRegisterOperandCount = 0;
200 static const int kRegisterOperandBitmap = 0; 300 static const int kRegisterOperandBitmap = 0;
201 }; 301 };
202 302
203 template <bool>
204 struct OperandScaler {
205 static int Multiply(int size, int operand_scale) { return 0; }
206 };
207
208 template <>
209 struct OperandScaler<false> {
210 static int Multiply(int size, int operand_scale) { return size; }
211 };
212
213 template <>
214 struct OperandScaler<true> {
215 static int Multiply(int size, int operand_scale) {
216 return size * operand_scale;
217 }
218 };
219
220 static OperandSize ScaledOperandSize(OperandType operand_type, 303 static OperandSize ScaledOperandSize(OperandType operand_type,
221 OperandScale operand_scale) { 304 OperandScale operand_scale) {
305 STATIC_ASSERT(static_cast<int>(OperandScale::kQuadruple) == 4 &&
306 OperandScale::kLast == OperandScale::kQuadruple);
307 int index = static_cast<int>(operand_scale) >> 1;
222 switch (operand_type) { 308 switch (operand_type) {
223 #define CASE(Name, TypeInfo) \ 309 #define CASE(Name, TypeInfo) \
224 case OperandType::k##Name: { \ 310 case OperandType::k##Name: { \
225 OperandSize base_size = OperandTypeInfoTraits<TypeInfo>::kUnscaledSize; \ 311 static const OperandSize kOperandSizes[] = { \
226 int size = \ 312 OperandScaler<OperandType::k##Name, \
227 OperandScaler<OperandTypeInfoTraits<TypeInfo>::kIsScalable>::Multiply( \ 313 OperandScale::kSingle>::kOperandSize, \
228 static_cast<int>(base_size), static_cast<int>(operand_scale)); \ 314 OperandScaler<OperandType::k##Name, \
229 OperandSize operand_size = static_cast<OperandSize>(size); \ 315 OperandScale::kDouble>::kOperandSize, \
230 DCHECK(operand_size == OperandSize::kByte || \ 316 OperandScaler<OperandType::k##Name, \
231 operand_size == OperandSize::kShort || \ 317 OperandScale::kQuadruple>::kOperandSize}; \
232 operand_size == OperandSize::kQuad); \ 318 return kOperandSizes[index]; \
233 return operand_size; \
234 } 319 }
235 OPERAND_TYPE_LIST(CASE) 320 OPERAND_TYPE_LIST(CASE)
236 #undef CASE 321 #undef CASE
237 } 322 }
238 UNREACHABLE(); 323 UNREACHABLE();
239 return OperandSize::kNone; 324 return OperandSize::kNone;
240 } 325 }
241 326
242 } // namespace interpreter 327 } // namespace interpreter
243 } // namespace internal 328 } // namespace internal
244 } // namespace v8 329 } // namespace v8
245 330
246 #endif // V8_INTERPRETER_BYTECODE_TRAITS_H_ 331 #endif // V8_INTERPRETER_BYTECODE_TRAITS_H_
OLDNEW
« no previous file with comments | « src/interpreter/bytecode-pipeline.cc ('k') | src/interpreter/bytecodes.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698