aboutsummaryrefslogtreecommitdiffstats
path: root/capstone/suite/synctools/instrinfo-arch.py
blob: fed572eaa7e8f65f883fc9c5b00a361465183e98 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#!/usr/bin/python
# convert LLVM GenInstrInfo.inc for Capstone disassembler.
# by Nguyen Anh Quynh, 2019

import sys

if len(sys.argv) == 1:
    print("Syntax: %s <GenInstrInfo.inc> <arch>" %sys.argv[0])
    sys.exit(1)


# lib/Target/X86/X86GenAsmMatcher.inc
# static const MatchEntry MatchTable1[] = {
#  { 0 /* aaa */, X86::AAA, Convert_NoOperands, Feature_Not64BitMode, {  }, },

# return (arch, mnem)
def extract_insn(line):
    tmp = line.split(',')
    insn_raw = tmp[1].strip()
    insn_mnem = tmp[0].split(' ')[3]
    # X86 mov.s
    if '.' in insn_mnem:
        tmp = insn_mnem.split('.')
        insn_mnem = tmp[0]
    tmp = insn_raw.split('::')
    arch = tmp[0]
    # AArch64 -> ARM64
    if arch.upper() == 'AArch64':
        arch = 'ARM64'
    return (arch, insn_mnem)

# get (arch, first insn) from MatchTable
def get_first_insn(filename):
    f = open(filename)
    lines = f.readlines()
    f.close()
    count = 0
    for line in lines:
        line = line.strip()
    
        if len(line) == 0:
            continue
    
        # Intel syntax in Table1
        if 'MatchEntry MatchTable1[] = {' in line:
            count += 1
            #print(line.strip())
            continue
    
        if count == 1:
            arch, mnem = extract_insn(line)
            return (arch, mnem)

    return (None, None)


#arch, first_insn = get_first_insn(sys.argv[2])
#first_insn = first_insn.upper()
#print(arch, first_insn)

arch = sys.argv[2].upper()

if arch.upper() == 'AARCH64':
    arch = 'AArch64'
elif arch.upper() == 'ARM64':
    arch = 'AArch64'

print("""
/* Capstone Disassembly Engine, http://www.capstone-engine.org */
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2019 */

/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
|*                                                                            *|
|* Target Instruction Enum Values and Descriptors                             *|
|*                                                                            *|
|* Automatically generated file, do not edit!                                 *|
|*                                                                            *|
\*===----------------------------------------------------------------------===*/

#ifdef GET_INSTRINFO_ENUM
#undef GET_INSTRINFO_ENUM
""")

enum_count = 0

f = open(sys.argv[1])
lines = f.readlines()
f.close()

# 1st enum is register enum
for line in lines:
    line = line.rstrip()

    if len(line.strip()) == 0:
        continue

    if line.strip() == 'enum {':
        enum_count += 1
        print(line.strip())
        continue

    line = line.strip()
    if enum_count == 1:
        if line == '};':
            # done with first enum
            break
        else:
            # skip pseudo instructions
            if '__' in line or 'setjmp' in line or 'longjmp' in line or 'Pseudo' in line:
                pass
            else:
                print("\t%s_%s" %(arch, line))

print('};\n')

print("#endif // GET_INSTRINFO_ENUM")

if arch == 'ARM64':
    sys.exit(0)

print("")
print("#ifdef GET_INSTRINFO_MC_DESC")
print("#undef GET_INSTRINFO_MC_DESC")
print("")
print("#define nullptr 0")
print("")

in_insts = False

for line in lines:
    if line.strip() == '':
        continue

    line = line.rstrip()

    if 'static const MCOperandInfo ' in line:
        line2 = line.replace('::', '_')
        print(line2)

    elif 'Insts[] = {' in line:
        # extern const MCInstrDesc ARMInsts[] = {
        line2 = line.replace('extern const ', 'static const ')
        print("")
        print(line2)
        in_insts = True

    elif in_insts:
        if line == '};':
            print(line)
            break
        # { 0,  1,  1,  0,  0,  0|(1ULL<<MCID::Pseudo)|(1ULL<<MCID::Variadic), 0x0ULL, nullptr, nullptr, OperandInfo2, -1 ,nullptr },  // Inst #0 = PHI
        # take 2nd & 10th entries 
        tmp = line.split(',')
        print("  { %s, %s }," %(tmp[1].strip(), tmp[9].strip()))


print("")
print("#endif // GET_INSTRINFO_MC_DESC")

#static const MCInstrDesc ARMInsts[] = {
#static MCOperandInfo OperandInfo2[] = { { -1, 0, MCOI_OPERAND_IMMEDIATE, 0 }, };