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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/assembler_arm64.h ('k') | runtime/vm/assembler_x64.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/assembler_arm64.cc
===================================================================
--- runtime/vm/assembler_arm64.cc (revision 35189)
+++ runtime/vm/assembler_arm64.cc (working copy)
@@ -257,6 +257,22 @@
}
+void Assembler::LoadPoolPointer(Register pp) {
+ const intptr_t object_pool_pc_dist =
+ Instructions::HeaderSize() - Instructions::object_pool_offset() +
+ CodeSize();
+ // PP <- Read(PC - object_pool_pc_dist).
+ ldr(pp, Address::PC(-object_pool_pc_dist));
+
+ // When in the PP register, the pool pointer is untagged. When we
+ // push it on the stack with PushPP it is tagged again. PopPP then untags
+ // when restoring from the stack. This will make loading from the object
+ // pool only one instruction for the first 4096 entries. Otherwise, because
+ // the offset wouldn't be aligned, it would always be at least two
+ // instructions.
+ sub(pp, pp, Operand(kHeapObjectTag));
+}
+
void Assembler::LoadWordFromPoolOffset(Register dst, Register pp,
uint32_t offset) {
ASSERT(dst != pp);
@@ -507,6 +523,129 @@
}
}
+
+void Assembler::AddImmediate(
+ Register dest, Register rn, int64_t imm, Register pp) {
+ ASSERT(rn != TMP2);
+ Operand op;
+ if (Operand::CanHold(imm, kXRegSizeInBits, &op) == Operand::Immediate) {
+ add(dest, rn, op);
+ } else if (Operand::CanHold(-imm, kXRegSizeInBits, &op) ==
+ Operand::Immediate) {
+ sub(dest, rn, op);
+ } else {
+ LoadImmediate(TMP2, imm, pp);
+ add(dest, rn, Operand(TMP2));
+ }
+}
+
+
+void Assembler::CompareImmediate(Register rn, int64_t imm, Register pp) {
+ ASSERT(rn != TMP2);
+ Operand op;
+ if (Operand::CanHold(imm, kXRegSizeInBits, &op) == Operand::Immediate) {
+ cmp(rn, op);
+ } else if (Operand::CanHold(-imm, kXRegSizeInBits, &op) ==
+ Operand::Immediate) {
+ cmn(rn, op);
+ } else {
+ LoadImmediate(TMP2, imm, pp);
+ cmp(rn, Operand(TMP2));
+ }
+}
+
+
+void Assembler::LoadFromOffset(Register dest, Register base, int32_t offset) {
+ ASSERT(base != TMP2);
+ if (Address::CanHoldOffset(offset)) {
+ ldr(dest, Address(base, offset));
+ } else if (Address::CanHoldOffset(offset, Address::PreIndex)) {
+ mov(TMP2, base);
+ ldr(dest, Address(TMP2, offset, Address::PreIndex));
+ } else {
+ // Since offset is 32-bits, it won't be loaded from the pool.
+ AddImmediate(TMP2, base, offset, kNoRegister);
+ ldr(dest, Address(TMP2));
+ }
+}
+
+
+void Assembler::StoreToOffset(Register src, Register base, int32_t offset) {
+ ASSERT(src != TMP2);
+ ASSERT(base != TMP2);
+ if (Address::CanHoldOffset(offset)) {
+ str(src, Address(base, offset));
+ } else if (Address::CanHoldOffset(offset, Address::PreIndex)) {
+ mov(TMP2, base);
+ str(src, Address(TMP2, offset, Address::PreIndex));
+ } else {
+ // Since offset is 32-bits, it won't be loaded from the pool.
+ AddImmediate(TMP2, base, offset, kNoRegister);
+ str(src, Address(TMP2));
+ }
+}
+
+
+void Assembler::ReserveAlignedFrameSpace(intptr_t frame_space) {
+ // Reserve space for arguments and align frame before entering
+ // the C++ world.
+ AddImmediate(SP, SP, -frame_space, kNoRegister);
+ if (OS::ActivationFrameAlignment() > 1) {
+ mov(TMP, SP); // SP can't be register operand of andi.
+ andi(TMP, TMP, ~(OS::ActivationFrameAlignment() - 1));
+ mov(SP, TMP);
+ }
+}
+
+
+void Assembler::EnterFrame(intptr_t frame_size) {
+ Push(LR);
+ Push(FP);
+ mov(FP, SP);
+
+ if (frame_size > 0) {
+ sub(SP, SP, Operand(frame_size));
+ }
+}
+
+
+void Assembler::LeaveFrame() {
+ mov(SP, FP);
+ Pop(FP);
+ Pop(LR);
+}
+
+
+void Assembler::EnterDartFrame(intptr_t frame_size) {
+ // Setup the frame.
+ adr(TMP, 0); // TMP gets PC of this instruction.
+ EnterFrame(0);
+ Push(TMP); // Save PC Marker.
+ PushPP(); // Save PP.
+
+ // Load the pool pointer.
+ LoadPoolPointer(PP);
+
+ // Reserve space.
+ if (frame_size > 0) {
+ sub(SP, SP, Operand(frame_size));
+ }
+}
+
+
+void Assembler::LeaveDartFrame() {
+ // Restore and untag PP.
+ LoadFromOffset(PP, FP, kSavedCallerPpSlotFromFp * kWordSize);
+ sub(PP, PP, Operand(kHeapObjectTag));
+ LeaveFrame();
+}
+
+
+void Assembler::CallRuntime(const RuntimeEntry& entry,
+ intptr_t argument_count) {
+ entry.Call(this, argument_count);
+}
+
} // namespace dart
#endif // defined TARGET_ARCH_ARM64
« no previous file with comments | « runtime/vm/assembler_arm64.h ('k') | runtime/vm/assembler_x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698