//===-- 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(); }

template <typename SnippetGeneratorT>
class PPCSnippetGeneratorTest : public PPCTestBase {
protected:
  PPCSnippetGeneratorTest() : 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 PPCSerialSnippetGeneratorTest = PPCSnippetGeneratorTest<SerialSnippetGenerator>;

using PPCParallelSnippetGeneratorTest =
    PPCSnippetGeneratorTest<ParallelSnippetGenerator>;

TEST_F(PPCSerialSnippetGeneratorTest, 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(PPCSerialSnippetGeneratorTest, 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(PPCParallelSnippetGeneratorTest, 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
