Skip to content

Commit 249c888

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

File tree

24 files changed

+96
-66
lines changed

24 files changed

+96
-66
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

+52-43
Original file line numberDiff line numberDiff line change
@@ -31,60 +31,48 @@ 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;
39-
40-
int64_t Min = minIntN(Width);
41-
int64_t Max = maxIntN(Width);
42-
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);
34+
static bool checkUnsignedWidth(unsigned Width, uint64_t Value,
35+
Twine Description, const MCFixup &Fixup,
36+
MCContext *Ctx) {
37+
if (isUIntN(Width, Value)) {
38+
return true;
4739
}
48-
}
49-
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;
5540

41+
if (Ctx) {
5642
int64_t Max = maxUIntN(Width);
5743

58-
Diagnostic +=
59-
" (expected an integer in the range 0 to " + std::to_string(Max) + ")";
60-
61-
Ctx->reportError(Fixup.getLoc(), Diagnostic);
44+
Ctx->reportError(Fixup.getLoc(),
45+
Twine("out of range ") + Description +
46+
" (expected an integer in the range 0 to " +
47+
Twine(Max) + ")");
6248
}
49+
50+
return false;
6351
}
6452

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

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

7664
/// 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) {
65+
static bool adjustRelativeBranch(unsigned Size, const MCFixup &Fixup,
66+
uint64_t &Value,
67+
const MCSubtargetInfo *STI = nullptr) {
7968
// Jumps are relative to the current instruction.
8069
Value -= 2;
8170

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

86-
if (!isIntN(Size, Value) &&
87-
Ctx->getSubtargetInfo()->hasFeature(AVR::FeatureWrappingRjmp)) {
75+
if (!isIntN(Size, Value) && STI->hasFeature(AVR::FeatureWrappingRjmp)) {
8876
const int32_t FlashSize = 0x2000;
8977
int32_t SignedValue = Value;
9078

@@ -96,10 +84,14 @@ static void adjustRelativeBranch(unsigned Size, const MCFixup &Fixup,
9684
}
9785
}
9886

99-
signed_width(Size, Value, std::string("branch target"), Fixup, Ctx);
87+
if (!isIntN(Size, Value)) {
88+
return false;
89+
}
10090

10191
// Rightshifts the value by one.
10292
AVR::fixups::adjustBranchTarget(Value);
93+
94+
return true;
10395
}
10496

10597
/// 22-bit absolute fixup.
@@ -126,7 +118,9 @@ static void fixup_call(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
126118
/// Offset of 0 (so the result is left shifted by 3 bits before application).
127119
static void fixup_7_pcrel(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
128120
MCContext *Ctx) {
129-
adjustRelativeBranch(Size, Fixup, Value, Ctx);
121+
if (!adjustRelativeBranch(Size, Fixup, Value, Ctx->getSubtargetInfo())) {
122+
llvm_unreachable("should've been emitted as a relocation");
123+
}
130124

131125
// Because the value may be negative, we must mask out the sign bits
132126
Value &= 0x7f;
@@ -140,7 +134,9 @@ static void fixup_7_pcrel(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
140134
/// Offset of 0 (so the result isn't left-shifted before application).
141135
static void fixup_13_pcrel(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
142136
MCContext *Ctx) {
143-
adjustRelativeBranch(Size, Fixup, Value, Ctx);
137+
if (!adjustRelativeBranch(Size, Fixup, Value, Ctx->getSubtargetInfo())) {
138+
llvm_unreachable("should've been emitted as a relocation");
139+
}
144140

145141
// Because the value may be negative, we must mask out the sign bits
146142
Value &= 0xfff;
@@ -152,7 +148,7 @@ static void fixup_13_pcrel(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
152148
/// Resolves to:
153149
/// 10q0 qq10 0000 1qqq
154150
static void fixup_6(const MCFixup &Fixup, uint64_t &Value, MCContext *Ctx) {
155-
unsigned_width(6, Value, std::string("immediate"), Fixup, Ctx);
151+
checkUnsignedWidth(6, Value, std::string("immediate"), Fixup, Ctx);
156152

157153
Value = ((Value & 0x20) << 8) | ((Value & 0x18) << 7) | (Value & 0x07);
158154
}
@@ -164,7 +160,7 @@ static void fixup_6(const MCFixup &Fixup, uint64_t &Value, MCContext *Ctx) {
164160
/// 0000 0000 kk00 kkkk
165161
static void fixup_6_adiw(const MCFixup &Fixup, uint64_t &Value,
166162
MCContext *Ctx) {
167-
unsigned_width(6, Value, std::string("immediate"), Fixup, Ctx);
163+
checkUnsignedWidth(6, Value, std::string("immediate"), Fixup, Ctx);
168164

169165
Value = ((Value & 0x30) << 2) | (Value & 0x0f);
170166
}
@@ -174,19 +170,19 @@ static void fixup_6_adiw(const MCFixup &Fixup, uint64_t &Value,
174170
/// Resolves to:
175171
/// 0000 0000 AAAA A000
176172
static void fixup_port5(const MCFixup &Fixup, uint64_t &Value, MCContext *Ctx) {
177-
unsigned_width(5, Value, std::string("port number"), Fixup, Ctx);
173+
checkUnsignedWidth(5, Value, std::string("port number"), Fixup, Ctx);
178174

179175
Value &= 0x1f;
180176

181177
Value <<= 3;
182178
}
183179

184-
/// 6-bit port number fixup on the `IN` family of instructions.
180+
/// 6-bit port number fixup on the IN family of instructions.
185181
///
186182
/// Resolves to:
187183
/// 1011 0AAd dddd AAAA
188184
static void fixup_port6(const MCFixup &Fixup, uint64_t &Value, MCContext *Ctx) {
189-
unsigned_width(6, Value, std::string("port number"), Fixup, Ctx);
185+
checkUnsignedWidth(6, Value, std::string("port number"), Fixup, Ctx);
190186

191187
Value = ((Value & 0x30) << 5) | (Value & 0x0f);
192188
}
@@ -197,7 +193,7 @@ static void fixup_port6(const MCFixup &Fixup, uint64_t &Value, MCContext *Ctx) {
197193
/// 1010 ikkk dddd kkkk
198194
static void fixup_lds_sts_16(const MCFixup &Fixup, uint64_t &Value,
199195
MCContext *Ctx) {
200-
unsigned_width(7, Value, std::string("immediate"), Fixup, Ctx);
196+
checkUnsignedWidth(7, Value, std::string("immediate"), Fixup, Ctx);
201197
Value = ((Value & 0x70) << 8) | (Value & 0x0f);
202198
}
203199

@@ -331,13 +327,15 @@ void AVRAsmBackend::adjustFixupValue(const MCFixup &Fixup,
331327
adjust::ldi::ms8(Size, Fixup, Value, Ctx);
332328
break;
333329
case AVR::fixup_16:
334-
adjust::unsigned_width(16, Value, std::string("port number"), Fixup, Ctx);
330+
adjust::checkUnsignedWidth(16, Value, std::string("port number"), Fixup,
331+
Ctx);
335332

336333
Value &= 0xffff;
337334
break;
338335
case AVR::fixup_16_pm:
339336
Value >>= 1; // Flash addresses are always shifted.
340-
adjust::unsigned_width(16, Value, std::string("port number"), Fixup, Ctx);
337+
adjust::checkUnsignedWidth(16, Value, std::string("port number"), Fixup,
338+
Ctx);
341339

342340
Value &= 0xffff;
343341
break;
@@ -512,14 +510,25 @@ bool AVRAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count,
512510
bool AVRAsmBackend::shouldForceRelocation(const MCAssembler &Asm,
513511
const MCFixup &Fixup,
514512
const MCValue &Target,
513+
const uint64_t Value,
515514
const MCSubtargetInfo *STI) {
516515
switch ((unsigned)Fixup.getKind()) {
517516
default:
518517
return Fixup.getKind() >= FirstLiteralRelocationKind;
518+
519519
case AVR::fixup_7_pcrel:
520-
case AVR::fixup_13_pcrel:
521-
// Always resolve relocations for PC-relative branches
522-
return false;
520+
case AVR::fixup_13_pcrel: {
521+
uint64_t ValueEx = Value;
522+
uint64_t Size = AVRAsmBackend::getFixupKindInfo(Fixup.getKind()).TargetSize;
523+
524+
// If the jump is too large to encode it, fall back to a relocation.
525+
//
526+
// Note that trying to actually link that relocation *would* fail, but the
527+
// hopes are that the module we're currently compiling won't be actually
528+
// linked to the final binary.
529+
return !adjust::adjustRelativeBranch(Size, Fixup, ValueEx, STI);
530+
}
531+
523532
case AVR::fixup_call:
524533
return true;
525534
}

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)