brintos

brintos / llvm-project-archived public Read only

0
0
Text · 34.3 KiB · 96e8afc Raw
967 lines · cpp
1//===-- RISCVAsmBackend.cpp - RISC-V 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 "RISCVAsmBackend.h"10#include "RISCVFixupKinds.h"11#include "llvm/ADT/APInt.h"12#include "llvm/MC/MCAsmInfo.h"13#include "llvm/MC/MCAssembler.h"14#include "llvm/MC/MCContext.h"15#include "llvm/MC/MCELFObjectWriter.h"16#include "llvm/MC/MCExpr.h"17#include "llvm/MC/MCObjectWriter.h"18#include "llvm/MC/MCSymbol.h"19#include "llvm/MC/MCValue.h"20#include "llvm/Support/CommandLine.h"21#include "llvm/Support/EndianStream.h"22#include "llvm/Support/ErrorHandling.h"23#include "llvm/Support/LEB128.h"24#include "llvm/Support/raw_ostream.h"25 26using namespace llvm;27 28// Temporary workaround for old linkers that do not support ULEB128 relocations,29// which are abused by DWARF v5 DW_LLE_offset_pair/DW_RLE_offset_pair30// implemented in Clang/LLVM.31static cl::opt<bool> ULEB128Reloc(32    "riscv-uleb128-reloc", cl::init(true), cl::Hidden,33    cl::desc("Emit R_RISCV_SET_ULEB128/E_RISCV_SUB_ULEB128 if appropriate"));34 35static cl::opt<bool>36    AlignRvc("riscv-align-rvc", cl::init(true), cl::Hidden,37             cl::desc("When generating R_RISCV_ALIGN, insert $alignment-2 "38                      "bytes of NOPs even in norvc code"));39 40RISCVAsmBackend::RISCVAsmBackend(const MCSubtargetInfo &STI, uint8_t OSABI,41                                 bool Is64Bit, bool IsLittleEndian,42                                 const MCTargetOptions &Options)43    : MCAsmBackend(IsLittleEndian ? llvm::endianness::little44                                  : llvm::endianness::big),45      STI(STI), OSABI(OSABI), Is64Bit(Is64Bit), TargetOptions(Options) {46  RISCVFeatures::validate(STI.getTargetTriple(), STI.getFeatureBits());47}48 49std::optional<MCFixupKind> RISCVAsmBackend::getFixupKind(StringRef Name) const {50  if (STI.getTargetTriple().isOSBinFormatELF()) {51    unsigned Type;52    Type = llvm::StringSwitch<unsigned>(Name)53#define ELF_RELOC(NAME, ID) .Case(#NAME, ID)54#include "llvm/BinaryFormat/ELFRelocs/RISCV.def"55#undef ELF_RELOC56#define ELF_RISCV_NONSTANDARD_RELOC(_VENDOR, NAME, ID) .Case(#NAME, ID)57#include "llvm/BinaryFormat/ELFRelocs/RISCV_nonstandard.def"58#undef ELF_RISCV_NONSTANDARD_RELOC59               .Case("BFD_RELOC_NONE", ELF::R_RISCV_NONE)60               .Case("BFD_RELOC_32", ELF::R_RISCV_32)61               .Case("BFD_RELOC_64", ELF::R_RISCV_64)62               .Default(-1u);63    if (Type != -1u)64      return static_cast<MCFixupKind>(FirstLiteralRelocationKind + Type);65  }66  return std::nullopt;67}68 69MCFixupKindInfo RISCVAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {70  const static MCFixupKindInfo Infos[] = {71      // This table *must* be in the order that the fixup_* kinds are defined in72      // RISCVFixupKinds.h.73      //74      // name                      offset bits  flags75      {"fixup_riscv_hi20", 12, 20, 0},76      {"fixup_riscv_lo12_i", 20, 12, 0},77      {"fixup_riscv_12_i", 20, 12, 0},78      {"fixup_riscv_lo12_s", 0, 32, 0},79      {"fixup_riscv_pcrel_hi20", 12, 20, 0},80      {"fixup_riscv_pcrel_lo12_i", 20, 12, 0},81      {"fixup_riscv_pcrel_lo12_s", 0, 32, 0},82      {"fixup_riscv_jal", 12, 20, 0},83      {"fixup_riscv_branch", 0, 32, 0},84      {"fixup_riscv_rvc_jump", 2, 11, 0},85      {"fixup_riscv_rvc_branch", 0, 16, 0},86      {"fixup_riscv_rvc_imm", 0, 16, 0},87      {"fixup_riscv_call", 0, 64, 0},88      {"fixup_riscv_call_plt", 0, 64, 0},89 90      {"fixup_riscv_qc_e_branch", 0, 48, 0},91      {"fixup_riscv_qc_e_32", 16, 32, 0},92      {"fixup_riscv_qc_abs20_u", 0, 32, 0},93      {"fixup_riscv_qc_e_call_plt", 0, 48, 0},94 95      // Andes fixups96      {"fixup_riscv_nds_branch_10", 0, 32, 0},97  };98  static_assert((std::size(Infos)) == RISCV::NumTargetFixupKinds,99                "Not all fixup kinds added to Infos array");100 101  // Fixup kinds from raw relocation types and .reloc directives force102  // relocations and do not use these fields.103  if (mc::isRelocation(Kind))104    return {};105 106  if (Kind < FirstTargetFixupKind)107    return MCAsmBackend::getFixupKindInfo(Kind);108 109  assert(unsigned(Kind - FirstTargetFixupKind) < RISCV::NumTargetFixupKinds &&110         "Invalid kind!");111  return Infos[Kind - FirstTargetFixupKind];112}113 114bool RISCVAsmBackend::fixupNeedsRelaxationAdvanced(const MCFragment &,115                                                   const MCFixup &Fixup,116                                                   const MCValue &,117                                                   uint64_t Value,118                                                   bool Resolved) const {119  int64_t Offset = int64_t(Value);120  auto Kind = Fixup.getKind();121 122  // Return true if the symbol is unresolved.123  if (!Resolved)124    return true;125 126  switch (Kind) {127  default:128    return false;129  case RISCV::fixup_riscv_rvc_branch:130    // For compressed branch instructions the immediate must be131    // in the range [-256, 254].132    return Offset > 254 || Offset < -256;133  case RISCV::fixup_riscv_rvc_jump:134    // For compressed jump instructions the immediate must be135    // in the range [-2048, 2046].136    return Offset > 2046 || Offset < -2048;137  case RISCV::fixup_riscv_branch:138  case RISCV::fixup_riscv_qc_e_branch:139    // For conditional branch instructions the immediate must be140    // in the range [-4096, 4094].141    return Offset > 4094 || Offset < -4096;142  case RISCV::fixup_riscv_jal:143    // For jump instructions the immediate must be in the range144    // [-1048576, 1048574]145    return Offset > 1048574 || Offset < -1048576;146  case RISCV::fixup_riscv_rvc_imm:147    // This fixup can never be emitted as a relocation, so always needs to be148    // relaxed.149    return true;150  }151}152 153// Given a compressed control flow instruction this function returns154// the expanded instruction, or the original instruction code if no155// expansion is available.156static unsigned getRelaxedOpcode(unsigned Opcode, ArrayRef<MCOperand> Operands,157                                 const MCSubtargetInfo &STI) {158  switch (Opcode) {159  case RISCV::C_BEQZ:160    return RISCV::BEQ;161  case RISCV::C_BNEZ:162    return RISCV::BNE;163  case RISCV::C_J:164  case RISCV::C_JAL: // fall through.165    // This only relaxes one "step" - i.e. from C.J to JAL, not from C.J to166    // QC.E.J, because we can always relax again if needed.167    return RISCV::JAL;168  case RISCV::C_LI:169    if (!STI.hasFeature(RISCV::FeatureVendorXqcili))170      break;171    // We only need this because `QC.E.LI` can be compressed into a `C.LI`. This172    // happens because the `simm6` MCOperandPredicate accepts bare symbols, and173    // `QC.E.LI` is the only instruction that accepts bare symbols at parse-time174    // and compresses to `C.LI`. `C.LI` does not itself accept bare symbols at175    // parse time.176    //177    // If we have a bare symbol, we need to turn this back to a `QC.E.LI`, as we178    // have no way to emit a relocation on a `C.LI` instruction.179    return RISCV::QC_E_LI;180  case RISCV::JAL: {181    // We can only relax JAL if we have Xqcilb182    if (!STI.hasFeature(RISCV::FeatureVendorXqcilb))183      break;184 185    // And only if it is using X0 or X1 for rd.186    MCRegister Reg = Operands[0].getReg();187    if (Reg == RISCV::X0)188      return RISCV::QC_E_J;189    if (Reg == RISCV::X1)190      return RISCV::QC_E_JAL;191 192    break;193  }194  case RISCV::BEQ:195    return RISCV::PseudoLongBEQ;196  case RISCV::BNE:197    return RISCV::PseudoLongBNE;198  case RISCV::BLT:199    return RISCV::PseudoLongBLT;200  case RISCV::BGE:201    return RISCV::PseudoLongBGE;202  case RISCV::BLTU:203    return RISCV::PseudoLongBLTU;204  case RISCV::BGEU:205    return RISCV::PseudoLongBGEU;206  case RISCV::QC_BEQI:207    return RISCV::PseudoLongQC_BEQI;208  case RISCV::QC_BNEI:209    return RISCV::PseudoLongQC_BNEI;210  case RISCV::QC_BLTI:211    return RISCV::PseudoLongQC_BLTI;212  case RISCV::QC_BGEI:213    return RISCV::PseudoLongQC_BGEI;214  case RISCV::QC_BLTUI:215    return RISCV::PseudoLongQC_BLTUI;216  case RISCV::QC_BGEUI:217    return RISCV::PseudoLongQC_BGEUI;218  case RISCV::QC_E_BEQI:219    return RISCV::PseudoLongQC_E_BEQI;220  case RISCV::QC_E_BNEI:221    return RISCV::PseudoLongQC_E_BNEI;222  case RISCV::QC_E_BLTI:223    return RISCV::PseudoLongQC_E_BLTI;224  case RISCV::QC_E_BGEI:225    return RISCV::PseudoLongQC_E_BGEI;226  case RISCV::QC_E_BLTUI:227    return RISCV::PseudoLongQC_E_BLTUI;228  case RISCV::QC_E_BGEUI:229    return RISCV::PseudoLongQC_E_BGEUI;230  }231 232  // Returning the original opcode means we cannot relax the instruction.233  return Opcode;234}235 236void RISCVAsmBackend::relaxInstruction(MCInst &Inst,237                                       const MCSubtargetInfo &STI) const {238  if (STI.hasFeature(RISCV::FeatureExactAssembly))239    return;240 241  MCInst Res;242  switch (Inst.getOpcode()) {243  default:244    llvm_unreachable("Opcode not expected!");245  case RISCV::C_BEQZ:246  case RISCV::C_BNEZ:247  case RISCV::C_J:248  case RISCV::C_JAL: {249    [[maybe_unused]] bool Success = RISCVRVC::uncompress(Res, Inst, STI);250    assert(Success && "Can't uncompress instruction");251    assert(Res.getOpcode() ==252               getRelaxedOpcode(Inst.getOpcode(), Inst.getOperands(), STI) &&253           "Branch Relaxation Error");254    break;255  }256  case RISCV::JAL: {257    // This has to be written manually because the QC.E.J -> JAL is258    // compression-only, so that it is not used when printing disassembly.259    assert(STI.hasFeature(RISCV::FeatureVendorXqcilb) &&260           "JAL is only relaxable with Xqcilb");261    assert((Inst.getOperand(0).getReg() == RISCV::X0 ||262            Inst.getOperand(0).getReg() == RISCV::X1) &&263           "JAL only relaxable with rd=x0 or rd=x1");264    Res.setOpcode(getRelaxedOpcode(Inst.getOpcode(), Inst.getOperands(), STI));265    Res.addOperand(Inst.getOperand(1));266    break;267  }268  case RISCV::C_LI: {269    // This should only be hit when trying to relax a `C.LI` into a `QC.E.LI`270    // because the `C.LI` has a bare symbol. We cannot use271    // `RISCVRVC::uncompress` because it will use decompression patterns. The272    // `QC.E.LI` compression pattern to `C.LI` is compression-only (because we273    // don't want `c.li` ever printed as `qc.e.li`, which might be done if the274    // pattern applied to decompression), but that doesn't help much becuase275    // `C.LI` with a bare symbol will decompress to an `ADDI` anyway (because276    // `simm12`'s MCOperandPredicate accepts a bare symbol and that pattern277    // comes first), and we still cannot emit an `ADDI` with a bare symbol.278    assert(STI.hasFeature(RISCV::FeatureVendorXqcili) &&279           "C.LI is only relaxable with Xqcili");280    Res.setOpcode(getRelaxedOpcode(Inst.getOpcode(), Inst.getOperands(), STI));281    Res.addOperand(Inst.getOperand(0));282    Res.addOperand(Inst.getOperand(1));283    break;284  }285  case RISCV::BEQ:286  case RISCV::BNE:287  case RISCV::BLT:288  case RISCV::BGE:289  case RISCV::BLTU:290  case RISCV::BGEU:291  case RISCV::QC_BEQI:292  case RISCV::QC_BNEI:293  case RISCV::QC_BLTI:294  case RISCV::QC_BGEI:295  case RISCV::QC_BLTUI:296  case RISCV::QC_BGEUI:297  case RISCV::QC_E_BEQI:298  case RISCV::QC_E_BNEI:299  case RISCV::QC_E_BLTI:300  case RISCV::QC_E_BGEI:301  case RISCV::QC_E_BLTUI:302  case RISCV::QC_E_BGEUI:303    Res.setOpcode(getRelaxedOpcode(Inst.getOpcode(), Inst.getOperands(), STI));304    Res.addOperand(Inst.getOperand(0));305    Res.addOperand(Inst.getOperand(1));306    Res.addOperand(Inst.getOperand(2));307    break;308  }309  Inst = std::move(Res);310}311 312// Check if an R_RISCV_ALIGN relocation is needed for an alignment directive.313// If conditions are met, compute the padding size and create a fixup encoding314// the padding size in the addend.315bool RISCVAsmBackend::relaxAlign(MCFragment &F, unsigned &Size) {316  // Alignments before the first linker-relaxable instruction have fixed sizes317  // and do not require relocations. Alignments after a linker-relaxable318  // instruction require a relocation, even if the STI specifies norelax.319  //320  // firstLinkerRelaxable is the layout order within the subsection, which may321  // be smaller than the section's order. Therefore, alignments in a322  // lower-numbered subsection may be unnecessarily treated as linker-relaxable.323  auto *Sec = F.getParent();324  if (F.getLayoutOrder() <= Sec->firstLinkerRelaxable())325    return false;326 327  // Use default handling unless the alignment is larger than the nop size.328  const MCSubtargetInfo *STI = F.getSubtargetInfo();329  unsigned MinNopLen =330      AlignRvc || STI->hasFeature(RISCV::FeatureStdExtZca) ? 2 : 4;331  if (F.getAlignment() <= MinNopLen)332    return false;333 334  Size = F.getAlignment().value() - MinNopLen;335  auto *Expr = MCConstantExpr::create(Size, getContext());336  MCFixup Fixup =337      MCFixup::create(0, Expr, FirstLiteralRelocationKind + ELF::R_RISCV_ALIGN);338  F.setVarFixups({Fixup});339  F.setLinkerRelaxable();340  return true;341}342 343bool RISCVAsmBackend::relaxDwarfLineAddr(MCFragment &F) const {344  int64_t LineDelta = F.getDwarfLineDelta();345  const MCExpr &AddrDelta = F.getDwarfAddrDelta();346  int64_t Value;347  // If the label difference can be resolved, use the default handling, which348  // utilizes a shorter special opcode.349  if (AddrDelta.evaluateAsAbsolute(Value, *Asm))350    return false;351  [[maybe_unused]] bool IsAbsolute =352      AddrDelta.evaluateKnownAbsolute(Value, *Asm);353  assert(IsAbsolute && "CFA with invalid expression");354 355  SmallVector<char> Data;356  raw_svector_ostream OS(Data);357 358  // INT64_MAX is a signal that this is actually a DW_LNE_end_sequence.359  if (LineDelta != INT64_MAX) {360    OS << uint8_t(dwarf::DW_LNS_advance_line);361    encodeSLEB128(LineDelta, OS);362  }363 364  // According to the DWARF specification, the `DW_LNS_fixed_advance_pc` opcode365  // takes a single unsigned half (unencoded) operand. The maximum encodable366  // value is therefore 65535.  Set a conservative upper bound for relaxation.367  unsigned PCBytes;368  if (Value > 60000) {369    PCBytes = getContext().getAsmInfo()->getCodePointerSize();370    OS << uint8_t(dwarf::DW_LNS_extended_op) << uint8_t(PCBytes + 1)371       << uint8_t(dwarf::DW_LNE_set_address);372    OS.write_zeros(PCBytes);373  } else {374    PCBytes = 2;375    OS << uint8_t(dwarf::DW_LNS_fixed_advance_pc);376    support::endian::write<uint16_t>(OS, 0, Endian);377  }378  auto Offset = OS.tell() - PCBytes;379 380  if (LineDelta == INT64_MAX) {381    OS << uint8_t(dwarf::DW_LNS_extended_op);382    OS << uint8_t(1);383    OS << uint8_t(dwarf::DW_LNE_end_sequence);384  } else {385    OS << uint8_t(dwarf::DW_LNS_copy);386  }387 388  F.setVarContents(Data);389  F.setVarFixups({MCFixup::create(Offset, &AddrDelta,390                                  MCFixup::getDataKindForSize(PCBytes))});391  return true;392}393 394bool RISCVAsmBackend::relaxDwarfCFA(MCFragment &F) const {395  const MCExpr &AddrDelta = F.getDwarfAddrDelta();396  SmallVector<MCFixup, 2> Fixups;397  int64_t Value;398  if (AddrDelta.evaluateAsAbsolute(Value, *Asm))399    return false;400  [[maybe_unused]] bool IsAbsolute =401      AddrDelta.evaluateKnownAbsolute(Value, *Asm);402  assert(IsAbsolute && "CFA with invalid expression");403 404  assert(getContext().getAsmInfo()->getMinInstAlignment() == 1 &&405         "expected 1-byte alignment");406  if (Value == 0) {407    F.clearVarContents();408    F.clearVarFixups();409    return true;410  }411 412  auto AddFixups = [&Fixups, &AddrDelta](unsigned Offset,413                                         std::pair<unsigned, unsigned> Fixup) {414    const MCBinaryExpr &MBE = cast<MCBinaryExpr>(AddrDelta);415    Fixups.push_back(MCFixup::create(Offset, MBE.getLHS(), std::get<0>(Fixup)));416    Fixups.push_back(MCFixup::create(Offset, MBE.getRHS(), std::get<1>(Fixup)));417  };418 419  SmallVector<char, 8> Data;420  raw_svector_ostream OS(Data);421  if (isUIntN(6, Value)) {422    OS << uint8_t(dwarf::DW_CFA_advance_loc);423    AddFixups(0, {ELF::R_RISCV_SET6, ELF::R_RISCV_SUB6});424  } else if (isUInt<8>(Value)) {425    OS << uint8_t(dwarf::DW_CFA_advance_loc1);426    support::endian::write<uint8_t>(OS, 0, Endian);427    AddFixups(1, {ELF::R_RISCV_SET8, ELF::R_RISCV_SUB8});428  } else if (isUInt<16>(Value)) {429    OS << uint8_t(dwarf::DW_CFA_advance_loc2);430    support::endian::write<uint16_t>(OS, 0, Endian);431    AddFixups(1, {ELF::R_RISCV_SET16, ELF::R_RISCV_SUB16});432  } else if (isUInt<32>(Value)) {433    OS << uint8_t(dwarf::DW_CFA_advance_loc4);434    support::endian::write<uint32_t>(OS, 0, Endian);435    AddFixups(1, {ELF::R_RISCV_SET32, ELF::R_RISCV_SUB32});436  } else {437    llvm_unreachable("unsupported CFA encoding");438  }439  F.setVarContents(Data);440  F.setVarFixups(Fixups);441  return true;442}443 444std::pair<bool, bool> RISCVAsmBackend::relaxLEB128(MCFragment &LF,445                                                   int64_t &Value) const {446  if (LF.isLEBSigned())447    return std::make_pair(false, false);448  const MCExpr &Expr = LF.getLEBValue();449  if (ULEB128Reloc) {450    LF.setVarFixups({MCFixup::create(0, &Expr, FK_Data_leb128)});451  }452  return std::make_pair(Expr.evaluateKnownAbsolute(Value, *Asm), false);453}454 455bool RISCVAsmBackend::mayNeedRelaxation(unsigned Opcode,456                                        ArrayRef<MCOperand> Operands,457                                        const MCSubtargetInfo &STI) const {458  // This function has access to two STIs, the member of the AsmBackend, and the459  // one passed as an argument. The latter is more specific, so we query it for460  // specific features.461  if (STI.hasFeature(RISCV::FeatureExactAssembly))462    return false;463 464  return getRelaxedOpcode(Opcode, Operands, STI) != Opcode;465}466 467bool RISCVAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count,468                                   const MCSubtargetInfo *STI) const {469  // We mostly follow binutils' convention here: align to even boundary with a470  // 0-fill padding.  We emit up to 1 2-byte nop, though we use c.nop if RVC is471  // enabled or 0-fill otherwise.  The remainder is now padded with 4-byte nops.472 473  // Instructions always are at even addresses.  We must be in a data area or474  // be unaligned due to some other reason.475  if (Count % 2) {476    OS.write("\0", 1);477    Count -= 1;478  }479 480  // TODO: emit a mapping symbol right here481 482  if (Count % 4 == 2) {483    // The canonical nop with Zca is c.nop. For .balign 4, we generate a 2-byte484    // c.nop even in a norvc region.485    OS.write("\x01\0", 2);486    Count -= 2;487  }488 489  // The canonical nop on RISC-V is addi x0, x0, 0.490  for (; Count >= 4; Count -= 4)491    OS.write("\x13\0\0\0", 4);492 493  return true;494}495 496static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value,497                                 MCContext &Ctx) {498  switch (Fixup.getKind()) {499  default:500    llvm_unreachable("Unknown fixup kind!");501  case FK_Data_1:502  case FK_Data_2:503  case FK_Data_4:504  case FK_Data_8:505  case FK_Data_leb128:506    return Value;507  case RISCV::fixup_riscv_lo12_i:508  case RISCV::fixup_riscv_pcrel_lo12_i:509    return Value & 0xfff;510  case RISCV::fixup_riscv_12_i:511    if (!isInt<12>(Value)) {512      Ctx.reportError(Fixup.getLoc(),513                      "operand must be a constant 12-bit integer");514    }515    return Value & 0xfff;516  case RISCV::fixup_riscv_lo12_s:517  case RISCV::fixup_riscv_pcrel_lo12_s:518    return (((Value >> 5) & 0x7f) << 25) | ((Value & 0x1f) << 7);519  case RISCV::fixup_riscv_hi20:520  case RISCV::fixup_riscv_pcrel_hi20:521    // Add 1 if bit 11 is 1, to compensate for low 12 bits being negative.522    return ((Value + 0x800) >> 12) & 0xfffff;523  case RISCV::fixup_riscv_jal: {524    if (!isInt<21>(Value))525      Ctx.reportError(Fixup.getLoc(), "fixup value out of range");526    if (Value & 0x1)527      Ctx.reportError(Fixup.getLoc(), "fixup value must be 2-byte aligned");528    // Need to produce imm[19|10:1|11|19:12] from the 21-bit Value.529    unsigned Sbit = (Value >> 20) & 0x1;530    unsigned Hi8 = (Value >> 12) & 0xff;531    unsigned Mid1 = (Value >> 11) & 0x1;532    unsigned Lo10 = (Value >> 1) & 0x3ff;533    // Inst{31} = Sbit;534    // Inst{30-21} = Lo10;535    // Inst{20} = Mid1;536    // Inst{19-12} = Hi8;537    Value = (Sbit << 19) | (Lo10 << 9) | (Mid1 << 8) | Hi8;538    return Value;539  }540  case RISCV::fixup_riscv_qc_e_branch:541  case RISCV::fixup_riscv_branch: {542    if (!isInt<13>(Value))543      Ctx.reportError(Fixup.getLoc(), "fixup value out of range");544    if (Value & 0x1)545      Ctx.reportError(Fixup.getLoc(), "fixup value must be 2-byte aligned");546    // Need to extract imm[12], imm[10:5], imm[4:1], imm[11] from the 13-bit547    // Value.548    unsigned Sbit = (Value >> 12) & 0x1;549    unsigned Hi1 = (Value >> 11) & 0x1;550    unsigned Mid6 = (Value >> 5) & 0x3f;551    unsigned Lo4 = (Value >> 1) & 0xf;552    // Inst{31} = Sbit;553    // Inst{30-25} = Mid6;554    // Inst{11-8} = Lo4;555    // Inst{7} = Hi1;556    Value = (Sbit << 31) | (Mid6 << 25) | (Lo4 << 8) | (Hi1 << 7);557    return Value;558  }559  case RISCV::fixup_riscv_call:560  case RISCV::fixup_riscv_call_plt: {561    // Jalr will add UpperImm with the sign-extended 12-bit LowerImm,562    // we need to add 0x800ULL before extract upper bits to reflect the563    // effect of the sign extension.564    uint64_t UpperImm = (Value + 0x800ULL) & 0xfffff000ULL;565    uint64_t LowerImm = Value & 0xfffULL;566    return UpperImm | ((LowerImm << 20) << 32);567  }568  case RISCV::fixup_riscv_rvc_jump: {569    if (!isInt<12>(Value))570      Ctx.reportError(Fixup.getLoc(), "fixup value out of range");571    // Need to produce offset[11|4|9:8|10|6|7|3:1|5] from the 11-bit Value.572    unsigned Bit11  = (Value >> 11) & 0x1;573    unsigned Bit4   = (Value >> 4) & 0x1;574    unsigned Bit9_8 = (Value >> 8) & 0x3;575    unsigned Bit10  = (Value >> 10) & 0x1;576    unsigned Bit6   = (Value >> 6) & 0x1;577    unsigned Bit7   = (Value >> 7) & 0x1;578    unsigned Bit3_1 = (Value >> 1) & 0x7;579    unsigned Bit5   = (Value >> 5) & 0x1;580    Value = (Bit11 << 10) | (Bit4 << 9) | (Bit9_8 << 7) | (Bit10 << 6) |581            (Bit6 << 5) | (Bit7 << 4) | (Bit3_1 << 1) | Bit5;582    return Value;583  }584  case RISCV::fixup_riscv_rvc_branch: {585    if (!isInt<9>(Value))586      Ctx.reportError(Fixup.getLoc(), "fixup value out of range");587    // Need to produce offset[8|4:3], [reg 3 bit], offset[7:6|2:1|5]588    unsigned Bit8   = (Value >> 8) & 0x1;589    unsigned Bit7_6 = (Value >> 6) & 0x3;590    unsigned Bit5   = (Value >> 5) & 0x1;591    unsigned Bit4_3 = (Value >> 3) & 0x3;592    unsigned Bit2_1 = (Value >> 1) & 0x3;593    Value = (Bit8 << 12) | (Bit4_3 << 10) | (Bit7_6 << 5) | (Bit2_1 << 3) |594            (Bit5 << 2);595    return Value;596  }597  case RISCV::fixup_riscv_rvc_imm: {598    if (!isInt<6>(Value))599      Ctx.reportError(Fixup.getLoc(), "fixup value out of range");600    unsigned Bit5 = (Value >> 5) & 0x1;601    unsigned Bit4_0 = Value & 0x1f;602    Value = (Bit5 << 12) | (Bit4_0 << 2);603    return Value;604  }605  case RISCV::fixup_riscv_qc_e_32: {606    if (!isInt<32>(Value))607      Ctx.reportError(Fixup.getLoc(), "fixup value out of range");608    return Value & 0xffffffffu;609  }610  case RISCV::fixup_riscv_qc_abs20_u: {611    if (!isInt<20>(Value))612      Ctx.reportError(Fixup.getLoc(), "fixup value out of range");613    unsigned Bit19 = (Value >> 19) & 0x1;614    unsigned Bit14_0 = Value & 0x7fff;615    unsigned Bit18_15 = (Value >> 15) & 0xf;616    Value = (Bit19 << 31) | (Bit14_0 << 16) | (Bit18_15 << 12);617    return Value;618  }619  case RISCV::fixup_riscv_qc_e_call_plt: {620    if (!isInt<32>(Value))621      Ctx.reportError(Fixup.getLoc(), "fixup value out of range");622    if (Value & 0x1)623      Ctx.reportError(Fixup.getLoc(), "fixup value must be 2-byte aligned");624    uint64_t Bit31_16 = (Value >> 16) & 0xffff;625    uint64_t Bit12 = (Value >> 12) & 0x1;626    uint64_t Bit10_5 = (Value >> 5) & 0x3f;627    uint64_t Bit15_13 = (Value >> 13) & 0x7;628    uint64_t Bit4_1 = (Value >> 1) & 0xf;629    uint64_t Bit11 = (Value >> 11) & 0x1;630    Value = (Bit31_16 << 32ull) | (Bit12 << 31) | (Bit10_5 << 25) |631            (Bit15_13 << 17) | (Bit4_1 << 8) | (Bit11 << 7);632    return Value;633  }634  case RISCV::fixup_riscv_nds_branch_10: {635    if (!isInt<11>(Value))636      Ctx.reportError(Fixup.getLoc(), "fixup value out of range");637    if (Value & 0x1)638      Ctx.reportError(Fixup.getLoc(), "fixup value must be 2-byte aligned");639    // Need to extract imm[10], imm[9:5], imm[4:1] from the 11-bit Value.640    unsigned Sbit = (Value >> 10) & 0x1;641    unsigned Hi5 = (Value >> 5) & 0x1f;642    unsigned Lo4 = (Value >> 1) & 0xf;643    // Inst{31} = Sbit;644    // Inst{29-25} = Hi5;645    // Inst{11-8} = Lo4;646    Value = (Sbit << 31) | (Hi5 << 25) | (Lo4 << 8);647    return Value;648  }649  }650}651 652bool RISCVAsmBackend::isPCRelFixupResolved(const MCSymbol *SymA,653                                           const MCFragment &F) {654  // If the section does not contain linker-relaxable fragments, PC-relative655  // fixups can be resolved.656  if (!F.getParent()->isLinkerRelaxable())657    return true;658 659  // Otherwise, check if the offset between the symbol and fragment is fully660  // resolved, unaffected by linker-relaxable fragments (e.g. instructions or661  // offset-affected FT_Align fragments). Complements the generic662  // isSymbolRefDifferenceFullyResolvedImpl.663  if (!PCRelTemp)664    PCRelTemp = getContext().createTempSymbol();665  PCRelTemp->setFragment(const_cast<MCFragment *>(&F));666  MCValue Res;667  MCExpr::evaluateSymbolicAdd(Asm, false, MCValue::get(SymA),668                              MCValue::get(nullptr, PCRelTemp), Res);669  return !Res.getSubSym();670}671 672// Get the corresponding PC-relative HI fixup that a S_PCREL_LO points to, and673// optionally the fragment containing it.674//675// \returns nullptr if this isn't a S_PCREL_LO pointing to a known PC-relative676// HI fixup.677static const MCFixup *getPCRelHiFixup(const MCSpecifierExpr &Expr,678                                      const MCFragment **DFOut) {679  MCValue AUIPCLoc;680  if (!Expr.getSubExpr()->evaluateAsRelocatable(AUIPCLoc, nullptr))681    return nullptr;682 683  const MCSymbol *AUIPCSymbol = AUIPCLoc.getAddSym();684  if (!AUIPCSymbol)685    return nullptr;686  const auto *DF = AUIPCSymbol->getFragment();687  if (!DF)688    return nullptr;689 690  uint64_t Offset = AUIPCSymbol->getOffset();691  if (DF->getContents().size() == Offset) {692    DF = DF->getNext();693    if (!DF)694      return nullptr;695    Offset = 0;696  }697 698  for (const MCFixup &F : DF->getFixups()) {699    if (F.getOffset() != Offset)700      continue;701    auto Kind = F.getKind();702    if (!mc::isRelocation(F.getKind())) {703      if (Kind == RISCV::fixup_riscv_pcrel_hi20) {704        *DFOut = DF;705        return &F;706      }707      break;708    }709    switch (Kind) {710    case ELF::R_RISCV_GOT_HI20:711    case ELF::R_RISCV_TLS_GOT_HI20:712    case ELF::R_RISCV_TLS_GD_HI20:713    case ELF::R_RISCV_TLSDESC_HI20:714      *DFOut = DF;715      return &F;716    }717  }718 719  return nullptr;720}721 722std::optional<bool> RISCVAsmBackend::evaluateFixup(const MCFragment &,723                                                   MCFixup &Fixup,724                                                   MCValue &Target,725                                                   uint64_t &Value) {726  const MCFixup *AUIPCFixup;727  const MCFragment *AUIPCDF;728  MCValue AUIPCTarget;729  switch (Fixup.getKind()) {730  default:731    // Use default handling for `Value` and `IsResolved`.732    return {};733  case RISCV::fixup_riscv_pcrel_lo12_i:734  case RISCV::fixup_riscv_pcrel_lo12_s: {735    AUIPCFixup =736        getPCRelHiFixup(cast<MCSpecifierExpr>(*Fixup.getValue()), &AUIPCDF);737    if (!AUIPCFixup) {738      getContext().reportError(Fixup.getLoc(),739                               "could not find corresponding %pcrel_hi");740      return true;741    }742 743    // MCAssembler::evaluateFixup will emit an error for this case when it sees744    // the %pcrel_hi, so don't duplicate it when also seeing the %pcrel_lo.745    const MCExpr *AUIPCExpr = AUIPCFixup->getValue();746    if (!AUIPCExpr->evaluateAsRelocatable(AUIPCTarget, Asm))747      return true;748    break;749  }750  }751 752  if (!AUIPCTarget.getAddSym())753    return false;754 755  auto &SA = static_cast<const MCSymbolELF &>(*AUIPCTarget.getAddSym());756  if (SA.isUndefined())757    return false;758 759  bool IsResolved = &SA.getSection() == AUIPCDF->getParent() &&760                    SA.getBinding() == ELF::STB_LOCAL &&761                    SA.getType() != ELF::STT_GNU_IFUNC;762  if (!IsResolved)763    return false;764 765  Value = Asm->getSymbolOffset(SA) + AUIPCTarget.getConstant();766  Value -= Asm->getFragmentOffset(*AUIPCDF) + AUIPCFixup->getOffset();767 768  return AUIPCFixup->getKind() == RISCV::fixup_riscv_pcrel_hi20 &&769         isPCRelFixupResolved(AUIPCTarget.getAddSym(), *AUIPCDF);770}771 772void RISCVAsmBackend::maybeAddVendorReloc(const MCFragment &F,773                                          const MCFixup &Fixup) {774  StringRef VendorIdentifier;775  switch (Fixup.getKind()) {776  default:777    // No Vendor Relocation Required.778    return;779  case RISCV::fixup_riscv_qc_e_branch:780  case RISCV::fixup_riscv_qc_abs20_u:781  case RISCV::fixup_riscv_qc_e_32:782  case RISCV::fixup_riscv_qc_e_call_plt:783    VendorIdentifier = "QUALCOMM";784    break;785  case RISCV::fixup_riscv_nds_branch_10:786    VendorIdentifier = "ANDES";787    break;788  }789 790  // Create a local symbol for the vendor relocation to reference. It's fine if791  // the symbol has the same name as an existing symbol.792  MCContext &Ctx = Asm->getContext();793  MCSymbol *VendorSymbol = Ctx.createLocalSymbol(VendorIdentifier);794  auto [It, Inserted] =795      VendorSymbols.try_emplace(VendorIdentifier, VendorSymbol);796 797  if (Inserted) {798    // Setup the just-created symbol799    VendorSymbol->setVariableValue(MCConstantExpr::create(0, Ctx));800    Asm->registerSymbol(*VendorSymbol);801  } else {802    // Fetch the existing symbol803    VendorSymbol = It->getValue();804  }805 806  MCFixup VendorFixup =807      MCFixup::create(Fixup.getOffset(), nullptr, ELF::R_RISCV_VENDOR);808  // Explicitly create MCValue rather than using an MCExpr and evaluating it so809  // that the absolute vendor symbol is not evaluated to constant 0.810  MCValue VendorTarget = MCValue::get(VendorSymbol);811  uint64_t VendorValue;812  Asm->getWriter().recordRelocation(F, VendorFixup, VendorTarget, VendorValue);813}814 815static bool relaxableFixupNeedsRelocation(const MCFixupKind Kind) {816  // Some Fixups are marked as LinkerRelaxable by817  // `RISCVMCCodeEmitter::getImmOpValue` only because they may be818  // (assembly-)relaxed into a linker-relaxable instruction. This function819  // should return `false` for those fixups so they do not get a `R_RISCV_RELAX`820  // relocation emitted in addition to the relocation.821  switch (Kind) {822  default:823    break;824  case RISCV::fixup_riscv_rvc_jump:825  case RISCV::fixup_riscv_rvc_branch:826  case RISCV::fixup_riscv_rvc_imm:827  case RISCV::fixup_riscv_jal:828    return false;829  }830  return true;831}832 833bool RISCVAsmBackend::addReloc(const MCFragment &F, const MCFixup &Fixup,834                               const MCValue &Target, uint64_t &FixedValue,835                               bool IsResolved) {836  uint64_t FixedValueA, FixedValueB;837  if (Target.getSubSym()) {838    assert(Target.getSpecifier() == 0 &&839           "relocatable SymA-SymB cannot have relocation specifier");840    unsigned TA = 0, TB = 0;841    switch (Fixup.getKind()) {842    case llvm::FK_Data_1:843      TA = ELF::R_RISCV_ADD8;844      TB = ELF::R_RISCV_SUB8;845      break;846    case llvm::FK_Data_2:847      TA = ELF::R_RISCV_ADD16;848      TB = ELF::R_RISCV_SUB16;849      break;850    case llvm::FK_Data_4:851      TA = ELF::R_RISCV_ADD32;852      TB = ELF::R_RISCV_SUB32;853      break;854    case llvm::FK_Data_8:855      TA = ELF::R_RISCV_ADD64;856      TB = ELF::R_RISCV_SUB64;857      break;858    case llvm::FK_Data_leb128:859      TA = ELF::R_RISCV_SET_ULEB128;860      TB = ELF::R_RISCV_SUB_ULEB128;861      break;862    default:863      llvm_unreachable("unsupported fixup size");864    }865    MCValue A = MCValue::get(Target.getAddSym(), nullptr, Target.getConstant());866    MCValue B = MCValue::get(Target.getSubSym());867    auto FA = MCFixup::create(Fixup.getOffset(), nullptr, TA);868    auto FB = MCFixup::create(Fixup.getOffset(), nullptr, TB);869    Asm->getWriter().recordRelocation(F, FA, A, FixedValueA);870    Asm->getWriter().recordRelocation(F, FB, B, FixedValueB);871    FixedValue = FixedValueA - FixedValueB;872    return false;873  }874 875  // If linker relaxation is enabled and supported by the current fixup, then we876  // always want to generate a relocation.877  bool NeedsRelax = Fixup.isLinkerRelaxable() &&878                    relaxableFixupNeedsRelocation(Fixup.getKind());879  if (NeedsRelax)880    IsResolved = false;881 882  if (IsResolved && Fixup.isPCRel())883    IsResolved = isPCRelFixupResolved(Target.getAddSym(), F);884 885  if (!IsResolved) {886    // Some Fixups require a VENDOR relocation, record it (directly) before we887    // add the relocation.888    maybeAddVendorReloc(F, Fixup);889 890    Asm->getWriter().recordRelocation(F, Fixup, Target, FixedValue);891 892    if (NeedsRelax) {893      // Some Fixups get a RELAX relocation, record it (directly) after we add894      // the relocation.895      MCFixup RelaxFixup =896          MCFixup::create(Fixup.getOffset(), nullptr, ELF::R_RISCV_RELAX);897      MCValue RelaxTarget = MCValue::get(nullptr);898      uint64_t RelaxValue;899      Asm->getWriter().recordRelocation(F, RelaxFixup, RelaxTarget, RelaxValue);900    }901  }902 903  return false;904}905 906// Data fixups should be swapped for big endian cores.907// Instruction fixups should not be swapped as RISC-V instructions908// are always little-endian.909static bool isDataFixup(unsigned Kind) {910  switch (Kind) {911  default:912    return false;913 914  case FK_Data_1:915  case FK_Data_2:916  case FK_Data_4:917  case FK_Data_8:918    return true;919  }920}921 922void RISCVAsmBackend::applyFixup(const MCFragment &F, const MCFixup &Fixup,923                                 const MCValue &Target, uint8_t *Data,924                                 uint64_t Value, bool IsResolved) {925  IsResolved = addReloc(F, Fixup, Target, Value, IsResolved);926  MCFixupKind Kind = Fixup.getKind();927  if (mc::isRelocation(Kind))928    return;929  MCContext &Ctx = getContext();930  MCFixupKindInfo Info = getFixupKindInfo(Kind);931  if (!Value)932    return; // Doesn't change encoding.933  // Apply any target-specific value adjustments.934  Value = adjustFixupValue(Fixup, Value, Ctx);935 936  // Shift the value into position.937  Value <<= Info.TargetOffset;938 939  unsigned NumBytes = alignTo(Info.TargetSize + Info.TargetOffset, 8) / 8;940  assert(Fixup.getOffset() + NumBytes <= F.getSize() &&941         "Invalid fixup offset!");942 943  // For each byte of the fragment that the fixup touches, mask in the944  // bits from the fixup value.945  // For big endian cores, data fixup should be swapped.946  bool SwapValue = Endian == llvm::endianness::big && isDataFixup(Kind);947  for (unsigned i = 0; i != NumBytes; ++i) {948    unsigned Idx = SwapValue ? (NumBytes - 1 - i) : i;949    Data[Idx] |= uint8_t((Value >> (i * 8)) & 0xff);950  }951}952 953std::unique_ptr<MCObjectTargetWriter>954RISCVAsmBackend::createObjectTargetWriter() const {955  return createRISCVELFObjectWriter(OSABI, Is64Bit);956}957 958MCAsmBackend *llvm::createRISCVAsmBackend(const Target &T,959                                          const MCSubtargetInfo &STI,960                                          const MCRegisterInfo &MRI,961                                          const MCTargetOptions &Options) {962  const Triple &TT = STI.getTargetTriple();963  uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TT.getOS());964  return new RISCVAsmBackend(STI, OSABI, TT.isArch64Bit(), TT.isLittleEndian(),965                             Options);966}967