| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/interpreter/bytecodes.h" | 5 #include "src/interpreter/bytecodes.h" |
| 6 | 6 |
| 7 #include <iomanip> | 7 #include <iomanip> |
| 8 | 8 |
| 9 #include "src/frames.h" | 9 #include "src/frames.h" |
| 10 #include "src/interpreter/bytecode-traits.h" | 10 #include "src/interpreter/bytecode-traits.h" |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 67 OPERAND_TYPE_LIST(CASE) | 67 OPERAND_TYPE_LIST(CASE) |
| 68 #undef CASE | 68 #undef CASE |
| 69 } | 69 } |
| 70 UNREACHABLE(); | 70 UNREACHABLE(); |
| 71 return ""; | 71 return ""; |
| 72 } | 72 } |
| 73 | 73 |
| 74 // static | 74 // static |
| 75 const char* Bytecodes::OperandScaleToString(OperandScale operand_scale) { | 75 const char* Bytecodes::OperandScaleToString(OperandScale operand_scale) { |
| 76 switch (operand_scale) { | 76 switch (operand_scale) { |
| 77 case OperandScale::kSingle: | 77 #define CASE(Name, _) \ |
| 78 return "Single"; | 78 case OperandScale::k##Name: \ |
| 79 case OperandScale::kDouble: | 79 return #Name; |
| 80 return "Double"; | 80 OPERAND_SCALE_LIST(CASE) |
| 81 case OperandScale::kQuadruple: | 81 #undef CASE |
| 82 return "Quadruple"; | |
| 83 case OperandScale::kInvalid: | |
| 84 UNREACHABLE(); | |
| 85 } | 82 } |
| 83 UNREACHABLE(); |
| 86 return ""; | 84 return ""; |
| 87 } | 85 } |
| 88 | 86 |
| 89 // static | 87 // static |
| 90 const char* Bytecodes::OperandSizeToString(OperandSize operand_size) { | 88 const char* Bytecodes::OperandSizeToString(OperandSize operand_size) { |
| 91 switch (operand_size) { | 89 switch (operand_size) { |
| 92 case OperandSize::kNone: | 90 case OperandSize::kNone: |
| 93 return "None"; | 91 return "None"; |
| 94 case OperandSize::kByte: | 92 case OperandSize::kByte: |
| 95 return "Byte"; | 93 return "Byte"; |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 234 AccumulatorUse::kRead; | 232 AccumulatorUse::kRead; |
| 235 } | 233 } |
| 236 | 234 |
| 237 // static | 235 // static |
| 238 bool Bytecodes::WritesAccumulator(Bytecode bytecode) { | 236 bool Bytecodes::WritesAccumulator(Bytecode bytecode) { |
| 239 return (GetAccumulatorUse(bytecode) & AccumulatorUse::kWrite) == | 237 return (GetAccumulatorUse(bytecode) & AccumulatorUse::kWrite) == |
| 240 AccumulatorUse::kWrite; | 238 AccumulatorUse::kWrite; |
| 241 } | 239 } |
| 242 | 240 |
| 243 // static | 241 // static |
| 242 bool Bytecodes::WritesAccumulatorWithBoolean(Bytecode bytecode) { |
| 243 switch (bytecode) { |
| 244 case Bytecode::kLdaTrue: |
| 245 case Bytecode::kLdaFalse: |
| 246 case Bytecode::kLogicalNot: |
| 247 case Bytecode::kTestEqual: |
| 248 case Bytecode::kTestNotEqual: |
| 249 case Bytecode::kTestEqualStrict: |
| 250 case Bytecode::kTestLessThan: |
| 251 case Bytecode::kTestLessThanOrEqual: |
| 252 case Bytecode::kTestGreaterThan: |
| 253 case Bytecode::kTestGreaterThanOrEqual: |
| 254 case Bytecode::kTestInstanceOf: |
| 255 case Bytecode::kTestIn: |
| 256 case Bytecode::kForInDone: |
| 257 return true; |
| 258 default: |
| 259 return false; |
| 260 } |
| 261 } |
| 262 |
| 263 // static |
| 264 bool Bytecodes::IsAccumulatorLoadWithoutEffects(Bytecode bytecode) { |
| 265 switch (bytecode) { |
| 266 case Bytecode::kLdaZero: |
| 267 case Bytecode::kLdaSmi: |
| 268 case Bytecode::kLdaUndefined: |
| 269 case Bytecode::kLdaNull: |
| 270 case Bytecode::kLdaTheHole: |
| 271 case Bytecode::kLdaTrue: |
| 272 case Bytecode::kLdaFalse: |
| 273 case Bytecode::kLdaConstant: |
| 274 case Bytecode::kLdar: |
| 275 return true; |
| 276 default: |
| 277 return false; |
| 278 } |
| 279 } |
| 280 |
| 281 // static |
| 244 OperandType Bytecodes::GetOperandType(Bytecode bytecode, int i) { | 282 OperandType Bytecodes::GetOperandType(Bytecode bytecode, int i) { |
| 283 DCHECK_LE(bytecode, Bytecode::kLast); |
| 284 DCHECK_LT(i, NumberOfOperands(bytecode)); |
| 285 DCHECK_GE(i, 0); |
| 286 return GetOperandTypes(bytecode)[i]; |
| 287 } |
| 288 |
| 289 // static |
| 290 const OperandType* Bytecodes::GetOperandTypes(Bytecode bytecode) { |
| 245 DCHECK(bytecode <= Bytecode::kLast); | 291 DCHECK(bytecode <= Bytecode::kLast); |
| 246 switch (bytecode) { | 292 switch (bytecode) { |
| 247 #define CASE(Name, ...) \ | 293 #define CASE(Name, ...) \ |
| 248 case Bytecode::k##Name: \ | 294 case Bytecode::k##Name: \ |
| 249 return BytecodeTraits<__VA_ARGS__>::GetOperandType(i); | 295 return BytecodeTraits<__VA_ARGS__>::GetOperandTypes(); |
| 250 BYTECODE_LIST(CASE) | 296 BYTECODE_LIST(CASE) |
| 251 #undef CASE | 297 #undef CASE |
| 252 } | 298 } |
| 253 UNREACHABLE(); | 299 UNREACHABLE(); |
| 254 return OperandType::kNone; | 300 return nullptr; |
| 255 } | 301 } |
| 256 | 302 |
| 257 // static | 303 // static |
| 258 OperandSize Bytecodes::GetOperandSize(Bytecode bytecode, int i, | 304 OperandSize Bytecodes::GetOperandSize(Bytecode bytecode, int i, |
| 259 OperandScale operand_scale) { | 305 OperandScale operand_scale) { |
| 260 OperandType op_type = GetOperandType(bytecode, i); | 306 DCHECK(bytecode <= Bytecode::kLast); |
| 261 return ScaledOperandSize(op_type, operand_scale); | 307 switch (bytecode) { |
| 308 #define CASE(Name, ...) \ |
| 309 case Bytecode::k##Name: \ |
| 310 return BytecodeTraits<__VA_ARGS__>::GetOperandSize(i, operand_scale); |
| 311 BYTECODE_LIST(CASE) |
| 312 #undef CASE |
| 313 } |
| 314 UNREACHABLE(); |
| 315 return OperandSize::kNone; |
| 262 } | 316 } |
| 263 | 317 |
| 264 // static | 318 // static |
| 265 int Bytecodes::GetRegisterOperandBitmap(Bytecode bytecode) { | 319 int Bytecodes::GetRegisterOperandBitmap(Bytecode bytecode) { |
| 266 DCHECK(bytecode <= Bytecode::kLast); | 320 DCHECK(bytecode <= Bytecode::kLast); |
| 267 switch (bytecode) { | 321 switch (bytecode) { |
| 268 #define CASE(Name, ...) \ | 322 #define CASE(Name, ...) \ |
| 269 case Bytecode::k##Name: \ | 323 case Bytecode::k##Name: \ |
| 270 typedef BytecodeTraits<__VA_ARGS__> Name##Trait; \ | 324 typedef BytecodeTraits<__VA_ARGS__> Name##Trait; \ |
| 271 return Name##Trait::kRegisterOperandBitmap; | 325 return Name##Trait::kRegisterOperandBitmap; |
| 272 BYTECODE_LIST(CASE) | 326 BYTECODE_LIST(CASE) |
| 273 #undef CASE | 327 #undef CASE |
| 274 } | 328 } |
| 275 UNREACHABLE(); | 329 UNREACHABLE(); |
| 276 return false; | 330 return false; |
| 277 } | 331 } |
| 278 | 332 |
| 279 // static | 333 // static |
| 280 int Bytecodes::GetOperandOffset(Bytecode bytecode, int i, | 334 int Bytecodes::GetOperandOffset(Bytecode bytecode, int i, |
| 281 OperandScale operand_scale) { | 335 OperandScale operand_scale) { |
| 336 DCHECK_LT(i, Bytecodes::NumberOfOperands(bytecode)); |
| 282 // TODO(oth): restore this to a statically determined constant. | 337 // TODO(oth): restore this to a statically determined constant. |
| 283 int offset = 1; | 338 int offset = 1; |
| 284 for (int operand_index = 0; operand_index < i; ++operand_index) { | 339 for (int operand_index = 0; operand_index < i; ++operand_index) { |
| 285 OperandSize operand_size = | 340 OperandSize operand_size = |
| 286 GetOperandSize(bytecode, operand_index, operand_scale); | 341 GetOperandSize(bytecode, operand_index, operand_scale); |
| 287 offset += static_cast<int>(operand_size); | 342 offset += static_cast<int>(operand_size); |
| 288 } | 343 } |
| 289 return offset; | 344 return offset; |
| 290 } | 345 } |
| 291 | 346 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 336 bool Bytecodes::IsJumpConstant(Bytecode bytecode) { | 391 bool Bytecodes::IsJumpConstant(Bytecode bytecode) { |
| 337 return bytecode == Bytecode::kJumpConstant || | 392 return bytecode == Bytecode::kJumpConstant || |
| 338 IsConditionalJumpConstant(bytecode); | 393 IsConditionalJumpConstant(bytecode); |
| 339 } | 394 } |
| 340 | 395 |
| 341 // static | 396 // static |
| 342 bool Bytecodes::IsJump(Bytecode bytecode) { | 397 bool Bytecodes::IsJump(Bytecode bytecode) { |
| 343 return IsJumpImmediate(bytecode) || IsJumpConstant(bytecode); | 398 return IsJumpImmediate(bytecode) || IsJumpConstant(bytecode); |
| 344 } | 399 } |
| 345 | 400 |
| 401 // static |
| 402 bool Bytecodes::IsJumpIfToBoolean(Bytecode bytecode) { |
| 403 return bytecode == Bytecode::kJumpIfToBooleanTrue || |
| 404 bytecode == Bytecode::kJumpIfToBooleanFalse || |
| 405 bytecode == Bytecode::kJumpIfToBooleanTrueConstant || |
| 406 bytecode == Bytecode::kJumpIfToBooleanFalseConstant; |
| 407 } |
| 408 |
| 409 // static |
| 410 Bytecode Bytecodes::GetJumpWithoutToBoolean(Bytecode bytecode) { |
| 411 switch (bytecode) { |
| 412 case Bytecode::kJumpIfToBooleanTrue: |
| 413 return Bytecode::kJumpIfTrue; |
| 414 case Bytecode::kJumpIfToBooleanFalse: |
| 415 return Bytecode::kJumpIfFalse; |
| 416 case Bytecode::kJumpIfToBooleanTrueConstant: |
| 417 return Bytecode::kJumpIfTrueConstant; |
| 418 case Bytecode::kJumpIfToBooleanFalseConstant: |
| 419 return Bytecode::kJumpIfFalseConstant; |
| 420 default: |
| 421 break; |
| 422 } |
| 423 UNREACHABLE(); |
| 424 return Bytecode::kIllegal; |
| 425 } |
| 346 | 426 |
| 347 // static | 427 // static |
| 348 bool Bytecodes::IsCallOrNew(Bytecode bytecode) { | 428 bool Bytecodes::IsCallOrNew(Bytecode bytecode) { |
| 349 return bytecode == Bytecode::kCall || bytecode == Bytecode::kTailCall || | 429 return bytecode == Bytecode::kCall || bytecode == Bytecode::kTailCall || |
| 350 bytecode == Bytecode::kNew; | 430 bytecode == Bytecode::kNew; |
| 351 } | 431 } |
| 352 | 432 |
| 353 // static | 433 // static |
| 354 bool Bytecodes::IsCallRuntime(Bytecode bytecode) { | 434 bool Bytecodes::IsCallRuntime(Bytecode bytecode) { |
| 355 return bytecode == Bytecode::kCallRuntime || | 435 return bytecode == Bytecode::kCallRuntime || |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 454 case OperandType::k##Name: \ | 534 case OperandType::k##Name: \ |
| 455 break; | 535 break; |
| 456 NON_REGISTER_OPERAND_TYPE_LIST(CASE) | 536 NON_REGISTER_OPERAND_TYPE_LIST(CASE) |
| 457 REGISTER_INPUT_OPERAND_TYPE_LIST(CASE) | 537 REGISTER_INPUT_OPERAND_TYPE_LIST(CASE) |
| 458 #undef CASE | 538 #undef CASE |
| 459 } | 539 } |
| 460 return false; | 540 return false; |
| 461 } | 541 } |
| 462 | 542 |
| 463 // static | 543 // static |
| 544 int Bytecodes::GetNumberOfRegistersRepresentedBy(OperandType operand_type) { |
| 545 switch (operand_type) { |
| 546 case OperandType::kMaybeReg: |
| 547 case OperandType::kReg: |
| 548 case OperandType::kRegOut: |
| 549 return 1; |
| 550 case OperandType::kRegPair: |
| 551 case OperandType::kRegOutPair: |
| 552 return 2; |
| 553 case OperandType::kRegOutTriple: |
| 554 return 3; |
| 555 default: |
| 556 UNREACHABLE(); |
| 557 } |
| 558 return 0; |
| 559 } |
| 560 |
| 561 // static |
| 464 bool Bytecodes::IsUnsignedOperandType(OperandType operand_type) { | 562 bool Bytecodes::IsUnsignedOperandType(OperandType operand_type) { |
| 465 switch (operand_type) { | 563 switch (operand_type) { |
| 466 #define CASE(Name, _) \ | 564 #define CASE(Name, _) \ |
| 467 case OperandType::k##Name: \ | 565 case OperandType::k##Name: \ |
| 468 return OperandTraits<OperandType::k##Name>::TypeInfo::kIsUnsigned; | 566 return OperandTraits<OperandType::k##Name>::TypeInfo::kIsUnsigned; |
| 469 OPERAND_TYPE_LIST(CASE) | 567 OPERAND_TYPE_LIST(CASE) |
| 470 #undef CASE | 568 #undef CASE |
| 471 } | 569 } |
| 472 UNREACHABLE(); | 570 UNREACHABLE(); |
| 473 return false; | 571 return false; |
| 474 } | 572 } |
| 475 | 573 |
| 476 // static | 574 // static |
| 477 OperandScale Bytecodes::NextOperandScale(OperandScale operand_scale) { | 575 OperandSize Bytecodes::SizeForSignedOperand(int value) { |
| 478 DCHECK(operand_scale >= OperandScale::kSingle && | 576 if (kMinInt8 <= value && value <= kMaxInt8) { |
| 479 operand_scale <= OperandScale::kMaxValid); | 577 return OperandSize::kByte; |
| 480 return static_cast<OperandScale>(2 * static_cast<int>(operand_scale)); | 578 } else if (kMinInt16 <= value && value <= kMaxInt16) { |
| 579 return OperandSize::kShort; |
| 580 } else { |
| 581 return OperandSize::kQuad; |
| 582 } |
| 481 } | 583 } |
| 482 | 584 |
| 483 // static | 585 // static |
| 586 OperandSize Bytecodes::SizeForUnsignedOperand(int value) { |
| 587 DCHECK_GE(value, 0); |
| 588 if (value <= kMaxUInt8) { |
| 589 return OperandSize::kByte; |
| 590 } else if (value <= kMaxUInt16) { |
| 591 return OperandSize::kShort; |
| 592 } else { |
| 593 return OperandSize::kQuad; |
| 594 } |
| 595 } |
| 596 |
| 597 OperandSize Bytecodes::SizeForUnsignedOperand(size_t value) { |
| 598 if (value <= static_cast<size_t>(kMaxUInt8)) { |
| 599 return OperandSize::kByte; |
| 600 } else if (value <= static_cast<size_t>(kMaxUInt16)) { |
| 601 return OperandSize::kShort; |
| 602 } else if (value <= kMaxUInt32) { |
| 603 return OperandSize::kQuad; |
| 604 } else { |
| 605 UNREACHABLE(); |
| 606 return OperandSize::kQuad; |
| 607 } |
| 608 } |
| 609 |
| 610 OperandScale Bytecodes::OperandSizesToScale(OperandSize size0, |
| 611 OperandSize size1, |
| 612 OperandSize size2, |
| 613 OperandSize size3) { |
| 614 OperandSize upper = std::max(size0, size1); |
| 615 OperandSize lower = std::max(size2, size3); |
| 616 OperandSize result = std::max(upper, lower); |
| 617 // Operand sizes have been scaled before calling this function. |
| 618 // Currently all scalable operands are byte sized at |
| 619 // OperandScale::kSingle. |
| 620 STATIC_ASSERT(static_cast<int>(OperandSize::kByte) == |
| 621 static_cast<int>(OperandScale::kSingle) && |
| 622 static_cast<int>(OperandSize::kShort) == |
| 623 static_cast<int>(OperandScale::kDouble) && |
| 624 static_cast<int>(OperandSize::kQuad) == |
| 625 static_cast<int>(OperandScale::kQuadruple)); |
| 626 OperandScale operand_scale = static_cast<OperandScale>(result); |
| 627 DCHECK(operand_scale == OperandScale::kSingle || |
| 628 operand_scale == OperandScale::kDouble || |
| 629 operand_scale == OperandScale::kQuadruple); |
| 630 return operand_scale; |
| 631 } |
| 632 |
| 633 // static |
| 484 Register Bytecodes::DecodeRegisterOperand(const uint8_t* operand_start, | 634 Register Bytecodes::DecodeRegisterOperand(const uint8_t* operand_start, |
| 485 OperandType operand_type, | 635 OperandType operand_type, |
| 486 OperandScale operand_scale) { | 636 OperandScale operand_scale) { |
| 487 DCHECK(Bytecodes::IsRegisterOperandType(operand_type)); | 637 DCHECK(Bytecodes::IsRegisterOperandType(operand_type)); |
| 488 int32_t operand = | 638 int32_t operand = |
| 489 DecodeSignedOperand(operand_start, operand_type, operand_scale); | 639 DecodeSignedOperand(operand_start, operand_type, operand_scale); |
| 490 return Register::FromOperand(operand); | 640 return Register::FromOperand(operand); |
| 491 } | 641 } |
| 492 | 642 |
| 493 // static | 643 // static |
| (...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 767 } else { | 917 } else { |
| 768 std::ostringstream s; | 918 std::ostringstream s; |
| 769 s << "r" << index(); | 919 s << "r" << index(); |
| 770 return s.str(); | 920 return s.str(); |
| 771 } | 921 } |
| 772 } | 922 } |
| 773 | 923 |
| 774 } // namespace interpreter | 924 } // namespace interpreter |
| 775 } // namespace internal | 925 } // namespace internal |
| 776 } // namespace v8 | 926 } // namespace v8 |
| OLD | NEW |