brintos

brintos / llvm-project-archived public Read only

0
0
Text · 24.6 KiB · 74e7baf Raw
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