xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===-- MipsAsmBackend.cpp - Mips Asm Backend  ----------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements the MipsAsmBackend class.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric //
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric #include "MCTargetDesc/MipsAsmBackend.h"
150b57cec5SDimitry Andric #include "MCTargetDesc/MipsABIInfo.h"
160b57cec5SDimitry Andric #include "MCTargetDesc/MipsFixupKinds.h"
170b57cec5SDimitry Andric #include "MCTargetDesc/MipsMCExpr.h"
180b57cec5SDimitry Andric #include "MCTargetDesc/MipsMCTargetDesc.h"
190b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
20*0fca6ea1SDimitry Andric #include "llvm/ADT/StringSwitch.h"
210b57cec5SDimitry Andric #include "llvm/MC/MCAsmBackend.h"
220b57cec5SDimitry Andric #include "llvm/MC/MCAssembler.h"
230b57cec5SDimitry Andric #include "llvm/MC/MCContext.h"
240b57cec5SDimitry Andric #include "llvm/MC/MCDirectives.h"
250b57cec5SDimitry Andric #include "llvm/MC/MCELFObjectWriter.h"
260b57cec5SDimitry Andric #include "llvm/MC/MCFixupKindInfo.h"
270b57cec5SDimitry Andric #include "llvm/MC/MCObjectWriter.h"
280b57cec5SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
290b57cec5SDimitry Andric #include "llvm/MC/MCTargetOptions.h"
300b57cec5SDimitry Andric #include "llvm/MC/MCValue.h"
310b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
320b57cec5SDimitry Andric #include "llvm/Support/Format.h"
330b57cec5SDimitry Andric #include "llvm/Support/MathExtras.h"
340b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
350b57cec5SDimitry Andric 
360b57cec5SDimitry Andric using namespace llvm;
370b57cec5SDimitry Andric 
380b57cec5SDimitry Andric // Prepare value for the target space for it
390b57cec5SDimitry Andric static unsigned adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
400b57cec5SDimitry Andric                                  MCContext &Ctx) {
410b57cec5SDimitry Andric 
420b57cec5SDimitry Andric   unsigned Kind = Fixup.getKind();
430b57cec5SDimitry Andric 
440b57cec5SDimitry Andric   // Add/subtract and shift
450b57cec5SDimitry Andric   switch (Kind) {
460b57cec5SDimitry Andric   default:
470b57cec5SDimitry Andric     return 0;
480b57cec5SDimitry Andric   case FK_Data_2:
490b57cec5SDimitry Andric   case Mips::fixup_Mips_LO16:
500b57cec5SDimitry Andric   case Mips::fixup_Mips_GPREL16:
510b57cec5SDimitry Andric   case Mips::fixup_Mips_GPOFF_HI:
520b57cec5SDimitry Andric   case Mips::fixup_Mips_GPOFF_LO:
530b57cec5SDimitry Andric   case Mips::fixup_Mips_GOT_PAGE:
540b57cec5SDimitry Andric   case Mips::fixup_Mips_GOT_OFST:
550b57cec5SDimitry Andric   case Mips::fixup_Mips_GOT_DISP:
560b57cec5SDimitry Andric   case Mips::fixup_Mips_GOT_LO16:
570b57cec5SDimitry Andric   case Mips::fixup_Mips_CALL_LO16:
580b57cec5SDimitry Andric   case Mips::fixup_MICROMIPS_GPOFF_HI:
590b57cec5SDimitry Andric   case Mips::fixup_MICROMIPS_GPOFF_LO:
600b57cec5SDimitry Andric   case Mips::fixup_MICROMIPS_LO16:
610b57cec5SDimitry Andric   case Mips::fixup_MICROMIPS_GOT_PAGE:
620b57cec5SDimitry Andric   case Mips::fixup_MICROMIPS_GOT_OFST:
630b57cec5SDimitry Andric   case Mips::fixup_MICROMIPS_GOT_DISP:
640b57cec5SDimitry Andric   case Mips::fixup_MIPS_PCLO16:
650b57cec5SDimitry Andric     Value &= 0xffff;
660b57cec5SDimitry Andric     break;
670b57cec5SDimitry Andric   case FK_DTPRel_4:
680b57cec5SDimitry Andric   case FK_DTPRel_8:
690b57cec5SDimitry Andric   case FK_TPRel_4:
700b57cec5SDimitry Andric   case FK_TPRel_8:
710b57cec5SDimitry Andric   case FK_GPRel_4:
720b57cec5SDimitry Andric   case FK_Data_4:
730b57cec5SDimitry Andric   case FK_Data_8:
740b57cec5SDimitry Andric   case Mips::fixup_Mips_SUB:
750b57cec5SDimitry Andric   case Mips::fixup_MICROMIPS_SUB:
760b57cec5SDimitry Andric     break;
770b57cec5SDimitry Andric   case Mips::fixup_Mips_PC16:
780b57cec5SDimitry Andric     // The displacement is then divided by 4 to give us an 18 bit
790b57cec5SDimitry Andric     // address range. Forcing a signed division because Value can be negative.
800b57cec5SDimitry Andric     Value = (int64_t)Value / 4;
810b57cec5SDimitry Andric     // We now check if Value can be encoded as a 16-bit signed immediate.
820b57cec5SDimitry Andric     if (!isInt<16>(Value)) {
830b57cec5SDimitry Andric       Ctx.reportError(Fixup.getLoc(), "out of range PC16 fixup");
840b57cec5SDimitry Andric       return 0;
850b57cec5SDimitry Andric     }
860b57cec5SDimitry Andric     break;
870b57cec5SDimitry Andric   case Mips::fixup_MIPS_PC19_S2:
880b57cec5SDimitry Andric   case Mips::fixup_MICROMIPS_PC19_S2:
890b57cec5SDimitry Andric     // Forcing a signed division because Value can be negative.
900b57cec5SDimitry Andric     Value = (int64_t)Value / 4;
910b57cec5SDimitry Andric     // We now check if Value can be encoded as a 19-bit signed immediate.
920b57cec5SDimitry Andric     if (!isInt<19>(Value)) {
930b57cec5SDimitry Andric       Ctx.reportError(Fixup.getLoc(), "out of range PC19 fixup");
940b57cec5SDimitry Andric       return 0;
950b57cec5SDimitry Andric     }
960b57cec5SDimitry Andric     break;
970b57cec5SDimitry Andric   case Mips::fixup_Mips_26:
980b57cec5SDimitry Andric     // So far we are only using this type for jumps.
990b57cec5SDimitry Andric     // The displacement is then divided by 4 to give us an 28 bit
1000b57cec5SDimitry Andric     // address range.
1010b57cec5SDimitry Andric     Value >>= 2;
1020b57cec5SDimitry Andric     break;
1030b57cec5SDimitry Andric   case Mips::fixup_Mips_HI16:
1040b57cec5SDimitry Andric   case Mips::fixup_Mips_GOT:
1050b57cec5SDimitry Andric   case Mips::fixup_MICROMIPS_GOT16:
1060b57cec5SDimitry Andric   case Mips::fixup_Mips_GOT_HI16:
1070b57cec5SDimitry Andric   case Mips::fixup_Mips_CALL_HI16:
1080b57cec5SDimitry Andric   case Mips::fixup_MICROMIPS_HI16:
1090b57cec5SDimitry Andric   case Mips::fixup_MIPS_PCHI16:
1100b57cec5SDimitry Andric     // Get the 2nd 16-bits. Also add 1 if bit 15 is 1.
1110b57cec5SDimitry Andric     Value = ((Value + 0x8000) >> 16) & 0xffff;
1120b57cec5SDimitry Andric     break;
1130b57cec5SDimitry Andric   case Mips::fixup_Mips_HIGHER:
1140b57cec5SDimitry Andric   case Mips::fixup_MICROMIPS_HIGHER:
1150b57cec5SDimitry Andric     // Get the 3rd 16-bits.
1160b57cec5SDimitry Andric     Value = ((Value + 0x80008000LL) >> 32) & 0xffff;
1170b57cec5SDimitry Andric     break;
1180b57cec5SDimitry Andric   case Mips::fixup_Mips_HIGHEST:
1190b57cec5SDimitry Andric   case Mips::fixup_MICROMIPS_HIGHEST:
1200b57cec5SDimitry Andric     // Get the 4th 16-bits.
1210b57cec5SDimitry Andric     Value = ((Value + 0x800080008000LL) >> 48) & 0xffff;
1220b57cec5SDimitry Andric     break;
1230b57cec5SDimitry Andric   case Mips::fixup_MICROMIPS_26_S1:
1240b57cec5SDimitry Andric     Value >>= 1;
1250b57cec5SDimitry Andric     break;
1260b57cec5SDimitry Andric   case Mips::fixup_MICROMIPS_PC7_S1:
1270b57cec5SDimitry Andric     Value -= 4;
1280b57cec5SDimitry Andric     // Forcing a signed division because Value can be negative.
1290b57cec5SDimitry Andric     Value = (int64_t) Value / 2;
1300b57cec5SDimitry Andric     // We now check if Value can be encoded as a 7-bit signed immediate.
1310b57cec5SDimitry Andric     if (!isInt<7>(Value)) {
1320b57cec5SDimitry Andric       Ctx.reportError(Fixup.getLoc(), "out of range PC7 fixup");
1330b57cec5SDimitry Andric       return 0;
1340b57cec5SDimitry Andric     }
1350b57cec5SDimitry Andric     break;
1360b57cec5SDimitry Andric   case Mips::fixup_MICROMIPS_PC10_S1:
1370b57cec5SDimitry Andric     Value -= 2;
1380b57cec5SDimitry Andric     // Forcing a signed division because Value can be negative.
1390b57cec5SDimitry Andric     Value = (int64_t) Value / 2;
1400b57cec5SDimitry Andric     // We now check if Value can be encoded as a 10-bit signed immediate.
1410b57cec5SDimitry Andric     if (!isInt<10>(Value)) {
1420b57cec5SDimitry Andric       Ctx.reportError(Fixup.getLoc(), "out of range PC10 fixup");
1430b57cec5SDimitry Andric       return 0;
1440b57cec5SDimitry Andric     }
1450b57cec5SDimitry Andric     break;
1460b57cec5SDimitry Andric   case Mips::fixup_MICROMIPS_PC16_S1:
1470b57cec5SDimitry Andric     Value -= 4;
1480b57cec5SDimitry Andric     // Forcing a signed division because Value can be negative.
1490b57cec5SDimitry Andric     Value = (int64_t)Value / 2;
1500b57cec5SDimitry Andric     // We now check if Value can be encoded as a 16-bit signed immediate.
1510b57cec5SDimitry Andric     if (!isInt<16>(Value)) {
1520b57cec5SDimitry Andric       Ctx.reportError(Fixup.getLoc(), "out of range PC16 fixup");
1530b57cec5SDimitry Andric       return 0;
1540b57cec5SDimitry Andric     }
1550b57cec5SDimitry Andric     break;
1560b57cec5SDimitry Andric   case Mips::fixup_MIPS_PC18_S3:
1570b57cec5SDimitry Andric     // Forcing a signed division because Value can be negative.
1580b57cec5SDimitry Andric     Value = (int64_t)Value / 8;
1590b57cec5SDimitry Andric     // We now check if Value can be encoded as a 18-bit signed immediate.
1600b57cec5SDimitry Andric     if (!isInt<18>(Value)) {
1610b57cec5SDimitry Andric       Ctx.reportError(Fixup.getLoc(), "out of range PC18 fixup");
1620b57cec5SDimitry Andric       return 0;
1630b57cec5SDimitry Andric     }
1640b57cec5SDimitry Andric     break;
1650b57cec5SDimitry Andric   case Mips::fixup_MICROMIPS_PC18_S3:
1660b57cec5SDimitry Andric     // Check alignment.
1670b57cec5SDimitry Andric     if ((Value & 7)) {
1680b57cec5SDimitry Andric       Ctx.reportError(Fixup.getLoc(), "out of range PC18 fixup");
1690b57cec5SDimitry Andric     }
1700b57cec5SDimitry Andric     // Forcing a signed division because Value can be negative.
1710b57cec5SDimitry Andric     Value = (int64_t)Value / 8;
1720b57cec5SDimitry Andric     // We now check if Value can be encoded as a 18-bit signed immediate.
1730b57cec5SDimitry Andric     if (!isInt<18>(Value)) {
1740b57cec5SDimitry Andric       Ctx.reportError(Fixup.getLoc(), "out of range PC18 fixup");
1750b57cec5SDimitry Andric       return 0;
1760b57cec5SDimitry Andric     }
1770b57cec5SDimitry Andric     break;
1780b57cec5SDimitry Andric   case Mips::fixup_MIPS_PC21_S2:
1790b57cec5SDimitry Andric     // Forcing a signed division because Value can be negative.
1800b57cec5SDimitry Andric     Value = (int64_t) Value / 4;
1810b57cec5SDimitry Andric     // We now check if Value can be encoded as a 21-bit signed immediate.
1820b57cec5SDimitry Andric     if (!isInt<21>(Value)) {
1830b57cec5SDimitry Andric       Ctx.reportError(Fixup.getLoc(), "out of range PC21 fixup");
1840b57cec5SDimitry Andric       return 0;
1850b57cec5SDimitry Andric     }
1860b57cec5SDimitry Andric     break;
1870b57cec5SDimitry Andric   case Mips::fixup_MIPS_PC26_S2:
1880b57cec5SDimitry Andric     // Forcing a signed division because Value can be negative.
1890b57cec5SDimitry Andric     Value = (int64_t) Value / 4;
1900b57cec5SDimitry Andric     // We now check if Value can be encoded as a 26-bit signed immediate.
1910b57cec5SDimitry Andric     if (!isInt<26>(Value)) {
1920b57cec5SDimitry Andric       Ctx.reportError(Fixup.getLoc(), "out of range PC26 fixup");
1930b57cec5SDimitry Andric       return 0;
1940b57cec5SDimitry Andric     }
1950b57cec5SDimitry Andric     break;
1960b57cec5SDimitry Andric   case Mips::fixup_MICROMIPS_PC26_S1:
1970b57cec5SDimitry Andric     // Forcing a signed division because Value can be negative.
1980b57cec5SDimitry Andric     Value = (int64_t)Value / 2;
1990b57cec5SDimitry Andric     // We now check if Value can be encoded as a 26-bit signed immediate.
2000b57cec5SDimitry Andric     if (!isInt<26>(Value)) {
20104eeddc0SDimitry Andric       Ctx.reportError(Fixup.getLoc(), "out of range PC26 fixup");
2020b57cec5SDimitry Andric       return 0;
2030b57cec5SDimitry Andric     }
2040b57cec5SDimitry Andric     break;
2050b57cec5SDimitry Andric   case Mips::fixup_MICROMIPS_PC21_S1:
2060b57cec5SDimitry Andric     // Forcing a signed division because Value can be negative.
2070b57cec5SDimitry Andric     Value = (int64_t)Value / 2;
2080b57cec5SDimitry Andric     // We now check if Value can be encoded as a 21-bit signed immediate.
2090b57cec5SDimitry Andric     if (!isInt<21>(Value)) {
2100b57cec5SDimitry Andric       Ctx.reportError(Fixup.getLoc(), "out of range PC21 fixup");
2110b57cec5SDimitry Andric       return 0;
2120b57cec5SDimitry Andric     }
2130b57cec5SDimitry Andric     break;
2140b57cec5SDimitry Andric   }
2150b57cec5SDimitry Andric 
2160b57cec5SDimitry Andric   return Value;
2170b57cec5SDimitry Andric }
2180b57cec5SDimitry Andric 
2190b57cec5SDimitry Andric std::unique_ptr<MCObjectTargetWriter>
2200b57cec5SDimitry Andric MipsAsmBackend::createObjectTargetWriter() const {
2210b57cec5SDimitry Andric   return createMipsELFObjectWriter(TheTriple, IsN32);
2220b57cec5SDimitry Andric }
2230b57cec5SDimitry Andric 
2240b57cec5SDimitry Andric // Little-endian fixup data byte ordering:
2250b57cec5SDimitry Andric //   mips32r2:   a | b | x | x
2260b57cec5SDimitry Andric //   microMIPS:  x | x | a | b
2270b57cec5SDimitry Andric 
2280b57cec5SDimitry Andric static bool needsMMLEByteOrder(unsigned Kind) {
2290b57cec5SDimitry Andric   return Kind != Mips::fixup_MICROMIPS_PC10_S1 &&
2300b57cec5SDimitry Andric          Kind >= Mips::fixup_MICROMIPS_26_S1 &&
2310b57cec5SDimitry Andric          Kind < Mips::LastTargetFixupKind;
2320b57cec5SDimitry Andric }
2330b57cec5SDimitry Andric 
2340b57cec5SDimitry Andric // Calculate index for microMIPS specific little endian byte order
2350b57cec5SDimitry Andric static unsigned calculateMMLEIndex(unsigned i) {
2360b57cec5SDimitry Andric   assert(i <= 3 && "Index out of range!");
2370b57cec5SDimitry Andric 
2380b57cec5SDimitry Andric   return (1 - i / 2) * 2 + i % 2;
2390b57cec5SDimitry Andric }
2400b57cec5SDimitry Andric 
2410b57cec5SDimitry Andric /// ApplyFixup - Apply the \p Value for given \p Fixup into the provided
2420b57cec5SDimitry Andric /// data fragment, at the offset specified by the fixup and following the
2430b57cec5SDimitry Andric /// fixup kind as appropriate.
2440b57cec5SDimitry Andric void MipsAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
2450b57cec5SDimitry Andric                                 const MCValue &Target,
2460b57cec5SDimitry Andric                                 MutableArrayRef<char> Data, uint64_t Value,
2470b57cec5SDimitry Andric                                 bool IsResolved,
2480b57cec5SDimitry Andric                                 const MCSubtargetInfo *STI) const {
2490b57cec5SDimitry Andric   MCFixupKind Kind = Fixup.getKind();
2500b57cec5SDimitry Andric   MCContext &Ctx = Asm.getContext();
2510b57cec5SDimitry Andric   Value = adjustFixupValue(Fixup, Value, Ctx);
2520b57cec5SDimitry Andric 
2530b57cec5SDimitry Andric   if (!Value)
2540b57cec5SDimitry Andric     return; // Doesn't change encoding.
2550b57cec5SDimitry Andric 
2560b57cec5SDimitry Andric   // Where do we start in the object
2570b57cec5SDimitry Andric   unsigned Offset = Fixup.getOffset();
2580b57cec5SDimitry Andric   // Number of bytes we need to fixup
2590b57cec5SDimitry Andric   unsigned NumBytes = (getFixupKindInfo(Kind).TargetSize + 7) / 8;
2600b57cec5SDimitry Andric   // Used to point to big endian bytes
2610b57cec5SDimitry Andric   unsigned FullSize;
2620b57cec5SDimitry Andric 
2630b57cec5SDimitry Andric   switch ((unsigned)Kind) {
2640b57cec5SDimitry Andric   case FK_Data_2:
2650b57cec5SDimitry Andric   case Mips::fixup_Mips_16:
2660b57cec5SDimitry Andric   case Mips::fixup_MICROMIPS_PC10_S1:
2670b57cec5SDimitry Andric     FullSize = 2;
2680b57cec5SDimitry Andric     break;
2690b57cec5SDimitry Andric   case FK_Data_8:
2700b57cec5SDimitry Andric   case Mips::fixup_Mips_64:
2710b57cec5SDimitry Andric     FullSize = 8;
2720b57cec5SDimitry Andric     break;
2730b57cec5SDimitry Andric   case FK_Data_4:
2740b57cec5SDimitry Andric   default:
2750b57cec5SDimitry Andric     FullSize = 4;
2760b57cec5SDimitry Andric     break;
2770b57cec5SDimitry Andric   }
2780b57cec5SDimitry Andric 
2790b57cec5SDimitry Andric   // Grab current value, if any, from bits.
2800b57cec5SDimitry Andric   uint64_t CurVal = 0;
2810b57cec5SDimitry Andric 
2820b57cec5SDimitry Andric   bool microMipsLEByteOrder = needsMMLEByteOrder((unsigned) Kind);
2830b57cec5SDimitry Andric 
2840b57cec5SDimitry Andric   for (unsigned i = 0; i != NumBytes; ++i) {
2855f757f3fSDimitry Andric     unsigned Idx = Endian == llvm::endianness::little
2860b57cec5SDimitry Andric                        ? (microMipsLEByteOrder ? calculateMMLEIndex(i) : i)
2870b57cec5SDimitry Andric                        : (FullSize - 1 - i);
2880b57cec5SDimitry Andric     CurVal |= (uint64_t)((uint8_t)Data[Offset + Idx]) << (i*8);
2890b57cec5SDimitry Andric   }
2900b57cec5SDimitry Andric 
2910b57cec5SDimitry Andric   uint64_t Mask = ((uint64_t)(-1) >>
2920b57cec5SDimitry Andric                     (64 - getFixupKindInfo(Kind).TargetSize));
2930b57cec5SDimitry Andric   CurVal |= Value & Mask;
2940b57cec5SDimitry Andric 
2950b57cec5SDimitry Andric   // Write out the fixed up bytes back to the code/data bits.
2960b57cec5SDimitry Andric   for (unsigned i = 0; i != NumBytes; ++i) {
2975f757f3fSDimitry Andric     unsigned Idx = Endian == llvm::endianness::little
2980b57cec5SDimitry Andric                        ? (microMipsLEByteOrder ? calculateMMLEIndex(i) : i)
2990b57cec5SDimitry Andric                        : (FullSize - 1 - i);
3000b57cec5SDimitry Andric     Data[Offset + Idx] = (uint8_t)((CurVal >> (i*8)) & 0xff);
3010b57cec5SDimitry Andric   }
3020b57cec5SDimitry Andric }
3030b57cec5SDimitry Andric 
304bdd1243dSDimitry Andric std::optional<MCFixupKind> MipsAsmBackend::getFixupKind(StringRef Name) const {
30581ad6265SDimitry Andric   unsigned Type = llvm::StringSwitch<unsigned>(Name)
30681ad6265SDimitry Andric                       .Case("BFD_RELOC_NONE", ELF::R_MIPS_NONE)
30781ad6265SDimitry Andric                       .Case("BFD_RELOC_16", ELF::R_MIPS_16)
30881ad6265SDimitry Andric                       .Case("BFD_RELOC_32", ELF::R_MIPS_32)
30981ad6265SDimitry Andric                       .Case("BFD_RELOC_64", ELF::R_MIPS_64)
31081ad6265SDimitry Andric                       .Default(-1u);
31181ad6265SDimitry Andric   if (Type != -1u)
31281ad6265SDimitry Andric     return static_cast<MCFixupKind>(FirstLiteralRelocationKind + Type);
31381ad6265SDimitry Andric 
314bdd1243dSDimitry Andric   return StringSwitch<std::optional<MCFixupKind>>(Name)
3150b57cec5SDimitry Andric       .Case("R_MIPS_NONE", FK_NONE)
3160b57cec5SDimitry Andric       .Case("R_MIPS_32", FK_Data_4)
3170b57cec5SDimitry Andric       .Case("R_MIPS_CALL_HI16", (MCFixupKind)Mips::fixup_Mips_CALL_HI16)
3180b57cec5SDimitry Andric       .Case("R_MIPS_CALL_LO16", (MCFixupKind)Mips::fixup_Mips_CALL_LO16)
3190b57cec5SDimitry Andric       .Case("R_MIPS_CALL16", (MCFixupKind)Mips::fixup_Mips_CALL16)
3200b57cec5SDimitry Andric       .Case("R_MIPS_GOT16", (MCFixupKind)Mips::fixup_Mips_GOT)
3210b57cec5SDimitry Andric       .Case("R_MIPS_GOT_PAGE", (MCFixupKind)Mips::fixup_Mips_GOT_PAGE)
3220b57cec5SDimitry Andric       .Case("R_MIPS_GOT_OFST", (MCFixupKind)Mips::fixup_Mips_GOT_OFST)
3230b57cec5SDimitry Andric       .Case("R_MIPS_GOT_DISP", (MCFixupKind)Mips::fixup_Mips_GOT_DISP)
3240b57cec5SDimitry Andric       .Case("R_MIPS_GOT_HI16", (MCFixupKind)Mips::fixup_Mips_GOT_HI16)
3250b57cec5SDimitry Andric       .Case("R_MIPS_GOT_LO16", (MCFixupKind)Mips::fixup_Mips_GOT_LO16)
3260b57cec5SDimitry Andric       .Case("R_MIPS_TLS_GOTTPREL", (MCFixupKind)Mips::fixup_Mips_GOTTPREL)
3270b57cec5SDimitry Andric       .Case("R_MIPS_TLS_DTPREL_HI16", (MCFixupKind)Mips::fixup_Mips_DTPREL_HI)
3280b57cec5SDimitry Andric       .Case("R_MIPS_TLS_DTPREL_LO16", (MCFixupKind)Mips::fixup_Mips_DTPREL_LO)
3290b57cec5SDimitry Andric       .Case("R_MIPS_TLS_GD", (MCFixupKind)Mips::fixup_Mips_TLSGD)
3300b57cec5SDimitry Andric       .Case("R_MIPS_TLS_LDM", (MCFixupKind)Mips::fixup_Mips_TLSLDM)
3310b57cec5SDimitry Andric       .Case("R_MIPS_TLS_TPREL_HI16", (MCFixupKind)Mips::fixup_Mips_TPREL_HI)
3320b57cec5SDimitry Andric       .Case("R_MIPS_TLS_TPREL_LO16", (MCFixupKind)Mips::fixup_Mips_TPREL_LO)
3330b57cec5SDimitry Andric       .Case("R_MICROMIPS_CALL16", (MCFixupKind)Mips::fixup_MICROMIPS_CALL16)
3340b57cec5SDimitry Andric       .Case("R_MICROMIPS_GOT_DISP", (MCFixupKind)Mips::fixup_MICROMIPS_GOT_DISP)
3350b57cec5SDimitry Andric       .Case("R_MICROMIPS_GOT_PAGE", (MCFixupKind)Mips::fixup_MICROMIPS_GOT_PAGE)
3360b57cec5SDimitry Andric       .Case("R_MICROMIPS_GOT_OFST", (MCFixupKind)Mips::fixup_MICROMIPS_GOT_OFST)
3370b57cec5SDimitry Andric       .Case("R_MICROMIPS_GOT16", (MCFixupKind)Mips::fixup_MICROMIPS_GOT16)
3380b57cec5SDimitry Andric       .Case("R_MICROMIPS_TLS_GOTTPREL",
3390b57cec5SDimitry Andric             (MCFixupKind)Mips::fixup_MICROMIPS_GOTTPREL)
3400b57cec5SDimitry Andric       .Case("R_MICROMIPS_TLS_DTPREL_HI16",
3410b57cec5SDimitry Andric             (MCFixupKind)Mips::fixup_MICROMIPS_TLS_DTPREL_HI16)
3420b57cec5SDimitry Andric       .Case("R_MICROMIPS_TLS_DTPREL_LO16",
3430b57cec5SDimitry Andric             (MCFixupKind)Mips::fixup_MICROMIPS_TLS_DTPREL_LO16)
3440b57cec5SDimitry Andric       .Case("R_MICROMIPS_TLS_GD", (MCFixupKind)Mips::fixup_MICROMIPS_TLS_GD)
3450b57cec5SDimitry Andric       .Case("R_MICROMIPS_TLS_LDM", (MCFixupKind)Mips::fixup_MICROMIPS_TLS_LDM)
3460b57cec5SDimitry Andric       .Case("R_MICROMIPS_TLS_TPREL_HI16",
3470b57cec5SDimitry Andric             (MCFixupKind)Mips::fixup_MICROMIPS_TLS_TPREL_HI16)
3480b57cec5SDimitry Andric       .Case("R_MICROMIPS_TLS_TPREL_LO16",
3490b57cec5SDimitry Andric             (MCFixupKind)Mips::fixup_MICROMIPS_TLS_TPREL_LO16)
3500b57cec5SDimitry Andric       .Case("R_MIPS_JALR", (MCFixupKind)Mips::fixup_Mips_JALR)
3510b57cec5SDimitry Andric       .Case("R_MICROMIPS_JALR", (MCFixupKind)Mips::fixup_MICROMIPS_JALR)
3520b57cec5SDimitry Andric       .Default(MCAsmBackend::getFixupKind(Name));
3530b57cec5SDimitry Andric }
3540b57cec5SDimitry Andric 
3550b57cec5SDimitry Andric const MCFixupKindInfo &MipsAsmBackend::
3560b57cec5SDimitry Andric getFixupKindInfo(MCFixupKind Kind) const {
3570b57cec5SDimitry Andric   const static MCFixupKindInfo LittleEndianInfos[] = {
3580b57cec5SDimitry Andric     // This table *must* be in same the order of fixup_* kinds in
3590b57cec5SDimitry Andric     // MipsFixupKinds.h.
3600b57cec5SDimitry Andric     //
3610b57cec5SDimitry Andric     // name                    offset  bits  flags
3620b57cec5SDimitry Andric     { "fixup_Mips_16",           0,     16,   0 },
3630b57cec5SDimitry Andric     { "fixup_Mips_32",           0,     32,   0 },
3640b57cec5SDimitry Andric     { "fixup_Mips_REL32",        0,     32,   0 },
3650b57cec5SDimitry Andric     { "fixup_Mips_26",           0,     26,   0 },
3660b57cec5SDimitry Andric     { "fixup_Mips_HI16",         0,     16,   0 },
3670b57cec5SDimitry Andric     { "fixup_Mips_LO16",         0,     16,   0 },
3680b57cec5SDimitry Andric     { "fixup_Mips_GPREL16",      0,     16,   0 },
3690b57cec5SDimitry Andric     { "fixup_Mips_LITERAL",      0,     16,   0 },
3700b57cec5SDimitry Andric     { "fixup_Mips_GOT",          0,     16,   0 },
3710b57cec5SDimitry Andric     { "fixup_Mips_PC16",         0,     16,  MCFixupKindInfo::FKF_IsPCRel },
3720b57cec5SDimitry Andric     { "fixup_Mips_CALL16",       0,     16,   0 },
3730b57cec5SDimitry Andric     { "fixup_Mips_GPREL32",      0,     32,   0 },
3740b57cec5SDimitry Andric     { "fixup_Mips_SHIFT5",       6,      5,   0 },
3750b57cec5SDimitry Andric     { "fixup_Mips_SHIFT6",       6,      5,   0 },
3760b57cec5SDimitry Andric     { "fixup_Mips_64",           0,     64,   0 },
3770b57cec5SDimitry Andric     { "fixup_Mips_TLSGD",        0,     16,   0 },
3780b57cec5SDimitry Andric     { "fixup_Mips_GOTTPREL",     0,     16,   0 },
3790b57cec5SDimitry Andric     { "fixup_Mips_TPREL_HI",     0,     16,   0 },
3800b57cec5SDimitry Andric     { "fixup_Mips_TPREL_LO",     0,     16,   0 },
3810b57cec5SDimitry Andric     { "fixup_Mips_TLSLDM",       0,     16,   0 },
3820b57cec5SDimitry Andric     { "fixup_Mips_DTPREL_HI",    0,     16,   0 },
3830b57cec5SDimitry Andric     { "fixup_Mips_DTPREL_LO",    0,     16,   0 },
3840b57cec5SDimitry Andric     { "fixup_Mips_Branch_PCRel", 0,     16,  MCFixupKindInfo::FKF_IsPCRel },
3850b57cec5SDimitry Andric     { "fixup_Mips_GPOFF_HI",     0,     16,   0 },
3860b57cec5SDimitry Andric     { "fixup_MICROMIPS_GPOFF_HI",0,     16,   0 },
3870b57cec5SDimitry Andric     { "fixup_Mips_GPOFF_LO",     0,     16,   0 },
3880b57cec5SDimitry Andric     { "fixup_MICROMIPS_GPOFF_LO",0,     16,   0 },
3890b57cec5SDimitry Andric     { "fixup_Mips_GOT_PAGE",     0,     16,   0 },
3900b57cec5SDimitry Andric     { "fixup_Mips_GOT_OFST",     0,     16,   0 },
3910b57cec5SDimitry Andric     { "fixup_Mips_GOT_DISP",     0,     16,   0 },
3920b57cec5SDimitry Andric     { "fixup_Mips_HIGHER",       0,     16,   0 },
3930b57cec5SDimitry Andric     { "fixup_MICROMIPS_HIGHER",  0,     16,   0 },
3940b57cec5SDimitry Andric     { "fixup_Mips_HIGHEST",      0,     16,   0 },
3950b57cec5SDimitry Andric     { "fixup_MICROMIPS_HIGHEST", 0,     16,   0 },
3960b57cec5SDimitry Andric     { "fixup_Mips_GOT_HI16",     0,     16,   0 },
3970b57cec5SDimitry Andric     { "fixup_Mips_GOT_LO16",     0,     16,   0 },
3980b57cec5SDimitry Andric     { "fixup_Mips_CALL_HI16",    0,     16,   0 },
3990b57cec5SDimitry Andric     { "fixup_Mips_CALL_LO16",    0,     16,   0 },
4000b57cec5SDimitry Andric     { "fixup_Mips_PC18_S3",      0,     18,  MCFixupKindInfo::FKF_IsPCRel },
4010b57cec5SDimitry Andric     { "fixup_MIPS_PC19_S2",      0,     19,  MCFixupKindInfo::FKF_IsPCRel },
4020b57cec5SDimitry Andric     { "fixup_MIPS_PC21_S2",      0,     21,  MCFixupKindInfo::FKF_IsPCRel },
4030b57cec5SDimitry Andric     { "fixup_MIPS_PC26_S2",      0,     26,  MCFixupKindInfo::FKF_IsPCRel },
4040b57cec5SDimitry Andric     { "fixup_MIPS_PCHI16",       0,     16,  MCFixupKindInfo::FKF_IsPCRel },
4050b57cec5SDimitry Andric     { "fixup_MIPS_PCLO16",       0,     16,  MCFixupKindInfo::FKF_IsPCRel },
4060b57cec5SDimitry Andric     { "fixup_MICROMIPS_26_S1",   0,     26,   0 },
4070b57cec5SDimitry Andric     { "fixup_MICROMIPS_HI16",    0,     16,   0 },
4080b57cec5SDimitry Andric     { "fixup_MICROMIPS_LO16",    0,     16,   0 },
4090b57cec5SDimitry Andric     { "fixup_MICROMIPS_GOT16",   0,     16,   0 },
4100b57cec5SDimitry Andric     { "fixup_MICROMIPS_PC7_S1",  0,      7,   MCFixupKindInfo::FKF_IsPCRel },
4110b57cec5SDimitry Andric     { "fixup_MICROMIPS_PC10_S1", 0,     10,   MCFixupKindInfo::FKF_IsPCRel },
4120b57cec5SDimitry Andric     { "fixup_MICROMIPS_PC16_S1", 0,     16,   MCFixupKindInfo::FKF_IsPCRel },
4130b57cec5SDimitry Andric     { "fixup_MICROMIPS_PC26_S1", 0,     26,   MCFixupKindInfo::FKF_IsPCRel },
4140b57cec5SDimitry Andric     { "fixup_MICROMIPS_PC19_S2", 0,     19,   MCFixupKindInfo::FKF_IsPCRel },
4150b57cec5SDimitry Andric     { "fixup_MICROMIPS_PC18_S3", 0,     18,   MCFixupKindInfo::FKF_IsPCRel },
4160b57cec5SDimitry Andric     { "fixup_MICROMIPS_PC21_S1", 0,     21,   MCFixupKindInfo::FKF_IsPCRel },
4170b57cec5SDimitry Andric     { "fixup_MICROMIPS_CALL16",  0,     16,   0 },
4180b57cec5SDimitry Andric     { "fixup_MICROMIPS_GOT_DISP",        0,     16,   0 },
4190b57cec5SDimitry Andric     { "fixup_MICROMIPS_GOT_PAGE",        0,     16,   0 },
4200b57cec5SDimitry Andric     { "fixup_MICROMIPS_GOT_OFST",        0,     16,   0 },
4210b57cec5SDimitry Andric     { "fixup_MICROMIPS_TLS_GD",          0,     16,   0 },
4220b57cec5SDimitry Andric     { "fixup_MICROMIPS_TLS_LDM",         0,     16,   0 },
4230b57cec5SDimitry Andric     { "fixup_MICROMIPS_TLS_DTPREL_HI16", 0,     16,   0 },
4240b57cec5SDimitry Andric     { "fixup_MICROMIPS_TLS_DTPREL_LO16", 0,     16,   0 },
4250b57cec5SDimitry Andric     { "fixup_MICROMIPS_GOTTPREL",        0,     16,   0 },
4260b57cec5SDimitry Andric     { "fixup_MICROMIPS_TLS_TPREL_HI16",  0,     16,   0 },
4270b57cec5SDimitry Andric     { "fixup_MICROMIPS_TLS_TPREL_LO16",  0,     16,   0 },
4280b57cec5SDimitry Andric     { "fixup_Mips_SUB",                  0,     64,   0 },
4290b57cec5SDimitry Andric     { "fixup_MICROMIPS_SUB",             0,     64,   0 },
4300b57cec5SDimitry Andric     { "fixup_Mips_JALR",                 0,     32,   0 },
4310b57cec5SDimitry Andric     { "fixup_MICROMIPS_JALR",            0,     32,   0 }
4320b57cec5SDimitry Andric   };
433bdd1243dSDimitry Andric   static_assert(std::size(LittleEndianInfos) == Mips::NumTargetFixupKinds,
4340b57cec5SDimitry Andric                 "Not all MIPS little endian fixup kinds added!");
4350b57cec5SDimitry Andric 
4360b57cec5SDimitry Andric   const static MCFixupKindInfo BigEndianInfos[] = {
4370b57cec5SDimitry Andric     // This table *must* be in same the order of fixup_* kinds in
4380b57cec5SDimitry Andric     // MipsFixupKinds.h.
4390b57cec5SDimitry Andric     //
4400b57cec5SDimitry Andric     // name                    offset  bits  flags
4410b57cec5SDimitry Andric     { "fixup_Mips_16",          16,     16,   0 },
4420b57cec5SDimitry Andric     { "fixup_Mips_32",           0,     32,   0 },
4430b57cec5SDimitry Andric     { "fixup_Mips_REL32",        0,     32,   0 },
4440b57cec5SDimitry Andric     { "fixup_Mips_26",           6,     26,   0 },
4450b57cec5SDimitry Andric     { "fixup_Mips_HI16",        16,     16,   0 },
4460b57cec5SDimitry Andric     { "fixup_Mips_LO16",        16,     16,   0 },
4470b57cec5SDimitry Andric     { "fixup_Mips_GPREL16",     16,     16,   0 },
4480b57cec5SDimitry Andric     { "fixup_Mips_LITERAL",     16,     16,   0 },
4490b57cec5SDimitry Andric     { "fixup_Mips_GOT",         16,     16,   0 },
4500b57cec5SDimitry Andric     { "fixup_Mips_PC16",        16,     16,  MCFixupKindInfo::FKF_IsPCRel },
4510b57cec5SDimitry Andric     { "fixup_Mips_CALL16",      16,     16,   0 },
4520b57cec5SDimitry Andric     { "fixup_Mips_GPREL32",      0,     32,   0 },
4530b57cec5SDimitry Andric     { "fixup_Mips_SHIFT5",      21,      5,   0 },
4540b57cec5SDimitry Andric     { "fixup_Mips_SHIFT6",      21,      5,   0 },
4550b57cec5SDimitry Andric     { "fixup_Mips_64",           0,     64,   0 },
4560b57cec5SDimitry Andric     { "fixup_Mips_TLSGD",       16,     16,   0 },
4570b57cec5SDimitry Andric     { "fixup_Mips_GOTTPREL",    16,     16,   0 },
4580b57cec5SDimitry Andric     { "fixup_Mips_TPREL_HI",    16,     16,   0 },
4590b57cec5SDimitry Andric     { "fixup_Mips_TPREL_LO",    16,     16,   0 },
4600b57cec5SDimitry Andric     { "fixup_Mips_TLSLDM",      16,     16,   0 },
4610b57cec5SDimitry Andric     { "fixup_Mips_DTPREL_HI",   16,     16,   0 },
4620b57cec5SDimitry Andric     { "fixup_Mips_DTPREL_LO",   16,     16,   0 },
4630b57cec5SDimitry Andric     { "fixup_Mips_Branch_PCRel",16,     16,  MCFixupKindInfo::FKF_IsPCRel },
4640b57cec5SDimitry Andric     { "fixup_Mips_GPOFF_HI",    16,     16,   0 },
4650b57cec5SDimitry Andric     { "fixup_MICROMIPS_GPOFF_HI", 16,     16,   0 },
4660b57cec5SDimitry Andric     { "fixup_Mips_GPOFF_LO",    16,     16,   0 },
4670b57cec5SDimitry Andric     { "fixup_MICROMIPS_GPOFF_LO", 16,     16,   0 },
4680b57cec5SDimitry Andric     { "fixup_Mips_GOT_PAGE",    16,     16,   0 },
4690b57cec5SDimitry Andric     { "fixup_Mips_GOT_OFST",    16,     16,   0 },
4700b57cec5SDimitry Andric     { "fixup_Mips_GOT_DISP",    16,     16,   0 },
4710b57cec5SDimitry Andric     { "fixup_Mips_HIGHER",      16,     16,   0 },
4720b57cec5SDimitry Andric     { "fixup_MICROMIPS_HIGHER", 16,     16,   0 },
4730b57cec5SDimitry Andric     { "fixup_Mips_HIGHEST",     16,     16,   0 },
4740b57cec5SDimitry Andric     { "fixup_MICROMIPS_HIGHEST",16,     16,   0 },
4750b57cec5SDimitry Andric     { "fixup_Mips_GOT_HI16",    16,     16,   0 },
4760b57cec5SDimitry Andric     { "fixup_Mips_GOT_LO16",    16,     16,   0 },
4770b57cec5SDimitry Andric     { "fixup_Mips_CALL_HI16",   16,     16,   0 },
4780b57cec5SDimitry Andric     { "fixup_Mips_CALL_LO16",   16,     16,   0 },
4790b57cec5SDimitry Andric     { "fixup_Mips_PC18_S3",     14,     18,  MCFixupKindInfo::FKF_IsPCRel },
4800b57cec5SDimitry Andric     { "fixup_MIPS_PC19_S2",     13,     19,  MCFixupKindInfo::FKF_IsPCRel },
4810b57cec5SDimitry Andric     { "fixup_MIPS_PC21_S2",     11,     21,  MCFixupKindInfo::FKF_IsPCRel },
4820b57cec5SDimitry Andric     { "fixup_MIPS_PC26_S2",      6,     26,  MCFixupKindInfo::FKF_IsPCRel },
4830b57cec5SDimitry Andric     { "fixup_MIPS_PCHI16",      16,     16,  MCFixupKindInfo::FKF_IsPCRel },
4840b57cec5SDimitry Andric     { "fixup_MIPS_PCLO16",      16,     16,  MCFixupKindInfo::FKF_IsPCRel },
4850b57cec5SDimitry Andric     { "fixup_MICROMIPS_26_S1",   6,     26,   0 },
4860b57cec5SDimitry Andric     { "fixup_MICROMIPS_HI16",   16,     16,   0 },
4870b57cec5SDimitry Andric     { "fixup_MICROMIPS_LO16",   16,     16,   0 },
4880b57cec5SDimitry Andric     { "fixup_MICROMIPS_GOT16",  16,     16,   0 },
4890b57cec5SDimitry Andric     { "fixup_MICROMIPS_PC7_S1",  9,      7,   MCFixupKindInfo::FKF_IsPCRel },
4900b57cec5SDimitry Andric     { "fixup_MICROMIPS_PC10_S1", 6,     10,   MCFixupKindInfo::FKF_IsPCRel },
4910b57cec5SDimitry Andric     { "fixup_MICROMIPS_PC16_S1",16,     16,   MCFixupKindInfo::FKF_IsPCRel },
4920b57cec5SDimitry Andric     { "fixup_MICROMIPS_PC26_S1", 6,     26,   MCFixupKindInfo::FKF_IsPCRel },
4930b57cec5SDimitry Andric     { "fixup_MICROMIPS_PC19_S2",13,     19,   MCFixupKindInfo::FKF_IsPCRel },
4940b57cec5SDimitry Andric     { "fixup_MICROMIPS_PC18_S3",14,     18,   MCFixupKindInfo::FKF_IsPCRel },
4950b57cec5SDimitry Andric     { "fixup_MICROMIPS_PC21_S1",11,     21,   MCFixupKindInfo::FKF_IsPCRel },
4960b57cec5SDimitry Andric     { "fixup_MICROMIPS_CALL16", 16,     16,   0 },
4970b57cec5SDimitry Andric     { "fixup_MICROMIPS_GOT_DISP",        16,     16,   0 },
4980b57cec5SDimitry Andric     { "fixup_MICROMIPS_GOT_PAGE",        16,     16,   0 },
4990b57cec5SDimitry Andric     { "fixup_MICROMIPS_GOT_OFST",        16,     16,   0 },
5000b57cec5SDimitry Andric     { "fixup_MICROMIPS_TLS_GD",          16,     16,   0 },
5010b57cec5SDimitry Andric     { "fixup_MICROMIPS_TLS_LDM",         16,     16,   0 },
5020b57cec5SDimitry Andric     { "fixup_MICROMIPS_TLS_DTPREL_HI16", 16,     16,   0 },
5030b57cec5SDimitry Andric     { "fixup_MICROMIPS_TLS_DTPREL_LO16", 16,     16,   0 },
5040b57cec5SDimitry Andric     { "fixup_MICROMIPS_GOTTPREL",        16,     16,   0 },
5050b57cec5SDimitry Andric     { "fixup_MICROMIPS_TLS_TPREL_HI16",  16,     16,   0 },
5060b57cec5SDimitry Andric     { "fixup_MICROMIPS_TLS_TPREL_LO16",  16,     16,   0 },
5070b57cec5SDimitry Andric     { "fixup_Mips_SUB",                   0,     64,   0 },
5080b57cec5SDimitry Andric     { "fixup_MICROMIPS_SUB",              0,     64,   0 },
5090b57cec5SDimitry Andric     { "fixup_Mips_JALR",                  0,     32,   0 },
5100b57cec5SDimitry Andric     { "fixup_MICROMIPS_JALR",             0,     32,   0 }
5110b57cec5SDimitry Andric   };
512bdd1243dSDimitry Andric   static_assert(std::size(BigEndianInfos) == Mips::NumTargetFixupKinds,
5130b57cec5SDimitry Andric                 "Not all MIPS big endian fixup kinds added!");
5140b57cec5SDimitry Andric 
51581ad6265SDimitry Andric   if (Kind >= FirstLiteralRelocationKind)
51681ad6265SDimitry Andric     return MCAsmBackend::getFixupKindInfo(FK_NONE);
5170b57cec5SDimitry Andric   if (Kind < FirstTargetFixupKind)
5180b57cec5SDimitry Andric     return MCAsmBackend::getFixupKindInfo(Kind);
5190b57cec5SDimitry Andric 
5200b57cec5SDimitry Andric   assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
5210b57cec5SDimitry Andric           "Invalid kind!");
5220b57cec5SDimitry Andric 
5235f757f3fSDimitry Andric   if (Endian == llvm::endianness::little)
5240b57cec5SDimitry Andric     return LittleEndianInfos[Kind - FirstTargetFixupKind];
5250b57cec5SDimitry Andric   return BigEndianInfos[Kind - FirstTargetFixupKind];
5260b57cec5SDimitry Andric }
5270b57cec5SDimitry Andric 
5280b57cec5SDimitry Andric /// WriteNopData - Write an (optimal) nop sequence of Count bytes
5290b57cec5SDimitry Andric /// to the given output. If the target cannot generate such a sequence,
5300b57cec5SDimitry Andric /// it should return an error.
5310b57cec5SDimitry Andric ///
5320b57cec5SDimitry Andric /// \return - True on success.
533349cc55cSDimitry Andric bool MipsAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count,
534349cc55cSDimitry Andric                                   const MCSubtargetInfo *STI) const {
5350b57cec5SDimitry Andric   // Check for a less than instruction size number of bytes
5360b57cec5SDimitry Andric   // FIXME: 16 bit instructions are not handled yet here.
5370b57cec5SDimitry Andric   // We shouldn't be using a hard coded number for instruction size.
5380b57cec5SDimitry Andric 
5390b57cec5SDimitry Andric   // If the count is not 4-byte aligned, we must be writing data into the text
5400b57cec5SDimitry Andric   // section (otherwise we have unaligned instructions, and thus have far
5410b57cec5SDimitry Andric   // bigger problems), so just write zeros instead.
5420b57cec5SDimitry Andric   OS.write_zeros(Count);
5430b57cec5SDimitry Andric   return true;
5440b57cec5SDimitry Andric }
5450b57cec5SDimitry Andric 
5460b57cec5SDimitry Andric bool MipsAsmBackend::shouldForceRelocation(const MCAssembler &Asm,
5470b57cec5SDimitry Andric                                            const MCFixup &Fixup,
5485f757f3fSDimitry Andric                                            const MCValue &Target,
5495f757f3fSDimitry Andric                                            const MCSubtargetInfo *STI) {
55081ad6265SDimitry Andric   if (Fixup.getKind() >= FirstLiteralRelocationKind)
55181ad6265SDimitry Andric     return true;
5520b57cec5SDimitry Andric   const unsigned FixupKind = Fixup.getKind();
5530b57cec5SDimitry Andric   switch (FixupKind) {
5540b57cec5SDimitry Andric   default:
5550b57cec5SDimitry Andric     return false;
5560b57cec5SDimitry Andric   // All these relocations require special processing
5570b57cec5SDimitry Andric   // at linking time. Delegate this work to a linker.
5580b57cec5SDimitry Andric   case Mips::fixup_Mips_CALL_HI16:
5590b57cec5SDimitry Andric   case Mips::fixup_Mips_CALL_LO16:
5600b57cec5SDimitry Andric   case Mips::fixup_Mips_CALL16:
5610b57cec5SDimitry Andric   case Mips::fixup_Mips_GOT:
5620b57cec5SDimitry Andric   case Mips::fixup_Mips_GOT_PAGE:
5630b57cec5SDimitry Andric   case Mips::fixup_Mips_GOT_OFST:
5640b57cec5SDimitry Andric   case Mips::fixup_Mips_GOT_DISP:
5650b57cec5SDimitry Andric   case Mips::fixup_Mips_GOT_HI16:
5660b57cec5SDimitry Andric   case Mips::fixup_Mips_GOT_LO16:
5670b57cec5SDimitry Andric   case Mips::fixup_Mips_GOTTPREL:
5680b57cec5SDimitry Andric   case Mips::fixup_Mips_DTPREL_HI:
5690b57cec5SDimitry Andric   case Mips::fixup_Mips_DTPREL_LO:
5700b57cec5SDimitry Andric   case Mips::fixup_Mips_TLSGD:
5710b57cec5SDimitry Andric   case Mips::fixup_Mips_TLSLDM:
5720b57cec5SDimitry Andric   case Mips::fixup_Mips_TPREL_HI:
5730b57cec5SDimitry Andric   case Mips::fixup_Mips_TPREL_LO:
5740b57cec5SDimitry Andric   case Mips::fixup_Mips_JALR:
5750b57cec5SDimitry Andric   case Mips::fixup_MICROMIPS_CALL16:
5760b57cec5SDimitry Andric   case Mips::fixup_MICROMIPS_GOT_DISP:
5770b57cec5SDimitry Andric   case Mips::fixup_MICROMIPS_GOT_PAGE:
5780b57cec5SDimitry Andric   case Mips::fixup_MICROMIPS_GOT_OFST:
5790b57cec5SDimitry Andric   case Mips::fixup_MICROMIPS_GOT16:
5800b57cec5SDimitry Andric   case Mips::fixup_MICROMIPS_GOTTPREL:
5810b57cec5SDimitry Andric   case Mips::fixup_MICROMIPS_TLS_DTPREL_HI16:
5820b57cec5SDimitry Andric   case Mips::fixup_MICROMIPS_TLS_DTPREL_LO16:
5830b57cec5SDimitry Andric   case Mips::fixup_MICROMIPS_TLS_GD:
5840b57cec5SDimitry Andric   case Mips::fixup_MICROMIPS_TLS_LDM:
5850b57cec5SDimitry Andric   case Mips::fixup_MICROMIPS_TLS_TPREL_HI16:
5860b57cec5SDimitry Andric   case Mips::fixup_MICROMIPS_TLS_TPREL_LO16:
5870b57cec5SDimitry Andric   case Mips::fixup_MICROMIPS_JALR:
5880b57cec5SDimitry Andric     return true;
5890b57cec5SDimitry Andric   }
5900b57cec5SDimitry Andric }
5910b57cec5SDimitry Andric 
5920b57cec5SDimitry Andric bool MipsAsmBackend::isMicroMips(const MCSymbol *Sym) const {
5930b57cec5SDimitry Andric   if (const auto *ElfSym = dyn_cast<const MCSymbolELF>(Sym)) {
5940b57cec5SDimitry Andric     if (ElfSym->getOther() & ELF::STO_MIPS_MICROMIPS)
5950b57cec5SDimitry Andric       return true;
5960b57cec5SDimitry Andric   }
5970b57cec5SDimitry Andric   return false;
5980b57cec5SDimitry Andric }
5990b57cec5SDimitry Andric 
6000b57cec5SDimitry Andric MCAsmBackend *llvm::createMipsAsmBackend(const Target &T,
6010b57cec5SDimitry Andric                                          const MCSubtargetInfo &STI,
6020b57cec5SDimitry Andric                                          const MCRegisterInfo &MRI,
6030b57cec5SDimitry Andric                                          const MCTargetOptions &Options) {
604480093f4SDimitry Andric   MipsABIInfo ABI = MipsABIInfo::computeTargetABI(STI.getTargetTriple(),
605480093f4SDimitry Andric                                                   STI.getCPU(), Options);
606480093f4SDimitry Andric   return new MipsAsmBackend(T, MRI, STI.getTargetTriple(), STI.getCPU(),
607480093f4SDimitry Andric                             ABI.IsN32());
6080b57cec5SDimitry Andric }
609