1 //===-- SparcAsmBackend.cpp - Sparc Assembler Backend ---------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "llvm/MC/MCAsmBackend.h" 11 #include "MCTargetDesc/SparcFixupKinds.h" 12 #include "MCTargetDesc/SparcMCTargetDesc.h" 13 #include "llvm/MC/MCELFObjectWriter.h" 14 #include "llvm/MC/MCFixupKindInfo.h" 15 #include "llvm/MC/MCObjectWriter.h" 16 #include "llvm/Support/TargetRegistry.h" 17 18 using namespace llvm; 19 20 static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) { 21 switch (Kind) { 22 default: 23 llvm_unreachable("Unknown fixup kind!"); 24 case FK_Data_1: 25 case FK_Data_2: 26 case FK_Data_4: 27 case FK_Data_8: 28 return Value; 29 case Sparc::fixup_sparc_call30: 30 return (Value >> 2) & 0x3fffffff; 31 case Sparc::fixup_sparc_br22: 32 return (Value >> 2) & 0x3fffff; 33 case Sparc::fixup_sparc_br19: 34 return (Value >> 2) & 0x7ffff; 35 case Sparc::fixup_sparc_hi22: 36 return (Value >> 10) & 0x3fffff; 37 case Sparc::fixup_sparc_lo10: 38 return Value & 0x3ff; 39 case Sparc::fixup_sparc_h44: 40 return (Value >> 22) & 0x3fffff; 41 case Sparc::fixup_sparc_m44: 42 return (Value >> 12) & 0x3ff; 43 case Sparc::fixup_sparc_l44: 44 return Value & 0xfff; 45 case Sparc::fixup_sparc_hh: 46 return (Value >> 42) & 0x3fffff; 47 case Sparc::fixup_sparc_hm: 48 return (Value >> 32) & 0x3ff; 49 } 50 } 51 52 namespace { 53 class SparcAsmBackend : public MCAsmBackend { 54 const Target &TheTarget; 55 public: 56 SparcAsmBackend(const Target &T) : MCAsmBackend(), TheTarget(T) {} 57 58 unsigned getNumFixupKinds() const { 59 return Sparc::NumTargetFixupKinds; 60 } 61 62 const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const { 63 const static MCFixupKindInfo Infos[Sparc::NumTargetFixupKinds] = { 64 // name offset bits flags 65 { "fixup_sparc_call30", 2, 30, MCFixupKindInfo::FKF_IsPCRel }, 66 { "fixup_sparc_br22", 10, 22, MCFixupKindInfo::FKF_IsPCRel }, 67 { "fixup_sparc_br19", 13, 19, MCFixupKindInfo::FKF_IsPCRel }, 68 { "fixup_sparc_hi22", 10, 22, 0 }, 69 { "fixup_sparc_lo10", 22, 10, 0 }, 70 { "fixup_sparc_h44", 10, 22, 0 }, 71 { "fixup_sparc_m44", 22, 10, 0 }, 72 { "fixup_sparc_l44", 20, 12, 0 }, 73 { "fixup_sparc_hh", 10, 22, 0 }, 74 { "fixup_sparc_hm", 22, 10, 0 }, 75 }; 76 77 if (Kind < FirstTargetFixupKind) 78 return MCAsmBackend::getFixupKindInfo(Kind); 79 80 assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() && 81 "Invalid kind!"); 82 return Infos[Kind - FirstTargetFixupKind]; 83 } 84 85 bool mayNeedRelaxation(const MCInst &Inst) const { 86 // FIXME. 87 return false; 88 } 89 90 /// fixupNeedsRelaxation - Target specific predicate for whether a given 91 /// fixup requires the associated instruction to be relaxed. 92 bool fixupNeedsRelaxation(const MCFixup &Fixup, 93 uint64_t Value, 94 const MCRelaxableFragment *DF, 95 const MCAsmLayout &Layout) const { 96 // FIXME. 97 assert(0 && "fixupNeedsRelaxation() unimplemented"); 98 return false; 99 } 100 void relaxInstruction(const MCInst &Inst, MCInst &Res) const { 101 // FIXME. 102 assert(0 && "relaxInstruction() unimplemented"); 103 } 104 105 bool writeNopData(uint64_t Count, MCObjectWriter *OW) const { 106 // FIXME: Zero fill for now. 107 for (uint64_t i = 0; i != Count; ++i) 108 OW->Write8(0); 109 return true; 110 } 111 112 bool is64Bit() const { 113 StringRef name = TheTarget.getName(); 114 return name == "sparcv9"; 115 } 116 }; 117 118 class ELFSparcAsmBackend : public SparcAsmBackend { 119 Triple::OSType OSType; 120 public: 121 ELFSparcAsmBackend(const Target &T, Triple::OSType OSType) : 122 SparcAsmBackend(T), OSType(OSType) { } 123 124 void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize, 125 uint64_t Value) const { 126 127 Value = adjustFixupValue(Fixup.getKind(), Value); 128 if (!Value) return; // Doesn't change encoding. 129 130 unsigned Offset = Fixup.getOffset(); 131 132 // For each byte of the fragment that the fixup touches, mask in the bits 133 // from the fixup value. The Value has been "split up" into the 134 // appropriate bitfields above. 135 for (unsigned i = 0; i != 4; ++i) 136 Data[Offset + i] |= uint8_t((Value >> ((4 - i - 1)*8)) & 0xff); 137 138 } 139 140 MCObjectWriter *createObjectWriter(raw_ostream &OS) const { 141 uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(OSType); 142 return createSparcELFObjectWriter(OS, is64Bit(), OSABI); 143 } 144 145 virtual bool doesSectionRequireSymbols(const MCSection &Section) const { 146 return false; 147 } 148 }; 149 150 } // end anonymous namespace 151 152 153 MCAsmBackend *llvm::createSparcAsmBackend(const Target &T, 154 const MCRegisterInfo &MRI, 155 StringRef TT, 156 StringRef CPU) { 157 return new ELFSparcAsmBackend(T, Triple(TT).getOS()); 158 } 159