Index: llvm/lib/Target/RISCV/MCTargetDesc/CMakeLists.txt =================================================================== --- llvm/lib/Target/RISCV/MCTargetDesc/CMakeLists.txt +++ llvm/lib/Target/RISCV/MCTargetDesc/CMakeLists.txt @@ -11,6 +11,7 @@ RISCVMatInt.cpp RISCVTargetStreamer.cpp RISCVELFStreamer.cpp + RISCVWinCOFFObjectWriter.cpp LINK_COMPONENTS MC Index: llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h =================================================================== --- llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h +++ llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h @@ -22,17 +22,15 @@ class raw_ostream; class RISCVAsmBackend : public MCAsmBackend { - const MCSubtargetInfo &STI; - uint8_t OSABI; - bool Is64Bit; bool ForceRelocs = false; const MCTargetOptions &TargetOptions; +protected: + const MCSubtargetInfo &STI; + public: - RISCVAsmBackend(const MCSubtargetInfo &STI, uint8_t OSABI, bool Is64Bit, - const MCTargetOptions &Options) - : MCAsmBackend(support::little), STI(STI), OSABI(OSABI), Is64Bit(Is64Bit), - TargetOptions(Options) { + RISCVAsmBackend(const MCSubtargetInfo &STI, const MCTargetOptions &Options) + : MCAsmBackend(support::little), TargetOptions(Options), STI(STI) { RISCVFeatures::validate(STI.getTargetTriple(), STI.getFeatureBits()); } ~RISCVAsmBackend() override = default; @@ -58,9 +56,6 @@ uint64_t Value, bool IsResolved, const MCSubtargetInfo *STI) const override; - std::unique_ptr - createObjectTargetWriter() const override; - bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup, const MCValue &Target) override; Index: llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp =================================================================== --- llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp +++ llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp @@ -651,16 +651,43 @@ return true; } -std::unique_ptr -RISCVAsmBackend::createObjectTargetWriter() const { - return createRISCVELFObjectWriter(OSABI, Is64Bit); -} +class ELFRISCVAsmBackend : public RISCVAsmBackend { + uint8_t OSABI; + bool Is64Bit; + +public: + ELFRISCVAsmBackend(const MCSubtargetInfo &STI, uint8_t OSABI, bool Is64Bit, + const MCTargetOptions &Options) + : RISCVAsmBackend(STI, Options), OSABI(OSABI), Is64Bit(Is64Bit) {} + + std::unique_ptr + createObjectTargetWriter() const override { + return createRISCVELFObjectWriter(OSABI, Is64Bit); + } +}; + +class COFFRISCVAsmBackend : public RISCVAsmBackend { +public: + COFFRISCVAsmBackend(const MCSubtargetInfo &STI, + const MCTargetOptions &Options) + : RISCVAsmBackend(STI, Options) {} + + std::unique_ptr + createObjectTargetWriter() const override { + return createRISCVWinCOFFObjectWriter(STI.getTargetTriple()); + } +}; MCAsmBackend *llvm::createRISCVAsmBackend(const Target &T, const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, const MCTargetOptions &Options) { const Triple &TT = STI.getTargetTriple(); + + if (TT.isOSBinFormatCOFF()) + return new COFFRISCVAsmBackend(STI, Options); + uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TT.getOS()); - return new RISCVAsmBackend(STI, OSABI, TT.isArch64Bit(), Options); + + return new ELFRISCVAsmBackend(STI, OSABI, TT.isArch64Bit(), Options); } Index: llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.h =================================================================== --- llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.h +++ llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.h @@ -27,6 +27,7 @@ class MCRegisterInfo; class MCSubtargetInfo; class Target; +class Triple; MCCodeEmitter *createRISCVMCCodeEmitter(const MCInstrInfo &MCII, MCContext &Ctx); @@ -37,6 +38,9 @@ std::unique_ptr createRISCVELFObjectWriter(uint8_t OSABI, bool Is64Bit); + +std::unique_ptr +createRISCVWinCOFFObjectWriter(const Triple &TheTriple); } // Defines symbolic names for RISC-V registers. Index: llvm/lib/Target/RISCV/MCTargetDesc/RISCVWinCOFFObjectWriter.cpp =================================================================== --- /dev/null +++ llvm/lib/Target/RISCV/MCTargetDesc/RISCVWinCOFFObjectWriter.cpp @@ -0,0 +1,62 @@ +//===-- RISCVWinCOFFObjectWriter.cpp - RISC-V Windows COFF Writer --------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===---------------------------------------------------------------------===// + +#include "RISCVMCTargetDesc.h" +#include "llvm/BinaryFormat/COFF.h" +#include "llvm/MC/MCAsmBackend.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCFixup.h" +#include "llvm/MC/MCObjectWriter.h" +#include "llvm/MC/MCValue.h" +#include "llvm/MC/MCWinCOFFObjectWriter.h" +#include "llvm/Support/ErrorHandling.h" + +using namespace llvm; + +class RISCVWinCOFFObjectWriter : public MCWinCOFFObjectTargetWriter { +public: + RISCVWinCOFFObjectWriter(const Triple &TheTriple); + ~RISCVWinCOFFObjectWriter() override = default; + + unsigned getRelocType(MCContext &Ctx, const MCValue &Target, + const MCFixup &Fixup, bool IsCrossSection, + const MCAsmBackend &MAB) const override; +}; + +static unsigned RISCVWinCOFFMachineFromTriple(const Triple &TheTriple) { + if (TheTriple.isRISCV32()) { + return COFF::IMAGE_FILE_MACHINE_RISCV32; + } else if (TheTriple.isRISCV64()) { + return COFF::IMAGE_FILE_MACHINE_RISCV64; + } else { + // FIXME: once TheTriple.isRISCV128() is implemented, + // map it to COFF::IMAGE_FILE_MACHINE_RISCV128 + llvm_unreachable("Unsupported triple for RISCVWinCOFFObjectWriter"); + } +} + +RISCVWinCOFFObjectWriter::RISCVWinCOFFObjectWriter(const Triple &TheTriple) + : MCWinCOFFObjectTargetWriter(RISCVWinCOFFMachineFromTriple(TheTriple)) {} + +unsigned RISCVWinCOFFObjectWriter::getRelocType(MCContext &Ctx, + const MCValue &Target, + const MCFixup &Fixup, + bool IsCrossSection, + const MCAsmBackend &MAB) const { + // RISCV does not have Windows COFF relocation type definitions yet; + // Add getRelocType functions here once those types have a chance to be + // declared. + report_fatal_error( + "RISCV does not have Windows COFF relocation type definitions yet"); +} + +std::unique_ptr +llvm::createRISCVWinCOFFObjectWriter(const Triple &TheTriple) { + return std::make_unique(TheTriple); +} Index: llvm/utils/gn/secondary/llvm/lib/Target/RISCV/MCTargetDesc/BUILD.gn =================================================================== --- llvm/utils/gn/secondary/llvm/lib/Target/RISCV/MCTargetDesc/BUILD.gn +++ llvm/utils/gn/secondary/llvm/lib/Target/RISCV/MCTargetDesc/BUILD.gn @@ -74,5 +74,6 @@ "RISCVMCTargetDesc.cpp", "RISCVMatInt.cpp", "RISCVTargetStreamer.cpp", + "RISCVWinCOFFObjectWriter.cpp", ] }