Skip to content

Commit

Permalink
[AVR] Force relocations for non-encodable jumps
Browse files Browse the repository at this point in the history
  • Loading branch information
Patryk27 committed Jan 2, 2025
1 parent 207e485 commit 0f27b8d
Show file tree
Hide file tree
Showing 24 changed files with 102 additions and 47 deletions.
1 change: 1 addition & 0 deletions llvm/include/llvm/MC/MCAsmBackend.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ class MCAsmBackend {
virtual bool shouldForceRelocation(const MCAssembler &Asm,
const MCFixup &Fixup,
const MCValue &Target,
const uint64_t Value,
const MCSubtargetInfo *STI) {
return false;
}
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/MC/MCAssembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ bool MCAssembler::evaluateFixup(const MCFixup &Fixup, const MCFragment *DF,

// Let the backend force a relocation if needed.
if (IsResolved &&
getBackend().shouldForceRelocation(*this, Fixup, Target, STI)) {
getBackend().shouldForceRelocation(*this, Fixup, Target, Value, STI)) {
IsResolved = false;
WasForced = true;
}
Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ class AArch64AsmBackend : public MCAsmBackend {
unsigned getFixupKindContainereSizeInBytes(unsigned Kind) const;

bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
const MCValue &Target,
const MCValue &Target, const uint64_t Value,
const MCSubtargetInfo *STI) override;
};

Expand Down Expand Up @@ -520,6 +520,7 @@ bool AArch64AsmBackend::writeNopData(raw_ostream &OS, uint64_t Count,
bool AArch64AsmBackend::shouldForceRelocation(const MCAssembler &Asm,
const MCFixup &Fixup,
const MCValue &Target,
const uint64_t,
const MCSubtargetInfo *STI) {
unsigned Kind = Fixup.getKind();
if (Kind >= FirstLiteralRelocationKind)
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUAsmBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class AMDGPUAsmBackend : public MCAsmBackend {
std::optional<MCFixupKind> getFixupKind(StringRef Name) const override;
const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override;
bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
const MCValue &Target,
const MCValue &Target, uint64_t Value,
const MCSubtargetInfo *STI) override;
};

Expand Down Expand Up @@ -196,7 +196,7 @@ const MCFixupKindInfo &AMDGPUAsmBackend::getFixupKindInfo(

bool AMDGPUAsmBackend::shouldForceRelocation(const MCAssembler &,
const MCFixup &Fixup,
const MCValue &,
const MCValue &, const uint64_t,
const MCSubtargetInfo *STI) {
return Fixup.getKind() >= FirstLiteralRelocationKind;
}
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -955,7 +955,7 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCAssembler &Asm,

bool ARMAsmBackend::shouldForceRelocation(const MCAssembler &Asm,
const MCFixup &Fixup,
const MCValue &Target,
const MCValue &Target, const uint64_t,
const MCSubtargetInfo *STI) {
const MCSymbolRefExpr *A = Target.getSymA();
const MCSymbol *Sym = A ? &A->getSymbol() : nullptr;
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class ARMAsmBackend : public MCAsmBackend {
const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override;

bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
const MCValue &Target,
const MCValue &Target, const uint64_t Value,
const MCSubtargetInfo *STI) override;

unsigned adjustFixupValue(const MCAssembler &Asm, const MCFixup &Fixup,
Expand Down
82 changes: 58 additions & 24 deletions llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,14 @@ namespace adjust {

using namespace llvm;

static void signed_width(unsigned Width, uint64_t Value,
std::string Description, const MCFixup &Fixup,
MCContext *Ctx) {
if (!isIntN(Width, Value)) {
static bool checkSignedWidth(unsigned Width, uint64_t Value,
std::string Description, const MCFixup &Fixup,
MCContext *Ctx) {
if (isIntN(Width, Value)) {
return true;
}

if (Ctx) {
std::string Diagnostic = "out of range " + Description;

int64_t Min = minIntN(Width);
Expand All @@ -45,12 +49,18 @@ static void signed_width(unsigned Width, uint64_t Value,

Ctx->reportError(Fixup.getLoc(), Diagnostic);
}

return false;
}

static void unsigned_width(unsigned Width, uint64_t Value,
std::string Description, const MCFixup &Fixup,
MCContext *Ctx) {
if (!isUIntN(Width, Value)) {
static bool checkUnsignedWidth(unsigned Width, uint64_t Value,
std::string Description, const MCFixup &Fixup,
MCContext *Ctx) {
if (isUIntN(Width, Value)) {
return true;
}

if (Ctx) {
std::string Diagnostic = "out of range " + Description;

int64_t Max = maxUIntN(Width);
Expand All @@ -60,31 +70,37 @@ static void unsigned_width(unsigned Width, uint64_t Value,

Ctx->reportError(Fixup.getLoc(), Diagnostic);
}

return false;
}

/// Adjusts the value of a branch target before fixup application.
static void adjustBranch(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
MCContext *Ctx) {
// We have one extra bit of precision because the value is rightshifted by
// one.
unsigned_width(Size + 1, Value, std::string("branch target"), Fixup, Ctx);
checkUnsignedWidth(Size + 1, Value, std::string("branch target"), Fixup, Ctx);

// Rightshifts the value by one.
AVR::fixups::adjustBranchTarget(Value);
}

/// Adjusts the value of a relative branch target before fixup application.
static void adjustRelativeBranch(unsigned Size, const MCFixup &Fixup,
uint64_t &Value, MCContext *Ctx) {
static bool adjustRelativeBranch(unsigned Size, const MCFixup &Fixup,
uint64_t &Value, MCContext *Ctx,
const MCSubtargetInfo *STI = nullptr) {
// Jumps are relative to the current instruction.
Value -= 2;

// We have one extra bit of precision because the value is rightshifted by
// one.
Size += 1;

if (!isIntN(Size, Value) &&
Ctx->getSubtargetInfo()->hasFeature(AVR::FeatureWrappingRjmp)) {
if (!STI) {
STI = Ctx->getSubtargetInfo();
}

if (!isIntN(Size, Value) && STI->hasFeature(AVR::FeatureWrappingRjmp)) {
const int32_t FlashSize = 0x2000;
int32_t SignedValue = Value;

Expand All @@ -96,10 +112,15 @@ static void adjustRelativeBranch(unsigned Size, const MCFixup &Fixup,
}
}

signed_width(Size, Value, std::string("branch target"), Fixup, Ctx);
if (!checkSignedWidth(Size, Value, std::string("branch target"), Fixup,
Ctx)) {
return false;
}

// Rightshifts the value by one.
AVR::fixups::adjustBranchTarget(Value);

return true;
}

/// 22-bit absolute fixup.
Expand Down Expand Up @@ -152,7 +173,7 @@ static void fixup_13_pcrel(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
/// Resolves to:
/// 10q0 qq10 0000 1qqq
static void fixup_6(const MCFixup &Fixup, uint64_t &Value, MCContext *Ctx) {
unsigned_width(6, Value, std::string("immediate"), Fixup, Ctx);
checkUnsignedWidth(6, Value, std::string("immediate"), Fixup, Ctx);

Value = ((Value & 0x20) << 8) | ((Value & 0x18) << 7) | (Value & 0x07);
}
Expand All @@ -164,7 +185,7 @@ static void fixup_6(const MCFixup &Fixup, uint64_t &Value, MCContext *Ctx) {
/// 0000 0000 kk00 kkkk
static void fixup_6_adiw(const MCFixup &Fixup, uint64_t &Value,
MCContext *Ctx) {
unsigned_width(6, Value, std::string("immediate"), Fixup, Ctx);
checkUnsignedWidth(6, Value, std::string("immediate"), Fixup, Ctx);

Value = ((Value & 0x30) << 2) | (Value & 0x0f);
}
Expand All @@ -174,7 +195,7 @@ static void fixup_6_adiw(const MCFixup &Fixup, uint64_t &Value,
/// Resolves to:
/// 0000 0000 AAAA A000
static void fixup_port5(const MCFixup &Fixup, uint64_t &Value, MCContext *Ctx) {
unsigned_width(5, Value, std::string("port number"), Fixup, Ctx);
checkUnsignedWidth(5, Value, std::string("port number"), Fixup, Ctx);

Value &= 0x1f;

Expand All @@ -186,7 +207,7 @@ static void fixup_port5(const MCFixup &Fixup, uint64_t &Value, MCContext *Ctx) {
/// Resolves to:
/// 1011 0AAd dddd AAAA
static void fixup_port6(const MCFixup &Fixup, uint64_t &Value, MCContext *Ctx) {
unsigned_width(6, Value, std::string("port number"), Fixup, Ctx);
checkUnsignedWidth(6, Value, std::string("port number"), Fixup, Ctx);

Value = ((Value & 0x30) << 5) | (Value & 0x0f);
}
Expand All @@ -197,7 +218,7 @@ static void fixup_port6(const MCFixup &Fixup, uint64_t &Value, MCContext *Ctx) {
/// 1010 ikkk dddd kkkk
static void fixup_lds_sts_16(const MCFixup &Fixup, uint64_t &Value,
MCContext *Ctx) {
unsigned_width(7, Value, std::string("immediate"), Fixup, Ctx);
checkUnsignedWidth(7, Value, std::string("immediate"), Fixup, Ctx);
Value = ((Value & 0x70) << 8) | (Value & 0x0f);
}

Expand Down Expand Up @@ -331,13 +352,15 @@ void AVRAsmBackend::adjustFixupValue(const MCFixup &Fixup,
adjust::ldi::ms8(Size, Fixup, Value, Ctx);
break;
case AVR::fixup_16:
adjust::unsigned_width(16, Value, std::string("port number"), Fixup, Ctx);
adjust::checkUnsignedWidth(16, Value, std::string("port number"), Fixup,
Ctx);

Value &= 0xffff;
break;
case AVR::fixup_16_pm:
Value >>= 1; // Flash addresses are always shifted.
adjust::unsigned_width(16, Value, std::string("port number"), Fixup, Ctx);
adjust::checkUnsignedWidth(16, Value, std::string("port number"), Fixup,
Ctx);

Value &= 0xffff;
break;
Expand Down Expand Up @@ -512,14 +535,25 @@ bool AVRAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count,
bool AVRAsmBackend::shouldForceRelocation(const MCAssembler &Asm,
const MCFixup &Fixup,
const MCValue &Target,
const uint64_t Value,
const MCSubtargetInfo *STI) {
switch ((unsigned)Fixup.getKind()) {
default:
return Fixup.getKind() >= FirstLiteralRelocationKind;

case AVR::fixup_7_pcrel:
case AVR::fixup_13_pcrel:
// Always resolve relocations for PC-relative branches
return false;
case AVR::fixup_13_pcrel: {
uint64_t ValueEx = Value;
uint64_t Size = AVRAsmBackend::getFixupKindInfo(Fixup.getKind()).TargetSize;

// If the jump is too large to encode it, fall back to a relocation.
//
// Note that trying to actually link that relocation *would* fail, but the
// hopes are that the module we're currently compiling won't be actually
// linked to the final binary.
return !adjust::adjustRelativeBranch(Size, Fixup, ValueEx, nullptr, STI);
}

case AVR::fixup_call:
return true;
}
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class AVRAsmBackend : public MCAsmBackend {
const MCSubtargetInfo *STI) const override;

bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
const MCValue &Target,
const MCValue &Target, const uint64_t Value,
const MCSubtargetInfo *STI) override;

private:
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@ bool CSKYAsmBackend::mayNeedRelaxation(const MCInst &Inst,
bool CSKYAsmBackend::shouldForceRelocation(const MCAssembler &Asm,
const MCFixup &Fixup,
const MCValue &Target,
const uint64_t /*Value*/,
const MCSubtargetInfo * /*STI*/) {
if (Fixup.getKind() >= FirstLiteralRelocationKind)
return true;
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class CSKYAsmBackend : public MCAsmBackend {
const MCSubtargetInfo *STI) const override;

bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
const MCValue &Target,
const MCValue &Target, const uint64_t Value,
const MCSubtargetInfo *STI) override;

std::unique_ptr<MCObjectTargetWriter>
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ class HexagonAsmBackend : public MCAsmBackend {
}

bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
const MCValue &Target,
const MCValue &Target, const uint64_t,
const MCSubtargetInfo *STI) override {
switch(Fixup.getTargetKind()) {
default:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ bool LoongArchAsmBackend::shouldInsertFixupForCodeAlign(MCAssembler &Asm,
bool LoongArchAsmBackend::shouldForceRelocation(const MCAssembler &Asm,
const MCFixup &Fixup,
const MCValue &Target,
const uint64_t,
const MCSubtargetInfo *STI) {
if (Fixup.getKind() >= FirstLiteralRelocationKind)
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ class LoongArchAsmBackend : public MCAsmBackend {
MCAlignFragment &AF) override;

bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
const MCValue &Target,
const MCValue &Target, const uint64_t Value,
const MCSubtargetInfo *STI) override;

unsigned getNumFixupKinds() const override {
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,7 @@ bool MipsAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count,
bool MipsAsmBackend::shouldForceRelocation(const MCAssembler &Asm,
const MCFixup &Fixup,
const MCValue &Target,
const uint64_t,
const MCSubtargetInfo *STI) {
if (Fixup.getKind() >= FirstLiteralRelocationKind)
return true;
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class MipsAsmBackend : public MCAsmBackend {
const MCSubtargetInfo *STI) const override;

bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
const MCValue &Target,
const MCValue &Target, const uint64_t Value,
const MCSubtargetInfo *STI) override;

bool isMicroMips(const MCSymbol *Sym) const override;
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ class PPCAsmBackend : public MCAsmBackend {
}

bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
const MCValue &Target,
const MCValue &Target, const uint64_t,
const MCSubtargetInfo *STI) override {
MCFixupKind Kind = Fixup.getKind();
switch ((unsigned)Kind) {
Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ RISCVAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
bool RISCVAsmBackend::shouldForceRelocation(const MCAssembler &Asm,
const MCFixup &Fixup,
const MCValue &Target,
const uint64_t,
const MCSubtargetInfo *STI) {
if (Fixup.getKind() >= FirstLiteralRelocationKind)
return true;
Expand Down Expand Up @@ -567,7 +568,7 @@ bool RISCVAsmBackend::evaluateTargetFixup(const MCAssembler &Asm,
Value = Asm.getSymbolOffset(SA) + AUIPCTarget.getConstant();
Value -= Asm.getFragmentOffset(*AUIPCDF) + AUIPCFixup->getOffset();

if (shouldForceRelocation(Asm, *AUIPCFixup, AUIPCTarget, STI)) {
if (shouldForceRelocation(Asm, *AUIPCFixup, AUIPCTarget, Value, STI)) {
WasForced = true;
return false;
}
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class RISCVAsmBackend : public MCAsmBackend {
createObjectTargetWriter() const override;

bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
const MCValue &Target,
const MCValue &Target, const uint64_t Value,
const MCSubtargetInfo *STI) override;

bool fixupNeedsRelaxationAdvanced(const MCAssembler &Asm,
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ namespace {
}

bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
const MCValue &Target,
const MCValue &Target, const uint64_t,
const MCSubtargetInfo *STI) override {
if (Fixup.getKind() >= FirstLiteralRelocationKind)
return true;
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ class SystemZMCAsmBackend : public MCAsmBackend {
std::optional<MCFixupKind> getFixupKind(StringRef Name) const override;
const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override;
bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
const MCValue &Target,
const MCValue &Target, const uint64_t Value,
const MCSubtargetInfo *STI) override;
void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
const MCValue &Target, MutableArrayRef<char> Data,
Expand Down Expand Up @@ -161,7 +161,7 @@ SystemZMCAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {

bool SystemZMCAsmBackend::shouldForceRelocation(const MCAssembler &,
const MCFixup &Fixup,
const MCValue &,
const MCValue &, const uint64_t,
const MCSubtargetInfo *STI) {
return Fixup.getKind() >= FirstLiteralRelocationKind;
}
Expand Down
Loading

0 comments on commit 0f27b8d

Please sign in to comment.