93 lines
2.6 KiB
C++
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);
|
|
}
|