diff options
-rw-r--r-- | llvm/lib/Target/RISCV/CMakeLists.txt | 2 | ||||
-rw-r--r-- | llvm/lib/Target/RISCV/LLVMBuild.txt | 2 | ||||
-rw-r--r-- | llvm/lib/Target/RISCV/MCTargetDesc/CMakeLists.txt | 7 | ||||
-rw-r--r-- | llvm/lib/Target/RISCV/MCTargetDesc/LLVMBuild.txt | 23 | ||||
-rw-r--r-- | llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp | 91 | ||||
-rw-r--r-- | llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp | 51 | ||||
-rw-r--r-- | llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp | 25 | ||||
-rw-r--r-- | llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.h | 31 | ||||
-rw-r--r-- | llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp | 91 | ||||
-rw-r--r-- | llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp | 59 | ||||
-rw-r--r-- | llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.h | 58 | ||||
-rw-r--r-- | llvm/lib/Target/RISCV/RISCVTargetMachine.h | 5 | ||||
-rw-r--r-- | llvm/lib/Target/RISCV/TargetInfo/RISCVTargetInfo.cpp | 5 |
13 files changed, 441 insertions, 9 deletions
diff --git a/llvm/lib/Target/RISCV/CMakeLists.txt b/llvm/lib/Target/RISCV/CMakeLists.txt index 5a98f9f719d..c8887548b91 100644 --- a/llvm/lib/Target/RISCV/CMakeLists.txt +++ b/llvm/lib/Target/RISCV/CMakeLists.txt @@ -2,6 +2,7 @@ set(LLVM_TARGET_DEFINITIONS RISCV.td) tablegen(LLVM RISCVGenRegisterInfo.inc -gen-register-info) tablegen(LLVM RISCVGenInstrInfo.inc -gen-instr-info) +tablegen(LLVM RISCVGenMCCodeEmitter.inc -gen-emitter) add_public_tablegen_target(RISCVCommonTableGen) @@ -10,3 +11,4 @@ add_llvm_target(RISCVCodeGen ) add_subdirectory(TargetInfo) +add_subdirectory(MCTargetDesc) diff --git a/llvm/lib/Target/RISCV/LLVMBuild.txt b/llvm/lib/Target/RISCV/LLVMBuild.txt index e5e5692490c..9ba5fec928f 100644 --- a/llvm/lib/Target/RISCV/LLVMBuild.txt +++ b/llvm/lib/Target/RISCV/LLVMBuild.txt @@ -16,7 +16,7 @@ ;===------------------------------------------------------------------------===; [common] -subdirectories = TargetInfo +subdirectories = TargetInfo MCTargetDesc [component_0] type = TargetGroup diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/CMakeLists.txt b/llvm/lib/Target/RISCV/MCTargetDesc/CMakeLists.txt new file mode 100644 index 00000000000..d79de74f7cf --- /dev/null +++ b/llvm/lib/Target/RISCV/MCTargetDesc/CMakeLists.txt @@ -0,0 +1,7 @@ +add_llvm_library(LLVMRISCVDesc + RISCVAsmBackend.cpp + RISCVELFObjectWriter.cpp + RISCVMCAsmInfo.cpp + RISCVMCTargetDesc.cpp + RISCVMCCodeEmitter.cpp +) diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/LLVMBuild.txt b/llvm/lib/Target/RISCV/MCTargetDesc/LLVMBuild.txt new file mode 100644 index 00000000000..e48f04963ff --- /dev/null +++ b/llvm/lib/Target/RISCV/MCTargetDesc/LLVMBuild.txt @@ -0,0 +1,23 @@ +;===- ./lib/Target/RISCV/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 = RISCVDesc +parent = RISCV +required_libraries = MC RISCVInfo Support +add_to_library_groups = RISCV diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp new file mode 100644 index 00000000000..f8ef142255c --- /dev/null +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp @@ -0,0 +1,91 @@ +//===-- RISCVAsmBackend.cpp - RISCV Assembler Backend ---------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "MCTargetDesc/RISCVMCTargetDesc.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/MC/MCExpr.h" +#include "llvm/MC/MCSymbol.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" + +using namespace llvm; + +namespace { +class RISCVAsmBackend : public MCAsmBackend { + uint8_t OSABI; + bool Is64Bit; + +public: + RISCVAsmBackend(uint8_t OSABI, bool Is64Bit) + : MCAsmBackend(), OSABI(OSABI), Is64Bit(Is64Bit) {} + ~RISCVAsmBackend() override {} + + void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize, + uint64_t Value, bool IsPCRel) const override; + + MCObjectWriter *createObjectWriter(raw_pwrite_stream &OS) const override; + + bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, + const MCRelaxableFragment *DF, + const MCAsmLayout &Layout) const override { + return false; + } + + unsigned getNumFixupKinds() const override { return 1; } + + bool mayNeedRelaxation(const MCInst &Inst) const override { return false; } + + void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI, + MCInst &Res) const override { + + llvm_unreachable("RISCVAsmBackend::relaxInstruction() unimplemented"); + } + + bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override; +}; + +bool RISCVAsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const { + // Once support for the compressed instruction set is added, we will be able + // to conditionally support 16-bit NOPs + if ((Count % 4) != 0) + return false; + + // The canonical nop on RISC-V is addi x0, x0, 0 + for (uint64_t i = 0; i < Count; i += 4) + OW->write32(0x13); + + return true; +} + +void RISCVAsmBackend::applyFixup(const MCFixup &Fixup, char *Data, + unsigned DataSize, uint64_t Value, + bool IsPCRel) const { + return; +} + +MCObjectWriter * +RISCVAsmBackend::createObjectWriter(raw_pwrite_stream &OS) const { + return createRISCVELFObjectWriter(OS, OSABI, Is64Bit); +} + +} // end anonymous namespace + +MCAsmBackend *llvm::createRISCVAsmBackend(const Target &T, + const MCRegisterInfo &MRI, + const Triple &TT, StringRef CPU, + const MCTargetOptions &Options) { + uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TT.getOS()); + return new RISCVAsmBackend(OSABI, TT.isArch64Bit()); +} diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp new file mode 100644 index 00000000000..def20dd48e4 --- /dev/null +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp @@ -0,0 +1,51 @@ +//===-- RISCVELFObjectWriter.cpp - RISCV 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/RISCVMCTargetDesc.h" +#include "llvm/MC/MCELFObjectWriter.h" +#include "llvm/MC/MCFixup.h" +#include "llvm/Support/ErrorHandling.h" + +using namespace llvm; + +namespace { +class RISCVELFObjectWriter : public MCELFObjectTargetWriter { +public: + RISCVELFObjectWriter(uint8_t OSABI, bool Is64Bit); + + ~RISCVELFObjectWriter() override; + +protected: + unsigned getRelocType(MCContext &Ctx, const MCValue &Target, + const MCFixup &Fixup, bool IsPCRel) const override; +}; +} + +RISCVELFObjectWriter::RISCVELFObjectWriter(uint8_t OSABI, bool Is64Bit) + : MCELFObjectTargetWriter(Is64Bit, OSABI, ELF::EM_RISCV, + /*HasRelocationAddend*/ false) {} + +RISCVELFObjectWriter::~RISCVELFObjectWriter() {} + +unsigned RISCVELFObjectWriter::getRelocType(MCContext &Ctx, + const MCValue &Target, + const MCFixup &Fixup, + bool IsPCRel) const { + // Determine the type of the relocation + switch ((unsigned)Fixup.getKind()) { + default: + llvm_unreachable("invalid fixup kind!"); + } +} + +MCObjectWriter *llvm::createRISCVELFObjectWriter(raw_pwrite_stream &OS, + uint8_t OSABI, bool Is64Bit) { + MCELFObjectTargetWriter *MOTW = new RISCVELFObjectWriter(OSABI, Is64Bit); + return createELFObjectWriter(MOTW, OS, /*IsLittleEndian*/ true); +} diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp new file mode 100644 index 00000000000..b164df8b595 --- /dev/null +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp @@ -0,0 +1,25 @@ +//===-- RISCVMCAsmInfo.cpp - RISCV 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 RISCVMCAsmInfo properties. +// +//===----------------------------------------------------------------------===// + +#include "RISCVMCAsmInfo.h" +#include "llvm/ADT/Triple.h" +using namespace llvm; + +void RISCVMCAsmInfo::anchor() {} + +RISCVMCAsmInfo::RISCVMCAsmInfo(const Triple &TT) { + PointerSize = CalleeSaveStackSlotSize = TT.isArch64Bit() ? 8 : 4; + CommentString = "#"; + AlignmentIsInBytes = false; + SupportsDebugInformation = true; +} diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.h new file mode 100644 index 00000000000..901a1eba8af --- /dev/null +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.h @@ -0,0 +1,31 @@ +//===-- RISCVMCAsmInfo.h - RISCV Asm Info ----------------------*- 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 RISCVMCAsmInfo class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVMCASMINFO_H +#define LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVMCASMINFO_H + +#include "llvm/MC/MCAsmInfoELF.h" + +namespace llvm { +class Triple; + +class RISCVMCAsmInfo : public MCAsmInfoELF { + void anchor() override; + +public: + explicit RISCVMCAsmInfo(const Triple &TargetTriple); +}; + +} // namespace llvm + +#endif diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp new file mode 100644 index 00000000000..b2ed13758d4 --- /dev/null +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp @@ -0,0 +1,91 @@ +//===-- RISCVMCCodeEmitter.cpp - Convert RISCV 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 RISCVMCCodeEmitter class. +// +//===----------------------------------------------------------------------===// + +#include "MCTargetDesc/RISCVMCTargetDesc.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/MC/MCCodeEmitter.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCInst.h" +#include "llvm/MC/MCRegisterInfo.h" +#include "llvm/MC/MCSymbol.h" +#include "llvm/MC/MCAsmInfo.h" +#include "llvm/Support/EndianStream.h" +#include "llvm/Support/raw_ostream.h" + +using namespace llvm; + +#define DEBUG_TYPE "mccodeemitter" + +STATISTIC(MCNumEmitted, "Number of MC instructions emitted"); + +namespace { +class RISCVMCCodeEmitter : public MCCodeEmitter { + RISCVMCCodeEmitter(const RISCVMCCodeEmitter &) = delete; + void operator=(const RISCVMCCodeEmitter &) = delete; + MCContext &Ctx; + +public: + RISCVMCCodeEmitter(MCContext &ctx) : Ctx(ctx) {} + + ~RISCVMCCodeEmitter() override {} + + void encodeInstruction(const MCInst &MI, raw_ostream &OS, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const override; + + /// TableGen'erated function for getting the binary encoding for an + /// instruction. + uint64_t getBinaryCodeForInstr(const MCInst &MI, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const; + + /// Return binary encoding of operand. If the machine operand requires + /// relocation, record the relocation and return zero. + unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const; +}; +} // end anonymous namespace + +MCCodeEmitter *llvm::createRISCVMCCodeEmitter(const MCInstrInfo &MCII, + const MCRegisterInfo &MRI, + MCContext &Ctx) { + return new RISCVMCCodeEmitter(Ctx); +} + +void RISCVMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const { + // For now, we only support RISC-V instructions with 32-bit length + uint32_t Bits = getBinaryCodeForInstr(MI, Fixups, STI); + support::endian::Writer<support::little>(OS).write(Bits); + ++MCNumEmitted; // Keep track of the # of mi's emitted. +} + +unsigned +RISCVMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const { + + if (MO.isReg()) + return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg()); + + if (MO.isImm()) + return static_cast<unsigned>(MO.getImm()); + + llvm_unreachable("Unhandled expression!"); + return 0; +} + +#include "RISCVGenMCCodeEmitter.inc" diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp new file mode 100644 index 00000000000..4fc69a7fcab --- /dev/null +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp @@ -0,0 +1,59 @@ +//===-- RISCVMCTargetDesc.cpp - RISCV 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 RISCV-specific target descriptions. +/// +//===----------------------------------------------------------------------===// + +#include "RISCVMCTargetDesc.h" +#include "RISCVMCAsmInfo.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCInstrInfo.h" +#include "llvm/MC/MCRegisterInfo.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 "RISCVGenInstrInfo.inc" + +#define GET_REGINFO_MC_DESC +#include "RISCVGenRegisterInfo.inc" + +using namespace llvm; + +static MCInstrInfo *createRISCVMCInstrInfo() { + MCInstrInfo *X = new MCInstrInfo(); + InitRISCVMCInstrInfo(X); + return X; +} + +static MCRegisterInfo *createRISCVMCRegisterInfo(const Triple &TT) { + MCRegisterInfo *X = new MCRegisterInfo(); + InitRISCVMCRegisterInfo(X, RISCV::X1_32); + return X; +} + +static MCAsmInfo *createRISCVMCAsmInfo(const MCRegisterInfo &MRI, + const Triple &TT) { + MCAsmInfo *MAI = new RISCVMCAsmInfo(TT); + return MAI; +} + +extern "C" void LLVMInitializeRISCVTargetMC() { + for (Target *T : {&getTheRISCV32Target(), &getTheRISCV64Target()}) { + RegisterMCAsmInfoFn X(*T, createRISCVMCAsmInfo); + TargetRegistry::RegisterMCInstrInfo(*T, createRISCVMCInstrInfo); + TargetRegistry::RegisterMCRegInfo(*T, createRISCVMCRegisterInfo); + TargetRegistry::RegisterMCAsmBackend(*T, createRISCVAsmBackend); + TargetRegistry::RegisterMCCodeEmitter(*T, createRISCVMCCodeEmitter); + } +} diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.h new file mode 100644 index 00000000000..ddc3bf35045 --- /dev/null +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.h @@ -0,0 +1,58 @@ +//===-- RISCVMCTargetDesc.h - RISCV 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 RISCV specific target descriptions. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVMCTARGETDESC_H +#define LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVMCTARGETDESC_H + +#include "llvm/MC/MCTargetOptions.h" +#include "llvm/Support/DataTypes.h" +#include "llvm/Config/config.h" + +namespace llvm { +class MCAsmBackend; +class MCCodeEmitter; +class MCContext; +class MCInstrInfo; +class MCObjectWriter; +class MCRegisterInfo; +class MCSubtargetInfo; +class StringRef; +class Target; +class Triple; +class raw_ostream; +class raw_pwrite_stream; + +Target &getTheRISCV32Target(); +Target &getTheRISCV64Target(); + +MCCodeEmitter *createRISCVMCCodeEmitter(const MCInstrInfo &MCII, + const MCRegisterInfo &MRI, + MCContext &Ctx); + +MCAsmBackend *createRISCVAsmBackend(const Target &T, const MCRegisterInfo &MRI, + const Triple &TT, StringRef CPU, + const MCTargetOptions &Options); + +MCObjectWriter *createRISCVELFObjectWriter(raw_pwrite_stream &OS, uint8_t OSABI, + bool Is64Bit); +} + +// Defines symbolic names for RISC-V registers. +#define GET_REGINFO_ENUM +#include "RISCVGenRegisterInfo.inc" + +// Defines symbolic names for RISC-V instructions. +#define GET_INSTRINFO_ENUM +#include "RISCVGenInstrInfo.inc" + +#endif diff --git a/llvm/lib/Target/RISCV/RISCVTargetMachine.h b/llvm/lib/Target/RISCV/RISCVTargetMachine.h index b4dd4efe0f9..d13e574c9bf 100644 --- a/llvm/lib/Target/RISCV/RISCVTargetMachine.h +++ b/llvm/lib/Target/RISCV/RISCVTargetMachine.h @@ -14,9 +14,10 @@ #ifndef LLVM_LIB_TARGET_RISCV_RISCVTARGETMACHINE_H #define LLVM_LIB_TARGET_RISCV_RISCVTARGETMACHINE_H +#include "MCTargetDesc/RISCVMCTargetDesc.h" #include "llvm/CodeGen/SelectionDAGTargetInfo.h" -#include "llvm/Target/TargetMachine.h" #include "llvm/IR/DataLayout.h" +#include "llvm/Target/TargetMachine.h" namespace llvm { class RISCVTargetMachine : public LLVMTargetMachine { @@ -34,8 +35,6 @@ public: return TLOF.get(); } }; -Target &getTheRISCV32Target(); -Target &getTheRISCV64Target(); } #endif diff --git a/llvm/lib/Target/RISCV/TargetInfo/RISCVTargetInfo.cpp b/llvm/lib/Target/RISCV/TargetInfo/RISCVTargetInfo.cpp index 3cb657a9978..34932c25915 100644 --- a/llvm/lib/Target/RISCV/TargetInfo/RISCVTargetInfo.cpp +++ b/llvm/lib/Target/RISCV/TargetInfo/RISCVTargetInfo.cpp @@ -28,8 +28,3 @@ extern "C" void LLVMInitializeRISCVTargetInfo() { RegisterTarget<Triple::riscv64> Y(getTheRISCV64Target(), "riscv64", "64-bit RISC-V"); } - -// FIXME: Temporary stub - this function must be defined for linking -// to succeed and will be called unconditionally by llc, so must be a no-op. -// Remove once this function is properly implemented. -extern "C" void LLVMInitializeRISCVTargetMC() {} |