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

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

Issue 243773002: Adds Runtime call stub and Dart entry stub to ARM64. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 8 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
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 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 imm_s_fixed >>= 1; 250 imm_s_fixed >>= 1;
251 continue; 251 continue;
252 } 252 }
253 253
254 // 6. Otherwise, the value can't be encoded. 254 // 6. Otherwise, the value can't be encoded.
255 return false; 255 return false;
256 } 256 }
257 } 257 }
258 258
259 259
260 void Assembler::LoadPoolPointer(Register pp) {
261 const intptr_t object_pool_pc_dist =
262 Instructions::HeaderSize() - Instructions::object_pool_offset() +
263 CodeSize();
264 // PP <- Read(PC - object_pool_pc_dist).
265 ldr(pp, Address::PC(-object_pool_pc_dist));
266
267 // When in the PP register, the pool pointer is untagged. When we
268 // push it on the stack with PushPP it is tagged again. PopPP then untags
269 // when restoring from the stack. This will make loading from the object
270 // pool only one instruction for the first 4096 entries. Otherwise, because
271 // the offset wouldn't be aligned, it would always be at least two
272 // instructions.
273 sub(pp, pp, Operand(kHeapObjectTag));
274 }
275
260 void Assembler::LoadWordFromPoolOffset(Register dst, Register pp, 276 void Assembler::LoadWordFromPoolOffset(Register dst, Register pp,
261 uint32_t offset) { 277 uint32_t offset) {
262 ASSERT(dst != pp); 278 ASSERT(dst != pp);
263 if (Address::CanHoldOffset(offset)) { 279 if (Address::CanHoldOffset(offset)) {
264 ldr(dst, Address(pp, offset)); 280 ldr(dst, Address(pp, offset));
265 } else { 281 } else {
266 const uint16_t offset_low = Utils::Low16Bits(offset); 282 const uint16_t offset_low = Utils::Low16Bits(offset);
267 const uint16_t offset_high = Utils::High16Bits(offset); 283 const uint16_t offset_high = Utils::High16Bits(offset);
268 movz(dst, offset_low, 0); 284 movz(dst, offset_low, 0);
269 if (offset_high != 0) { 285 if (offset_high != 0) {
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
500 if (h3 != 0) { 516 if (h3 != 0) {
501 if (initialized) { 517 if (initialized) {
502 movk(reg, h3, 3); 518 movk(reg, h3, 3);
503 } else { 519 } else {
504 movz(reg, h3, 3); 520 movz(reg, h3, 3);
505 } 521 }
506 } 522 }
507 } 523 }
508 } 524 }
509 525
526
527 void Assembler::AddImmediate(
528 Register dest, Register rn, int64_t imm, Register pp) {
529 ASSERT(rn != TMP2);
530 Operand op;
531 if (Operand::CanHold(imm, kXRegSizeInBits, &op) == Operand::Immediate) {
532 add(dest, rn, op);
533 } else if (Operand::CanHold(-imm, kXRegSizeInBits, &op) ==
534 Operand::Immediate) {
535 sub(dest, rn, op);
536 } else {
537 LoadImmediate(TMP2, imm, pp);
538 add(dest, rn, Operand(TMP2));
539 }
540 }
541
542
543 void Assembler::CompareImmediate(Register rn, int64_t imm, Register pp) {
544 ASSERT(rn != TMP2);
545 Operand op;
546 if (Operand::CanHold(imm, kXRegSizeInBits, &op) == Operand::Immediate) {
547 cmp(rn, op);
548 } else if (Operand::CanHold(-imm, kXRegSizeInBits, &op) ==
549 Operand::Immediate) {
550 cmn(rn, op);
551 } else {
552 LoadImmediate(TMP2, imm, pp);
553 cmp(rn, Operand(TMP2));
554 }
555 }
556
557
558 void Assembler::LoadFromOffset(Register dest, Register base, int32_t offset) {
559 ASSERT(base != TMP2);
560 if (Address::CanHoldOffset(offset)) {
561 ldr(dest, Address(base, offset));
562 } else if (Address::CanHoldOffset(offset, Address::PreIndex)) {
563 mov(TMP2, base);
564 ldr(dest, Address(TMP2, offset, Address::PreIndex));
565 } else {
566 // Since offset is 32-bits, it won't be loaded from the pool.
567 AddImmediate(TMP2, base, offset, kNoRegister);
568 ldr(dest, Address(TMP2));
569 }
570 }
571
572
573 void Assembler::StoreToOffset(Register src, Register base, int32_t offset) {
574 ASSERT(src != TMP2);
575 ASSERT(base != TMP2);
576 if (Address::CanHoldOffset(offset)) {
577 str(src, Address(base, offset));
578 } else if (Address::CanHoldOffset(offset, Address::PreIndex)) {
579 mov(TMP2, base);
580 str(src, Address(TMP2, offset, Address::PreIndex));
581 } else {
582 // Since offset is 32-bits, it won't be loaded from the pool.
583 AddImmediate(TMP2, base, offset, kNoRegister);
584 str(src, Address(TMP2));
585 }
586 }
587
588
589 void Assembler::ReserveAlignedFrameSpace(intptr_t frame_space) {
590 // Reserve space for arguments and align frame before entering
591 // the C++ world.
592 AddImmediate(SP, SP, -frame_space, kNoRegister);
593 if (OS::ActivationFrameAlignment() > 1) {
594 mov(TMP, SP); // SP can't be register operand of andi.
595 andi(SP, TMP, ~(OS::ActivationFrameAlignment() - 1));
596 }
597 }
598
599
600 void Assembler::EnterDartFrame(intptr_t frame_size) {
601 adr(TMP, 0); // TMP gets PC of this instruction.
602 Push(TMP); // Save PC Marker.
603 Push(LR); // Save return address.
604 Push(FP); // Save FP.
605 PushPP(); // Save PP.
606
607 // Set FP to saved previous FP.
608 add(FP, SP, Operand(1 * kWordSize));
609
610 // Load the pool pointer.
611 LoadPoolPointer(PP);
612
613 // Reserve space.
614 sub(SP, SP, Operand(frame_size));
615 }
616
617
618 void Assembler::LeaveDartFrame() {
619 sub(SP, FP, Operand(1 * kWordSize));
620 PopPP(); // Restore pool pointer.
621 Pop(FP); // Restore frame pointer.
622 Pop(LR); // Restore return address.
623 Pop(TMP); // Pop PC marker, and restore SP.
624 }
625
626
627 void Assembler::CallRuntime(const RuntimeEntry& entry,
628 intptr_t argument_count) {
629 entry.Call(this, argument_count);
630 }
631
510 } // namespace dart 632 } // namespace dart
511 633
512 #endif // defined TARGET_ARCH_ARM64 634 #endif // defined TARGET_ARCH_ARM64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698