27
27
#include " llvm/Support/MathExtras.h"
28
28
#include " llvm/Support/raw_ostream.h"
29
29
30
- // FIXME: we should be doing checks to make sure asm operands
31
- // are not out of bounds.
32
-
33
30
namespace adjust {
34
31
35
32
using namespace llvm ;
36
33
37
- static void signed_width (unsigned Width, uint64_t Value,
38
- std::string Description, const MCFixup &Fixup,
39
- MCContext *Ctx = nullptr ) {
40
- if (!isIntN (Width, Value)) {
41
- std::string Diagnostic = " out of range " + Description;
42
-
43
- int64_t Min = minIntN (Width);
44
- int64_t Max = maxIntN (Width);
45
-
46
- Diagnostic += " (expected an integer in the range " + std::to_string (Min) +
47
- " to " + std::to_string (Max) + " )" ;
48
-
49
- if (Ctx) {
50
- Ctx->reportError (Fixup.getLoc (), Diagnostic);
51
- } else {
52
- llvm_unreachable (Diagnostic.c_str ());
53
- }
54
- }
55
- }
56
-
57
- static void unsigned_width (unsigned Width, uint64_t Value,
58
- std::string Description, const MCFixup &Fixup,
59
- MCContext *Ctx = nullptr ) {
34
+ static void ensureUnsignedWidth (unsigned Width, uint64_t Value,
35
+ std::string Description, const MCFixup &Fixup,
36
+ MCContext *Ctx) {
60
37
if (!isUIntN (Width, Value)) {
61
38
std::string Diagnostic = " out of range " + Description;
62
39
63
40
int64_t Max = maxUIntN (Width);
64
41
65
- Diagnostic +=
66
- " (expected an integer in the range 0 to " + std::to_string (Max ) + " )" ;
42
+ Diagnostic += " (expected an unsigned integer in the range 0 to " +
43
+ std::to_string (Max) + " , got " + std::to_string (Value ) + " )" ;
67
44
68
- if (Ctx) {
69
- Ctx->reportError (Fixup.getLoc (), Diagnostic);
70
- } else {
71
- llvm_unreachable (Diagnostic.c_str ());
72
- }
45
+ Ctx->reportError (Fixup.getLoc (), Diagnostic);
73
46
}
74
47
}
75
48
76
- // / Adjusts the value of a branch target before fixup application.
77
- static void adjustBranch (unsigned Size , const MCFixup &Fixup, uint64_t &Value,
78
- MCContext *Ctx = nullptr ) {
79
- // We have one extra bit of precision because the value is rightshifted by
80
- // one.
81
- unsigned_width (Size + 1 , Value, std::string (" branch target" ), Fixup, Ctx);
82
-
83
- // Rightshifts the value by one.
84
- AVR::fixups::adjustBranchTarget (Value);
85
- }
86
-
87
- // / Adjusts the value of a relative branch target before fixup application.
88
- static void adjustRelativeBranch (unsigned Size , const MCFixup &Fixup,
89
- uint64_t &Value, MCContext *Ctx = nullptr ) {
90
- // Jumps are relative to the current instruction.
91
- Value -= 2 ;
92
-
93
- // We have one extra bit of precision because the value is rightshifted by
94
- // one.
95
- signed_width (Size + 1 , Value, std::string (" branch target" ), Fixup, Ctx);
96
-
97
- // Rightshifts the value by one.
98
- AVR::fixups::adjustBranchTarget (Value);
99
- }
100
-
101
- // / 22-bit absolute fixup.
102
- // /
103
- // / Resolves to:
104
- // / 1001 kkkk 010k kkkk kkkk kkkk 111k kkkk
105
- // /
106
- // / Offset of 0 (so the result is left shifted by 3 bits before application).
107
- static void fixup_call (unsigned Size , const MCFixup &Fixup, uint64_t &Value,
108
- MCContext *Ctx = nullptr ) {
109
- adjustBranch (Size , Fixup, Value, Ctx);
110
-
111
- auto top = Value & (0xf00000 << 6 ); // the top four bits
112
- auto middle = Value & (0x1ffff << 5 ); // the middle 13 bits
113
- auto bottom = Value & 0x1f ; // end bottom 5 bits
114
-
115
- Value = (top << 6 ) | (middle << 3 ) | (bottom << 0 );
116
- }
117
-
118
- // / 7-bit PC-relative fixup.
119
- // /
120
- // / Resolves to:
121
- // / 0000 00kk kkkk k000
122
- // / Offset of 0 (so the result is left shifted by 3 bits before application).
123
- static void fixup_7_pcrel (unsigned Size , const MCFixup &Fixup, uint64_t &Value,
124
- MCContext *Ctx = nullptr ) {
125
- adjustRelativeBranch (Size , Fixup, Value, Ctx);
126
-
127
- // Because the value may be negative, we must mask out the sign bits
128
- Value &= 0x7f ;
129
- }
130
-
131
- // / 12-bit PC-relative fixup.
132
- // / Yes, the fixup is 12 bits even though the name says otherwise.
133
- // /
134
- // / Resolves to:
135
- // / 0000 kkkk kkkk kkkk
136
- // / Offset of 0 (so the result isn't left-shifted before application).
137
- static void fixup_13_pcrel (unsigned Size , const MCFixup &Fixup, uint64_t &Value,
138
- MCContext *Ctx = nullptr ) {
139
- adjustRelativeBranch (Size , Fixup, Value, Ctx);
140
-
141
- // Because the value may be negative, we must mask out the sign bits
142
- Value &= 0xfff ;
143
- }
144
-
145
49
// / 6-bit fixup for the immediate operand of the STD/LDD family of
146
50
// / instructions.
147
51
// /
148
52
// / Resolves to:
149
53
// / 10q0 qq10 0000 1qqq
150
- static void fixup_6 (const MCFixup &Fixup, uint64_t &Value,
151
- MCContext *Ctx = nullptr ) {
152
- unsigned_width (6 , Value, std::string (" immediate" ), Fixup, Ctx);
54
+ static void fixup_6 (const MCFixup &Fixup, uint64_t &Value, MCContext *Ctx) {
55
+ ensureUnsignedWidth (6 , Value, std::string (" immediate" ), Fixup, Ctx);
153
56
154
57
Value = ((Value & 0x20 ) << 8 ) | ((Value & 0x18 ) << 7 ) | (Value & 0x07 );
155
58
}
@@ -160,8 +63,8 @@ static void fixup_6(const MCFixup &Fixup, uint64_t &Value,
160
63
// / Resolves to:
161
64
// / 0000 0000 kk00 kkkk
162
65
static void fixup_6_adiw (const MCFixup &Fixup, uint64_t &Value,
163
- MCContext *Ctx = nullptr ) {
164
- unsigned_width (6 , Value, std::string (" immediate" ), Fixup, Ctx);
66
+ MCContext *Ctx) {
67
+ ensureUnsignedWidth (6 , Value, std::string (" immediate" ), Fixup, Ctx);
165
68
166
69
Value = ((Value & 0x30 ) << 2 ) | (Value & 0x0f );
167
70
}
@@ -170,9 +73,8 @@ static void fixup_6_adiw(const MCFixup &Fixup, uint64_t &Value,
170
73
// /
171
74
// / Resolves to:
172
75
// / 0000 0000 AAAA A000
173
- static void fixup_port5 (const MCFixup &Fixup, uint64_t &Value,
174
- MCContext *Ctx = nullptr ) {
175
- unsigned_width (5 , Value, std::string (" port number" ), Fixup, Ctx);
76
+ static void fixup_port5 (const MCFixup &Fixup, uint64_t &Value, MCContext *Ctx) {
77
+ ensureUnsignedWidth (5 , Value, std::string (" port number" ), Fixup, Ctx);
176
78
177
79
Value &= 0x1f ;
178
80
@@ -183,9 +85,8 @@ static void fixup_port5(const MCFixup &Fixup, uint64_t &Value,
183
85
// /
184
86
// / Resolves to:
185
87
// / 1011 0AAd dddd AAAA
186
- static void fixup_port6 (const MCFixup &Fixup, uint64_t &Value,
187
- MCContext *Ctx = nullptr ) {
188
- unsigned_width (6 , Value, std::string (" port number" ), Fixup, Ctx);
88
+ static void fixup_port6 (const MCFixup &Fixup, uint64_t &Value, MCContext *Ctx) {
89
+ ensureUnsignedWidth (6 , Value, std::string (" port number" ), Fixup, Ctx);
189
90
190
91
Value = ((Value & 0x30 ) << 5 ) | (Value & 0x0f );
191
92
}
@@ -195,8 +96,8 @@ static void fixup_port6(const MCFixup &Fixup, uint64_t &Value,
195
96
// / Resolves to:
196
97
// / 1010 ikkk dddd kkkk
197
98
static void fixup_lds_sts_16 (const MCFixup &Fixup, uint64_t &Value,
198
- MCContext *Ctx = nullptr ) {
199
- unsigned_width (7 , Value, std::string (" immediate" ), Fixup, Ctx);
99
+ MCContext *Ctx) {
100
+ ensureUnsignedWidth (7 , Value, std::string (" immediate" ), Fixup, Ctx);
200
101
Value = ((Value & 0x70 ) << 8 ) | (Value & 0x0f );
201
102
}
202
103
@@ -213,7 +114,7 @@ namespace ldi {
213
114
// / 0000 KKKK 0000 KKKK
214
115
// / Offset of 0 (so the result isn't left-shifted before application).
215
116
static void fixup (unsigned Size , const MCFixup &Fixup, uint64_t &Value,
216
- MCContext *Ctx = nullptr ) {
117
+ MCContext *Ctx) {
217
118
uint64_t upper = Value & 0xf0 ;
218
119
uint64_t lower = Value & 0x0f ;
219
120
@@ -223,25 +124,25 @@ static void fixup(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
223
124
static void neg (uint64_t &Value) { Value *= -1 ; }
224
125
225
126
static void lo8 (unsigned Size , const MCFixup &Fixup, uint64_t &Value,
226
- MCContext *Ctx = nullptr ) {
127
+ MCContext *Ctx) {
227
128
Value &= 0xff ;
228
129
ldi::fixup (Size , Fixup, Value, Ctx);
229
130
}
230
131
231
132
static void hi8 (unsigned Size , const MCFixup &Fixup, uint64_t &Value,
232
- MCContext *Ctx = nullptr ) {
133
+ MCContext *Ctx) {
233
134
Value = (Value & 0xff00 ) >> 8 ;
234
135
ldi::fixup (Size , Fixup, Value, Ctx);
235
136
}
236
137
237
138
static void hh8 (unsigned Size , const MCFixup &Fixup, uint64_t &Value,
238
- MCContext *Ctx = nullptr ) {
139
+ MCContext *Ctx) {
239
140
Value = (Value & 0xff0000 ) >> 16 ;
240
141
ldi::fixup (Size , Fixup, Value, Ctx);
241
142
}
242
143
243
144
static void ms8 (unsigned Size , const MCFixup &Fixup, uint64_t &Value,
244
- MCContext *Ctx = nullptr ) {
145
+ MCContext *Ctx) {
245
146
Value = (Value & 0xff000000 ) >> 24 ;
246
147
ldi::fixup (Size , Fixup, Value, Ctx);
247
148
}
@@ -263,13 +164,9 @@ void AVRAsmBackend::adjustFixupValue(const MCFixup &Fixup,
263
164
default :
264
165
llvm_unreachable (" unhandled fixup" );
265
166
case AVR::fixup_7_pcrel:
266
- adjust::fixup_7_pcrel (Size , Fixup, Value, Ctx);
267
- break ;
268
167
case AVR::fixup_13_pcrel:
269
- adjust::fixup_13_pcrel (Size , Fixup, Value, Ctx);
270
- break ;
271
168
case AVR::fixup_call:
272
- adjust::fixup_call ( Size , Fixup, Value, Ctx);
169
+ // Handled by linker, see `shouldForceRelocation()`
273
170
break ;
274
171
case AVR::fixup_ldi:
275
172
adjust::ldi::fixup (Size , Fixup, Value, Ctx);
@@ -330,13 +227,15 @@ void AVRAsmBackend::adjustFixupValue(const MCFixup &Fixup,
330
227
adjust::ldi::ms8 (Size , Fixup, Value, Ctx);
331
228
break ;
332
229
case AVR::fixup_16:
333
- adjust::unsigned_width (16 , Value, std::string (" port number" ), Fixup, Ctx);
230
+ adjust::ensureUnsignedWidth (16 , Value, std::string (" port number" ), Fixup,
231
+ Ctx);
334
232
335
233
Value &= 0xffff ;
336
234
break ;
337
235
case AVR::fixup_16_pm:
338
236
Value >>= 1 ; // Flash addresses are always shifted.
339
- adjust::unsigned_width (16 , Value, std::string (" port number" ), Fixup, Ctx);
237
+ adjust::ensureUnsignedWidth (16 , Value, std::string (" port number" ), Fixup,
238
+ Ctx);
340
239
341
240
Value &= 0xffff ;
342
241
break ;
@@ -517,8 +416,6 @@ bool AVRAsmBackend::shouldForceRelocation(const MCAssembler &Asm,
517
416
return Fixup.getKind () >= FirstLiteralRelocationKind;
518
417
case AVR::fixup_7_pcrel:
519
418
case AVR::fixup_13_pcrel:
520
- // Always resolve relocations for PC-relative branches
521
- return false ;
522
419
case AVR::fixup_call:
523
420
return true ;
524
421
}
0 commit comments