1 //===-- MipsAsmBackend.cpp - Mips Asm 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 // This file implements the MipsAsmBackend class. 10 // 11 //===----------------------------------------------------------------------===// 12 // 13 14 #include "MCTargetDesc/MipsAsmBackend.h" 15 #include "MCTargetDesc/MipsABIInfo.h" 16 #include "MCTargetDesc/MipsFixupKinds.h" 17 #include "MCTargetDesc/MipsMCExpr.h" 18 #include "MCTargetDesc/MipsMCTargetDesc.h" 19 #include "llvm/ADT/STLExtras.h" 20 #include "llvm/MC/MCAsmBackend.h" 21 #include "llvm/MC/MCAssembler.h" 22 #include "llvm/MC/MCContext.h" 23 #include "llvm/MC/MCDirectives.h" 24 #include "llvm/MC/MCELFObjectWriter.h" 25 #include "llvm/MC/MCFixupKindInfo.h" 26 #include "llvm/MC/MCObjectWriter.h" 27 #include "llvm/MC/MCSubtargetInfo.h" 28 #include "llvm/MC/MCTargetOptions.h" 29 #include "llvm/MC/MCValue.h" 30 #include "llvm/Support/ErrorHandling.h" 31 #include "llvm/Support/Format.h" 32 #include "llvm/Support/MathExtras.h" 33 #include "llvm/Support/raw_ostream.h" 34 35 using namespace llvm; 36 37 // Prepare value for the target space for it 38 static unsigned adjustFixupValue(const MCFixup &Fixup, uint64_t Value, 39 MCContext &Ctx) { 40 41 unsigned Kind = Fixup.getKind(); 42 43 // Add/subtract and shift 44 switch (Kind) { 45 default: 46 return 0; 47 case FK_Data_2: 48 case Mips::fixup_Mips_LO16: 49 case Mips::fixup_Mips_GPREL16: 50 case Mips::fixup_Mips_GPOFF_HI: 51 case Mips::fixup_Mips_GPOFF_LO: 52 case Mips::fixup_Mips_GOT_PAGE: 53 case Mips::fixup_Mips_GOT_OFST: 54 case Mips::fixup_Mips_GOT_DISP: 55 case Mips::fixup_Mips_GOT_LO16: 56 case Mips::fixup_Mips_CALL_LO16: 57 case Mips::fixup_MICROMIPS_GPOFF_HI: 58 case Mips::fixup_MICROMIPS_GPOFF_LO: 59 case Mips::fixup_MICROMIPS_LO16: 60 case Mips::fixup_MICROMIPS_GOT_PAGE: 61 case Mips::fixup_MICROMIPS_GOT_OFST: 62 case Mips::fixup_MICROMIPS_GOT_DISP: 63 case Mips::fixup_MIPS_PCLO16: 64 Value &= 0xffff; 65 break; 66 case FK_DTPRel_4: 67 case FK_DTPRel_8: 68 case FK_TPRel_4: 69 case FK_TPRel_8: 70 case FK_GPRel_4: 71 case FK_Data_4: 72 case FK_Data_8: 73 case Mips::fixup_Mips_SUB: 74 case Mips::fixup_MICROMIPS_SUB: 75 break; 76 case Mips::fixup_Mips_PC16: 77 // The displacement is then divided by 4 to give us an 18 bit 78 // address range. Forcing a signed division because Value can be negative. 79 Value = (int64_t)Value / 4; 80 // We now check if Value can be encoded as a 16-bit signed immediate. 81 if (!isInt<16>(Value)) { 82 Ctx.reportError(Fixup.getLoc(), "out of range PC16 fixup"); 83 return 0; 84 } 85 break; 86 case Mips::fixup_MIPS_PC19_S2: 87 case Mips::fixup_MICROMIPS_PC19_S2: 88 // Forcing a signed division because Value can be negative. 89 Value = (int64_t)Value / 4; 90 // We now check if Value can be encoded as a 19-bit signed immediate. 91 if (!isInt<19>(Value)) { 92 Ctx.reportError(Fixup.getLoc(), "out of range PC19 fixup"); 93 return 0; 94 } 95 break; 96 case Mips::fixup_Mips_26: 97 // So far we are only using this type for jumps. 98 // The displacement is then divided by 4 to give us an 28 bit 99 // address range. 100 Value >>= 2; 101 break; 102 case Mips::fixup_Mips_HI16: 103 case Mips::fixup_Mips_GOT: 104 case Mips::fixup_MICROMIPS_GOT16: 105 case Mips::fixup_Mips_GOT_HI16: 106 case Mips::fixup_Mips_CALL_HI16: 107 case Mips::fixup_MICROMIPS_HI16: 108 case Mips::fixup_MIPS_PCHI16: 109 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1. 110 Value = ((Value + 0x8000) >> 16) & 0xffff; 111 break; 112 case Mips::fixup_Mips_HIGHER: 113 case Mips::fixup_MICROMIPS_HIGHER: 114 // Get the 3rd 16-bits. 115 Value = ((Value + 0x80008000LL) >> 32) & 0xffff; 116 break; 117 case Mips::fixup_Mips_HIGHEST: 118 case Mips::fixup_MICROMIPS_HIGHEST: 119 // Get the 4th 16-bits. 120 Value = ((Value + 0x800080008000LL) >> 48) & 0xffff; 121 break; 122 case Mips::fixup_MICROMIPS_26_S1: 123 Value >>= 1; 124 break; 125 case Mips::fixup_MICROMIPS_PC7_S1: 126 Value -= 4; 127 // Forcing a signed division because Value can be negative. 128 Value = (int64_t) Value / 2; 129 // We now check if Value can be encoded as a 7-bit signed immediate. 130 if (!isInt<7>(Value)) { 131 Ctx.reportError(Fixup.getLoc(), "out of range PC7 fixup"); 132 return 0; 133 } 134 break; 135 case Mips::fixup_MICROMIPS_PC10_S1: 136 Value -= 2; 137 // Forcing a signed division because Value can be negative. 138 Value = (int64_t) Value / 2; 139 // We now check if Value can be encoded as a 10-bit signed immediate. 140 if (!isInt<10>(Value)) { 141 Ctx.reportError(Fixup.getLoc(), "out of range PC10 fixup"); 142 return 0; 143 } 144 break; 145 case Mips::fixup_MICROMIPS_PC16_S1: 146 Value -= 4; 147 // Forcing a signed division because Value can be negative. 148 Value = (int64_t)Value / 2; 149 // We now check if Value can be encoded as a 16-bit signed immediate. 150 if (!isInt<16>(Value)) { 151 Ctx.reportError(Fixup.getLoc(), "out of range PC16 fixup"); 152 return 0; 153 } 154 break; 155 case Mips::fixup_MIPS_PC18_S3: 156 // Forcing a signed division because Value can be negative. 157 Value = (int64_t)Value / 8; 158 // We now check if Value can be encoded as a 18-bit signed immediate. 159 if (!isInt<18>(Value)) { 160 Ctx.reportError(Fixup.getLoc(), "out of range PC18 fixup"); 161 return 0; 162 } 163 break; 164 case Mips::fixup_MICROMIPS_PC18_S3: 165 // Check alignment. 166 if ((Value & 7)) { 167 Ctx.reportError(Fixup.getLoc(), "out of range PC18 fixup"); 168 } 169 // Forcing a signed division because Value can be negative. 170 Value = (int64_t)Value / 8; 171 // We now check if Value can be encoded as a 18-bit signed immediate. 172 if (!isInt<18>(Value)) { 173 Ctx.reportError(Fixup.getLoc(), "out of range PC18 fixup"); 174 return 0; 175 } 176 break; 177 case Mips::fixup_MIPS_PC21_S2: 178 // Forcing a signed division because Value can be negative. 179 Value = (int64_t) Value / 4; 180 // We now check if Value can be encoded as a 21-bit signed immediate. 181 if (!isInt<21>(Value)) { 182 Ctx.reportError(Fixup.getLoc(), "out of range PC21 fixup"); 183 return 0; 184 } 185 break; 186 case Mips::fixup_MIPS_PC26_S2: 187 // Forcing a signed division because Value can be negative. 188 Value = (int64_t) Value / 4; 189 // We now check if Value can be encoded as a 26-bit signed immediate. 190 if (!isInt<26>(Value)) { 191 Ctx.reportError(Fixup.getLoc(), "out of range PC26 fixup"); 192 return 0; 193 } 194 break; 195 case Mips::fixup_MICROMIPS_PC26_S1: 196 // Forcing a signed division because Value can be negative. 197 Value = (int64_t)Value / 2; 198 // We now check if Value can be encoded as a 26-bit signed immediate. 199 if (!isInt<26>(Value)) { 200 Ctx.reportError(Fixup.getLoc(), "out of range PC26 fixup"); 201 return 0; 202 } 203 break; 204 case Mips::fixup_MICROMIPS_PC21_S1: 205 // Forcing a signed division because Value can be negative. 206 Value = (int64_t)Value / 2; 207 // We now check if Value can be encoded as a 21-bit signed immediate. 208 if (!isInt<21>(Value)) { 209 Ctx.reportError(Fixup.getLoc(), "out of range PC21 fixup"); 210 return 0; 211 } 212 break; 213 } 214 215 return Value; 216 } 217 218 std::unique_ptr<MCObjectTargetWriter> 219 MipsAsmBackend::createObjectTargetWriter() const { 220 return createMipsELFObjectWriter(TheTriple, IsN32); 221 } 222 223 // Little-endian fixup data byte ordering: 224 // mips32r2: a | b | x | x 225 // microMIPS: x | x | a | b 226 227 static bool needsMMLEByteOrder(unsigned Kind) { 228 return Kind != Mips::fixup_MICROMIPS_PC10_S1 && 229 Kind >= Mips::fixup_MICROMIPS_26_S1 && 230 Kind < Mips::LastTargetFixupKind; 231 } 232 233 // Calculate index for microMIPS specific little endian byte order 234 static unsigned calculateMMLEIndex(unsigned i) { 235 assert(i <= 3 && "Index out of range!"); 236 237 return (1 - i / 2) * 2 + i % 2; 238 } 239 240 /// ApplyFixup - Apply the \p Value for given \p Fixup into the provided 241 /// data fragment, at the offset specified by the fixup and following the 242 /// fixup kind as appropriate. 243 void MipsAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, 244 const MCValue &Target, 245 MutableArrayRef<char> Data, uint64_t Value, 246 bool IsResolved, 247 const MCSubtargetInfo *STI) const { 248 MCFixupKind Kind = Fixup.getKind(); 249 MCContext &Ctx = Asm.getContext(); 250 Value = adjustFixupValue(Fixup, Value, Ctx); 251 252 if (!Value) 253 return; // Doesn't change encoding. 254 255 // Where do we start in the object 256 unsigned Offset = Fixup.getOffset(); 257 // Number of bytes we need to fixup 258 unsigned NumBytes = (getFixupKindInfo(Kind).TargetSize + 7) / 8; 259 // Used to point to big endian bytes 260 unsigned FullSize; 261 262 switch ((unsigned)Kind) { 263 case FK_Data_2: 264 case Mips::fixup_Mips_16: 265 case Mips::fixup_MICROMIPS_PC10_S1: 266 FullSize = 2; 267 break; 268 case FK_Data_8: 269 case Mips::fixup_Mips_64: 270 FullSize = 8; 271 break; 272 case FK_Data_4: 273 default: 274 FullSize = 4; 275 break; 276 } 277 278 // Grab current value, if any, from bits. 279 uint64_t CurVal = 0; 280 281 bool microMipsLEByteOrder = needsMMLEByteOrder((unsigned) Kind); 282 283 for (unsigned i = 0; i != NumBytes; ++i) { 284 unsigned Idx = Endian == support::little 285 ? (microMipsLEByteOrder ? calculateMMLEIndex(i) : i) 286 : (FullSize - 1 - i); 287 CurVal |= (uint64_t)((uint8_t)Data[Offset + Idx]) << (i*8); 288 } 289 290 uint64_t Mask = ((uint64_t)(-1) >> 291 (64 - getFixupKindInfo(Kind).TargetSize)); 292 CurVal |= Value & Mask; 293 294 // Write out the fixed up bytes back to the code/data bits. 295 for (unsigned i = 0; i != NumBytes; ++i) { 296 unsigned Idx = Endian == support::little 297 ? (microMipsLEByteOrder ? calculateMMLEIndex(i) : i) 298 : (FullSize - 1 - i); 299 Data[Offset + Idx] = (uint8_t)((CurVal >> (i*8)) & 0xff); 300 } 301 } 302 303 Optional<MCFixupKind> MipsAsmBackend::getFixupKind(StringRef Name) const { 304 return StringSwitch<Optional<MCFixupKind>>(Name) 305 .Case("R_MIPS_NONE", FK_NONE) 306 .Case("R_MIPS_32", FK_Data_4) 307 .Case("R_MIPS_CALL_HI16", (MCFixupKind)Mips::fixup_Mips_CALL_HI16) 308 .Case("R_MIPS_CALL_LO16", (MCFixupKind)Mips::fixup_Mips_CALL_LO16) 309 .Case("R_MIPS_CALL16", (MCFixupKind)Mips::fixup_Mips_CALL16) 310 .Case("R_MIPS_GOT16", (MCFixupKind)Mips::fixup_Mips_GOT) 311 .Case("R_MIPS_GOT_PAGE", (MCFixupKind)Mips::fixup_Mips_GOT_PAGE) 312 .Case("R_MIPS_GOT_OFST", (MCFixupKind)Mips::fixup_Mips_GOT_OFST) 313 .Case("R_MIPS_GOT_DISP", (MCFixupKind)Mips::fixup_Mips_GOT_DISP) 314 .Case("R_MIPS_GOT_HI16", (MCFixupKind)Mips::fixup_Mips_GOT_HI16) 315 .Case("R_MIPS_GOT_LO16", (MCFixupKind)Mips::fixup_Mips_GOT_LO16) 316 .Case("R_MIPS_TLS_GOTTPREL", (MCFixupKind)Mips::fixup_Mips_GOTTPREL) 317 .Case("R_MIPS_TLS_DTPREL_HI16", (MCFixupKind)Mips::fixup_Mips_DTPREL_HI) 318 .Case("R_MIPS_TLS_DTPREL_LO16", (MCFixupKind)Mips::fixup_Mips_DTPREL_LO) 319 .Case("R_MIPS_TLS_GD", (MCFixupKind)Mips::fixup_Mips_TLSGD) 320 .Case("R_MIPS_TLS_LDM", (MCFixupKind)Mips::fixup_Mips_TLSLDM) 321 .Case("R_MIPS_TLS_TPREL_HI16", (MCFixupKind)Mips::fixup_Mips_TPREL_HI) 322 .Case("R_MIPS_TLS_TPREL_LO16", (MCFixupKind)Mips::fixup_Mips_TPREL_LO) 323 .Case("R_MICROMIPS_CALL16", (MCFixupKind)Mips::fixup_MICROMIPS_CALL16) 324 .Case("R_MICROMIPS_GOT_DISP", (MCFixupKind)Mips::fixup_MICROMIPS_GOT_DISP) 325 .Case("R_MICROMIPS_GOT_PAGE", (MCFixupKind)Mips::fixup_MICROMIPS_GOT_PAGE) 326 .Case("R_MICROMIPS_GOT_OFST", (MCFixupKind)Mips::fixup_MICROMIPS_GOT_OFST) 327 .Case("R_MICROMIPS_GOT16", (MCFixupKind)Mips::fixup_MICROMIPS_GOT16) 328 .Case("R_MICROMIPS_TLS_GOTTPREL", 329 (MCFixupKind)Mips::fixup_MICROMIPS_GOTTPREL) 330 .Case("R_MICROMIPS_TLS_DTPREL_HI16", 331 (MCFixupKind)Mips::fixup_MICROMIPS_TLS_DTPREL_HI16) 332 .Case("R_MICROMIPS_TLS_DTPREL_LO16", 333 (MCFixupKind)Mips::fixup_MICROMIPS_TLS_DTPREL_LO16) 334 .Case("R_MICROMIPS_TLS_GD", (MCFixupKind)Mips::fixup_MICROMIPS_TLS_GD) 335 .Case("R_MICROMIPS_TLS_LDM", (MCFixupKind)Mips::fixup_MICROMIPS_TLS_LDM) 336 .Case("R_MICROMIPS_TLS_TPREL_HI16", 337 (MCFixupKind)Mips::fixup_MICROMIPS_TLS_TPREL_HI16) 338 .Case("R_MICROMIPS_TLS_TPREL_LO16", 339 (MCFixupKind)Mips::fixup_MICROMIPS_TLS_TPREL_LO16) 340 .Case("R_MIPS_JALR", (MCFixupKind)Mips::fixup_Mips_JALR) 341 .Case("R_MICROMIPS_JALR", (MCFixupKind)Mips::fixup_MICROMIPS_JALR) 342 .Default(MCAsmBackend::getFixupKind(Name)); 343 } 344 345 const MCFixupKindInfo &MipsAsmBackend:: 346 getFixupKindInfo(MCFixupKind Kind) const { 347 const static MCFixupKindInfo LittleEndianInfos[] = { 348 // This table *must* be in same the order of fixup_* kinds in 349 // MipsFixupKinds.h. 350 // 351 // name offset bits flags 352 { "fixup_Mips_16", 0, 16, 0 }, 353 { "fixup_Mips_32", 0, 32, 0 }, 354 { "fixup_Mips_REL32", 0, 32, 0 }, 355 { "fixup_Mips_26", 0, 26, 0 }, 356 { "fixup_Mips_HI16", 0, 16, 0 }, 357 { "fixup_Mips_LO16", 0, 16, 0 }, 358 { "fixup_Mips_GPREL16", 0, 16, 0 }, 359 { "fixup_Mips_LITERAL", 0, 16, 0 }, 360 { "fixup_Mips_GOT", 0, 16, 0 }, 361 { "fixup_Mips_PC16", 0, 16, MCFixupKindInfo::FKF_IsPCRel }, 362 { "fixup_Mips_CALL16", 0, 16, 0 }, 363 { "fixup_Mips_GPREL32", 0, 32, 0 }, 364 { "fixup_Mips_SHIFT5", 6, 5, 0 }, 365 { "fixup_Mips_SHIFT6", 6, 5, 0 }, 366 { "fixup_Mips_64", 0, 64, 0 }, 367 { "fixup_Mips_TLSGD", 0, 16, 0 }, 368 { "fixup_Mips_GOTTPREL", 0, 16, 0 }, 369 { "fixup_Mips_TPREL_HI", 0, 16, 0 }, 370 { "fixup_Mips_TPREL_LO", 0, 16, 0 }, 371 { "fixup_Mips_TLSLDM", 0, 16, 0 }, 372 { "fixup_Mips_DTPREL_HI", 0, 16, 0 }, 373 { "fixup_Mips_DTPREL_LO", 0, 16, 0 }, 374 { "fixup_Mips_Branch_PCRel", 0, 16, MCFixupKindInfo::FKF_IsPCRel }, 375 { "fixup_Mips_GPOFF_HI", 0, 16, 0 }, 376 { "fixup_MICROMIPS_GPOFF_HI",0, 16, 0 }, 377 { "fixup_Mips_GPOFF_LO", 0, 16, 0 }, 378 { "fixup_MICROMIPS_GPOFF_LO",0, 16, 0 }, 379 { "fixup_Mips_GOT_PAGE", 0, 16, 0 }, 380 { "fixup_Mips_GOT_OFST", 0, 16, 0 }, 381 { "fixup_Mips_GOT_DISP", 0, 16, 0 }, 382 { "fixup_Mips_HIGHER", 0, 16, 0 }, 383 { "fixup_MICROMIPS_HIGHER", 0, 16, 0 }, 384 { "fixup_Mips_HIGHEST", 0, 16, 0 }, 385 { "fixup_MICROMIPS_HIGHEST", 0, 16, 0 }, 386 { "fixup_Mips_GOT_HI16", 0, 16, 0 }, 387 { "fixup_Mips_GOT_LO16", 0, 16, 0 }, 388 { "fixup_Mips_CALL_HI16", 0, 16, 0 }, 389 { "fixup_Mips_CALL_LO16", 0, 16, 0 }, 390 { "fixup_Mips_PC18_S3", 0, 18, MCFixupKindInfo::FKF_IsPCRel }, 391 { "fixup_MIPS_PC19_S2", 0, 19, MCFixupKindInfo::FKF_IsPCRel }, 392 { "fixup_MIPS_PC21_S2", 0, 21, MCFixupKindInfo::FKF_IsPCRel }, 393 { "fixup_MIPS_PC26_S2", 0, 26, MCFixupKindInfo::FKF_IsPCRel }, 394 { "fixup_MIPS_PCHI16", 0, 16, MCFixupKindInfo::FKF_IsPCRel }, 395 { "fixup_MIPS_PCLO16", 0, 16, MCFixupKindInfo::FKF_IsPCRel }, 396 { "fixup_MICROMIPS_26_S1", 0, 26, 0 }, 397 { "fixup_MICROMIPS_HI16", 0, 16, 0 }, 398 { "fixup_MICROMIPS_LO16", 0, 16, 0 }, 399 { "fixup_MICROMIPS_GOT16", 0, 16, 0 }, 400 { "fixup_MICROMIPS_PC7_S1", 0, 7, MCFixupKindInfo::FKF_IsPCRel }, 401 { "fixup_MICROMIPS_PC10_S1", 0, 10, MCFixupKindInfo::FKF_IsPCRel }, 402 { "fixup_MICROMIPS_PC16_S1", 0, 16, MCFixupKindInfo::FKF_IsPCRel }, 403 { "fixup_MICROMIPS_PC26_S1", 0, 26, MCFixupKindInfo::FKF_IsPCRel }, 404 { "fixup_MICROMIPS_PC19_S2", 0, 19, MCFixupKindInfo::FKF_IsPCRel }, 405 { "fixup_MICROMIPS_PC18_S3", 0, 18, MCFixupKindInfo::FKF_IsPCRel }, 406 { "fixup_MICROMIPS_PC21_S1", 0, 21, MCFixupKindInfo::FKF_IsPCRel }, 407 { "fixup_MICROMIPS_CALL16", 0, 16, 0 }, 408 { "fixup_MICROMIPS_GOT_DISP", 0, 16, 0 }, 409 { "fixup_MICROMIPS_GOT_PAGE", 0, 16, 0 }, 410 { "fixup_MICROMIPS_GOT_OFST", 0, 16, 0 }, 411 { "fixup_MICROMIPS_TLS_GD", 0, 16, 0 }, 412 { "fixup_MICROMIPS_TLS_LDM", 0, 16, 0 }, 413 { "fixup_MICROMIPS_TLS_DTPREL_HI16", 0, 16, 0 }, 414 { "fixup_MICROMIPS_TLS_DTPREL_LO16", 0, 16, 0 }, 415 { "fixup_MICROMIPS_GOTTPREL", 0, 16, 0 }, 416 { "fixup_MICROMIPS_TLS_TPREL_HI16", 0, 16, 0 }, 417 { "fixup_MICROMIPS_TLS_TPREL_LO16", 0, 16, 0 }, 418 { "fixup_Mips_SUB", 0, 64, 0 }, 419 { "fixup_MICROMIPS_SUB", 0, 64, 0 }, 420 { "fixup_Mips_JALR", 0, 32, 0 }, 421 { "fixup_MICROMIPS_JALR", 0, 32, 0 } 422 }; 423 static_assert(array_lengthof(LittleEndianInfos) == Mips::NumTargetFixupKinds, 424 "Not all MIPS little endian fixup kinds added!"); 425 426 const static MCFixupKindInfo BigEndianInfos[] = { 427 // This table *must* be in same the order of fixup_* kinds in 428 // MipsFixupKinds.h. 429 // 430 // name offset bits flags 431 { "fixup_Mips_16", 16, 16, 0 }, 432 { "fixup_Mips_32", 0, 32, 0 }, 433 { "fixup_Mips_REL32", 0, 32, 0 }, 434 { "fixup_Mips_26", 6, 26, 0 }, 435 { "fixup_Mips_HI16", 16, 16, 0 }, 436 { "fixup_Mips_LO16", 16, 16, 0 }, 437 { "fixup_Mips_GPREL16", 16, 16, 0 }, 438 { "fixup_Mips_LITERAL", 16, 16, 0 }, 439 { "fixup_Mips_GOT", 16, 16, 0 }, 440 { "fixup_Mips_PC16", 16, 16, MCFixupKindInfo::FKF_IsPCRel }, 441 { "fixup_Mips_CALL16", 16, 16, 0 }, 442 { "fixup_Mips_GPREL32", 0, 32, 0 }, 443 { "fixup_Mips_SHIFT5", 21, 5, 0 }, 444 { "fixup_Mips_SHIFT6", 21, 5, 0 }, 445 { "fixup_Mips_64", 0, 64, 0 }, 446 { "fixup_Mips_TLSGD", 16, 16, 0 }, 447 { "fixup_Mips_GOTTPREL", 16, 16, 0 }, 448 { "fixup_Mips_TPREL_HI", 16, 16, 0 }, 449 { "fixup_Mips_TPREL_LO", 16, 16, 0 }, 450 { "fixup_Mips_TLSLDM", 16, 16, 0 }, 451 { "fixup_Mips_DTPREL_HI", 16, 16, 0 }, 452 { "fixup_Mips_DTPREL_LO", 16, 16, 0 }, 453 { "fixup_Mips_Branch_PCRel",16, 16, MCFixupKindInfo::FKF_IsPCRel }, 454 { "fixup_Mips_GPOFF_HI", 16, 16, 0 }, 455 { "fixup_MICROMIPS_GPOFF_HI", 16, 16, 0 }, 456 { "fixup_Mips_GPOFF_LO", 16, 16, 0 }, 457 { "fixup_MICROMIPS_GPOFF_LO", 16, 16, 0 }, 458 { "fixup_Mips_GOT_PAGE", 16, 16, 0 }, 459 { "fixup_Mips_GOT_OFST", 16, 16, 0 }, 460 { "fixup_Mips_GOT_DISP", 16, 16, 0 }, 461 { "fixup_Mips_HIGHER", 16, 16, 0 }, 462 { "fixup_MICROMIPS_HIGHER", 16, 16, 0 }, 463 { "fixup_Mips_HIGHEST", 16, 16, 0 }, 464 { "fixup_MICROMIPS_HIGHEST",16, 16, 0 }, 465 { "fixup_Mips_GOT_HI16", 16, 16, 0 }, 466 { "fixup_Mips_GOT_LO16", 16, 16, 0 }, 467 { "fixup_Mips_CALL_HI16", 16, 16, 0 }, 468 { "fixup_Mips_CALL_LO16", 16, 16, 0 }, 469 { "fixup_Mips_PC18_S3", 14, 18, MCFixupKindInfo::FKF_IsPCRel }, 470 { "fixup_MIPS_PC19_S2", 13, 19, MCFixupKindInfo::FKF_IsPCRel }, 471 { "fixup_MIPS_PC21_S2", 11, 21, MCFixupKindInfo::FKF_IsPCRel }, 472 { "fixup_MIPS_PC26_S2", 6, 26, MCFixupKindInfo::FKF_IsPCRel }, 473 { "fixup_MIPS_PCHI16", 16, 16, MCFixupKindInfo::FKF_IsPCRel }, 474 { "fixup_MIPS_PCLO16", 16, 16, MCFixupKindInfo::FKF_IsPCRel }, 475 { "fixup_MICROMIPS_26_S1", 6, 26, 0 }, 476 { "fixup_MICROMIPS_HI16", 16, 16, 0 }, 477 { "fixup_MICROMIPS_LO16", 16, 16, 0 }, 478 { "fixup_MICROMIPS_GOT16", 16, 16, 0 }, 479 { "fixup_MICROMIPS_PC7_S1", 9, 7, MCFixupKindInfo::FKF_IsPCRel }, 480 { "fixup_MICROMIPS_PC10_S1", 6, 10, MCFixupKindInfo::FKF_IsPCRel }, 481 { "fixup_MICROMIPS_PC16_S1",16, 16, MCFixupKindInfo::FKF_IsPCRel }, 482 { "fixup_MICROMIPS_PC26_S1", 6, 26, MCFixupKindInfo::FKF_IsPCRel }, 483 { "fixup_MICROMIPS_PC19_S2",13, 19, MCFixupKindInfo::FKF_IsPCRel }, 484 { "fixup_MICROMIPS_PC18_S3",14, 18, MCFixupKindInfo::FKF_IsPCRel }, 485 { "fixup_MICROMIPS_PC21_S1",11, 21, MCFixupKindInfo::FKF_IsPCRel }, 486 { "fixup_MICROMIPS_CALL16", 16, 16, 0 }, 487 { "fixup_MICROMIPS_GOT_DISP", 16, 16, 0 }, 488 { "fixup_MICROMIPS_GOT_PAGE", 16, 16, 0 }, 489 { "fixup_MICROMIPS_GOT_OFST", 16, 16, 0 }, 490 { "fixup_MICROMIPS_TLS_GD", 16, 16, 0 }, 491 { "fixup_MICROMIPS_TLS_LDM", 16, 16, 0 }, 492 { "fixup_MICROMIPS_TLS_DTPREL_HI16", 16, 16, 0 }, 493 { "fixup_MICROMIPS_TLS_DTPREL_LO16", 16, 16, 0 }, 494 { "fixup_MICROMIPS_GOTTPREL", 16, 16, 0 }, 495 { "fixup_MICROMIPS_TLS_TPREL_HI16", 16, 16, 0 }, 496 { "fixup_MICROMIPS_TLS_TPREL_LO16", 16, 16, 0 }, 497 { "fixup_Mips_SUB", 0, 64, 0 }, 498 { "fixup_MICROMIPS_SUB", 0, 64, 0 }, 499 { "fixup_Mips_JALR", 0, 32, 0 }, 500 { "fixup_MICROMIPS_JALR", 0, 32, 0 } 501 }; 502 static_assert(array_lengthof(BigEndianInfos) == Mips::NumTargetFixupKinds, 503 "Not all MIPS big endian fixup kinds added!"); 504 505 if (Kind < FirstTargetFixupKind) 506 return MCAsmBackend::getFixupKindInfo(Kind); 507 508 assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() && 509 "Invalid kind!"); 510 511 if (Endian == support::little) 512 return LittleEndianInfos[Kind - FirstTargetFixupKind]; 513 return BigEndianInfos[Kind - FirstTargetFixupKind]; 514 } 515 516 /// WriteNopData - Write an (optimal) nop sequence of Count bytes 517 /// to the given output. If the target cannot generate such a sequence, 518 /// it should return an error. 519 /// 520 /// \return - True on success. 521 bool MipsAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count, 522 const MCSubtargetInfo *STI) const { 523 // Check for a less than instruction size number of bytes 524 // FIXME: 16 bit instructions are not handled yet here. 525 // We shouldn't be using a hard coded number for instruction size. 526 527 // If the count is not 4-byte aligned, we must be writing data into the text 528 // section (otherwise we have unaligned instructions, and thus have far 529 // bigger problems), so just write zeros instead. 530 OS.write_zeros(Count); 531 return true; 532 } 533 534 bool MipsAsmBackend::shouldForceRelocation(const MCAssembler &Asm, 535 const MCFixup &Fixup, 536 const MCValue &Target) { 537 const unsigned FixupKind = Fixup.getKind(); 538 switch (FixupKind) { 539 default: 540 return false; 541 // All these relocations require special processing 542 // at linking time. Delegate this work to a linker. 543 case Mips::fixup_Mips_CALL_HI16: 544 case Mips::fixup_Mips_CALL_LO16: 545 case Mips::fixup_Mips_CALL16: 546 case Mips::fixup_Mips_GOT: 547 case Mips::fixup_Mips_GOT_PAGE: 548 case Mips::fixup_Mips_GOT_OFST: 549 case Mips::fixup_Mips_GOT_DISP: 550 case Mips::fixup_Mips_GOT_HI16: 551 case Mips::fixup_Mips_GOT_LO16: 552 case Mips::fixup_Mips_GOTTPREL: 553 case Mips::fixup_Mips_DTPREL_HI: 554 case Mips::fixup_Mips_DTPREL_LO: 555 case Mips::fixup_Mips_TLSGD: 556 case Mips::fixup_Mips_TLSLDM: 557 case Mips::fixup_Mips_TPREL_HI: 558 case Mips::fixup_Mips_TPREL_LO: 559 case Mips::fixup_Mips_JALR: 560 case Mips::fixup_MICROMIPS_CALL16: 561 case Mips::fixup_MICROMIPS_GOT_DISP: 562 case Mips::fixup_MICROMIPS_GOT_PAGE: 563 case Mips::fixup_MICROMIPS_GOT_OFST: 564 case Mips::fixup_MICROMIPS_GOT16: 565 case Mips::fixup_MICROMIPS_GOTTPREL: 566 case Mips::fixup_MICROMIPS_TLS_DTPREL_HI16: 567 case Mips::fixup_MICROMIPS_TLS_DTPREL_LO16: 568 case Mips::fixup_MICROMIPS_TLS_GD: 569 case Mips::fixup_MICROMIPS_TLS_LDM: 570 case Mips::fixup_MICROMIPS_TLS_TPREL_HI16: 571 case Mips::fixup_MICROMIPS_TLS_TPREL_LO16: 572 case Mips::fixup_MICROMIPS_JALR: 573 return true; 574 } 575 } 576 577 bool MipsAsmBackend::isMicroMips(const MCSymbol *Sym) const { 578 if (const auto *ElfSym = dyn_cast<const MCSymbolELF>(Sym)) { 579 if (ElfSym->getOther() & ELF::STO_MIPS_MICROMIPS) 580 return true; 581 } 582 return false; 583 } 584 585 MCAsmBackend *llvm::createMipsAsmBackend(const Target &T, 586 const MCSubtargetInfo &STI, 587 const MCRegisterInfo &MRI, 588 const MCTargetOptions &Options) { 589 MipsABIInfo ABI = MipsABIInfo::computeTargetABI(STI.getTargetTriple(), 590 STI.getCPU(), Options); 591 return new MipsAsmBackend(T, MRI, STI.getTargetTriple(), STI.getCPU(), 592 ABI.IsN32()); 593 } 594