Skip to content

Commit 27a86fe

Browse files
leecheechenheiher
andcommitted
[MC][LoongArch] Add WinCOFFObjectWriter/WinCOFFStreamer
Co-Authored-By: WANG Rui <[email protected]>
1 parent f175030 commit 27a86fe

File tree

18 files changed

+292
-27
lines changed

18 files changed

+292
-27
lines changed

clang/lib/Driver/Driver.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -699,8 +699,10 @@ static llvm::Triple computeTargetTriple(const Driver &D,
699699
}
700700
}
701701

702-
// Currently the only architecture supported by *-uefi triples are x86_64.
703-
if (Target.isUEFI() && Target.getArch() != llvm::Triple::x86_64)
702+
// Currently the only architectures supported by *-uefi triples are
703+
// x86_64 and LoongArch64.
704+
if (Target.isUEFI() && Target.getArch() != llvm::Triple::x86_64 &&
705+
Target.getArch() != llvm::Triple::loongarch64)
704706
D.Diag(diag::err_target_unknown_triple) << Target.str();
705707

706708
// The `-maix[32|64]` flags are only valid for AIX targets.

llvm/include/llvm/BinaryFormat/COFF.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ enum MachineTypes : unsigned {
103103
IMAGE_FILE_MACHINE_EBC = 0xEBC,
104104
IMAGE_FILE_MACHINE_I386 = 0x14C,
105105
IMAGE_FILE_MACHINE_IA64 = 0x200,
106+
IMAGE_FILE_MACHINE_LOONGARCH64 = 0x6264,
106107
IMAGE_FILE_MACHINE_M32R = 0x9041,
107108
IMAGE_FILE_MACHINE_MIPS16 = 0x266,
108109
IMAGE_FILE_MACHINE_MIPSFPU = 0x366,
@@ -435,6 +436,23 @@ enum RelocationTypesMips : unsigned {
435436
IMAGE_REL_MIPS_PAIR = 0x0025,
436437
};
437438

439+
enum RelocationTypesLoongArch : unsigned {
440+
IMAGE_REL_LARCH_ABSOLUTE = 0x0000,
441+
IMAGE_REL_LARCH_ADDR32 = 0x0001,
442+
IMAGE_REL_LARCH_ADDR32NB = 0x0002,
443+
IMAGE_REL_LARCH_BRANCH26 = 0x0003,
444+
IMAGE_REL_LARCH_SECREL = 0x0004,
445+
IMAGE_REL_LARCH_SECTION = 0x0005,
446+
IMAGE_REL_LARCH_ADDR64 = 0x0006,
447+
IMAGE_REL_LARCH_ADDR_HI20 = 0x0007,
448+
IMAGE_REL_LARCH_ADDR_LO12 = 0x008,
449+
IMAGE_REL_LARCH_ADDR64_LO20 = 0x0009,
450+
IMAGE_REL_LARCH_ADDR64_HI12 = 0x000A,
451+
IMAGE_REL_LARCH_BRANCH21 = 0x000B,
452+
IMAGE_REL_LARCH_BRANCH16 = 0x000C,
453+
IMAGE_REL_LARCH_REL32 = 0x000D,
454+
};
455+
438456
enum DynamicRelocationType : unsigned {
439457
IMAGE_DYNAMIC_RELOCATION_GUARD_RF_PROLOGUE = 1,
440458
IMAGE_DYNAMIC_RELOCATION_GUARD_RF_EPILOGUE = 2,
@@ -726,6 +744,7 @@ enum BaseRelocationType : unsigned {
726744
IMAGE_REL_BASED_MIPS_JMPADDR = 5,
727745
IMAGE_REL_BASED_ARM_MOV32A = 5,
728746
IMAGE_REL_BASED_ARM_MOV32T = 7,
747+
IMAGE_REL_BASED_LOONGARCH64_MARK_LA = 8,
729748
IMAGE_REL_BASED_MIPS_JMPADDR16 = 9,
730749
IMAGE_REL_BASED_DIR64 = 10
731750
};

llvm/include/llvm/Object/WindowsMachineFlag.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ template <typename T> Triple::ArchType getMachineArchType(T machine) {
4343
case COFF::IMAGE_FILE_MACHINE_ARM64EC:
4444
case COFF::IMAGE_FILE_MACHINE_ARM64X:
4545
return llvm::Triple::ArchType::aarch64;
46+
case COFF::IMAGE_FILE_MACHINE_LOONGARCH64:
47+
return llvm::Triple::ArchType::loongarch64;
4648
case COFF::IMAGE_FILE_MACHINE_R4000:
4749
return llvm::Triple::ArchType::mipsel;
4850
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 or 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: 30 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:
@@ -1488,6 +1497,26 @@ StringRef COFFObjectFile::getRelocationTypeName(uint16_t Type) const {
14881497
return "Unknown";
14891498
}
14901499
break;
1500+
case Triple::loongarch64:
1501+
switch (Type) {
1502+
LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_LARCH_ABSOLUTE);
1503+
LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_LARCH_ADDR32);
1504+
LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_LARCH_ADDR32NB);
1505+
LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_LARCH_BRANCH26);
1506+
LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_LARCH_SECREL);
1507+
LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_LARCH_SECTION);
1508+
LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_LARCH_ADDR64);
1509+
LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_LARCH_ADDR_HI20);
1510+
LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_LARCH_ADDR_LO12);
1511+
LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_LARCH_ADDR64_LO20);
1512+
LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_LARCH_ADDR64_HI12);
1513+
LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_LARCH_BRANCH21);
1514+
LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_LARCH_BRANCH16);
1515+
LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_LARCH_REL32);
1516+
default:
1517+
return "Unknown";
1518+
}
1519+
break;
14911520
default:
14921521
return "Unknown";
14931522
}

llvm/lib/Target/LoongArch/LoongArchTargetMachine.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,14 +87,20 @@ getEffectiveLoongArchCodeModel(const Triple &TT,
8787
}
8888
}
8989

90+
static std::unique_ptr<TargetLoweringObjectFile> createTLOF(const Triple &TT) {
91+
if (TT.isOSBinFormatCOFF())
92+
return std::make_unique<TargetLoweringObjectFileCOFF>();
93+
return std::make_unique<TargetLoweringObjectFileELF>();
94+
}
95+
9096
LoongArchTargetMachine::LoongArchTargetMachine(
9197
const Target &T, const Triple &TT, StringRef CPU, StringRef FS,
9298
const TargetOptions &Options, std::optional<Reloc::Model> RM,
9399
std::optional<CodeModel::Model> CM, CodeGenOptLevel OL, bool JIT)
94100
: CodeGenTargetMachineImpl(T, computeDataLayout(TT), TT, CPU, FS, Options,
95101
getEffectiveRelocModel(TT, RM),
96102
getEffectiveLoongArchCodeModel(TT, CM), OL),
97-
TLOF(std::make_unique<TargetLoweringObjectFileELF>()) {
103+
TLOF(createTLOF(getTargetTriple())) {
98104
initAsmInfo();
99105
}
100106

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

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

1416
LINK_COMPONENTS
1517
MC

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

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -490,17 +490,45 @@ bool LoongArchAsmBackend::handleAddSubRelocations(const MCAssembler &Asm,
490490
return true;
491491
}
492492

493-
std::unique_ptr<MCObjectTargetWriter>
494-
LoongArchAsmBackend::createObjectTargetWriter() const {
495-
return createLoongArchELFObjectWriter(
496-
OSABI, Is64Bit, STI.hasFeature(LoongArch::FeatureRelax));
497-
}
493+
namespace {
494+
class LoongArchELFAsmBackend : public LoongArchAsmBackend {
495+
uint8_t OSABI;
496+
497+
public:
498+
LoongArchELFAsmBackend(const MCSubtargetInfo &STI, uint8_t OSABI,
499+
bool Is64Bit, const MCTargetOptions &Options)
500+
: LoongArchAsmBackend(STI, Is64Bit, Options), OSABI(OSABI) {}
501+
502+
std::unique_ptr<MCObjectTargetWriter>
503+
createObjectTargetWriter() const override {
504+
return createLoongArchELFObjectWriter(
505+
OSABI, Is64Bit, STI.hasFeature(LoongArch::FeatureRelax));
506+
}
507+
};
508+
509+
class LoongArchCOFFAsmBackend : public LoongArchAsmBackend {
510+
public:
511+
LoongArchCOFFAsmBackend(const MCSubtargetInfo &STI, bool Is64Bit,
512+
const MCTargetOptions &Options)
513+
: LoongArchAsmBackend(STI, Is64Bit, Options) {}
514+
515+
std::unique_ptr<MCObjectTargetWriter>
516+
createObjectTargetWriter() const override {
517+
return createLoongArchWinCOFFObjectWriter(Is64Bit);
518+
}
519+
};
520+
} // end anonymous namespace
498521

499522
MCAsmBackend *llvm::createLoongArchAsmBackend(const Target &T,
500523
const MCSubtargetInfo &STI,
501524
const MCRegisterInfo &MRI,
502525
const MCTargetOptions &Options) {
503526
const Triple &TT = STI.getTargetTriple();
527+
if (TT.isUEFI()) {
528+
assert(TT.isOSBinFormatCOFF() &&
529+
"Only COFF format is supported in UEFI environment.");
530+
return new LoongArchCOFFAsmBackend(STI, TT.isArch64Bit(), Options);
531+
}
504532
uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TT.getOS());
505-
return new LoongArchAsmBackend(STI, OSABI, TT.isArch64Bit(), Options);
533+
return new LoongArchELFAsmBackend(STI, OSABI, TT.isArch64Bit(), Options);
506534
}

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

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,18 @@
2525
namespace llvm {
2626

2727
class LoongArchAsmBackend : public MCAsmBackend {
28+
DenseMap<MCSection *, const MCSymbolRefExpr *> SecToAlignSym;
29+
30+
protected:
2831
const MCSubtargetInfo &STI;
29-
uint8_t OSABI;
30-
bool Is64Bit;
3132
const MCTargetOptions &TargetOptions;
32-
DenseMap<MCSection *, const MCSymbolRefExpr *> SecToAlignSym;
33+
bool Is64Bit;
3334

3435
public:
35-
LoongArchAsmBackend(const MCSubtargetInfo &STI, uint8_t OSABI, bool Is64Bit,
36+
LoongArchAsmBackend(const MCSubtargetInfo &STI, bool Is64Bit,
3637
const MCTargetOptions &Options)
3738
: MCAsmBackend(llvm::endianness::little, ELF::R_LARCH_RELAX), STI(STI),
38-
OSABI(OSABI), Is64Bit(Is64Bit), TargetOptions(Options) {}
39+
TargetOptions(Options), Is64Bit(Is64Bit) {}
3940
~LoongArchAsmBackend() override {}
4041

4142
bool handleAddSubRelocations(const MCAssembler &Asm, const MCFragment &F,
@@ -78,8 +79,6 @@ class LoongArchAsmBackend : public MCAsmBackend {
7879
bool writeNopData(raw_ostream &OS, uint64_t Count,
7980
const MCSubtargetInfo *STI) const override;
8081

81-
std::unique_ptr<MCObjectTargetWriter>
82-
createObjectTargetWriter() const override;
8382
const MCTargetOptions &getTargetOptions() const { return TargetOptions; }
8483
DenseMap<MCSection *, const MCSymbolRefExpr *> &getSecToAlignSym() {
8584
return SecToAlignSym;

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

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@
1717

1818
using namespace llvm;
1919

20-
void LoongArchMCAsmInfo::anchor() {}
20+
void LoongArchMCAsmInfoELF::anchor() {}
2121

22-
LoongArchMCAsmInfo::LoongArchMCAsmInfo(const Triple &TT) {
22+
LoongArchMCAsmInfoELF::LoongArchMCAsmInfoELF(const Triple &TT) {
2323
CodePointerSize = CalleeSaveStackSlotSize = TT.isArch64Bit() ? 8 : 4;
2424
AlignmentIsInBytes = false;
2525
Data8bitsDirective = "\t.byte\t";
@@ -32,3 +32,19 @@ LoongArchMCAsmInfo::LoongArchMCAsmInfo(const Triple &TT) {
3232
DwarfRegNumForCFI = true;
3333
ExceptionsType = ExceptionHandling::DwarfCFI;
3434
}
35+
36+
void LoongArchMCAsmInfoGNUCOFF::anchor() {}
37+
38+
LoongArchMCAsmInfoGNUCOFF::LoongArchMCAsmInfoGNUCOFF(const Triple &TT) {
39+
CodePointerSize = CalleeSaveStackSlotSize = TT.isArch64Bit() ? 8 : 4;
40+
AlignmentIsInBytes = false;
41+
Data8bitsDirective = "\t.byte\t";
42+
Data16bitsDirective = "\t.half\t";
43+
Data32bitsDirective = "\t.word\t";
44+
Data64bitsDirective = "\t.dword\t";
45+
ZeroDirective = "\t.space\t";
46+
CommentString = "//";
47+
SupportsDebugInformation = true;
48+
ExceptionsType = ExceptionHandling::WinEH;
49+
WinEHEncodingType = WinEH::EncodingType::Itanium;
50+
}

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

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,24 @@
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

1819
namespace llvm {
1920
class Triple;
2021

21-
class LoongArchMCAsmInfo : public MCAsmInfoELF {
22+
class LoongArchMCAsmInfoELF : public MCAsmInfoELF {
2223
void anchor() override;
2324

2425
public:
25-
explicit LoongArchMCAsmInfo(const Triple &TargetTriple);
26+
explicit LoongArchMCAsmInfoELF(const Triple &TargetTriple);
27+
};
28+
29+
class LoongArchMCAsmInfoGNUCOFF : public MCAsmInfoGNUCOFF {
30+
void anchor() override;
31+
32+
public:
33+
explicit LoongArchMCAsmInfoGNUCOFF(const Triple &TargetTriple);
2634
};
2735

2836
} // end namespace llvm

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

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "LoongArchELFStreamer.h"
1515
#include "LoongArchInstPrinter.h"
1616
#include "LoongArchMCAsmInfo.h"
17+
#include "LoongArchWinCOFFStreamer.h"
1718
#include "TargetInfo/LoongArchTargetInfo.h"
1819
#include "llvm/MC/MCAsmBackend.h"
1920
#include "llvm/MC/MCAsmInfo.h"
@@ -61,7 +62,14 @@ createLoongArchMCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS) {
6162
static MCAsmInfo *createLoongArchMCAsmInfo(const MCRegisterInfo &MRI,
6263
const Triple &TT,
6364
const MCTargetOptions &Options) {
64-
MCAsmInfo *MAI = new LoongArchMCAsmInfo(TT);
65+
MCAsmInfo *MAI;
66+
67+
if (TT.isOSBinFormatCOFF()) {
68+
MAI = new LoongArchMCAsmInfoGNUCOFF(TT);
69+
} else {
70+
assert(TT.isOSBinFormatELF() && "Invalid target");
71+
MAI = new LoongArchMCAsmInfoELF(TT);
72+
}
6573

6674
// Initial state of the frame pointer is sp(r3).
6775
unsigned SP = MRI.getDwarfRegNum(LoongArch::R3, true);
@@ -81,9 +89,9 @@ static MCInstPrinter *createLoongArchMCInstPrinter(const Triple &T,
8189

8290
static MCTargetStreamer *
8391
createLoongArchObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) {
84-
return STI.getTargetTriple().isOSBinFormatELF()
85-
? new LoongArchTargetELFStreamer(S, STI)
86-
: nullptr;
92+
if (STI.getTargetTriple().isOSBinFormatCOFF())
93+
return new LoongArchTargetWinCOFFStreamer(S);
94+
return new LoongArchTargetELFStreamer(S, STI);
8795
}
8896

8997
static MCTargetStreamer *
@@ -215,6 +223,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeLoongArchTargetMC() {
215223
TargetRegistry::RegisterMCInstPrinter(*T, createLoongArchMCInstPrinter);
216224
TargetRegistry::RegisterMCInstrAnalysis(*T, createLoongArchInstrAnalysis);
217225
TargetRegistry::RegisterELFStreamer(*T, createLoongArchELFStreamer);
226+
TargetRegistry::RegisterCOFFStreamer(*T, createLoongArchWinCOFFStreamer);
218227
TargetRegistry::RegisterObjectTargetStreamer(
219228
*T, createLoongArchObjectTargetStreamer);
220229
TargetRegistry::RegisterAsmTargetStreamer(*T,

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ MCAsmBackend *createLoongArchAsmBackend(const Target &T,
3737

3838
std::unique_ptr<MCObjectTargetWriter>
3939
createLoongArchELFObjectWriter(uint8_t OSABI, bool Is64Bit, bool Relax);
40+
std::unique_ptr<MCObjectTargetWriter>
41+
createLoongArchWinCOFFObjectWriter(bool Is64Bit);
4042

4143
} // end namespace llvm
4244

0 commit comments

Comments
 (0)