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