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

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') | runtime/vm/runtime_entry_arm64.cc » ('J')
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 void AddImmediate(Register dest, Register rn, int64_t imm, Register pp);
regis 2014/04/18 22:15:30 You should explain in a comment what is the purpos
zra 2014/04/18 23:24:21 Done.
643 void CompareImmediate(Register rn, int64_t imm, Register pp);
644 void LoadFromOffset(Register dest, Register base, int32_t offset);
645 void LoadFieldFromOffset(Register dest, Register base, int32_t offset) {
646 LoadFromOffset(dest, base, offset - kHeapObjectTag);
647 }
648 void StoreToOffset(Register dest, Register base, int32_t offset);
649 void StoreFieldToOffset(Register dest, Register base, int32_t offset) {
650 StoreToOffset(dest, base, offset - kHeapObjectTag);
651 }
652
630 // Object pool, loading from pool, etc. 653 // Object pool, loading from pool, etc.
631 void LoadPoolPointer(Register pp) { 654 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 655
647 enum Patchability { 656 enum Patchability {
648 kPatchable, 657 kPatchable,
649 kNotPatchable, 658 kNotPatchable,
650 }; 659 };
651 660
652 void LoadWordFromPoolOffset(Register dst, Register pp, uint32_t offset); 661 void LoadWordFromPoolOffset(Register dst, Register pp, uint32_t offset);
653 intptr_t FindExternalLabel(const ExternalLabel* label, 662 intptr_t FindExternalLabel(const ExternalLabel* label,
654 Patchability patchable); 663 Patchability patchable);
655 intptr_t FindObject(const Object& obj, Patchability patchable); 664 intptr_t FindObject(const Object& obj, Patchability patchable);
656 intptr_t FindImmediate(int64_t imm); 665 intptr_t FindImmediate(int64_t imm);
657 bool CanLoadObjectFromPool(const Object& object); 666 bool CanLoadObjectFromPool(const Object& object);
658 bool CanLoadImmediateFromPool(int64_t imm, Register pp); 667 bool CanLoadImmediateFromPool(int64_t imm, Register pp);
659 void LoadExternalLabel(Register dst, const ExternalLabel* label, 668 void LoadExternalLabel(Register dst, const ExternalLabel* label,
660 Patchability patchable, Register pp); 669 Patchability patchable, Register pp);
661 void LoadObject(Register dst, const Object& obj, Register pp); 670 void LoadObject(Register dst, const Object& obj, Register pp);
662 void LoadDecodableImmediate(Register reg, int64_t imm, Register pp); 671 void LoadDecodableImmediate(Register reg, int64_t imm, Register pp);
663 void LoadPatchableImmediate(Register reg, int64_t imm); 672 void LoadPatchableImmediate(Register reg, int64_t imm);
664 void LoadImmediate(Register reg, int64_t imm, Register pp); 673 void LoadImmediate(Register reg, int64_t imm, Register pp);
665 674
675 void PushObject(const Object& object, Register pp) {
676 LoadObject(TMP, object, pp);
677 Push(TMP);
678 }
679
680 void EnterDartFrame(intptr_t frame_size);
681 void LeaveDartFrame();
682
683 void CallRuntime(const RuntimeEntry& entry, intptr_t argument_count);
684
666 private: 685 private:
667 AssemblerBuffer buffer_; // Contains position independent code. 686 AssemblerBuffer buffer_; // Contains position independent code.
668 687
669 // Objects and patchable jump targets. 688 // Objects and patchable jump targets.
670 GrowableObjectArray& object_pool_; 689 GrowableObjectArray& object_pool_;
671 690
672 // Patchability of pool entries. 691 // Patchability of pool entries.
673 GrowableArray<Patchability> patchable_pool_entries_; 692 GrowableArray<Patchability> patchable_pool_entries_;
674 693
675 // Pair type parameter for DirectChainedHashMap. 694 // Pair type parameter for DirectChainedHashMap.
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
823 842
824 int64_t DecodeImm19BranchOffset(int32_t instr) { 843 int64_t DecodeImm19BranchOffset(int32_t instr) {
825 const int32_t off = (((instr >> kImm19Shift) & kImm19Shift) << 13) >> 13; 844 const int32_t off = (((instr >> kImm19Shift) & kImm19Shift) << 13) >> 13;
826 return static_cast<int64_t>(off); 845 return static_cast<int64_t>(off);
827 } 846 }
828 847
829 void EmitCompareAndBranch(CompareAndBranchOp op, Register rt, int64_t imm, 848 void EmitCompareAndBranch(CompareAndBranchOp op, Register rt, int64_t imm,
830 OperandSize sz) { 849 OperandSize sz) {
831 ASSERT((sz == kDoubleWord) || (sz == kWord)); 850 ASSERT((sz == kDoubleWord) || (sz == kWord));
832 ASSERT(Utils::IsInt(21, imm) && ((imm & 0x3) == 0)); 851 ASSERT(Utils::IsInt(21, imm) && ((imm & 0x3) == 0));
852 ASSERT((rt != SP) && (rt != R31));
853 const Register crt = ConcreteRegister(rt);
833 const int32_t size = (sz == kDoubleWord) ? B31 : 0; 854 const int32_t size = (sz == kDoubleWord) ? B31 : 0;
834 const int32_t encoded_offset = EncodeImm19BranchOffset(imm, 0); 855 const int32_t encoded_offset = EncodeImm19BranchOffset(imm, 0);
835 const int32_t encoding = 856 const int32_t encoding =
836 op | size | 857 op | size |
837 (static_cast<int32_t>(rt) << kRtShift) | 858 (static_cast<int32_t>(crt) << kRtShift) |
838 encoded_offset; 859 encoded_offset;
839 Emit(encoding); 860 Emit(encoding);
840 } 861 }
841 862
842 void EmitConditionalBranch(ConditionalBranchOp op, Condition cond, 863 void EmitConditionalBranch(ConditionalBranchOp op, Condition cond,
843 int64_t imm) { 864 int64_t imm) {
844 ASSERT(Utils::IsInt(21, imm) && ((imm & 0x3) == 0)); 865 ASSERT(Utils::IsInt(21, imm) && ((imm & 0x3) == 0));
845 const int32_t encoding = 866 const int32_t encoding =
846 op | 867 op |
847 (static_cast<int32_t>(cond) << kCondShift) | 868 (static_cast<int32_t>(cond) << kCondShift) |
(...skipping 14 matching lines...) Expand all
862 EmitConditionalBranch(op, cond, dest); 883 EmitConditionalBranch(op, cond, dest);
863 } else { 884 } else {
864 const int64_t position = buffer_.Size(); 885 const int64_t position = buffer_.Size();
865 ASSERT(CanEncodeImm19BranchOffset(position)); 886 ASSERT(CanEncodeImm19BranchOffset(position));
866 EmitConditionalBranch(op, cond, label->position_); 887 EmitConditionalBranch(op, cond, label->position_);
867 label->LinkTo(position); 888 label->LinkTo(position);
868 } 889 }
869 } 890 }
870 891
871 void EmitUnconditionalBranchRegOp(UnconditionalBranchRegOp op, Register rn) { 892 void EmitUnconditionalBranchRegOp(UnconditionalBranchRegOp op, Register rn) {
893 ASSERT((rn != SP) && (rn != R31));
894 const Register crn = ConcreteRegister(rn);
872 const int32_t encoding = 895 const int32_t encoding =
873 op | (static_cast<int32_t>(rn) << kRnShift); 896 op | (static_cast<int32_t>(crn) << kRnShift);
874 Emit(encoding); 897 Emit(encoding);
875 } 898 }
876 899
877 void EmitExceptionGenOp(ExceptionGenOp op, uint16_t imm) { 900 void EmitExceptionGenOp(ExceptionGenOp op, uint16_t imm) {
878 const int32_t encoding = 901 const int32_t encoding =
879 op | (static_cast<int32_t>(imm) << kImm16Shift); 902 op | (static_cast<int32_t>(imm) << kImm16Shift);
880 Emit(encoding); 903 Emit(encoding);
881 } 904 }
882 905
883 void EmitMoveWideOp(MoveWideOp op, Register rd, uint16_t imm, int hw_idx, 906 void EmitMoveWideOp(MoveWideOp op, Register rd, uint16_t imm, int hw_idx,
884 OperandSize sz) { 907 OperandSize sz) {
885 ASSERT((hw_idx >= 0) && (hw_idx <= 3)); 908 ASSERT((hw_idx >= 0) && (hw_idx <= 3));
886 ASSERT((sz == kDoubleWord) || (sz == kWord)); 909 ASSERT((sz == kDoubleWord) || (sz == kWord));
887 const int32_t size = (sz == kDoubleWord) ? B31 : 0; 910 const int32_t size = (sz == kDoubleWord) ? B31 : 0;
888 const int32_t encoding = 911 const int32_t encoding =
889 op | size | 912 op | size |
890 (static_cast<int32_t>(rd) << kRdShift) | 913 (static_cast<int32_t>(rd) << kRdShift) |
891 (static_cast<int32_t>(hw_idx) << kHWShift) | 914 (static_cast<int32_t>(hw_idx) << kHWShift) |
892 (static_cast<int32_t>(imm) << kImm16Shift); 915 (static_cast<int32_t>(imm) << kImm16Shift);
893 Emit(encoding); 916 Emit(encoding);
894 } 917 }
895 918
896 void EmitLoadStoreReg(LoadStoreRegOp op, Register rt, Address a, 919 void EmitLoadStoreReg(LoadStoreRegOp op, Register rt, Address a,
897 OperandSize sz) { 920 OperandSize sz) {
921 const Register crt = ConcreteRegister(rt);
898 const int32_t size = Log2OperandSizeBytes(sz); 922 const int32_t size = Log2OperandSizeBytes(sz);
899 const int32_t encoding = 923 const int32_t encoding =
900 op | (size << kSzShift) | 924 op | (size << kSzShift) |
901 (static_cast<int32_t>(rt) << kRtShift) | 925 (static_cast<int32_t>(crt) << kRtShift) |
902 a.encoding(); 926 a.encoding();
903 Emit(encoding); 927 Emit(encoding);
904 } 928 }
905 929
906 void EmitLoadRegLiteral(LoadRegLiteralOp op, Register rt, Address a, 930 void EmitLoadRegLiteral(LoadRegLiteralOp op, Register rt, Address a,
907 OperandSize sz) { 931 OperandSize sz) {
908 ASSERT((sz == kDoubleWord) || (sz == kWord)); 932 ASSERT((sz == kDoubleWord) || (sz == kWord));
933 ASSERT((rt != SP) && (rt != R31));
934 const Register crt = ConcreteRegister(rt);
909 const int32_t size = (sz == kDoubleWord) ? B30 : 0; 935 const int32_t size = (sz == kDoubleWord) ? B30 : 0;
910 const int32_t encoding = 936 const int32_t encoding =
911 op | size | 937 op | size |
912 (static_cast<int32_t>(rt) << kRtShift) | 938 (static_cast<int32_t>(crt) << kRtShift) |
913 a.encoding(); 939 a.encoding();
914 Emit(encoding); 940 Emit(encoding);
915 } 941 }
916 942
917 void EmitPCRelOp(PCRelOp op, Register rd, int64_t imm) { 943 void EmitPCRelOp(PCRelOp op, Register rd, int64_t imm) {
918 ASSERT(Utils::IsInt(21, imm)); 944 ASSERT(Utils::IsInt(21, imm));
919 ASSERT((rd != R31) && (rd != SP)); 945 ASSERT((rd != R31) && (rd != SP));
920 const Register crd = ConcreteRegister(rd); 946 const Register crd = ConcreteRegister(rd);
921 const int32_t loimm = (imm & 0x3) << 29; 947 const int32_t loimm = (imm & 0x3) << 29;
922 const int32_t hiimm = ((imm >> 2) << kImm19Shift) & kImm19Mask; 948 const int32_t hiimm = ((imm >> 2) << kImm19Shift) & kImm19Mask;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
960 Emit(encoding); 986 Emit(encoding);
961 } 987 }
962 988
963 DISALLOW_ALLOCATION(); 989 DISALLOW_ALLOCATION();
964 DISALLOW_COPY_AND_ASSIGN(Assembler); 990 DISALLOW_COPY_AND_ASSIGN(Assembler);
965 }; 991 };
966 992
967 } // namespace dart 993 } // namespace dart
968 994
969 #endif // VM_ASSEMBLER_ARM64_H_ 995 #endif // VM_ASSEMBLER_ARM64_H_
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/assembler_arm64.cc » ('j') | runtime/vm/runtime_entry_arm64.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698