Generating output for system register declarations in the dyn_regs header
[dyninst.git] / instructionAPI / aarch64_sysreg_builder.py
1 import os
2 from os import path
3 from xml.dom.minidom import parse
4 import xml.dom.minidom
5 from collections import OrderedDict
6
7 sys_reg_dir = "/p/paradyn/arm/arm-download-1350222/AR100-DA-70000-r0p0-00rel10/AR100-DA-70000-r0p0-00rel10/SysReg_xml/ARMv8-SysReg-00bet12/SysReg_xml-00bet12"
8 reg_names = list()
9 reg_encodings = OrderedDict()
10 reg_sizes = dict()
11
12 reg_names = [f.split('.')[0].split("AArch64-")[1] for f in os.listdir(sys_reg_dir) if (path.isfile(sys_reg_dir + os.sep + f) and f.find("AArch64") != -1)]
13
14 for name in reg_names:
15     DOMTree = xml.dom.minidom.parse(sys_reg_dir + "/AArch64-" + name + ".xml")
16     collection = DOMTree.documentElement
17
18     encodings = collection.getElementsByTagName("encoding_param")
19     encoding_dict = OrderedDict()
20
21     for encoding in encodings:
22         encoding_fieldname = encoding.getElementsByTagName("encoding_fieldname")[0].childNodes[0].data
23         encoding_fieldvalue = encoding.getElementsByTagName("encoding_fieldvalue")[0].childNodes[0].data
24
25         encoding_dict[encoding_fieldname] = encoding_fieldvalue
26
27     encoding_val = list()
28     for encoding_fieldname in encoding_dict:
29         encoding_fieldvalue =  encoding_dict[encoding_fieldname]
30         for c in encoding_fieldvalue:
31             encoding_val.append(c)
32
33     attributes = collection.getElementsByTagName("reg_attributes")
34     for attr in attributes:
35         para = attr.getElementsByTagName("para")[0].childNodes[0].data
36     if(para.find("-bit") != -1 and para.find("is a ") != -1):
37         size = para.split("-bit")[0].split("is a ")[1]
38     
39     try: 
40         reg_encodings[name] = hex(int(''.join(str(i) for i in encoding_val), 2))
41         reg_sizes[name] = size
42     except:
43         encoding_str = ''.join(encoding_val)
44         if len(encoding_str) < 1 or encoding_str.find("n") == -1:
45             print(name)
46             continue
47
48         replace_parts = encoding_str.split("n", 1)[1].split('>')
49         replace_list = list()
50         
51         for part in replace_parts:
52             if len(part) > 0 and part.find('<') != -1:
53                 bit_positions = part.split('<')[1].split(':')
54                 
55                 if len(bit_positions) == 2:
56                     start_pos = int(bit_positions[1])
57                     end_pos = int(bit_positions[0])
58                 else:
59                     start_pos = end_pos = int(bit_positions[0])
60                 encoding_str = encoding_str.replace(part + ">", ''.join(['0'] * (end_pos - start_pos + 1)))
61                 
62                 for pos in range(start_pos, end_pos+1):
63                     replace_list.append(pos)
64         
65         encoding_str = encoding_str.replace(':', '').replace('n', '')
66         replace_list = sorted(replace_list, reverse=True)  
67         
68         max_val = 2**len(replace_list)
69         for idx in range(0, max_val):
70             bin_arr = "{0:b}".format(idx).split()
71             cur_encoding = encoding_str
72
73             format_args = '%0' + str(len(replace_list)) + 'd'
74             bin_arr = str(format_args % int(''.join(bin_arr)))
75             
76             for val in replace_list:
77                 cur_encoding = cur_encoding[:(len(encoding_str) - 1 - int(val))] + bin_arr[len(replace_list) - 1 - int(val)] + cur_encoding[(len(encoding_str) - int(val)):]
78             #print(hex(int(cur_encoding, 2)))
79             reg_encodings[name.replace("n_", str(idx) + "_")] = hex(int(cur_encoding, 2))
80             reg_sizes[name.replace("n_", str(idx) + "_")] = size
81
82 for elem in reg_encodings:
83     print("sysRegMap[" + reg_encodings[elem] + "] = aarch64::" + elem + ";");
84
85 print()
86 ct = 0
87 for elem in reg_encodings:
88     size_str = ""
89     if reg_sizes[elem] == "32":
90         size_str = "D_REG"
91     else:
92         size_str = "FULL"
93     print("DEF_REGISTER(" + elem + ",\t\t" + str(ct) + " | " + size_str + " |SYSREG | Arch_aarch64, \"aarch64\");");
94     ct += 1