// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//     * Neither the name of Google Inc. nor the names of its
//       contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "arm/lithium-gap-resolver-arm.h"
#include "arm/lithium-codegen-arm.h"

namespace v8 {
namespace internal {

static const Register kSavedValueRegister = { 9 };
static const DoubleRegister kSavedDoubleValueRegister = { 0 };

LGapResolver::LGapResolver(LCodeGen* owner)
    : cgen_(owner), moves_(32), root_index_(0), in_cycle_(false),
      saved_destination_(NULL) { }


void LGapResolver::Resolve(LParallelMove* parallel_move) {
  ASSERT(moves_.is_empty());
  // Build up a worklist of moves.
  BuildInitialMoveList(parallel_move);

  for (int i = 0; i < moves_.length(); ++i) {
    LMoveOperands move = moves_[i];
    // Skip constants to perform them last.  They don't block other moves
    // and skipping such moves with register destinations keeps those
    // registers free for the whole algorithm.
    if (!move.IsEliminated() && !move.source()->IsConstantOperand()) {
      root_index_ = i;  // Any cycle is found when by reaching this move again.
      PerformMove(i);
      if (in_cycle_) {
        RestoreValue();
      }
    }
  }

  // Perform the moves with constant sources.
  for (int i = 0; i < moves_.length(); ++i) {
    if (!moves_[i].IsEliminated()) {
      ASSERT(moves_[i].source()->IsConstantOperand());
      EmitMove(i);
    }
  }

  moves_.Rewind(0);
}


void LGapResolver::BuildInitialMoveList(LParallelMove* parallel_move) {
  // Perform a linear sweep of the moves to add them to the initial list of
  // moves to perform, ignoring any move that is redundant (the source is
  // the same as the destination, the destination is ignored and
  // unallocated, or the move was already eliminated).
  const ZoneList<LMoveOperands>* moves = parallel_move->move_operands();
  for (int i = 0; i < moves->length(); ++i) {
    LMoveOperands move = moves->at(i);
    if (!move.IsRedundant()) moves_.Add(move);
  }
  Verify();
}


void LGapResolver::PerformMove(int index) {
  // Each call to this function performs a move and deletes it from the move
  // graph.  We first recursively perform any move blocking this one.  We
  // mark a move as "pending" on entry to PerformMove in order to detect
  // cycles in the move graph.

  // We can only find a cycle, when doing a depth-first traversal of moves,
  // be encountering the starting move again. So by spilling the source of
  // the starting move, we break the cycle.  All moves are then unblocked,
  // and the starting move is completed by writing the spilled value to
  // its destination.  All other moves from the spilled source have been
  // completed prior to breaking the cycle.
  // An additional complication is that moves to MemOperands with large
  // offsets (more than 1K or 4K) require us to spill this spilled value to
  // the stack, to free up the register.
  ASSERT(!moves_[index].IsPending());
  ASSERT(!moves_[index].IsRedundant());

  // Clear this move's destination to indicate a pending move.  The actual
  // destination is saved in a stack allocated local.  Multiple moves can
  // be pending because this function is recursive.
  ASSERT(moves_[index].source() != NULL);  // Or else it will look eliminated.
  LOperand* destination = moves_[index].destination();
  moves_[index].set_destination(NULL);

  // Perform a depth-first traversal of the move graph to resolve
  // dependencies.  Any unperformed, unpending move with a source the same
  // as this one's destination blocks this one so recursively perform all
  // such moves.
  for (int i = 0; i < moves_.length(); ++i) {
    LMoveOperands other_move = moves_[i];
    if (other_move.Blocks(destination) && !other_move.IsPending()) {
      PerformMove(i);
      // If there is a blocking, pending move it must be moves_[root_index_]
      // and all other moves with the same source as moves_[root_index_] are
      // sucessfully executed (because they are cycle-free) by this loop.
    }
  }

  // We are about to resolve this move and don't need it marked as
  // pending, so restore its destination.
  moves_[index].set_destination(destination);

  // The move may be blocked on a pending move, which must be the starting move.
  // In this case, we have a cycle, and we save the source of this move to
  // a scratch register to break it.
  LMoveOperands other_move = moves_[root_index_];
  if (other_move.Blocks(destination)) {
    ASSERT(other_move.IsPending());
    BreakCycle(index);
    return;
  }

  // This move is no longer blocked.
  EmitMove(index);
}


void LGapResolver::Verify() {
#ifdef ENABLE_SLOW_ASSERTS
  // No operand should be the destination for more than one move.
  for (int i = 0; i < moves_.length(); ++i) {
    LOperand* destination = moves_[i].destination();
    for (int j = i + 1; j < moves_.length(); ++j) {
      SLOW_ASSERT(!destination->Equals(moves_[j].destination()));
    }
  }
#endif
}

#define __ ACCESS_MASM(cgen_->masm())

void LGapResolver::BreakCycle(int index) {
  // We save in a register the value that should end up in the source of
  // moves_[root_index].  After performing all moves in the tree rooted
  // in that move, we save the value to that source.
  ASSERT(moves_[index].destination()->Equals(moves_[root_index_].source()));
  ASSERT(!in_cycle_);
  in_cycle_ = true;
  LOperand* source = moves_[index].source();
  saved_destination_ = moves_[index].destination();
  if (source->IsRegister()) {
    __ mov(kSavedValueRegister, cgen_->ToRegister(source));
  } else if (source->IsStackSlot()) {
    __ ldr(kSavedValueRegister, cgen_->ToMemOperand(source));
  } else if (source->IsDoubleRegister()) {
    __ vmov(kSavedDoubleValueRegister, cgen_->ToDoubleRegister(source));
  } else if (source->IsDoubleStackSlot()) {
    __ vldr(kSavedDoubleValueRegister, cgen_->ToMemOperand(source));
  } else {
    UNREACHABLE();
  }
  // This move will be done by restoring the saved value to the destination.
  moves_[index].Eliminate();
}


void LGapResolver::RestoreValue() {
  ASSERT(in_cycle_);
  ASSERT(saved_destination_ != NULL);

  // Spilled value is in kSavedValueRegister or kSavedDoubleValueRegister.
  if (saved_destination_->IsRegister()) {
    __ mov(cgen_->ToRegister(saved_destination_), kSavedValueRegister);
  } else if (saved_destination_->IsStackSlot()) {
    __ str(kSavedValueRegister, cgen_->ToMemOperand(saved_destination_));
  } else if (saved_destination_->IsDoubleRegister()) {
    __ vmov(cgen_->ToDoubleRegister(saved_destination_),
            kSavedDoubleValueRegister);
  } else if (saved_destination_->IsDoubleStackSlot()) {
    __ vstr(kSavedDoubleValueRegister,
            cgen_->ToMemOperand(saved_destination_));
  } else {
    UNREACHABLE();
  }

  in_cycle_ = false;
  saved_destination_ = NULL;
}


void LGapResolver::EmitMove(int index) {
  LOperand* source = moves_[index].source();
  LOperand* destination = moves_[index].destination();

  // Dispatch on the source and destination operand kinds.  Not all
  // combinations are possible.

  if (source->IsRegister()) {
    Register source_register = cgen_->ToRegister(source);
    if (destination->IsRegister()) {
      __ mov(cgen_->ToRegister(destination), source_register);
    } else {
      ASSERT(destination->IsStackSlot());
      __ str(source_register, cgen_->ToMemOperand(destination));
    }

  } else if (source->IsStackSlot()) {
    MemOperand source_operand = cgen_->ToMemOperand(source);
    if (destination->IsRegister()) {
      __ ldr(cgen_->ToRegister(destination), source_operand);
    } else {
      ASSERT(destination->IsStackSlot());
      MemOperand destination_operand = cgen_->ToMemOperand(destination);
      if (in_cycle_) {
        if (!destination_operand.OffsetIsUint12Encodable()) {
          // ip is overwritten while saving the value to the destination.
          // Therefore we can't use ip.  It is OK if the read from the source
          // destroys ip, since that happens before the value is read.
          __ vldr(kSavedDoubleValueRegister.low(), source_operand);
          __ vstr(kSavedDoubleValueRegister.low(), destination_operand);
        } else {
          __ ldr(ip, source_operand);
          __ str(ip, destination_operand);
        }
      } else {
        __ ldr(kSavedValueRegister, source_operand);
        __ str(kSavedValueRegister, destination_operand);
      }
    }

  } else if (source->IsConstantOperand()) {
    Operand source_operand = cgen_->ToOperand(source);
    if (destination->IsRegister()) {
      __ mov(cgen_->ToRegister(destination), source_operand);
    } else {
      ASSERT(destination->IsStackSlot());
      ASSERT(!in_cycle_);  // Constant moves happen after all cycles are gone.
      MemOperand destination_operand = cgen_->ToMemOperand(destination);
      __ mov(kSavedValueRegister, source_operand);
      __ str(kSavedValueRegister, cgen_->ToMemOperand(destination));
    }

  } else if (source->IsDoubleRegister()) {
    DoubleRegister source_register = cgen_->ToDoubleRegister(source);
    if (destination->IsDoubleRegister()) {
      __ vmov(cgen_->ToDoubleRegister(destination), source_register);
    } else {
      ASSERT(destination->IsDoubleStackSlot());
      MemOperand destination_operand = cgen_->ToMemOperand(destination);
      __ vstr(source_register, destination_operand);
    }

  } else if (source->IsDoubleStackSlot()) {
    MemOperand source_operand = cgen_->ToMemOperand(source);
    if (destination->IsDoubleRegister()) {
      __ vldr(cgen_->ToDoubleRegister(destination), source_operand);
    } else {
      ASSERT(destination->IsDoubleStackSlot());
      MemOperand destination_operand = cgen_->ToMemOperand(destination);
      if (in_cycle_) {
        // kSavedDoubleValueRegister was used to break the cycle,
        // but kSavedValueRegister is free.
        MemOperand source_high_operand =
            cgen_->ToHighMemOperand(source);
        MemOperand destination_high_operand =
            cgen_->ToHighMemOperand(destination);
        __ ldr(kSavedValueRegister, source_operand);
        __ str(kSavedValueRegister, destination_operand);
        __ ldr(kSavedValueRegister, source_high_operand);
        __ str(kSavedValueRegister, destination_high_operand);
      } else {
        __ vldr(kSavedDoubleValueRegister, source_operand);
        __ vstr(kSavedDoubleValueRegister, destination_operand);
      }
    }
  } else {
    UNREACHABLE();
  }

  moves_[index].Eliminate();
}


#undef __

} }  // namespace v8::internal
