mirror of
https://github.com/RPCSX/xed.git
synced 2024-11-27 05:20:24 +00:00
e7d734962c
Change-Id: I166833daaa56c33eca01bdf7b9aa6e74a490ba9a (cherry picked from commit 1212ba962dff6dfbfa0bd2469327ff447ce59058)
202 lines
6.9 KiB
Python
Executable File
202 lines
6.9 KiB
Python
Executable File
#!/usr/bin/env python
|
|
#BEGIN_LEGAL
|
|
#
|
|
#Copyright (c) 2017 Intel Corporation
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
#
|
|
#END_LEGAL
|
|
from __future__ import print_function
|
|
import re
|
|
import types
|
|
import sys
|
|
import os
|
|
import genutil
|
|
import codegen
|
|
import enum_txt_writer
|
|
|
|
# emit XED_OPERAND_CONVERT_ enum
|
|
# emit mapping from XED_OPERAND_CONVERT_* enum to the arrays created here
|
|
|
|
|
|
def emit_convert_enum(converts,xeddir='.',gendir='obj'):
|
|
i = enum_txt_writer.enum_info_t(converts, xeddir, gendir,
|
|
'xed-operand-convert',
|
|
'xed_operand_convert_enum_t',
|
|
'XED_OPERAND_CONVERT_',
|
|
cplusplus=False)
|
|
i.print_enum()
|
|
i.run_enumer()
|
|
return [i.src_full_file_name, i.hdr_full_file_name]
|
|
|
|
|
|
class constant_table_t(object):
|
|
"""Create string constant lookup tables. Invalid error elements
|
|
are null strings. The inputs must be dense and ordered. FIXME: add
|
|
something that handles dont-cares, sorts, and fills in missing
|
|
entries. The input left hand column is ignored right now, and
|
|
assumed to be binary."""
|
|
match_blank = re.compile(r'^$')
|
|
match_header = \
|
|
re.compile(r'(?P<name>[A-Za-z0-9_]+)[(](?P<operand>[A-Za-z0-9_]+)[)]::')
|
|
|
|
match_pair = re.compile(r"""(?P<value>[bxmA-F0-9_]+)[ \t]*[-][>][ \t]*['](?P<symbol>[^']*)[']""")
|
|
|
|
match_pair_error = \
|
|
re.compile(r'(?P<value>[bxmA-F0-9_]+)[ \t]*[-][>][ \t]*error')
|
|
|
|
def __init__(self):
|
|
self.name=None
|
|
self.operand=None
|
|
self.value_string_pairs=[]
|
|
|
|
def valid(self):
|
|
if self.name != None:
|
|
return True
|
|
return False
|
|
def dump(self):
|
|
print("%s(%s)::" % (self.name, self.operand))
|
|
for (v,p) in self.value_string_pairs:
|
|
if genutil.is_stringish(p):
|
|
print("%s '%s'" % (hex(v),p))
|
|
else:
|
|
print("%s error" %(hex(v)))
|
|
|
|
def emit_init(self):
|
|
lines = []
|
|
self.string_table_name = 'xed_convert_table_%s' % (self.name)
|
|
lines.append('static const char* %s[] = {' % (self.string_table_name))
|
|
|
|
for (v,p) in self.value_string_pairs:
|
|
if genutil.is_stringish(p):
|
|
lines.append( '/*%s*/ "%s",' % (hex(v),p))
|
|
else:
|
|
lines.append( '/*%s*/ 0, /* error */' % (hex(v)))
|
|
lines.append('};')
|
|
return lines
|
|
|
|
|
|
def _read_constant_tables(lines, tables):
|
|
"""Read lines from lines until a new header or a blank line is reached"""
|
|
nlines = 0
|
|
y = None
|
|
for line in lines:
|
|
nlines += 1
|
|
line = line.strip()
|
|
line = re.sub(r'#.*','',line)
|
|
m = constant_table_t.match_blank.match(line)
|
|
if m:
|
|
continue
|
|
m = constant_table_t.match_header.match(line)
|
|
if m: # found next header
|
|
name = m.group('name')
|
|
y = None
|
|
for t in tables:
|
|
if t.name == name:
|
|
y = t
|
|
if not y:
|
|
y = constant_table_t()
|
|
tables.append(y)
|
|
y.name = name
|
|
y.operand = m.group('operand')
|
|
continue
|
|
m = constant_table_t.match_pair.match(line)
|
|
if m:
|
|
value = m.group('value')
|
|
symbol = m.group('symbol')
|
|
numeric_value = genutil.make_numeric(value)
|
|
#print "INPUT: [%s] [%s]" % (value,symbol)
|
|
if not y:
|
|
genutil.die("Malformed constant table line {}: [{}]\n\n".format(nlines,line))
|
|
y.value_string_pairs.append((numeric_value,symbol))
|
|
continue
|
|
m = constant_table_t.match_pair_error.match(line)
|
|
if m:
|
|
value = m.group('value')
|
|
numeric_value = genutil.make_numeric(value)
|
|
if not y:
|
|
genutil.die("Malformed constant table line {}: [{}]\n\n".format(nlines,line))
|
|
y.value_string_pairs.append((numeric_value,None))
|
|
continue
|
|
else:
|
|
genutil.die("Could not parse line {}: [{}]\n\n".format(nlines,line))
|
|
|
|
|
|
|
|
|
|
def work(lines, xeddir = '.', gendir = 'obj'):
|
|
tables = []
|
|
_read_constant_tables(lines,tables)
|
|
|
|
|
|
tables=list(filter(lambda x: x.valid() , tables))
|
|
names= [ x.name for x in tables ]
|
|
|
|
srcs = emit_convert_enum(['INVALID'] + names, xeddir, gendir)
|
|
src_file_name = 'xed-convert-table-init.c'
|
|
hdr_file_name = 'xed-convert-table-init.h'
|
|
xfe = codegen.xed_file_emitter_t(xeddir, gendir, src_file_name)
|
|
xfe.add_header(hdr_file_name)
|
|
xfe.start()
|
|
|
|
hfe = codegen.xed_file_emitter_t(xeddir,
|
|
gendir,
|
|
hdr_file_name)
|
|
hfe.start()
|
|
|
|
xfe.add_code('xed_convert_table_t xed_convert_table[XED_OPERAND_CONVERT_LAST];')
|
|
|
|
for t in tables:
|
|
l = t.emit_init()
|
|
l = [ x+'\n' for x in l]
|
|
xfe.writelines(l)
|
|
fo = codegen.function_object_t('xed_init_convert_tables', 'void')
|
|
|
|
s1 = 'xed_convert_table[XED_OPERAND_CONVERT_%s].table_name = %s;' % ('INVALID', '0')
|
|
s2 = 'xed_convert_table[XED_OPERAND_CONVERT_%s].limit = %s;' % ('INVALID', '0')
|
|
s3 = 'xed_convert_table[XED_OPERAND_CONVERT_%s].opnd = %s;' % ('INVALID', 'XED_OPERAND_INVALID')
|
|
fo.add_code(s1)
|
|
fo.add_code(s2)
|
|
fo.add_code(s3)
|
|
|
|
for t in tables:
|
|
s1 = 'xed_convert_table[XED_OPERAND_CONVERT_%s].table_name = %s;' % (t.name, t.string_table_name)
|
|
s2 = 'xed_convert_table[XED_OPERAND_CONVERT_%s].limit = %s;' % (t.name, len(t.value_string_pairs))
|
|
s3 = 'xed_convert_table[XED_OPERAND_CONVERT_%s].opnd = %s;' % (t.name, t.operand)
|
|
fo.add_code(s1)
|
|
fo.add_code(s2)
|
|
fo.add_code(s3)
|
|
|
|
fo.emit_file_emitter(xfe)
|
|
xfe.close()
|
|
|
|
hdr = []
|
|
hdr.append("typedef struct {\n")
|
|
hdr.append(" const char** table_name;\n")
|
|
hdr.append(" xed_operand_enum_t opnd;\n") # which operand indexes the table!
|
|
hdr.append(" unsigned int limit;\n")
|
|
hdr.append("} xed_convert_table_t;")
|
|
hdr.append("extern xed_convert_table_t xed_convert_table[XED_OPERAND_CONVERT_LAST];")
|
|
hfe.writelines( [ x+'\n' for x in hdr] )
|
|
hfe.close()
|
|
|
|
srcs.append(hfe.full_file_name)
|
|
srcs.append(xfe.full_file_name)
|
|
return srcs
|
|
|
|
if __name__ == '__main__':
|
|
import sys
|
|
lines = open(sys.argv[1],'r').readlines()
|
|
srcs = work(lines,xeddir='.',gendir='obj')
|
|
print("WROTE: ", "\n\t".join(srcs))
|