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

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

Powered by Google App Engine
This is Rietveld 408576698