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