| Index: src/arm64/lithium-gap-resolver-arm64.cc
|
| diff --git a/src/arm64/lithium-gap-resolver-arm64.cc b/src/arm64/lithium-gap-resolver-arm64.cc
|
| index de6717a7707b599749ba9eed23b2acd7c635a751..f0a2e6bd0e3da8f028b27b3a7de6852b2d3d9f32 100644
|
| --- a/src/arm64/lithium-gap-resolver-arm64.cc
|
| +++ b/src/arm64/lithium-gap-resolver-arm64.cc
|
| @@ -42,6 +42,12 @@ namespace internal {
|
| // once we have resolved a cycle.
|
| #define kSavedValue root
|
|
|
| +// We use the MacroAssembler floating-point scratch register to break a cycle
|
| +// involving double values as the MacroAssembler will not need it for the
|
| +// operations performed by the gap resolver.
|
| +#define kSavedDoubleValue fp_scratch
|
| +
|
| +
|
| LGapResolver::LGapResolver(LCodeGen* owner)
|
| : cgen_(owner), moves_(32, owner->zone()), root_index_(0), in_cycle_(false),
|
| saved_destination_(NULL), need_to_restore_root_(false) { }
|
| @@ -169,10 +175,10 @@ void LGapResolver::BreakCycle(int index) {
|
| ASSERT(moves_[index].destination()->Equals(moves_[root_index_].source()));
|
| ASSERT(!in_cycle_);
|
|
|
| - // We use a register which is not allocatable by crankshaft to break the cycle
|
| - // to be sure it doesn't interfere with the moves we are resolving.
|
| + // We use registers which are not allocatable by crankshaft to break the cycle
|
| + // to be sure they don't interfere with the moves we are resolving.
|
| ASSERT(!kSavedValue.IsAllocatable());
|
| - need_to_restore_root_ = true;
|
| + ASSERT(!kSavedDoubleValue.IsAllocatable());
|
|
|
| // We save in a register the source of that move and we remember its
|
| // destination. Then we mark this move as resolved so the cycle is
|
| @@ -182,19 +188,19 @@ void LGapResolver::BreakCycle(int index) {
|
| saved_destination_ = moves_[index].destination();
|
|
|
| if (source->IsRegister()) {
|
| + need_to_restore_root_ = true;
|
| __ Mov(kSavedValue, cgen_->ToRegister(source));
|
| } else if (source->IsStackSlot()) {
|
| + need_to_restore_root_ = true;
|
| __ Ldr(kSavedValue, cgen_->ToMemOperand(source));
|
| } else if (source->IsDoubleRegister()) {
|
| - // TODO(all): We should use a double register to store the value to avoid
|
| - // the penalty of the mov across register banks. We are going to reserve
|
| - // d31 to hold 0.0 value. We could clobber this register while breaking the
|
| - // cycle and restore it after like we do with the root register.
|
| - // LGapResolver::RestoreValue() will need to be updated as well when we'll
|
| - // do that.
|
| - __ Fmov(kSavedValue, cgen_->ToDoubleRegister(source));
|
| + ASSERT(cgen_->masm()->FPTmpList()->IncludesAliasOf(kSavedDoubleValue));
|
| + cgen_->masm()->FPTmpList()->Remove(kSavedDoubleValue);
|
| + __ Fmov(kSavedDoubleValue, cgen_->ToDoubleRegister(source));
|
| } else if (source->IsDoubleStackSlot()) {
|
| - __ Ldr(kSavedValue, cgen_->ToMemOperand(source));
|
| + ASSERT(cgen_->masm()->FPTmpList()->IncludesAliasOf(kSavedDoubleValue));
|
| + cgen_->masm()->FPTmpList()->Remove(kSavedDoubleValue);
|
| + __ Ldr(kSavedDoubleValue, cgen_->ToMemOperand(source));
|
| } else {
|
| UNREACHABLE();
|
| }
|
| @@ -215,9 +221,11 @@ void LGapResolver::RestoreValue() {
|
| } else if (saved_destination_->IsStackSlot()) {
|
| __ Str(kSavedValue, cgen_->ToMemOperand(saved_destination_));
|
| } else if (saved_destination_->IsDoubleRegister()) {
|
| - __ Fmov(cgen_->ToDoubleRegister(saved_destination_), kSavedValue);
|
| + __ Fmov(cgen_->ToDoubleRegister(saved_destination_), kSavedDoubleValue);
|
| + cgen_->masm()->FPTmpList()->Combine(kSavedDoubleValue);
|
| } else if (saved_destination_->IsDoubleStackSlot()) {
|
| - __ Str(kSavedValue, cgen_->ToMemOperand(saved_destination_));
|
| + __ Str(kSavedDoubleValue, cgen_->ToMemOperand(saved_destination_));
|
| + cgen_->masm()->FPTmpList()->Combine(kSavedDoubleValue);
|
| } else {
|
| UNREACHABLE();
|
| }
|
|
|