Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bazad/72a4d6b1b57047f9ac4842898ba2182c to your computer and use it in GitHub Desktop.
Save bazad/72a4d6b1b57047f9ac4842898ba2182c to your computer and use it in GitHub Desktop.
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('<reg_short_name>', '')
line = line.replace('</reg_short_name>', '')
reg_name = html.unescape(line)
elif 'reg_long_name' in line:
line = line.replace('<reg_long_name>', '')
line = line.replace('</reg_long_name>', '')
reg_description = html.unescape(line)
elif reg_op0 is None and '<enc n="op0" v="' in line:
line = line.replace('<enc n="op0" v="', '')
reg_op0 = line.replace('"/>', '')
reg_op0 = int(reg_op0, 2)
elif reg_op1 is None and '<enc n="op1" v="' in line:
line = line.replace('<enc n="op1" v="', '')
reg_op1 = line.replace('"/>', '')
reg_op1 = int(reg_op1, 2)
elif reg_CRn is None and '<enc n="CRn" v="' in line:
line = line.replace('<enc n="CRn" v="', '')
reg_CRn = line.replace('"/>', '')
reg_CRn = int(reg_CRn, 2)
elif reg_CRm is None and '<enc n="CRm" v="' in line:
line = line.replace('<enc n="CRm" v="', '')
reg_CRm = line.replace('"/>', '')
reg_CRm = int(reg_CRm, 2)
elif reg_op2 is None and '<enc n="op2" v="' in line:
line = line.replace('<enc n="op2" v="', '')
reg_op2 = line.replace('"/>', '')
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 '<n>' 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('<n>', 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)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment