2727#include " llvm/Support/MathExtras.h"
2828#include " llvm/Support/raw_ostream.h"
2929
30- // FIXME: we should be doing checks to make sure asm operands
31- // are not out of bounds.
32-
3330namespace adjust {
3431
3532using namespace llvm ;
3633
3734static void signed_width (unsigned Width, uint64_t Value,
3835 std::string Description, const MCFixup &Fixup,
39- MCContext *Ctx = nullptr ) {
36+ MCContext *Ctx) {
4037 if (!isIntN (Width, Value)) {
4138 std::string Diagnostic = " out of range " + Description;
4239
@@ -46,17 +43,13 @@ static void signed_width(unsigned Width, uint64_t Value,
4643 Diagnostic += " (expected an integer in the range " + std::to_string (Min) +
4744 " to " + std::to_string (Max) + " )" ;
4845
49- if (Ctx) {
50- Ctx->reportError (Fixup.getLoc (), Diagnostic);
51- } else {
52- llvm_unreachable (Diagnostic.c_str ());
53- }
46+ Ctx->reportError (Fixup.getLoc (), Diagnostic);
5447 }
5548}
5649
5750static void unsigned_width (unsigned Width, uint64_t Value,
5851 std::string Description, const MCFixup &Fixup,
59- MCContext *Ctx = nullptr ) {
52+ MCContext *Ctx) {
6053 if (!isUIntN (Width, Value)) {
6154 std::string Diagnostic = " out of range " + Description;
6255
@@ -65,17 +58,13 @@ static void unsigned_width(unsigned Width, uint64_t Value,
6558 Diagnostic +=
6659 " (expected an integer in the range 0 to " + std::to_string (Max) + " )" ;
6760
68- if (Ctx) {
69- Ctx->reportError (Fixup.getLoc (), Diagnostic);
70- } else {
71- llvm_unreachable (Diagnostic.c_str ());
72- }
61+ Ctx->reportError (Fixup.getLoc (), Diagnostic);
7362 }
7463}
7564
7665// / Adjusts the value of a branch target before fixup application.
7766static void adjustBranch (unsigned Size, const MCFixup &Fixup, uint64_t &Value,
78- MCContext *Ctx = nullptr ) {
67+ MCContext *Ctx) {
7968 // We have one extra bit of precision because the value is rightshifted by
8069 // one.
8170 unsigned_width (Size + 1 , Value, std::string (" branch target" ), Fixup, Ctx);
@@ -86,13 +75,28 @@ static void adjustBranch(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
8675
8776// / Adjusts the value of a relative branch target before fixup application.
8877static void adjustRelativeBranch (unsigned Size, const MCFixup &Fixup,
89- uint64_t &Value, MCContext *Ctx = nullptr ) {
78+ uint64_t &Value, MCContext *Ctx) {
9079 // Jumps are relative to the current instruction.
9180 Value -= 2 ;
9281
9382 // We have one extra bit of precision because the value is rightshifted by
9483 // one.
95- signed_width (Size + 1 , Value, std::string (" branch target" ), Fixup, Ctx);
84+ Size += 1 ;
85+
86+ if (!isIntN (Size, Value) &&
87+ Ctx->getSubtargetInfo ()->hasFeature (AVR::FeatureWrappingRjmp)) {
88+ const int32_t FlashSize = 0x2000 ;
89+ int32_t SignedValue = Value;
90+
91+ uint64_t WrappedValue = SignedValue > 0 ? (uint64_t )(Value - FlashSize)
92+ : (uint64_t )(FlashSize + Value);
93+
94+ if (isIntN (Size, WrappedValue)) {
95+ Value = WrappedValue;
96+ }
97+ }
98+
99+ signed_width (Size, Value, std::string (" branch target" ), Fixup, Ctx);
96100
97101 // Rightshifts the value by one.
98102 AVR::fixups::adjustBranchTarget (Value);
@@ -105,7 +109,7 @@ static void adjustRelativeBranch(unsigned Size, const MCFixup &Fixup,
105109// /
106110// / Offset of 0 (so the result is left shifted by 3 bits before application).
107111static void fixup_call (unsigned Size, const MCFixup &Fixup, uint64_t &Value,
108- MCContext *Ctx = nullptr ) {
112+ MCContext *Ctx) {
109113 adjustBranch (Size, Fixup, Value, Ctx);
110114
111115 auto top = Value & (0xf00000 << 6 ); // the top four bits
@@ -121,7 +125,7 @@ static void fixup_call(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
121125// / 0000 00kk kkkk k000
122126// / Offset of 0 (so the result is left shifted by 3 bits before application).
123127static void fixup_7_pcrel (unsigned Size, const MCFixup &Fixup, uint64_t &Value,
124- MCContext *Ctx = nullptr ) {
128+ MCContext *Ctx) {
125129 adjustRelativeBranch (Size, Fixup, Value, Ctx);
126130
127131 // Because the value may be negative, we must mask out the sign bits
@@ -135,7 +139,7 @@ static void fixup_7_pcrel(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
135139// / 0000 kkkk kkkk kkkk
136140// / Offset of 0 (so the result isn't left-shifted before application).
137141static void fixup_13_pcrel (unsigned Size, const MCFixup &Fixup, uint64_t &Value,
138- MCContext *Ctx = nullptr ) {
142+ MCContext *Ctx) {
139143 adjustRelativeBranch (Size, Fixup, Value, Ctx);
140144
141145 // Because the value may be negative, we must mask out the sign bits
@@ -147,8 +151,7 @@ static void fixup_13_pcrel(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
147151// /
148152// / Resolves to:
149153// / 10q0 qq10 0000 1qqq
150- static void fixup_6 (const MCFixup &Fixup, uint64_t &Value,
151- MCContext *Ctx = nullptr ) {
154+ static void fixup_6 (const MCFixup &Fixup, uint64_t &Value, MCContext *Ctx) {
152155 unsigned_width (6 , Value, std::string (" immediate" ), Fixup, Ctx);
153156
154157 Value = ((Value & 0x20 ) << 8 ) | ((Value & 0x18 ) << 7 ) | (Value & 0x07 );
@@ -160,7 +163,7 @@ static void fixup_6(const MCFixup &Fixup, uint64_t &Value,
160163// / Resolves to:
161164// / 0000 0000 kk00 kkkk
162165static void fixup_6_adiw (const MCFixup &Fixup, uint64_t &Value,
163- MCContext *Ctx = nullptr ) {
166+ MCContext *Ctx) {
164167 unsigned_width (6 , Value, std::string (" immediate" ), Fixup, Ctx);
165168
166169 Value = ((Value & 0x30 ) << 2 ) | (Value & 0x0f );
@@ -170,8 +173,7 @@ static void fixup_6_adiw(const MCFixup &Fixup, uint64_t &Value,
170173// /
171174// / Resolves to:
172175// / 0000 0000 AAAA A000
173- static void fixup_port5 (const MCFixup &Fixup, uint64_t &Value,
174- MCContext *Ctx = nullptr ) {
176+ static void fixup_port5 (const MCFixup &Fixup, uint64_t &Value, MCContext *Ctx) {
175177 unsigned_width (5 , Value, std::string (" port number" ), Fixup, Ctx);
176178
177179 Value &= 0x1f ;
@@ -183,8 +185,7 @@ static void fixup_port5(const MCFixup &Fixup, uint64_t &Value,
183185// /
184186// / Resolves to:
185187// / 1011 0AAd dddd AAAA
186- static void fixup_port6 (const MCFixup &Fixup, uint64_t &Value,
187- MCContext *Ctx = nullptr ) {
188+ static void fixup_port6 (const MCFixup &Fixup, uint64_t &Value, MCContext *Ctx) {
188189 unsigned_width (6 , Value, std::string (" port number" ), Fixup, Ctx);
189190
190191 Value = ((Value & 0x30 ) << 5 ) | (Value & 0x0f );
@@ -195,7 +196,7 @@ static void fixup_port6(const MCFixup &Fixup, uint64_t &Value,
195196// / Resolves to:
196197// / 1010 ikkk dddd kkkk
197198static void fixup_lds_sts_16 (const MCFixup &Fixup, uint64_t &Value,
198- MCContext *Ctx = nullptr ) {
199+ MCContext *Ctx) {
199200 unsigned_width (7 , Value, std::string (" immediate" ), Fixup, Ctx);
200201 Value = ((Value & 0x70 ) << 8 ) | (Value & 0x0f );
201202}
@@ -213,7 +214,7 @@ namespace ldi {
213214// / 0000 KKKK 0000 KKKK
214215// / Offset of 0 (so the result isn't left-shifted before application).
215216static void fixup (unsigned Size, const MCFixup &Fixup, uint64_t &Value,
216- MCContext *Ctx = nullptr ) {
217+ MCContext *Ctx) {
217218 uint64_t upper = Value & 0xf0 ;
218219 uint64_t lower = Value & 0x0f ;
219220
@@ -223,25 +224,25 @@ static void fixup(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
223224static void neg (uint64_t &Value) { Value *= -1 ; }
224225
225226static void lo8 (unsigned Size, const MCFixup &Fixup, uint64_t &Value,
226- MCContext *Ctx = nullptr ) {
227+ MCContext *Ctx) {
227228 Value &= 0xff ;
228229 ldi::fixup (Size, Fixup, Value, Ctx);
229230}
230231
231232static void hi8 (unsigned Size, const MCFixup &Fixup, uint64_t &Value,
232- MCContext *Ctx = nullptr ) {
233+ MCContext *Ctx) {
233234 Value = (Value & 0xff00 ) >> 8 ;
234235 ldi::fixup (Size, Fixup, Value, Ctx);
235236}
236237
237238static void hh8 (unsigned Size, const MCFixup &Fixup, uint64_t &Value,
238- MCContext *Ctx = nullptr ) {
239+ MCContext *Ctx) {
239240 Value = (Value & 0xff0000 ) >> 16 ;
240241 ldi::fixup (Size, Fixup, Value, Ctx);
241242}
242243
243244static void ms8 (unsigned Size, const MCFixup &Fixup, uint64_t &Value,
244- MCContext *Ctx = nullptr ) {
245+ MCContext *Ctx) {
245246 Value = (Value & 0xff000000 ) >> 24 ;
246247 ldi::fixup (Size, Fixup, Value, Ctx);
247248}
0 commit comments