xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp (revision 52418fc2be8efa5172b90a3a9e617017173612c4)
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 
490b57cec5SDimitry 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:
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>
690b57cec5SDimitry Andric   createObjectTargetWriter() const override {
700b57cec5SDimitry Andric     return createHexagonELFObjectWriter(OSABI, CPU);
710b57cec5SDimitry Andric   }
720b57cec5SDimitry Andric 
730b57cec5SDimitry Andric   void setExtender(MCContext &Context) const {
740b57cec5SDimitry Andric     if (Extender == nullptr)
75e8d8bef9SDimitry Andric       const_cast<HexagonAsmBackend *>(this)->Extender = Context.createMCInst();
760b57cec5SDimitry Andric   }
770b57cec5SDimitry Andric 
780b57cec5SDimitry 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 
850b57cec5SDimitry Andric   unsigned getNumFixupKinds() const override {
860b57cec5SDimitry Andric     return Hexagon::NumTargetFixupKinds;
870b57cec5SDimitry Andric   }
880b57cec5SDimitry Andric 
890b57cec5SDimitry 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 
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.
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.
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 
3910b57cec5SDimitry 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.
4130b57cec5SDimitry 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 
5370b57cec5SDimitry 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.
5630b57cec5SDimitry 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.
5700fca6ea1SDimitry 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 
6465ffd83dbSDimitry 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 
681349cc55cSDimitry 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 
705*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
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