1 //===-- SparcAsmBackend.cpp - Sparc Assembler Backend ---------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "MCTargetDesc/SparcFixupKinds.h" 10 #include "MCTargetDesc/SparcMCTargetDesc.h" 11 #include "llvm/MC/MCAsmBackend.h" 12 #include "llvm/MC/MCELFObjectWriter.h" 13 #include "llvm/MC/MCExpr.h" 14 #include "llvm/MC/MCFixupKindInfo.h" 15 #include "llvm/MC/MCObjectWriter.h" 16 #include "llvm/MC/MCSubtargetInfo.h" 17 #include "llvm/MC/MCValue.h" 18 #include "llvm/Support/EndianStream.h" 19 #include "llvm/Support/TargetRegistry.h" 20 21 using namespace llvm; 22 23 static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) { 24 switch (Kind) { 25 default: 26 llvm_unreachable("Unknown fixup kind!"); 27 case FK_Data_1: 28 case FK_Data_2: 29 case FK_Data_4: 30 case FK_Data_8: 31 return Value; 32 33 case Sparc::fixup_sparc_wplt30: 34 case Sparc::fixup_sparc_call30: 35 return (Value >> 2) & 0x3fffffff; 36 37 case Sparc::fixup_sparc_br22: 38 return (Value >> 2) & 0x3fffff; 39 40 case Sparc::fixup_sparc_br19: 41 return (Value >> 2) & 0x7ffff; 42 43 case Sparc::fixup_sparc_br16_2: 44 return (Value >> 2) & 0xc000; 45 46 case Sparc::fixup_sparc_br16_14: 47 return (Value >> 2) & 0x3fff; 48 49 case Sparc::fixup_sparc_pc22: 50 case Sparc::fixup_sparc_got22: 51 case Sparc::fixup_sparc_tls_gd_hi22: 52 case Sparc::fixup_sparc_tls_ldm_hi22: 53 case Sparc::fixup_sparc_tls_ie_hi22: 54 case Sparc::fixup_sparc_hi22: 55 case Sparc::fixup_sparc_lm: 56 return (Value >> 10) & 0x3fffff; 57 58 case Sparc::fixup_sparc_got13: 59 case Sparc::fixup_sparc_13: 60 return Value & 0x1fff; 61 62 case Sparc::fixup_sparc_pc10: 63 case Sparc::fixup_sparc_got10: 64 case Sparc::fixup_sparc_tls_gd_lo10: 65 case Sparc::fixup_sparc_tls_ldm_lo10: 66 case Sparc::fixup_sparc_tls_ie_lo10: 67 case Sparc::fixup_sparc_lo10: 68 return Value & 0x3ff; 69 70 case Sparc::fixup_sparc_h44: 71 return (Value >> 22) & 0x3fffff; 72 73 case Sparc::fixup_sparc_m44: 74 return (Value >> 12) & 0x3ff; 75 76 case Sparc::fixup_sparc_l44: 77 return Value & 0xfff; 78 79 case Sparc::fixup_sparc_hh: 80 return (Value >> 42) & 0x3fffff; 81 82 case Sparc::fixup_sparc_hm: 83 return (Value >> 32) & 0x3ff; 84 85 case Sparc::fixup_sparc_tls_ldo_hix22: 86 case Sparc::fixup_sparc_tls_le_hix22: 87 case Sparc::fixup_sparc_tls_ldo_lox10: 88 case Sparc::fixup_sparc_tls_le_lox10: 89 assert(Value == 0 && "Sparc TLS relocs expect zero Value"); 90 return 0; 91 92 case Sparc::fixup_sparc_tls_gd_add: 93 case Sparc::fixup_sparc_tls_gd_call: 94 case Sparc::fixup_sparc_tls_ldm_add: 95 case Sparc::fixup_sparc_tls_ldm_call: 96 case Sparc::fixup_sparc_tls_ldo_add: 97 case Sparc::fixup_sparc_tls_ie_ld: 98 case Sparc::fixup_sparc_tls_ie_ldx: 99 case Sparc::fixup_sparc_tls_ie_add: 100 return 0; 101 } 102 } 103 104 /// getFixupKindNumBytes - The number of bytes the fixup may change. 105 static unsigned getFixupKindNumBytes(unsigned Kind) { 106 switch (Kind) { 107 default: 108 return 4; 109 case FK_Data_1: 110 return 1; 111 case FK_Data_2: 112 return 2; 113 case FK_Data_8: 114 return 8; 115 } 116 } 117 118 namespace { 119 class SparcAsmBackend : public MCAsmBackend { 120 protected: 121 const Target &TheTarget; 122 bool Is64Bit; 123 124 public: 125 SparcAsmBackend(const Target &T) 126 : MCAsmBackend(StringRef(T.getName()) == "sparcel" ? support::little 127 : support::big), 128 TheTarget(T), Is64Bit(StringRef(TheTarget.getName()) == "sparcv9") {} 129 130 unsigned getNumFixupKinds() const override { 131 return Sparc::NumTargetFixupKinds; 132 } 133 134 const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override { 135 const static MCFixupKindInfo InfosBE[Sparc::NumTargetFixupKinds] = { 136 // name offset bits flags 137 { "fixup_sparc_call30", 2, 30, MCFixupKindInfo::FKF_IsPCRel }, 138 { "fixup_sparc_br22", 10, 22, MCFixupKindInfo::FKF_IsPCRel }, 139 { "fixup_sparc_br19", 13, 19, MCFixupKindInfo::FKF_IsPCRel }, 140 { "fixup_sparc_br16_2", 10, 2, MCFixupKindInfo::FKF_IsPCRel }, 141 { "fixup_sparc_br16_14", 18, 14, MCFixupKindInfo::FKF_IsPCRel }, 142 { "fixup_sparc_13", 19, 13, 0 }, 143 { "fixup_sparc_hi22", 10, 22, 0 }, 144 { "fixup_sparc_lo10", 22, 10, 0 }, 145 { "fixup_sparc_h44", 10, 22, 0 }, 146 { "fixup_sparc_m44", 22, 10, 0 }, 147 { "fixup_sparc_l44", 20, 12, 0 }, 148 { "fixup_sparc_hh", 10, 22, 0 }, 149 { "fixup_sparc_hm", 22, 10, 0 }, 150 { "fixup_sparc_lm", 10, 22, 0 }, 151 { "fixup_sparc_pc22", 10, 22, MCFixupKindInfo::FKF_IsPCRel }, 152 { "fixup_sparc_pc10", 22, 10, MCFixupKindInfo::FKF_IsPCRel }, 153 { "fixup_sparc_got22", 10, 22, 0 }, 154 { "fixup_sparc_got10", 22, 10, 0 }, 155 { "fixup_sparc_got13", 19, 13, 0 }, 156 { "fixup_sparc_wplt30", 2, 30, MCFixupKindInfo::FKF_IsPCRel }, 157 { "fixup_sparc_tls_gd_hi22", 10, 22, 0 }, 158 { "fixup_sparc_tls_gd_lo10", 22, 10, 0 }, 159 { "fixup_sparc_tls_gd_add", 0, 0, 0 }, 160 { "fixup_sparc_tls_gd_call", 0, 0, 0 }, 161 { "fixup_sparc_tls_ldm_hi22", 10, 22, 0 }, 162 { "fixup_sparc_tls_ldm_lo10", 22, 10, 0 }, 163 { "fixup_sparc_tls_ldm_add", 0, 0, 0 }, 164 { "fixup_sparc_tls_ldm_call", 0, 0, 0 }, 165 { "fixup_sparc_tls_ldo_hix22", 10, 22, 0 }, 166 { "fixup_sparc_tls_ldo_lox10", 22, 10, 0 }, 167 { "fixup_sparc_tls_ldo_add", 0, 0, 0 }, 168 { "fixup_sparc_tls_ie_hi22", 10, 22, 0 }, 169 { "fixup_sparc_tls_ie_lo10", 22, 10, 0 }, 170 { "fixup_sparc_tls_ie_ld", 0, 0, 0 }, 171 { "fixup_sparc_tls_ie_ldx", 0, 0, 0 }, 172 { "fixup_sparc_tls_ie_add", 0, 0, 0 }, 173 { "fixup_sparc_tls_le_hix22", 0, 0, 0 }, 174 { "fixup_sparc_tls_le_lox10", 0, 0, 0 } 175 }; 176 177 const static MCFixupKindInfo InfosLE[Sparc::NumTargetFixupKinds] = { 178 // name offset bits flags 179 { "fixup_sparc_call30", 0, 30, MCFixupKindInfo::FKF_IsPCRel }, 180 { "fixup_sparc_br22", 0, 22, MCFixupKindInfo::FKF_IsPCRel }, 181 { "fixup_sparc_br19", 0, 19, MCFixupKindInfo::FKF_IsPCRel }, 182 { "fixup_sparc_br16_2", 20, 2, MCFixupKindInfo::FKF_IsPCRel }, 183 { "fixup_sparc_br16_14", 0, 14, MCFixupKindInfo::FKF_IsPCRel }, 184 { "fixup_sparc_13", 0, 13, 0 }, 185 { "fixup_sparc_hi22", 0, 22, 0 }, 186 { "fixup_sparc_lo10", 0, 10, 0 }, 187 { "fixup_sparc_h44", 0, 22, 0 }, 188 { "fixup_sparc_m44", 0, 10, 0 }, 189 { "fixup_sparc_l44", 0, 12, 0 }, 190 { "fixup_sparc_hh", 0, 22, 0 }, 191 { "fixup_sparc_hm", 0, 10, 0 }, 192 { "fixup_sparc_lm", 0, 22, 0 }, 193 { "fixup_sparc_pc22", 0, 22, MCFixupKindInfo::FKF_IsPCRel }, 194 { "fixup_sparc_pc10", 0, 10, MCFixupKindInfo::FKF_IsPCRel }, 195 { "fixup_sparc_got22", 0, 22, 0 }, 196 { "fixup_sparc_got10", 0, 10, 0 }, 197 { "fixup_sparc_got13", 0, 13, 0 }, 198 { "fixup_sparc_wplt30", 0, 30, MCFixupKindInfo::FKF_IsPCRel }, 199 { "fixup_sparc_tls_gd_hi22", 0, 22, 0 }, 200 { "fixup_sparc_tls_gd_lo10", 0, 10, 0 }, 201 { "fixup_sparc_tls_gd_add", 0, 0, 0 }, 202 { "fixup_sparc_tls_gd_call", 0, 0, 0 }, 203 { "fixup_sparc_tls_ldm_hi22", 0, 22, 0 }, 204 { "fixup_sparc_tls_ldm_lo10", 0, 10, 0 }, 205 { "fixup_sparc_tls_ldm_add", 0, 0, 0 }, 206 { "fixup_sparc_tls_ldm_call", 0, 0, 0 }, 207 { "fixup_sparc_tls_ldo_hix22", 0, 22, 0 }, 208 { "fixup_sparc_tls_ldo_lox10", 0, 10, 0 }, 209 { "fixup_sparc_tls_ldo_add", 0, 0, 0 }, 210 { "fixup_sparc_tls_ie_hi22", 0, 22, 0 }, 211 { "fixup_sparc_tls_ie_lo10", 0, 10, 0 }, 212 { "fixup_sparc_tls_ie_ld", 0, 0, 0 }, 213 { "fixup_sparc_tls_ie_ldx", 0, 0, 0 }, 214 { "fixup_sparc_tls_ie_add", 0, 0, 0 }, 215 { "fixup_sparc_tls_le_hix22", 0, 0, 0 }, 216 { "fixup_sparc_tls_le_lox10", 0, 0, 0 } 217 }; 218 219 if (Kind < FirstTargetFixupKind) 220 return MCAsmBackend::getFixupKindInfo(Kind); 221 222 assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() && 223 "Invalid kind!"); 224 if (Endian == support::little) 225 return InfosLE[Kind - FirstTargetFixupKind]; 226 227 return InfosBE[Kind - FirstTargetFixupKind]; 228 } 229 230 bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup, 231 const MCValue &Target) override { 232 switch ((Sparc::Fixups)Fixup.getKind()) { 233 default: 234 return false; 235 case Sparc::fixup_sparc_wplt30: 236 if (Target.getSymA()->getSymbol().isTemporary()) 237 return false; 238 LLVM_FALLTHROUGH; 239 case Sparc::fixup_sparc_tls_gd_hi22: 240 case Sparc::fixup_sparc_tls_gd_lo10: 241 case Sparc::fixup_sparc_tls_gd_add: 242 case Sparc::fixup_sparc_tls_gd_call: 243 case Sparc::fixup_sparc_tls_ldm_hi22: 244 case Sparc::fixup_sparc_tls_ldm_lo10: 245 case Sparc::fixup_sparc_tls_ldm_add: 246 case Sparc::fixup_sparc_tls_ldm_call: 247 case Sparc::fixup_sparc_tls_ldo_hix22: 248 case Sparc::fixup_sparc_tls_ldo_lox10: 249 case Sparc::fixup_sparc_tls_ldo_add: 250 case Sparc::fixup_sparc_tls_ie_hi22: 251 case Sparc::fixup_sparc_tls_ie_lo10: 252 case Sparc::fixup_sparc_tls_ie_ld: 253 case Sparc::fixup_sparc_tls_ie_ldx: 254 case Sparc::fixup_sparc_tls_ie_add: 255 case Sparc::fixup_sparc_tls_le_hix22: 256 case Sparc::fixup_sparc_tls_le_lox10: 257 return true; 258 } 259 } 260 261 /// fixupNeedsRelaxation - Target specific predicate for whether a given 262 /// fixup requires the associated instruction to be relaxed. 263 bool fixupNeedsRelaxation(const MCFixup &Fixup, 264 uint64_t Value, 265 const MCRelaxableFragment *DF, 266 const MCAsmLayout &Layout) const override { 267 // FIXME. 268 llvm_unreachable("fixupNeedsRelaxation() unimplemented"); 269 return false; 270 } 271 void relaxInstruction(MCInst &Inst, 272 const MCSubtargetInfo &STI) const override { 273 // FIXME. 274 llvm_unreachable("relaxInstruction() unimplemented"); 275 } 276 277 bool writeNopData(raw_ostream &OS, uint64_t Count) const override { 278 // Cannot emit NOP with size not multiple of 32 bits. 279 if (Count % 4 != 0) 280 return false; 281 282 uint64_t NumNops = Count / 4; 283 for (uint64_t i = 0; i != NumNops; ++i) 284 support::endian::write<uint32_t>(OS, 0x01000000, Endian); 285 286 return true; 287 } 288 }; 289 290 class ELFSparcAsmBackend : public SparcAsmBackend { 291 Triple::OSType OSType; 292 public: 293 ELFSparcAsmBackend(const Target &T, Triple::OSType OSType) : 294 SparcAsmBackend(T), OSType(OSType) { } 295 296 void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, 297 const MCValue &Target, MutableArrayRef<char> Data, 298 uint64_t Value, bool IsResolved, 299 const MCSubtargetInfo *STI) const override { 300 301 Value = adjustFixupValue(Fixup.getKind(), Value); 302 if (!Value) return; // Doesn't change encoding. 303 304 unsigned NumBytes = getFixupKindNumBytes(Fixup.getKind()); 305 unsigned Offset = Fixup.getOffset(); 306 // For each byte of the fragment that the fixup touches, mask in the bits 307 // from the fixup value. The Value has been "split up" into the 308 // appropriate bitfields above. 309 for (unsigned i = 0; i != NumBytes; ++i) { 310 unsigned Idx = Endian == support::little ? i : (NumBytes - 1) - i; 311 Data[Offset + Idx] |= uint8_t((Value >> (i * 8)) & 0xff); 312 } 313 } 314 315 std::unique_ptr<MCObjectTargetWriter> 316 createObjectTargetWriter() const override { 317 uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(OSType); 318 return createSparcELFObjectWriter(Is64Bit, OSABI); 319 } 320 }; 321 322 } // end anonymous namespace 323 324 MCAsmBackend *llvm::createSparcAsmBackend(const Target &T, 325 const MCSubtargetInfo &STI, 326 const MCRegisterInfo &MRI, 327 const MCTargetOptions &Options) { 328 return new ELFSparcAsmBackend(T, STI.getTargetTriple().getOS()); 329 } 330