@@ -223,133 +223,81 @@ pub fn fields(
223
223
r_impl_items : & mut Vec < TokenStream > ,
224
224
w_impl_items : & mut Vec < TokenStream > ,
225
225
) -> Result < ( ) > {
226
- struct F < ' a > {
227
- _pc_w : Ident ,
228
- _sc : Ident ,
229
- access : Option < Access > ,
230
- description : String ,
231
- description_with_bits : String ,
232
- evs : & ' a [ EnumeratedValues ] ,
233
- mask : u64 ,
234
- name : & ' a str ,
235
- offset : u64 ,
236
- pc_r : Ident ,
237
- _pc_r : Ident ,
238
- pc_w : Ident ,
239
- sc : Ident ,
240
- bits : Ident ,
241
- ty : Ident ,
242
- width : u32 ,
243
- write_constraint : Option < & ' a WriteConstraint > ,
244
- }
245
-
246
- impl < ' a > F < ' a > {
247
- fn from ( f : & ' a Field ) -> Result < Self > {
248
- // TODO(AJM) - do we need to do anything with this range type?
249
- let BitRange { offset, width, .. } = f. bit_range ;
250
- let sc = f. name . to_sanitized_snake_case ( ) ;
251
- let pc = f. name . to_sanitized_upper_case ( ) ;
252
- let span = Span :: call_site ( ) ;
253
- let pc_r = Ident :: new ( & format ! ( "{}_A" , pc) , span) ;
254
- let _pc_r = Ident :: new ( & format ! ( "{}_R" , pc) , span) ;
255
- let pc_w = Ident :: new ( & format ! ( "{}_AW" , pc) , span) ;
256
- let _pc_w = Ident :: new ( & format ! ( "{}_W" , pc) , span) ;
257
- let _sc = Ident :: new ( & format ! ( "_{}" , sc) , span) ;
258
- let bits = Ident :: new ( if width == 1 { "bit" } else { "bits" } , span) ;
259
- let mut description_with_bits = if width == 1 {
260
- format ! ( "Bit {}" , offset)
261
- } else {
262
- format ! ( "Bits {}:{}" , offset, offset + width - 1 )
263
- } ;
264
- if let Some ( d) = & f. description {
265
- description_with_bits. push_str ( " - " ) ;
266
- description_with_bits. push_str ( & util:: respace ( & util:: escape_brackets ( d) ) ) ;
267
- }
268
- let description = if let Some ( d) = & f. description {
269
- util:: respace ( & util:: escape_brackets ( d) )
270
- } else {
271
- "" . to_owned ( )
272
- } ;
273
-
274
- Ok ( F {
275
- _pc_w,
276
- _sc,
277
- description,
278
- description_with_bits,
279
- pc_r,
280
- _pc_r,
281
- pc_w,
282
- bits,
283
- width,
284
- access : f. access ,
285
- evs : & f. enumerated_values ,
286
- sc : Ident :: new ( & sc, span) ,
287
- mask : 1u64 . wrapping_neg ( ) >> ( 64 - width) ,
288
- name : & f. name ,
289
- offset : u64:: from ( offset) ,
290
- ty : width. to_ty ( ) ?,
291
- write_constraint : f. write_constraint . as_ref ( ) ,
292
- } )
293
- }
294
- }
295
-
296
226
// TODO enumeratedValues
297
- for f in fields. iter ( ) . map ( F :: from) {
298
- let f = f?;
227
+ for f in fields. into_iter ( ) {
228
+ // TODO(AJM) - do we need to do anything with this range type?
229
+ let BitRange { offset, width, .. } = f. bit_range ;
230
+ let span = Span :: call_site ( ) ;
231
+ let sc = Ident :: new ( & f. name . to_sanitized_snake_case ( ) , span) ;
232
+ let pc = f. name . to_sanitized_upper_case ( ) ;
233
+ let bits = Ident :: new ( if width == 1 { "bit" } else { "bits" } , span) ;
234
+ let mut description_with_bits = if width == 1 {
235
+ format ! ( "Bit {}" , offset)
236
+ } else {
237
+ format ! ( "Bits {}:{}" , offset, offset + width - 1 )
238
+ } ;
239
+ let description = if let Some ( d) = & f. description {
240
+ util:: respace ( & util:: escape_brackets ( d) )
241
+ } else {
242
+ "" . to_owned ( )
243
+ } ;
244
+ if !description. is_empty ( ) {
245
+ description_with_bits. push_str ( " - " ) ;
246
+ description_with_bits. push_str ( & description) ;
247
+ }
299
248
300
249
let can_read = [ Access :: ReadOnly , Access :: ReadWriteOnce , Access :: ReadWrite ]
301
250
. contains ( & access)
302
251
&& ( f. access != Some ( Access :: WriteOnly ) )
303
252
&& ( f. access != Some ( Access :: WriteOnce ) ) ;
304
253
let can_write = ( access != Access :: ReadOnly ) && ( f. access != Some ( Access :: ReadOnly ) ) ;
305
254
306
- let bits = & f. bits ;
307
- let mask = & util:: hex ( f. mask ) ;
308
- let offset = f. offset ;
309
- let rv = reset_value. map ( |rv| ( rv >> offset) & f. mask ) ;
310
- let fty = & f. ty ;
255
+ let mask = 1u64 . wrapping_neg ( ) >> ( 64 - width) ;
256
+ let hexmask = & util:: hex ( mask) ;
257
+ let offset = u64:: from ( offset) ;
258
+ let rv = reset_value. map ( |rv| ( rv >> offset) & mask) ;
259
+ let fty = width. to_ty ( ) ?;
260
+ let evs = & f. enumerated_values ;
311
261
312
262
let lookup_results = lookup (
313
- & f . evs ,
263
+ evs,
314
264
fields,
315
265
parent,
316
266
all_registers,
317
267
peripheral,
318
268
all_peripherals,
319
269
) ?;
320
270
321
- let pc_r = & f. pc_r ;
322
- let mut pc_w = & f. pc_r ;
271
+ // Reader and writer use one common `Enum_A` unless a fields have two `enumeratedValues`,
272
+ // then we have one for read-only `Enum_A` and another for write-only `Enum_AW`
273
+ let pc_r = Ident :: new ( & ( pc. clone ( ) + "_A" ) , span) ;
274
+ let mut pc_w = & pc_r;
323
275
324
276
let mut base_pc_w = None ;
325
277
let mut evs_r = None ;
326
278
327
- let _pc_r = & f. _pc_r ;
328
- let _pc_w = & f. _pc_w ;
329
- let description = & f. description ;
330
- let description_with_bits = & f. description_with_bits ;
331
-
332
279
if can_read {
333
- let cast = if f. width == 1 {
280
+ let _pc_r = Ident :: new ( & ( pc. clone ( ) + "_R" ) , span) ;
281
+
282
+ let cast = if width == 1 {
334
283
quote ! { != 0 }
335
284
} else {
336
285
quote ! { as #fty }
337
286
} ;
338
287
let value = if offset != 0 {
339
288
let offset = & util:: unsuffixed ( offset) ;
340
289
quote ! {
341
- ( ( self . bits >> #offset) & #mask ) #cast
290
+ ( ( self . bits >> #offset) & #hexmask ) #cast
342
291
}
343
292
} else {
344
293
quote ! {
345
- ( self . bits & #mask ) #cast
294
+ ( self . bits & #hexmask ) #cast
346
295
}
347
296
} ;
348
297
349
298
if let Some ( ( evs, base) ) = lookup_filter ( & lookup_results, Usage :: Read ) {
350
299
evs_r = Some ( evs. clone ( ) ) ;
351
300
352
- let sc = & f. sc ;
353
301
r_impl_items. push ( quote ! {
354
302
#[ doc = #description_with_bits]
355
303
#[ inline( always) ]
@@ -360,9 +308,9 @@ pub fn fields(
360
308
361
309
base_pc_w = base. as_ref ( ) . map ( |base| {
362
310
let pc = base. field . to_sanitized_upper_case ( ) ;
363
- let base_pc_r = Ident :: new ( & format ! ( "{} _A", pc ) , Span :: call_site ( ) ) ;
311
+ let base_pc_r = Ident :: new ( & ( pc . clone ( ) + " _A") , span ) ;
364
312
let base_pc_r =
365
- derive_from_base ( mod_items, & base, & pc_r, & base_pc_r, description) ;
313
+ derive_from_base ( mod_items, & base, & pc_r, & base_pc_r, & description) ;
366
314
367
315
let doc = format ! ( "Reader of field `{}`" , f. name) ;
368
316
mod_items. push ( quote ! {
@@ -374,17 +322,17 @@ pub fn fields(
374
322
} ) ;
375
323
376
324
if base. is_none ( ) {
377
- let has_reserved_variant = evs. values . len ( ) != ( 1 << f . width ) ;
325
+ let has_reserved_variant = evs. values . len ( ) != ( 1 << width) ;
378
326
let variants = Variant :: from_enumerated_values ( evs) ?;
379
327
380
- add_from_variants ( mod_items, & variants, pc_r, fty, description, rv) ;
328
+ add_from_variants ( mod_items, & variants, & pc_r, & fty, & description, rv) ;
381
329
382
330
let mut enum_items = vec ! [ ] ;
383
331
384
332
let mut arms = variants
385
333
. iter ( )
386
334
. map ( |v| {
387
- let i = util:: unsuffixed_or_bool ( v. value , f . width ) ;
335
+ let i = util:: unsuffixed_or_bool ( v. value , width) ;
388
336
let pc = & v. pc ;
389
337
390
338
if has_reserved_variant {
@@ -399,7 +347,7 @@ pub fn fields(
399
347
arms. push ( quote ! {
400
348
i => Res ( i)
401
349
} ) ;
402
- } else if 1 << f . width . to_ty_width ( ) ? != variants. len ( ) {
350
+ } else if 1 << width. to_ty_width ( ) ? != variants. len ( ) {
403
351
arms. push ( quote ! {
404
352
_ => unreachable!( )
405
353
} ) ;
@@ -438,7 +386,7 @@ pub fn fields(
438
386
} else {
439
387
format ! ( "is_{}" , sc)
440
388
} ,
441
- Span :: call_site ( ) ,
389
+ span ,
442
390
) ;
443
391
444
392
let doc = format ! ( "Checks if the value of the field is `{}`" , pc) ;
@@ -461,7 +409,6 @@ pub fn fields(
461
409
} ) ;
462
410
}
463
411
} else {
464
- let sc = & f. sc ;
465
412
r_impl_items. push ( quote ! {
466
413
#[ doc = #description_with_bits]
467
414
#[ inline( always) ]
@@ -479,29 +426,29 @@ pub fn fields(
479
426
}
480
427
481
428
if can_write {
482
- let mut proxy_items = vec ! [ ] ;
429
+ let new_pc_w = Ident :: new ( & ( pc. clone ( ) + "_AW" ) , span) ;
430
+ let _pc_w = Ident :: new ( & ( pc. clone ( ) + "_W" ) , span) ;
483
431
484
- let mut unsafety = unsafety ( f . write_constraint , f . width ) ;
485
- let width = f . width ;
432
+ let mut proxy_items = vec ! [ ] ;
433
+ let mut unsafety = unsafety ( f . write_constraint . as_ref ( ) , width) ;
486
434
487
435
if let Some ( ( evs, base) ) = lookup_filter ( & lookup_results, Usage :: Write ) {
488
436
let variants = Variant :: from_enumerated_values ( evs) ?;
489
437
490
- if variants. len ( ) == 1 << f . width {
438
+ if variants. len ( ) == 1 << width {
491
439
unsafety = None ;
492
440
}
493
441
494
442
if Some ( evs) != evs_r. as_ref ( ) {
495
- pc_w = & f. pc_w ;
496
-
443
+ pc_w = & new_pc_w;
497
444
base_pc_w = base. as_ref ( ) . map ( |base| {
498
445
let pc = base. field . to_sanitized_upper_case ( ) ;
499
- let base_pc_w = Ident :: new ( & format ! ( "{} _AW", pc ) , Span :: call_site ( ) ) ;
500
- derive_from_base ( mod_items, & base, & pc_w, & base_pc_w, description)
446
+ let base_pc_w = Ident :: new ( & ( pc + " _AW") , span ) ;
447
+ derive_from_base ( mod_items, & base, & pc_w, & base_pc_w, & description)
501
448
} ) ;
502
449
503
450
if base. is_none ( ) {
504
- add_from_variants ( mod_items, & variants, pc_w, fty, description, rv) ;
451
+ add_from_variants ( mod_items, & variants, & pc_w, & fty, & description, rv) ;
505
452
}
506
453
}
507
454
@@ -562,7 +509,7 @@ pub fn fields(
562
509
///Writes raw bits to the field
563
510
#[ inline( always) ]
564
511
pub #unsafety fn #bits( self , value: #fty) -> & ' a mut W {
565
- self . w. bits = ( self . w. bits & !( #mask << #offset) ) | ( ( ( value as #rty) & #mask ) << #offset) ;
512
+ self . w. bits = ( self . w. bits & !( #hexmask << #offset) ) | ( ( ( value as #rty) & #hexmask ) << #offset) ;
566
513
self . w
567
514
}
568
515
}
@@ -571,7 +518,7 @@ pub fn fields(
571
518
///Writes raw bits to the field
572
519
#[ inline( always) ]
573
520
pub #unsafety fn #bits( self , value: #fty) -> & ' a mut W {
574
- self . w. bits = ( self . w. bits & !#mask ) | ( ( value as #rty) & #mask ) ;
521
+ self . w. bits = ( self . w. bits & !#hexmask ) | ( ( value as #rty) & #hexmask ) ;
575
522
self . w
576
523
}
577
524
}
@@ -589,7 +536,6 @@ pub fn fields(
589
536
}
590
537
} ) ;
591
538
592
- let sc = & f. sc ;
593
539
w_impl_items. push ( quote ! {
594
540
#[ doc = #description_with_bits]
595
541
#[ inline( always) ]
0 commit comments