1*61046927SAndroid Build Coastguard Worker#!/usr/bin/python3 2*61046927SAndroid Build Coastguard Worker# 3*61046927SAndroid Build Coastguard Worker# Copyright © 2019-2024 Google, Inc. 4*61046927SAndroid Build Coastguard Worker# 5*61046927SAndroid Build Coastguard Worker# SPDX-License-Identifier: MIT 6*61046927SAndroid Build Coastguard Worker 7*61046927SAndroid Build Coastguard Workerimport xml.parsers.expat 8*61046927SAndroid Build Coastguard Workerimport sys 9*61046927SAndroid Build Coastguard Workerimport os 10*61046927SAndroid Build Coastguard Workerimport collections 11*61046927SAndroid Build Coastguard Workerimport argparse 12*61046927SAndroid Build Coastguard Workerimport time 13*61046927SAndroid Build Coastguard Workerimport datetime 14*61046927SAndroid Build Coastguard Worker 15*61046927SAndroid Build Coastguard Workerclass Error(Exception): 16*61046927SAndroid Build Coastguard Worker def __init__(self, message): 17*61046927SAndroid Build Coastguard Worker self.message = message 18*61046927SAndroid Build Coastguard Worker 19*61046927SAndroid Build Coastguard Workerclass Enum(object): 20*61046927SAndroid Build Coastguard Worker def __init__(self, name): 21*61046927SAndroid Build Coastguard Worker self.name = name 22*61046927SAndroid Build Coastguard Worker self.values = [] 23*61046927SAndroid Build Coastguard Worker 24*61046927SAndroid Build Coastguard Worker def has_name(self, name): 25*61046927SAndroid Build Coastguard Worker for (n, value) in self.values: 26*61046927SAndroid Build Coastguard Worker if n == name: 27*61046927SAndroid Build Coastguard Worker return True 28*61046927SAndroid Build Coastguard Worker return False 29*61046927SAndroid Build Coastguard Worker 30*61046927SAndroid Build Coastguard Worker def names(self): 31*61046927SAndroid Build Coastguard Worker return [n for (n, value) in self.values] 32*61046927SAndroid Build Coastguard Worker 33*61046927SAndroid Build Coastguard Worker def dump(self, is_deprecated): 34*61046927SAndroid Build Coastguard Worker use_hex = False 35*61046927SAndroid Build Coastguard Worker for (name, value) in self.values: 36*61046927SAndroid Build Coastguard Worker if value > 0x1000: 37*61046927SAndroid Build Coastguard Worker use_hex = True 38*61046927SAndroid Build Coastguard Worker 39*61046927SAndroid Build Coastguard Worker print("enum %s {" % self.name) 40*61046927SAndroid Build Coastguard Worker for (name, value) in self.values: 41*61046927SAndroid Build Coastguard Worker if use_hex: 42*61046927SAndroid Build Coastguard Worker print("\t%s = 0x%08x," % (name, value)) 43*61046927SAndroid Build Coastguard Worker else: 44*61046927SAndroid Build Coastguard Worker print("\t%s = %d," % (name, value)) 45*61046927SAndroid Build Coastguard Worker print("};\n") 46*61046927SAndroid Build Coastguard Worker 47*61046927SAndroid Build Coastguard Worker def dump_pack_struct(self, is_deprecated): 48*61046927SAndroid Build Coastguard Worker pass 49*61046927SAndroid Build Coastguard Worker 50*61046927SAndroid Build Coastguard Workerclass Field(object): 51*61046927SAndroid Build Coastguard Worker def __init__(self, name, low, high, shr, type, parser): 52*61046927SAndroid Build Coastguard Worker self.name = name 53*61046927SAndroid Build Coastguard Worker self.low = low 54*61046927SAndroid Build Coastguard Worker self.high = high 55*61046927SAndroid Build Coastguard Worker self.shr = shr 56*61046927SAndroid Build Coastguard Worker self.type = type 57*61046927SAndroid Build Coastguard Worker 58*61046927SAndroid Build Coastguard Worker builtin_types = [ None, "a3xx_regid", "boolean", "uint", "hex", "int", "fixed", "ufixed", "float", "address", "waddress" ] 59*61046927SAndroid Build Coastguard Worker 60*61046927SAndroid Build Coastguard Worker maxpos = parser.current_bitsize - 1 61*61046927SAndroid Build Coastguard Worker 62*61046927SAndroid Build Coastguard Worker if low < 0 or low > maxpos: 63*61046927SAndroid Build Coastguard Worker raise parser.error("low attribute out of range: %d" % low) 64*61046927SAndroid Build Coastguard Worker if high < 0 or high > maxpos: 65*61046927SAndroid Build Coastguard Worker raise parser.error("high attribute out of range: %d" % high) 66*61046927SAndroid Build Coastguard Worker if high < low: 67*61046927SAndroid Build Coastguard Worker raise parser.error("low is greater than high: low=%d, high=%d" % (low, high)) 68*61046927SAndroid Build Coastguard Worker if self.type == "boolean" and not low == high: 69*61046927SAndroid Build Coastguard Worker raise parser.error("booleans should be 1 bit fields") 70*61046927SAndroid Build Coastguard Worker elif self.type == "float" and not (high - low == 31 or high - low == 15): 71*61046927SAndroid Build Coastguard Worker raise parser.error("floats should be 16 or 32 bit fields") 72*61046927SAndroid Build Coastguard Worker elif not self.type in builtin_types and not self.type in parser.enums: 73*61046927SAndroid Build Coastguard Worker raise parser.error("unknown type '%s'" % self.type) 74*61046927SAndroid Build Coastguard Worker 75*61046927SAndroid Build Coastguard Worker def ctype(self, var_name): 76*61046927SAndroid Build Coastguard Worker if self.type == None: 77*61046927SAndroid Build Coastguard Worker type = "uint32_t" 78*61046927SAndroid Build Coastguard Worker val = var_name 79*61046927SAndroid Build Coastguard Worker elif self.type == "boolean": 80*61046927SAndroid Build Coastguard Worker type = "bool" 81*61046927SAndroid Build Coastguard Worker val = var_name 82*61046927SAndroid Build Coastguard Worker elif self.type == "uint" or self.type == "hex" or self.type == "a3xx_regid": 83*61046927SAndroid Build Coastguard Worker type = "uint32_t" 84*61046927SAndroid Build Coastguard Worker val = var_name 85*61046927SAndroid Build Coastguard Worker elif self.type == "int": 86*61046927SAndroid Build Coastguard Worker type = "int32_t" 87*61046927SAndroid Build Coastguard Worker val = var_name 88*61046927SAndroid Build Coastguard Worker elif self.type == "fixed": 89*61046927SAndroid Build Coastguard Worker type = "float" 90*61046927SAndroid Build Coastguard Worker val = "((int32_t)(%s * %d.0))" % (var_name, 1 << self.radix) 91*61046927SAndroid Build Coastguard Worker elif self.type == "ufixed": 92*61046927SAndroid Build Coastguard Worker type = "float" 93*61046927SAndroid Build Coastguard Worker val = "((uint32_t)(%s * %d.0))" % (var_name, 1 << self.radix) 94*61046927SAndroid Build Coastguard Worker elif self.type == "float" and self.high - self.low == 31: 95*61046927SAndroid Build Coastguard Worker type = "float" 96*61046927SAndroid Build Coastguard Worker val = "fui(%s)" % var_name 97*61046927SAndroid Build Coastguard Worker elif self.type == "float" and self.high - self.low == 15: 98*61046927SAndroid Build Coastguard Worker type = "float" 99*61046927SAndroid Build Coastguard Worker val = "_mesa_float_to_half(%s)" % var_name 100*61046927SAndroid Build Coastguard Worker elif self.type in [ "address", "waddress" ]: 101*61046927SAndroid Build Coastguard Worker type = "uint64_t" 102*61046927SAndroid Build Coastguard Worker val = var_name 103*61046927SAndroid Build Coastguard Worker else: 104*61046927SAndroid Build Coastguard Worker type = "enum %s" % self.type 105*61046927SAndroid Build Coastguard Worker val = var_name 106*61046927SAndroid Build Coastguard Worker 107*61046927SAndroid Build Coastguard Worker if self.shr > 0: 108*61046927SAndroid Build Coastguard Worker val = "(%s >> %d)" % (val, self.shr) 109*61046927SAndroid Build Coastguard Worker 110*61046927SAndroid Build Coastguard Worker return (type, val) 111*61046927SAndroid Build Coastguard Worker 112*61046927SAndroid Build Coastguard Workerdef tab_to(name, value): 113*61046927SAndroid Build Coastguard Worker tab_count = (68 - (len(name) & ~7)) // 8 114*61046927SAndroid Build Coastguard Worker if tab_count <= 0: 115*61046927SAndroid Build Coastguard Worker tab_count = 1 116*61046927SAndroid Build Coastguard Worker print(name + ('\t' * tab_count) + value) 117*61046927SAndroid Build Coastguard Worker 118*61046927SAndroid Build Coastguard Workerdef mask(low, high): 119*61046927SAndroid Build Coastguard Worker return ((0xffffffffffffffff >> (64 - (high + 1 - low))) << low) 120*61046927SAndroid Build Coastguard Worker 121*61046927SAndroid Build Coastguard Workerdef field_name(reg, f): 122*61046927SAndroid Build Coastguard Worker if f.name: 123*61046927SAndroid Build Coastguard Worker name = f.name.lower() 124*61046927SAndroid Build Coastguard Worker else: 125*61046927SAndroid Build Coastguard Worker # We hit this path when a reg is defined with no bitset fields, ie. 126*61046927SAndroid Build Coastguard Worker # <reg32 offset="0x88db" name="RB_BLIT_DST_ARRAY_PITCH" low="0" high="28" shr="6" type="uint"/> 127*61046927SAndroid Build Coastguard Worker name = reg.name.lower() 128*61046927SAndroid Build Coastguard Worker 129*61046927SAndroid Build Coastguard Worker if (name in [ "double", "float", "int" ]) or not (name[0].isalpha()): 130*61046927SAndroid Build Coastguard Worker name = "_" + name 131*61046927SAndroid Build Coastguard Worker 132*61046927SAndroid Build Coastguard Worker return name 133*61046927SAndroid Build Coastguard Worker 134*61046927SAndroid Build Coastguard Worker# indices - array of (ctype, stride, __offsets_NAME) 135*61046927SAndroid Build Coastguard Workerdef indices_varlist(indices): 136*61046927SAndroid Build Coastguard Worker return ", ".join(["i%d" % i for i in range(len(indices))]) 137*61046927SAndroid Build Coastguard Worker 138*61046927SAndroid Build Coastguard Workerdef indices_prototype(indices): 139*61046927SAndroid Build Coastguard Worker return ", ".join(["%s i%d" % (ctype, idx) 140*61046927SAndroid Build Coastguard Worker for (idx, (ctype, stride, offset)) in enumerate(indices)]) 141*61046927SAndroid Build Coastguard Worker 142*61046927SAndroid Build Coastguard Workerdef indices_strides(indices): 143*61046927SAndroid Build Coastguard Worker return " + ".join(["0x%x*i%d" % (stride, idx) 144*61046927SAndroid Build Coastguard Worker if stride else 145*61046927SAndroid Build Coastguard Worker "%s(i%d)" % (offset, idx) 146*61046927SAndroid Build Coastguard Worker for (idx, (ctype, stride, offset)) in enumerate(indices)]) 147*61046927SAndroid Build Coastguard Worker 148*61046927SAndroid Build Coastguard Workerclass Bitset(object): 149*61046927SAndroid Build Coastguard Worker def __init__(self, name, template): 150*61046927SAndroid Build Coastguard Worker self.name = name 151*61046927SAndroid Build Coastguard Worker self.inline = False 152*61046927SAndroid Build Coastguard Worker if template: 153*61046927SAndroid Build Coastguard Worker self.fields = template.fields[:] 154*61046927SAndroid Build Coastguard Worker else: 155*61046927SAndroid Build Coastguard Worker self.fields = [] 156*61046927SAndroid Build Coastguard Worker 157*61046927SAndroid Build Coastguard Worker # Get address field if there is one in the bitset, else return None: 158*61046927SAndroid Build Coastguard Worker def get_address_field(self): 159*61046927SAndroid Build Coastguard Worker for f in self.fields: 160*61046927SAndroid Build Coastguard Worker if f.type in [ "address", "waddress" ]: 161*61046927SAndroid Build Coastguard Worker return f 162*61046927SAndroid Build Coastguard Worker return None 163*61046927SAndroid Build Coastguard Worker 164*61046927SAndroid Build Coastguard Worker def dump_regpair_builder(self, reg): 165*61046927SAndroid Build Coastguard Worker print("#ifndef NDEBUG") 166*61046927SAndroid Build Coastguard Worker known_mask = 0 167*61046927SAndroid Build Coastguard Worker for f in self.fields: 168*61046927SAndroid Build Coastguard Worker known_mask |= mask(f.low, f.high) 169*61046927SAndroid Build Coastguard Worker if f.type in [ "boolean", "address", "waddress" ]: 170*61046927SAndroid Build Coastguard Worker continue 171*61046927SAndroid Build Coastguard Worker type, val = f.ctype("fields.%s" % field_name(reg, f)) 172*61046927SAndroid Build Coastguard Worker print(" assert((%-40s & 0x%08x) == 0);" % (val, 0xffffffff ^ mask(0 , f.high - f.low))) 173*61046927SAndroid Build Coastguard Worker print(" assert((%-40s & 0x%08x) == 0);" % ("fields.unknown", known_mask)) 174*61046927SAndroid Build Coastguard Worker print("#endif\n") 175*61046927SAndroid Build Coastguard Worker 176*61046927SAndroid Build Coastguard Worker print(" return (struct fd_reg_pair) {") 177*61046927SAndroid Build Coastguard Worker print(" .reg = (uint32_t)%s," % reg.reg_offset()) 178*61046927SAndroid Build Coastguard Worker print(" .value =") 179*61046927SAndroid Build Coastguard Worker for f in self.fields: 180*61046927SAndroid Build Coastguard Worker if f.type in [ "address", "waddress" ]: 181*61046927SAndroid Build Coastguard Worker continue 182*61046927SAndroid Build Coastguard Worker else: 183*61046927SAndroid Build Coastguard Worker type, val = f.ctype("fields.%s" % field_name(reg, f)) 184*61046927SAndroid Build Coastguard Worker print(" (%-40s << %2d) |" % (val, f.low)) 185*61046927SAndroid Build Coastguard Worker value_name = "dword" 186*61046927SAndroid Build Coastguard Worker if reg.bit_size == 64: 187*61046927SAndroid Build Coastguard Worker value_name = "qword" 188*61046927SAndroid Build Coastguard Worker print(" fields.unknown | fields.%s," % (value_name,)) 189*61046927SAndroid Build Coastguard Worker 190*61046927SAndroid Build Coastguard Worker address = self.get_address_field() 191*61046927SAndroid Build Coastguard Worker if address: 192*61046927SAndroid Build Coastguard Worker print(" .bo = fields.bo,") 193*61046927SAndroid Build Coastguard Worker print(" .is_address = true,") 194*61046927SAndroid Build Coastguard Worker if f.type == "waddress": 195*61046927SAndroid Build Coastguard Worker print(" .bo_write = true,") 196*61046927SAndroid Build Coastguard Worker print(" .bo_offset = fields.bo_offset,") 197*61046927SAndroid Build Coastguard Worker print(" .bo_shift = %d," % address.shr) 198*61046927SAndroid Build Coastguard Worker print(" .bo_low = %d," % address.low) 199*61046927SAndroid Build Coastguard Worker 200*61046927SAndroid Build Coastguard Worker print(" };") 201*61046927SAndroid Build Coastguard Worker 202*61046927SAndroid Build Coastguard Worker def dump_pack_struct(self, is_deprecated, reg=None): 203*61046927SAndroid Build Coastguard Worker if not reg: 204*61046927SAndroid Build Coastguard Worker return 205*61046927SAndroid Build Coastguard Worker 206*61046927SAndroid Build Coastguard Worker prefix = reg.full_name 207*61046927SAndroid Build Coastguard Worker 208*61046927SAndroid Build Coastguard Worker print("struct %s {" % prefix) 209*61046927SAndroid Build Coastguard Worker for f in self.fields: 210*61046927SAndroid Build Coastguard Worker if f.type in [ "address", "waddress" ]: 211*61046927SAndroid Build Coastguard Worker tab_to(" __bo_type", "bo;") 212*61046927SAndroid Build Coastguard Worker tab_to(" uint32_t", "bo_offset;") 213*61046927SAndroid Build Coastguard Worker continue 214*61046927SAndroid Build Coastguard Worker name = field_name(reg, f) 215*61046927SAndroid Build Coastguard Worker 216*61046927SAndroid Build Coastguard Worker type, val = f.ctype("var") 217*61046927SAndroid Build Coastguard Worker 218*61046927SAndroid Build Coastguard Worker tab_to(" %s" % type, "%s;" % name) 219*61046927SAndroid Build Coastguard Worker if reg.bit_size == 64: 220*61046927SAndroid Build Coastguard Worker tab_to(" uint64_t", "unknown;") 221*61046927SAndroid Build Coastguard Worker tab_to(" uint64_t", "qword;") 222*61046927SAndroid Build Coastguard Worker else: 223*61046927SAndroid Build Coastguard Worker tab_to(" uint32_t", "unknown;") 224*61046927SAndroid Build Coastguard Worker tab_to(" uint32_t", "dword;") 225*61046927SAndroid Build Coastguard Worker print("};\n") 226*61046927SAndroid Build Coastguard Worker 227*61046927SAndroid Build Coastguard Worker depcrstr = "" 228*61046927SAndroid Build Coastguard Worker if is_deprecated: 229*61046927SAndroid Build Coastguard Worker depcrstr = " __attribute__((deprecated))" 230*61046927SAndroid Build Coastguard Worker if reg.array: 231*61046927SAndroid Build Coastguard Worker print("static inline%s struct fd_reg_pair\npack_%s(uint32_t __i, struct %s fields)\n{" % 232*61046927SAndroid Build Coastguard Worker (depcrstr, prefix, prefix)) 233*61046927SAndroid Build Coastguard Worker else: 234*61046927SAndroid Build Coastguard Worker print("static inline%s struct fd_reg_pair\npack_%s(struct %s fields)\n{" % 235*61046927SAndroid Build Coastguard Worker (depcrstr, prefix, prefix)) 236*61046927SAndroid Build Coastguard Worker 237*61046927SAndroid Build Coastguard Worker self.dump_regpair_builder(reg) 238*61046927SAndroid Build Coastguard Worker 239*61046927SAndroid Build Coastguard Worker print("\n}\n") 240*61046927SAndroid Build Coastguard Worker 241*61046927SAndroid Build Coastguard Worker if self.get_address_field(): 242*61046927SAndroid Build Coastguard Worker skip = ", { .reg = 0 }" 243*61046927SAndroid Build Coastguard Worker else: 244*61046927SAndroid Build Coastguard Worker skip = "" 245*61046927SAndroid Build Coastguard Worker 246*61046927SAndroid Build Coastguard Worker if reg.array: 247*61046927SAndroid Build Coastguard Worker print("#define %s(__i, ...) pack_%s(__i, __struct_cast(%s) { __VA_ARGS__ })%s\n" % 248*61046927SAndroid Build Coastguard Worker (prefix, prefix, prefix, skip)) 249*61046927SAndroid Build Coastguard Worker else: 250*61046927SAndroid Build Coastguard Worker print("#define %s(...) pack_%s(__struct_cast(%s) { __VA_ARGS__ })%s\n" % 251*61046927SAndroid Build Coastguard Worker (prefix, prefix, prefix, skip)) 252*61046927SAndroid Build Coastguard Worker 253*61046927SAndroid Build Coastguard Worker 254*61046927SAndroid Build Coastguard Worker def dump(self, is_deprecated, prefix=None): 255*61046927SAndroid Build Coastguard Worker if prefix == None: 256*61046927SAndroid Build Coastguard Worker prefix = self.name 257*61046927SAndroid Build Coastguard Worker for f in self.fields: 258*61046927SAndroid Build Coastguard Worker if f.name: 259*61046927SAndroid Build Coastguard Worker name = prefix + "_" + f.name 260*61046927SAndroid Build Coastguard Worker else: 261*61046927SAndroid Build Coastguard Worker name = prefix 262*61046927SAndroid Build Coastguard Worker 263*61046927SAndroid Build Coastguard Worker if not f.name and f.low == 0 and f.shr == 0 and not f.type in ["float", "fixed", "ufixed"]: 264*61046927SAndroid Build Coastguard Worker pass 265*61046927SAndroid Build Coastguard Worker elif f.type == "boolean" or (f.type == None and f.low == f.high): 266*61046927SAndroid Build Coastguard Worker tab_to("#define %s" % name, "0x%08x" % (1 << f.low)) 267*61046927SAndroid Build Coastguard Worker else: 268*61046927SAndroid Build Coastguard Worker tab_to("#define %s__MASK" % name, "0x%08x" % mask(f.low, f.high)) 269*61046927SAndroid Build Coastguard Worker tab_to("#define %s__SHIFT" % name, "%d" % f.low) 270*61046927SAndroid Build Coastguard Worker type, val = f.ctype("val") 271*61046927SAndroid Build Coastguard Worker 272*61046927SAndroid Build Coastguard Worker print("static inline uint32_t %s(%s val)\n{" % (name, type)) 273*61046927SAndroid Build Coastguard Worker if f.shr > 0: 274*61046927SAndroid Build Coastguard Worker print("\tassert(!(val & 0x%x));" % mask(0, f.shr - 1)) 275*61046927SAndroid Build Coastguard Worker print("\treturn ((%s) << %s__SHIFT) & %s__MASK;\n}" % (val, name, name)) 276*61046927SAndroid Build Coastguard Worker print() 277*61046927SAndroid Build Coastguard Worker 278*61046927SAndroid Build Coastguard Workerclass Array(object): 279*61046927SAndroid Build Coastguard Worker def __init__(self, attrs, domain, variant, parent, index_type): 280*61046927SAndroid Build Coastguard Worker if "name" in attrs: 281*61046927SAndroid Build Coastguard Worker self.local_name = attrs["name"] 282*61046927SAndroid Build Coastguard Worker else: 283*61046927SAndroid Build Coastguard Worker self.local_name = "" 284*61046927SAndroid Build Coastguard Worker self.domain = domain 285*61046927SAndroid Build Coastguard Worker self.variant = variant 286*61046927SAndroid Build Coastguard Worker self.parent = parent 287*61046927SAndroid Build Coastguard Worker if self.parent: 288*61046927SAndroid Build Coastguard Worker self.name = self.parent.name + "_" + self.local_name 289*61046927SAndroid Build Coastguard Worker else: 290*61046927SAndroid Build Coastguard Worker self.name = self.local_name 291*61046927SAndroid Build Coastguard Worker if "offsets" in attrs: 292*61046927SAndroid Build Coastguard Worker self.offsets = map(lambda i: "0x%08x" % int(i, 0), attrs["offsets"].split(",")) 293*61046927SAndroid Build Coastguard Worker self.fixed_offsets = True 294*61046927SAndroid Build Coastguard Worker elif "doffsets" in attrs: 295*61046927SAndroid Build Coastguard Worker self.offsets = map(lambda s: "(%s)" % s , attrs["doffsets"].split(",")) 296*61046927SAndroid Build Coastguard Worker self.fixed_offsets = True 297*61046927SAndroid Build Coastguard Worker else: 298*61046927SAndroid Build Coastguard Worker self.offset = int(attrs["offset"], 0) 299*61046927SAndroid Build Coastguard Worker self.stride = int(attrs["stride"], 0) 300*61046927SAndroid Build Coastguard Worker self.fixed_offsets = False 301*61046927SAndroid Build Coastguard Worker if "index" in attrs: 302*61046927SAndroid Build Coastguard Worker self.index_type = index_type 303*61046927SAndroid Build Coastguard Worker else: 304*61046927SAndroid Build Coastguard Worker self.index_type = None 305*61046927SAndroid Build Coastguard Worker self.length = int(attrs["length"], 0) 306*61046927SAndroid Build Coastguard Worker if "usage" in attrs: 307*61046927SAndroid Build Coastguard Worker self.usages = attrs["usage"].split(',') 308*61046927SAndroid Build Coastguard Worker else: 309*61046927SAndroid Build Coastguard Worker self.usages = None 310*61046927SAndroid Build Coastguard Worker 311*61046927SAndroid Build Coastguard Worker def index_ctype(self): 312*61046927SAndroid Build Coastguard Worker if not self.index_type: 313*61046927SAndroid Build Coastguard Worker return "uint32_t" 314*61046927SAndroid Build Coastguard Worker else: 315*61046927SAndroid Build Coastguard Worker return "enum %s" % self.index_type.name 316*61046927SAndroid Build Coastguard Worker 317*61046927SAndroid Build Coastguard Worker # Generate array of (ctype, stride, __offsets_NAME) 318*61046927SAndroid Build Coastguard Worker def indices(self): 319*61046927SAndroid Build Coastguard Worker if self.parent: 320*61046927SAndroid Build Coastguard Worker indices = self.parent.indices() 321*61046927SAndroid Build Coastguard Worker else: 322*61046927SAndroid Build Coastguard Worker indices = [] 323*61046927SAndroid Build Coastguard Worker if self.length != 1: 324*61046927SAndroid Build Coastguard Worker if self.fixed_offsets: 325*61046927SAndroid Build Coastguard Worker indices.append((self.index_ctype(), None, f"__offset_{self.local_name}")) 326*61046927SAndroid Build Coastguard Worker else: 327*61046927SAndroid Build Coastguard Worker indices.append((self.index_ctype(), self.stride, None)) 328*61046927SAndroid Build Coastguard Worker return indices 329*61046927SAndroid Build Coastguard Worker 330*61046927SAndroid Build Coastguard Worker def total_offset(self): 331*61046927SAndroid Build Coastguard Worker offset = 0 332*61046927SAndroid Build Coastguard Worker if not self.fixed_offsets: 333*61046927SAndroid Build Coastguard Worker offset += self.offset 334*61046927SAndroid Build Coastguard Worker if self.parent: 335*61046927SAndroid Build Coastguard Worker offset += self.parent.total_offset() 336*61046927SAndroid Build Coastguard Worker return offset 337*61046927SAndroid Build Coastguard Worker 338*61046927SAndroid Build Coastguard Worker def dump(self, is_deprecated): 339*61046927SAndroid Build Coastguard Worker depcrstr = "" 340*61046927SAndroid Build Coastguard Worker if is_deprecated: 341*61046927SAndroid Build Coastguard Worker depcrstr = " __attribute__((deprecated))" 342*61046927SAndroid Build Coastguard Worker proto = indices_varlist(self.indices()) 343*61046927SAndroid Build Coastguard Worker strides = indices_strides(self.indices()) 344*61046927SAndroid Build Coastguard Worker array_offset = self.total_offset() 345*61046927SAndroid Build Coastguard Worker if self.fixed_offsets: 346*61046927SAndroid Build Coastguard Worker print("static inline%s uint32_t __offset_%s(%s idx)" % (depcrstr, self.local_name, self.index_ctype())) 347*61046927SAndroid Build Coastguard Worker print("{\n\tswitch (idx) {") 348*61046927SAndroid Build Coastguard Worker if self.index_type: 349*61046927SAndroid Build Coastguard Worker for val, offset in zip(self.index_type.names(), self.offsets): 350*61046927SAndroid Build Coastguard Worker print("\t\tcase %s: return %s;" % (val, offset)) 351*61046927SAndroid Build Coastguard Worker else: 352*61046927SAndroid Build Coastguard Worker for idx, offset in enumerate(self.offsets): 353*61046927SAndroid Build Coastguard Worker print("\t\tcase %d: return %s;" % (idx, offset)) 354*61046927SAndroid Build Coastguard Worker print("\t\tdefault: return INVALID_IDX(idx);") 355*61046927SAndroid Build Coastguard Worker print("\t}\n}") 356*61046927SAndroid Build Coastguard Worker if proto == '': 357*61046927SAndroid Build Coastguard Worker tab_to("#define REG_%s_%s" % (self.domain, self.name), "0x%08x\n" % array_offset) 358*61046927SAndroid Build Coastguard Worker else: 359*61046927SAndroid Build Coastguard Worker tab_to("#define REG_%s_%s(%s)" % (self.domain, self.name, proto), "(0x%08x + %s )\n" % (array_offset, strides)) 360*61046927SAndroid Build Coastguard Worker 361*61046927SAndroid Build Coastguard Worker def dump_pack_struct(self, is_deprecated): 362*61046927SAndroid Build Coastguard Worker pass 363*61046927SAndroid Build Coastguard Worker 364*61046927SAndroid Build Coastguard Worker def dump_regpair_builder(self): 365*61046927SAndroid Build Coastguard Worker pass 366*61046927SAndroid Build Coastguard Worker 367*61046927SAndroid Build Coastguard Workerclass Reg(object): 368*61046927SAndroid Build Coastguard Worker def __init__(self, attrs, domain, array, bit_size): 369*61046927SAndroid Build Coastguard Worker self.name = attrs["name"] 370*61046927SAndroid Build Coastguard Worker self.domain = domain 371*61046927SAndroid Build Coastguard Worker self.array = array 372*61046927SAndroid Build Coastguard Worker self.offset = int(attrs["offset"], 0) 373*61046927SAndroid Build Coastguard Worker self.type = None 374*61046927SAndroid Build Coastguard Worker self.bit_size = bit_size 375*61046927SAndroid Build Coastguard Worker if array: 376*61046927SAndroid Build Coastguard Worker self.name = array.name + "_" + self.name 377*61046927SAndroid Build Coastguard Worker self.full_name = self.domain + "_" + self.name 378*61046927SAndroid Build Coastguard Worker if "stride" in attrs: 379*61046927SAndroid Build Coastguard Worker self.stride = int(attrs["stride"], 0) 380*61046927SAndroid Build Coastguard Worker self.length = int(attrs["length"], 0) 381*61046927SAndroid Build Coastguard Worker else: 382*61046927SAndroid Build Coastguard Worker self.stride = None 383*61046927SAndroid Build Coastguard Worker self.length = None 384*61046927SAndroid Build Coastguard Worker 385*61046927SAndroid Build Coastguard Worker # Generate array of (ctype, stride, __offsets_NAME) 386*61046927SAndroid Build Coastguard Worker def indices(self): 387*61046927SAndroid Build Coastguard Worker if self.array: 388*61046927SAndroid Build Coastguard Worker indices = self.array.indices() 389*61046927SAndroid Build Coastguard Worker else: 390*61046927SAndroid Build Coastguard Worker indices = [] 391*61046927SAndroid Build Coastguard Worker if self.stride: 392*61046927SAndroid Build Coastguard Worker indices.append(("uint32_t", self.stride, None)) 393*61046927SAndroid Build Coastguard Worker return indices 394*61046927SAndroid Build Coastguard Worker 395*61046927SAndroid Build Coastguard Worker def total_offset(self): 396*61046927SAndroid Build Coastguard Worker if self.array: 397*61046927SAndroid Build Coastguard Worker return self.array.total_offset() + self.offset 398*61046927SAndroid Build Coastguard Worker else: 399*61046927SAndroid Build Coastguard Worker return self.offset 400*61046927SAndroid Build Coastguard Worker 401*61046927SAndroid Build Coastguard Worker def reg_offset(self): 402*61046927SAndroid Build Coastguard Worker if self.array: 403*61046927SAndroid Build Coastguard Worker offset = self.array.offset + self.offset 404*61046927SAndroid Build Coastguard Worker return "(0x%08x + 0x%x*__i)" % (offset, self.array.stride) 405*61046927SAndroid Build Coastguard Worker return "0x%08x" % self.offset 406*61046927SAndroid Build Coastguard Worker 407*61046927SAndroid Build Coastguard Worker def dump(self, is_deprecated): 408*61046927SAndroid Build Coastguard Worker depcrstr = "" 409*61046927SAndroid Build Coastguard Worker if is_deprecated: 410*61046927SAndroid Build Coastguard Worker depcrstr = " __attribute__((deprecated)) " 411*61046927SAndroid Build Coastguard Worker proto = indices_prototype(self.indices()) 412*61046927SAndroid Build Coastguard Worker strides = indices_strides(self.indices()) 413*61046927SAndroid Build Coastguard Worker offset = self.total_offset() 414*61046927SAndroid Build Coastguard Worker if proto == '': 415*61046927SAndroid Build Coastguard Worker tab_to("#define REG_%s" % self.full_name, "0x%08x" % offset) 416*61046927SAndroid Build Coastguard Worker else: 417*61046927SAndroid Build Coastguard Worker print("static inline%s uint32_t REG_%s(%s) { return 0x%08x + %s; }" % (depcrstr, self.full_name, proto, offset, strides)) 418*61046927SAndroid Build Coastguard Worker 419*61046927SAndroid Build Coastguard Worker if self.bitset.inline: 420*61046927SAndroid Build Coastguard Worker self.bitset.dump(is_deprecated, self.full_name) 421*61046927SAndroid Build Coastguard Worker print("") 422*61046927SAndroid Build Coastguard Worker 423*61046927SAndroid Build Coastguard Worker def dump_pack_struct(self, is_deprecated): 424*61046927SAndroid Build Coastguard Worker if self.bitset.inline: 425*61046927SAndroid Build Coastguard Worker self.bitset.dump_pack_struct(is_deprecated, self) 426*61046927SAndroid Build Coastguard Worker 427*61046927SAndroid Build Coastguard Worker def dump_regpair_builder(self): 428*61046927SAndroid Build Coastguard Worker if self.bitset.inline: 429*61046927SAndroid Build Coastguard Worker self.bitset.dump_regpair_builder(self) 430*61046927SAndroid Build Coastguard Worker 431*61046927SAndroid Build Coastguard Worker def dump_py(self): 432*61046927SAndroid Build Coastguard Worker print("\tREG_%s = 0x%08x" % (self.full_name, self.offset)) 433*61046927SAndroid Build Coastguard Worker 434*61046927SAndroid Build Coastguard Worker 435*61046927SAndroid Build Coastguard Workerclass Parser(object): 436*61046927SAndroid Build Coastguard Worker def __init__(self): 437*61046927SAndroid Build Coastguard Worker self.current_array = None 438*61046927SAndroid Build Coastguard Worker self.current_domain = None 439*61046927SAndroid Build Coastguard Worker self.current_prefix = None 440*61046927SAndroid Build Coastguard Worker self.current_prefix_type = None 441*61046927SAndroid Build Coastguard Worker self.current_stripe = None 442*61046927SAndroid Build Coastguard Worker self.current_bitset = None 443*61046927SAndroid Build Coastguard Worker self.current_bitsize = 32 444*61046927SAndroid Build Coastguard Worker # The varset attribute on the domain specifies the enum which 445*61046927SAndroid Build Coastguard Worker # specifies all possible hw variants: 446*61046927SAndroid Build Coastguard Worker self.current_varset = None 447*61046927SAndroid Build Coastguard Worker # Regs that have multiple variants.. we only generated the C++ 448*61046927SAndroid Build Coastguard Worker # template based struct-packers for these 449*61046927SAndroid Build Coastguard Worker self.variant_regs = {} 450*61046927SAndroid Build Coastguard Worker # Information in which contexts regs are used, to be used in 451*61046927SAndroid Build Coastguard Worker # debug options 452*61046927SAndroid Build Coastguard Worker self.usage_regs = collections.defaultdict(list) 453*61046927SAndroid Build Coastguard Worker self.bitsets = {} 454*61046927SAndroid Build Coastguard Worker self.enums = {} 455*61046927SAndroid Build Coastguard Worker self.variants = set() 456*61046927SAndroid Build Coastguard Worker self.file = [] 457*61046927SAndroid Build Coastguard Worker self.xml_files = [] 458*61046927SAndroid Build Coastguard Worker self.copyright_year = None 459*61046927SAndroid Build Coastguard Worker self.authors = [] 460*61046927SAndroid Build Coastguard Worker self.license = None 461*61046927SAndroid Build Coastguard Worker 462*61046927SAndroid Build Coastguard Worker def error(self, message): 463*61046927SAndroid Build Coastguard Worker parser, filename = self.stack[-1] 464*61046927SAndroid Build Coastguard Worker return Error("%s:%d:%d: %s" % (filename, parser.CurrentLineNumber, parser.CurrentColumnNumber, message)) 465*61046927SAndroid Build Coastguard Worker 466*61046927SAndroid Build Coastguard Worker def prefix(self, variant=None): 467*61046927SAndroid Build Coastguard Worker if self.current_prefix_type == "variant" and variant: 468*61046927SAndroid Build Coastguard Worker return variant 469*61046927SAndroid Build Coastguard Worker elif self.current_stripe: 470*61046927SAndroid Build Coastguard Worker return self.current_stripe + "_" + self.current_domain 471*61046927SAndroid Build Coastguard Worker elif self.current_prefix: 472*61046927SAndroid Build Coastguard Worker return self.current_prefix + "_" + self.current_domain 473*61046927SAndroid Build Coastguard Worker else: 474*61046927SAndroid Build Coastguard Worker return self.current_domain 475*61046927SAndroid Build Coastguard Worker 476*61046927SAndroid Build Coastguard Worker def parse_field(self, name, attrs): 477*61046927SAndroid Build Coastguard Worker try: 478*61046927SAndroid Build Coastguard Worker if "pos" in attrs: 479*61046927SAndroid Build Coastguard Worker high = low = int(attrs["pos"], 0) 480*61046927SAndroid Build Coastguard Worker elif "high" in attrs and "low" in attrs: 481*61046927SAndroid Build Coastguard Worker high = int(attrs["high"], 0) 482*61046927SAndroid Build Coastguard Worker low = int(attrs["low"], 0) 483*61046927SAndroid Build Coastguard Worker else: 484*61046927SAndroid Build Coastguard Worker low = 0 485*61046927SAndroid Build Coastguard Worker high = self.current_bitsize - 1 486*61046927SAndroid Build Coastguard Worker 487*61046927SAndroid Build Coastguard Worker if "type" in attrs: 488*61046927SAndroid Build Coastguard Worker type = attrs["type"] 489*61046927SAndroid Build Coastguard Worker else: 490*61046927SAndroid Build Coastguard Worker type = None 491*61046927SAndroid Build Coastguard Worker 492*61046927SAndroid Build Coastguard Worker if "shr" in attrs: 493*61046927SAndroid Build Coastguard Worker shr = int(attrs["shr"], 0) 494*61046927SAndroid Build Coastguard Worker else: 495*61046927SAndroid Build Coastguard Worker shr = 0 496*61046927SAndroid Build Coastguard Worker 497*61046927SAndroid Build Coastguard Worker b = Field(name, low, high, shr, type, self) 498*61046927SAndroid Build Coastguard Worker 499*61046927SAndroid Build Coastguard Worker if type == "fixed" or type == "ufixed": 500*61046927SAndroid Build Coastguard Worker b.radix = int(attrs["radix"], 0) 501*61046927SAndroid Build Coastguard Worker 502*61046927SAndroid Build Coastguard Worker self.current_bitset.fields.append(b) 503*61046927SAndroid Build Coastguard Worker except ValueError as e: 504*61046927SAndroid Build Coastguard Worker raise self.error(e) 505*61046927SAndroid Build Coastguard Worker 506*61046927SAndroid Build Coastguard Worker def parse_varset(self, attrs): 507*61046927SAndroid Build Coastguard Worker # Inherit the varset from the enclosing domain if not overriden: 508*61046927SAndroid Build Coastguard Worker varset = self.current_varset 509*61046927SAndroid Build Coastguard Worker if "varset" in attrs: 510*61046927SAndroid Build Coastguard Worker varset = self.enums[attrs["varset"]] 511*61046927SAndroid Build Coastguard Worker return varset 512*61046927SAndroid Build Coastguard Worker 513*61046927SAndroid Build Coastguard Worker def parse_variants(self, attrs): 514*61046927SAndroid Build Coastguard Worker if not "variants" in attrs: 515*61046927SAndroid Build Coastguard Worker return None 516*61046927SAndroid Build Coastguard Worker variant = attrs["variants"].split(",")[0] 517*61046927SAndroid Build Coastguard Worker if "-" in variant: 518*61046927SAndroid Build Coastguard Worker variant = variant[:variant.index("-")] 519*61046927SAndroid Build Coastguard Worker 520*61046927SAndroid Build Coastguard Worker varset = self.parse_varset(attrs) 521*61046927SAndroid Build Coastguard Worker 522*61046927SAndroid Build Coastguard Worker assert varset.has_name(variant) 523*61046927SAndroid Build Coastguard Worker 524*61046927SAndroid Build Coastguard Worker return variant 525*61046927SAndroid Build Coastguard Worker 526*61046927SAndroid Build Coastguard Worker def add_all_variants(self, reg, attrs, parent_variant): 527*61046927SAndroid Build Coastguard Worker # TODO this should really handle *all* variants, including dealing 528*61046927SAndroid Build Coastguard Worker # with open ended ranges (ie. "A2XX,A4XX-") (we have the varset 529*61046927SAndroid Build Coastguard Worker # enum now to make that possible) 530*61046927SAndroid Build Coastguard Worker variant = self.parse_variants(attrs) 531*61046927SAndroid Build Coastguard Worker if not variant: 532*61046927SAndroid Build Coastguard Worker variant = parent_variant 533*61046927SAndroid Build Coastguard Worker 534*61046927SAndroid Build Coastguard Worker if reg.name not in self.variant_regs: 535*61046927SAndroid Build Coastguard Worker self.variant_regs[reg.name] = {} 536*61046927SAndroid Build Coastguard Worker else: 537*61046927SAndroid Build Coastguard Worker # All variants must be same size: 538*61046927SAndroid Build Coastguard Worker v = next(iter(self.variant_regs[reg.name])) 539*61046927SAndroid Build Coastguard Worker assert self.variant_regs[reg.name][v].bit_size == reg.bit_size 540*61046927SAndroid Build Coastguard Worker 541*61046927SAndroid Build Coastguard Worker self.variant_regs[reg.name][variant] = reg 542*61046927SAndroid Build Coastguard Worker 543*61046927SAndroid Build Coastguard Worker def add_all_usages(self, reg, usages): 544*61046927SAndroid Build Coastguard Worker if not usages: 545*61046927SAndroid Build Coastguard Worker return 546*61046927SAndroid Build Coastguard Worker 547*61046927SAndroid Build Coastguard Worker for usage in usages: 548*61046927SAndroid Build Coastguard Worker self.usage_regs[usage].append(reg) 549*61046927SAndroid Build Coastguard Worker 550*61046927SAndroid Build Coastguard Worker self.variants.add(reg.domain) 551*61046927SAndroid Build Coastguard Worker 552*61046927SAndroid Build Coastguard Worker def do_validate(self, schemafile): 553*61046927SAndroid Build Coastguard Worker try: 554*61046927SAndroid Build Coastguard Worker from lxml import etree 555*61046927SAndroid Build Coastguard Worker 556*61046927SAndroid Build Coastguard Worker parser, filename = self.stack[-1] 557*61046927SAndroid Build Coastguard Worker dirname = os.path.dirname(filename) 558*61046927SAndroid Build Coastguard Worker 559*61046927SAndroid Build Coastguard Worker # we expect this to look like <namespace url> schema.xsd.. I think 560*61046927SAndroid Build Coastguard Worker # technically it is supposed to be just a URL, but that doesn't 561*61046927SAndroid Build Coastguard Worker # quite match up to what we do.. Just skip over everything up to 562*61046927SAndroid Build Coastguard Worker # and including the first whitespace character: 563*61046927SAndroid Build Coastguard Worker schemafile = schemafile[schemafile.rindex(" ")+1:] 564*61046927SAndroid Build Coastguard Worker 565*61046927SAndroid Build Coastguard Worker # this is a bit cheezy, but the xml file to validate could be 566*61046927SAndroid Build Coastguard Worker # in a child director, ie. we don't really know where the schema 567*61046927SAndroid Build Coastguard Worker # file is, the way the rnn C code does. So if it doesn't exist 568*61046927SAndroid Build Coastguard Worker # just look one level up 569*61046927SAndroid Build Coastguard Worker if not os.path.exists(dirname + "/" + schemafile): 570*61046927SAndroid Build Coastguard Worker schemafile = "../" + schemafile 571*61046927SAndroid Build Coastguard Worker 572*61046927SAndroid Build Coastguard Worker if not os.path.exists(dirname + "/" + schemafile): 573*61046927SAndroid Build Coastguard Worker raise self.error("Cannot find schema for: " + filename) 574*61046927SAndroid Build Coastguard Worker 575*61046927SAndroid Build Coastguard Worker xmlschema_doc = etree.parse(dirname + "/" + schemafile) 576*61046927SAndroid Build Coastguard Worker xmlschema = etree.XMLSchema(xmlschema_doc) 577*61046927SAndroid Build Coastguard Worker 578*61046927SAndroid Build Coastguard Worker xml_doc = etree.parse(filename) 579*61046927SAndroid Build Coastguard Worker if not xmlschema.validate(xml_doc): 580*61046927SAndroid Build Coastguard Worker error_str = str(xmlschema.error_log.filter_from_errors()[0]) 581*61046927SAndroid Build Coastguard Worker raise self.error("Schema validation failed for: " + filename + "\n" + error_str) 582*61046927SAndroid Build Coastguard Worker except ImportError: 583*61046927SAndroid Build Coastguard Worker print("lxml not found, skipping validation", file=sys.stderr) 584*61046927SAndroid Build Coastguard Worker 585*61046927SAndroid Build Coastguard Worker def do_parse(self, filename): 586*61046927SAndroid Build Coastguard Worker filepath = os.path.abspath(filename) 587*61046927SAndroid Build Coastguard Worker if filepath in self.xml_files: 588*61046927SAndroid Build Coastguard Worker return 589*61046927SAndroid Build Coastguard Worker self.xml_files.append(filepath) 590*61046927SAndroid Build Coastguard Worker file = open(filename, "rb") 591*61046927SAndroid Build Coastguard Worker parser = xml.parsers.expat.ParserCreate() 592*61046927SAndroid Build Coastguard Worker self.stack.append((parser, filename)) 593*61046927SAndroid Build Coastguard Worker parser.StartElementHandler = self.start_element 594*61046927SAndroid Build Coastguard Worker parser.EndElementHandler = self.end_element 595*61046927SAndroid Build Coastguard Worker parser.CharacterDataHandler = self.character_data 596*61046927SAndroid Build Coastguard Worker parser.buffer_text = True 597*61046927SAndroid Build Coastguard Worker parser.ParseFile(file) 598*61046927SAndroid Build Coastguard Worker self.stack.pop() 599*61046927SAndroid Build Coastguard Worker file.close() 600*61046927SAndroid Build Coastguard Worker 601*61046927SAndroid Build Coastguard Worker def parse(self, rnn_path, filename): 602*61046927SAndroid Build Coastguard Worker self.path = rnn_path 603*61046927SAndroid Build Coastguard Worker self.stack = [] 604*61046927SAndroid Build Coastguard Worker self.do_parse(filename) 605*61046927SAndroid Build Coastguard Worker 606*61046927SAndroid Build Coastguard Worker def parse_reg(self, attrs, bit_size): 607*61046927SAndroid Build Coastguard Worker self.current_bitsize = bit_size 608*61046927SAndroid Build Coastguard Worker if "type" in attrs and attrs["type"] in self.bitsets: 609*61046927SAndroid Build Coastguard Worker bitset = self.bitsets[attrs["type"]] 610*61046927SAndroid Build Coastguard Worker if bitset.inline: 611*61046927SAndroid Build Coastguard Worker self.current_bitset = Bitset(attrs["name"], bitset) 612*61046927SAndroid Build Coastguard Worker self.current_bitset.inline = True 613*61046927SAndroid Build Coastguard Worker else: 614*61046927SAndroid Build Coastguard Worker self.current_bitset = bitset 615*61046927SAndroid Build Coastguard Worker else: 616*61046927SAndroid Build Coastguard Worker self.current_bitset = Bitset(attrs["name"], None) 617*61046927SAndroid Build Coastguard Worker self.current_bitset.inline = True 618*61046927SAndroid Build Coastguard Worker if "type" in attrs: 619*61046927SAndroid Build Coastguard Worker self.parse_field(None, attrs) 620*61046927SAndroid Build Coastguard Worker 621*61046927SAndroid Build Coastguard Worker variant = self.parse_variants(attrs) 622*61046927SAndroid Build Coastguard Worker if not variant and self.current_array: 623*61046927SAndroid Build Coastguard Worker variant = self.current_array.variant 624*61046927SAndroid Build Coastguard Worker 625*61046927SAndroid Build Coastguard Worker self.current_reg = Reg(attrs, self.prefix(variant), self.current_array, bit_size) 626*61046927SAndroid Build Coastguard Worker self.current_reg.bitset = self.current_bitset 627*61046927SAndroid Build Coastguard Worker 628*61046927SAndroid Build Coastguard Worker if len(self.stack) == 1: 629*61046927SAndroid Build Coastguard Worker self.file.append(self.current_reg) 630*61046927SAndroid Build Coastguard Worker 631*61046927SAndroid Build Coastguard Worker if variant is not None: 632*61046927SAndroid Build Coastguard Worker self.add_all_variants(self.current_reg, attrs, variant) 633*61046927SAndroid Build Coastguard Worker 634*61046927SAndroid Build Coastguard Worker usages = None 635*61046927SAndroid Build Coastguard Worker if "usage" in attrs: 636*61046927SAndroid Build Coastguard Worker usages = attrs["usage"].split(',') 637*61046927SAndroid Build Coastguard Worker elif self.current_array: 638*61046927SAndroid Build Coastguard Worker usages = self.current_array.usages 639*61046927SAndroid Build Coastguard Worker 640*61046927SAndroid Build Coastguard Worker self.add_all_usages(self.current_reg, usages) 641*61046927SAndroid Build Coastguard Worker 642*61046927SAndroid Build Coastguard Worker def start_element(self, name, attrs): 643*61046927SAndroid Build Coastguard Worker self.cdata = "" 644*61046927SAndroid Build Coastguard Worker if name == "import": 645*61046927SAndroid Build Coastguard Worker filename = attrs["file"] 646*61046927SAndroid Build Coastguard Worker self.do_parse(os.path.join(self.path, filename)) 647*61046927SAndroid Build Coastguard Worker elif name == "domain": 648*61046927SAndroid Build Coastguard Worker self.current_domain = attrs["name"] 649*61046927SAndroid Build Coastguard Worker if "prefix" in attrs: 650*61046927SAndroid Build Coastguard Worker self.current_prefix = self.parse_variants(attrs) 651*61046927SAndroid Build Coastguard Worker self.current_prefix_type = attrs["prefix"] 652*61046927SAndroid Build Coastguard Worker else: 653*61046927SAndroid Build Coastguard Worker self.current_prefix = None 654*61046927SAndroid Build Coastguard Worker self.current_prefix_type = None 655*61046927SAndroid Build Coastguard Worker if "varset" in attrs: 656*61046927SAndroid Build Coastguard Worker self.current_varset = self.enums[attrs["varset"]] 657*61046927SAndroid Build Coastguard Worker elif name == "stripe": 658*61046927SAndroid Build Coastguard Worker self.current_stripe = self.parse_variants(attrs) 659*61046927SAndroid Build Coastguard Worker elif name == "enum": 660*61046927SAndroid Build Coastguard Worker self.current_enum_value = 0 661*61046927SAndroid Build Coastguard Worker self.current_enum = Enum(attrs["name"]) 662*61046927SAndroid Build Coastguard Worker self.enums[attrs["name"]] = self.current_enum 663*61046927SAndroid Build Coastguard Worker if len(self.stack) == 1: 664*61046927SAndroid Build Coastguard Worker self.file.append(self.current_enum) 665*61046927SAndroid Build Coastguard Worker elif name == "value": 666*61046927SAndroid Build Coastguard Worker if "value" in attrs: 667*61046927SAndroid Build Coastguard Worker value = int(attrs["value"], 0) 668*61046927SAndroid Build Coastguard Worker else: 669*61046927SAndroid Build Coastguard Worker value = self.current_enum_value 670*61046927SAndroid Build Coastguard Worker self.current_enum.values.append((attrs["name"], value)) 671*61046927SAndroid Build Coastguard Worker elif name == "reg32": 672*61046927SAndroid Build Coastguard Worker self.parse_reg(attrs, 32) 673*61046927SAndroid Build Coastguard Worker elif name == "reg64": 674*61046927SAndroid Build Coastguard Worker self.parse_reg(attrs, 64) 675*61046927SAndroid Build Coastguard Worker elif name == "array": 676*61046927SAndroid Build Coastguard Worker self.current_bitsize = 32 677*61046927SAndroid Build Coastguard Worker variant = self.parse_variants(attrs) 678*61046927SAndroid Build Coastguard Worker index_type = self.enums[attrs["index"]] if "index" in attrs else None 679*61046927SAndroid Build Coastguard Worker self.current_array = Array(attrs, self.prefix(variant), variant, self.current_array, index_type) 680*61046927SAndroid Build Coastguard Worker if len(self.stack) == 1: 681*61046927SAndroid Build Coastguard Worker self.file.append(self.current_array) 682*61046927SAndroid Build Coastguard Worker elif name == "bitset": 683*61046927SAndroid Build Coastguard Worker self.current_bitset = Bitset(attrs["name"], None) 684*61046927SAndroid Build Coastguard Worker if "inline" in attrs and attrs["inline"] == "yes": 685*61046927SAndroid Build Coastguard Worker self.current_bitset.inline = True 686*61046927SAndroid Build Coastguard Worker self.bitsets[self.current_bitset.name] = self.current_bitset 687*61046927SAndroid Build Coastguard Worker if len(self.stack) == 1 and not self.current_bitset.inline: 688*61046927SAndroid Build Coastguard Worker self.file.append(self.current_bitset) 689*61046927SAndroid Build Coastguard Worker elif name == "bitfield" and self.current_bitset: 690*61046927SAndroid Build Coastguard Worker self.parse_field(attrs["name"], attrs) 691*61046927SAndroid Build Coastguard Worker elif name == "database": 692*61046927SAndroid Build Coastguard Worker self.do_validate(attrs["xsi:schemaLocation"]) 693*61046927SAndroid Build Coastguard Worker elif name == "copyright": 694*61046927SAndroid Build Coastguard Worker self.copyright_year = attrs["year"] 695*61046927SAndroid Build Coastguard Worker elif name == "author": 696*61046927SAndroid Build Coastguard Worker self.authors.append(attrs["name"] + " <" + attrs["email"] + "> " + attrs["name"]) 697*61046927SAndroid Build Coastguard Worker 698*61046927SAndroid Build Coastguard Worker def end_element(self, name): 699*61046927SAndroid Build Coastguard Worker if name == "domain": 700*61046927SAndroid Build Coastguard Worker self.current_domain = None 701*61046927SAndroid Build Coastguard Worker self.current_prefix = None 702*61046927SAndroid Build Coastguard Worker self.current_prefix_type = None 703*61046927SAndroid Build Coastguard Worker elif name == "stripe": 704*61046927SAndroid Build Coastguard Worker self.current_stripe = None 705*61046927SAndroid Build Coastguard Worker elif name == "bitset": 706*61046927SAndroid Build Coastguard Worker self.current_bitset = None 707*61046927SAndroid Build Coastguard Worker elif name == "reg32": 708*61046927SAndroid Build Coastguard Worker self.current_reg = None 709*61046927SAndroid Build Coastguard Worker elif name == "array": 710*61046927SAndroid Build Coastguard Worker self.current_array = self.current_array.parent 711*61046927SAndroid Build Coastguard Worker elif name == "enum": 712*61046927SAndroid Build Coastguard Worker self.current_enum = None 713*61046927SAndroid Build Coastguard Worker elif name == "license": 714*61046927SAndroid Build Coastguard Worker self.license = self.cdata 715*61046927SAndroid Build Coastguard Worker 716*61046927SAndroid Build Coastguard Worker def character_data(self, data): 717*61046927SAndroid Build Coastguard Worker self.cdata += data 718*61046927SAndroid Build Coastguard Worker 719*61046927SAndroid Build Coastguard Worker def dump_reg_usages(self): 720*61046927SAndroid Build Coastguard Worker d = collections.defaultdict(list) 721*61046927SAndroid Build Coastguard Worker for usage, regs in self.usage_regs.items(): 722*61046927SAndroid Build Coastguard Worker for reg in regs: 723*61046927SAndroid Build Coastguard Worker variants = self.variant_regs.get(reg.name) 724*61046927SAndroid Build Coastguard Worker if variants: 725*61046927SAndroid Build Coastguard Worker for variant, vreg in variants.items(): 726*61046927SAndroid Build Coastguard Worker if reg == vreg: 727*61046927SAndroid Build Coastguard Worker d[(usage, variant)].append(reg) 728*61046927SAndroid Build Coastguard Worker else: 729*61046927SAndroid Build Coastguard Worker for variant in self.variants: 730*61046927SAndroid Build Coastguard Worker d[(usage, variant)].append(reg) 731*61046927SAndroid Build Coastguard Worker 732*61046927SAndroid Build Coastguard Worker print("#ifdef __cplusplus") 733*61046927SAndroid Build Coastguard Worker 734*61046927SAndroid Build Coastguard Worker for usage, regs in self.usage_regs.items(): 735*61046927SAndroid Build Coastguard Worker print("template<chip CHIP> constexpr inline uint16_t %s_REGS[] = {};" % (usage.upper())) 736*61046927SAndroid Build Coastguard Worker 737*61046927SAndroid Build Coastguard Worker for (usage, variant), regs in d.items(): 738*61046927SAndroid Build Coastguard Worker offsets = [] 739*61046927SAndroid Build Coastguard Worker 740*61046927SAndroid Build Coastguard Worker for reg in regs: 741*61046927SAndroid Build Coastguard Worker if reg.array: 742*61046927SAndroid Build Coastguard Worker for i in range(reg.array.length): 743*61046927SAndroid Build Coastguard Worker offsets.append(reg.array.offset + reg.offset + i * reg.array.stride) 744*61046927SAndroid Build Coastguard Worker if reg.bit_size == 64: 745*61046927SAndroid Build Coastguard Worker offsets.append(offsets[-1] + 1) 746*61046927SAndroid Build Coastguard Worker else: 747*61046927SAndroid Build Coastguard Worker offsets.append(reg.offset) 748*61046927SAndroid Build Coastguard Worker if reg.bit_size == 64: 749*61046927SAndroid Build Coastguard Worker offsets.append(offsets[-1] + 1) 750*61046927SAndroid Build Coastguard Worker 751*61046927SAndroid Build Coastguard Worker offsets.sort() 752*61046927SAndroid Build Coastguard Worker 753*61046927SAndroid Build Coastguard Worker print("template<> constexpr inline uint16_t %s_REGS<%s>[] = {" % (usage.upper(), variant)) 754*61046927SAndroid Build Coastguard Worker for offset in offsets: 755*61046927SAndroid Build Coastguard Worker print("\t%s," % hex(offset)) 756*61046927SAndroid Build Coastguard Worker print("};") 757*61046927SAndroid Build Coastguard Worker 758*61046927SAndroid Build Coastguard Worker print("#endif") 759*61046927SAndroid Build Coastguard Worker 760*61046927SAndroid Build Coastguard Worker def has_variants(self, reg): 761*61046927SAndroid Build Coastguard Worker return reg.name in self.variant_regs and len(self.variant_regs[reg.name]) > 1 762*61046927SAndroid Build Coastguard Worker 763*61046927SAndroid Build Coastguard Worker def dump(self): 764*61046927SAndroid Build Coastguard Worker enums = [] 765*61046927SAndroid Build Coastguard Worker bitsets = [] 766*61046927SAndroid Build Coastguard Worker regs = [] 767*61046927SAndroid Build Coastguard Worker for e in self.file: 768*61046927SAndroid Build Coastguard Worker if isinstance(e, Enum): 769*61046927SAndroid Build Coastguard Worker enums.append(e) 770*61046927SAndroid Build Coastguard Worker elif isinstance(e, Bitset): 771*61046927SAndroid Build Coastguard Worker bitsets.append(e) 772*61046927SAndroid Build Coastguard Worker else: 773*61046927SAndroid Build Coastguard Worker regs.append(e) 774*61046927SAndroid Build Coastguard Worker 775*61046927SAndroid Build Coastguard Worker for e in enums + bitsets + regs: 776*61046927SAndroid Build Coastguard Worker e.dump(self.has_variants(e)) 777*61046927SAndroid Build Coastguard Worker 778*61046927SAndroid Build Coastguard Worker self.dump_reg_usages() 779*61046927SAndroid Build Coastguard Worker 780*61046927SAndroid Build Coastguard Worker 781*61046927SAndroid Build Coastguard Worker def dump_regs_py(self): 782*61046927SAndroid Build Coastguard Worker regs = [] 783*61046927SAndroid Build Coastguard Worker for e in self.file: 784*61046927SAndroid Build Coastguard Worker if isinstance(e, Reg): 785*61046927SAndroid Build Coastguard Worker regs.append(e) 786*61046927SAndroid Build Coastguard Worker 787*61046927SAndroid Build Coastguard Worker for e in regs: 788*61046927SAndroid Build Coastguard Worker e.dump_py() 789*61046927SAndroid Build Coastguard Worker 790*61046927SAndroid Build Coastguard Worker 791*61046927SAndroid Build Coastguard Worker def dump_reg_variants(self, regname, variants): 792*61046927SAndroid Build Coastguard Worker # Don't bother for things that only have a single variant: 793*61046927SAndroid Build Coastguard Worker if len(variants) == 1: 794*61046927SAndroid Build Coastguard Worker return 795*61046927SAndroid Build Coastguard Worker print("#ifdef __cplusplus") 796*61046927SAndroid Build Coastguard Worker print("struct __%s {" % regname) 797*61046927SAndroid Build Coastguard Worker # TODO be more clever.. we should probably figure out which 798*61046927SAndroid Build Coastguard Worker # fields have the same type in all variants (in which they 799*61046927SAndroid Build Coastguard Worker # appear) and stuff everything else in a variant specific 800*61046927SAndroid Build Coastguard Worker # sub-structure. 801*61046927SAndroid Build Coastguard Worker seen_fields = [] 802*61046927SAndroid Build Coastguard Worker bit_size = 32 803*61046927SAndroid Build Coastguard Worker array = False 804*61046927SAndroid Build Coastguard Worker address = None 805*61046927SAndroid Build Coastguard Worker for variant in variants.keys(): 806*61046927SAndroid Build Coastguard Worker print(" /* %s fields: */" % variant) 807*61046927SAndroid Build Coastguard Worker reg = variants[variant] 808*61046927SAndroid Build Coastguard Worker bit_size = reg.bit_size 809*61046927SAndroid Build Coastguard Worker array = reg.array 810*61046927SAndroid Build Coastguard Worker for f in reg.bitset.fields: 811*61046927SAndroid Build Coastguard Worker fld_name = field_name(reg, f) 812*61046927SAndroid Build Coastguard Worker if fld_name in seen_fields: 813*61046927SAndroid Build Coastguard Worker continue 814*61046927SAndroid Build Coastguard Worker seen_fields.append(fld_name) 815*61046927SAndroid Build Coastguard Worker name = fld_name.lower() 816*61046927SAndroid Build Coastguard Worker if f.type in [ "address", "waddress" ]: 817*61046927SAndroid Build Coastguard Worker if address: 818*61046927SAndroid Build Coastguard Worker continue 819*61046927SAndroid Build Coastguard Worker address = f 820*61046927SAndroid Build Coastguard Worker tab_to(" __bo_type", "bo;") 821*61046927SAndroid Build Coastguard Worker tab_to(" uint32_t", "bo_offset;") 822*61046927SAndroid Build Coastguard Worker continue 823*61046927SAndroid Build Coastguard Worker type, val = f.ctype("var") 824*61046927SAndroid Build Coastguard Worker tab_to(" %s" %type, "%s;" %name) 825*61046927SAndroid Build Coastguard Worker print(" /* fallback fields: */") 826*61046927SAndroid Build Coastguard Worker if bit_size == 64: 827*61046927SAndroid Build Coastguard Worker tab_to(" uint64_t", "unknown;") 828*61046927SAndroid Build Coastguard Worker tab_to(" uint64_t", "qword;") 829*61046927SAndroid Build Coastguard Worker else: 830*61046927SAndroid Build Coastguard Worker tab_to(" uint32_t", "unknown;") 831*61046927SAndroid Build Coastguard Worker tab_to(" uint32_t", "dword;") 832*61046927SAndroid Build Coastguard Worker print("};") 833*61046927SAndroid Build Coastguard Worker # TODO don't hardcode the varset enum name 834*61046927SAndroid Build Coastguard Worker varenum = "chip" 835*61046927SAndroid Build Coastguard Worker print("template <%s %s>" % (varenum, varenum.upper())) 836*61046927SAndroid Build Coastguard Worker print("static inline struct fd_reg_pair") 837*61046927SAndroid Build Coastguard Worker xtra = "" 838*61046927SAndroid Build Coastguard Worker xtravar = "" 839*61046927SAndroid Build Coastguard Worker if array: 840*61046927SAndroid Build Coastguard Worker xtra = "int __i, " 841*61046927SAndroid Build Coastguard Worker xtravar = "__i, " 842*61046927SAndroid Build Coastguard Worker print("__%s(%sstruct __%s fields) {" % (regname, xtra, regname)) 843*61046927SAndroid Build Coastguard Worker for variant in variants.keys(): 844*61046927SAndroid Build Coastguard Worker print(" if (%s == %s) {" % (varenum.upper(), variant)) 845*61046927SAndroid Build Coastguard Worker reg = variants[variant] 846*61046927SAndroid Build Coastguard Worker reg.dump_regpair_builder() 847*61046927SAndroid Build Coastguard Worker print(" } else") 848*61046927SAndroid Build Coastguard Worker print(" assert(!\"invalid variant\");") 849*61046927SAndroid Build Coastguard Worker print("}") 850*61046927SAndroid Build Coastguard Worker 851*61046927SAndroid Build Coastguard Worker if bit_size == 64: 852*61046927SAndroid Build Coastguard Worker skip = ", { .reg = 0 }" 853*61046927SAndroid Build Coastguard Worker else: 854*61046927SAndroid Build Coastguard Worker skip = "" 855*61046927SAndroid Build Coastguard Worker 856*61046927SAndroid Build Coastguard Worker print("#define %s(VARIANT, %s...) __%s<VARIANT>(%s{__VA_ARGS__})%s" % (regname, xtravar, regname, xtravar, skip)) 857*61046927SAndroid Build Coastguard Worker print("#endif /* __cplusplus */") 858*61046927SAndroid Build Coastguard Worker 859*61046927SAndroid Build Coastguard Worker def dump_structs(self): 860*61046927SAndroid Build Coastguard Worker for e in self.file: 861*61046927SAndroid Build Coastguard Worker e.dump_pack_struct(self.has_variants(e)) 862*61046927SAndroid Build Coastguard Worker 863*61046927SAndroid Build Coastguard Worker for regname in self.variant_regs: 864*61046927SAndroid Build Coastguard Worker self.dump_reg_variants(regname, self.variant_regs[regname]) 865*61046927SAndroid Build Coastguard Worker 866*61046927SAndroid Build Coastguard Worker 867*61046927SAndroid Build Coastguard Workerdef dump_c(args, guard, func): 868*61046927SAndroid Build Coastguard Worker p = Parser() 869*61046927SAndroid Build Coastguard Worker 870*61046927SAndroid Build Coastguard Worker try: 871*61046927SAndroid Build Coastguard Worker p.parse(args.rnn, args.xml) 872*61046927SAndroid Build Coastguard Worker except Error as e: 873*61046927SAndroid Build Coastguard Worker print(e, file=sys.stderr) 874*61046927SAndroid Build Coastguard Worker exit(1) 875*61046927SAndroid Build Coastguard Worker 876*61046927SAndroid Build Coastguard Worker print("#ifndef %s\n#define %s\n" % (guard, guard)) 877*61046927SAndroid Build Coastguard Worker 878*61046927SAndroid Build Coastguard Worker print("""/* Autogenerated file, DO NOT EDIT manually! 879*61046927SAndroid Build Coastguard Worker 880*61046927SAndroid Build Coastguard WorkerThis file was generated by the rules-ng-ng gen_header.py tool in this git repository: 881*61046927SAndroid Build Coastguard Workerhttp://gitlab.freedesktop.org/mesa/mesa/ 882*61046927SAndroid Build Coastguard Workergit clone https://gitlab.freedesktop.org/mesa/mesa.git 883*61046927SAndroid Build Coastguard Worker 884*61046927SAndroid Build Coastguard WorkerThe rules-ng-ng source files this header was generated from are: 885*61046927SAndroid Build Coastguard Worker""") 886*61046927SAndroid Build Coastguard Worker maxlen = 0 887*61046927SAndroid Build Coastguard Worker for filepath in p.xml_files: 888*61046927SAndroid Build Coastguard Worker maxlen = max(maxlen, len(filepath)) 889*61046927SAndroid Build Coastguard Worker for filepath in p.xml_files: 890*61046927SAndroid Build Coastguard Worker pad = " " * (maxlen - len(filepath)) 891*61046927SAndroid Build Coastguard Worker filesize = str(os.path.getsize(filepath)) 892*61046927SAndroid Build Coastguard Worker filesize = " " * (7 - len(filesize)) + filesize 893*61046927SAndroid Build Coastguard Worker filetime = time.ctime(os.path.getmtime(filepath)) 894*61046927SAndroid Build Coastguard Worker print("- " + filepath + pad + " (" + filesize + " bytes, from " + filetime + ")") 895*61046927SAndroid Build Coastguard Worker if p.copyright_year: 896*61046927SAndroid Build Coastguard Worker current_year = str(datetime.date.today().year) 897*61046927SAndroid Build Coastguard Worker print() 898*61046927SAndroid Build Coastguard Worker print("Copyright © %s-%s by the following authors:" % (p.copyright_year, current_year)) 899*61046927SAndroid Build Coastguard Worker for author in p.authors: 900*61046927SAndroid Build Coastguard Worker print("- " + author) 901*61046927SAndroid Build Coastguard Worker if p.license: 902*61046927SAndroid Build Coastguard Worker print(p.license) 903*61046927SAndroid Build Coastguard Worker print("*/") 904*61046927SAndroid Build Coastguard Worker 905*61046927SAndroid Build Coastguard Worker print() 906*61046927SAndroid Build Coastguard Worker print("#ifdef __KERNEL__") 907*61046927SAndroid Build Coastguard Worker print("#include <linux/bug.h>") 908*61046927SAndroid Build Coastguard Worker print("#define assert(x) BUG_ON(!(x))") 909*61046927SAndroid Build Coastguard Worker print("#else") 910*61046927SAndroid Build Coastguard Worker print("#include <assert.h>") 911*61046927SAndroid Build Coastguard Worker print("#endif") 912*61046927SAndroid Build Coastguard Worker print() 913*61046927SAndroid Build Coastguard Worker 914*61046927SAndroid Build Coastguard Worker print("#ifdef __cplusplus") 915*61046927SAndroid Build Coastguard Worker print("#define __struct_cast(X)") 916*61046927SAndroid Build Coastguard Worker print("#else") 917*61046927SAndroid Build Coastguard Worker print("#define __struct_cast(X) (struct X)") 918*61046927SAndroid Build Coastguard Worker print("#endif") 919*61046927SAndroid Build Coastguard Worker print() 920*61046927SAndroid Build Coastguard Worker 921*61046927SAndroid Build Coastguard Worker func(p) 922*61046927SAndroid Build Coastguard Worker 923*61046927SAndroid Build Coastguard Worker print("\n#endif /* %s */" % guard) 924*61046927SAndroid Build Coastguard Worker 925*61046927SAndroid Build Coastguard Worker 926*61046927SAndroid Build Coastguard Workerdef dump_c_defines(args): 927*61046927SAndroid Build Coastguard Worker guard = str.replace(os.path.basename(args.xml), '.', '_').upper() 928*61046927SAndroid Build Coastguard Worker dump_c(args, guard, lambda p: p.dump()) 929*61046927SAndroid Build Coastguard Worker 930*61046927SAndroid Build Coastguard Worker 931*61046927SAndroid Build Coastguard Workerdef dump_c_pack_structs(args): 932*61046927SAndroid Build Coastguard Worker guard = str.replace(os.path.basename(args.xml), '.', '_').upper() + '_STRUCTS' 933*61046927SAndroid Build Coastguard Worker dump_c(args, guard, lambda p: p.dump_structs()) 934*61046927SAndroid Build Coastguard Worker 935*61046927SAndroid Build Coastguard Worker 936*61046927SAndroid Build Coastguard Workerdef dump_py_defines(args): 937*61046927SAndroid Build Coastguard Worker p = Parser() 938*61046927SAndroid Build Coastguard Worker 939*61046927SAndroid Build Coastguard Worker try: 940*61046927SAndroid Build Coastguard Worker p.parse(args.rnn, args.xml) 941*61046927SAndroid Build Coastguard Worker except Error as e: 942*61046927SAndroid Build Coastguard Worker print(e, file=sys.stderr) 943*61046927SAndroid Build Coastguard Worker exit(1) 944*61046927SAndroid Build Coastguard Worker 945*61046927SAndroid Build Coastguard Worker file_name = os.path.splitext(os.path.basename(args.xml))[0] 946*61046927SAndroid Build Coastguard Worker 947*61046927SAndroid Build Coastguard Worker print("from enum import IntEnum") 948*61046927SAndroid Build Coastguard Worker print("class %sRegs(IntEnum):" % file_name.upper()) 949*61046927SAndroid Build Coastguard Worker 950*61046927SAndroid Build Coastguard Worker os.path.basename(args.xml) 951*61046927SAndroid Build Coastguard Worker 952*61046927SAndroid Build Coastguard Worker p.dump_regs_py() 953*61046927SAndroid Build Coastguard Worker 954*61046927SAndroid Build Coastguard Worker 955*61046927SAndroid Build Coastguard Workerdef main(): 956*61046927SAndroid Build Coastguard Worker parser = argparse.ArgumentParser() 957*61046927SAndroid Build Coastguard Worker parser.add_argument('--rnn', type=str, required=True) 958*61046927SAndroid Build Coastguard Worker parser.add_argument('--xml', type=str, required=True) 959*61046927SAndroid Build Coastguard Worker 960*61046927SAndroid Build Coastguard Worker subparsers = parser.add_subparsers(required=True) 961*61046927SAndroid Build Coastguard Worker 962*61046927SAndroid Build Coastguard Worker parser_c_defines = subparsers.add_parser('c-defines') 963*61046927SAndroid Build Coastguard Worker parser_c_defines.set_defaults(func=dump_c_defines) 964*61046927SAndroid Build Coastguard Worker 965*61046927SAndroid Build Coastguard Worker parser_c_pack_structs = subparsers.add_parser('c-pack-structs') 966*61046927SAndroid Build Coastguard Worker parser_c_pack_structs.set_defaults(func=dump_c_pack_structs) 967*61046927SAndroid Build Coastguard Worker 968*61046927SAndroid Build Coastguard Worker parser_py_defines = subparsers.add_parser('py-defines') 969*61046927SAndroid Build Coastguard Worker parser_py_defines.set_defaults(func=dump_py_defines) 970*61046927SAndroid Build Coastguard Worker 971*61046927SAndroid Build Coastguard Worker args = parser.parse_args() 972*61046927SAndroid Build Coastguard Worker args.func(args) 973*61046927SAndroid Build Coastguard Worker 974*61046927SAndroid Build Coastguard Worker 975*61046927SAndroid Build Coastguard Workerif __name__ == '__main__': 976*61046927SAndroid Build Coastguard Worker main() 977