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

#ifndef V8_CRANKSHAFT_ARM64_LITHIUM_GAP_RESOLVER_ARM64_H_
#define V8_CRANKSHAFT_ARM64_LITHIUM_GAP_RESOLVER_ARM64_H_

#include "src/crankshaft/arm64/delayed-masm-arm64.h"
#include "src/crankshaft/lithium.h"

namespace v8 {
namespace internal {

class LCodeGen;
class LGapResolver;

class DelayedGapMasm : public DelayedMasm {
 public:
  DelayedGapMasm(LCodeGen* owner, MacroAssembler* masm)
    : DelayedMasm(owner, masm, root) {
    // We use the root register as an extra scratch register.
    // The root register has two advantages:
    //  - It is not in crankshaft allocatable registers list, so it can't
    //    interfere with the allocatable registers.
    //  - We don't need to push it on the stack, as we can reload it with its
    //    value once we have finish.
  }
  void EndDelayedUse();
};


class LGapResolver BASE_EMBEDDED {
 public:
  explicit LGapResolver(LCodeGen* owner);

  // Resolve a set of parallel moves, emitting assembler instructions.
  void Resolve(LParallelMove* parallel_move);

 private:
  // Build the initial list of moves.
  void BuildInitialMoveList(LParallelMove* parallel_move);

  // Perform the move at the moves_ index in question (possibly requiring
  // other moves to satisfy dependencies).
  void PerformMove(int index);

  // If a cycle is found in the series of moves, save the blocking value to
  // a scratch register.  The cycle must be found by hitting the root of the
  // depth-first search.
  void BreakCycle(int index);

  // After a cycle has been resolved, restore the value from the scratch
  // register to its proper destination.
  void RestoreValue();

  // Emit a move and remove it from the move graph.
  void EmitMove(int index);

  // Emit a move from one stack slot to another.
  void EmitStackSlotMove(int index) {
    masm_.StackSlotMove(moves_[index].source(), moves_[index].destination());
  }

  // Verify the move list before performing moves.
  void Verify();

  // Registers used to solve cycles.
  const Register& SavedValueRegister() {
    DCHECK(!RegisterConfiguration::Crankshaft()->IsAllocatableGeneralCode(
        masm_.ScratchRegister().code()));
    return masm_.ScratchRegister();
  }
  // The scratch register is used to break cycles and to store constant.
  // These two methods switch from one mode to the other.
  void AcquireSavedValueRegister() { masm_.AcquireScratchRegister(); }
  void ReleaseSavedValueRegister() { masm_.ReleaseScratchRegister(); }
  const FPRegister& SavedFPValueRegister() {
    // We use the Crankshaft 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.
    DCHECK(!RegisterConfiguration::Crankshaft()->IsAllocatableGeneralCode(
        crankshaft_fp_scratch.code()));
    return crankshaft_fp_scratch;
  }

  LCodeGen* cgen_;
  DelayedGapMasm masm_;

  // List of moves not yet resolved.
  ZoneList<LMoveOperands> moves_;

  int root_index_;
  bool in_cycle_;
  LOperand* saved_destination_;
};

}  // namespace internal
}  // namespace v8

#endif  // V8_CRANKSHAFT_ARM64_LITHIUM_GAP_RESOLVER_ARM64_H_
