Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(91)

Side by Side Diff: runtime/vm/assembler_arm64.h

Issue 243773002: Adds Runtime call stub and Dart entry stub to ARM64. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | runtime/vm/assembler_arm64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 360 matching lines...) Expand 10 before | Expand all | Expand 10 after
371 static void InitializeMemoryWithBreakpoints(uword data, intptr_t length); 371 static void InitializeMemoryWithBreakpoints(uword data, intptr_t length);
372 372
373 void Comment(const char* format, ...) PRINTF_ATTRIBUTE(2, 3); 373 void Comment(const char* format, ...) PRINTF_ATTRIBUTE(2, 3);
374 374
375 const Code::Comments& GetCodeComments() const; 375 const Code::Comments& GetCodeComments() const;
376 376
377 static const char* RegisterName(Register reg); 377 static const char* RegisterName(Register reg);
378 378
379 static const char* FpuRegisterName(FpuRegister reg); 379 static const char* FpuRegisterName(FpuRegister reg);
380 380
381 void SetPrologueOffset() {
382 if (prologue_offset_ == -1) {
383 prologue_offset_ = CodeSize();
384 }
385 }
386
387 void ReserveAlignedFrameSpace(intptr_t frame_space);
388
381 // TODO(zra): Make sure this is right. 389 // TODO(zra): Make sure this is right.
382 // Instruction pattern from entrypoint is used in Dart frame prologs 390 // Instruction pattern from entrypoint is used in Dart frame prologs
383 // to set up the frame and save a PC which can be used to figure out the 391 // to set up the frame and save a PC which can be used to figure out the
384 // RawInstruction object corresponding to the code running in the frame. 392 // RawInstruction object corresponding to the code running in the frame.
385 static const intptr_t kEntryPointToPcMarkerOffset = 0; 393 static const intptr_t kEntryPointToPcMarkerOffset = 0;
386 394
387 // Emit data (e.g encoded instruction or immediate) in instruction stream. 395 // Emit data (e.g encoded instruction or immediate) in instruction stream.
388 void Emit(int32_t value); 396 void Emit(int32_t value);
389 397
390 // On some other platforms, we draw a distinction between safe and unsafe 398 // On some other platforms, we draw a distinction between safe and unsafe
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
594 ldr(PP, Address(SP, 1 * kWordSize, Address::PostIndex)); 602 ldr(PP, Address(SP, 1 * kWordSize, Address::PostIndex));
595 sub(PP, PP, Operand(kHeapObjectTag)); 603 sub(PP, PP, Operand(kHeapObjectTag));
596 } 604 }
597 void tst(Register rn, Operand o) { 605 void tst(Register rn, Operand o) {
598 ands(ZR, rn, o); 606 ands(ZR, rn, o);
599 } 607 }
600 void tsti(Register rn, uint64_t imm) { 608 void tsti(Register rn, uint64_t imm) {
601 andis(ZR, rn, imm); 609 andis(ZR, rn, imm);
602 } 610 }
603 611
612 void SmiUntag(Register reg) {
613 add(reg, ZR, Operand(reg, ASR, kSmiTagSize));
614 }
615
604 // Branching to ExternalLabels. 616 // Branching to ExternalLabels.
605 void Branch(const ExternalLabel* label) { 617 void Branch(const ExternalLabel* label) {
606 LoadExternalLabel(TMP, label, kPatchable, PP); 618 LoadExternalLabel(TMP, label, kPatchable, PP);
607 br(TMP); 619 br(TMP);
608 } 620 }
609 621
610 void BranchPatchable(const ExternalLabel* label) { 622 void BranchPatchable(const ExternalLabel* label) {
611 LoadPatchableImmediate(TMP, label->address()); 623 LoadPatchableImmediate(TMP, label->address());
612 br(TMP); 624 br(TMP);
613 } 625 }
614 626
615 void BranchLink(const ExternalLabel* label, Register pp) { 627 void BranchLink(const ExternalLabel* label, Register pp) {
616 if (Isolate::Current() == Dart::vm_isolate()) { 628 if (Isolate::Current() == Dart::vm_isolate()) {
617 LoadImmediate(TMP, label->address(), kNoRegister); 629 LoadImmediate(TMP, label->address(), kNoRegister);
618 blr(TMP); 630 blr(TMP);
619 } else { 631 } else {
620 LoadExternalLabel(TMP, label, kNotPatchable, pp); 632 LoadExternalLabel(TMP, label, kNotPatchable, pp);
621 blr(TMP); 633 blr(TMP);
622 } 634 }
623 } 635 }
624 636
625 void BranchLinkPatchable(const ExternalLabel* label) { 637 void BranchLinkPatchable(const ExternalLabel* label) {
626 LoadExternalLabel(TMP, label, kPatchable, PP); 638 LoadExternalLabel(TMP, label, kPatchable, PP);
627 blr(TMP); 639 blr(TMP);
628 } 640 }
629 641
642 // Macros accepting a pp Register argument may attempt to load values from
643 // the object pool when possible. Unless you are sure that the untagged object
644 // pool pointer is in another register, or that it is not available at all,
645 // PP should be passed for pp.
646 void AddImmediate(Register dest, Register rn, int64_t imm, Register pp);
647 void CompareImmediate(Register rn, int64_t imm, Register pp);
648 void LoadFromOffset(Register dest, Register base, int32_t offset);
649 void LoadFieldFromOffset(Register dest, Register base, int32_t offset) {
650 LoadFromOffset(dest, base, offset - kHeapObjectTag);
651 }
652 void StoreToOffset(Register dest, Register base, int32_t offset);
653 void StoreFieldToOffset(Register dest, Register base, int32_t offset) {
654 StoreToOffset(dest, base, offset - kHeapObjectTag);
655 }
656
630 // Object pool, loading from pool, etc. 657 // Object pool, loading from pool, etc.
631 void LoadPoolPointer(Register pp) { 658 void LoadPoolPointer(Register pp);
632 const intptr_t object_pool_pc_dist =
633 Instructions::HeaderSize() - Instructions::object_pool_offset() +
634 CodeSize();
635 // PP <- Read(PC - object_pool_pc_dist).
636 ldr(pp, Address::PC(-object_pool_pc_dist));
637
638 // When in the PP register, the pool pointer is untagged. When we
639 // push it on the stack with PushPP it is tagged again. PopPP then untags
640 // when restoring from the stack. This will make loading from the object
641 // pool only one instruction for the first 4096 entries. Otherwise, because
642 // the offset wouldn't be aligned, it would always be at least two
643 // instructions.
644 sub(pp, pp, Operand(kHeapObjectTag));
645 }
646 659
647 enum Patchability { 660 enum Patchability {
648 kPatchable, 661 kPatchable,
649 kNotPatchable, 662 kNotPatchable,
650 }; 663 };
651 664
652 void LoadWordFromPoolOffset(Register dst, Register pp, uint32_t offset); 665 void LoadWordFromPoolOffset(Register dst, Register pp, uint32_t offset);
653 intptr_t FindExternalLabel(const ExternalLabel* label, 666 intptr_t FindExternalLabel(const ExternalLabel* label,
654 Patchability patchable); 667 Patchability patchable);
655 intptr_t FindObject(const Object& obj, Patchability patchable); 668 intptr_t FindObject(const Object& obj, Patchability patchable);
656 intptr_t FindImmediate(int64_t imm); 669 intptr_t FindImmediate(int64_t imm);
657 bool CanLoadObjectFromPool(const Object& object); 670 bool CanLoadObjectFromPool(const Object& object);
658 bool CanLoadImmediateFromPool(int64_t imm, Register pp); 671 bool CanLoadImmediateFromPool(int64_t imm, Register pp);
659 void LoadExternalLabel(Register dst, const ExternalLabel* label, 672 void LoadExternalLabel(Register dst, const ExternalLabel* label,
660 Patchability patchable, Register pp); 673 Patchability patchable, Register pp);
661 void LoadObject(Register dst, const Object& obj, Register pp); 674 void LoadObject(Register dst, const Object& obj, Register pp);
662 void LoadDecodableImmediate(Register reg, int64_t imm, Register pp); 675 void LoadDecodableImmediate(Register reg, int64_t imm, Register pp);
663 void LoadPatchableImmediate(Register reg, int64_t imm); 676 void LoadPatchableImmediate(Register reg, int64_t imm);
664 void LoadImmediate(Register reg, int64_t imm, Register pp); 677 void LoadImmediate(Register reg, int64_t imm, Register pp);
665 678
679 void PushObject(const Object& object, Register pp) {
680 LoadObject(TMP, object, pp);
681 Push(TMP);
682 }
683
684 void EnterFrame(intptr_t frame_size);
685 void LeaveFrame();
686
687 void EnterDartFrame(intptr_t frame_size);
688 void LeaveDartFrame();
689
690 void CallRuntime(const RuntimeEntry& entry, intptr_t argument_count);
691
666 private: 692 private:
667 AssemblerBuffer buffer_; // Contains position independent code. 693 AssemblerBuffer buffer_; // Contains position independent code.
668 694
669 // Objects and patchable jump targets. 695 // Objects and patchable jump targets.
670 GrowableObjectArray& object_pool_; 696 GrowableObjectArray& object_pool_;
671 697
672 // Patchability of pool entries. 698 // Patchability of pool entries.
673 GrowableArray<Patchability> patchable_pool_entries_; 699 GrowableArray<Patchability> patchable_pool_entries_;
674 700
675 // Pair type parameter for DirectChainedHashMap. 701 // Pair type parameter for DirectChainedHashMap.
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
823 849
824 int64_t DecodeImm19BranchOffset(int32_t instr) { 850 int64_t DecodeImm19BranchOffset(int32_t instr) {
825 const int32_t off = (((instr >> kImm19Shift) & kImm19Shift) << 13) >> 13; 851 const int32_t off = (((instr >> kImm19Shift) & kImm19Shift) << 13) >> 13;
826 return static_cast<int64_t>(off); 852 return static_cast<int64_t>(off);
827 } 853 }
828 854
829 void EmitCompareAndBranch(CompareAndBranchOp op, Register rt, int64_t imm, 855 void EmitCompareAndBranch(CompareAndBranchOp op, Register rt, int64_t imm,
830 OperandSize sz) { 856 OperandSize sz) {
831 ASSERT((sz == kDoubleWord) || (sz == kWord)); 857 ASSERT((sz == kDoubleWord) || (sz == kWord));
832 ASSERT(Utils::IsInt(21, imm) && ((imm & 0x3) == 0)); 858 ASSERT(Utils::IsInt(21, imm) && ((imm & 0x3) == 0));
859 ASSERT((rt != SP) && (rt != R31));
860 const Register crt = ConcreteRegister(rt);
833 const int32_t size = (sz == kDoubleWord) ? B31 : 0; 861 const int32_t size = (sz == kDoubleWord) ? B31 : 0;
834 const int32_t encoded_offset = EncodeImm19BranchOffset(imm, 0); 862 const int32_t encoded_offset = EncodeImm19BranchOffset(imm, 0);
835 const int32_t encoding = 863 const int32_t encoding =
836 op | size | 864 op | size |
837 (static_cast<int32_t>(rt) << kRtShift) | 865 (static_cast<int32_t>(crt) << kRtShift) |
838 encoded_offset; 866 encoded_offset;
839 Emit(encoding); 867 Emit(encoding);
840 } 868 }
841 869
842 void EmitConditionalBranch(ConditionalBranchOp op, Condition cond, 870 void EmitConditionalBranch(ConditionalBranchOp op, Condition cond,
843 int64_t imm) { 871 int64_t imm) {
844 ASSERT(Utils::IsInt(21, imm) && ((imm & 0x3) == 0)); 872 ASSERT(Utils::IsInt(21, imm) && ((imm & 0x3) == 0));
845 const int32_t encoding = 873 const int32_t encoding =
846 op | 874 op |
847 (static_cast<int32_t>(cond) << kCondShift) | 875 (static_cast<int32_t>(cond) << kCondShift) |
(...skipping 14 matching lines...) Expand all
862 EmitConditionalBranch(op, cond, dest); 890 EmitConditionalBranch(op, cond, dest);
863 } else { 891 } else {
864 const int64_t position = buffer_.Size(); 892 const int64_t position = buffer_.Size();
865 ASSERT(CanEncodeImm19BranchOffset(position)); 893 ASSERT(CanEncodeImm19BranchOffset(position));
866 EmitConditionalBranch(op, cond, label->position_); 894 EmitConditionalBranch(op, cond, label->position_);
867 label->LinkTo(position); 895 label->LinkTo(position);
868 } 896 }
869 } 897 }
870 898
871 void EmitUnconditionalBranchRegOp(UnconditionalBranchRegOp op, Register rn) { 899 void EmitUnconditionalBranchRegOp(UnconditionalBranchRegOp op, Register rn) {
900 ASSERT((rn != SP) && (rn != R31));
901 const Register crn = ConcreteRegister(rn);
872 const int32_t encoding = 902 const int32_t encoding =
873 op | (static_cast<int32_t>(rn) << kRnShift); 903 op | (static_cast<int32_t>(crn) << kRnShift);
874 Emit(encoding); 904 Emit(encoding);
875 } 905 }
876 906
877 void EmitExceptionGenOp(ExceptionGenOp op, uint16_t imm) { 907 void EmitExceptionGenOp(ExceptionGenOp op, uint16_t imm) {
878 const int32_t encoding = 908 const int32_t encoding =
879 op | (static_cast<int32_t>(imm) << kImm16Shift); 909 op | (static_cast<int32_t>(imm) << kImm16Shift);
880 Emit(encoding); 910 Emit(encoding);
881 } 911 }
882 912
883 void EmitMoveWideOp(MoveWideOp op, Register rd, uint16_t imm, int hw_idx, 913 void EmitMoveWideOp(MoveWideOp op, Register rd, uint16_t imm, int hw_idx,
884 OperandSize sz) { 914 OperandSize sz) {
885 ASSERT((hw_idx >= 0) && (hw_idx <= 3)); 915 ASSERT((hw_idx >= 0) && (hw_idx <= 3));
886 ASSERT((sz == kDoubleWord) || (sz == kWord)); 916 ASSERT((sz == kDoubleWord) || (sz == kWord));
887 const int32_t size = (sz == kDoubleWord) ? B31 : 0; 917 const int32_t size = (sz == kDoubleWord) ? B31 : 0;
888 const int32_t encoding = 918 const int32_t encoding =
889 op | size | 919 op | size |
890 (static_cast<int32_t>(rd) << kRdShift) | 920 (static_cast<int32_t>(rd) << kRdShift) |
891 (static_cast<int32_t>(hw_idx) << kHWShift) | 921 (static_cast<int32_t>(hw_idx) << kHWShift) |
892 (static_cast<int32_t>(imm) << kImm16Shift); 922 (static_cast<int32_t>(imm) << kImm16Shift);
893 Emit(encoding); 923 Emit(encoding);
894 } 924 }
895 925
896 void EmitLoadStoreReg(LoadStoreRegOp op, Register rt, Address a, 926 void EmitLoadStoreReg(LoadStoreRegOp op, Register rt, Address a,
897 OperandSize sz) { 927 OperandSize sz) {
928 const Register crt = ConcreteRegister(rt);
898 const int32_t size = Log2OperandSizeBytes(sz); 929 const int32_t size = Log2OperandSizeBytes(sz);
899 const int32_t encoding = 930 const int32_t encoding =
900 op | (size << kSzShift) | 931 op | (size << kSzShift) |
901 (static_cast<int32_t>(rt) << kRtShift) | 932 (static_cast<int32_t>(crt) << kRtShift) |
902 a.encoding(); 933 a.encoding();
903 Emit(encoding); 934 Emit(encoding);
904 } 935 }
905 936
906 void EmitLoadRegLiteral(LoadRegLiteralOp op, Register rt, Address a, 937 void EmitLoadRegLiteral(LoadRegLiteralOp op, Register rt, Address a,
907 OperandSize sz) { 938 OperandSize sz) {
908 ASSERT((sz == kDoubleWord) || (sz == kWord)); 939 ASSERT((sz == kDoubleWord) || (sz == kWord));
940 ASSERT((rt != SP) && (rt != R31));
941 const Register crt = ConcreteRegister(rt);
909 const int32_t size = (sz == kDoubleWord) ? B30 : 0; 942 const int32_t size = (sz == kDoubleWord) ? B30 : 0;
910 const int32_t encoding = 943 const int32_t encoding =
911 op | size | 944 op | size |
912 (static_cast<int32_t>(rt) << kRtShift) | 945 (static_cast<int32_t>(crt) << kRtShift) |
913 a.encoding(); 946 a.encoding();
914 Emit(encoding); 947 Emit(encoding);
915 } 948 }
916 949
917 void EmitPCRelOp(PCRelOp op, Register rd, int64_t imm) { 950 void EmitPCRelOp(PCRelOp op, Register rd, int64_t imm) {
918 ASSERT(Utils::IsInt(21, imm)); 951 ASSERT(Utils::IsInt(21, imm));
919 ASSERT((rd != R31) && (rd != SP)); 952 ASSERT((rd != R31) && (rd != SP));
920 const Register crd = ConcreteRegister(rd); 953 const Register crd = ConcreteRegister(rd);
921 const int32_t loimm = (imm & 0x3) << 29; 954 const int32_t loimm = (imm & 0x3) << 29;
922 const int32_t hiimm = ((imm >> 2) << kImm19Shift) & kImm19Mask; 955 const int32_t hiimm = ((imm >> 2) << kImm19Shift) & kImm19Mask;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
960 Emit(encoding); 993 Emit(encoding);
961 } 994 }
962 995
963 DISALLOW_ALLOCATION(); 996 DISALLOW_ALLOCATION();
964 DISALLOW_COPY_AND_ASSIGN(Assembler); 997 DISALLOW_COPY_AND_ASSIGN(Assembler);
965 }; 998 };
966 999
967 } // namespace dart 1000 } // namespace dart
968 1001
969 #endif // VM_ASSEMBLER_ARM64_H_ 1002 #endif // VM_ASSEMBLER_ARM64_H_
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/assembler_arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698