1c8ec685cSJinsong Ji //===-- SnippetGeneratorTest.cpp --------------------------------*- C++ -*-===//
2c8ec685cSJinsong Ji //
3c8ec685cSJinsong Ji // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4c8ec685cSJinsong Ji // See https://llvm.org/LICENSE.txt for license information.
5c8ec685cSJinsong Ji // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6c8ec685cSJinsong Ji //
7c8ec685cSJinsong Ji //===----------------------------------------------------------------------===//
8c8ec685cSJinsong Ji
9c8ec685cSJinsong Ji #include "../Common/AssemblerUtils.h"
10c8ec685cSJinsong Ji #include "LlvmState.h"
11c8ec685cSJinsong Ji #include "MCInstrDescView.h"
12c8ec685cSJinsong Ji #include "PPCInstrInfo.h"
13c8ec685cSJinsong Ji #include "ParallelSnippetGenerator.h"
14c8ec685cSJinsong Ji #include "RegisterAliasing.h"
15c8ec685cSJinsong Ji #include "SerialSnippetGenerator.h"
16c8ec685cSJinsong Ji #include "TestBase.h"
17c8ec685cSJinsong Ji
18c8ec685cSJinsong Ji namespace llvm {
19c8ec685cSJinsong Ji namespace exegesis {
20c8ec685cSJinsong Ji namespace {
21c8ec685cSJinsong Ji
22c8ec685cSJinsong Ji using testing::AnyOf;
23c8ec685cSJinsong Ji using testing::ElementsAre;
24c8ec685cSJinsong Ji using testing::HasSubstr;
25c8ec685cSJinsong Ji using testing::SizeIs;
26c8ec685cSJinsong Ji
27c8ec685cSJinsong Ji MATCHER(IsInvalid, "") { return !arg.isValid(); }
28c8ec685cSJinsong Ji MATCHER(IsReg, "") { return arg.isReg(); }
29c8ec685cSJinsong Ji
30c8ec685cSJinsong Ji template <typename SnippetGeneratorT>
31dbefcde6STom Stellard class PPCSnippetGeneratorTest : public PPCTestBase {
32c8ec685cSJinsong Ji protected:
PPCSnippetGeneratorTest()33dbefcde6STom Stellard PPCSnippetGeneratorTest() : Generator(State, SnippetGenerator::Options()) {}
34c8ec685cSJinsong Ji
checkAndGetCodeTemplates(unsigned Opcode)35c8ec685cSJinsong Ji std::vector<CodeTemplate> checkAndGetCodeTemplates(unsigned Opcode) {
36c8ec685cSJinsong Ji randomGenerator().seed(0); // Initialize seed.
37c8ec685cSJinsong Ji const Instruction &Instr = State.getIC().getInstr(Opcode);
38c8ec685cSJinsong Ji auto CodeTemplateOrError = Generator.generateCodeTemplates(
39c8ec685cSJinsong Ji &Instr, State.getRATC().emptyRegisters());
40c8ec685cSJinsong Ji EXPECT_FALSE(CodeTemplateOrError.takeError()); // Valid configuration.
41c8ec685cSJinsong Ji return std::move(CodeTemplateOrError.get());
42c8ec685cSJinsong Ji }
43c8ec685cSJinsong Ji
44c8ec685cSJinsong Ji SnippetGeneratorT Generator;
45c8ec685cSJinsong Ji };
46c8ec685cSJinsong Ji
47dbefcde6STom Stellard using PPCSerialSnippetGeneratorTest = PPCSnippetGeneratorTest<SerialSnippetGenerator>;
48c8ec685cSJinsong Ji
49dbefcde6STom Stellard using PPCParallelSnippetGeneratorTest =
50dbefcde6STom Stellard PPCSnippetGeneratorTest<ParallelSnippetGenerator>;
51c8ec685cSJinsong Ji
TEST_F(PPCSerialSnippetGeneratorTest,ImplicitSelfDependencyThroughExplicitRegs)52dbefcde6STom Stellard TEST_F(PPCSerialSnippetGeneratorTest, ImplicitSelfDependencyThroughExplicitRegs) {
53c8ec685cSJinsong Ji // - ADD8
54c8ec685cSJinsong Ji // - Op0 Explicit Def RegClass(G8RC)
55c8ec685cSJinsong Ji // - Op1 Explicit Use RegClass(G8RC)
56c8ec685cSJinsong Ji // - Op2 Explicit Use RegClass(G8RC)
57c8ec685cSJinsong Ji // - Var0 [Op0]
58c8ec685cSJinsong Ji // - Var1 [Op1]
59c8ec685cSJinsong Ji // - Var2 [Op2]
60c8ec685cSJinsong Ji // - hasAliasingRegisters
61c8ec685cSJinsong Ji const unsigned Opcode = PPC::ADD8;
62c8ec685cSJinsong Ji const auto CodeTemplates = checkAndGetCodeTemplates(Opcode);
63c8ec685cSJinsong Ji ASSERT_THAT(CodeTemplates, SizeIs(1));
64c8ec685cSJinsong Ji const auto &CT = CodeTemplates[0];
65c8ec685cSJinsong Ji EXPECT_THAT(CT.Execution, ExecutionMode::SERIAL_VIA_EXPLICIT_REGS);
66c8ec685cSJinsong Ji ASSERT_THAT(CT.Instructions, SizeIs(1));
67c8ec685cSJinsong Ji const InstructionTemplate &IT = CT.Instructions[0];
68c8ec685cSJinsong Ji EXPECT_THAT(IT.getOpcode(), Opcode);
69c8ec685cSJinsong Ji ASSERT_THAT(IT.getVariableValues(), SizeIs(3));
70c8ec685cSJinsong Ji EXPECT_THAT(IT.getVariableValues(),
71c8ec685cSJinsong Ji AnyOf(ElementsAre(IsReg(), IsInvalid(), IsReg()),
72c8ec685cSJinsong Ji ElementsAre(IsReg(), IsReg(), IsInvalid())))
73c8ec685cSJinsong Ji << "Op0 is either set to Op1 or to Op2";
74c8ec685cSJinsong Ji }
75c8ec685cSJinsong Ji
TEST_F(PPCSerialSnippetGeneratorTest,ImplicitSelfDependencyThroughTiedRegs)76dbefcde6STom Stellard TEST_F(PPCSerialSnippetGeneratorTest, ImplicitSelfDependencyThroughTiedRegs) {
77c8ec685cSJinsong Ji
78c8ec685cSJinsong Ji // - RLDIMI
79c8ec685cSJinsong Ji // - Op0 Explicit Def RegClass(G8RC)
80c8ec685cSJinsong Ji // - Op1 Explicit Use RegClass(G8RC) TiedToOp0
81c8ec685cSJinsong Ji // - Op2 Explicit Use RegClass(G8RC)
82c8ec685cSJinsong Ji // - Op3 Explicit Use Immediate
83c8ec685cSJinsong Ji // - Op4 Explicit Use Immediate
84c8ec685cSJinsong Ji // - Var0 [Op0,Op1]
85c8ec685cSJinsong Ji // - Var1 [Op2]
86c8ec685cSJinsong Ji // - Var2 [Op3]
87c8ec685cSJinsong Ji // - Var3 [Op4]
88c8ec685cSJinsong Ji // - hasTiedRegisters (execution is always serial)
89c8ec685cSJinsong Ji // - hasAliasingRegisters
90c8ec685cSJinsong Ji // - RLDIMI
91c8ec685cSJinsong Ji const unsigned Opcode = PPC::RLDIMI;
92c8ec685cSJinsong Ji const auto CodeTemplates = checkAndGetCodeTemplates(Opcode);
93c8ec685cSJinsong Ji ASSERT_THAT(CodeTemplates, SizeIs(1));
94c8ec685cSJinsong Ji const auto &CT = CodeTemplates[0];
95c8ec685cSJinsong Ji EXPECT_THAT(CT.Execution, ExecutionMode::ALWAYS_SERIAL_TIED_REGS_ALIAS);
96c8ec685cSJinsong Ji ASSERT_THAT(CT.Instructions, SizeIs(1));
97c8ec685cSJinsong Ji const InstructionTemplate &IT = CT.Instructions[0];
98c8ec685cSJinsong Ji EXPECT_THAT(IT.getOpcode(), Opcode);
99c8ec685cSJinsong Ji ASSERT_THAT(IT.getVariableValues(), SizeIs(4));
100c8ec685cSJinsong Ji EXPECT_THAT(IT.getVariableValues()[2], IsInvalid()) << "Operand 1 is not set";
101c8ec685cSJinsong Ji EXPECT_THAT(IT.getVariableValues()[3], IsInvalid()) << "Operand 2 is not set";
102c8ec685cSJinsong Ji }
103c8ec685cSJinsong Ji
TEST_F(PPCParallelSnippetGeneratorTest,MemoryUse)104dbefcde6STom Stellard TEST_F(PPCParallelSnippetGeneratorTest, MemoryUse) {
105c8ec685cSJinsong Ji // - LDX
106c8ec685cSJinsong Ji // - Op0 Explicit Def RegClass(G8RC)
107c8ec685cSJinsong Ji // - Op1 Explicit Use Memory RegClass(GPRC)
108c8ec685cSJinsong Ji // - Op2 Explicit Use Memory RegClass(VSSRC)
109c8ec685cSJinsong Ji // - Var0 [Op0]
110c8ec685cSJinsong Ji // - Var1 [Op1]
111c8ec685cSJinsong Ji // - Var2 [Op2]
112c8ec685cSJinsong Ji // - hasMemoryOperands
113c8ec685cSJinsong Ji // - hasAliasingRegisters
114c8ec685cSJinsong Ji const unsigned Opcode = PPC::LDX;
115c8ec685cSJinsong Ji const auto CodeTemplates = checkAndGetCodeTemplates(Opcode);
116c8ec685cSJinsong Ji ASSERT_THAT(CodeTemplates, SizeIs(1));
117*2ffe225dSRoman Lebedev for (const auto &CT : CodeTemplates) {
118*2ffe225dSRoman Lebedev EXPECT_THAT(CT.Info, HasSubstr("instruction has no tied variables"));
119c8ec685cSJinsong Ji EXPECT_THAT(CT.Execution, ExecutionMode::UNKNOWN);
120c8ec685cSJinsong Ji ASSERT_THAT(CT.Instructions,
121c8ec685cSJinsong Ji SizeIs(ParallelSnippetGenerator::kMinNumDifferentAddresses));
122c8ec685cSJinsong Ji const InstructionTemplate &IT = CT.Instructions[0];
123c8ec685cSJinsong Ji EXPECT_THAT(IT.getOpcode(), Opcode);
124c8ec685cSJinsong Ji ASSERT_THAT(IT.getVariableValues(), SizeIs(3));
125c8ec685cSJinsong Ji EXPECT_EQ(IT.getVariableValues()[1].getReg(), PPC::X1);
126c8ec685cSJinsong Ji EXPECT_EQ(IT.getVariableValues()[2].getReg(), PPC::X13);
127c8ec685cSJinsong Ji }
128*2ffe225dSRoman Lebedev }
129c8ec685cSJinsong Ji
130c8ec685cSJinsong Ji } // namespace
131c8ec685cSJinsong Ji } // namespace exegesis
132c8ec685cSJinsong Ji } // namespace llvm
133