-
Notifications
You must be signed in to change notification settings - Fork 14.9k
[LoongArch] Add basic UEFI support #154883
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
@llvm/pr-subscribers-clang @llvm/pr-subscribers-backend-loongarch Author: None (leecheechen) ChangesThis patch adds initial UEFI support for LoongArch64, enabling the compilation and generation of UEFI applications for LoongArch targets. Key changes include:
The implementation provides the foundational infrastructure for generating UEFI-compatible PE/COFF binaries for LoongArch64 systems. Patch is 25.25 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/154883.diff 21 Files Affected:
diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp
index e3f9760ac7ce3..ea854e42e4396 100644
--- a/clang/lib/Basic/Targets.cpp
+++ b/clang/lib/Basic/Targets.cpp
@@ -760,6 +760,9 @@ std::unique_ptr<TargetInfo> AllocateTarget(const llvm::Triple &Triple,
case llvm::Triple::OpenBSD:
return std::make_unique<OpenBSDTargetInfo<LoongArch64TargetInfo>>(Triple,
Opts);
+ case llvm::Triple::UEFI:
+ return std::make_unique<UEFITargetInfo<LoongArch64TargetInfo>>(Triple,
+ Opts);
default:
return std::make_unique<LoongArch64TargetInfo>(Triple, Opts);
}
diff --git a/clang/lib/Basic/Targets/LoongArch.h b/clang/lib/Basic/Targets/LoongArch.h
index 88dc433924d6c..ae0838a58dd63 100644
--- a/clang/lib/Basic/Targets/LoongArch.h
+++ b/clang/lib/Basic/Targets/LoongArch.h
@@ -13,6 +13,7 @@
#ifndef LLVM_CLANG_LIB_BASIC_TARGETS_LOONGARCH_H
#define LLVM_CLANG_LIB_BASIC_TARGETS_LOONGARCH_H
+#include "OSTargets.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"
#include "llvm/Support/Compiler.h"
@@ -159,6 +160,8 @@ class LLVM_LIBRARY_VISIBILITY LoongArch64TargetInfo
IntMaxType = Int64Type = SignedLong;
HasUnalignedAccess = true;
resetDataLayout("e-m:e-p:64:64-i64:64-i128:128-n32:64-S128");
+ if (Triple.isUEFI())
+ resetDataLayout("e-m:w-p:64:64-i64:64-i128:128-n32:64-S128");
// TODO: select appropriate ABI.
setABI("lp64d");
}
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index d682ffc832c83..9faeb33ba10b6 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -698,8 +698,10 @@ static llvm::Triple computeTargetTriple(const Driver &D,
}
}
- // Currently the only architecture supported by *-uefi triples are x86_64.
- if (Target.isUEFI() && Target.getArch() != llvm::Triple::x86_64)
+ // Currently the only architectures supported by *-uefi triples are
+ // x86_64 and loongarch64.
+ if (Target.isUEFI() && Target.getArch() != llvm::Triple::x86_64 &&
+ Target.getArch() != llvm::Triple::loongarch64)
D.Diag(diag::err_target_unknown_triple) << Target.str();
// The `-maix[32|64]` flags are only valid for AIX targets.
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..979e5002c5ed4 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,14 @@ 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 +89,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 +226,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::createLoongArch...
[truncated]
|
@llvm/pr-subscribers-llvm-binary-utilities Author: None (leecheechen) ChangesThis patch adds initial UEFI support for LoongArch64, enabling the compilation and generation of UEFI applications for LoongArch targets. Key changes include:
The implementation provides the foundational infrastructure for generating UEFI-compatible PE/COFF binaries for LoongArch64 systems. Patch is 25.25 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/154883.diff 21 Files Affected:
diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp
index e3f9760ac7ce3..ea854e42e4396 100644
--- a/clang/lib/Basic/Targets.cpp
+++ b/clang/lib/Basic/Targets.cpp
@@ -760,6 +760,9 @@ std::unique_ptr<TargetInfo> AllocateTarget(const llvm::Triple &Triple,
case llvm::Triple::OpenBSD:
return std::make_unique<OpenBSDTargetInfo<LoongArch64TargetInfo>>(Triple,
Opts);
+ case llvm::Triple::UEFI:
+ return std::make_unique<UEFITargetInfo<LoongArch64TargetInfo>>(Triple,
+ Opts);
default:
return std::make_unique<LoongArch64TargetInfo>(Triple, Opts);
}
diff --git a/clang/lib/Basic/Targets/LoongArch.h b/clang/lib/Basic/Targets/LoongArch.h
index 88dc433924d6c..ae0838a58dd63 100644
--- a/clang/lib/Basic/Targets/LoongArch.h
+++ b/clang/lib/Basic/Targets/LoongArch.h
@@ -13,6 +13,7 @@
#ifndef LLVM_CLANG_LIB_BASIC_TARGETS_LOONGARCH_H
#define LLVM_CLANG_LIB_BASIC_TARGETS_LOONGARCH_H
+#include "OSTargets.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"
#include "llvm/Support/Compiler.h"
@@ -159,6 +160,8 @@ class LLVM_LIBRARY_VISIBILITY LoongArch64TargetInfo
IntMaxType = Int64Type = SignedLong;
HasUnalignedAccess = true;
resetDataLayout("e-m:e-p:64:64-i64:64-i128:128-n32:64-S128");
+ if (Triple.isUEFI())
+ resetDataLayout("e-m:w-p:64:64-i64:64-i128:128-n32:64-S128");
// TODO: select appropriate ABI.
setABI("lp64d");
}
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index d682ffc832c83..9faeb33ba10b6 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -698,8 +698,10 @@ static llvm::Triple computeTargetTriple(const Driver &D,
}
}
- // Currently the only architecture supported by *-uefi triples are x86_64.
- if (Target.isUEFI() && Target.getArch() != llvm::Triple::x86_64)
+ // Currently the only architectures supported by *-uefi triples are
+ // x86_64 and loongarch64.
+ if (Target.isUEFI() && Target.getArch() != llvm::Triple::x86_64 &&
+ Target.getArch() != llvm::Triple::loongarch64)
D.Diag(diag::err_target_unknown_triple) << Target.str();
// The `-maix[32|64]` flags are only valid for AIX targets.
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..979e5002c5ed4 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,14 @@ 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 +89,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 +226,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::createLoongArch...
[truncated]
|
You can test this locally with the following command:git-clang-format --diff HEAD~1 HEAD --extensions h,cpp -- llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchWinCOFFObjectWriter.cpp llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchWinCOFFStreamer.cpp llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchWinCOFFStreamer.h llvm/include/llvm/BinaryFormat/COFF.h llvm/include/llvm/Object/WindowsMachineFlag.h llvm/lib/BinaryFormat/Magic.cpp llvm/lib/Object/COFFObjectFile.cpp llvm/lib/Target/LoongArch/LoongArchTargetMachine.cpp llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.h llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCAsmInfo.cpp llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCAsmInfo.h llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCTargetDesc.cpp llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCTargetDesc.h llvm/lib/TargetParser/Triple.cpp llvm/tools/llvm-readobj/COFFDumper.cpp View the diff from clang-format here.diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchWinCOFFStreamer.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchWinCOFFStreamer.cpp
index a0b6c1aff..2a129989c 100644
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchWinCOFFStreamer.cpp
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchWinCOFFStreamer.cpp
@@ -25,10 +25,9 @@ public:
};
} // namespace
-MCStreamer *
-llvm::createLoongArchWinCOFFStreamer(MCContext &C, std::unique_ptr<MCAsmBackend> &&AB,
- std::unique_ptr<MCObjectWriter> &&OW,
- std::unique_ptr<MCCodeEmitter> &&CE) {
+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/tools/llvm-readobj/COFFDumper.cpp b/llvm/tools/llvm-readobj/COFFDumper.cpp
index cc5a48dd2..553daba73 100644
--- a/llvm/tools/llvm-readobj/COFFDumper.cpp
+++ b/llvm/tools/llvm-readobj/COFFDumper.cpp
@@ -340,32 +340,31 @@ void COFFDumper::printBinaryBlockWithRelocs(StringRef Label,
}
const EnumEntry<COFF::MachineTypes> ImageFileMachineType[] = {
- LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_UNKNOWN ),
- LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_AM33 ),
- LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_AMD64 ),
- LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_ARM ),
- LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_ARM64 ),
- LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_ARM64EC ),
- LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_ARM64X ),
- LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_ARMNT ),
- LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_EBC ),
- 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),
- LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_POWERPC ),
- LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_POWERPCFP),
- LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_R4000 ),
- LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_SH3 ),
- LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_SH3DSP ),
- LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_SH4 ),
- LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_SH5 ),
- LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_THUMB ),
- LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_WCEMIPSV2)
-};
+ LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_UNKNOWN),
+ LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_AM33),
+ LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_AMD64),
+ LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_ARM),
+ LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_ARM64),
+ LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_ARM64EC),
+ LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_ARM64X),
+ LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_ARMNT),
+ LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_EBC),
+ 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),
+ LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_POWERPC),
+ LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_POWERPCFP),
+ LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_R4000),
+ LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_SH3),
+ LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_SH3DSP),
+ LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_SH4),
+ LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_SH5),
+ LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_THUMB),
+ LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_WCEMIPSV2)};
const EnumEntry<COFF::Characteristics> ImageFileCharacteristics[] = {
LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_RELOCS_STRIPPED ),
|
|
||
namespace llvm { | ||
MCStreamer * | ||
createLoongArchWinCOFFStreamer(MCContext &C, std::unique_ptr<MCAsmBackend> &&AB, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
llvm::createLoongArchWinCOFFStreamer
https://llvm.org/docs/CodingStandards.html#use-namespace-qualifiers-to-implement-previously-declared-functions
@@ -61,7 +62,14 @@ 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; | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
delete blank line
we don't typically insert a blank line after variable declaration.
clang/lib/Driver/Driver.cpp
Outdated
if (Target.isUEFI() && Target.getArch() != llvm::Triple::x86_64) | ||
// Currently the only architectures supported by *-uefi triples are | ||
// x86_64 and loongarch64. | ||
if (Target.isUEFI() && Target.getArch() != llvm::Triple::x86_64 && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs clang/test/Driver test
clang/lib/Basic/Targets.cpp
Outdated
@@ -760,6 +760,9 @@ std::unique_ptr<TargetInfo> AllocateTarget(const llvm::Triple &Triple, | |||
case llvm::Triple::OpenBSD: | |||
return std::make_unique<OpenBSDTargetInfo<LoongArch64TargetInfo>>(Triple, | |||
Opts); | |||
case llvm::Triple::UEFI: | |||
return std::make_unique<UEFITargetInfo<LoongArch64TargetInfo>>(Triple, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
need a clang/test/CodeGen/LoongArch/ test. please check existing uefi target tests.
Please extract the clang part to a separate patch
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All comments have been addressed. Thanks for all the reviews!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR has been split into two separate PRS. The other PR is #155598
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@loongson.cn>
7efe043
to
a47f54c
Compare
The commit message should be updated. |
This patch adds initial UEFI support for LoongArch64, enabling the compilation and generation of UEFI applications for LoongArch targets.
Key changes include:
Target support enhancements:
https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#machine-types
COFF object file support:
Code generation infrastructure:
Toolchain updates:
The implementation provides the foundational infrastructure for generating UEFI-compatible PE/COFF binaries for LoongArch64 systems.