1 #include "MCTargetDesc/MipsMCTargetDesc.h" 2 #include "llvm/ADT/Twine.h" 3 #include "llvm/MC/MCAssembler.h" 4 #include "llvm/MC/MCDirectives.h" 5 #include "llvm/MC/MCELFObjectWriter.h" 6 #include "llvm/MC/MCExpr.h" 7 #include "llvm/MC/MCMachObjectWriter.h" 8 #include "llvm/MC/MCObjectWriter.h" 9 #include "llvm/MC/MCSectionELF.h" 10 #include "llvm/MC/MCSectionMachO.h" 11 #include "llvm/MC/MCAsmBackend.h" 12 #include "llvm/MC/MCSubtargetInfo.h" 13 #include "llvm/Object/MachOFormat.h" 14 #include "llvm/Support/ELF.h" 15 #include "llvm/Support/ErrorHandling.h" 16 #include "llvm/Support/raw_ostream.h" 17 using namespace llvm; 18 19 namespace { 20 class MipsELFObjectWriter : public MCELFObjectTargetWriter { 21 public: 22 MipsELFObjectWriter(bool is64Bit, Triple::OSType OSType, uint16_t EMachine, 23 bool HasRelocationAddend) 24 : MCELFObjectTargetWriter(is64Bit, OSType, EMachine, 25 HasRelocationAddend) {} 26 }; 27 28 class MipsAsmBackend : public MCAsmBackend { 29 public: 30 MipsAsmBackend(const Target &T) 31 : MCAsmBackend() {} 32 33 unsigned getNumFixupKinds() const { 34 return 1; //tbd 35 } 36 37 /// ApplyFixup - Apply the \arg Value for given \arg Fixup into the provided 38 /// data fragment, at the offset specified by the fixup and following the 39 /// fixup kind as appropriate. 40 void ApplyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize, 41 uint64_t Value) const { 42 } 43 44 /// @name Target Relaxation Interfaces 45 /// @{ 46 47 /// MayNeedRelaxation - Check whether the given instruction may need 48 /// relaxation. 49 /// 50 /// \param Inst - The instruction to test. 51 bool MayNeedRelaxation(const MCInst &Inst) const { 52 return false; 53 } 54 55 /// RelaxInstruction - Relax the instruction in the given fragment to the next 56 /// wider instruction. 57 /// 58 /// \param Inst - The instruction to relax, which may be the same as the 59 /// output. 60 /// \parm Res [output] - On return, the relaxed instruction. 61 void RelaxInstruction(const MCInst &Inst, MCInst &Res) const { 62 } 63 64 /// @} 65 66 /// WriteNopData - Write an (optimal) nop sequence of Count bytes to the given 67 /// output. If the target cannot generate such a sequence, it should return an 68 /// error. 69 /// 70 /// \return - True on success. 71 bool WriteNopData(uint64_t Count, MCObjectWriter *OW) const { 72 return false; 73 } 74 }; 75 76 class MipsEB_AsmBackend : public MipsAsmBackend { 77 public: 78 Triple::OSType OSType; 79 80 MipsEB_AsmBackend(const Target &T, Triple::OSType _OSType) 81 : MipsAsmBackend(T), OSType(_OSType) {} 82 83 MCObjectWriter *createObjectWriter(raw_ostream &OS) const { 84 return createELFObjectWriter(createELFObjectTargetWriter(), 85 OS, /*IsLittleEndian*/ false); 86 } 87 88 MCELFObjectTargetWriter *createELFObjectTargetWriter() const { 89 return new MipsELFObjectWriter(false, OSType, ELF::EM_MIPS, false); 90 } 91 }; 92 93 class MipsEL_AsmBackend : public MipsAsmBackend { 94 public: 95 Triple::OSType OSType; 96 97 MipsEL_AsmBackend(const Target &T, Triple::OSType _OSType) 98 : MipsAsmBackend(T), OSType(_OSType) {} 99 100 MCObjectWriter *createObjectWriter(raw_ostream &OS) const { 101 return createELFObjectWriter(createELFObjectTargetWriter(), 102 OS, /*IsLittleEndian*/ true); 103 } 104 105 MCELFObjectTargetWriter *createELFObjectTargetWriter() const { 106 return new MipsELFObjectWriter(false, OSType, ELF::EM_MIPS, false); 107 } 108 }; 109 } 110 111 MCAsmBackend *llvm::createMipsAsmBackend(const Target &T, StringRef TT) { 112 Triple TheTriple(TT); 113 114 // just return little endian for now 115 // 116 return new MipsEL_AsmBackend(T, Triple(TT).getOS()); 117 } 118