4c606025ba70ab71d4448f95f229656f1e0eeb7d
4 * Copyright 2015 Advanced Micro Devices, Inc.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * on the rights to use, copy, modify, merge, publish, distribute, sub
10 * license, and/or sell copies of the Software, and to permit persons to whom
11 * the Software is furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
21 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
22 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
23 * USE OR OTHER DEALINGS IN THE SOFTWARE.
34 A class for collecting multiple strings in a single larger string that is
35 used by indexing (to avoid relocations in the resulting binary)
41 def add(self
, string
):
42 # We might get lucky with string being a suffix of a previously added string
44 if te
[0].endswith(string
):
45 idx
= te
[1] + len(te
[0]) - len(string
)
50 self
.table
.append((string
, idx
, set((idx
,))))
51 self
.length
+= len(string
) + 1
55 def emit(self
, filp
, name
, static
=True):
58 [static] const char name[] = "...";
62 '"%s\\0" /* %s */' % (
63 te
[0].encode('string_escape'),
64 ', '.join(str(idx
) for idx
in te
[2])
68 filp
.write('%sconst char %s[] =\n%s;\n' % (
69 'static ' if static
else '',
71 '\n'.join('\t' + fragment
for fragment
in fragments
)
76 A class for collecting multiple arrays of integers in a single big array
77 that is used by indexing (to avoid relocations in the resulting binary)
79 def __init__(self
, typename
):
80 self
.typename
= typename
85 # We might get lucky and find the array somewhere in the existing data
89 idx
= self
.table
.index(array
[0], idx
, len(self
.table
) - len(array
) + 1)
91 for i
in range(1, len(array
)):
92 if array
[i
] != self
.table
[idx
+ i
]:
102 idx
= len(self
.table
)
107 def emit(self
, filp
, name
, static
=True):
110 [static] const typename name[] = { ... };
113 idxs
= sorted(self
.idxs
) + [-1]
118 ' '.join((str(elt
) + ',') for elt
in self
.table
[idxs
[i
]:idxs
[i
+1]])
120 for i
in range(len(idxs
) - 1)
123 filp
.write('%sconst %s %s[] = {\n%s\n};\n' % (
124 'static ' if static
else '',
130 def __init__(self
, reg
, s_name
):
132 self
.name
= strip_prefix(s_name
)
134 self
.varname_values
= '%s__%s__values' % (reg
.r_name
.lower(), self
.name
.lower())
137 def __init__(self
, r_name
):
139 self
.name
= strip_prefix(r_name
)
141 self
.own_fields
= True
145 '''Strip prefix in the form ._.*_, e.g. R_001234_'''
146 return s
[s
[2:].find('_')+3:]
148 def parse(filename
, regs
, packets
):
149 stream
= open(filename
)
152 if not line
.startswith('#define '):
155 line
= line
[8:].strip()
157 if line
.startswith('R_'):
158 name
= line
.split()[0]
161 if it
.r_name
== name
:
168 elif line
.startswith('S_'):
169 name
= line
[:line
.find('(')]
171 for it
in reg
.fields
:
172 if it
.s_name
== name
:
176 field
= Field(reg
, name
)
177 reg
.fields
.append(field
)
179 elif line
.startswith('V_'):
182 value
= int(split
[1], 0)
184 for (n
,v
) in field
.values
:
187 sys
.exit('Value mismatch: name = ' + name
)
189 field
.values
.append((name
, value
))
191 elif line
.startswith('PKT3_') and line
.find('0x') != -1 and line
.find('(') == -1:
192 packets
.append(line
.split()[0])
194 # Copy fields to indexed registers which have their fields only defined
195 # at register index 0.
196 # For example, copy fields from CB_COLOR0_INFO to CB_COLORn_INFO, n > 0.
197 match_number
= re
.compile('[0-9]+')
200 # Create a dict of registers with fields and '0' in their name
202 if len(reg
.fields
) and reg
.name
.find('0') != -1:
203 reg_dict
[reg
.name
] = reg
207 if not len(reg
.fields
):
208 reg0
= reg_dict
.get(match_number
.sub('0', reg
.name
))
210 reg
.fields
= reg0
.fields
211 reg
.fields_owner
= reg0
212 reg
.own_fields
= False
215 def write_tables(regs
, packets
):
217 strings
= StringTable()
218 strings_offsets
= IntTable("int")
220 print '/* This file is autogenerated by egd_tables.py from evergreend.h. Do not edit directly. */'
222 print CopyRight
.strip()
228 unsigned name_offset;
231 unsigned values_offset; /* offset into eg_strings_offsets */
235 unsigned name_offset;
238 unsigned fields_offset;
242 unsigned name_offset;
247 print 'static const struct eg_packet3 packet3_table[] = {'
249 print '\t{%s, %s},' % (strings
.add(pkt
[5:]), pkt
)
253 print 'static const struct eg_field egd_fields_table[] = {'
257 if len(reg
.fields
) and reg
.own_fields
:
258 print '\t/* %s */' % (fields_idx
)
260 reg
.fields_idx
= fields_idx
262 for field
in reg
.fields
:
263 if len(field
.values
):
265 for value
in field
.values
:
266 while value
[1] >= len(values_offsets
):
267 values_offsets
.append(-1)
268 values_offsets
[value
[1]] = strings
.add(strip_prefix(value
[0]))
269 print '\t{%s, %s(~0u), %s, %s},' % (
270 strings
.add(field
.name
), field
.s_name
,
271 len(values_offsets
), strings_offsets
.add(values_offsets
))
273 print '\t{%s, %s(~0u)},' % (strings
.add(field
.name
), field
.s_name
)
279 print 'static const struct eg_reg egd_reg_table[] = {'
282 print '\t{%s, %s, %s, %s},' % (strings
.add(reg
.name
), reg
.r_name
,
283 len(reg
.fields
), reg
.fields_idx
if reg
.own_fields
else reg
.fields_owner
.fields_idx
)
285 print '\t{%s, %s},' % (strings
.add(reg
.name
), reg
.r_name
)
289 strings
.emit(sys
.stdout
, "egd_strings")
293 strings_offsets
.emit(sys
.stdout
, "egd_strings_offsets")
302 for arg
in sys
.argv
[1:]:
303 parse(arg
, regs
, packets
)
304 write_tables(regs
, packets
)
307 if __name__
== '__main__':
310 # kate: space-indent on; indent-width 4; replace-tabs on;