10add79aeSMiloš Stojanović //===-- SnippetGeneratorTest.cpp --------------------------------*- C++ -*-===//
20add79aeSMiloš Stojanović //
30add79aeSMiloš Stojanović // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40add79aeSMiloš Stojanović // See https://llvm.org/LICENSE.txt for license information.
50add79aeSMiloš Stojanović // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60add79aeSMiloš Stojanović //
70add79aeSMiloš Stojanović //===----------------------------------------------------------------------===//
80add79aeSMiloš Stojanović
90add79aeSMiloš Stojanović #include "../Common/AssemblerUtils.h"
100add79aeSMiloš Stojanović #include "LlvmState.h"
110add79aeSMiloš Stojanović #include "MCInstrDescView.h"
120add79aeSMiloš Stojanović #include "MipsInstrInfo.h"
1324b7b99bSMiloš Stojanović #include "ParallelSnippetGenerator.h"
1431458a9fSMiloš Stojanović #include "RegisterAliasing.h"
1524b7b99bSMiloš Stojanović #include "SerialSnippetGenerator.h"
1631458a9fSMiloš Stojanović #include "TestBase.h"
170add79aeSMiloš Stojanović
180add79aeSMiloš Stojanović namespace llvm {
190add79aeSMiloš Stojanović namespace exegesis {
200add79aeSMiloš Stojanović namespace {
210add79aeSMiloš Stojanović
220add79aeSMiloš Stojanović using testing::AnyOf;
230add79aeSMiloš Stojanović using testing::ElementsAre;
24ea91758aSMiloš Stojanović using testing::HasSubstr;
250add79aeSMiloš Stojanović using testing::SizeIs;
260add79aeSMiloš Stojanović
270add79aeSMiloš Stojanović MATCHER(IsInvalid, "") { return !arg.isValid(); }
280add79aeSMiloš Stojanović MATCHER(IsReg, "") { return arg.isReg(); }
290add79aeSMiloš Stojanović
300add79aeSMiloš Stojanović template <typename SnippetGeneratorT>
31*dbefcde6STom Stellard class MipsSnippetGeneratorTest : public MipsTestBase {
320add79aeSMiloš Stojanović protected:
MipsSnippetGeneratorTest()33*dbefcde6STom Stellard MipsSnippetGeneratorTest() : Generator(State, SnippetGenerator::Options()) {}
340add79aeSMiloš Stojanović
checkAndGetCodeTemplates(unsigned Opcode)350add79aeSMiloš Stojanović std::vector<CodeTemplate> checkAndGetCodeTemplates(unsigned Opcode) {
360add79aeSMiloš Stojanović randomGenerator().seed(0); // Initialize seed.
370add79aeSMiloš Stojanović const Instruction &Instr = State.getIC().getInstr(Opcode);
380add79aeSMiloš Stojanović auto CodeTemplateOrError = Generator.generateCodeTemplates(
396030fe01SRoman Lebedev &Instr, State.getRATC().emptyRegisters());
400add79aeSMiloš Stojanović EXPECT_FALSE(CodeTemplateOrError.takeError()); // Valid configuration.
410add79aeSMiloš Stojanović return std::move(CodeTemplateOrError.get());
420add79aeSMiloš Stojanović }
430add79aeSMiloš Stojanović
440add79aeSMiloš Stojanović SnippetGeneratorT Generator;
450add79aeSMiloš Stojanović };
460add79aeSMiloš Stojanović
47*dbefcde6STom Stellard using MipsSerialSnippetGeneratorTest = MipsSnippetGeneratorTest<SerialSnippetGenerator>;
480add79aeSMiloš Stojanović
49*dbefcde6STom Stellard using MipsParallelSnippetGeneratorTest =
50*dbefcde6STom Stellard MipsSnippetGeneratorTest<ParallelSnippetGenerator>;
51ea91758aSMiloš Stojanović
TEST_F(MipsSerialSnippetGeneratorTest,ImplicitSelfDependencyThroughExplicitRegs)52*dbefcde6STom Stellard TEST_F(MipsSerialSnippetGeneratorTest, ImplicitSelfDependencyThroughExplicitRegs) {
530add79aeSMiloš Stojanović // - ADD
540add79aeSMiloš Stojanović // - Op0 Explicit Def RegClass(GPR32)
550add79aeSMiloš Stojanović // - Op1 Explicit Use RegClass(GPR32)
560add79aeSMiloš Stojanović // - Op2 Explicit Use RegClass(GPR32)
570add79aeSMiloš Stojanović // - Var0 [Op0]
580add79aeSMiloš Stojanović // - Var1 [Op1]
590add79aeSMiloš Stojanović // - Var2 [Op2]
60ea91758aSMiloš Stojanović // - hasAliasingRegisters
610add79aeSMiloš Stojanović const unsigned Opcode = Mips::ADD;
620add79aeSMiloš Stojanović const auto CodeTemplates = checkAndGetCodeTemplates(Opcode);
630add79aeSMiloš Stojanović ASSERT_THAT(CodeTemplates, SizeIs(1));
640add79aeSMiloš Stojanović const auto &CT = CodeTemplates[0];
650add79aeSMiloš Stojanović EXPECT_THAT(CT.Execution, ExecutionMode::SERIAL_VIA_EXPLICIT_REGS);
660add79aeSMiloš Stojanović ASSERT_THAT(CT.Instructions, SizeIs(1));
670add79aeSMiloš Stojanović const InstructionTemplate &IT = CT.Instructions[0];
680add79aeSMiloš Stojanović EXPECT_THAT(IT.getOpcode(), Opcode);
6932d384c0SGuillaume Chatelet ASSERT_THAT(IT.getVariableValues(), SizeIs(3));
7032d384c0SGuillaume Chatelet EXPECT_THAT(IT.getVariableValues(),
710add79aeSMiloš Stojanović AnyOf(ElementsAre(IsReg(), IsInvalid(), IsReg()),
720add79aeSMiloš Stojanović ElementsAre(IsReg(), IsReg(), IsInvalid())))
730add79aeSMiloš Stojanović << "Op0 is either set to Op1 or to Op2";
740add79aeSMiloš Stojanović }
750add79aeSMiloš Stojanović
TEST_F(MipsSerialSnippetGeneratorTest,ImplicitSelfDependencyThroughExplicitRegsForbidAll)76*dbefcde6STom Stellard TEST_F(MipsSerialSnippetGeneratorTest,
770add79aeSMiloš Stojanović ImplicitSelfDependencyThroughExplicitRegsForbidAll) {
780add79aeSMiloš Stojanović // - XOR
790add79aeSMiloš Stojanović // - Op0 Explicit Def RegClass(GPR32)
800add79aeSMiloš Stojanović // - Op1 Explicit Use RegClass(GPR32)
810add79aeSMiloš Stojanović // - Op2 Explicit Use RegClass(GPR32)
820add79aeSMiloš Stojanović // - Var0 [Op0]
830add79aeSMiloš Stojanović // - Var1 [Op1]
840add79aeSMiloš Stojanović // - Var2 [Op2]
85ea91758aSMiloš Stojanović // - hasAliasingRegisters
860add79aeSMiloš Stojanović randomGenerator().seed(0); // Initialize seed.
870add79aeSMiloš Stojanović const Instruction &Instr = State.getIC().getInstr(Mips::XOR);
880add79aeSMiloš Stojanović auto AllRegisters = State.getRATC().emptyRegisters();
890add79aeSMiloš Stojanović AllRegisters.flip();
906030fe01SRoman Lebedev auto Error =
916030fe01SRoman Lebedev Generator.generateCodeTemplates(&Instr, AllRegisters).takeError();
920add79aeSMiloš Stojanović EXPECT_TRUE((bool)Error);
930add79aeSMiloš Stojanović consumeError(std::move(Error));
940add79aeSMiloš Stojanović }
950add79aeSMiloš Stojanović
TEST_F(MipsParallelSnippetGeneratorTest,MemoryUse)96*dbefcde6STom Stellard TEST_F(MipsParallelSnippetGeneratorTest, MemoryUse) {
97ea91758aSMiloš Stojanović // LB reads from memory.
98ea91758aSMiloš Stojanović // - LB
99ea91758aSMiloš Stojanović // - Op0 Explicit Def RegClass(GPR32)
100ea91758aSMiloš Stojanović // - Op1 Explicit Use Memory RegClass(MSA128F16)
101ea91758aSMiloš Stojanović // - Op2 Explicit Use Memory
102ea91758aSMiloš Stojanović // - Var0 [Op0]
103ea91758aSMiloš Stojanović // - Var1 [Op1]
104ea91758aSMiloš Stojanović // - Var2 [Op2]
105ea91758aSMiloš Stojanović // - hasMemoryOperands
106ea91758aSMiloš Stojanović const unsigned Opcode = Mips::LB;
107ea91758aSMiloš Stojanović const auto CodeTemplates = checkAndGetCodeTemplates(Opcode);
108ea91758aSMiloš Stojanović ASSERT_THAT(CodeTemplates, SizeIs(1));
109ea91758aSMiloš Stojanović const auto &CT = CodeTemplates[0];
11024b7b99bSMiloš Stojanović EXPECT_THAT(CT.Info,
11124b7b99bSMiloš Stojanović HasSubstr("instruction is parallel, repeating a random one."));
112ea91758aSMiloš Stojanović EXPECT_THAT(CT.Execution, ExecutionMode::UNKNOWN);
113ea91758aSMiloš Stojanović ASSERT_THAT(CT.Instructions,
11424b7b99bSMiloš Stojanović SizeIs(ParallelSnippetGenerator::kMinNumDifferentAddresses));
115ea91758aSMiloš Stojanović const InstructionTemplate &IT = CT.Instructions[0];
116ea91758aSMiloš Stojanović EXPECT_THAT(IT.getOpcode(), Opcode);
117ea91758aSMiloš Stojanović ASSERT_THAT(IT.getVariableValues(), SizeIs(3));
118ea91758aSMiloš Stojanović EXPECT_EQ(IT.getVariableValues()[0].getReg(), 0u);
119ea91758aSMiloš Stojanović EXPECT_EQ(IT.getVariableValues()[2].getImm(), 0);
120ea91758aSMiloš Stojanović }
121ea91758aSMiloš Stojanović
1220add79aeSMiloš Stojanović } // namespace
1230add79aeSMiloš Stojanović } // namespace exegesis
1240add79aeSMiloš Stojanović } // namespace llvm
125