Skip to content

Commit b02203d

Browse files
committed
[MC][Mips] Add MipsWinCOFFObjectWriter/MipsWinCOFFStreamer
Implement GNU and MSVC variants.
1 parent 38bcda6 commit b02203d

13 files changed

+244
-1
lines changed

llvm/lib/Object/COFFObjectFile.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2349,6 +2349,9 @@ ResourceSectionRef::getContents(const coff_resource_data_entry &Entry) {
23492349
case Triple::aarch64:
23502350
RVAReloc = COFF::IMAGE_REL_ARM64_ADDR32NB;
23512351
break;
2352+
case Triple::mipsel:
2353+
RVAReloc = COFF::IMAGE_REL_MIPS_REFWORDNB;
2354+
break;
23522355
default:
23532356
return createStringError(object_error::parse_failed,
23542357
"unsupported architecture");

llvm/lib/Object/WindowsResource.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -992,6 +992,9 @@ void WindowsResourceCOFFWriter::writeFirstSectionRelocations() {
992992
case Triple::aarch64:
993993
Reloc->Type = COFF::IMAGE_REL_ARM64_ADDR32NB;
994994
break;
995+
case Triple::mipsel:
996+
Reloc->Type = COFF::IMAGE_REL_MIPS_REFWORDNB;
997+
break;
995998
default:
996999
llvm_unreachable("unknown machine type");
9971000
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ add_llvm_component_library(LLVMMipsDesc
1212
MipsNaClELFStreamer.cpp
1313
MipsOptionRecord.cpp
1414
MipsTargetStreamer.cpp
15+
MipsWinCOFFObjectWriter.cpp
16+
MipsWinCOFFStreamer.cpp
1517

1618
LINK_COMPONENTS
1719
CodeGenTypes

llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -597,10 +597,31 @@ bool MipsAsmBackend::isMicroMips(const MCSymbol *Sym) const {
597597
return false;
598598
}
599599

600+
namespace {
601+
602+
class WindowsMipsAsmBackend : public MipsAsmBackend {
603+
public:
604+
WindowsMipsAsmBackend(const Target &T, const MCRegisterInfo &MRI,
605+
const MCSubtargetInfo &STI)
606+
: MipsAsmBackend(T, MRI, STI.getTargetTriple(), STI.getCPU(), false) {
607+
}
608+
609+
std::unique_ptr<MCObjectTargetWriter>
610+
createObjectTargetWriter() const override {
611+
return createMipsWinCOFFObjectWriter();
612+
}
613+
};
614+
615+
} // end anonymous namespace
616+
600617
MCAsmBackend *llvm::createMipsAsmBackend(const Target &T,
601618
const MCSubtargetInfo &STI,
602619
const MCRegisterInfo &MRI,
603620
const MCTargetOptions &Options) {
621+
const Triple &TheTriple = STI.getTargetTriple();
622+
if (TheTriple.isOSWindows())
623+
return new WindowsMipsAsmBackend(T, MRI, STI);
624+
604625
MipsABIInfo ABI = MipsABIInfo::computeTargetABI(STI.getTargetTriple(),
605626
STI.getCPU(), Options);
606627
return new MipsAsmBackend(T, MRI, STI.getTargetTriple(), STI.getCPU(),

llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,25 @@ MipsELFMCAsmInfo::MipsELFMCAsmInfo(const Triple &TheTriple,
5151
DwarfRegNumForCFI = true;
5252
HasMipsExpressions = true;
5353
}
54+
55+
void MipsCOFFMCAsmInfoMicrosoft::anchor() { }
56+
57+
MipsCOFFMCAsmInfoMicrosoft::MipsCOFFMCAsmInfoMicrosoft() {
58+
WinEHEncodingType = WinEH::EncodingType::Itanium;
59+
CommentString = ";";
60+
61+
ExceptionsType = ExceptionHandling::WinEH;
62+
63+
AllowAtInName = true;
64+
}
65+
66+
void MipsCOFFMCAsmInfoGNU::anchor() { }
67+
68+
MipsCOFFMCAsmInfoGNU::MipsCOFFMCAsmInfoGNU() {
69+
HasSingleParameterDotFile = true;
70+
WinEHEncodingType = WinEH::EncodingType::Itanium;
71+
72+
ExceptionsType = ExceptionHandling::WinEH;
73+
74+
AllowAtInName = true;
75+
}

llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.h

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

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

1819
namespace llvm {
@@ -26,6 +27,20 @@ class MipsELFMCAsmInfo : public MCAsmInfoELF {
2627
const MCTargetOptions &Options);
2728
};
2829

30+
class MipsCOFFMCAsmInfoMicrosoft : public MCAsmInfoMicrosoft {
31+
void anchor() override;
32+
33+
public:
34+
explicit MipsCOFFMCAsmInfoMicrosoft();
35+
};
36+
37+
class MipsCOFFMCAsmInfoGNU : public MCAsmInfoGNUCOFF {
38+
void anchor() override;
39+
40+
public:
41+
explicit MipsCOFFMCAsmInfoGNU();
42+
};
43+
2944
} // namespace llvm
3045

3146
#endif

llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,13 @@ using namespace llvm;
4545
#define GET_REGINFO_MC_DESC
4646
#include "MipsGenRegisterInfo.inc"
4747

48+
namespace {
49+
class MipsWinCOFFTargetStreamer : public MipsTargetStreamer {
50+
public:
51+
MipsWinCOFFTargetStreamer(MCStreamer &S) : MipsTargetStreamer(S) {}
52+
};
53+
} // end namespace
54+
4855
/// Select the Mips CPU for the given triple and cpu name.
4956
StringRef MIPS_MC::selectMipsCPU(const Triple &TT, StringRef CPU) {
5057
if (CPU.empty() || CPU == "generic") {
@@ -84,7 +91,14 @@ static MCSubtargetInfo *createMipsMCSubtargetInfo(const Triple &TT,
8491
static MCAsmInfo *createMipsMCAsmInfo(const MCRegisterInfo &MRI,
8592
const Triple &TT,
8693
const MCTargetOptions &Options) {
87-
MCAsmInfo *MAI = new MipsELFMCAsmInfo(TT, Options);
94+
MCAsmInfo *MAI;
95+
96+
if (TT.isWindowsMSVCEnvironment())
97+
MAI = new MipsCOFFMCAsmInfoMicrosoft();
98+
else if (TT.isOSWindows())
99+
MAI = new MipsCOFFMCAsmInfoGNU();
100+
else
101+
MAI = new MipsELFMCAsmInfo(TT, Options);
88102

89103
unsigned SP = MRI.getDwarfRegNum(Mips::SP, true);
90104
MCCFIInstruction Inst = MCCFIInstruction::createDefCfaRegister(nullptr, SP);
@@ -127,6 +141,8 @@ static MCTargetStreamer *createMipsNullTargetStreamer(MCStreamer &S) {
127141

128142
static MCTargetStreamer *
129143
createMipsObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) {
144+
if (STI.getTargetTriple().isOSBinFormatCOFF())
145+
return new MipsWinCOFFTargetStreamer(S);
130146
return new MipsTargetELFStreamer(S, STI);
131147
}
132148

@@ -186,6 +202,8 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMipsTargetMC() {
186202
TargetRegistry::RegisterNullTargetStreamer(*T,
187203
createMipsNullTargetStreamer);
188204

205+
TargetRegistry::RegisterCOFFStreamer(*T, createMipsWinCOFFStreamer);
206+
189207
// Register the MC subtarget info.
190208
TargetRegistry::RegisterMCSubtargetInfo(*T, createMipsMCSubtargetInfo);
191209

llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ class MCCodeEmitter;
2323
class MCContext;
2424
class MCInstrInfo;
2525
class MCObjectTargetWriter;
26+
class MCObjectWriter;
2627
class MCRegisterInfo;
28+
class MCStreamer;
2729
class MCSubtargetInfo;
2830
class MCTargetOptions;
2931
class StringRef;
@@ -39,8 +41,21 @@ MCAsmBackend *createMipsAsmBackend(const Target &T, const MCSubtargetInfo &STI,
3941
const MCRegisterInfo &MRI,
4042
const MCTargetOptions &Options);
4143

44+
/// Construct an MIPS Windows COFF machine code streamer which will generate
45+
/// PE/COFF format object files.
46+
///
47+
/// Takes ownership of \p AB and \p CE.
48+
MCStreamer *createMipsWinCOFFStreamer(MCContext &C,
49+
std::unique_ptr<MCAsmBackend> &&AB,
50+
std::unique_ptr<MCObjectWriter> &&OW,
51+
std::unique_ptr<MCCodeEmitter> &&CE);
52+
53+
/// Construct a Mips ELF object writer.
4254
std::unique_ptr<MCObjectTargetWriter>
4355
createMipsELFObjectWriter(const Triple &TT, bool IsN32);
56+
/// Construct a Mips Win COFF object writer.
57+
std::unique_ptr<MCObjectTargetWriter>
58+
createMipsWinCOFFObjectWriter();
4459

4560
namespace MIPS_MC {
4661
StringRef selectMipsCPU(const Triple &TT, StringRef CPU);
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
//===-- MipsWinCOFFObjectWriter.cpp - Mips Win COFF Writer -----------------===//
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/MipsFixupKinds.h"
10+
#include "MCTargetDesc/MipsMCTargetDesc.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 MipsWinCOFFObjectWriter : public MCWinCOFFObjectTargetWriter {
20+
public:
21+
MipsWinCOFFObjectWriter();
22+
23+
unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
24+
const MCFixup &Fixup, bool IsCrossSection,
25+
const MCAsmBackend &MAB) const override;
26+
};
27+
28+
} // end anonymous namespace
29+
30+
MipsWinCOFFObjectWriter::MipsWinCOFFObjectWriter()
31+
: MCWinCOFFObjectTargetWriter(COFF::IMAGE_FILE_MACHINE_R4000) {}
32+
33+
unsigned MipsWinCOFFObjectWriter::getRelocType(MCContext &Ctx,
34+
const MCValue &Target,
35+
const MCFixup &Fixup,
36+
bool IsCrossSection,
37+
const MCAsmBackend &MAB) const {
38+
unsigned FixupKind = Fixup.getKind();
39+
40+
switch (FixupKind) {
41+
case FK_Data_4:
42+
return COFF::IMAGE_REL_MIPS_REFWORD;
43+
case Mips::fixup_Mips_26:
44+
return COFF::IMAGE_REL_MIPS_JMPADDR;
45+
case Mips::fixup_Mips_HI16:
46+
return COFF::IMAGE_REL_MIPS_REFHI;
47+
case Mips::fixup_Mips_LO16:
48+
return COFF::IMAGE_REL_MIPS_REFLO;
49+
default:
50+
Ctx.reportError(Fixup.getLoc(), "unsupported relocation type");
51+
return COFF::IMAGE_REL_MIPS_REFWORD;
52+
}
53+
}
54+
55+
std::unique_ptr<MCObjectTargetWriter>
56+
llvm::createMipsWinCOFFObjectWriter() {
57+
return std::make_unique<MipsWinCOFFObjectWriter>();
58+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//===-- MipsWinCOFFStreamer.cpp - MIPS Target WinCOFF Streamer --*- 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 "MipsMCTargetDesc.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 MipsWinCOFFStreamer : public MCWinCOFFStreamer {
20+
public:
21+
MipsWinCOFFStreamer(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::createMipsWinCOFFStreamer(MCContext &C,
29+
std::unique_ptr<MCAsmBackend> &&AB,
30+
std::unique_ptr<MCObjectWriter> &&OW,
31+
std::unique_ptr<MCCodeEmitter> &&CE) {
32+
return new MipsWinCOFFStreamer(C, std::move(AB), std::move(CE), std::move(OW));
33+
}

llvm/lib/Target/Mips/MipsTargetMachine.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMipsTarget() {
7171
}
7272

7373
static std::unique_ptr<TargetLoweringObjectFile> createTLOF(const Triple &TT) {
74+
if (TT.isOSBinFormatCOFF())
75+
return std::make_unique<TargetLoweringObjectFileCOFF>();
7476
return std::make_unique<MipsTargetObjectFile>();
7577
}
7678

llvm/test/MC/Mips/coff-basic.ll

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
; RUN: llc -mtriple mipsel-windows-msvc -filetype=obj < %s | obj2yaml | FileCheck %s
2+
; RUN: llc -mtriple mipsel-windows-gnu -filetype=obj < %s | obj2yaml | FileCheck %s
3+
4+
define i32 @foo() {
5+
ret i32 0
6+
}
7+
8+
; CHECK: Machine: IMAGE_FILE_MACHINE_R4000

llvm/test/MC/Mips/coff-relocs.ll

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
; RUN: llc -mtriple mipsel-windows-msvc -filetype=obj < %s | obj2yaml | FileCheck %s
2+
; RUN: llc -mtriple mipsel-windows-gnu -filetype=obj < %s | obj2yaml | FileCheck %s
3+
4+
; CHECK: Machine: IMAGE_FILE_MACHINE_R4000
5+
6+
7+
8+
; CHECK: - Name: .text
9+
; CHECK: Relocations:
10+
11+
declare void @bar()
12+
define i32 @foo_jmp() {
13+
call i32 @bar()
14+
; CHECK: - VirtualAddress: 8
15+
; CHECK: SymbolName: bar
16+
; CHECK: Type: IMAGE_REL_MIPS_JMPADDR
17+
ret i32 0
18+
}
19+
20+
@var = external global i32
21+
define i32 @foo_var() {
22+
%1 = load i32, i32* @var
23+
; CHECK: - VirtualAddress: 32
24+
; CHECK: SymbolName: var
25+
; CHECK: Type: IMAGE_REL_MIPS_REFHI
26+
; CHECK: - VirtualAddress: 40
27+
; CHECK: SymbolName: var
28+
; CHECK: Type: IMAGE_REL_MIPS_REFLO
29+
ret i32 %1
30+
}
31+
32+
33+
34+
; CHECK: - Name: .data
35+
; CHECK: Relocations:
36+
37+
%struct._PTR = type { ptr }
38+
39+
@var1 = internal global %struct._PTR { ptr @var2 }
40+
@var2 = external global i32
41+
; CHECK: - VirtualAddress: 0
42+
; CHECK: SymbolName: var2
43+
; CHECK: Type: IMAGE_REL_MIPS_REFWORD

0 commit comments

Comments
 (0)