| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart 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 file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef VM_ASSEMBLER_ARM64_H_ | 5 #ifndef VM_ASSEMBLER_ARM64_H_ |
| 6 #define VM_ASSEMBLER_ARM64_H_ | 6 #define VM_ASSEMBLER_ARM64_H_ |
| 7 | 7 |
| 8 #ifndef VM_ASSEMBLER_H_ | 8 #ifndef VM_ASSEMBLER_H_ |
| 9 #error Do not include assembler_arm64.h directly; use assembler.h instead. | 9 #error Do not include assembler_arm64.h directly; use assembler.h instead. |
| 10 #endif | 10 #endif |
| (...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 403 | 403 |
| 404 // Emit data (e.g encoded instruction or immediate) in instruction stream. | 404 // Emit data (e.g encoded instruction or immediate) in instruction stream. |
| 405 void Emit(int32_t value); | 405 void Emit(int32_t value); |
| 406 | 406 |
| 407 // On some other platforms, we draw a distinction between safe and unsafe | 407 // On some other platforms, we draw a distinction between safe and unsafe |
| 408 // smis. | 408 // smis. |
| 409 static bool IsSafe(const Object& object) { return true; } | 409 static bool IsSafe(const Object& object) { return true; } |
| 410 static bool IsSafeSmi(const Object& object) { return object.IsSmi(); } | 410 static bool IsSafeSmi(const Object& object) { return object.IsSmi(); } |
| 411 | 411 |
| 412 // Addition and subtraction. | 412 // Addition and subtraction. |
| 413 // For add and sub, to use SP for rn, o must be of type Operand::Extend. |
| 414 // For an unmodified rm in this case, use Operand(rm, UXTX, 0); |
| 413 void add(Register rd, Register rn, Operand o) { | 415 void add(Register rd, Register rn, Operand o) { |
| 414 AddSubHelper(kDoubleWord, false, false, rd, rn, o); | 416 AddSubHelper(kDoubleWord, false, false, rd, rn, o); |
| 415 } | 417 } |
| 416 void adds(Register rd, Register rn, Operand o) { | 418 void adds(Register rd, Register rn, Operand o) { |
| 417 AddSubHelper(kDoubleWord, true, false, rd, rn, o); | 419 AddSubHelper(kDoubleWord, true, false, rd, rn, o); |
| 418 } | 420 } |
| 419 void addw(Register rd, Register rn, Operand o) { | 421 void addw(Register rd, Register rn, Operand o) { |
| 420 AddSubHelper(kWord, false, false, rd, rn, o); | 422 AddSubHelper(kWord, false, false, rd, rn, o); |
| 421 } | 423 } |
| 422 void sub(Register rd, Register rn, Operand o) { | 424 void sub(Register rd, Register rn, Operand o) { |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 535 (rt != a.base())); | 537 (rt != a.base())); |
| 536 EmitLoadStoreReg(LDR, rt, a, kDoubleWord); | 538 EmitLoadStoreReg(LDR, rt, a, kDoubleWord); |
| 537 } | 539 } |
| 538 } | 540 } |
| 539 void str(Register rt, Address a) { | 541 void str(Register rt, Address a) { |
| 540 EmitLoadStoreReg(STR, rt, a, kDoubleWord); | 542 EmitLoadStoreReg(STR, rt, a, kDoubleWord); |
| 541 } | 543 } |
| 542 | 544 |
| 543 // Comparison. | 545 // Comparison. |
| 544 // rn cmp o. | 546 // rn cmp o. |
| 547 // For add and sub, to use SP for rn, o must be of type Operand::Extend. |
| 548 // For an unmodified rm in this case, use Operand(rm, UXTX, 0); |
| 545 void cmp(Register rn, Operand o) { | 549 void cmp(Register rn, Operand o) { |
| 546 subs(ZR, rn, o); | 550 subs(ZR, rn, o); |
| 547 } | 551 } |
| 548 // rn cmp -o. | 552 // rn cmp -o. |
| 549 void cmn(Register rn, Operand o) { | 553 void cmn(Register rn, Operand o) { |
| 550 adds(ZR, rn, o); | 554 adds(ZR, rn, o); |
| 551 } | 555 } |
| 552 | 556 |
| 557 void CompareRegisters(Register rn, Register rm) { |
| 558 if (rn == SP) { |
| 559 // UXTX 0 on a 64-bit register (rm) is a nop, but forces R31 to be |
| 560 // interpreted as SP. |
| 561 cmp(SP, Operand(rm, UXTX, 0)); |
| 562 } else { |
| 563 cmp(rn, Operand(rm)); |
| 564 } |
| 565 } |
| 566 |
| 553 // Conditional branch. | 567 // Conditional branch. |
| 554 void b(Label* label, Condition cond = AL) { | 568 void b(Label* label, Condition cond = AL) { |
| 555 EmitBranch(BCOND, cond, label); | 569 EmitBranch(BCOND, cond, label); |
| 556 } | 570 } |
| 557 | 571 |
| 558 // TODO(zra): branch and link with imm26 offset. | 572 // TODO(zra): branch and link with imm26 offset. |
| 559 // TODO(zra): cbz, cbnz. | 573 // TODO(zra): cbz, cbnz. |
| 560 | 574 |
| 561 // Branch, link, return. | 575 // Branch, link, return. |
| 562 void br(Register rn) { | 576 void br(Register rn) { |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 626 } | 640 } |
| 627 void Asr(Register rd, Register rn, int shift) { | 641 void Asr(Register rd, Register rn, int shift) { |
| 628 add(rd, ZR, Operand(rn, ASR, shift)); | 642 add(rd, ZR, Operand(rn, ASR, shift)); |
| 629 } | 643 } |
| 630 | 644 |
| 631 void SmiUntag(Register reg) { | 645 void SmiUntag(Register reg) { |
| 632 Asr(reg, reg, kSmiTagSize); | 646 Asr(reg, reg, kSmiTagSize); |
| 633 } | 647 } |
| 634 | 648 |
| 635 // Branching to ExternalLabels. | 649 // Branching to ExternalLabels. |
| 636 void Branch(const ExternalLabel* label) { | 650 void BranchPatchable(const ExternalLabel* label, Register pp) { |
| 637 LoadExternalLabel(TMP, label, kPatchable, PP); | 651 LoadExternalLabel(TMP, label, kPatchable, pp); |
| 638 br(TMP); | 652 br(TMP); |
| 639 } | 653 } |
| 640 | 654 |
| 641 void BranchPatchable(const ExternalLabel* label) { | 655 void Branch(const ExternalLabel* label, Register pp) { |
| 642 LoadPatchableImmediate(TMP, label->address()); | 656 LoadExternalLabel(TMP, label, kNotPatchable, pp); |
| 657 br(TMP); |
| 658 } |
| 659 |
| 660 // Fixed length branch to label. |
| 661 void BranchFixed(const ExternalLabel* label) { |
| 662 LoadImmediateFixed(TMP, label->address()); |
| 643 br(TMP); | 663 br(TMP); |
| 644 } | 664 } |
| 645 | 665 |
| 646 void BranchLink(const ExternalLabel* label, Register pp) { | 666 void BranchLink(const ExternalLabel* label, Register pp) { |
| 647 if (Isolate::Current() == Dart::vm_isolate()) { | 667 if (Isolate::Current() == Dart::vm_isolate()) { |
| 648 LoadImmediate(TMP, label->address(), kNoRegister); | 668 LoadImmediate(TMP, label->address(), kNoRegister); |
| 649 blr(TMP); | 669 blr(TMP); |
| 650 } else { | 670 } else { |
| 651 LoadExternalLabel(TMP, label, kNotPatchable, pp); | 671 LoadExternalLabel(TMP, label, kNotPatchable, pp); |
| 652 blr(TMP); | 672 blr(TMP); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 697 intptr_t FindExternalLabel(const ExternalLabel* label, | 717 intptr_t FindExternalLabel(const ExternalLabel* label, |
| 698 Patchability patchable); | 718 Patchability patchable); |
| 699 intptr_t FindObject(const Object& obj, Patchability patchable); | 719 intptr_t FindObject(const Object& obj, Patchability patchable); |
| 700 intptr_t FindImmediate(int64_t imm); | 720 intptr_t FindImmediate(int64_t imm); |
| 701 bool CanLoadObjectFromPool(const Object& object); | 721 bool CanLoadObjectFromPool(const Object& object); |
| 702 bool CanLoadImmediateFromPool(int64_t imm, Register pp); | 722 bool CanLoadImmediateFromPool(int64_t imm, Register pp); |
| 703 void LoadExternalLabel(Register dst, const ExternalLabel* label, | 723 void LoadExternalLabel(Register dst, const ExternalLabel* label, |
| 704 Patchability patchable, Register pp); | 724 Patchability patchable, Register pp); |
| 705 void LoadObject(Register dst, const Object& obj, Register pp); | 725 void LoadObject(Register dst, const Object& obj, Register pp); |
| 706 void LoadDecodableImmediate(Register reg, int64_t imm, Register pp); | 726 void LoadDecodableImmediate(Register reg, int64_t imm, Register pp); |
| 707 void LoadPatchableImmediate(Register reg, int64_t imm); | 727 void LoadImmediateFixed(Register reg, int64_t imm); |
| 708 void LoadImmediate(Register reg, int64_t imm, Register pp); | 728 void LoadImmediate(Register reg, int64_t imm, Register pp); |
| 709 | 729 |
| 710 void PushObject(const Object& object, Register pp) { | 730 void PushObject(const Object& object, Register pp) { |
| 711 LoadObject(TMP, object, pp); | 731 LoadObject(TMP, object, pp); |
| 712 Push(TMP); | 732 Push(TMP); |
| 713 } | 733 } |
| 714 | 734 |
| 715 void EnterFrame(intptr_t frame_size); | 735 void EnterFrame(intptr_t frame_size); |
| 716 void LeaveFrame(); | 736 void LeaveFrame(); |
| 717 | 737 |
| 718 void EnterDartFrame(intptr_t frame_size); | 738 void EnterDartFrame(intptr_t frame_size); |
| 739 void EnterDartFrameWithInfo(intptr_t frame_size, Register new_pp); |
| 740 void EnterOsrFrame(intptr_t extra_size, Register new_pp); |
| 719 void LeaveDartFrame(); | 741 void LeaveDartFrame(); |
| 720 | 742 |
| 721 void EnterCallRuntimeFrame(intptr_t frame_size); | 743 void EnterCallRuntimeFrame(intptr_t frame_size); |
| 722 void LeaveCallRuntimeFrame(); | 744 void LeaveCallRuntimeFrame(); |
| 723 | 745 |
| 724 void CallRuntime(const RuntimeEntry& entry, intptr_t argument_count); | 746 void CallRuntime(const RuntimeEntry& entry, intptr_t argument_count); |
| 725 | 747 |
| 726 private: | 748 private: |
| 727 AssemblerBuffer buffer_; // Contains position independent code. | 749 AssemblerBuffer buffer_; // Contains position independent code. |
| 728 | 750 |
| (...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1034 Register value, | 1056 Register value, |
| 1035 Label* no_update); | 1057 Label* no_update); |
| 1036 | 1058 |
| 1037 DISALLOW_ALLOCATION(); | 1059 DISALLOW_ALLOCATION(); |
| 1038 DISALLOW_COPY_AND_ASSIGN(Assembler); | 1060 DISALLOW_COPY_AND_ASSIGN(Assembler); |
| 1039 }; | 1061 }; |
| 1040 | 1062 |
| 1041 } // namespace dart | 1063 } // namespace dart |
| 1042 | 1064 |
| 1043 #endif // VM_ASSEMBLER_ARM64_H_ | 1065 #endif // VM_ASSEMBLER_ARM64_H_ |
| OLD | NEW |