From 2c769209a103dde2a6eed9b2326f826590bbb299 Mon Sep 17 00:00:00 2001 From: Colin LeMahieu Date: Thu, 6 Nov 2014 17:05:51 +0000 Subject: [PATCH] [Hexagon] Adding basic Hexagon ELF object emitter. llvm-svn: 221465 --- .../lib/Target/Hexagon/MCTargetDesc/CMakeLists.txt | 4 +- .../Hexagon/MCTargetDesc/HexagonAsmBackend.cpp | 74 ++++++++++++++++++++++ .../MCTargetDesc/HexagonELFObjectWriter.cpp | 62 ++++++++++++++++++ .../Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp | 27 ++++++++ .../Hexagon/MCTargetDesc/HexagonMCTargetDesc.h | 19 +++++- llvm/test/MC/Hexagon/basic.ll | 7 ++ llvm/test/MC/Hexagon/lit.local.cfg | 3 + 7 files changed, 192 insertions(+), 4 deletions(-) create mode 100644 llvm/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp create mode 100644 llvm/lib/Target/Hexagon/MCTargetDesc/HexagonELFObjectWriter.cpp create mode 100644 llvm/test/MC/Hexagon/basic.ll create mode 100644 llvm/test/MC/Hexagon/lit.local.cfg diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/CMakeLists.txt b/llvm/lib/Target/Hexagon/MCTargetDesc/CMakeLists.txt index 2b7cc85..d198208 100644 --- a/llvm/lib/Target/Hexagon/MCTargetDesc/CMakeLists.txt +++ b/llvm/lib/Target/Hexagon/MCTargetDesc/CMakeLists.txt @@ -1,8 +1,10 @@ add_llvm_library(LLVMHexagonDesc + HexagonAsmBackend.cpp + HexagonELFObjectWriter.cpp HexagonMCAsmInfo.cpp HexagonMCCodeEmitter.cpp HexagonMCInst.cpp HexagonMCTargetDesc.cpp ) -add_dependencies(LLVMHexagonDesc HexagonCommonTableGen) \ No newline at end of file +add_dependencies(LLVMHexagonDesc HexagonCommonTableGen) diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp new file mode 100644 index 0000000..bdccf88 --- /dev/null +++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp @@ -0,0 +1,74 @@ +//===-- HexagonAsmBackend.cpp - Hexagon Assembler Backend -----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "HexagonMCTargetDesc.h" +#include "llvm/MC/MCAsmBackend.h" +#include "llvm/MC/MCELFObjectWriter.h" + +using namespace llvm; + +namespace { + +class HexagonAsmBackend : public MCAsmBackend { +public: + HexagonAsmBackend(Target const & /*T*/) {} + + unsigned getNumFixupKinds() const override { return 0; } + + void applyFixup(MCFixup const & /*Fixup*/, char * /*Data*/, + unsigned /*DataSize*/, uint64_t /*Value*/, + bool /*IsPCRel*/) const override { + return; + } + + bool mayNeedRelaxation(MCInst const & /*Inst*/) const override { + return false; + } + + bool fixupNeedsRelaxation(MCFixup const & /*Fixup*/, uint64_t /*Value*/, + MCRelaxableFragment const * /*DF*/, + MCAsmLayout const & /*Layout*/) const override { + llvm_unreachable("fixupNeedsRelaxation() unimplemented"); + } + + void relaxInstruction(MCInst const & /*Inst*/, + MCInst & /*Res*/) const override { + llvm_unreachable("relaxInstruction() unimplemented"); + } + + bool writeNopData(uint64_t /*Count*/, + MCObjectWriter * /*OW*/) const override { + return true; + } +}; +} // end anonymous namespace + +namespace { +class ELFHexagonAsmBackend : public HexagonAsmBackend { + uint8_t OSABI; + +public: + ELFHexagonAsmBackend(Target const &T, uint8_t OSABI) + : HexagonAsmBackend(T), OSABI(OSABI) {} + + MCObjectWriter *createObjectWriter(raw_ostream &OS) const override { + StringRef CPU("HexagonV4"); + return createHexagonELFObjectWriter(OS, OSABI, CPU); + } +}; +} // end anonymous namespace + +namespace llvm { +MCAsmBackend *createHexagonAsmBackend(Target const &T, + MCRegisterInfo const & /*MRI*/, + StringRef TT, StringRef /*CPU*/) { + uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(Triple(TT).getOS()); + return new ELFHexagonAsmBackend(T, OSABI); +} +} diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonELFObjectWriter.cpp b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonELFObjectWriter.cpp new file mode 100644 index 0000000..4966fa9 --- /dev/null +++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonELFObjectWriter.cpp @@ -0,0 +1,62 @@ +//===-- HexagonELFObjectWriter.cpp - Hexagon Target Descriptions ----------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "Hexagon.h" +#include "llvm/MC/MCAssembler.h" +#include "llvm/MC/MCELFObjectWriter.h" +#include "llvm/Support/Debug.h" + +#define DEBUG_TYPE "hexagon-elf-writer" + +using namespace llvm; +using namespace Hexagon; + +namespace { + +class HexagonELFObjectWriter : public MCELFObjectTargetWriter { +private: + StringRef _CPU; + +public: + HexagonELFObjectWriter(uint8_t OSABI, StringRef CPU); + + virtual unsigned GetRelocType(MCValue const &Target, MCFixup const &Fixup, + bool IsPCRel) const override; +}; +} + +HexagonELFObjectWriter::HexagonELFObjectWriter(uint8_t OSABI, StringRef CPU) + : MCELFObjectTargetWriter(/*Is64bit*/ false, OSABI, ELF::EM_HEXAGON, + /*HasRelocationAddend*/ true), + _CPU(CPU) {} + +unsigned HexagonELFObjectWriter::GetRelocType(MCValue const &/*Target*/, + MCFixup const &Fixup, + bool IsPCRel) const { + unsigned Type = (unsigned)ELF::R_HEX_NONE; + llvm::MCFixupKind Kind = Fixup.getKind(); + + switch (Kind) { + default: + DEBUG(dbgs() << "unrecognized relocation " << Fixup.getKind() << "\n"); + llvm_unreachable("Unimplemented Fixup kind!"); + break; + case FK_Data_4: + Type = (IsPCRel) ? ELF::R_HEX_32_PCREL : ELF::R_HEX_32; + break; + } + return Type; +} + +MCObjectWriter *llvm::createHexagonELFObjectWriter(raw_ostream &OS, + uint8_t OSABI, + StringRef CPU) { + MCELFObjectTargetWriter *MOTW = new HexagonELFObjectWriter(OSABI, CPU); + return createELFObjectWriter(MOTW, OS, /*IsLittleEndian*/ true); +} \ No newline at end of file diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp index 65cf42a..09dd80d 100644 --- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp +++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp @@ -15,6 +15,7 @@ #include "HexagonMCAsmInfo.h" #include "InstPrinter/HexagonInstPrinter.h" #include "llvm/MC/MCCodeGenInfo.h" +#include "llvm/MC/MCELFStreamer.h" #include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCStreamer.h" @@ -46,6 +47,15 @@ static MCRegisterInfo *createHexagonMCRegisterInfo(StringRef TT) { return X; } +static MCStreamer * +createHexagonELFStreamer(MCContext &Context, MCAsmBackend &MAB, + raw_ostream &OS, MCCodeEmitter *CE, + bool RelaxAll) { + MCELFStreamer *ES = new MCELFStreamer(Context, MAB, OS, CE); + return ES; +} + + static MCSubtargetInfo * createHexagonMCSubtargetInfo(StringRef TT, StringRef CPU, StringRef FS) { MCSubtargetInfo *X = new MCSubtargetInfo(); @@ -65,6 +75,16 @@ static MCAsmInfo *createHexagonMCAsmInfo(const MCRegisterInfo &MRI, return MAI; } +static MCStreamer *createMCStreamer(Target const &T, StringRef TT, + MCContext &Context, MCAsmBackend &MAB, + raw_ostream &OS, MCCodeEmitter *Emitter, + MCSubtargetInfo const &STI, bool RelaxAll) { + MCStreamer *ES = createHexagonELFStreamer(Context, MAB, OS, Emitter, RelaxAll); + new MCTargetStreamer(*ES); + return ES; +} + + static MCCodeGenInfo *createHexagonMCCodeGenInfo(StringRef TT, Reloc::Model RM, CodeModel::Model CM, CodeGenOpt::Level OL) { @@ -111,4 +131,11 @@ extern "C" void LLVMInitializeHexagonTargetMC() { // Register the MC Inst Printer TargetRegistry::RegisterMCInstPrinter(TheHexagonTarget, createHexagonMCInstPrinter); + + // Register the asm backend + TargetRegistry::RegisterMCAsmBackend(TheHexagonTarget, + createHexagonAsmBackend); + + // Register the obj streamer + TargetRegistry::RegisterMCObjectStreamer(TheHexagonTarget, createMCStreamer); } diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.h b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.h index 4ce429c..02fd516 100644 --- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.h +++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.h @@ -14,21 +14,34 @@ #ifndef LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONMCTARGETDESC_H #define LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONMCTARGETDESC_H +#include + namespace llvm { +class MCAsmBackend; class MCCodeEmitter; class MCContext; class MCInstrInfo; +class MCObjectWriter; class MCRegisterInfo; class MCSubtargetInfo; class Target; +class StringRef; +class raw_ostream; extern Target TheHexagonTarget; -MCCodeEmitter *createHexagonMCCodeEmitter(const MCInstrInfo &MCII, - const MCRegisterInfo &MRI, - const MCSubtargetInfo &MST, +MCCodeEmitter *createHexagonMCCodeEmitter(MCInstrInfo const &MCII, + MCRegisterInfo const &MRI, + MCSubtargetInfo const &MST, MCContext &MCT); +MCAsmBackend *createHexagonAsmBackend(Target const &T, + MCRegisterInfo const &MRI, StringRef TT, + StringRef CPU); + +MCObjectWriter *createHexagonELFObjectWriter(raw_ostream &OS, uint8_t OSABI, + StringRef CPU); + } // End llvm namespace // Define symbolic names for Hexagon registers. This defines a mapping from diff --git a/llvm/test/MC/Hexagon/basic.ll b/llvm/test/MC/Hexagon/basic.ll new file mode 100644 index 0000000..8a5d2e6 --- /dev/null +++ b/llvm/test/MC/Hexagon/basic.ll @@ -0,0 +1,7 @@ +;; RUN: llc -mtriple=hexagon-unknown-elf -filetype=obj %s -o - \ +;; RUN: | llvm-readobj -h -r | FileCheck -check-prefix=OBJ %s + +; OBJ: Format: ELF32-hexagon +; OBJ: Arch: hexagon +; OBJ: AddressSize: 32bit +; OBJ: Machine: EM_HEXAGON diff --git a/llvm/test/MC/Hexagon/lit.local.cfg b/llvm/test/MC/Hexagon/lit.local.cfg new file mode 100644 index 0000000..ba72ff6 --- /dev/null +++ b/llvm/test/MC/Hexagon/lit.local.cfg @@ -0,0 +1,3 @@ +if not 'Hexagon' in config.root.targets: + config.unsupported = True + -- 2.7.4