1- from typing import TextIO , Set , Optional , List
1+ from typing import Type , TextIO , Set , Optional , List
22import os
33import re
44
@@ -39,6 +39,10 @@ def run(self, path: str, top_nodes: List[AddrmapNode]) -> None:
3939 template .stream (context ).dump (f )
4040 f .write ("\n " )
4141
42+ # Write enums
43+ if self .ds .generate_enums :
44+ self .write_enums (top_nodes )
45+
4246 # Generate definitions
4347 for node in top_nodes :
4448 self .root_node = node
@@ -102,14 +106,19 @@ def write_bitfields(self, grp_name: str, regwidth: int, fields: List[FieldNode])
102106 self .write ("struct __attribute__ ((__packed__)) {\n " )
103107 self .push_indent ()
104108
109+ def get_field_type (field : FieldNode ) -> str :
110+ encode = field .get_property ("encode" )
111+ return f"uint{ regwidth } _t" if not self .ds .generate_enums or encode is None else \
112+ f"{ self .get_enum_prefix (encode )} _e"
113+
105114 if self .ds .bitfield_order_ltoh :
106115 # Bits are packed in struct LSb --> MSb
107116 current_offset = 0
108117 for field in fields :
109118 if field .low > current_offset :
110119 self .write (f"uint{ regwidth } _t :{ field .low - current_offset :d} ;\n " )
111120 current_offset = field .low
112- self .write (f"uint { regwidth } _t { kwf (field .inst_name )} :{ field .width :d} ;\n " )
121+ self .write (f"{ get_field_type ( field ) } { kwf (field .inst_name )} :{ field .width :d} ;\n " )
113122 current_offset += field .width
114123
115124 if current_offset < regwidth :
@@ -121,7 +130,7 @@ def write_bitfields(self, grp_name: str, regwidth: int, fields: List[FieldNode])
121130 if field .high < current_offset :
122131 self .write (f"uint{ regwidth } _t :{ current_offset - field .high :d} ;\n " )
123132 current_offset = field .high
124- self .write (f"uint { regwidth } _t { kwf (field .inst_name )} :{ field .width :d} ;\n " )
133+ self .write (f"{ get_field_type ( field ) } { kwf (field .inst_name )} :{ field .width :d} ;\n " )
125134 current_offset -= field .width
126135
127136 if current_offset > - 1 :
@@ -343,3 +352,39 @@ def write_group_struct_member(self, node: AddressableNode) -> None:
343352
344353 struct_name = self .get_struct_name (node )
345354 self .write (f"{ struct_name } { kwf (node .inst_name )} { array_suffix } ;\n " )
355+
356+ @staticmethod
357+ def get_enum_prefix (user_enum : Type ['UserEnum' ]) -> str :
358+ scope = user_enum .get_scope_path ("__" )
359+ if scope :
360+ return f"{ scope } __{ user_enum .type_name } "
361+ else :
362+ return user_enum .type_name
363+
364+ def write_enum (self , user_enum : Type ['UserEnum' ]) -> None :
365+ prefix = self .get_enum_prefix (user_enum )
366+ lines = []
367+ for enum_member in user_enum :
368+ lines .append (f" { prefix } __{ enum_member .name } = { enum_member .value } " )
369+
370+ self .write ("typedef enum {\n "
371+ + ",\n " .join (lines )
372+ + f"\n }} { prefix } _e;\n " )
373+
374+ def write_enums (self , top_nodes : List [AddrmapNode ]) -> None :
375+ user_enums = []
376+
377+ class Listener (RDLListener ):
378+ def enter_Field (listener , node : FieldNode ) -> Optional [WalkerAction ]:
379+ encode = node .get_property ("encode" )
380+ if encode is not None and encode not in user_enums :
381+ user_enums .append (encode )
382+ return None
383+
384+ for node in top_nodes :
385+ self .root_node = node
386+ RDLWalker ().walk (node , Listener ())
387+
388+ for user_enum in user_enums :
389+ self .write ("\n " )
390+ self .write_enum (user_enum )
0 commit comments