|  | //===- MCInstrAnalysisTest.cpp - RISCVMCInstrAnalysis unit tests ----------===// | 
|  | // | 
|  | // 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 "llvm/MC/MCInstrAnalysis.h" | 
|  | #include "MCTargetDesc/RISCVMCTargetDesc.h" | 
|  | #include "llvm/MC/MCInstBuilder.h" | 
|  | #include "llvm/MC/TargetRegistry.h" | 
|  | #include "llvm/Support/TargetSelect.h" | 
|  |  | 
|  | #include "gtest/gtest.h" | 
|  |  | 
|  | #include <memory> | 
|  |  | 
|  | using namespace llvm; | 
|  |  | 
|  | namespace { | 
|  |  | 
|  | class InstrAnalysisTest : public testing::TestWithParam<const char *> { | 
|  | protected: | 
|  | std::unique_ptr<const MCInstrInfo> Info; | 
|  | std::unique_ptr<const MCInstrAnalysis> Analysis; | 
|  |  | 
|  | static void SetUpTestSuite() { | 
|  | LLVMInitializeRISCVTargetInfo(); | 
|  | LLVMInitializeRISCVTarget(); | 
|  | LLVMInitializeRISCVTargetMC(); | 
|  | } | 
|  |  | 
|  | InstrAnalysisTest() { | 
|  | std::string Error; | 
|  | const Target *TheTarget = | 
|  | TargetRegistry::lookupTarget(Triple::normalize(GetParam()), Error); | 
|  | Info = std::unique_ptr<const MCInstrInfo>(TheTarget->createMCInstrInfo()); | 
|  | Analysis = std::unique_ptr<const MCInstrAnalysis>( | 
|  | TheTarget->createMCInstrAnalysis(Info.get())); | 
|  | } | 
|  | }; | 
|  |  | 
|  | } // namespace | 
|  |  | 
|  | static MCInst jal(unsigned RD) { | 
|  | return MCInstBuilder(RISCV::JAL).addReg(RD).addImm(16); | 
|  | } | 
|  |  | 
|  | static MCInst jalr(unsigned RD, unsigned RS1 = RISCV::X10) { | 
|  | return MCInstBuilder(RISCV::JALR).addReg(RD).addReg(RS1).addImm(16); | 
|  | } | 
|  |  | 
|  | static MCInst cjr(unsigned RS1) { | 
|  | return MCInstBuilder(RISCV::C_JR).addReg(RS1); | 
|  | } | 
|  |  | 
|  | static MCInst cj() { return MCInstBuilder(RISCV::C_J).addImm(16); } | 
|  | static MCInst cjal() { return MCInstBuilder(RISCV::C_JAL).addImm(16); } | 
|  |  | 
|  | static MCInst cjalr(unsigned RS1) { | 
|  | return MCInstBuilder(RISCV::C_JALR).addReg(RS1); | 
|  | } | 
|  |  | 
|  | static MCInst beq() { | 
|  | return MCInstBuilder(RISCV::BEQ) | 
|  | .addReg(RISCV::X0) | 
|  | .addReg(RISCV::X1) | 
|  | .addImm(32); | 
|  | } | 
|  |  | 
|  | static MCInst cbeqz() { | 
|  | return MCInstBuilder(RISCV::C_BEQZ).addReg(RISCV::X1).addImm(32); | 
|  | } | 
|  |  | 
|  | TEST_P(InstrAnalysisTest, IsTerminator) { | 
|  | EXPECT_TRUE(Analysis->isTerminator(beq())); | 
|  | EXPECT_TRUE(Analysis->isTerminator(cbeqz())); | 
|  | EXPECT_TRUE(Analysis->isTerminator(jal(RISCV::X0))); | 
|  | EXPECT_FALSE(Analysis->isTerminator(jal(RISCV::X5))); | 
|  | EXPECT_TRUE(Analysis->isTerminator(jalr(RISCV::X0))); | 
|  | EXPECT_FALSE(Analysis->isTerminator(jalr(RISCV::X5))); | 
|  | EXPECT_TRUE(Analysis->isTerminator(cj())); | 
|  | EXPECT_FALSE(Analysis->isTerminator(cjal())); | 
|  | } | 
|  |  | 
|  | TEST_P(InstrAnalysisTest, IsCall) { | 
|  | EXPECT_FALSE(Analysis->isCall(beq())); | 
|  | EXPECT_FALSE(Analysis->isCall(cbeqz())); | 
|  | EXPECT_FALSE(Analysis->isCall(jal(RISCV::X0))); | 
|  | EXPECT_TRUE(Analysis->isCall(jal(RISCV::X1))); | 
|  | EXPECT_TRUE(Analysis->isCall(jalr(RISCV::X1, RISCV::X1))); | 
|  | EXPECT_FALSE(Analysis->isCall(jalr(RISCV::X0, RISCV::X5))); | 
|  | EXPECT_FALSE(Analysis->isCall(cj())); | 
|  | EXPECT_FALSE(Analysis->isCall(cjr(RISCV::X5))); | 
|  | EXPECT_TRUE(Analysis->isCall(cjal())); | 
|  | EXPECT_TRUE(Analysis->isCall(cjalr(RISCV::X5))); | 
|  | } | 
|  |  | 
|  | TEST_P(InstrAnalysisTest, IsReturn) { | 
|  | EXPECT_FALSE(Analysis->isReturn(beq())); | 
|  | EXPECT_FALSE(Analysis->isReturn(cbeqz())); | 
|  | EXPECT_FALSE(Analysis->isReturn(jal(RISCV::X0))); | 
|  | EXPECT_TRUE(Analysis->isReturn(jalr(RISCV::X0, RISCV::X1))); | 
|  | EXPECT_FALSE(Analysis->isReturn(jalr(RISCV::X1, RISCV::X1))); | 
|  | EXPECT_TRUE(Analysis->isReturn(jalr(RISCV::X0, RISCV::X5))); | 
|  | EXPECT_FALSE(Analysis->isReturn(cj())); | 
|  | EXPECT_TRUE(Analysis->isReturn(cjr(RISCV::X1))); | 
|  | EXPECT_FALSE(Analysis->isReturn(cjr(RISCV::X2))); | 
|  | EXPECT_TRUE(Analysis->isReturn(cjr(RISCV::X5))); | 
|  | EXPECT_FALSE(Analysis->isReturn(cjal())); | 
|  | EXPECT_FALSE(Analysis->isReturn(cjalr(RISCV::X1))); | 
|  | EXPECT_FALSE(Analysis->isReturn(cjalr(RISCV::X5))); | 
|  | } | 
|  |  | 
|  | TEST_P(InstrAnalysisTest, IsBranch) { | 
|  | EXPECT_TRUE(Analysis->isBranch(beq())); | 
|  | EXPECT_TRUE(Analysis->isBranch(cbeqz())); | 
|  | EXPECT_TRUE(Analysis->isBranch(jal(RISCV::X0))); | 
|  | EXPECT_FALSE(Analysis->isBranch(jal(RISCV::X1))); | 
|  | EXPECT_FALSE(Analysis->isBranch(jal(RISCV::X5))); | 
|  | EXPECT_TRUE(Analysis->isBranch(jalr(RISCV::X0))); | 
|  | EXPECT_FALSE(Analysis->isBranch(jalr(RISCV::X1))); | 
|  | EXPECT_FALSE(Analysis->isBranch(jalr(RISCV::X5))); | 
|  | EXPECT_FALSE(Analysis->isBranch(jalr(RISCV::X0, RISCV::X1))); | 
|  | EXPECT_FALSE(Analysis->isBranch(jalr(RISCV::X0, RISCV::X5))); | 
|  | EXPECT_TRUE(Analysis->isBranch(cj())); | 
|  | EXPECT_TRUE(Analysis->isBranch(cjr(RISCV::X2))); | 
|  | EXPECT_FALSE(Analysis->isBranch(cjr(RISCV::X1))); | 
|  | EXPECT_FALSE(Analysis->isBranch(cjr(RISCV::X5))); | 
|  | EXPECT_FALSE(Analysis->isBranch(cjal())); | 
|  | EXPECT_FALSE(Analysis->isBranch(cjalr(RISCV::X6))); | 
|  | EXPECT_FALSE(Analysis->isBranch(cjalr(RISCV::X1))); | 
|  | EXPECT_FALSE(Analysis->isBranch(cjalr(RISCV::X5))); | 
|  | } | 
|  |  | 
|  | TEST_P(InstrAnalysisTest, IsUnconditionalBranch) { | 
|  | EXPECT_FALSE(Analysis->isUnconditionalBranch(beq())); | 
|  | EXPECT_FALSE(Analysis->isUnconditionalBranch(cbeqz())); | 
|  | EXPECT_TRUE(Analysis->isUnconditionalBranch(jal(RISCV::X0))); | 
|  | EXPECT_FALSE(Analysis->isUnconditionalBranch(jal(RISCV::X1))); | 
|  | EXPECT_FALSE(Analysis->isUnconditionalBranch(jal(RISCV::X5))); | 
|  | EXPECT_TRUE(Analysis->isUnconditionalBranch(jalr(RISCV::X0))); | 
|  | EXPECT_FALSE(Analysis->isUnconditionalBranch(jalr(RISCV::X1))); | 
|  | EXPECT_FALSE(Analysis->isUnconditionalBranch(jalr(RISCV::X5))); | 
|  | EXPECT_FALSE(Analysis->isUnconditionalBranch(jalr(RISCV::X0, RISCV::X1))); | 
|  | EXPECT_FALSE(Analysis->isUnconditionalBranch(jalr(RISCV::X0, RISCV::X5))); | 
|  | EXPECT_TRUE(Analysis->isUnconditionalBranch(cj())); | 
|  | EXPECT_TRUE(Analysis->isUnconditionalBranch(cjr(RISCV::X2))); | 
|  | EXPECT_FALSE(Analysis->isUnconditionalBranch(cjr(RISCV::X1))); | 
|  | EXPECT_FALSE(Analysis->isUnconditionalBranch(cjr(RISCV::X5))); | 
|  | EXPECT_FALSE(Analysis->isUnconditionalBranch(cjal())); | 
|  | EXPECT_FALSE(Analysis->isUnconditionalBranch(cjalr(RISCV::X6))); | 
|  | EXPECT_FALSE(Analysis->isUnconditionalBranch(cjalr(RISCV::X1))); | 
|  | EXPECT_FALSE(Analysis->isUnconditionalBranch(cjalr(RISCV::X5))); | 
|  | } | 
|  |  | 
|  | TEST_P(InstrAnalysisTest, IsIndirectBranch) { | 
|  | EXPECT_FALSE(Analysis->isIndirectBranch(beq())); | 
|  | EXPECT_FALSE(Analysis->isIndirectBranch(cbeqz())); | 
|  | EXPECT_FALSE(Analysis->isIndirectBranch(jal(RISCV::X0))); | 
|  | EXPECT_FALSE(Analysis->isIndirectBranch(jal(RISCV::X1))); | 
|  | EXPECT_TRUE(Analysis->isIndirectBranch(jalr(RISCV::X0))); | 
|  | EXPECT_FALSE(Analysis->isIndirectBranch(jalr(RISCV::X1))); | 
|  | EXPECT_FALSE(Analysis->isIndirectBranch(cj())); | 
|  | EXPECT_TRUE(Analysis->isIndirectBranch(cjr(RISCV::X10))); | 
|  | EXPECT_FALSE(Analysis->isIndirectBranch(cjr(RISCV::X1))); | 
|  | EXPECT_FALSE(Analysis->isIndirectBranch(cjr(RISCV::X5))); | 
|  | EXPECT_FALSE(Analysis->isIndirectBranch(cjal())); | 
|  | EXPECT_FALSE(Analysis->isIndirectBranch(cjalr(RISCV::X5))); | 
|  | } | 
|  |  | 
|  | INSTANTIATE_TEST_SUITE_P(RV32And64, InstrAnalysisTest, | 
|  | testing::Values("riscv32", "riscv64")); |