1#!/usr/bin/python
2# convert LLVM GenInstrInfo.inc for Capstone disassembler.
3# by Nguyen Anh Quynh, 2019
4
5import sys
6
7if len(sys.argv) == 1:
8    print("Syntax: %s <GenInstrInfo.inc> <AsmMatcher.info>" %sys.argv[0])
9    sys.exit(1)
10
11
12# lib/Target/X86/X86GenAsmMatcher.inc
13# static const MatchEntry MatchTable1[] = {
14#  { 0 /* aaa */, X86::AAA, Convert_NoOperands, Feature_Not64BitMode, {  }, },
15
16# return (arch, mnem)
17def extract_insn(line):
18    tmp = line.split(',')
19    insn_raw = tmp[1].strip()
20    insn_mnem = tmp[0].split(' ')[3]
21    # X86 mov.s
22    if '.' in insn_mnem:
23        tmp = insn_mnem.split('.')
24        insn_mnem = tmp[0]
25    tmp = insn_raw.split('::')
26    arch = tmp[0]
27    # AArch64 -> ARM64
28    if arch.upper() == 'AArch64':
29        arch = 'ARM64'
30    return (arch, insn_mnem)
31
32# get (arch, first insn) from MatchTable
33def get_first_insn(filename):
34    f = open(filename)
35    lines = f.readlines()
36    f.close()
37    count = 0
38    for line in lines:
39        line = line.strip()
40
41        if len(line) == 0:
42            continue
43
44        # Intel syntax in Table1
45        if 'MatchEntry MatchTable1[] = {' in line:
46            count += 1
47            #print(line.strip())
48            continue
49
50        if count == 1:
51            arch, mnem = extract_insn(line)
52            return (arch, mnem)
53
54    return (None, None)
55
56
57arch, first_insn = get_first_insn(sys.argv[2])
58first_insn = first_insn.upper()
59arch = arch.upper()
60#print(arch, first_insn)
61
62print("""
63/* Capstone Disassembly Engine, http://www.capstone-engine.org */
64/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2019 */
65
66/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
67|*                                                                            *|
68|* Target Instruction Enum Values and Descriptors                             *|
69|*                                                                            *|
70|* Automatically generated file, do not edit!                                 *|
71|*                                                                            *|
72\*===----------------------------------------------------------------------===*/
73
74#ifdef GET_INSTRINFO_ENUM
75#undef GET_INSTRINFO_ENUM
76""")
77
78enum_count = 0
79meet_insn = False
80
81f = open(sys.argv[1])
82lines = f.readlines()
83f.close()
84
85# 1st enum is register enum
86for line in lines:
87    line = line.rstrip()
88
89    if len(line.strip()) == 0:
90        continue
91
92    if line.strip() == 'enum {':
93        enum_count += 1
94        print(line.strip())
95        continue
96
97    line = line.strip()
98    if enum_count == 1:
99        if line == '};':
100            # done with first enum
101            break
102        else:
103            insn = None
104            if meet_insn:
105                # enum items
106                insn = line
107            elif line.startswith(first_insn):
108                insn = line
109                meet_insn = True
110            if insn:
111                print("\t%s_%s" %(arch, line))
112
113print('};\n')
114
115print("#endif // GET_INSTRINFO_ENUM")
116