Skip to content

Commit 1bebbb2

Browse files
committed
Initial adding PE/COFF file output support to RISC-V target
1 parent 05325c2 commit 1bebbb2

File tree

8 files changed

+164
-1
lines changed

8 files changed

+164
-1
lines changed

llvm/lib/Target/RISCV/MCTargetDesc/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ add_llvm_component_library(LLVMRISCVDesc
1111
RISCVMatInt.cpp
1212
RISCVTargetStreamer.cpp
1313
RISCVELFStreamer.cpp
14+
RISCVWinCOFFObjectWriter.cpp
15+
RISCVWinCOFFStreamer.cpp
1416

1517
LINK_COMPONENTS
1618
MC

llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -895,6 +895,30 @@ bool RISCVAsmBackend::shouldInsertFixupForCodeAlign(MCAssembler &Asm,
895895
return true;
896896
}
897897

898+
namespace {
899+
900+
class WindowsRISCVAsmBackend : public RISCVAsmBackend {
901+
bool is64Bit;
902+
903+
public:
904+
WindowsRISCVAsmBackend(const Target &T, const MCSubtargetInfo &STI,
905+
const MCRegisterInfo &MRI,
906+
const MCTargetOptions &Options)
907+
: RISCVAsmBackend(
908+
STI,
909+
MCELFObjectTargetWriter::getOSABI(STI.getTargetTriple().getOS()),
910+
STI.getTargetTriple().isArch64Bit(), Options) {
911+
is64Bit = STI.getTargetTriple().isArch64Bit();
912+
}
913+
914+
std::unique_ptr<MCObjectTargetWriter>
915+
createObjectTargetWriter() const override {
916+
return createRISCVWinCOFFObjectWriter(is64Bit);
917+
}
918+
};
919+
920+
} // namespace
921+
898922
std::unique_ptr<MCObjectTargetWriter>
899923
RISCVAsmBackend::createObjectTargetWriter() const {
900924
return createRISCVELFObjectWriter(OSABI, Is64Bit);
@@ -905,6 +929,11 @@ MCAsmBackend *llvm::createRISCVAsmBackend(const Target &T,
905929
const MCRegisterInfo &MRI,
906930
const MCTargetOptions &Options) {
907931
const Triple &TT = STI.getTargetTriple();
932+
933+
if (TT.isOSWindows() && TT.isOSBinFormatCOFF()) {
934+
return new WindowsRISCVAsmBackend(T, STI, MRI, Options);
935+
}
936+
908937
uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TT.getOS());
909938
return new RISCVAsmBackend(STI, OSABI, TT.isArch64Bit(), Options);
910939
}

llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,15 @@ void RISCVMCAsmInfo::printSpecifierExpr(raw_ostream &OS,
5757
if (HasSpecifier)
5858
OS << ')';
5959
}
60+
61+
62+
void RISCVCOFFMCAsmInfo::anchor() {}
63+
64+
RISCVCOFFMCAsmInfo::RISCVCOFFMCAsmInfo() {
65+
HasSingleParameterDotFile = true;
66+
WinEHEncodingType = WinEH::EncodingType::Itanium;
67+
68+
ExceptionsType = ExceptionHandling::WinEH;
69+
70+
AllowAtInName = true;
71+
}

llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#ifndef LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVMCASMINFO_H
1414
#define LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVMCASMINFO_H
1515

16+
#include "llvm/MC/MCAsmInfoCOFF.h"
1617
#include "llvm/MC/MCAsmInfoELF.h"
1718
#include "llvm/MC/MCFixup.h"
1819

@@ -31,6 +32,13 @@ class RISCVMCAsmInfo : public MCAsmInfoELF {
3132
const MCSpecifierExpr &Expr) const override;
3233
};
3334

35+
class RISCVCOFFMCAsmInfo : public MCAsmInfoGNUCOFF {
36+
void anchor() override;
37+
38+
public:
39+
explicit RISCVCOFFMCAsmInfo();
40+
};
41+
3442
namespace RISCV {
3543
using Specifier = uint16_t;
3644
// Specifiers mapping to relocation types below FirstTargetFixupKind are

llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,13 @@
4444

4545
using namespace llvm;
4646

47+
namespace {
48+
class RISCVWinCOFFTargetStreamer : public RISCVTargetStreamer {
49+
public:
50+
RISCVWinCOFFTargetStreamer(MCStreamer &S) : RISCVTargetStreamer(S) {}
51+
};
52+
} // end namespace
53+
4754
static MCInstrInfo *createRISCVMCInstrInfo() {
4855
MCInstrInfo *X = new MCInstrInfo();
4956
InitRISCVMCInstrInfo(X);
@@ -59,7 +66,13 @@ static MCRegisterInfo *createRISCVMCRegisterInfo(const Triple &TT) {
5966
static MCAsmInfo *createRISCVMCAsmInfo(const MCRegisterInfo &MRI,
6067
const Triple &TT,
6168
const MCTargetOptions &Options) {
62-
MCAsmInfo *MAI = new RISCVMCAsmInfo(TT);
69+
MCAsmInfo *MAI;
70+
71+
if(TT.isOSWindows()){
72+
MAI = new RISCVCOFFMCAsmInfo();
73+
} else {
74+
MAI = new RISCVMCAsmInfo(TT);
75+
}
6376

6477
unsigned SP = MRI.getDwarfRegNum(RISCV::X2, true);
6578
MCCFIInstruction Inst = MCCFIInstruction::cfiDefCfa(nullptr, SP, 0);
@@ -110,6 +123,8 @@ static MCInstPrinter *createRISCVMCInstPrinter(const Triple &T,
110123
static MCTargetStreamer *
111124
createRISCVObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) {
112125
const Triple &TT = STI.getTargetTriple();
126+
if(TT.isOSBinFormatCOFF())
127+
return new RISCVWinCOFFTargetStreamer(S);
113128
if (TT.isOSBinFormatELF())
114129
return new RISCVTargetELFStreamer(S, STI);
115130
return nullptr;
@@ -344,6 +359,7 @@ LLVMInitializeRISCVTargetMC() {
344359
TargetRegistry::RegisterMCInstPrinter(*T, createRISCVMCInstPrinter);
345360
TargetRegistry::RegisterMCSubtargetInfo(*T, createRISCVMCSubtargetInfo);
346361
TargetRegistry::RegisterELFStreamer(*T, createRISCVELFStreamer);
362+
TargetRegistry::RegisterCOFFStreamer(*T, createRISCVWinCOFFStreamer);
347363
TargetRegistry::RegisterObjectTargetStreamer(
348364
*T, createRISCVObjectTargetStreamer);
349365
TargetRegistry::RegisterMCInstrAnalysis(*T, createRISCVInstrAnalysis);

llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
#ifndef LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVMCTARGETDESC_H
1414
#define LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVMCTARGETDESC_H
1515

16+
#include "llvm/MC/MCObjectWriter.h"
17+
#include "llvm/MC/MCStreamer.h"
1618
#include "llvm/MC/MCTargetOptions.h"
1719
#include "llvm/Support/DataTypes.h"
1820
#include <memory>
@@ -23,7 +25,9 @@ class MCCodeEmitter;
2325
class MCContext;
2426
class MCInstrInfo;
2527
class MCObjectTargetWriter;
28+
class MCObjectWriter;
2629
class MCRegisterInfo;
30+
class MCStreamer;
2731
class MCSubtargetInfo;
2832
class Target;
2933

@@ -34,8 +38,16 @@ MCAsmBackend *createRISCVAsmBackend(const Target &T, const MCSubtargetInfo &STI,
3438
const MCRegisterInfo &MRI,
3539
const MCTargetOptions &Options);
3640

41+
MCStreamer *createRISCVWinCOFFStreamer(MCContext &C,
42+
std::unique_ptr<MCAsmBackend> &&AB,
43+
std::unique_ptr<MCObjectWriter> &&OW,
44+
std::unique_ptr<MCCodeEmitter> &&CE);
45+
3746
std::unique_ptr<MCObjectTargetWriter> createRISCVELFObjectWriter(uint8_t OSABI,
3847
bool Is64Bit);
48+
49+
std::unique_ptr<MCObjectTargetWriter> createRISCVWinCOFFObjectWriter(bool Is64Bit);
50+
3951
} // namespace llvm
4052

4153
// Defines symbolic names for RISC-V registers.
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
//===- RISCVWinCOFFObjectWriter.cpp-----------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===---------------------------------------------------------------------===//
8+
9+
#include "MCTargetDesc/RISCVFixupKinds.h"
10+
#include "MCTargetDesc/RISCVMCTargetDesc.h"
11+
#include "llvm/BinaryFormat/COFF.h"
12+
#include "llvm/MC/MCContext.h"
13+
#include "llvm/MC/MCWinCOFFObjectWriter.h"
14+
15+
using namespace llvm;
16+
17+
namespace {
18+
19+
class RISCVWinCOFFObjectWriter : public MCWinCOFFObjectTargetWriter {
20+
public:
21+
RISCVWinCOFFObjectWriter(bool Is64Bit);
22+
23+
unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
24+
const MCFixup &Fixup, bool IsCrossSection,
25+
const MCAsmBackend &MAB) const override;
26+
};
27+
28+
} // namespace
29+
30+
RISCVWinCOFFObjectWriter::RISCVWinCOFFObjectWriter(bool Is64Bit)
31+
: MCWinCOFFObjectTargetWriter(Is64Bit ? COFF::IMAGE_FILE_MACHINE_RISCV64
32+
: COFF::IMAGE_FILE_MACHINE_RISCV32) {}
33+
34+
unsigned RISCVWinCOFFObjectWriter::getRelocType(MCContext &Ctx,
35+
const MCValue &Target,
36+
const MCFixup &Fixup,
37+
bool IsCrossSection,
38+
const MCAsmBackend &MAB) const {
39+
unsigned FixupKind = Fixup.getKind();
40+
41+
switch (FixupKind) {
42+
default:
43+
Ctx.reportError(Fixup.getLoc(), "unsupported relocation type");
44+
return COFF::IMAGE_REL_BASED_RISCV_HI20; // FIXME
45+
}
46+
}
47+
48+
std::unique_ptr<MCObjectTargetWriter>
49+
llvm::createRISCVWinCOFFObjectWriter(bool Is64Bit) {
50+
return std::make_unique<RISCVWinCOFFObjectWriter>(Is64Bit);
51+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//===- RISCVWinCOFFStreamer.cpp----------------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===---------------------------------------------------------------------===//
8+
9+
#include "RISCVMCTargetDesc.h"
10+
#include "llvm/MC/MCAsmBackend.h"
11+
#include "llvm/MC/MCAssembler.h"
12+
#include "llvm/MC/MCCodeEmitter.h"
13+
#include "llvm/MC/MCObjectWriter.h"
14+
#include "llvm/MC/MCWinCOFFStreamer.h"
15+
16+
using namespace llvm;
17+
18+
namespace {
19+
class RISCVWinCOFFStreamer : public MCWinCOFFStreamer {
20+
public:
21+
RISCVWinCOFFStreamer(MCContext &C, std::unique_ptr<MCAsmBackend> AB,
22+
std::unique_ptr<MCCodeEmitter> CE,
23+
std::unique_ptr<MCObjectWriter> OW)
24+
: MCWinCOFFStreamer(C, std::move(AB), std::move(CE), std::move(OW)) {}
25+
};
26+
} // namespace
27+
28+
MCStreamer *llvm::createRISCVWinCOFFStreamer(
29+
MCContext &C, std::unique_ptr<MCAsmBackend> &&AB,
30+
std::unique_ptr<MCObjectWriter> &&OW, std::unique_ptr<MCCodeEmitter> &&CE) {
31+
return new RISCVWinCOFFStreamer(C, std::move(AB), std::move(CE),
32+
std::move(OW));
33+
}

0 commit comments

Comments
 (0)