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

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: Operand renaming. 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 {
(...skipping 11 matching lines...) Expand all
22 #undef CASE 22 #undef CASE
23 } 23 }
24 UNREACHABLE(); 24 UNREACHABLE();
25 return ""; 25 return "";
26 } 26 }
27 27
28 28
29 // static 29 // static
30 const char* Bytecodes::OperandTypeToString(OperandType operand_type) { 30 const char* Bytecodes::OperandTypeToString(OperandType operand_type) {
31 switch (operand_type) { 31 switch (operand_type) {
32 #define CASE(Name, _) \ 32 #define CASE(Name, _, __) \
33 case OperandType::k##Name: \ 33 case OperandType::k##Name: \
34 return #Name; 34 return #Name;
35 OPERAND_TYPE_LIST(CASE) 35 OPERAND_TYPE_LIST(CASE)
36 #undef CASE 36 #undef CASE
37 } 37 }
38 UNREACHABLE(); 38 UNREACHABLE();
39 return ""; 39 return "";
40 } 40 }
41 41
42 42
43 // static 43 // static
44 const char* Bytecodes::OperandSizeToString(OperandSize operand_size) { 44 const char* Bytecodes::OperandSizeToString(OperandSize operand_size) {
45 switch (operand_size) { 45 switch (operand_size) {
46 case OperandSize::kNone: 46 case OperandSize::kNone:
47 return "None"; 47 return "None";
48 case OperandSize::kByte: 48 case OperandSize::kByte:
49 return "Byte"; 49 return "Byte";
50 case OperandSize::kShort: 50 case OperandSize::kShort:
51 return "Short"; 51 return "Short";
52 case OperandSize::kQuad:
53 return "Quad";
52 } 54 }
53 UNREACHABLE(); 55 UNREACHABLE();
54 return ""; 56 return "";
55 } 57 }
56 58
57 59
58 // static 60 // static
59 uint8_t Bytecodes::ToByte(Bytecode bytecode) { 61 uint8_t Bytecodes::ToByte(Bytecode bytecode) {
60 DCHECK(bytecode <= Bytecode::kLast); 62 DCHECK(bytecode <= Bytecode::kLast);
61 return static_cast<uint8_t>(bytecode); 63 return static_cast<uint8_t>(bytecode);
62 } 64 }
63 65
64 66
65 // static 67 // static
66 Bytecode Bytecodes::FromByte(uint8_t value) { 68 Bytecode Bytecodes::FromByte(uint8_t value) {
67 Bytecode bytecode = static_cast<Bytecode>(value); 69 Bytecode bytecode = static_cast<Bytecode>(value);
68 DCHECK(bytecode <= Bytecode::kLast); 70 DCHECK(bytecode <= Bytecode::kLast);
69 return bytecode; 71 return bytecode;
70 } 72 }
71 73
72 74
73 // static 75 // static
74 Bytecode Bytecodes::GetDebugBreak(Bytecode bytecode) { 76 Bytecode Bytecodes::GetDebugBreak(Bytecode bytecode, int operand_scale) {
75 switch (Size(bytecode)) { 77 int bytecode_size = Size(bytecode, operand_scale);
76 #define CASE(Name, ...) \ 78 #define RETURN_IF_DEBUG_BREAK_SIZE_MATCHES(Name, ...) \
77 case BytecodeTraits<__VA_ARGS__, OPERAND_TERM>::kSize: \ 79 if (bytecode_size == Size(Bytecode::k##Name, operand_scale)) { \
78 return Bytecode::k##Name; 80 return Bytecode::k##Name; \
79 DEBUG_BREAK_BYTECODE_LIST(CASE)
80 #undef CASE
81 default:
82 break;
83 } 81 }
82 DEBUG_BREAK_BYTECODE_LIST(RETURN_IF_DEBUG_BREAK_SIZE_MATCHES)
83 #undef RETURN_IF_DEBUG_BREAK_SIZE_MATCHES
84 UNREACHABLE(); 84 UNREACHABLE();
85 return static_cast<Bytecode>(-1); 85 return static_cast<Bytecode>(-1);
86 } 86 }
87 87
88 // static 88 // static
89 int Bytecodes::Size(Bytecode bytecode) { 89 int Bytecodes::Size(Bytecode bytecode, int operand_scale) {
90 DCHECK(bytecode <= Bytecode::kLast); 90 int size = 1;
91 switch (bytecode) { 91 for (int i = 0; i < NumberOfOperands(bytecode); i++) {
92 #define CASE(Name, ...) \ 92 OperandSize operand_size = GetOperandSize(bytecode, i, operand_scale);
93 case Bytecode::k##Name: \ 93 int delta = static_cast<int>(operand_size);
94 return BytecodeTraits<__VA_ARGS__, OPERAND_TERM>::kSize; 94 DCHECK(base::bits::IsPowerOfTwo32(static_cast<uint32_t>(delta)));
95 BYTECODE_LIST(CASE) 95 size += delta;
96 #undef CASE
97 } 96 }
98 UNREACHABLE(); 97 return size;
99 return 0;
100 } 98 }
101 99
102 100
103 // static 101 // static
104 int Bytecodes::NumberOfOperands(Bytecode bytecode) { 102 int Bytecodes::NumberOfOperands(Bytecode bytecode) {
105 DCHECK(bytecode <= Bytecode::kLast); 103 DCHECK(bytecode <= Bytecode::kLast);
106 switch (bytecode) { 104 switch (bytecode) {
107 #define CASE(Name, ...) \ 105 #define CASE(Name, ...) \
108 case Bytecode::k##Name: \ 106 case Bytecode::k##Name: \
109 return BytecodeTraits<__VA_ARGS__, OPERAND_TERM>::kOperandCount; 107 return BytecodeTraits<__VA_ARGS__, OPERAND_TERM>::kOperandCount;
(...skipping 14 matching lines...) Expand all
124 typedef BytecodeTraits<__VA_ARGS__, OPERAND_TERM> Name##Trait; \ 122 typedef BytecodeTraits<__VA_ARGS__, OPERAND_TERM> Name##Trait; \
125 return Name##Trait::kRegisterOperandCount; 123 return Name##Trait::kRegisterOperandCount;
126 BYTECODE_LIST(CASE) 124 BYTECODE_LIST(CASE)
127 #undef CASE 125 #undef CASE
128 } 126 }
129 UNREACHABLE(); 127 UNREACHABLE();
130 return false; 128 return false;
131 } 129 }
132 130
133 // static 131 // static
132 int Bytecodes::GetPrefixBytecodeScale(Bytecode bytecode) {
133 switch (bytecode) {
rmcilroy 2016/03/10 16:45:37 Could we make this DCHECK if it is passed a non-pr
oth 2016/03/11 16:26:12 Not really, this is one of the main ways of determ
oth 2016/03/17 13:48:38 Done.
134 case Bytecode::kExtraWide:
135 return 4;
136 case Bytecode::kWide:
137 return 2;
138 default:
139 return 1;
140 }
141 }
142
143 // static
134 OperandType Bytecodes::GetOperandType(Bytecode bytecode, int i) { 144 OperandType Bytecodes::GetOperandType(Bytecode bytecode, int i) {
135 DCHECK(bytecode <= Bytecode::kLast); 145 DCHECK(bytecode <= Bytecode::kLast);
136 switch (bytecode) { 146 switch (bytecode) {
137 #define CASE(Name, ...) \ 147 #define CASE(Name, ...) \
138 case Bytecode::k##Name: \ 148 case Bytecode::k##Name: \
139 return BytecodeTraits<__VA_ARGS__, OPERAND_TERM>::GetOperandType(i); 149 return BytecodeTraits<__VA_ARGS__, OPERAND_TERM>::GetOperandType(i);
140 BYTECODE_LIST(CASE) 150 BYTECODE_LIST(CASE)
141 #undef CASE 151 #undef CASE
142 } 152 }
143 UNREACHABLE(); 153 UNREACHABLE();
144 return OperandType::kNone; 154 return OperandType::kNone;
145 } 155 }
146 156
157 // TODO(oth): TEMPORARY
158 namespace {
159
160 template <OperandTypeTrait O>
161 struct OperandScaler {
162 static int Multiply(int size, int scale) { return 0; }
163 };
164
165 template <>
166 struct OperandScaler<OperandTypeTrait::kFixed> {
167 static int Multiply(int size, int scale) { return size; }
168 };
169
170 template <>
171 struct OperandScaler<OperandTypeTrait::kScalable> {
172 static int Multiply(int size, int scale) { return size * scale; }
173 };
174
175 } // namespace
176
177 // TODO(oth): TEMPORARY
178 static int ScaledOperandSize(OperandType operand_type, int scale) {
179 switch (operand_type) {
180 #define CASE(Name, Size, Trait) \
181 case OperandType::k##Name: \
182 return OperandScaler<Trait>::Multiply(static_cast<int>(Size), scale);
183 OPERAND_TYPE_LIST(CASE)
184 #undef CASE
185 }
186 UNREACHABLE();
187 return 0;
188 }
189
147 190
148 // static 191 // static
149 OperandSize Bytecodes::GetOperandSize(Bytecode bytecode, int i) { 192 OperandSize Bytecodes::GetOperandSize(Bytecode bytecode, int i, int scale) {
150 DCHECK(bytecode <= Bytecode::kLast); 193 OperandType op_type = GetOperandType(bytecode, i);
151 switch (bytecode) { 194 return static_cast<OperandSize>(ScaledOperandSize(op_type, scale));
152 #define CASE(Name, ...) \
153 case Bytecode::k##Name: \
154 return BytecodeTraits<__VA_ARGS__, OPERAND_TERM>::GetOperandSize(i);
155 BYTECODE_LIST(CASE)
156 #undef CASE
157 }
158 UNREACHABLE();
159 return OperandSize::kNone;
160 } 195 }
161 196
162
163 // static 197 // static
164 int Bytecodes::GetRegisterOperandBitmap(Bytecode bytecode) { 198 int Bytecodes::GetRegisterOperandBitmap(Bytecode bytecode) {
165 DCHECK(bytecode <= Bytecode::kLast); 199 DCHECK(bytecode <= Bytecode::kLast);
166 switch (bytecode) { 200 switch (bytecode) {
167 #define CASE(Name, ...) \ 201 #define CASE(Name, ...) \
168 case Bytecode::k##Name: \ 202 case Bytecode::k##Name: \
169 typedef BytecodeTraits<__VA_ARGS__, OPERAND_TERM> Name##Trait; \ 203 typedef BytecodeTraits<__VA_ARGS__, OPERAND_TERM> Name##Trait; \
170 return Name##Trait::kRegisterOperandBitmap; 204 return Name##Trait::kRegisterOperandBitmap;
171 BYTECODE_LIST(CASE) 205 BYTECODE_LIST(CASE)
172 #undef CASE 206 #undef CASE
173 } 207 }
174 UNREACHABLE(); 208 UNREACHABLE();
175 return false; 209 return false;
176 } 210 }
177 211
178 // static 212 // static
179 int Bytecodes::GetOperandOffset(Bytecode bytecode, int i) { 213 int Bytecodes::GetOperandOffset(Bytecode bytecode, int i, int scale) {
180 DCHECK(bytecode <= Bytecode::kLast); 214 int offset = 1;
181 switch (bytecode) { 215 for (int operand_index = 0; operand_index < i; ++operand_index) {
182 #define CASE(Name, ...) \ 216 OperandSize operand_size = GetOperandSize(bytecode, operand_index, scale);
183 case Bytecode::k##Name: \ 217 offset += static_cast<int>(operand_size);
184 return BytecodeTraits<__VA_ARGS__, OPERAND_TERM>::GetOperandOffset(i);
185 BYTECODE_LIST(CASE)
186 #undef CASE
187 } 218 }
188 UNREACHABLE(); 219 return offset;
189 return 0; 220 }
221
222 // static
223 OperandSize Bytecodes::SizeOfOperand(OperandType operand_type, int scale) {
224 return static_cast<OperandSize>(ScaledOperandSize(operand_type, scale));
190 } 225 }
191 226
192 227
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 228 // static
208 bool Bytecodes::IsConditionalJumpImmediate(Bytecode bytecode) { 229 bool Bytecodes::IsConditionalJumpImmediate(Bytecode bytecode) {
209 return bytecode == Bytecode::kJumpIfTrue || 230 return bytecode == Bytecode::kJumpIfTrue ||
210 bytecode == Bytecode::kJumpIfFalse || 231 bytecode == Bytecode::kJumpIfFalse ||
211 bytecode == Bytecode::kJumpIfToBooleanTrue || 232 bytecode == Bytecode::kJumpIfToBooleanTrue ||
212 bytecode == Bytecode::kJumpIfToBooleanFalse || 233 bytecode == Bytecode::kJumpIfToBooleanFalse ||
213 bytecode == Bytecode::kJumpIfNotHole || 234 bytecode == Bytecode::kJumpIfNotHole ||
214 bytecode == Bytecode::kJumpIfNull || 235 bytecode == Bytecode::kJumpIfNull ||
215 bytecode == Bytecode::kJumpIfUndefined; 236 bytecode == Bytecode::kJumpIfUndefined;
216 } 237 }
217 238
218 239
219 // static 240 // static
220 bool Bytecodes::IsConditionalJumpConstant(Bytecode bytecode) { 241 bool Bytecodes::IsConditionalJumpConstant(Bytecode bytecode) {
221 return bytecode == Bytecode::kJumpIfTrueConstant || 242 return bytecode == Bytecode::kJumpIfTrueConstant ||
222 bytecode == Bytecode::kJumpIfFalseConstant || 243 bytecode == Bytecode::kJumpIfFalseConstant ||
223 bytecode == Bytecode::kJumpIfToBooleanTrueConstant || 244 bytecode == Bytecode::kJumpIfToBooleanTrueConstant ||
224 bytecode == Bytecode::kJumpIfToBooleanFalseConstant || 245 bytecode == Bytecode::kJumpIfToBooleanFalseConstant ||
225 bytecode == Bytecode::kJumpIfNotHoleConstant || 246 bytecode == Bytecode::kJumpIfNotHoleConstant ||
226 bytecode == Bytecode::kJumpIfNullConstant || 247 bytecode == Bytecode::kJumpIfNullConstant ||
227 bytecode == Bytecode::kJumpIfUndefinedConstant; 248 bytecode == Bytecode::kJumpIfUndefinedConstant;
228 } 249 }
229 250
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 251 // static
244 bool Bytecodes::IsConditionalJump(Bytecode bytecode) { 252 bool Bytecodes::IsConditionalJump(Bytecode bytecode) {
245 return IsConditionalJumpImmediate(bytecode) || 253 return IsConditionalJumpImmediate(bytecode) ||
246 IsConditionalJumpConstant(bytecode) || 254 IsConditionalJumpConstant(bytecode);
247 IsConditionalJumpConstantWide(bytecode);
248 } 255 }
249 256
250 257
251 // static 258 // static
252 bool Bytecodes::IsJumpImmediate(Bytecode bytecode) { 259 bool Bytecodes::IsJumpImmediate(Bytecode bytecode) {
253 return bytecode == Bytecode::kJump || IsConditionalJumpImmediate(bytecode); 260 return bytecode == Bytecode::kJump || IsConditionalJumpImmediate(bytecode);
254 } 261 }
255 262
256 263
257 // static 264 // static
258 bool Bytecodes::IsJumpConstant(Bytecode bytecode) { 265 bool Bytecodes::IsJumpConstant(Bytecode bytecode) {
259 return bytecode == Bytecode::kJumpConstant || 266 return bytecode == Bytecode::kJumpConstant ||
260 IsConditionalJumpConstant(bytecode); 267 IsConditionalJumpConstant(bytecode);
261 } 268 }
262 269
263
264 // static
265 bool Bytecodes::IsJumpConstantWide(Bytecode bytecode) {
266 return bytecode == Bytecode::kJumpConstantWide ||
267 IsConditionalJumpConstantWide(bytecode);
268 }
269
270
271 // static 270 // static
272 bool Bytecodes::IsJump(Bytecode bytecode) { 271 bool Bytecodes::IsJump(Bytecode bytecode) {
273 return IsJumpImmediate(bytecode) || IsJumpConstant(bytecode) || 272 return IsJumpImmediate(bytecode) || IsJumpConstant(bytecode);
274 IsJumpConstantWide(bytecode);
275 } 273 }
276 274
277 275
278 // static 276 // static
279 bool Bytecodes::IsCallOrNew(Bytecode bytecode) { 277 bool Bytecodes::IsCallOrNew(Bytecode bytecode) {
280 return bytecode == Bytecode::kCall || bytecode == Bytecode::kTailCall || 278 return bytecode == Bytecode::kCall || bytecode == Bytecode::kTailCall ||
281 bytecode == Bytecode::kNew || bytecode == Bytecode::kCallWide || 279 bytecode == Bytecode::kNew;
282 bytecode == Bytecode::kTailCallWide || bytecode == Bytecode::kNewWide;
283 } 280 }
284 281
285 // static 282 // static
286 bool Bytecodes::IsCallRuntime(Bytecode bytecode) { 283 bool Bytecodes::IsCallRuntime(Bytecode bytecode) {
287 return bytecode == Bytecode::kCallRuntime || 284 return bytecode == Bytecode::kCallRuntime ||
288 bytecode == Bytecode::kCallRuntimeWide || 285 bytecode == Bytecode::kCallRuntimeForPair;
289 bytecode == Bytecode::kCallRuntimeForPair ||
290 bytecode == Bytecode::kCallRuntimeForPairWide;
291 } 286 }
292 287
293 // static 288 // static
294 bool Bytecodes::IsDebugBreak(Bytecode bytecode) { 289 bool Bytecodes::IsDebugBreak(Bytecode bytecode) {
295 switch (bytecode) { 290 switch (bytecode) {
296 #define CASE(Name, ...) case Bytecode::k##Name: 291 #define CASE(Name, ...) case Bytecode::k##Name:
297 DEBUG_BREAK_BYTECODE_LIST(CASE); 292 DEBUG_BREAK_BYTECODE_LIST(CASE);
298 #undef CASE 293 #undef CASE
299 return true; 294 return true;
300 default: 295 default:
301 break; 296 break;
302 } 297 }
303 return false; 298 return false;
304 } 299 }
305 300
306 // static 301 // static
302 bool Bytecodes::IsBytecodeWithScalableOperands(Bytecode bytecode) {
303 switch (bytecode) {
304 #define CASE(Name, ...) \
305 case Bytecode::k##Name: \
306 typedef BytecodeTraits<__VA_ARGS__, OPERAND_TERM> Name##Trait; \
307 return Name##Trait::IsScalable();
308 BYTECODE_LIST(CASE)
309 #undef CASE
310 }
311 UNREACHABLE();
312 return false;
313 }
314
315 // static
307 bool Bytecodes::IsJumpOrReturn(Bytecode bytecode) { 316 bool Bytecodes::IsJumpOrReturn(Bytecode bytecode) {
308 return bytecode == Bytecode::kReturn || IsJump(bytecode); 317 return bytecode == Bytecode::kReturn || IsJump(bytecode);
309 } 318 }
310 319
311 // static 320 // static
321 bool Bytecodes::IsFlagOperandType(OperandType operand_type) {
322 return operand_type == OperandType::kFlag8;
323 }
324
325 // static
312 bool Bytecodes::IsIndexOperandType(OperandType operand_type) { 326 bool Bytecodes::IsIndexOperandType(OperandType operand_type) {
313 return operand_type == OperandType::kIdx8 || 327 return operand_type == OperandType::kIdx;
314 operand_type == OperandType::kIdx16;
315 } 328 }
316 329
317 // static 330 // static
318 bool Bytecodes::IsImmediateOperandType(OperandType operand_type) { 331 bool Bytecodes::IsImmediateOperandType(OperandType operand_type) {
319 return operand_type == OperandType::kImm8; 332 return operand_type == OperandType::kImm;
320 } 333 }
321 334
322 // static 335 // static
323 bool Bytecodes::IsRegisterCountOperandType(OperandType operand_type) { 336 bool Bytecodes::IsRegisterCountOperandType(OperandType operand_type) {
324 return (operand_type == OperandType::kRegCount8 || 337 return operand_type == OperandType::kRegCount;
325 operand_type == OperandType::kRegCount16);
326 } 338 }
327 339
328 // static 340 // static
329 bool Bytecodes::IsMaybeRegisterOperandType(OperandType operand_type) { 341 bool Bytecodes::IsMaybeRegisterOperandType(OperandType operand_type) {
330 return (operand_type == OperandType::kMaybeReg8 || 342 return operand_type == OperandType::kMaybeReg;
331 operand_type == OperandType::kMaybeReg16); 343 }
344
345 // static
346 bool Bytecodes::IsRuntimeIdOperandType(OperandType operand_type) {
rmcilroy 2016/03/10 16:45:37 Wondering whether these IsXXXOperandType are neces
oth 2016/03/11 16:26:12 Done. Removed all except the still useful IsRegist
347 return operand_type == OperandType::kRuntimeId;
332 } 348 }
333 349
334 // static 350 // static
335 bool Bytecodes::IsRegisterOperandType(OperandType operand_type) { 351 bool Bytecodes::IsRegisterOperandType(OperandType operand_type) {
336 switch (operand_type) { 352 switch (operand_type) {
337 #define CASE(Name, _) \ 353 #define CASE(Name, _, __) \
338 case OperandType::k##Name: \ 354 case OperandType::k##Name: \
339 return true; 355 return true;
340 REGISTER_OPERAND_TYPE_LIST(CASE) 356 REGISTER_OPERAND_TYPE_LIST(CASE)
341 #undef CASE 357 #undef CASE
342 #define CASE(Name, _) \ 358 #define CASE(Name, _, __) \
343 case OperandType::k##Name: \ 359 case OperandType::k##Name: \
344 break; 360 break;
345 NON_REGISTER_OPERAND_TYPE_LIST(CASE) 361 NON_REGISTER_OPERAND_TYPE_LIST(CASE)
346 #undef CASE 362 #undef CASE
347 } 363 }
348 return false; 364 return false;
349 } 365 }
350 366
351 // static 367 // static
352 bool Bytecodes::IsRegisterInputOperandType(OperandType operand_type) { 368 bool Bytecodes::IsRegisterInputOperandType(OperandType operand_type) {
353 switch (operand_type) { 369 switch (operand_type) {
354 #define CASE(Name, _) \ 370 #define CASE(Name, _, __) \
355 case OperandType::k##Name: \ 371 case OperandType::k##Name: \
356 return true; 372 return true;
357 REGISTER_INPUT_OPERAND_TYPE_LIST(CASE) 373 REGISTER_INPUT_OPERAND_TYPE_LIST(CASE)
358 #undef CASE 374 #undef CASE
359 #define CASE(Name, _) \ 375 #define CASE(Name, _, __) \
360 case OperandType::k##Name: \ 376 case OperandType::k##Name: \
361 break; 377 break;
362 NON_REGISTER_OPERAND_TYPE_LIST(CASE) 378 NON_REGISTER_OPERAND_TYPE_LIST(CASE)
363 REGISTER_OUTPUT_OPERAND_TYPE_LIST(CASE) 379 REGISTER_OUTPUT_OPERAND_TYPE_LIST(CASE)
364 #undef CASE 380 #undef CASE
365 } 381 }
366 return false; 382 return false;
367 } 383 }
368 384
369 // static 385 // static
370 bool Bytecodes::IsRegisterOutputOperandType(OperandType operand_type) { 386 bool Bytecodes::IsRegisterOutputOperandType(OperandType operand_type) {
371 switch (operand_type) { 387 switch (operand_type) {
372 #define CASE(Name, _) \ 388 #define CASE(Name, _, __) \
373 case OperandType::k##Name: \ 389 case OperandType::k##Name: \
374 return true; 390 return true;
375 REGISTER_OUTPUT_OPERAND_TYPE_LIST(CASE) 391 REGISTER_OUTPUT_OPERAND_TYPE_LIST(CASE)
376 #undef CASE 392 #undef CASE
377 #define CASE(Name, _) \ 393 #define CASE(Name, _, __) \
378 case OperandType::k##Name: \ 394 case OperandType::k##Name: \
379 break; 395 break;
380 NON_REGISTER_OPERAND_TYPE_LIST(CASE) 396 NON_REGISTER_OPERAND_TYPE_LIST(CASE)
381 REGISTER_INPUT_OPERAND_TYPE_LIST(CASE) 397 REGISTER_INPUT_OPERAND_TYPE_LIST(CASE)
382 #undef CASE 398 #undef CASE
383 } 399 }
384 return false; 400 return false;
385 } 401 }
386 402
387 namespace { 403 namespace {
388 static Register DecodeRegister(const uint8_t* operand_start, 404 static Register DecodeRegister(const uint8_t* operand_start,
389 OperandType operand_type) { 405 OperandType operand_type, int operand_scale) {
390 switch (Bytecodes::SizeOfOperand(operand_type)) { 406 switch (Bytecodes::SizeOfOperand(operand_type, operand_scale)) {
391 case OperandSize::kByte: 407 case OperandSize::kByte:
392 return Register::FromOperand(*operand_start); 408 return Register::FromOperand(*operand_start);
393 case OperandSize::kShort: 409 case OperandSize::kShort:
394 return Register::FromWideOperand(ReadUnalignedUInt16(operand_start)); 410 return Register::FromWideOperand(ReadUnalignedUInt16(operand_start));
411 case OperandSize::kQuad:
412 return Register::FromWideOperand(ReadUnalignedUInt32(operand_start));
395 case OperandSize::kNone: { 413 case OperandSize::kNone: {
396 UNREACHABLE(); 414 UNREACHABLE();
397 } 415 }
398 } 416 }
399 return Register(); 417 return Register();
400 } 418 }
419
420 static uint32_t DecodeUnsignedOperand(const uint8_t* operand_start,
421 OperandType operand_type,
422 int operand_scale) {
423 switch (Bytecodes::SizeOfOperand(operand_type, operand_scale)) {
424 case OperandSize::kByte:
425 return *operand_start;
426 case OperandSize::kShort:
427 return ReadUnalignedUInt16(operand_start);
428 case OperandSize::kQuad:
429 return ReadUnalignedUInt32(operand_start);
430 case OperandSize::kNone:
431 UNREACHABLE();
432 }
433 return 0;
434 }
435
436 static int32_t DecodeSignedOperand(const uint8_t* operand_start,
437 OperandType operand_type,
438 int operand_scale) {
439 switch (Bytecodes::SizeOfOperand(operand_type, operand_scale)) {
440 case OperandSize::kByte:
441 return static_cast<int8_t>(*operand_start);
442 case OperandSize::kShort:
443 return static_cast<int16_t>(ReadUnalignedUInt16(operand_start));
444 case OperandSize::kQuad:
445 return static_cast<int32_t>(ReadUnalignedUInt32(operand_start));
446 case OperandSize::kNone:
447 UNREACHABLE();
448 }
449 return 0;
450 }
401 } // namespace 451 } // namespace
402 452
403 453
404 // static 454 // static
405 std::ostream& Bytecodes::Decode(std::ostream& os, const uint8_t* bytecode_start, 455 std::ostream& Bytecodes::Decode(std::ostream& os, const uint8_t* bytecode_start,
406 int parameter_count) { 456 int parameter_count) {
407 Vector<char> buf = Vector<char>::New(50); 457 Vector<char> buf = Vector<char>::New(50);
408 458
409 Bytecode bytecode = Bytecodes::FromByte(bytecode_start[0]); 459 Bytecode bytecode = Bytecodes::FromByte(bytecode_start[0]);
410 int bytecode_size = Bytecodes::Size(bytecode); 460 int prefix_offset = 0;
461 int operand_scale = Bytecodes::GetPrefixBytecodeScale(bytecode);
462 if (operand_scale > 1) {
463 prefix_offset += 1;
464 bytecode = Bytecodes::FromByte(bytecode_start[1]);
465 }
411 466
412 for (int i = 0; i < bytecode_size; i++) { 467 int bytecode_size = Bytecodes::Size(bytecode, operand_scale);
468
469 for (int i = 0; i < prefix_offset + bytecode_size; i++) {
413 SNPrintF(buf, "%02x ", bytecode_start[i]); 470 SNPrintF(buf, "%02x ", bytecode_start[i]);
414 os << buf.start(); 471 os << buf.start();
415 } 472 }
416 const int kBytecodeColumnSize = 6; 473 const int kBytecodeColumnSize = 6;
417 for (int i = bytecode_size; i < kBytecodeColumnSize; i++) { 474 for (int i = prefix_offset + bytecode_size; i < kBytecodeColumnSize; i++) {
418 os << " "; 475 os << " ";
419 } 476 }
420 477
421 os << bytecode << " "; 478 os << bytecode;
479 if (operand_scale == 2) {
480 os << "." << Bytecodes::ToString(Bytecode::kWide);
481 } else if (operand_scale == 4) {
482 os << "." << Bytecodes::ToString(Bytecode::kExtraWide);
483 }
484 os << " ";
422 485
423 // Operands for the debug break are from the original instruction. 486 // Operands for the debug break are from the original instruction.
424 if (IsDebugBreak(bytecode)) return os; 487 if (IsDebugBreak(bytecode)) return os;
425 488
426 int number_of_operands = NumberOfOperands(bytecode); 489 int number_of_operands = NumberOfOperands(bytecode);
427 int range = 0; 490 int range = 0;
428 for (int i = 0; i < number_of_operands; i++) { 491 for (int i = 0; i < number_of_operands; i++) {
429 OperandType op_type = GetOperandType(bytecode, i); 492 OperandType op_type = GetOperandType(bytecode, i);
430 const uint8_t* operand_start = 493 const uint8_t* operand_start =
431 &bytecode_start[GetOperandOffset(bytecode, i)]; 494 &bytecode_start[prefix_offset +
495 GetOperandOffset(bytecode, i, operand_scale)];
432 switch (op_type) { 496 switch (op_type) {
433 case interpreter::OperandType::kRegCount8: 497 case interpreter::OperandType::kRegCount:
434 os << "#" << static_cast<unsigned int>(*operand_start); 498 os << "#"
499 << DecodeUnsignedOperand(operand_start, op_type, operand_scale);
435 break; 500 break;
436 case interpreter::OperandType::kRegCount16: 501 case interpreter::OperandType::kIdx:
437 os << '#' << ReadUnalignedUInt16(operand_start); 502 case interpreter::OperandType::kRuntimeId:
503 os << "["
504 << DecodeUnsignedOperand(operand_start, op_type, operand_scale)
505 << "]";
438 break; 506 break;
439 case interpreter::OperandType::kIdx8: 507 case interpreter::OperandType::kImm:
440 os << "[" << static_cast<unsigned int>(*operand_start) << "]"; 508 os << "[" << DecodeSignedOperand(operand_start, op_type, operand_scale)
509 << "]";
441 break; 510 break;
442 case interpreter::OperandType::kIdx16: 511 case interpreter::OperandType::kFlag8:
443 os << "[" << ReadUnalignedUInt16(operand_start) << "]"; 512 os << "#"
513 << DecodeUnsignedOperand(operand_start, op_type, operand_scale);
444 break; 514 break;
445 case interpreter::OperandType::kImm8: 515 case interpreter::OperandType::kMaybeReg:
446 os << "#" << static_cast<int>(static_cast<int8_t>(*operand_start)); 516 case interpreter::OperandType::kReg:
447 break; 517 case interpreter::OperandType::kRegOut: {
448 case interpreter::OperandType::kMaybeReg8: 518 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); 519 os << reg.ToString(parameter_count);
456 break; 520 break;
457 } 521 }
458 case interpreter::OperandType::kRegOutTriple8: 522 case interpreter::OperandType::kRegOutTriple:
459 case interpreter::OperandType::kRegOutTriple16:
460 range += 1; 523 range += 1;
461 case interpreter::OperandType::kRegOutPair8: 524 case interpreter::OperandType::kRegOutPair:
462 case interpreter::OperandType::kRegOutPair16: 525 case interpreter::OperandType::kRegPair: {
463 case interpreter::OperandType::kRegPair8:
464 case interpreter::OperandType::kRegPair16: {
465 range += 1; 526 range += 1;
466 Register first_reg = DecodeRegister(operand_start, op_type); 527 Register first_reg =
528 DecodeRegister(operand_start, op_type, operand_scale);
467 Register last_reg = Register(first_reg.index() + range); 529 Register last_reg = Register(first_reg.index() + range);
468 os << first_reg.ToString(parameter_count) << "-" 530 os << first_reg.ToString(parameter_count) << "-"
469 << last_reg.ToString(parameter_count); 531 << last_reg.ToString(parameter_count);
470 break; 532 break;
471 } 533 }
472 case interpreter::OperandType::kNone: 534 case interpreter::OperandType::kNone:
473 UNREACHABLE(); 535 UNREACHABLE();
474 break; 536 break;
475 } 537 }
476 if (i != number_of_operands - 1) { 538 if (i != number_of_operands - 1) {
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
639 } else { 701 } else {
640 std::ostringstream s; 702 std::ostringstream s;
641 s << "r" << index(); 703 s << "r" << index();
642 return s.str(); 704 return s.str();
643 } 705 }
644 } 706 }
645 707
646 } // namespace interpreter 708 } // namespace interpreter
647 } // namespace internal 709 } // namespace internal
648 } // namespace v8 710 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698