Skip to content

Commit 5578970

Browse files
committed
[AVR] Force relocations for non-encodable jumps
1 parent 207e485 commit 5578970

File tree

24 files changed

+108
-57
lines changed

24 files changed

+108
-57
lines changed

llvm/include/llvm/MC/MCAsmBackend.h

+1
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ class MCAsmBackend {
9696
virtual bool shouldForceRelocation(const MCAssembler &Asm,
9797
const MCFixup &Fixup,
9898
const MCValue &Target,
99+
const uint64_t Value,
99100
const MCSubtargetInfo *STI) {
100101
return false;
101102
}

llvm/lib/MC/MCAssembler.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ bool MCAssembler::evaluateFixup(const MCFixup &Fixup, const MCFragment *DF,
222222

223223
// Let the backend force a relocation if needed.
224224
if (IsResolved &&
225-
getBackend().shouldForceRelocation(*this, Fixup, Target, STI)) {
225+
getBackend().shouldForceRelocation(*this, Fixup, Target, Value, STI)) {
226226
IsResolved = false;
227227
WasForced = true;
228228
}

llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ class AArch64AsmBackend : public MCAsmBackend {
9898
unsigned getFixupKindContainereSizeInBytes(unsigned Kind) const;
9999

100100
bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
101-
const MCValue &Target,
101+
const MCValue &Target, const uint64_t Value,
102102
const MCSubtargetInfo *STI) override;
103103
};
104104

@@ -520,6 +520,7 @@ bool AArch64AsmBackend::writeNopData(raw_ostream &OS, uint64_t Count,
520520
bool AArch64AsmBackend::shouldForceRelocation(const MCAssembler &Asm,
521521
const MCFixup &Fixup,
522522
const MCValue &Target,
523+
const uint64_t,
523524
const MCSubtargetInfo *STI) {
524525
unsigned Kind = Fixup.getKind();
525526
if (Kind >= FirstLiteralRelocationKind)

llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUAsmBackend.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ class AMDGPUAsmBackend : public MCAsmBackend {
5353
std::optional<MCFixupKind> getFixupKind(StringRef Name) const override;
5454
const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override;
5555
bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
56-
const MCValue &Target,
56+
const MCValue &Target, uint64_t Value,
5757
const MCSubtargetInfo *STI) override;
5858
};
5959

@@ -196,7 +196,7 @@ const MCFixupKindInfo &AMDGPUAsmBackend::getFixupKindInfo(
196196

197197
bool AMDGPUAsmBackend::shouldForceRelocation(const MCAssembler &,
198198
const MCFixup &Fixup,
199-
const MCValue &,
199+
const MCValue &, const uint64_t,
200200
const MCSubtargetInfo *STI) {
201201
return Fixup.getKind() >= FirstLiteralRelocationKind;
202202
}

llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -955,7 +955,7 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCAssembler &Asm,
955955

956956
bool ARMAsmBackend::shouldForceRelocation(const MCAssembler &Asm,
957957
const MCFixup &Fixup,
958-
const MCValue &Target,
958+
const MCValue &Target, const uint64_t,
959959
const MCSubtargetInfo *STI) {
960960
const MCSymbolRefExpr *A = Target.getSymA();
961961
const MCSymbol *Sym = A ? &A->getSymbol() : nullptr;

llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ class ARMAsmBackend : public MCAsmBackend {
3636
const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override;
3737

3838
bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
39-
const MCValue &Target,
39+
const MCValue &Target, const uint64_t Value,
4040
const MCSubtargetInfo *STI) override;
4141

4242
unsigned adjustFixupValue(const MCAssembler &Asm, const MCFixup &Fixup,

llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.cpp

+64-34
Original file line numberDiff line numberDiff line change
@@ -31,60 +31,72 @@ namespace adjust {
3131

3232
using namespace llvm;
3333

34-
static void signed_width(unsigned Width, uint64_t Value,
35-
std::string Description, const MCFixup &Fixup,
36-
MCContext *Ctx) {
37-
if (!isIntN(Width, Value)) {
38-
std::string Diagnostic = "out of range " + Description;
34+
static bool checkSignedWidth(unsigned Width, uint64_t Value,
35+
std::string Description, const MCFixup &Fixup,
36+
MCContext *Ctx) {
37+
if (isIntN(Width, Value)) {
38+
return true;
39+
}
3940

41+
if (Ctx) {
4042
int64_t Min = minIntN(Width);
4143
int64_t Max = maxIntN(Width);
4244

43-
Diagnostic += " (expected an integer in the range " + std::to_string(Min) +
44-
" to " + std::to_string(Max) + ")";
45-
46-
Ctx->reportError(Fixup.getLoc(), Diagnostic);
45+
Ctx->reportError(Fixup.getLoc(), Twine("out of range ") + Description +
46+
" (expected an integer in the range " +
47+
Twine(Min) + " to " + Twine(Max) +
48+
")");
4749
}
50+
51+
return false;
4852
}
4953

50-
static void unsigned_width(unsigned Width, uint64_t Value,
51-
std::string Description, const MCFixup &Fixup,
52-
MCContext *Ctx) {
53-
if (!isUIntN(Width, Value)) {
54-
std::string Diagnostic = "out of range " + Description;
54+
static bool checkUnsignedWidth(unsigned Width, uint64_t Value,
55+
std::string Description, const MCFixup &Fixup,
56+
MCContext *Ctx) {
57+
if (isUIntN(Width, Value)) {
58+
return true;
59+
}
5560

61+
if (Ctx) {
5662
int64_t Max = maxUIntN(Width);
5763

58-
Diagnostic +=
59-
" (expected an integer in the range 0 to " + std::to_string(Max) + ")";
60-
61-
Ctx->reportError(Fixup.getLoc(), Diagnostic);
64+
Ctx->reportError(Fixup.getLoc(),
65+
Twine("out of range ") + Description +
66+
" (expected an integer in the range 0 to " +
67+
Twine(Max) + ")");
6268
}
69+
70+
return false;
6371
}
6472

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

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

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

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

86-
if (!isIntN(Size, Value) &&
87-
Ctx->getSubtargetInfo()->hasFeature(AVR::FeatureWrappingRjmp)) {
95+
if (!STI) {
96+
STI = Ctx->getSubtargetInfo();
97+
}
98+
99+
if (!isIntN(Size, Value) && STI->hasFeature(AVR::FeatureWrappingRjmp)) {
88100
const int32_t FlashSize = 0x2000;
89101
int32_t SignedValue = Value;
90102

@@ -96,10 +108,15 @@ static void adjustRelativeBranch(unsigned Size, const MCFixup &Fixup,
96108
}
97109
}
98110

99-
signed_width(Size, Value, std::string("branch target"), Fixup, Ctx);
111+
if (!checkSignedWidth(Size, Value, std::string("branch target"), Fixup,
112+
Ctx)) {
113+
return false;
114+
}
100115

101116
// Rightshifts the value by one.
102117
AVR::fixups::adjustBranchTarget(Value);
118+
119+
return true;
103120
}
104121

105122
/// 22-bit absolute fixup.
@@ -152,7 +169,7 @@ static void fixup_13_pcrel(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
152169
/// Resolves to:
153170
/// 10q0 qq10 0000 1qqq
154171
static void fixup_6(const MCFixup &Fixup, uint64_t &Value, MCContext *Ctx) {
155-
unsigned_width(6, Value, std::string("immediate"), Fixup, Ctx);
172+
checkUnsignedWidth(6, Value, std::string("immediate"), Fixup, Ctx);
156173

157174
Value = ((Value & 0x20) << 8) | ((Value & 0x18) << 7) | (Value & 0x07);
158175
}
@@ -164,7 +181,7 @@ static void fixup_6(const MCFixup &Fixup, uint64_t &Value, MCContext *Ctx) {
164181
/// 0000 0000 kk00 kkkk
165182
static void fixup_6_adiw(const MCFixup &Fixup, uint64_t &Value,
166183
MCContext *Ctx) {
167-
unsigned_width(6, Value, std::string("immediate"), Fixup, Ctx);
184+
checkUnsignedWidth(6, Value, std::string("immediate"), Fixup, Ctx);
168185

169186
Value = ((Value & 0x30) << 2) | (Value & 0x0f);
170187
}
@@ -174,7 +191,7 @@ static void fixup_6_adiw(const MCFixup &Fixup, uint64_t &Value,
174191
/// Resolves to:
175192
/// 0000 0000 AAAA A000
176193
static void fixup_port5(const MCFixup &Fixup, uint64_t &Value, MCContext *Ctx) {
177-
unsigned_width(5, Value, std::string("port number"), Fixup, Ctx);
194+
checkUnsignedWidth(5, Value, std::string("port number"), Fixup, Ctx);
178195

179196
Value &= 0x1f;
180197

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

191208
Value = ((Value & 0x30) << 5) | (Value & 0x0f);
192209
}
@@ -197,7 +214,7 @@ static void fixup_port6(const MCFixup &Fixup, uint64_t &Value, MCContext *Ctx) {
197214
/// 1010 ikkk dddd kkkk
198215
static void fixup_lds_sts_16(const MCFixup &Fixup, uint64_t &Value,
199216
MCContext *Ctx) {
200-
unsigned_width(7, Value, std::string("immediate"), Fixup, Ctx);
217+
checkUnsignedWidth(7, Value, std::string("immediate"), Fixup, Ctx);
201218
Value = ((Value & 0x70) << 8) | (Value & 0x0f);
202219
}
203220

@@ -331,13 +348,15 @@ void AVRAsmBackend::adjustFixupValue(const MCFixup &Fixup,
331348
adjust::ldi::ms8(Size, Fixup, Value, Ctx);
332349
break;
333350
case AVR::fixup_16:
334-
adjust::unsigned_width(16, Value, std::string("port number"), Fixup, Ctx);
351+
adjust::checkUnsignedWidth(16, Value, std::string("port number"), Fixup,
352+
Ctx);
335353

336354
Value &= 0xffff;
337355
break;
338356
case AVR::fixup_16_pm:
339357
Value >>= 1; // Flash addresses are always shifted.
340-
adjust::unsigned_width(16, Value, std::string("port number"), Fixup, Ctx);
358+
adjust::checkUnsignedWidth(16, Value, std::string("port number"), Fixup,
359+
Ctx);
341360

342361
Value &= 0xffff;
343362
break;
@@ -512,14 +531,25 @@ bool AVRAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count,
512531
bool AVRAsmBackend::shouldForceRelocation(const MCAssembler &Asm,
513532
const MCFixup &Fixup,
514533
const MCValue &Target,
534+
const uint64_t Value,
515535
const MCSubtargetInfo *STI) {
516536
switch ((unsigned)Fixup.getKind()) {
517537
default:
518538
return Fixup.getKind() >= FirstLiteralRelocationKind;
539+
519540
case AVR::fixup_7_pcrel:
520-
case AVR::fixup_13_pcrel:
521-
// Always resolve relocations for PC-relative branches
522-
return false;
541+
case AVR::fixup_13_pcrel: {
542+
uint64_t ValueEx = Value;
543+
uint64_t Size = AVRAsmBackend::getFixupKindInfo(Fixup.getKind()).TargetSize;
544+
545+
// If the jump is too large to encode it, fall back to a relocation.
546+
//
547+
// Note that trying to actually link that relocation *would* fail, but the
548+
// hopes are that the module we're currently compiling won't be actually
549+
// linked to the final binary.
550+
return !adjust::adjustRelativeBranch(Size, Fixup, ValueEx, nullptr, STI);
551+
}
552+
523553
case AVR::fixup_call:
524554
return true;
525555
}

llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ class AVRAsmBackend : public MCAsmBackend {
5353
const MCSubtargetInfo *STI) const override;
5454

5555
bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
56-
const MCValue &Target,
56+
const MCValue &Target, const uint64_t Value,
5757
const MCSubtargetInfo *STI) override;
5858

5959
private:

llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,7 @@ bool CSKYAsmBackend::mayNeedRelaxation(const MCInst &Inst,
262262
bool CSKYAsmBackend::shouldForceRelocation(const MCAssembler &Asm,
263263
const MCFixup &Fixup,
264264
const MCValue &Target,
265+
const uint64_t /*Value*/,
265266
const MCSubtargetInfo * /*STI*/) {
266267
if (Fixup.getKind() >= FirstLiteralRelocationKind)
267268
return true;

llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ class CSKYAsmBackend : public MCAsmBackend {
5252
const MCSubtargetInfo *STI) const override;
5353

5454
bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
55-
const MCValue &Target,
55+
const MCValue &Target, const uint64_t Value,
5656
const MCSubtargetInfo *STI) override;
5757

5858
std::unique_ptr<MCObjectTargetWriter>

llvm/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ class HexagonAsmBackend : public MCAsmBackend {
201201
}
202202

203203
bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
204-
const MCValue &Target,
204+
const MCValue &Target, const uint64_t,
205205
const MCSubtargetInfo *STI) override {
206206
switch(Fixup.getTargetKind()) {
207207
default:

llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,7 @@ bool LoongArchAsmBackend::shouldInsertFixupForCodeAlign(MCAssembler &Asm,
251251
bool LoongArchAsmBackend::shouldForceRelocation(const MCAssembler &Asm,
252252
const MCFixup &Fixup,
253253
const MCValue &Target,
254+
const uint64_t,
254255
const MCSubtargetInfo *STI) {
255256
if (Fixup.getKind() >= FirstLiteralRelocationKind)
256257
return true;

llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ class LoongArchAsmBackend : public MCAsmBackend {
5757
MCAlignFragment &AF) override;
5858

5959
bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
60-
const MCValue &Target,
60+
const MCValue &Target, const uint64_t Value,
6161
const MCSubtargetInfo *STI) override;
6262

6363
unsigned getNumFixupKinds() const override {

llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,7 @@ bool MipsAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count,
542542
bool MipsAsmBackend::shouldForceRelocation(const MCAssembler &Asm,
543543
const MCFixup &Fixup,
544544
const MCValue &Target,
545+
const uint64_t,
545546
const MCSubtargetInfo *STI) {
546547
if (Fixup.getKind() >= FirstLiteralRelocationKind)
547548
return true;

llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ class MipsAsmBackend : public MCAsmBackend {
5555
const MCSubtargetInfo *STI) const override;
5656

5757
bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
58-
const MCValue &Target,
58+
const MCValue &Target, const uint64_t Value,
5959
const MCSubtargetInfo *STI) override;
6060

6161
bool isMicroMips(const MCSymbol *Sym) const override;

llvm/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ class PPCAsmBackend : public MCAsmBackend {
161161
}
162162

163163
bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
164-
const MCValue &Target,
164+
const MCValue &Target, const uint64_t,
165165
const MCSubtargetInfo *STI) override {
166166
MCFixupKind Kind = Fixup.getKind();
167167
switch ((unsigned)Kind) {

llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ RISCVAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
112112
bool RISCVAsmBackend::shouldForceRelocation(const MCAssembler &Asm,
113113
const MCFixup &Fixup,
114114
const MCValue &Target,
115+
const uint64_t,
115116
const MCSubtargetInfo *STI) {
116117
if (Fixup.getKind() >= FirstLiteralRelocationKind)
117118
return true;
@@ -567,7 +568,7 @@ bool RISCVAsmBackend::evaluateTargetFixup(const MCAssembler &Asm,
567568
Value = Asm.getSymbolOffset(SA) + AUIPCTarget.getConstant();
568569
Value -= Asm.getFragmentOffset(*AUIPCDF) + AUIPCFixup->getOffset();
569570

570-
if (shouldForceRelocation(Asm, *AUIPCFixup, AUIPCTarget, STI)) {
571+
if (shouldForceRelocation(Asm, *AUIPCFixup, AUIPCTarget, Value, STI)) {
571572
WasForced = true;
572573
return false;
573574
}

llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ class RISCVAsmBackend : public MCAsmBackend {
6565
createObjectTargetWriter() const override;
6666

6767
bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
68-
const MCValue &Target,
68+
const MCValue &Target, const uint64_t Value,
6969
const MCSubtargetInfo *STI) override;
7070

7171
bool fixupNeedsRelaxationAdvanced(const MCAssembler &Asm,

llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ namespace {
273273
}
274274

275275
bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
276-
const MCValue &Target,
276+
const MCValue &Target, const uint64_t,
277277
const MCSubtargetInfo *STI) override {
278278
if (Fixup.getKind() >= FirstLiteralRelocationKind)
279279
return true;

0 commit comments

Comments
 (0)