@@ -202,6 +202,7 @@ fn register_or_cluster_block(
202
202
name : Option < & str > ,
203
203
) -> Result < Tokens > {
204
204
let mut fields = Tokens :: new ( ) ;
205
+ let mut helper_types = Tokens :: new ( ) ;
205
206
206
207
let ercs_expanded = expand ( ercs, defs, name) ?;
207
208
@@ -230,32 +231,48 @@ fn register_or_cluster_block(
230
231
231
232
last_end = Some ( region. end ) ;
232
233
233
- if region. fields . len ( ) > 1 {
234
- // TODO: this is where we'd emit a union container
235
- eprintln ! ( "WARNING: overlaps for region offset={}-{}. \
236
- Using the first one of these:",
237
- region. offset, region. end-1 ) ;
238
-
239
- for f in & region. fields {
240
- eprintln ! ( " {:?} {}-{}" , f. field. ident, f. offset,
241
- ( f. offset + f. size / BITS_PER_BYTE ) -1 ) ;
242
- }
243
- }
234
+ let mut region_fields = Tokens :: new ( ) ;
235
+
236
+ for reg_block_field in & region. fields {
237
+ let comment = & format ! (
238
+ "0x{:02x} - {}" ,
239
+ reg_block_field. offset,
240
+ util:: respace( & reg_block_field. description) ,
241
+ ) [ ..] ;
244
242
245
- let reg_block_field = & region. fields [ 0 ] ;
243
+ region_fields. append ( quote ! {
244
+ #[ doc = #comment]
245
+ } ) ;
246
246
247
- let comment = & format ! (
248
- "0x{:02x} - {}" ,
249
- reg_block_field. offset,
250
- util:: respace( & reg_block_field. description) ,
251
- ) [ ..] ;
252
247
253
- fields. append ( quote ! {
254
- #[ doc = #comment]
255
- } ) ;
248
+ reg_block_field. field . to_tokens ( & mut region_fields) ;
249
+ Ident :: new ( "," ) . to_tokens ( & mut region_fields) ;
250
+ }
251
+
252
+ if region. fields . len ( ) > 1 {
253
+ // TODO: come up with nicer naming. Right now we're using the
254
+ // region index as a unique-within-this-block identifier counter.
255
+ let name = Ident :: new ( format ! ( "u{}" , i) ) ;
256
+
257
+ // TODO: if we only have a single region and that region is a
258
+ // union, the overall RegisterBlock could be a union
259
+
260
+ helper_types. append ( quote ! {
261
+ /// Union container for a set of overlapping registers
262
+ #[ repr( C ) ]
263
+ pub union #name {
264
+ #region_fields
265
+ }
266
+ } ) ;
267
+
268
+ fields. append ( quote ! {
269
+ #name: #name
270
+ } ) ;
271
+ Ident :: new ( "," ) . to_tokens ( & mut fields) ;
256
272
257
- reg_block_field. field . to_tokens ( & mut fields) ;
258
- Ident :: new ( "," ) . to_tokens ( & mut fields) ;
273
+ } else {
274
+ fields. append ( & region_fields) ;
275
+ }
259
276
}
260
277
261
278
let name = Ident :: new ( match name {
@@ -269,6 +286,8 @@ fn register_or_cluster_block(
269
286
pub struct #name {
270
287
#fields
271
288
}
289
+
290
+ #helper_types
272
291
} )
273
292
}
274
293
0 commit comments