//===-- 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 "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 <class... Bs> inline void Check(llvm::MCInst MCInst, Bs... Bytes) {
    CheckWithSetup(ExegesisTarget::getDefault(), {}, MCInst, Bytes...);
  }

  template <class... Bs>
  inline void CheckWithSetup(const ExegesisTarget &ET,
                             llvm::ArrayRef<unsigned> 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)
      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(const ExegesisTarget &ET,
                     llvm::ArrayRef<unsigned> RegsToDef,
                     llvm::ArrayRef<llvm::MCInst> Instructions) {
    llvm::SmallString<256> Buffer;
    llvm::raw_svector_ostream AsmStream(Buffer);
    assembleToStream(ET, createTargetMachine(), RegsToDef, Instructions,
                     AsmStream);
    return ExecutableFunction(createTargetMachine(),
                              getObjectFromBuffer(AsmStream.str()));
  }

  const std::string TT;
  const std::string CpuName;
  const bool CanExecute;
};

} // namespace exegesis
