isa_parser: move the formatMap and exportContext into the ISAParser class

This commit is contained in:
Nathan Binkert 2010-02-26 18:14:48 -08:00
parent 4e105f6fe1
commit 4ef6e129d6

View file

@ -209,21 +209,9 @@ class Template(object):
# a defineInst() method that generates the code for an instruction # a defineInst() method that generates the code for an instruction
# definition. # definition.
exportContextSymbols = ('InstObjParams', 'makeList', 're', 'string')
exportContext = {}
def updateExportContext():
exportContext.update(exportDict(*exportContextSymbols))
exportContext.update(parser.templateMap)
def exportDict(*symNames):
return dict([(s, eval(s)) for s in symNames])
class Format(object): class Format(object):
def __init__(self, id, params, code): def __init__(self, parser, id, params, code):
# constructor: just save away arguments self.parser = parser
self.id = id self.id = id
self.params = params self.params = params
label = 'def format ' + id label = 'def format ' + id
@ -238,14 +226,13 @@ class Format(object):
self.func = defInst self.func = defInst
def defineInst(self, name, args, lineno): def defineInst(self, name, args, lineno):
context = {} self.parser.updateExportContext()
updateExportContext() context = self.parser.exportContext.copy()
context.update(exportContext)
if len(name): if len(name):
Name = name[0].upper() Name = name[0].upper()
if len(name) > 1: if len(name) > 1:
Name += name[1:] Name += name[1:]
context.update({ 'name': name, 'Name': Name }) context.update({ 'name' : name, 'Name' : Name })
try: try:
vars = self.func(self.user_code, context, *args[0], **args[1]) vars = self.func(self.user_code, context, *args[0], **args[1])
except Exception, exc: except Exception, exc:
@ -268,17 +255,6 @@ class NoFormat(object):
error(lineno, error(lineno,
'instruction definition "%s" with no active format!' % name) 'instruction definition "%s" with no active format!' % name)
# This dictionary maps format name strings to Format objects.
formatMap = {}
# Define a new format
def defFormat(id, params, code, lineno):
# make sure we haven't already defined this one
if formatMap.get(id, None) != None:
error(lineno, 'format %s redefined.' % id)
# create new object and store in global map
formatMap[id] = Format(id, params, code)
##################################################################### #####################################################################
# #
# Support Classes # Support Classes
@ -1250,12 +1226,17 @@ class ISAParser(Grammar):
self.templateMap = {} self.templateMap = {}
# This dictionary maps format name strings to Format objects.
self.formatMap = {}
# The format stack. # The format stack.
self.formatStack = Stack(NoFormat()) self.formatStack = Stack(NoFormat())
# The default case stack. # The default case stack.
self.defaultStack = Stack(None) self.defaultStack = Stack(None)
self.exportContext = {}
##################################################################### #####################################################################
# #
# Lexer # Lexer
@ -1516,21 +1497,21 @@ StaticInstPtr
# from polluting this script's namespace. # from polluting this script's namespace.
def p_global_let(self, t): def p_global_let(self, t):
'global_let : LET CODELIT SEMI' 'global_let : LET CODELIT SEMI'
updateExportContext() self.updateExportContext()
exportContext["header_output"] = '' self.exportContext["header_output"] = ''
exportContext["decoder_output"] = '' self.exportContext["decoder_output"] = ''
exportContext["exec_output"] = '' self.exportContext["exec_output"] = ''
exportContext["decode_block"] = '' self.exportContext["decode_block"] = ''
try: try:
exec fixPythonIndentation(t[2]) in exportContext exec fixPythonIndentation(t[2]) in self.exportContext
except Exception, exc: except Exception, exc:
if debug: if debug:
raise raise
error(t, 'error: %s in global let block "%s".' % (exc, t[2])) error(t, 'error: %s in global let block "%s".' % (exc, t[2]))
t[0] = GenCode(header_output = exportContext["header_output"], t[0] = GenCode(header_output=self.exportContext["header_output"],
decoder_output = exportContext["decoder_output"], decoder_output=self.exportContext["decoder_output"],
exec_output = exportContext["exec_output"], exec_output=self.exportContext["exec_output"],
decode_block = exportContext["decode_block"]) decode_block=self.exportContext["decode_block"])
# Define the mapping from operand type extensions to C++ types and # Define the mapping from operand type extensions to C++ types and
# bit widths (stored in operandTypeMap). # bit widths (stored in operandTypeMap).
@ -1553,7 +1534,7 @@ StaticInstPtr
if not globals().has_key('operandTypeMap'): if not globals().has_key('operandTypeMap'):
error(t, 'error: operand types must be defined before operands') error(t, 'error: operand types must be defined before operands')
try: try:
user_dict = eval('{' + t[3] + '}', exportContext) user_dict = eval('{' + t[3] + '}', self.exportContext)
except Exception, exc: except Exception, exc:
if debug: if debug:
raise raise
@ -1616,7 +1597,7 @@ StaticInstPtr
def p_def_format(self, t): def p_def_format(self, t):
'def_format : DEF FORMAT ID LPAREN param_list RPAREN CODELIT SEMI' 'def_format : DEF FORMAT ID LPAREN param_list RPAREN CODELIT SEMI'
(id, params, code) = (t[3], t[5], t[7]) (id, params, code) = (t[3], t[5], t[7])
defFormat(id, params, code, t.lexer.lineno) self.defFormat(id, params, code, t.lexer.lineno)
t[0] = GenCode() t[0] = GenCode()
# The formal parameter list for an instruction format is a # The formal parameter list for an instruction format is a
@ -1771,7 +1752,7 @@ StaticInstPtr
def p_push_format_id(self, t): def p_push_format_id(self, t):
'push_format_id : ID' 'push_format_id : ID'
try: try:
self.formatStack.push(formatMap[t[1]]) self.formatStack.push(self.formatMap[t[1]])
t[0] = ('', '// format %s' % t[1]) t[0] = ('', '// format %s' % t[1])
except KeyError: except KeyError:
error(t, 'instruction format "%s" not defined.' % t[1]) error(t, 'instruction format "%s" not defined.' % t[1])
@ -1845,7 +1826,7 @@ StaticInstPtr
def p_inst_1(self, t): def p_inst_1(self, t):
'inst : ID DBLCOLON ID LPAREN arg_list RPAREN' 'inst : ID DBLCOLON ID LPAREN arg_list RPAREN'
try: try:
format = formatMap[t[1]] format = self.formatMap[t[1]]
except KeyError: except KeyError:
error(t, 'instruction format "%s" not defined.' % t[1]) error(t, 'instruction format "%s" not defined.' % t[1])
codeObj = format.defineInst(t[3], t[5], t.lexer.lineno) codeObj = format.defineInst(t[3], t[5], t.lexer.lineno)
@ -1945,6 +1926,22 @@ StaticInstPtr
# END OF GRAMMAR RULES # END OF GRAMMAR RULES
exportContextSymbols = ('InstObjParams', 'makeList', 're', 'string')
def updateExportContext(self):
exportDict = dict([(s, eval(s)) for s in self.exportContextSymbols])
self.exportContext.update(exportDict)
self.exportContext.update(parser.templateMap)
def defFormat(self, id, params, code, lineno):
'''Define a new format'''
# make sure we haven't already defined this one
if id in self.formatMap:
error(lineno, 'format %s redefined.' % id)
# create new object and store in global map
self.formatMap[id] = Format(self, id, params, code)
def update_if_needed(self, file, contents): def update_if_needed(self, file, contents):
'''Update the output file only if the new contents are '''Update the output file only if the new contents are
different from the current contents. Minimizes the files that different from the current contents. Minimizes the files that