1
1
use crate :: diagn:: { Span , RcReport } ;
2
2
use crate :: expr:: { Expression , ExpressionValue , ExpressionEvalContext } ;
3
- use crate :: asm:: { AssemblerParser , BinaryOutput , LabelManager , LabelContext } ;
3
+ use crate :: asm:: { AssemblerParser , LabelManager , LabelContext } ;
4
4
use crate :: asm:: BankDef ;
5
+ use crate :: asm:: Bank ;
5
6
use crate :: asm:: BinaryBlock ;
6
7
use crate :: asm:: cpudef:: CpuDef ;
7
8
use crate :: util:: FileServer ;
@@ -16,7 +17,7 @@ pub struct AssemblerState
16
17
pub parsed_exprs : Vec < ParsedExpression > ,
17
18
18
19
pub bankdefs : Vec < BankDef > ,
19
- pub blocks : Vec < BinaryBlock > ,
20
+ pub blocks : Vec < Bank > ,
20
21
pub cur_bank : usize ,
21
22
pub cur_block : usize
22
23
}
@@ -48,6 +49,16 @@ pub struct ParsedExpression
48
49
}
49
50
50
51
52
+ #[ derive( Debug , Clone , PartialEq ) ]
53
+ pub struct BitRangeSpan
54
+ {
55
+ pub start : usize ,
56
+ pub end : usize ,
57
+ pub addr : usize ,
58
+ pub span : Span
59
+ }
60
+
61
+
51
62
impl AssemblerState
52
63
{
53
64
pub fn new ( ) -> AssemblerState
@@ -66,7 +77,7 @@ impl AssemblerState
66
77
} ;
67
78
68
79
state. bankdefs . push ( BankDef :: new ( "" , 0 , 0 , Some ( 0 ) , false , None ) ) ;
69
- state. blocks . push ( BinaryBlock :: new ( "" ) ) ;
80
+ state. blocks . push ( Bank :: new ( "" ) ) ;
70
81
state
71
82
}
72
83
@@ -90,6 +101,9 @@ impl AssemblerState
90
101
self . resolve_exprs ( report. clone ( ) ) ?;
91
102
self . check_bank_overlap ( report. clone ( ) ) ;
92
103
104
+ //for block in &self.blocks
105
+ // { println!("{:#?}", block.bits.spans); }
106
+
93
107
match report. has_errors ( )
94
108
{
95
109
true => Err ( ( ) ) ,
@@ -98,9 +112,9 @@ impl AssemblerState
98
112
}
99
113
100
114
101
- pub fn get_binary_output ( & self ) -> BinaryOutput
115
+ pub fn get_binary_output ( & self ) -> BinaryBlock
102
116
{
103
- let mut output = BinaryOutput :: new ( ) ;
117
+ let mut output = BinaryBlock :: new ( ) ;
104
118
105
119
for block in & self . blocks
106
120
{
@@ -114,13 +128,32 @@ impl AssemblerState
114
128
115
129
if let Some ( output_index) = bankdef. outp
116
130
{
117
- for i in 0 ..block. len ( )
118
- { output. write ( output_index * bits + i, block. read ( i) ) ; }
131
+ let mut sorted_spans = block. bits . spans . clone ( ) ;
132
+ sorted_spans. sort_by ( |a, b| a. start . cmp ( & b. start ) ) ;
133
+
134
+ let mut sorted_span_index = 0 ;
135
+
136
+ for i in 0 ..block. bits . len ( )
137
+ {
138
+ let bitrange_index = sorted_spans[ sorted_span_index..] . iter ( ) . position ( |s| i >= s. start && i < s. end ) ;
139
+ let bitrange = bitrange_index. map ( |i| & sorted_spans[ sorted_span_index + i] ) ;
140
+
141
+ if let Some ( bitrange_index) = bitrange_index
142
+ { sorted_span_index += bitrange_index; }
143
+
144
+ if let Some ( bitrange) = bitrange
145
+ { output. write ( output_index * bits + i, block. bits . read ( i) , Some ( ( bitrange. addr , & bitrange. span ) ) ) ; }
146
+ else
147
+ { output. write ( output_index * bits + i, block. bits . read ( i) , None ) ; }
148
+ }
149
+
150
+ for bitrange in block. bits . spans . iter ( ) . filter ( |s| s. start == s. end )
151
+ { output. mark_label ( output_index * bits + bitrange. start , bitrange. addr , & bitrange. span ) ; }
119
152
120
153
if bankdef. fill
121
154
{
122
- for i in block. len ( ) ..( bankdef. size * bits)
123
- { output. write ( output_index * bits + i, false ) ; }
155
+ for i in block. bits . len ( ) ..( bankdef. size * bits)
156
+ { output. write ( output_index * bits + i, false , None ) ; }
124
157
}
125
158
}
126
159
}
@@ -148,7 +181,7 @@ impl AssemblerState
148
181
ExpressionContext
149
182
{
150
183
block : self . cur_block ,
151
- offset : block. len ( ) ,
184
+ offset : block. bits . len ( ) ,
152
185
label_ctx : self . labels . get_cur_context ( )
153
186
}
154
187
}
@@ -195,7 +228,7 @@ impl AssemblerState
195
228
let bits = self . cpudef . as_ref ( ) . unwrap ( ) . bits ;
196
229
let block = & self . blocks [ self . cur_block ] ;
197
230
198
- let excess_bits = block. len ( ) % bits;
231
+ let excess_bits = block. bits . len ( ) % bits;
199
232
if excess_bits != 0
200
233
{
201
234
let bits_short = bits - excess_bits;
@@ -206,7 +239,7 @@ impl AssemblerState
206
239
let bankdef_index = self . find_bankdef ( & block. bank_name ) . unwrap ( ) ;
207
240
let bankdef = & self . bankdefs [ bankdef_index] ;
208
241
209
- let block_offset = block. len ( ) / bits;
242
+ let block_offset = block. bits . len ( ) / bits;
210
243
let addr = match block_offset. checked_add ( bankdef. addr )
211
244
{
212
245
Some ( addr) => addr,
@@ -220,6 +253,28 @@ impl AssemblerState
220
253
}
221
254
222
255
256
+ fn get_bitrange_address ( & self , report : RcReport , span : & Span ) -> Result < usize , ( ) >
257
+ {
258
+ if self . cpudef . is_none ( )
259
+ { return Ok ( 0 ) ; }
260
+
261
+ let bits = self . cpudef . as_ref ( ) . unwrap ( ) . bits ;
262
+ let block = & self . blocks [ self . cur_block ] ;
263
+
264
+ let bankdef_index = self . find_bankdef ( & block. bank_name ) . unwrap ( ) ;
265
+ let bankdef = & self . bankdefs [ bankdef_index] ;
266
+
267
+ let block_offset = block. bits . len ( ) / bits;
268
+ let addr = match block_offset. checked_add ( bankdef. addr )
269
+ {
270
+ Some ( addr) => addr,
271
+ None => return Err ( report. error_span ( "address overflowed valid range" , span) )
272
+ } ;
273
+
274
+ Ok ( addr)
275
+ }
276
+
277
+
223
278
pub fn check_valid_address ( & self , report : RcReport , block_index : usize , addr : usize , span : & Span ) -> Result < ( ) , ( ) >
224
279
{
225
280
let block = & self . blocks [ block_index] ;
@@ -236,52 +291,69 @@ impl AssemblerState
236
291
}
237
292
238
293
239
- pub fn output_bits_until_aligned ( & mut self , report : RcReport , multiple_of : usize , span : & Span ) -> Result < ( ) , ( ) >
294
+ pub fn output_bits_until_aligned ( & mut self , report : RcReport , multiple_of : usize , report_span : & Span , output_span : Option < & Span > ) -> Result < ( ) , ( ) >
240
295
{
241
296
if multiple_of == 0
242
- { return Err ( report. error_span ( "invalid alignment" , span ) ) ; }
297
+ { return Err ( report. error_span ( "invalid alignment" , report_span ) ) ; }
243
298
244
- self . check_cpudef_active ( report. clone ( ) , span ) ?;
299
+ self . check_cpudef_active ( report. clone ( ) , report_span ) ?;
245
300
246
301
let bits = self . cpudef . as_ref ( ) . unwrap ( ) . bits ;
247
302
248
- while self . blocks [ self . cur_block ] . len ( ) % ( bits * multiple_of) != 0
249
- { self . output_bit ( report. clone ( ) , false , true , span ) ?; }
303
+ while self . blocks [ self . cur_block ] . bits . len ( ) % ( bits * multiple_of) != 0
304
+ { self . output_bit ( report. clone ( ) , false , true , report_span , output_span ) ?; }
250
305
251
306
Ok ( ( ) )
252
307
}
253
308
254
309
255
- pub fn output_bit ( & mut self , report : RcReport , bit : bool , skipping : bool , span : & Span ) -> Result < ( ) , ( ) >
310
+ pub fn output_bit ( & mut self , report : RcReport , bit : bool , skipping : bool , report_span : & Span , output_span : Option < & Span > ) -> Result < ( ) , ( ) >
256
311
{
257
312
{
258
313
let block = & self . blocks [ self . cur_block ] ;
259
314
let bankdef = & self . bankdefs [ self . cur_bank ] ;
260
315
261
316
if bankdef. outp . is_none ( ) && !skipping
262
- { return Err ( report. error_span ( "attempt to place data in non-writable bank" , span ) ) ; }
317
+ { return Err ( report. error_span ( "attempt to place data in non-writable bank" , report_span ) ) ; }
263
318
264
319
if self . cur_bank != 0
265
320
{
266
- self . check_cpudef_active ( report. clone ( ) , span ) ?;
321
+ self . check_cpudef_active ( report. clone ( ) , report_span ) ?;
267
322
268
- if block. len ( ) / self . cpudef . as_ref ( ) . unwrap ( ) . bits >= bankdef. size
269
- { return Err ( report. error_span ( "data overflowed bank size" , span ) ) ; }
323
+ if block. bits . len ( ) / self . cpudef . as_ref ( ) . unwrap ( ) . bits >= bankdef. size
324
+ { return Err ( report. error_span ( "data overflowed bank size" , report_span ) ) ; }
270
325
}
271
326
}
272
327
273
- self . blocks [ self . cur_block ] . append ( bit) ;
328
+ let bitrange = match output_span
329
+ {
330
+ Some ( output_span) =>
331
+ {
332
+ let addr = self . get_bitrange_address ( report, output_span) ?;
333
+ Some ( ( addr, output_span) )
334
+ }
335
+ None => None
336
+ } ;
337
+
338
+ self . blocks [ self . cur_block ] . bits . append ( bit, bitrange) ;
274
339
Ok ( ( ) )
275
340
}
276
341
277
342
278
- pub fn output_zero_bits ( & mut self , report : RcReport , num : usize , skipping : bool , span : & Span ) -> Result < ( ) , ( ) >
343
+ pub fn output_zero_bits ( & mut self , report : RcReport , num : usize , skipping : bool , report_span : & Span , output_span : Option < & Span > ) -> Result < ( ) , ( ) >
279
344
{
280
345
for _ in 0 ..num
281
- { self . output_bit ( report. clone ( ) , false , skipping, span ) ?; }
346
+ { self . output_bit ( report. clone ( ) , false , skipping, report_span , output_span ) ?; }
282
347
283
348
Ok ( ( ) )
284
349
}
350
+
351
+
352
+ pub fn mark_label ( & mut self , addr : usize , output_span : & Span )
353
+ {
354
+ let index = self . blocks [ self . cur_block ] . bits . len ( ) ;
355
+ self . blocks [ self . cur_block ] . bits . mark_label ( index, addr, output_span) ;
356
+ }
285
357
286
358
287
359
pub fn resolve_instrs ( & mut self , report : RcReport ) -> Result < ( ) , ( ) >
@@ -342,12 +414,14 @@ impl AssemblerState
342
414
343
415
let value = self . expr_eval ( report. clone ( ) , & instr. ctx , & rule. production , & mut args_eval_ctx) ?;
344
416
417
+ let addr = self . get_bitrange_address ( report, & instr. span ) ?;
418
+
345
419
let block = & mut self . blocks [ instr. ctx . block ] ;
346
420
347
421
for i in 0 ..( left - right + 1 )
348
422
{
349
423
let bit = value. get_bit ( left - right - i) ;
350
- block. write ( instr. ctx . offset + i, bit) ;
424
+ block. bits . write ( instr. ctx . offset + i, bit, Some ( ( addr , & instr . span ) ) ) ;
351
425
}
352
426
353
427
Ok ( ( ) )
@@ -374,7 +448,7 @@ impl AssemblerState
374
448
for i in 0 ..expr. width
375
449
{
376
450
let bit = value. get_bit ( expr. width - i - 1 ) ;
377
- block. write ( expr. ctx . offset + i, bit) ;
451
+ block. bits . write ( expr. ctx . offset + i, bit, None ) ;
378
452
}
379
453
380
454
Ok ( ( ) )
@@ -455,7 +529,7 @@ impl ExpressionContext
455
529
let bits = state. cpudef . as_ref ( ) . unwrap ( ) . bits ;
456
530
let block = & state. blocks [ self . block ] ;
457
531
458
- if block. len ( ) % bits != 0
532
+ if block. bits . len ( ) % bits != 0
459
533
{ return Err ( { report. error_span ( "address is not aligned to a byte" , span) ; true } ) ; }
460
534
461
535
let bankdef = state. find_bankdef ( & block. bank_name ) . unwrap ( ) ;
0 commit comments