//===-- SnippetGeneratorTest.cpp --------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "../Common/AssemblerUtils.h"
#include "LlvmState.h"
#include "MCInstrDescView.h"
#include "PPCInstrInfo.h"
#include "ParallelSnippetGenerator.h"
#include "RegisterAliasing.h"
#include "SerialSnippetGenerator.h"
#include "TestBase.h"

#include <unordered_set>

namespace llvm {
namespace exegesis {
namespace {

using testing::AnyOf;
using testing::ElementsAre;
using testing::HasSubstr;
using testing::SizeIs;

MATCHER(IsInvalid, "") { return !arg.isValid(); }
MATCHER(IsReg, "") { return arg.isReg(); }

class PPCSnippetGeneratorTest : public PPCTestBase {};

template <typename SnippetGeneratorT>
class SnippetGeneratorTest : public PPCSnippetGeneratorTest {
protected:
  SnippetGeneratorTest() : Generator(State, SnippetGenerator::Options()) {}

  std::vector<CodeTemplate> checkAndGetCodeTemplates(unsigned Opcode) {
    randomGenerator().seed(0); // Initialize seed.
    const Instruction &Instr = State.getIC().getInstr(Opcode);
    auto CodeTemplateOrError = Generator.generateCodeTemplates(
        &Instr, State.getRATC().emptyRegisters());
    EXPECT_FALSE(CodeTemplateOrError.takeError()); // Valid configuration.
    return std::move(CodeTemplateOrError.get());
  }

  SnippetGeneratorT Generator;
};

using SerialSnippetGeneratorTest = SnippetGeneratorTest<SerialSnippetGenerator>;

using ParallelSnippetGeneratorTest =
    SnippetGeneratorTest<ParallelSnippetGenerator>;

TEST_F(SerialSnippetGeneratorTest, ImplicitSelfDependencyThroughExplicitRegs) {
  // - ADD8
  // - Op0 Explicit Def RegClass(G8RC)
  // - Op1 Explicit Use RegClass(G8RC)
  // - Op2 Explicit Use RegClass(G8RC)
  // - Var0 [Op0]
  // - Var1 [Op1]
  // - Var2 [Op2]
  // - hasAliasingRegisters
  const unsigned Opcode = PPC::ADD8;
  const auto CodeTemplates = checkAndGetCodeTemplates(Opcode);
  ASSERT_THAT(CodeTemplates, SizeIs(1));
  const auto &CT = CodeTemplates[0];
  EXPECT_THAT(CT.Execution, ExecutionMode::SERIAL_VIA_EXPLICIT_REGS);
  ASSERT_THAT(CT.Instructions, SizeIs(1));
  const InstructionTemplate &IT = CT.Instructions[0];
  EXPECT_THAT(IT.getOpcode(), Opcode);
  ASSERT_THAT(IT.getVariableValues(), SizeIs(3));
  EXPECT_THAT(IT.getVariableValues(),
              AnyOf(ElementsAre(IsReg(), IsInvalid(), IsReg()),
                    ElementsAre(IsReg(), IsReg(), IsInvalid())))
      << "Op0 is either set to Op1 or to Op2";
}

TEST_F(SerialSnippetGeneratorTest, ImplicitSelfDependencyThroughTiedRegs) {

  // - RLDIMI
  // - Op0 Explicit Def RegClass(G8RC)
  // - Op1 Explicit Use RegClass(G8RC) TiedToOp0
  // - Op2 Explicit Use RegClass(G8RC)
  // - Op3 Explicit Use Immediate
  // - Op4 Explicit Use Immediate
  // - Var0 [Op0,Op1]
  // - Var1 [Op2]
  // - Var2 [Op3]
  // - Var3 [Op4]
  // - hasTiedRegisters (execution is always serial)
  // - hasAliasingRegisters
  // - RLDIMI
  const unsigned Opcode = PPC::RLDIMI;
  const auto CodeTemplates = checkAndGetCodeTemplates(Opcode);
  ASSERT_THAT(CodeTemplates, SizeIs(1));
  const auto &CT = CodeTemplates[0];
  EXPECT_THAT(CT.Execution, ExecutionMode::ALWAYS_SERIAL_TIED_REGS_ALIAS);
  ASSERT_THAT(CT.Instructions, SizeIs(1));
  const InstructionTemplate &IT = CT.Instructions[0];
  EXPECT_THAT(IT.getOpcode(), Opcode);
  ASSERT_THAT(IT.getVariableValues(), SizeIs(4));
  EXPECT_THAT(IT.getVariableValues()[2], IsInvalid()) << "Operand 1 is not set";
  EXPECT_THAT(IT.getVariableValues()[3], IsInvalid()) << "Operand 2 is not set";
}

TEST_F(ParallelSnippetGeneratorTest, MemoryUse) {
  // - LDX
  // - Op0 Explicit Def RegClass(G8RC)
  // - Op1 Explicit Use Memory RegClass(GPRC)
  // - Op2 Explicit Use Memory RegClass(VSSRC)
  // - Var0 [Op0]
  // - Var1 [Op1]
  // - Var2 [Op2]
  // - hasMemoryOperands
  // - hasAliasingRegisters
  const unsigned Opcode = PPC::LDX;
  const auto CodeTemplates = checkAndGetCodeTemplates(Opcode);
  ASSERT_THAT(CodeTemplates, SizeIs(1));
  const auto &CT = CodeTemplates[0];
  EXPECT_THAT(CT.Info, HasSubstr("instruction has no tied variables picking "
                                 "Uses different from defs"));
  EXPECT_THAT(CT.Execution, ExecutionMode::UNKNOWN);
  ASSERT_THAT(CT.Instructions,
              SizeIs(ParallelSnippetGenerator::kMinNumDifferentAddresses));
  const InstructionTemplate &IT = CT.Instructions[0];
  EXPECT_THAT(IT.getOpcode(), Opcode);
  ASSERT_THAT(IT.getVariableValues(), SizeIs(3));
  EXPECT_EQ(IT.getVariableValues()[1].getReg(), PPC::X1);
  EXPECT_EQ(IT.getVariableValues()[2].getReg(), PPC::X13);
}

} // namespace
} // namespace exegesis
} // namespace llvm
