-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[MC][Mips] Add MipsWinCOFFObjectWriter/MipsWinCOFFStreamer #114611
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
@llvm/pr-subscribers-debuginfo @llvm/pr-subscribers-mc Author: Hervé Poussineau (hpoussin) Changesllc is now able to create MIPS COFF files for simple cases. Full diff: https://github.com/llvm/llvm-project/pull/114611.diff 11 Files Affected:
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/CMakeLists.txt b/llvm/lib/Target/Mips/MCTargetDesc/CMakeLists.txt
index 97a6f886d114ec..d3f16e5042c3ac 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/CMakeLists.txt
+++ b/llvm/lib/Target/Mips/MCTargetDesc/CMakeLists.txt
@@ -12,6 +12,8 @@ add_llvm_component_library(LLVMMipsDesc
MipsNaClELFStreamer.cpp
MipsOptionRecord.cpp
MipsTargetStreamer.cpp
+ MipsWinCOFFObjectWriter.cpp
+ MipsWinCOFFStreamer.cpp
LINK_COMPONENTS
CodeGenTypes
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp
index f8172e576ce4c1..c40372995a9126 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp
@@ -597,10 +597,30 @@ bool MipsAsmBackend::isMicroMips(const MCSymbol *Sym) const {
return false;
}
+namespace {
+
+class WindowsMipsAsmBackend : public MipsAsmBackend {
+public:
+ WindowsMipsAsmBackend(const Target &T, const MCRegisterInfo &MRI,
+ const MCSubtargetInfo &STI)
+ : MipsAsmBackend(T, MRI, STI.getTargetTriple(), STI.getCPU(), false) {}
+
+ std::unique_ptr<MCObjectTargetWriter>
+ createObjectTargetWriter() const override {
+ return createMipsWinCOFFObjectWriter();
+ }
+};
+
+} // end anonymous namespace
+
MCAsmBackend *llvm::createMipsAsmBackend(const Target &T,
const MCSubtargetInfo &STI,
const MCRegisterInfo &MRI,
const MCTargetOptions &Options) {
+ const Triple &TheTriple = STI.getTargetTriple();
+ if (TheTriple.isOSWindows() && TheTriple.isOSBinFormatCOFF())
+ return new WindowsMipsAsmBackend(T, MRI, STI);
+
MipsABIInfo ABI = MipsABIInfo::computeTargetABI(STI.getTargetTriple(),
STI.getCPU(), Options);
return new MipsAsmBackend(T, MRI, STI.getTargetTriple(), STI.getCPU(),
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp
index 074a58cadb556d..fa09a14b3e2380 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp
@@ -51,3 +51,14 @@ MipsELFMCAsmInfo::MipsELFMCAsmInfo(const Triple &TheTriple,
DwarfRegNumForCFI = true;
HasMipsExpressions = true;
}
+
+void MipsCOFFMCAsmInfo::anchor() {}
+
+MipsCOFFMCAsmInfo::MipsCOFFMCAsmInfo() {
+ HasSingleParameterDotFile = true;
+ WinEHEncodingType = WinEH::EncodingType::Itanium;
+
+ ExceptionsType = ExceptionHandling::WinEH;
+
+ AllowAtInName = true;
+}
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.h
index b52ed12d3a0e77..3a2895a79f9c7f 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.h
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.h
@@ -13,6 +13,7 @@
#ifndef LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSMCASMINFO_H
#define LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSMCASMINFO_H
+#include "llvm/MC/MCAsmInfoCOFF.h"
#include "llvm/MC/MCAsmInfoELF.h"
namespace llvm {
@@ -26,6 +27,13 @@ class MipsELFMCAsmInfo : public MCAsmInfoELF {
const MCTargetOptions &Options);
};
+class MipsCOFFMCAsmInfo : public MCAsmInfoGNUCOFF {
+ void anchor() override;
+
+public:
+ explicit MipsCOFFMCAsmInfo();
+};
+
} // namespace llvm
#endif
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp
index eff9ecf0d53d31..2d44a8582b1364 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp
@@ -45,6 +45,13 @@ using namespace llvm;
#define GET_REGINFO_MC_DESC
#include "MipsGenRegisterInfo.inc"
+namespace {
+class MipsWinCOFFTargetStreamer : public MipsTargetStreamer {
+public:
+ MipsWinCOFFTargetStreamer(MCStreamer &S) : MipsTargetStreamer(S) {}
+};
+} // end namespace
+
/// Select the Mips CPU for the given triple and cpu name.
StringRef MIPS_MC::selectMipsCPU(const Triple &TT, StringRef CPU) {
if (CPU.empty() || CPU == "generic") {
@@ -84,7 +91,12 @@ static MCSubtargetInfo *createMipsMCSubtargetInfo(const Triple &TT,
static MCAsmInfo *createMipsMCAsmInfo(const MCRegisterInfo &MRI,
const Triple &TT,
const MCTargetOptions &Options) {
- MCAsmInfo *MAI = new MipsELFMCAsmInfo(TT, Options);
+ MCAsmInfo *MAI;
+
+ if (TT.isOSWindows())
+ MAI = new MipsCOFFMCAsmInfo();
+ else
+ MAI = new MipsELFMCAsmInfo(TT, Options);
unsigned SP = MRI.getDwarfRegNum(Mips::SP, true);
MCCFIInstruction Inst = MCCFIInstruction::createDefCfaRegister(nullptr, SP);
@@ -127,6 +139,8 @@ static MCTargetStreamer *createMipsNullTargetStreamer(MCStreamer &S) {
static MCTargetStreamer *
createMipsObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) {
+ if (STI.getTargetTriple().isOSBinFormatCOFF())
+ return new MipsWinCOFFTargetStreamer(S);
return new MipsTargetELFStreamer(S, STI);
}
@@ -186,6 +200,8 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMipsTargetMC() {
TargetRegistry::RegisterNullTargetStreamer(*T,
createMipsNullTargetStreamer);
+ TargetRegistry::RegisterCOFFStreamer(*T, createMipsWinCOFFStreamer);
+
// Register the MC subtarget info.
TargetRegistry::RegisterMCSubtargetInfo(*T, createMipsMCSubtargetInfo);
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.h
index d51f3b9abcfd1b..c5293b03b0ac5a 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.h
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.h
@@ -23,7 +23,9 @@ class MCCodeEmitter;
class MCContext;
class MCInstrInfo;
class MCObjectTargetWriter;
+class MCObjectWriter;
class MCRegisterInfo;
+class MCStreamer;
class MCSubtargetInfo;
class MCTargetOptions;
class StringRef;
@@ -39,8 +41,20 @@ MCAsmBackend *createMipsAsmBackend(const Target &T, const MCSubtargetInfo &STI,
const MCRegisterInfo &MRI,
const MCTargetOptions &Options);
+/// Construct an MIPS Windows COFF machine code streamer which will generate
+/// PE/COFF format object files.
+///
+/// Takes ownership of \p AB and \p CE.
+MCStreamer *createMipsWinCOFFStreamer(MCContext &C,
+ std::unique_ptr<MCAsmBackend> &&AB,
+ std::unique_ptr<MCObjectWriter> &&OW,
+ std::unique_ptr<MCCodeEmitter> &&CE);
+
+/// Construct a Mips ELF object writer.
std::unique_ptr<MCObjectTargetWriter>
createMipsELFObjectWriter(const Triple &TT, bool IsN32);
+/// Construct a Mips Win COFF object writer.
+std::unique_ptr<MCObjectTargetWriter> createMipsWinCOFFObjectWriter();
namespace MIPS_MC {
StringRef selectMipsCPU(const Triple &TT, StringRef CPU);
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsWinCOFFObjectWriter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsWinCOFFObjectWriter.cpp
new file mode 100644
index 00000000000000..94187c71ba70d6
--- /dev/null
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsWinCOFFObjectWriter.cpp
@@ -0,0 +1,57 @@
+//===- MipsWinCOFFObjectWriter.cpp------------------------------*- C++ -*-===//
+//
+// 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 "MCTargetDesc/MipsFixupKinds.h"
+#include "MCTargetDesc/MipsMCTargetDesc.h"
+#include "llvm/BinaryFormat/COFF.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCWinCOFFObjectWriter.h"
+
+using namespace llvm;
+
+namespace {
+
+class MipsWinCOFFObjectWriter : public MCWinCOFFObjectTargetWriter {
+public:
+ MipsWinCOFFObjectWriter();
+
+ unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
+ const MCFixup &Fixup, bool IsCrossSection,
+ const MCAsmBackend &MAB) const override;
+};
+
+} // end anonymous namespace
+
+MipsWinCOFFObjectWriter::MipsWinCOFFObjectWriter()
+ : MCWinCOFFObjectTargetWriter(COFF::IMAGE_FILE_MACHINE_R4000) {}
+
+unsigned MipsWinCOFFObjectWriter::getRelocType(MCContext &Ctx,
+ const MCValue &Target,
+ const MCFixup &Fixup,
+ bool IsCrossSection,
+ const MCAsmBackend &MAB) const {
+ unsigned FixupKind = Fixup.getKind();
+
+ switch (FixupKind) {
+ case FK_Data_4:
+ return COFF::IMAGE_REL_MIPS_REFWORD;
+ case Mips::fixup_Mips_26:
+ return COFF::IMAGE_REL_MIPS_JMPADDR;
+ case Mips::fixup_Mips_HI16:
+ return COFF::IMAGE_REL_MIPS_REFHI;
+ case Mips::fixup_Mips_LO16:
+ return COFF::IMAGE_REL_MIPS_REFLO;
+ default:
+ Ctx.reportError(Fixup.getLoc(), "unsupported relocation type");
+ return COFF::IMAGE_REL_MIPS_REFWORD;
+ }
+}
+
+std::unique_ptr<MCObjectTargetWriter> llvm::createMipsWinCOFFObjectWriter() {
+ return std::make_unique<MipsWinCOFFObjectWriter>();
+}
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsWinCOFFStreamer.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsWinCOFFStreamer.cpp
new file mode 100644
index 00000000000000..22bf2e1be203cf
--- /dev/null
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsWinCOFFStreamer.cpp
@@ -0,0 +1,33 @@
+//===- MipsWinCOFFStreamer.cpp-----------------------------------*- C++ -*-===//
+//
+// 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 "MipsMCTargetDesc.h"
+#include "llvm/MC/MCAsmBackend.h"
+#include "llvm/MC/MCAssembler.h"
+#include "llvm/MC/MCCodeEmitter.h"
+#include "llvm/MC/MCObjectWriter.h"
+#include "llvm/MC/MCWinCOFFStreamer.h"
+
+using namespace llvm;
+
+namespace {
+class MipsWinCOFFStreamer : public MCWinCOFFStreamer {
+public:
+ MipsWinCOFFStreamer(MCContext &C, std::unique_ptr<MCAsmBackend> AB,
+ std::unique_ptr<MCCodeEmitter> CE,
+ std::unique_ptr<MCObjectWriter> OW)
+ : MCWinCOFFStreamer(C, std::move(AB), std::move(CE), std::move(OW)) {}
+};
+} // namespace
+
+MCStreamer *llvm::createMipsWinCOFFStreamer(
+ MCContext &C, std::unique_ptr<MCAsmBackend> &&AB,
+ std::unique_ptr<MCObjectWriter> &&OW, std::unique_ptr<MCCodeEmitter> &&CE) {
+ return new MipsWinCOFFStreamer(C, std::move(AB), std::move(CE),
+ std::move(OW));
+}
diff --git a/llvm/lib/Target/Mips/MipsTargetMachine.cpp b/llvm/lib/Target/Mips/MipsTargetMachine.cpp
index c7dbcc80148ae4..a98f636d5d867a 100644
--- a/llvm/lib/Target/Mips/MipsTargetMachine.cpp
+++ b/llvm/lib/Target/Mips/MipsTargetMachine.cpp
@@ -71,6 +71,8 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMipsTarget() {
}
static std::unique_ptr<TargetLoweringObjectFile> createTLOF(const Triple &TT) {
+ if (TT.isOSBinFormatCOFF())
+ return std::make_unique<TargetLoweringObjectFileCOFF>();
return std::make_unique<MipsTargetObjectFile>();
}
diff --git a/llvm/test/MC/Mips/coff-basic.ll b/llvm/test/MC/Mips/coff-basic.ll
new file mode 100644
index 00000000000000..4c25cd659c5c79
--- /dev/null
+++ b/llvm/test/MC/Mips/coff-basic.ll
@@ -0,0 +1,7 @@
+; RUN: llc -mtriple mipsel-windows -filetype=obj < %s | obj2yaml | FileCheck %s
+
+define i32 @foo() {
+ ret i32 0
+}
+
+; CHECK: Machine: IMAGE_FILE_MACHINE_R4000
diff --git a/llvm/test/MC/Mips/coff-relocs.ll b/llvm/test/MC/Mips/coff-relocs.ll
new file mode 100644
index 00000000000000..1d8b3f192d7af6
--- /dev/null
+++ b/llvm/test/MC/Mips/coff-relocs.ll
@@ -0,0 +1,42 @@
+; RUN: llc -mtriple mipsel-windows -filetype=obj < %s | obj2yaml | FileCheck %s
+
+; CHECK: Machine: IMAGE_FILE_MACHINE_R4000
+
+
+
+; CHECK: - Name: .text
+; CHECK: Relocations:
+
+declare void @bar()
+define i32 @foo_jmp() {
+ call i32 @bar()
+; CHECK: - VirtualAddress: 8
+; CHECK: SymbolName: bar
+; CHECK: Type: IMAGE_REL_MIPS_JMPADDR
+ ret i32 0
+}
+
+@var = external global i32
+define i32 @foo_var() {
+ %1 = load i32, i32* @var
+; CHECK: - VirtualAddress: 32
+; CHECK: SymbolName: var
+; CHECK: Type: IMAGE_REL_MIPS_REFHI
+; CHECK: - VirtualAddress: 40
+; CHECK: SymbolName: var
+; CHECK: Type: IMAGE_REL_MIPS_REFLO
+ ret i32 %1
+}
+
+
+
+; CHECK: - Name: .data
+; CHECK: Relocations:
+
+%struct._PTR = type { ptr }
+
+@var1 = internal global %struct._PTR { ptr @var2 }
+@var2 = external global i32
+; CHECK: - VirtualAddress: 0
+; CHECK: SymbolName: var2
+; CHECK: Type: IMAGE_REL_MIPS_REFWORD
|
|
This is an extract of PR #107744 |
97455c2 to
9b4615b
Compare
a59cce1 to
2e4d28e
Compare
|
Depends of PR #114678 to prevent some failures in unit tests |
|
Ping. |
|
This part LGTM @wzssyqa. |
|
Ping. |
1 similar comment
|
Ping. |
|
LGTM. |
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
This will be required once MIPS architecture defaults to COFF files on Windows platforms.
llc is now able to create MIPS COFF files for simple cases.
f749369 to
3319256
Compare
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/98/builds/893 Here is the relevant piece of the build log for the reference |
llc is now able to create MIPS COFF files for simple cases.