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 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
864 // Untag the value in the register assuming it is a smi. | 867 // Untag the value in the register assuming it is a smi. |
865 // Untagging shifts tag bit into the carry flag - if carry is clear | 868 // Untagging shifts tag bit into the carry flag - if carry is clear |
866 // assumption was correct. In this case jump to the is_smi label. | 869 // assumption was correct. In this case jump to the is_smi label. |
867 // Otherwise fall-through. | 870 // Otherwise fall-through. |
868 void SmiUntag(Register dst, Register src, Label* is_smi) { | 871 void SmiUntag(Register dst, Register src, Label* is_smi) { |
869 ASSERT(kSmiTagSize == 1); | 872 ASSERT(kSmiTagSize == 1); |
870 Asrs(dst, src, Operand(kSmiTagSize)); | 873 Asrs(dst, src, Operand(kSmiTagSize)); |
871 b(is_smi, CC); | 874 b(is_smi, CC); |
872 } | 875 } |
873 | 876 |
| 877 void CheckCodePointer(); |
| 878 |
874 // Function frame setup and tear down. | 879 // Function frame setup and tear down. |
875 void EnterFrame(RegList regs, intptr_t frame_space); | 880 void EnterFrame(RegList regs, intptr_t frame_space); |
876 void LeaveFrame(RegList regs); | 881 void LeaveFrame(RegList regs); |
877 void Ret(); | 882 void Ret(); |
878 void ReserveAlignedFrameSpace(intptr_t frame_space); | 883 void ReserveAlignedFrameSpace(intptr_t frame_space); |
879 | 884 |
880 // Create a frame for calling into runtime that preserves all volatile | 885 // Create a frame for calling into runtime that preserves all volatile |
881 // registers. Frame's SP is guaranteed to be correctly aligned and | 886 // registers. Frame's SP is guaranteed to be correctly aligned and |
882 // frame_space bytes are reserved under it. | 887 // frame_space bytes are reserved under it. |
883 void EnterCallRuntimeFrame(intptr_t frame_space); | 888 void EnterCallRuntimeFrame(intptr_t frame_space); |
884 void LeaveCallRuntimeFrame(); | 889 void LeaveCallRuntimeFrame(); |
885 | 890 |
886 void CallRuntime(const RuntimeEntry& entry, intptr_t argument_count); | 891 void CallRuntime(const RuntimeEntry& entry, intptr_t argument_count); |
887 | 892 |
888 // Set up a Dart frame on entry with a frame pointer and PC information to | 893 // Set up a Dart frame on entry with a frame pointer and PC information to |
889 // enable easy access to the RawInstruction object of code corresponding | 894 // enable easy access to the RawInstruction object of code corresponding |
890 // to this frame. | 895 // to this frame. |
891 void EnterDartFrame(intptr_t frame_size); | 896 void EnterDartFrame(intptr_t frame_size); |
892 void LeaveDartFrame(); | 897 void LeaveDartFrame(RestorePP restore_pp = kRestoreCallerPP); |
893 | 898 |
894 // Set up a Dart frame for a function compiled for on-stack replacement. | 899 // Set up a Dart frame for a function compiled for on-stack replacement. |
895 // The frame layout is a normal Dart frame, but the frame is partially set | 900 // The frame layout is a normal Dart frame, but the frame is partially set |
896 // up on entry (it is the frame of the unoptimized code). | 901 // up on entry (it is the frame of the unoptimized code). |
897 void EnterOsrFrame(intptr_t extra_size); | 902 void EnterOsrFrame(intptr_t extra_size); |
898 | 903 |
899 // Set up a stub frame so that the stack traversal code can easily identify | 904 // Set up a stub frame so that the stack traversal code can easily identify |
900 // a stub frame. | 905 // a stub frame. |
901 void EnterStubFrame(); | 906 void EnterStubFrame(); |
902 void LeaveStubFrame(); | 907 void LeaveStubFrame(); |
903 | 908 |
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 | |
911 // The register into which the allocation stats table is loaded with | 909 // The register into which the allocation stats table is loaded with |
912 // LoadAllocationStatsAddress should be passed to | 910 // LoadAllocationStatsAddress should be passed to |
913 // IncrementAllocationStats(WithSize) as stats_addr_reg to update the | 911 // IncrementAllocationStats(WithSize) as stats_addr_reg to update the |
914 // allocation stats. These are separate assembler macros so we can | 912 // allocation stats. These are separate assembler macros so we can |
915 // avoid a dependent load too nearby the load of the table address. | 913 // avoid a dependent load too nearby the load of the table address. |
916 void LoadAllocationStatsAddress(Register dest, | 914 void LoadAllocationStatsAddress(Register dest, |
917 intptr_t cid, | 915 intptr_t cid, |
918 bool inline_isolate = true); | 916 bool inline_isolate = true); |
919 void IncrementAllocationStats(Register stats_addr, | 917 void IncrementAllocationStats(Register stats_addr, |
920 intptr_t cid, | 918 intptr_t cid, |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
986 bool use_far_branches_; | 984 bool use_far_branches_; |
987 | 985 |
988 // If you are thinking of using one or both of these instructions directly, | 986 // If you are thinking of using one or both of these instructions directly, |
989 // instead LoadImmediate should probably be used. | 987 // instead LoadImmediate should probably be used. |
990 void movw(Register rd, uint16_t imm16, Condition cond = AL); | 988 void movw(Register rd, uint16_t imm16, Condition cond = AL); |
991 void movt(Register rd, uint16_t imm16, Condition cond = AL); | 989 void movt(Register rd, uint16_t imm16, Condition cond = AL); |
992 | 990 |
993 void BindARMv6(Label* label); | 991 void BindARMv6(Label* label); |
994 void BindARMv7(Label* label); | 992 void BindARMv7(Label* label); |
995 | 993 |
| 994 void LoadWordFromPoolOffset(Register rd, |
| 995 int32_t offset, |
| 996 Register pp, |
| 997 Condition cond); |
| 998 |
996 void BranchLink(const ExternalLabel* label); | 999 void BranchLink(const ExternalLabel* label); |
997 | 1000 |
998 void LoadWordFromPoolOffset(Register rd, int32_t offset, Condition cond); | |
999 | |
1000 class CodeComment : public ZoneAllocated { | 1001 class CodeComment : public ZoneAllocated { |
1001 public: | 1002 public: |
1002 CodeComment(intptr_t pc_offset, const String& comment) | 1003 CodeComment(intptr_t pc_offset, const String& comment) |
1003 : pc_offset_(pc_offset), comment_(comment) { } | 1004 : pc_offset_(pc_offset), comment_(comment) { } |
1004 | 1005 |
1005 intptr_t pc_offset() const { return pc_offset_; } | 1006 intptr_t pc_offset() const { return pc_offset_; } |
1006 const String& comment() const { return comment_; } | 1007 const String& comment() const { return comment_; } |
1007 | 1008 |
1008 private: | 1009 private: |
1009 intptr_t pc_offset_; | 1010 intptr_t pc_offset_; |
1010 const String& comment_; | 1011 const String& comment_; |
1011 | 1012 |
1012 DISALLOW_COPY_AND_ASSIGN(CodeComment); | 1013 DISALLOW_COPY_AND_ASSIGN(CodeComment); |
1013 }; | 1014 }; |
1014 | 1015 |
1015 GrowableArray<CodeComment*> comments_; | 1016 GrowableArray<CodeComment*> comments_; |
1016 | 1017 |
1017 bool constant_pool_allowed_; | 1018 bool constant_pool_allowed_; |
1018 | 1019 |
1019 void LoadObjectHelper(Register rd, | 1020 void LoadObjectHelper(Register rd, |
1020 const Object& object, | 1021 const Object& object, |
1021 Condition cond, | 1022 Condition cond, |
1022 bool is_unique); | 1023 bool is_unique, |
| 1024 Register pp); |
1023 | 1025 |
1024 void EmitType01(Condition cond, | 1026 void EmitType01(Condition cond, |
1025 int type, | 1027 int type, |
1026 Opcode opcode, | 1028 Opcode opcode, |
1027 int set_cc, | 1029 int set_cc, |
1028 Register rn, | 1030 Register rn, |
1029 Register rd, | 1031 Register rd, |
1030 Operand o); | 1032 Operand o); |
1031 | 1033 |
1032 void EmitType5(Condition cond, int32_t offset, bool link); | 1034 void EmitType5(Condition cond, int32_t offset, bool link); |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1149 Register new_value, | 1151 Register new_value, |
1150 FieldContent old_content); | 1152 FieldContent old_content); |
1151 | 1153 |
1152 DISALLOW_ALLOCATION(); | 1154 DISALLOW_ALLOCATION(); |
1153 DISALLOW_COPY_AND_ASSIGN(Assembler); | 1155 DISALLOW_COPY_AND_ASSIGN(Assembler); |
1154 }; | 1156 }; |
1155 | 1157 |
1156 } // namespace dart | 1158 } // namespace dart |
1157 | 1159 |
1158 #endif // VM_ASSEMBLER_ARM_H_ | 1160 #endif // VM_ASSEMBLER_ARM_H_ |
OLD | NEW |