| 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; |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 336 bool Bytecodes::IsJumpConstant(Bytecode bytecode) { | 390 bool Bytecodes::IsJumpConstant(Bytecode bytecode) { |
| 337 return bytecode == Bytecode::kJumpConstant || | 391 return bytecode == Bytecode::kJumpConstant || |
| 338 IsConditionalJumpConstant(bytecode); | 392 IsConditionalJumpConstant(bytecode); |
| 339 } | 393 } |
| 340 | 394 |
| 341 // static | 395 // static |
| 342 bool Bytecodes::IsJump(Bytecode bytecode) { | 396 bool Bytecodes::IsJump(Bytecode bytecode) { |
| 343 return IsJumpImmediate(bytecode) || IsJumpConstant(bytecode); | 397 return IsJumpImmediate(bytecode) || IsJumpConstant(bytecode); |
| 344 } | 398 } |
| 345 | 399 |
| 400 // static |
| 401 bool Bytecodes::IsJumpIfToBoolean(Bytecode bytecode) { |
| 402 return bytecode == Bytecode::kJumpIfToBooleanTrue || |
| 403 bytecode == Bytecode::kJumpIfToBooleanFalse || |
| 404 bytecode == Bytecode::kJumpIfToBooleanTrueConstant || |
| 405 bytecode == Bytecode::kJumpIfToBooleanFalseConstant; |
| 406 } |
| 407 |
| 408 // static |
| 409 Bytecode Bytecodes::GetJumpWithoutToBoolean(Bytecode bytecode) { |
| 410 switch (bytecode) { |
| 411 case Bytecode::kJumpIfToBooleanTrue: |
| 412 return Bytecode::kJumpIfTrue; |
| 413 case Bytecode::kJumpIfToBooleanFalse: |
| 414 return Bytecode::kJumpIfFalse; |
| 415 case Bytecode::kJumpIfToBooleanTrueConstant: |
| 416 return Bytecode::kJumpIfTrueConstant; |
| 417 case Bytecode::kJumpIfToBooleanFalseConstant: |
| 418 return Bytecode::kJumpIfFalseConstant; |
| 419 default: |
| 420 UNREACHABLE(); |
| 421 } |
| 422 } |
| 346 | 423 |
| 347 // static | 424 // static |
| 348 bool Bytecodes::IsCallOrNew(Bytecode bytecode) { | 425 bool Bytecodes::IsCallOrNew(Bytecode bytecode) { |
| 349 return bytecode == Bytecode::kCall || bytecode == Bytecode::kTailCall || | 426 return bytecode == Bytecode::kCall || bytecode == Bytecode::kTailCall || |
| 350 bytecode == Bytecode::kNew; | 427 bytecode == Bytecode::kNew; |
| 351 } | 428 } |
| 352 | 429 |
| 353 // static | 430 // static |
| 354 bool Bytecodes::IsCallRuntime(Bytecode bytecode) { | 431 bool Bytecodes::IsCallRuntime(Bytecode bytecode) { |
| 355 return bytecode == Bytecode::kCallRuntime || | 432 return bytecode == Bytecode::kCallRuntime || |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 454 case OperandType::k##Name: \ | 531 case OperandType::k##Name: \ |
| 455 break; | 532 break; |
| 456 NON_REGISTER_OPERAND_TYPE_LIST(CASE) | 533 NON_REGISTER_OPERAND_TYPE_LIST(CASE) |
| 457 REGISTER_INPUT_OPERAND_TYPE_LIST(CASE) | 534 REGISTER_INPUT_OPERAND_TYPE_LIST(CASE) |
| 458 #undef CASE | 535 #undef CASE |
| 459 } | 536 } |
| 460 return false; | 537 return false; |
| 461 } | 538 } |
| 462 | 539 |
| 463 // static | 540 // static |
| 541 int Bytecodes::GetNumberOfRegistersRepresentedBy(OperandType operand_type) { |
| 542 switch (operand_type) { |
| 543 case OperandType::kMaybeReg: |
| 544 case OperandType::kReg: |
| 545 case OperandType::kRegOut: |
| 546 return 1; |
| 547 case OperandType::kRegPair: |
| 548 case OperandType::kRegOutPair: |
| 549 return 2; |
| 550 case OperandType::kRegOutTriple: |
| 551 return 3; |
| 552 default: |
| 553 UNREACHABLE(); |
| 554 } |
| 555 return 0; |
| 556 } |
| 557 |
| 558 // static |
| 464 bool Bytecodes::IsUnsignedOperandType(OperandType operand_type) { | 559 bool Bytecodes::IsUnsignedOperandType(OperandType operand_type) { |
| 465 switch (operand_type) { | 560 switch (operand_type) { |
| 466 #define CASE(Name, _) \ | 561 #define CASE(Name, _) \ |
| 467 case OperandType::k##Name: \ | 562 case OperandType::k##Name: \ |
| 468 return OperandTraits<OperandType::k##Name>::TypeInfo::kIsUnsigned; | 563 return OperandTraits<OperandType::k##Name>::TypeInfo::kIsUnsigned; |
| 469 OPERAND_TYPE_LIST(CASE) | 564 OPERAND_TYPE_LIST(CASE) |
| 470 #undef CASE | 565 #undef CASE |
| 471 } | 566 } |
| 472 UNREACHABLE(); | 567 UNREACHABLE(); |
| 473 return false; | 568 return false; |
| 474 } | 569 } |
| 475 | 570 |
| 476 // static | 571 // static |
| 477 OperandScale Bytecodes::NextOperandScale(OperandScale operand_scale) { | 572 OperandSize Bytecodes::SizeForSignedOperand(int value) { |
| 478 DCHECK(operand_scale >= OperandScale::kSingle && | 573 if (kMinInt8 <= value && value <= kMaxInt8) { |
| 479 operand_scale <= OperandScale::kMaxValid); | 574 return OperandSize::kByte; |
| 480 return static_cast<OperandScale>(2 * static_cast<int>(operand_scale)); | 575 } else if (kMinInt16 <= value && value <= kMaxInt16) { |
| 576 return OperandSize::kShort; |
| 577 } else { |
| 578 return OperandSize::kQuad; |
| 579 } |
| 481 } | 580 } |
| 482 | 581 |
| 483 // static | 582 // static |
| 583 OperandSize Bytecodes::SizeForUnsignedOperand(int value) { |
| 584 DCHECK_GE(value, 0); |
| 585 if (value <= kMaxUInt8) { |
| 586 return OperandSize::kByte; |
| 587 } else if (value <= kMaxUInt16) { |
| 588 return OperandSize::kShort; |
| 589 } else { |
| 590 return OperandSize::kQuad; |
| 591 } |
| 592 } |
| 593 |
| 594 OperandSize Bytecodes::SizeForUnsignedOperand(size_t value) { |
| 595 if (value <= static_cast<size_t>(kMaxUInt8)) { |
| 596 return OperandSize::kByte; |
| 597 } else if (value <= static_cast<size_t>(kMaxUInt16)) { |
| 598 return OperandSize::kShort; |
| 599 } else if (value <= kMaxUInt32) { |
| 600 return OperandSize::kQuad; |
| 601 } else { |
| 602 UNREACHABLE(); |
| 603 return OperandSize::kQuad; |
| 604 } |
| 605 } |
| 606 |
| 607 OperandScale Bytecodes::OperandSizesToScale(OperandSize size0, |
| 608 OperandSize size1, |
| 609 OperandSize size2, |
| 610 OperandSize size3) { |
| 611 OperandSize upper = std::max(size0, size1); |
| 612 OperandSize lower = std::max(size2, size3); |
| 613 OperandSize result = std::max(upper, lower); |
| 614 // Operand sizes have been scaled before calling this function. |
| 615 // Currently all scalable operands are byte sized at |
| 616 // OperandScale::kSingle. |
| 617 STATIC_ASSERT(static_cast<int>(OperandSize::kByte) == |
| 618 static_cast<int>(OperandScale::kSingle) && |
| 619 static_cast<int>(OperandSize::kShort) == |
| 620 static_cast<int>(OperandScale::kDouble) && |
| 621 static_cast<int>(OperandSize::kQuad) == |
| 622 static_cast<int>(OperandScale::kQuadruple)); |
| 623 OperandScale operand_scale = static_cast<OperandScale>(result); |
| 624 DCHECK(operand_scale == OperandScale::kSingle || |
| 625 operand_scale == OperandScale::kDouble || |
| 626 operand_scale == OperandScale::kQuadruple); |
| 627 return operand_scale; |
| 628 } |
| 629 |
| 630 // static |
| 484 Register Bytecodes::DecodeRegisterOperand(const uint8_t* operand_start, | 631 Register Bytecodes::DecodeRegisterOperand(const uint8_t* operand_start, |
| 485 OperandType operand_type, | 632 OperandType operand_type, |
| 486 OperandScale operand_scale) { | 633 OperandScale operand_scale) { |
| 487 DCHECK(Bytecodes::IsRegisterOperandType(operand_type)); | 634 DCHECK(Bytecodes::IsRegisterOperandType(operand_type)); |
| 488 int32_t operand = | 635 int32_t operand = |
| 489 DecodeSignedOperand(operand_start, operand_type, operand_scale); | 636 DecodeSignedOperand(operand_start, operand_type, operand_scale); |
| 490 return Register::FromOperand(operand); | 637 return Register::FromOperand(operand); |
| 491 } | 638 } |
| 492 | 639 |
| 493 // static | 640 // static |
| (...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 767 } else { | 914 } else { |
| 768 std::ostringstream s; | 915 std::ostringstream s; |
| 769 s << "r" << index(); | 916 s << "r" << index(); |
| 770 return s.str(); | 917 return s.str(); |
| 771 } | 918 } |
| 772 } | 919 } |
| 773 | 920 |
| 774 } // namespace interpreter | 921 } // namespace interpreter |
| 775 } // namespace internal | 922 } // namespace internal |
| 776 } // namespace v8 | 923 } // namespace v8 |
| OLD | NEW |