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