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