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

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

Issue 262793006: Uses double load/store on arm64, enables tests. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 7 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 | « runtime/vm/assembler_arm64.h ('k') | runtime/vm/constants_arm64.h » ('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 #include "vm/globals.h" 5 #include "vm/globals.h"
6 #if defined(TARGET_ARCH_ARM64) 6 #if defined(TARGET_ARCH_ARM64)
7 7
8 #include "vm/assembler.h" 8 #include "vm/assembler.h"
9 #include "vm/cpu.h" 9 #include "vm/cpu.h"
10 #include "vm/longjump.h" 10 #include "vm/longjump.h"
(...skipping 612 matching lines...) Expand 10 before | Expand all | Expand 10 after
623 if (Address::CanHoldOffset(offset, Address::Offset, sz)) { 623 if (Address::CanHoldOffset(offset, Address::Offset, sz)) {
624 ldr(dest, Address(base, offset, Address::Offset, sz), sz); 624 ldr(dest, Address(base, offset, Address::Offset, sz), sz);
625 } else { 625 } else {
626 // Since offset is 32-bits, it won't be loaded from the pool. 626 // Since offset is 32-bits, it won't be loaded from the pool.
627 AddImmediate(TMP2, base, offset, kNoPP); 627 AddImmediate(TMP2, base, offset, kNoPP);
628 ldr(dest, Address(TMP2), sz); 628 ldr(dest, Address(TMP2), sz);
629 } 629 }
630 } 630 }
631 631
632 632
633 void Assembler::LoadDFromOffset(VRegister dest, Register base, int32_t offset) {
634 ASSERT(base != TMP2);
regis 2014/05/02 19:59:16 I would move this assert to the else branch.
zra 2014/05/02 20:16:11 Done.
635 if (Address::CanHoldOffset(offset, Address::Offset, kDWord)) {
636 fldrd(dest, Address(base, offset, Address::Offset, kDWord));
637 } else {
638 // Since offset is 32-bits, it won't be loaded from the pool.
639 AddImmediate(TMP2, base, offset, kNoPP);
640 fldrd(dest, Address(TMP2));
641 }
642 }
643
644
633 void Assembler::StoreToOffset( 645 void Assembler::StoreToOffset(
634 Register src, Register base, int32_t offset, OperandSize sz) { 646 Register src, Register base, int32_t offset, OperandSize sz) {
635 ASSERT(src != TMP2); 647 ASSERT(src != TMP2);
636 ASSERT(base != TMP2); 648 ASSERT(base != TMP2);
637 if (Address::CanHoldOffset(offset, Address::Offset, sz)) { 649 if (Address::CanHoldOffset(offset, Address::Offset, sz)) {
638 str(src, Address(base, offset, Address::Offset, sz), sz); 650 str(src, Address(base, offset, Address::Offset, sz), sz);
639 } else { 651 } else {
640 // Since offset is 32-bits, it won't be loaded from the pool. 652 // Since offset is 32-bits, it won't be loaded from the pool.
641 AddImmediate(TMP2, base, offset, kNoPP); 653 AddImmediate(TMP2, base, offset, kNoPP);
642 str(src, Address(TMP2), sz); 654 str(src, Address(TMP2), sz);
643 } 655 }
644 } 656 }
645 657
646 658
659 void Assembler::StoreDToOffset(VRegister src, Register base, int32_t offset) {
660 ASSERT(base != TMP2);
regis 2014/05/02 19:59:16 ditto
zra 2014/05/02 20:16:11 Done.
661 if (Address::CanHoldOffset(offset, Address::Offset, kDWord)) {
662 fstrd(src, Address(base, offset, Address::Offset, kDWord));
663 } else {
664 // Since offset is 32-bits, it won't be loaded from the pool.
665 AddImmediate(TMP2, base, offset, kNoPP);
666 fstrd(src, Address(TMP2));
667 }
668 }
669
670
647 // Store into object. 671 // Store into object.
648 // Preserves object and value registers. 672 // Preserves object and value registers.
649 void Assembler::StoreIntoObjectFilterNoSmi(Register object, 673 void Assembler::StoreIntoObjectFilterNoSmi(Register object,
650 Register value, 674 Register value,
651 Label* no_update) { 675 Label* no_update) {
652 COMPILE_ASSERT((kNewObjectAlignmentOffset == kWordSize) && 676 COMPILE_ASSERT((kNewObjectAlignmentOffset == kWordSize) &&
653 (kOldObjectAlignmentOffset == 0), young_alignment); 677 (kOldObjectAlignmentOffset == 0), young_alignment);
654 678
655 // Write-barrier triggers if the value is in the new space (has bit set) and 679 // Write-barrier triggers if the value is in the new space (has bit set) and
656 // the object is in the old space (has bit cleared). 680 // the object is in the old space (has bit cleared).
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
866 // Restore and untag PP. 890 // Restore and untag PP.
867 LoadFromOffset(PP, FP, kSavedCallerPpSlotFromFp * kWordSize); 891 LoadFromOffset(PP, FP, kSavedCallerPpSlotFromFp * kWordSize);
868 sub(PP, PP, Operand(kHeapObjectTag)); 892 sub(PP, PP, Operand(kHeapObjectTag));
869 LeaveFrame(); 893 LeaveFrame();
870 } 894 }
871 895
872 896
873 void Assembler::EnterCallRuntimeFrame(intptr_t frame_size) { 897 void Assembler::EnterCallRuntimeFrame(intptr_t frame_size) {
874 EnterFrame(0); 898 EnterFrame(0);
875 899
876 // TODO(zra): also save volatile FPU registers. 900 // Store fpu registers with the lowest register number at the lowest
901 // address.
902 for (int i = kNumberOfVRegisters - 1; i >= 0; i--) {
903 if ((i >= kAbiFirstPreservedFpuReg) && (i <= kAbiLastPreservedFpuReg)) {
904 // TODO(zra): When SIMD is added, we must also preserve the top
905 // 64-bits of the callee-saved registers.
906 continue;
907 }
908 // TODO(zra): Save the whole V register.
909 VRegister reg = static_cast<VRegister>(i);
910 PushDouble(reg);
911 }
877 912
878 for (int i = kDartFirstVolatileCpuReg; i <= kDartLastVolatileCpuReg; i++) { 913 for (int i = kDartFirstVolatileCpuReg; i <= kDartLastVolatileCpuReg; i++) {
879 const Register reg = static_cast<Register>(i); 914 const Register reg = static_cast<Register>(i);
880 if ((reg != R16) && (reg != R17)) { 915 if ((reg != TMP) && (reg != TMP2)) {
881 Push(reg); 916 Push(reg);
882 } 917 }
883 } 918 }
884 919
885 ReserveAlignedFrameSpace(frame_size); 920 ReserveAlignedFrameSpace(frame_size);
886 } 921 }
887 922
888 923
889 void Assembler::LeaveCallRuntimeFrame() { 924 void Assembler::LeaveCallRuntimeFrame() {
890 // SP might have been modified to reserve space for arguments 925 // SP might have been modified to reserve space for arguments
891 // and ensure proper alignment of the stack frame. 926 // and ensure proper alignment of the stack frame.
892 // We need to restore it before restoring registers. 927 // We need to restore it before restoring registers.
893 // TODO(zra): Also include FPU regs in this count once they are added. 928 // TODO(zra): Also include FPU regs in this count once they are added.
894 const intptr_t kPushedRegistersSize = 929 const intptr_t kPushedRegistersSize =
895 kDartVolatileCpuRegCount * kWordSize; 930 kDartVolatileCpuRegCount * kWordSize +
931 kDartVolatileFpuRegCount * kWordSize;
896 AddImmediate(SP, FP, -kPushedRegistersSize, PP); 932 AddImmediate(SP, FP, -kPushedRegistersSize, PP);
897 for (int i = kDartLastVolatileCpuReg; i >= kDartFirstVolatileCpuReg; i--) { 933 for (int i = kDartLastVolatileCpuReg; i >= kDartFirstVolatileCpuReg; i--) {
898 const Register reg = static_cast<Register>(i); 934 const Register reg = static_cast<Register>(i);
899 if ((reg != R16) && (reg != R17)) { 935 if ((reg != TMP) && (reg != TMP2)) {
900 Pop(reg); 936 Pop(reg);
901 } 937 }
902 } 938 }
903 939
940 for (int i = 0; i < kNumberOfVRegisters; i++) {
941 if ((i >= kAbiFirstPreservedFpuReg) && (i <= kAbiLastPreservedFpuReg)) {
942 // TODO(zra): When SIMD is added, we must also restore the top
943 // 64-bits of the callee-saved registers.
944 continue;
945 }
946 // TODO(zra): Restore the whole V register.
947 VRegister reg = static_cast<VRegister>(i);
948 PopDouble(reg);
949 }
950
904 Pop(FP); 951 Pop(FP);
905 Pop(LR); 952 Pop(LR);
906 } 953 }
907 954
908 955
909 void Assembler::CallRuntime(const RuntimeEntry& entry, 956 void Assembler::CallRuntime(const RuntimeEntry& entry,
910 intptr_t argument_count) { 957 intptr_t argument_count) {
911 entry.Call(this, argument_count); 958 entry.Call(this, argument_count);
912 } 959 }
913 960
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
1010 AddImmediate(temp_reg, temp_reg, class_offset, pp); 1057 AddImmediate(temp_reg, temp_reg, class_offset, pp);
1011 ldr(TMP, Address(temp_reg, count_field_offset)); 1058 ldr(TMP, Address(temp_reg, count_field_offset));
1012 AddImmediate(TMP, TMP, 1, pp); 1059 AddImmediate(TMP, TMP, 1, pp);
1013 str(TMP, Address(temp_reg, count_field_offset)); 1060 str(TMP, Address(temp_reg, count_field_offset));
1014 ldr(TMP, Address(temp_reg, size_field_offset)); 1061 ldr(TMP, Address(temp_reg, size_field_offset));
1015 add(TMP, TMP, Operand(size_reg)); 1062 add(TMP, TMP, Operand(size_reg));
1016 str(TMP, Address(temp_reg, size_field_offset)); 1063 str(TMP, Address(temp_reg, size_field_offset));
1017 } 1064 }
1018 } 1065 }
1019 1066
1067
1068 void Assembler::TryAllocate(const Class& cls,
1069 Label* failure,
1070 Register instance_reg,
1071 Register temp_reg,
1072 Register pp) {
1073 ASSERT(failure != NULL);
1074 if (FLAG_inline_alloc) {
1075 Heap* heap = Isolate::Current()->heap();
1076 const intptr_t instance_size = cls.instance_size();
1077 LoadImmediate(instance_reg, heap->TopAddress(), pp);
1078 ldr(instance_reg, Address(instance_reg));
1079 AddImmediate(instance_reg, instance_reg, instance_size, pp);
1080
1081 // instance_reg: potential next object start.
1082 LoadImmediate(TMP, heap->EndAddress(), pp);
1083 ldr(TMP, Address(TMP));
1084 CompareRegisters(TMP, instance_reg);
1085 // fail if heap end unsigned less than or equal to instance_reg.
1086 b(failure, LS);
1087
1088 // Successfully allocated the object, now update top to point to
1089 // next object start and store the class in the class field of object.
1090 LoadImmediate(TMP, heap->TopAddress(), pp);
1091 str(instance_reg, Address(TMP));
1092
1093 ASSERT(instance_size >= kHeapObjectTag);
1094 AddImmediate(
1095 instance_reg, instance_reg, -instance_size + kHeapObjectTag, pp);
1096 UpdateAllocationStats(cls.id(), temp_reg, pp);
1097
1098 uword tags = 0;
1099 tags = RawObject::SizeTag::update(instance_size, tags);
1100 ASSERT(cls.id() != kIllegalCid);
1101 tags = RawObject::ClassIdTag::update(cls.id(), tags);
1102 LoadImmediate(TMP, tags, pp);
1103 StoreFieldToOffset(TMP, instance_reg, Object::tags_offset());
1104 } else {
1105 b(failure);
1106 }
1107 }
1108
1020 } // namespace dart 1109 } // namespace dart
1021 1110
1022 #endif // defined TARGET_ARCH_ARM64 1111 #endif // defined TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « runtime/vm/assembler_arm64.h ('k') | runtime/vm/constants_arm64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698