=?utf-8?q?Hervé?= Poussineau <hpous...@reactos.org>, =?utf-8?q?Hervé?= Poussineau <hpous...@reactos.org>, =?utf-8?q?Hervé?= Poussineau <hpous...@reactos.org>, =?utf-8?q?Hervé?= Poussineau <hpous...@reactos.org>, =?utf-8?q?Hervé?= Poussineau <hpous...@reactos.org>, =?utf-8?q?Hervé?= Poussineau <hpous...@reactos.org>, =?utf-8?q?Hervé?= Poussineau <hpous...@reactos.org>, =?utf-8?q?Hervé?= Poussineau <hpous...@reactos.org>, =?utf-8?q?Hervé?= Poussineau <hpous...@reactos.org>, =?utf-8?q?Hervé?= Poussineau <hpous...@reactos.org>, =?utf-8?q?Hervé?= Poussineau <hpous...@reactos.org>, =?utf-8?q?Hervé?= Poussineau <hpous...@reactos.org> Message-ID: In-Reply-To: <llvm.org/llvm/llvm-project/pull/107...@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?= <hpous...@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?= <hpous...@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?= <hpous...@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?= <hpous...@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?= <hpous...@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 +} + +@var = external global i32 +define i32 @foo_var() { + %1 = load i32, i32* @var +; CHECK: - VirtualAddress: 32 +; CHECK: SymbolName: var +; CHECK: Type: IMAGE_REL_MIPS_REFHI +; CHECK: - VirtualAddress: 40 +; CHECK: SymbolName: var +; CHECK: Type: IMAGE_REL_MIPS_REFLO + ret i32 %1 +} + + + +; CHECK: - Name: .data +; CHECK: Relocations: + +%struct._PTR = type { ptr } + +@var1 = internal global %struct._PTR { ptr @var2 } +@var2 = external global i32 +; CHECK: - VirtualAddress: 0 +; CHECK: SymbolName: var2 +; CHECK: Type: IMAGE_REL_MIPS_REFWORD >From 95a56b62088c3133c11da4d11f1b66956fa4121e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= <hpous...@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?= <hpous...@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?= <hpous...@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 + +@Var1 = external dllimport global i32 +@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 +@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?= <hpous...@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?= <hpous...@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?= <hpous...@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?= <hpous...@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?= <hpous...@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(); } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits