1bf215546Sopenharmony_ciCopyRight = ''' 2bf215546Sopenharmony_ci/* 3bf215546Sopenharmony_ci * Copyright 2015 Advanced Micro Devices, Inc. 4bf215546Sopenharmony_ci * 5bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 6bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 7bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 8bf215546Sopenharmony_ci * on the rights to use, copy, modify, merge, publish, distribute, sub 9bf215546Sopenharmony_ci * license, and/or sell copies of the Software, and to permit persons to whom 10bf215546Sopenharmony_ci * the Software is furnished to do so, subject to the following conditions: 11bf215546Sopenharmony_ci * 12bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 13bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 14bf215546Sopenharmony_ci * Software. 15bf215546Sopenharmony_ci * 16bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 19bf215546Sopenharmony_ci * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 20bf215546Sopenharmony_ci * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 21bf215546Sopenharmony_ci * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 22bf215546Sopenharmony_ci * USE OR OTHER DEALINGS IN THE SOFTWARE. 23bf215546Sopenharmony_ci * 24bf215546Sopenharmony_ci */ 25bf215546Sopenharmony_ci''' 26bf215546Sopenharmony_ci 27bf215546Sopenharmony_ciimport sys 28bf215546Sopenharmony_ciimport re 29bf215546Sopenharmony_ci 30bf215546Sopenharmony_ci 31bf215546Sopenharmony_ciclass StringTable: 32bf215546Sopenharmony_ci """ 33bf215546Sopenharmony_ci A class for collecting multiple strings in a single larger string that is 34bf215546Sopenharmony_ci used by indexing (to avoid relocations in the resulting binary) 35bf215546Sopenharmony_ci """ 36bf215546Sopenharmony_ci def __init__(self): 37bf215546Sopenharmony_ci self.table = [] 38bf215546Sopenharmony_ci self.length = 0 39bf215546Sopenharmony_ci 40bf215546Sopenharmony_ci def add(self, string): 41bf215546Sopenharmony_ci # We might get lucky with string being a suffix of a previously added string 42bf215546Sopenharmony_ci for te in self.table: 43bf215546Sopenharmony_ci if te[0].endswith(string): 44bf215546Sopenharmony_ci idx = te[1] + len(te[0]) - len(string) 45bf215546Sopenharmony_ci te[2].add(idx) 46bf215546Sopenharmony_ci return idx 47bf215546Sopenharmony_ci 48bf215546Sopenharmony_ci idx = self.length 49bf215546Sopenharmony_ci self.table.append((string, idx, set((idx,)))) 50bf215546Sopenharmony_ci self.length += len(string) + 1 51bf215546Sopenharmony_ci 52bf215546Sopenharmony_ci return idx 53bf215546Sopenharmony_ci 54bf215546Sopenharmony_ci def emit(self, filp, name, static=True): 55bf215546Sopenharmony_ci """ 56bf215546Sopenharmony_ci Write 57bf215546Sopenharmony_ci [static] const char name[] = "..."; 58bf215546Sopenharmony_ci to filp. 59bf215546Sopenharmony_ci """ 60bf215546Sopenharmony_ci fragments = [ 61bf215546Sopenharmony_ci '"%s\\0" /* %s */' % ( 62bf215546Sopenharmony_ci te[0].encode('unicode_escape').decode(), 63bf215546Sopenharmony_ci ', '.join(str(idx) for idx in te[2]) 64bf215546Sopenharmony_ci ) 65bf215546Sopenharmony_ci for te in self.table 66bf215546Sopenharmony_ci ] 67bf215546Sopenharmony_ci filp.write('%sconst char %s[] =\n%s;\n' % ( 68bf215546Sopenharmony_ci 'static ' if static else '', 69bf215546Sopenharmony_ci name, 70bf215546Sopenharmony_ci '\n'.join('\t' + fragment for fragment in fragments) 71bf215546Sopenharmony_ci )) 72bf215546Sopenharmony_ci 73bf215546Sopenharmony_ciclass IntTable: 74bf215546Sopenharmony_ci """ 75bf215546Sopenharmony_ci A class for collecting multiple arrays of integers in a single big array 76bf215546Sopenharmony_ci that is used by indexing (to avoid relocations in the resulting binary) 77bf215546Sopenharmony_ci """ 78bf215546Sopenharmony_ci def __init__(self, typename): 79bf215546Sopenharmony_ci self.typename = typename 80bf215546Sopenharmony_ci self.table = [] 81bf215546Sopenharmony_ci self.idxs = set() 82bf215546Sopenharmony_ci 83bf215546Sopenharmony_ci def add(self, array): 84bf215546Sopenharmony_ci # We might get lucky and find the array somewhere in the existing data 85bf215546Sopenharmony_ci try: 86bf215546Sopenharmony_ci idx = 0 87bf215546Sopenharmony_ci while True: 88bf215546Sopenharmony_ci idx = self.table.index(array[0], idx, len(self.table) - len(array) + 1) 89bf215546Sopenharmony_ci 90bf215546Sopenharmony_ci for i in range(1, len(array)): 91bf215546Sopenharmony_ci if array[i] != self.table[idx + i]: 92bf215546Sopenharmony_ci break 93bf215546Sopenharmony_ci else: 94bf215546Sopenharmony_ci self.idxs.add(idx) 95bf215546Sopenharmony_ci return idx 96bf215546Sopenharmony_ci 97bf215546Sopenharmony_ci idx += 1 98bf215546Sopenharmony_ci except ValueError: 99bf215546Sopenharmony_ci pass 100bf215546Sopenharmony_ci 101bf215546Sopenharmony_ci idx = len(self.table) 102bf215546Sopenharmony_ci self.table += array 103bf215546Sopenharmony_ci self.idxs.add(idx) 104bf215546Sopenharmony_ci return idx 105bf215546Sopenharmony_ci 106bf215546Sopenharmony_ci def emit(self, filp, name, static=True): 107bf215546Sopenharmony_ci """ 108bf215546Sopenharmony_ci Write 109bf215546Sopenharmony_ci [static] const typename name[] = { ... }; 110bf215546Sopenharmony_ci to filp. 111bf215546Sopenharmony_ci """ 112bf215546Sopenharmony_ci idxs = sorted(self.idxs) + [len(self.table)] 113bf215546Sopenharmony_ci 114bf215546Sopenharmony_ci fragments = [ 115bf215546Sopenharmony_ci ('\t/* %s */ %s' % ( 116bf215546Sopenharmony_ci idxs[i], 117bf215546Sopenharmony_ci ' '.join((str(elt) + ',') for elt in self.table[idxs[i]:idxs[i+1]]) 118bf215546Sopenharmony_ci )) 119bf215546Sopenharmony_ci for i in range(len(idxs) - 1) 120bf215546Sopenharmony_ci ] 121bf215546Sopenharmony_ci 122bf215546Sopenharmony_ci filp.write('%sconst %s %s[] = {\n%s\n};\n' % ( 123bf215546Sopenharmony_ci 'static ' if static else '', 124bf215546Sopenharmony_ci self.typename, name, 125bf215546Sopenharmony_ci '\n'.join(fragments) 126bf215546Sopenharmony_ci )) 127bf215546Sopenharmony_ci 128bf215546Sopenharmony_ciclass Field: 129bf215546Sopenharmony_ci def __init__(self, reg, s_name): 130bf215546Sopenharmony_ci self.s_name = s_name 131bf215546Sopenharmony_ci self.name = strip_prefix(s_name) 132bf215546Sopenharmony_ci self.values = [] 133bf215546Sopenharmony_ci self.varname_values = '%s__%s__values' % (reg.r_name.lower(), self.name.lower()) 134bf215546Sopenharmony_ci 135bf215546Sopenharmony_ciclass Reg: 136bf215546Sopenharmony_ci def __init__(self, r_name): 137bf215546Sopenharmony_ci self.r_name = r_name 138bf215546Sopenharmony_ci self.name = strip_prefix(r_name) 139bf215546Sopenharmony_ci self.fields = [] 140bf215546Sopenharmony_ci self.own_fields = True 141bf215546Sopenharmony_ci 142bf215546Sopenharmony_ci 143bf215546Sopenharmony_cidef strip_prefix(s): 144bf215546Sopenharmony_ci '''Strip prefix in the form ._.*_, e.g. R_001234_''' 145bf215546Sopenharmony_ci return s[s[2:].find('_')+3:] 146bf215546Sopenharmony_ci 147bf215546Sopenharmony_cidef parse(filename, regs, packets): 148bf215546Sopenharmony_ci stream = open(filename) 149bf215546Sopenharmony_ci 150bf215546Sopenharmony_ci for line in stream: 151bf215546Sopenharmony_ci if not line.startswith('#define '): 152bf215546Sopenharmony_ci continue 153bf215546Sopenharmony_ci 154bf215546Sopenharmony_ci line = line[8:].strip() 155bf215546Sopenharmony_ci 156bf215546Sopenharmony_ci if line.startswith('R_'): 157bf215546Sopenharmony_ci name = line.split()[0] 158bf215546Sopenharmony_ci 159bf215546Sopenharmony_ci for it in regs: 160bf215546Sopenharmony_ci if it.r_name == name: 161bf215546Sopenharmony_ci reg = it 162bf215546Sopenharmony_ci break 163bf215546Sopenharmony_ci else: 164bf215546Sopenharmony_ci reg = Reg(name) 165bf215546Sopenharmony_ci regs.append(reg) 166bf215546Sopenharmony_ci 167bf215546Sopenharmony_ci elif line.startswith('S_'): 168bf215546Sopenharmony_ci name = line[:line.find('(')] 169bf215546Sopenharmony_ci 170bf215546Sopenharmony_ci for it in reg.fields: 171bf215546Sopenharmony_ci if it.s_name == name: 172bf215546Sopenharmony_ci field = it 173bf215546Sopenharmony_ci break 174bf215546Sopenharmony_ci else: 175bf215546Sopenharmony_ci field = Field(reg, name) 176bf215546Sopenharmony_ci reg.fields.append(field) 177bf215546Sopenharmony_ci 178bf215546Sopenharmony_ci elif line.startswith('V_'): 179bf215546Sopenharmony_ci split = line.split() 180bf215546Sopenharmony_ci name = split[0] 181bf215546Sopenharmony_ci value = int(split[1], 0) 182bf215546Sopenharmony_ci 183bf215546Sopenharmony_ci for (n,v) in field.values: 184bf215546Sopenharmony_ci if n == name: 185bf215546Sopenharmony_ci if v != value: 186bf215546Sopenharmony_ci sys.exit('Value mismatch: name = ' + name) 187bf215546Sopenharmony_ci 188bf215546Sopenharmony_ci field.values.append((name, value)) 189bf215546Sopenharmony_ci 190bf215546Sopenharmony_ci elif line.startswith('PKT3_') and line.find('0x') != -1 and line.find('(') == -1: 191bf215546Sopenharmony_ci packets.append(line.split()[0]) 192bf215546Sopenharmony_ci 193bf215546Sopenharmony_ci # Copy fields to indexed registers which have their fields only defined 194bf215546Sopenharmony_ci # at register index 0. 195bf215546Sopenharmony_ci # For example, copy fields from CB_COLOR0_INFO to CB_COLORn_INFO, n > 0. 196bf215546Sopenharmony_ci match_number = re.compile('[0-9]+') 197bf215546Sopenharmony_ci reg_dict = dict() 198bf215546Sopenharmony_ci 199bf215546Sopenharmony_ci # Create a dict of registers with fields and '0' in their name 200bf215546Sopenharmony_ci for reg in regs: 201bf215546Sopenharmony_ci if len(reg.fields) and reg.name.find('0') != -1: 202bf215546Sopenharmony_ci reg_dict[reg.name] = reg 203bf215546Sopenharmony_ci 204bf215546Sopenharmony_ci # Assign fields 205bf215546Sopenharmony_ci for reg in regs: 206bf215546Sopenharmony_ci if not len(reg.fields): 207bf215546Sopenharmony_ci reg0 = reg_dict.get(match_number.sub('0', reg.name)) 208bf215546Sopenharmony_ci if reg0 != None: 209bf215546Sopenharmony_ci reg.fields = reg0.fields 210bf215546Sopenharmony_ci reg.fields_owner = reg0 211bf215546Sopenharmony_ci reg.own_fields = False 212bf215546Sopenharmony_ci 213bf215546Sopenharmony_ci 214bf215546Sopenharmony_cidef write_tables(regs, packets): 215bf215546Sopenharmony_ci 216bf215546Sopenharmony_ci strings = StringTable() 217bf215546Sopenharmony_ci strings_offsets = IntTable("int") 218bf215546Sopenharmony_ci 219bf215546Sopenharmony_ci print('/* This file is autogenerated by egd_tables.py from evergreend.h. Do not edit directly. */') 220bf215546Sopenharmony_ci print() 221bf215546Sopenharmony_ci print(CopyRight.strip()) 222bf215546Sopenharmony_ci print(''' 223bf215546Sopenharmony_ci#ifndef EG_TABLES_H 224bf215546Sopenharmony_ci#define EG_TABLES_H 225bf215546Sopenharmony_ci 226bf215546Sopenharmony_cistruct eg_field { 227bf215546Sopenharmony_ci unsigned name_offset; 228bf215546Sopenharmony_ci unsigned mask; 229bf215546Sopenharmony_ci unsigned num_values; 230bf215546Sopenharmony_ci unsigned values_offset; /* offset into eg_strings_offsets */ 231bf215546Sopenharmony_ci}; 232bf215546Sopenharmony_ci 233bf215546Sopenharmony_cistruct eg_reg { 234bf215546Sopenharmony_ci unsigned name_offset; 235bf215546Sopenharmony_ci unsigned offset; 236bf215546Sopenharmony_ci unsigned num_fields; 237bf215546Sopenharmony_ci unsigned fields_offset; 238bf215546Sopenharmony_ci}; 239bf215546Sopenharmony_ci 240bf215546Sopenharmony_cistruct eg_packet3 { 241bf215546Sopenharmony_ci unsigned name_offset; 242bf215546Sopenharmony_ci unsigned op; 243bf215546Sopenharmony_ci}; 244bf215546Sopenharmony_ci''') 245bf215546Sopenharmony_ci 246bf215546Sopenharmony_ci print('static const struct eg_packet3 packet3_table[] = {') 247bf215546Sopenharmony_ci for pkt in packets: 248bf215546Sopenharmony_ci print('\t{%s, %s},' % (strings.add(pkt[5:]), pkt)) 249bf215546Sopenharmony_ci print('};') 250bf215546Sopenharmony_ci print() 251bf215546Sopenharmony_ci 252bf215546Sopenharmony_ci print('static const struct eg_field egd_fields_table[] = {') 253bf215546Sopenharmony_ci 254bf215546Sopenharmony_ci fields_idx = 0 255bf215546Sopenharmony_ci for reg in regs: 256bf215546Sopenharmony_ci if len(reg.fields) and reg.own_fields: 257bf215546Sopenharmony_ci print('\t/* %s */' % (fields_idx)) 258bf215546Sopenharmony_ci 259bf215546Sopenharmony_ci reg.fields_idx = fields_idx 260bf215546Sopenharmony_ci 261bf215546Sopenharmony_ci for field in reg.fields: 262bf215546Sopenharmony_ci if len(field.values): 263bf215546Sopenharmony_ci values_offsets = [] 264bf215546Sopenharmony_ci for value in field.values: 265bf215546Sopenharmony_ci while value[1] >= len(values_offsets): 266bf215546Sopenharmony_ci values_offsets.append(-1) 267bf215546Sopenharmony_ci values_offsets[value[1]] = strings.add(strip_prefix(value[0])) 268bf215546Sopenharmony_ci print('\t{%s, %s(~0u), %s, %s},' % ( 269bf215546Sopenharmony_ci strings.add(field.name), field.s_name, 270bf215546Sopenharmony_ci len(values_offsets), strings_offsets.add(values_offsets))) 271bf215546Sopenharmony_ci else: 272bf215546Sopenharmony_ci print('\t{%s, %s(~0u)},' % (strings.add(field.name), field.s_name)) 273bf215546Sopenharmony_ci fields_idx += 1 274bf215546Sopenharmony_ci 275bf215546Sopenharmony_ci print('};') 276bf215546Sopenharmony_ci print() 277bf215546Sopenharmony_ci 278bf215546Sopenharmony_ci print('static const struct eg_reg egd_reg_table[] = {') 279bf215546Sopenharmony_ci for reg in regs: 280bf215546Sopenharmony_ci if len(reg.fields): 281bf215546Sopenharmony_ci print('\t{%s, %s, %s, %s},' % (strings.add(reg.name), reg.r_name, 282bf215546Sopenharmony_ci len(reg.fields), reg.fields_idx if reg.own_fields else reg.fields_owner.fields_idx)) 283bf215546Sopenharmony_ci else: 284bf215546Sopenharmony_ci print('\t{%s, %s},' % (strings.add(reg.name), reg.r_name)) 285bf215546Sopenharmony_ci print('};') 286bf215546Sopenharmony_ci print() 287bf215546Sopenharmony_ci 288bf215546Sopenharmony_ci strings.emit(sys.stdout, "egd_strings") 289bf215546Sopenharmony_ci 290bf215546Sopenharmony_ci print() 291bf215546Sopenharmony_ci 292bf215546Sopenharmony_ci strings_offsets.emit(sys.stdout, "egd_strings_offsets") 293bf215546Sopenharmony_ci 294bf215546Sopenharmony_ci print() 295bf215546Sopenharmony_ci print('#endif') 296bf215546Sopenharmony_ci 297bf215546Sopenharmony_ci 298bf215546Sopenharmony_cidef main(): 299bf215546Sopenharmony_ci regs = [] 300bf215546Sopenharmony_ci packets = [] 301bf215546Sopenharmony_ci for arg in sys.argv[1:]: 302bf215546Sopenharmony_ci parse(arg, regs, packets) 303bf215546Sopenharmony_ci write_tables(regs, packets) 304bf215546Sopenharmony_ci 305bf215546Sopenharmony_ci 306bf215546Sopenharmony_ciif __name__ == '__main__': 307bf215546Sopenharmony_ci main() 308bf215546Sopenharmony_ci 309bf215546Sopenharmony_ci# kate: space-indent on; indent-width 4; replace-tabs on; 310