import html import os import re directory = os.fsencode('SysReg_xml_v86A-2020-03') def output_reg(name, description, spec): assert(all(map(lambda x: type(x) == int, spec))) print("{:020b} 'S{}_{}_c{}_c{}_{}' : ( '{}', '{}' ),".format( (spec[0] << 16) + (spec[1] << 12) + (spec[2] << 8) + (spec[3] << 4) + (spec[4] << 0), spec[0], spec[1], spec[2], spec[3], spec[4], name, description)) for file in os.listdir(directory): filename = os.fsdecode(file) if filename.startswith('AArch64') and filename.endswith(".xml"): filename = os.path.join(directory, os.fsencode(filename)) reg_name = None reg_description = None reg_op0 = None reg_op1 = None reg_CRn = None reg_CRm = None reg_op2 = None with open(filename, 'r') as f: for line in f: line = line.strip() try: if 'reg_short_name' in line: line = line.replace('', '') line = line.replace('', '') reg_name = html.unescape(line) elif 'reg_long_name' in line: line = line.replace('', '') line = line.replace('', '') reg_description = html.unescape(line) elif reg_op0 is None and '', '') reg_op0 = int(reg_op0, 2) elif reg_op1 is None and '', '') reg_op1 = int(reg_op1, 2) elif reg_CRn is None and '', '') reg_CRn = int(reg_CRn, 2) elif reg_CRm is None and '', '') reg_CRm = int(reg_CRm, 2) elif reg_op2 is None and '', '') reg_op2 = int(reg_op2, 2) except: pass spec = (reg_op0, reg_op1, reg_CRn, reg_CRm, reg_op2) if not reg_name: continue # sysindex, regindex elif '' in reg_name: # We have a set! One of the spec components is a range, like # '0b110:n[3]' or 'n[2:0]'. assert(any(map(lambda x: type(x) == str, spec))) # Find the bit width. max_bit = -1 for s in spec: if type(s) == str: # 0 = 0b(110):n[0] 1 = n[(3)] 2 = n[3:(0)] 3 = n[3]:0b(110) m = re.match(r'^(?:0b([01]+):)?n\[([0-9])(?::([0-9]))?\](?::0b([01]+))?$', s) max_bit = max(int(m.groups()[1]), max_bit) assert(max_bit >= 0) # Iterate each n value. for n in range(2 ** (max_bit + 1)): # Generate the new spec. specN = [] for s in spec: if type(s) == str: # 0 = 0b(110):n[0] 1 = n[(3)] 2 = n[3:(0)] 3 = n[3]:0b(110) m = re.match(r'^(?:0b([01]+):)?n\[([0-9])(?::([0-9]))?\](?::0b([01]+))?$', s) g = list(map(lambda x: x if x else '', m.groups())) bi_max = int(g[1]) bi_min = int(g[2] if g[2] else bi_max) n_str = '{:08b}'.format(n)[8-bi_max-1:8-bi_min] val = '0b' + g[0] + n_str + g[3] specN.append(int(val, 2)) else: specN.append(s) # Output the reg. output_reg(reg_name.replace('', str(n)), reg_description.replace('Registers', 'Register') + ' {}'.format(n), tuple(specN)) elif any(map(lambda x: type(x) == str, spec)): # These are AArch64-s1_op1_cn_cm_op2.xml and AArch64-s3_op1_cn_cm_op2.xml. pass elif any(map(lambda x: x is None, spec)): # This is AArch64-sp_el3.xml. pass else: output_reg(reg_name, reg_description, spec)