| 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" // NOLINT | 5 #include "vm/globals.h" // NOLINT |
| 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 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 353 const Operand::OperandType ot = | 353 const Operand::OperandType ot = |
| 354 Operand::CanHold(upper20, kXRegSizeInBits, &op); | 354 Operand::CanHold(upper20, kXRegSizeInBits, &op); |
| 355 ASSERT(ot == Operand::Immediate); | 355 ASSERT(ot == Operand::Immediate); |
| 356 ASSERT(Address::CanHoldOffset(lower12)); | 356 ASSERT(Address::CanHoldOffset(lower12)); |
| 357 add(dst, pp, op); | 357 add(dst, pp, op); |
| 358 ldr(dst, Address(dst, lower12)); | 358 ldr(dst, Address(dst, lower12)); |
| 359 } | 359 } |
| 360 | 360 |
| 361 | 361 |
| 362 intptr_t Assembler::FindImmediate(int64_t imm) { | 362 intptr_t Assembler::FindImmediate(int64_t imm) { |
| 363 ASSERT(Isolate::Current() != Dart::vm_isolate()); | |
| 364 return object_pool_wrapper_.FindImmediate(imm); | 363 return object_pool_wrapper_.FindImmediate(imm); |
| 365 } | 364 } |
| 366 | 365 |
| 367 | 366 |
| 368 bool Assembler::CanLoadFromObjectPool(const Object& object) const { | 367 bool Assembler::CanLoadFromObjectPool(const Object& object) const { |
| 369 ASSERT(!Thread::CanLoadFromThread(object)); | 368 ASSERT(!Thread::CanLoadFromThread(object)); |
| 370 if (!allow_constant_pool()) { | 369 if (!allow_constant_pool()) { |
| 371 return false; | 370 return false; |
| 372 } | 371 } |
| 373 | 372 |
| 374 // TODO(zra, kmillikin): Also load other large immediates from the object | 373 // TODO(zra, kmillikin): Also load other large immediates from the object |
| 375 // pool | 374 // pool |
| 376 if (object.IsSmi()) { | 375 if (object.IsSmi()) { |
| 377 // If the raw smi does not fit into a 32-bit signed int, then we'll keep | 376 // If the raw smi does not fit into a 32-bit signed int, then we'll keep |
| 378 // the raw value in the object pool. | 377 // the raw value in the object pool. |
| 379 return !Utils::IsInt(32, reinterpret_cast<int64_t>(object.raw())); | 378 return !Utils::IsInt(32, reinterpret_cast<int64_t>(object.raw())); |
| 380 } | 379 } |
| 381 ASSERT(object.IsNotTemporaryScopedHandle()); | 380 ASSERT(object.IsNotTemporaryScopedHandle()); |
| 382 ASSERT(object.IsOld()); | 381 ASSERT(object.IsOld()); |
| 383 return (Isolate::Current() != Dart::vm_isolate()); | 382 return true; |
| 384 } | 383 } |
| 385 | 384 |
| 386 | 385 |
| 387 bool Assembler::CanLoadImmediateFromPool(int64_t imm, Register pp) { | 386 bool Assembler::CanLoadImmediateFromPool(int64_t imm, Register pp) { |
| 388 if (!allow_constant_pool()) { | 387 if (!allow_constant_pool()) { |
| 389 return false; | 388 return false; |
| 390 } | 389 } |
| 391 return !Utils::IsInt(32, imm) && | 390 return !Utils::IsInt(32, imm) && (pp != kNoPP); |
| 392 (pp != kNoPP) && | |
| 393 // We *could* put constants in the pool in a VM isolate, but it is | |
| 394 // simpler to maintain the invariant that the object pool is not used | |
| 395 // in the VM isolate. | |
| 396 (Isolate::Current() != Dart::vm_isolate()); | |
| 397 } | 391 } |
| 398 | 392 |
| 399 | 393 |
| 400 void Assembler::LoadExternalLabel(Register dst, | 394 void Assembler::LoadExternalLabel(Register dst, |
| 401 const ExternalLabel* label, | 395 const ExternalLabel* label, |
| 402 Patchability patchable, | 396 Patchability patchable, |
| 403 Register pp) { | 397 Register pp) { |
| 404 const int64_t target = static_cast<int64_t>(label->address()); | 398 const int64_t target = static_cast<int64_t>(label->address()); |
| 405 if (CanLoadImmediateFromPool(target, pp)) { | 399 if (CanLoadImmediateFromPool(target, pp)) { |
| 406 const int32_t offset = ObjectPool::element_offset( | 400 const int32_t offset = ObjectPool::element_offset( |
| (...skipping 25 matching lines...) Expand all Loading... |
| 432 Register pp, | 426 Register pp, |
| 433 bool is_unique) { | 427 bool is_unique) { |
| 434 if (Thread::CanLoadFromThread(object)) { | 428 if (Thread::CanLoadFromThread(object)) { |
| 435 ldr(dst, Address(THR, Thread::OffsetFromThread(object))); | 429 ldr(dst, Address(THR, Thread::OffsetFromThread(object))); |
| 436 } else if (CanLoadFromObjectPool(object)) { | 430 } else if (CanLoadFromObjectPool(object)) { |
| 437 const int32_t offset = ObjectPool::element_offset( | 431 const int32_t offset = ObjectPool::element_offset( |
| 438 is_unique ? object_pool_wrapper_.AddObject(object) | 432 is_unique ? object_pool_wrapper_.AddObject(object) |
| 439 : object_pool_wrapper_.FindObject(object)); | 433 : object_pool_wrapper_.FindObject(object)); |
| 440 LoadWordFromPoolOffset(dst, pp, offset); | 434 LoadWordFromPoolOffset(dst, pp, offset); |
| 441 } else { | 435 } else { |
| 442 ASSERT((Isolate::Current() == Dart::vm_isolate()) || | 436 ASSERT(object.IsSmi() || object.InVMHeap()); |
| 443 object.IsSmi() || | |
| 444 object.InVMHeap()); | |
| 445 LoadDecodableImmediate(dst, reinterpret_cast<int64_t>(object.raw()), pp); | 437 LoadDecodableImmediate(dst, reinterpret_cast<int64_t>(object.raw()), pp); |
| 446 } | 438 } |
| 447 } | 439 } |
| 448 | 440 |
| 449 | 441 |
| 450 void Assembler::LoadObject(Register dst, const Object& object, Register pp) { | 442 void Assembler::LoadObject(Register dst, const Object& object, Register pp) { |
| 451 LoadObjectHelper(dst, object, pp, false); | 443 LoadObjectHelper(dst, object, pp, false); |
| 452 } | 444 } |
| 453 | 445 |
| 454 | 446 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 466 } else if (CanLoadFromObjectPool(object)) { | 458 } else if (CanLoadFromObjectPool(object)) { |
| 467 LoadObject(TMP, object, pp); | 459 LoadObject(TMP, object, pp); |
| 468 CompareRegisters(reg, TMP); | 460 CompareRegisters(reg, TMP); |
| 469 } else { | 461 } else { |
| 470 CompareImmediate(reg, reinterpret_cast<int64_t>(object.raw()), pp); | 462 CompareImmediate(reg, reinterpret_cast<int64_t>(object.raw()), pp); |
| 471 } | 463 } |
| 472 } | 464 } |
| 473 | 465 |
| 474 | 466 |
| 475 void Assembler::LoadDecodableImmediate(Register reg, int64_t imm, Register pp) { | 467 void Assembler::LoadDecodableImmediate(Register reg, int64_t imm, Register pp) { |
| 476 if ((pp != kNoPP) && | 468 if ((pp != kNoPP) && allow_constant_pool()) { |
| 477 (Isolate::Current() != Dart::vm_isolate()) && | |
| 478 allow_constant_pool()) { | |
| 479 int64_t val_smi_tag = imm & kSmiTagMask; | |
| 480 imm &= ~kSmiTagMask; // Mask off the tag bits. | |
| 481 const int32_t offset = ObjectPool::element_offset(FindImmediate(imm)); | 469 const int32_t offset = ObjectPool::element_offset(FindImmediate(imm)); |
| 482 LoadWordFromPoolOffset(reg, pp, offset); | 470 LoadWordFromPoolOffset(reg, pp, offset); |
| 483 if (val_smi_tag != 0) { | |
| 484 // Add back the tag bits. | |
| 485 orri(reg, reg, Immediate(val_smi_tag)); | |
| 486 } | |
| 487 } else { | 471 } else { |
| 488 // TODO(zra): Since this sequence only needs to be decodable, it can be | 472 // TODO(zra): Since this sequence only needs to be decodable, it can be |
| 489 // of variable length. | 473 // of variable length. |
| 490 LoadImmediateFixed(reg, imm); | 474 LoadImmediateFixed(reg, imm); |
| 491 } | 475 } |
| 492 } | 476 } |
| 493 | 477 |
| 494 | 478 |
| 495 void Assembler::LoadImmediateFixed(Register reg, int64_t imm) { | 479 void Assembler::LoadImmediateFixed(Register reg, int64_t imm) { |
| 496 const uint32_t w0 = Utils::Low32Bits(imm); | 480 const uint32_t w0 = Utils::Low32Bits(imm); |
| (...skipping 951 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1448 add(base, array, Operand(index, LSL, shift)); | 1432 add(base, array, Operand(index, LSL, shift)); |
| 1449 } | 1433 } |
| 1450 const OperandSize size = Address::OperandSizeFor(cid); | 1434 const OperandSize size = Address::OperandSizeFor(cid); |
| 1451 ASSERT(Address::CanHoldOffset(offset, Address::Offset, size)); | 1435 ASSERT(Address::CanHoldOffset(offset, Address::Offset, size)); |
| 1452 return Address(base, offset, Address::Offset, size); | 1436 return Address(base, offset, Address::Offset, size); |
| 1453 } | 1437 } |
| 1454 | 1438 |
| 1455 } // namespace dart | 1439 } // namespace dart |
| 1456 | 1440 |
| 1457 #endif // defined TARGET_ARCH_ARM64 | 1441 #endif // defined TARGET_ARCH_ARM64 |
| OLD | NEW |