@@ -31,22 +31,6 @@ namespace adjust {
3131
3232using 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);
47- }
48- }
49-
5034static void unsigned_width (unsigned Width, uint64_t Value,
5135 std::string Description, const MCFixup &Fixup,
5236 MCContext *Ctx) {
@@ -74,17 +58,18 @@ static void adjustBranch(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
7458}
7559
7660// / 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 ) {
7963 // Jumps are relative to the current instruction.
8064 Value -= 2 ;
8165
8266 // We have one extra bit of precision because the value is rightshifted by
8367 // one.
8468 Size += 1 ;
8569
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)) {
8873 const int32_t FlashSize = 0x2000 ;
8974 int32_t SignedValue = Value;
9075
@@ -96,10 +81,14 @@ static void adjustRelativeBranch(unsigned Size, const MCFixup &Fixup,
9681 }
9782 }
9883
99- signed_width (Size, Value, std::string (" branch target" ), Fixup, Ctx);
84+ if (!isIntN (Size, Value)) {
85+ return false ;
86+ }
10087
10188 // Rightshifts the value by one.
10289 AVR::fixups::adjustBranchTarget (Value);
90+
91+ return true ;
10392}
10493
10594// / 22-bit absolute fixup.
@@ -126,7 +115,9 @@ static void fixup_call(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
126115// / Offset of 0 (so the result is left shifted by 3 bits before application).
127116static void fixup_7_pcrel (unsigned Size, const MCFixup &Fixup, uint64_t &Value,
128117 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+ }
130121
131122 // Because the value may be negative, we must mask out the sign bits
132123 Value &= 0x7f ;
@@ -140,7 +131,9 @@ static void fixup_7_pcrel(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
140131// / Offset of 0 (so the result isn't left-shifted before application).
141132static void fixup_13_pcrel (unsigned Size, const MCFixup &Fixup, uint64_t &Value,
142133 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+ }
144137
145138 // Because the value may be negative, we must mask out the sign bits
146139 Value &= 0xfff ;
@@ -181,7 +174,7 @@ static void fixup_port5(const MCFixup &Fixup, uint64_t &Value, MCContext *Ctx) {
181174 Value <<= 3 ;
182175}
183176
184- // / 6-bit port number fixup on the `IN` family of instructions.
177+ // / 6-bit port number fixup on the IN family of instructions.
185178// /
186179// / Resolves to:
187180// / 1011 0AAd dddd AAAA
@@ -512,14 +505,25 @@ bool AVRAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count,
512505bool AVRAsmBackend::shouldForceRelocation (const MCAssembler &Asm,
513506 const MCFixup &Fixup,
514507 const MCValue &Target,
508+ const uint64_t Value,
515509 const MCSubtargetInfo *STI) {
516510 switch ((unsigned )Fixup.getKind ()) {
517511 default :
518512 return Fixup.getKind () >= FirstLiteralRelocationKind;
513+
519514 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+
523527 case AVR::fixup_call:
524528 return true ;
525529 }
0 commit comments