xref: /llvm-project/llvm/unittests/tools/llvm-exegesis/Common/AssemblerUtils.h (revision 0e69e2d74739a119a78d131c29b92c25787ec2f3)
1 //===-- AssemblerUtils.h ----------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "Assembler.h"
11 #include "llvm/ADT/ArrayRef.h"
12 #include "llvm/CodeGen/MachineInstrBuilder.h"
13 #include "llvm/CodeGen/TargetInstrInfo.h"
14 #include "llvm/CodeGen/TargetSubtargetInfo.h"
15 #include "llvm/MC/MCInstBuilder.h"
16 #include "llvm/Support/Host.h"
17 #include "llvm/Support/TargetRegistry.h"
18 #include "llvm/Support/TargetSelect.h"
19 #include "gmock/gmock.h"
20 #include "gtest/gtest.h"
21 
22 namespace exegesis {
23 
24 class MachineFunctionGeneratorBaseTest : public ::testing::Test {
25 protected:
26   MachineFunctionGeneratorBaseTest(const std::string &TT,
27                                    const std::string &CpuName)
28       : TT(TT), CpuName(CpuName),
29         CanExecute(llvm::Triple(TT).getArch() ==
30                    llvm::Triple(llvm::sys::getProcessTriple()).getArch()) {
31     if (!CanExecute) {
32       llvm::outs() << "Skipping execution, host:"
33                    << llvm::sys::getProcessTriple() << ", target:" << TT
34                    << "\n";
35     }
36   }
37 
38   void RunIfSupported(const ExecutableFunction &Function) const {
39     if (CanExecute)
40       Function();
41   }
42 
43   template <class... Bs> inline void Check(llvm::MCInst MCInst, Bs... Bytes) {
44     ExecutableFunction Function = (MCInst.getOpcode() == 0)
45                                       ? assembleToFunction({})
46                                       : assembleToFunction({MCInst});
47     ASSERT_THAT(Function.getFunctionBytes().str(),
48                 testing::ElementsAre(Bytes...));
49     if (CanExecute)
50       Function();
51   }
52 
53 private:
54   std::unique_ptr<llvm::LLVMTargetMachine> createTargetMachine() {
55     std::string Error;
56     const llvm::Target *TheTarget =
57         llvm::TargetRegistry::lookupTarget(TT, Error);
58     EXPECT_TRUE(TheTarget) << Error << " " << TT;
59     const llvm::TargetOptions Options;
60     llvm::TargetMachine *TM = TheTarget->createTargetMachine(
61         TT, CpuName, "", Options, llvm::Reloc::Model::Static);
62     EXPECT_TRUE(TM) << TT << " " << CpuName;
63     return std::unique_ptr<llvm::LLVMTargetMachine>(
64         static_cast<llvm::LLVMTargetMachine *>(TM));
65   }
66 
67   ExecutableFunction
68   assembleToFunction(llvm::ArrayRef<llvm::MCInst> Instructions) {
69     llvm::SmallString<256> Buffer;
70     llvm::raw_svector_ostream AsmStream(Buffer);
71     assembleToStream(createTargetMachine(), Instructions, AsmStream);
72     return ExecutableFunction(createTargetMachine(),
73                               getObjectFromBuffer(AsmStream.str()));
74   }
75 
76   const std::string TT;
77   const std::string CpuName;
78   const bool CanExecute;
79 };
80 
81 } // namespace exegesis
82