@@ -31,22 +31,6 @@ namespace adjust {
31
31
32
32
using namespace llvm ;
33
33
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);
47
- }
48
- }
49
-
50
34
static void unsigned_width (unsigned Width, uint64_t Value,
51
35
std::string Description, const MCFixup &Fixup,
52
36
MCContext *Ctx) {
@@ -74,17 +58,18 @@ static void adjustBranch(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
74
58
}
75
59
76
60
// / 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 ) {
61
+ static bool adjustRelativeBranch (unsigned Size , const MCFixup &Fixup,
62
+ uint64_t &Value, const MCSubtargetInfo *STI ) {
79
63
// Jumps are relative to the current instruction.
80
64
Value -= 2 ;
81
65
82
66
// We have one extra bit of precision because the value is rightshifted by
83
67
// one.
84
68
Size += 1 ;
85
69
86
- if (!isIntN (Size , Value) &&
87
- Ctx->getSubtargetInfo ()->hasFeature (AVR::FeatureWrappingRjmp)) {
70
+ assert (STI && " STI can not be NULL" );
71
+
72
+ if (!isIntN (Size , Value) && STI->hasFeature (AVR::FeatureWrappingRjmp)) {
88
73
const int32_t FlashSize = 0x2000 ;
89
74
int32_t SignedValue = Value;
90
75
@@ -96,10 +81,14 @@ static void adjustRelativeBranch(unsigned Size, const MCFixup &Fixup,
96
81
}
97
82
}
98
83
99
- signed_width (Size , Value, std::string (" branch target" ), Fixup, Ctx);
84
+ if (!isIntN (Size , Value)) {
85
+ return false ;
86
+ }
100
87
101
88
// Rightshifts the value by one.
102
89
AVR::fixups::adjustBranchTarget (Value);
90
+
91
+ return true ;
103
92
}
104
93
105
94
// / 22-bit absolute fixup.
@@ -126,7 +115,9 @@ static void fixup_call(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
126
115
// / Offset of 0 (so the result is left shifted by 3 bits before application).
127
116
static void fixup_7_pcrel (unsigned Size , const MCFixup &Fixup, uint64_t &Value,
128
117
MCContext *Ctx) {
129
- adjustRelativeBranch (Size , Fixup, Value, Ctx);
118
+ if (!adjustRelativeBranch (Size , Fixup, Value, Ctx->getSubtargetInfo ())) {
119
+ llvm_unreachable (" should've been emitted as a relocation" );
120
+ }
130
121
131
122
// Because the value may be negative, we must mask out the sign bits
132
123
Value &= 0x7f ;
@@ -140,7 +131,9 @@ static void fixup_7_pcrel(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
140
131
// / Offset of 0 (so the result isn't left-shifted before application).
141
132
static void fixup_13_pcrel (unsigned Size , const MCFixup &Fixup, uint64_t &Value,
142
133
MCContext *Ctx) {
143
- adjustRelativeBranch (Size , Fixup, Value, Ctx);
134
+ if (!adjustRelativeBranch (Size , Fixup, Value, Ctx->getSubtargetInfo ())) {
135
+ llvm_unreachable (" should've been emitted as a relocation" );
136
+ }
144
137
145
138
// Because the value may be negative, we must mask out the sign bits
146
139
Value &= 0xfff ;
@@ -181,7 +174,7 @@ static void fixup_port5(const MCFixup &Fixup, uint64_t &Value, MCContext *Ctx) {
181
174
Value <<= 3 ;
182
175
}
183
176
184
- // / 6-bit port number fixup on the `IN` family of instructions.
177
+ // / 6-bit port number fixup on the IN family of instructions.
185
178
// /
186
179
// / Resolves to:
187
180
// / 1011 0AAd dddd AAAA
@@ -512,14 +505,25 @@ bool AVRAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count,
512
505
bool AVRAsmBackend::shouldForceRelocation (const MCAssembler &Asm,
513
506
const MCFixup &Fixup,
514
507
const MCValue &Target,
508
+ const uint64_t Value,
515
509
const MCSubtargetInfo *STI) {
516
510
switch ((unsigned )Fixup.getKind ()) {
517
511
default :
518
512
return Fixup.getKind () >= FirstLiteralRelocationKind;
513
+
519
514
case AVR::fixup_7_pcrel:
520
- case AVR::fixup_13_pcrel:
521
- // Always resolve relocations for PC-relative branches
522
- return false ;
515
+ case AVR::fixup_13_pcrel: {
516
+ uint64_t ValueEx = Value;
517
+ uint64_t Size = AVRAsmBackend::getFixupKindInfo (Fixup.getKind ()).TargetSize ;
518
+
519
+ // If the jump is too large to encode it, fall back to a relocation.
520
+ //
521
+ // Note that trying to actually link that relocation *would* fail, but the
522
+ // hopes are that the module we're currently compiling won't be actually
523
+ // linked to the final binary.
524
+ return !adjust::adjustRelativeBranch (Size , Fixup, ValueEx, STI);
525
+ }
526
+
523
527
case AVR::fixup_call:
524
528
return true ;
525
529
}
0 commit comments