[clang] [lld] [llvm] [clang][MIPS] Add support for mipsel-windows-* targets (PR #107744)
via cfe-commits
cfe-commits at lists.llvm.org
Sun Sep 8 13:32:53 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>,
=?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>,
=?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>
https://github.com/hpoussin updated https://github.com/llvm/llvm-project/pull/107744
>From 193f3d3d60c2c9742db50dcb47d689b7968b08d9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= <hpoussin at reactos.org>
Date: Sun, 22 Oct 2023 07:19:08 +0200
Subject: [PATCH 01/13] [Triple] Make mipsel-*-windows-* use COFF files by
default
Windows NT/MIPS and Windows CE/MIPS always used COFF format.
---
llvm/lib/TargetParser/Triple.cpp | 6 +++++-
llvm/unittests/TargetParser/TripleTest.cpp | 3 +++
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/TargetParser/Triple.cpp b/llvm/lib/TargetParser/Triple.cpp
index 55911a7d71ac70..18e2d4fa465f8f 100644
--- a/llvm/lib/TargetParser/Triple.cpp
+++ b/llvm/lib/TargetParser/Triple.cpp
@@ -905,7 +905,6 @@ static Triple::ObjectFormatType getDefaultFormat(const Triple &T) {
case Triple::mips64:
case Triple::mips64el:
case Triple::mips:
- case Triple::mipsel:
case Triple::msp430:
case Triple::nvptx64:
case Triple::nvptx:
@@ -930,6 +929,11 @@ static Triple::ObjectFormatType getDefaultFormat(const Triple &T) {
case Triple::xtensa:
return Triple::ELF;
+ case Triple::mipsel:
+ if (T.isOSWindows())
+ return Triple::COFF;
+ return Triple::ELF;
+
case Triple::ppc64:
case Triple::ppc:
if (T.isOSAIX())
diff --git a/llvm/unittests/TargetParser/TripleTest.cpp b/llvm/unittests/TargetParser/TripleTest.cpp
index 0aecfc64da2080..1beb52088941e9 100644
--- a/llvm/unittests/TargetParser/TripleTest.cpp
+++ b/llvm/unittests/TargetParser/TripleTest.cpp
@@ -2302,6 +2302,9 @@ TEST(TripleTest, NormalizeWindows) {
Triple::normalize("i686-pc-windows-elf-elf"));
EXPECT_TRUE(Triple("x86_64-pc-win32").isWindowsMSVCEnvironment());
+
+ EXPECT_TRUE(Triple(Triple::normalize("mipsel-windows-msvccoff")).isOSBinFormatCOFF());
+ EXPECT_TRUE(Triple(Triple::normalize("mipsel-windows-msvc")).isOSBinFormatCOFF());
}
TEST(TripleTest, NormalizeAndroid) {
>From f99b2ea9f3f744500acaab0c05a346250e0e7751 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= <hpoussin at reactos.org>
Date: Sun, 22 Oct 2023 07:30:37 +0200
Subject: [PATCH 02/13] [COFF] Add MIPS relocation types
Add the MIPS COFF relocation types. They will be needed to add support for
MIPS Windows object file.
---
llvm/include/llvm/BinaryFormat/COFF.h | 18 ++++++++++++++++++
llvm/lib/Object/COFFObjectFile.cpp | 21 +++++++++++++++++++++
2 files changed, 39 insertions(+)
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/lib/Object/COFFObjectFile.cpp b/llvm/lib/Object/COFFObjectFile.cpp
index 5fdf3baf8c02cc..f55138bb23907a 100644
--- a/llvm/lib/Object/COFFObjectFile.cpp
+++ b/llvm/lib/Object/COFFObjectFile.cpp
@@ -1465,6 +1465,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";
}
>From db61c9193d3e7c6eeffce98314d349fa94d0381d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= <hpoussin at reactos.org>
Date: Sun, 22 Oct 2023 08:00:06 +0200
Subject: [PATCH 03/13] [yaml2obj][objdump] Handle IMAGE_FILE_MACHINE_R4000
machine type and MIPS COFF relocations
llvm-objdump can now parse MIPS COFF files.
---
lld/COFF/Config.h | 1 +
llvm/include/llvm/Object/WindowsMachineFlag.h | 2 ++
llvm/include/llvm/ObjectYAML/COFFYAML.h | 5 ++++
llvm/lib/Object/COFFObjectFile.cpp | 2 ++
llvm/lib/Object/WindowsMachineFlag.cpp | 4 ++++
llvm/lib/ObjectYAML/COFFYAML.cpp | 23 +++++++++++++++++++
llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp | 3 +++
llvm/test/Object/Inputs/COFF/mipsel.yaml | 8 +++++++
llvm/test/Object/objdump-section-content.test | 4 ++++
9 files changed, 52 insertions(+)
create mode 100644 llvm/test/Object/Inputs/COFF/mipsel.yaml
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/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/Object/COFFObjectFile.cpp b/llvm/lib/Object/COFFObjectFile.cpp
index f55138bb23907a..4b3999126c89fb 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>";
}
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/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/test/Object/Inputs/COFF/mipsel.yaml b/llvm/test/Object/Inputs/COFF/mipsel.yaml
new file mode 100644
index 00000000000000..0d23dfb77ac0bf
--- /dev/null
+++ b/llvm/test/Object/Inputs/COFF/mipsel.yaml
@@ -0,0 +1,8 @@
+!COFF
+header: !Header
+ Machine: IMAGE_FILE_MACHINE_R4000 # (0x166)
+ Characteristics: [ IMAGE_FILE_DEBUG_STRIPPED ]
+
+sections:
+
+symbols:
diff --git a/llvm/test/Object/objdump-section-content.test b/llvm/test/Object/objdump-section-content.test
index d4c2cd8190b7c1..ce084677a980bf 100644
--- a/llvm/test/Object/objdump-section-content.test
+++ b/llvm/test/Object/objdump-section-content.test
@@ -39,3 +39,7 @@ Sections:
# BSS: Contents of section .bss:
# BSS-NEXT: <skipping contents of bss section at [12c8, 12cc)>
+
+# RUN: yaml2obj %p/Inputs/COFF/mipsel.yaml | llvm-objdump -s - | FileCheck %s --check-prefix=COFF-R4000
+
+# COFF-R4000: <stdin>: file format coff-r4000
>From 38bcda668912f9c6e9b899daba9666482c069c2b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= <hpoussin at reactos.org>
Date: Sun, 22 Oct 2023 08:12:10 +0200
Subject: [PATCH 04/13] [MC][Mips] Rename MipsMCAsmInfo to MipsELFMCAsmInfo
Also change MipsAsmPrinter::emitStartOfAsmFile to emit ELF-related
sections only when using ELF output file format.
---
.../Mips/MCTargetDesc/MipsMCAsmInfo.cpp | 6 +-
.../Target/Mips/MCTargetDesc/MipsMCAsmInfo.h | 6 +-
.../Mips/MCTargetDesc/MipsMCTargetDesc.cpp | 2 +-
llvm/lib/Target/Mips/MipsAsmPrinter.cpp | 115 +++++++++---------
llvm/lib/Target/Mips/MipsTargetMachine.cpp | 6 +-
5 files changed, 71 insertions(+), 64 deletions(-)
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp
index f89c78e75d3ee7..c112b3abe0ba75 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);
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.h
index d8bfe58d24a838..b52ed12d3a0e77 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.h
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.h
@@ -18,12 +18,12 @@
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);
};
} // namespace llvm
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp
index ca95f67174da1e..eff9ecf0d53d31 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp
@@ -84,7 +84,7 @@ 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 = new MipsELFMCAsmInfo(TT, Options);
unsigned SP = MRI.getDwarfRegNum(Mips::SP, true);
MCCFIInstruction Inst = MCCFIInstruction::createDefCfaRegister(nullptr, SP);
diff --git a/llvm/lib/Target/Mips/MipsAsmPrinter.cpp b/llvm/lib/Target/Mips/MipsAsmPrinter.cpp
index e267a6d0844c64..89b79693a83dcf 100644
--- a/llvm/lib/Target/Mips/MipsAsmPrinter.cpp
+++ b/llvm/lib/Target/Mips/MipsAsmPrinter.cpp
@@ -734,70 +734,73 @@ printRegisterList(const MachineInstr *MI, int opNum, raw_ostream &O) {
}
void MipsAsmPrinter::emitStartOfAsmFile(Module &M) {
- MipsTargetStreamer &TS = getTargetStreamer();
-
- // MipsTargetStreamer has an initialization order problem when emitting an
- // object file directly (see MipsTargetELFStreamer for full details). Work
- // around it by re-initializing the PIC state here.
- TS.setPic(OutContext.getObjectFileInfo()->isPositionIndependent());
-
- // Try to get target-features from the first function.
- StringRef FS = TM.getTargetFeatureString();
- Module::iterator F = M.begin();
- if (FS.empty() && M.size() && F->hasFnAttribute("target-features"))
- FS = F->getFnAttribute("target-features").getValueAsString();
-
- // Compute MIPS architecture attributes based on the default subtarget
- // that we'd have constructed.
- // FIXME: For ifunc related functions we could iterate over and look
- // for a feature string that doesn't match the default one.
const Triple &TT = TM.getTargetTriple();
- StringRef CPU = MIPS_MC::selectMipsCPU(TT, TM.getTargetCPU());
- const MipsTargetMachine &MTM = static_cast<const MipsTargetMachine &>(TM);
- const MipsSubtarget STI(TT, CPU, FS, MTM.isLittleEndian(), MTM, std::nullopt);
-
- bool IsABICalls = STI.isABICalls();
- const MipsABIInfo &ABI = MTM.getABI();
- if (IsABICalls) {
- TS.emitDirectiveAbiCalls();
- // FIXME: This condition should be a lot more complicated that it is here.
- // Ideally it should test for properties of the ABI and not the ABI
- // itself.
- // For the moment, I'm only correcting enough to make MIPS-IV work.
- if (!isPositionIndependent() && STI.hasSym32())
- TS.emitDirectiveOptionPic0();
- }
- // Tell the assembler which ABI we are using
- std::string SectionName = std::string(".mdebug.") + getCurrentABIString();
- OutStreamer->switchSection(
- OutContext.getELFSection(SectionName, ELF::SHT_PROGBITS, 0));
+ if (TT.isOSBinFormatELF()) {
+ MipsTargetStreamer &TS = getTargetStreamer();
+
+ // MipsTargetStreamer has an initialization order problem when emitting an
+ // object file directly (see MipsTargetELFStreamer for full details). Work
+ // around it by re-initializing the PIC state here.
+ TS.setPic(OutContext.getObjectFileInfo()->isPositionIndependent());
+
+ // Try to get target-features from the first function.
+ StringRef FS = TM.getTargetFeatureString();
+ Module::iterator F = M.begin();
+ if (FS.empty() && M.size() && F->hasFnAttribute("target-features"))
+ FS = F->getFnAttribute("target-features").getValueAsString();
+
+ // Compute MIPS architecture attributes based on the default subtarget
+ // that we'd have constructed.
+ // FIXME: For ifunc related functions we could iterate over and look
+ // for a feature string that doesn't match the default one.
+ StringRef CPU = MIPS_MC::selectMipsCPU(TT, TM.getTargetCPU());
+ const MipsTargetMachine &MTM = static_cast<const MipsTargetMachine &>(TM);
+ const MipsSubtarget STI(TT, CPU, FS, MTM.isLittleEndian(), MTM, std::nullopt);
+
+ bool IsABICalls = STI.isABICalls();
+ const MipsABIInfo &ABI = MTM.getABI();
+ if (IsABICalls) {
+ TS.emitDirectiveAbiCalls();
+ // FIXME: This condition should be a lot more complicated that it is here.
+ // Ideally it should test for properties of the ABI and not the ABI
+ // itself.
+ // For the moment, I'm only correcting enough to make MIPS-IV work.
+ if (!isPositionIndependent() && STI.hasSym32())
+ TS.emitDirectiveOptionPic0();
+ }
+
+ // Tell the assembler which ABI we are using
+ std::string SectionName = std::string(".mdebug.") + getCurrentABIString();
+ OutStreamer->switchSection(
+ OutContext.getELFSection(SectionName, ELF::SHT_PROGBITS, 0));
- // NaN: At the moment we only support:
- // 1. .nan legacy (default)
- // 2. .nan 2008
- STI.isNaN2008() ? TS.emitDirectiveNaN2008()
- : TS.emitDirectiveNaNLegacy();
+ // NaN: At the moment we only support:
+ // 1. .nan legacy (default)
+ // 2. .nan 2008
+ STI.isNaN2008() ? TS.emitDirectiveNaN2008()
+ : TS.emitDirectiveNaNLegacy();
- // TODO: handle O64 ABI
+ // TODO: handle O64 ABI
- TS.updateABIInfo(STI);
+ TS.updateABIInfo(STI);
- // We should always emit a '.module fp=...' but binutils 2.24 does not accept
- // it. We therefore emit it when it contradicts the ABI defaults (-mfpxx or
- // -mfp64) and omit it otherwise.
- if ((ABI.IsO32() && (STI.isABI_FPXX() || STI.isFP64bit())) ||
- STI.useSoftFloat())
- TS.emitDirectiveModuleFP();
+ // We should always emit a '.module fp=...' but binutils 2.24 does not accept
+ // it. We therefore emit it when it contradicts the ABI defaults (-mfpxx or
+ // -mfp64) and omit it otherwise.
+ if ((ABI.IsO32() && (STI.isABI_FPXX() || STI.isFP64bit())) ||
+ STI.useSoftFloat())
+ TS.emitDirectiveModuleFP();
- // We should always emit a '.module [no]oddspreg' but binutils 2.24 does not
- // accept it. We therefore emit it when it contradicts the default or an
- // option has changed the default (i.e. FPXX) and omit it otherwise.
- if (ABI.IsO32() && (!STI.useOddSPReg() || STI.isABI_FPXX()))
- TS.emitDirectiveModuleOddSPReg();
+ // We should always emit a '.module [no]oddspreg' but binutils 2.24 does not
+ // accept it. We therefore emit it when it contradicts the default or an
+ // option has changed the default (i.e. FPXX) and omit it otherwise.
+ if (ABI.IsO32() && (!STI.useOddSPReg() || STI.isABI_FPXX()))
+ TS.emitDirectiveModuleOddSPReg();
- // Switch to the .text section.
- OutStreamer->switchSection(getObjFileLowering().getTextSection());
+ // Switch to the .text section.
+ OutStreamer->switchSection(getObjFileLowering().getTextSection());
+ }
}
void MipsAsmPrinter::emitInlineAsmStart() const {
diff --git a/llvm/lib/Target/Mips/MipsTargetMachine.cpp b/llvm/lib/Target/Mips/MipsTargetMachine.cpp
index 7802767e31c2f6..c7dbcc80148ae4 100644
--- a/llvm/lib/Target/Mips/MipsTargetMachine.cpp
+++ b/llvm/lib/Target/Mips/MipsTargetMachine.cpp
@@ -70,6 +70,10 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMipsTarget() {
initializeMipsDAGToDAGISelLegacyPass(*PR);
}
+static std::unique_ptr<TargetLoweringObjectFile> createTLOF(const Triple &TT) {
+ return std::make_unique<MipsTargetObjectFile>();
+}
+
static std::string computeDataLayout(const Triple &TT, StringRef CPU,
const TargetOptions &Options,
bool isLittle) {
@@ -128,7 +132,7 @@ MipsTargetMachine::MipsTargetMachine(const Target &T, const Triple &TT,
: LLVMTargetMachine(T, computeDataLayout(TT, CPU, Options, isLittle), TT,
CPU, FS, Options, getEffectiveRelocModel(JIT, RM),
getEffectiveCodeModel(CM, CodeModel::Small), OL),
- isLittle(isLittle), TLOF(std::make_unique<MipsTargetObjectFile>()),
+ isLittle(isLittle), TLOF(createTLOF(getTargetTriple())),
ABI(MipsABIInfo::computeTargetABI(TT, CPU, Options.MCOptions)),
Subtarget(nullptr),
DefaultSubtarget(TT, CPU, FS, isLittle, *this, std::nullopt),
>From b02203d8120a99ac5c3b042245cdd1c0f6815a4b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= <hpoussin at reactos.org>
Date: Sun, 22 Oct 2023 09:07:52 +0200
Subject: [PATCH 05/13] [MC][Mips] Add
MipsWinCOFFObjectWriter/MipsWinCOFFStreamer
Implement GNU and MSVC variants.
---
llvm/lib/Object/COFFObjectFile.cpp | 3 +
llvm/lib/Object/WindowsResource.cpp | 3 +
.../Target/Mips/MCTargetDesc/CMakeLists.txt | 2 +
.../Mips/MCTargetDesc/MipsAsmBackend.cpp | 21 +++++++
.../Mips/MCTargetDesc/MipsMCAsmInfo.cpp | 22 +++++++
.../Target/Mips/MCTargetDesc/MipsMCAsmInfo.h | 15 +++++
.../Mips/MCTargetDesc/MipsMCTargetDesc.cpp | 20 ++++++-
.../Mips/MCTargetDesc/MipsMCTargetDesc.h | 15 +++++
.../MCTargetDesc/MipsWinCOFFObjectWriter.cpp | 58 +++++++++++++++++++
.../Mips/MCTargetDesc/MipsWinCOFFStreamer.cpp | 33 +++++++++++
llvm/lib/Target/Mips/MipsTargetMachine.cpp | 2 +
llvm/test/MC/Mips/coff-basic.ll | 8 +++
llvm/test/MC/Mips/coff-relocs.ll | 43 ++++++++++++++
13 files changed, 244 insertions(+), 1 deletion(-)
create mode 100644 llvm/lib/Target/Mips/MCTargetDesc/MipsWinCOFFObjectWriter.cpp
create mode 100644 llvm/lib/Target/Mips/MCTargetDesc/MipsWinCOFFStreamer.cpp
create mode 100644 llvm/test/MC/Mips/coff-basic.ll
create mode 100644 llvm/test/MC/Mips/coff-relocs.ll
diff --git a/llvm/lib/Object/COFFObjectFile.cpp b/llvm/lib/Object/COFFObjectFile.cpp
index 4b3999126c89fb..ad15d42135b319 100644
--- a/llvm/lib/Object/COFFObjectFile.cpp
+++ b/llvm/lib/Object/COFFObjectFile.cpp
@@ -2349,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/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/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 c112b3abe0ba75..960256bc38f244 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp
@@ -51,3 +51,25 @@ MipsELFMCAsmInfo::MipsELFMCAsmInfo(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 b52ed12d3a0e77..96348b17e57696 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,20 @@ class MipsELFMCAsmInfo : public MCAsmInfoELF {
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
#endif
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp
index eff9ecf0d53d31..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 MipsELFMCAsmInfo(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_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..77044a0ff3357e
--- /dev/null
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsWinCOFFStreamer.cpp
@@ -0,0 +1,33 @@
+//===-- MipsWinCOFFStreamer.cpp - MIPS Target WinCOFF Streamer --*- 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..21e355fc4883b9
--- /dev/null
+++ b/llvm/test/MC/Mips/coff-basic.ll
@@ -0,0 +1,8 @@
+; RUN: llc -mtriple mipsel-windows-msvc -filetype=obj < %s | obj2yaml | FileCheck %s
+; RUN: llc -mtriple mipsel-windows-gnu -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..bbe732c3d76ff2
--- /dev/null
+++ b/llvm/test/MC/Mips/coff-relocs.ll
@@ -0,0 +1,43 @@
+; RUN: llc -mtriple mipsel-windows-msvc -filetype=obj < %s | obj2yaml | FileCheck %s
+; RUN: llc -mtriple mipsel-windows-gnu -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
+}
+
+ at 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 }
+
+ at var1 = internal global %struct._PTR { ptr @var2 }
+ at var2 = external global i32
+; CHECK: - VirtualAddress: 0
+; CHECK: SymbolName: var2
+; CHECK: Type: IMAGE_REL_MIPS_REFWORD
>From 95a56b62088c3133c11da4d11f1b66956fa4121e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= <hpoussin at reactos.org>
Date: Sun, 22 Oct 2023 09:52:31 +0200
Subject: [PATCH 06/13] [MC][Mips] Add the required IMAGE_REL_MIPS_PAIR
relocation after IMAGE_REL_MIPS_REFHI/IMAGE_REL_MIPS_SECRELHI
---
llvm/lib/MC/WinCOFFObjectWriter.cpp | 17 +++++++++++++++--
llvm/test/MC/Mips/coff-relocs.ll | 3 +++
2 files changed, 18 insertions(+), 2 deletions(-)
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/test/MC/Mips/coff-relocs.ll b/llvm/test/MC/Mips/coff-relocs.ll
index bbe732c3d76ff2..1b5c0e09033b8d 100644
--- a/llvm/test/MC/Mips/coff-relocs.ll
+++ b/llvm/test/MC/Mips/coff-relocs.ll
@@ -23,6 +23,9 @@ define i32 @foo_var() {
; CHECK: - VirtualAddress: 32
; CHECK: SymbolName: var
; CHECK: Type: IMAGE_REL_MIPS_REFHI
+; CHECK: - VirtualAddress: 32
+; CHECK: SymbolName: .text
+; CHECK: Type: IMAGE_REL_MIPS_PAIR
; CHECK: - VirtualAddress: 40
; CHECK: SymbolName: var
; CHECK: Type: IMAGE_REL_MIPS_REFLO
>From 40f4c9a3f14d76ad3cd4a10b4acb6735f2bfb1f9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= <hpoussin at reactos.org>
Date: Sun, 22 Oct 2023 09:54:00 +0200
Subject: [PATCH 07/13] [MC][CodeGen][Mips] Add CodeView mapping
Also add support for new relocation types required by debug information.
---
.../DebugInfo/CodeView/CodeViewRegisters.def | 88 ++++++++++++++++++-
llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp | 2 +
.../Mips/MCTargetDesc/MipsMCTargetDesc.cpp | 81 +++++++++++++++++
.../Mips/MCTargetDesc/MipsMCTargetDesc.h | 2 +
.../MCTargetDesc/MipsWinCOFFObjectWriter.cpp | 4 +
llvm/lib/Target/Mips/MipsRegisterInfo.cpp | 4 +-
llvm/test/MC/Mips/coff-relocs.ll | 36 ++++++++
7 files changed, 215 insertions(+), 2 deletions(-)
diff --git a/llvm/include/llvm/DebugInfo/CodeView/CodeViewRegisters.def b/llvm/include/llvm/DebugInfo/CodeView/CodeViewRegisters.def
index 5d537755b2d680..7c38b536c277f0 100644
--- a/llvm/include/llvm/DebugInfo/CodeView/CodeViewRegisters.def
+++ b/llvm/include/llvm/DebugInfo/CodeView/CodeViewRegisters.def
@@ -16,7 +16,8 @@
#if !defined(CV_REGISTERS_ALL) && !defined(CV_REGISTERS_X86) && \
!defined(CV_REGISTERS_ARM) && \
- !defined(CV_REGISTERS_ARM64)
+ !defined(CV_REGISTERS_ARM64) && \
+ !defined(CV_REGISTERS_MIPS)
#error Need include at least one register set.
#endif
@@ -793,3 +794,88 @@ CV_REGISTER(ARM64_H31, 301)
#pragma pop_macro("ARM64_FPCR")
#endif // defined(CV_REGISTERS_ALL) || defined(CV_REGISTERS_ARM64)
+
+#if defined(CV_REGISTERS_ALL) || defined(CV_REGISTERS_MIPS)
+
+// MIPS registers
+CV_REGISTER(MIPS_NOREG, 0)
+
+// General purpose integer registers
+
+CV_REGISTER(MIPS_ZERO, 10)
+CV_REGISTER(MIPS_AT, 11)
+CV_REGISTER(MIPS_V0, 12)
+CV_REGISTER(MIPS_V1, 13)
+CV_REGISTER(MIPS_A0, 14)
+CV_REGISTER(MIPS_A1, 15)
+CV_REGISTER(MIPS_A2, 16)
+CV_REGISTER(MIPS_A3, 17)
+CV_REGISTER(MIPS_T0, 18)
+CV_REGISTER(MIPS_T1, 19)
+CV_REGISTER(MIPS_T2, 20)
+CV_REGISTER(MIPS_T3, 21)
+CV_REGISTER(MIPS_T4, 22)
+CV_REGISTER(MIPS_T5, 23)
+CV_REGISTER(MIPS_T6, 24)
+CV_REGISTER(MIPS_T7, 25)
+CV_REGISTER(MIPS_S0, 26)
+CV_REGISTER(MIPS_S1, 27)
+CV_REGISTER(MIPS_S2, 28)
+CV_REGISTER(MIPS_S3, 29)
+CV_REGISTER(MIPS_S4, 30)
+CV_REGISTER(MIPS_S5, 31)
+CV_REGISTER(MIPS_S6, 32)
+CV_REGISTER(MIPS_S7, 33)
+CV_REGISTER(MIPS_T8, 34)
+CV_REGISTER(MIPS_T9, 35)
+CV_REGISTER(MIPS_K0, 36)
+CV_REGISTER(MIPS_K1, 37)
+CV_REGISTER(MIPS_GP, 38)
+CV_REGISTER(MIPS_SP, 39)
+CV_REGISTER(MIPS_S8, 40)
+CV_REGISTER(MIPS_RA, 41)
+CV_REGISTER(MIPS_LO, 42)
+CV_REGISTER(MIPS_HI, 43)
+
+// Status registers
+
+CV_REGISTER(MIPS_Fir, 50)
+CV_REGISTER(MIPS_Psr, 51)
+
+// Floating-point registers
+
+CV_REGISTER(MIPS_F0, 60)
+CV_REGISTER(MIPS_F1, 61)
+CV_REGISTER(MIPS_F2, 62)
+CV_REGISTER(MIPS_F3, 63)
+CV_REGISTER(MIPS_F4, 64)
+CV_REGISTER(MIPS_F5, 65)
+CV_REGISTER(MIPS_F6, 66)
+CV_REGISTER(MIPS_F7, 67)
+CV_REGISTER(MIPS_F8, 68)
+CV_REGISTER(MIPS_F9, 69)
+CV_REGISTER(MIPS_F10, 70)
+CV_REGISTER(MIPS_F11, 71)
+CV_REGISTER(MIPS_F12, 72)
+CV_REGISTER(MIPS_F13, 73)
+CV_REGISTER(MIPS_F14, 74)
+CV_REGISTER(MIPS_F15, 75)
+CV_REGISTER(MIPS_F16, 76)
+CV_REGISTER(MIPS_F17, 77)
+CV_REGISTER(MIPS_F18, 78)
+CV_REGISTER(MIPS_F19, 79)
+CV_REGISTER(MIPS_F20, 80)
+CV_REGISTER(MIPS_F21, 81)
+CV_REGISTER(MIPS_F22, 82)
+CV_REGISTER(MIPS_F23, 83)
+CV_REGISTER(MIPS_F24, 84)
+CV_REGISTER(MIPS_F25, 85)
+CV_REGISTER(MIPS_F26, 86)
+CV_REGISTER(MIPS_F27, 87)
+CV_REGISTER(MIPS_F28, 88)
+CV_REGISTER(MIPS_F29, 89)
+CV_REGISTER(MIPS_F30, 90)
+CV_REGISTER(MIPS_F31, 91)
+CV_REGISTER(MIPS_Fsr, 92)
+
+#endif // defined(CV_REGISTERS_ALL) || defined(CV_REGISTERS_MIPS)
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
index 7700ffd6da8030..e5fb2f712a4b13 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -125,6 +125,8 @@ static CPUType mapArchToCVCPUType(Triple::ArchType Type) {
return CPUType::ARMNT;
case Triple::ArchType::aarch64:
return CPUType::ARM64;
+ case Triple::ArchType::mipsel:
+ return CPUType::MIPS;
default:
report_fatal_error("target architecture doesn't map to a CodeView CPUType");
}
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp
index 378cc12388bae3..46dada7830928d 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp
@@ -19,6 +19,7 @@
#include "MipsMCNaCl.h"
#include "MipsTargetStreamer.h"
#include "TargetInfo/MipsTargetInfo.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCELFStreamer.h"
#include "llvm/MC/MCInstrAnalysis.h"
@@ -45,6 +46,86 @@ using namespace llvm;
#define GET_REGINFO_MC_DESC
#include "MipsGenRegisterInfo.inc"
+void MIPS_MC::initLLVMToCVRegMapping(MCRegisterInfo *MRI) {
+ // Mapping from CodeView to MC register id.
+ static const struct {
+ codeview::RegisterId CVReg;
+ MCPhysReg Reg;
+ } RegMap[] = {
+ {codeview::RegisterId::MIPS_ZERO, Mips::ZERO},
+ {codeview::RegisterId::MIPS_AT, Mips::AT},
+ {codeview::RegisterId::MIPS_V0, Mips::V0},
+ {codeview::RegisterId::MIPS_V1, Mips::V1},
+ {codeview::RegisterId::MIPS_A0, Mips::A0},
+ {codeview::RegisterId::MIPS_A1, Mips::A1},
+ {codeview::RegisterId::MIPS_A2, Mips::A2},
+ {codeview::RegisterId::MIPS_A3, Mips::A3},
+ {codeview::RegisterId::MIPS_T0, Mips::T0},
+ {codeview::RegisterId::MIPS_T1, Mips::T1},
+ {codeview::RegisterId::MIPS_T2, Mips::T2},
+ {codeview::RegisterId::MIPS_T3, Mips::T3},
+ {codeview::RegisterId::MIPS_T4, Mips::T4},
+ {codeview::RegisterId::MIPS_T5, Mips::T5},
+ {codeview::RegisterId::MIPS_T6, Mips::T6},
+ {codeview::RegisterId::MIPS_T7, Mips::T7},
+ {codeview::RegisterId::MIPS_S0, Mips::S0},
+ {codeview::RegisterId::MIPS_S1, Mips::S1},
+ {codeview::RegisterId::MIPS_S2, Mips::S2},
+ {codeview::RegisterId::MIPS_S3, Mips::S3},
+ {codeview::RegisterId::MIPS_S4, Mips::S4},
+ {codeview::RegisterId::MIPS_S5, Mips::S5},
+ {codeview::RegisterId::MIPS_S6, Mips::S6},
+ {codeview::RegisterId::MIPS_S7, Mips::S7},
+ {codeview::RegisterId::MIPS_T8, Mips::T8},
+ {codeview::RegisterId::MIPS_T9, Mips::T9},
+ {codeview::RegisterId::MIPS_K0, Mips::K0},
+ {codeview::RegisterId::MIPS_K1, Mips::K1},
+ {codeview::RegisterId::MIPS_GP, Mips::GP},
+ {codeview::RegisterId::MIPS_SP, Mips::SP},
+ {codeview::RegisterId::MIPS_S8, Mips::FP},
+ {codeview::RegisterId::MIPS_RA, Mips::RA},
+ {codeview::RegisterId::MIPS_LO, Mips::HI0},
+ {codeview::RegisterId::MIPS_HI, Mips::LO0},
+ //{codeview::RegisterId::MIPS_Fir, Mips::},
+ //{codeview::RegisterId::MIPS_Psr, Mips::},
+ {codeview::RegisterId::MIPS_F0, Mips::F0},
+ {codeview::RegisterId::MIPS_F1, Mips::F1},
+ {codeview::RegisterId::MIPS_F2, Mips::F2},
+ {codeview::RegisterId::MIPS_F3, Mips::F3},
+ {codeview::RegisterId::MIPS_F4, Mips::F4},
+ {codeview::RegisterId::MIPS_F5, Mips::F5},
+ {codeview::RegisterId::MIPS_F6, Mips::F6},
+ {codeview::RegisterId::MIPS_F7, Mips::F7},
+ {codeview::RegisterId::MIPS_F8, Mips::F8},
+ {codeview::RegisterId::MIPS_F9, Mips::F9},
+ {codeview::RegisterId::MIPS_F10, Mips::F10},
+ {codeview::RegisterId::MIPS_F11, Mips::F11},
+ {codeview::RegisterId::MIPS_F12, Mips::F12},
+ {codeview::RegisterId::MIPS_F13, Mips::F13},
+ {codeview::RegisterId::MIPS_F14, Mips::F14},
+ {codeview::RegisterId::MIPS_F15, Mips::F15},
+ {codeview::RegisterId::MIPS_F16, Mips::F16},
+ {codeview::RegisterId::MIPS_F17, Mips::F17},
+ {codeview::RegisterId::MIPS_F18, Mips::F18},
+ {codeview::RegisterId::MIPS_F19, Mips::F19},
+ {codeview::RegisterId::MIPS_F20, Mips::F20},
+ {codeview::RegisterId::MIPS_F21, Mips::F21},
+ {codeview::RegisterId::MIPS_F22, Mips::F22},
+ {codeview::RegisterId::MIPS_F23, Mips::F23},
+ {codeview::RegisterId::MIPS_F24, Mips::F24},
+ {codeview::RegisterId::MIPS_F25, Mips::F25},
+ {codeview::RegisterId::MIPS_F26, Mips::F26},
+ {codeview::RegisterId::MIPS_F27, Mips::F27},
+ {codeview::RegisterId::MIPS_F28, Mips::F28},
+ {codeview::RegisterId::MIPS_F29, Mips::F29},
+ {codeview::RegisterId::MIPS_F30, Mips::F30},
+ {codeview::RegisterId::MIPS_F31, Mips::F31},
+ //{codeview::RegisterId::MIPS_Fsr, Mips::},
+ };
+ for (const auto &I : RegMap)
+ MRI->mapLLVMRegToCVReg(I.Reg, static_cast<int>(I.CVReg));
+}
+
namespace {
class MipsWinCOFFTargetStreamer : public MipsTargetStreamer {
public:
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.h
index a02e4fa2208880..114fec0ccc02e9 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.h
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.h
@@ -58,6 +58,8 @@ std::unique_ptr<MCObjectTargetWriter>
createMipsWinCOFFObjectWriter();
namespace MIPS_MC {
+void initLLVMToCVRegMapping(MCRegisterInfo *MRI);
+
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
index d014cc1b0c1b55..17c21bc8b1326b 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsWinCOFFObjectWriter.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsWinCOFFObjectWriter.cpp
@@ -40,6 +40,10 @@ unsigned MipsWinCOFFObjectWriter::getRelocType(MCContext &Ctx,
switch (FixupKind) {
case FK_Data_4:
return COFF::IMAGE_REL_MIPS_REFWORD;
+ case FK_SecRel_2:
+ return COFF::IMAGE_REL_MIPS_SECTION;
+ case FK_SecRel_4:
+ return COFF::IMAGE_REL_MIPS_SECREL;
case Mips::fixup_Mips_26:
return COFF::IMAGE_REL_MIPS_JMPADDR;
case Mips::fixup_Mips_HI16:
diff --git a/llvm/lib/Target/Mips/MipsRegisterInfo.cpp b/llvm/lib/Target/Mips/MipsRegisterInfo.cpp
index 3b12cb35b36731..f80e8fa1631df3 100644
--- a/llvm/lib/Target/Mips/MipsRegisterInfo.cpp
+++ b/llvm/lib/Target/Mips/MipsRegisterInfo.cpp
@@ -39,7 +39,9 @@ using namespace llvm;
#define GET_REGINFO_TARGET_DESC
#include "MipsGenRegisterInfo.inc"
-MipsRegisterInfo::MipsRegisterInfo() : MipsGenRegisterInfo(Mips::RA) {}
+MipsRegisterInfo::MipsRegisterInfo() : MipsGenRegisterInfo(Mips::RA) {
+ MIPS_MC::initLLVMToCVRegMapping(this);
+}
unsigned MipsRegisterInfo::getPICCallReg() { return Mips::T9; }
diff --git a/llvm/test/MC/Mips/coff-relocs.ll b/llvm/test/MC/Mips/coff-relocs.ll
index 1b5c0e09033b8d..39d349b9819614 100644
--- a/llvm/test/MC/Mips/coff-relocs.ll
+++ b/llvm/test/MC/Mips/coff-relocs.ll
@@ -44,3 +44,39 @@ define i32 @foo_var() {
; CHECK: - VirtualAddress: 0
; CHECK: SymbolName: var2
; CHECK: Type: IMAGE_REL_MIPS_REFWORD
+
+
+
+
+; CHECK: - Name: '.debug$S'
+; CHECK: Relocations:
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!2, !3, !4}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, emissionKind: FullDebug)
+!1 = !DIFile(filename: "dummy.c", directory: "/tmp/private")
+!2 = !{i32 2, !"CodeView", i32 1}
+!3 = !{i32 2, !"Debug Info Version", i32 3}
+!4 = !{i32 1, !"wchar_size", i32 2}
+!5 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !6, scopeLine: 2, spFlags: DISPFlagDefinition, unit: !0)
+!6 = !DISubroutineType(types: !7)
+!7 = !{null}
+!8 = !DILocation(line: 3, scope: !5)
+
+define dso_local void @foo_dbg() #0 !dbg !5 {
+ ret void, !dbg !8
+; CHECK: - VirtualAddress: 92
+; CHECK: SymbolName: foo_dbg
+; CHECK: Type: IMAGE_REL_MIPS_SECREL
+; CHECK: - VirtualAddress: 96
+; CHECK: SymbolName: foo_dbg
+; CHECK: Type: IMAGE_REL_MIPS_SECTION
+; CHECK: - VirtualAddress: 148
+; CHECK: SymbolName: foo_dbg
+; CHECK: Type: IMAGE_REL_MIPS_SECREL
+; CHECK: - VirtualAddress: 152
+; CHECK: SymbolName: foo_dbg
+; CHECK: Type: IMAGE_REL_MIPS_SECTION
+}
+
>From d6ce440503f755a46eaa1c9a508633869d0da7b9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= <hpoussin at reactos.org>
Date: Sun, 22 Oct 2023 11:24:08 +0200
Subject: [PATCH 08/13] [Mips] Handle declspec(dllimport) on mipsel-windows-*
triples
---
.../Target/Mips/MCTargetDesc/MipsBaseInfo.h | 7 ++-
llvm/lib/Target/Mips/MipsISelLowering.cpp | 16 +++++-
llvm/lib/Target/Mips/MipsISelLowering.h | 26 +++++++++
llvm/lib/Target/Mips/MipsMCInstLower.cpp | 14 ++++-
llvm/lib/Target/Mips/MipsSubtarget.h | 2 +
llvm/test/CodeGen/Mips/dllimport.ll | 55 +++++++++++++++++++
llvm/test/MC/Mips/coff-relocs-dllimport.ll | 12 ++++
7 files changed, 128 insertions(+), 4 deletions(-)
create mode 100644 llvm/test/CodeGen/Mips/dllimport.ll
create mode 100644 llvm/test/MC/Mips/coff-relocs-dllimport.ll
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h
index aa35e7db6bda44..b9a2af3341236a 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h
@@ -92,7 +92,12 @@ namespace MipsII {
MO_CALL_LO16,
/// Helper operand used to generate R_MIPS_JALR
- MO_JALR
+ MO_JALR,
+
+ /// MO_DLLIMPORT - On a symbol operand "FOO", this indicates that the
+ /// reference is actually to the "__imp_FOO" symbol. This is used for
+ /// dllimport linkage on windows.
+ MO_DLLIMPORT = 0x20,
};
enum {
diff --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp
index fa57a3fa9b1557..94cadfffa8794f 100644
--- a/llvm/lib/Target/Mips/MipsISelLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsISelLowering.cpp
@@ -2105,6 +2105,14 @@ SDValue MipsTargetLowering::lowerGlobalAddress(SDValue Op,
GlobalAddressSDNode *N = cast<GlobalAddressSDNode>(Op);
const GlobalValue *GV = N->getGlobal();
+ if (GV->hasDLLImportStorageClass()) {
+ assert(Subtarget.isTargetWindows() &&
+ "Windows is the only supported COFF target");
+ return getDllimportVariable(
+ N, SDLoc(N), Ty, DAG,
+ DAG.getEntryNode(), MachinePointerInfo::getGOT(DAG.getMachineFunction()));
+ }
+
if (!isPositionIndependent()) {
const MipsTargetObjectFile *TLOF =
static_cast<const MipsTargetObjectFile *>(
@@ -3460,7 +3468,13 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
}
if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
- if (IsPIC) {
+ if (Subtarget.isTargetCOFF() && G->getGlobal()->hasDLLImportStorageClass()) {
+ assert(Subtarget.isTargetWindows() &&
+ "Windows is the only supported COFF target");
+ auto PtrInfo = MachinePointerInfo();
+ Callee = DAG.getLoad(Ty, DL, Chain, getDllimportSymbol(G, SDLoc(G), Ty, DAG),
+ PtrInfo);
+ } else if (IsPIC) {
const GlobalValue *Val = G->getGlobal();
InternalLinkage = Val->hasInternalLinkage();
diff --git a/llvm/lib/Target/Mips/MipsISelLowering.h b/llvm/lib/Target/Mips/MipsISelLowering.h
index 2b18b299180926..12dfa6bc1c8079 100644
--- a/llvm/lib/Target/Mips/MipsISelLowering.h
+++ b/llvm/lib/Target/Mips/MipsISelLowering.h
@@ -485,6 +485,32 @@ class TargetRegisterClass;
DAG.getNode(MipsISD::GPRel, DL, DAG.getVTList(Ty), GPRel));
}
+ // This method creates the following nodes, which are necessary for
+ // loading a dllimported symbol:
+ //
+ // (lw (add (shl(%high(sym), 16), %low(sym)))
+ template <class NodeTy>
+ SDValue getDllimportSymbol(NodeTy *N, const SDLoc &DL, EVT Ty, SelectionDAG &DAG) const {
+ SDValue Hi = getTargetNode(N, Ty, DAG, MipsII::MO_ABS_HI | MipsII::MO_DLLIMPORT);
+ SDValue Lo = getTargetNode(N, Ty, DAG, MipsII::MO_ABS_LO | MipsII::MO_DLLIMPORT);
+ return DAG.getNode(ISD::ADD, DL, Ty,
+ DAG.getNode(MipsISD::Lo, DL, Ty, Lo),
+ DAG.getNode(MipsISD::Hi, DL, Ty, Hi));
+ }
+
+ // This method creates the following nodes, which are necessary for
+ // loading a dllimported global variable:
+ //
+ // (lw (lw (add (shl(%high(sym), 16), %low(sym))))
+ template <class NodeTy>
+ SDValue getDllimportVariable(NodeTy *N, const SDLoc &DL, EVT Ty, SelectionDAG &DAG,
+ SDValue Chain,
+ const MachinePointerInfo &PtrInfo) const {
+ return DAG.getLoad(Ty, DL, Chain,
+ getDllimportSymbol(N, DL, Ty, DAG),
+ PtrInfo);
+ }
+
/// This function fills Ops, which is the list of operands that will later
/// be used when a function call node is created. It also generates
/// copyToReg nodes to set up argument registers.
diff --git a/llvm/lib/Target/Mips/MipsMCInstLower.cpp b/llvm/lib/Target/Mips/MipsMCInstLower.cpp
index b0642f3d1ff283..667cf26b60fd31 100644
--- a/llvm/lib/Target/Mips/MipsMCInstLower.cpp
+++ b/llvm/lib/Target/Mips/MipsMCInstLower.cpp
@@ -18,6 +18,7 @@
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineOperand.h"
+#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/Support/ErrorHandling.h"
@@ -38,8 +39,16 @@ MCOperand MipsMCInstLower::LowerSymbolOperand(const MachineOperand &MO,
MipsMCExpr::MipsExprKind TargetKind = MipsMCExpr::MEK_None;
bool IsGpOff = false;
const MCSymbol *Symbol;
+ SmallString<128> Name;
+ unsigned TargetFlags = MO.getTargetFlags();
- switch(MO.getTargetFlags()) {
+ if (TargetFlags & MipsII::MO_DLLIMPORT) {
+ // Handle dllimport linkage
+ Name += "__imp_";
+ TargetFlags &= ~MipsII::MO_DLLIMPORT;
+ }
+
+ switch(TargetFlags) {
default:
llvm_unreachable("Invalid target flag!");
case MipsII::MO_NO_FLAG:
@@ -125,7 +134,8 @@ MCOperand MipsMCInstLower::LowerSymbolOperand(const MachineOperand &MO,
break;
case MachineOperand::MO_GlobalAddress:
- Symbol = AsmPrinter.getSymbol(MO.getGlobal());
+ AsmPrinter.getNameWithPrefix(Name, MO.getGlobal());
+ Symbol = Ctx->getOrCreateSymbol(Name);
Offset += MO.getOffset();
break;
diff --git a/llvm/lib/Target/Mips/MipsSubtarget.h b/llvm/lib/Target/Mips/MipsSubtarget.h
index fea7f11fd07054..0dd349f59ea65f 100644
--- a/llvm/lib/Target/Mips/MipsSubtarget.h
+++ b/llvm/lib/Target/Mips/MipsSubtarget.h
@@ -300,6 +300,7 @@ class MipsSubtarget : public MipsGenSubtargetInfo {
return (HasSym32 && isABI_N64()) || isABI_N32() || isABI_O32();
}
bool isSingleFloat() const { return IsSingleFloat; }
+ bool isTargetCOFF() const { return TargetTriple.isOSBinFormatCOFF(); }
bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); }
bool hasVFPU() const { return HasVFPU; }
bool inMips16Mode() const { return InMips16Mode; }
@@ -355,6 +356,7 @@ class MipsSubtarget : public MipsGenSubtargetInfo {
bool os16() const { return Os16; }
bool isTargetNaCl() const { return TargetTriple.isOSNaCl(); }
+ bool isTargetWindows() const { return TargetTriple.isOSWindows(); }
bool isXRaySupported() const override { return true; }
diff --git a/llvm/test/CodeGen/Mips/dllimport.ll b/llvm/test/CodeGen/Mips/dllimport.ll
new file mode 100644
index 00000000000000..385199892821e7
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/dllimport.ll
@@ -0,0 +1,55 @@
+; RUN: llc -mtriple mipsel-windows < %s | FileCheck %s
+
+ at Var1 = external dllimport global i32
+ at Var2 = available_externally dllimport unnamed_addr constant i32 1
+
+declare dllimport void @fun()
+
+define available_externally dllimport void @inline1() {
+ ret void
+}
+
+define available_externally dllimport void @inline2() alwaysinline {
+ ret void
+}
+
+declare void @dummy(...)
+
+define void @use() nounwind {
+; CHECK: lui $1, %hi(__imp_fun)
+; CHECK: addiu $1, $1, %lo(__imp_fun)
+; CHECK: lw $25, 0($1)
+; CHECK: jalr $25
+ call void @fun()
+
+; CHECK: lui $1, %hi(__imp_inline1)
+; CHECK: addiu $1, $1, %lo(__imp_inline1)
+; CHECK: lw $25, 0($1)
+; CHECK: jalr $25
+ call void @inline1()
+
+; CHECK: lui $1, %hi(__imp_inline2)
+; CHECK: addiu $1, $1, %lo(__imp_inline2)
+; CHECK: lw $25, 0($1)
+; CHECK: jalr $25
+ call void @inline2()
+
+; CHECK: lui $1, %hi(__imp_Var2)
+; CHECK: addiu $1, $1, %lo(__imp_Var2)
+; CHECK: lw $1, 0($1)
+; CHECK: lw $5, 0($1)
+; CHECK: lui $1, %hi(__imp_Var1)
+; CHECK: addiu $1, $1, %lo(__imp_Var1)
+; CHECK: lw $1, 0($1)
+; CHECK: lw $4, 0($1)
+ %1 = load i32, ptr @Var1
+ %2 = load i32, ptr @Var2
+ call void(...) @dummy(i32 %1, i32 %2)
+
+ ret void
+}
+
+; CHECK: fp:
+; CHECK-NEXT: .long fun
+ at fp = constant ptr @fun
+
diff --git a/llvm/test/MC/Mips/coff-relocs-dllimport.ll b/llvm/test/MC/Mips/coff-relocs-dllimport.ll
new file mode 100644
index 00000000000000..e4f3f498177aee
--- /dev/null
+++ b/llvm/test/MC/Mips/coff-relocs-dllimport.ll
@@ -0,0 +1,12 @@
+; RUN: llc -mtriple mipsel-windows -filetype obj < %s | llvm-objdump --reloc - | FileCheck %s
+
+declare dllimport void @fun()
+
+define void @use() nounwind {
+; CHECK: 00000008 IMAGE_REL_MIPS_REFHI __imp_fun
+; CHECK: 00000008 IMAGE_REL_MIPS_PAIR .text
+; CHECK: 0000000c IMAGE_REL_MIPS_REFLO __imp_fun
+ call void() @fun()
+
+ ret void
+}
>From 965c46d4f1052f9c2827b6b99e4c7d5808e75172 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= <hpoussin at reactos.org>
Date: Sun, 22 Oct 2023 14:12:42 +0200
Subject: [PATCH 09/13] [llvm-lib] Handle MIPS architecture
---
llvm/lib/Object/COFFImportFile.cpp | 2 ++
llvm/lib/ToolDrivers/llvm-lib/LibDriver.cpp | 3 +++
llvm/test/tools/llvm-lib/machine.test | 13 +++++++++++++
3 files changed, 18 insertions(+)
create mode 100644 llvm/test/tools/llvm-lib/machine.test
diff --git a/llvm/lib/Object/COFFImportFile.cpp b/llvm/lib/Object/COFFImportFile.cpp
index cc0a5da7e0d16a..8f63b828ed16f5 100644
--- a/llvm/lib/Object/COFFImportFile.cpp
+++ b/llvm/lib/Object/COFFImportFile.cpp
@@ -133,6 +133,8 @@ static uint16_t getImgRelRelocation(MachineTypes Machine) {
return IMAGE_REL_ARM64_ADDR32NB;
case IMAGE_FILE_MACHINE_I386:
return IMAGE_REL_I386_DIR32NB;
+ case IMAGE_FILE_MACHINE_R4000:
+ return IMAGE_REL_MIPS_REFWORDNB;
}
}
diff --git a/llvm/lib/ToolDrivers/llvm-lib/LibDriver.cpp b/llvm/lib/ToolDrivers/llvm-lib/LibDriver.cpp
index 07389a5ffb2b8a..617fd8f031ac87 100644
--- a/llvm/lib/ToolDrivers/llvm-lib/LibDriver.cpp
+++ b/llvm/lib/ToolDrivers/llvm-lib/LibDriver.cpp
@@ -168,6 +168,7 @@ static Expected<COFF::MachineTypes> getCOFFFileMachine(MemoryBufferRef MB) {
uint16_t Machine = (*Obj)->getMachine();
if (Machine != COFF::IMAGE_FILE_MACHINE_I386 &&
Machine != COFF::IMAGE_FILE_MACHINE_AMD64 &&
+ Machine != COFF::IMAGE_FILE_MACHINE_R4000 &&
Machine != COFF::IMAGE_FILE_MACHINE_ARMNT && !COFF::isAnyArm64(Machine)) {
return createStringError(inconvertibleErrorCode(),
"unknown machine: " + std::to_string(Machine));
@@ -192,6 +193,8 @@ static Expected<COFF::MachineTypes> getBitcodeFileMachine(MemoryBufferRef MB) {
case Triple::aarch64:
return T.isWindowsArm64EC() ? COFF::IMAGE_FILE_MACHINE_ARM64EC
: COFF::IMAGE_FILE_MACHINE_ARM64;
+ case Triple::mipsel:
+ return COFF::IMAGE_FILE_MACHINE_R4000;
default:
return createStringError(inconvertibleErrorCode(),
"unknown arch in target triple: " + *TripleStr);
diff --git a/llvm/test/tools/llvm-lib/machine.test b/llvm/test/tools/llvm-lib/machine.test
new file mode 100644
index 00000000000000..db85d589d773d7
--- /dev/null
+++ b/llvm/test/tools/llvm-lib/machine.test
@@ -0,0 +1,13 @@
+RUN: rm -f %t.lib
+
+RUN: llvm-lib /out:%t.lib /machine:i386 2>&1 | FileCheck --check-prefix=EMPTYWARN %s
+RUN: llvm-lib /out:%t.lib /machine:amd64 2>&1 | FileCheck --check-prefix=EMPTYWARN %s
+
+RUN: llvm-lib /out:%t.lib /machine:mipsel 2>&1 | FileCheck --check-prefix=EMPTYWARN %s
+
+RUN: llvm-lib /out:%t.lib /machine:arm 2>&1 | FileCheck --check-prefix=EMPTYWARN %s
+RUN: llvm-lib /out:%t.lib /machine:arm64 2>&1 | FileCheck --check-prefix=EMPTYWARN %s
+RUN: llvm-lib /out:%t.lib /machine:arm64x 2>&1 | FileCheck --check-prefix=EMPTYWARN %s
+
+EMPTYWARN: warning: no input files, not writing output file
+
>From 607f719fc63b0ad7ddc3dc8457bace34cde0b31a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= <hpoussin at reactos.org>
Date: Sun, 22 Oct 2023 17:10:19 +0200
Subject: [PATCH 10/13] [llvm-dlltool] Handle MIPS architecture
---
llvm/lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp | 1 +
llvm/test/tools/llvm-dlltool/machine-opt.def | 3 +++
2 files changed, 4 insertions(+)
diff --git a/llvm/lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp b/llvm/lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp
index 15e4cac08cd4ed..91e62b8d46dc9f 100644
--- a/llvm/lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp
+++ b/llvm/lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp
@@ -76,6 +76,7 @@ MachineTypes getEmulation(StringRef S) {
.Case("arm", IMAGE_FILE_MACHINE_ARMNT)
.Case("arm64", IMAGE_FILE_MACHINE_ARM64)
.Case("arm64ec", IMAGE_FILE_MACHINE_ARM64EC)
+ .Case("mipsel", IMAGE_FILE_MACHINE_R4000)
.Default(IMAGE_FILE_MACHINE_UNKNOWN);
}
diff --git a/llvm/test/tools/llvm-dlltool/machine-opt.def b/llvm/test/tools/llvm-dlltool/machine-opt.def
index 6dce8255a43db3..5f28c2a1790245 100644
--- a/llvm/test/tools/llvm-dlltool/machine-opt.def
+++ b/llvm/test/tools/llvm-dlltool/machine-opt.def
@@ -6,6 +6,8 @@
; RUN: llvm-readobj %t.a | FileCheck --check-prefix=ARM %s
; RUN: llvm-dlltool -m arm64 -d %s -l %t.a
; RUN: llvm-readobj %t.a | FileCheck --check-prefix=ARM64 %s
+; RUN: llvm-dlltool -m mipsel -d %s -l %t.a
+; RUN: llvm-readobj %t.a | FileCheck --check-prefix=MIPSEL %s
LIBRARY test.dll
EXPORTS
@@ -15,3 +17,4 @@ TestFunction
; X86_64: Format: COFF-x86-64
; ARM: Format: COFF-ARM{{$}}
; ARM64: Format: COFF-ARM64
+; MIPSEL: Format: COFF-R4000
>From e6157bb33ffca378d12022adec61a0a627c4ca3b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= <hpoussin at reactos.org>
Date: Sun, 22 Oct 2023 17:01:02 +0200
Subject: [PATCH 11/13] [Clang][MIPS] Create specific targets for MIPS PE/COFF
Implement GNU and MSVC variants.
When using them, _WIN32 and _M_MRX000/_MIPS_ macros are correctly defined.
---
clang/lib/Basic/Targets.cpp | 8 +++
clang/lib/Basic/Targets/Mips.cpp | 60 +++++++++++++++++++
clang/lib/Basic/Targets/Mips.h | 36 +++++++++++
.../test/Preprocessor/predefined-win-macros.c | 16 +++++
4 files changed, 120 insertions(+)
diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp
index 0b8e565345b6a4..5774b9d9499f37 100644
--- a/clang/lib/Basic/Targets.cpp
+++ b/clang/lib/Basic/Targets.cpp
@@ -297,6 +297,14 @@ std::unique_ptr<TargetInfo> AllocateTarget(const llvm::Triple &Triple,
case llvm::Triple::NaCl:
return std::make_unique<NaClTargetInfo<NaClMips32TargetInfo>>(Triple,
Opts);
+ case llvm::Triple::Win32:
+ switch (Triple.getEnvironment()) {
+ case llvm::Triple::GNU:
+ return std::make_unique<MinGWMipsTargetInfo>(Triple, Opts);
+ case llvm::Triple::MSVC:
+ default: // Assume MSVC for unknown environments
+ return std::make_unique<MicrosoftMipsTargetInfo>(Triple, Opts);
+ }
default:
return std::make_unique<MipsTargetInfo>(Triple, Opts);
}
diff --git a/clang/lib/Basic/Targets/Mips.cpp b/clang/lib/Basic/Targets/Mips.cpp
index 174bc9d2ab9967..858cdd1c6f49a2 100644
--- a/clang/lib/Basic/Targets/Mips.cpp
+++ b/clang/lib/Basic/Targets/Mips.cpp
@@ -304,3 +304,63 @@ bool MipsTargetInfo::validateTarget(DiagnosticsEngine &Diags) const {
return true;
}
+
+WindowsMipsTargetInfo::WindowsMipsTargetInfo(const llvm::Triple &Triple,
+ const TargetOptions &Opts)
+ : WindowsTargetInfo<MipsTargetInfo>(Triple, Opts), Triple(Triple) {
+}
+
+void WindowsMipsTargetInfo::getVisualStudioDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const {
+ Builder.defineMacro("_M_MRX000", "4000");
+}
+
+TargetInfo::BuiltinVaListKind
+WindowsMipsTargetInfo::getBuiltinVaListKind() const {
+ return TargetInfo::CharPtrBuiltinVaList;
+}
+
+TargetInfo::CallingConvCheckResult
+WindowsMipsTargetInfo::checkCallingConvention(CallingConv CC) const {
+ switch (CC) {
+ case CC_X86StdCall:
+ case CC_X86ThisCall:
+ case CC_X86FastCall:
+ case CC_X86VectorCall:
+ return CCCR_Ignore;
+ case CC_C:
+ case CC_OpenCLKernel:
+ case CC_PreserveMost:
+ case CC_PreserveAll:
+ case CC_Swift:
+ case CC_SwiftAsync:
+ return CCCR_OK;
+ default:
+ return CCCR_Warning;
+ }
+}
+
+// Windows MIPS, MS (C++) ABI
+MicrosoftMipsTargetInfo::MicrosoftMipsTargetInfo(const llvm::Triple &Triple,
+ const TargetOptions &Opts)
+ : WindowsMipsTargetInfo(Triple, Opts) {
+ TheCXXABI.set(TargetCXXABI::Microsoft);
+}
+
+void MicrosoftMipsTargetInfo::getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const {
+ WindowsMipsTargetInfo::getTargetDefines(Opts, Builder);
+ WindowsMipsTargetInfo::getVisualStudioDefines(Opts, Builder);
+}
+
+MinGWMipsTargetInfo::MinGWMipsTargetInfo(const llvm::Triple &Triple,
+ const TargetOptions &Opts)
+ : WindowsMipsTargetInfo(Triple, Opts) {
+ TheCXXABI.set(TargetCXXABI::GenericMIPS);
+}
+
+void MinGWMipsTargetInfo::getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const {
+ WindowsMipsTargetInfo::getTargetDefines(Opts, Builder);
+ Builder.defineMacro("_MIPS_");
+}
diff --git a/clang/lib/Basic/Targets/Mips.h b/clang/lib/Basic/Targets/Mips.h
index b6f110249fa78e..b138710bb83d39 100644
--- a/clang/lib/Basic/Targets/Mips.h
+++ b/clang/lib/Basic/Targets/Mips.h
@@ -13,6 +13,7 @@
#ifndef LLVM_CLANG_LIB_BASIC_TARGETS_MIPS_H
#define LLVM_CLANG_LIB_BASIC_TARGETS_MIPS_H
+#include "OSTargets.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"
#include "llvm/Support/Compiler.h"
@@ -450,6 +451,41 @@ class LLVM_LIBRARY_VISIBILITY MipsTargetInfo : public TargetInfo {
return std::make_pair(32, 32);
}
};
+
+class LLVM_LIBRARY_VISIBILITY WindowsMipsTargetInfo
+ : public WindowsTargetInfo<MipsTargetInfo> {
+ const llvm::Triple Triple;
+
+public:
+ WindowsMipsTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
+
+ void getVisualStudioDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const;
+
+ BuiltinVaListKind getBuiltinVaListKind() const override;
+
+ CallingConvCheckResult checkCallingConvention(CallingConv CC) const override;
+};
+
+// Windows MIPS, MS (C++) ABI
+class LLVM_LIBRARY_VISIBILITY MicrosoftMipsTargetInfo
+ : public WindowsMipsTargetInfo {
+public:
+ MicrosoftMipsTargetInfo(const llvm::Triple &Triple,
+ const TargetOptions &Opts);
+
+ void getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const override;
+};
+
+// MIPS MinGW target
+class LLVM_LIBRARY_VISIBILITY MinGWMipsTargetInfo : public WindowsMipsTargetInfo {
+public:
+ MinGWMipsTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
+
+ void getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const override;
+};
} // namespace targets
} // namespace clang
diff --git a/clang/test/Preprocessor/predefined-win-macros.c b/clang/test/Preprocessor/predefined-win-macros.c
index 7d29e45c7d5ac6..8635724bd620b2 100644
--- a/clang/test/Preprocessor/predefined-win-macros.c
+++ b/clang/test/Preprocessor/predefined-win-macros.c
@@ -108,6 +108,13 @@
// CHECK-ARM64EC-WIN: #define _WIN32 1
// CHECK-ARM64EC-WIN: #define _WIN64 1
+// RUN: %clang_cc1 -triple mipsel-windows %s -E -dM -o - \
+// RUN: | FileCheck -match-full-lines %s --check-prefix=CHECK-MIPSEL-WIN
+
+// CHECK-MIPSEL-WIN: #define _M_MRX000 4000
+// CHECK-MIPSEL-WIN: #define _WIN32 1
+// CHECK-MIPSEL-WIN-NOT: #define _MIPS_ 1
+
// RUN: %clang_cc1 -triple i686-windows-gnu %s -E -dM -o - \
// RUN: | FileCheck -match-full-lines %s --check-prefix=CHECK-X86-MINGW
@@ -168,3 +175,12 @@
// CHECK-ARM64EC-MINGW: #define __arm64ec__ 1
// CHECK-ARM64EC-MINGW: #define __x86_64 1
// CHECK-ARM64EC-MINGW: #define __x86_64__ 1
+
+// RUN: %clang_cc1 -triple mipsel-windows-gnu %s -E -dM -o - \
+// RUN: | FileCheck -match-full-lines %s --check-prefix=CHECK-MIPSEL-MINGW
+
+// CHECK-MIPSEL-MINGW-NOT: #define _M_MRX000 4000
+// CHECK-MIPSEL-MINGW: #define _MIPS_ 1
+// CHECK-MIPSEL-MINGW: #define _WIN32 1
+// CHECK-MIPSEL-MINGW: #define __mips 32
+// CHECK-MIPSEL-MINGW: #define __mips__ 1
>From fda924559331ad61cff10386df4c9a6dc7a2134b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= <hpoussin at reactos.org>
Date: Fri, 10 Nov 2023 23:06:52 +0100
Subject: [PATCH 12/13] [Clang][MIPS] Create correct linker arguments for
Windows toolchains
---
clang/lib/CodeGen/CodeGenModule.cpp | 2 ++
clang/lib/CodeGen/TargetInfo.h | 3 +++
clang/lib/CodeGen/Targets/Mips.cpp | 23 +++++++++++++++++++++++
clang/test/CodeGen/pragma-comment.c | 1 +
4 files changed, 29 insertions(+)
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index df4c13c9ad97aa..0237fdad54c1c2 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -122,6 +122,8 @@ createTargetCodeGenInfo(CodeGenModule &CGM) {
case llvm::Triple::mipsel:
if (Triple.getOS() == llvm::Triple::NaCl)
return createPNaClTargetCodeGenInfo(CGM);
+ else if (Triple.getOS() == llvm::Triple::Win32)
+ return createWindowsMIPSTargetCodeGenInfo(CGM, /*IsOS32=*/true);
return createMIPSTargetCodeGenInfo(CGM, /*IsOS32=*/true);
case llvm::Triple::mips64:
diff --git a/clang/lib/CodeGen/TargetInfo.h b/clang/lib/CodeGen/TargetInfo.h
index 0244ca006d498b..7ab02b21708e76 100644
--- a/clang/lib/CodeGen/TargetInfo.h
+++ b/clang/lib/CodeGen/TargetInfo.h
@@ -502,6 +502,9 @@ createM68kTargetCodeGenInfo(CodeGenModule &CGM);
std::unique_ptr<TargetCodeGenInfo>
createMIPSTargetCodeGenInfo(CodeGenModule &CGM, bool IsOS32);
+std::unique_ptr<TargetCodeGenInfo>
+createWindowsMIPSTargetCodeGenInfo(CodeGenModule &CGM, bool IsOS32);
+
std::unique_ptr<TargetCodeGenInfo>
createMSP430TargetCodeGenInfo(CodeGenModule &CGM);
diff --git a/clang/lib/CodeGen/Targets/Mips.cpp b/clang/lib/CodeGen/Targets/Mips.cpp
index 06d9b6d4a57615..e7601564f67d1d 100644
--- a/clang/lib/CodeGen/Targets/Mips.cpp
+++ b/clang/lib/CodeGen/Targets/Mips.cpp
@@ -105,6 +105,24 @@ class MIPSTargetCodeGenInfo : public TargetCodeGenInfo {
return SizeOfUnwindException;
}
};
+
+class WindowsMIPSTargetCodeGenInfo : public MIPSTargetCodeGenInfo {
+public:
+ WindowsMIPSTargetCodeGenInfo(CodeGenTypes &CGT, bool IsO32)
+ : MIPSTargetCodeGenInfo(CGT, IsO32) {}
+
+ void getDependentLibraryOption(llvm::StringRef Lib,
+ llvm::SmallString<24> &Opt) const override {
+ Opt = "/DEFAULTLIB:";
+ Opt += qualifyWindowsLibrary(Lib);
+ }
+
+ void getDetectMismatchOption(llvm::StringRef Name,
+ llvm::StringRef Value,
+ llvm::SmallString<32> &Opt) const override {
+ Opt = "/FAILIFMISMATCH:\"" + Name.str() + "=" + Value.str() + "\"";
+ }
+};
}
void MipsABIInfo::CoerceToIntArgs(
@@ -436,3 +454,8 @@ std::unique_ptr<TargetCodeGenInfo>
CodeGen::createMIPSTargetCodeGenInfo(CodeGenModule &CGM, bool IsOS32) {
return std::make_unique<MIPSTargetCodeGenInfo>(CGM.getTypes(), IsOS32);
}
+
+std::unique_ptr<TargetCodeGenInfo>
+CodeGen::createWindowsMIPSTargetCodeGenInfo(CodeGenModule &CGM, bool IsOS32) {
+ return std::make_unique<WindowsMIPSTargetCodeGenInfo>(CGM.getTypes(), IsOS32);
+}
diff --git a/clang/test/CodeGen/pragma-comment.c b/clang/test/CodeGen/pragma-comment.c
index a4746f5c47bf6b..a966840f7c26fc 100644
--- a/clang/test/CodeGen/pragma-comment.c
+++ b/clang/test/CodeGen/pragma-comment.c
@@ -6,6 +6,7 @@
// RUN: %clang_cc1 %s -triple x86_64-scei-ps4 -fms-extensions -emit-llvm -o - | FileCheck -check-prefix ELF %s --implicit-check-not llvm.linker.options
// RUN: %clang_cc1 %s -triple x86_64-sie-ps5 -fms-extensions -emit-llvm -o - | FileCheck -check-prefix ELF %s --implicit-check-not llvm.linker.options
// RUN: %clang_cc1 %s -triple aarch64-windows-msvc -fms-extensions -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple mipsel-windows-msvc -fms-extensions -emit-llvm -o - | FileCheck %s
#pragma comment(lib, "msvcrt.lib")
#pragma comment(lib, "kernel32")
>From 9deeff4e9136c88813f26e83241328eb680938c6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= <hpoussin at reactos.org>
Date: Fri, 10 Nov 2023 23:09:05 +0100
Subject: [PATCH 13/13] [Clang][MIPS] Send correct architecture for MinGW
toolchains
'mipspe' name was chosen by binutils, when the project was able to create
executables for Windows CE/MIPS.
---
clang/lib/Driver/ToolChains/MinGW.cpp | 3 +++
1 file changed, 3 insertions(+)
diff --git a/clang/lib/Driver/ToolChains/MinGW.cpp b/clang/lib/Driver/ToolChains/MinGW.cpp
index c81a7ed1702963..f24cc71263ddbe 100644
--- a/clang/lib/Driver/ToolChains/MinGW.cpp
+++ b/clang/lib/Driver/ToolChains/MinGW.cpp
@@ -137,6 +137,9 @@ void tools::MinGW::Linker::ConstructJob(Compilation &C, const JobAction &JA,
else
CmdArgs.push_back("arm64pe");
break;
+ case llvm::Triple::mipsel:
+ CmdArgs.push_back("mipspe");
+ break;
default:
D.Diag(diag::err_target_unknown_triple) << TC.getEffectiveTriple().str();
}
More information about the cfe-commits
mailing list