17ec681f3Smrg#!/usr/bin/python3
27ec681f3Smrg
37ec681f3Smrgimport xml.parsers.expat
47ec681f3Smrgimport sys
57ec681f3Smrgimport os
67ec681f3Smrg
77ec681f3Smrgclass Error(Exception):
87ec681f3Smrg	def __init__(self, message):
97ec681f3Smrg		self.message = message
107ec681f3Smrg
117ec681f3Smrgclass Enum(object):
127ec681f3Smrg	def __init__(self, name):
137ec681f3Smrg		self.name = name
147ec681f3Smrg		self.values = []
157ec681f3Smrg
167ec681f3Smrg	def dump(self):
177ec681f3Smrg		prev = 0
187ec681f3Smrg		use_hex = False
197ec681f3Smrg		for (name, value) in self.values:
207ec681f3Smrg			if value > 0x1000:
217ec681f3Smrg				use_hex = True
227ec681f3Smrg
237ec681f3Smrg		print("enum %s {" % self.name)
247ec681f3Smrg		for (name, value) in self.values:
257ec681f3Smrg			if use_hex:
267ec681f3Smrg				print("\t%s = 0x%08x," % (name, value))
277ec681f3Smrg			else:
287ec681f3Smrg				print("\t%s = %d," % (name, value))
297ec681f3Smrg		print("};\n")
307ec681f3Smrg
317ec681f3Smrg	def dump_pack_struct(self):
327ec681f3Smrg		pass
337ec681f3Smrg
347ec681f3Smrgclass Field(object):
357ec681f3Smrg	def __init__(self, name, low, high, shr, type, parser):
367ec681f3Smrg		self.name = name
377ec681f3Smrg		self.low = low
387ec681f3Smrg		self.high = high
397ec681f3Smrg		self.shr = shr
407ec681f3Smrg		self.type = type
417ec681f3Smrg
427ec681f3Smrg		builtin_types = [ None, "a3xx_regid", "boolean", "uint", "hex", "int", "fixed", "ufixed", "float", "address", "waddress" ]
437ec681f3Smrg
447ec681f3Smrg		if low < 0 or low > 31:
457ec681f3Smrg			raise parser.error("low attribute out of range: %d" % low)
467ec681f3Smrg		if high < 0 or high > 31:
477ec681f3Smrg			raise parser.error("high attribute out of range: %d" % high)
487ec681f3Smrg		if high < low:
497ec681f3Smrg			raise parser.error("low is greater than high: low=%d, high=%d" % (low, high))
507ec681f3Smrg		if self.type == "boolean" and not low == high:
517ec681f3Smrg			raise parser.error("booleans should be 1 bit fields");
527ec681f3Smrg		elif self.type == "float" and not (high - low == 31 or high - low == 15):
537ec681f3Smrg			raise parser.error("floats should be 16 or 32 bit fields")
547ec681f3Smrg		elif not self.type in builtin_types and not self.type in parser.enums:
557ec681f3Smrg			raise parser.error("unknown type '%s'" % self.type);
567ec681f3Smrg
577ec681f3Smrg	def ctype(self, var_name):
587ec681f3Smrg		if self.type == None:
597ec681f3Smrg			type = "uint32_t"
607ec681f3Smrg			val = var_name
617ec681f3Smrg		elif self.type == "boolean":
627ec681f3Smrg			type = "bool"
637ec681f3Smrg			val = var_name
647ec681f3Smrg		elif self.type == "uint" or self.type == "hex" or self.type == "a3xx_regid":
657ec681f3Smrg			type = "uint32_t"
667ec681f3Smrg			val = var_name
677ec681f3Smrg		elif self.type == "int":
687ec681f3Smrg			type = "int32_t"
697ec681f3Smrg			val = var_name
707ec681f3Smrg		elif self.type == "fixed":
717ec681f3Smrg			type = "float"
727ec681f3Smrg			val = "((int32_t)(%s * %d.0))" % (var_name, 1 << self.radix)
737ec681f3Smrg		elif self.type == "ufixed":
747ec681f3Smrg			type = "float"
757ec681f3Smrg			val = "((uint32_t)(%s * %d.0))" % (var_name, 1 << self.radix)
767ec681f3Smrg		elif self.type == "float" and self.high - self.low == 31:
777ec681f3Smrg			type = "float"
787ec681f3Smrg			val = "fui(%s)" % var_name
797ec681f3Smrg		elif self.type == "float" and self.high - self.low == 15:
807ec681f3Smrg			type = "float"
817ec681f3Smrg			val = "_mesa_float_to_half(%s)" % var_name
827ec681f3Smrg		elif self.type in [ "address", "waddress" ]:
837ec681f3Smrg			type = "uint64_t"
847ec681f3Smrg			val = var_name
857ec681f3Smrg		else:
867ec681f3Smrg			type = "enum %s" % self.type
877ec681f3Smrg			val = var_name
887ec681f3Smrg
897ec681f3Smrg		if self.shr > 0:
907ec681f3Smrg			val = "(%s >> %d)" % (val, self.shr)
917ec681f3Smrg
927ec681f3Smrg		return (type, val)
937ec681f3Smrg
947ec681f3Smrgdef tab_to(name, value):
957ec681f3Smrg	tab_count = (68 - (len(name) & ~7)) // 8
967ec681f3Smrg	if tab_count <= 0:
977ec681f3Smrg		tab_count = 1
987ec681f3Smrg	print(name + ('\t' * tab_count) + value)
997ec681f3Smrg
1007ec681f3Smrgdef mask(low, high):
1017ec681f3Smrg	return ((0xffffffff >> (32 - (high + 1 - low))) << low)
1027ec681f3Smrg
1037ec681f3Smrgclass Bitset(object):
1047ec681f3Smrg	def __init__(self, name, template):
1057ec681f3Smrg		self.name = name
1067ec681f3Smrg		self.inline = False
1077ec681f3Smrg		if template:
1087ec681f3Smrg			self.fields = template.fields[:]
1097ec681f3Smrg		else:
1107ec681f3Smrg			self.fields = []
1117ec681f3Smrg
1127ec681f3Smrg	def dump_pack_struct(self, prefix=None, array=None, bit_size=32):
1137ec681f3Smrg		def field_name(prefix, name):
1147ec681f3Smrg			if f.name:
1157ec681f3Smrg				name = f.name.lower()
1167ec681f3Smrg			else:
1177ec681f3Smrg				name = prefix.lower()
1187ec681f3Smrg
1197ec681f3Smrg			if (name in [ "double", "float", "int" ]) or not (name[0].isalpha()):
1207ec681f3Smrg					name = "_" + name
1217ec681f3Smrg
1227ec681f3Smrg			return name
1237ec681f3Smrg
1247ec681f3Smrg		if not prefix:
1257ec681f3Smrg			return
1267ec681f3Smrg		if prefix == None:
1277ec681f3Smrg			prefix = self.name
1287ec681f3Smrg
1297ec681f3Smrg		value_name = "dword"
1307ec681f3Smrg		print("struct %s {" % prefix)
1317ec681f3Smrg		for f in self.fields:
1327ec681f3Smrg			if f.type in [ "address", "waddress" ]:
1337ec681f3Smrg				tab_to("    __bo_type", "bo;")
1347ec681f3Smrg				tab_to("    uint32_t", "bo_offset;")
1357ec681f3Smrg				if bit_size == 64:
1367ec681f3Smrg                                    value_name = "qword"
1377ec681f3Smrg				continue
1387ec681f3Smrg			name = field_name(prefix, f.name)
1397ec681f3Smrg
1407ec681f3Smrg			type, val = f.ctype("var")
1417ec681f3Smrg
1427ec681f3Smrg			tab_to("    %s" % type, "%s;" % name)
1437ec681f3Smrg		if value_name == "qword":
1447ec681f3Smrg			tab_to("    uint64_t", "unknown;")
1457ec681f3Smrg			tab_to("    uint64_t", "qword;")
1467ec681f3Smrg		else:
1477ec681f3Smrg			tab_to("    uint32_t", "unknown;")
1487ec681f3Smrg			tab_to("    uint32_t", "dword;")
1497ec681f3Smrg		print("};\n")
1507ec681f3Smrg
1517ec681f3Smrg		address = None;
1527ec681f3Smrg		for f in self.fields:
1537ec681f3Smrg			if f.type in [ "address", "waddress" ]:
1547ec681f3Smrg				address = f
1557ec681f3Smrg		if array:
1567ec681f3Smrg			print("static inline struct fd_reg_pair\npack_%s(uint32_t i, struct %s fields)\n{" %
1577ec681f3Smrg				  (prefix, prefix));
1587ec681f3Smrg		else:
1597ec681f3Smrg			print("static inline struct fd_reg_pair\npack_%s(struct %s fields)\n{" %
1607ec681f3Smrg				  (prefix, prefix));
1617ec681f3Smrg
1627ec681f3Smrg		print("#ifndef NDEBUG")
1637ec681f3Smrg		known_mask = 0
1647ec681f3Smrg		for f in self.fields:
1657ec681f3Smrg			known_mask |= mask(f.low, f.high)
1667ec681f3Smrg			if f.type in [ "boolean", "address", "waddress" ]:
1677ec681f3Smrg				continue
1687ec681f3Smrg			type, val = f.ctype("fields.%s" % field_name(prefix, f.name))
1697ec681f3Smrg			print("    assert((%-40s & 0x%08x) == 0);" % (val, 0xffffffff ^ mask(0 , f.high - f.low)))
1707ec681f3Smrg		print("    assert((%-40s & 0x%08x) == 0);" % ("fields.unknown", known_mask))
1717ec681f3Smrg		print("#endif\n")
1727ec681f3Smrg
1737ec681f3Smrg		print("    return (struct fd_reg_pair) {")
1747ec681f3Smrg		if array:
1757ec681f3Smrg			print("        .reg = REG_%s(i)," % prefix)
1767ec681f3Smrg		else:
1777ec681f3Smrg			print("        .reg = REG_%s," % prefix)
1787ec681f3Smrg
1797ec681f3Smrg		print("        .value =")
1807ec681f3Smrg		for f in self.fields:
1817ec681f3Smrg			if f.type in [ "address", "waddress" ]:
1827ec681f3Smrg				continue
1837ec681f3Smrg			else:
1847ec681f3Smrg				type, val = f.ctype("fields.%s" % field_name(prefix, f.name))
1857ec681f3Smrg				print("            (%-40s << %2d) |" % (val, f.low))
1867ec681f3Smrg		print("            fields.unknown | fields.%s," % (value_name,))
1877ec681f3Smrg
1887ec681f3Smrg		if address:
1897ec681f3Smrg			print("        .is_address = true,")
1907ec681f3Smrg			print("        .bo = fields.bo,")
1917ec681f3Smrg			if f.type == "waddress":
1927ec681f3Smrg				print("        .bo_write = true,")
1937ec681f3Smrg			print("        .bo_offset = fields.bo_offset,")
1947ec681f3Smrg			print("        .bo_shift = %d" % address.shr)
1957ec681f3Smrg
1967ec681f3Smrg		print("    };\n}\n")
1977ec681f3Smrg
1987ec681f3Smrg		if address:
1997ec681f3Smrg			skip = ", { .reg = 0 }"
2007ec681f3Smrg		else:
2017ec681f3Smrg			skip = ""
2027ec681f3Smrg
2037ec681f3Smrg		if array:
2047ec681f3Smrg			print("#define %s(i, ...) pack_%s(i, (struct %s) { __VA_ARGS__ })%s\n" %
2057ec681f3Smrg				  (prefix, prefix, prefix, skip))
2067ec681f3Smrg		else:
2077ec681f3Smrg			print("#define %s(...) pack_%s((struct %s) { __VA_ARGS__ })%s\n" %
2087ec681f3Smrg				  (prefix, prefix, prefix, skip))
2097ec681f3Smrg
2107ec681f3Smrg
2117ec681f3Smrg	def dump(self, prefix=None):
2127ec681f3Smrg		if prefix == None:
2137ec681f3Smrg			prefix = self.name
2147ec681f3Smrg		for f in self.fields:
2157ec681f3Smrg			if f.name:
2167ec681f3Smrg				name = prefix + "_" + f.name
2177ec681f3Smrg			else:
2187ec681f3Smrg				name = prefix
2197ec681f3Smrg
2207ec681f3Smrg			if not f.name and f.low == 0 and f.shr == 0 and not f.type in ["float", "fixed", "ufixed"]:
2217ec681f3Smrg				pass
2227ec681f3Smrg			elif f.type == "boolean" or (f.type == None and f.low == f.high):
2237ec681f3Smrg				tab_to("#define %s" % name, "0x%08x" % (1 << f.low))
2247ec681f3Smrg			else:
2257ec681f3Smrg				tab_to("#define %s__MASK" % name, "0x%08x" % mask(f.low, f.high))
2267ec681f3Smrg				tab_to("#define %s__SHIFT" % name, "%d" % f.low)
2277ec681f3Smrg				type, val = f.ctype("val")
2287ec681f3Smrg
2297ec681f3Smrg				print("static inline uint32_t %s(%s val)\n{" % (name, type))
2307ec681f3Smrg				if f.shr > 0:
2317ec681f3Smrg					print("\tassert(!(val & 0x%x));" % mask(0, f.shr - 1))
2327ec681f3Smrg				print("\treturn ((%s) << %s__SHIFT) & %s__MASK;\n}" % (val, name, name))
2337ec681f3Smrg		print()
2347ec681f3Smrg
2357ec681f3Smrgclass Array(object):
2367ec681f3Smrg	def __init__(self, attrs, domain):
2377ec681f3Smrg		if "name" in attrs:
2387ec681f3Smrg			self.name = attrs["name"]
2397ec681f3Smrg		else:
2407ec681f3Smrg			self.name = ""
2417ec681f3Smrg		self.domain = domain
2427ec681f3Smrg		self.offset = int(attrs["offset"], 0)
2437ec681f3Smrg		self.stride = int(attrs["stride"], 0)
2447ec681f3Smrg		self.length = int(attrs["length"], 0)
2457ec681f3Smrg
2467ec681f3Smrg	def dump(self):
2477ec681f3Smrg		print("#define REG_%s_%s(i0) (0x%08x + 0x%x*(i0))\n" % (self.domain, self.name, self.offset, self.stride))
2487ec681f3Smrg
2497ec681f3Smrg	def dump_pack_struct(self):
2507ec681f3Smrg		pass
2517ec681f3Smrg
2527ec681f3Smrgclass Reg(object):
2537ec681f3Smrg	def __init__(self, attrs, domain, array, bit_size):
2547ec681f3Smrg		self.name = attrs["name"]
2557ec681f3Smrg		self.domain = domain
2567ec681f3Smrg		self.array = array
2577ec681f3Smrg		self.offset = int(attrs["offset"], 0)
2587ec681f3Smrg		self.type = None
2597ec681f3Smrg		self.bit_size = bit_size
2607ec681f3Smrg
2617ec681f3Smrg		if self.array:
2627ec681f3Smrg			self.full_name = self.domain + "_" + self.array.name + "_" + self.name
2637ec681f3Smrg		else:
2647ec681f3Smrg			self.full_name = self.domain + "_" + self.name
2657ec681f3Smrg
2667ec681f3Smrg	def dump(self):
2677ec681f3Smrg		if self.array:
2687ec681f3Smrg			offset = self.array.offset + self.offset
2697ec681f3Smrg			print("static inline uint32_t REG_%s(uint32_t i0) { return 0x%08x + 0x%x*i0; }" % (self.full_name, offset, self.array.stride))
2707ec681f3Smrg		else:
2717ec681f3Smrg			tab_to("#define REG_%s" % self.full_name, "0x%08x" % self.offset)
2727ec681f3Smrg
2737ec681f3Smrg		if self.bitset.inline:
2747ec681f3Smrg			self.bitset.dump(self.full_name)
2757ec681f3Smrg		print("")
2767ec681f3Smrg
2777ec681f3Smrg	def dump_pack_struct(self):
2787ec681f3Smrg		if self.bitset.inline:
2797ec681f3Smrg			self.bitset.dump_pack_struct(self.full_name, not self.array == None, self.bit_size)
2807ec681f3Smrg
2817ec681f3Smrg
2827ec681f3Smrgdef parse_variants(attrs):
2837ec681f3Smrg		if not "variants" in attrs:
2847ec681f3Smrg				return None
2857ec681f3Smrg		variant = attrs["variants"].split(",")[0]
2867ec681f3Smrg		if "-" in variant:
2877ec681f3Smrg			variant = variant[:variant.index("-")]
2887ec681f3Smrg
2897ec681f3Smrg		return variant
2907ec681f3Smrg
2917ec681f3Smrgclass Parser(object):
2927ec681f3Smrg	def __init__(self):
2937ec681f3Smrg		self.current_array = None
2947ec681f3Smrg		self.current_domain = None
2957ec681f3Smrg		self.current_prefix = None
2967ec681f3Smrg		self.current_stripe = None
2977ec681f3Smrg		self.current_bitset = None
2987ec681f3Smrg		self.bitsets = {}
2997ec681f3Smrg		self.enums = {}
3007ec681f3Smrg		self.file = []
3017ec681f3Smrg
3027ec681f3Smrg	def error(self, message):
3037ec681f3Smrg		parser, filename = self.stack[-1]
3047ec681f3Smrg		return Error("%s:%d:%d: %s" % (filename, parser.CurrentLineNumber, parser.CurrentColumnNumber, message))
3057ec681f3Smrg
3067ec681f3Smrg	def prefix(self):
3077ec681f3Smrg		if self.current_stripe:
3087ec681f3Smrg			return self.current_stripe + "_" + self.current_domain
3097ec681f3Smrg		elif self.current_prefix:
3107ec681f3Smrg			return self.current_prefix + "_" + self.current_domain
3117ec681f3Smrg		else:
3127ec681f3Smrg			return self.current_domain
3137ec681f3Smrg
3147ec681f3Smrg	def parse_field(self, name, attrs):
3157ec681f3Smrg		try:
3167ec681f3Smrg			if "pos" in attrs:
3177ec681f3Smrg				high = low = int(attrs["pos"], 0)
3187ec681f3Smrg			elif "high" in attrs and "low" in attrs:
3197ec681f3Smrg				high = int(attrs["high"], 0)
3207ec681f3Smrg				low = int(attrs["low"], 0)
3217ec681f3Smrg			else:
3227ec681f3Smrg				low = 0
3237ec681f3Smrg				high = 31
3247ec681f3Smrg
3257ec681f3Smrg			if "type" in attrs:
3267ec681f3Smrg				type = attrs["type"]
3277ec681f3Smrg			else:
3287ec681f3Smrg				type = None
3297ec681f3Smrg
3307ec681f3Smrg			if "shr" in attrs:
3317ec681f3Smrg				shr = int(attrs["shr"], 0)
3327ec681f3Smrg			else:
3337ec681f3Smrg				shr = 0
3347ec681f3Smrg
3357ec681f3Smrg			b = Field(name, low, high, shr, type, self)
3367ec681f3Smrg
3377ec681f3Smrg			if type == "fixed" or type == "ufixed":
3387ec681f3Smrg				b.radix = int(attrs["radix"], 0)
3397ec681f3Smrg
3407ec681f3Smrg			self.current_bitset.fields.append(b)
3417ec681f3Smrg		except ValueError as e:
3427ec681f3Smrg			raise self.error(e);
3437ec681f3Smrg
3447ec681f3Smrg	def do_parse(self, filename):
3457ec681f3Smrg		file = open(filename, "rb")
3467ec681f3Smrg		parser = xml.parsers.expat.ParserCreate()
3477ec681f3Smrg		self.stack.append((parser, filename))
3487ec681f3Smrg		parser.StartElementHandler = self.start_element
3497ec681f3Smrg		parser.EndElementHandler = self.end_element
3507ec681f3Smrg		parser.ParseFile(file)
3517ec681f3Smrg		self.stack.pop()
3527ec681f3Smrg		file.close()
3537ec681f3Smrg
3547ec681f3Smrg	def parse(self, rnn_path, filename):
3557ec681f3Smrg		self.path = rnn_path
3567ec681f3Smrg		self.stack = []
3577ec681f3Smrg		self.do_parse(filename)
3587ec681f3Smrg
3597ec681f3Smrg	def parse_reg(self, attrs, bit_size):
3607ec681f3Smrg		if "type" in attrs and attrs["type"] in self.bitsets:
3617ec681f3Smrg			bitset = self.bitsets[attrs["type"]]
3627ec681f3Smrg			if bitset.inline:
3637ec681f3Smrg				self.current_bitset = Bitset(attrs["name"], bitset)
3647ec681f3Smrg				self.current_bitset.inline = True
3657ec681f3Smrg			else:
3667ec681f3Smrg				self.current_bitset = bitset
3677ec681f3Smrg		else:
3687ec681f3Smrg			self.current_bitset = Bitset(attrs["name"], None)
3697ec681f3Smrg			self.current_bitset.inline = True
3707ec681f3Smrg			if "type" in attrs:
3717ec681f3Smrg				self.parse_field(None, attrs)
3727ec681f3Smrg
3737ec681f3Smrg		self.current_reg = Reg(attrs, self.prefix(), self.current_array, bit_size)
3747ec681f3Smrg		self.current_reg.bitset = self.current_bitset
3757ec681f3Smrg
3767ec681f3Smrg		if len(self.stack) == 1:
3777ec681f3Smrg			self.file.append(self.current_reg)
3787ec681f3Smrg
3797ec681f3Smrg	def start_element(self, name, attrs):
3807ec681f3Smrg		if name == "import":
3817ec681f3Smrg			filename = attrs["file"]
3827ec681f3Smrg			self.do_parse(os.path.join(self.path, filename))
3837ec681f3Smrg		elif name == "domain":
3847ec681f3Smrg			self.current_domain = attrs["name"]
3857ec681f3Smrg			if "prefix" in attrs and attrs["prefix"] == "chip":
3867ec681f3Smrg				self.current_prefix = parse_variants(attrs)
3877ec681f3Smrg		elif name == "stripe":
3887ec681f3Smrg			self.current_stripe = parse_variants(attrs)
3897ec681f3Smrg		elif name == "enum":
3907ec681f3Smrg			self.current_enum_value = 0
3917ec681f3Smrg			self.current_enum = Enum(attrs["name"])
3927ec681f3Smrg			self.enums[attrs["name"]] = self.current_enum
3937ec681f3Smrg			if len(self.stack) == 1:
3947ec681f3Smrg				self.file.append(self.current_enum)
3957ec681f3Smrg		elif name == "value":
3967ec681f3Smrg			if "value" in attrs:
3977ec681f3Smrg				value = int(attrs["value"], 0)
3987ec681f3Smrg			else:
3997ec681f3Smrg				value = self.current_enum_value
4007ec681f3Smrg			self.current_enum.values.append((attrs["name"], value))
4017ec681f3Smrg			# self.current_enum_value = value + 1
4027ec681f3Smrg		elif name == "reg32":
4037ec681f3Smrg			self.parse_reg(attrs, 32)
4047ec681f3Smrg		elif name == "reg64":
4057ec681f3Smrg			self.parse_reg(attrs, 64)
4067ec681f3Smrg		elif name == "array":
4077ec681f3Smrg			self.current_array = Array(attrs, self.prefix())
4087ec681f3Smrg			if len(self.stack) == 1:
4097ec681f3Smrg				self.file.append(self.current_array)
4107ec681f3Smrg		elif name == "bitset":
4117ec681f3Smrg			self.current_bitset = Bitset(attrs["name"], None)
4127ec681f3Smrg			if "inline" in attrs and attrs["inline"] == "yes":
4137ec681f3Smrg				self.current_bitset.inline = True
4147ec681f3Smrg			self.bitsets[self.current_bitset.name] = self.current_bitset
4157ec681f3Smrg			if len(self.stack) == 1 and not self.current_bitset.inline:
4167ec681f3Smrg				self.file.append(self.current_bitset)
4177ec681f3Smrg		elif name == "bitfield" and self.current_bitset:
4187ec681f3Smrg			self.parse_field(attrs["name"], attrs)
4197ec681f3Smrg
4207ec681f3Smrg	def end_element(self, name):
4217ec681f3Smrg		if name == "domain":
4227ec681f3Smrg			self.current_domain = None
4237ec681f3Smrg			self.current_prefix = None
4247ec681f3Smrg		elif name == "stripe":
4257ec681f3Smrg			self.current_stripe = None
4267ec681f3Smrg		elif name == "bitset":
4277ec681f3Smrg			self.current_bitset = None
4287ec681f3Smrg		elif name == "reg32":
4297ec681f3Smrg			self.current_reg = None
4307ec681f3Smrg		elif name == "array":
4317ec681f3Smrg			self.current_array = None;
4327ec681f3Smrg		elif name == "enum":
4337ec681f3Smrg			self.current_enum = None
4347ec681f3Smrg
4357ec681f3Smrg	def dump(self):
4367ec681f3Smrg		enums = []
4377ec681f3Smrg		bitsets = []
4387ec681f3Smrg		regs = []
4397ec681f3Smrg		for e in self.file:
4407ec681f3Smrg			if isinstance(e, Enum):
4417ec681f3Smrg				enums.append(e)
4427ec681f3Smrg			elif isinstance(e, Bitset):
4437ec681f3Smrg				bitsets.append(e)
4447ec681f3Smrg			else:
4457ec681f3Smrg				regs.append(e)
4467ec681f3Smrg
4477ec681f3Smrg		for e in enums + bitsets + regs:
4487ec681f3Smrg			e.dump()
4497ec681f3Smrg
4507ec681f3Smrg	def dump_structs(self):
4517ec681f3Smrg		for e in self.file:
4527ec681f3Smrg			e.dump_pack_struct()
4537ec681f3Smrg
4547ec681f3Smrg
4557ec681f3Smrgdef main():
4567ec681f3Smrg	p = Parser()
4577ec681f3Smrg	rnn_path = sys.argv[1]
4587ec681f3Smrg	xml_file = sys.argv[2]
4597ec681f3Smrg	if len(sys.argv) > 3 and sys.argv[3] == '--pack-structs':
4607ec681f3Smrg		do_structs = True
4617ec681f3Smrg		guard = str.replace(os.path.basename(xml_file), '.', '_').upper() + '_STRUCTS'
4627ec681f3Smrg	else:
4637ec681f3Smrg		do_structs = False
4647ec681f3Smrg		guard = str.replace(os.path.basename(xml_file), '.', '_').upper()
4657ec681f3Smrg
4667ec681f3Smrg	print("#ifndef %s\n#define %s\n" % (guard, guard))
4677ec681f3Smrg
4687ec681f3Smrg	try:
4697ec681f3Smrg		p.parse(rnn_path, xml_file)
4707ec681f3Smrg	except Error as e:
4717ec681f3Smrg		print(e)
4727ec681f3Smrg		exit(1)
4737ec681f3Smrg
4747ec681f3Smrg	if do_structs:
4757ec681f3Smrg		p.dump_structs()
4767ec681f3Smrg	else:
4777ec681f3Smrg		p.dump()
4787ec681f3Smrg
4797ec681f3Smrg	print("\n#endif /* %s */" % guard)
4807ec681f3Smrg
4817ec681f3Smrgif __name__ == '__main__':
4827ec681f3Smrg	main()
483