diff options
Diffstat (limited to 'lib/Target/Lanai/MCTargetDesc')
-rw-r--r-- | lib/Target/Lanai/MCTargetDesc/CMakeLists.txt | 8 | ||||
-rw-r--r-- | lib/Target/Lanai/MCTargetDesc/LLVMBuild.txt | 23 | ||||
-rw-r--r-- | lib/Target/Lanai/MCTargetDesc/LanaiAsmBackend.cpp | 168 | ||||
-rw-r--r-- | lib/Target/Lanai/MCTargetDesc/LanaiBaseInfo.h | 145 | ||||
-rw-r--r-- | lib/Target/Lanai/MCTargetDesc/LanaiELFObjectWriter.cpp | 95 | ||||
-rw-r--r-- | lib/Target/Lanai/MCTargetDesc/LanaiFixupKinds.h | 43 | ||||
-rw-r--r-- | lib/Target/Lanai/MCTargetDesc/LanaiMCAsmInfo.cpp | 43 | ||||
-rw-r--r-- | lib/Target/Lanai/MCTargetDesc/LanaiMCAsmInfo.h | 32 | ||||
-rw-r--r-- | lib/Target/Lanai/MCTargetDesc/LanaiMCCodeEmitter.cpp | 325 | ||||
-rw-r--r-- | lib/Target/Lanai/MCTargetDesc/LanaiMCExpr.cpp | 60 | ||||
-rw-r--r-- | lib/Target/Lanai/MCTargetDesc/LanaiMCExpr.h | 56 | ||||
-rw-r--r-- | lib/Target/Lanai/MCTargetDesc/LanaiMCTargetDesc.cpp | 163 | ||||
-rw-r--r-- | lib/Target/Lanai/MCTargetDesc/LanaiMCTargetDesc.h | 59 |
13 files changed, 1220 insertions, 0 deletions
diff --git a/lib/Target/Lanai/MCTargetDesc/CMakeLists.txt b/lib/Target/Lanai/MCTargetDesc/CMakeLists.txt new file mode 100644 index 00000000000..d65a1fd5890 --- /dev/null +++ b/lib/Target/Lanai/MCTargetDesc/CMakeLists.txt @@ -0,0 +1,8 @@ +add_llvm_library(LLVMLanaiMCTargetDesc + LanaiAsmBackend.cpp + LanaiELFObjectWriter.cpp + LanaiMCAsmInfo.cpp + LanaiMCCodeEmitter.cpp + LanaiMCExpr.cpp + LanaiMCTargetDesc.cpp +) diff --git a/lib/Target/Lanai/MCTargetDesc/LLVMBuild.txt b/lib/Target/Lanai/MCTargetDesc/LLVMBuild.txt new file mode 100644 index 00000000000..7dc2a7694ab --- /dev/null +++ b/lib/Target/Lanai/MCTargetDesc/LLVMBuild.txt @@ -0,0 +1,23 @@ +;===-- ./lib/Target/Lanai/MCTargetDesc/LLVMBuild.txt -----------*- Conf -*--===; +; +; The LLVM Compiler Infrastructure +; +; This file is distributed under the University of Illinois Open Source +; License. See LICENSE.TXT for details. +; +;===------------------------------------------------------------------------===; +; +; This is an LLVMBuild description file for the components in this subdirectory. +; +; For more information on the LLVMBuild system, please see: +; +; http://llvm.org/docs/LLVMBuild.html +; +;===------------------------------------------------------------------------===; + +[component_0] +type = Library +name = LanaiMCTargetDesc +parent = Lanai +required_libraries = LanaiInfo LanaiInstPrinter MC Support +add_to_library_groups = Lanai diff --git a/lib/Target/Lanai/MCTargetDesc/LanaiAsmBackend.cpp b/lib/Target/Lanai/MCTargetDesc/LanaiAsmBackend.cpp new file mode 100644 index 00000000000..d3a075cef16 --- /dev/null +++ b/lib/Target/Lanai/MCTargetDesc/LanaiAsmBackend.cpp @@ -0,0 +1,168 @@ +//===-- LanaiAsmBackend.cpp - Lanai Assembler Backend ---------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "LanaiFixupKinds.h" +#include "MCTargetDesc/LanaiMCTargetDesc.h" +#include "llvm/MC/MCAsmBackend.h" +#include "llvm/MC/MCAssembler.h" +#include "llvm/MC/MCDirectives.h" +#include "llvm/MC/MCELFObjectWriter.h" +#include "llvm/MC/MCFixupKindInfo.h" +#include "llvm/MC/MCObjectWriter.h" +#include "llvm/MC/MCSubtargetInfo.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" + +using namespace llvm; + +// Prepare value for the target space +static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) { + switch (Kind) { + case FK_Data_1: + case FK_Data_2: + case FK_Data_4: + case FK_Data_8: + return Value; + case Lanai::FIXUP_LANAI_21: + case Lanai::FIXUP_LANAI_21_F: + case Lanai::FIXUP_LANAI_25: + case Lanai::FIXUP_LANAI_32: + case Lanai::FIXUP_LANAI_HI16: + case Lanai::FIXUP_LANAI_LO16: + return Value; + default: + llvm_unreachable("Unknown fixup kind!"); + } +} + +namespace { +class LanaiAsmBackend : public MCAsmBackend { + Triple::OSType OSType; + +public: + LanaiAsmBackend(const Target &T, Triple::OSType OST) + : MCAsmBackend(), OSType(OST) {} + + void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize, + uint64_t Value, bool IsPCRel) const override; + + MCObjectWriter *createObjectWriter(raw_pwrite_stream &OS) const override; + + // No instruction requires relaxation + bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, + const MCRelaxableFragment *DF, + const MCAsmLayout &Layout) const override { + return false; + } + + const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override; + + unsigned getNumFixupKinds() const override { + return Lanai::NumTargetFixupKinds; + } + + bool mayNeedRelaxation(const MCInst &Inst) const override { return false; } + + void relaxInstruction(const MCInst &Inst, MCInst &Res) const override {} + + bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override; +}; + +bool LanaiAsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const { + if ((Count % 4) != 0) + return false; + + for (uint64_t i = 0; i < Count; i += 4) + OW->write32(0x15000000); + + return true; +} + +void LanaiAsmBackend::applyFixup(const MCFixup &Fixup, char *Data, + unsigned DataSize, uint64_t Value, + bool IsPCRel) const { + MCFixupKind Kind = Fixup.getKind(); + Value = adjustFixupValue(static_cast<unsigned>(Kind), Value); + + if (!Value) + return; // This value doesn't change the encoding + + // Where in the object and where the number of bytes that need + // fixing up + unsigned Offset = Fixup.getOffset(); + unsigned NumBytes = (getFixupKindInfo(Kind).TargetSize + 7) / 8; + unsigned FullSize = 4; + + // Grab current value, if any, from bits. + uint64_t CurVal = 0; + + // Load instruction and apply value + for (unsigned i = 0; i != NumBytes; ++i) { + unsigned Idx = (FullSize - 1 - i); + CurVal |= static_cast<uint64_t>(static_cast<uint8_t>(Data[Offset + Idx])) + << (i * 8); + } + + uint64_t Mask = + (static_cast<uint64_t>(-1) >> (64 - getFixupKindInfo(Kind).TargetSize)); + CurVal |= Value & Mask; + + // Write out the fixed up bytes back to the code/data bits. + for (unsigned i = 0; i != NumBytes; ++i) { + unsigned Idx = (FullSize - 1 - i); + Data[Offset + Idx] = static_cast<uint8_t>((CurVal >> (i * 8)) & 0xff); + } +} + +MCObjectWriter * +LanaiAsmBackend::createObjectWriter(raw_pwrite_stream &OS) const { + return createLanaiELFObjectWriter(OS, + MCELFObjectTargetWriter::getOSABI(OSType)); +} + +const MCFixupKindInfo & +LanaiAsmBackend::getFixupKindInfo(MCFixupKind Kind) const { + static const MCFixupKindInfo Infos[Lanai::NumTargetFixupKinds] = { + // This table *must* be in same the order of fixup_* kinds in + // LanaiFixupKinds.h. + // Note: The number of bits indicated here are assumed to be contiguous. + // This does not hold true for LANAI_21 and LANAI_21_F which are applied + // to bits 0x7cffff and 0x7cfffc, respectively. Since the 'bits' counts + // here are used only for cosmetic purposes, we set the size to 16 bits + // for these 21-bit relocation as llvm/lib/MC/MCAsmStreamer.cpp checks + // no bits are set in the fixup range. + // + // name offset bits flags + {"FIXUP_LANAI_NONE", 0, 32, 0}, + {"FIXUP_LANAI_21", 16, 16 /*21*/, 0}, + {"FIXUP_LANAI_21_F", 16, 16 /*21*/, 0}, + {"FIXUP_LANAI_25", 7, 25, 0}, + {"FIXUP_LANAI_32", 0, 32, 0}, + {"FIXUP_LANAI_HI16", 16, 16, 0}, + {"FIXUP_LANAI_LO16", 16, 16, 0}}; + + if (Kind < FirstTargetFixupKind) + return MCAsmBackend::getFixupKindInfo(Kind); + + assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() && + "Invalid kind!"); + return Infos[Kind - FirstTargetFixupKind]; +} + +} // namespace + +MCAsmBackend *llvm::createLanaiAsmBackend(const Target &T, + const MCRegisterInfo &MRI, + const Triple &TheTriple, + StringRef CPU) { + if (!TheTriple.isOSBinFormatELF()) + llvm_unreachable("OS not supported"); + + return new LanaiAsmBackend(T, TheTriple.getOS()); +} diff --git a/lib/Target/Lanai/MCTargetDesc/LanaiBaseInfo.h b/lib/Target/Lanai/MCTargetDesc/LanaiBaseInfo.h new file mode 100644 index 00000000000..42bda1e894f --- /dev/null +++ b/lib/Target/Lanai/MCTargetDesc/LanaiBaseInfo.h @@ -0,0 +1,145 @@ +//===-- LanaiBaseInfo.h - Top level definitions for Lanai MC ----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains small standalone helper functions and enum definitions for +// the Lanai target useful for the compiler back-end and the MC libraries. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_LANAI_MCTARGETDESC_LANAIBASEINFO_H +#define LLVM_LIB_TARGET_LANAI_MCTARGETDESC_LANAIBASEINFO_H + +#include "LanaiMCTargetDesc.h" +#include "llvm/MC/MCExpr.h" +#include "llvm/Support/DataTypes.h" +#include "llvm/Support/ErrorHandling.h" + +namespace llvm { + +// LanaiII - This namespace holds all of the target specific flags that +// instruction info tracks. +// +namespace LanaiII { +// Target Operand Flag enum. +enum TOF { + //===------------------------------------------------------------------===// + // Lanai Specific MachineOperand flags. + MO_NO_FLAG, + + // MO_ABS_HI/LO - Represents the hi or low part of an absolute symbol + // address. + MO_ABS_HI, + MO_ABS_LO, + + // MO_PIC_BASE_OFFSET - On a symbol operand this indicates that the + // immediate should get the value of the symbol minus the PIC base label: + // SYMBOL_LABEL - PICBASELABEL + MO_PIC_BASE_OFFSET, + + // MO_GOT - On a symbol operand this indicates that the immediate is the + // offset to the GOT entry for the symbol name from the base of the GOT. + MO_GOT, + + // MO_GOTOFFHI/MO_GOTOFFLO - On a symbol operand this indicates that the + // immediate is the offset to the location of the symbol name from the + // base of the GOT. + MO_GOTOFFHI, + MO_GOTOFFLO, + + // MO_GOTPCHI/MO_GOTPCLO - On a symbol operand this indicates that + // the immediate is an offset to the GOT entry for the symbol name + // from the current code location. + MO_GOTPCHI, + MO_GOTPCLO, + + // MO_PLT - On a symbol operand this indicates that the immediate is + // offset to the PLT entry of symbol name from the current code location. + MO_PLT +}; +} // namespace LanaiII + +static inline unsigned getLanaiRegisterNumbering(unsigned Reg) { + switch (Reg) { + case Lanai::R0: + return 0; + case Lanai::R1: + return 1; + case Lanai::R2: + case Lanai::PC: + return 2; + case Lanai::R3: + return 3; + case Lanai::R4: + case Lanai::SP: + return 4; + case Lanai::R5: + case Lanai::FP: + return 5; + case Lanai::R6: + return 6; + case Lanai::R7: + return 7; + case Lanai::R8: + case Lanai::RV: + return 8; + case Lanai::R9: + return 9; + case Lanai::R10: + case Lanai::RR1: + return 10; + case Lanai::R11: + case Lanai::RR2: + return 11; + case Lanai::R12: + return 12; + case Lanai::R13: + return 13; + case Lanai::R14: + return 14; + case Lanai::R15: + case Lanai::RCA: + return 15; + case Lanai::R16: + return 16; + case Lanai::R17: + return 17; + case Lanai::R18: + return 18; + case Lanai::R19: + return 19; + case Lanai::R20: + return 20; + case Lanai::R21: + return 21; + case Lanai::R22: + return 22; + case Lanai::R23: + return 23; + case Lanai::R24: + return 24; + case Lanai::R25: + return 25; + case Lanai::R26: + return 26; + case Lanai::R27: + return 27; + case Lanai::R28: + return 28; + case Lanai::R29: + return 29; + case Lanai::R30: + return 30; + case Lanai::R31: + return 31; + default: + llvm_unreachable("Unknown register number!"); + } +} +} // namespace llvm +#endif // LLVM_LIB_TARGET_LANAI_MCTARGETDESC_LANAIBASEINFO_H diff --git a/lib/Target/Lanai/MCTargetDesc/LanaiELFObjectWriter.cpp b/lib/Target/Lanai/MCTargetDesc/LanaiELFObjectWriter.cpp new file mode 100644 index 00000000000..d11eb0ab81d --- /dev/null +++ b/lib/Target/Lanai/MCTargetDesc/LanaiELFObjectWriter.cpp @@ -0,0 +1,95 @@ +//===-- LanaiELFObjectWriter.cpp - Lanai ELF Writer -----------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "MCTargetDesc/LanaiBaseInfo.h" +#include "MCTargetDesc/LanaiFixupKinds.h" +#include "MCTargetDesc/LanaiMCTargetDesc.h" +#include "llvm/MC/MCELFObjectWriter.h" +#include "llvm/MC/MCSymbol.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" + +using namespace llvm; + +namespace { +class LanaiELFObjectWriter : public MCELFObjectTargetWriter { +public: + explicit LanaiELFObjectWriter(uint8_t OSABI); + + ~LanaiELFObjectWriter() override; + +protected: + unsigned getRelocType(MCContext &Ctx, const MCValue &Target, + const MCFixup &Fixup, bool IsPCRel) const override; + bool needsRelocateWithSymbol(const MCSymbol &SD, + unsigned Type) const override; +}; +} // namespace + +LanaiELFObjectWriter::LanaiELFObjectWriter(uint8_t OSABI) + : MCELFObjectTargetWriter(/*Is64Bit=*/false, OSABI, ELF::EM_LANAI, + /*HasRelocationAddend=*/true) {} + +LanaiELFObjectWriter::~LanaiELFObjectWriter() {} + +unsigned LanaiELFObjectWriter::getRelocType(MCContext &Ctx, + const MCValue &Target, + const MCFixup &Fixup, + bool IsPCRel) const { + unsigned Type; + unsigned Kind = static_cast<unsigned>(Fixup.getKind()); + switch (Kind) { + case Lanai::FIXUP_LANAI_21: + Type = ELF::R_LANAI_21; + break; + case Lanai::FIXUP_LANAI_21_F: + Type = ELF::R_LANAI_21_F; + break; + case Lanai::FIXUP_LANAI_25: + Type = ELF::R_LANAI_25; + break; + case Lanai::FIXUP_LANAI_32: + case FK_Data_4: + Type = ELF::R_LANAI_32; + break; + case Lanai::FIXUP_LANAI_HI16: + Type = ELF::R_LANAI_HI16; + break; + case Lanai::FIXUP_LANAI_LO16: + Type = ELF::R_LANAI_LO16; + break; + case Lanai::FIXUP_LANAI_NONE: + Type = ELF::R_LANAI_NONE; + break; + + default: + llvm_unreachable("Invalid fixup kind!"); + } + return Type; +} + +bool LanaiELFObjectWriter::needsRelocateWithSymbol(const MCSymbol &SD, + unsigned Type) const { + switch (Type) { + case ELF::R_LANAI_21: + case ELF::R_LANAI_21_F: + case ELF::R_LANAI_25: + case ELF::R_LANAI_32: + case ELF::R_LANAI_HI16: + return true; + default: + return false; + } +} + +MCObjectWriter *llvm::createLanaiELFObjectWriter(raw_pwrite_stream &OS, + uint8_t OSABI) { + MCELFObjectTargetWriter *MOTW = new LanaiELFObjectWriter(OSABI); + return createELFObjectWriter(MOTW, OS, /*IsLittleEndian=*/false); +} diff --git a/lib/Target/Lanai/MCTargetDesc/LanaiFixupKinds.h b/lib/Target/Lanai/MCTargetDesc/LanaiFixupKinds.h new file mode 100644 index 00000000000..9ff8340d292 --- /dev/null +++ b/lib/Target/Lanai/MCTargetDesc/LanaiFixupKinds.h @@ -0,0 +1,43 @@ +//===-- LanaiFixupKinds.h - Lanai Specific Fixup Entries --------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_LANAI_MCTARGETDESC_LANAIFIXUPKINDS_H +#define LLVM_LIB_TARGET_LANAI_MCTARGETDESC_LANAIFIXUPKINDS_H + +#include "llvm/MC/MCFixup.h" + +namespace llvm { +namespace Lanai { +// Although most of the current fixup types reflect a unique relocation +// one can have multiple fixup types for a given relocation and thus need +// to be uniquely named. +// +// This table *must* be in the save order of +// MCFixupKindInfo Infos[Lanai::NumTargetFixupKinds] +// in LanaiAsmBackend.cpp. +// +enum Fixups { + // Results in R_Lanai_NONE + FIXUP_LANAI_NONE = FirstTargetFixupKind, + + FIXUP_LANAI_21, // 21-bit symbol relocation + FIXUP_LANAI_21_F, // 21-bit symbol relocation, last two bits masked to 0 + FIXUP_LANAI_25, // 25-bit branch targets + FIXUP_LANAI_32, // general 32-bit relocation + FIXUP_LANAI_HI16, // upper 16-bits of a symbolic relocation + FIXUP_LANAI_LO16, // lower 16-bits of a symbolic relocation + + // Marker + LastTargetFixupKind, + NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind +}; +} // namespace Lanai +} // namespace llvm + +#endif // LLVM_LIB_TARGET_LANAI_MCTARGETDESC_LANAIFIXUPKINDS_H diff --git a/lib/Target/Lanai/MCTargetDesc/LanaiMCAsmInfo.cpp b/lib/Target/Lanai/MCTargetDesc/LanaiMCAsmInfo.cpp new file mode 100644 index 00000000000..491a7084757 --- /dev/null +++ b/lib/Target/Lanai/MCTargetDesc/LanaiMCAsmInfo.cpp @@ -0,0 +1,43 @@ +//===-- LanaiMCAsmInfo.cpp - Lanai asm properties -----------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains the declarations of the LanaiMCAsmInfo properties. +// +//===----------------------------------------------------------------------===// + +#include "LanaiMCAsmInfo.h" + +#include "llvm/ADT/Triple.h" + +using namespace llvm; + +void LanaiMCAsmInfo::anchor() {} + +LanaiMCAsmInfo::LanaiMCAsmInfo(const Triple &TheTriple) { + IsLittleEndian = false; + PrivateGlobalPrefix = ".L"; + WeakRefDirective = "\t.weak\t"; + ExceptionsType = ExceptionHandling::DwarfCFI; + + // Lanai assembly requires ".section" before ".bss" + UsesELFSectionDirectiveForBSS = true; + + // Use the integrated assembler instead of system one. + UseIntegratedAssembler = true; + + // Use '!' as comment string to correspond with old toolchain. + CommentString = "!"; + + // Target supports emission of debugging information. + SupportsDebugInformation = true; + + // Set the instruction alignment. Currently used only for address adjustment + // in dwarf generation. + MinInstAlignment = 4; +} diff --git a/lib/Target/Lanai/MCTargetDesc/LanaiMCAsmInfo.h b/lib/Target/Lanai/MCTargetDesc/LanaiMCAsmInfo.h new file mode 100644 index 00000000000..054e7fd3504 --- /dev/null +++ b/lib/Target/Lanai/MCTargetDesc/LanaiMCAsmInfo.h @@ -0,0 +1,32 @@ +//=====-- LanaiMCAsmInfo.h - Lanai asm properties -----------*- C++ -*--====// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains the declaration of the LanaiMCAsmInfo class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_LANAI_MCTARGETDESC_LANAIMCASMINFO_H +#define LLVM_LIB_TARGET_LANAI_MCTARGETDESC_LANAIMCASMINFO_H + +#include "llvm/ADT/StringRef.h" +#include "llvm/MC/MCAsmInfoELF.h" + +namespace llvm { +class Triple; + +class LanaiMCAsmInfo : public MCAsmInfoELF { + void anchor() override; + +public: + explicit LanaiMCAsmInfo(const Triple &TheTriple); +}; + +} // namespace llvm + +#endif // LLVM_LIB_TARGET_LANAI_MCTARGETDESC_LANAIMCASMINFO_H diff --git a/lib/Target/Lanai/MCTargetDesc/LanaiMCCodeEmitter.cpp b/lib/Target/Lanai/MCTargetDesc/LanaiMCCodeEmitter.cpp new file mode 100644 index 00000000000..b4ffa7c23bf --- /dev/null +++ b/lib/Target/Lanai/MCTargetDesc/LanaiMCCodeEmitter.cpp @@ -0,0 +1,325 @@ +//===-- LanaiMCCodeEmitter.cpp - Convert Lanai code to machine code -------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the LanaiMCCodeEmitter class. +// +//===----------------------------------------------------------------------===// + +#include "Lanai.h" +#include "MCTargetDesc/LanaiBaseInfo.h" +#include "MCTargetDesc/LanaiFixupKinds.h" +#include "MCTargetDesc/LanaiMCExpr.h" +#include "MCTargetDesc/LanaiMCTargetDesc.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/MC/MCCodeEmitter.h" +#include "llvm/MC/MCFixup.h" +#include "llvm/MC/MCInst.h" +#include "llvm/MC/MCInstrInfo.h" +#include "llvm/MC/MCRegisterInfo.h" +#include "llvm/MC/MCSubtargetInfo.h" +#include "llvm/MC/MCSymbol.h" +#include "llvm/Support/raw_ostream.h" + +#define DEBUG_TYPE "mccodeemitter" + +STATISTIC(MCNumEmitted, "Number of MC instructions emitted"); + +namespace llvm { +namespace { +class LanaiMCCodeEmitter : public MCCodeEmitter { + LanaiMCCodeEmitter(const LanaiMCCodeEmitter &); // DO NOT IMPLEMENT + void operator=(const LanaiMCCodeEmitter &); // DO NOT IMPLEMENT + const MCInstrInfo &InstrInfo; + MCContext &Context; + +public: + LanaiMCCodeEmitter(const MCInstrInfo &MCII, MCContext &C) + : InstrInfo(MCII), Context(C) {} + + ~LanaiMCCodeEmitter() override {} + + // The functions below are called by TableGen generated functions for getting + // the binary encoding of instructions/opereands. + + // getBinaryCodeForInstr - TableGen'erated function for getting the + // binary encoding for an instruction. + uint64_t getBinaryCodeForInstr(const MCInst &Inst, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &SubtargetInfo) const; + + // getMachineOpValue - Return binary encoding of operand. If the machine + // operand requires relocation, record the relocation and return zero. + unsigned getMachineOpValue(const MCInst &Inst, const MCOperand &MCOp, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &SubtargetInfo) const; + + unsigned getRiMemoryOpValue(const MCInst &Inst, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &SubtargetInfo) const; + + unsigned getRrMemoryOpValue(const MCInst &Inst, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &SubtargetInfo) const; + + unsigned getSplsOpValue(const MCInst &Inst, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &SubtargetInfo) const; + + unsigned getBranchTargetOpValue(const MCInst &Inst, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &SubtargetInfo) const; + + unsigned getCallTargetOpValue(const MCInst &Inst, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &SubtargetInfo) const; + + void encodeInstruction(const MCInst &Inst, raw_ostream &Ostream, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &SubtargetInfo) const override; + + unsigned adjustPqBitsRmAndRrm(const MCInst &Inst, unsigned Value, + const MCSubtargetInfo &STI) const; + + unsigned adjustPqBitsSpls(const MCInst &Inst, unsigned Value, + const MCSubtargetInfo &STI) const; +}; + +Lanai::Fixups FixupKind(const MCExpr *Expr) { + if (isa<MCSymbolRefExpr>(Expr)) + return Lanai::FIXUP_LANAI_21; + if (const LanaiMCExpr *McExpr = dyn_cast<LanaiMCExpr>(Expr)) { + LanaiMCExpr::VariantKind ExprKind = McExpr->getKind(); + switch (ExprKind) { + case LanaiMCExpr::VK_Lanai_None: + return Lanai::FIXUP_LANAI_21; + case LanaiMCExpr::VK_Lanai_ABS_HI: + return Lanai::FIXUP_LANAI_HI16; + case LanaiMCExpr::VK_Lanai_ABS_LO: + return Lanai::FIXUP_LANAI_LO16; + } + } + return Lanai::Fixups(0); +} + +// getMachineOpValue - Return binary encoding of operand. If the machine +// operand requires relocation, record the relocation and return zero. +unsigned LanaiMCCodeEmitter::getMachineOpValue( + const MCInst &Inst, const MCOperand &MCOp, SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &SubtargetInfo) const { + if (MCOp.isReg()) + return getLanaiRegisterNumbering(MCOp.getReg()); + if (MCOp.isImm()) + return static_cast<unsigned>(MCOp.getImm()); + + // MCOp must be an expression + assert(MCOp.isExpr()); + const MCExpr *Expr = MCOp.getExpr(); + + // Extract the symbolic reference side of a binary expression. + if (Expr->getKind() == MCExpr::Binary) { + const MCBinaryExpr *BinaryExpr = static_cast<const MCBinaryExpr *>(Expr); + Expr = BinaryExpr->getLHS(); + } + + assert(isa<LanaiMCExpr>(Expr) || Expr->getKind() == MCExpr::SymbolRef); + // Push fixup (all info is contained within) + Fixups.push_back( + MCFixup::create(0, MCOp.getExpr(), MCFixupKind(FixupKind(Expr)))); + return 0; +} + +// Helper function to adjust P and Q bits on load and store instructions. +unsigned adjustPqBits(const MCInst &Inst, unsigned Value, unsigned PBitShift, + unsigned QBitShift) { + const MCOperand AluOp = Inst.getOperand(3); + unsigned AluCode = AluOp.getImm(); + + // Set the P bit to one iff the immediate is nonzero and not a post-op + // instruction. + const MCOperand Op2 = Inst.getOperand(2); + Value &= ~(1 << PBitShift); + if (!LPAC::isPostOp(AluCode) && + ((Op2.isImm() && Op2.getImm() != 0) || + (Op2.isReg() && Op2.getReg() != Lanai::R0) || (Op2.isExpr()))) + Value |= (1 << PBitShift); + + // Set the Q bit to one iff it is a post- or pre-op instruction. + assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() && + "Expected register operand."); + Value &= ~(1 << QBitShift); + if (LPAC::modifiesOp(AluCode) && ((Op2.isImm() && Op2.getImm() != 0) || + (Op2.isReg() && Op2.getReg() != Lanai::R0))) + Value |= (1 << QBitShift); + + return Value; +} + +unsigned +LanaiMCCodeEmitter::adjustPqBitsRmAndRrm(const MCInst &Inst, unsigned Value, + const MCSubtargetInfo &STI) const { + return adjustPqBits(Inst, Value, 17, 16); +} + +unsigned +LanaiMCCodeEmitter::adjustPqBitsSpls(const MCInst &Inst, unsigned Value, + const MCSubtargetInfo &STI) const { + return adjustPqBits(Inst, Value, 11, 10); +} + +void LanaiMCCodeEmitter::encodeInstruction( + const MCInst &Inst, raw_ostream &Ostream, SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &SubtargetInfo) const { + // Get instruction encoding and emit it + unsigned Value = getBinaryCodeForInstr(Inst, Fixups, SubtargetInfo); + ++MCNumEmitted; // Keep track of the number of emitted insns. + + // Emit bytes in big-endian + for (int i = (4 - 1) * 8; i >= 0; i -= 8) + Ostream << static_cast<char>((Value >> i) & 0xff); +} + +// Encode Lanai Memory Operand +unsigned LanaiMCCodeEmitter::getRiMemoryOpValue( + const MCInst &Inst, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &SubtargetInfo) const { + unsigned Encoding; + const MCOperand Op1 = Inst.getOperand(OpNo + 0); + const MCOperand Op2 = Inst.getOperand(OpNo + 1); + const MCOperand AluOp = Inst.getOperand(OpNo + 2); + + assert(Op1.isReg() && "First operand is not register."); + assert((Op2.isImm() || Op2.isExpr()) && + "Second operand is neither an immediate nor an expression."); + assert((LPAC::getAluOp(AluOp.getImm()) == LPAC::ADD) && + "Register immediate only supports addition operator"); + + Encoding = (getLanaiRegisterNumbering(Op1.getReg()) << 18); + if (Op2.isImm()) { + assert(isInt<16>(Op2.getImm()) && + "Constant value truncated (limited to 16-bit)"); + + Encoding |= (Op2.getImm() & 0xffff); + if (Op2.getImm() != 0) { + if (LPAC::isPreOp(AluOp.getImm())) + Encoding |= (0x3 << 16); + if (LPAC::isPostOp(AluOp.getImm())) + Encoding |= (0x1 << 16); + } + } else + getMachineOpValue(Inst, Op2, Fixups, SubtargetInfo); + + return Encoding; +} + +unsigned LanaiMCCodeEmitter::getRrMemoryOpValue( + const MCInst &Inst, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &SubtargetInfo) const { + unsigned Encoding; + const MCOperand Op1 = Inst.getOperand(OpNo + 0); + const MCOperand Op2 = Inst.getOperand(OpNo + 1); + const MCOperand AluMCOp = Inst.getOperand(OpNo + 2); + + assert(Op1.isReg() && "First operand is not register."); + Encoding = (getLanaiRegisterNumbering(Op1.getReg()) << 15); + assert(Op2.isReg() && "Second operand is not register."); + Encoding |= (getLanaiRegisterNumbering(Op2.getReg()) << 10); + + assert(AluMCOp.isImm() && "Third operator is not immediate."); + // Set BBB + unsigned AluOp = AluMCOp.getImm(); + Encoding |= LPAC::encodeLanaiAluCode(AluOp) << 5; + // Set P and Q + if (LPAC::isPreOp(AluOp)) + Encoding |= (0x3 << 8); + if (LPAC::isPostOp(AluOp)) + Encoding |= (0x1 << 8); + // Set JJJJ + switch (LPAC::getAluOp(AluOp)) { + case LPAC::SHL: + case LPAC::SRL: + Encoding |= 0x10; + break; + case LPAC::SRA: + Encoding |= 0x18; + break; + default: + break; + } + + return Encoding; +} + +unsigned +LanaiMCCodeEmitter::getSplsOpValue(const MCInst &Inst, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &SubtargetInfo) const { + unsigned Encoding; + const MCOperand Op1 = Inst.getOperand(OpNo + 0); + const MCOperand Op2 = Inst.getOperand(OpNo + 1); + const MCOperand AluOp = Inst.getOperand(OpNo + 2); + + assert(Op1.isReg() && "First operand is not register."); + assert((Op2.isImm() || Op2.isExpr()) && + "Second operand is neither an immediate nor an expression."); + assert((LPAC::getAluOp(AluOp.getImm()) == LPAC::ADD) && + "Register immediate only supports addition operator"); + + Encoding = (getLanaiRegisterNumbering(Op1.getReg()) << 12); + if (Op2.isImm()) { + assert(isInt<10>(Op2.getImm()) && + "Constant value truncated (limited to 10-bit)"); + + Encoding |= (Op2.getImm() & 0x3ff); + if (Op2.getImm() != 0) { + if (LPAC::isPreOp(AluOp.getImm())) + Encoding |= (0x3 << 10); + if (LPAC::isPostOp(AluOp.getImm())) + Encoding |= (0x1 << 10); + } + } else + getMachineOpValue(Inst, Op2, Fixups, SubtargetInfo); + + return Encoding; +} + +unsigned LanaiMCCodeEmitter::getCallTargetOpValue( + const MCInst &Inst, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &SubtargetInfo) const { + const MCOperand &MCOp = Inst.getOperand(OpNo); + if (MCOp.isReg() || MCOp.isImm()) + return getMachineOpValue(Inst, MCOp, Fixups, SubtargetInfo); + + Fixups.push_back(MCFixup::create( + 0, MCOp.getExpr(), static_cast<MCFixupKind>(Lanai::FIXUP_LANAI_25))); + + return 0; +} + +unsigned LanaiMCCodeEmitter::getBranchTargetOpValue( + const MCInst &Inst, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &SubtargetInfo) const { + const MCOperand &MCOp = Inst.getOperand(OpNo); + if (MCOp.isReg() || MCOp.isImm()) + return getMachineOpValue(Inst, MCOp, Fixups, SubtargetInfo); + + Fixups.push_back(MCFixup::create( + 0, MCOp.getExpr(), static_cast<MCFixupKind>(Lanai::FIXUP_LANAI_25))); + + return 0; +} + +#include "LanaiGenMCCodeEmitter.inc" +} // namespace +} // namespace llvm + +llvm::MCCodeEmitter * +llvm::createLanaiMCCodeEmitter(const MCInstrInfo &InstrInfo, + const MCRegisterInfo &MRI, MCContext &context) { + return new LanaiMCCodeEmitter(InstrInfo, context); +} diff --git a/lib/Target/Lanai/MCTargetDesc/LanaiMCExpr.cpp b/lib/Target/Lanai/MCTargetDesc/LanaiMCExpr.cpp new file mode 100644 index 00000000000..201c95de07f --- /dev/null +++ b/lib/Target/Lanai/MCTargetDesc/LanaiMCExpr.cpp @@ -0,0 +1,60 @@ +//===-- LanaiMCExpr.cpp - Lanai specific MC expression classes ------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "LanaiMCExpr.h" +#include "llvm/MC/MCAssembler.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCStreamer.h" +using namespace llvm; + +#define DEBUG_TYPE "lanaimcexpr" + +const LanaiMCExpr *LanaiMCExpr::create(VariantKind Kind, const MCExpr *Expr, + MCContext &Ctx) { + return new (Ctx) LanaiMCExpr(Kind, Expr); +} + +void LanaiMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const { + if (Kind == VK_Lanai_None) { + Expr->print(OS, MAI); + return; + } + + switch (Kind) { + default: + llvm_unreachable("Invalid kind!"); + case VK_Lanai_ABS_HI: + OS << "hi"; + break; + case VK_Lanai_ABS_LO: + OS << "lo"; + break; + } + + OS << '('; + const MCExpr *Expr = getSubExpr(); + Expr->print(OS, MAI); + OS << ')'; +} + +void LanaiMCExpr::visitUsedExpr(MCStreamer &Streamer) const { + Streamer.visitUsedExpr(*getSubExpr()); +} + +bool LanaiMCExpr::evaluateAsRelocatableImpl(MCValue &Res, + const MCAsmLayout *Layout, + const MCFixup *Fixup) const { + if (!getSubExpr()->evaluateAsRelocatable(Res, Layout, Fixup)) + return false; + + Res = + MCValue::get(Res.getSymA(), Res.getSymB(), Res.getConstant(), getKind()); + + return true; +} diff --git a/lib/Target/Lanai/MCTargetDesc/LanaiMCExpr.h b/lib/Target/Lanai/MCTargetDesc/LanaiMCExpr.h new file mode 100644 index 00000000000..f481b039bda --- /dev/null +++ b/lib/Target/Lanai/MCTargetDesc/LanaiMCExpr.h @@ -0,0 +1,56 @@ +//===-- LanaiMCExpr.h - Lanai specific MC expression classes ----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_LANAI_MCTARGETDESC_LANAIMCEXPR_H +#define LLVM_LIB_TARGET_LANAI_MCTARGETDESC_LANAIMCEXPR_H + +#include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCValue.h" + +namespace llvm { + +class LanaiMCExpr : public MCTargetExpr { +public: + enum VariantKind { VK_Lanai_None, VK_Lanai_ABS_HI, VK_Lanai_ABS_LO }; + +private: + const VariantKind Kind; + const MCExpr *Expr; + + explicit LanaiMCExpr(VariantKind Kind, const MCExpr *Expr) + : Kind(Kind), Expr(Expr) {} + +public: + static const LanaiMCExpr *create(VariantKind Kind, const MCExpr *Expr, + MCContext &Ctx); + + // Returns the kind of this expression. + VariantKind getKind() const { return Kind; } + + // Returns the child of this expression. + const MCExpr *getSubExpr() const { return Expr; } + + void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const override; + bool evaluateAsRelocatableImpl(MCValue &Res, const MCAsmLayout *Layout, + const MCFixup *Fixup) const override; + void visitUsedExpr(MCStreamer &Streamer) const override; + MCFragment *findAssociatedFragment() const override { + return getSubExpr()->findAssociatedFragment(); + } + + // There are no TLS LanaiMCExprs at the moment. + void fixELFSymbolsInTLSFixups(MCAssembler &Asm) const override {} + + static bool classof(const MCExpr *E) { + return E->getKind() == MCExpr::Target; + } +}; +} // end namespace llvm + +#endif diff --git a/lib/Target/Lanai/MCTargetDesc/LanaiMCTargetDesc.cpp b/lib/Target/Lanai/MCTargetDesc/LanaiMCTargetDesc.cpp new file mode 100644 index 00000000000..9db240100b4 --- /dev/null +++ b/lib/Target/Lanai/MCTargetDesc/LanaiMCTargetDesc.cpp @@ -0,0 +1,163 @@ +//===-- LanaiMCTargetDesc.cpp - Lanai Target Descriptions -----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file provides Lanai specific target descriptions. +// +//===----------------------------------------------------------------------===// + +#include "LanaiMCTargetDesc.h" + +#include "InstPrinter/LanaiInstPrinter.h" +#include "LanaiMCAsmInfo.h" +#include "llvm/MC/MCCodeGenInfo.h" +#include "llvm/MC/MCInstrAnalysis.h" +#include "llvm/MC/MCInstrInfo.h" +#include "llvm/MC/MCStreamer.h" +#include "llvm/MC/MCSubtargetInfo.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/TargetRegistry.h" + +#define GET_INSTRINFO_MC_DESC +#include "LanaiGenInstrInfo.inc" + +#define GET_SUBTARGETINFO_MC_DESC +#include "LanaiGenSubtargetInfo.inc" + +#define GET_REGINFO_MC_DESC +#include "LanaiGenRegisterInfo.inc" + +using namespace llvm; + +static MCInstrInfo *createLanaiMCInstrInfo() { + MCInstrInfo *X = new MCInstrInfo(); + InitLanaiMCInstrInfo(X); + return X; +} + +static MCRegisterInfo *createLanaiMCRegisterInfo(const Triple &TT) { + MCRegisterInfo *X = new MCRegisterInfo(); + InitLanaiMCRegisterInfo(X, Lanai::RCA, 0, 0, Lanai::PC); + return X; +} + +static MCSubtargetInfo * +createLanaiMCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS) { + std::string CPUName = CPU; + if (CPUName.empty()) + CPUName = "generic"; + + return createLanaiMCSubtargetInfoImpl(TT, CPUName, FS); +} + +static MCCodeGenInfo *createLanaiMCCodeGenInfo(const Triple &TT, + Reloc::Model RM, + CodeModel::Model CM, + CodeGenOpt::Level OL) { + MCCodeGenInfo *X = new MCCodeGenInfo(); + X->initMCCodeGenInfo(RM, CM, OL); + return X; +} + +static MCStreamer *createMCStreamer(const Triple &T, MCContext &Context, + MCAsmBackend &MAB, raw_pwrite_stream &OS, + MCCodeEmitter *Emitter, bool RelaxAll) { + if (!T.isOSBinFormatELF()) + llvm_unreachable("OS not supported"); + + return createELFStreamer(Context, MAB, OS, Emitter, RelaxAll); +} + +static MCInstPrinter *createLanaiMCInstPrinter(const Triple &T, + unsigned SyntaxVariant, + const MCAsmInfo &MAI, + const MCInstrInfo &MII, + const MCRegisterInfo &MRI) { + if (SyntaxVariant == 0) + return new LanaiInstPrinter(MAI, MII, MRI); + return 0; +} + +MCRelocationInfo *createLanaiElfRelocation(const Triple &TheTriple, + MCContext &Ctx) { + return createMCRelocationInfo(TheTriple, Ctx); +} + +class LanaiMCInstrAnalysis : public MCInstrAnalysis { +public: + explicit LanaiMCInstrAnalysis(const MCInstrInfo *Info) + : MCInstrAnalysis(Info) {} + + bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size, + uint64_t &Target) const override { + if (Inst.getNumOperands() == 0) + return false; + + if (Info->get(Inst.getOpcode()).OpInfo[0].OperandType == + MCOI::OPERAND_PCREL) { + int64_t Imm = Inst.getOperand(0).getImm(); + Target = Addr + Size + Imm; + return true; + } else { + int64_t Imm = Inst.getOperand(0).getImm(); + + // Skip case where immediate is 0 as that occurs in file that isn't linked + // and the branch target inferred would be wrong. + if (Imm == 0) + return false; + + Target = Imm; + return true; + } + } +}; + +static MCInstrAnalysis *createLanaiInstrAnalysis(const MCInstrInfo *Info) { + return new LanaiMCInstrAnalysis(Info); +} + +extern "C" void LLVMInitializeLanaiTargetMC() { + // Register the MC asm info. + RegisterMCAsmInfo<LanaiMCAsmInfo> X(TheLanaiTarget); + + // Register the MC codegen info. + TargetRegistry::RegisterMCCodeGenInfo(TheLanaiTarget, + createLanaiMCCodeGenInfo); + + // Register the MC instruction info. + TargetRegistry::RegisterMCInstrInfo(TheLanaiTarget, createLanaiMCInstrInfo); + + // Register the MC register info. + TargetRegistry::RegisterMCRegInfo(TheLanaiTarget, createLanaiMCRegisterInfo); + + // Register the MC subtarget info. + TargetRegistry::RegisterMCSubtargetInfo(TheLanaiTarget, + createLanaiMCSubtargetInfo); + + // Register the MC code emitter + TargetRegistry::RegisterMCCodeEmitter(TheLanaiTarget, + llvm::createLanaiMCCodeEmitter); + + // Register the ASM Backend + TargetRegistry::RegisterMCAsmBackend(TheLanaiTarget, createLanaiAsmBackend); + + // Register the MCInstPrinter. + TargetRegistry::RegisterMCInstPrinter(TheLanaiTarget, + createLanaiMCInstPrinter); + + // Register the ELF streamer. + TargetRegistry::RegisterELFStreamer(TheLanaiTarget, createMCStreamer); + + // Register the MC relocation info. + TargetRegistry::RegisterMCRelocationInfo(TheLanaiTarget, + createLanaiElfRelocation); + + // Register the MC instruction analyzer. + TargetRegistry::RegisterMCInstrAnalysis(TheLanaiTarget, + createLanaiInstrAnalysis); +} diff --git a/lib/Target/Lanai/MCTargetDesc/LanaiMCTargetDesc.h b/lib/Target/Lanai/MCTargetDesc/LanaiMCTargetDesc.h new file mode 100644 index 00000000000..e117ed7a500 --- /dev/null +++ b/lib/Target/Lanai/MCTargetDesc/LanaiMCTargetDesc.h @@ -0,0 +1,59 @@ +//===-- LanaiMCTargetDesc.h - Lanai Target Descriptions ---------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file provides Lanai specific target descriptions. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_LANAI_MCTARGETDESC_LANAIMCTARGETDESC_H +#define LLVM_LIB_TARGET_LANAI_MCTARGETDESC_LANAIMCTARGETDESC_H + +#include "llvm/MC/MCRegisterInfo.h" +#include "llvm/Support/DataTypes.h" + +namespace llvm { +class MCAsmBackend; +class MCCodeEmitter; +class MCContext; +class MCInstrInfo; +class MCInstrAnalysis; +class MCObjectWriter; +class MCRelocationInfo; +class MCSubtargetInfo; +class Target; +class Triple; +class StringRef; +class raw_pwrite_stream; + +extern Target TheLanaiTarget; + +MCCodeEmitter *createLanaiMCCodeEmitter(const MCInstrInfo &MCII, + const MCRegisterInfo &MRI, + MCContext &Ctx); + +MCAsmBackend *createLanaiAsmBackend(const Target &T, const MCRegisterInfo &MRI, + const Triple &TheTriple, StringRef CPU); + +MCObjectWriter *createLanaiELFObjectWriter(raw_pwrite_stream &OS, + uint8_t OSABI); +} // namespace llvm + +// Defines symbolic names for Lanai registers. This defines a mapping from +// register name to register number. +#define GET_REGINFO_ENUM +#include "LanaiGenRegisterInfo.inc" + +// Defines symbolic names for the Lanai instructions. +#define GET_INSTRINFO_ENUM +#include "LanaiGenInstrInfo.inc" + +#define GET_SUBTARGETINFO_ENUM +#include "LanaiGenSubtargetInfo.inc" + +#endif // LLVM_LIB_TARGET_LANAI_MCTARGETDESC_LANAIMCTARGETDESC_H |