Index: tools/llvm-exegesis/lib/CMakeLists.txt =================================================================== --- tools/llvm-exegesis/lib/CMakeLists.txt +++ tools/llvm-exegesis/lib/CMakeLists.txt @@ -18,6 +18,7 @@ CodeGen Core ExecutionEngine + GlobalISel MC MCJIT Object Index: tools/llvm-exegesis/lib/InMemoryAssembler.cpp =================================================================== --- tools/llvm-exegesis/lib/InMemoryAssembler.cpp +++ tools/llvm-exegesis/lib/InMemoryAssembler.cpp @@ -10,6 +10,8 @@ #include "InMemoryAssembler.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" +#include "llvm/CodeGen/GlobalISel/CallLowering.h" +#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h" @@ -139,9 +141,15 @@ } } } - // Adding the Return Opcode. + // Insert the return code. const llvm::TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo(); - llvm::BuildMI(MBB, DL, TII->get(TII->getReturnOpcode())); + if (TII->getReturnOpcode() < TII->getNumOpcodes()) { + llvm::BuildMI(MBB, DL, TII->get(TII->getReturnOpcode())); + } else { + llvm::MachineIRBuilder MIB(MF); + MIB.setMBB(*MBB); + MF.getSubtarget().getCallLowering()->lowerReturn(MIB, nullptr, 0); + } } namespace { Index: unittests/tools/llvm-exegesis/ARM/CMakeLists.txt =================================================================== --- /dev/null +++ unittests/tools/llvm-exegesis/ARM/CMakeLists.txt @@ -0,0 +1,20 @@ +include_directories( + ${LLVM_MAIN_SRC_DIR}/lib/Target/ARM + ${LLVM_BINARY_DIR}/lib/Target/ARM + ${LLVM_MAIN_SRC_DIR}/tools/llvm-exegesis/lib + ) + +set(LLVM_LINK_COMPONENTS + MC + MCParser + Object + Support + Symbolize + ARM + ) + +add_llvm_unittest(LLVMExegesisARMTests + InMemoryAssemblerTest.cpp + ) +target_link_libraries(LLVMExegesisARMTests PRIVATE LLVMExegesis) + Index: unittests/tools/llvm-exegesis/ARM/InMemoryAssemblerTest.cpp =================================================================== --- /dev/null +++ unittests/tools/llvm-exegesis/ARM/InMemoryAssemblerTest.cpp @@ -0,0 +1,79 @@ +//===-- InMemoryAssemblerTest.cpp -------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "InMemoryAssembler.h" +#include "ARMInstrInfo.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" +#include + +namespace exegesis { +namespace { + +using llvm::MCInstBuilder; +using testing::ElementsAre; + +class MachineFunctionGeneratorTest : public ::testing::Test { +protected: + MachineFunctionGeneratorTest() + : TT("armv7-none-linux-gnueabi"), CpuName("") {} + + static void SetUpTestCase() { + LLVMInitializeARMTargetInfo(); + LLVMInitializeARMTargetMC(); + LLVMInitializeARMTarget(); + LLVMInitializeARMAsmPrinter(); + } + + std::unique_ptr createTargetMachine() { + std::string Error; + const llvm::Target *TheTarget = + llvm::TargetRegistry::lookupTarget(TT, Error); + assert(TheTarget); + const llvm::TargetOptions Options; + return std::unique_ptr( + static_cast(TheTarget->createTargetMachine( + TT, CpuName, "", Options, llvm::Reloc::Model::Static))); + } + +private: + const std::string TT; + const std::string CpuName; +}; + +TEST_F(MachineFunctionGeneratorTest, JitFunction) { + JitFunctionContext Context(createTargetMachine()); + JitFunction Function(std::move(Context), {}); + ASSERT_THAT(Function.getFunctionBytes().str(), + ElementsAre(0x1e, 0xff, 0x2f, 0xe1)); +} + +TEST_F(MachineFunctionGeneratorTest, JitFunctionADDrr) { + JitFunctionContext Context(createTargetMachine()); + JitFunction Function(std::move(Context), {MCInstBuilder(llvm::ARM::ADDrr) + .addReg(llvm::ARM::R0) + .addReg(llvm::ARM::R0) + .addReg(llvm::ARM::R0) + .addImm(llvm::ARMCC::AL) + .addReg(0) + .addReg(0)}); + ASSERT_THAT(Function.getFunctionBytes().str(), + ElementsAre(0x00, 0x00, 0x80, 0xe0, 0x1e, 0xff, 0x2f, 0xe1)); +} + +} // namespace +} // namespace exegesis Index: unittests/tools/llvm-exegesis/CMakeLists.txt =================================================================== --- unittests/tools/llvm-exegesis/CMakeLists.txt +++ unittests/tools/llvm-exegesis/CMakeLists.txt @@ -22,7 +22,8 @@ endif() if(LLVM_TARGETS_TO_BUILD MATCHES "X86") - add_subdirectory( - X86 - ) + add_subdirectory(X86) +endif() +if(LLVM_TARGETS_TO_BUILD MATCHES "ARM") + add_subdirectory(ARM) endif()