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 #ifndef LLVM_UNITTESTS_TOOLS_LLVMEXEGESIS_ASSEMBLERUTILS_H 11 #define LLVM_UNITTESTS_TOOLS_LLVMEXEGESIS_ASSEMBLERUTILS_H 12 13 #include "Assembler.h" 14 #include "BenchmarkRunner.h" 15 #include "Target.h" 16 #include "llvm/ADT/ArrayRef.h" 17 #include "llvm/CodeGen/MachineInstrBuilder.h" 18 #include "llvm/CodeGen/TargetInstrInfo.h" 19 #include "llvm/CodeGen/TargetSubtargetInfo.h" 20 #include "llvm/MC/MCInstBuilder.h" 21 #include "llvm/Support/Host.h" 22 #include "llvm/Support/TargetRegistry.h" 23 #include "llvm/Support/TargetSelect.h" 24 #include "gmock/gmock.h" 25 #include "gtest/gtest.h" 26 27 namespace exegesis { 28 29 class MachineFunctionGeneratorBaseTest : public ::testing::Test { 30 protected: 31 MachineFunctionGeneratorBaseTest(const std::string &TT, 32 const std::string &CpuName) 33 : TT(TT), CpuName(CpuName), 34 CanExecute(llvm::Triple(TT).getArch() == 35 llvm::Triple(llvm::sys::getProcessTriple()).getArch()) { 36 if (!CanExecute) { 37 llvm::outs() << "Skipping execution, host:" 38 << llvm::sys::getProcessTriple() << ", target:" << TT 39 << "\n"; 40 } 41 } 42 43 template <class... Bs> 44 inline void Check(const ExegesisTarget &ET, 45 llvm::ArrayRef<unsigned> RegsToDef, llvm::MCInst MCInst, 46 Bs... Bytes) { 47 ExecutableFunction Function = 48 (MCInst.getOpcode() == 0) ? assembleToFunction(ET, RegsToDef, {}) 49 : assembleToFunction(ET, RegsToDef, {MCInst}); 50 ASSERT_THAT(Function.getFunctionBytes().str(), 51 testing::ElementsAre(Bytes...)); 52 if (CanExecute) { 53 BenchmarkRunner::ScratchSpace Scratch; 54 Function(Scratch.ptr()); 55 } 56 } 57 58 private: 59 std::unique_ptr<llvm::LLVMTargetMachine> createTargetMachine() { 60 std::string Error; 61 const llvm::Target *TheTarget = 62 llvm::TargetRegistry::lookupTarget(TT, Error); 63 EXPECT_TRUE(TheTarget) << Error << " " << TT; 64 const llvm::TargetOptions Options; 65 llvm::TargetMachine *TM = TheTarget->createTargetMachine( 66 TT, CpuName, "", Options, llvm::Reloc::Model::Static); 67 EXPECT_TRUE(TM) << TT << " " << CpuName; 68 return std::unique_ptr<llvm::LLVMTargetMachine>( 69 static_cast<llvm::LLVMTargetMachine *>(TM)); 70 } 71 72 ExecutableFunction 73 assembleToFunction(const ExegesisTarget &ET, 74 llvm::ArrayRef<unsigned> RegsToDef, 75 llvm::ArrayRef<llvm::MCInst> Instructions) { 76 llvm::SmallString<256> Buffer; 77 llvm::raw_svector_ostream AsmStream(Buffer); 78 assembleToStream(ET, createTargetMachine(), /*LiveIns=*/{}, 79 RegsToDef, Instructions, 80 AsmStream); 81 return ExecutableFunction(createTargetMachine(), 82 getObjectFromBuffer(AsmStream.str())); 83 } 84 85 const std::string TT; 86 const std::string CpuName; 87 const bool CanExecute; 88 }; 89 90 } // namespace exegesis 91 92 #endif 93