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