96 lines
3.4 KiB
C++
96 lines
3.4 KiB
C++
//===-- AssemblerUtils.h ----------------------------------------*- C++ -*-===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_UNITTESTS_TOOLS_LLVMEXEGESIS_ASSEMBLERUTILS_H
|
|
#define LLVM_UNITTESTS_TOOLS_LLVMEXEGESIS_ASSEMBLERUTILS_H
|
|
|
|
#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 llvm {
|
|
namespace exegesis {
|
|
|
|
class MachineFunctionGeneratorBaseTest : public ::testing::Test {
|
|
protected:
|
|
MachineFunctionGeneratorBaseTest(const std::string &TT,
|
|
const std::string &CpuName)
|
|
: TT(TT), CpuName(CpuName),
|
|
CanExecute(Triple(TT).getArch() ==
|
|
Triple(sys::getProcessTriple()).getArch()),
|
|
ET(ExegesisTarget::lookup(Triple(TT))) {
|
|
assert(ET);
|
|
if (!CanExecute) {
|
|
outs() << "Skipping execution, host:" << sys::getProcessTriple()
|
|
<< ", target:" << TT << "\n";
|
|
}
|
|
}
|
|
|
|
template <class... Bs>
|
|
inline void Check(ArrayRef<RegisterValue> RegisterInitialValues, MCInst Inst,
|
|
Bs... Bytes) {
|
|
ExecutableFunction Function =
|
|
(Inst.getOpcode() == 0)
|
|
? assembleToFunction(RegisterInitialValues, [](FunctionFiller &) {})
|
|
: assembleToFunction(RegisterInitialValues,
|
|
[Inst](FunctionFiller &Filler) {
|
|
Filler.getEntry().addInstruction(Inst);
|
|
});
|
|
ASSERT_THAT(Function.getFunctionBytes().str(),
|
|
testing::ElementsAre(Bytes...));
|
|
if (CanExecute) {
|
|
BenchmarkRunner::ScratchSpace Scratch;
|
|
Function(Scratch.ptr());
|
|
}
|
|
}
|
|
|
|
private:
|
|
std::unique_ptr<LLVMTargetMachine> createTargetMachine() {
|
|
std::string Error;
|
|
const Target *TheTarget = TargetRegistry::lookupTarget(TT, Error);
|
|
EXPECT_TRUE(TheTarget) << Error << " " << TT;
|
|
const TargetOptions Options;
|
|
TargetMachine *TM = TheTarget->createTargetMachine(TT, CpuName, "", Options,
|
|
Reloc::Model::Static);
|
|
EXPECT_TRUE(TM) << TT << " " << CpuName;
|
|
return std::unique_ptr<LLVMTargetMachine>(
|
|
static_cast<LLVMTargetMachine *>(TM));
|
|
}
|
|
|
|
ExecutableFunction
|
|
assembleToFunction(ArrayRef<RegisterValue> RegisterInitialValues,
|
|
FillFunction Fill) {
|
|
SmallString<256> Buffer;
|
|
raw_svector_ostream AsmStream(Buffer);
|
|
EXPECT_FALSE(assembleToStream(*ET, createTargetMachine(), /*LiveIns=*/{},
|
|
RegisterInitialValues, Fill, AsmStream));
|
|
return ExecutableFunction(createTargetMachine(),
|
|
getObjectFromBuffer(AsmStream.str()));
|
|
}
|
|
|
|
const std::string TT;
|
|
const std::string CpuName;
|
|
const bool CanExecute;
|
|
const ExegesisTarget *const ET;
|
|
};
|
|
|
|
} // namespace exegesis
|
|
} // namespace llvm
|
|
|
|
#endif
|