brintos

brintos / llvm-project-archived public Read only

0
0
Text · 29.3 KiB · 5a187d2 Raw
786 lines · cpp
1//===-- HexagonAsmBackend.cpp - Hexagon Assembler Backend -----------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "HexagonFixupKinds.h"10#include "MCTargetDesc/HexagonBaseInfo.h"11#include "MCTargetDesc/HexagonMCChecker.h"12#include "MCTargetDesc/HexagonMCCodeEmitter.h"13#include "MCTargetDesc/HexagonMCInstrInfo.h"14#include "MCTargetDesc/HexagonMCShuffler.h"15#include "MCTargetDesc/HexagonMCTargetDesc.h"16#include "llvm/MC/MCAsmBackend.h"17#include "llvm/MC/MCAssembler.h"18#include "llvm/MC/MCContext.h"19#include "llvm/MC/MCELFObjectWriter.h"20#include "llvm/MC/MCInstrInfo.h"21#include "llvm/MC/MCObjectWriter.h"22#include "llvm/MC/MCSubtargetInfo.h"23#include "llvm/MC/TargetRegistry.h"24#include "llvm/Support/Debug.h"25#include "llvm/Support/EndianStream.h"26 27#include <sstream>28 29using namespace llvm;30using namespace Hexagon;31 32#define DEBUG_TYPE "hexagon-asm-backend"33 34static cl::opt<bool> DisableFixup35  ("mno-fixup", cl::desc("Disable fixing up resolved relocations for Hexagon"));36 37namespace {38 39class HexagonAsmBackend : public MCAsmBackend {40  uint8_t OSABI;41  StringRef CPU;42  mutable uint64_t relaxedCnt;43  mutable MCInst RelaxedMCB;44  std::unique_ptr <MCInstrInfo> MCII;45  std::unique_ptr <MCInst *> RelaxTarget;46  MCInst * Extender;47  unsigned MaxPacketSize;48 49  void ReplaceInstruction(MCCodeEmitter &E, MCFragment &RF, MCInst &HMB) const {50    SmallVector<MCFixup, 4> Fixups;51    SmallString<256> Code;52    E.encodeInstruction(HMB, Code, Fixups, *RF.getSubtargetInfo());53 54    // Update the fragment.55    RF.setInst(HMB);56    RF.setVarContents(Code);57    RF.setVarFixups(Fixups);58  }59 60public:61  HexagonAsmBackend(const Target &T, const Triple &TT, uint8_t OSABI,62                    StringRef CPU)63      : MCAsmBackend(llvm::endianness::little), OSABI(OSABI), CPU(CPU),64        relaxedCnt(0), MCII(T.createMCInstrInfo()), RelaxTarget(new MCInst *),65        Extender(nullptr), MaxPacketSize(HexagonMCInstrInfo::packetSize(CPU)) {}66 67  std::unique_ptr<MCObjectTargetWriter>68  createObjectTargetWriter() const override {69    return createHexagonELFObjectWriter(OSABI, CPU);70  }71 72  void setExtender(MCContext &Context) const {73    if (Extender == nullptr)74      const_cast<HexagonAsmBackend *>(this)->Extender = Context.createMCInst();75  }76 77  MCInst *takeExtender() const {78    assert(Extender != nullptr);79    MCInst * Result = Extender;80    const_cast<HexagonAsmBackend *>(this)->Extender = nullptr;81    return Result;82  }83 84  MCFixupKindInfo getFixupKindInfo(MCFixupKind Kind) const override {85    // clang-format off86    const static MCFixupKindInfo Infos[Hexagon::NumTargetFixupKinds] = {87      // This table *must* be in same the order of fixup_* kinds in88      // HexagonFixupKinds.h.89      //90      // namei                          offset  bits    flags91      { "fixup_Hexagon_B22_PCREL",      0,      32,     0 },92      { "fixup_Hexagon_B15_PCREL",      0,      32,     0 },93      { "fixup_Hexagon_B7_PCREL",       0,      32,     0 },94      { "fixup_Hexagon_LO16",           0,      32,     0 },95      { "fixup_Hexagon_HI16",           0,      32,     0 },96      { "fixup_Hexagon_32",             0,      32,     0 },97      { "fixup_Hexagon_16",             0,      32,     0 },98      { "fixup_Hexagon_8",              0,      32,     0 },99      { "fixup_Hexagon_GPREL16_0",      0,      32,     0 },100      { "fixup_Hexagon_GPREL16_1",      0,      32,     0 },101      { "fixup_Hexagon_GPREL16_2",      0,      32,     0 },102      { "fixup_Hexagon_GPREL16_3",      0,      32,     0 },103      { "fixup_Hexagon_HL16",           0,      32,     0 },104      { "fixup_Hexagon_B13_PCREL",      0,      32,     0 },105      { "fixup_Hexagon_B9_PCREL",       0,      32,     0 },106      { "fixup_Hexagon_B32_PCREL_X",    0,      32,     0 },107      { "fixup_Hexagon_32_6_X",         0,      32,     0 },108      { "fixup_Hexagon_B22_PCREL_X",    0,      32,     0 },109      { "fixup_Hexagon_B15_PCREL_X",    0,      32,     0 },110      { "fixup_Hexagon_B13_PCREL_X",    0,      32,     0 },111      { "fixup_Hexagon_B9_PCREL_X",     0,      32,     0 },112      { "fixup_Hexagon_B7_PCREL_X",     0,      32,     0 },113      { "fixup_Hexagon_16_X",           0,      32,     0 },114      { "fixup_Hexagon_12_X",           0,      32,     0 },115      { "fixup_Hexagon_11_X",           0,      32,     0 },116      { "fixup_Hexagon_10_X",           0,      32,     0 },117      { "fixup_Hexagon_9_X",            0,      32,     0 },118      { "fixup_Hexagon_8_X",            0,      32,     0 },119      { "fixup_Hexagon_7_X",            0,      32,     0 },120      { "fixup_Hexagon_6_X",            0,      32,     0 },121      { "fixup_Hexagon_32_PCREL",       0,      32,     0 },122      { "fixup_Hexagon_COPY",           0,      32,     0 },123      { "fixup_Hexagon_GLOB_DAT",       0,      32,     0 },124      { "fixup_Hexagon_JMP_SLOT",       0,      32,     0 },125      { "fixup_Hexagon_RELATIVE",       0,      32,     0 },126      { "fixup_Hexagon_PLT_B22_PCREL",  0,      32,     0 },127      { "fixup_Hexagon_GOTREL_LO16",    0,      32,     0 },128      { "fixup_Hexagon_GOTREL_HI16",    0,      32,     0 },129      { "fixup_Hexagon_GOTREL_32",      0,      32,     0 },130      { "fixup_Hexagon_GOT_LO16",       0,      32,     0 },131      { "fixup_Hexagon_GOT_HI16",       0,      32,     0 },132      { "fixup_Hexagon_GOT_32",         0,      32,     0 },133      { "fixup_Hexagon_GOT_16",         0,      32,     0 },134      { "fixup_Hexagon_DTPMOD_32",      0,      32,     0 },135      { "fixup_Hexagon_DTPREL_LO16",    0,      32,     0 },136      { "fixup_Hexagon_DTPREL_HI16",    0,      32,     0 },137      { "fixup_Hexagon_DTPREL_32",      0,      32,     0 },138      { "fixup_Hexagon_DTPREL_16",      0,      32,     0 },139      { "fixup_Hexagon_GD_PLT_B22_PCREL",0,     32,     0 },140      { "fixup_Hexagon_LD_PLT_B22_PCREL",0,     32,     0 },141      { "fixup_Hexagon_GD_GOT_LO16",    0,      32,     0 },142      { "fixup_Hexagon_GD_GOT_HI16",    0,      32,     0 },143      { "fixup_Hexagon_GD_GOT_32",      0,      32,     0 },144      { "fixup_Hexagon_GD_GOT_16",      0,      32,     0 },145      { "fixup_Hexagon_LD_GOT_LO16",    0,      32,     0 },146      { "fixup_Hexagon_LD_GOT_HI16",    0,      32,     0 },147      { "fixup_Hexagon_LD_GOT_32",      0,      32,     0 },148      { "fixup_Hexagon_LD_GOT_16",      0,      32,     0 },149      { "fixup_Hexagon_IE_LO16",        0,      32,     0 },150      { "fixup_Hexagon_IE_HI16",        0,      32,     0 },151      { "fixup_Hexagon_IE_32",          0,      32,     0 },152      { "fixup_Hexagon_IE_16",          0,      32,     0 },153      { "fixup_Hexagon_IE_GOT_LO16",    0,      32,     0 },154      { "fixup_Hexagon_IE_GOT_HI16",    0,      32,     0 },155      { "fixup_Hexagon_IE_GOT_32",      0,      32,     0 },156      { "fixup_Hexagon_IE_GOT_16",      0,      32,     0 },157      { "fixup_Hexagon_TPREL_LO16",     0,      32,     0 },158      { "fixup_Hexagon_TPREL_HI16",     0,      32,     0 },159      { "fixup_Hexagon_TPREL_32",       0,      32,     0 },160      { "fixup_Hexagon_TPREL_16",       0,      32,     0 },161      { "fixup_Hexagon_6_PCREL_X",      0,      32,     0 },162      { "fixup_Hexagon_GOTREL_32_6_X",  0,      32,     0 },163      { "fixup_Hexagon_GOTREL_16_X",    0,      32,     0 },164      { "fixup_Hexagon_GOTREL_11_X",    0,      32,     0 },165      { "fixup_Hexagon_GOT_32_6_X",     0,      32,     0 },166      { "fixup_Hexagon_GOT_16_X",       0,      32,     0 },167      { "fixup_Hexagon_GOT_11_X",       0,      32,     0 },168      { "fixup_Hexagon_DTPREL_32_6_X",  0,      32,     0 },169      { "fixup_Hexagon_DTPREL_16_X",    0,      32,     0 },170      { "fixup_Hexagon_DTPREL_11_X",    0,      32,     0 },171      { "fixup_Hexagon_GD_GOT_32_6_X",  0,      32,     0 },172      { "fixup_Hexagon_GD_GOT_16_X",    0,      32,     0 },173      { "fixup_Hexagon_GD_GOT_11_X",    0,      32,     0 },174      { "fixup_Hexagon_LD_GOT_32_6_X",  0,      32,     0 },175      { "fixup_Hexagon_LD_GOT_16_X",    0,      32,     0 },176      { "fixup_Hexagon_LD_GOT_11_X",    0,      32,     0 },177      { "fixup_Hexagon_IE_32_6_X",      0,      32,     0 },178      { "fixup_Hexagon_IE_16_X",        0,      32,     0 },179      { "fixup_Hexagon_IE_GOT_32_6_X",  0,      32,     0 },180      { "fixup_Hexagon_IE_GOT_16_X",    0,      32,     0 },181      { "fixup_Hexagon_IE_GOT_11_X",    0,      32,     0 },182      { "fixup_Hexagon_TPREL_32_6_X",   0,      32,     0 },183      { "fixup_Hexagon_TPREL_16_X",     0,      32,     0 },184      { "fixup_Hexagon_TPREL_11_X",     0,      32,     0 },185      { "fixup_Hexagon_GD_PLT_B22_PCREL_X", 0,  32,     0 },186      { "fixup_Hexagon_GD_PLT_B32_PCREL_X", 0,  32,     0 },187      { "fixup_Hexagon_LD_PLT_B22_PCREL_X", 0,  32,     0 },188      { "fixup_Hexagon_LD_PLT_B32_PCREL_X", 0,  32,     0 },189    };190    // clang-format on191 192    if (Kind < FirstTargetFixupKind)193      return MCAsmBackend::getFixupKindInfo(Kind);194 195    assert(unsigned(Kind - FirstTargetFixupKind) <196               Hexagon::NumTargetFixupKinds &&197           "Invalid kind!");198    return Infos[Kind - FirstTargetFixupKind];199  }200 201  bool shouldForceRelocation(const MCFixup &Fixup) {202    switch(Fixup.getKind()) {203      default:204        llvm_unreachable("Unknown Fixup Kind!");205 206      case fixup_Hexagon_LO16:207      case fixup_Hexagon_HI16:208      case fixup_Hexagon_16:209      case fixup_Hexagon_8:210      case fixup_Hexagon_GPREL16_0:211      case fixup_Hexagon_GPREL16_1:212      case fixup_Hexagon_GPREL16_2:213      case fixup_Hexagon_GPREL16_3:214      case fixup_Hexagon_HL16:215      case fixup_Hexagon_32_6_X:216      case fixup_Hexagon_16_X:217      case fixup_Hexagon_12_X:218      case fixup_Hexagon_11_X:219      case fixup_Hexagon_10_X:220      case fixup_Hexagon_9_X:221      case fixup_Hexagon_8_X:222      case fixup_Hexagon_7_X:223      case fixup_Hexagon_6_X:224      case fixup_Hexagon_COPY:225      case fixup_Hexagon_GLOB_DAT:226      case fixup_Hexagon_JMP_SLOT:227      case fixup_Hexagon_RELATIVE:228      case fixup_Hexagon_PLT_B22_PCREL:229      case fixup_Hexagon_GOTREL_LO16:230      case fixup_Hexagon_GOTREL_HI16:231      case fixup_Hexagon_GOTREL_32:232      case fixup_Hexagon_GOT_LO16:233      case fixup_Hexagon_GOT_HI16:234      case fixup_Hexagon_GOT_32:235      case fixup_Hexagon_GOT_16:236      case fixup_Hexagon_DTPMOD_32:237      case fixup_Hexagon_DTPREL_LO16:238      case fixup_Hexagon_DTPREL_HI16:239      case fixup_Hexagon_DTPREL_32:240      case fixup_Hexagon_DTPREL_16:241      case fixup_Hexagon_GD_PLT_B22_PCREL:242      case fixup_Hexagon_LD_PLT_B22_PCREL:243      case fixup_Hexagon_GD_GOT_LO16:244      case fixup_Hexagon_GD_GOT_HI16:245      case fixup_Hexagon_GD_GOT_32:246      case fixup_Hexagon_GD_GOT_16:247      case fixup_Hexagon_LD_GOT_LO16:248      case fixup_Hexagon_LD_GOT_HI16:249      case fixup_Hexagon_LD_GOT_32:250      case fixup_Hexagon_LD_GOT_16:251      case fixup_Hexagon_IE_LO16:252      case fixup_Hexagon_IE_HI16:253      case fixup_Hexagon_IE_32:254      case fixup_Hexagon_IE_16:255      case fixup_Hexagon_IE_GOT_LO16:256      case fixup_Hexagon_IE_GOT_HI16:257      case fixup_Hexagon_IE_GOT_32:258      case fixup_Hexagon_IE_GOT_16:259      case fixup_Hexagon_TPREL_LO16:260      case fixup_Hexagon_TPREL_HI16:261      case fixup_Hexagon_TPREL_32:262      case fixup_Hexagon_TPREL_16:263      case fixup_Hexagon_GOTREL_32_6_X:264      case fixup_Hexagon_GOTREL_16_X:265      case fixup_Hexagon_GOTREL_11_X:266      case fixup_Hexagon_GOT_32_6_X:267      case fixup_Hexagon_GOT_16_X:268      case fixup_Hexagon_GOT_11_X:269      case fixup_Hexagon_DTPREL_32_6_X:270      case fixup_Hexagon_DTPREL_16_X:271      case fixup_Hexagon_DTPREL_11_X:272      case fixup_Hexagon_GD_GOT_32_6_X:273      case fixup_Hexagon_GD_GOT_16_X:274      case fixup_Hexagon_GD_GOT_11_X:275      case fixup_Hexagon_LD_GOT_32_6_X:276      case fixup_Hexagon_LD_GOT_16_X:277      case fixup_Hexagon_LD_GOT_11_X:278      case fixup_Hexagon_IE_32_6_X:279      case fixup_Hexagon_IE_16_X:280      case fixup_Hexagon_IE_GOT_32_6_X:281      case fixup_Hexagon_IE_GOT_16_X:282      case fixup_Hexagon_IE_GOT_11_X:283      case fixup_Hexagon_TPREL_32_6_X:284      case fixup_Hexagon_TPREL_16_X:285      case fixup_Hexagon_TPREL_11_X:286      case fixup_Hexagon_32_PCREL:287      case fixup_Hexagon_6_PCREL_X:288      case fixup_Hexagon_23_REG:289      case fixup_Hexagon_27_REG:290      case fixup_Hexagon_GD_PLT_B22_PCREL_X:291      case fixup_Hexagon_GD_PLT_B32_PCREL_X:292      case fixup_Hexagon_LD_PLT_B22_PCREL_X:293      case fixup_Hexagon_LD_PLT_B32_PCREL_X:294        // These relocations should always have a relocation recorded295        return true;296 297      case fixup_Hexagon_B22_PCREL:298        //IsResolved = false;299        break;300 301      case fixup_Hexagon_B13_PCREL:302      case fixup_Hexagon_B13_PCREL_X:303      case fixup_Hexagon_B32_PCREL_X:304      case fixup_Hexagon_B22_PCREL_X:305      case fixup_Hexagon_B15_PCREL:306      case fixup_Hexagon_B15_PCREL_X:307      case fixup_Hexagon_B9_PCREL:308      case fixup_Hexagon_B9_PCREL_X:309      case fixup_Hexagon_B7_PCREL:310      case fixup_Hexagon_B7_PCREL_X:311        if (DisableFixup)312          return true;313        break;314 315      case FK_Data_1:316      case FK_Data_2:317      case FK_Data_4:318      case fixup_Hexagon_32:319        // Leave these relocations alone as they are used for EH.320        return false;321    }322    return false;323  }324 325  /// getFixupKindNumBytes - The number of bytes the fixup may change.326  static unsigned getFixupKindNumBytes(unsigned Kind) {327    switch (Kind) {328    default:329        return 0;330 331      case FK_Data_1:332        return 1;333      case FK_Data_2:334        return 2;335      case FK_Data_4: // this later gets mapped to R_HEX_32 or R_HEX_32_PCREL336      case fixup_Hexagon_32:337      case fixup_Hexagon_B32_PCREL_X:338      case fixup_Hexagon_B22_PCREL:339      case fixup_Hexagon_B22_PCREL_X:340      case fixup_Hexagon_B15_PCREL:341      case fixup_Hexagon_B15_PCREL_X:342      case fixup_Hexagon_B13_PCREL:343      case fixup_Hexagon_B13_PCREL_X:344      case fixup_Hexagon_B9_PCREL:345      case fixup_Hexagon_B9_PCREL_X:346      case fixup_Hexagon_B7_PCREL:347      case fixup_Hexagon_B7_PCREL_X:348      case fixup_Hexagon_GD_PLT_B32_PCREL_X:349      case fixup_Hexagon_LD_PLT_B32_PCREL_X:350        return 4;351    }352  }353 354  // Make up for left shift when encoding the operand.355  static uint64_t adjustFixupValue(MCFixupKind Kind, uint64_t Value) {356    switch((unsigned)Kind) {357      default:358        break;359 360      case fixup_Hexagon_B7_PCREL:361      case fixup_Hexagon_B9_PCREL:362      case fixup_Hexagon_B13_PCREL:363      case fixup_Hexagon_B15_PCREL:364      case fixup_Hexagon_B22_PCREL:365        Value >>= 2;366        break;367 368      case fixup_Hexagon_B7_PCREL_X:369      case fixup_Hexagon_B9_PCREL_X:370      case fixup_Hexagon_B13_PCREL_X:371      case fixup_Hexagon_B15_PCREL_X:372      case fixup_Hexagon_B22_PCREL_X:373        Value &= 0x3f;374        break;375 376      case fixup_Hexagon_B32_PCREL_X:377      case fixup_Hexagon_GD_PLT_B32_PCREL_X:378      case fixup_Hexagon_LD_PLT_B32_PCREL_X:379        Value >>= 6;380        break;381    }382    return (Value);383  }384 385  void HandleFixupError(const int bits, const int align_bits,386    const int64_t FixupValue, const char *fixupStr) const {387    // Error: value 1124 out of range: -1024-1023 when resolving388    // symbol in file xprtsock.S389    const APInt IntMin = APInt::getSignedMinValue(bits+align_bits);390    const APInt IntMax = APInt::getSignedMaxValue(bits+align_bits);391    std::stringstream errStr;392    errStr << "\nError: value " <<393      FixupValue <<394      " out of range: " <<395      IntMin.getSExtValue() <<396      "-" <<397      IntMax.getSExtValue() <<398      " when resolving " <<399      fixupStr <<400      " fixup\n";401    llvm_unreachable(errStr.str().c_str());402  }403 404  void applyFixup(const MCFragment &, const MCFixup &, const MCValue &,405                  uint8_t *Data, uint64_t FixupValue, bool IsResolved) override;406 407  bool isInstRelaxable(MCInst const &HMI) const {408    const MCInstrDesc &MCID = HexagonMCInstrInfo::getDesc(*MCII, HMI);409    bool Relaxable = false;410    // Branches and loop-setup insns are handled as necessary by relaxation.411    if (llvm::HexagonMCInstrInfo::getType(*MCII, HMI) == HexagonII::TypeJ ||412        (llvm::HexagonMCInstrInfo::getType(*MCII, HMI) == HexagonII::TypeCJ &&413         MCID.isBranch()) ||414        (llvm::HexagonMCInstrInfo::getType(*MCII, HMI) == HexagonII::TypeNCJ &&415         MCID.isBranch()) ||416        (llvm::HexagonMCInstrInfo::getType(*MCII, HMI) == HexagonII::TypeCR &&417         HMI.getOpcode() != Hexagon::C4_addipc))418      if (HexagonMCInstrInfo::isExtendable(*MCII, HMI)) {419        Relaxable = true;420        MCOperand const &Operand =421            HMI.getOperand(HexagonMCInstrInfo::getExtendableOp(*MCII, HMI));422        if (HexagonMCInstrInfo::mustNotExtend(*Operand.getExpr()))423          Relaxable = false;424      }425 426    return Relaxable;427  }428 429  bool mayNeedRelaxation(unsigned Opcode, ArrayRef<MCOperand> Operands,430                         const MCSubtargetInfo &STI) const override {431    RelaxedMCB.clear();432    RelaxedMCB.setOpcode(Opcode);433    RelaxedMCB.setOperands(Operands);434    return true;435  }436 437  /// fixupNeedsRelaxation - Target specific predicate for whether a given438  /// fixup requires the associated instruction to be relaxed.439  bool fixupNeedsRelaxationAdvanced(const MCFragment &F, const MCFixup &Fixup,440                                    const MCValue &, uint64_t Value,441                                    bool Resolved) const override {442    MCInst const &MCB = RelaxedMCB;443    assert(HexagonMCInstrInfo::isBundle(MCB));444 445    *RelaxTarget = nullptr;446    MCInst &MCI = const_cast<MCInst &>(HexagonMCInstrInfo::instruction(447        MCB, (Fixup.getOffset() - F.getFixedSize()) / HEXAGON_INSTR_SIZE));448    bool Relaxable = isInstRelaxable(MCI);449    if (Relaxable == false)450      return false;451    // If we cannot resolve the fixup value, it requires relaxation.452    if (!Resolved) {453      switch (Fixup.getKind()) {454      case fixup_Hexagon_B22_PCREL:455        // GetFixupCount assumes B22 won't relax456        [[fallthrough]];457      default:458        return false;459        break;460      case fixup_Hexagon_B13_PCREL:461      case fixup_Hexagon_B15_PCREL:462      case fixup_Hexagon_B9_PCREL:463      case fixup_Hexagon_B7_PCREL: {464        if (HexagonMCInstrInfo::bundleSize(MCB) < HEXAGON_PACKET_SIZE) {465          ++relaxedCnt;466          *RelaxTarget = &MCI;467          setExtender(getContext());468          return true;469        } else {470          return false;471        }472        break;473      }474      }475    }476 477    MCFixupKind Kind = Fixup.getKind();478    int64_t sValue = Value;479    int64_t maxValue;480 481    switch ((unsigned)Kind) {482    case fixup_Hexagon_B7_PCREL:483      maxValue = 1 << 8;484      break;485    case fixup_Hexagon_B9_PCREL:486      maxValue = 1 << 10;487      break;488    case fixup_Hexagon_B15_PCREL:489      maxValue = 1 << 16;490      break;491    case fixup_Hexagon_B22_PCREL:492      maxValue = 1 << 23;493      break;494    default:495      maxValue = INT64_MAX;496      break;497    }498 499    bool isFarAway = -maxValue > sValue || sValue > maxValue - 1;500 501    if (isFarAway) {502      if (HexagonMCInstrInfo::bundleSize(MCB) < HEXAGON_PACKET_SIZE) {503        ++relaxedCnt;504        *RelaxTarget = &MCI;505        setExtender(getContext());506        return true;507      }508    }509 510    return false;511  }512 513  void relaxInstruction(MCInst &Inst,514                        const MCSubtargetInfo &STI) const override {515    assert(HexagonMCInstrInfo::isBundle(Inst) &&516           "Hexagon relaxInstruction only works on bundles");517 518    MCInst Res;519    Res.setOpcode(Hexagon::BUNDLE);520    Res.addOperand(MCOperand::createImm(Inst.getOperand(0).getImm()));521    // Copy the results into the bundle.522    bool Update = false;523    for (auto &I : HexagonMCInstrInfo::bundleInstructions(Inst)) {524      MCInst &CrntHMI = const_cast<MCInst &>(*I.getInst());525 526      // if immediate extender needed, add it in527      if (*RelaxTarget == &CrntHMI) {528        Update = true;529        assert((HexagonMCInstrInfo::bundleSize(Res) < HEXAGON_PACKET_SIZE) &&530               "No room to insert extender for relaxation");531 532        MCInst *HMIx = takeExtender();533        *HMIx = HexagonMCInstrInfo::deriveExtender(534                *MCII, CrntHMI,535                HexagonMCInstrInfo::getExtendableOperand(*MCII, CrntHMI));536        Res.addOperand(MCOperand::createInst(HMIx));537        *RelaxTarget = nullptr;538      }539      // now copy over the original instruction(the one we may have extended)540      Res.addOperand(MCOperand::createInst(I.getInst()));541    }542 543    Inst = std::move(Res);544    (void)Update;545    assert(Update && "Didn't find relaxation target");546  }547 548  bool writeNopData(raw_ostream &OS, uint64_t Count,549                    const MCSubtargetInfo *STI) const override {550    static const uint32_t Nopcode = 0x7f000000, // Hard-coded NOP.551        ParseIn = 0x00004000,                   // In packet parse-bits.552        ParseEnd = 0x0000c000;                  // End of packet parse-bits.553 554    while (Count % HEXAGON_INSTR_SIZE) {555      LLVM_DEBUG(dbgs() << "Alignment not a multiple of the instruction size:"556                        << Count % HEXAGON_INSTR_SIZE << "/"557                        << HEXAGON_INSTR_SIZE << "\n");558      --Count;559      OS << '\0';560    }561 562    while (Count) {563      Count -= HEXAGON_INSTR_SIZE;564      // Close the packet whenever a multiple of the maximum packet size remains565      uint32_t ParseBits = (Count % (MaxPacketSize * HEXAGON_INSTR_SIZE)) ?566                           ParseIn : ParseEnd;567      support::endian::write<uint32_t>(OS, Nopcode | ParseBits, Endian);568    }569    return true;570  }571 572  bool finishLayout() const override {573    SmallVector<MCFragment *> Frags;574    for (MCSection &Sec : *Asm) {575      Frags.clear();576      for (MCFragment &F : Sec)577        Frags.push_back(&F);578      for (size_t J = 0, E = Frags.size(); J != E; ++J) {579        switch (Frags[J]->getKind()) {580        default:581          break;582        case MCFragment::FT_Align: {583          auto Size = Asm->computeFragmentSize(*Frags[J]);584          for (auto K = J; K != 0 && Size >= HEXAGON_PACKET_SIZE;) {585            --K;586            switch (Frags[K]->getKind()) {587            default:588              break;589            case MCFragment::FT_Align: {590              // Don't pad before other alignments591              Size = 0;592              break;593            }594            case MCFragment::FT_Relaxable: {595              MCContext &Context = getContext();596              auto &RF = *Frags[K];597              MCInst Inst = RF.getInst();598 599              const bool WouldTraverseLabel = llvm::any_of(600                  Asm->symbols(), [&RF, &Inst, Asm = Asm](MCSymbol const &sym) {601                    uint64_t Offset = 0;602                    const bool HasOffset = Asm->getSymbolOffset(sym, Offset);603                    const unsigned PacketSizeBytes =604                        HexagonMCInstrInfo::bundleSize(Inst) *605                        HEXAGON_INSTR_SIZE;606                    const bool OffsetPastSym =607                        Offset <= Asm->getFragmentOffset(RF) + PacketSizeBytes;608                    return !sym.isVariable() && Offset != 0 && HasOffset &&609                           OffsetPastSym;610                  });611              if (WouldTraverseLabel) {612                Size = 0;613                break;614              }615 616              while (Size > 0 &&617                     HexagonMCInstrInfo::bundleSize(Inst) < MaxPacketSize) {618                MCInst *Nop = Context.createMCInst();619                Nop->setOpcode(Hexagon::A2_nop);620                Inst.addOperand(MCOperand::createInst(Nop));621                Size -= 4;622                if (!HexagonMCChecker(623                         Context, *MCII, *RF.getSubtargetInfo(), Inst,624                         *Context.getRegisterInfo(), false)625                         .check()) {626                  Inst.erase(Inst.end() - 1);627                  Size = 0;628                }629              }630              bool Error = HexagonMCShuffle(Context, true, *MCII,631                                            *RF.getSubtargetInfo(), Inst);632              //assert(!Error);633              (void)Error;634              ReplaceInstruction(Asm->getEmitter(), RF, Inst);635              Size = 0; // Only look back one instruction636              break;637            }638            }639          }640        }641        }642      }643    }644    return true;645  }646}; // class HexagonAsmBackend647 648} // namespace649 650void HexagonAsmBackend::applyFixup(const MCFragment &F, const MCFixup &Fixup,651                                   const MCValue &Target, uint8_t *InstAddr,652                                   uint64_t FixupValue, bool IsResolved) {653  if (IsResolved && shouldForceRelocation(Fixup))654    IsResolved = false;655  maybeAddReloc(F, Fixup, Target, FixupValue, IsResolved);656  // When FixupValue is 0 the relocation is external and there657  // is nothing for us to do.658  if (!FixupValue)659    return;660 661  MCFixupKind Kind = Fixup.getKind();662  uint64_t Value;663  uint32_t InstMask;664  uint32_t Reloc;665 666  // LLVM gives us an encoded value, we have to convert it back667  // to a real offset before we can use it.668  unsigned NumBytes = getFixupKindNumBytes(Kind);669  assert(Fixup.getOffset() + NumBytes <= F.getSize() &&670         "Invalid fixup offset!");671 672  Value = adjustFixupValue(Kind, FixupValue);673  if (!Value)674    return;675  int sValue = (int)Value;676 677  switch ((unsigned)Kind) {678  default:679    return;680 681  case fixup_Hexagon_B7_PCREL:682    if (!(isIntN(7, sValue)))683      HandleFixupError(7, 2, (int64_t)FixupValue, "B7_PCREL");684    [[fallthrough]];685  case fixup_Hexagon_B7_PCREL_X:686    InstMask = 0x00001f18;                 // Word32_B7687    Reloc = (((Value >> 2) & 0x1f) << 8) | // Value 6-2 = Target 12-8688            ((Value & 0x3) << 3);          // Value 1-0 = Target 4-3689    break;690 691  case fixup_Hexagon_B9_PCREL:692    if (!(isIntN(9, sValue)))693      HandleFixupError(9, 2, (int64_t)FixupValue, "B9_PCREL");694    [[fallthrough]];695  case fixup_Hexagon_B9_PCREL_X:696    InstMask = 0x003000fe;                 // Word32_B9697    Reloc = (((Value >> 7) & 0x3) << 20) | // Value 8-7 = Target 21-20698            ((Value & 0x7f) << 1);         // Value 6-0 = Target 7-1699    break;700 701    // Since the existing branches that use this relocation cannot be702    // extended, they should only be fixed up if the target is within range.703  case fixup_Hexagon_B13_PCREL:704    if (!(isIntN(13, sValue)))705      HandleFixupError(13, 2, (int64_t)FixupValue, "B13_PCREL");706    [[fallthrough]];707  case fixup_Hexagon_B13_PCREL_X:708    InstMask = 0x00202ffe;                  // Word32_B13709    Reloc = (((Value >> 12) & 0x1) << 21) | // Value 12   = Target 21710            (((Value >> 11) & 0x1) << 13) | // Value 11   = Target 13711            ((Value & 0x7ff) << 1);         // Value 10-0 = Target 11-1712    break;713 714  case fixup_Hexagon_B15_PCREL:715    if (!(isIntN(15, sValue)))716      HandleFixupError(15, 2, (int64_t)FixupValue, "B15_PCREL");717    [[fallthrough]];718  case fixup_Hexagon_B15_PCREL_X:719    InstMask = 0x00df20fe;                  // Word32_B15720    Reloc = (((Value >> 13) & 0x3) << 22) | // Value 14-13 = Target 23-22721            (((Value >> 8) & 0x1f) << 16) | // Value 12-8  = Target 20-16722            (((Value >> 7) & 0x1) << 13) |  // Value 7     = Target 13723            ((Value & 0x7f) << 1);          // Value 6-0   = Target 7-1724    break;725 726  case fixup_Hexagon_B22_PCREL:727    if (!(isIntN(22, sValue)))728      HandleFixupError(22, 2, (int64_t)FixupValue, "B22_PCREL");729    [[fallthrough]];730  case fixup_Hexagon_B22_PCREL_X:731    InstMask = 0x01ff3ffe;                    // Word32_B22732    Reloc = (((Value >> 13) & 0x1ff) << 16) | // Value 21-13 = Target 24-16733            ((Value & 0x1fff) << 1);          // Value 12-0  = Target 13-1734    break;735 736  case fixup_Hexagon_B32_PCREL_X:737    InstMask = 0x0fff3fff;                    // Word32_X26738    Reloc = (((Value >> 14) & 0xfff) << 16) | // Value 25-14 = Target 27-16739            (Value & 0x3fff);                 // Value 13-0  = Target 13-0740    break;741 742  case FK_Data_1:743  case FK_Data_2:744  case FK_Data_4:745  case fixup_Hexagon_32:746    InstMask = 0xffffffff; // Word32747    Reloc = Value;748    break;749  }750 751  LLVM_DEBUG(dbgs() << "Name=" << getFixupKindInfo(Kind).Name << "("752                    << (unsigned)Kind << ")\n");753  LLVM_DEBUG(754      uint32_t OldData = 0; for (unsigned i = 0; i < NumBytes; i++) OldData |=755                            (InstAddr[i] << (i * 8)) & (0xff << (i * 8));756      dbgs() << "\tBValue=0x"; dbgs().write_hex(Value) << ": AValue=0x";757      dbgs().write_hex(FixupValue) << ": Offset=" << Fixup.getOffset()758                                   << ": Size=" << F.getSize() << ": OInst=0x";759      dbgs().write_hex(OldData) << ": Reloc=0x"; dbgs().write_hex(Reloc););760 761  // For each byte of the fragment that the fixup touches, mask in the762  // bits from the fixup value. The Value has been "split up" into the763  // appropriate bitfields above.764  for (unsigned i = 0; i < NumBytes; i++) {765    InstAddr[i] &= uint8_t(~InstMask >> (i * 8)) & 0xff; // Clear reloc bits766    InstAddr[i] |= uint8_t(Reloc >> (i * 8)) & 0xff;     // Apply new reloc767  }768 769  LLVM_DEBUG(uint32_t NewData = 0;770             for (unsigned i = 0; i < NumBytes; i++) NewData |=771             (InstAddr[i] << (i * 8)) & (0xff << (i * 8));772             dbgs() << ": NInst=0x"; dbgs().write_hex(NewData) << "\n";);773}774 775// MCAsmBackend776MCAsmBackend *llvm::createHexagonAsmBackend(Target const &T,777                                            const MCSubtargetInfo &STI,778                                            MCRegisterInfo const & /*MRI*/,779                                            const MCTargetOptions &Options) {780  const Triple &TT = STI.getTargetTriple();781  uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TT.getOS());782 783  StringRef CPUString = Hexagon_MC::selectHexagonCPU(STI.getCPU());784  return new HexagonAsmBackend(T, TT, OSABI, CPUString);785}786