| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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_ARM_H_ | 5 #ifndef VM_ASSEMBLER_ARM_H_ |
| 6 #define VM_ASSEMBLER_ARM_H_ | 6 #define VM_ASSEMBLER_ARM_H_ |
| 7 | 7 |
| 8 #ifndef VM_ASSEMBLER_H_ | 8 #ifndef VM_ASSEMBLER_H_ |
| 9 #error Do not include assembler_arm.h directly; use assembler.h instead. | 9 #error Do not include assembler_arm.h directly; use assembler.h instead. |
| 10 #endif | 10 #endif |
| (...skipping 588 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 599 // The words of qd and qm are interleaved with the low words of the result | 599 // The words of qd and qm are interleaved with the low words of the result |
| 600 // in qd and the high words in qm. | 600 // in qd and the high words in qm. |
| 601 void vzipqw(QRegister qd, QRegister qm); | 601 void vzipqw(QRegister qd, QRegister qm); |
| 602 | 602 |
| 603 // Branch instructions. | 603 // Branch instructions. |
| 604 void b(Label* label, Condition cond = AL); | 604 void b(Label* label, Condition cond = AL); |
| 605 void bl(Label* label, Condition cond = AL); | 605 void bl(Label* label, Condition cond = AL); |
| 606 void bx(Register rm, Condition cond = AL); | 606 void bx(Register rm, Condition cond = AL); |
| 607 void blx(Register rm, Condition cond = AL); | 607 void blx(Register rm, Condition cond = AL); |
| 608 | 608 |
| 609 void Branch(const StubEntry& stub_entry, | 609 // Macros. |
| 610 Patchability patchable = kNotPatchable, | 610 // Branch to an entry address. Call sequence is never patched. |
| 611 Register pp = PP, | 611 void Branch(const StubEntry& stub_entry, Condition cond = AL); |
| 612 Condition cond = AL); | 612 |
| 613 // Branch to an entry address. Call sequence can be patched or even replaced. |
| 614 void BranchPatchable(const StubEntry& stub_entry); |
| 613 | 615 |
| 614 void BranchLink(const StubEntry& stub_entry, | 616 void BranchLink(const StubEntry& stub_entry, |
| 615 Patchability patchable = kNotPatchable); | 617 Patchability patchable = kNotPatchable); |
| 616 void BranchLink(const Code& code, Patchability patchable); | 618 void BranchLink(const ExternalLabel* label, Patchability patchable); |
| 617 | 619 |
| 618 // Branch and link to an entry address. Call sequence can be patched. | 620 // Branch and link to an entry address. Call sequence can be patched. |
| 619 void BranchLinkPatchable(const StubEntry& stub_entry); | 621 void BranchLinkPatchable(const StubEntry& stub_entry); |
| 620 void BranchLinkPatchable(const Code& code); | |
| 621 | 622 |
| 622 // Branch and link to [base + offset]. Call sequence is never patched. | 623 // Branch and link to [base + offset]. Call sequence is never patched. |
| 623 void BranchLinkOffset(Register base, int32_t offset); | 624 void BranchLinkOffset(Register base, int32_t offset); |
| 624 | 625 |
| 625 // Add signed immediate value to rd. May clobber IP. | 626 // Add signed immediate value to rd. May clobber IP. |
| 626 void AddImmediate(Register rd, int32_t value, Condition cond = AL); | 627 void AddImmediate(Register rd, int32_t value, Condition cond = AL); |
| 627 void AddImmediate(Register rd, Register rn, int32_t value, | 628 void AddImmediate(Register rd, Register rn, int32_t value, |
| 628 Condition cond = AL); | 629 Condition cond = AL); |
| 629 void AddImmediateSetFlags(Register rd, Register rn, int32_t value, | 630 void AddImmediateSetFlags(Register rd, Register rn, int32_t value, |
| 630 Condition cond = AL); | 631 Condition cond = AL); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 653 void LoadImmediate(Register rd, int32_t value, Condition cond = AL); | 654 void LoadImmediate(Register rd, int32_t value, Condition cond = AL); |
| 654 // These two may clobber IP. | 655 // These two may clobber IP. |
| 655 void LoadSImmediate(SRegister sd, float value, Condition cond = AL); | 656 void LoadSImmediate(SRegister sd, float value, Condition cond = AL); |
| 656 void LoadDImmediate(DRegister dd, double value, | 657 void LoadDImmediate(DRegister dd, double value, |
| 657 Register scratch, Condition cond = AL); | 658 Register scratch, Condition cond = AL); |
| 658 | 659 |
| 659 void MarkExceptionHandler(Label* label); | 660 void MarkExceptionHandler(Label* label); |
| 660 | 661 |
| 661 void Drop(intptr_t stack_elements); | 662 void Drop(intptr_t stack_elements); |
| 662 | 663 |
| 663 void RestoreCodePointer(); | 664 void LoadPoolPointer(); |
| 664 void LoadPoolPointer(Register reg = PP); | |
| 665 | 665 |
| 666 void LoadIsolate(Register rd); | 666 void LoadIsolate(Register rd); |
| 667 | 667 |
| 668 void LoadObject(Register rd, const Object& object, Condition cond = AL); | 668 void LoadObject(Register rd, const Object& object, Condition cond = AL); |
| 669 void LoadUniqueObject(Register rd, const Object& object, Condition cond = AL); | 669 void LoadUniqueObject(Register rd, const Object& object, Condition cond = AL); |
| 670 void LoadExternalLabel(Register dst, | 670 void LoadExternalLabel(Register dst, |
| 671 const ExternalLabel* label, | 671 const ExternalLabel* label, |
| 672 Patchability patchable, | 672 Patchability patchable, |
| 673 Condition cond = AL); | 673 Condition cond = AL); |
| 674 void LoadFunctionFromCalleePool(Register dst, | |
| 675 const Function& function, | |
| 676 Register new_pp); | |
| 677 void LoadNativeEntry(Register dst, | 674 void LoadNativeEntry(Register dst, |
| 678 const ExternalLabel* label, | 675 const ExternalLabel* label, |
| 679 Patchability patchable, | 676 Patchability patchable, |
| 680 Condition cond = AL); | 677 Condition cond = AL); |
| 681 void PushObject(const Object& object); | 678 void PushObject(const Object& object); |
| 682 void CompareObject(Register rn, const Object& object); | 679 void CompareObject(Register rn, const Object& object); |
| 683 | 680 |
| 684 // When storing into a heap object field, knowledge of the previous content | 681 // When storing into a heap object field, knowledge of the previous content |
| 685 // is expressed through these constants. | 682 // is expressed through these constants. |
| 686 enum FieldContent { | 683 enum FieldContent { |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 867 // Untag the value in the register assuming it is a smi. | 864 // Untag the value in the register assuming it is a smi. |
| 868 // Untagging shifts tag bit into the carry flag - if carry is clear | 865 // Untagging shifts tag bit into the carry flag - if carry is clear |
| 869 // assumption was correct. In this case jump to the is_smi label. | 866 // assumption was correct. In this case jump to the is_smi label. |
| 870 // Otherwise fall-through. | 867 // Otherwise fall-through. |
| 871 void SmiUntag(Register dst, Register src, Label* is_smi) { | 868 void SmiUntag(Register dst, Register src, Label* is_smi) { |
| 872 ASSERT(kSmiTagSize == 1); | 869 ASSERT(kSmiTagSize == 1); |
| 873 Asrs(dst, src, Operand(kSmiTagSize)); | 870 Asrs(dst, src, Operand(kSmiTagSize)); |
| 874 b(is_smi, CC); | 871 b(is_smi, CC); |
| 875 } | 872 } |
| 876 | 873 |
| 877 void CheckCodePointer(); | |
| 878 | |
| 879 // Function frame setup and tear down. | 874 // Function frame setup and tear down. |
| 880 void EnterFrame(RegList regs, intptr_t frame_space); | 875 void EnterFrame(RegList regs, intptr_t frame_space); |
| 881 void LeaveFrame(RegList regs); | 876 void LeaveFrame(RegList regs); |
| 882 void Ret(); | 877 void Ret(); |
| 883 void ReserveAlignedFrameSpace(intptr_t frame_space); | 878 void ReserveAlignedFrameSpace(intptr_t frame_space); |
| 884 | 879 |
| 885 // Create a frame for calling into runtime that preserves all volatile | 880 // Create a frame for calling into runtime that preserves all volatile |
| 886 // registers. Frame's SP is guaranteed to be correctly aligned and | 881 // registers. Frame's SP is guaranteed to be correctly aligned and |
| 887 // frame_space bytes are reserved under it. | 882 // frame_space bytes are reserved under it. |
| 888 void EnterCallRuntimeFrame(intptr_t frame_space); | 883 void EnterCallRuntimeFrame(intptr_t frame_space); |
| 889 void LeaveCallRuntimeFrame(); | 884 void LeaveCallRuntimeFrame(); |
| 890 | 885 |
| 891 void CallRuntime(const RuntimeEntry& entry, intptr_t argument_count); | 886 void CallRuntime(const RuntimeEntry& entry, intptr_t argument_count); |
| 892 | 887 |
| 893 // Set up a Dart frame on entry with a frame pointer and PC information to | 888 // Set up a Dart frame on entry with a frame pointer and PC information to |
| 894 // enable easy access to the RawInstruction object of code corresponding | 889 // enable easy access to the RawInstruction object of code corresponding |
| 895 // to this frame. | 890 // to this frame. |
| 896 void EnterDartFrame(intptr_t frame_size); | 891 void EnterDartFrame(intptr_t frame_size); |
| 897 void LeaveDartFrame(RestorePP restore_pp = kRestoreCallerPP); | 892 void LeaveDartFrame(); |
| 898 | 893 |
| 899 // Set up a Dart frame for a function compiled for on-stack replacement. | 894 // Set up a Dart frame for a function compiled for on-stack replacement. |
| 900 // The frame layout is a normal Dart frame, but the frame is partially set | 895 // The frame layout is a normal Dart frame, but the frame is partially set |
| 901 // up on entry (it is the frame of the unoptimized code). | 896 // up on entry (it is the frame of the unoptimized code). |
| 902 void EnterOsrFrame(intptr_t extra_size); | 897 void EnterOsrFrame(intptr_t extra_size); |
| 903 | 898 |
| 904 // Set up a stub frame so that the stack traversal code can easily identify | 899 // Set up a stub frame so that the stack traversal code can easily identify |
| 905 // a stub frame. | 900 // a stub frame. |
| 906 void EnterStubFrame(); | 901 void EnterStubFrame(); |
| 907 void LeaveStubFrame(); | 902 void LeaveStubFrame(); |
| 908 | 903 |
| 904 // Instruction pattern from entrypoint is used in Dart frame prologs |
| 905 // to set up the frame and save a PC which can be used to figure out the |
| 906 // RawInstruction object corresponding to the code running in the frame. |
| 907 static intptr_t EntryPointToPcMarkerOffset() { |
| 908 return TargetCPUFeatures::store_pc_read_offset(); |
| 909 } |
| 910 |
| 909 // The register into which the allocation stats table is loaded with | 911 // The register into which the allocation stats table is loaded with |
| 910 // LoadAllocationStatsAddress should be passed to | 912 // LoadAllocationStatsAddress should be passed to |
| 911 // IncrementAllocationStats(WithSize) as stats_addr_reg to update the | 913 // IncrementAllocationStats(WithSize) as stats_addr_reg to update the |
| 912 // allocation stats. These are separate assembler macros so we can | 914 // allocation stats. These are separate assembler macros so we can |
| 913 // avoid a dependent load too nearby the load of the table address. | 915 // avoid a dependent load too nearby the load of the table address. |
| 914 void LoadAllocationStatsAddress(Register dest, | 916 void LoadAllocationStatsAddress(Register dest, |
| 915 intptr_t cid, | 917 intptr_t cid, |
| 916 bool inline_isolate = true); | 918 bool inline_isolate = true); |
| 917 void IncrementAllocationStats(Register stats_addr, | 919 void IncrementAllocationStats(Register stats_addr, |
| 918 intptr_t cid, | 920 intptr_t cid, |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 984 bool use_far_branches_; | 986 bool use_far_branches_; |
| 985 | 987 |
| 986 // If you are thinking of using one or both of these instructions directly, | 988 // If you are thinking of using one or both of these instructions directly, |
| 987 // instead LoadImmediate should probably be used. | 989 // instead LoadImmediate should probably be used. |
| 988 void movw(Register rd, uint16_t imm16, Condition cond = AL); | 990 void movw(Register rd, uint16_t imm16, Condition cond = AL); |
| 989 void movt(Register rd, uint16_t imm16, Condition cond = AL); | 991 void movt(Register rd, uint16_t imm16, Condition cond = AL); |
| 990 | 992 |
| 991 void BindARMv6(Label* label); | 993 void BindARMv6(Label* label); |
| 992 void BindARMv7(Label* label); | 994 void BindARMv7(Label* label); |
| 993 | 995 |
| 994 void LoadWordFromPoolOffset(Register rd, | 996 void BranchLink(const ExternalLabel* label); |
| 995 int32_t offset, | |
| 996 Register pp, | |
| 997 Condition cond); | |
| 998 | 997 |
| 999 void BranchLink(const ExternalLabel* label); | 998 void LoadWordFromPoolOffset(Register rd, int32_t offset, Condition cond); |
| 1000 | 999 |
| 1001 class CodeComment : public ZoneAllocated { | 1000 class CodeComment : public ZoneAllocated { |
| 1002 public: | 1001 public: |
| 1003 CodeComment(intptr_t pc_offset, const String& comment) | 1002 CodeComment(intptr_t pc_offset, const String& comment) |
| 1004 : pc_offset_(pc_offset), comment_(comment) { } | 1003 : pc_offset_(pc_offset), comment_(comment) { } |
| 1005 | 1004 |
| 1006 intptr_t pc_offset() const { return pc_offset_; } | 1005 intptr_t pc_offset() const { return pc_offset_; } |
| 1007 const String& comment() const { return comment_; } | 1006 const String& comment() const { return comment_; } |
| 1008 | 1007 |
| 1009 private: | 1008 private: |
| 1010 intptr_t pc_offset_; | 1009 intptr_t pc_offset_; |
| 1011 const String& comment_; | 1010 const String& comment_; |
| 1012 | 1011 |
| 1013 DISALLOW_COPY_AND_ASSIGN(CodeComment); | 1012 DISALLOW_COPY_AND_ASSIGN(CodeComment); |
| 1014 }; | 1013 }; |
| 1015 | 1014 |
| 1016 GrowableArray<CodeComment*> comments_; | 1015 GrowableArray<CodeComment*> comments_; |
| 1017 | 1016 |
| 1018 bool constant_pool_allowed_; | 1017 bool constant_pool_allowed_; |
| 1019 | 1018 |
| 1020 void LoadObjectHelper(Register rd, | 1019 void LoadObjectHelper(Register rd, |
| 1021 const Object& object, | 1020 const Object& object, |
| 1022 Condition cond, | 1021 Condition cond, |
| 1023 bool is_unique, | 1022 bool is_unique); |
| 1024 Register pp); | |
| 1025 | 1023 |
| 1026 void EmitType01(Condition cond, | 1024 void EmitType01(Condition cond, |
| 1027 int type, | 1025 int type, |
| 1028 Opcode opcode, | 1026 Opcode opcode, |
| 1029 int set_cc, | 1027 int set_cc, |
| 1030 Register rn, | 1028 Register rn, |
| 1031 Register rd, | 1029 Register rd, |
| 1032 Operand o); | 1030 Operand o); |
| 1033 | 1031 |
| 1034 void EmitType5(Condition cond, int32_t offset, bool link); | 1032 void EmitType5(Condition cond, int32_t offset, bool link); |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1151 Register new_value, | 1149 Register new_value, |
| 1152 FieldContent old_content); | 1150 FieldContent old_content); |
| 1153 | 1151 |
| 1154 DISALLOW_ALLOCATION(); | 1152 DISALLOW_ALLOCATION(); |
| 1155 DISALLOW_COPY_AND_ASSIGN(Assembler); | 1153 DISALLOW_COPY_AND_ASSIGN(Assembler); |
| 1156 }; | 1154 }; |
| 1157 | 1155 |
| 1158 } // namespace dart | 1156 } // namespace dart |
| 1159 | 1157 |
| 1160 #endif // VM_ASSEMBLER_ARM_H_ | 1158 #endif // VM_ASSEMBLER_ARM_H_ |
| OLD | NEW |