aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp118
1 files changed, 62 insertions, 56 deletions
diff --git a/contrib/llvm-project/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp b/contrib/llvm-project/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
index 1b890fbe041a..716fb67c5824 100644
--- a/contrib/llvm-project/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
+++ b/contrib/llvm-project/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
@@ -1,4 +1,4 @@
-//===-- RISCVAsmBackend.cpp - RISCV Assembler Backend ---------------------===//
+//===-- RISCVAsmBackend.cpp - RISC-V Assembler Backend --------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -19,6 +19,7 @@
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCValue.h"
+#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/EndianStream.h"
#include "llvm/Support/ErrorHandling.h"
@@ -27,6 +28,15 @@
using namespace llvm;
+static cl::opt<bool> RelaxBranches("riscv-asm-relax-branches", cl::init(true),
+ cl::Hidden);
+// Temporary workaround for old linkers that do not support ULEB128 relocations,
+// which are abused by DWARF v5 DW_LLE_offset_pair/DW_RLE_offset_pair
+// implemented in Clang/LLVM.
+static cl::opt<bool> ULEB128Reloc(
+ "riscv-uleb128-reloc", cl::init(true), cl::Hidden,
+ cl::desc("Emit R_RISCV_SET_ULEB128/E_RISCV_SUB_ULEB128 if appropriate"));
+
std::optional<MCFixupKind> RISCVAsmBackend::getFixupKind(StringRef Name) const {
if (STI.getTargetTriple().isOSBinFormatELF()) {
unsigned Type;
@@ -76,24 +86,6 @@ RISCVAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
{"fixup_riscv_call_plt", 0, 64, MCFixupKindInfo::FKF_IsPCRel},
{"fixup_riscv_relax", 0, 0, 0},
{"fixup_riscv_align", 0, 0, 0},
-
- {"fixup_riscv_set_8", 0, 8, 0},
- {"fixup_riscv_add_8", 0, 8, 0},
- {"fixup_riscv_sub_8", 0, 8, 0},
-
- {"fixup_riscv_set_16", 0, 16, 0},
- {"fixup_riscv_add_16", 0, 16, 0},
- {"fixup_riscv_sub_16", 0, 16, 0},
-
- {"fixup_riscv_set_32", 0, 32, 0},
- {"fixup_riscv_add_32", 0, 32, 0},
- {"fixup_riscv_sub_32", 0, 32, 0},
-
- {"fixup_riscv_add_64", 0, 64, 0},
- {"fixup_riscv_sub_64", 0, 64, 0},
-
- {"fixup_riscv_set_6b", 2, 6, 0},
- {"fixup_riscv_sub_6b", 2, 6, 0},
};
static_assert((std::size(Infos)) == RISCV::NumTargetFixupKinds,
"Not all fixup kinds added to Infos array");
@@ -116,7 +108,8 @@ RISCVAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
// necessary for correctness as offsets may change during relaxation.
bool RISCVAsmBackend::shouldForceRelocation(const MCAssembler &Asm,
const MCFixup &Fixup,
- const MCValue &Target) {
+ const MCValue &Target,
+ const MCSubtargetInfo *STI) {
if (Fixup.getKind() >= FirstLiteralRelocationKind)
return true;
switch (Fixup.getTargetKind()) {
@@ -126,6 +119,7 @@ bool RISCVAsmBackend::shouldForceRelocation(const MCAssembler &Asm,
case FK_Data_2:
case FK_Data_4:
case FK_Data_8:
+ case FK_Data_leb128:
if (Target.isAbsolute())
return false;
break;
@@ -135,7 +129,7 @@ bool RISCVAsmBackend::shouldForceRelocation(const MCAssembler &Asm,
return true;
}
- return STI.hasFeature(RISCV::FeatureRelax) || ForceRelocs;
+ return STI->hasFeature(RISCV::FeatureRelax) || ForceRelocs;
}
bool RISCVAsmBackend::fixupNeedsRelaxationAdvanced(const MCFixup &Fixup,
@@ -144,15 +138,12 @@ bool RISCVAsmBackend::fixupNeedsRelaxationAdvanced(const MCFixup &Fixup,
const MCRelaxableFragment *DF,
const MCAsmLayout &Layout,
const bool WasForced) const {
+ if (!RelaxBranches)
+ return false;
+
int64_t Offset = int64_t(Value);
unsigned Kind = Fixup.getTargetKind();
- // We only do conditional branch relaxation when the symbol is resolved.
- // For conditional branch, the immediate must be in the range
- // [-4096, 4094].
- if (Kind == RISCV::fixup_riscv_branch)
- return Resolved && !isInt<13>(Offset);
-
// Return true if the symbol is actually unresolved.
// Resolved could be always false when shouldForceRelocation return true.
// We use !WasForced to indicate that the symbol is unresolved and not forced
@@ -171,6 +162,10 @@ bool RISCVAsmBackend::fixupNeedsRelaxationAdvanced(const MCFixup &Fixup,
// For compressed jump instructions the immediate must be
// in the range [-2048, 2046].
return Offset > 2046 || Offset < -2048;
+ case RISCV::fixup_riscv_branch:
+ // For conditional branch instructions the immediate must be
+ // in the range [-4096, 4095].
+ return !isInt<13>(Offset);
}
}
@@ -251,7 +246,7 @@ bool RISCVAsmBackend::relaxDwarfLineAddr(MCDwarfLineAddrFragment &DF,
OS << uint8_t(dwarf::DW_LNS_fixed_advance_pc);
Offset = OS.tell();
Fixup = RISCV::getRelocPairForSize(2);
- support::endian::write<uint16_t>(OS, 0, support::little);
+ support::endian::write<uint16_t>(OS, 0, llvm::endianness::little);
}
const MCBinaryExpr &MBE = cast<MCBinaryExpr>(AddrDelta);
@@ -301,27 +296,31 @@ bool RISCVAsmBackend::relaxDwarfCFA(MCDwarfCallFrameFragment &DF,
auto AddFixups = [&Fixups, &AddrDelta](unsigned Offset,
std::pair<unsigned, unsigned> Fixup) {
const MCBinaryExpr &MBE = cast<MCBinaryExpr>(AddrDelta);
- Fixups.push_back(MCFixup::create(
- Offset, MBE.getLHS(), static_cast<MCFixupKind>(std::get<0>(Fixup))));
- Fixups.push_back(MCFixup::create(
- Offset, MBE.getRHS(), static_cast<MCFixupKind>(std::get<1>(Fixup))));
+ Fixups.push_back(
+ MCFixup::create(Offset, MBE.getLHS(),
+ static_cast<MCFixupKind>(FirstLiteralRelocationKind +
+ std::get<0>(Fixup))));
+ Fixups.push_back(
+ MCFixup::create(Offset, MBE.getRHS(),
+ static_cast<MCFixupKind>(FirstLiteralRelocationKind +
+ std::get<1>(Fixup))));
};
if (isUIntN(6, Value)) {
OS << uint8_t(dwarf::DW_CFA_advance_loc);
- AddFixups(0, {RISCV::fixup_riscv_set_6b, RISCV::fixup_riscv_sub_6b});
+ AddFixups(0, {ELF::R_RISCV_SET6, ELF::R_RISCV_SUB6});
} else if (isUInt<8>(Value)) {
OS << uint8_t(dwarf::DW_CFA_advance_loc1);
- support::endian::write<uint8_t>(OS, 0, support::little);
- AddFixups(1, {RISCV::fixup_riscv_set_8, RISCV::fixup_riscv_sub_8});
+ support::endian::write<uint8_t>(OS, 0, llvm::endianness::little);
+ AddFixups(1, {ELF::R_RISCV_SET8, ELF::R_RISCV_SUB8});
} else if (isUInt<16>(Value)) {
OS << uint8_t(dwarf::DW_CFA_advance_loc2);
- support::endian::write<uint16_t>(OS, 0, support::little);
- AddFixups(1, {RISCV::fixup_riscv_set_16, RISCV::fixup_riscv_sub_16});
+ support::endian::write<uint16_t>(OS, 0, llvm::endianness::little);
+ AddFixups(1, {ELF::R_RISCV_SET16, ELF::R_RISCV_SUB16});
} else if (isUInt<32>(Value)) {
OS << uint8_t(dwarf::DW_CFA_advance_loc4);
- support::endian::write<uint32_t>(OS, 0, support::little);
- AddFixups(1, {RISCV::fixup_riscv_set_32, RISCV::fixup_riscv_sub_32});
+ support::endian::write<uint32_t>(OS, 0, llvm::endianness::little);
+ AddFixups(1, {ELF::R_RISCV_SET32, ELF::R_RISCV_SUB32});
} else {
llvm_unreachable("unsupported CFA encoding");
}
@@ -330,6 +329,18 @@ bool RISCVAsmBackend::relaxDwarfCFA(MCDwarfCallFrameFragment &DF,
return true;
}
+bool RISCVAsmBackend::relaxLEB128(MCLEBFragment &LF, MCAsmLayout &Layout,
+ int64_t &Value) const {
+ if (LF.isSigned())
+ return false;
+ const MCExpr &Expr = LF.getValue();
+ if (ULEB128Reloc) {
+ LF.getFixups().push_back(
+ MCFixup::create(0, &Expr, FK_Data_leb128, Expr.getLoc()));
+ }
+ return Expr.evaluateKnownAbsolute(Value, Layout);
+}
+
// Given a compressed control flow instruction this function returns
// the expanded instruction.
unsigned RISCVAsmBackend::getRelaxedOpcode(unsigned Op) const {
@@ -400,25 +411,12 @@ static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
case RISCV::fixup_riscv_tls_got_hi20:
case RISCV::fixup_riscv_tls_gd_hi20:
llvm_unreachable("Relocation should be unconditionally forced\n");
- case RISCV::fixup_riscv_set_8:
- case RISCV::fixup_riscv_add_8:
- case RISCV::fixup_riscv_sub_8:
- case RISCV::fixup_riscv_set_16:
- case RISCV::fixup_riscv_add_16:
- case RISCV::fixup_riscv_sub_16:
- case RISCV::fixup_riscv_set_32:
- case RISCV::fixup_riscv_add_32:
- case RISCV::fixup_riscv_sub_32:
- case RISCV::fixup_riscv_add_64:
- case RISCV::fixup_riscv_sub_64:
case FK_Data_1:
case FK_Data_2:
case FK_Data_4:
case FK_Data_8:
- case FK_Data_6b:
+ case FK_Data_leb128:
return Value;
- case RISCV::fixup_riscv_set_6b:
- return Value & 0x03;
case RISCV::fixup_riscv_lo12_i:
case RISCV::fixup_riscv_pcrel_lo12_i:
case RISCV::fixup_riscv_tprel_lo12_i:
@@ -483,6 +481,8 @@ static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
return UpperImm | ((LowerImm << 20) << 32);
}
case RISCV::fixup_riscv_rvc_jump: {
+ if (!isInt<12>(Value))
+ Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
// Need to produce offset[11|4|9:8|10|6|7|3:1|5] from the 11-bit Value.
unsigned Bit11 = (Value >> 11) & 0x1;
unsigned Bit4 = (Value >> 4) & 0x1;
@@ -497,6 +497,8 @@ static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
return Value;
}
case RISCV::fixup_riscv_rvc_branch: {
+ if (!isInt<9>(Value))
+ Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
// Need to produce offset[8|4:3], [reg 3 bit], offset[7:6|2:1|5]
unsigned Bit8 = (Value >> 8) & 0x1;
unsigned Bit7_6 = (Value >> 6) & 0x3;
@@ -513,8 +515,8 @@ static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
bool RISCVAsmBackend::evaluateTargetFixup(
const MCAssembler &Asm, const MCAsmLayout &Layout, const MCFixup &Fixup,
- const MCFragment *DF, const MCValue &Target, uint64_t &Value,
- bool &WasForced) {
+ const MCFragment *DF, const MCValue &Target, const MCSubtargetInfo *STI,
+ uint64_t &Value, bool &WasForced) {
const MCFixup *AUIPCFixup;
const MCFragment *AUIPCDF;
MCValue AUIPCTarget;
@@ -564,7 +566,7 @@ bool RISCVAsmBackend::evaluateTargetFixup(
Value = Layout.getSymbolOffset(SA) + AUIPCTarget.getConstant();
Value -= Layout.getFragmentOffset(AUIPCDF) + AUIPCFixup->getOffset();
- if (shouldForceRelocation(Asm, *AUIPCFixup, AUIPCTarget)) {
+ if (shouldForceRelocation(Asm, *AUIPCFixup, AUIPCTarget, STI)) {
WasForced = true;
return false;
}
@@ -596,6 +598,10 @@ bool RISCVAsmBackend::handleAddSubRelocations(const MCAsmLayout &Layout,
TA = ELF::R_RISCV_ADD64;
TB = ELF::R_RISCV_SUB64;
break;
+ case llvm::FK_Data_leb128:
+ TA = ELF::R_RISCV_SET_ULEB128;
+ TB = ELF::R_RISCV_SUB_ULEB128;
+ break;
default:
llvm_unreachable("unsupported fixup size");
}