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
adjustFixupValue(unsigned Kind,uint64_t Value)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.
getFixupKindNumBytes(unsigned Kind)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:
SparcAsmBackend(const MCSubtargetInfo & STI)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
getNumFixupKinds() const1450b57cec5SDimitry Andric unsigned getNumFixupKinds() const override {
1460b57cec5SDimitry Andric return Sparc::NumTargetFixupKinds;
1470b57cec5SDimitry Andric }
1480b57cec5SDimitry Andric
getFixupKind(StringRef Name) const149bdd1243dSDimitry 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
getFixupKindInfo(MCFixupKind Kind) const1660b57cec5SDimitry 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
shouldForceRelocation(const MCAssembler & Asm,const MCFixup & Fixup,const MCValue & Target,const MCSubtargetInfo * STI)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
relaxInstruction(MCInst & Inst,const MCSubtargetInfo & STI) const3095ffd83dbSDimitry 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
writeNopData(raw_ostream & OS,uint64_t Count,const MCSubtargetInfo * STI) const315349cc55cSDimitry 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:
ELFSparcAsmBackend(const MCSubtargetInfo & STI,Triple::OSType OSType)334*0fca6ea1SDimitry Andric ELFSparcAsmBackend(const MCSubtargetInfo &STI, Triple::OSType OSType)
335*0fca6ea1SDimitry Andric : SparcAsmBackend(STI), OSType(OSType) {}
3360b57cec5SDimitry Andric
applyFixup(const MCAssembler & Asm,const MCFixup & Fixup,const MCValue & Target,MutableArrayRef<char> Data,uint64_t Value,bool IsResolved,const MCSubtargetInfo * STI) const3370b57cec5SDimitry 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>
createObjectTargetWriter() const3600b57cec5SDimitry 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
createSparcAsmBackend(const Target & T,const MCSubtargetInfo & STI,const MCRegisterInfo & MRI,const MCTargetOptions & Options)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