1#!/usr/bin/python 2# convert LLVM GenRegisterInfo.inc for Capstone disassembler. 3# by Nguyen Anh Quynh, 2019 4 5import sys 6 7if len(sys.argv) == 1: 8 print("Syntax: %s <GenRegisterInfo.inc> <architecture>" %sys.argv[0]) 9 sys.exit(1) 10 11f = open(sys.argv[1]) 12lines = f.readlines() 13f.close() 14 15arch = sys.argv[2] 16 17print(""" 18/* Capstone Disassembly Engine, http://www.capstone-engine.org */ 19/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2019 */ 20 21/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\\ 22|* *| 23|* Target Register Enum Values *| 24|* *| 25|* Automatically generated file, do not edit! *| 26|* *| 27\*===----------------------------------------------------------------------===*/ 28 29#ifdef GET_REGINFO_ENUM 30#undef GET_REGINFO_ENUM 31""") 32 33enum_count = 0 34 35# 1st enum is register enum 36for line in lines: 37 line = line.rstrip() 38 39 if len(line.strip()) == 0: 40 continue 41 42 if line.strip() == 'enum {': 43 enum_count += 1 44 print(line) 45 continue 46 47 if enum_count == 1: 48 if line.strip() == '};': 49 print(line) 50 # done with first enum 51 break 52 else: 53 # enum items 54 print(" %s_%s" %(arch, line.strip())) 55 56# 2nd enum is register class 57enum_count = 0 58print("\n// Register classes") 59for line in lines: 60 line = line.rstrip() 61 62 if len(line.strip()) == 0: 63 continue 64 65 if line.strip() == 'enum {': 66 enum_count += 1 67 if enum_count == 2: 68 print(line) 69 continue 70 71 if enum_count == 2: 72 if line.strip() == '};': 73 # done with 2nd enum 74 print(line.strip()) 75 break 76 else: 77 # enum items 78 print(" %s_%s" %(arch, line.strip())) 79 80if arch.upper() == 'ARM': 81 # 3rd enum is Subregister indices 82 enum_count = 0 83 print("\n// Subregister indices") 84 for line in lines: 85 line = line.rstrip() 86 87 if len(line.strip()) == 0: 88 continue 89 90 if line.strip() == 'enum {': 91 enum_count += 1 92 if enum_count == 3: 93 print(line) 94 continue 95 96 if enum_count == 3: 97 if line.strip() == '};': 98 # done with 2nd enum 99 print(line.strip()) 100 break 101 else: 102 # enum items 103 print(" %s_%s" %(arch, line.strip())) 104 105if arch.upper() == 'AARCH64': 106 # 3rd enum is Register alternate name indices 107 enum_count = 0 108 print("\n// Register alternate name indices") 109 for line in lines: 110 line = line.rstrip() 111 112 if len(line.strip()) == 0: 113 continue 114 115 if line.strip() == 'enum {': 116 enum_count += 1 117 if enum_count == 3: 118 print(line) 119 continue 120 121 if enum_count == 3: 122 if line.strip() == '};': 123 # done with 2nd enum 124 print(line.strip()) 125 break 126 else: 127 # enum items 128 print(" %s_%s" %(arch, line.strip())) 129 130 # 4th enum is Subregister indices 131 enum_count = 0 132 print("\n// Subregister indices") 133 for line in lines: 134 line = line.rstrip() 135 136 if len(line.strip()) == 0: 137 continue 138 139 if line.strip() == 'enum {': 140 enum_count += 1 141 if enum_count == 4: 142 print(line) 143 continue 144 145 if enum_count == 4: 146 if line.strip() == '};': 147 # done with 2nd enum 148 print(line.strip()) 149 break 150 else: 151 # enum items 152 print(" %s_%s" %(arch, line.strip())) 153 154# end of enum 155print("") 156print("#endif // GET_REGINFO_ENUM") 157 158print(""" 159#ifdef GET_REGINFO_MC_DESC 160#undef GET_REGINFO_MC_DESC 161 162""") 163 164# extract RegDiffLists 165finding_struct = True 166for line in lines: 167 line = line.rstrip() 168 169 if len(line.strip()) == 0: 170 continue 171 172 if arch + 'RegDiffLists' in line: 173 finding_struct = False 174 print("static const MCPhysReg " + arch + "RegDiffLists[] = {") 175 continue 176 177 if finding_struct: 178 continue 179 else: 180 print(line) 181 if line == '};': 182 # done with this struct 183 print("") 184 break 185 186# extract SubRegIdxLists 187finding_struct = True 188for line in lines: 189 line = line.rstrip() 190 191 if len(line.strip()) == 0: 192 continue 193 194 if arch + 'SubRegIdxLists' in line: 195 finding_struct = False 196 print("static const uint16_t " + arch + "SubRegIdxLists[] = {") 197 continue 198 199 if finding_struct: 200 continue 201 else: 202 print(line) 203 if line == '};': 204 # done with this struct 205 print("") 206 break 207 208# extract RegDesc 209finding_struct = True 210for line in lines: 211 line = line.rstrip() 212 213 if len(line.strip()) == 0: 214 continue 215 216 if arch + 'RegDesc' in line: 217 finding_struct = False 218 print("static const MCRegisterDesc " + arch + "RegDesc[] = {") 219 continue 220 221 if finding_struct: 222 continue 223 else: 224 print(line) 225 if line == '};': 226 # done with this struct 227 print("") 228 break 229 230# extract register classes 231finding_struct = True 232for line in lines: 233 line = line.rstrip() 234 235 if len(line.strip()) == 0: 236 continue 237 238 if 'Register classes' in line and 'namespace' in line: 239 finding_struct = False 240 continue 241 242 if finding_struct: 243 continue 244 else: 245 if 'const' in line: 246 line2 = line.replace('const', 'static const') 247 print(line2) 248 elif '::' in line: 249 line2 = line.replace('::', '_') 250 print(line2) 251 elif 'end anonymous namespace' in line: 252 # done with this struct 253 break 254 else: 255 print(line) 256 257print("\n") 258 259# extract MCRegisterClasses 260finding_struct = True 261for line in lines: 262 line = line.rstrip() 263 264 if len(line.strip()) == 0: 265 continue 266 267 if 'MCRegisterClass ' + arch + 'MCRegisterClasses[] = {' in line: 268 finding_struct = False 269 print("static const MCRegisterClass " + arch + "MCRegisterClasses[] = {") 270 continue 271 272 if finding_struct: 273 continue 274 else: 275 if line == '};': 276 # done with this struct 277 print('};\n') 278 break 279 elif '::' in line: 280 line = line.replace('::', '_') 281 282 # { GR8, GR8Bits, 130, 20, sizeof(GR8Bits), X86_GR8RegClassID, 1, 1, 1, 1 }, 283 tmp = line.split(',') 284 print(" %s, %s, %s }," %(tmp[0].strip(), tmp[1].strip(), tmp[4].strip())) 285 286print("#endif // GET_REGINFO_MC_DESC") 287