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

Side by Side Diff: src/interpreter/bytecodes.cc

Issue 1783483002: [interpreter] Add support for scalable operands. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase onto 3c1dc424d3f2f651ad Created 4 years, 9 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
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 #include "src/interpreter/bytecodes.h" 5 #include "src/interpreter/bytecodes.h"
6 6
7 #include "src/frames.h" 7 #include "src/frames.h"
8 #include "src/interpreter/bytecode-traits.h" 8 #include "src/interpreter/bytecode-traits.h"
9 9
10 namespace v8 { 10 namespace v8 {
11 namespace internal { 11 namespace internal {
12 namespace interpreter { 12 namespace interpreter {
13 13
14 14
15 // static 15 // static
16 const char* Bytecodes::ToString(Bytecode bytecode) { 16 const char* Bytecodes::ToString(Bytecode bytecode) {
17 switch (bytecode) { 17 switch (bytecode) {
18 #define CASE(Name, ...) \ 18 #define CASE(Name, ...) \
19 case Bytecode::k##Name: \ 19 case Bytecode::k##Name: \
20 return #Name; 20 return #Name;
21 BYTECODE_LIST(CASE) 21 BYTECODE_LIST(CASE)
22 #undef CASE 22 #undef CASE
23 } 23 }
24 UNREACHABLE(); 24 UNREACHABLE();
25 return ""; 25 return "";
26 } 26 }
27 27
28 // static
29 std::string Bytecodes::ToString(Bytecode bytecode, int operand_scale) {
30 static const char kSeparator = '.';
31
32 std::string value(ToString(bytecode));
33 switch (operand_scale) {
34 case 1:
35 return value;
36 case 2: {
37 DCHECK(IsBytecodeWithScalableOperands(bytecode));
38 const char* suffix =
39 interpreter::Bytecodes::ToString(interpreter::Bytecode::kWide);
40 return value.append(1, kSeparator).append(suffix);
41 }
42 case 4: {
43 DCHECK(IsBytecodeWithScalableOperands(bytecode));
44 const char* suffix =
45 interpreter::Bytecodes::ToString(interpreter::Bytecode::kExtraWide);
46 return value.append(1, kSeparator).append(suffix);
47 }
48 default:
49 UNREACHABLE();
50 }
51 return value;
52 }
28 53
29 // static 54 // static
30 const char* Bytecodes::OperandTypeToString(OperandType operand_type) { 55 const char* Bytecodes::OperandTypeToString(OperandType operand_type) {
31 switch (operand_type) { 56 switch (operand_type) {
32 #define CASE(Name, _) \ 57 #define CASE(Name, _) \
33 case OperandType::k##Name: \ 58 case OperandType::k##Name: \
34 return #Name; 59 return #Name;
35 OPERAND_TYPE_LIST(CASE) 60 OPERAND_TYPE_LIST(CASE)
36 #undef CASE 61 #undef CASE
37 } 62 }
38 UNREACHABLE(); 63 UNREACHABLE();
39 return ""; 64 return "";
40 } 65 }
41 66
42 67
43 // static 68 // static
44 const char* Bytecodes::OperandSizeToString(OperandSize operand_size) { 69 const char* Bytecodes::OperandSizeToString(OperandSize operand_size) {
45 switch (operand_size) { 70 switch (operand_size) {
46 case OperandSize::kNone: 71 case OperandSize::kNone:
47 return "None"; 72 return "None";
48 case OperandSize::kByte: 73 case OperandSize::kByte:
49 return "Byte"; 74 return "Byte";
50 case OperandSize::kShort: 75 case OperandSize::kShort:
51 return "Short"; 76 return "Short";
77 case OperandSize::kQuad:
78 return "Quad";
52 } 79 }
53 UNREACHABLE(); 80 UNREACHABLE();
54 return ""; 81 return "";
55 } 82 }
56 83
57 84
58 // static 85 // static
59 uint8_t Bytecodes::ToByte(Bytecode bytecode) { 86 uint8_t Bytecodes::ToByte(Bytecode bytecode) {
60 DCHECK(bytecode <= Bytecode::kLast); 87 DCHECK(bytecode <= Bytecode::kLast);
61 return static_cast<uint8_t>(bytecode); 88 return static_cast<uint8_t>(bytecode);
62 } 89 }
63 90
64 91
65 // static 92 // static
66 Bytecode Bytecodes::FromByte(uint8_t value) { 93 Bytecode Bytecodes::FromByte(uint8_t value) {
67 Bytecode bytecode = static_cast<Bytecode>(value); 94 Bytecode bytecode = static_cast<Bytecode>(value);
68 DCHECK(bytecode <= Bytecode::kLast); 95 DCHECK(bytecode <= Bytecode::kLast);
69 return bytecode; 96 return bytecode;
70 } 97 }
71 98
72 99
73 // static 100 // static
74 Bytecode Bytecodes::GetDebugBreak(Bytecode bytecode) { 101 Bytecode Bytecodes::GetDebugBreak(Bytecode bytecode, int operand_scale) {
75 switch (Size(bytecode)) { 102 int bytecode_size = Size(bytecode, operand_scale);
76 #define CASE(Name, ...) \ 103 #define RETURN_IF_DEBUG_BREAK_SIZE_MATCHES(Name, ...) \
77 case BytecodeTraits<__VA_ARGS__, OPERAND_TERM>::kSize: \ 104 if (bytecode_size == Size(Bytecode::k##Name, operand_scale)) { \
78 return Bytecode::k##Name; 105 return Bytecode::k##Name; \
79 DEBUG_BREAK_BYTECODE_LIST(CASE)
80 #undef CASE
81 default:
82 break;
83 } 106 }
107 DEBUG_BREAK_BYTECODE_LIST(RETURN_IF_DEBUG_BREAK_SIZE_MATCHES)
108 #undef RETURN_IF_DEBUG_BREAK_SIZE_MATCHES
84 UNREACHABLE(); 109 UNREACHABLE();
85 return static_cast<Bytecode>(-1); 110 return Bytecode::kIllegal;
86 } 111 }
87 112
88 // static 113 // static
89 int Bytecodes::Size(Bytecode bytecode) { 114 int Bytecodes::Size(Bytecode bytecode, int operand_scale) {
90 DCHECK(bytecode <= Bytecode::kLast); 115 int size = 1;
91 switch (bytecode) { 116 for (int i = 0; i < NumberOfOperands(bytecode); i++) {
92 #define CASE(Name, ...) \ 117 OperandSize operand_size = GetOperandSize(bytecode, i, operand_scale);
93 case Bytecode::k##Name: \ 118 int delta = static_cast<int>(operand_size);
94 return BytecodeTraits<__VA_ARGS__, OPERAND_TERM>::kSize; 119 DCHECK(base::bits::IsPowerOfTwo32(static_cast<uint32_t>(delta)));
95 BYTECODE_LIST(CASE) 120 size += delta;
96 #undef CASE
97 } 121 }
98 UNREACHABLE(); 122 return size;
99 return 0;
100 } 123 }
101 124
102 125
103 // static 126 // static
104 int Bytecodes::NumberOfOperands(Bytecode bytecode) { 127 int Bytecodes::NumberOfOperands(Bytecode bytecode) {
105 DCHECK(bytecode <= Bytecode::kLast); 128 DCHECK(bytecode <= Bytecode::kLast);
106 switch (bytecode) { 129 switch (bytecode) {
107 #define CASE(Name, ...) \ 130 #define CASE(Name, ...) \
108 case Bytecode::k##Name: \ 131 case Bytecode::k##Name: \
109 return BytecodeTraits<__VA_ARGS__, OPERAND_TERM>::kOperandCount; 132 return BytecodeTraits<__VA_ARGS__, OPERAND_TERM>::kOperandCount;
(...skipping 14 matching lines...) Expand all
124 typedef BytecodeTraits<__VA_ARGS__, OPERAND_TERM> Name##Trait; \ 147 typedef BytecodeTraits<__VA_ARGS__, OPERAND_TERM> Name##Trait; \
125 return Name##Trait::kRegisterOperandCount; 148 return Name##Trait::kRegisterOperandCount;
126 BYTECODE_LIST(CASE) 149 BYTECODE_LIST(CASE)
127 #undef CASE 150 #undef CASE
128 } 151 }
129 UNREACHABLE(); 152 UNREACHABLE();
130 return false; 153 return false;
131 } 154 }
132 155
133 // static 156 // static
157 int Bytecodes::GetPrefixBytecodeScale(Bytecode bytecode) {
158 switch (bytecode) {
159 case Bytecode::kExtraWide:
160 return 4;
161 case Bytecode::kWide:
162 return 2;
163 default:
164 return 1;
165 }
166 }
167
168 // static
134 OperandType Bytecodes::GetOperandType(Bytecode bytecode, int i) { 169 OperandType Bytecodes::GetOperandType(Bytecode bytecode, int i) {
135 DCHECK(bytecode <= Bytecode::kLast); 170 DCHECK(bytecode <= Bytecode::kLast);
136 switch (bytecode) { 171 switch (bytecode) {
137 #define CASE(Name, ...) \ 172 #define CASE(Name, ...) \
138 case Bytecode::k##Name: \ 173 case Bytecode::k##Name: \
139 return BytecodeTraits<__VA_ARGS__, OPERAND_TERM>::GetOperandType(i); 174 return BytecodeTraits<__VA_ARGS__, OPERAND_TERM>::GetOperandType(i);
140 BYTECODE_LIST(CASE) 175 BYTECODE_LIST(CASE)
141 #undef CASE 176 #undef CASE
142 } 177 }
143 UNREACHABLE(); 178 UNREACHABLE();
144 return OperandType::kNone; 179 return OperandType::kNone;
145 } 180 }
146 181
182 namespace {
147 183
148 // static 184 template <bool>
149 OperandSize Bytecodes::GetOperandSize(Bytecode bytecode, int i) { 185 struct OperandScaler {
150 DCHECK(bytecode <= Bytecode::kLast); 186 static int Multiply(int size, int scale) { return 0; }
151 switch (bytecode) { 187 };
152 #define CASE(Name, ...) \ 188
153 case Bytecode::k##Name: \ 189 template <>
154 return BytecodeTraits<__VA_ARGS__, OPERAND_TERM>::GetOperandSize(i); 190 struct OperandScaler<false> {
155 BYTECODE_LIST(CASE) 191 static int Multiply(int size, int scale) { return size; }
192 };
193
194 template <>
195 struct OperandScaler<true> {
196 static int Multiply(int size, int scale) { return size * scale; }
197 };
198
199 static int ScaledOperandSize(OperandType operand_type, int scale) {
200 switch (operand_type) {
201 #define CASE(Name, TypeInfo) \
202 case OperandType::k##Name: { \
203 OperandSize base_size = OperandTypeInfoTraits<TypeInfo>::kUnscaledSize; \
204 return OperandScaler<OperandTypeInfoTraits<TypeInfo>::kIsScalable>:: \
205 Multiply(static_cast<int>(base_size), scale); \
206 }
207 OPERAND_TYPE_LIST(CASE)
156 #undef CASE 208 #undef CASE
157 } 209 }
158 UNREACHABLE(); 210 UNREACHABLE();
159 return OperandSize::kNone; 211 return 0;
160 } 212 }
213 } // namespace
161 214
215 // static
216 OperandSize Bytecodes::GetOperandSize(Bytecode bytecode, int i, int scale) {
217 OperandType op_type = GetOperandType(bytecode, i);
218 return static_cast<OperandSize>(ScaledOperandSize(op_type, scale));
219 }
162 220
163 // static 221 // static
164 int Bytecodes::GetRegisterOperandBitmap(Bytecode bytecode) { 222 int Bytecodes::GetRegisterOperandBitmap(Bytecode bytecode) {
165 DCHECK(bytecode <= Bytecode::kLast); 223 DCHECK(bytecode <= Bytecode::kLast);
166 switch (bytecode) { 224 switch (bytecode) {
167 #define CASE(Name, ...) \ 225 #define CASE(Name, ...) \
168 case Bytecode::k##Name: \ 226 case Bytecode::k##Name: \
169 typedef BytecodeTraits<__VA_ARGS__, OPERAND_TERM> Name##Trait; \ 227 typedef BytecodeTraits<__VA_ARGS__, OPERAND_TERM> Name##Trait; \
170 return Name##Trait::kRegisterOperandBitmap; 228 return Name##Trait::kRegisterOperandBitmap;
171 BYTECODE_LIST(CASE) 229 BYTECODE_LIST(CASE)
172 #undef CASE 230 #undef CASE
173 } 231 }
174 UNREACHABLE(); 232 UNREACHABLE();
175 return false; 233 return false;
176 } 234 }
177 235
178 // static 236 // static
179 int Bytecodes::GetOperandOffset(Bytecode bytecode, int i) { 237 int Bytecodes::GetOperandOffset(Bytecode bytecode, int i, int scale) {
180 DCHECK(bytecode <= Bytecode::kLast); 238 int offset = 1;
181 switch (bytecode) { 239 for (int operand_index = 0; operand_index < i; ++operand_index) {
182 #define CASE(Name, ...) \ 240 OperandSize operand_size = GetOperandSize(bytecode, operand_index, scale);
183 case Bytecode::k##Name: \ 241 offset += static_cast<int>(operand_size);
184 return BytecodeTraits<__VA_ARGS__, OPERAND_TERM>::GetOperandOffset(i);
185 BYTECODE_LIST(CASE)
186 #undef CASE
187 } 242 }
188 UNREACHABLE(); 243 return offset;
189 return 0; 244 }
245
246 // static
247 OperandSize Bytecodes::SizeOfOperand(OperandType operand_type, int scale) {
248 return static_cast<OperandSize>(ScaledOperandSize(operand_type, scale));
190 } 249 }
191 250
192 251
193 // static
194 OperandSize Bytecodes::SizeOfOperand(OperandType operand_type) {
195 switch (operand_type) {
196 #define CASE(Name, Size) \
197 case OperandType::k##Name: \
198 return Size;
199 OPERAND_TYPE_LIST(CASE)
200 #undef CASE
201 }
202 UNREACHABLE();
203 return OperandSize::kNone;
204 }
205
206
207 // static 252 // static
208 bool Bytecodes::IsConditionalJumpImmediate(Bytecode bytecode) { 253 bool Bytecodes::IsConditionalJumpImmediate(Bytecode bytecode) {
209 return bytecode == Bytecode::kJumpIfTrue || 254 return bytecode == Bytecode::kJumpIfTrue ||
210 bytecode == Bytecode::kJumpIfFalse || 255 bytecode == Bytecode::kJumpIfFalse ||
211 bytecode == Bytecode::kJumpIfToBooleanTrue || 256 bytecode == Bytecode::kJumpIfToBooleanTrue ||
212 bytecode == Bytecode::kJumpIfToBooleanFalse || 257 bytecode == Bytecode::kJumpIfToBooleanFalse ||
213 bytecode == Bytecode::kJumpIfNotHole || 258 bytecode == Bytecode::kJumpIfNotHole ||
214 bytecode == Bytecode::kJumpIfNull || 259 bytecode == Bytecode::kJumpIfNull ||
215 bytecode == Bytecode::kJumpIfUndefined; 260 bytecode == Bytecode::kJumpIfUndefined;
216 } 261 }
217 262
218 263
219 // static 264 // static
220 bool Bytecodes::IsConditionalJumpConstant(Bytecode bytecode) { 265 bool Bytecodes::IsConditionalJumpConstant(Bytecode bytecode) {
221 return bytecode == Bytecode::kJumpIfTrueConstant || 266 return bytecode == Bytecode::kJumpIfTrueConstant ||
222 bytecode == Bytecode::kJumpIfFalseConstant || 267 bytecode == Bytecode::kJumpIfFalseConstant ||
223 bytecode == Bytecode::kJumpIfToBooleanTrueConstant || 268 bytecode == Bytecode::kJumpIfToBooleanTrueConstant ||
224 bytecode == Bytecode::kJumpIfToBooleanFalseConstant || 269 bytecode == Bytecode::kJumpIfToBooleanFalseConstant ||
225 bytecode == Bytecode::kJumpIfNotHoleConstant || 270 bytecode == Bytecode::kJumpIfNotHoleConstant ||
226 bytecode == Bytecode::kJumpIfNullConstant || 271 bytecode == Bytecode::kJumpIfNullConstant ||
227 bytecode == Bytecode::kJumpIfUndefinedConstant; 272 bytecode == Bytecode::kJumpIfUndefinedConstant;
228 } 273 }
229 274
230
231 // static
232 bool Bytecodes::IsConditionalJumpConstantWide(Bytecode bytecode) {
233 return bytecode == Bytecode::kJumpIfTrueConstantWide ||
234 bytecode == Bytecode::kJumpIfFalseConstantWide ||
235 bytecode == Bytecode::kJumpIfToBooleanTrueConstantWide ||
236 bytecode == Bytecode::kJumpIfToBooleanFalseConstantWide ||
237 bytecode == Bytecode::kJumpIfNotHoleConstantWide ||
238 bytecode == Bytecode::kJumpIfNullConstantWide ||
239 bytecode == Bytecode::kJumpIfUndefinedConstantWide;
240 }
241
242
243 // static 275 // static
244 bool Bytecodes::IsConditionalJump(Bytecode bytecode) { 276 bool Bytecodes::IsConditionalJump(Bytecode bytecode) {
245 return IsConditionalJumpImmediate(bytecode) || 277 return IsConditionalJumpImmediate(bytecode) ||
246 IsConditionalJumpConstant(bytecode) || 278 IsConditionalJumpConstant(bytecode);
247 IsConditionalJumpConstantWide(bytecode);
248 } 279 }
249 280
250 281
251 // static 282 // static
252 bool Bytecodes::IsJumpImmediate(Bytecode bytecode) { 283 bool Bytecodes::IsJumpImmediate(Bytecode bytecode) {
253 return bytecode == Bytecode::kJump || IsConditionalJumpImmediate(bytecode); 284 return bytecode == Bytecode::kJump || IsConditionalJumpImmediate(bytecode);
254 } 285 }
255 286
256 287
257 // static 288 // static
258 bool Bytecodes::IsJumpConstant(Bytecode bytecode) { 289 bool Bytecodes::IsJumpConstant(Bytecode bytecode) {
259 return bytecode == Bytecode::kJumpConstant || 290 return bytecode == Bytecode::kJumpConstant ||
260 IsConditionalJumpConstant(bytecode); 291 IsConditionalJumpConstant(bytecode);
261 } 292 }
262 293
263
264 // static
265 bool Bytecodes::IsJumpConstantWide(Bytecode bytecode) {
266 return bytecode == Bytecode::kJumpConstantWide ||
267 IsConditionalJumpConstantWide(bytecode);
268 }
269
270
271 // static 294 // static
272 bool Bytecodes::IsJump(Bytecode bytecode) { 295 bool Bytecodes::IsJump(Bytecode bytecode) {
273 return IsJumpImmediate(bytecode) || IsJumpConstant(bytecode) || 296 return IsJumpImmediate(bytecode) || IsJumpConstant(bytecode);
274 IsJumpConstantWide(bytecode);
275 } 297 }
276 298
277 299
278 // static 300 // static
279 bool Bytecodes::IsCallOrNew(Bytecode bytecode) { 301 bool Bytecodes::IsCallOrNew(Bytecode bytecode) {
280 return bytecode == Bytecode::kCall || bytecode == Bytecode::kTailCall || 302 return bytecode == Bytecode::kCall || bytecode == Bytecode::kTailCall ||
281 bytecode == Bytecode::kNew || bytecode == Bytecode::kCallWide || 303 bytecode == Bytecode::kNew;
282 bytecode == Bytecode::kTailCallWide || bytecode == Bytecode::kNewWide;
283 } 304 }
284 305
285 // static 306 // static
286 bool Bytecodes::IsCallRuntime(Bytecode bytecode) { 307 bool Bytecodes::IsCallRuntime(Bytecode bytecode) {
287 return bytecode == Bytecode::kCallRuntime || 308 return bytecode == Bytecode::kCallRuntime ||
288 bytecode == Bytecode::kCallRuntimeWide || 309 bytecode == Bytecode::kCallRuntimeForPair;
289 bytecode == Bytecode::kCallRuntimeForPair ||
290 bytecode == Bytecode::kCallRuntimeForPairWide;
291 } 310 }
292 311
293 // static 312 // static
294 bool Bytecodes::IsDebugBreak(Bytecode bytecode) { 313 bool Bytecodes::IsDebugBreak(Bytecode bytecode) {
295 switch (bytecode) { 314 switch (bytecode) {
296 #define CASE(Name, ...) case Bytecode::k##Name: 315 #define CASE(Name, ...) case Bytecode::k##Name:
297 DEBUG_BREAK_BYTECODE_LIST(CASE); 316 DEBUG_BREAK_BYTECODE_LIST(CASE);
298 #undef CASE 317 #undef CASE
299 return true; 318 return true;
300 default: 319 default:
301 break; 320 break;
302 } 321 }
303 return false; 322 return false;
304 } 323 }
305 324
306 // static 325 // static
326 bool Bytecodes::IsBytecodeWithScalableOperands(Bytecode bytecode) {
327 switch (bytecode) {
328 #define CASE(Name, ...) \
329 case Bytecode::k##Name: \
330 typedef BytecodeTraits<__VA_ARGS__, OPERAND_TERM> Name##Trait; \
331 return Name##Trait::IsScalable();
332 BYTECODE_LIST(CASE)
333 #undef CASE
334 }
335 UNREACHABLE();
336 return false;
337 }
338
339 // static
340 bool Bytecodes::IsPrefixScalingBytecode(Bytecode bytecode) {
341 return GetPrefixBytecodeScale(bytecode) != 1;
342 }
343
344 // static
307 bool Bytecodes::IsJumpOrReturn(Bytecode bytecode) { 345 bool Bytecodes::IsJumpOrReturn(Bytecode bytecode) {
308 return bytecode == Bytecode::kReturn || IsJump(bytecode); 346 return bytecode == Bytecode::kReturn || IsJump(bytecode);
309 } 347 }
310 348
311 // static 349 // static
312 bool Bytecodes::IsIndexOperandType(OperandType operand_type) { 350 bool Bytecodes::IsMaybeRegisterOperandType(OperandType operand_type) {
313 return operand_type == OperandType::kIdx8 || 351 return operand_type == OperandType::kMaybeReg;
314 operand_type == OperandType::kIdx16;
315 } 352 }
316 353
317 // static 354 // static
318 bool Bytecodes::IsImmediateOperandType(OperandType operand_type) {
319 return operand_type == OperandType::kImm8;
320 }
321
322 // static
323 bool Bytecodes::IsRegisterCountOperandType(OperandType operand_type) {
324 return (operand_type == OperandType::kRegCount8 ||
325 operand_type == OperandType::kRegCount16);
326 }
327
328 // static
329 bool Bytecodes::IsMaybeRegisterOperandType(OperandType operand_type) {
330 return (operand_type == OperandType::kMaybeReg8 ||
331 operand_type == OperandType::kMaybeReg16);
332 }
333
334 // static
335 bool Bytecodes::IsRegisterOperandType(OperandType operand_type) { 355 bool Bytecodes::IsRegisterOperandType(OperandType operand_type) {
336 switch (operand_type) { 356 switch (operand_type) {
337 #define CASE(Name, _) \ 357 #define CASE(Name, _) \
338 case OperandType::k##Name: \ 358 case OperandType::k##Name: \
339 return true; 359 return true;
340 REGISTER_OPERAND_TYPE_LIST(CASE) 360 REGISTER_OPERAND_TYPE_LIST(CASE)
341 #undef CASE 361 #undef CASE
342 #define CASE(Name, _) \ 362 #define CASE(Name, _) \
343 case OperandType::k##Name: \ 363 case OperandType::k##Name: \
344 break; 364 break;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
377 #define CASE(Name, _) \ 397 #define CASE(Name, _) \
378 case OperandType::k##Name: \ 398 case OperandType::k##Name: \
379 break; 399 break;
380 NON_REGISTER_OPERAND_TYPE_LIST(CASE) 400 NON_REGISTER_OPERAND_TYPE_LIST(CASE)
381 REGISTER_INPUT_OPERAND_TYPE_LIST(CASE) 401 REGISTER_INPUT_OPERAND_TYPE_LIST(CASE)
382 #undef CASE 402 #undef CASE
383 } 403 }
384 return false; 404 return false;
385 } 405 }
386 406
407 // static
408 bool Bytecodes::IsUnsignedOperandType(OperandType operand_type) {
409 switch (operand_type) {
410 #define CASE(Name, _) \
411 case OperandType::k##Name: \
412 return OperandTraits<OperandType::k##Name>::TypeInfo::kIsUnsigned;
413 OPERAND_TYPE_LIST(CASE)
414 #undef CASE
415 }
416 UNREACHABLE();
417 return false;
418 }
419
387 namespace { 420 namespace {
421 static uint32_t DecodeUnsignedOperand(const uint8_t* operand_start,
422 OperandType operand_type,
423 int operand_scale) {
424 DCHECK(Bytecodes::IsUnsignedOperandType(operand_type));
425 switch (Bytecodes::SizeOfOperand(operand_type, operand_scale)) {
426 case OperandSize::kByte:
427 return *operand_start;
428 case OperandSize::kShort:
429 return ReadUnalignedUInt16(operand_start);
430 case OperandSize::kQuad:
431 return ReadUnalignedUInt32(operand_start);
432 case OperandSize::kNone:
433 UNREACHABLE();
434 }
435 return 0;
436 }
437
438 static int32_t DecodeSignedOperand(const uint8_t* operand_start,
439 OperandType operand_type,
440 int operand_scale) {
441 DCHECK(!Bytecodes::IsUnsignedOperandType(operand_type));
442 switch (Bytecodes::SizeOfOperand(operand_type, operand_scale)) {
443 case OperandSize::kByte:
444 return static_cast<int8_t>(*operand_start);
445 case OperandSize::kShort:
446 return static_cast<int16_t>(ReadUnalignedUInt16(operand_start));
447 case OperandSize::kQuad:
448 return static_cast<int32_t>(ReadUnalignedUInt32(operand_start));
449 case OperandSize::kNone:
450 UNREACHABLE();
451 }
452 return 0;
453 }
454
388 static Register DecodeRegister(const uint8_t* operand_start, 455 static Register DecodeRegister(const uint8_t* operand_start,
389 OperandType operand_type) { 456 OperandType operand_type, int operand_scale) {
390 switch (Bytecodes::SizeOfOperand(operand_type)) { 457 DCHECK(Bytecodes::IsRegisterOperandType(operand_type));
391 case OperandSize::kByte: 458 int32_t operand =
392 return Register::FromOperand(*operand_start); 459 DecodeSignedOperand(operand_start, operand_type, operand_scale);
393 case OperandSize::kShort: 460 return Register::FromOperand(operand);
394 return Register::FromWideOperand(ReadUnalignedUInt16(operand_start));
395 case OperandSize::kNone: {
396 UNREACHABLE();
397 }
398 }
399 return Register();
400 } 461 }
401 } // namespace 462 } // namespace
402 463
403 464
404 // static 465 // static
405 std::ostream& Bytecodes::Decode(std::ostream& os, const uint8_t* bytecode_start, 466 std::ostream& Bytecodes::Decode(std::ostream& os, const uint8_t* bytecode_start,
406 int parameter_count) { 467 int parameter_count) {
407 Vector<char> buf = Vector<char>::New(50); 468 Vector<char> buf = Vector<char>::New(50);
408 469
409 Bytecode bytecode = Bytecodes::FromByte(bytecode_start[0]); 470 Bytecode bytecode = Bytecodes::FromByte(bytecode_start[0]);
410 int bytecode_size = Bytecodes::Size(bytecode); 471 int prefix_offset = 0;
472 int operand_scale = Bytecodes::GetPrefixBytecodeScale(bytecode);
473 if (operand_scale > 1) {
474 prefix_offset += 1;
475 bytecode = Bytecodes::FromByte(bytecode_start[1]);
476 }
411 477
412 for (int i = 0; i < bytecode_size; i++) { 478 int bytecode_size = Bytecodes::Size(bytecode, operand_scale);
479
480 for (int i = 0; i < prefix_offset + bytecode_size; i++) {
413 SNPrintF(buf, "%02x ", bytecode_start[i]); 481 SNPrintF(buf, "%02x ", bytecode_start[i]);
414 os << buf.start(); 482 os << buf.start();
415 } 483 }
416 const int kBytecodeColumnSize = 6; 484 const int kBytecodeColumnSize = 6;
417 for (int i = bytecode_size; i < kBytecodeColumnSize; i++) { 485 for (int i = prefix_offset + bytecode_size; i < kBytecodeColumnSize; i++) {
418 os << " "; 486 os << " ";
419 } 487 }
420 488
421 os << bytecode << " "; 489 os << Bytecodes::ToString(bytecode, operand_scale) << " ";
422 490
423 // Operands for the debug break are from the original instruction. 491 // Operands for the debug break are from the original instruction.
424 if (IsDebugBreak(bytecode)) return os; 492 if (IsDebugBreak(bytecode)) return os;
425 493
426 int number_of_operands = NumberOfOperands(bytecode); 494 int number_of_operands = NumberOfOperands(bytecode);
427 int range = 0; 495 int range = 0;
428 for (int i = 0; i < number_of_operands; i++) { 496 for (int i = 0; i < number_of_operands; i++) {
429 OperandType op_type = GetOperandType(bytecode, i); 497 OperandType op_type = GetOperandType(bytecode, i);
430 const uint8_t* operand_start = 498 const uint8_t* operand_start =
431 &bytecode_start[GetOperandOffset(bytecode, i)]; 499 &bytecode_start[prefix_offset +
500 GetOperandOffset(bytecode, i, operand_scale)];
432 switch (op_type) { 501 switch (op_type) {
433 case interpreter::OperandType::kRegCount8: 502 case interpreter::OperandType::kRegCount:
434 os << "#" << static_cast<unsigned int>(*operand_start); 503 os << "#"
504 << DecodeUnsignedOperand(operand_start, op_type, operand_scale);
435 break; 505 break;
436 case interpreter::OperandType::kRegCount16: 506 case interpreter::OperandType::kIdx:
437 os << '#' << ReadUnalignedUInt16(operand_start); 507 case interpreter::OperandType::kRuntimeId:
508 os << "["
509 << DecodeUnsignedOperand(operand_start, op_type, operand_scale)
510 << "]";
438 break; 511 break;
439 case interpreter::OperandType::kIdx8: 512 case interpreter::OperandType::kImm:
440 os << "[" << static_cast<unsigned int>(*operand_start) << "]"; 513 os << "[" << DecodeSignedOperand(operand_start, op_type, operand_scale)
514 << "]";
441 break; 515 break;
442 case interpreter::OperandType::kIdx16: 516 case interpreter::OperandType::kFlag8:
443 os << "[" << ReadUnalignedUInt16(operand_start) << "]"; 517 os << "#"
518 << DecodeUnsignedOperand(operand_start, op_type, operand_scale);
444 break; 519 break;
445 case interpreter::OperandType::kImm8: 520 case interpreter::OperandType::kMaybeReg:
446 os << "#" << static_cast<int>(static_cast<int8_t>(*operand_start)); 521 case interpreter::OperandType::kReg:
447 break; 522 case interpreter::OperandType::kRegOut: {
448 case interpreter::OperandType::kMaybeReg8: 523 Register reg = DecodeRegister(operand_start, op_type, operand_scale);
449 case interpreter::OperandType::kMaybeReg16:
450 case interpreter::OperandType::kReg8:
451 case interpreter::OperandType::kReg16:
452 case interpreter::OperandType::kRegOut8:
453 case interpreter::OperandType::kRegOut16: {
454 Register reg = DecodeRegister(operand_start, op_type);
455 os << reg.ToString(parameter_count); 524 os << reg.ToString(parameter_count);
456 break; 525 break;
457 } 526 }
458 case interpreter::OperandType::kRegOutTriple8: 527 case interpreter::OperandType::kRegOutTriple:
459 case interpreter::OperandType::kRegOutTriple16:
460 range += 1; 528 range += 1;
461 case interpreter::OperandType::kRegOutPair8: 529 case interpreter::OperandType::kRegOutPair:
462 case interpreter::OperandType::kRegOutPair16: 530 case interpreter::OperandType::kRegPair: {
463 case interpreter::OperandType::kRegPair8:
464 case interpreter::OperandType::kRegPair16: {
465 range += 1; 531 range += 1;
466 Register first_reg = DecodeRegister(operand_start, op_type); 532 Register first_reg =
533 DecodeRegister(operand_start, op_type, operand_scale);
467 Register last_reg = Register(first_reg.index() + range); 534 Register last_reg = Register(first_reg.index() + range);
468 os << first_reg.ToString(parameter_count) << "-" 535 os << first_reg.ToString(parameter_count) << "-"
469 << last_reg.ToString(parameter_count); 536 << last_reg.ToString(parameter_count);
470 break; 537 break;
471 } 538 }
472 case interpreter::OperandType::kNone: 539 case interpreter::OperandType::kNone:
473 UNREACHABLE(); 540 UNREACHABLE();
474 break; 541 break;
475 } 542 }
476 if (i != number_of_operands - 1) { 543 if (i != number_of_operands - 1) {
477 os << ", "; 544 os << ", ";
478 } 545 }
479 } 546 }
480 return os; 547 return os;
481 } 548 }
482 549
483 std::ostream& operator<<(std::ostream& os, const Bytecode& bytecode) { 550 std::ostream& operator<<(std::ostream& os, const Bytecode& bytecode) {
484 return os << Bytecodes::ToString(bytecode); 551 return os << Bytecodes::ToString(bytecode);
485 } 552 }
486 553
487
488 std::ostream& operator<<(std::ostream& os, const OperandType& operand_type) { 554 std::ostream& operator<<(std::ostream& os, const OperandType& operand_type) {
489 return os << Bytecodes::OperandTypeToString(operand_type); 555 return os << Bytecodes::OperandTypeToString(operand_type);
490 } 556 }
491 557
492
493 std::ostream& operator<<(std::ostream& os, const OperandSize& operand_size) { 558 std::ostream& operator<<(std::ostream& os, const OperandSize& operand_size) {
494 return os << Bytecodes::OperandSizeToString(operand_size); 559 return os << Bytecodes::OperandSizeToString(operand_size);
495 } 560 }
496 561
497 static const int kLastParamRegisterIndex = 562 static const int kLastParamRegisterIndex =
498 -InterpreterFrameConstants::kLastParamFromRegisterPointer / kPointerSize; 563 -InterpreterFrameConstants::kLastParamFromRegisterPointer / kPointerSize;
499 static const int kFunctionClosureRegisterIndex = 564 static const int kFunctionClosureRegisterIndex =
500 -InterpreterFrameConstants::kFunctionFromRegisterPointer / kPointerSize; 565 -InterpreterFrameConstants::kFunctionFromRegisterPointer / kPointerSize;
501 static const int kCurrentContextRegisterIndex = 566 static const int kCurrentContextRegisterIndex =
502 -InterpreterFrameConstants::kContextFromRegisterPointer / kPointerSize; 567 -InterpreterFrameConstants::kContextFromRegisterPointer / kPointerSize;
503 static const int kNewTargetRegisterIndex = 568 static const int kNewTargetRegisterIndex =
504 -InterpreterFrameConstants::kNewTargetFromRegisterPointer / kPointerSize; 569 -InterpreterFrameConstants::kNewTargetFromRegisterPointer / kPointerSize;
505 570
506 // The register space is a signed 16-bit space. Register operands
507 // occupy range above 0. Parameter indices are biased with the
508 // negative value kLastParamRegisterIndex for ease of access in the
509 // interpreter.
510 static const int kMaxParameterIndex = kMaxInt16 + kLastParamRegisterIndex;
511 static const int kMaxRegisterIndex = -kMinInt16;
512 static const int kMaxReg8Index = -kMinInt8;
513 static const int kMinReg8Index = -kMaxInt8;
514 static const int kMaxReg16Index = -kMinInt16;
515 static const int kMinReg16Index = -kMaxInt16;
516
517 bool Register::is_byte_operand() const { 571 bool Register::is_byte_operand() const {
518 return index_ >= kMinReg8Index && index_ <= kMaxReg8Index; 572 return index_ >= -kMaxInt8 && index_ <= -kMinInt8;
519 } 573 }
520 574
521 bool Register::is_short_operand() const { 575 bool Register::is_short_operand() const {
522 return index_ >= kMinReg16Index && index_ <= kMaxReg16Index; 576 return index_ >= -kMaxInt16 && index_ <= -kMinInt16;
523 } 577 }
524 578
525 Register Register::FromParameterIndex(int index, int parameter_count) { 579 Register Register::FromParameterIndex(int index, int parameter_count) {
526 DCHECK_GE(index, 0); 580 DCHECK_GE(index, 0);
527 DCHECK_LT(index, parameter_count); 581 DCHECK_LT(index, parameter_count);
528 DCHECK_LE(parameter_count, kMaxParameterIndex + 1);
529 int register_index = kLastParamRegisterIndex - parameter_count + index + 1; 582 int register_index = kLastParamRegisterIndex - parameter_count + index + 1;
530 DCHECK_LT(register_index, 0); 583 DCHECK_LT(register_index, 0);
531 return Register(register_index); 584 return Register(register_index);
532 } 585 }
533 586
534 587
535 int Register::ToParameterIndex(int parameter_count) const { 588 int Register::ToParameterIndex(int parameter_count) const {
536 DCHECK(is_parameter()); 589 DCHECK(is_parameter());
537 return index() - kLastParamRegisterIndex + parameter_count - 1; 590 return index() - kLastParamRegisterIndex + parameter_count - 1;
538 } 591 }
(...skipping 19 matching lines...) Expand all
558 } 611 }
559 612
560 613
561 Register Register::new_target() { return Register(kNewTargetRegisterIndex); } 614 Register Register::new_target() { return Register(kNewTargetRegisterIndex); }
562 615
563 616
564 bool Register::is_new_target() const { 617 bool Register::is_new_target() const {
565 return index() == kNewTargetRegisterIndex; 618 return index() == kNewTargetRegisterIndex;
566 } 619 }
567 620
568 int Register::MaxParameterIndex() { return kMaxParameterIndex; }
569
570 int Register::MaxRegisterIndex() { return kMaxRegisterIndex; }
571
572 int Register::MaxRegisterIndexForByteOperand() { return kMaxReg8Index; }
573
574 uint8_t Register::ToOperand() const {
575 DCHECK(is_byte_operand());
576 return static_cast<uint8_t>(-index_);
577 }
578
579
580 Register Register::FromOperand(uint8_t operand) {
581 return Register(-static_cast<int8_t>(operand));
582 }
583
584
585 uint16_t Register::ToWideOperand() const {
586 DCHECK(is_short_operand());
587 return static_cast<uint16_t>(-index_);
588 }
589
590
591 Register Register::FromWideOperand(uint16_t operand) {
592 return Register(-static_cast<int16_t>(operand));
593 }
594
595
596 uint32_t Register::ToRawOperand() const {
597 return static_cast<uint32_t>(-index_);
598 }
599
600
601 Register Register::FromRawOperand(uint32_t operand) {
602 return Register(-static_cast<int32_t>(operand));
603 }
604
605
606 bool Register::AreContiguous(Register reg1, Register reg2, Register reg3, 621 bool Register::AreContiguous(Register reg1, Register reg2, Register reg3,
607 Register reg4, Register reg5) { 622 Register reg4, Register reg5) {
608 if (reg1.index() + 1 != reg2.index()) { 623 if (reg1.index() + 1 != reg2.index()) {
609 return false; 624 return false;
610 } 625 }
611 if (reg3.is_valid() && reg2.index() + 1 != reg3.index()) { 626 if (reg3.is_valid() && reg2.index() + 1 != reg3.index()) {
612 return false; 627 return false;
613 } 628 }
614 if (reg4.is_valid() && reg3.index() + 1 != reg4.index()) { 629 if (reg4.is_valid() && reg3.index() + 1 != reg4.index()) {
615 return false; 630 return false;
(...skipping 23 matching lines...) Expand all
639 } else { 654 } else {
640 std::ostringstream s; 655 std::ostringstream s;
641 s << "r" << index(); 656 s << "r" << index();
642 return s.str(); 657 return s.str();
643 } 658 }
644 } 659 }
645 660
646 } // namespace interpreter 661 } // namespace interpreter
647 } // namespace internal 662 } // namespace internal
648 } // namespace v8 663 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698