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 #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 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
112 PCOffset, | 112 PCOffset, |
113 Unknown, | 113 Unknown, |
114 }; | 114 }; |
115 | 115 |
116 // Offset is in bytes. For the unsigned imm12 case, we unscale based on the | 116 // Offset is in bytes. For the unsigned imm12 case, we unscale based on the |
117 // operand size, and assert that offset is aligned accordingly. | 117 // operand size, and assert that offset is aligned accordingly. |
118 // For the smaller signed imm9 case, the offset is the number of bytes, but | 118 // For the smaller signed imm9 case, the offset is the number of bytes, but |
119 // is unscaled. | 119 // is unscaled. |
120 Address(Register rn, int32_t offset = 0, AddressType at = Offset, | 120 Address(Register rn, int32_t offset = 0, AddressType at = Offset, |
121 OperandSize sz = kDoubleWord) { | 121 OperandSize sz = kDoubleWord) { |
122 ASSERT((rn != R31) && (rn != ZR)); | 122 ASSERT((rn != kNoRegister) && (rn != R31) && (rn != ZR)); |
123 ASSERT(CanHoldOffset(offset, at, sz)); | 123 ASSERT(CanHoldOffset(offset, at, sz)); |
124 const Register crn = ConcreteRegister(rn); | 124 const Register crn = ConcreteRegister(rn); |
125 const int32_t scale = Log2OperandSizeBytes(sz); | 125 const int32_t scale = Log2OperandSizeBytes(sz); |
126 if ((at == Offset) && | 126 if ((at == Offset) && |
127 Utils::IsUint(12 + scale, offset) && | 127 Utils::IsUint(12 + scale, offset) && |
128 (offset == ((offset >> scale) << scale))) { | 128 (offset == ((offset >> scale) << scale))) { |
129 encoding_ = | 129 encoding_ = |
130 B24 | | 130 B24 | |
131 ((offset >> scale) << kImm12Shift) | | 131 ((offset >> scale) << kImm12Shift) | |
132 (static_cast<int32_t>(crn) << kRnShift); | 132 (static_cast<int32_t>(crn) << kRnShift); |
(...skipping 1021 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1154 void TagAndPushPPAndPcMarker(Register pc_marker_reg) { | 1154 void TagAndPushPPAndPcMarker(Register pc_marker_reg) { |
1155 ASSERT(pc_marker_reg != TMP2); | 1155 ASSERT(pc_marker_reg != TMP2); |
1156 // Add the heap object tag back to PP before putting it on the stack. | 1156 // Add the heap object tag back to PP before putting it on the stack. |
1157 add(TMP2, PP, Operand(kHeapObjectTag)); | 1157 add(TMP2, PP, Operand(kHeapObjectTag)); |
1158 stp(TMP2, pc_marker_reg, | 1158 stp(TMP2, pc_marker_reg, |
1159 Address(SP, -2 * kWordSize, Address::PairPreIndex)); | 1159 Address(SP, -2 * kWordSize, Address::PairPreIndex)); |
1160 } | 1160 } |
1161 void PopAndUntagPP() { | 1161 void PopAndUntagPP() { |
1162 ldr(PP, Address(SP, 1 * kWordSize, Address::PostIndex)); | 1162 ldr(PP, Address(SP, 1 * kWordSize, Address::PostIndex)); |
1163 sub(PP, PP, Operand(kHeapObjectTag)); | 1163 sub(PP, PP, Operand(kHeapObjectTag)); |
| 1164 // The caller of PopAndUntagPP() must explicitly allow use of popped PP. |
| 1165 set_constant_pool_allowed(false); |
1164 } | 1166 } |
1165 void tst(Register rn, Operand o) { | 1167 void tst(Register rn, Operand o) { |
1166 ands(ZR, rn, o); | 1168 ands(ZR, rn, o); |
1167 } | 1169 } |
1168 void tsti(Register rn, const Immediate& imm) { | 1170 void tsti(Register rn, const Immediate& imm) { |
1169 andis(ZR, rn, imm); | 1171 andis(ZR, rn, imm); |
1170 } | 1172 } |
1171 | 1173 |
1172 void LslImmediate(Register rd, Register rn, int shift) { | 1174 void LslImmediate(Register rd, Register rn, int shift) { |
1173 add(rd, ZR, Operand(rn, LSL, shift)); | 1175 add(rd, ZR, Operand(rn, LSL, shift)); |
(...skipping 15 matching lines...) Expand all Loading... |
1189 AsrImmediate(dst, src, kSmiTagSize); | 1191 AsrImmediate(dst, src, kSmiTagSize); |
1190 } | 1192 } |
1191 void SmiTag(Register reg) { | 1193 void SmiTag(Register reg) { |
1192 LslImmediate(reg, reg, kSmiTagSize); | 1194 LslImmediate(reg, reg, kSmiTagSize); |
1193 } | 1195 } |
1194 void SmiTag(Register dst, Register src) { | 1196 void SmiTag(Register dst, Register src) { |
1195 LslImmediate(dst, src, kSmiTagSize); | 1197 LslImmediate(dst, src, kSmiTagSize); |
1196 } | 1198 } |
1197 | 1199 |
1198 // Branching to ExternalLabels. | 1200 // Branching to ExternalLabels. |
1199 void Branch(const ExternalLabel* label, Register pp) { | 1201 void Branch(const ExternalLabel* label) { |
1200 LoadExternalLabel(TMP, label, kNotPatchable, pp); | 1202 LoadExternalLabel(TMP, label); |
1201 br(TMP); | 1203 br(TMP); |
1202 } | 1204 } |
1203 | 1205 |
1204 // Fixed length branch to label. | 1206 // Fixed length branch to label. |
1205 void BranchPatchable(const ExternalLabel* label) { | 1207 void BranchPatchable(const ExternalLabel* label) { |
1206 // TODO(zra): Use LoadExternalLabelFixed if possible. | 1208 // TODO(zra): Use LoadExternalLabelFixed if possible. |
1207 LoadImmediateFixed(TMP, label->address()); | 1209 LoadImmediateFixed(TMP, label->address()); |
1208 br(TMP); | 1210 br(TMP); |
1209 } | 1211 } |
1210 | 1212 |
1211 void BranchLink(const ExternalLabel* label, Register pp) { | 1213 void BranchLink(const ExternalLabel* label) { |
1212 LoadExternalLabel(TMP, label, kNotPatchable, pp); | 1214 LoadExternalLabel(TMP, label); |
1213 blr(TMP); | 1215 blr(TMP); |
1214 } | 1216 } |
1215 | 1217 |
1216 // BranchLinkPatchable must be a fixed-length sequence so we can patch it | 1218 // BranchLinkPatchable must be a fixed-length sequence so we can patch it |
1217 // with the debugger. | 1219 // with the debugger. |
1218 void BranchLinkPatchable(const ExternalLabel* label) { | 1220 void BranchLinkPatchable(const ExternalLabel* label) { |
1219 LoadExternalLabelFixed(TMP, label, kPatchable, PP); | 1221 LoadExternalLabelFixed(TMP, label, kPatchable); |
1220 blr(TMP); | 1222 blr(TMP); |
1221 } | 1223 } |
1222 | 1224 |
1223 // Macros accepting a pp Register argument may attempt to load values from | 1225 // Macros accepting a pp Register argument may attempt to load values from |
1224 // the object pool when possible. Unless you are sure that the untagged object | 1226 // the object pool when possible. Unless you are sure that the untagged object |
1225 // pool pointer is in another register, or that it is not available at all, | 1227 // pool pointer is in another register, or that it is not available at all, |
1226 // PP should be passed for pp. | 1228 // PP should be passed for pp. |
1227 void AddImmediate(Register dest, Register rn, int64_t imm, Register pp); | 1229 void AddImmediate(Register dest, Register rn, int64_t imm); |
1228 void AddImmediateSetFlags( | 1230 void AddImmediateSetFlags(Register dest, Register rn, int64_t imm); |
1229 Register dest, Register rn, int64_t imm, Register pp); | 1231 void SubImmediateSetFlags(Register dest, Register rn, int64_t imm); |
1230 void SubImmediateSetFlags( | 1232 void AndImmediate(Register rd, Register rn, int64_t imm); |
1231 Register dest, Register rn, int64_t imm, Register pp); | 1233 void OrImmediate(Register rd, Register rn, int64_t imm); |
1232 void AndImmediate(Register rd, Register rn, int64_t imm, Register pp); | 1234 void XorImmediate(Register rd, Register rn, int64_t imm); |
1233 void OrImmediate(Register rd, Register rn, int64_t imm, Register pp); | 1235 void TestImmediate(Register rn, int64_t imm); |
1234 void XorImmediate(Register rd, Register rn, int64_t imm, Register pp); | 1236 void CompareImmediate(Register rn, int64_t imm); |
1235 void TestImmediate(Register rn, int64_t imm, Register pp); | |
1236 void CompareImmediate(Register rn, int64_t imm, Register pp); | |
1237 | 1237 |
1238 void LoadFromOffset(Register dest, Register base, int32_t offset, | 1238 void LoadFromOffset(Register dest, Register base, int32_t offset, |
1239 Register pp, OperandSize sz = kDoubleWord); | 1239 OperandSize sz = kDoubleWord); |
1240 void LoadFieldFromOffset(Register dest, Register base, int32_t offset, | 1240 void LoadFieldFromOffset(Register dest, Register base, int32_t offset, |
1241 Register pp, OperandSize sz = kDoubleWord) { | 1241 OperandSize sz = kDoubleWord) { |
1242 LoadFromOffset(dest, base, offset - kHeapObjectTag, pp, sz); | 1242 LoadFromOffset(dest, base, offset - kHeapObjectTag, sz); |
1243 } | 1243 } |
1244 void LoadDFromOffset( | 1244 void LoadDFromOffset(VRegister dest, Register base, int32_t offset); |
1245 VRegister dest, Register base, int32_t offset, Register pp); | 1245 void LoadDFieldFromOffset(VRegister dest, Register base, int32_t offset) { |
1246 void LoadDFieldFromOffset( | 1246 LoadDFromOffset(dest, base, offset - kHeapObjectTag); |
1247 VRegister dest, Register base, int32_t offset, Register pp) { | |
1248 LoadDFromOffset(dest, base, offset - kHeapObjectTag, pp); | |
1249 } | 1247 } |
1250 void LoadQFromOffset( | 1248 void LoadQFromOffset(VRegister dest, Register base, int32_t offset); |
1251 VRegister dest, Register base, int32_t offset, Register pp); | 1249 void LoadQFieldFromOffset(VRegister dest, Register base, int32_t offset) { |
1252 void LoadQFieldFromOffset( | 1250 LoadQFromOffset(dest, base, offset - kHeapObjectTag); |
1253 VRegister dest, Register base, int32_t offset, Register pp) { | |
1254 LoadQFromOffset(dest, base, offset - kHeapObjectTag, pp); | |
1255 } | 1251 } |
1256 | 1252 |
1257 void StoreToOffset(Register src, Register base, int32_t offset, | 1253 void StoreToOffset(Register src, Register base, int32_t offset, |
1258 Register pp, OperandSize sz = kDoubleWord); | 1254 OperandSize sz = kDoubleWord); |
1259 void StoreFieldToOffset(Register src, Register base, int32_t offset, | 1255 void StoreFieldToOffset(Register src, Register base, int32_t offset, |
1260 Register pp, OperandSize sz = kDoubleWord) { | 1256 OperandSize sz = kDoubleWord) { |
1261 StoreToOffset(src, base, offset - kHeapObjectTag, pp, sz); | 1257 StoreToOffset(src, base, offset - kHeapObjectTag, sz); |
1262 } | 1258 } |
1263 void StoreDToOffset( | 1259 void StoreDToOffset(VRegister src, Register base, int32_t offset); |
1264 VRegister src, Register base, int32_t offset, Register pp); | 1260 void StoreDFieldToOffset(VRegister src, Register base, int32_t offset) { |
1265 void StoreDFieldToOffset( | 1261 StoreDToOffset(src, base, offset - kHeapObjectTag); |
1266 VRegister src, Register base, int32_t offset, Register pp) { | |
1267 StoreDToOffset(src, base, offset - kHeapObjectTag, pp); | |
1268 } | 1262 } |
1269 void StoreQToOffset( | 1263 void StoreQToOffset(VRegister src, Register base, int32_t offset); |
1270 VRegister src, Register base, int32_t offset, Register pp); | 1264 void StoreQFieldToOffset(VRegister src, Register base, int32_t offset) { |
1271 void StoreQFieldToOffset( | 1265 StoreQToOffset(src, base, offset - kHeapObjectTag); |
1272 VRegister src, Register base, int32_t offset, Register pp) { | |
1273 StoreQToOffset(src, base, offset - kHeapObjectTag, pp); | |
1274 } | 1266 } |
1275 | 1267 |
1276 // Storing into an object. | 1268 // Storing into an object. |
1277 void StoreIntoObject(Register object, | 1269 void StoreIntoObject(Register object, |
1278 const Address& dest, | 1270 const Address& dest, |
1279 Register value, | 1271 Register value, |
1280 bool can_value_be_smi = true); | 1272 bool can_value_be_smi = true); |
1281 void StoreIntoObjectOffset(Register object, | 1273 void StoreIntoObjectOffset(Register object, |
1282 int32_t offset, | 1274 int32_t offset, |
1283 Register value, | 1275 Register value, |
1284 Register pp, | |
1285 bool can_value_be_smi = true); | 1276 bool can_value_be_smi = true); |
1286 void StoreIntoObjectNoBarrier(Register object, | 1277 void StoreIntoObjectNoBarrier(Register object, |
1287 const Address& dest, | 1278 const Address& dest, |
1288 Register value); | 1279 Register value); |
1289 void StoreIntoObjectOffsetNoBarrier(Register object, | 1280 void StoreIntoObjectOffsetNoBarrier(Register object, |
1290 int32_t offset, | 1281 int32_t offset, |
1291 Register value, | 1282 Register value); |
1292 Register pp); | |
1293 void StoreIntoObjectNoBarrier(Register object, | 1283 void StoreIntoObjectNoBarrier(Register object, |
1294 const Address& dest, | 1284 const Address& dest, |
1295 const Object& value); | 1285 const Object& value); |
1296 void StoreIntoObjectOffsetNoBarrier(Register object, | 1286 void StoreIntoObjectOffsetNoBarrier(Register object, |
1297 int32_t offset, | 1287 int32_t offset, |
1298 const Object& value, | 1288 const Object& value); |
1299 Register pp); | |
1300 | 1289 |
1301 // Object pool, loading from pool, etc. | 1290 // Object pool, loading from pool, etc. |
1302 void LoadPoolPointer(Register pp); | 1291 void LoadPoolPointer(); |
1303 | 1292 |
1304 bool constant_pool_allowed() const { | 1293 bool constant_pool_allowed() const { |
1305 return constant_pool_allowed_; | 1294 return constant_pool_allowed_; |
1306 } | 1295 } |
1307 void set_constant_pool_allowed(bool b) { | 1296 void set_constant_pool_allowed(bool b) { |
1308 constant_pool_allowed_ = b; | 1297 constant_pool_allowed_ = b; |
1309 } | 1298 } |
1310 | 1299 |
1311 void LoadWordFromPoolOffset(Register dst, Register pp, uint32_t offset); | 1300 void LoadWordFromPoolOffset(Register dst, uint32_t offset); |
1312 void LoadWordFromPoolOffsetFixed(Register dst, Register pp, uint32_t offset); | 1301 void LoadWordFromPoolOffsetFixed(Register dst, uint32_t offset); |
1313 intptr_t FindImmediate(int64_t imm); | 1302 intptr_t FindImmediate(int64_t imm); |
1314 bool CanLoadFromObjectPool(const Object& object) const; | 1303 bool CanLoadFromObjectPool(const Object& object) const; |
1315 bool CanLoadImmediateFromPool(int64_t imm, Register pp); | 1304 void LoadExternalLabel(Register dst, const ExternalLabel* label); |
1316 void LoadExternalLabel(Register dst, const ExternalLabel* label, | |
1317 Patchability patchable, Register pp); | |
1318 void LoadExternalLabelFixed(Register dst, | 1305 void LoadExternalLabelFixed(Register dst, |
1319 const ExternalLabel* label, | 1306 const ExternalLabel* label, |
1320 Patchability patchable, | 1307 Patchability patchable); |
1321 Register pp); | |
1322 void LoadIsolate(Register dst); | 1308 void LoadIsolate(Register dst); |
1323 void LoadObject(Register dst, const Object& obj, Register pp); | 1309 void LoadObject(Register dst, const Object& obj); |
1324 void LoadUniqueObject(Register dst, const Object& obj, Register pp); | 1310 void LoadUniqueObject(Register dst, const Object& obj); |
1325 void LoadDecodableImmediate(Register reg, int64_t imm, Register pp); | 1311 void LoadDecodableImmediate(Register reg, int64_t imm); |
1326 void LoadImmediateFixed(Register reg, int64_t imm); | 1312 void LoadImmediateFixed(Register reg, int64_t imm); |
1327 void LoadImmediate(Register reg, int64_t imm, Register pp); | 1313 void LoadImmediate(Register reg, int64_t imm); |
1328 void LoadDImmediate(VRegister reg, double immd, Register pp); | 1314 void LoadDImmediate(VRegister reg, double immd); |
1329 | 1315 |
1330 void PushObject(const Object& object, Register pp) { | 1316 void PushObject(const Object& object) { |
1331 LoadObject(TMP, object, pp); | 1317 LoadObject(TMP, object); |
1332 Push(TMP); | 1318 Push(TMP); |
1333 } | 1319 } |
1334 void CompareObject(Register reg, const Object& object, Register pp); | 1320 void CompareObject(Register reg, const Object& object); |
1335 | 1321 |
1336 void LoadClassId(Register result, Register object, Register pp); | 1322 void LoadClassId(Register result, Register object); |
1337 void LoadClassById(Register result, Register class_id, Register pp); | 1323 void LoadClassById(Register result, Register class_id); |
1338 void LoadClass(Register result, Register object, Register pp); | 1324 void LoadClass(Register result, Register object); |
1339 void CompareClassId(Register object, intptr_t class_id, Register pp); | 1325 void CompareClassId(Register object, intptr_t class_id); |
1340 void LoadClassIdMayBeSmi(Register result, Register object); | 1326 void LoadClassIdMayBeSmi(Register result, Register object); |
1341 void LoadTaggedClassIdMayBeSmi(Register result, Register object); | 1327 void LoadTaggedClassIdMayBeSmi(Register result, Register object); |
1342 | 1328 |
1343 void ComputeRange(Register result, | 1329 void ComputeRange(Register result, |
1344 Register value, | 1330 Register value, |
1345 Register scratch, | 1331 Register scratch, |
1346 Label* miss); | 1332 Label* miss); |
1347 | 1333 |
1348 void UpdateRangeFeedback(Register value, | 1334 void UpdateRangeFeedback(Register value, |
1349 intptr_t idx, | 1335 intptr_t idx, |
(...skipping 22 matching lines...) Expand all Loading... |
1372 void EnterCallRuntimeFrame(intptr_t frame_size); | 1358 void EnterCallRuntimeFrame(intptr_t frame_size); |
1373 void LeaveCallRuntimeFrame(); | 1359 void LeaveCallRuntimeFrame(); |
1374 void CallRuntime(const RuntimeEntry& entry, intptr_t argument_count); | 1360 void CallRuntime(const RuntimeEntry& entry, intptr_t argument_count); |
1375 | 1361 |
1376 // Set up a stub frame so that the stack traversal code can easily identify | 1362 // Set up a stub frame so that the stack traversal code can easily identify |
1377 // a stub frame. | 1363 // a stub frame. |
1378 void EnterStubFrame(); | 1364 void EnterStubFrame(); |
1379 void LeaveStubFrame(); | 1365 void LeaveStubFrame(); |
1380 | 1366 |
1381 void UpdateAllocationStats(intptr_t cid, | 1367 void UpdateAllocationStats(intptr_t cid, |
1382 Register pp, | |
1383 Heap::Space space, | 1368 Heap::Space space, |
1384 bool inline_isolate = true); | 1369 bool inline_isolate = true); |
1385 | 1370 |
1386 void UpdateAllocationStatsWithSize(intptr_t cid, | 1371 void UpdateAllocationStatsWithSize(intptr_t cid, |
1387 Register size_reg, | 1372 Register size_reg, |
1388 Register pp, | |
1389 Heap::Space space, | 1373 Heap::Space space, |
1390 bool inline_isolate = true); | 1374 bool inline_isolate = true); |
1391 | 1375 |
1392 // If allocation tracing for |cid| is enabled, will jump to |trace| label, | 1376 // If allocation tracing for |cid| is enabled, will jump to |trace| label, |
1393 // which will allocate in the runtime where tracing occurs. | 1377 // which will allocate in the runtime where tracing occurs. |
1394 void MaybeTraceAllocation(intptr_t cid, | 1378 void MaybeTraceAllocation(intptr_t cid, |
1395 Register temp_reg, | 1379 Register temp_reg, |
1396 Register pp, | |
1397 Label* trace, | 1380 Label* trace, |
1398 bool inline_isolate = true); | 1381 bool inline_isolate = true); |
1399 | 1382 |
1400 // Inlined allocation of an instance of class 'cls', code has no runtime | 1383 // Inlined allocation of an instance of class 'cls', code has no runtime |
1401 // calls. Jump to 'failure' if the instance cannot be allocated here. | 1384 // calls. Jump to 'failure' if the instance cannot be allocated here. |
1402 // Allocated instance is returned in 'instance_reg'. | 1385 // Allocated instance is returned in 'instance_reg'. |
1403 // Only the tags field of the object is initialized. | 1386 // Only the tags field of the object is initialized. |
1404 void TryAllocate(const Class& cls, | 1387 void TryAllocate(const Class& cls, |
1405 Label* failure, | 1388 Label* failure, |
1406 Register instance_reg, | 1389 Register instance_reg, |
1407 Register temp_reg, | 1390 Register temp_reg); |
1408 Register pp); | |
1409 | 1391 |
1410 void TryAllocateArray(intptr_t cid, | 1392 void TryAllocateArray(intptr_t cid, |
1411 intptr_t instance_size, | 1393 intptr_t instance_size, |
1412 Label* failure, | 1394 Label* failure, |
1413 Register instance, | 1395 Register instance, |
1414 Register end_address, | 1396 Register end_address, |
1415 Register temp1, | 1397 Register temp1, |
1416 Register temp2); | 1398 Register temp2); |
1417 | 1399 |
1418 Address ElementAddressForIntIndex(bool is_external, | 1400 Address ElementAddressForIntIndex(bool is_external, |
(...skipping 29 matching lines...) Expand all Loading... |
1448 intptr_t pc_offset_; | 1430 intptr_t pc_offset_; |
1449 const String& comment_; | 1431 const String& comment_; |
1450 | 1432 |
1451 DISALLOW_COPY_AND_ASSIGN(CodeComment); | 1433 DISALLOW_COPY_AND_ASSIGN(CodeComment); |
1452 }; | 1434 }; |
1453 | 1435 |
1454 GrowableArray<CodeComment*> comments_; | 1436 GrowableArray<CodeComment*> comments_; |
1455 | 1437 |
1456 bool constant_pool_allowed_; | 1438 bool constant_pool_allowed_; |
1457 | 1439 |
1458 void LoadObjectHelper(Register dst, | 1440 void LoadObjectHelper(Register dst, const Object& obj, bool is_unique); |
1459 const Object& obj, | |
1460 Register pp, | |
1461 bool is_unique); | |
1462 | 1441 |
1463 void AddSubHelper(OperandSize os, bool set_flags, bool subtract, | 1442 void AddSubHelper(OperandSize os, bool set_flags, bool subtract, |
1464 Register rd, Register rn, Operand o) { | 1443 Register rd, Register rn, Operand o) { |
1465 ASSERT((rd != R31) && (rn != R31)); | 1444 ASSERT((rd != R31) && (rn != R31)); |
1466 const Register crd = ConcreteRegister(rd); | 1445 const Register crd = ConcreteRegister(rd); |
1467 const Register crn = ConcreteRegister(rn); | 1446 const Register crn = ConcreteRegister(rn); |
1468 if (o.type() == Operand::Immediate) { | 1447 if (o.type() == Operand::Immediate) { |
1469 ASSERT(rn != ZR); | 1448 ASSERT(rn != ZR); |
1470 EmitAddSubImmOp(subtract ? SUBI : ADDI, crd, crn, o, os, set_flags); | 1449 EmitAddSubImmOp(subtract ? SUBI : ADDI, crd, crn, o, os, set_flags); |
1471 } else if (o.type() == Operand::Shifted) { | 1450 } else if (o.type() == Operand::Shifted) { |
(...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1952 Register value, | 1931 Register value, |
1953 Label* no_update); | 1932 Label* no_update); |
1954 | 1933 |
1955 DISALLOW_ALLOCATION(); | 1934 DISALLOW_ALLOCATION(); |
1956 DISALLOW_COPY_AND_ASSIGN(Assembler); | 1935 DISALLOW_COPY_AND_ASSIGN(Assembler); |
1957 }; | 1936 }; |
1958 | 1937 |
1959 } // namespace dart | 1938 } // namespace dart |
1960 | 1939 |
1961 #endif // VM_ASSEMBLER_ARM64_H_ | 1940 #endif // VM_ASSEMBLER_ARM64_H_ |
OLD | NEW |