Skip to content

Commit 29d4eee

Browse files
leecheechenheiher
andcommitted
[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 <[email protected]>
1 parent 114b3b8 commit 29d4eee

File tree

22 files changed

+320
-57
lines changed

22 files changed

+320
-57
lines changed

llvm/include/llvm/BinaryFormat/COFF.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ enum MachineTypes : unsigned {
104104
IMAGE_FILE_MACHINE_EBC = 0xEBC,
105105
IMAGE_FILE_MACHINE_I386 = 0x14C,
106106
IMAGE_FILE_MACHINE_IA64 = 0x200,
107+
IMAGE_FILE_MACHINE_LOONGARCH64 = 0x6264,
107108
IMAGE_FILE_MACHINE_M32R = 0x9041,
108109
IMAGE_FILE_MACHINE_MIPS16 = 0x266,
109110
IMAGE_FILE_MACHINE_MIPSFPU = 0x366,
@@ -132,7 +133,8 @@ template <typename T> bool isAnyArm64(T Machine) {
132133
}
133134

134135
template <typename T> bool is64Bit(T Machine) {
135-
return Machine == IMAGE_FILE_MACHINE_AMD64 || isAnyArm64(Machine);
136+
return Machine == IMAGE_FILE_MACHINE_AMD64 || isAnyArm64(Machine) ||
137+
Machine == IMAGE_FILE_MACHINE_LOONGARCH64;
136138
}
137139

138140
enum Characteristics : unsigned {

llvm/include/llvm/Object/WindowsMachineFlag.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ template <typename T> Triple::ArchType getMachineArchType(T machine) {
4444
case COFF::IMAGE_FILE_MACHINE_ARM64EC:
4545
case COFF::IMAGE_FILE_MACHINE_ARM64X:
4646
return llvm::Triple::ArchType::aarch64;
47+
case COFF::IMAGE_FILE_MACHINE_LOONGARCH64:
48+
return llvm::Triple::ArchType::loongarch64;
4749
case COFF::IMAGE_FILE_MACHINE_R4000:
4850
return llvm::Triple::ArchType::mipsel;
4951
default:

llvm/lib/BinaryFormat/Magic.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,8 +237,9 @@ file_magic llvm::identify_magic(StringRef Magic) {
237237
return file_magic::minidump;
238238
break;
239239

240-
case 0x64: // x86-64 or ARM64 Windows.
241-
if (Magic[1] == char(0x86) || Magic[1] == char(0xaa))
240+
case 0x64: // x86-64, ARM64 Windows, or loongarch64.
241+
if (Magic[1] == char(0x86) || Magic[1] == char(0xaa) ||
242+
Magic[1] == char(0x62))
242243
return file_magic::coff_object;
243244
break;
244245

llvm/lib/Object/COFFObjectFile.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1115,7 +1115,14 @@ dynamic_reloc_iterator COFFObjectFile::dynamic_reloc_end() const {
11151115
}
11161116

11171117
uint8_t COFFObjectFile::getBytesInAddress() const {
1118-
return getArch() == Triple::x86_64 || getArch() == Triple::aarch64 ? 8 : 4;
1118+
switch (getArch()) {
1119+
case Triple::x86_64:
1120+
case Triple::aarch64:
1121+
case Triple::loongarch64:
1122+
return 8;
1123+
default:
1124+
return 4;
1125+
}
11191126
}
11201127

11211128
StringRef COFFObjectFile::getFileFormatName() const {
@@ -1132,6 +1139,8 @@ StringRef COFFObjectFile::getFileFormatName() const {
11321139
return "COFF-ARM64EC";
11331140
case COFF::IMAGE_FILE_MACHINE_ARM64X:
11341141
return "COFF-ARM64X";
1142+
case COFF::IMAGE_FILE_MACHINE_LOONGARCH64:
1143+
return "COFF-loongarch64";
11351144
case COFF::IMAGE_FILE_MACHINE_R4000:
11361145
return "COFF-MIPS";
11371146
default:

llvm/lib/Target/LoongArch/LoongArchTargetMachine.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,14 +82,20 @@ getEffectiveLoongArchCodeModel(const Triple &TT,
8282
}
8383
}
8484

85+
static std::unique_ptr<TargetLoweringObjectFile> createTLOF(const Triple &TT) {
86+
if (TT.isOSBinFormatCOFF())
87+
return std::make_unique<TargetLoweringObjectFileCOFF>();
88+
return std::make_unique<TargetLoweringObjectFileELF>();
89+
}
90+
8591
LoongArchTargetMachine::LoongArchTargetMachine(
8692
const Target &T, const Triple &TT, StringRef CPU, StringRef FS,
8793
const TargetOptions &Options, std::optional<Reloc::Model> RM,
8894
std::optional<CodeModel::Model> CM, CodeGenOptLevel OL, bool JIT)
8995
: CodeGenTargetMachineImpl(T, TT.computeDataLayout(), TT, CPU, FS, Options,
9096
getEffectiveRelocModel(TT, RM),
9197
getEffectiveLoongArchCodeModel(TT, CM), OL),
92-
TLOF(std::make_unique<TargetLoweringObjectFileELF>()) {
98+
TLOF(createTLOF(getTargetTriple())) {
9399
initAsmInfo();
94100
}
95101

llvm/lib/Target/LoongArch/MCTargetDesc/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ add_llvm_component_library(LLVMLoongArchDesc
99
LoongArchMCTargetDesc.cpp
1010
LoongArchMatInt.cpp
1111
LoongArchTargetStreamer.cpp
12+
LoongArchWinCOFFObjectWriter.cpp
13+
LoongArchWinCOFFStreamer.cpp
1214

1315
LINK_COMPONENTS
1416
MC

llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,10 @@
2929
using namespace llvm;
3030

3131
LoongArchAsmBackend::LoongArchAsmBackend(const MCSubtargetInfo &STI,
32-
uint8_t OSABI, bool Is64Bit,
32+
bool Is64Bit,
3333
const MCTargetOptions &Options)
34-
: MCAsmBackend(llvm::endianness::little), STI(STI), OSABI(OSABI),
35-
Is64Bit(Is64Bit), TargetOptions(Options) {}
34+
: MCAsmBackend(llvm::endianness::little), STI(STI), TargetOptions(Options),
35+
Is64Bit(Is64Bit) {}
3636

3737
std::optional<MCFixupKind>
3838
LoongArchAsmBackend::getFixupKind(StringRef Name) const {
@@ -484,16 +484,46 @@ bool LoongArchAsmBackend::addReloc(const MCFragment &F, const MCFixup &Fixup,
484484
return true;
485485
}
486486

487-
std::unique_ptr<MCObjectTargetWriter>
488-
LoongArchAsmBackend::createObjectTargetWriter() const {
489-
return createLoongArchELFObjectWriter(OSABI, Is64Bit);
490-
}
487+
namespace {
488+
class ELFLoongArchAsmBackend : public LoongArchAsmBackend {
489+
uint8_t OSABI;
490+
491+
public:
492+
ELFLoongArchAsmBackend(const MCSubtargetInfo &STI, uint8_t OSABI,
493+
bool Is64Bit, const MCTargetOptions &Options)
494+
: LoongArchAsmBackend(STI, Is64Bit, Options), OSABI(OSABI) {}
495+
496+
std::unique_ptr<MCObjectTargetWriter>
497+
createObjectTargetWriter() const override {
498+
return createLoongArchELFObjectWriter(OSABI, Is64Bit);
499+
}
500+
};
501+
} // namespace
502+
503+
namespace {
504+
class COFFLoongArchAsmBackend : public LoongArchAsmBackend {
505+
public:
506+
COFFLoongArchAsmBackend(const MCSubtargetInfo &STI, bool Is64Bit,
507+
const MCTargetOptions &Options)
508+
: LoongArchAsmBackend(STI, Is64Bit, Options) {}
509+
510+
std::unique_ptr<MCObjectTargetWriter>
511+
createObjectTargetWriter() const override {
512+
return createLoongArchWinCOFFObjectWriter(Is64Bit);
513+
}
514+
};
515+
} // namespace
491516

492517
MCAsmBackend *llvm::createLoongArchAsmBackend(const Target &T,
493518
const MCSubtargetInfo &STI,
494519
const MCRegisterInfo &MRI,
495520
const MCTargetOptions &Options) {
496521
const Triple &TT = STI.getTargetTriple();
522+
if (TT.isOSBinFormatCOFF())
523+
return new COFFLoongArchAsmBackend(STI, TT.isArch64Bit(), Options);
524+
525+
assert(TT.isOSBinFormatELF() && "Invalid target");
526+
497527
uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TT.getOS());
498-
return new LoongArchAsmBackend(STI, OSABI, TT.isArch64Bit(), Options);
528+
return new ELFLoongArchAsmBackend(STI, OSABI, TT.isArch64Bit(), Options);
499529
}

llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.h

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,19 @@
2424
namespace llvm {
2525

2626
class LoongArchAsmBackend : public MCAsmBackend {
27-
const MCSubtargetInfo &STI;
28-
uint8_t OSABI;
29-
bool Is64Bit;
30-
const MCTargetOptions &TargetOptions;
3127
DenseMap<MCSection *, const MCSymbolRefExpr *> SecToAlignSym;
3228
// Temporary symbol used to check whether a PC-relative fixup is resolved.
3329
MCSymbol *PCRelTemp = nullptr;
3430

3531
bool isPCRelFixupResolved(const MCSymbol *SymA, const MCFragment &F);
3632

33+
protected:
34+
const MCSubtargetInfo &STI;
35+
const MCTargetOptions &TargetOptions;
36+
bool Is64Bit;
37+
3738
public:
38-
LoongArchAsmBackend(const MCSubtargetInfo &STI, uint8_t OSABI, bool Is64Bit,
39+
LoongArchAsmBackend(const MCSubtargetInfo &STI, bool Is64Bit,
3940
const MCTargetOptions &Options);
4041

4142
bool addReloc(const MCFragment &, const MCFixup &, const MCValue &,
@@ -57,8 +58,6 @@ class LoongArchAsmBackend : public MCAsmBackend {
5758
bool writeNopData(raw_ostream &OS, uint64_t Count,
5859
const MCSubtargetInfo *STI) const override;
5960

60-
std::unique_ptr<MCObjectTargetWriter>
61-
createObjectTargetWriter() const override;
6261
const MCTargetOptions &getTargetOptions() const { return TargetOptions; }
6362
DenseMap<MCSection *, const MCSymbolRefExpr *> &getSecToAlignSym() {
6463
return SecToAlignSym;

llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCAsmInfo.cpp

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "llvm/BinaryFormat/Dwarf.h"
1515
#include "llvm/BinaryFormat/ELF.h"
1616
#include "llvm/MC/MCContext.h"
17+
#include "llvm/MC/MCExpr.h"
1718
#include "llvm/MC/MCStreamer.h"
1819
#include "llvm/TargetParser/Triple.h"
1920

@@ -194,9 +195,9 @@ LoongArchMCExpr::Specifier LoongArch::parseSpecifier(StringRef name) {
194195
.Default(0);
195196
}
196197

197-
void LoongArchMCAsmInfo::anchor() {}
198+
void LoongArchMCAsmInfoELF::anchor() {}
198199

199-
LoongArchMCAsmInfo::LoongArchMCAsmInfo(const Triple &TT) {
200+
LoongArchMCAsmInfoELF::LoongArchMCAsmInfoELF(const Triple &TT) {
200201
CodePointerSize = CalleeSaveStackSlotSize = TT.isArch64Bit() ? 8 : 4;
201202
AlignmentIsInBytes = false;
202203
Data8bitsDirective = "\t.byte\t";
@@ -211,8 +212,8 @@ LoongArchMCAsmInfo::LoongArchMCAsmInfo(const Triple &TT) {
211212
ExceptionsType = ExceptionHandling::DwarfCFI;
212213
}
213214

214-
void LoongArchMCAsmInfo::printSpecifierExpr(raw_ostream &OS,
215-
const MCSpecifierExpr &Expr) const {
215+
void LoongArchMCAsmInfoELF::printSpecifierExpr(
216+
raw_ostream &OS, const MCSpecifierExpr &Expr) const {
216217
auto S = Expr.getSpecifier();
217218
bool HasSpecifier = S != 0 && S != ELF::R_LARCH_B26;
218219
if (HasSpecifier)
@@ -221,3 +222,21 @@ void LoongArchMCAsmInfo::printSpecifierExpr(raw_ostream &OS,
221222
if (HasSpecifier)
222223
OS << ')';
223224
}
225+
226+
void LoongArchMCAsmInfoMicrosoftCOFF::anchor() {}
227+
228+
LoongArchMCAsmInfoMicrosoftCOFF::LoongArchMCAsmInfoMicrosoftCOFF(
229+
const Triple &TT) {
230+
PrivateGlobalPrefix = ".L";
231+
PrivateLabelPrefix = ".L";
232+
233+
Data16bitsDirective = "\t.hword\t";
234+
Data32bitsDirective = "\t.word\t";
235+
236+
AlignmentIsInBytes = false;
237+
SupportsDebugInformation = true;
238+
CodePointerSize = 8;
239+
240+
ExceptionsType = ExceptionHandling::WinEH;
241+
WinEHEncodingType = WinEH::EncodingType::Itanium;
242+
}

llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCAsmInfo.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#ifndef LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHMCASMINFO_H
1414
#define LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHMCASMINFO_H
1515

16+
#include "llvm/MC/MCAsmInfoCOFF.h"
1617
#include "llvm/MC/MCAsmInfoELF.h"
1718
#include "llvm/MC/MCExpr.h"
1819

@@ -38,15 +39,22 @@ class LoongArchMCExpr : public MCSpecifierExpr {
3839
bool getRelaxHint() const { return RelaxHint; }
3940
};
4041

41-
class LoongArchMCAsmInfo : public MCAsmInfoELF {
42+
class LoongArchMCAsmInfoELF : public MCAsmInfoELF {
4243
void anchor() override;
4344

4445
public:
45-
explicit LoongArchMCAsmInfo(const Triple &TargetTriple);
46+
explicit LoongArchMCAsmInfoELF(const Triple &TargetTriple);
4647
void printSpecifierExpr(raw_ostream &OS,
4748
const MCSpecifierExpr &Expr) const override;
4849
};
4950

51+
class LoongArchMCAsmInfoMicrosoftCOFF : public MCAsmInfoMicrosoft {
52+
void anchor() override;
53+
54+
public:
55+
explicit LoongArchMCAsmInfoMicrosoftCOFF(const Triple &Triple);
56+
};
57+
5058
namespace LoongArch {
5159
uint16_t parseSpecifier(StringRef name);
5260
} // namespace LoongArch

0 commit comments

Comments
 (0)