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 |