llvm-project/llvm/lib/Target/Foot/MCTargetDesc/FootMCAsmBackend.cpp
2025-10-25 22:30:05 -04:00

93 lines
2.6 KiB
C++

#include "MCTargetDesc/FootMCTargetDesc.h"
#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCELFObjectWriter.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCValue.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Support/Debug.h"
#include "llvm/TargetParser/Triple.h"
#include "llvm/BinaryFormat/ELF.h"
using namespace llvm;
namespace {
class FootELFObjectWriter : public MCELFObjectTargetWriter {
public:
FootELFObjectWriter()
: MCELFObjectTargetWriter(false, ELF::ELFOSABI_NONE, ELF::EM_FOOT, true) {}
bool needsRelocateWithSymbol(const MCValue &Val, unsigned RelTy) const override {
switch (RelTy) {
case ELF::R_FOOT_CNST16:
return true;
default:
return false;
}
}
unsigned getRelocType(const MCFixup &Fixup, const MCValue &Target, bool IsPcRel) const override {
switch (Fixup.getKind()) {
case FK_Data_2:
return ELF::R_FOOT_CNST16;
default:
return ELF::R_FOOT_NONE;
}
}
};
class FootAsmBackend : public MCAsmBackend {
Triple TheTriple;
public:
FootAsmBackend(const Triple &TT)
: MCAsmBackend(endianness::little), TheTriple(TT) {}
std::unique_ptr<MCObjectTargetWriter>
createObjectTargetWriter() const override {
return std::make_unique<FootELFObjectWriter>();
}
void applyFixup(const MCFragment &Frag, const MCFixup &Fixup,
const MCValue &Target, uint8_t* Data, uint64_t Value,
bool IsResolved) override {
unsigned Offset = Fixup.getOffset();
unsigned Kind = Fixup.getKind();
if (Value == 0) { return; }
maybeAddReloc(Frag, Fixup, Target, Value, IsResolved);
MCFixupKindInfo Info = getFixupKindInfo(Kind);
unsigned NumBits = Info.TargetSize;
uint64_t Mask = (1u << NumBits) - 1; // no need to handle 64-bit case, Foot is a 32-bit architecture
assert(Value % 4 == 0 && "invalid fixup value");
Value /= 4; // foot is 32-bit addressable
Value &= Mask;
support::endian::write16le(&Data[Offset], Value);
}
bool writeNopData(raw_ostream &OS, uint64_t Count,
const MCSubtargetInfo *STI) const override {
for (uint64_t I = 0; I != Count; ++I) {
OS.write("\x00\x00\x00\x00", 4);
}
return true;
}
};
} // namespace
MCAsmBackend *llvm::createFootAsmBackend(const Target &T,
const MCSubtargetInfo &STI,
const MCRegisterInfo &,
const MCTargetOptions &) {
const Triple &TheTriple = STI.getTargetTriple();
return new FootAsmBackend(TheTriple);
}