[llvm] [LoongArch] Add basic UEFI support (PR #154883)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 22 03:01:16 PDT 2025
https://github.com/leecheechen updated https://github.com/llvm/llvm-project/pull/154883
>From a47f54c2e99751b6e5f9e1984cb2e9864b302a94 Mon Sep 17 00:00:00 2001
From: chenli <chenli at loongson.cn>
Date: Fri, 22 Aug 2025 12:27:31 +0800
Subject: [PATCH] [LoongArch] Add basic UEFI support
This patch adds initial UEFI support for LoongArch64, enabling the
compilation and generation of UEFI applications for LoongArch targets.
Key changes include:
1. Target support enhancements:
- Updated data layout for UEFI target (Windows-style instead of ELF)
- Added LoongArch64 (0x6264) COFF machine type definitions. See:
https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#machine-types
2. COFF object file support:
- Added LoongArch64 machine type recognition in COFF headers
- Enhanced magic number detection for LoongArch COFF files
- Updated COFF object file handling for LoongArch64 architecture
3. Code generation infrastructure:
- Implemented Windows COFF object writer for LoongArch
- Added COFF streamer support for UEFI target
- Created COFF-specific MCAsmInfo for Microsoft compatibility
- Enhanced AsmBackend to support both ELF and COFF output formats
4. Toolchain updates:
- Extended llvm-readobj to recognize LoongArch64 COFF files
- Updated triple handling to default to COFF format for UEFI targets
- Added build system support for new COFF components
The implementation provides the foundational infrastructure for generating
UEFI-compatible PE/COFF binaries for LoongArch64 systems.
Co-Authored-By: WANG Rui <wangrui at loongson.cn>
---
llvm/include/llvm/BinaryFormat/COFF.h | 4 +-
llvm/include/llvm/Object/WindowsMachineFlag.h | 2 +
llvm/lib/BinaryFormat/Magic.cpp | 5 +-
llvm/lib/Object/COFFObjectFile.cpp | 11 ++++-
.../LoongArch/LoongArchTargetMachine.cpp | 13 +++++-
.../LoongArch/MCTargetDesc/CMakeLists.txt | 2 +
.../MCTargetDesc/LoongArchAsmBackend.cpp | 46 +++++++++++++++----
.../MCTargetDesc/LoongArchAsmBackend.h | 13 +++---
.../MCTargetDesc/LoongArchMCAsmInfo.cpp | 28 +++++++++--
.../MCTargetDesc/LoongArchMCAsmInfo.h | 12 ++++-
.../MCTargetDesc/LoongArchMCTargetDesc.cpp | 18 ++++++--
.../MCTargetDesc/LoongArchMCTargetDesc.h | 2 +
.../LoongArchWinCOFFObjectWriter.cpp | 43 +++++++++++++++++
.../MCTargetDesc/LoongArchWinCOFFStreamer.cpp | 34 ++++++++++++++
.../MCTargetDesc/LoongArchWinCOFFStreamer.h | 28 +++++++++++
llvm/lib/TargetParser/Triple.cpp | 6 ++-
llvm/tools/llvm-readobj/COFFDumper.cpp | 1 +
.../Target/LoongArch/MCTargetDesc/BUILD.gn | 2 +
18 files changed, 238 insertions(+), 32 deletions(-)
create mode 100644 llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchWinCOFFObjectWriter.cpp
create mode 100644 llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchWinCOFFStreamer.cpp
create mode 100644 llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchWinCOFFStreamer.h
diff --git a/llvm/include/llvm/BinaryFormat/COFF.h b/llvm/include/llvm/BinaryFormat/COFF.h
index 64fe2160f9970..8732a4969bc33 100644
--- a/llvm/include/llvm/BinaryFormat/COFF.h
+++ b/llvm/include/llvm/BinaryFormat/COFF.h
@@ -104,6 +104,7 @@ enum MachineTypes : unsigned {
IMAGE_FILE_MACHINE_EBC = 0xEBC,
IMAGE_FILE_MACHINE_I386 = 0x14C,
IMAGE_FILE_MACHINE_IA64 = 0x200,
+ IMAGE_FILE_MACHINE_LOONGARCH64 = 0x6264,
IMAGE_FILE_MACHINE_M32R = 0x9041,
IMAGE_FILE_MACHINE_MIPS16 = 0x266,
IMAGE_FILE_MACHINE_MIPSFPU = 0x366,
@@ -132,7 +133,8 @@ template <typename T> bool isAnyArm64(T Machine) {
}
template <typename T> bool is64Bit(T Machine) {
- return Machine == IMAGE_FILE_MACHINE_AMD64 || isAnyArm64(Machine);
+ return Machine == IMAGE_FILE_MACHINE_AMD64 || isAnyArm64(Machine) ||
+ Machine == IMAGE_FILE_MACHINE_LOONGARCH64;
}
enum Characteristics : unsigned {
diff --git a/llvm/include/llvm/Object/WindowsMachineFlag.h b/llvm/include/llvm/Object/WindowsMachineFlag.h
index 7655819ef50fd..82148de4b7c3b 100644
--- a/llvm/include/llvm/Object/WindowsMachineFlag.h
+++ b/llvm/include/llvm/Object/WindowsMachineFlag.h
@@ -44,6 +44,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_LOONGARCH64:
+ return llvm::Triple::ArchType::loongarch64;
case COFF::IMAGE_FILE_MACHINE_R4000:
return llvm::Triple::ArchType::mipsel;
default:
diff --git a/llvm/lib/BinaryFormat/Magic.cpp b/llvm/lib/BinaryFormat/Magic.cpp
index bd378337ed333..05d9e83822269 100644
--- a/llvm/lib/BinaryFormat/Magic.cpp
+++ b/llvm/lib/BinaryFormat/Magic.cpp
@@ -237,8 +237,9 @@ file_magic llvm::identify_magic(StringRef Magic) {
return file_magic::minidump;
break;
- case 0x64: // x86-64 or ARM64 Windows.
- if (Magic[1] == char(0x86) || Magic[1] == char(0xaa))
+ case 0x64: // x86-64 or ARM64 Windows or loongarch64.
+ if (Magic[1] == char(0x86) || Magic[1] == char(0xaa) ||
+ Magic[1] == char(0x62))
return file_magic::coff_object;
break;
diff --git a/llvm/lib/Object/COFFObjectFile.cpp b/llvm/lib/Object/COFFObjectFile.cpp
index 242c123665f76..46280e9e4bd40 100644
--- a/llvm/lib/Object/COFFObjectFile.cpp
+++ b/llvm/lib/Object/COFFObjectFile.cpp
@@ -1115,7 +1115,14 @@ dynamic_reloc_iterator COFFObjectFile::dynamic_reloc_end() const {
}
uint8_t COFFObjectFile::getBytesInAddress() const {
- return getArch() == Triple::x86_64 || getArch() == Triple::aarch64 ? 8 : 4;
+ switch (getArch()) {
+ case Triple::x86_64:
+ case Triple::aarch64:
+ case Triple::loongarch64:
+ return 8;
+ default:
+ return 4;
+ }
}
StringRef COFFObjectFile::getFileFormatName() const {
@@ -1132,6 +1139,8 @@ StringRef COFFObjectFile::getFileFormatName() const {
return "COFF-ARM64EC";
case COFF::IMAGE_FILE_MACHINE_ARM64X:
return "COFF-ARM64X";
+ case COFF::IMAGE_FILE_MACHINE_LOONGARCH64:
+ return "COFF-loongarch64";
case COFF::IMAGE_FILE_MACHINE_R4000:
return "COFF-MIPS";
default:
diff --git a/llvm/lib/Target/LoongArch/LoongArchTargetMachine.cpp b/llvm/lib/Target/LoongArch/LoongArchTargetMachine.cpp
index c36db9c75dd3a..1cb48a7c76162 100644
--- a/llvm/lib/Target/LoongArch/LoongArchTargetMachine.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchTargetMachine.cpp
@@ -58,8 +58,11 @@ static cl::opt<bool>
cl::init(false));
static std::string computeDataLayout(const Triple &TT) {
- if (TT.isArch64Bit())
+ if (TT.isArch64Bit()) {
+ if (TT.isUEFI())
+ return "e-m:w-p:64:64-i64:64-i128:128-n32:64-S128";
return "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128";
+ }
assert(TT.isArch32Bit() && "only LA32 and LA64 are currently supported");
return "e-m:e-p:32:32-i64:64-n32-S128";
}
@@ -89,6 +92,12 @@ getEffectiveLoongArchCodeModel(const Triple &TT,
}
}
+static std::unique_ptr<TargetLoweringObjectFile> createTLOF(const Triple &TT) {
+ if (TT.isOSBinFormatCOFF())
+ return std::make_unique<TargetLoweringObjectFileCOFF>();
+ return std::make_unique<TargetLoweringObjectFileELF>();
+}
+
LoongArchTargetMachine::LoongArchTargetMachine(
const Target &T, const Triple &TT, StringRef CPU, StringRef FS,
const TargetOptions &Options, std::optional<Reloc::Model> RM,
@@ -96,7 +105,7 @@ LoongArchTargetMachine::LoongArchTargetMachine(
: CodeGenTargetMachineImpl(T, computeDataLayout(TT), TT, CPU, FS, Options,
getEffectiveRelocModel(TT, RM),
getEffectiveLoongArchCodeModel(TT, CM), OL),
- TLOF(std::make_unique<TargetLoweringObjectFileELF>()) {
+ TLOF(createTLOF(getTargetTriple())) {
initAsmInfo();
}
diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/CMakeLists.txt b/llvm/lib/Target/LoongArch/MCTargetDesc/CMakeLists.txt
index 39b4423a63623..ae9077a7935c1 100644
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/CMakeLists.txt
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/CMakeLists.txt
@@ -9,6 +9,8 @@ add_llvm_component_library(LLVMLoongArchDesc
LoongArchMCTargetDesc.cpp
LoongArchMatInt.cpp
LoongArchTargetStreamer.cpp
+ LoongArchWinCOFFObjectWriter.cpp
+ LoongArchWinCOFFStreamer.cpp
LINK_COMPONENTS
MC
diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp
index 3b38ac95dcafa..d95b32e6d28e1 100644
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp
@@ -29,10 +29,10 @@
using namespace llvm;
LoongArchAsmBackend::LoongArchAsmBackend(const MCSubtargetInfo &STI,
- uint8_t OSABI, bool Is64Bit,
+ bool Is64Bit,
const MCTargetOptions &Options)
- : MCAsmBackend(llvm::endianness::little), STI(STI), OSABI(OSABI),
- Is64Bit(Is64Bit), TargetOptions(Options) {}
+ : MCAsmBackend(llvm::endianness::little), STI(STI), TargetOptions(Options),
+ Is64Bit(Is64Bit) {}
std::optional<MCFixupKind>
LoongArchAsmBackend::getFixupKind(StringRef Name) const {
@@ -494,16 +494,46 @@ bool LoongArchAsmBackend::addReloc(const MCFragment &F, const MCFixup &Fixup,
return true;
}
-std::unique_ptr<MCObjectTargetWriter>
-LoongArchAsmBackend::createObjectTargetWriter() const {
- return createLoongArchELFObjectWriter(OSABI, Is64Bit);
-}
+namespace {
+class ELFLoongArchAsmBackend : public LoongArchAsmBackend {
+ uint8_t OSABI;
+
+public:
+ ELFLoongArchAsmBackend(const MCSubtargetInfo &STI, uint8_t OSABI,
+ bool Is64Bit, const MCTargetOptions &Options)
+ : LoongArchAsmBackend(STI, Is64Bit, Options), OSABI(OSABI) {}
+
+ std::unique_ptr<MCObjectTargetWriter>
+ createObjectTargetWriter() const override {
+ return createLoongArchELFObjectWriter(OSABI, Is64Bit);
+ }
+};
+} // namespace
+
+namespace {
+class COFFLoongArchAsmBackend : public LoongArchAsmBackend {
+public:
+ COFFLoongArchAsmBackend(const MCSubtargetInfo &STI, bool Is64Bit,
+ const MCTargetOptions &Options)
+ : LoongArchAsmBackend(STI, Is64Bit, Options) {}
+
+ std::unique_ptr<MCObjectTargetWriter>
+ createObjectTargetWriter() const override {
+ return createLoongArchWinCOFFObjectWriter(Is64Bit);
+ }
+};
+} // namespace
MCAsmBackend *llvm::createLoongArchAsmBackend(const Target &T,
const MCSubtargetInfo &STI,
const MCRegisterInfo &MRI,
const MCTargetOptions &Options) {
const Triple &TT = STI.getTargetTriple();
+ if (TT.isOSBinFormatCOFF())
+ return new COFFLoongArchAsmBackend(STI, TT.isArch64Bit(), Options);
+
+ assert(TT.isOSBinFormatELF() && "Invalid target");
+
uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TT.getOS());
- return new LoongArchAsmBackend(STI, OSABI, TT.isArch64Bit(), Options);
+ return new ELFLoongArchAsmBackend(STI, OSABI, TT.isArch64Bit(), Options);
}
diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.h b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.h
index f79d3aa48c54c..b03282ba029a7 100644
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.h
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.h
@@ -24,18 +24,19 @@
namespace llvm {
class LoongArchAsmBackend : public MCAsmBackend {
- const MCSubtargetInfo &STI;
- uint8_t OSABI;
- bool Is64Bit;
- const MCTargetOptions &TargetOptions;
DenseMap<MCSection *, const MCSymbolRefExpr *> SecToAlignSym;
// Temporary symbol used to check whether a PC-relative fixup is resolved.
MCSymbol *PCRelTemp = nullptr;
bool isPCRelFixupResolved(const MCSymbol *SymA, const MCFragment &F);
+protected:
+ const MCSubtargetInfo &STI;
+ const MCTargetOptions &TargetOptions;
+ bool Is64Bit;
+
public:
- LoongArchAsmBackend(const MCSubtargetInfo &STI, uint8_t OSABI, bool Is64Bit,
+ LoongArchAsmBackend(const MCSubtargetInfo &STI, bool Is64Bit,
const MCTargetOptions &Options);
bool addReloc(const MCFragment &, const MCFixup &, const MCValue &,
@@ -57,8 +58,6 @@ class LoongArchAsmBackend : public MCAsmBackend {
bool writeNopData(raw_ostream &OS, uint64_t Count,
const MCSubtargetInfo *STI) const override;
- std::unique_ptr<MCObjectTargetWriter>
- createObjectTargetWriter() const override;
const MCTargetOptions &getTargetOptions() const { return TargetOptions; }
DenseMap<MCSection *, const MCSymbolRefExpr *> &getSecToAlignSym() {
return SecToAlignSym;
diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCAsmInfo.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCAsmInfo.cpp
index 0d7761777cb7d..e72bf3a5b7ff0 100644
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCAsmInfo.cpp
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCAsmInfo.cpp
@@ -14,6 +14,7 @@
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/TargetParser/Triple.h"
@@ -194,9 +195,9 @@ LoongArchMCExpr::Specifier LoongArch::parseSpecifier(StringRef name) {
.Default(0);
}
-void LoongArchMCAsmInfo::anchor() {}
+void LoongArchMCAsmInfoELF::anchor() {}
-LoongArchMCAsmInfo::LoongArchMCAsmInfo(const Triple &TT) {
+LoongArchMCAsmInfoELF::LoongArchMCAsmInfoELF(const Triple &TT) {
CodePointerSize = CalleeSaveStackSlotSize = TT.isArch64Bit() ? 8 : 4;
AlignmentIsInBytes = false;
Data8bitsDirective = "\t.byte\t";
@@ -211,8 +212,8 @@ LoongArchMCAsmInfo::LoongArchMCAsmInfo(const Triple &TT) {
ExceptionsType = ExceptionHandling::DwarfCFI;
}
-void LoongArchMCAsmInfo::printSpecifierExpr(raw_ostream &OS,
- const MCSpecifierExpr &Expr) const {
+void LoongArchMCAsmInfoELF::printSpecifierExpr(
+ raw_ostream &OS, const MCSpecifierExpr &Expr) const {
auto S = Expr.getSpecifier();
bool HasSpecifier = S != 0 && S != ELF::R_LARCH_B26;
if (HasSpecifier)
@@ -221,3 +222,22 @@ void LoongArchMCAsmInfo::printSpecifierExpr(raw_ostream &OS,
if (HasSpecifier)
OS << ')';
}
+
+void LoongArchMCAsmInfoMicrosoftCOFF::anchor() {}
+
+LoongArchMCAsmInfoMicrosoftCOFF::LoongArchMCAsmInfoMicrosoftCOFF(
+ const Triple &TT) {
+ PrivateGlobalPrefix = ".L";
+ PrivateLabelPrefix = ".L";
+
+ Data16bitsDirective = "\t.hword\t";
+ Data32bitsDirective = "\t.word\t";
+
+ AlignmentIsInBytes = false;
+ SupportsDebugInformation = true;
+ CodePointerSize = 8;
+
+ CommentString = "//";
+ ExceptionsType = ExceptionHandling::WinEH;
+ WinEHEncodingType = WinEH::EncodingType::Itanium;
+}
diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCAsmInfo.h b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCAsmInfo.h
index e4b29b2741fed..8a50dc23c42b9 100644
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCAsmInfo.h
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCAsmInfo.h
@@ -13,6 +13,7 @@
#ifndef LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHMCASMINFO_H
#define LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHMCASMINFO_H
+#include "llvm/MC/MCAsmInfoCOFF.h"
#include "llvm/MC/MCAsmInfoELF.h"
#include "llvm/MC/MCExpr.h"
@@ -38,15 +39,22 @@ class LoongArchMCExpr : public MCSpecifierExpr {
bool getRelaxHint() const { return RelaxHint; }
};
-class LoongArchMCAsmInfo : public MCAsmInfoELF {
+class LoongArchMCAsmInfoELF : public MCAsmInfoELF {
void anchor() override;
public:
- explicit LoongArchMCAsmInfo(const Triple &TargetTriple);
+ explicit LoongArchMCAsmInfoELF(const Triple &TargetTriple);
void printSpecifierExpr(raw_ostream &OS,
const MCSpecifierExpr &Expr) const override;
};
+class LoongArchMCAsmInfoMicrosoftCOFF : public MCAsmInfoMicrosoft {
+ void anchor() override;
+
+public:
+ explicit LoongArchMCAsmInfoMicrosoftCOFF(const Triple &Triple);
+};
+
namespace LoongArch {
uint16_t parseSpecifier(StringRef name);
} // namespace LoongArch
diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCTargetDesc.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCTargetDesc.cpp
index 35277ce094a7d..ec4c4c96b6f8a 100644
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCTargetDesc.cpp
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCTargetDesc.cpp
@@ -14,6 +14,7 @@
#include "LoongArchELFStreamer.h"
#include "LoongArchInstPrinter.h"
#include "LoongArchMCAsmInfo.h"
+#include "LoongArchWinCOFFStreamer.h"
#include "TargetInfo/LoongArchTargetInfo.h"
#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCAsmInfo.h"
@@ -61,7 +62,13 @@ createLoongArchMCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS) {
static MCAsmInfo *createLoongArchMCAsmInfo(const MCRegisterInfo &MRI,
const Triple &TT,
const MCTargetOptions &Options) {
- MCAsmInfo *MAI = new LoongArchMCAsmInfo(TT);
+ MCAsmInfo *MAI;
+ if (TT.isOSBinFormatCOFF()) {
+ MAI = new LoongArchMCAsmInfoMicrosoftCOFF(TT);
+ } else {
+ assert(TT.isOSBinFormatELF() && "Invalid target");
+ MAI = new LoongArchMCAsmInfoELF(TT);
+ }
// Initial state of the frame pointer is sp(r3).
unsigned SP = MRI.getDwarfRegNum(LoongArch::R3, true);
@@ -81,9 +88,11 @@ static MCInstPrinter *createLoongArchMCInstPrinter(const Triple &T,
static MCTargetStreamer *
createLoongArchObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) {
- return STI.getTargetTriple().isOSBinFormatELF()
- ? new LoongArchTargetELFStreamer(S, STI)
- : nullptr;
+ if (STI.getTargetTriple().isOSBinFormatELF())
+ return new LoongArchTargetELFStreamer(S, STI);
+ if (STI.getTargetTriple().isOSBinFormatCOFF())
+ return new LoongArchTargetWinCOFFStreamer(S);
+ return nullptr;
}
static MCTargetStreamer *
@@ -216,6 +225,7 @@ LLVMInitializeLoongArchTargetMC() {
TargetRegistry::RegisterMCInstPrinter(*T, createLoongArchMCInstPrinter);
TargetRegistry::RegisterMCInstrAnalysis(*T, createLoongArchInstrAnalysis);
TargetRegistry::RegisterELFStreamer(*T, createLoongArchELFStreamer);
+ TargetRegistry::RegisterCOFFStreamer(*T, createLoongArchWinCOFFStreamer);
TargetRegistry::RegisterObjectTargetStreamer(
*T, createLoongArchObjectTargetStreamer);
TargetRegistry::RegisterAsmTargetStreamer(*T,
diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCTargetDesc.h b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCTargetDesc.h
index ab35a0096c8a2..cbb5d51ed8662 100644
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCTargetDesc.h
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCTargetDesc.h
@@ -37,6 +37,8 @@ MCAsmBackend *createLoongArchAsmBackend(const Target &T,
std::unique_ptr<MCObjectTargetWriter>
createLoongArchELFObjectWriter(uint8_t OSABI, bool Is64Bit);
+std::unique_ptr<MCObjectTargetWriter>
+createLoongArchWinCOFFObjectWriter(bool Is64Bit);
} // end namespace llvm
diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchWinCOFFObjectWriter.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchWinCOFFObjectWriter.cpp
new file mode 100644
index 0000000000000..057cb3bcf4ed6
--- /dev/null
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchWinCOFFObjectWriter.cpp
@@ -0,0 +1,43 @@
+//===- LoongArchWinCOFFObjectWriter.cpp -----------------------*- C++ -*---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "MCTargetDesc/LoongArchFixupKinds.h"
+#include "MCTargetDesc/LoongArchMCTargetDesc.h"
+#include "llvm/BinaryFormat/COFF.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCWinCOFFObjectWriter.h"
+
+using namespace llvm;
+
+namespace {
+
+class LoongArchWinCOFFObjectWriter : public MCWinCOFFObjectTargetWriter {
+public:
+ LoongArchWinCOFFObjectWriter(bool Is64Bit);
+
+ unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
+ const MCFixup &Fixup, bool IsCrossSection,
+ const MCAsmBackend &MAB) const override;
+};
+
+} // end anonymous namespace
+
+LoongArchWinCOFFObjectWriter::LoongArchWinCOFFObjectWriter(bool Is64Bit)
+ : MCWinCOFFObjectTargetWriter(COFF::IMAGE_FILE_MACHINE_LOONGARCH64) {}
+
+unsigned LoongArchWinCOFFObjectWriter::getRelocType(
+ MCContext &Ctx, const MCValue &Target, const MCFixup &Fixup,
+ bool IsCrossSection, const MCAsmBackend &MAB) const {
+ // UEFI TODO: convert fixup to coff relocation
+ return Fixup.getKind();
+}
+
+std::unique_ptr<MCObjectTargetWriter>
+llvm::createLoongArchWinCOFFObjectWriter(bool Is64Bit) {
+ return std::make_unique<LoongArchWinCOFFObjectWriter>(Is64Bit);
+}
diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchWinCOFFStreamer.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchWinCOFFStreamer.cpp
new file mode 100644
index 0000000000000..a0b6c1aff1d30
--- /dev/null
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchWinCOFFStreamer.cpp
@@ -0,0 +1,34 @@
+//===- LoongArchWinCOFFStreamer.cpp -----------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "LoongArchWinCOFFStreamer.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 LoongArchWinCOFFStreamer : public MCWinCOFFStreamer {
+public:
+ LoongArchWinCOFFStreamer(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::createLoongArchWinCOFFStreamer(MCContext &C, std::unique_ptr<MCAsmBackend> &&AB,
+ std::unique_ptr<MCObjectWriter> &&OW,
+ std::unique_ptr<MCCodeEmitter> &&CE) {
+ return new LoongArchWinCOFFStreamer(C, std::move(AB), std::move(CE),
+ std::move(OW));
+}
diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchWinCOFFStreamer.h b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchWinCOFFStreamer.h
new file mode 100644
index 0000000000000..852cdbc6f0cba
--- /dev/null
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchWinCOFFStreamer.h
@@ -0,0 +1,28 @@
+//===-- LoongArchWinCOFFStreamer.h -----------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHWINCOFFSTREAMER_H
+#define LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHWINCOFFSTREAMER_H
+
+#include "LoongArchTargetStreamer.h"
+#include "llvm/MC/MCWinCOFFStreamer.h"
+
+namespace llvm {
+
+class LoongArchTargetWinCOFFStreamer : public LoongArchTargetStreamer {
+public:
+ LoongArchTargetWinCOFFStreamer(MCStreamer &S) : LoongArchTargetStreamer(S) {}
+};
+
+MCStreamer *
+createLoongArchWinCOFFStreamer(MCContext &C,
+ std::unique_ptr<MCAsmBackend> &&MAB,
+ std::unique_ptr<MCObjectWriter> &&MOW,
+ std::unique_ptr<MCCodeEmitter> &&MCE);
+} // end namespace llvm
+#endif
diff --git a/llvm/lib/TargetParser/Triple.cpp b/llvm/lib/TargetParser/Triple.cpp
index 6acb0bc49ecfe..b4a877c50fa84 100644
--- a/llvm/lib/TargetParser/Triple.cpp
+++ b/llvm/lib/TargetParser/Triple.cpp
@@ -966,7 +966,6 @@ static Triple::ObjectFormatType getDefaultFormat(const Triple &T) {
case Triple::kalimba:
case Triple::lanai:
case Triple::loongarch32:
- case Triple::loongarch64:
case Triple::m68k:
case Triple::mips64:
case Triple::mips64el:
@@ -997,6 +996,11 @@ static Triple::ObjectFormatType getDefaultFormat(const Triple &T) {
case Triple::xtensa:
return Triple::ELF;
+ case Triple::loongarch64:
+ if (T.isUEFI())
+ return Triple::COFF;
+ return Triple::ELF;
+
case Triple::mipsel:
if (T.isOSWindows())
return Triple::COFF;
diff --git a/llvm/tools/llvm-readobj/COFFDumper.cpp b/llvm/tools/llvm-readobj/COFFDumper.cpp
index 96e0a634648e4..cc5a48dd25300 100644
--- a/llvm/tools/llvm-readobj/COFFDumper.cpp
+++ b/llvm/tools/llvm-readobj/COFFDumper.cpp
@@ -352,6 +352,7 @@ const EnumEntry<COFF::MachineTypes> ImageFileMachineType[] = {
LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_I386 ),
LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_IA64 ),
LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_M32R ),
+ LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_LOONGARCH64),
LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_MIPS16 ),
LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_MIPSFPU ),
LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_MIPSFPU16),
diff --git a/llvm/utils/gn/secondary/llvm/lib/Target/LoongArch/MCTargetDesc/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/Target/LoongArch/MCTargetDesc/BUILD.gn
index 1ec5591cd6596..d5a99541bd36f 100644
--- a/llvm/utils/gn/secondary/llvm/lib/Target/LoongArch/MCTargetDesc/BUILD.gn
+++ b/llvm/utils/gn/secondary/llvm/lib/Target/LoongArch/MCTargetDesc/BUILD.gn
@@ -61,5 +61,7 @@ static_library("MCTargetDesc") {
"LoongArchMCTargetDesc.cpp",
"LoongArchMatInt.cpp",
"LoongArchTargetStreamer.cpp",
+ "LoongArchWinCOFFObjectWriter.cpp",
+ "LoongArchWinCOFFStreamer.cpp",
]
}
More information about the llvm-commits
mailing list