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