llvm-project/llvm/lib/Target/Foot/MCTargetDesc/FootMCAsmBackend.cpp

101 lines
2.6 KiB
C++

#include "MCTargetDesc/FootMCTargetDesc.h"
#include "llvm/BinaryFormat/ELF.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"
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;
case FK_Data_4:
return ELF::R_FOOT_32;
case FK_Data_8:
return ELF::R_FOOT_64;
default:
llvm_unreachable("unsupported relocation");
}
}
};
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 {
switch (Fixup.getKind()) {
case FK_Data_1:
Data[0] = Value;
break;
case FK_Data_2:
support::endian::write16le(Data, Value);
break;
case FK_Data_4:
support::endian::write32le(Data, Value);
break;
case FK_Data_8:
support::endian::write64le(Data, Value);
break;
}
if (!IsResolved) {
maybeAddReloc(Frag, Fixup, Target, Value, IsResolved);
}
}
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);
}