diff options
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.cpp | 118 |
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"); } |