Home | History | Annotate | Download | only in MCTargetDesc
      1 //===-- MipsAsmBackend.cpp - Mips Asm 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 // This file implements the MipsAsmBackend class.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 //
     14 
     15 #include "MCTargetDesc/MipsAsmBackend.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/MCSymbolELF.h"
     29 #include "llvm/MC/MCTargetOptions.h"
     30 #include "llvm/MC/MCValue.h"
     31 #include "llvm/Support/ErrorHandling.h"
     32 #include "llvm/Support/Format.h"
     33 #include "llvm/Support/MathExtras.h"
     34 #include "llvm/Support/raw_ostream.h"
     35 
     36 using namespace llvm;
     37 
     38 // Prepare value for the target space for it
     39 static unsigned adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
     40                                  MCContext &Ctx) {
     41 
     42   unsigned Kind = Fixup.getKind();
     43 
     44   // Add/subtract and shift
     45   switch (Kind) {
     46   default:
     47     return 0;
     48   case FK_Data_2:
     49   case Mips::fixup_Mips_LO16:
     50   case Mips::fixup_Mips_GPREL16:
     51   case Mips::fixup_Mips_GPOFF_HI:
     52   case Mips::fixup_Mips_GPOFF_LO:
     53   case Mips::fixup_Mips_GOT_PAGE:
     54   case Mips::fixup_Mips_GOT_OFST:
     55   case Mips::fixup_Mips_GOT_DISP:
     56   case Mips::fixup_Mips_GOT_LO16:
     57   case Mips::fixup_Mips_CALL_LO16:
     58   case Mips::fixup_MICROMIPS_GPOFF_HI:
     59   case Mips::fixup_MICROMIPS_GPOFF_LO:
     60   case Mips::fixup_MICROMIPS_LO16:
     61   case Mips::fixup_MICROMIPS_GOT_PAGE:
     62   case Mips::fixup_MICROMIPS_GOT_OFST:
     63   case Mips::fixup_MICROMIPS_GOT_DISP:
     64   case Mips::fixup_MIPS_PCLO16:
     65     Value &= 0xffff;
     66     break;
     67   case FK_DTPRel_4:
     68   case FK_DTPRel_8:
     69   case FK_TPRel_4:
     70   case FK_TPRel_8:
     71   case FK_GPRel_4:
     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 bit
     79     // 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 bit
    100     // 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.reportFatalError(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 
    219 std::unique_ptr<MCObjectTargetWriter>
    220 MipsAsmBackend::createObjectTargetWriter() const {
    221   return createMipsELFObjectWriter(TheTriple, IsN32);
    222 }
    223 
    224 // Little-endian fixup data byte ordering:
    225 //   mips32r2:   a | b | x | x
    226 //   microMIPS:  x | x | a | b
    227 
    228 static 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 order
    235 static unsigned calculateMMLEIndex(unsigned i) {
    236   assert(i <= 3 && "Index out of range!");
    237 
    238   return (1 - i / 2) * 2 + i % 2;
    239 }
    240 
    241 /// ApplyFixup - Apply the \p Value for given \p Fixup into the provided
    242 /// data fragment, at the offset specified by the fixup and following the
    243 /// fixup kind as appropriate.
    244 void MipsAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
    245                                 const MCValue &Target,
    246                                 MutableArrayRef<char> Data, uint64_t Value,
    247                                 bool IsResolved,
    248                                 const MCSubtargetInfo *STI) const {
    249   MCFixupKind Kind = Fixup.getKind();
    250   MCContext &Ctx = Asm.getContext();
    251   Value = adjustFixupValue(Fixup, Value, Ctx);
    252 
    253   if (!Value)
    254     return; // Doesn't change encoding.
    255 
    256   // Where do we start in the object
    257   unsigned Offset = Fixup.getOffset();
    258   // Number of bytes we need to fixup
    259   unsigned NumBytes = (getFixupKindInfo(Kind).TargetSize + 7) / 8;
    260   // Used to point to big endian bytes
    261   unsigned FullSize;
    262 
    263   switch ((unsigned)Kind) {
    264   case FK_Data_2:
    265   case Mips::fixup_Mips_16:
    266   case Mips::fixup_MICROMIPS_PC10_S1:
    267     FullSize = 2;
    268     break;
    269   case FK_Data_8:
    270   case Mips::fixup_Mips_64:
    271     FullSize = 8;
    272     break;
    273   case FK_Data_4:
    274   default:
    275     FullSize = 4;
    276     break;
    277   }
    278 
    279   // Grab current value, if any, from bits.
    280   uint64_t CurVal = 0;
    281 
    282   bool microMipsLEByteOrder = needsMMLEByteOrder((unsigned) Kind);
    283 
    284   for (unsigned i = 0; i != NumBytes; ++i) {
    285     unsigned Idx = Endian == support::little
    286                        ? (microMipsLEByteOrder ? calculateMMLEIndex(i) : i)
    287                        : (FullSize - 1 - i);
    288     CurVal |= (uint64_t)((uint8_t)Data[Offset + Idx]) << (i*8);
    289   }
    290 
    291   uint64_t Mask = ((uint64_t)(-1) >>
    292                     (64 - getFixupKindInfo(Kind).TargetSize));
    293   CurVal |= Value & Mask;
    294 
    295   // Write out the fixed up bytes back to the code/data bits.
    296   for (unsigned i = 0; i != NumBytes; ++i) {
    297     unsigned Idx = Endian == support::little
    298                        ? (microMipsLEByteOrder ? calculateMMLEIndex(i) : i)
    299                        : (FullSize - 1 - i);
    300     Data[Offset + Idx] = (uint8_t)((CurVal >> (i*8)) & 0xff);
    301   }
    302 }
    303 
    304 Optional<MCFixupKind> MipsAsmBackend::getFixupKind(StringRef Name) const {
    305   return StringSwitch<Optional<MCFixupKind>>(Name)
    306       .Case("R_MIPS_NONE", (MCFixupKind)Mips::fixup_Mips_NONE)
    307       .Case("R_MIPS_32", FK_Data_4)
    308       .Case("R_MIPS_GOT_PAGE", (MCFixupKind)Mips::fixup_Mips_GOT_PAGE)
    309       .Case("R_MIPS_CALL_HI16", (MCFixupKind)Mips::fixup_Mips_CALL_HI16)
    310       .Case("R_MIPS_CALL_LO16", (MCFixupKind)Mips::fixup_Mips_CALL_LO16)
    311       .Case("R_MIPS_CALL16", (MCFixupKind)Mips::fixup_Mips_CALL16)
    312       .Case("R_MIPS_GOT16", (MCFixupKind)Mips::fixup_Mips_GOT)
    313       .Case("R_MIPS_GOT_PAGE", (MCFixupKind)Mips::fixup_Mips_GOT_PAGE)
    314       .Case("R_MIPS_GOT_OFST", (MCFixupKind)Mips::fixup_Mips_GOT_OFST)
    315       .Case("R_MIPS_GOT_DISP", (MCFixupKind)Mips::fixup_Mips_GOT_DISP)
    316       .Case("R_MIPS_GOT_HI16", (MCFixupKind)Mips::fixup_Mips_GOT_HI16)
    317       .Case("R_MIPS_GOT_LO16", (MCFixupKind)Mips::fixup_Mips_GOT_LO16)
    318       .Case("R_MIPS_TLS_GOTTPREL", (MCFixupKind)Mips::fixup_Mips_GOTTPREL)
    319       .Case("R_MIPS_TLS_DTPREL_HI16", (MCFixupKind)Mips::fixup_Mips_DTPREL_HI)
    320       .Case("R_MIPS_TLS_DTPREL_LO16", (MCFixupKind)Mips::fixup_Mips_DTPREL_LO)
    321       .Case("R_MIPS_TLS_GD", (MCFixupKind)Mips::fixup_Mips_TLSGD)
    322       .Case("R_MIPS_TLS_LDM", (MCFixupKind)Mips::fixup_Mips_TLSLDM)
    323       .Case("R_MIPS_TLS_TPREL_HI16", (MCFixupKind)Mips::fixup_Mips_TPREL_HI)
    324       .Case("R_MIPS_TLS_TPREL_LO16", (MCFixupKind)Mips::fixup_Mips_TPREL_LO)
    325       .Case("R_MICROMIPS_CALL16", (MCFixupKind)Mips::fixup_MICROMIPS_CALL16)
    326       .Case("R_MICROMIPS_GOT_DISP", (MCFixupKind)Mips::fixup_MICROMIPS_GOT_DISP)
    327       .Case("R_MICROMIPS_GOT_PAGE", (MCFixupKind)Mips::fixup_MICROMIPS_GOT_PAGE)
    328       .Case("R_MICROMIPS_GOT_OFST", (MCFixupKind)Mips::fixup_MICROMIPS_GOT_OFST)
    329       .Case("R_MICROMIPS_GOT16", (MCFixupKind)Mips::fixup_MICROMIPS_GOT16)
    330       .Case("R_MICROMIPS_TLS_GOTTPREL",
    331             (MCFixupKind)Mips::fixup_MICROMIPS_GOTTPREL)
    332       .Case("R_MICROMIPS_TLS_DTPREL_HI16",
    333             (MCFixupKind)Mips::fixup_MICROMIPS_TLS_DTPREL_HI16)
    334       .Case("R_MICROMIPS_TLS_DTPREL_LO16",
    335             (MCFixupKind)Mips::fixup_MICROMIPS_TLS_DTPREL_LO16)
    336       .Case("R_MICROMIPS_TLS_GD", (MCFixupKind)Mips::fixup_MICROMIPS_TLS_GD)
    337       .Case("R_MICROMIPS_TLS_LDM", (MCFixupKind)Mips::fixup_MICROMIPS_TLS_LDM)
    338       .Case("R_MICROMIPS_TLS_TPREL_HI16",
    339             (MCFixupKind)Mips::fixup_MICROMIPS_TLS_TPREL_HI16)
    340       .Case("R_MICROMIPS_TLS_TPREL_LO16",
    341             (MCFixupKind)Mips::fixup_MICROMIPS_TLS_TPREL_LO16)
    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_NONE",         0,      0,   0 },
    353     { "fixup_Mips_16",           0,     16,   0 },
    354     { "fixup_Mips_32",           0,     32,   0 },
    355     { "fixup_Mips_REL32",        0,     32,   0 },
    356     { "fixup_Mips_26",           0,     26,   0 },
    357     { "fixup_Mips_HI16",         0,     16,   0 },
    358     { "fixup_Mips_LO16",         0,     16,   0 },
    359     { "fixup_Mips_GPREL16",      0,     16,   0 },
    360     { "fixup_Mips_LITERAL",      0,     16,   0 },
    361     { "fixup_Mips_GOT",          0,     16,   0 },
    362     { "fixup_Mips_PC16",         0,     16,  MCFixupKindInfo::FKF_IsPCRel },
    363     { "fixup_Mips_CALL16",       0,     16,   0 },
    364     { "fixup_Mips_GPREL32",      0,     32,   0 },
    365     { "fixup_Mips_SHIFT5",       6,      5,   0 },
    366     { "fixup_Mips_SHIFT6",       6,      5,   0 },
    367     { "fixup_Mips_64",           0,     64,   0 },
    368     { "fixup_Mips_TLSGD",        0,     16,   0 },
    369     { "fixup_Mips_GOTTPREL",     0,     16,   0 },
    370     { "fixup_Mips_TPREL_HI",     0,     16,   0 },
    371     { "fixup_Mips_TPREL_LO",     0,     16,   0 },
    372     { "fixup_Mips_TLSLDM",       0,     16,   0 },
    373     { "fixup_Mips_DTPREL_HI",    0,     16,   0 },
    374     { "fixup_Mips_DTPREL_LO",    0,     16,   0 },
    375     { "fixup_Mips_Branch_PCRel", 0,     16,  MCFixupKindInfo::FKF_IsPCRel },
    376     { "fixup_Mips_GPOFF_HI",     0,     16,   0 },
    377     { "fixup_MICROMIPS_GPOFF_HI",0,     16,   0 },
    378     { "fixup_Mips_GPOFF_LO",     0,     16,   0 },
    379     { "fixup_MICROMIPS_GPOFF_LO",0,     16,   0 },
    380     { "fixup_Mips_GOT_PAGE",     0,     16,   0 },
    381     { "fixup_Mips_GOT_OFST",     0,     16,   0 },
    382     { "fixup_Mips_GOT_DISP",     0,     16,   0 },
    383     { "fixup_Mips_HIGHER",       0,     16,   0 },
    384     { "fixup_MICROMIPS_HIGHER",  0,     16,   0 },
    385     { "fixup_Mips_HIGHEST",      0,     16,   0 },
    386     { "fixup_MICROMIPS_HIGHEST", 0,     16,   0 },
    387     { "fixup_Mips_GOT_HI16",     0,     16,   0 },
    388     { "fixup_Mips_GOT_LO16",     0,     16,   0 },
    389     { "fixup_Mips_CALL_HI16",    0,     16,   0 },
    390     { "fixup_Mips_CALL_LO16",    0,     16,   0 },
    391     { "fixup_Mips_PC18_S3",      0,     18,  MCFixupKindInfo::FKF_IsPCRel },
    392     { "fixup_MIPS_PC19_S2",      0,     19,  MCFixupKindInfo::FKF_IsPCRel },
    393     { "fixup_MIPS_PC21_S2",      0,     21,  MCFixupKindInfo::FKF_IsPCRel },
    394     { "fixup_MIPS_PC26_S2",      0,     26,  MCFixupKindInfo::FKF_IsPCRel },
    395     { "fixup_MIPS_PCHI16",       0,     16,  MCFixupKindInfo::FKF_IsPCRel },
    396     { "fixup_MIPS_PCLO16",       0,     16,  MCFixupKindInfo::FKF_IsPCRel },
    397     { "fixup_MICROMIPS_26_S1",   0,     26,   0 },
    398     { "fixup_MICROMIPS_HI16",    0,     16,   0 },
    399     { "fixup_MICROMIPS_LO16",    0,     16,   0 },
    400     { "fixup_MICROMIPS_GOT16",   0,     16,   0 },
    401     { "fixup_MICROMIPS_PC7_S1",  0,      7,   MCFixupKindInfo::FKF_IsPCRel },
    402     { "fixup_MICROMIPS_PC10_S1", 0,     10,   MCFixupKindInfo::FKF_IsPCRel },
    403     { "fixup_MICROMIPS_PC16_S1", 0,     16,   MCFixupKindInfo::FKF_IsPCRel },
    404     { "fixup_MICROMIPS_PC26_S1", 0,     26,   MCFixupKindInfo::FKF_IsPCRel },
    405     { "fixup_MICROMIPS_PC19_S2", 0,     19,   MCFixupKindInfo::FKF_IsPCRel },
    406     { "fixup_MICROMIPS_PC18_S3", 0,     18,   MCFixupKindInfo::FKF_IsPCRel },
    407     { "fixup_MICROMIPS_PC21_S1", 0,     21,   MCFixupKindInfo::FKF_IsPCRel },
    408     { "fixup_MICROMIPS_CALL16",  0,     16,   0 },
    409     { "fixup_MICROMIPS_GOT_DISP",        0,     16,   0 },
    410     { "fixup_MICROMIPS_GOT_PAGE",        0,     16,   0 },
    411     { "fixup_MICROMIPS_GOT_OFST",        0,     16,   0 },
    412     { "fixup_MICROMIPS_TLS_GD",          0,     16,   0 },
    413     { "fixup_MICROMIPS_TLS_LDM",         0,     16,   0 },
    414     { "fixup_MICROMIPS_TLS_DTPREL_HI16", 0,     16,   0 },
    415     { "fixup_MICROMIPS_TLS_DTPREL_LO16", 0,     16,   0 },
    416     { "fixup_MICROMIPS_GOTTPREL",        0,     16,   0 },
    417     { "fixup_MICROMIPS_TLS_TPREL_HI16",  0,     16,   0 },
    418     { "fixup_MICROMIPS_TLS_TPREL_LO16",  0,     16,   0 },
    419     { "fixup_Mips_SUB",                  0,     64,   0 },
    420     { "fixup_MICROMIPS_SUB",             0,     64,   0 }
    421   };
    422   static_assert(array_lengthof(LittleEndianInfos) == Mips::NumTargetFixupKinds,
    423                 "Not all MIPS little endian fixup kinds added!");
    424 
    425   const static MCFixupKindInfo BigEndianInfos[] = {
    426     // This table *must* be in same the order of fixup_* kinds in
    427     // MipsFixupKinds.h.
    428     //
    429     // name                    offset  bits  flags
    430     { "fixup_Mips_NONE",         0,      0,   0 },
    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   };
    500   static_assert(array_lengthof(BigEndianInfos) == Mips::NumTargetFixupKinds,
    501                 "Not all MIPS big endian fixup kinds added!");
    502 
    503   if (Kind < FirstTargetFixupKind)
    504     return MCAsmBackend::getFixupKindInfo(Kind);
    505 
    506   assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
    507           "Invalid kind!");
    508 
    509   if (Endian == support::little)
    510     return LittleEndianInfos[Kind - FirstTargetFixupKind];
    511   return BigEndianInfos[Kind - FirstTargetFixupKind];
    512 }
    513 
    514 /// WriteNopData - Write an (optimal) nop sequence of Count bytes
    515 /// to the given output. If the target cannot generate such a sequence,
    516 /// it should return an error.
    517 ///
    518 /// \return - True on success.
    519 bool MipsAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count) const {
    520   // Check for a less than instruction size number of bytes
    521   // FIXME: 16 bit instructions are not handled yet here.
    522   // We shouldn't be using a hard coded number for instruction size.
    523 
    524   // If the count is not 4-byte aligned, we must be writing data into the text
    525   // section (otherwise we have unaligned instructions, and thus have far
    526   // bigger problems), so just write zeros instead.
    527   OS.write_zeros(Count);
    528   return true;
    529 }
    530 
    531 bool MipsAsmBackend::shouldForceRelocation(const MCAssembler &Asm,
    532                                            const MCFixup &Fixup,
    533                                            const MCValue &Target) {
    534   const unsigned FixupKind = Fixup.getKind();
    535   switch (FixupKind) {
    536   default:
    537     return false;
    538   // All these relocations require special processing
    539   // at linking time. Delegate this work to a linker.
    540   case Mips::fixup_Mips_CALL_HI16:
    541   case Mips::fixup_Mips_CALL_LO16:
    542   case Mips::fixup_Mips_CALL16:
    543   case Mips::fixup_Mips_GOT:
    544   case Mips::fixup_Mips_GOT_PAGE:
    545   case Mips::fixup_Mips_GOT_OFST:
    546   case Mips::fixup_Mips_GOT_DISP:
    547   case Mips::fixup_Mips_GOT_HI16:
    548   case Mips::fixup_Mips_GOT_LO16:
    549   case Mips::fixup_Mips_GOTTPREL:
    550   case Mips::fixup_Mips_DTPREL_HI:
    551   case Mips::fixup_Mips_DTPREL_LO:
    552   case Mips::fixup_Mips_TLSGD:
    553   case Mips::fixup_Mips_TLSLDM:
    554   case Mips::fixup_Mips_TPREL_HI:
    555   case Mips::fixup_Mips_TPREL_LO:
    556   case Mips::fixup_MICROMIPS_CALL16:
    557   case Mips::fixup_MICROMIPS_GOT_DISP:
    558   case Mips::fixup_MICROMIPS_GOT_PAGE:
    559   case Mips::fixup_MICROMIPS_GOT_OFST:
    560   case Mips::fixup_MICROMIPS_GOT16:
    561   case Mips::fixup_MICROMIPS_GOTTPREL:
    562   case Mips::fixup_MICROMIPS_TLS_DTPREL_HI16:
    563   case Mips::fixup_MICROMIPS_TLS_DTPREL_LO16:
    564   case Mips::fixup_MICROMIPS_TLS_GD:
    565   case Mips::fixup_MICROMIPS_TLS_LDM:
    566   case Mips::fixup_MICROMIPS_TLS_TPREL_HI16:
    567   case Mips::fixup_MICROMIPS_TLS_TPREL_LO16:
    568     return true;
    569   }
    570 }
    571 
    572 bool MipsAsmBackend::isMicroMips(const MCSymbol *Sym) const {
    573   if (const auto *ElfSym = dyn_cast<const MCSymbolELF>(Sym)) {
    574     if (ElfSym->getOther() & ELF::STO_MIPS_MICROMIPS)
    575       return true;
    576   }
    577   return false;
    578 }
    579 
    580 MCAsmBackend *llvm::createMipsAsmBackend(const Target &T,
    581                                          const MCSubtargetInfo &STI,
    582                                          const MCRegisterInfo &MRI,
    583                                          const MCTargetOptions &Options) {
    584   return new MipsAsmBackend(T, MRI, STI.getTargetTriple(), STI.getCPU(),
    585                             Options.ABIName == "n32");
    586 }
    587