summaryrefslogtreecommitdiffstats
path: root/llvm/unittests/tools/llvm-exegesis/Common/AssemblerUtils.h
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/unittests/tools/llvm-exegesis/Common/AssemblerUtils.h')
-rw-r--r--llvm/unittests/tools/llvm-exegesis/Common/AssemblerUtils.h81
1 files changed, 81 insertions, 0 deletions
diff --git a/llvm/unittests/tools/llvm-exegesis/Common/AssemblerUtils.h b/llvm/unittests/tools/llvm-exegesis/Common/AssemblerUtils.h
new file mode 100644
index 00000000000..78b0c2506fa
--- /dev/null
+++ b/llvm/unittests/tools/llvm-exegesis/Common/AssemblerUtils.h
@@ -0,0 +1,81 @@
+//===-- 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 "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";
+ }
+ }
+
+ void RunIfSupported(const ExecutableFunction &Function) const {
+ if (CanExecute)
+ Function();
+ }
+
+ template <class... Bs> inline void Check(llvm::MCInst MCInst, Bs... Bytes) {
+ ExecutableFunction Function = (MCInst.getOpcode() == 0)
+ ? assembleToFunction({})
+ : assembleToFunction({MCInst});
+ ASSERT_THAT(Function.getFunctionBytes().str(),
+ testing::ElementsAre(Bytes...));
+ if (CanExecute)
+ Function();
+ }
+
+private:
+ std::unique_ptr<llvm::LLVMTargetMachine> 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<llvm::LLVMTargetMachine>(
+ static_cast<llvm::LLVMTargetMachine *>(TM));
+ }
+
+ ExecutableFunction
+ assembleToFunction(llvm::ArrayRef<llvm::MCInst> Instructions) {
+ llvm::SmallString<256> Buffer;
+ llvm::raw_svector_ostream AsmStream(Buffer);
+ assembleToStream(createTargetMachine(), Instructions, AsmStream);
+ return ExecutableFunction(createTargetMachine(),
+ getObjectFromBuffer(AsmStream.str()));
+ }
+
+ const std::string TT;
+ const std::string CpuName;
+ const bool CanExecute;
+};
+
+} // namespace exegesis
OpenPOWER on IntegriCloud