#include "MCTargetDesc/MipsMCTargetDesc.h" #include "llvm/ADT/Twine.h" #include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCDirectives.h" #include "llvm/MC/MCELFObjectWriter.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCMachObjectWriter.h" #include "llvm/MC/MCObjectWriter.h" #include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCSectionMachO.h" #include "llvm/MC/MCAsmBackend.h" #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/Object/MachOFormat.h" #include "llvm/Support/ELF.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; namespace { class MipsELFObjectWriter : public MCELFObjectTargetWriter { public: MipsELFObjectWriter(bool is64Bit, Triple::OSType OSType, uint16_t EMachine, bool HasRelocationAddend) : MCELFObjectTargetWriter(is64Bit, OSType, EMachine, HasRelocationAddend) {} }; class MipsAsmBackend : public MCAsmBackend { public: MipsAsmBackend(const Target &T) : MCAsmBackend() {} unsigned getNumFixupKinds() const { return 1; //tbd } /// ApplyFixup - Apply the \arg Value for given \arg Fixup into the provided /// data fragment, at the offset specified by the fixup and following the /// fixup kind as appropriate. void ApplyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize, uint64_t Value) const { } /// @name Target Relaxation Interfaces /// @{ /// MayNeedRelaxation - Check whether the given instruction may need /// relaxation. /// /// \param Inst - The instruction to test. bool MayNeedRelaxation(const MCInst &Inst) const { return false; } /// RelaxInstruction - Relax the instruction in the given fragment to the next /// wider instruction. /// /// \param Inst - The instruction to relax, which may be the same as the /// output. /// \parm Res [output] - On return, the relaxed instruction. void RelaxInstruction(const MCInst &Inst, MCInst &Res) const { } /// @} /// WriteNopData - Write an (optimal) nop sequence of Count bytes to the given /// output. If the target cannot generate such a sequence, it should return an /// error. /// /// \return - True on success. bool WriteNopData(uint64_t Count, MCObjectWriter *OW) const { return false; } }; class MipsEB_AsmBackend : public MipsAsmBackend { public: Triple::OSType OSType; MipsEB_AsmBackend(const Target &T, Triple::OSType _OSType) : MipsAsmBackend(T), OSType(_OSType) {} MCObjectWriter *createObjectWriter(raw_ostream &OS) const { return createELFObjectWriter(createELFObjectTargetWriter(), OS, /*IsLittleEndian*/ false); } MCELFObjectTargetWriter *createELFObjectTargetWriter() const { return new MipsELFObjectWriter(false, OSType, ELF::EM_MIPS, false); } }; class MipsEL_AsmBackend : public MipsAsmBackend { public: Triple::OSType OSType; MipsEL_AsmBackend(const Target &T, Triple::OSType _OSType) : MipsAsmBackend(T), OSType(_OSType) {} MCObjectWriter *createObjectWriter(raw_ostream &OS) const { return createELFObjectWriter(createELFObjectTargetWriter(), OS, /*IsLittleEndian*/ true); } MCELFObjectTargetWriter *createELFObjectTargetWriter() const { return new MipsELFObjectWriter(false, OSType, ELF::EM_MIPS, false); } }; } MCAsmBackend *llvm::createMipsAsmBackend(const Target &T, StringRef TT) { Triple TheTriple(TT); // just return little endian for now // return new MipsEL_AsmBackend(T, Triple(TT).getOS()); }