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

Side by Side Diff: src/vm/interpreter_mips.cc

Issue 2088133005: [mips] implement enough bytecodes to run hello.dart (Closed) Base URL: git@github.com:dartino/sdk.git@master
Patch Set: Created 4 years, 6 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 | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698