xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===-- SparcAsmBackend.cpp - Sparc Assembler 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 #include "MCTargetDesc/SparcFixupKinds.h"
100b57cec5SDimitry Andric #include "MCTargetDesc/SparcMCTargetDesc.h"
111fd87a68SDimitry Andric #include "llvm/ADT/StringSwitch.h"
120b57cec5SDimitry Andric #include "llvm/MC/MCAsmBackend.h"
130b57cec5SDimitry Andric #include "llvm/MC/MCELFObjectWriter.h"
140b57cec5SDimitry Andric #include "llvm/MC/MCExpr.h"
150b57cec5SDimitry Andric #include "llvm/MC/MCFixupKindInfo.h"
160b57cec5SDimitry Andric #include "llvm/MC/MCObjectWriter.h"
170b57cec5SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
180b57cec5SDimitry Andric #include "llvm/MC/MCValue.h"
19349cc55cSDimitry Andric #include "llvm/MC/TargetRegistry.h"
205ffd83dbSDimitry Andric #include "llvm/Support/EndianStream.h"
210b57cec5SDimitry Andric 
220b57cec5SDimitry Andric using namespace llvm;
230b57cec5SDimitry Andric 
240b57cec5SDimitry Andric static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) {
250b57cec5SDimitry Andric   switch (Kind) {
260b57cec5SDimitry Andric   default:
270b57cec5SDimitry Andric     llvm_unreachable("Unknown fixup kind!");
280b57cec5SDimitry Andric   case FK_Data_1:
290b57cec5SDimitry Andric   case FK_Data_2:
300b57cec5SDimitry Andric   case FK_Data_4:
310b57cec5SDimitry Andric   case FK_Data_8:
320b57cec5SDimitry Andric     return Value;
330b57cec5SDimitry Andric 
340b57cec5SDimitry Andric   case Sparc::fixup_sparc_wplt30:
350b57cec5SDimitry Andric   case Sparc::fixup_sparc_call30:
360b57cec5SDimitry Andric     return (Value >> 2) & 0x3fffffff;
370b57cec5SDimitry Andric 
380b57cec5SDimitry Andric   case Sparc::fixup_sparc_br22:
390b57cec5SDimitry Andric     return (Value >> 2) & 0x3fffff;
400b57cec5SDimitry Andric 
410b57cec5SDimitry Andric   case Sparc::fixup_sparc_br19:
420b57cec5SDimitry Andric     return (Value >> 2) & 0x7ffff;
430b57cec5SDimitry Andric 
4406c3fb27SDimitry Andric   case Sparc::fixup_sparc_br16: {
4506c3fb27SDimitry Andric     // A.3 Branch on Integer Register with Prediction (BPr)
4606c3fb27SDimitry Andric     // Inst{21-20} = d16hi;
4706c3fb27SDimitry Andric     // Inst{13-0}  = d16lo;
4806c3fb27SDimitry Andric     unsigned d16hi = (Value >> 16) & 0x3;
4906c3fb27SDimitry Andric     unsigned d16lo = (Value >> 2) & 0x3fff;
5006c3fb27SDimitry Andric     return (d16hi << 20) | d16lo;
5106c3fb27SDimitry Andric   }
520b57cec5SDimitry Andric 
5381ad6265SDimitry Andric   case Sparc::fixup_sparc_hix22:
5481ad6265SDimitry Andric     return (~Value >> 10) & 0x3fffff;
5581ad6265SDimitry Andric 
560b57cec5SDimitry Andric   case Sparc::fixup_sparc_pc22:
570b57cec5SDimitry Andric   case Sparc::fixup_sparc_got22:
580b57cec5SDimitry Andric   case Sparc::fixup_sparc_tls_gd_hi22:
590b57cec5SDimitry Andric   case Sparc::fixup_sparc_tls_ldm_hi22:
600b57cec5SDimitry Andric   case Sparc::fixup_sparc_tls_ie_hi22:
610b57cec5SDimitry Andric   case Sparc::fixup_sparc_hi22:
62fe6060f1SDimitry Andric   case Sparc::fixup_sparc_lm:
630b57cec5SDimitry Andric     return (Value >> 10) & 0x3fffff;
640b57cec5SDimitry Andric 
650b57cec5SDimitry Andric   case Sparc::fixup_sparc_got13:
660b57cec5SDimitry Andric   case Sparc::fixup_sparc_13:
670b57cec5SDimitry Andric     return Value & 0x1fff;
680b57cec5SDimitry Andric 
6981ad6265SDimitry Andric   case Sparc::fixup_sparc_lox10:
7081ad6265SDimitry Andric     return (Value & 0x3ff) | 0x1c00;
7181ad6265SDimitry Andric 
720b57cec5SDimitry Andric   case Sparc::fixup_sparc_pc10:
730b57cec5SDimitry Andric   case Sparc::fixup_sparc_got10:
740b57cec5SDimitry Andric   case Sparc::fixup_sparc_tls_gd_lo10:
750b57cec5SDimitry Andric   case Sparc::fixup_sparc_tls_ldm_lo10:
760b57cec5SDimitry Andric   case Sparc::fixup_sparc_tls_ie_lo10:
770b57cec5SDimitry Andric   case Sparc::fixup_sparc_lo10:
780b57cec5SDimitry Andric     return Value & 0x3ff;
790b57cec5SDimitry Andric 
800b57cec5SDimitry Andric   case Sparc::fixup_sparc_h44:
810b57cec5SDimitry Andric     return (Value >> 22) & 0x3fffff;
820b57cec5SDimitry Andric 
830b57cec5SDimitry Andric   case Sparc::fixup_sparc_m44:
840b57cec5SDimitry Andric     return (Value >> 12) & 0x3ff;
850b57cec5SDimitry Andric 
860b57cec5SDimitry Andric   case Sparc::fixup_sparc_l44:
870b57cec5SDimitry Andric     return Value & 0xfff;
880b57cec5SDimitry Andric 
890b57cec5SDimitry Andric   case Sparc::fixup_sparc_hh:
900b57cec5SDimitry Andric     return (Value >> 42) & 0x3fffff;
910b57cec5SDimitry Andric 
920b57cec5SDimitry Andric   case Sparc::fixup_sparc_hm:
930b57cec5SDimitry Andric     return (Value >> 32) & 0x3ff;
940b57cec5SDimitry Andric 
950b57cec5SDimitry Andric   case Sparc::fixup_sparc_tls_ldo_hix22:
960b57cec5SDimitry Andric   case Sparc::fixup_sparc_tls_le_hix22:
970b57cec5SDimitry Andric   case Sparc::fixup_sparc_tls_ldo_lox10:
980b57cec5SDimitry Andric   case Sparc::fixup_sparc_tls_le_lox10:
990b57cec5SDimitry Andric     assert(Value == 0 && "Sparc TLS relocs expect zero Value");
1000b57cec5SDimitry Andric     return 0;
1010b57cec5SDimitry Andric 
1020b57cec5SDimitry Andric   case Sparc::fixup_sparc_tls_gd_add:
1030b57cec5SDimitry Andric   case Sparc::fixup_sparc_tls_gd_call:
1040b57cec5SDimitry Andric   case Sparc::fixup_sparc_tls_ldm_add:
1050b57cec5SDimitry Andric   case Sparc::fixup_sparc_tls_ldm_call:
1060b57cec5SDimitry Andric   case Sparc::fixup_sparc_tls_ldo_add:
1070b57cec5SDimitry Andric   case Sparc::fixup_sparc_tls_ie_ld:
1080b57cec5SDimitry Andric   case Sparc::fixup_sparc_tls_ie_ldx:
1090b57cec5SDimitry Andric   case Sparc::fixup_sparc_tls_ie_add:
11081ad6265SDimitry Andric   case Sparc::fixup_sparc_gotdata_lox10:
11181ad6265SDimitry Andric   case Sparc::fixup_sparc_gotdata_hix22:
11281ad6265SDimitry Andric   case Sparc::fixup_sparc_gotdata_op:
1130b57cec5SDimitry Andric     return 0;
1140b57cec5SDimitry Andric   }
1150b57cec5SDimitry Andric }
1160b57cec5SDimitry Andric 
1170b57cec5SDimitry Andric /// getFixupKindNumBytes - The number of bytes the fixup may change.
1180b57cec5SDimitry Andric static unsigned getFixupKindNumBytes(unsigned Kind) {
1190b57cec5SDimitry Andric     switch (Kind) {
1200b57cec5SDimitry Andric   default:
1210b57cec5SDimitry Andric     return 4;
1220b57cec5SDimitry Andric   case FK_Data_1:
1230b57cec5SDimitry Andric     return 1;
1240b57cec5SDimitry Andric   case FK_Data_2:
1250b57cec5SDimitry Andric     return 2;
1260b57cec5SDimitry Andric   case FK_Data_8:
1270b57cec5SDimitry Andric     return 8;
1280b57cec5SDimitry Andric   }
1290b57cec5SDimitry Andric }
1300b57cec5SDimitry Andric 
1310b57cec5SDimitry Andric namespace {
1320b57cec5SDimitry Andric   class SparcAsmBackend : public MCAsmBackend {
1330b57cec5SDimitry Andric   protected:
1340b57cec5SDimitry Andric     bool Is64Bit;
135*0fca6ea1SDimitry Andric     bool HasV9;
1360b57cec5SDimitry Andric 
1370b57cec5SDimitry Andric   public:
138*0fca6ea1SDimitry Andric     SparcAsmBackend(const MCSubtargetInfo &STI)
139*0fca6ea1SDimitry Andric         : MCAsmBackend(STI.getTargetTriple().isLittleEndian()
1405f757f3fSDimitry Andric                            ? llvm::endianness::little
1415f757f3fSDimitry Andric                            : llvm::endianness::big),
142*0fca6ea1SDimitry Andric           Is64Bit(STI.getTargetTriple().isArch64Bit()),
143*0fca6ea1SDimitry Andric           HasV9(STI.hasFeature(Sparc::FeatureV9)) {}
1440b57cec5SDimitry Andric 
1450b57cec5SDimitry Andric     unsigned getNumFixupKinds() const override {
1460b57cec5SDimitry Andric       return Sparc::NumTargetFixupKinds;
1470b57cec5SDimitry Andric     }
1480b57cec5SDimitry Andric 
149bdd1243dSDimitry Andric     std::optional<MCFixupKind> getFixupKind(StringRef Name) const override {
1501fd87a68SDimitry Andric       unsigned Type;
1511fd87a68SDimitry Andric       Type = llvm::StringSwitch<unsigned>(Name)
1521fd87a68SDimitry Andric #define ELF_RELOC(X, Y) .Case(#X, Y)
1531fd87a68SDimitry Andric #include "llvm/BinaryFormat/ELFRelocs/Sparc.def"
1541fd87a68SDimitry Andric #undef ELF_RELOC
1551fd87a68SDimitry Andric                  .Case("BFD_RELOC_NONE", ELF::R_SPARC_NONE)
1561fd87a68SDimitry Andric                  .Case("BFD_RELOC_8", ELF::R_SPARC_8)
1571fd87a68SDimitry Andric                  .Case("BFD_RELOC_16", ELF::R_SPARC_16)
1581fd87a68SDimitry Andric                  .Case("BFD_RELOC_32", ELF::R_SPARC_32)
1591fd87a68SDimitry Andric                  .Case("BFD_RELOC_64", ELF::R_SPARC_64)
1601fd87a68SDimitry Andric                  .Default(-1u);
1611fd87a68SDimitry Andric       if (Type == -1u)
162bdd1243dSDimitry Andric         return std::nullopt;
1631fd87a68SDimitry Andric       return static_cast<MCFixupKind>(FirstLiteralRelocationKind + Type);
1641fd87a68SDimitry Andric     }
1651fd87a68SDimitry Andric 
1660b57cec5SDimitry Andric     const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override {
1670b57cec5SDimitry Andric       const static MCFixupKindInfo InfosBE[Sparc::NumTargetFixupKinds] = {
1680b57cec5SDimitry Andric         // name                    offset bits  flags
1690b57cec5SDimitry Andric         { "fixup_sparc_call30",     2,     30,  MCFixupKindInfo::FKF_IsPCRel },
1700b57cec5SDimitry Andric         { "fixup_sparc_br22",      10,     22,  MCFixupKindInfo::FKF_IsPCRel },
1710b57cec5SDimitry Andric         { "fixup_sparc_br19",      13,     19,  MCFixupKindInfo::FKF_IsPCRel },
17206c3fb27SDimitry Andric         { "fixup_sparc_br16",       0,     32,  MCFixupKindInfo::FKF_IsPCRel },
1730b57cec5SDimitry Andric         { "fixup_sparc_13",        19,     13,  0 },
1740b57cec5SDimitry Andric         { "fixup_sparc_hi22",      10,     22,  0 },
1750b57cec5SDimitry Andric         { "fixup_sparc_lo10",      22,     10,  0 },
1760b57cec5SDimitry Andric         { "fixup_sparc_h44",       10,     22,  0 },
1770b57cec5SDimitry Andric         { "fixup_sparc_m44",       22,     10,  0 },
1780b57cec5SDimitry Andric         { "fixup_sparc_l44",       20,     12,  0 },
1790b57cec5SDimitry Andric         { "fixup_sparc_hh",        10,     22,  0 },
1800b57cec5SDimitry Andric         { "fixup_sparc_hm",        22,     10,  0 },
181fe6060f1SDimitry Andric         { "fixup_sparc_lm",        10,     22,  0 },
1820b57cec5SDimitry Andric         { "fixup_sparc_pc22",      10,     22,  MCFixupKindInfo::FKF_IsPCRel },
1830b57cec5SDimitry Andric         { "fixup_sparc_pc10",      22,     10,  MCFixupKindInfo::FKF_IsPCRel },
1840b57cec5SDimitry Andric         { "fixup_sparc_got22",     10,     22,  0 },
1850b57cec5SDimitry Andric         { "fixup_sparc_got10",     22,     10,  0 },
1860b57cec5SDimitry Andric         { "fixup_sparc_got13",     19,     13,  0 },
1870b57cec5SDimitry Andric         { "fixup_sparc_wplt30",     2,     30,  MCFixupKindInfo::FKF_IsPCRel },
1880b57cec5SDimitry Andric         { "fixup_sparc_tls_gd_hi22",   10, 22,  0 },
1890b57cec5SDimitry Andric         { "fixup_sparc_tls_gd_lo10",   22, 10,  0 },
1900b57cec5SDimitry Andric         { "fixup_sparc_tls_gd_add",     0,  0,  0 },
1910b57cec5SDimitry Andric         { "fixup_sparc_tls_gd_call",    0,  0,  0 },
1920b57cec5SDimitry Andric         { "fixup_sparc_tls_ldm_hi22",  10, 22,  0 },
1930b57cec5SDimitry Andric         { "fixup_sparc_tls_ldm_lo10",  22, 10,  0 },
1940b57cec5SDimitry Andric         { "fixup_sparc_tls_ldm_add",    0,  0,  0 },
1950b57cec5SDimitry Andric         { "fixup_sparc_tls_ldm_call",   0,  0,  0 },
1960b57cec5SDimitry Andric         { "fixup_sparc_tls_ldo_hix22", 10, 22,  0 },
1970b57cec5SDimitry Andric         { "fixup_sparc_tls_ldo_lox10", 22, 10,  0 },
1980b57cec5SDimitry Andric         { "fixup_sparc_tls_ldo_add",    0,  0,  0 },
1990b57cec5SDimitry Andric         { "fixup_sparc_tls_ie_hi22",   10, 22,  0 },
2000b57cec5SDimitry Andric         { "fixup_sparc_tls_ie_lo10",   22, 10,  0 },
2010b57cec5SDimitry Andric         { "fixup_sparc_tls_ie_ld",      0,  0,  0 },
2020b57cec5SDimitry Andric         { "fixup_sparc_tls_ie_ldx",     0,  0,  0 },
2030b57cec5SDimitry Andric         { "fixup_sparc_tls_ie_add",     0,  0,  0 },
2040b57cec5SDimitry Andric         { "fixup_sparc_tls_le_hix22",   0,  0,  0 },
20581ad6265SDimitry Andric         { "fixup_sparc_tls_le_lox10",   0,  0,  0 },
20681ad6265SDimitry Andric         { "fixup_sparc_hix22",         10, 22,  0 },
20781ad6265SDimitry Andric         { "fixup_sparc_lox10",         19, 13,  0 },
20881ad6265SDimitry Andric         { "fixup_sparc_gotdata_hix22",  0,  0,  0 },
20981ad6265SDimitry Andric         { "fixup_sparc_gotdata_lox10",  0,  0,  0 },
21081ad6265SDimitry Andric         { "fixup_sparc_gotdata_op",     0,  0,  0 },
2110b57cec5SDimitry Andric       };
2120b57cec5SDimitry Andric 
2130b57cec5SDimitry Andric       const static MCFixupKindInfo InfosLE[Sparc::NumTargetFixupKinds] = {
2140b57cec5SDimitry Andric         // name                    offset bits  flags
2150b57cec5SDimitry Andric         { "fixup_sparc_call30",     0,     30,  MCFixupKindInfo::FKF_IsPCRel },
2160b57cec5SDimitry Andric         { "fixup_sparc_br22",       0,     22,  MCFixupKindInfo::FKF_IsPCRel },
2170b57cec5SDimitry Andric         { "fixup_sparc_br19",       0,     19,  MCFixupKindInfo::FKF_IsPCRel },
21806c3fb27SDimitry Andric         { "fixup_sparc_br16",      32,      0,  MCFixupKindInfo::FKF_IsPCRel },
2190b57cec5SDimitry Andric         { "fixup_sparc_13",         0,     13,  0 },
2200b57cec5SDimitry Andric         { "fixup_sparc_hi22",       0,     22,  0 },
2210b57cec5SDimitry Andric         { "fixup_sparc_lo10",       0,     10,  0 },
2220b57cec5SDimitry Andric         { "fixup_sparc_h44",        0,     22,  0 },
2230b57cec5SDimitry Andric         { "fixup_sparc_m44",        0,     10,  0 },
2240b57cec5SDimitry Andric         { "fixup_sparc_l44",        0,     12,  0 },
2250b57cec5SDimitry Andric         { "fixup_sparc_hh",         0,     22,  0 },
2260b57cec5SDimitry Andric         { "fixup_sparc_hm",         0,     10,  0 },
227fe6060f1SDimitry Andric         { "fixup_sparc_lm",         0,     22,  0 },
2280b57cec5SDimitry Andric         { "fixup_sparc_pc22",       0,     22,  MCFixupKindInfo::FKF_IsPCRel },
2290b57cec5SDimitry Andric         { "fixup_sparc_pc10",       0,     10,  MCFixupKindInfo::FKF_IsPCRel },
2300b57cec5SDimitry Andric         { "fixup_sparc_got22",      0,     22,  0 },
2310b57cec5SDimitry Andric         { "fixup_sparc_got10",      0,     10,  0 },
2320b57cec5SDimitry Andric         { "fixup_sparc_got13",      0,     13,  0 },
2330b57cec5SDimitry Andric         { "fixup_sparc_wplt30",      0,     30,  MCFixupKindInfo::FKF_IsPCRel },
2340b57cec5SDimitry Andric         { "fixup_sparc_tls_gd_hi22",    0, 22,  0 },
2350b57cec5SDimitry Andric         { "fixup_sparc_tls_gd_lo10",    0, 10,  0 },
2360b57cec5SDimitry Andric         { "fixup_sparc_tls_gd_add",     0,  0,  0 },
2370b57cec5SDimitry Andric         { "fixup_sparc_tls_gd_call",    0,  0,  0 },
2380b57cec5SDimitry Andric         { "fixup_sparc_tls_ldm_hi22",   0, 22,  0 },
2390b57cec5SDimitry Andric         { "fixup_sparc_tls_ldm_lo10",   0, 10,  0 },
2400b57cec5SDimitry Andric         { "fixup_sparc_tls_ldm_add",    0,  0,  0 },
2410b57cec5SDimitry Andric         { "fixup_sparc_tls_ldm_call",   0,  0,  0 },
2420b57cec5SDimitry Andric         { "fixup_sparc_tls_ldo_hix22",  0, 22,  0 },
2430b57cec5SDimitry Andric         { "fixup_sparc_tls_ldo_lox10",  0, 10,  0 },
2440b57cec5SDimitry Andric         { "fixup_sparc_tls_ldo_add",    0,  0,  0 },
2450b57cec5SDimitry Andric         { "fixup_sparc_tls_ie_hi22",    0, 22,  0 },
2460b57cec5SDimitry Andric         { "fixup_sparc_tls_ie_lo10",    0, 10,  0 },
2470b57cec5SDimitry Andric         { "fixup_sparc_tls_ie_ld",      0,  0,  0 },
2480b57cec5SDimitry Andric         { "fixup_sparc_tls_ie_ldx",     0,  0,  0 },
2490b57cec5SDimitry Andric         { "fixup_sparc_tls_ie_add",     0,  0,  0 },
2500b57cec5SDimitry Andric         { "fixup_sparc_tls_le_hix22",   0,  0,  0 },
25181ad6265SDimitry Andric         { "fixup_sparc_tls_le_lox10",   0,  0,  0 },
25281ad6265SDimitry Andric         { "fixup_sparc_hix22",          0, 22,  0 },
25381ad6265SDimitry Andric         { "fixup_sparc_lox10",          0, 13,  0 },
25481ad6265SDimitry Andric         { "fixup_sparc_gotdata_hix22",  0,  0,  0 },
25581ad6265SDimitry Andric         { "fixup_sparc_gotdata_lox10",  0,  0,  0 },
25681ad6265SDimitry Andric         { "fixup_sparc_gotdata_op",     0,  0,  0 },
2570b57cec5SDimitry Andric       };
2580b57cec5SDimitry Andric 
2591fd87a68SDimitry Andric       // Fixup kinds from .reloc directive are like R_SPARC_NONE. They do
2601fd87a68SDimitry Andric       // not require any extra processing.
2611fd87a68SDimitry Andric       if (Kind >= FirstLiteralRelocationKind)
2621fd87a68SDimitry Andric         return MCAsmBackend::getFixupKindInfo(FK_NONE);
2631fd87a68SDimitry Andric 
2640b57cec5SDimitry Andric       if (Kind < FirstTargetFixupKind)
2650b57cec5SDimitry Andric         return MCAsmBackend::getFixupKindInfo(Kind);
2660b57cec5SDimitry Andric 
2670b57cec5SDimitry Andric       assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
2680b57cec5SDimitry Andric              "Invalid kind!");
2695f757f3fSDimitry Andric       if (Endian == llvm::endianness::little)
2700b57cec5SDimitry Andric         return InfosLE[Kind - FirstTargetFixupKind];
2710b57cec5SDimitry Andric 
2720b57cec5SDimitry Andric       return InfosBE[Kind - FirstTargetFixupKind];
2730b57cec5SDimitry Andric     }
2740b57cec5SDimitry Andric 
2750b57cec5SDimitry Andric     bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
2765f757f3fSDimitry Andric                                const MCValue &Target,
2775f757f3fSDimitry Andric                                const MCSubtargetInfo *STI) override {
2781fd87a68SDimitry Andric       if (Fixup.getKind() >= FirstLiteralRelocationKind)
2791fd87a68SDimitry Andric         return true;
2800b57cec5SDimitry Andric       switch ((Sparc::Fixups)Fixup.getKind()) {
2810b57cec5SDimitry Andric       default:
2820b57cec5SDimitry Andric         return false;
2830b57cec5SDimitry Andric       case Sparc::fixup_sparc_wplt30:
2840b57cec5SDimitry Andric         if (Target.getSymA()->getSymbol().isTemporary())
2850b57cec5SDimitry Andric           return false;
286bdd1243dSDimitry Andric         [[fallthrough]];
2870b57cec5SDimitry Andric       case Sparc::fixup_sparc_tls_gd_hi22:
2880b57cec5SDimitry Andric       case Sparc::fixup_sparc_tls_gd_lo10:
2890b57cec5SDimitry Andric       case Sparc::fixup_sparc_tls_gd_add:
2900b57cec5SDimitry Andric       case Sparc::fixup_sparc_tls_gd_call:
2910b57cec5SDimitry Andric       case Sparc::fixup_sparc_tls_ldm_hi22:
2920b57cec5SDimitry Andric       case Sparc::fixup_sparc_tls_ldm_lo10:
2930b57cec5SDimitry Andric       case Sparc::fixup_sparc_tls_ldm_add:
2940b57cec5SDimitry Andric       case Sparc::fixup_sparc_tls_ldm_call:
2950b57cec5SDimitry Andric       case Sparc::fixup_sparc_tls_ldo_hix22:
2960b57cec5SDimitry Andric       case Sparc::fixup_sparc_tls_ldo_lox10:
2970b57cec5SDimitry Andric       case Sparc::fixup_sparc_tls_ldo_add:
2980b57cec5SDimitry Andric       case Sparc::fixup_sparc_tls_ie_hi22:
2990b57cec5SDimitry Andric       case Sparc::fixup_sparc_tls_ie_lo10:
3000b57cec5SDimitry Andric       case Sparc::fixup_sparc_tls_ie_ld:
3010b57cec5SDimitry Andric       case Sparc::fixup_sparc_tls_ie_ldx:
3020b57cec5SDimitry Andric       case Sparc::fixup_sparc_tls_ie_add:
3030b57cec5SDimitry Andric       case Sparc::fixup_sparc_tls_le_hix22:
3040b57cec5SDimitry Andric       case Sparc::fixup_sparc_tls_le_lox10:
3050b57cec5SDimitry Andric         return true;
3060b57cec5SDimitry Andric       }
3070b57cec5SDimitry Andric     }
3080b57cec5SDimitry Andric 
3095ffd83dbSDimitry Andric     void relaxInstruction(MCInst &Inst,
3105ffd83dbSDimitry Andric                           const MCSubtargetInfo &STI) const override {
3110b57cec5SDimitry Andric       // FIXME.
3120b57cec5SDimitry Andric       llvm_unreachable("relaxInstruction() unimplemented");
3130b57cec5SDimitry Andric     }
3140b57cec5SDimitry Andric 
315349cc55cSDimitry Andric     bool writeNopData(raw_ostream &OS, uint64_t Count,
316349cc55cSDimitry Andric                       const MCSubtargetInfo *STI) const override {
317*0fca6ea1SDimitry Andric 
318*0fca6ea1SDimitry Andric       // If the count is not 4-byte aligned, we must be writing data into the
319*0fca6ea1SDimitry Andric       // text section (otherwise we have unaligned instructions, and thus have
320*0fca6ea1SDimitry Andric       // far bigger problems), so just write zeros instead.
321*0fca6ea1SDimitry Andric       OS.write_zeros(Count % 4);
3220b57cec5SDimitry Andric 
3230b57cec5SDimitry Andric       uint64_t NumNops = Count / 4;
3240b57cec5SDimitry Andric       for (uint64_t i = 0; i != NumNops; ++i)
3250b57cec5SDimitry Andric         support::endian::write<uint32_t>(OS, 0x01000000, Endian);
3260b57cec5SDimitry Andric 
3270b57cec5SDimitry Andric       return true;
3280b57cec5SDimitry Andric     }
3290b57cec5SDimitry Andric   };
3300b57cec5SDimitry Andric 
3310b57cec5SDimitry Andric   class ELFSparcAsmBackend : public SparcAsmBackend {
3320b57cec5SDimitry Andric     Triple::OSType OSType;
3330b57cec5SDimitry Andric   public:
334*0fca6ea1SDimitry Andric     ELFSparcAsmBackend(const MCSubtargetInfo &STI, Triple::OSType OSType)
335*0fca6ea1SDimitry Andric         : SparcAsmBackend(STI), OSType(OSType) {}
3360b57cec5SDimitry Andric 
3370b57cec5SDimitry Andric     void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
3380b57cec5SDimitry Andric                     const MCValue &Target, MutableArrayRef<char> Data,
3390b57cec5SDimitry Andric                     uint64_t Value, bool IsResolved,
3400b57cec5SDimitry Andric                     const MCSubtargetInfo *STI) const override {
3410b57cec5SDimitry Andric 
3421fd87a68SDimitry Andric       if (Fixup.getKind() >= FirstLiteralRelocationKind)
3431fd87a68SDimitry Andric         return;
3440b57cec5SDimitry Andric       Value = adjustFixupValue(Fixup.getKind(), Value);
3450b57cec5SDimitry Andric       if (!Value) return;           // Doesn't change encoding.
3460b57cec5SDimitry Andric 
3470b57cec5SDimitry Andric       unsigned NumBytes = getFixupKindNumBytes(Fixup.getKind());
3480b57cec5SDimitry Andric       unsigned Offset = Fixup.getOffset();
3490b57cec5SDimitry Andric       // For each byte of the fragment that the fixup touches, mask in the bits
3500b57cec5SDimitry Andric       // from the fixup value. The Value has been "split up" into the
3510b57cec5SDimitry Andric       // appropriate bitfields above.
3520b57cec5SDimitry Andric       for (unsigned i = 0; i != NumBytes; ++i) {
3535f757f3fSDimitry Andric         unsigned Idx =
3545f757f3fSDimitry Andric             Endian == llvm::endianness::little ? i : (NumBytes - 1) - i;
3550b57cec5SDimitry Andric         Data[Offset + Idx] |= uint8_t((Value >> (i * 8)) & 0xff);
3560b57cec5SDimitry Andric       }
3570b57cec5SDimitry Andric     }
3580b57cec5SDimitry Andric 
3590b57cec5SDimitry Andric     std::unique_ptr<MCObjectTargetWriter>
3600b57cec5SDimitry Andric     createObjectTargetWriter() const override {
3610b57cec5SDimitry Andric       uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(OSType);
362*0fca6ea1SDimitry Andric       return createSparcELFObjectWriter(Is64Bit, HasV9, OSABI);
3630b57cec5SDimitry Andric     }
3640b57cec5SDimitry Andric   };
3650b57cec5SDimitry Andric 
3660b57cec5SDimitry Andric } // end anonymous namespace
3670b57cec5SDimitry Andric 
3680b57cec5SDimitry Andric MCAsmBackend *llvm::createSparcAsmBackend(const Target &T,
3690b57cec5SDimitry Andric                                           const MCSubtargetInfo &STI,
3700b57cec5SDimitry Andric                                           const MCRegisterInfo &MRI,
3710b57cec5SDimitry Andric                                           const MCTargetOptions &Options) {
372*0fca6ea1SDimitry Andric   return new ELFSparcAsmBackend(STI, STI.getTargetTriple().getOS());
3730b57cec5SDimitry Andric }
374