[lld] [llvm] [clang][MIPS] Add support for mipsel-windows-* targets (PR #107744)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Sep 8 09:37:15 PDT 2024
=?utf-8?q?Hervé?= Poussineau <hpoussin at reactos.org>,
=?utf-8?q?Hervé?= Poussineau <hpoussin at reactos.org>,
=?utf-8?q?Hervé?= Poussineau <hpoussin at reactos.org>,
=?utf-8?q?Hervé?= Poussineau <hpoussin at reactos.org>,
=?utf-8?q?Hervé?= Poussineau <hpoussin at reactos.org>
Message-ID:
In-Reply-To: <llvm.org/llvm/llvm-project/pull/107744 at github.com>
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-binary-utilities
@llvm/pr-subscribers-objectyaml
Author: None (hpoussin)
<details>
<summary>Changes</summary>
- Add support for Windows MIPS relocations types
- Support reading MIPS COFF files in objdump
- Support generating MIPS COFF files in yaml2obj
- Support generating MIPS COFF files in llvm-lib
- Support generating MIPS COFF files in llvm-dlltool
- Support generating MIPS COFF files in clang
Compiler and library creation have been cross-tested with Microsoft counterparts.
Linker part is not yet ready (although available in my [mips-pe](https://github.com/hpoussin/llvm-project/tree/mips-pe) branch).
By using Microsoft linker (or my work-in-process work on lld), I get working executables.
![clang-20-mips](https://github.com/user-attachments/assets/6914fc93-8c07-41de-8bdc-acd64d31b376)
---
Patch is 33.84 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/107744.diff
26 Files Affected:
- (modified) lld/COFF/Config.h (+1)
- (modified) llvm/include/llvm/BinaryFormat/COFF.h (+18)
- (modified) llvm/include/llvm/Object/WindowsMachineFlag.h (+2)
- (modified) llvm/include/llvm/ObjectYAML/COFFYAML.h (+5)
- (modified) llvm/lib/MC/WinCOFFObjectWriter.cpp (+15-2)
- (modified) llvm/lib/Object/COFFObjectFile.cpp (+26)
- (modified) llvm/lib/Object/WindowsMachineFlag.cpp (+4)
- (modified) llvm/lib/Object/WindowsResource.cpp (+3)
- (modified) llvm/lib/ObjectYAML/COFFYAML.cpp (+23)
- (modified) llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp (+3)
- (modified) llvm/lib/Target/Mips/MCTargetDesc/CMakeLists.txt (+2)
- (modified) llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp (+21)
- (modified) llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp (+25-3)
- (modified) llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.h (+18-3)
- (modified) llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp (+19-1)
- (modified) llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.h (+15)
- (added) llvm/lib/Target/Mips/MCTargetDesc/MipsWinCOFFObjectWriter.cpp (+58)
- (added) llvm/lib/Target/Mips/MCTargetDesc/MipsWinCOFFStreamer.cpp (+33)
- (modified) llvm/lib/Target/Mips/MipsAsmPrinter.cpp (+59-56)
- (modified) llvm/lib/Target/Mips/MipsTargetMachine.cpp (+7-1)
- (modified) llvm/lib/TargetParser/Triple.cpp (+5-1)
- (added) llvm/test/MC/Mips/coff-basic.ll (+8)
- (added) llvm/test/MC/Mips/coff-relocs.ll (+46)
- (added) llvm/test/Object/Inputs/COFF/mipsel.yaml (+8)
- (modified) llvm/test/Object/objdump-section-content.test (+4)
- (modified) llvm/unittests/TargetParser/TripleTest.cpp (+3)
``````````diff
diff --git a/lld/COFF/Config.h b/lld/COFF/Config.h
index 947f3fead54e03..a7984753c7e917 100644
--- a/lld/COFF/Config.h
+++ b/lld/COFF/Config.h
@@ -40,6 +40,7 @@ static const auto ARM64EC = llvm::COFF::IMAGE_FILE_MACHINE_ARM64EC;
static const auto ARM64X = llvm::COFF::IMAGE_FILE_MACHINE_ARM64X;
static const auto ARMNT = llvm::COFF::IMAGE_FILE_MACHINE_ARMNT;
static const auto I386 = llvm::COFF::IMAGE_FILE_MACHINE_I386;
+static const auto MIPS = llvm::COFF::IMAGE_FILE_MACHINE_R4000;
enum class ExportSource {
Unset,
diff --git a/llvm/include/llvm/BinaryFormat/COFF.h b/llvm/include/llvm/BinaryFormat/COFF.h
index 3fc543f73c49db..bbc5264d17872a 100644
--- a/llvm/include/llvm/BinaryFormat/COFF.h
+++ b/llvm/include/llvm/BinaryFormat/COFF.h
@@ -417,6 +417,24 @@ enum RelocationTypesARM64 : unsigned {
IMAGE_REL_ARM64_REL32 = 0x0011,
};
+enum RelocationTypesMips : unsigned {
+ IMAGE_REL_MIPS_ABSOLUTE = 0x0000,
+ IMAGE_REL_MIPS_REFHALF = 0x0001,
+ IMAGE_REL_MIPS_REFWORD = 0x0002,
+ IMAGE_REL_MIPS_JMPADDR = 0x0003,
+ IMAGE_REL_MIPS_REFHI = 0x0004,
+ IMAGE_REL_MIPS_REFLO = 0x0005,
+ IMAGE_REL_MIPS_GPREL = 0x0006,
+ IMAGE_REL_MIPS_LITERAL = 0x0007,
+ IMAGE_REL_MIPS_SECTION = 0x000A,
+ IMAGE_REL_MIPS_SECREL = 0x000B,
+ IMAGE_REL_MIPS_SECRELLO = 0x000C,
+ IMAGE_REL_MIPS_SECRELHI = 0x000D,
+ IMAGE_REL_MIPS_JMPADDR16 = 0x0010,
+ IMAGE_REL_MIPS_REFWORDNB = 0x0022,
+ IMAGE_REL_MIPS_PAIR = 0x0025,
+};
+
enum DynamicRelocationType : unsigned {
IMAGE_DYNAMIC_RELOCATION_GUARD_RF_PROLOGUE = 1,
IMAGE_DYNAMIC_RELOCATION_GUARD_RF_EPILOGUE = 2,
diff --git a/llvm/include/llvm/Object/WindowsMachineFlag.h b/llvm/include/llvm/Object/WindowsMachineFlag.h
index 1cb408ed13d420..ce5b356f8bfeed 100644
--- a/llvm/include/llvm/Object/WindowsMachineFlag.h
+++ b/llvm/include/llvm/Object/WindowsMachineFlag.h
@@ -43,6 +43,8 @@ template <typename T> Triple::ArchType getMachineArchType(T machine) {
case COFF::IMAGE_FILE_MACHINE_ARM64EC:
case COFF::IMAGE_FILE_MACHINE_ARM64X:
return llvm::Triple::ArchType::aarch64;
+ case COFF::IMAGE_FILE_MACHINE_R4000:
+ return llvm::Triple::ArchType::mipsel;
default:
return llvm::Triple::ArchType::UnknownArch;
}
diff --git a/llvm/include/llvm/ObjectYAML/COFFYAML.h b/llvm/include/llvm/ObjectYAML/COFFYAML.h
index 2f9a1aae0eb05a..f7797fc7f67bcd 100644
--- a/llvm/include/llvm/ObjectYAML/COFFYAML.h
+++ b/llvm/include/llvm/ObjectYAML/COFFYAML.h
@@ -179,6 +179,11 @@ struct ScalarEnumerationTraits<COFF::RelocationTypeAMD64> {
static void enumeration(IO &IO, COFF::RelocationTypeAMD64 &Value);
};
+template <>
+struct ScalarEnumerationTraits<COFF::RelocationTypesMips> {
+ static void enumeration(IO &IO, COFF::RelocationTypesMips &Value);
+};
+
template <>
struct ScalarEnumerationTraits<COFF::RelocationTypesARM> {
static void enumeration(IO &IO, COFF::RelocationTypesARM &Value);
diff --git a/llvm/lib/MC/WinCOFFObjectWriter.cpp b/llvm/lib/MC/WinCOFFObjectWriter.cpp
index 62f53423126ea9..d5a30d332d2b92 100644
--- a/llvm/lib/MC/WinCOFFObjectWriter.cpp
+++ b/llvm/lib/MC/WinCOFFObjectWriter.cpp
@@ -773,7 +773,10 @@ void WinCOFFWriter::assignFileOffsets(MCAssembler &Asm) {
for (auto &Relocation : Sec->Relocations) {
assert(Relocation.Symb->getIndex() != -1);
- Relocation.Data.SymbolTableIndex = Relocation.Symb->getIndex();
+ if (Header.Machine != COFF::IMAGE_FILE_MACHINE_R4000 ||
+ Relocation.Data.Type != COFF::IMAGE_REL_MIPS_PAIR) {
+ Relocation.Data.SymbolTableIndex = Relocation.Symb->getIndex();
+ }
}
}
@@ -967,8 +970,18 @@ void WinCOFFWriter::recordRelocation(MCAssembler &Asm,
if (Fixup.getKind() == FK_SecRel_2)
FixedValue = 0;
- if (OWriter.TargetObjectWriter->recordRelocation(Fixup))
+ if (OWriter.TargetObjectWriter->recordRelocation(Fixup)) {
Sec->Relocations.push_back(Reloc);
+ if (Header.Machine == COFF::IMAGE_FILE_MACHINE_R4000 &&
+ (Reloc.Data.Type == COFF::IMAGE_REL_MIPS_REFHI ||
+ Reloc.Data.Type == COFF::IMAGE_REL_MIPS_SECRELHI)) {
+ // IMAGE_REL_MIPS_REFHI and IMAGE_REL_MIPS_SECRELHI *must*
+ // be followed by IMAGE_REL_MIPS_PAIR
+ auto RelocPair = Reloc;
+ RelocPair.Data.Type = COFF::IMAGE_REL_MIPS_PAIR;
+ Sec->Relocations.push_back(RelocPair);
+ }
+ }
}
static std::time_t getTime() {
diff --git a/llvm/lib/Object/COFFObjectFile.cpp b/llvm/lib/Object/COFFObjectFile.cpp
index 5fdf3baf8c02cc..ad15d42135b319 100644
--- a/llvm/lib/Object/COFFObjectFile.cpp
+++ b/llvm/lib/Object/COFFObjectFile.cpp
@@ -1132,6 +1132,8 @@ StringRef COFFObjectFile::getFileFormatName() const {
return "COFF-ARM64EC";
case COFF::IMAGE_FILE_MACHINE_ARM64X:
return "COFF-ARM64X";
+ case COFF::IMAGE_FILE_MACHINE_R4000:
+ return "COFF-R4000";
default:
return "COFF-<unknown arch>";
}
@@ -1465,6 +1467,27 @@ StringRef COFFObjectFile::getRelocationTypeName(uint16_t Type) const {
return "Unknown";
}
break;
+ case Triple::mipsel:
+ switch (Type) {
+ LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_MIPS_ABSOLUTE);
+ LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_MIPS_REFHALF);
+ LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_MIPS_REFWORD);
+ LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_MIPS_JMPADDR);
+ LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_MIPS_REFHI);
+ LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_MIPS_REFLO);
+ LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_MIPS_GPREL);
+ LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_MIPS_LITERAL);
+ LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_MIPS_SECTION);
+ LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_MIPS_SECREL);
+ LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_MIPS_SECRELLO);
+ LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_MIPS_SECRELHI);
+ LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_MIPS_JMPADDR16);
+ LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_MIPS_REFWORDNB);
+ LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_MIPS_PAIR);
+ default:
+ return "Unknown";
+ }
+ break;
default:
return "Unknown";
}
@@ -2326,6 +2349,9 @@ ResourceSectionRef::getContents(const coff_resource_data_entry &Entry) {
case Triple::aarch64:
RVAReloc = COFF::IMAGE_REL_ARM64_ADDR32NB;
break;
+ case Triple::mipsel:
+ RVAReloc = COFF::IMAGE_REL_MIPS_REFWORDNB;
+ break;
default:
return createStringError(object_error::parse_failed,
"unsupported architecture");
diff --git a/llvm/lib/Object/WindowsMachineFlag.cpp b/llvm/lib/Object/WindowsMachineFlag.cpp
index b9f818775768a2..bade2d4f0f6a74 100644
--- a/llvm/lib/Object/WindowsMachineFlag.cpp
+++ b/llvm/lib/Object/WindowsMachineFlag.cpp
@@ -28,6 +28,8 @@ COFF::MachineTypes llvm::getMachineType(StringRef S) {
.Case("arm64", COFF::IMAGE_FILE_MACHINE_ARM64)
.Case("arm64ec", COFF::IMAGE_FILE_MACHINE_ARM64EC)
.Case("arm64x", COFF::IMAGE_FILE_MACHINE_ARM64X)
+ .Case("mips", COFF::IMAGE_FILE_MACHINE_R4000) // also handle mips (big-endian) because we want to support '/machine:MIPS'
+ .Case("mipsel", COFF::IMAGE_FILE_MACHINE_R4000)
.Default(COFF::IMAGE_FILE_MACHINE_UNKNOWN);
}
@@ -45,6 +47,8 @@ StringRef llvm::machineToStr(COFF::MachineTypes MT) {
return "x64";
case COFF::IMAGE_FILE_MACHINE_I386:
return "x86";
+ case COFF::IMAGE_FILE_MACHINE_R4000:
+ return "mipsel";
default:
llvm_unreachable("unknown machine type");
}
diff --git a/llvm/lib/Object/WindowsResource.cpp b/llvm/lib/Object/WindowsResource.cpp
index 306e8ec542068b..211e581a7da6a9 100644
--- a/llvm/lib/Object/WindowsResource.cpp
+++ b/llvm/lib/Object/WindowsResource.cpp
@@ -992,6 +992,9 @@ void WindowsResourceCOFFWriter::writeFirstSectionRelocations() {
case Triple::aarch64:
Reloc->Type = COFF::IMAGE_REL_ARM64_ADDR32NB;
break;
+ case Triple::mipsel:
+ Reloc->Type = COFF::IMAGE_REL_MIPS_REFWORDNB;
+ break;
default:
llvm_unreachable("unknown machine type");
}
diff --git a/llvm/lib/ObjectYAML/COFFYAML.cpp b/llvm/lib/ObjectYAML/COFFYAML.cpp
index e14e1b5e467b41..53ea40a0354cea 100644
--- a/llvm/lib/ObjectYAML/COFFYAML.cpp
+++ b/llvm/lib/ObjectYAML/COFFYAML.cpp
@@ -183,6 +183,25 @@ void ScalarEnumerationTraits<COFF::RelocationTypeAMD64>::enumeration(
ECase(IMAGE_REL_AMD64_SSPAN32);
}
+void ScalarEnumerationTraits<COFF::RelocationTypesMips>::enumeration(
+ IO &IO, COFF::RelocationTypesMips &Value) {
+ ECase(IMAGE_REL_MIPS_ABSOLUTE);
+ ECase(IMAGE_REL_MIPS_REFHALF);
+ ECase(IMAGE_REL_MIPS_REFWORD);
+ ECase(IMAGE_REL_MIPS_JMPADDR);
+ ECase(IMAGE_REL_MIPS_REFHI);
+ ECase(IMAGE_REL_MIPS_REFLO);
+ ECase(IMAGE_REL_MIPS_GPREL);
+ ECase(IMAGE_REL_MIPS_LITERAL);
+ ECase(IMAGE_REL_MIPS_SECTION);
+ ECase(IMAGE_REL_MIPS_SECREL);
+ ECase(IMAGE_REL_MIPS_SECRELLO);
+ ECase(IMAGE_REL_MIPS_SECRELHI);
+ ECase(IMAGE_REL_MIPS_JMPADDR16);
+ ECase(IMAGE_REL_MIPS_REFWORDNB);
+ ECase(IMAGE_REL_MIPS_PAIR);
+}
+
void ScalarEnumerationTraits<COFF::RelocationTypesARM>::enumeration(
IO &IO, COFF::RelocationTypesARM &Value) {
ECase(IMAGE_REL_ARM_ABSOLUTE);
@@ -427,6 +446,10 @@ void MappingTraits<COFFYAML::Relocation>::mapping(IO &IO,
MappingNormalization<NType<COFF::RelocationTypeAMD64>, uint16_t> NT(
IO, Rel.Type);
IO.mapRequired("Type", NT->Type);
+ } else if (H.Machine == COFF::IMAGE_FILE_MACHINE_R4000) {
+ MappingNormalization<NType<COFF::RelocationTypesMips>, uint16_t> NT(
+ IO, Rel.Type);
+ IO.mapRequired("Type", NT->Type);
} else if (H.Machine == COFF::IMAGE_FILE_MACHINE_ARMNT) {
MappingNormalization<NType<COFF::RelocationTypesARM>, uint16_t> NT(
IO, Rel.Type);
diff --git a/llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp b/llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp
index e1d2700623ec3c..26d71e624aee5b 100644
--- a/llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp
+++ b/llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp
@@ -171,6 +171,9 @@ void ScalarEnumerationTraits<RegisterId>::enumeration(IO &io, RegisterId &Reg) {
case COFF::IMAGE_FILE_MACHINE_ARM64X:
CpuType = CPUType::ARM64;
break;
+ case COFF::IMAGE_FILE_MACHINE_R4000:
+ CpuType = CPUType::MIPSIII;
+ break;
}
if (CpuType)
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..16318cffd7470e 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp
@@ -597,10 +597,31 @@ 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())
+ 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 f89c78e75d3ee7..960256bc38f244 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp
@@ -16,10 +16,10 @@
using namespace llvm;
-void MipsMCAsmInfo::anchor() { }
+void MipsELFMCAsmInfo::anchor() { }
-MipsMCAsmInfo::MipsMCAsmInfo(const Triple &TheTriple,
- const MCTargetOptions &Options) {
+MipsELFMCAsmInfo::MipsELFMCAsmInfo(const Triple &TheTriple,
+ const MCTargetOptions &Options) {
IsLittleEndian = TheTriple.isLittleEndian();
MipsABIInfo ABI = MipsABIInfo::computeTargetABI(TheTriple, "", Options);
@@ -51,3 +51,25 @@ MipsMCAsmInfo::MipsMCAsmInfo(const Triple &TheTriple,
DwarfRegNumForCFI = true;
HasMipsExpressions = true;
}
+
+void MipsCOFFMCAsmInfoMicrosoft::anchor() { }
+
+MipsCOFFMCAsmInfoMicrosoft::MipsCOFFMCAsmInfoMicrosoft() {
+ WinEHEncodingType = WinEH::EncodingType::Itanium;
+ CommentString = ";";
+
+ ExceptionsType = ExceptionHandling::WinEH;
+
+ AllowAtInName = true;
+}
+
+void MipsCOFFMCAsmInfoGNU::anchor() { }
+
+MipsCOFFMCAsmInfoGNU::MipsCOFFMCAsmInfoGNU() {
+ 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 d8bfe58d24a838..96348b17e57696 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.h
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.h
@@ -13,17 +13,32 @@
#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 {
class Triple;
-class MipsMCAsmInfo : public MCAsmInfoELF {
+class MipsELFMCAsmInfo : public MCAsmInfoELF {
void anchor() override;
public:
- explicit MipsMCAsmInfo(const Triple &TheTriple,
- const MCTargetOptions &Options);
+ explicit MipsELFMCAsmInfo(const Triple &TheTriple,
+ const MCTargetOptions &Options);
+};
+
+class MipsCOFFMCAsmInfoMicrosoft : public MCAsmInfoMicrosoft {
+ void anchor() override;
+
+public:
+ explicit MipsCOFFMCAsmInfoMicrosoft();
+};
+
+class MipsCOFFMCAsmInfoGNU : public MCAsmInfoGNUCOFF {
+ void anchor() override;
+
+public:
+ explicit MipsCOFFMCAsmInfoGNU();
};
} // namespace llvm
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp
index ca95f67174da1e..378cc12388bae3 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,14 @@ static MCSubtargetInfo *createMipsMCSubtargetInfo(const Triple &TT,
static MCAsmInfo *createMipsMCAsmInfo(const MCRegisterInfo &MRI,
const Triple &TT,
const MCTargetOptions &Options) {
- MCAsmInfo *MAI = new MipsMCAsmInfo(TT, Options);
+ MCAsmInfo *MAI;
+
+ if (TT.isWindowsMSVCEnvironment())
+ MAI = new MipsCOFFMCAsmInfoMicrosoft();
+ else if (TT.isOSWindows())
+ MAI = new MipsCOFFMCAsmInfoGNU();
+ else
+ MAI = new MipsELFMCAsmInfo(TT, Options);
unsigned SP = MRI.getDwarfRegNum(Mips::SP, true);
MCCFIInstruction Inst = MCCFIInstruction::createDefCfaRegister(nullptr, SP);
@@ -127,6 +141,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 +202,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..a02e4fa2208880 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,21 @@ 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..d014cc1b0c1b55
--- /dev/null
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsWinCOFFObjectWriter.cpp
@@ -0,0 +1,58 @@
+//===-- MipsWinCOFFObjectWriter.cpp - Mips Win 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 "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_...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/107744
More information about the llvm-commits
mailing list