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