10b57cec5SDimitry Andric //===-- HexagonAsmBackend.cpp - Hexagon 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 "HexagonFixupKinds.h"
100b57cec5SDimitry Andric #include "MCTargetDesc/HexagonBaseInfo.h"
110b57cec5SDimitry Andric #include "MCTargetDesc/HexagonMCChecker.h"
120b57cec5SDimitry Andric #include "MCTargetDesc/HexagonMCCodeEmitter.h"
130b57cec5SDimitry Andric #include "MCTargetDesc/HexagonMCInstrInfo.h"
140b57cec5SDimitry Andric #include "MCTargetDesc/HexagonMCShuffler.h"
150b57cec5SDimitry Andric #include "MCTargetDesc/HexagonMCTargetDesc.h"
160b57cec5SDimitry Andric #include "llvm/MC/MCAsmBackend.h"
170b57cec5SDimitry Andric #include "llvm/MC/MCAssembler.h"
180b57cec5SDimitry Andric #include "llvm/MC/MCContext.h"
190b57cec5SDimitry Andric #include "llvm/MC/MCELFObjectWriter.h"
200b57cec5SDimitry Andric #include "llvm/MC/MCFixupKindInfo.h"
210b57cec5SDimitry Andric #include "llvm/MC/MCInstrInfo.h"
220b57cec5SDimitry Andric #include "llvm/MC/MCObjectWriter.h"
2381ad6265SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
24349cc55cSDimitry Andric #include "llvm/MC/TargetRegistry.h"
250b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
265ffd83dbSDimitry Andric #include "llvm/Support/EndianStream.h"
270b57cec5SDimitry Andric
280b57cec5SDimitry Andric #include <sstream>
290b57cec5SDimitry Andric
300b57cec5SDimitry Andric using namespace llvm;
310b57cec5SDimitry Andric using namespace Hexagon;
320b57cec5SDimitry Andric
330b57cec5SDimitry Andric #define DEBUG_TYPE "hexagon-asm-backend"
340b57cec5SDimitry Andric
350b57cec5SDimitry Andric static cl::opt<bool> DisableFixup
360b57cec5SDimitry Andric ("mno-fixup", cl::desc("Disable fixing up resolved relocations for Hexagon"));
370b57cec5SDimitry Andric
380b57cec5SDimitry Andric namespace {
390b57cec5SDimitry Andric
400b57cec5SDimitry Andric class HexagonAsmBackend : public MCAsmBackend {
410b57cec5SDimitry Andric uint8_t OSABI;
420b57cec5SDimitry Andric StringRef CPU;
430b57cec5SDimitry Andric mutable uint64_t relaxedCnt;
440b57cec5SDimitry Andric std::unique_ptr <MCInstrInfo> MCII;
450b57cec5SDimitry Andric std::unique_ptr <MCInst *> RelaxTarget;
460b57cec5SDimitry Andric MCInst * Extender;
475ffd83dbSDimitry Andric unsigned MaxPacketSize;
480b57cec5SDimitry Andric
ReplaceInstruction(MCCodeEmitter & E,MCRelaxableFragment & RF,MCInst & HMB) const490b57cec5SDimitry Andric void ReplaceInstruction(MCCodeEmitter &E, MCRelaxableFragment &RF,
500b57cec5SDimitry Andric MCInst &HMB) const {
510b57cec5SDimitry Andric SmallVector<MCFixup, 4> Fixups;
520b57cec5SDimitry Andric SmallString<256> Code;
5306c3fb27SDimitry Andric E.encodeInstruction(HMB, Code, Fixups, *RF.getSubtargetInfo());
540b57cec5SDimitry Andric
550b57cec5SDimitry Andric // Update the fragment.
560b57cec5SDimitry Andric RF.setInst(HMB);
570b57cec5SDimitry Andric RF.getContents() = Code;
580b57cec5SDimitry Andric RF.getFixups() = Fixups;
590b57cec5SDimitry Andric }
600b57cec5SDimitry Andric
610b57cec5SDimitry Andric public:
HexagonAsmBackend(const Target & T,const Triple & TT,uint8_t OSABI,StringRef CPU)620b57cec5SDimitry Andric HexagonAsmBackend(const Target &T, const Triple &TT, uint8_t OSABI,
630b57cec5SDimitry Andric StringRef CPU)
645f757f3fSDimitry Andric : MCAsmBackend(llvm::endianness::little), OSABI(OSABI), CPU(CPU),
655f757f3fSDimitry Andric relaxedCnt(0), MCII(T.createMCInstrInfo()), RelaxTarget(new MCInst *),
665f757f3fSDimitry Andric Extender(nullptr), MaxPacketSize(HexagonMCInstrInfo::packetSize(CPU)) {}
670b57cec5SDimitry Andric
680b57cec5SDimitry Andric std::unique_ptr<MCObjectTargetWriter>
createObjectTargetWriter() const690b57cec5SDimitry Andric createObjectTargetWriter() const override {
700b57cec5SDimitry Andric return createHexagonELFObjectWriter(OSABI, CPU);
710b57cec5SDimitry Andric }
720b57cec5SDimitry Andric
setExtender(MCContext & Context) const730b57cec5SDimitry Andric void setExtender(MCContext &Context) const {
740b57cec5SDimitry Andric if (Extender == nullptr)
75e8d8bef9SDimitry Andric const_cast<HexagonAsmBackend *>(this)->Extender = Context.createMCInst();
760b57cec5SDimitry Andric }
770b57cec5SDimitry Andric
takeExtender() const780b57cec5SDimitry Andric MCInst *takeExtender() const {
790b57cec5SDimitry Andric assert(Extender != nullptr);
800b57cec5SDimitry Andric MCInst * Result = Extender;
810b57cec5SDimitry Andric const_cast<HexagonAsmBackend *>(this)->Extender = nullptr;
820b57cec5SDimitry Andric return Result;
830b57cec5SDimitry Andric }
840b57cec5SDimitry Andric
getNumFixupKinds() const850b57cec5SDimitry Andric unsigned getNumFixupKinds() const override {
860b57cec5SDimitry Andric return Hexagon::NumTargetFixupKinds;
870b57cec5SDimitry Andric }
880b57cec5SDimitry Andric
getFixupKindInfo(MCFixupKind Kind) const890b57cec5SDimitry Andric const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override {
900b57cec5SDimitry Andric const static MCFixupKindInfo Infos[Hexagon::NumTargetFixupKinds] = {
910b57cec5SDimitry Andric // This table *must* be in same the order of fixup_* kinds in
920b57cec5SDimitry Andric // HexagonFixupKinds.h.
930b57cec5SDimitry Andric //
940b57cec5SDimitry Andric // namei offset bits flags
950b57cec5SDimitry Andric { "fixup_Hexagon_B22_PCREL", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
960b57cec5SDimitry Andric { "fixup_Hexagon_B15_PCREL", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
970b57cec5SDimitry Andric { "fixup_Hexagon_B7_PCREL", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
980b57cec5SDimitry Andric { "fixup_Hexagon_LO16", 0, 32, 0 },
990b57cec5SDimitry Andric { "fixup_Hexagon_HI16", 0, 32, 0 },
1000b57cec5SDimitry Andric { "fixup_Hexagon_32", 0, 32, 0 },
1010b57cec5SDimitry Andric { "fixup_Hexagon_16", 0, 32, 0 },
1020b57cec5SDimitry Andric { "fixup_Hexagon_8", 0, 32, 0 },
1030b57cec5SDimitry Andric { "fixup_Hexagon_GPREL16_0", 0, 32, 0 },
1040b57cec5SDimitry Andric { "fixup_Hexagon_GPREL16_1", 0, 32, 0 },
1050b57cec5SDimitry Andric { "fixup_Hexagon_GPREL16_2", 0, 32, 0 },
1060b57cec5SDimitry Andric { "fixup_Hexagon_GPREL16_3", 0, 32, 0 },
1070b57cec5SDimitry Andric { "fixup_Hexagon_HL16", 0, 32, 0 },
1080b57cec5SDimitry Andric { "fixup_Hexagon_B13_PCREL", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
1090b57cec5SDimitry Andric { "fixup_Hexagon_B9_PCREL", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
1100b57cec5SDimitry Andric { "fixup_Hexagon_B32_PCREL_X", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
1110b57cec5SDimitry Andric { "fixup_Hexagon_32_6_X", 0, 32, 0 },
1120b57cec5SDimitry Andric { "fixup_Hexagon_B22_PCREL_X", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
1130b57cec5SDimitry Andric { "fixup_Hexagon_B15_PCREL_X", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
1140b57cec5SDimitry Andric { "fixup_Hexagon_B13_PCREL_X", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
1150b57cec5SDimitry Andric { "fixup_Hexagon_B9_PCREL_X", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
1160b57cec5SDimitry Andric { "fixup_Hexagon_B7_PCREL_X", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
1170b57cec5SDimitry Andric { "fixup_Hexagon_16_X", 0, 32, 0 },
1180b57cec5SDimitry Andric { "fixup_Hexagon_12_X", 0, 32, 0 },
1190b57cec5SDimitry Andric { "fixup_Hexagon_11_X", 0, 32, 0 },
1200b57cec5SDimitry Andric { "fixup_Hexagon_10_X", 0, 32, 0 },
1210b57cec5SDimitry Andric { "fixup_Hexagon_9_X", 0, 32, 0 },
1220b57cec5SDimitry Andric { "fixup_Hexagon_8_X", 0, 32, 0 },
1230b57cec5SDimitry Andric { "fixup_Hexagon_7_X", 0, 32, 0 },
1240b57cec5SDimitry Andric { "fixup_Hexagon_6_X", 0, 32, 0 },
1250b57cec5SDimitry Andric { "fixup_Hexagon_32_PCREL", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
1260b57cec5SDimitry Andric { "fixup_Hexagon_COPY", 0, 32, 0 },
1270b57cec5SDimitry Andric { "fixup_Hexagon_GLOB_DAT", 0, 32, 0 },
1280b57cec5SDimitry Andric { "fixup_Hexagon_JMP_SLOT", 0, 32, 0 },
1290b57cec5SDimitry Andric { "fixup_Hexagon_RELATIVE", 0, 32, 0 },
1300b57cec5SDimitry Andric { "fixup_Hexagon_PLT_B22_PCREL", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
1310b57cec5SDimitry Andric { "fixup_Hexagon_GOTREL_LO16", 0, 32, 0 },
1320b57cec5SDimitry Andric { "fixup_Hexagon_GOTREL_HI16", 0, 32, 0 },
1330b57cec5SDimitry Andric { "fixup_Hexagon_GOTREL_32", 0, 32, 0 },
1340b57cec5SDimitry Andric { "fixup_Hexagon_GOT_LO16", 0, 32, 0 },
1350b57cec5SDimitry Andric { "fixup_Hexagon_GOT_HI16", 0, 32, 0 },
1360b57cec5SDimitry Andric { "fixup_Hexagon_GOT_32", 0, 32, 0 },
1370b57cec5SDimitry Andric { "fixup_Hexagon_GOT_16", 0, 32, 0 },
1380b57cec5SDimitry Andric { "fixup_Hexagon_DTPMOD_32", 0, 32, 0 },
1390b57cec5SDimitry Andric { "fixup_Hexagon_DTPREL_LO16", 0, 32, 0 },
1400b57cec5SDimitry Andric { "fixup_Hexagon_DTPREL_HI16", 0, 32, 0 },
1410b57cec5SDimitry Andric { "fixup_Hexagon_DTPREL_32", 0, 32, 0 },
1420b57cec5SDimitry Andric { "fixup_Hexagon_DTPREL_16", 0, 32, 0 },
1430b57cec5SDimitry Andric { "fixup_Hexagon_GD_PLT_B22_PCREL",0, 32, MCFixupKindInfo::FKF_IsPCRel },
1440b57cec5SDimitry Andric { "fixup_Hexagon_LD_PLT_B22_PCREL",0, 32, MCFixupKindInfo::FKF_IsPCRel },
1450b57cec5SDimitry Andric { "fixup_Hexagon_GD_GOT_LO16", 0, 32, 0 },
1460b57cec5SDimitry Andric { "fixup_Hexagon_GD_GOT_HI16", 0, 32, 0 },
1470b57cec5SDimitry Andric { "fixup_Hexagon_GD_GOT_32", 0, 32, 0 },
1480b57cec5SDimitry Andric { "fixup_Hexagon_GD_GOT_16", 0, 32, 0 },
1490b57cec5SDimitry Andric { "fixup_Hexagon_LD_GOT_LO16", 0, 32, 0 },
1500b57cec5SDimitry Andric { "fixup_Hexagon_LD_GOT_HI16", 0, 32, 0 },
1510b57cec5SDimitry Andric { "fixup_Hexagon_LD_GOT_32", 0, 32, 0 },
1520b57cec5SDimitry Andric { "fixup_Hexagon_LD_GOT_16", 0, 32, 0 },
1530b57cec5SDimitry Andric { "fixup_Hexagon_IE_LO16", 0, 32, 0 },
1540b57cec5SDimitry Andric { "fixup_Hexagon_IE_HI16", 0, 32, 0 },
1550b57cec5SDimitry Andric { "fixup_Hexagon_IE_32", 0, 32, 0 },
1560b57cec5SDimitry Andric { "fixup_Hexagon_IE_16", 0, 32, 0 },
1570b57cec5SDimitry Andric { "fixup_Hexagon_IE_GOT_LO16", 0, 32, 0 },
1580b57cec5SDimitry Andric { "fixup_Hexagon_IE_GOT_HI16", 0, 32, 0 },
1590b57cec5SDimitry Andric { "fixup_Hexagon_IE_GOT_32", 0, 32, 0 },
1600b57cec5SDimitry Andric { "fixup_Hexagon_IE_GOT_16", 0, 32, 0 },
1610b57cec5SDimitry Andric { "fixup_Hexagon_TPREL_LO16", 0, 32, 0 },
1620b57cec5SDimitry Andric { "fixup_Hexagon_TPREL_HI16", 0, 32, 0 },
1630b57cec5SDimitry Andric { "fixup_Hexagon_TPREL_32", 0, 32, 0 },
1640b57cec5SDimitry Andric { "fixup_Hexagon_TPREL_16", 0, 32, 0 },
1650b57cec5SDimitry Andric { "fixup_Hexagon_6_PCREL_X", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
1660b57cec5SDimitry Andric { "fixup_Hexagon_GOTREL_32_6_X", 0, 32, 0 },
1670b57cec5SDimitry Andric { "fixup_Hexagon_GOTREL_16_X", 0, 32, 0 },
1680b57cec5SDimitry Andric { "fixup_Hexagon_GOTREL_11_X", 0, 32, 0 },
1690b57cec5SDimitry Andric { "fixup_Hexagon_GOT_32_6_X", 0, 32, 0 },
1700b57cec5SDimitry Andric { "fixup_Hexagon_GOT_16_X", 0, 32, 0 },
1710b57cec5SDimitry Andric { "fixup_Hexagon_GOT_11_X", 0, 32, 0 },
1720b57cec5SDimitry Andric { "fixup_Hexagon_DTPREL_32_6_X", 0, 32, 0 },
1730b57cec5SDimitry Andric { "fixup_Hexagon_DTPREL_16_X", 0, 32, 0 },
1740b57cec5SDimitry Andric { "fixup_Hexagon_DTPREL_11_X", 0, 32, 0 },
1750b57cec5SDimitry Andric { "fixup_Hexagon_GD_GOT_32_6_X", 0, 32, 0 },
1760b57cec5SDimitry Andric { "fixup_Hexagon_GD_GOT_16_X", 0, 32, 0 },
1770b57cec5SDimitry Andric { "fixup_Hexagon_GD_GOT_11_X", 0, 32, 0 },
1780b57cec5SDimitry Andric { "fixup_Hexagon_LD_GOT_32_6_X", 0, 32, 0 },
1790b57cec5SDimitry Andric { "fixup_Hexagon_LD_GOT_16_X", 0, 32, 0 },
1800b57cec5SDimitry Andric { "fixup_Hexagon_LD_GOT_11_X", 0, 32, 0 },
1810b57cec5SDimitry Andric { "fixup_Hexagon_IE_32_6_X", 0, 32, 0 },
1820b57cec5SDimitry Andric { "fixup_Hexagon_IE_16_X", 0, 32, 0 },
1830b57cec5SDimitry Andric { "fixup_Hexagon_IE_GOT_32_6_X", 0, 32, 0 },
1840b57cec5SDimitry Andric { "fixup_Hexagon_IE_GOT_16_X", 0, 32, 0 },
1850b57cec5SDimitry Andric { "fixup_Hexagon_IE_GOT_11_X", 0, 32, 0 },
1860b57cec5SDimitry Andric { "fixup_Hexagon_TPREL_32_6_X", 0, 32, 0 },
1870b57cec5SDimitry Andric { "fixup_Hexagon_TPREL_16_X", 0, 32, 0 },
1880b57cec5SDimitry Andric { "fixup_Hexagon_TPREL_11_X", 0, 32, 0 },
1890b57cec5SDimitry Andric { "fixup_Hexagon_GD_PLT_B22_PCREL_X",0, 32, MCFixupKindInfo::FKF_IsPCRel },
1900b57cec5SDimitry Andric { "fixup_Hexagon_GD_PLT_B32_PCREL_X",0, 32, MCFixupKindInfo::FKF_IsPCRel },
1910b57cec5SDimitry Andric { "fixup_Hexagon_LD_PLT_B22_PCREL_X",0, 32, MCFixupKindInfo::FKF_IsPCRel },
1920b57cec5SDimitry Andric { "fixup_Hexagon_LD_PLT_B32_PCREL_X",0, 32, MCFixupKindInfo::FKF_IsPCRel }
1930b57cec5SDimitry Andric };
1940b57cec5SDimitry Andric
1950b57cec5SDimitry Andric if (Kind < FirstTargetFixupKind)
1960b57cec5SDimitry Andric return MCAsmBackend::getFixupKindInfo(Kind);
1970b57cec5SDimitry Andric
1980b57cec5SDimitry Andric assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
1990b57cec5SDimitry Andric "Invalid kind!");
2000b57cec5SDimitry Andric return Infos[Kind - FirstTargetFixupKind];
2010b57cec5SDimitry Andric }
2020b57cec5SDimitry Andric
shouldForceRelocation(const MCAssembler & Asm,const MCFixup & Fixup,const MCValue & Target,const MCSubtargetInfo * STI)2030b57cec5SDimitry Andric bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
2045f757f3fSDimitry Andric const MCValue &Target,
2055f757f3fSDimitry Andric const MCSubtargetInfo *STI) override {
2068bcb0991SDimitry Andric switch(Fixup.getTargetKind()) {
2070b57cec5SDimitry Andric default:
2080b57cec5SDimitry Andric llvm_unreachable("Unknown Fixup Kind!");
2090b57cec5SDimitry Andric
2100b57cec5SDimitry Andric case fixup_Hexagon_LO16:
2110b57cec5SDimitry Andric case fixup_Hexagon_HI16:
2120b57cec5SDimitry Andric case fixup_Hexagon_16:
2130b57cec5SDimitry Andric case fixup_Hexagon_8:
2140b57cec5SDimitry Andric case fixup_Hexagon_GPREL16_0:
2150b57cec5SDimitry Andric case fixup_Hexagon_GPREL16_1:
2160b57cec5SDimitry Andric case fixup_Hexagon_GPREL16_2:
2170b57cec5SDimitry Andric case fixup_Hexagon_GPREL16_3:
2180b57cec5SDimitry Andric case fixup_Hexagon_HL16:
2190b57cec5SDimitry Andric case fixup_Hexagon_32_6_X:
2200b57cec5SDimitry Andric case fixup_Hexagon_16_X:
2210b57cec5SDimitry Andric case fixup_Hexagon_12_X:
2220b57cec5SDimitry Andric case fixup_Hexagon_11_X:
2230b57cec5SDimitry Andric case fixup_Hexagon_10_X:
2240b57cec5SDimitry Andric case fixup_Hexagon_9_X:
2250b57cec5SDimitry Andric case fixup_Hexagon_8_X:
2260b57cec5SDimitry Andric case fixup_Hexagon_7_X:
2270b57cec5SDimitry Andric case fixup_Hexagon_6_X:
2280b57cec5SDimitry Andric case fixup_Hexagon_COPY:
2290b57cec5SDimitry Andric case fixup_Hexagon_GLOB_DAT:
2300b57cec5SDimitry Andric case fixup_Hexagon_JMP_SLOT:
2310b57cec5SDimitry Andric case fixup_Hexagon_RELATIVE:
2320b57cec5SDimitry Andric case fixup_Hexagon_PLT_B22_PCREL:
2330b57cec5SDimitry Andric case fixup_Hexagon_GOTREL_LO16:
2340b57cec5SDimitry Andric case fixup_Hexagon_GOTREL_HI16:
2350b57cec5SDimitry Andric case fixup_Hexagon_GOTREL_32:
2360b57cec5SDimitry Andric case fixup_Hexagon_GOT_LO16:
2370b57cec5SDimitry Andric case fixup_Hexagon_GOT_HI16:
2380b57cec5SDimitry Andric case fixup_Hexagon_GOT_32:
2390b57cec5SDimitry Andric case fixup_Hexagon_GOT_16:
2400b57cec5SDimitry Andric case fixup_Hexagon_DTPMOD_32:
2410b57cec5SDimitry Andric case fixup_Hexagon_DTPREL_LO16:
2420b57cec5SDimitry Andric case fixup_Hexagon_DTPREL_HI16:
2430b57cec5SDimitry Andric case fixup_Hexagon_DTPREL_32:
2440b57cec5SDimitry Andric case fixup_Hexagon_DTPREL_16:
2450b57cec5SDimitry Andric case fixup_Hexagon_GD_PLT_B22_PCREL:
2460b57cec5SDimitry Andric case fixup_Hexagon_LD_PLT_B22_PCREL:
2470b57cec5SDimitry Andric case fixup_Hexagon_GD_GOT_LO16:
2480b57cec5SDimitry Andric case fixup_Hexagon_GD_GOT_HI16:
2490b57cec5SDimitry Andric case fixup_Hexagon_GD_GOT_32:
2500b57cec5SDimitry Andric case fixup_Hexagon_GD_GOT_16:
2510b57cec5SDimitry Andric case fixup_Hexagon_LD_GOT_LO16:
2520b57cec5SDimitry Andric case fixup_Hexagon_LD_GOT_HI16:
2530b57cec5SDimitry Andric case fixup_Hexagon_LD_GOT_32:
2540b57cec5SDimitry Andric case fixup_Hexagon_LD_GOT_16:
2550b57cec5SDimitry Andric case fixup_Hexagon_IE_LO16:
2560b57cec5SDimitry Andric case fixup_Hexagon_IE_HI16:
2570b57cec5SDimitry Andric case fixup_Hexagon_IE_32:
2580b57cec5SDimitry Andric case fixup_Hexagon_IE_16:
2590b57cec5SDimitry Andric case fixup_Hexagon_IE_GOT_LO16:
2600b57cec5SDimitry Andric case fixup_Hexagon_IE_GOT_HI16:
2610b57cec5SDimitry Andric case fixup_Hexagon_IE_GOT_32:
2620b57cec5SDimitry Andric case fixup_Hexagon_IE_GOT_16:
2630b57cec5SDimitry Andric case fixup_Hexagon_TPREL_LO16:
2640b57cec5SDimitry Andric case fixup_Hexagon_TPREL_HI16:
2650b57cec5SDimitry Andric case fixup_Hexagon_TPREL_32:
2660b57cec5SDimitry Andric case fixup_Hexagon_TPREL_16:
2670b57cec5SDimitry Andric case fixup_Hexagon_GOTREL_32_6_X:
2680b57cec5SDimitry Andric case fixup_Hexagon_GOTREL_16_X:
2690b57cec5SDimitry Andric case fixup_Hexagon_GOTREL_11_X:
2700b57cec5SDimitry Andric case fixup_Hexagon_GOT_32_6_X:
2710b57cec5SDimitry Andric case fixup_Hexagon_GOT_16_X:
2720b57cec5SDimitry Andric case fixup_Hexagon_GOT_11_X:
2730b57cec5SDimitry Andric case fixup_Hexagon_DTPREL_32_6_X:
2740b57cec5SDimitry Andric case fixup_Hexagon_DTPREL_16_X:
2750b57cec5SDimitry Andric case fixup_Hexagon_DTPREL_11_X:
2760b57cec5SDimitry Andric case fixup_Hexagon_GD_GOT_32_6_X:
2770b57cec5SDimitry Andric case fixup_Hexagon_GD_GOT_16_X:
2780b57cec5SDimitry Andric case fixup_Hexagon_GD_GOT_11_X:
2790b57cec5SDimitry Andric case fixup_Hexagon_LD_GOT_32_6_X:
2800b57cec5SDimitry Andric case fixup_Hexagon_LD_GOT_16_X:
2810b57cec5SDimitry Andric case fixup_Hexagon_LD_GOT_11_X:
2820b57cec5SDimitry Andric case fixup_Hexagon_IE_32_6_X:
2830b57cec5SDimitry Andric case fixup_Hexagon_IE_16_X:
2840b57cec5SDimitry Andric case fixup_Hexagon_IE_GOT_32_6_X:
2850b57cec5SDimitry Andric case fixup_Hexagon_IE_GOT_16_X:
2860b57cec5SDimitry Andric case fixup_Hexagon_IE_GOT_11_X:
2870b57cec5SDimitry Andric case fixup_Hexagon_TPREL_32_6_X:
2880b57cec5SDimitry Andric case fixup_Hexagon_TPREL_16_X:
2890b57cec5SDimitry Andric case fixup_Hexagon_TPREL_11_X:
2900b57cec5SDimitry Andric case fixup_Hexagon_32_PCREL:
2910b57cec5SDimitry Andric case fixup_Hexagon_6_PCREL_X:
2920b57cec5SDimitry Andric case fixup_Hexagon_23_REG:
2930b57cec5SDimitry Andric case fixup_Hexagon_27_REG:
2940b57cec5SDimitry Andric case fixup_Hexagon_GD_PLT_B22_PCREL_X:
2950b57cec5SDimitry Andric case fixup_Hexagon_GD_PLT_B32_PCREL_X:
2960b57cec5SDimitry Andric case fixup_Hexagon_LD_PLT_B22_PCREL_X:
2970b57cec5SDimitry Andric case fixup_Hexagon_LD_PLT_B32_PCREL_X:
2980b57cec5SDimitry Andric // These relocations should always have a relocation recorded
2990b57cec5SDimitry Andric return true;
3000b57cec5SDimitry Andric
3010b57cec5SDimitry Andric case fixup_Hexagon_B22_PCREL:
3020b57cec5SDimitry Andric //IsResolved = false;
3030b57cec5SDimitry Andric break;
3040b57cec5SDimitry Andric
3050b57cec5SDimitry Andric case fixup_Hexagon_B13_PCREL:
3060b57cec5SDimitry Andric case fixup_Hexagon_B13_PCREL_X:
3070b57cec5SDimitry Andric case fixup_Hexagon_B32_PCREL_X:
3080b57cec5SDimitry Andric case fixup_Hexagon_B22_PCREL_X:
3090b57cec5SDimitry Andric case fixup_Hexagon_B15_PCREL:
3100b57cec5SDimitry Andric case fixup_Hexagon_B15_PCREL_X:
3110b57cec5SDimitry Andric case fixup_Hexagon_B9_PCREL:
3120b57cec5SDimitry Andric case fixup_Hexagon_B9_PCREL_X:
3130b57cec5SDimitry Andric case fixup_Hexagon_B7_PCREL:
3140b57cec5SDimitry Andric case fixup_Hexagon_B7_PCREL_X:
3150b57cec5SDimitry Andric if (DisableFixup)
3160b57cec5SDimitry Andric return true;
3170b57cec5SDimitry Andric break;
3180b57cec5SDimitry Andric
3190b57cec5SDimitry Andric case FK_Data_1:
3200b57cec5SDimitry Andric case FK_Data_2:
3210b57cec5SDimitry Andric case FK_Data_4:
3220b57cec5SDimitry Andric case FK_PCRel_4:
3230b57cec5SDimitry Andric case fixup_Hexagon_32:
3240b57cec5SDimitry Andric // Leave these relocations alone as they are used for EH.
3250b57cec5SDimitry Andric return false;
3260b57cec5SDimitry Andric }
3270b57cec5SDimitry Andric return false;
3280b57cec5SDimitry Andric }
3290b57cec5SDimitry Andric
3300b57cec5SDimitry Andric /// getFixupKindNumBytes - The number of bytes the fixup may change.
getFixupKindNumBytes(unsigned Kind)3310b57cec5SDimitry Andric static unsigned getFixupKindNumBytes(unsigned Kind) {
3320b57cec5SDimitry Andric switch (Kind) {
3330b57cec5SDimitry Andric default:
3340b57cec5SDimitry Andric return 0;
3350b57cec5SDimitry Andric
3360b57cec5SDimitry Andric case FK_Data_1:
3370b57cec5SDimitry Andric return 1;
3380b57cec5SDimitry Andric case FK_Data_2:
3390b57cec5SDimitry Andric return 2;
3400b57cec5SDimitry Andric case FK_Data_4: // this later gets mapped to R_HEX_32
3410b57cec5SDimitry Andric case FK_PCRel_4: // this later gets mapped to R_HEX_32_PCREL
3420b57cec5SDimitry Andric case fixup_Hexagon_32:
3430b57cec5SDimitry Andric case fixup_Hexagon_B32_PCREL_X:
3440b57cec5SDimitry Andric case fixup_Hexagon_B22_PCREL:
3450b57cec5SDimitry Andric case fixup_Hexagon_B22_PCREL_X:
3460b57cec5SDimitry Andric case fixup_Hexagon_B15_PCREL:
3470b57cec5SDimitry Andric case fixup_Hexagon_B15_PCREL_X:
3480b57cec5SDimitry Andric case fixup_Hexagon_B13_PCREL:
3490b57cec5SDimitry Andric case fixup_Hexagon_B13_PCREL_X:
3500b57cec5SDimitry Andric case fixup_Hexagon_B9_PCREL:
3510b57cec5SDimitry Andric case fixup_Hexagon_B9_PCREL_X:
3520b57cec5SDimitry Andric case fixup_Hexagon_B7_PCREL:
3530b57cec5SDimitry Andric case fixup_Hexagon_B7_PCREL_X:
3540b57cec5SDimitry Andric case fixup_Hexagon_GD_PLT_B32_PCREL_X:
3550b57cec5SDimitry Andric case fixup_Hexagon_LD_PLT_B32_PCREL_X:
3560b57cec5SDimitry Andric return 4;
3570b57cec5SDimitry Andric }
3580b57cec5SDimitry Andric }
3590b57cec5SDimitry Andric
3600b57cec5SDimitry Andric // Make up for left shift when encoding the operand.
adjustFixupValue(MCFixupKind Kind,uint64_t Value)3610b57cec5SDimitry Andric static uint64_t adjustFixupValue(MCFixupKind Kind, uint64_t Value) {
3620b57cec5SDimitry Andric switch((unsigned)Kind) {
3630b57cec5SDimitry Andric default:
3640b57cec5SDimitry Andric break;
3650b57cec5SDimitry Andric
3660b57cec5SDimitry Andric case fixup_Hexagon_B7_PCREL:
3670b57cec5SDimitry Andric case fixup_Hexagon_B9_PCREL:
3680b57cec5SDimitry Andric case fixup_Hexagon_B13_PCREL:
3690b57cec5SDimitry Andric case fixup_Hexagon_B15_PCREL:
3700b57cec5SDimitry Andric case fixup_Hexagon_B22_PCREL:
3710b57cec5SDimitry Andric Value >>= 2;
3720b57cec5SDimitry Andric break;
3730b57cec5SDimitry Andric
3740b57cec5SDimitry Andric case fixup_Hexagon_B7_PCREL_X:
3750b57cec5SDimitry Andric case fixup_Hexagon_B9_PCREL_X:
3760b57cec5SDimitry Andric case fixup_Hexagon_B13_PCREL_X:
3770b57cec5SDimitry Andric case fixup_Hexagon_B15_PCREL_X:
3780b57cec5SDimitry Andric case fixup_Hexagon_B22_PCREL_X:
3790b57cec5SDimitry Andric Value &= 0x3f;
3800b57cec5SDimitry Andric break;
3810b57cec5SDimitry Andric
3820b57cec5SDimitry Andric case fixup_Hexagon_B32_PCREL_X:
3830b57cec5SDimitry Andric case fixup_Hexagon_GD_PLT_B32_PCREL_X:
3840b57cec5SDimitry Andric case fixup_Hexagon_LD_PLT_B32_PCREL_X:
3850b57cec5SDimitry Andric Value >>= 6;
3860b57cec5SDimitry Andric break;
3870b57cec5SDimitry Andric }
3880b57cec5SDimitry Andric return (Value);
3890b57cec5SDimitry Andric }
3900b57cec5SDimitry Andric
HandleFixupError(const int bits,const int align_bits,const int64_t FixupValue,const char * fixupStr) const3910b57cec5SDimitry Andric void HandleFixupError(const int bits, const int align_bits,
3920b57cec5SDimitry Andric const int64_t FixupValue, const char *fixupStr) const {
3930b57cec5SDimitry Andric // Error: value 1124 out of range: -1024-1023 when resolving
3940b57cec5SDimitry Andric // symbol in file xprtsock.S
3950b57cec5SDimitry Andric const APInt IntMin = APInt::getSignedMinValue(bits+align_bits);
3960b57cec5SDimitry Andric const APInt IntMax = APInt::getSignedMaxValue(bits+align_bits);
3970b57cec5SDimitry Andric std::stringstream errStr;
3980b57cec5SDimitry Andric errStr << "\nError: value " <<
3990b57cec5SDimitry Andric FixupValue <<
4000b57cec5SDimitry Andric " out of range: " <<
4010b57cec5SDimitry Andric IntMin.getSExtValue() <<
4020b57cec5SDimitry Andric "-" <<
4030b57cec5SDimitry Andric IntMax.getSExtValue() <<
4040b57cec5SDimitry Andric " when resolving " <<
4050b57cec5SDimitry Andric fixupStr <<
4060b57cec5SDimitry Andric " fixup\n";
4070b57cec5SDimitry Andric llvm_unreachable(errStr.str().c_str());
4080b57cec5SDimitry Andric }
4090b57cec5SDimitry Andric
4100b57cec5SDimitry Andric /// ApplyFixup - Apply the \arg Value for given \arg Fixup into the provided
4110b57cec5SDimitry Andric /// data fragment, at the offset specified by the fixup and following the
4120b57cec5SDimitry Andric /// fixup kind as appropriate.
applyFixup(const MCAssembler & Asm,const MCFixup & Fixup,const MCValue & Target,MutableArrayRef<char> Data,uint64_t FixupValue,bool IsResolved,const MCSubtargetInfo * STI) const4130b57cec5SDimitry Andric void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
4140b57cec5SDimitry Andric const MCValue &Target, MutableArrayRef<char> Data,
4150b57cec5SDimitry Andric uint64_t FixupValue, bool IsResolved,
4160b57cec5SDimitry Andric const MCSubtargetInfo *STI) const override {
4170b57cec5SDimitry Andric
4180b57cec5SDimitry Andric // When FixupValue is 0 the relocation is external and there
4190b57cec5SDimitry Andric // is nothing for us to do.
4200b57cec5SDimitry Andric if (!FixupValue) return;
4210b57cec5SDimitry Andric
4220b57cec5SDimitry Andric MCFixupKind Kind = Fixup.getKind();
4230b57cec5SDimitry Andric uint64_t Value;
4240b57cec5SDimitry Andric uint32_t InstMask;
4250b57cec5SDimitry Andric uint32_t Reloc;
4260b57cec5SDimitry Andric
4270b57cec5SDimitry Andric // LLVM gives us an encoded value, we have to convert it back
4280b57cec5SDimitry Andric // to a real offset before we can use it.
4290b57cec5SDimitry Andric uint32_t Offset = Fixup.getOffset();
4300b57cec5SDimitry Andric unsigned NumBytes = getFixupKindNumBytes(Kind);
4310b57cec5SDimitry Andric assert(Offset + NumBytes <= Data.size() && "Invalid fixup offset!");
4320b57cec5SDimitry Andric char *InstAddr = Data.data() + Offset;
4330b57cec5SDimitry Andric
4340b57cec5SDimitry Andric Value = adjustFixupValue(Kind, FixupValue);
4350b57cec5SDimitry Andric if(!Value)
4360b57cec5SDimitry Andric return;
4370b57cec5SDimitry Andric int sValue = (int)Value;
4380b57cec5SDimitry Andric
4390b57cec5SDimitry Andric switch((unsigned)Kind) {
4400b57cec5SDimitry Andric default:
4410b57cec5SDimitry Andric return;
4420b57cec5SDimitry Andric
4430b57cec5SDimitry Andric case fixup_Hexagon_B7_PCREL:
4440b57cec5SDimitry Andric if (!(isIntN(7, sValue)))
4450b57cec5SDimitry Andric HandleFixupError(7, 2, (int64_t)FixupValue, "B7_PCREL");
446bdd1243dSDimitry Andric [[fallthrough]];
4470b57cec5SDimitry Andric case fixup_Hexagon_B7_PCREL_X:
4480b57cec5SDimitry Andric InstMask = 0x00001f18; // Word32_B7
4490b57cec5SDimitry Andric Reloc = (((Value >> 2) & 0x1f) << 8) | // Value 6-2 = Target 12-8
4500b57cec5SDimitry Andric ((Value & 0x3) << 3); // Value 1-0 = Target 4-3
4510b57cec5SDimitry Andric break;
4520b57cec5SDimitry Andric
4530b57cec5SDimitry Andric case fixup_Hexagon_B9_PCREL:
4540b57cec5SDimitry Andric if (!(isIntN(9, sValue)))
4550b57cec5SDimitry Andric HandleFixupError(9, 2, (int64_t)FixupValue, "B9_PCREL");
456bdd1243dSDimitry Andric [[fallthrough]];
4570b57cec5SDimitry Andric case fixup_Hexagon_B9_PCREL_X:
4580b57cec5SDimitry Andric InstMask = 0x003000fe; // Word32_B9
4590b57cec5SDimitry Andric Reloc = (((Value >> 7) & 0x3) << 20) | // Value 8-7 = Target 21-20
4600b57cec5SDimitry Andric ((Value & 0x7f) << 1); // Value 6-0 = Target 7-1
4610b57cec5SDimitry Andric break;
4620b57cec5SDimitry Andric
4630b57cec5SDimitry Andric // Since the existing branches that use this relocation cannot be
4640b57cec5SDimitry Andric // extended, they should only be fixed up if the target is within range.
4650b57cec5SDimitry Andric case fixup_Hexagon_B13_PCREL:
4660b57cec5SDimitry Andric if (!(isIntN(13, sValue)))
4670b57cec5SDimitry Andric HandleFixupError(13, 2, (int64_t)FixupValue, "B13_PCREL");
468bdd1243dSDimitry Andric [[fallthrough]];
4690b57cec5SDimitry Andric case fixup_Hexagon_B13_PCREL_X:
4700b57cec5SDimitry Andric InstMask = 0x00202ffe; // Word32_B13
4710b57cec5SDimitry Andric Reloc = (((Value >> 12) & 0x1) << 21) | // Value 12 = Target 21
4720b57cec5SDimitry Andric (((Value >> 11) & 0x1) << 13) | // Value 11 = Target 13
4730b57cec5SDimitry Andric ((Value & 0x7ff) << 1); // Value 10-0 = Target 11-1
4740b57cec5SDimitry Andric break;
4750b57cec5SDimitry Andric
4760b57cec5SDimitry Andric case fixup_Hexagon_B15_PCREL:
4770b57cec5SDimitry Andric if (!(isIntN(15, sValue)))
4780b57cec5SDimitry Andric HandleFixupError(15, 2, (int64_t)FixupValue, "B15_PCREL");
479bdd1243dSDimitry Andric [[fallthrough]];
4800b57cec5SDimitry Andric case fixup_Hexagon_B15_PCREL_X:
4810b57cec5SDimitry Andric InstMask = 0x00df20fe; // Word32_B15
4820b57cec5SDimitry Andric Reloc = (((Value >> 13) & 0x3) << 22) | // Value 14-13 = Target 23-22
4830b57cec5SDimitry Andric (((Value >> 8) & 0x1f) << 16) | // Value 12-8 = Target 20-16
4840b57cec5SDimitry Andric (((Value >> 7) & 0x1) << 13) | // Value 7 = Target 13
4850b57cec5SDimitry Andric ((Value & 0x7f) << 1); // Value 6-0 = Target 7-1
4860b57cec5SDimitry Andric break;
4870b57cec5SDimitry Andric
4880b57cec5SDimitry Andric case fixup_Hexagon_B22_PCREL:
4890b57cec5SDimitry Andric if (!(isIntN(22, sValue)))
4900b57cec5SDimitry Andric HandleFixupError(22, 2, (int64_t)FixupValue, "B22_PCREL");
491bdd1243dSDimitry Andric [[fallthrough]];
4920b57cec5SDimitry Andric case fixup_Hexagon_B22_PCREL_X:
4930b57cec5SDimitry Andric InstMask = 0x01ff3ffe; // Word32_B22
4940b57cec5SDimitry Andric Reloc = (((Value >> 13) & 0x1ff) << 16) | // Value 21-13 = Target 24-16
4950b57cec5SDimitry Andric ((Value & 0x1fff) << 1); // Value 12-0 = Target 13-1
4960b57cec5SDimitry Andric break;
4970b57cec5SDimitry Andric
4980b57cec5SDimitry Andric case fixup_Hexagon_B32_PCREL_X:
4990b57cec5SDimitry Andric InstMask = 0x0fff3fff; // Word32_X26
5000b57cec5SDimitry Andric Reloc = (((Value >> 14) & 0xfff) << 16) | // Value 25-14 = Target 27-16
5010b57cec5SDimitry Andric (Value & 0x3fff); // Value 13-0 = Target 13-0
5020b57cec5SDimitry Andric break;
5030b57cec5SDimitry Andric
5040b57cec5SDimitry Andric case FK_Data_1:
5050b57cec5SDimitry Andric case FK_Data_2:
5060b57cec5SDimitry Andric case FK_Data_4:
5070b57cec5SDimitry Andric case fixup_Hexagon_32:
5080b57cec5SDimitry Andric InstMask = 0xffffffff; // Word32
5090b57cec5SDimitry Andric Reloc = Value;
5100b57cec5SDimitry Andric break;
5110b57cec5SDimitry Andric }
5120b57cec5SDimitry Andric
5130b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Name=" << getFixupKindInfo(Kind).Name << "("
5140b57cec5SDimitry Andric << (unsigned)Kind << ")\n");
5150b57cec5SDimitry Andric LLVM_DEBUG(
5160b57cec5SDimitry Andric uint32_t OldData = 0; for (unsigned i = 0; i < NumBytes; i++) OldData |=
5170b57cec5SDimitry Andric (InstAddr[i] << (i * 8)) & (0xff << (i * 8));
5180b57cec5SDimitry Andric dbgs() << "\tBValue=0x"; dbgs().write_hex(Value) << ": AValue=0x";
5190b57cec5SDimitry Andric dbgs().write_hex(FixupValue)
5200b57cec5SDimitry Andric << ": Offset=" << Offset << ": Size=" << Data.size() << ": OInst=0x";
5210b57cec5SDimitry Andric dbgs().write_hex(OldData) << ": Reloc=0x"; dbgs().write_hex(Reloc););
5220b57cec5SDimitry Andric
5230b57cec5SDimitry Andric // For each byte of the fragment that the fixup touches, mask in the
5240b57cec5SDimitry Andric // bits from the fixup value. The Value has been "split up" into the
5250b57cec5SDimitry Andric // appropriate bitfields above.
5260b57cec5SDimitry Andric for (unsigned i = 0; i < NumBytes; i++){
5270b57cec5SDimitry Andric InstAddr[i] &= uint8_t(~InstMask >> (i * 8)) & 0xff; // Clear reloc bits
5280b57cec5SDimitry Andric InstAddr[i] |= uint8_t(Reloc >> (i * 8)) & 0xff; // Apply new reloc
5290b57cec5SDimitry Andric }
5300b57cec5SDimitry Andric
5310b57cec5SDimitry Andric LLVM_DEBUG(uint32_t NewData = 0;
5320b57cec5SDimitry Andric for (unsigned i = 0; i < NumBytes; i++) NewData |=
5330b57cec5SDimitry Andric (InstAddr[i] << (i * 8)) & (0xff << (i * 8));
5340b57cec5SDimitry Andric dbgs() << ": NInst=0x"; dbgs().write_hex(NewData) << "\n";);
5350b57cec5SDimitry Andric }
5360b57cec5SDimitry Andric
isInstRelaxable(MCInst const & HMI) const5370b57cec5SDimitry Andric bool isInstRelaxable(MCInst const &HMI) const {
5380b57cec5SDimitry Andric const MCInstrDesc &MCID = HexagonMCInstrInfo::getDesc(*MCII, HMI);
5390b57cec5SDimitry Andric bool Relaxable = false;
5400b57cec5SDimitry Andric // Branches and loop-setup insns are handled as necessary by relaxation.
5410b57cec5SDimitry Andric if (llvm::HexagonMCInstrInfo::getType(*MCII, HMI) == HexagonII::TypeJ ||
5420b57cec5SDimitry Andric (llvm::HexagonMCInstrInfo::getType(*MCII, HMI) == HexagonII::TypeCJ &&
5430b57cec5SDimitry Andric MCID.isBranch()) ||
5440b57cec5SDimitry Andric (llvm::HexagonMCInstrInfo::getType(*MCII, HMI) == HexagonII::TypeNCJ &&
5450b57cec5SDimitry Andric MCID.isBranch()) ||
5460b57cec5SDimitry Andric (llvm::HexagonMCInstrInfo::getType(*MCII, HMI) == HexagonII::TypeCR &&
5470b57cec5SDimitry Andric HMI.getOpcode() != Hexagon::C4_addipc))
5480b57cec5SDimitry Andric if (HexagonMCInstrInfo::isExtendable(*MCII, HMI)) {
5490b57cec5SDimitry Andric Relaxable = true;
5500b57cec5SDimitry Andric MCOperand const &Operand =
5510b57cec5SDimitry Andric HMI.getOperand(HexagonMCInstrInfo::getExtendableOp(*MCII, HMI));
5520b57cec5SDimitry Andric if (HexagonMCInstrInfo::mustNotExtend(*Operand.getExpr()))
5530b57cec5SDimitry Andric Relaxable = false;
5540b57cec5SDimitry Andric }
5550b57cec5SDimitry Andric
5560b57cec5SDimitry Andric return Relaxable;
5570b57cec5SDimitry Andric }
5580b57cec5SDimitry Andric
5590b57cec5SDimitry Andric /// MayNeedRelaxation - Check whether the given instruction may need
5600b57cec5SDimitry Andric /// relaxation.
5610b57cec5SDimitry Andric ///
5620b57cec5SDimitry Andric /// \param Inst - The instruction to test.
mayNeedRelaxation(MCInst const & Inst,const MCSubtargetInfo & STI) const5630b57cec5SDimitry Andric bool mayNeedRelaxation(MCInst const &Inst,
5640b57cec5SDimitry Andric const MCSubtargetInfo &STI) const override {
5650b57cec5SDimitry Andric return true;
5660b57cec5SDimitry Andric }
5670b57cec5SDimitry Andric
5680b57cec5SDimitry Andric /// fixupNeedsRelaxation - Target specific predicate for whether a given
5690b57cec5SDimitry Andric /// fixup requires the associated instruction to be relaxed.
fixupNeedsRelaxationAdvanced(const MCAssembler & Asm,const MCFixup & Fixup,bool Resolved,uint64_t Value,const MCRelaxableFragment * DF,const bool WasForced) const5700fca6ea1SDimitry Andric bool fixupNeedsRelaxationAdvanced(const MCAssembler &Asm,
5710fca6ea1SDimitry Andric const MCFixup &Fixup, bool Resolved,
5720b57cec5SDimitry Andric uint64_t Value,
5730b57cec5SDimitry Andric const MCRelaxableFragment *DF,
5740b57cec5SDimitry Andric const bool WasForced) const override {
5750b57cec5SDimitry Andric MCInst const &MCB = DF->getInst();
5760b57cec5SDimitry Andric assert(HexagonMCInstrInfo::isBundle(MCB));
5770b57cec5SDimitry Andric
5780b57cec5SDimitry Andric *RelaxTarget = nullptr;
5790b57cec5SDimitry Andric MCInst &MCI = const_cast<MCInst &>(HexagonMCInstrInfo::instruction(
5800b57cec5SDimitry Andric MCB, Fixup.getOffset() / HEXAGON_INSTR_SIZE));
5810b57cec5SDimitry Andric bool Relaxable = isInstRelaxable(MCI);
5820b57cec5SDimitry Andric if (Relaxable == false)
5830b57cec5SDimitry Andric return false;
5840b57cec5SDimitry Andric // If we cannot resolve the fixup value, it requires relaxation.
5850b57cec5SDimitry Andric if (!Resolved) {
5868bcb0991SDimitry Andric switch (Fixup.getTargetKind()) {
5870b57cec5SDimitry Andric case fixup_Hexagon_B22_PCREL:
5880b57cec5SDimitry Andric // GetFixupCount assumes B22 won't relax
589bdd1243dSDimitry Andric [[fallthrough]];
5900b57cec5SDimitry Andric default:
5910b57cec5SDimitry Andric return false;
5920b57cec5SDimitry Andric break;
5930b57cec5SDimitry Andric case fixup_Hexagon_B13_PCREL:
5940b57cec5SDimitry Andric case fixup_Hexagon_B15_PCREL:
5950b57cec5SDimitry Andric case fixup_Hexagon_B9_PCREL:
5960b57cec5SDimitry Andric case fixup_Hexagon_B7_PCREL: {
5970b57cec5SDimitry Andric if (HexagonMCInstrInfo::bundleSize(MCB) < HEXAGON_PACKET_SIZE) {
5980b57cec5SDimitry Andric ++relaxedCnt;
5990b57cec5SDimitry Andric *RelaxTarget = &MCI;
6000fca6ea1SDimitry Andric setExtender(Asm.getContext());
6010b57cec5SDimitry Andric return true;
6020b57cec5SDimitry Andric } else {
6030b57cec5SDimitry Andric return false;
6040b57cec5SDimitry Andric }
6050b57cec5SDimitry Andric break;
6060b57cec5SDimitry Andric }
6070b57cec5SDimitry Andric }
6080b57cec5SDimitry Andric }
6090b57cec5SDimitry Andric
6100b57cec5SDimitry Andric MCFixupKind Kind = Fixup.getKind();
6110b57cec5SDimitry Andric int64_t sValue = Value;
6120b57cec5SDimitry Andric int64_t maxValue;
6130b57cec5SDimitry Andric
6140b57cec5SDimitry Andric switch ((unsigned)Kind) {
6150b57cec5SDimitry Andric case fixup_Hexagon_B7_PCREL:
6160b57cec5SDimitry Andric maxValue = 1 << 8;
6170b57cec5SDimitry Andric break;
6180b57cec5SDimitry Andric case fixup_Hexagon_B9_PCREL:
6190b57cec5SDimitry Andric maxValue = 1 << 10;
6200b57cec5SDimitry Andric break;
6210b57cec5SDimitry Andric case fixup_Hexagon_B15_PCREL:
6220b57cec5SDimitry Andric maxValue = 1 << 16;
6230b57cec5SDimitry Andric break;
6240b57cec5SDimitry Andric case fixup_Hexagon_B22_PCREL:
6250b57cec5SDimitry Andric maxValue = 1 << 23;
6260b57cec5SDimitry Andric break;
6270b57cec5SDimitry Andric default:
6280b57cec5SDimitry Andric maxValue = INT64_MAX;
6290b57cec5SDimitry Andric break;
6300b57cec5SDimitry Andric }
6310b57cec5SDimitry Andric
6320b57cec5SDimitry Andric bool isFarAway = -maxValue > sValue || sValue > maxValue - 1;
6330b57cec5SDimitry Andric
6340b57cec5SDimitry Andric if (isFarAway) {
6350b57cec5SDimitry Andric if (HexagonMCInstrInfo::bundleSize(MCB) < HEXAGON_PACKET_SIZE) {
6360b57cec5SDimitry Andric ++relaxedCnt;
6370b57cec5SDimitry Andric *RelaxTarget = &MCI;
6380fca6ea1SDimitry Andric setExtender(Asm.getContext());
6390b57cec5SDimitry Andric return true;
6400b57cec5SDimitry Andric }
6410b57cec5SDimitry Andric }
6420b57cec5SDimitry Andric
6430b57cec5SDimitry Andric return false;
6440b57cec5SDimitry Andric }
6450b57cec5SDimitry Andric
relaxInstruction(MCInst & Inst,const MCSubtargetInfo & STI) const6465ffd83dbSDimitry Andric void relaxInstruction(MCInst &Inst,
6475ffd83dbSDimitry Andric const MCSubtargetInfo &STI) const override {
6480b57cec5SDimitry Andric assert(HexagonMCInstrInfo::isBundle(Inst) &&
6490b57cec5SDimitry Andric "Hexagon relaxInstruction only works on bundles");
6500b57cec5SDimitry Andric
6515ffd83dbSDimitry Andric MCInst Res;
6520b57cec5SDimitry Andric Res.setOpcode(Hexagon::BUNDLE);
6530b57cec5SDimitry Andric Res.addOperand(MCOperand::createImm(Inst.getOperand(0).getImm()));
6540b57cec5SDimitry Andric // Copy the results into the bundle.
6550b57cec5SDimitry Andric bool Update = false;
6560b57cec5SDimitry Andric for (auto &I : HexagonMCInstrInfo::bundleInstructions(Inst)) {
6570b57cec5SDimitry Andric MCInst &CrntHMI = const_cast<MCInst &>(*I.getInst());
6580b57cec5SDimitry Andric
6590b57cec5SDimitry Andric // if immediate extender needed, add it in
6600b57cec5SDimitry Andric if (*RelaxTarget == &CrntHMI) {
6610b57cec5SDimitry Andric Update = true;
6620b57cec5SDimitry Andric assert((HexagonMCInstrInfo::bundleSize(Res) < HEXAGON_PACKET_SIZE) &&
6630b57cec5SDimitry Andric "No room to insert extender for relaxation");
6640b57cec5SDimitry Andric
6650b57cec5SDimitry Andric MCInst *HMIx = takeExtender();
6660b57cec5SDimitry Andric *HMIx = HexagonMCInstrInfo::deriveExtender(
6670b57cec5SDimitry Andric *MCII, CrntHMI,
6680b57cec5SDimitry Andric HexagonMCInstrInfo::getExtendableOperand(*MCII, CrntHMI));
6690b57cec5SDimitry Andric Res.addOperand(MCOperand::createInst(HMIx));
6700b57cec5SDimitry Andric *RelaxTarget = nullptr;
6710b57cec5SDimitry Andric }
6720b57cec5SDimitry Andric // now copy over the original instruction(the one we may have extended)
6730b57cec5SDimitry Andric Res.addOperand(MCOperand::createInst(I.getInst()));
6740b57cec5SDimitry Andric }
6755ffd83dbSDimitry Andric
6765ffd83dbSDimitry Andric Inst = std::move(Res);
6770b57cec5SDimitry Andric (void)Update;
6780b57cec5SDimitry Andric assert(Update && "Didn't find relaxation target");
6790b57cec5SDimitry Andric }
6800b57cec5SDimitry Andric
writeNopData(raw_ostream & OS,uint64_t Count,const MCSubtargetInfo * STI) const681349cc55cSDimitry Andric bool writeNopData(raw_ostream &OS, uint64_t Count,
682349cc55cSDimitry Andric const MCSubtargetInfo *STI) const override {
6830b57cec5SDimitry Andric static const uint32_t Nopcode = 0x7f000000, // Hard-coded NOP.
6840b57cec5SDimitry Andric ParseIn = 0x00004000, // In packet parse-bits.
6850b57cec5SDimitry Andric ParseEnd = 0x0000c000; // End of packet parse-bits.
6860b57cec5SDimitry Andric
6870b57cec5SDimitry Andric while (Count % HEXAGON_INSTR_SIZE) {
6880b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Alignment not a multiple of the instruction size:"
6890b57cec5SDimitry Andric << Count % HEXAGON_INSTR_SIZE << "/"
6900b57cec5SDimitry Andric << HEXAGON_INSTR_SIZE << "\n");
6910b57cec5SDimitry Andric --Count;
6920b57cec5SDimitry Andric OS << '\0';
6930b57cec5SDimitry Andric }
6940b57cec5SDimitry Andric
6950b57cec5SDimitry Andric while (Count) {
6960b57cec5SDimitry Andric Count -= HEXAGON_INSTR_SIZE;
6970b57cec5SDimitry Andric // Close the packet whenever a multiple of the maximum packet size remains
6985ffd83dbSDimitry Andric uint32_t ParseBits = (Count % (MaxPacketSize * HEXAGON_INSTR_SIZE)) ?
6990b57cec5SDimitry Andric ParseIn : ParseEnd;
7000b57cec5SDimitry Andric support::endian::write<uint32_t>(OS, Nopcode | ParseBits, Endian);
7010b57cec5SDimitry Andric }
7020b57cec5SDimitry Andric return true;
7030b57cec5SDimitry Andric }
7040b57cec5SDimitry Andric
finishLayout(MCAssembler const & Asm) const705*52418fc2SDimitry Andric void finishLayout(MCAssembler const &Asm) const override {
7060fca6ea1SDimitry Andric SmallVector<MCFragment *> Frags;
7070fca6ea1SDimitry Andric for (MCSection &Sec : Asm) {
7080fca6ea1SDimitry Andric Frags.clear();
7090fca6ea1SDimitry Andric for (MCFragment &F : Sec)
7100fca6ea1SDimitry Andric Frags.push_back(&F);
7110fca6ea1SDimitry Andric for (size_t J = 0, E = Frags.size(); J != E; ++J) {
7120fca6ea1SDimitry Andric switch (Frags[J]->getKind()) {
7130b57cec5SDimitry Andric default:
7140b57cec5SDimitry Andric break;
7150b57cec5SDimitry Andric case MCFragment::FT_Align: {
7160fca6ea1SDimitry Andric auto Size = Asm.computeFragmentSize(*Frags[J]);
7170fca6ea1SDimitry Andric for (auto K = J; K != 0 && Size >= HEXAGON_PACKET_SIZE;) {
7180b57cec5SDimitry Andric --K;
7190fca6ea1SDimitry Andric switch (Frags[K]->getKind()) {
7200b57cec5SDimitry Andric default:
7210b57cec5SDimitry Andric break;
7220b57cec5SDimitry Andric case MCFragment::FT_Align: {
7230b57cec5SDimitry Andric // Don't pad before other alignments
7240b57cec5SDimitry Andric Size = 0;
7250b57cec5SDimitry Andric break;
7260b57cec5SDimitry Andric }
7270b57cec5SDimitry Andric case MCFragment::FT_Relaxable: {
7280b57cec5SDimitry Andric MCContext &Context = Asm.getContext();
7290fca6ea1SDimitry Andric auto &RF = cast<MCRelaxableFragment>(*Frags[K]);
7300b57cec5SDimitry Andric auto &Inst = const_cast<MCInst &>(RF.getInst());
7315ffd83dbSDimitry Andric while (Size > 0 &&
7325ffd83dbSDimitry Andric HexagonMCInstrInfo::bundleSize(Inst) < MaxPacketSize) {
733e8d8bef9SDimitry Andric MCInst *Nop = Context.createMCInst();
7340b57cec5SDimitry Andric Nop->setOpcode(Hexagon::A2_nop);
7350b57cec5SDimitry Andric Inst.addOperand(MCOperand::createInst(Nop));
7360b57cec5SDimitry Andric Size -= 4;
7370b57cec5SDimitry Andric if (!HexagonMCChecker(
7380b57cec5SDimitry Andric Context, *MCII, *RF.getSubtargetInfo(), Inst,
7390b57cec5SDimitry Andric *Context.getRegisterInfo(), false)
7400b57cec5SDimitry Andric .check()) {
7410b57cec5SDimitry Andric Inst.erase(Inst.end() - 1);
7420b57cec5SDimitry Andric Size = 0;
7430b57cec5SDimitry Andric }
7440b57cec5SDimitry Andric }
7450b57cec5SDimitry Andric bool Error = HexagonMCShuffle(Context, true, *MCII,
7460b57cec5SDimitry Andric *RF.getSubtargetInfo(), Inst);
7470b57cec5SDimitry Andric //assert(!Error);
7480b57cec5SDimitry Andric (void)Error;
7490b57cec5SDimitry Andric ReplaceInstruction(Asm.getEmitter(), RF, Inst);
750*52418fc2SDimitry Andric Sec.setHasLayout(false);
7510b57cec5SDimitry Andric Size = 0; // Only look back one instruction
7520b57cec5SDimitry Andric break;
7530b57cec5SDimitry Andric }
7540b57cec5SDimitry Andric }
7550b57cec5SDimitry Andric }
7560b57cec5SDimitry Andric }
7570b57cec5SDimitry Andric }
7580b57cec5SDimitry Andric }
7590b57cec5SDimitry Andric }
7600b57cec5SDimitry Andric }
7610b57cec5SDimitry Andric }; // class HexagonAsmBackend
7620b57cec5SDimitry Andric
7630b57cec5SDimitry Andric } // namespace
7640b57cec5SDimitry Andric
7650b57cec5SDimitry Andric // MCAsmBackend
createHexagonAsmBackend(Target const & T,const MCSubtargetInfo & STI,MCRegisterInfo const &,const MCTargetOptions & Options)7660b57cec5SDimitry Andric MCAsmBackend *llvm::createHexagonAsmBackend(Target const &T,
7670b57cec5SDimitry Andric const MCSubtargetInfo &STI,
7680b57cec5SDimitry Andric MCRegisterInfo const & /*MRI*/,
7690b57cec5SDimitry Andric const MCTargetOptions &Options) {
7700b57cec5SDimitry Andric const Triple &TT = STI.getTargetTriple();
7710b57cec5SDimitry Andric uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TT.getOS());
7720b57cec5SDimitry Andric
7730b57cec5SDimitry Andric StringRef CPUString = Hexagon_MC::selectHexagonCPU(STI.getCPU());
7740b57cec5SDimitry Andric return new HexagonAsmBackend(T, TT, OSABI, CPUString);
7750b57cec5SDimitry Andric }
776