OLD | NEW |
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" // Needed here to get TARGET_ARCH_ARM64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM64. |
6 #if defined(TARGET_ARCH_ARM64) | 6 #if defined(TARGET_ARCH_ARM64) |
7 | 7 |
8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
9 | 9 |
10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
(...skipping 1009 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1020 (representation() == kUnboxedInt32x4) || | 1020 (representation() == kUnboxedInt32x4) || |
1021 (representation() == kUnboxedFloat64x2)) { | 1021 (representation() == kUnboxedFloat64x2)) { |
1022 locs->set_out(0, Location::RequiresFpuRegister()); | 1022 locs->set_out(0, Location::RequiresFpuRegister()); |
1023 } else { | 1023 } else { |
1024 locs->set_out(0, Location::RequiresRegister()); | 1024 locs->set_out(0, Location::RequiresRegister()); |
1025 } | 1025 } |
1026 return locs; | 1026 return locs; |
1027 } | 1027 } |
1028 | 1028 |
1029 | 1029 |
1030 static Address ElementAddressForIntIndex(bool is_external, | |
1031 intptr_t cid, | |
1032 intptr_t index_scale, | |
1033 Register array, | |
1034 intptr_t index) { | |
1035 const int64_t offset = index * index_scale + | |
1036 (is_external ? 0 : (Instance::DataOffsetFor(cid) - kHeapObjectTag)); | |
1037 ASSERT(Utils::IsInt(32, offset)); | |
1038 const OperandSize size = Address::OperandSizeFor(cid); | |
1039 ASSERT(Address::CanHoldOffset(offset, Address::Offset, size)); | |
1040 return Address(array, static_cast<int32_t>(offset), Address::Offset, size); | |
1041 } | |
1042 | |
1043 | |
1044 static Address ElementAddressForRegIndex(Assembler* assembler, | |
1045 bool is_load, | |
1046 bool is_external, | |
1047 intptr_t cid, | |
1048 intptr_t index_scale, | |
1049 Register array, | |
1050 Register index) { | |
1051 // Note that index is expected smi-tagged, (i.e, LSL 1) for all arrays. | |
1052 const intptr_t shift = Utils::ShiftForPowerOfTwo(index_scale) - kSmiTagShift; | |
1053 const int32_t offset = | |
1054 is_external ? 0 : (Instance::DataOffsetFor(cid) - kHeapObjectTag); | |
1055 ASSERT(array != TMP); | |
1056 ASSERT(index != TMP); | |
1057 const Register base = is_load ? TMP : index; | |
1058 if ((offset == 0) && (shift == 0)) { | |
1059 return Address(array, index, UXTX, Address::Unscaled); | |
1060 } else if (shift < 0) { | |
1061 ASSERT(shift == -1); | |
1062 assembler->add(base, array, Operand(index, ASR, 1)); | |
1063 } else { | |
1064 assembler->add(base, array, Operand(index, LSL, shift)); | |
1065 } | |
1066 const OperandSize size = Address::OperandSizeFor(cid); | |
1067 ASSERT(Address::CanHoldOffset(offset, Address::Offset, size)); | |
1068 return Address(base, offset, Address::Offset, size); | |
1069 } | |
1070 | |
1071 | |
1072 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1030 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
1073 // The array register points to the backing store for external arrays. | 1031 // The array register points to the backing store for external arrays. |
1074 const Register array = locs()->in(0).reg(); | 1032 const Register array = locs()->in(0).reg(); |
1075 const Location index = locs()->in(1); | 1033 const Location index = locs()->in(1); |
1076 | 1034 |
1077 Address element_address = index.IsRegister() | 1035 Address element_address = index.IsRegister() |
1078 ? ElementAddressForRegIndex(compiler->assembler(), | 1036 ? __ ElementAddressForRegIndex(true, // Load. |
1079 true, // Load. | 1037 IsExternal(), class_id(), index_scale(), |
1080 IsExternal(), class_id(), index_scale(), | 1038 array, index.reg()) |
1081 array, index.reg()) | 1039 : __ ElementAddressForIntIndex( |
1082 : ElementAddressForIntIndex(IsExternal(), class_id(), index_scale(), | 1040 IsExternal(), class_id(), index_scale(), |
1083 array, Smi::Cast(index.constant()).Value()); | 1041 array, Smi::Cast(index.constant()).Value()); |
1084 // Warning: element_address may use register TMP as base. | 1042 // Warning: element_address may use register TMP as base. |
1085 | 1043 |
1086 if ((representation() == kUnboxedDouble) || | 1044 if ((representation() == kUnboxedDouble) || |
1087 (representation() == kUnboxedFloat32x4) || | 1045 (representation() == kUnboxedFloat32x4) || |
1088 (representation() == kUnboxedInt32x4) || | 1046 (representation() == kUnboxedInt32x4) || |
1089 (representation() == kUnboxedFloat64x2)) { | 1047 (representation() == kUnboxedFloat64x2)) { |
1090 const VRegister result = locs()->out(0).fpu_reg(); | 1048 const VRegister result = locs()->out(0).fpu_reg(); |
1091 switch (class_id()) { | 1049 switch (class_id()) { |
1092 case kTypedDataFloat32ArrayCid: | 1050 case kTypedDataFloat32ArrayCid: |
1093 // Load single precision float. | 1051 // Load single precision float. |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1230 return locs; | 1188 return locs; |
1231 } | 1189 } |
1232 | 1190 |
1233 | 1191 |
1234 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1192 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
1235 // The array register points to the backing store for external arrays. | 1193 // The array register points to the backing store for external arrays. |
1236 const Register array = locs()->in(0).reg(); | 1194 const Register array = locs()->in(0).reg(); |
1237 const Location index = locs()->in(1); | 1195 const Location index = locs()->in(1); |
1238 | 1196 |
1239 Address element_address = index.IsRegister() | 1197 Address element_address = index.IsRegister() |
1240 ? ElementAddressForRegIndex(compiler->assembler(), | 1198 ? __ ElementAddressForRegIndex(false, // Store. |
1241 false, // Store. | 1199 IsExternal(), class_id(), index_scale(), |
1242 IsExternal(), class_id(), index_scale(), | 1200 array, index.reg()) |
1243 array, index.reg()) | 1201 : __ ElementAddressForIntIndex( |
1244 : ElementAddressForIntIndex(IsExternal(), class_id(), index_scale(), | 1202 IsExternal(), class_id(), index_scale(), |
1245 array, Smi::Cast(index.constant()).Value()); | 1203 array, Smi::Cast(index.constant()).Value()); |
1246 | 1204 |
1247 switch (class_id()) { | 1205 switch (class_id()) { |
1248 case kArrayCid: | 1206 case kArrayCid: |
1249 if (ShouldEmitStoreBarrier()) { | 1207 if (ShouldEmitStoreBarrier()) { |
1250 const Register value = locs()->in(2).reg(); | 1208 const Register value = locs()->in(2).reg(); |
1251 __ StoreIntoObject(array, element_address, value); | 1209 __ StoreIntoObject(array, element_address, value); |
1252 } else if (locs()->in(2).IsConstant()) { | 1210 } else if (locs()->in(2).IsConstant()) { |
1253 const Object& constant = locs()->in(2).constant(); | 1211 const Object& constant = locs()->in(2).constant(); |
1254 __ StoreIntoObjectNoBarrier(array, element_address, constant); | 1212 __ StoreIntoObjectNoBarrier(array, element_address, constant); |
1255 } else { | 1213 } else { |
(...skipping 4260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5516 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs()); | 5474 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs()); |
5517 #if defined(DEBUG) | 5475 #if defined(DEBUG) |
5518 __ LoadImmediate(R4, kInvalidObjectPointer, kNoPP); | 5476 __ LoadImmediate(R4, kInvalidObjectPointer, kNoPP); |
5519 __ LoadImmediate(R5, kInvalidObjectPointer, kNoPP); | 5477 __ LoadImmediate(R5, kInvalidObjectPointer, kNoPP); |
5520 #endif | 5478 #endif |
5521 } | 5479 } |
5522 | 5480 |
5523 } // namespace dart | 5481 } // namespace dart |
5524 | 5482 |
5525 #endif // defined TARGET_ARCH_ARM64 | 5483 #endif // defined TARGET_ARCH_ARM64 |
OLD | NEW |