Index: src/arm64/delayed-masm-arm64.cc |
diff --git a/src/arm64/delayed-masm-arm64.cc b/src/arm64/delayed-masm-arm64.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..b7040e1aea7495ceeb00064afbb45cfb27ba3e5f |
--- /dev/null |
+++ b/src/arm64/delayed-masm-arm64.cc |
@@ -0,0 +1,198 @@ |
+// Copyright 2013 the V8 project authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "src/v8.h" |
+ |
+#if V8_TARGET_ARCH_ARM64 |
+ |
+#include "src/arm64/delayed-masm-arm64.h" |
+#include "src/arm64/lithium-codegen-arm64.h" |
+ |
+namespace v8 { |
+namespace internal { |
+ |
+#define __ ACCESS_MASM(masm_) |
+ |
+ |
+void DelayedMasm::StackSlotMove(LOperand* src, LOperand* dst) { |
+ ASSERT(src->IsStackSlot()); |
+ ASSERT(dst->IsStackSlot()); |
+ MemOperand src_operand = cgen_->ToMemOperand(src); |
+ MemOperand dst_operand = cgen_->ToMemOperand(dst); |
+ if (pending_ == kStackSlotMove) { |
+ ASSERT(pending_pc_ == masm_->pc_offset()); |
+ UseScratchRegisterScope scope(masm_); |
+ DoubleRegister temp1 = scope.AcquireD(); |
+ DoubleRegister temp2 = scope.AcquireD(); |
+ switch (MemOperand::AreConsistentForPair(pending_address_src_, |
+ src_operand)) { |
+ case MemOperand::kNotPair: |
+ __ Ldr(temp1, pending_address_src_); |
+ __ Ldr(temp2, src_operand); |
+ break; |
+ case MemOperand::kPairAB: |
+ __ Ldp(temp1, temp2, pending_address_src_); |
+ break; |
+ case MemOperand::kPairBA: |
+ __ Ldp(temp2, temp1, src_operand); |
+ break; |
+ } |
+ switch (MemOperand::AreConsistentForPair(pending_address_dst_, |
+ dst_operand)) { |
+ case MemOperand::kNotPair: |
+ __ Str(temp1, pending_address_dst_); |
+ __ Str(temp2, dst_operand); |
+ break; |
+ case MemOperand::kPairAB: |
+ __ Stp(temp1, temp2, pending_address_dst_); |
+ break; |
+ case MemOperand::kPairBA: |
+ __ Stp(temp2, temp1, dst_operand); |
+ break; |
+ } |
+ ResetPending(); |
+ return; |
+ } |
+ |
+ EmitPending(); |
+ pending_ = kStackSlotMove; |
+ pending_address_src_ = src_operand; |
+ pending_address_dst_ = dst_operand; |
+#ifdef DEBUG |
+ pending_pc_ = masm_->pc_offset(); |
+#endif |
+} |
+ |
+ |
+void DelayedMasm::StoreConstant(uint64_t value, const MemOperand& operand) { |
+ ASSERT(!scratch_register_acquired_); |
+ if ((pending_ == kStoreConstant) && (value == pending_value_)) { |
+ MemOperand::PairResult result = |
+ MemOperand::AreConsistentForPair(pending_address_dst_, operand); |
+ if (result != MemOperand::kNotPair) { |
+ const MemOperand& dst = |
+ (result == MemOperand::kPairAB) ? |
+ pending_address_dst_ : |
+ operand; |
+ ASSERT(pending_pc_ == masm_->pc_offset()); |
+ if (pending_value_ == 0) { |
+ __ Stp(xzr, xzr, dst); |
+ } else { |
+ SetSavedValue(pending_value_); |
+ __ Stp(ScratchRegister(), ScratchRegister(), dst); |
+ } |
+ ResetPending(); |
+ return; |
+ } |
+ } |
+ |
+ EmitPending(); |
+ pending_ = kStoreConstant; |
+ pending_address_dst_ = operand; |
+ pending_value_ = value; |
+#ifdef DEBUG |
+ pending_pc_ = masm_->pc_offset(); |
+#endif |
+} |
+ |
+ |
+void DelayedMasm::Load(const CPURegister& rd, const MemOperand& operand) { |
+ if ((pending_ == kLoad) && |
+ pending_register_.IsSameSizeAndType(rd)) { |
+ switch (MemOperand::AreConsistentForPair(pending_address_src_, operand)) { |
+ case MemOperand::kNotPair: |
+ break; |
+ case MemOperand::kPairAB: |
+ ASSERT(pending_pc_ == masm_->pc_offset()); |
+ ASSERT(!IsScratchRegister(pending_register_) || |
+ scratch_register_acquired_); |
+ ASSERT(!IsScratchRegister(rd) || scratch_register_acquired_); |
+ __ Ldp(pending_register_, rd, pending_address_src_); |
+ ResetPending(); |
+ return; |
+ case MemOperand::kPairBA: |
+ ASSERT(pending_pc_ == masm_->pc_offset()); |
+ ASSERT(!IsScratchRegister(pending_register_) || |
+ scratch_register_acquired_); |
+ ASSERT(!IsScratchRegister(rd) || scratch_register_acquired_); |
+ __ Ldp(rd, pending_register_, operand); |
+ ResetPending(); |
+ return; |
+ } |
+ } |
+ |
+ EmitPending(); |
+ pending_ = kLoad; |
+ pending_register_ = rd; |
+ pending_address_src_ = operand; |
+#ifdef DEBUG |
+ pending_pc_ = masm_->pc_offset(); |
+#endif |
+} |
+ |
+ |
+void DelayedMasm::Store(const CPURegister& rd, const MemOperand& operand) { |
+ if ((pending_ == kStore) && |
+ pending_register_.IsSameSizeAndType(rd)) { |
+ switch (MemOperand::AreConsistentForPair(pending_address_dst_, operand)) { |
+ case MemOperand::kNotPair: |
+ break; |
+ case MemOperand::kPairAB: |
+ ASSERT(pending_pc_ == masm_->pc_offset()); |
+ __ Stp(pending_register_, rd, pending_address_dst_); |
+ ResetPending(); |
+ return; |
+ case MemOperand::kPairBA: |
+ ASSERT(pending_pc_ == masm_->pc_offset()); |
+ __ Stp(rd, pending_register_, operand); |
+ ResetPending(); |
+ return; |
+ } |
+ } |
+ |
+ EmitPending(); |
+ pending_ = kStore; |
+ pending_register_ = rd; |
+ pending_address_dst_ = operand; |
+#ifdef DEBUG |
+ pending_pc_ = masm_->pc_offset(); |
+#endif |
+} |
+ |
+ |
+void DelayedMasm::EmitPending() { |
+ ASSERT((pending_ == kNone) || (pending_pc_ == masm_->pc_offset())); |
+ switch (pending_) { |
+ case kNone: |
+ return; |
+ case kStoreConstant: |
+ if (pending_value_ == 0) { |
+ __ Str(xzr, pending_address_dst_); |
+ } else { |
+ SetSavedValue(pending_value_); |
+ __ Str(ScratchRegister(), pending_address_dst_); |
+ } |
+ break; |
+ case kLoad: |
+ ASSERT(!IsScratchRegister(pending_register_) || |
+ scratch_register_acquired_); |
+ __ Ldr(pending_register_, pending_address_src_); |
+ break; |
+ case kStore: |
+ __ Str(pending_register_, pending_address_dst_); |
+ break; |
+ case kStackSlotMove: { |
+ UseScratchRegisterScope scope(masm_); |
+ DoubleRegister temp = scope.AcquireD(); |
+ __ Ldr(temp, pending_address_src_); |
+ __ Str(temp, pending_address_dst_); |
+ break; |
+ } |
+ } |
+ ResetPending(); |
+} |
+ |
+} } // namespace v8::internal |
+ |
+#endif // V8_TARGET_ARCH_ARM64 |