Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2016, the Dartino project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dartino project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE.md file. | 3 // BSD-style license that can be found in the LICENSE.md file. |
| 4 | 4 |
| 5 #if defined(DARTINO_TARGET_MIPS) | 5 #if defined(DARTINO_TARGET_MIPS) |
| 6 | 6 |
| 7 #include "src/shared/bytecodes.h" | 7 #include "src/shared/bytecodes.h" |
| 8 #include "src/shared/names.h" | 8 #include "src/shared/names.h" |
| 9 #include "src/shared/selectors.h" | 9 #include "src/shared/selectors.h" |
| 10 | 10 |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 85 #undef V | 85 #undef V |
| 86 } | 86 } |
| 87 | 87 |
| 88 class InterpreterGeneratorMIPS: public InterpreterGenerator { | 88 class InterpreterGeneratorMIPS: public InterpreterGenerator { |
| 89 public: | 89 public: |
| 90 explicit InterpreterGeneratorMIPS(Assembler* assembler) | 90 explicit InterpreterGeneratorMIPS(Assembler* assembler) |
| 91 : InterpreterGenerator(assembler) { } | 91 : InterpreterGenerator(assembler) { } |
| 92 | 92 |
| 93 // Registers | 93 // Registers |
| 94 // --------- | 94 // --------- |
| 95 // s0: current process | 95 // S0: current process |
| 96 // s1: bytecode pointer | 96 // S1: bytecode pointer |
| 97 // s2: stack pointer | 97 // S2: stack pointer (top) |
| 98 // s4: null | 98 // S4: null |
| 99 // s6: true | 99 // S6: program |
| 100 // s7: false | 100 // S7: dispatch table |
| 101 | |
| 102 virtual void GeneratePrologue(); | 101 virtual void GeneratePrologue(); |
| 103 virtual void GenerateEpilogue(); | 102 virtual void GenerateEpilogue(); |
| 104 | 103 |
| 105 virtual void GenerateMethodEntry(); | 104 virtual void GenerateMethodEntry(); |
| 106 | 105 |
| 107 virtual void GenerateBytecodePrologue(const char* name); | 106 virtual void GenerateBytecodePrologue(const char* name); |
| 108 virtual void GenerateDebugAtBytecode(); | 107 virtual void GenerateDebugAtBytecode(); |
| 109 | 108 |
| 110 virtual void DoLoadLocal0(); | 109 virtual void DoLoadLocal0(); |
| 111 virtual void DoLoadLocal1(); | 110 virtual void DoLoadLocal1(); |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 238 Label done_; | 237 Label done_; |
| 239 Label done_state_saved_; | 238 Label done_state_saved_; |
| 240 Label check_stack_overflow_; | 239 Label check_stack_overflow_; |
| 241 Label check_stack_overflow_0_; | 240 Label check_stack_overflow_0_; |
| 242 Label gc_; | 241 Label gc_; |
| 243 Label intrinsic_failure_; | 242 Label intrinsic_failure_; |
| 244 Label interpreter_entry_; | 243 Label interpreter_entry_; |
| 245 int spill_size_; | 244 int spill_size_; |
| 246 // Used in GeneratePrologue/Epilogue, S0-S7 + RA + FP. | 245 // Used in GeneratePrologue/Epilogue, S0-S7 + RA + FP. |
| 247 static const int kSaveFrameSize = 10; | 246 static const int kSaveFrameSize = 10; |
| 247 static const int kFalseOffset = 8; | |
| 248 static const int kTrueOffset = 16; | |
| 248 | 249 |
| 249 void LoadLocal(Register reg, int index); | 250 void LoadLocal(Register reg, int index); |
| 250 void StoreLocal(Register reg, int index); | 251 void StoreLocal(Register reg, int index); |
| 251 | 252 |
| 252 void Push(Register reg); | 253 void Push(Register reg); |
| 253 void Pop(Register reg); | 254 void Pop(Register reg); |
| 254 void Drop(int n); | 255 void Drop(int n); |
| 255 void Drop(Register reg); | 256 void Drop(Register reg); |
| 256 void DropNAndSetTop(int dropping_slots, Register reg); | 257 void DropNAndSetTop(int dropping_slots, Register reg); |
| 257 | 258 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 290 void InvokeBitXor(const char* fallback); | 291 void InvokeBitXor(const char* fallback); |
| 291 void InvokeBitShr(const char* fallback); | 292 void InvokeBitShr(const char* fallback); |
| 292 void InvokeBitShl(const char* fallback); | 293 void InvokeBitShl(const char* fallback); |
| 293 | 294 |
| 294 void InvokeMethodUnfold(bool test); | 295 void InvokeMethodUnfold(bool test); |
| 295 void InvokeMethod(bool test); | 296 void InvokeMethod(bool test); |
| 296 | 297 |
| 297 void InvokeNative(bool yield, bool safepoint); | 298 void InvokeNative(bool yield, bool safepoint); |
| 298 void InvokeStatic(); | 299 void InvokeStatic(); |
| 299 | 300 |
| 300 void ConditionalStore(Register cmp, Register reg_if_eq, Register reg_if_ne, | 301 void AddIf(Register reg1, Register reg2, Condition cond, |
| 301 const Address& address); | 302 Register reg, int immediate); |
| 303 void ToBoolean(Register reg1, Register reg2, Condition cond, Register reg); | |
| 304 void LoadFalse(Register reg); | |
| 305 void LoadTrue(Register reg); | |
| 302 | 306 |
| 303 void CheckStackOverflow(int size); | 307 void CheckStackOverflow(int size); |
| 304 | 308 |
| 305 void Dispatch(int size); | 309 void Dispatch(int size); |
| 306 | 310 |
| 307 void SaveState(Label* resume); | 311 void SaveState(Label* resume); |
| 308 void RestoreState(); | 312 void RestoreState(); |
| 309 | 313 |
| 310 void ShiftAddJump(Register reg1, Register reg2, int imm); | 314 void ShiftAddJump(Register reg1, Register reg2, int imm); |
| 311 void ShiftAddLoad(Register reg1, Register reg2, Register reg3, int imm); | 315 void ShiftAddLoad(Register reg1, Register reg2, Register reg3, int imm); |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 420 __ B(NEQ, V0, T0, &overflow); | 424 __ B(NEQ, V0, T0, &overflow); |
| 421 __ b(&done_); | 425 __ b(&done_); |
| 422 __ ori(V0, ZR, Immediate(Interpreter::kBreakpoint)); // Delay-slot. | 426 __ ori(V0, ZR, Immediate(Interpreter::kBreakpoint)); // Delay-slot. |
| 423 | 427 |
| 424 __ Bind(&stay_fast); | 428 __ Bind(&stay_fast); |
| 425 Dispatch(0); | 429 Dispatch(0); |
| 426 | 430 |
| 427 __ Bind(&overflow); | 431 __ Bind(&overflow); |
| 428 Label throw_resume; | 432 Label throw_resume; |
| 429 SaveState(&throw_resume); | 433 SaveState(&throw_resume); |
| 430 __ lw(S3, Address(S0, Process::kProgramOffset)); | 434 __ lw(S3, Address(S6, Program::kStackOverflowErrorOffset)); |
| 431 __ lw(S3, Address(S3, Program::kStackOverflowErrorOffset)); | |
| 432 DoThrowAfterSaveState(&throw_resume); | 435 DoThrowAfterSaveState(&throw_resume); |
| 433 | 436 |
| 434 // Intrinsic failure: Just invoke the method. | 437 // Intrinsic failure: Just invoke the method. |
| 435 __ Bind(&intrinsic_failure_); | 438 __ Bind(&intrinsic_failure_); |
| 436 __ la(T9, "InterpreterMethodEntry"); | 439 __ la(T9, "InterpreterMethodEntry"); |
| 437 __ Jr(T9); | 440 __ Jr(T9); |
| 438 } | 441 } |
| 439 | 442 |
| 440 void InterpreterGeneratorMIPS::GenerateMethodEntry() { | 443 void InterpreterGeneratorMIPS::GenerateMethodEntry() { |
| 441 __ SwitchToText(); | 444 __ SwitchToText(); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 485 Dispatch(kLoadLocal0Length); | 488 Dispatch(kLoadLocal0Length); |
| 486 } | 489 } |
| 487 | 490 |
| 488 void InterpreterGeneratorMIPS::DoLoadLocal1() { | 491 void InterpreterGeneratorMIPS::DoLoadLocal1() { |
| 489 LoadLocal(A0, 1); | 492 LoadLocal(A0, 1); |
| 490 Push(A0); | 493 Push(A0); |
| 491 Dispatch(kLoadLocal1Length); | 494 Dispatch(kLoadLocal1Length); |
| 492 } | 495 } |
| 493 | 496 |
| 494 void InterpreterGeneratorMIPS::DoLoadLocal2() { | 497 void InterpreterGeneratorMIPS::DoLoadLocal2() { |
| 498 LoadLocal(A0, 2); | |
| 499 Push(A0); | |
| 500 Dispatch(kLoadLocal2Length); | |
| 495 } | 501 } |
| 496 | 502 |
| 497 void InterpreterGeneratorMIPS::DoLoadLocal3() { | 503 void InterpreterGeneratorMIPS::DoLoadLocal3() { |
| 498 LoadLocal(A0, 3); | 504 LoadLocal(A0, 3); |
| 499 Push(A0); | 505 Push(A0); |
| 500 Dispatch(kLoadLocal3Length); | 506 Dispatch(kLoadLocal3Length); |
| 501 } | 507 } |
| 502 | 508 |
| 503 void InterpreterGeneratorMIPS::DoLoadLocal4() { | 509 void InterpreterGeneratorMIPS::DoLoadLocal4() { |
| 504 LoadLocal(A0, 4); | 510 LoadLocal(A0, 4); |
| 505 Push(A0); | 511 Push(A0); |
| 506 Dispatch(kLoadLocal4Length); | 512 Dispatch(kLoadLocal4Length); |
| 507 } | 513 } |
| 508 | 514 |
| 509 void InterpreterGeneratorMIPS::DoLoadLocal5() { | 515 void InterpreterGeneratorMIPS::DoLoadLocal5() { |
| 516 LoadLocal(A0, 5); | |
| 517 Push(A0); | |
| 518 Dispatch(kLoadLocal5Length); | |
| 510 } | 519 } |
| 511 | 520 |
| 512 void InterpreterGeneratorMIPS::DoLoadLocal() { | 521 void InterpreterGeneratorMIPS::DoLoadLocal() { |
| 522 __ lbu(A0, Address(S1, 1)); | |
| 523 ShiftAddLoad(A0, S2, A0, TIMES_WORD_SIZE); | |
| 524 Push(A0); | |
| 525 Dispatch(kLoadLocalLength); | |
| 513 } | 526 } |
| 514 | 527 |
| 515 void InterpreterGeneratorMIPS::DoLoadLocalWide() { | 528 void InterpreterGeneratorMIPS::DoLoadLocalWide() { |
| 516 } | 529 } |
| 517 | 530 |
| 518 void InterpreterGeneratorMIPS::DoLoadBoxed() { | 531 void InterpreterGeneratorMIPS::DoLoadBoxed() { |
| 532 __ lbu(A0, Address(S1, 1)); | |
| 533 ShiftAddLoad(A1, S2, A0, TIMES_WORD_SIZE); | |
| 534 __ lw(A0, Address(A1, Boxed::kValueOffset - HeapObject::kTag)); | |
| 535 Push(A0); | |
| 536 Dispatch(kLoadBoxedLength); | |
| 519 } | 537 } |
| 520 | 538 |
| 521 void InterpreterGeneratorMIPS::DoLoadStatic() { | 539 void InterpreterGeneratorMIPS::DoLoadStatic() { |
| 522 __ lw(A0, Address(S1, 1)); | 540 __ lw(A0, Address(S1, 1)); |
| 523 __ lw(A1, Address(S0, Process::kStaticsOffset)); | 541 __ lw(A1, Address(S0, Process::kStaticsOffset)); |
| 524 __ addiu(A1, A1, Immediate(Array::kSize - HeapObject::kTag)); | 542 __ addiu(A1, A1, Immediate(Array::kSize - HeapObject::kTag)); |
| 525 ShiftAddLoad(A0, A1, A0, TIMES_WORD_SIZE); | 543 ShiftAddLoad(A0, A1, A0, TIMES_WORD_SIZE); |
| 526 Push(A0); | 544 Push(A0); |
| 527 Dispatch(kLoadStaticLength); | 545 Dispatch(kLoadStaticLength); |
| 528 } | 546 } |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 553 __ lw(A0, Address(A0, | 571 __ lw(A0, Address(A0, |
| 554 Initializer::kFunctionOffset - HeapObject::kTag)); // Delay-slot. | 572 Initializer::kFunctionOffset - HeapObject::kTag)); // Delay-slot. |
| 555 RestoreByteCodePointer(A2); | 573 RestoreByteCodePointer(A2); |
| 556 | 574 |
| 557 __ Bind(&done); | 575 __ Bind(&done); |
| 558 Push(A0); | 576 Push(A0); |
| 559 Dispatch(kLoadStaticInitLength); | 577 Dispatch(kLoadStaticInitLength); |
| 560 } | 578 } |
| 561 | 579 |
| 562 void InterpreterGeneratorMIPS::DoLoadField() { | 580 void InterpreterGeneratorMIPS::DoLoadField() { |
| 581 __ lbu(A1, Address(S1, 1)); | |
| 582 LoadLocal(A0, 0); | |
| 583 __ addiu(A0, A0, Immediate(Instance::kSize - HeapObject::kTag)); | |
| 584 ShiftAddLoad(A0, A0, A1, TIMES_WORD_SIZE); | |
| 585 StoreLocal(A0, 0); | |
| 586 Dispatch(kLoadFieldLength); | |
| 563 } | 587 } |
| 564 | 588 |
| 565 void InterpreterGeneratorMIPS::DoLoadFieldWide() { | 589 void InterpreterGeneratorMIPS::DoLoadFieldWide() { |
| 566 } | 590 } |
| 567 | 591 |
| 568 void InterpreterGeneratorMIPS::DoLoadConst() { | 592 void InterpreterGeneratorMIPS::DoLoadConst() { |
| 569 __ lw(A0, Address(S1, 1)); | 593 __ lw(A0, Address(S1, 1)); |
| 570 ShiftAddLoad(A2, S1, A0, TIMES_1); | 594 ShiftAddLoad(A2, S1, A0, TIMES_1); |
| 571 Push(A2); | 595 Push(A2); |
| 572 Dispatch(kLoadConstLength); | 596 Dispatch(kLoadConstLength); |
| 573 } | 597 } |
| 574 | 598 |
| 575 void InterpreterGeneratorMIPS::DoStoreLocal() { | 599 void InterpreterGeneratorMIPS::DoStoreLocal() { |
| 576 LoadLocal(A1, 0); | 600 LoadLocal(A1, 0); |
| 577 __ lbu(A0, Address(S1, 1)); | 601 __ lbu(A0, Address(S1, 1)); |
| 578 ShiftAddStore(A1, S2, A0, TIMES_WORD_SIZE); | 602 ShiftAddStore(A1, S2, A0, TIMES_WORD_SIZE); |
| 579 Dispatch(kStoreLocalLength); | 603 Dispatch(kStoreLocalLength); |
| 580 } | 604 } |
| 581 | 605 |
| 582 void InterpreterGeneratorMIPS::DoStoreBoxed() { | 606 void InterpreterGeneratorMIPS::DoStoreBoxed() { |
| 607 LoadLocal(A2, 0); | |
| 608 __ lbu(A0, Address(S1, 1)); | |
| 609 ShiftAddLoad(A1, S2, A0, TIMES_WORD_SIZE); | |
| 610 __ sw(A2, Address(A1, Boxed::kValueOffset - HeapObject::kTag)); | |
| 611 | |
| 612 AddToRememberedSet(A1, A2, A3); | |
| 613 | |
| 614 Dispatch(kStoreBoxedLength); | |
| 583 } | 615 } |
| 584 | 616 |
| 585 void InterpreterGeneratorMIPS::DoStoreStatic() { | 617 void InterpreterGeneratorMIPS::DoStoreStatic() { |
| 586 LoadLocal(A2, 0); | 618 LoadLocal(A2, 0); |
| 587 __ lw(A0, Address(S1, 1)); | 619 __ lw(A0, Address(S1, 1)); |
| 588 __ lw(A1, Address(S0, Process::kStaticsOffset)); | 620 __ lw(A1, Address(S0, Process::kStaticsOffset)); |
| 589 __ addiu(A3, A1, Immediate(Array::kSize - HeapObject::kTag)); | 621 __ addiu(A3, A1, Immediate(Array::kSize - HeapObject::kTag)); |
| 590 ShiftAddStore(A2, A3, A0, TIMES_WORD_SIZE); | 622 ShiftAddStore(A2, A3, A0, TIMES_WORD_SIZE); |
| 591 | 623 |
| 592 AddToRememberedSet(A1, A2, A0); | 624 AddToRememberedSet(A1, A2, A0); |
| 593 | 625 |
| 594 Dispatch(kStoreStaticLength); | 626 Dispatch(kStoreStaticLength); |
| 595 } | 627 } |
| 596 | 628 |
| 597 void InterpreterGeneratorMIPS::DoStoreField() { | 629 void InterpreterGeneratorMIPS::DoStoreField() { |
| 598 } | 630 } |
| 599 | 631 |
| 600 void InterpreterGeneratorMIPS::DoStoreFieldWide() { | 632 void InterpreterGeneratorMIPS::DoStoreFieldWide() { |
| 601 } | 633 } |
| 602 | 634 |
| 603 void InterpreterGeneratorMIPS::DoLoadLiteralNull() { | 635 void InterpreterGeneratorMIPS::DoLoadLiteralNull() { |
| 604 Push(S4); | 636 Push(S4); |
| 605 Dispatch(kLoadLiteralNullLength); | 637 Dispatch(kLoadLiteralNullLength); |
| 606 } | 638 } |
| 607 | 639 |
| 608 void InterpreterGeneratorMIPS::DoLoadLiteralTrue() { | 640 void InterpreterGeneratorMIPS::DoLoadLiteralTrue() { |
| 641 LoadTrue(A2); | |
| 642 Push(A2); | |
| 643 Dispatch(kLoadLiteralTrueLength); | |
| 609 } | 644 } |
| 610 | 645 |
| 611 void InterpreterGeneratorMIPS::DoLoadLiteralFalse() { | 646 void InterpreterGeneratorMIPS::DoLoadLiteralFalse() { |
| 647 LoadFalse(A2); | |
| 648 Push(A2); | |
| 649 Dispatch(kLoadLiteralFalseLength); | |
| 612 } | 650 } |
| 613 | 651 |
| 614 void InterpreterGeneratorMIPS::DoLoadLiteral0() { | 652 void InterpreterGeneratorMIPS::DoLoadLiteral0() { |
| 615 __ li(A0, Immediate(reinterpret_cast<int32_t>(Smi::FromWord(0)))); | 653 __ li(A0, Immediate(reinterpret_cast<int32_t>(Smi::FromWord(0)))); |
| 616 Push(A0); | 654 Push(A0); |
| 617 Dispatch(kLoadLiteral0Length); | 655 Dispatch(kLoadLiteral0Length); |
| 618 } | 656 } |
| 619 | 657 |
| 620 void InterpreterGeneratorMIPS::DoLoadLiteral1() { | 658 void InterpreterGeneratorMIPS::DoLoadLiteral1() { |
| 659 __ li(A0, Immediate(reinterpret_cast<int32_t>(Smi::FromWord(1)))); | |
| 660 Push(A0); | |
| 661 Dispatch(kLoadLiteral1Length); | |
| 621 } | 662 } |
| 622 | 663 |
| 623 void InterpreterGeneratorMIPS::DoLoadLiteral() { | 664 void InterpreterGeneratorMIPS::DoLoadLiteral() { |
| 624 __ lbu(A0, Address(S1, 1)); | 665 __ lbu(A0, Address(S1, 1)); |
| 625 __ sll(A0, A0, Immediate(Smi::kTagSize)); | 666 __ sll(A0, A0, Immediate(Smi::kTagSize)); |
| 626 ASSERT(Smi::kTag == 0); | 667 ASSERT(Smi::kTag == 0); |
| 627 Push(A0); | 668 Push(A0); |
| 628 Dispatch(kLoadLiteralLength); | 669 Dispatch(kLoadLiteralLength); |
| 629 } | 670 } |
| 630 | 671 |
| 631 void InterpreterGeneratorMIPS::DoLoadLiteralWide() { | 672 void InterpreterGeneratorMIPS::DoLoadLiteralWide() { |
| 673 ASSERT(Smi::kTag == 0); | |
| 674 __ lw(A0, Address(S1, 1)); | |
| 675 __ sll(A0, A0, Immediate(Smi::kTagSize)); | |
| 676 Push(A0); | |
| 677 Dispatch(kLoadLiteralWideLength); | |
| 632 } | 678 } |
| 633 | 679 |
| 634 void InterpreterGeneratorMIPS::DoInvokeMethodUnfold() { | 680 void InterpreterGeneratorMIPS::DoInvokeMethodUnfold() { |
| 635 } | 681 } |
| 636 | 682 |
| 637 void InterpreterGeneratorMIPS::DoInvokeMethod() { | 683 void InterpreterGeneratorMIPS::DoInvokeMethod() { |
| 638 InvokeMethod(false); | 684 InvokeMethod(false); |
| 639 } | 685 } |
| 640 | 686 |
| 641 void InterpreterGeneratorMIPS::DoInvokeNoSuchMethod() { | 687 void InterpreterGeneratorMIPS::DoInvokeNoSuchMethod() { |
| 642 } | 688 } |
| 643 | 689 |
| 644 void InterpreterGeneratorMIPS::DoInvokeTestNoSuchMethod() { | 690 void InterpreterGeneratorMIPS::DoInvokeTestNoSuchMethod() { |
| 645 } | 691 } |
| 646 | 692 |
| 647 void InterpreterGeneratorMIPS::DoInvokeTestUnfold() { | 693 void InterpreterGeneratorMIPS::DoInvokeTestUnfold() { |
| 648 } | 694 } |
| 649 | 695 |
| 650 void InterpreterGeneratorMIPS::DoInvokeTest() { | 696 void InterpreterGeneratorMIPS::DoInvokeTest() { |
| 697 InvokeMethod(true); | |
| 651 } | 698 } |
| 652 | 699 |
| 653 void InterpreterGeneratorMIPS::DoInvokeStatic() { | 700 void InterpreterGeneratorMIPS::DoInvokeStatic() { |
| 654 InvokeStatic(); | 701 InvokeStatic(); |
| 655 } | 702 } |
| 656 | 703 |
| 657 void InterpreterGeneratorMIPS::DoInvokeFactory() { | 704 void InterpreterGeneratorMIPS::DoInvokeFactory() { |
| 705 InvokeStatic(); | |
| 658 } | 706 } |
| 659 | 707 |
| 660 void InterpreterGeneratorMIPS::DoInvokeLeafNative() { | 708 void InterpreterGeneratorMIPS::DoInvokeLeafNative() { |
| 661 InvokeNative(false, false); | 709 InvokeNative(false, false); |
| 662 } | 710 } |
| 663 | 711 |
| 664 void InterpreterGeneratorMIPS::DoInvokeNative() { | 712 void InterpreterGeneratorMIPS::DoInvokeNative() { |
| 713 InvokeNative(false, true); | |
| 665 } | 714 } |
| 666 | 715 |
| 667 void InterpreterGeneratorMIPS::DoInvokeNativeYield() { | 716 void InterpreterGeneratorMIPS::DoInvokeNativeYield() { |
| 668 } | 717 } |
| 669 | 718 |
| 670 void InterpreterGeneratorMIPS::DoInvokeSelector() { | 719 void InterpreterGeneratorMIPS::DoInvokeSelector() { |
| 671 Label resume; | 720 Label resume; |
| 672 SaveState(&resume); | 721 SaveState(&resume); |
| 673 PrepareStack(); | 722 PrepareStack(); |
| 674 __ la(T9, "HandleInvokeSelector"); | 723 __ la(T9, "HandleInvokeSelector"); |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 698 | 747 |
| 699 StoreLocal(A0, 0); | 748 StoreLocal(A0, 0); |
| 700 Dispatch(kInvokeSelectorLength); | 749 Dispatch(kInvokeSelectorLength); |
| 701 } | 750 } |
| 702 | 751 |
| 703 void InterpreterGeneratorMIPS::InvokeEq(const char* fallback) { | 752 void InterpreterGeneratorMIPS::InvokeEq(const char* fallback) { |
| 704 InvokeCompare(fallback, EQ); | 753 InvokeCompare(fallback, EQ); |
| 705 } | 754 } |
| 706 | 755 |
| 707 void InterpreterGeneratorMIPS::InvokeLt(const char* fallback) { | 756 void InterpreterGeneratorMIPS::InvokeLt(const char* fallback) { |
| 757 InvokeCompare(fallback, LT); | |
| 708 } | 758 } |
| 709 | 759 |
| 710 void InterpreterGeneratorMIPS::InvokeLe(const char* fallback) { | 760 void InterpreterGeneratorMIPS::InvokeLe(const char* fallback) { |
| 761 InvokeCompare(fallback, LE); | |
| 711 } | 762 } |
| 712 | 763 |
| 713 void InterpreterGeneratorMIPS::InvokeGt(const char* fallback) { | 764 void InterpreterGeneratorMIPS::InvokeGt(const char* fallback) { |
| 765 InvokeCompare(fallback, GT); | |
| 714 } | 766 } |
| 715 | 767 |
| 716 void InterpreterGeneratorMIPS::InvokeGe(const char* fallback) { | 768 void InterpreterGeneratorMIPS::InvokeGe(const char* fallback) { |
| 769 InvokeCompare(fallback, GE); | |
| 717 } | 770 } |
| 718 | 771 |
| 719 void InterpreterGeneratorMIPS::InvokeAdd(const char* fallback) { | 772 void InterpreterGeneratorMIPS::InvokeAdd(const char* fallback) { |
| 720 Label no_overflow; | 773 Label no_overflow; |
| 721 LoadLocal(A0, 1); | 774 LoadLocal(A0, 1); |
| 722 __ andi(T0, A0, Immediate(Smi::kTagMask)); | 775 __ andi(T0, A0, Immediate(Smi::kTagMask)); |
| 723 __ B(NEQ, T0, ZR, fallback); | 776 __ B(NEQ, T0, ZR, fallback); |
| 724 LoadLocal(A1, 0); | 777 LoadLocal(A1, 0); |
| 725 __ andi(T1, A1, Immediate(Smi::kTagMask)); | 778 __ andi(T1, A1, Immediate(Smi::kTagMask)); |
| 726 __ B(NEQ, T1, ZR, fallback); | 779 __ B(NEQ, T1, ZR, fallback); |
| 727 | 780 |
| 728 __ xor_(T1, A0, A1); | 781 __ xor_(T1, A0, A1); |
| 729 __ b(LT, T1, ZR, &no_overflow); | 782 __ b(LT, T1, ZR, &no_overflow); |
| 730 __ addu(T0, A0, A1); // Delay-slot. | 783 __ addu(T0, A0, A1); // Delay-slot. |
| 731 __ xor_(T1, T0, A0); | 784 __ xor_(T1, T0, A0); |
| 732 __ slt(T1, T1, ZR); | 785 __ b(LT, T1, ZR, fallback); |
| 733 __ b(NEQ, T1, ZR, fallback); | |
| 734 __ Bind(&no_overflow); | 786 __ Bind(&no_overflow); |
| 735 __ move(A0, T0); // Delay-slot. | 787 __ move(A0, T0); // Delay-slot. |
| 736 DropNAndSetTop(1, A0); | 788 DropNAndSetTop(1, A0); |
| 737 Dispatch(kInvokeAddLength); | 789 Dispatch(kInvokeAddLength); |
| 738 } | 790 } |
| 739 | 791 |
| 740 void InterpreterGeneratorMIPS::InvokeSub(const char* fallback) { | 792 void InterpreterGeneratorMIPS::InvokeSub(const char* fallback) { |
| 793 Label no_overflow; | |
| 794 LoadLocal(A0, 1); | |
| 795 __ andi(T0, A0, Immediate(Smi::kTagMask)); | |
| 796 __ B(NEQ, T0, ZR, fallback); | |
| 797 LoadLocal(A1, 0); | |
| 798 __ andi(T0, A1, Immediate(Smi::kTagMask)); | |
| 799 __ B(NEQ, T0, ZR, fallback); | |
| 800 | |
| 801 __ xor_(T1, A0, A1); | |
| 802 __ srl(T1, T1, Immediate(31)); | |
| 803 __ b(EQ, T1, ZR, &no_overflow); | |
| 804 __ subu(T0, A0, A1); // Delay-slot. | |
| 805 __ xor_(T1, T0, A0); | |
| 806 __ b(LT, T1, ZR, fallback); | |
| 807 __ Bind(&no_overflow); | |
| 808 __ move(A0, T0); // Delay-slot. | |
| 809 DropNAndSetTop(1, A0); | |
| 810 Dispatch(kInvokeAddLength); | |
|
erikcorry
2016/06/27 15:51:08
kInvokeSubLength
petarj
2016/06/29 02:09:15
Done.
| |
| 741 } | 811 } |
| 742 | 812 |
| 743 void InterpreterGeneratorMIPS::InvokeMod(const char* fallback) { | 813 void InterpreterGeneratorMIPS::InvokeMod(const char* fallback) { |
| 744 } | 814 } |
| 745 | 815 |
| 746 void InterpreterGeneratorMIPS::InvokeMul(const char* fallback) { | 816 void InterpreterGeneratorMIPS::InvokeMul(const char* fallback) { |
| 817 LoadLocal(A0, 1); | |
| 818 __ andi(T0, A0, Immediate(Smi::kTagMask)); | |
| 819 __ B(NEQ, T0, ZR, fallback); | |
| 820 LoadLocal(A1, 0); | |
| 821 __ andi(T1, A1, Immediate(Smi::kTagMask)); | |
| 822 __ B(NEQ, T1, ZR, fallback); | |
| 823 | |
| 824 __ sra(A0, A0, Immediate(1)); | |
| 825 __ mult(A0, A1); | |
| 826 __ mfhi(T1); | |
| 827 __ mflo(T0); | |
| 828 __ move(A0, T0); | |
| 829 __ sra(T0, T0, Immediate(31)); | |
| 830 __ B(NEQ, T1, T0, fallback); | |
| 831 | |
| 832 DropNAndSetTop(1, A0); | |
| 833 Dispatch(kInvokeMulLength); | |
| 747 } | 834 } |
| 748 | 835 |
| 749 void InterpreterGeneratorMIPS::InvokeTruncDiv(const char* fallback) { | 836 void InterpreterGeneratorMIPS::InvokeTruncDiv(const char* fallback) { |
| 750 } | 837 } |
| 751 | 838 |
| 752 void InterpreterGeneratorMIPS::InvokeBitNot(const char* fallback) { | 839 void InterpreterGeneratorMIPS::InvokeBitNot(const char* fallback) { |
| 753 } | 840 } |
| 754 | 841 |
| 755 void InterpreterGeneratorMIPS::InvokeBitAnd(const char* fallback) { | 842 void InterpreterGeneratorMIPS::InvokeBitAnd(const char* fallback) { |
| 843 LoadLocal(A0, 1); | |
| 844 __ andi(T0, A0, Immediate(Smi::kTagMask)); | |
| 845 __ B(NEQ, T0, ZR, fallback); | |
| 846 LoadLocal(A1, 0); | |
| 847 __ andi(T0, A1, Immediate(Smi::kTagMask)); | |
| 848 __ B(NEQ, T0, ZR, fallback); | |
| 849 | |
| 850 __ and_(A0, A0, A1); | |
| 851 DropNAndSetTop(1, A0); | |
| 852 Dispatch(kInvokeBitAndLength); | |
| 756 } | 853 } |
| 757 | 854 |
| 758 void InterpreterGeneratorMIPS::InvokeBitOr(const char* fallback) { | 855 void InterpreterGeneratorMIPS::InvokeBitOr(const char* fallback) { |
| 759 } | 856 } |
| 760 | 857 |
| 761 void InterpreterGeneratorMIPS::InvokeBitXor(const char* fallback) { | 858 void InterpreterGeneratorMIPS::InvokeBitXor(const char* fallback) { |
| 762 } | 859 } |
| 763 | 860 |
| 764 void InterpreterGeneratorMIPS::InvokeBitShr(const char* fallback) { | 861 void InterpreterGeneratorMIPS::InvokeBitShr(const char* fallback) { |
| 862 LoadLocal(A0, 1); | |
| 863 __ andi(T0, A0, Immediate(Smi::kTagMask)); | |
| 864 __ B(NEQ, T0, ZR, fallback); | |
| 865 LoadLocal(A1, 0); | |
| 866 __ andi(T0, A1, Immediate(Smi::kTagMask)); | |
| 867 __ B(NEQ, T0, ZR, fallback); | |
| 868 | |
| 869 // Untag and shift. | |
| 870 __ sra(A0, A0, Immediate(1)); | |
| 871 __ sra(A1, A1, Immediate(1)); | |
| 872 | |
| 873 Label shift; | |
| 874 __ li(T0, Immediate(32)); | |
| 875 __ B(LT, A1, T0, &shift); | |
| 876 __ li(A1, Immediate(31)); | |
| 877 __ Bind(&shift); | |
| 878 __ srav(A0, A0, A1); | |
| 879 | |
| 880 // Retag and store. | |
| 881 __ addu(A0, A0, A0); | |
| 882 DropNAndSetTop(1, A0); | |
| 883 Dispatch(kInvokeBitAndLength); | |
| 765 } | 884 } |
| 766 | 885 |
| 767 void InterpreterGeneratorMIPS::InvokeBitShl(const char* fallback) { | 886 void InterpreterGeneratorMIPS::InvokeBitShl(const char* fallback) { |
| 887 LoadLocal(A0, 1); | |
| 888 __ andi(T0, A0, Immediate(Smi::kTagMask)); | |
| 889 __ B(NEQ, T0, ZR, fallback); | |
| 890 LoadLocal(A1, 0); | |
| 891 __ andi(T0, A1, Immediate(Smi::kTagSize)); | |
| 892 __ B(NEQ, T0, ZR, fallback); | |
| 893 | |
| 894 // Untag the shift count, but not the value. If the shift | |
| 895 // count is greater than 31 (or negative), the shift is going | |
| 896 // to misbehave so we have to guard against that. | |
| 897 __ sra(A1, A1, Immediate(1)); | |
| 898 __ li(T0, Immediate(31)); | |
|
erikcorry
2016/06/27 15:51:08
Perhaps save one instruction with
sra(T0, A1, Imm
petarj
2016/06/29 02:09:15
Done, thanks for the idea.
| |
| 899 __ sltu(T1, T0, A1); | |
| 900 __ B(GT, T1, ZR, fallback); | |
| 901 | |
| 902 // Only allow to shift out "sign bits". If we shift | |
| 903 // out any other bit, it's an overflow. | |
| 904 __ sllv(A2, A0, A1); | |
| 905 __ srav(A3, A2, A1); | |
| 906 __ B(NEQ, A3, A0, fallback); | |
| 907 | |
| 908 DropNAndSetTop(1, A2); | |
| 909 Dispatch(kInvokeBitShlLength); | |
| 768 } | 910 } |
| 769 | 911 |
| 770 void InterpreterGeneratorMIPS::DoPop() { | 912 void InterpreterGeneratorMIPS::DoPop() { |
| 771 Drop(1); | 913 Drop(1); |
| 772 Dispatch(kPopLength); | 914 Dispatch(kPopLength); |
| 773 } | 915 } |
| 774 | 916 |
| 775 void InterpreterGeneratorMIPS::DoDrop() { | 917 void InterpreterGeneratorMIPS::DoDrop() { |
| 918 __ lbu(A0, Address(S1, 1)); | |
| 919 Drop(A0); | |
| 920 Dispatch(kDropLength); | |
| 776 } | 921 } |
| 777 | 922 |
| 778 void InterpreterGeneratorMIPS::DoReturn() { | 923 void InterpreterGeneratorMIPS::DoReturn() { |
| 779 Return(false); | 924 Return(false); |
| 780 } | 925 } |
| 781 | 926 |
| 782 void InterpreterGeneratorMIPS::DoReturnNull() { | 927 void InterpreterGeneratorMIPS::DoReturnNull() { |
| 783 Return(true); | 928 Return(true); |
| 784 } | 929 } |
| 785 | 930 |
| 786 void InterpreterGeneratorMIPS::DoBranchWide() { | 931 void InterpreterGeneratorMIPS::DoBranchWide() { |
| 787 __ lw(A0, Address(S1, 1)); | 932 __ lw(A0, Address(S1, 1)); |
| 788 __ addu(S1, S1, A0); | 933 __ addu(S1, S1, A0); |
| 789 Dispatch(0); | 934 Dispatch(0); |
| 790 } | 935 } |
| 791 | 936 |
| 792 void InterpreterGeneratorMIPS::DoBranchIfTrueWide() { | 937 void InterpreterGeneratorMIPS::DoBranchIfTrueWide() { |
| 793 Label branch; | 938 Label branch; |
| 794 Pop(S3); | 939 Pop(S3); |
| 795 __ B(EQ, S3, S6, &branch); | 940 LoadTrue(A2); |
| 941 __ B(EQ, S3, A2, &branch); | |
| 796 Dispatch(kBranchIfTrueWideLength); | 942 Dispatch(kBranchIfTrueWideLength); |
| 797 | 943 |
| 798 __ Bind(&branch); | 944 __ Bind(&branch); |
| 799 __ lw(A0, Address(S1, 1)); | 945 __ lw(A0, Address(S1, 1)); |
| 800 __ addu(S1, S1, A0); | 946 __ addu(S1, S1, A0); |
| 801 Dispatch(0); | 947 Dispatch(0); |
| 802 } | 948 } |
| 803 | 949 |
| 804 void InterpreterGeneratorMIPS::DoBranchIfFalseWide() { | 950 void InterpreterGeneratorMIPS::DoBranchIfFalseWide() { |
| 805 Label branch; | 951 Label branch; |
| 806 Pop(S3); | 952 Pop(S3); |
| 807 __ B(NEQ, S3, S6, &branch); | 953 LoadTrue(A2); |
| 954 __ B(NEQ, S3, A2, &branch); | |
| 808 Dispatch(kBranchIfFalseWideLength); | 955 Dispatch(kBranchIfFalseWideLength); |
| 809 | 956 |
| 810 __ Bind(&branch); | 957 __ Bind(&branch); |
| 811 __ lw(A0, Address(S1, 1)); | 958 __ lw(A0, Address(S1, 1)); |
| 812 __ addu(S1, S1, A0); | 959 __ addu(S1, S1, A0); |
| 813 Dispatch(0); | 960 Dispatch(0); |
| 814 } | 961 } |
| 815 | 962 |
| 816 void InterpreterGeneratorMIPS::DoBranchBack() { | 963 void InterpreterGeneratorMIPS::DoBranchBack() { |
| 964 CheckStackOverflow(0); | |
| 965 __ lbu(A0, Address(S1, 1)); | |
| 966 __ subu(S1, S1, A0); | |
| 967 Dispatch(0); | |
| 817 } | 968 } |
| 818 | 969 |
| 819 void InterpreterGeneratorMIPS::DoBranchBackIfTrue() { | 970 void InterpreterGeneratorMIPS::DoBranchBackIfTrue() { |
| 820 } | 971 } |
| 821 | 972 |
| 822 void InterpreterGeneratorMIPS::DoBranchBackIfFalse() { | 973 void InterpreterGeneratorMIPS::DoBranchBackIfFalse() { |
| 823 } | 974 } |
| 824 | 975 |
| 825 void InterpreterGeneratorMIPS::DoBranchBackWide() { | 976 void InterpreterGeneratorMIPS::DoBranchBackWide() { |
| 826 } | 977 } |
| 827 | 978 |
| 828 void InterpreterGeneratorMIPS::DoBranchBackIfTrueWide() { | 979 void InterpreterGeneratorMIPS::DoBranchBackIfTrueWide() { |
| 829 } | 980 } |
| 830 | 981 |
| 831 void InterpreterGeneratorMIPS::DoBranchBackIfFalseWide() { | 982 void InterpreterGeneratorMIPS::DoBranchBackIfFalseWide() { |
| 832 } | 983 } |
| 833 | 984 |
| 834 void InterpreterGeneratorMIPS::DoPopAndBranchWide() { | 985 void InterpreterGeneratorMIPS::DoPopAndBranchWide() { |
| 986 __ lbu(A0, Address(S1, 1)); | |
| 987 ShiftAdd(S2, S2, A0, TIMES_WORD_SIZE); | |
| 988 | |
| 989 __ lw(A0, Address(S1, 2)); | |
| 990 __ addu(S1, S1, A0); | |
| 991 Dispatch(0); | |
| 835 } | 992 } |
| 836 | 993 |
| 837 void InterpreterGeneratorMIPS::DoPopAndBranchBackWide() { | 994 void InterpreterGeneratorMIPS::DoPopAndBranchBackWide() { |
| 838 } | 995 } |
| 839 | 996 |
| 840 void InterpreterGeneratorMIPS::DoAllocate() { | 997 void InterpreterGeneratorMIPS::DoAllocate() { |
| 841 Allocate(false); | 998 Allocate(false); |
| 842 } | 999 } |
| 843 | 1000 |
| 844 void InterpreterGeneratorMIPS::DoAllocateImmutable() { | 1001 void InterpreterGeneratorMIPS::DoAllocateImmutable() { |
| 1002 Allocate(true); | |
| 845 } | 1003 } |
| 846 | 1004 |
| 847 void InterpreterGeneratorMIPS::DoAllocateBoxed() { | 1005 void InterpreterGeneratorMIPS::DoAllocateBoxed() { |
| 1006 LoadLocal(A1, 0); | |
| 1007 PrepareStack(); | |
| 1008 __ la(T9, "HandleAllocateBoxed"); | |
| 1009 __ jalr(T9); | |
| 1010 __ move(A0, S0); // Delay-slot. | |
| 1011 RestoreStack(); | |
| 1012 __ move(A0, V0); | |
| 1013 __ andi(A1, A0, Immediate(Failure::kTagMask | Failure::kTypeMask)); | |
| 1014 __ li(T0, Immediate(Failure::kTag)); | |
| 1015 __ B(EQ, A1, T0, &gc_); | |
| 1016 StoreLocal(A0, 0); | |
| 1017 Dispatch(kAllocateBoxedLength); | |
| 848 } | 1018 } |
| 849 | 1019 |
| 850 void InterpreterGeneratorMIPS::DoNegate() { | 1020 void InterpreterGeneratorMIPS::DoNegate() { |
| 851 } | 1021 } |
| 852 | 1022 |
| 853 void InterpreterGeneratorMIPS::DoStackOverflowCheck() { | 1023 void InterpreterGeneratorMIPS::DoStackOverflowCheck() { |
| 854 } | 1024 } |
| 855 | 1025 |
| 856 void InterpreterGeneratorMIPS::DoThrowAfterSaveState(Label* resume) { | 1026 void InterpreterGeneratorMIPS::DoThrowAfterSaveState(Label* resume) { |
| 857 // Use the stack to store the stack delta initialized to zero, and the | 1027 // Use the stack to store the stack delta initialized to zero, and the |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 887 ShiftAdd(S2, S2, A3, TIMES_WORD_SIZE); | 1057 ShiftAdd(S2, S2, A3, TIMES_WORD_SIZE); |
| 888 | 1058 |
| 889 StoreLocal(S3, 0); | 1059 StoreLocal(S3, 0); |
| 890 Dispatch(0); | 1060 Dispatch(0); |
| 891 } | 1061 } |
| 892 | 1062 |
| 893 void InterpreterGeneratorMIPS::DoThrow() { | 1063 void InterpreterGeneratorMIPS::DoThrow() { |
| 894 } | 1064 } |
| 895 | 1065 |
| 896 void InterpreterGeneratorMIPS::DoSubroutineCall() { | 1066 void InterpreterGeneratorMIPS::DoSubroutineCall() { |
| 1067 __ lw(A0, Address(S1, 1)); | |
| 1068 __ lw(A1, Address(S1, 5)); | |
| 1069 | |
| 1070 // Push the return delta as a tagged smi. | |
| 1071 ASSERT(Smi::kTag == 0); | |
| 1072 __ sll(A1, A1, Immediate(Smi::kTagSize)); | |
| 1073 Push(A1); | |
| 1074 | |
| 1075 __ addu(S1, S1, A0); | |
| 1076 Dispatch(0); | |
| 897 } | 1077 } |
| 898 | 1078 |
| 899 void InterpreterGeneratorMIPS::DoSubroutineReturn() { | 1079 void InterpreterGeneratorMIPS::DoSubroutineReturn() { |
| 1080 Pop(A0); | |
| 1081 __ srl(A0, A0, Immediate(Smi::kTagSize)); | |
| 1082 __ subu(S1, S1, A0); | |
| 1083 Dispatch(0); | |
| 900 } | 1084 } |
| 901 | 1085 |
| 902 void InterpreterGeneratorMIPS::DoProcessYield() { | 1086 void InterpreterGeneratorMIPS::DoProcessYield() { |
| 903 LoadLocal(A0, 0); | 1087 LoadLocal(A0, 0); |
| 904 __ sra(V0, A0, Immediate(1)); | 1088 __ sra(V0, A0, Immediate(1)); |
| 905 __ addiu(S1, S1, Immediate(kProcessYieldLength)); | 1089 __ addiu(S1, S1, Immediate(kProcessYieldLength)); |
| 906 StoreLocal(S4, 0); | 1090 StoreLocal(S4, 0); |
| 907 __ B(&done_); | 1091 __ B(&done_); |
| 908 } | 1092 } |
| 909 | 1093 |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 928 DropNAndSetTop(1, S3); | 1112 DropNAndSetTop(1, S3); |
| 929 Dispatch(kCoroutineChangeLength); | 1113 Dispatch(kCoroutineChangeLength); |
| 930 } | 1114 } |
| 931 | 1115 |
| 932 void InterpreterGeneratorMIPS::DoIdentical() { | 1116 void InterpreterGeneratorMIPS::DoIdentical() { |
| 933 } | 1117 } |
| 934 | 1118 |
| 935 void InterpreterGeneratorMIPS::DoIdenticalNonNumeric() { | 1119 void InterpreterGeneratorMIPS::DoIdenticalNonNumeric() { |
| 936 LoadLocal(A0, 0); | 1120 LoadLocal(A0, 0); |
| 937 LoadLocal(A1, 1); | 1121 LoadLocal(A1, 1); |
| 938 __ subu(T0, A0, A1); | 1122 ToBoolean(A0, A1, EQ, A2); |
| 939 ConditionalStore(T0, S6, S7, Address(S2, kWordSize)); | 1123 StoreLocal(A2, 1); |
| 1124 | |
| 940 Drop(1); | 1125 Drop(1); |
| 941 Dispatch(kIdenticalNonNumericLength); | 1126 Dispatch(kIdenticalNonNumericLength); |
| 942 } | 1127 } |
| 943 | 1128 |
| 944 void InterpreterGeneratorMIPS::DoEnterNoSuchMethod() { | 1129 void InterpreterGeneratorMIPS::DoEnterNoSuchMethod() { |
| 945 } | 1130 } |
| 946 | 1131 |
| 947 void InterpreterGeneratorMIPS::DoExitNoSuchMethod() { | 1132 void InterpreterGeneratorMIPS::DoExitNoSuchMethod() { |
| 948 } | 1133 } |
| 949 | 1134 |
| 950 void InterpreterGeneratorMIPS::DoMethodEnd() { | 1135 void InterpreterGeneratorMIPS::DoMethodEnd() { |
| 951 } | 1136 } |
| 952 | 1137 |
| 953 void InterpreterGeneratorMIPS::DoIntrinsicObjectEquals() { | 1138 void InterpreterGeneratorMIPS::DoIntrinsicObjectEquals() { |
| 954 } | 1139 } |
| 955 | 1140 |
| 956 void InterpreterGeneratorMIPS::DoIntrinsicGetField() { | 1141 void InterpreterGeneratorMIPS::DoIntrinsicGetField() { |
| 957 __ lbu(A1, Address(A0, 2 + Function::kSize - HeapObject::kTag)); | 1142 __ lbu(A1, Address(A0, 2 + Function::kSize - HeapObject::kTag)); |
| 958 LoadLocal(A0, 0); | 1143 LoadLocal(A0, 0); |
| 959 __ addiu(A0, A0, Immediate(Instance::kSize - HeapObject::kTag)); | 1144 __ addiu(A0, A0, Immediate(Instance::kSize - HeapObject::kTag)); |
| 960 ShiftAddLoad(A0, A0, A1, TIMES_WORD_SIZE); | 1145 ShiftAddLoad(A0, A0, A1, TIMES_WORD_SIZE); |
| 961 | 1146 |
| 962 __ Jr(RA); | 1147 __ Jr(RA); |
| 963 } | 1148 } |
| 964 | 1149 |
| 965 void InterpreterGeneratorMIPS::DoIntrinsicSetField() { | 1150 void InterpreterGeneratorMIPS::DoIntrinsicSetField() { |
| 1151 __ lbu(A1, Address(A0, 3 + Function::kSize - HeapObject::kTag)); | |
| 1152 LoadLocal(S3, 0); | |
| 1153 LoadLocal(A2, 1); | |
| 1154 __ addiu(A3, A2, Immediate(Instance::kSize - HeapObject::kTag)); | |
| 1155 ShiftAddStore(S3, A3, A1, TIMES_WORD_SIZE); | |
| 1156 | |
| 1157 // S3 is not trashed. | |
| 1158 AddToRememberedSet(A2, S3, A3); | |
| 1159 | |
| 1160 __ move(T9, RA); | |
| 1161 __ jr(T9); | |
| 1162 __ move(A0, S3); // Delay-slot. | |
| 966 } | 1163 } |
| 967 | 1164 |
| 968 void InterpreterGeneratorMIPS::DoIntrinsicListIndexGet() { | 1165 void InterpreterGeneratorMIPS::DoIntrinsicListIndexGet() { |
| 969 } | 1166 } |
| 970 | 1167 |
| 971 void InterpreterGeneratorMIPS::DoIntrinsicListIndexSet() { | 1168 void InterpreterGeneratorMIPS::DoIntrinsicListIndexSet() { |
| 972 } | 1169 } |
| 973 | 1170 |
| 974 void InterpreterGeneratorMIPS::DoIntrinsicListLength() { | 1171 void InterpreterGeneratorMIPS::DoIntrinsicListLength() { |
| 975 } | 1172 } |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1048 void InterpreterGeneratorMIPS::ReadFrameDescriptor(Register scratch) { | 1245 void InterpreterGeneratorMIPS::ReadFrameDescriptor(Register scratch) { |
| 1049 } | 1246 } |
| 1050 | 1247 |
| 1051 void InterpreterGeneratorMIPS::InvokeMethodUnfold(bool test) { | 1248 void InterpreterGeneratorMIPS::InvokeMethodUnfold(bool test) { |
| 1052 } | 1249 } |
| 1053 | 1250 |
| 1054 void InterpreterGeneratorMIPS::InvokeMethod(bool test) { | 1251 void InterpreterGeneratorMIPS::InvokeMethod(bool test) { |
| 1055 // Get the selector from the bytecodes. | 1252 // Get the selector from the bytecodes. |
| 1056 __ lw(S3, Address(S1, 1)); | 1253 __ lw(S3, Address(S1, 1)); |
| 1057 | 1254 |
| 1058 // Fetch the virtual table from the program. | 1255 // Fetch the virtual table from the program. |
|
erikcorry
2016/06/27 15:51:08
Comment is out of date.
petarj
2016/06/29 02:09:15
Removed.
| |
| 1059 __ lw(A1, Address(S0, Process::kProgramOffset)); | 1256 __ lw(A1, Address(S6, Program::kDispatchTableOffset)); |
| 1060 __ lw(A1, Address(A1, Program::kDispatchTableOffset)); | |
| 1061 | 1257 |
| 1062 if (!test) { | 1258 if (!test) { |
| 1063 // Compute the arity from the selector. | 1259 // Compute the arity from the selector. |
| 1064 ASSERT(Selector::ArityField::shift() == 0); | 1260 ASSERT(Selector::ArityField::shift() == 0); |
| 1065 __ andi(A2, S3, Immediate(Selector::ArityField::mask())); | 1261 __ andi(A2, S3, Immediate(Selector::ArityField::mask())); |
| 1066 } | 1262 } |
| 1067 | 1263 |
| 1068 // Compute the selector offset (smi tagged) from the selector. | 1264 // Compute the selector offset (smi tagged) from the selector. |
| 1069 __ li(S5, Immediate(Selector::IdField::mask())); | 1265 __ li(S5, Immediate(Selector::IdField::mask())); |
| 1070 __ and_(S3, S3, S5); | 1266 __ and_(S3, S3, S5); |
| 1071 __ srl(S3, S3, Immediate(Selector::IdField::shift() - Smi::kTagSize)); | 1267 __ srl(S3, S3, Immediate(Selector::IdField::shift() - Smi::kTagSize)); |
| 1072 | 1268 |
| 1073 // Get the receiver from the stack. | 1269 // Get the receiver from the stack. |
| 1074 if (test) { | 1270 if (test) { |
| 1075 LoadLocal(A2, 0); | 1271 LoadLocal(A2, 0); |
| 1076 } else { | 1272 } else { |
| 1077 ShiftAddLoad(A2, S2, A2, TIMES_WORD_SIZE); | 1273 ShiftAddLoad(A2, S2, A2, TIMES_WORD_SIZE); |
| 1078 } | 1274 } |
| 1275 | |
| 1079 // Compute the receiver class. | 1276 // Compute the receiver class. |
| 1080 Label smi, dispatch; | 1277 Label smi, dispatch; |
| 1081 ASSERT(Smi::kTag == 0); | 1278 ASSERT(Smi::kTag == 0); |
| 1082 __ andi(T0, A2, Immediate(Smi::kTagMask)); | 1279 __ andi(T0, A2, Immediate(Smi::kTagMask)); |
| 1083 __ B(EQ, T0, ZR, &smi); | 1280 __ B(EQ, T0, ZR, &smi); |
| 1084 __ lw(A2, Address(A2, HeapObject::kClassOffset - HeapObject::kTag)); | 1281 __ lw(A2, Address(A2, HeapObject::kClassOffset - HeapObject::kTag)); |
| 1085 | 1282 |
| 1086 // Compute entry index: class id + selector offset. | 1283 // Compute entry index: class id + selector offset. |
| 1087 int id_offset = Class::kIdOrTransformationTargetOffset - HeapObject::kTag; | 1284 int id_offset = Class::kIdOrTransformationTargetOffset - HeapObject::kTag; |
| 1088 __ Bind(&dispatch); | 1285 __ Bind(&dispatch); |
| 1089 __ lw(A2, Address(A2, id_offset)); | 1286 __ lw(A2, Address(A2, id_offset)); |
| 1090 __ addu(A2, A2, S3); | 1287 __ addu(A2, A2, S3); |
| 1091 | 1288 |
| 1092 // Fetch the entry from the table. Because the index is smi tagged | 1289 // Fetch the entry from the table. Because the index is smi tagged |
| 1093 // we only multiply by two -- not four -- when indexing. | 1290 // we only multiply by two -- not four -- when indexing. |
| 1094 ASSERT(Smi::kTagSize == 1); | 1291 ASSERT(Smi::kTagSize == 1); |
| 1095 __ addiu(A1, A1, Immediate(Array::kSize - HeapObject::kTag)); | 1292 __ addiu(A1, A1, Immediate(Array::kSize - HeapObject::kTag)); |
| 1096 ShiftAddLoad(A1, A1, A2, TIMES_2); | 1293 ShiftAddLoad(A1, A1, A2, TIMES_2); |
| 1097 | 1294 |
| 1098 // Validate that the offset stored in the entry matches the offset | 1295 // Validate that the offset stored in the entry matches the offset |
| 1099 // we used to find it. | 1296 // we used to find it. |
| 1100 Label invalid; | 1297 Label invalid; |
| 1101 __ lw(A3, Address(A1, DispatchTableEntry::kOffsetOffset - HeapObject::kTag)); | 1298 __ lw(A3, Address(A1, DispatchTableEntry::kOffsetOffset - HeapObject::kTag)); |
| 1102 __ B(NEQ, S3, A3, &invalid); | 1299 __ B(NEQ, S3, A3, &invalid); |
| 1103 | 1300 |
| 1104 // Load the target and the intrinsic from the entry. | 1301 // Load the target and the intrinsic from the entry. |
| 1105 Label validated, intrinsified; | 1302 Label validated, intrinsified; |
| 1106 if (test) { | 1303 if (test) { |
| 1107 // Valid entry: The answer is true. | 1304 // Valid entry: The answer is true. |
| 1108 StoreLocal(S6, 0); | 1305 LoadTrue(A2); |
| 1306 StoreLocal(A2, 0); | |
| 1109 Dispatch(kInvokeTestLength); | 1307 Dispatch(kInvokeTestLength); |
| 1110 } else { | 1308 } else { |
| 1111 __ Bind(&validated); | 1309 __ Bind(&validated); |
| 1112 | 1310 |
| 1113 __ lw(A0, Address(A1, | 1311 __ lw(A0, Address(A1, |
| 1114 DispatchTableEntry::kTargetOffset - HeapObject::kTag)); | 1312 DispatchTableEntry::kTargetOffset - HeapObject::kTag)); |
| 1115 | 1313 |
| 1116 SaveByteCodePointer(A2); | 1314 SaveByteCodePointer(A2); |
| 1117 __ lw(A1, Address(A1, DispatchTableEntry::kCodeOffset - HeapObject::kTag)); | 1315 __ lw(A1, Address(A1, DispatchTableEntry::kCodeOffset - HeapObject::kTag)); |
| 1118 __ move(T9, A1); | 1316 __ move(T9, A1); |
| 1119 __ Jalr(T9); | 1317 __ Jalr(T9); |
| 1120 RestoreByteCodePointer(A2); | 1318 RestoreByteCodePointer(A2); |
| 1121 | 1319 |
| 1122 __ lw(S3, Address(S1, 1)); | 1320 __ lw(S3, Address(S1, 1)); |
| 1123 // Compute the arity from the selector. | 1321 // Compute the arity from the selector. |
| 1124 ASSERT(Selector::ArityField::shift() == 0); | 1322 ASSERT(Selector::ArityField::shift() == 0); |
| 1125 __ andi(A2, S3, Immediate(Selector::ArityField::mask())); | 1323 __ andi(A2, S3, Immediate(Selector::ArityField::mask())); |
| 1126 | 1324 |
| 1127 Drop(A2); | 1325 Drop(A2); |
| 1128 | 1326 |
| 1129 StoreLocal(A0, 0); | 1327 StoreLocal(A0, 0); |
| 1130 Dispatch(kInvokeMethodLength); | 1328 Dispatch(kInvokeMethodLength); |
| 1131 } | 1329 } |
| 1132 | 1330 |
| 1133 __ Bind(&smi); | 1331 __ Bind(&smi); |
| 1134 __ lw(A2, Address(S0, Process::kProgramOffset)); | |
| 1135 __ b(&dispatch); | 1332 __ b(&dispatch); |
| 1136 __ lw(A2, Address(A2, Program::kSmiClassOffset)); // Delay-slot. | 1333 __ lw(A2, Address(S6, Program::kSmiClassOffset)); // Delay-slot. |
| 1137 | 1334 |
| 1138 if (test) { | 1335 if (test) { |
| 1139 // Invalid entry: The answer is false. | 1336 // Invalid entry: The answer is false. |
| 1140 __ Bind(&invalid); | 1337 __ Bind(&invalid); |
| 1141 StoreLocal(S7, 0); | 1338 LoadFalse(A2); |
| 1339 StoreLocal(A2, 0); | |
| 1142 Dispatch(kInvokeTestLength); | 1340 Dispatch(kInvokeTestLength); |
| 1143 } else { | 1341 } else { |
| 1144 __ Bind(&intrinsified); | 1342 __ Bind(&intrinsified); |
| 1145 __ move(T9, A2); | 1343 __ move(T9, A2); |
| 1146 __ Jr(T9); | 1344 __ Jr(T9); |
| 1147 | 1345 |
| 1148 // Invalid entry: Use the noSuchMethod entry from entry zero of | 1346 // Invalid entry: Use the noSuchMethod entry from entry zero of |
| 1149 // the virtual table. | 1347 // the virtual table. |
| 1150 __ Bind(&invalid); | 1348 __ Bind(&invalid); |
| 1151 __ lw(A1, Address(S0, Process::kProgramOffset)); | 1349 __ lw(A1, Address(S6, Program::kDispatchTableOffset)); |
| 1152 __ lw(A1, Address(A1, Program::kDispatchTableOffset)); | |
| 1153 __ b(&validated); | 1350 __ b(&validated); |
| 1154 __ lw(A1, Address(A1, Array::kSize - HeapObject::kTag)); // Delay-slot. | 1351 __ lw(A1, Address(A1, Array::kSize - HeapObject::kTag)); // Delay-slot. |
| 1155 } | 1352 } |
| 1156 } | 1353 } |
| 1157 | 1354 |
| 1158 void InterpreterGeneratorMIPS::InvokeNative(bool yield, bool safepoint) { | 1355 void InterpreterGeneratorMIPS::InvokeNative(bool yield, bool safepoint) { |
| 1159 __ lbu(A1, Address(S1, 1)); | 1356 __ lbu(A1, Address(S1, 1)); |
| 1160 // Also skip two empty slots. | 1357 // Also skip two empty slots. |
| 1161 __ addiu(A1, A1, Immediate(2)); | 1358 __ addiu(A1, A1, Immediate(2)); |
| 1162 __ lbu(A0, Address(S1, 2)); | 1359 __ lbu(A0, Address(S1, 2)); |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1391 | 1588 |
| 1392 void InterpreterGeneratorMIPS::InvokeCompare(const char* fallback, | 1589 void InterpreterGeneratorMIPS::InvokeCompare(const char* fallback, |
| 1393 Condition cond) { | 1590 Condition cond) { |
| 1394 LoadLocal(A0, 0); | 1591 LoadLocal(A0, 0); |
| 1395 __ andi(T0, A0, Immediate(Smi::kTagMask)); | 1592 __ andi(T0, A0, Immediate(Smi::kTagMask)); |
| 1396 __ B(NEQ, T0, ZR, fallback); | 1593 __ B(NEQ, T0, ZR, fallback); |
| 1397 LoadLocal(A1, 1); | 1594 LoadLocal(A1, 1); |
| 1398 __ andi(T0, A1, Immediate(Smi::kTagMask)); | 1595 __ andi(T0, A1, Immediate(Smi::kTagMask)); |
| 1399 __ B(NEQ, T0, ZR, fallback); | 1596 __ B(NEQ, T0, ZR, fallback); |
| 1400 | 1597 |
| 1401 Label true_case; | 1598 ToBoolean(A1, A0, cond, A2); |
| 1402 __ B(cond, A1, A0, &true_case); | 1599 DropNAndSetTop(1, A2); |
| 1403 | |
| 1404 DropNAndSetTop(1, S7); | |
| 1405 Dispatch(5); | 1600 Dispatch(5); |
| 1406 | 1601 |
| 1407 __ Bind(&true_case); | |
| 1408 DropNAndSetTop(1, S6); | 1602 DropNAndSetTop(1, S6); |
| 1409 Dispatch(5); | 1603 Dispatch(5); |
| 1410 } | 1604 } |
| 1411 | 1605 |
| 1412 void InterpreterGeneratorMIPS::ConditionalStore(Register cmp, | 1606 void InterpreterGeneratorMIPS::AddIf(Register reg1, Register reg2, |
| 1413 Register reg_if_eq, | 1607 Condition cond, Register dest, |
| 1414 Register reg_if_ne, | 1608 int add_if_eq) { |
| 1415 const Address& address) { | 1609 Label done, add; |
| 1416 Label if_ne, done; | 1610 __ B(cond, reg1, reg2, &add); |
|
erikcorry
2016/06/27 15:51:08
Optimization idea for a later CL: If the condition
petarj
2016/06/29 02:09:15
Thanks, will use in one of the later CLs.
| |
| 1417 __ B(NEQ, cmp, ZR, &if_ne); | 1611 __ B(&done); |
| 1418 __ b(&done); | 1612 __ Bind(&add); |
| 1419 __ sw(reg_if_eq, address); // Delay-slot. | 1613 __ addiu(dest, dest, Immediate(add_if_eq)); |
| 1420 __ Bind(&if_ne); | |
| 1421 __ sw(reg_if_ne, address); | |
| 1422 __ Bind(&done); | 1614 __ Bind(&done); |
| 1423 } | 1615 } |
| 1424 | 1616 |
| 1617 void InterpreterGeneratorMIPS::LoadTrue(Register reg) { | |
| 1618 __ addiu(reg, S4, Immediate(kTrueOffset)); | |
| 1619 } | |
| 1620 | |
| 1621 void InterpreterGeneratorMIPS::LoadFalse(Register reg) { | |
| 1622 __ addiu(reg, S4, Immediate(kFalseOffset)); | |
| 1623 } | |
| 1624 | |
| 1625 void InterpreterGeneratorMIPS::ToBoolean(Register reg1, | |
| 1626 Register reg2, | |
| 1627 Condition cond, | |
| 1628 Register reg) { | |
| 1629 LoadFalse(reg); | |
| 1630 AddIf(reg1, reg2, cond, reg, kTrueOffset - kFalseOffset); | |
| 1631 } | |
| 1632 | |
| 1425 void InterpreterGeneratorMIPS::CheckStackOverflow(int size) { | 1633 void InterpreterGeneratorMIPS::CheckStackOverflow(int size) { |
| 1426 __ lw(A1, Address(S0, Process::kStackLimitOffset)); | 1634 __ lw(A1, Address(S0, Process::kStackLimitOffset)); |
| 1427 __ sltu(T0, A1, S2); | 1635 __ sltu(T0, A1, S2); |
| 1428 if (size == 0) { | 1636 if (size == 0) { |
| 1429 __ B(EQ, T0, ZR, &check_stack_overflow_0_); | 1637 __ B(EQ, T0, ZR, &check_stack_overflow_0_); |
| 1430 } else { | 1638 } else { |
| 1431 Label done; | 1639 Label done; |
| 1432 __ B(GT, T0, ZR, &done); | 1640 __ B(GT, T0, ZR, &done); |
| 1433 __ b(&check_stack_overflow_); | 1641 __ b(&check_stack_overflow_); |
| 1434 __ ori(A0, ZR, Immediate(size)); // Delay-slot. | 1642 __ ori(A0, ZR, Immediate(size)); // Delay-slot. |
| 1435 __ Bind(&done); | 1643 __ Bind(&done); |
| 1436 } | 1644 } |
| 1437 } | 1645 } |
| 1438 | 1646 |
| 1439 void InterpreterGeneratorMIPS::Dispatch(int size) { | 1647 void InterpreterGeneratorMIPS::Dispatch(int size) { |
| 1440 __ lbu(S3, Address(S1, size)); | 1648 __ lbu(S3, Address(S1, size)); |
| 1441 if (size > 0) { | 1649 if (size > 0) { |
| 1442 __ addiu(S1, S1, Immediate(size)); | 1650 __ addiu(S1, S1, Immediate(size)); |
| 1443 } | 1651 } |
| 1444 __ la(S5, "Interpret_DispatchTable"); | 1652 ShiftAddJump(S7, S3, TIMES_WORD_SIZE); |
| 1445 ShiftAddJump(S5, S3, TIMES_WORD_SIZE); | |
| 1446 } | 1653 } |
| 1447 | 1654 |
| 1448 void InterpreterGeneratorMIPS::SaveState(Label* resume) { | 1655 void InterpreterGeneratorMIPS::SaveState(Label* resume) { |
| 1449 // Save the bytecode pointer at the return-address slot. | 1656 // Save the bytecode pointer at the return-address slot. |
| 1450 LoadFramePointer(A3); | 1657 LoadFramePointer(A3); |
| 1451 __ sw(S1, Address(A3, -kWordSize)); | 1658 __ sw(S1, Address(A3, -kWordSize)); |
| 1452 | 1659 |
| 1453 // Push resume address. | 1660 // Push resume address. |
| 1454 __ la(S1, resume); | 1661 __ la(S1, resume); |
| 1455 | 1662 |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 1470 void InterpreterGeneratorMIPS::RestoreState() { | 1677 void InterpreterGeneratorMIPS::RestoreState() { |
| 1471 // Load the current stack pointer into S2. | 1678 // Load the current stack pointer into S2. |
| 1472 __ lw(S2, Address(S0, Process::kCoroutineOffset)); | 1679 __ lw(S2, Address(S0, Process::kCoroutineOffset)); |
| 1473 __ lw(S2, Address(S2, Coroutine::kStackOffset - HeapObject::kTag)); | 1680 __ lw(S2, Address(S2, Coroutine::kStackOffset - HeapObject::kTag)); |
| 1474 __ lw(S1, Address(S2, Stack::kTopOffset - HeapObject::kTag)); | 1681 __ lw(S1, Address(S2, Stack::kTopOffset - HeapObject::kTag)); |
| 1475 __ addiu(S2, S2, Immediate(Stack::kSize - HeapObject::kTag)); | 1682 __ addiu(S2, S2, Immediate(Stack::kSize - HeapObject::kTag)); |
| 1476 ShiftAdd(S2, S2, S1, TIMES_2); | 1683 ShiftAdd(S2, S2, S1, TIMES_2); |
| 1477 | 1684 |
| 1478 // Load constants into registers. | 1685 // Load constants into registers. |
| 1479 __ lw(S6, Address(S0, Process::kProgramOffset)); | 1686 __ lw(S6, Address(S0, Process::kProgramOffset)); |
| 1480 __ lw(S7, Address(S6, Program::kFalseObjectOffset)); | |
| 1481 __ lw(S4, Address(S6, Program::kNullObjectOffset)); | 1687 __ lw(S4, Address(S6, Program::kNullObjectOffset)); |
| 1482 __ lw(S6, Address(S6, Program::kTrueObjectOffset)); | 1688 __ la(S7, "Interpret_DispatchTable"); |
| 1483 | 1689 |
| 1484 // Pop and store frame pointer. | 1690 // Pop and store frame pointer. |
| 1485 Pop(S1); | 1691 Pop(S1); |
| 1486 StoreFramePointer(S1); | 1692 StoreFramePointer(S1); |
| 1487 // Set the bytecode pointer from the stack. | 1693 // Set the bytecode pointer from the stack. |
| 1488 __ lw(S1, Address(S1, -kWordSize)); | 1694 __ lw(S1, Address(S1, -kWordSize)); |
| 1489 | 1695 |
| 1490 // Pop and branch to resume address. | 1696 // Pop and branch to resume address. |
| 1491 Pop(RA); | 1697 Pop(RA); |
| 1492 | 1698 |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1576 __ addiu(SP, SP, Immediate(-6 * kWordSize)); | 1782 __ addiu(SP, SP, Immediate(-6 * kWordSize)); |
| 1577 __ sw(GP, Address(SP, 5 * kWordSize)); | 1783 __ sw(GP, Address(SP, 5 * kWordSize)); |
| 1578 } | 1784 } |
| 1579 | 1785 |
| 1580 void InterpreterGeneratorMIPS::RestoreStack() { | 1786 void InterpreterGeneratorMIPS::RestoreStack() { |
| 1581 __ lw(GP, Address(SP, 5 * kWordSize)); | 1787 __ lw(GP, Address(SP, 5 * kWordSize)); |
| 1582 __ addiu(SP, SP, Immediate(6 * kWordSize)); | 1788 __ addiu(SP, SP, Immediate(6 * kWordSize)); |
| 1583 } | 1789 } |
| 1584 } // namespace dartino | 1790 } // namespace dartino |
| 1585 #endif // defined DARTINO_TARGET_MIPS | 1791 #endif // defined DARTINO_TARGET_MIPS |
| OLD | NEW |