]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/udis86/lib/contrib/libudis86/itab.py
update
[l4.git] / l4 / pkg / udis86 / lib / contrib / libudis86 / itab.py
1 # udis86 - scripts/itab.py
2
3 # Copyright (c) 2009 Vivek Thampi
4 # All rights reserved.
5
6 # Redistribution and use in source and binary forms, with or without modification, 
7 # are permitted provided that the following conditions are met:
8
9 #     * Redistributions of source code must retain the above copyright notice, 
10 #       this list of conditions and the following disclaimer.
11 #     * Redistributions in binary form must reproduce the above copyright notice, 
12 #       this list of conditions and the following disclaimer in the documentation 
13 #       and/or other materials provided with the distribution.
14
15 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
16 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
17 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
18 # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 
19 # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
20 # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
21 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 
22 # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
23 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
24 # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
26 import sys
27
28 sys.path.append( '../scripts' );
29
30 import ud_optable
31 import ud_opcode
32
33 class UdItabGenerator( ud_opcode.UdOpcodeTables ):
34
35     OperandDict = {
36         "Ap"       : [    "OP_A"        , "SZ_P"     ],
37         "E"        : [    "OP_E"        , "SZ_NA"    ],
38         "Eb"       : [    "OP_E"        , "SZ_B"     ],
39         "Ew"       : [    "OP_E"        , "SZ_W"     ],
40         "Ev"       : [    "OP_E"        , "SZ_V"     ],
41         "Ed"       : [    "OP_E"        , "SZ_D"     ],
42         "Eq"       : [    "OP_E"        , "SZ_Q"     ],
43         "Ez"       : [    "OP_E"        , "SZ_Z"     ],
44         "Ex"       : [    "OP_E"        , "SZ_MDQ"   ],
45         "Ep"       : [    "OP_E"        , "SZ_P"     ],
46         "G"        : [    "OP_G"        , "SZ_NA"    ],
47         "Gb"       : [    "OP_G"        , "SZ_B"     ],
48         "Gw"       : [    "OP_G"        , "SZ_W"     ],
49         "Gv"       : [    "OP_G"        , "SZ_V"     ],
50         "Gvw"      : [    "OP_G"        , "SZ_MDQ"   ],
51         "Gd"       : [    "OP_G"        , "SZ_D"     ],
52         "Gq"       : [    "OP_G"        , "SZ_Q"     ],
53         "Gx"       : [    "OP_G"        , "SZ_MDQ"   ],
54         "Gz"       : [    "OP_G"        , "SZ_Z"     ],
55         "M"        : [    "OP_M"        , "SZ_NA"    ],
56         "Mb"       : [    "OP_M"        , "SZ_B"     ],
57         "Mw"       : [    "OP_M"        , "SZ_W"     ],
58         "Ms"       : [    "OP_M"        , "SZ_W"     ],
59         "Md"       : [    "OP_M"        , "SZ_D"     ],
60         "Mq"       : [    "OP_M"        , "SZ_Q"     ],
61         "Mt"       : [    "OP_M"        , "SZ_T"     ],
62         "Mo"       : [    "OP_M"        , "SZ_O"     ],
63         "MwRv"     : [    "OP_MR"       , "SZ_WV"    ],
64         "MbRv"     : [    "OP_MR"       , "SZ_BV"    ],
65         "I1"       : [    "OP_I1"       , "SZ_NA"    ],
66         "I3"       : [    "OP_I3"       , "SZ_NA"    ],
67         "Ib"       : [    "OP_I"        , "SZ_B"     ],
68         "Isb"      : [    "OP_I"        , "SZ_SB"    ],
69         "Iw"       : [    "OP_I"        , "SZ_W"     ],
70         "Iv"       : [    "OP_I"        , "SZ_V"     ],
71         "Iz"       : [    "OP_I"        , "SZ_Z"     ],
72         "Jv"       : [    "OP_J"        , "SZ_V"     ],
73         "Jz"       : [    "OP_J"        , "SZ_Z"     ],
74         "Jb"       : [    "OP_J"        , "SZ_B"     ],
75         "R"        : [    "OP_R"        , "SZ_RDQ"   ], 
76         "C"        : [    "OP_C"        , "SZ_NA"    ],
77         "D"        : [    "OP_D"        , "SZ_NA"    ],
78         "S"        : [    "OP_S"        , "SZ_NA"    ],
79         "Ob"       : [    "OP_O"        , "SZ_B"     ],
80         "Ow"       : [    "OP_O"        , "SZ_W"     ],
81         "Ov"       : [    "OP_O"        , "SZ_V"     ],
82         "V"        : [    "OP_V"        , "SZ_O"     ],
83         "W"        : [    "OP_W"        , "SZ_O"     ],
84         "P"        : [    "OP_P"        , "SZ_Q"     ],
85         "Q"        : [    "OP_Q"        , "SZ_Q"     ],
86         "VR"       : [    "OP_VR"       , "SZ_O"     ],
87         "PR"       : [    "OP_PR"       , "SZ_Q"     ],
88         "AL"       : [    "OP_AL"       , "SZ_NA"    ],
89         "CL"       : [    "OP_CL"       , "SZ_NA"    ],
90         "DL"       : [    "OP_DL"       , "SZ_NA"    ],
91         "BL"       : [    "OP_BL"       , "SZ_NA"    ],
92         "AH"       : [    "OP_AH"       , "SZ_NA"    ],
93         "CH"       : [    "OP_CH"       , "SZ_NA"    ],
94         "DH"       : [    "OP_DH"       , "SZ_NA"    ],
95         "BH"       : [    "OP_BH"       , "SZ_NA"    ],
96         "AX"       : [    "OP_AX"       , "SZ_NA"    ],
97         "CX"       : [    "OP_CX"       , "SZ_NA"    ],
98         "DX"       : [    "OP_DX"       , "SZ_NA"    ],
99         "BX"       : [    "OP_BX"       , "SZ_NA"    ],
100         "SI"       : [    "OP_SI"       , "SZ_NA"    ],
101         "DI"       : [    "OP_DI"       , "SZ_NA"    ],
102         "SP"       : [    "OP_SP"       , "SZ_NA"    ],
103         "BP"       : [    "OP_BP"       , "SZ_NA"    ],
104         "eAX"      : [    "OP_eAX"      , "SZ_NA"    ],
105         "eCX"      : [    "OP_eCX"      , "SZ_NA"    ],
106         "eDX"      : [    "OP_eDX"      , "SZ_NA"    ],
107         "eBX"      : [    "OP_eBX"      , "SZ_NA"    ],
108         "eSI"      : [    "OP_eSI"      , "SZ_NA"    ],
109         "eDI"      : [    "OP_eDI"      , "SZ_NA"    ],
110         "eSP"      : [    "OP_eSP"      , "SZ_NA"    ],
111         "eBP"      : [    "OP_eBP"      , "SZ_NA"    ],
112         "rAX"      : [    "OP_rAX"      , "SZ_NA"    ],
113         "rCX"      : [    "OP_rCX"      , "SZ_NA"    ],
114         "rBX"      : [    "OP_rBX"      , "SZ_NA"    ],
115         "rDX"      : [    "OP_rDX"      , "SZ_NA"    ],
116         "rSI"      : [    "OP_rSI"      , "SZ_NA"    ],
117         "rDI"      : [    "OP_rDI"      , "SZ_NA"    ],
118         "rSP"      : [    "OP_rSP"      , "SZ_NA"    ],
119         "rBP"      : [    "OP_rBP"      , "SZ_NA"    ],
120         "ES"       : [    "OP_ES"       , "SZ_NA"    ],
121         "CS"       : [    "OP_CS"       , "SZ_NA"    ],
122         "DS"       : [    "OP_DS"       , "SZ_NA"    ],
123         "SS"       : [    "OP_SS"       , "SZ_NA"    ],
124         "GS"       : [    "OP_GS"       , "SZ_NA"    ],
125         "FS"       : [    "OP_FS"       , "SZ_NA"    ],
126         "ST0"      : [    "OP_ST0"      , "SZ_NA"    ],
127         "ST1"      : [    "OP_ST1"      , "SZ_NA"    ],
128         "ST2"      : [    "OP_ST2"      , "SZ_NA"    ],
129         "ST3"      : [    "OP_ST3"      , "SZ_NA"    ],
130         "ST4"      : [    "OP_ST4"      , "SZ_NA"    ],
131         "ST5"      : [    "OP_ST5"      , "SZ_NA"    ],
132         "ST6"      : [    "OP_ST6"      , "SZ_NA"    ],
133         "ST7"      : [    "OP_ST7"      , "SZ_NA"    ],
134         "NONE"     : [    "OP_NONE"     , "SZ_NA"    ],
135         "ALr8b"    : [    "OP_ALr8b"    , "SZ_NA"    ],
136         "CLr9b"    : [    "OP_CLr9b"    , "SZ_NA"    ],
137         "DLr10b"   : [    "OP_DLr10b"   , "SZ_NA"    ],
138         "BLr11b"   : [    "OP_BLr11b"   , "SZ_NA"    ],
139         "AHr12b"   : [    "OP_AHr12b"   , "SZ_NA"    ],
140         "CHr13b"   : [    "OP_CHr13b"   , "SZ_NA"    ],
141         "DHr14b"   : [    "OP_DHr14b"   , "SZ_NA"    ],
142         "BHr15b"   : [    "OP_BHr15b"   , "SZ_NA"    ],
143         "rAXr8"    : [    "OP_rAXr8"    , "SZ_NA"    ],
144         "rCXr9"    : [    "OP_rCXr9"    , "SZ_NA"    ],
145         "rDXr10"   : [    "OP_rDXr10"   , "SZ_NA"    ],
146         "rBXr11"   : [    "OP_rBXr11"   , "SZ_NA"    ],
147         "rSPr12"   : [    "OP_rSPr12"   , "SZ_NA"    ],
148         "rBPr13"   : [    "OP_rBPr13"   , "SZ_NA"    ],
149         "rSIr14"   : [    "OP_rSIr14"   , "SZ_NA"    ],
150         "rDIr15"   : [    "OP_rDIr15"   , "SZ_NA"    ],
151         "jWP"      : [    "OP_J"        , "SZ_WP"    ],
152         "jDP"      : [    "OP_J"        , "SZ_DP"    ],
153
154     }
155
156     #
157     # opcode prefix dictionary
158     # 
159     PrefixDict = { 
160         "aso"      : "P_aso",   
161         "oso"      : "P_oso",   
162         "rexw"     : "P_rexw", 
163         "rexb"     : "P_rexb",  
164         "rexx"     : "P_rexx",  
165         "rexr"     : "P_rexr",
166         "seg"      : "P_seg",
167         "inv64"    : "P_inv64", 
168         "def64"    : "P_def64", 
169         "depM"     : "P_depM",
170         "cast1"    : "P_c1",    
171         "cast2"    : "P_c2",    
172         "cast3"    : "P_c3",
173         "cast"     : "P_cast",
174         "sext"     : "P_sext"
175     }
176
177     InvalidEntryIdx = 0 
178     InvalidEntry = { 'type'     : 'invalid', 
179                      'mnemonic' : 'invalid', 
180                      'operands' : '', 
181                      'prefixes' : '',
182                      'meta'     : '' }
183
184     Itab     = []   # instruction table
185     ItabIdx  = 1    # instruction table index
186     GtabIdx  = 0    # group table index
187     GtabMeta = []
188
189     ItabLookup = {}
190
191     MnemonicAliases = ( "invalid", "3dnow", "none", "db", "pause" )
192     
193     def __init__( self ):
194         # first itab entry (0) is Invalid
195         self.Itab.append( self.InvalidEntry )
196         self.MnemonicsTable.extend( self.MnemonicAliases )
197
198     def toGroupId( self, id ):
199         return 0x8000 | id
200
201     def genLookupTable( self, table, scope = '' ):
202         idxArray = [ ]
203         ( tabIdx, self.GtabIdx ) = ( self.GtabIdx, self.GtabIdx + 1 )
204         self.GtabMeta.append( { 'type' : table[ 'type' ], 'meta' : table[ 'meta' ] } )
205
206         for _idx in range( self.sizeOfTable( table[ 'type' ] ) ):
207             idx = "%02x" % _idx 
208
209             e   = self.InvalidEntry
210             i   = self.InvalidEntryIdx
211
212             if idx in table[ 'entries' ].keys():
213                 e = table[ 'entries' ][ idx ]
214
215             # leaf node (insn)
216             if e[ 'type' ] == 'insn':
217                 ( i, self.ItabIdx ) = ( self.ItabIdx, self.ItabIdx + 1 )
218                 self.Itab.append( e )
219             elif e[ 'type' ] != 'invalid':
220                 i = self.genLookupTable( e, 'static' )
221
222             idxArray.append( i )
223
224         name = "ud_itab__%s" % tabIdx
225         self.ItabLookup[ tabIdx ] = name
226
227         self.ItabC.write( "\n" );
228         if len( scope ):
229             self.ItabC.write( scope + ' ' )
230         self.ItabC.write( "const uint16_t %s[] = {\n" % name )
231         for i in range( len( idxArray ) ):
232             if i > 0 and i % 4 == 0: 
233                 self.ItabC.write( "\n" )
234             if ( i%4 == 0 ):
235                 self.ItabC.write( "  /* %2x */" % i)
236             self.ItabC.write( "%12d," % ( idxArray[ i ] ))
237         self.ItabC.write( "\n" )
238         self.ItabC.write( "};\n" )
239
240         return self.toGroupId( tabIdx )
241
242     def genLookupTableList( self ):
243         self.ItabC.write( "\n\n"  );
244         self.ItabC.write( "struct ud_lookup_table_list_entry ud_lookup_table_list[] = {\n" )
245         for i in range( len( self.GtabMeta ) ):
246             f0 = self.ItabLookup[ i ] + ","
247             f1 = ( self.nameOfTable( self.GtabMeta[ i ][ 'type' ] ) ) + ","
248             f2 = "\"%s\"" % self.GtabMeta[ i ][ 'meta' ]
249             self.ItabC.write( "    /* %03d */ { %s %s %s },\n" % ( i, f0, f1, f2 ) )
250         self.ItabC.write( "};" )
251
252     def genInsnTable( self ):
253         self.ItabC.write( "struct ud_itab_entry ud_itab[] = {\n" );
254         idx = 0
255         for e in self.Itab:
256             opr_c = [ "O_NONE", "O_NONE", "O_NONE" ]
257             pfx_c = []
258             opr   = e[ 'operands' ]
259             for i in range(len(opr)): 
260                 if not (opr[i] in self.OperandDict.keys()):
261                     print "error: invalid operand declaration: %s\n" % opr[i]
262                 opr_c[i] = "O_" + opr[i]
263             opr = "%s %s %s" % (opr_c[0] + ",", opr_c[1] + ",", opr_c[2])
264
265             for p in e['prefixes']:
266                 if not ( p in self.PrefixDict.keys() ):
267                     print "error: invalid prefix specification: %s \n" % pfx
268                 pfx_c.append( self.PrefixDict[p] )
269             if len(e['prefixes']) == 0:
270                 pfx_c.append( "P_none" )
271             pfx = "|".join( pfx_c )
272
273             self.ItabC.write( "  /* %04d */ { UD_I%s %s, %s },\n" \
274                         % ( idx, e[ 'mnemonic' ] + ',', opr, pfx ) )
275             idx += 1
276         self.ItabC.write( "};\n" )
277
278         self.ItabC.write( "\n\n"  );
279         self.ItabC.write( "const char * ud_mnemonics_str[] = {\n" )
280         self.ItabC.write( ",\n    ".join( [ "\"%s\"" % m for m in self.MnemonicsTable ] ) )
281         self.ItabC.write( "\n};\n" )
282  
283
284     def genItabH( self ):
285         self.ItabH = open( "itab.h", "w" )
286
287         # Generate Table Type Enumeration
288         self.ItabH.write( "#ifndef UD_ITAB_H\n" )
289         self.ItabH.write( "#define UD_ITAB_H\n\n" )
290
291         # table type enumeration
292         self.ItabH.write( "/* ud_table_type -- lookup table types (see lookup.c) */\n" )
293         self.ItabH.write( "enum ud_table_type {\n    " )
294         enum = [ self.TableInfo[ k ][ 'name' ] for k in self.TableInfo.keys() ]
295         self.ItabH.write( ",\n    ".join( enum ) )
296         self.ItabH.write( "\n};\n\n" );
297
298         # mnemonic enumeration
299         self.ItabH.write( "/* ud_mnemonic -- mnemonic constants */\n" )
300         enum  = "enum ud_mnemonic_code {\n    "
301         enum += ",\n    ".join( [ "UD_I%s" % m for m in self.MnemonicsTable ] )
302         enum += "\n} UD_ATTR_PACKED;\n"
303         self.ItabH.write( enum )
304         self.ItabH.write( "\n" )
305
306         self.ItabH.write("\n/* itab entry operand definitions */\n");
307         operands = self.OperandDict.keys()
308         operands.sort()
309         for o in operands:
310             self.ItabH.write("#define O_%-7s { %-12s %-8s }\n" %
311                     (o, self.OperandDict[o][0] + ",", self.OperandDict[o][1]));
312         self.ItabH.write("\n\n");
313
314         self.ItabH.write( "extern const char * ud_mnemonics_str[];\n" )
315
316         self.ItabH.write( "\n#endif /* UD_ITAB_H */\n" )
317     
318         self.ItabH.close()
319
320
321     def genItabC( self ):
322         self.ItabC = open( "itab.c", "w" )
323         self.ItabC.write( "/* itab.c -- generated by itab.py, do no edit" )
324         self.ItabC.write( " */\n" );
325         self.ItabC.write( "#include \"decode.h\"\n\n" );
326
327         self.genLookupTable( self.OpcodeTable0 ) 
328         self.genLookupTableList()
329         self.genInsnTable()
330
331         self.ItabC.close()
332
333     def genItab( self ):
334         self.genItabC()
335         self.genItabH()
336
337 def main():
338     generator = UdItabGenerator()
339     optableXmlParser = ud_optable.UdOptableXmlParser()
340     optableXmlParser.parse( sys.argv[ 1 ], generator.addInsnDef )
341
342     generator.genItab()
343
344 if __name__ == '__main__':
345     main()