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