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 |