/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "base/arena_allocator.h"
#include "base/macros.h"
#include "base/malloc_arena_pool.h"
#include "nodes.h"
#include "parallel_move_resolver.h"

#include "gtest/gtest-typed-test.h"
#include "gtest/gtest.h"

namespace art HIDDEN {

constexpr int kScratchRegisterStartIndexForTest = 100;

static void DumpRegisterForTest(std::ostream& os, int reg) {
  if (reg >= kScratchRegisterStartIndexForTest) {
    os << "T" << reg - kScratchRegisterStartIndexForTest;
  } else {
    os << reg;
  }
}

static void DumpLocationForTest(std::ostream& os, Location location) {
  if (location.IsConstant()) {
    os << "C";
  } else if (location.IsPair()) {
    DumpRegisterForTest(os, location.low());
    os << ",";
    DumpRegisterForTest(os, location.high());
  } else if (location.IsRegister()) {
    DumpRegisterForTest(os, location.reg());
  } else if (location.IsStackSlot()) {
    os << location.GetStackIndex() << "(sp)";
  } else {
    DCHECK(location.IsDoubleStackSlot())<< location;
    os << "2x" << location.GetStackIndex() << "(sp)";
  }
}

class TestParallelMoveResolverWithSwap : public ParallelMoveResolverWithSwap {
 public:
  explicit TestParallelMoveResolverWithSwap(ArenaAllocator* allocator)
      : ParallelMoveResolverWithSwap(allocator) {}

  void EmitMove(size_t index) override {
    MoveOperands* move = moves_[index];
    if (!message_.str().empty()) {
      message_ << " ";
    }
    message_ << "(";
    DumpLocationForTest(message_, move->GetSource());
    message_ << " -> ";
    DumpLocationForTest(message_, move->GetDestination());
    message_ << ")";
  }

  void EmitSwap(size_t index) override {
    MoveOperands* move = moves_[index];
    if (!message_.str().empty()) {
      message_ << " ";
    }
    message_ << "(";
    DumpLocationForTest(message_, move->GetSource());
    message_ << " <-> ";
    DumpLocationForTest(message_, move->GetDestination());
    message_ << ")";
  }

  void SpillScratch([[maybe_unused]] int reg) override {}
  void RestoreScratch([[maybe_unused]] int reg) override {}

  std::string GetMessage() const {
    return  message_.str();
  }

 private:
  std::ostringstream message_;


  DISALLOW_COPY_AND_ASSIGN(TestParallelMoveResolverWithSwap);
};

class TestParallelMoveResolverNoSwap : public ParallelMoveResolverNoSwap {
 public:
  explicit TestParallelMoveResolverNoSwap(ArenaAllocator* allocator)
      : ParallelMoveResolverNoSwap(allocator), scratch_index_(kScratchRegisterStartIndexForTest) {}

  void PrepareForEmitNativeCode() override {
    scratch_index_ = kScratchRegisterStartIndexForTest;
  }

  void FinishEmitNativeCode() override {}

  Location AllocateScratchLocationFor(Location::Kind kind) override {
    if (kind == Location::kStackSlot || kind == Location::kFpuRegister ||
        kind == Location::kRegister) {
      kind = Location::kRegister;
    } else {
      // Allocate register pair for double stack slot which simulates 32-bit backend's behavior.
      kind = Location::kRegisterPair;
    }
    Location scratch = GetScratchLocation(kind);
    if (scratch.Equals(Location::NoLocation())) {
      AddScratchLocation(Location::RegisterLocation(scratch_index_));
      AddScratchLocation(Location::RegisterLocation(scratch_index_ + 1));
      AddScratchLocation(Location::RegisterPairLocation(scratch_index_, scratch_index_ + 1));
      scratch = (kind == Location::kRegister) ? Location::RegisterLocation(scratch_index_)
          : Location::RegisterPairLocation(scratch_index_, scratch_index_ + 1);
      scratch_index_ += 2;
    }
    return scratch;
  }

  void FreeScratchLocation([[maybe_unused]] Location loc) override {}

  void EmitMove(size_t index) override {
    MoveOperands* move = moves_[index];
    if (!message_.str().empty()) {
      message_ << " ";
    }
    message_ << "(";
    DumpLocationForTest(message_, move->GetSource());
    message_ << " -> ";
    DumpLocationForTest(message_, move->GetDestination());
    message_ << ")";
  }

  std::string GetMessage() const {
    return  message_.str();
  }

 private:
  std::ostringstream message_;

  int scratch_index_;

  DISALLOW_COPY_AND_ASSIGN(TestParallelMoveResolverNoSwap);
};

static HParallelMove* BuildParallelMove(ArenaAllocator* allocator,
                                        const size_t operands[][2],
                                        size_t number_of_moves) {
  HParallelMove* moves = new (allocator) HParallelMove(allocator);
  for (size_t i = 0; i < number_of_moves; ++i) {
    moves->AddMove(
        Location::RegisterLocation(operands[i][0]),
        Location::RegisterLocation(operands[i][1]),
        DataType::Type::kInt32,
        nullptr);
  }
  return moves;
}

template <typename T>
class ParallelMoveTest : public ::testing::Test {
 public:
  static const bool has_swap;
};

template<> const bool ParallelMoveTest<TestParallelMoveResolverWithSwap>::has_swap = true;
template<> const bool ParallelMoveTest<TestParallelMoveResolverNoSwap>::has_swap = false;

using ParallelMoveResolverTestTypes =
    ::testing::Types<TestParallelMoveResolverWithSwap, TestParallelMoveResolverNoSwap>;

TYPED_TEST_CASE(ParallelMoveTest, ParallelMoveResolverTestTypes);


TYPED_TEST(ParallelMoveTest, Dependency) {
  MallocArenaPool pool;
  ArenaAllocator allocator(&pool);

  {
    TypeParam resolver(&allocator);
    static constexpr size_t moves[][2] = {{0, 1}, {1, 2}};
    resolver.EmitNativeCode(BuildParallelMove(&allocator, moves, arraysize(moves)));
    if (TestFixture::has_swap) {
      ASSERT_STREQ("(1 -> 2) (0 -> 1)", resolver.GetMessage().c_str());
    } else {
      ASSERT_STREQ("(1 -> 2) (0 -> 1)", resolver.GetMessage().c_str());
    }
  }

  {
    TypeParam resolver(&allocator);
    static constexpr size_t moves[][2] = {{0, 1}, {1, 2}, {2, 3}, {1, 4}};
    resolver.EmitNativeCode(BuildParallelMove(&allocator, moves, arraysize(moves)));
    if (TestFixture::has_swap) {
      ASSERT_STREQ("(2 -> 3) (1 -> 2) (1 -> 4) (0 -> 1)", resolver.GetMessage().c_str());
    } else {
      ASSERT_STREQ("(2 -> 3) (1 -> 2) (0 -> 1) (2 -> 4)", resolver.GetMessage().c_str());
    }
  }
}

TYPED_TEST(ParallelMoveTest, Cycle) {
  MallocArenaPool pool;
  ArenaAllocator allocator(&pool);

  {
    TypeParam resolver(&allocator);
    static constexpr size_t moves[][2] = {{0, 1}, {1, 0}};
    resolver.EmitNativeCode(BuildParallelMove(&allocator, moves, arraysize(moves)));
    if (TestFixture::has_swap) {
      ASSERT_STREQ("(1 <-> 0)", resolver.GetMessage().c_str());
    } else {
      ASSERT_STREQ("(1 -> T0) (0 -> 1) (T0 -> 0)", resolver.GetMessage().c_str());
    }
  }

  {
    TypeParam resolver(&allocator);
    static constexpr size_t moves[][2] = {{0, 1}, {1, 2}, {1, 0}};
    resolver.EmitNativeCode(BuildParallelMove(&allocator, moves, arraysize(moves)));
    if (TestFixture::has_swap) {
      ASSERT_STREQ("(1 -> 2) (1 <-> 0)", resolver.GetMessage().c_str());
    } else {
      ASSERT_STREQ("(1 -> 2) (0 -> 1) (2 -> 0)", resolver.GetMessage().c_str());
    }
  }

  {
    TypeParam resolver(&allocator);
    static constexpr size_t moves[][2] = {{0, 1}, {1, 0}, {0, 2}};
    resolver.EmitNativeCode(BuildParallelMove(&allocator, moves, arraysize(moves)));
    if (TestFixture::has_swap) {
      ASSERT_STREQ("(0 -> 2) (1 <-> 0)", resolver.GetMessage().c_str());
    } else {
      ASSERT_STREQ("(0 -> 2) (1 -> 0) (2 -> 1)", resolver.GetMessage().c_str());
    }
  }

  {
    TypeParam resolver(&allocator);
    static constexpr size_t moves[][2] = {{0, 1}, {1, 2}, {2, 3}, {3, 4}, {4, 0}};
    resolver.EmitNativeCode(BuildParallelMove(&allocator, moves, arraysize(moves)));
    if (TestFixture::has_swap) {
      ASSERT_STREQ("(4 <-> 0) (3 <-> 4) (2 <-> 3) (1 <-> 2)", resolver.GetMessage().c_str());
    } else {
      ASSERT_STREQ("(4 -> T0) (3 -> 4) (2 -> 3) (1 -> 2) (0 -> 1) (T0 -> 0)",
          resolver.GetMessage().c_str());
    }
  }
}

TYPED_TEST(ParallelMoveTest, ConstantLast) {
  MallocArenaPool pool;
  ArenaAllocator allocator(&pool);
  TypeParam resolver(&allocator);
  HParallelMove* moves = new (&allocator) HParallelMove(&allocator);
  moves->AddMove(
      Location::ConstantLocation(new (&allocator) HIntConstant(0)),
      Location::RegisterLocation(0),
      DataType::Type::kInt32,
      nullptr);
  moves->AddMove(
      Location::RegisterLocation(1),
      Location::RegisterLocation(2),
      DataType::Type::kInt32,
      nullptr);
  resolver.EmitNativeCode(moves);
  ASSERT_STREQ("(1 -> 2) (C -> 0)", resolver.GetMessage().c_str());
}

TYPED_TEST(ParallelMoveTest, Pairs) {
  MallocArenaPool pool;
  ArenaAllocator allocator(&pool);

  {
    TypeParam resolver(&allocator);
    HParallelMove* moves = new (&allocator) HParallelMove(&allocator);
    moves->AddMove(
        Location::RegisterLocation(2),
        Location::RegisterLocation(4),
        DataType::Type::kInt32,
        nullptr);
    moves->AddMove(
        Location::RegisterPairLocation(0, 1),
        Location::RegisterPairLocation(2, 3),
        DataType::Type::kInt64,
        nullptr);
    resolver.EmitNativeCode(moves);
    ASSERT_STREQ("(2 -> 4) (0,1 -> 2,3)", resolver.GetMessage().c_str());
  }

  {
    TypeParam resolver(&allocator);
    HParallelMove* moves = new (&allocator) HParallelMove(&allocator);
    moves->AddMove(
        Location::RegisterPairLocation(0, 1),
        Location::RegisterPairLocation(2, 3),
        DataType::Type::kInt64,
        nullptr);
    moves->AddMove(
        Location::RegisterLocation(2),
        Location::RegisterLocation(4),
        DataType::Type::kInt32,
        nullptr);
    resolver.EmitNativeCode(moves);
    ASSERT_STREQ("(2 -> 4) (0,1 -> 2,3)", resolver.GetMessage().c_str());
  }

  {
    TypeParam resolver(&allocator);
    HParallelMove* moves = new (&allocator) HParallelMove(&allocator);
    moves->AddMove(
        Location::RegisterPairLocation(0, 1),
        Location::RegisterPairLocation(2, 3),
        DataType::Type::kInt64,
        nullptr);
    moves->AddMove(
        Location::RegisterLocation(2),
        Location::RegisterLocation(0),
        DataType::Type::kInt32,
        nullptr);
    resolver.EmitNativeCode(moves);
    if (TestFixture::has_swap) {
      ASSERT_STREQ("(0,1 <-> 2,3)", resolver.GetMessage().c_str());
    } else {
      ASSERT_STREQ("(2 -> T0) (0,1 -> 2,3) (T0 -> 0)", resolver.GetMessage().c_str());
    }
  }
  {
    TypeParam resolver(&allocator);
    HParallelMove* moves = new (&allocator) HParallelMove(&allocator);
    moves->AddMove(
        Location::RegisterLocation(2),
        Location::RegisterLocation(7),
        DataType::Type::kInt32,
        nullptr);
    moves->AddMove(
        Location::RegisterLocation(7),
        Location::RegisterLocation(1),
        DataType::Type::kInt32,
        nullptr);
    moves->AddMove(
        Location::RegisterPairLocation(0, 1),
        Location::RegisterPairLocation(2, 3),
        DataType::Type::kInt64,
        nullptr);
    resolver.EmitNativeCode(moves);
    if (TestFixture::has_swap) {
      ASSERT_STREQ("(0,1 <-> 2,3) (7 -> 1) (0 -> 7)", resolver.GetMessage().c_str());
    } else {
      ASSERT_STREQ("(0,1 -> T0,T1) (7 -> 1) (2 -> 7) (T0,T1 -> 2,3)",
          resolver.GetMessage().c_str());
    }
  }
  {
    TypeParam resolver(&allocator);
    HParallelMove* moves = new (&allocator) HParallelMove(&allocator);
    moves->AddMove(
        Location::RegisterLocation(2),
        Location::RegisterLocation(7),
        DataType::Type::kInt32,
        nullptr);
    moves->AddMove(
        Location::RegisterPairLocation(0, 1),
        Location::RegisterPairLocation(2, 3),
        DataType::Type::kInt64,
        nullptr);
    moves->AddMove(
        Location::RegisterLocation(7),
        Location::RegisterLocation(1),
        DataType::Type::kInt32,
        nullptr);
    resolver.EmitNativeCode(moves);
    if (TestFixture::has_swap) {
      ASSERT_STREQ("(0,1 <-> 2,3) (7 -> 1) (0 -> 7)", resolver.GetMessage().c_str());
    } else {
      ASSERT_STREQ("(0,1 -> T0,T1) (7 -> 1) (2 -> 7) (T0,T1 -> 2,3)",
          resolver.GetMessage().c_str());
    }
  }
  {
    TypeParam resolver(&allocator);
    HParallelMove* moves = new (&allocator) HParallelMove(&allocator);
    moves->AddMove(
        Location::RegisterPairLocation(0, 1),
        Location::RegisterPairLocation(2, 3),
        DataType::Type::kInt64,
        nullptr);
    moves->AddMove(
        Location::RegisterLocation(2),
        Location::RegisterLocation(7),
        DataType::Type::kInt32,
        nullptr);
    moves->AddMove(
        Location::RegisterLocation(7),
        Location::RegisterLocation(1),
        DataType::Type::kInt32,
        nullptr);
    resolver.EmitNativeCode(moves);
    if (TestFixture::has_swap) {
      ASSERT_STREQ("(0,1 <-> 2,3) (7 -> 1) (0 -> 7)", resolver.GetMessage().c_str());
    } else {
      ASSERT_STREQ("(7 -> T0) (2 -> 7) (0,1 -> 2,3) (T0 -> 1)", resolver.GetMessage().c_str());
    }
  }
  {
    TypeParam resolver(&allocator);
    HParallelMove* moves = new (&allocator) HParallelMove(&allocator);
    moves->AddMove(
        Location::RegisterPairLocation(0, 1),
        Location::RegisterPairLocation(2, 3),
        DataType::Type::kInt64,
        nullptr);
    moves->AddMove(
        Location::RegisterPairLocation(2, 3),
        Location::RegisterPairLocation(0, 1),
        DataType::Type::kInt64,
        nullptr);
    resolver.EmitNativeCode(moves);
    if (TestFixture::has_swap) {
      ASSERT_STREQ("(2,3 <-> 0,1)", resolver.GetMessage().c_str());
    } else {
      ASSERT_STREQ("(2,3 -> T0,T1) (0,1 -> 2,3) (T0,T1 -> 0,1)", resolver.GetMessage().c_str());
    }
  }
  {
    TypeParam resolver(&allocator);
    HParallelMove* moves = new (&allocator) HParallelMove(&allocator);
    moves->AddMove(
        Location::RegisterPairLocation(2, 3),
        Location::RegisterPairLocation(0, 1),
        DataType::Type::kInt64,
        nullptr);
    moves->AddMove(
        Location::RegisterPairLocation(0, 1),
        Location::RegisterPairLocation(2, 3),
        DataType::Type::kInt64,
        nullptr);
    resolver.EmitNativeCode(moves);
    if (TestFixture::has_swap) {
      ASSERT_STREQ("(0,1 <-> 2,3)", resolver.GetMessage().c_str());
    } else {
      ASSERT_STREQ("(0,1 -> T0,T1) (2,3 -> 0,1) (T0,T1 -> 2,3)", resolver.GetMessage().c_str());
    }
  }
}

TYPED_TEST(ParallelMoveTest, MultiCycles) {
  MallocArenaPool pool;
  ArenaAllocator allocator(&pool);

  {
    TypeParam resolver(&allocator);
    static constexpr size_t moves[][2] = {{0, 1}, {1, 0}, {2, 3}, {3, 2}};
    resolver.EmitNativeCode(BuildParallelMove(&allocator, moves, arraysize(moves)));
    if (TestFixture::has_swap) {
      ASSERT_STREQ("(1 <-> 0) (3 <-> 2)",  resolver.GetMessage().c_str());
    } else {
      ASSERT_STREQ("(1 -> T0) (0 -> 1) (T0 -> 0) (3 -> T0) (2 -> 3) (T0 -> 2)",
          resolver.GetMessage().c_str());
    }
  }
  {
    TypeParam resolver(&allocator);
    HParallelMove* moves = new (&allocator) HParallelMove(&allocator);
    moves->AddMove(
        Location::RegisterPairLocation(0, 1),
        Location::RegisterPairLocation(2, 3),
        DataType::Type::kInt64,
        nullptr);
    moves->AddMove(
        Location::RegisterLocation(2),
        Location::RegisterLocation(0),
        DataType::Type::kInt32,
        nullptr);
    moves->AddMove(
        Location::RegisterLocation(3),
        Location::RegisterLocation(1),
        DataType::Type::kInt32,
        nullptr);
    resolver.EmitNativeCode(moves);
    if (TestFixture::has_swap) {
      ASSERT_STREQ("(0,1 <-> 2,3)", resolver.GetMessage().c_str());
    } else {
      ASSERT_STREQ("(2 -> T0) (3 -> T1) (0,1 -> 2,3) (T0 -> 0) (T1 -> 1)",
          resolver.GetMessage().c_str());
    }
  }
  {
    TypeParam resolver(&allocator);
    HParallelMove* moves = new (&allocator) HParallelMove(&allocator);
    moves->AddMove(
        Location::RegisterLocation(2),
        Location::RegisterLocation(0),
        DataType::Type::kInt32,
        nullptr);
    moves->AddMove(
        Location::RegisterLocation(3),
        Location::RegisterLocation(1),
        DataType::Type::kInt32,
        nullptr);
    moves->AddMove(
        Location::RegisterPairLocation(0, 1),
        Location::RegisterPairLocation(2, 3),
        DataType::Type::kInt64,
        nullptr);
    resolver.EmitNativeCode(moves);
    if (TestFixture::has_swap) {
      ASSERT_STREQ("(0,1 <-> 2,3)", resolver.GetMessage().c_str());
    } else {
      ASSERT_STREQ("(3 -> T0) (0,1 -> T2,T3) (T0 -> 1) (2 -> 0) (T2,T3 -> 2,3)",
          resolver.GetMessage().c_str());
    }
  }

  {
    // Test involving registers used in single context and pair context.
    TypeParam resolver(&allocator);
    HParallelMove* moves = new (&allocator) HParallelMove(&allocator);
    moves->AddMove(
        Location::RegisterLocation(10),
        Location::RegisterLocation(5),
        DataType::Type::kInt32,
        nullptr);
    moves->AddMove(
        Location::RegisterPairLocation(4, 5),
        Location::DoubleStackSlot(32),
        DataType::Type::kInt64,
        nullptr);
    moves->AddMove(
        Location::DoubleStackSlot(32),
        Location::RegisterPairLocation(10, 11),
        DataType::Type::kInt64,
        nullptr);
    resolver.EmitNativeCode(moves);
    if (TestFixture::has_swap) {
      ASSERT_STREQ("(2x32(sp) <-> 10,11) (4,5 <-> 2x32(sp)) (4 -> 5)", resolver.GetMessage().c_str());
    } else {
      ASSERT_STREQ("(2x32(sp) -> T0,T1) (4,5 -> 2x32(sp)) (10 -> 5) (T0,T1 -> 10,11)",
          resolver.GetMessage().c_str());
    }
  }
}

// Test that we do 64bits moves before 32bits moves.
TYPED_TEST(ParallelMoveTest, CyclesWith64BitsMoves) {
  MallocArenaPool pool;
  ArenaAllocator allocator(&pool);

  {
    TypeParam resolver(&allocator);
    HParallelMove* moves = new (&allocator) HParallelMove(&allocator);
    moves->AddMove(
        Location::RegisterLocation(0),
        Location::RegisterLocation(1),
        DataType::Type::kInt64,
        nullptr);
    moves->AddMove(
        Location::RegisterLocation(1),
        Location::StackSlot(48),
        DataType::Type::kInt32,
        nullptr);
    moves->AddMove(
        Location::StackSlot(48),
        Location::RegisterLocation(0),
        DataType::Type::kInt32,
        nullptr);
    resolver.EmitNativeCode(moves);
    if (TestFixture::has_swap) {
      ASSERT_STREQ("(0 <-> 1) (48(sp) <-> 0)", resolver.GetMessage().c_str());
    } else {
      ASSERT_STREQ("(48(sp) -> T0) (1 -> 48(sp)) (0 -> 1) (T0 -> 0)",
          resolver.GetMessage().c_str());
    }
  }

  {
    TypeParam resolver(&allocator);
    HParallelMove* moves = new (&allocator) HParallelMove(&allocator);
    moves->AddMove(
        Location::RegisterPairLocation(0, 1),
        Location::RegisterPairLocation(2, 3),
        DataType::Type::kInt64,
        nullptr);
    moves->AddMove(
        Location::RegisterPairLocation(2, 3),
        Location::DoubleStackSlot(32),
        DataType::Type::kInt64,
        nullptr);
    moves->AddMove(
        Location::DoubleStackSlot(32),
        Location::RegisterPairLocation(0, 1),
        DataType::Type::kInt64,
        nullptr);
    resolver.EmitNativeCode(moves);
    if (TestFixture::has_swap) {
      ASSERT_STREQ("(2x32(sp) <-> 0,1) (2,3 <-> 2x32(sp))", resolver.GetMessage().c_str());
    } else {
      ASSERT_STREQ("(2x32(sp) -> T0,T1) (2,3 -> 2x32(sp)) (0,1 -> 2,3) (T0,T1 -> 0,1)",
          resolver.GetMessage().c_str());
    }
  }
}

TYPED_TEST(ParallelMoveTest, CyclesWith64BitsMoves2) {
  MallocArenaPool pool;
  ArenaAllocator allocator(&pool);

  {
    TypeParam resolver(&allocator);
    HParallelMove* moves = new (&allocator) HParallelMove(&allocator);
    moves->AddMove(
        Location::RegisterLocation(0),
        Location::RegisterLocation(3),
        DataType::Type::kInt32,
        nullptr);
    moves->AddMove(
        Location::RegisterPairLocation(2, 3),
        Location::RegisterPairLocation(0, 1),
        DataType::Type::kInt64,
        nullptr);
    moves->AddMove(
        Location::RegisterLocation(7),
        Location::RegisterLocation(2),
        DataType::Type::kInt32,
        nullptr);
    resolver.EmitNativeCode(moves);
    if (TestFixture::has_swap) {
      ASSERT_STREQ("(2,3 <-> 0,1) (2 -> 3) (7 -> 2)", resolver.GetMessage().c_str());
    } else {
      ASSERT_STREQ("(2,3 -> T0,T1) (0 -> 3) (T0,T1 -> 0,1) (7 -> 2)",
          resolver.GetMessage().c_str());
    }
  }
}

}  // namespace art
