[lld] [llvm] [clang][MIPS] Add support for mipsel-windows-* targets (PR #107744)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Sep 8 12:38:36 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>
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 1/4] [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 2/4] [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 3/4] [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 4/4] [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),
More information about the llvm-commits
mailing list