//===-- AssemblerUtils.h ----------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #include "Assembler.h" #include "BenchmarkRunner.h" #include "Target.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/TargetInstrInfo.h" #include "llvm/CodeGen/TargetSubtargetInfo.h" #include "llvm/MC/MCInstBuilder.h" #include "llvm/Support/Host.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/TargetSelect.h" #include "gmock/gmock.h" #include "gtest/gtest.h" namespace exegesis { class MachineFunctionGeneratorBaseTest : public ::testing::Test { protected: MachineFunctionGeneratorBaseTest(const std::string &TT, const std::string &CpuName) : TT(TT), CpuName(CpuName), CanExecute(llvm::Triple(TT).getArch() == llvm::Triple(llvm::sys::getProcessTriple()).getArch()) { if (!CanExecute) { llvm::outs() << "Skipping execution, host:" << llvm::sys::getProcessTriple() << ", target:" << TT << "\n"; } } template inline void Check(const ExegesisTarget &ET, llvm::ArrayRef RegsToDef, llvm::MCInst MCInst, Bs... Bytes) { ExecutableFunction Function = (MCInst.getOpcode() == 0) ? assembleToFunction(ET, RegsToDef, {}) : assembleToFunction(ET, RegsToDef, {MCInst}); ASSERT_THAT(Function.getFunctionBytes().str(), testing::ElementsAre(Bytes...)); if (CanExecute) { BenchmarkRunner::ScratchSpace Scratch; Function(Scratch.ptr()); } } private: std::unique_ptr createTargetMachine() { std::string Error; const llvm::Target *TheTarget = llvm::TargetRegistry::lookupTarget(TT, Error); EXPECT_TRUE(TheTarget) << Error << " " << TT; const llvm::TargetOptions Options; llvm::TargetMachine *TM = TheTarget->createTargetMachine( TT, CpuName, "", Options, llvm::Reloc::Model::Static); EXPECT_TRUE(TM) << TT << " " << CpuName; return std::unique_ptr( static_cast(TM)); } ExecutableFunction assembleToFunction(const ExegesisTarget &ET, llvm::ArrayRef RegsToDef, llvm::ArrayRef Instructions) { llvm::SmallString<256> Buffer; llvm::raw_svector_ostream AsmStream(Buffer); assembleToStream(ET, createTargetMachine(), /*LiveIns=*/{}, RegsToDef, Instructions, AsmStream); return ExecutableFunction(createTargetMachine(), getObjectFromBuffer(AsmStream.str())); } const std::string TT; const std::string CpuName; const bool CanExecute; }; } // namespace exegesis