44#
55# Usage: awk -f gen-sysreg.awk sysregs.txt
66
7+ function block_current () {
8+ return __current_block[ __current_block_depth] ;
9+ }
10+
711# Log an error and terminate
812function fatal (msg ) {
913 print " Error at " NR " : " msg > " /dev/stderr"
14+
15+ printf " Current block nesting:"
16+
17+ for (i = 0 ; i <= __current_block_depth; i++ ) {
18+ printf " " __current_block[ i]
19+ }
20+ printf " \n "
21+
1022 exit 1
1123}
1224
13- # Sanity check that the start or end of a block makes sense at this point in
14- # the file. If not, produce an error and terminate.
15- #
16- # @this - the $Block or $EndBlock
17- # @prev - the only valid block to already be in (value of @block)
18- # @new - the new value of @ block
19- function change_block ( this , prev , new ) {
20- if (block != prev )
21- fatal(" unexpected " this " (inside " block " ) " )
22-
23- block = new
25+ # Enter a new block, setting the active block to @block
26+ function block_push ( block ) {
27+ __current_block [ ++ __current_block_depth ] = block
28+ }
29+
30+ # Exit a block, setting the active block to the parent block
31+ function block_pop ( ) {
32+ if (__current_block_depth == 0 )
33+ fatal(" error: block_pop() in root block " )
34+
35+ __current_block_depth -- ;
2436}
2537
2638# Sanity check the number of records for a field makes sense. If not, produce
@@ -84,19 +96,24 @@ BEGIN {
8496 print " /* Generated file - do not edit */"
8597 print " "
8698
87- block = " None"
99+ __current_block_depth = 0
100+ __current_block[ __current_block_depth] = " Root"
88101}
89102
90103END {
104+ if (__current_block_depth != 0 )
105+ fatal(" Missing terminator for " block_current() " block" )
106+
91107 print " #endif /* __ASM_SYSREG_DEFS_H */"
92108}
93109
94110# skip blank lines and comment lines
95111/^ $ / { next }
96112/^ [\t ]* # / { next }
97113
98- /^ SysregFields / {
99- change_block(" SysregFields" , " None" , " SysregFields" )
114+ /^ SysregFields / && block_current() == " Root" {
115+ block_push(" SysregFields" )
116+
100117 expect_fields(2 )
101118
102119 reg = $2
@@ -110,12 +127,10 @@ END {
110127 next
111128}
112129
113- /^ EndSysregFields / {
130+ /^ EndSysregFields / && block_current() == " SysregFields " {
114131 if (next_bit > 0 )
115132 fatal(" Unspecified bits in " reg)
116133
117- change_block(" EndSysregFields" , " SysregFields" , " None" )
118-
119134 define(reg " _RES0" , " (" res0 " )" )
120135 define(reg " _RES1" , " (" res1 " )" )
121136 define(reg " _UNKN" , " (" unkn " )" )
@@ -126,11 +141,13 @@ END {
126141 res1 = null
127142 unkn = null
128143
144+ block_pop()
129145 next
130146}
131147
132- /^ Sysreg / {
133- change_block(" Sysreg" , " None" , " Sysreg" )
148+ /^ Sysreg / && block_current() == " Root" {
149+ block_push(" Sysreg" )
150+
134151 expect_fields(7 )
135152
136153 reg = $2
@@ -160,12 +177,10 @@ END {
160177 next
161178}
162179
163- /^ EndSysreg / {
180+ /^ EndSysreg / && block_current() == " Sysreg " {
164181 if (next_bit > 0 )
165182 fatal(" Unspecified bits in " reg)
166183
167- change_block(" EndSysreg" , " Sysreg" , " None" )
168-
169184 if (res0 != null)
170185 define(reg " _RES0" , " (" res0 " )" )
171186 if (res1 != null)
@@ -185,12 +200,13 @@ END {
185200 res1 = null
186201 unkn = null
187202
203+ block_pop()
188204 next
189205}
190206
191207# Currently this is effectivey a comment, in future we may want to emit
192208# defines for the fields.
193- /^ Fields / && (block == " Sysreg" ) {
209+ /^ Fields / && block_current() == " Sysreg" {
194210 expect_fields(2 )
195211
196212 if (next_bit != 63 )
@@ -208,7 +224,7 @@ END {
208224}
209225
210226
211- /^ Res0 / && (block == " Sysreg" || block == " SysregFields" ) {
227+ /^ Res0 / && (block_current() == " Sysreg" || block_current() == " SysregFields" ) {
212228 expect_fields(2 )
213229 parse_bitdef(reg, " RES0" , $2 )
214230 field = " RES0_" msb " _" lsb
@@ -218,7 +234,7 @@ END {
218234 next
219235}
220236
221- /^ Res1 / && (block == " Sysreg" || block == " SysregFields" ) {
237+ /^ Res1 / && (block_current() == " Sysreg" || block_current() == " SysregFields" ) {
222238 expect_fields(2 )
223239 parse_bitdef(reg, " RES1" , $2 )
224240 field = " RES1_" msb " _" lsb
@@ -228,7 +244,7 @@ END {
228244 next
229245}
230246
231- /^ Unkn / && (block == " Sysreg" || block == " SysregFields" ) {
247+ /^ Unkn / && (block_current() == " Sysreg" || block_current() == " SysregFields" ) {
232248 expect_fields(2 )
233249 parse_bitdef(reg, " UNKN" , $2 )
234250 field = " UNKN_" msb " _" lsb
@@ -238,7 +254,7 @@ END {
238254 next
239255}
240256
241- /^ Field / && (block == " Sysreg" || block == " SysregFields" ) {
257+ /^ Field / && (block_current() == " Sysreg" || block_current() == " SysregFields" ) {
242258 expect_fields(3 )
243259 field = $3
244260 parse_bitdef(reg, field, $2 )
@@ -249,15 +265,16 @@ END {
249265 next
250266}
251267
252- /^ Raz / && (block == " Sysreg" || block == " SysregFields" ) {
268+ /^ Raz / && (block_current() == " Sysreg" || block_current() == " SysregFields" ) {
253269 expect_fields(2 )
254270 parse_bitdef(reg, field, $2 )
255271
256272 next
257273}
258274
259- /^ SignedEnum / {
260- change_block(" Enum<" , " Sysreg" , " Enum" )
275+ /^ SignedEnum / && (block_current() == " Sysreg" || block_current() == " SysregFields" ) {
276+ block_push(" Enum" )
277+
261278 expect_fields(3 )
262279 field = $3
263280 parse_bitdef(reg, field, $2 )
@@ -268,8 +285,9 @@ END {
268285 next
269286}
270287
271- /^ UnsignedEnum / {
272- change_block(" Enum<" , " Sysreg" , " Enum" )
288+ /^ UnsignedEnum / && (block_current() == " Sysreg" || block_current() == " SysregFields" ) {
289+ block_push(" Enum" )
290+
273291 expect_fields(3 )
274292 field = $3
275293 parse_bitdef(reg, field, $2 )
@@ -280,8 +298,9 @@ END {
280298 next
281299}
282300
283- /^ Enum / {
284- change_block(" Enum" , " Sysreg" , " Enum" )
301+ /^ Enum / && (block_current() == " Sysreg" || block_current() == " SysregFields" ) {
302+ block_push(" Enum" )
303+
285304 expect_fields(3 )
286305 field = $3
287306 parse_bitdef(reg, field, $2 )
@@ -291,16 +310,18 @@ END {
291310 next
292311}
293312
294- /^ EndEnum / {
295- change_block( " EndEnum " , " Enum " , " Sysreg " )
313+ /^ EndEnum / && block_current() == " Enum " {
314+
296315 field = null
297316 msb = null
298317 lsb = null
299318 print " "
319+
320+ block_pop()
300321 next
301322}
302323
303- /0b[01 ]+ / && block == " Enum" {
324+ /0b[01 ]+ / && block_current() == " Enum" {
304325 expect_fields(2 )
305326 val = $1
306327 name = $2
0 commit comments