5 * Copyright 2015 Advanced Micro Devices, Inc.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * on the rights to use, copy, modify, merge, publish, distribute, sub
11 * license, and/or sell copies of the Software, and to permit persons to whom
12 * the Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice (including the next
15 * paragraph) shall be included in all copies or substantial portions of the
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
22 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24 * USE OR OTHER DEALINGS IN THE SOFTWARE.
35 A class for collecting multiple strings in a single larger string that is
36 used by indexing (to avoid relocations in the resulting binary)
42 def add(self
, string
):
43 # We might get lucky with string being a suffix of a previously added string
45 if te
[0].endswith(string
):
46 idx
= te
[1] + len(te
[0]) - len(string
)
51 self
.table
.append((string
, idx
, set((idx
,))))
52 self
.length
+= len(string
) + 1
56 def emit(self
, filp
, name
, static
=True):
59 [static] const char name[] = "...";
63 '"%s\\0" /* %s */' % (
64 te
[0].encode('string_escape'),
65 ', '.join(str(idx
) for idx
in te
[2])
69 filp
.write('%sconst char %s[] =\n%s;\n' % (
70 'static ' if static
else '',
72 '\n'.join('\t' + fragment
for fragment
in fragments
)
77 A class for collecting multiple arrays of integers in a single big array
78 that is used by indexing (to avoid relocations in the resulting binary)
80 def __init__(self
, typename
):
81 self
.typename
= typename
86 # We might get lucky and find the array somewhere in the existing data
90 idx
= self
.table
.index(array
[0], idx
, len(self
.table
) - len(array
) + 1)
92 for i
in range(1, len(array
)):
93 if array
[i
] != self
.table
[idx
+ i
]:
103 idx
= len(self
.table
)
108 def emit(self
, filp
, name
, static
=True):
111 [static] const typename name[] = { ... };
114 idxs
= sorted(self
.idxs
) + [-1]
119 ' '.join((str(elt
) + ',') for elt
in self
.table
[idxs
[i
]:idxs
[i
+1]])
121 for i
in range(len(idxs
) - 1)
124 filp
.write('%sconst %s %s[] = {\n%s\n};\n' % (
125 'static ' if static
else '',
131 def __init__(self
, reg
, s_name
):
133 self
.name
= strip_prefix(s_name
)
135 self
.varname_values
= '%s__%s__values' % (reg
.r_name
.lower(), self
.name
.lower())
138 def __init__(self
, r_name
):
140 self
.name
= strip_prefix(r_name
)
142 self
.own_fields
= True
146 '''Strip prefix in the form ._.*_, e.g. R_001234_'''
147 return s
[s
[2:].find('_')+3:]
151 stream
= open(filename
)
156 if not line
.startswith('#define '):
159 line
= line
[8:].strip()
161 if line
.startswith('R_'):
162 reg
= Reg(line
.split()[0])
165 elif line
.startswith('S_'):
166 field
= Field(reg
, line
[:line
.find('(')])
167 reg
.fields
.append(field
)
169 elif line
.startswith('V_'):
171 field
.values
.append((split
[0], int(split
[1], 0)))
173 elif line
.startswith('PKT3_') and line
.find('0x') != -1 and line
.find('(') == -1:
174 packets
.append(line
.split()[0])
176 # Copy fields to indexed registers which have their fields only defined
177 # at register index 0.
178 # For example, copy fields from CB_COLOR0_INFO to CB_COLORn_INFO, n > 0.
179 match_number
= re
.compile('[0-9]+')
182 # Create a dict of registers with fields and '0' in their name
184 if len(reg
.fields
) and reg
.name
.find('0') != -1:
185 reg_dict
[reg
.name
] = reg
189 if not len(reg
.fields
):
190 reg0
= reg_dict
.get(match_number
.sub('0', reg
.name
))
192 reg
.fields
= reg0
.fields
193 reg
.fields_owner
= reg0
194 reg
.own_fields
= False
196 return (regs
, packets
)
199 def write_tables(tables
):
203 strings
= StringTable()
204 strings_offsets
= IntTable("int")
206 print '/* This file is autogenerated by sid_tables.py from sid.h. Do not edit directly. */'
208 print CopyRight
.strip()
214 unsigned name_offset;
217 unsigned values_offset; /* offset into sid_strings_offsets */
221 unsigned name_offset;
224 unsigned fields_offset;
228 unsigned name_offset;
233 print 'static const struct si_packet3 packet3_table[] = {'
235 print '\t{%s, %s},' % (strings
.add(pkt
[5:]), pkt
)
239 print 'static const struct si_field sid_fields_table[] = {'
243 if len(reg
.fields
) and reg
.own_fields
:
244 print '\t/* %s */' % (fields_idx
)
246 reg
.fields_idx
= fields_idx
248 for field
in reg
.fields
:
249 if len(field
.values
):
251 for value
in field
.values
:
252 while value
[1] >= len(values_offsets
):
253 values_offsets
.append(-1)
254 values_offsets
[value
[1]] = strings
.add(strip_prefix(value
[0]))
255 print '\t{%s, %s(~0u), %s, %s},' % (
256 strings
.add(field
.name
), field
.s_name
,
257 len(values_offsets
), strings_offsets
.add(values_offsets
))
259 print '\t{%s, %s(~0u)},' % (strings
.add(field
.name
), field
.s_name
)
265 print 'static const struct si_reg sid_reg_table[] = {'
268 print '\t{%s, %s, %s, %s},' % (strings
.add(reg
.name
), reg
.r_name
,
269 len(reg
.fields
), reg
.fields_idx
if reg
.own_fields
else reg
.fields_owner
.fields_idx
)
271 print '\t{%s, %s},' % (strings
.add(reg
.name
), reg
.r_name
)
275 strings
.emit(sys
.stdout
, "sid_strings")
279 strings_offsets
.emit(sys
.stdout
, "sid_strings_offsets")
287 for arg
in sys
.argv
[1:]:
288 tables
.extend(parse(arg
))
292 if __name__
== '__main__':
295 # kate: space-indent on; indent-width 4; replace-tabs on;