| 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
|
|
|