Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion llvm/include/llvm/BinaryFormat/COFF.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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 {
Expand Down
2 changes: 2 additions & 0 deletions llvm/include/llvm/Object/WindowsMachineFlag.h
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
5 changes: 3 additions & 2 deletions llvm/lib/BinaryFormat/Magic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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, ARM64 Windows, or loongarch64.
if (Magic[1] == char(0x86) || Magic[1] == char(0xaa) ||
Magic[1] == char(0x62))
return file_magic::coff_object;
break;

Expand Down
11 changes: 10 additions & 1 deletion llvm/lib/Object/COFFObjectFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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:
Expand Down
8 changes: 7 additions & 1 deletion llvm/lib/Target/LoongArch/LoongArchTargetMachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,14 +82,20 @@ 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,
std::optional<CodeModel::Model> CM, CodeGenOptLevel OL, bool JIT)
: CodeGenTargetMachineImpl(T, TT.computeDataLayout(), TT, CPU, FS, Options,
getEffectiveRelocModel(TT, RM),
getEffectiveLoongArchCodeModel(TT, CM), OL),
TLOF(std::make_unique<TargetLoweringObjectFileELF>()) {
TLOF(createTLOF(getTargetTriple())) {
initAsmInfo();
}

Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/LoongArch/MCTargetDesc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ add_llvm_component_library(LLVMLoongArchDesc
LoongArchMCTargetDesc.cpp
LoongArchMatInt.cpp
LoongArchTargetStreamer.cpp
LoongArchWinCOFFObjectWriter.cpp
LoongArchWinCOFFStreamer.cpp

LINK_COMPONENTS
MC
Expand Down
46 changes: 38 additions & 8 deletions llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -484,16 +484,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);
}
13 changes: 6 additions & 7 deletions llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 &,
Expand All @@ -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;
Expand Down
27 changes: 23 additions & 4 deletions llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCAsmInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -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";
Expand All @@ -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)
Expand All @@ -221,3 +222,21 @@ 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;

ExceptionsType = ExceptionHandling::WinEH;
WinEHEncodingType = WinEH::EncodingType::Itanium;
}
12 changes: 10 additions & 2 deletions llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCAsmInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand All @@ -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
Expand Down
18 changes: 14 additions & 4 deletions llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCTargetDesc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -62,7 +63,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);
Expand All @@ -82,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 *
Expand Down Expand Up @@ -296,6 +305,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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
Original file line number Diff line number Diff line change
@@ -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);
}
Loading