isa_parser: move the operand map stuff into the ISAParser class.
This commit is contained in:
parent
4db57edade
commit
629e8df196
1 changed files with 152 additions and 151 deletions
|
@ -157,7 +157,7 @@ class Template(object):
|
||||||
snippetLabels = [l for l in labelRE.findall(template)
|
snippetLabels = [l for l in labelRE.findall(template)
|
||||||
if d.snippets.has_key(l)]
|
if d.snippets.has_key(l)]
|
||||||
|
|
||||||
snippets = dict([(s, mungeSnippet(d.snippets[s]))
|
snippets = dict([(s, self.parser.mungeSnippet(d.snippets[s]))
|
||||||
for s in snippetLabels])
|
for s in snippetLabels])
|
||||||
|
|
||||||
myDict.update(snippets)
|
myDict.update(snippets)
|
||||||
|
@ -168,7 +168,7 @@ class Template(object):
|
||||||
# operands explicitly (like Mem)
|
# operands explicitly (like Mem)
|
||||||
compositeCode += ' ' + template
|
compositeCode += ' ' + template
|
||||||
|
|
||||||
operands = SubOperandList(compositeCode, d.operands)
|
operands = SubOperandList(self.parser, compositeCode, d.operands)
|
||||||
|
|
||||||
myDict['op_decl'] = operands.concatAttrStrings('op_decl')
|
myDict['op_decl'] = operands.concatAttrStrings('op_decl')
|
||||||
|
|
||||||
|
@ -380,34 +380,6 @@ def makeList(arg):
|
||||||
else:
|
else:
|
||||||
return [ arg ]
|
return [ arg ]
|
||||||
|
|
||||||
# Generate operandTypeMap from the user's 'def operand_types'
|
|
||||||
# statement.
|
|
||||||
def buildOperandTypeMap(user_dict, lineno):
|
|
||||||
global operandTypeMap
|
|
||||||
operandTypeMap = {}
|
|
||||||
for (ext, (desc, size)) in user_dict.iteritems():
|
|
||||||
if desc == 'signed int':
|
|
||||||
ctype = 'int%d_t' % size
|
|
||||||
is_signed = 1
|
|
||||||
elif desc == 'unsigned int':
|
|
||||||
ctype = 'uint%d_t' % size
|
|
||||||
is_signed = 0
|
|
||||||
elif desc == 'float':
|
|
||||||
is_signed = 1 # shouldn't really matter
|
|
||||||
if size == 32:
|
|
||||||
ctype = 'float'
|
|
||||||
elif size == 64:
|
|
||||||
ctype = 'double'
|
|
||||||
elif desc == 'twin64 int':
|
|
||||||
is_signed = 0
|
|
||||||
ctype = 'Twin64_t'
|
|
||||||
elif desc == 'twin32 int':
|
|
||||||
is_signed = 0
|
|
||||||
ctype = 'Twin32_t'
|
|
||||||
if ctype == '':
|
|
||||||
error(lineno, 'Unrecognized type description "%s" in user_dict')
|
|
||||||
operandTypeMap[ext] = (size, ctype, is_signed)
|
|
||||||
|
|
||||||
class Operand(object):
|
class Operand(object):
|
||||||
'''Base class for operand descriptors. An instance of this class
|
'''Base class for operand descriptors. An instance of this class
|
||||||
(or actually a class derived from this one) represents a specific
|
(or actually a class derived from this one) represents a specific
|
||||||
|
@ -448,7 +420,7 @@ class Operand(object):
|
||||||
if (traceData) { traceData->setData(final_val); }
|
if (traceData) { traceData->setData(final_val); }
|
||||||
}''' % (self.dflt_ctype, final_val, code)
|
}''' % (self.dflt_ctype, final_val, code)
|
||||||
|
|
||||||
def __init__(self, full_name, ext, is_src, is_dest):
|
def __init__(self, parser, full_name, ext, is_src, is_dest):
|
||||||
self.full_name = full_name
|
self.full_name = full_name
|
||||||
self.ext = ext
|
self.ext = ext
|
||||||
self.is_src = is_src
|
self.is_src = is_src
|
||||||
|
@ -460,7 +432,8 @@ class Operand(object):
|
||||||
else:
|
else:
|
||||||
self.eff_ext = self.dflt_ext
|
self.eff_ext = self.dflt_ext
|
||||||
|
|
||||||
(self.size, self.ctype, self.is_signed) = operandTypeMap[self.eff_ext]
|
self.size, self.ctype, self.is_signed = \
|
||||||
|
parser.operandTypeMap[self.eff_ext]
|
||||||
|
|
||||||
# note that mem_acc_size is undefined for non-mem operands...
|
# note that mem_acc_size is undefined for non-mem operands...
|
||||||
# template must be careful not to use it if it doesn't apply.
|
# template must be careful not to use it if it doesn't apply.
|
||||||
|
@ -770,91 +743,6 @@ class NNPCOperand(Operand):
|
||||||
return self.buildWriteCode('setNextNPC')
|
return self.buildWriteCode('setNextNPC')
|
||||||
return 'xc->setNextNPC(%s);\n' % self.base_name
|
return 'xc->setNextNPC(%s);\n' % self.base_name
|
||||||
|
|
||||||
def buildOperandNameMap(user_dict, lineno):
|
|
||||||
global operandNameMap
|
|
||||||
operandNameMap = {}
|
|
||||||
for (op_name, val) in user_dict.iteritems():
|
|
||||||
(base_cls_name, dflt_ext, reg_spec, flags, sort_pri) = val[:5]
|
|
||||||
if len(val) > 5:
|
|
||||||
read_code = val[5]
|
|
||||||
else:
|
|
||||||
read_code = None
|
|
||||||
if len(val) > 6:
|
|
||||||
write_code = val[6]
|
|
||||||
else:
|
|
||||||
write_code = None
|
|
||||||
if len(val) > 7:
|
|
||||||
error(lineno,
|
|
||||||
'error: too many attributes for operand "%s"' %
|
|
||||||
base_cls_name)
|
|
||||||
|
|
||||||
(dflt_size, dflt_ctype, dflt_is_signed) = operandTypeMap[dflt_ext]
|
|
||||||
# Canonical flag structure is a triple of lists, where each list
|
|
||||||
# indicates the set of flags implied by this operand always, when
|
|
||||||
# used as a source, and when used as a dest, respectively.
|
|
||||||
# For simplicity this can be initialized using a variety of fairly
|
|
||||||
# obvious shortcuts; we convert these to canonical form here.
|
|
||||||
if not flags:
|
|
||||||
# no flags specified (e.g., 'None')
|
|
||||||
flags = ( [], [], [] )
|
|
||||||
elif isinstance(flags, str):
|
|
||||||
# a single flag: assumed to be unconditional
|
|
||||||
flags = ( [ flags ], [], [] )
|
|
||||||
elif isinstance(flags, list):
|
|
||||||
# a list of flags: also assumed to be unconditional
|
|
||||||
flags = ( flags, [], [] )
|
|
||||||
elif isinstance(flags, tuple):
|
|
||||||
# it's a tuple: it should be a triple,
|
|
||||||
# but each item could be a single string or a list
|
|
||||||
(uncond_flags, src_flags, dest_flags) = flags
|
|
||||||
flags = (makeList(uncond_flags),
|
|
||||||
makeList(src_flags), makeList(dest_flags))
|
|
||||||
# Accumulate attributes of new operand class in tmp_dict
|
|
||||||
tmp_dict = {}
|
|
||||||
for attr in ('dflt_ext', 'reg_spec', 'flags', 'sort_pri',
|
|
||||||
'dflt_size', 'dflt_ctype', 'dflt_is_signed',
|
|
||||||
'read_code', 'write_code'):
|
|
||||||
tmp_dict[attr] = eval(attr)
|
|
||||||
tmp_dict['base_name'] = op_name
|
|
||||||
# New class name will be e.g. "IntReg_Ra"
|
|
||||||
cls_name = base_cls_name + '_' + op_name
|
|
||||||
# Evaluate string arg to get class object. Note that the
|
|
||||||
# actual base class for "IntReg" is "IntRegOperand", i.e. we
|
|
||||||
# have to append "Operand".
|
|
||||||
try:
|
|
||||||
base_cls = eval(base_cls_name + 'Operand')
|
|
||||||
except NameError:
|
|
||||||
if debug:
|
|
||||||
raise
|
|
||||||
error(lineno,
|
|
||||||
'error: unknown operand base class "%s"' % base_cls_name)
|
|
||||||
# The following statement creates a new class called
|
|
||||||
# <cls_name> as a subclass of <base_cls> with the attributes
|
|
||||||
# in tmp_dict, just as if we evaluated a class declaration.
|
|
||||||
operandNameMap[op_name] = type(cls_name, (base_cls,), tmp_dict)
|
|
||||||
|
|
||||||
# Define operand variables.
|
|
||||||
operands = user_dict.keys()
|
|
||||||
|
|
||||||
operandsREString = (r'''
|
|
||||||
(?<![\w\.]) # neg. lookbehind assertion: prevent partial matches
|
|
||||||
((%s)(?:\.(\w+))?) # match: operand with optional '.' then suffix
|
|
||||||
(?![\w\.]) # neg. lookahead assertion: prevent partial matches
|
|
||||||
'''
|
|
||||||
% string.join(operands, '|'))
|
|
||||||
|
|
||||||
global operandsRE
|
|
||||||
operandsRE = re.compile(operandsREString, re.MULTILINE|re.VERBOSE)
|
|
||||||
|
|
||||||
# Same as operandsREString, but extension is mandatory, and only two
|
|
||||||
# groups are returned (base and ext, not full name as above).
|
|
||||||
# Used for subtituting '_' for '.' to make C++ identifiers.
|
|
||||||
operandsWithExtREString = (r'(?<![\w\.])(%s)\.(\w+)(?![\w\.])'
|
|
||||||
% string.join(operands, '|'))
|
|
||||||
|
|
||||||
global operandsWithExtRE
|
|
||||||
operandsWithExtRE = re.compile(operandsWithExtREString, re.MULTILINE)
|
|
||||||
|
|
||||||
class OperandList(object):
|
class OperandList(object):
|
||||||
'''Find all the operands in the given code block. Returns an operand
|
'''Find all the operands in the given code block. Returns an operand
|
||||||
descriptor list (instance of class OperandList).'''
|
descriptor list (instance of class OperandList).'''
|
||||||
|
@ -866,7 +754,7 @@ class OperandList(object):
|
||||||
# search for operands
|
# search for operands
|
||||||
next_pos = 0
|
next_pos = 0
|
||||||
while 1:
|
while 1:
|
||||||
match = operandsRE.search(code, next_pos)
|
match = parser.operandsRE.search(code, next_pos)
|
||||||
if not match:
|
if not match:
|
||||||
# no more matches: we're done
|
# no more matches: we're done
|
||||||
break
|
break
|
||||||
|
@ -887,8 +775,8 @@ class OperandList(object):
|
||||||
op_desc.is_dest = op_desc.is_dest or is_dest
|
op_desc.is_dest = op_desc.is_dest or is_dest
|
||||||
else:
|
else:
|
||||||
# new operand: create new descriptor
|
# new operand: create new descriptor
|
||||||
op_desc = operandNameMap[op_base](op_full, op_ext,
|
op_desc = parser.operandNameMap[op_base](parser,
|
||||||
is_src, is_dest)
|
op_full, op_ext, is_src, is_dest)
|
||||||
self.append(op_desc)
|
self.append(op_desc)
|
||||||
# start next search after end of current match
|
# start next search after end of current match
|
||||||
next_pos = match.end()
|
next_pos = match.end()
|
||||||
|
@ -973,7 +861,7 @@ class OperandList(object):
|
||||||
class SubOperandList(OperandList):
|
class SubOperandList(OperandList):
|
||||||
'''Find all the operands in the given code block. Returns an operand
|
'''Find all the operands in the given code block. Returns an operand
|
||||||
descriptor list (instance of class OperandList).'''
|
descriptor list (instance of class OperandList).'''
|
||||||
def __init__(self, code, master_list):
|
def __init__(self, parser, code, master_list):
|
||||||
self.items = []
|
self.items = []
|
||||||
self.bases = {}
|
self.bases = {}
|
||||||
# delete comments so we don't match on reg specifiers inside
|
# delete comments so we don't match on reg specifiers inside
|
||||||
|
@ -981,7 +869,7 @@ class SubOperandList(OperandList):
|
||||||
# search for operands
|
# search for operands
|
||||||
next_pos = 0
|
next_pos = 0
|
||||||
while 1:
|
while 1:
|
||||||
match = operandsRE.search(code, next_pos)
|
match = parser.operandsRE.search(code, next_pos)
|
||||||
if not match:
|
if not match:
|
||||||
# no more matches: we're done
|
# no more matches: we're done
|
||||||
break
|
break
|
||||||
|
@ -1018,19 +906,6 @@ commentRE = re.compile(r'//.*\n')
|
||||||
# (used in findOperands())
|
# (used in findOperands())
|
||||||
assignRE = re.compile(r'\s*=(?!=)', re.MULTILINE)
|
assignRE = re.compile(r'\s*=(?!=)', re.MULTILINE)
|
||||||
|
|
||||||
# Munge operand names in code string to make legal C++ variable names.
|
|
||||||
# This means getting rid of the type extension if any.
|
|
||||||
# (Will match base_name attribute of Operand object.)
|
|
||||||
def substMungedOpNames(code):
|
|
||||||
return operandsWithExtRE.sub(r'\1', code)
|
|
||||||
|
|
||||||
# Fix up code snippets for final substitution in templates.
|
|
||||||
def mungeSnippet(s):
|
|
||||||
if isinstance(s, str):
|
|
||||||
return substMungedOpNames(substBitOps(s))
|
|
||||||
else:
|
|
||||||
return s
|
|
||||||
|
|
||||||
def makeFlagConstructor(flag_list):
|
def makeFlagConstructor(flag_list):
|
||||||
if len(flag_list) == 0:
|
if len(flag_list) == 0:
|
||||||
return ''
|
return ''
|
||||||
|
@ -1128,13 +1003,6 @@ class Stack(list):
|
||||||
def top(self):
|
def top(self):
|
||||||
return self[-1]
|
return self[-1]
|
||||||
|
|
||||||
# Global stack that tracks current file and line number.
|
|
||||||
# Each element is a tuple (filename, lineno) that records the
|
|
||||||
# *current* filename and the line number in the *previous* file where
|
|
||||||
# it was included.
|
|
||||||
fileNameStack = Stack()
|
|
||||||
|
|
||||||
|
|
||||||
#######################
|
#######################
|
||||||
#
|
#
|
||||||
# Output file template
|
# Output file template
|
||||||
|
@ -1195,6 +1063,12 @@ class ISAParser(Grammar):
|
||||||
# The default case stack.
|
# The default case stack.
|
||||||
self.defaultStack = Stack(None)
|
self.defaultStack = Stack(None)
|
||||||
|
|
||||||
|
# Stack that tracks current file and line number. Each
|
||||||
|
# element is a tuple (filename, lineno) that records the
|
||||||
|
# *current* filename and the line number in the *previous*
|
||||||
|
# file where it was included.
|
||||||
|
self.fileNameStack = Stack()
|
||||||
|
|
||||||
symbols = ('makeList', 're', 'string')
|
symbols = ('makeList', 're', 'string')
|
||||||
self.exportContext = dict([(s, eval(s)) for s in symbols])
|
self.exportContext = dict([(s, eval(s)) for s in symbols])
|
||||||
|
|
||||||
|
@ -1322,12 +1196,12 @@ class ISAParser(Grammar):
|
||||||
|
|
||||||
def t_NEWFILE(self, t):
|
def t_NEWFILE(self, t):
|
||||||
r'^\#\#newfile\s+"[\w/.-]*"'
|
r'^\#\#newfile\s+"[\w/.-]*"'
|
||||||
fileNameStack.push((t.value[11:-1], t.lexer.lineno))
|
self.fileNameStack.push((t.value[11:-1], t.lexer.lineno))
|
||||||
t.lexer.lineno = 0
|
t.lexer.lineno = 0
|
||||||
|
|
||||||
def t_ENDFILE(self, t):
|
def t_ENDFILE(self, t):
|
||||||
r'^\#\#endfile'
|
r'^\#\#endfile'
|
||||||
(old_filename, t.lexer.lineno) = fileNameStack.pop()
|
(old_filename, t.lexer.lineno) = self.fileNameStack.pop()
|
||||||
|
|
||||||
#
|
#
|
||||||
# The functions t_NEWLINE, t_ignore, and t_error are
|
# The functions t_NEWLINE, t_ignore, and t_error are
|
||||||
|
@ -1489,14 +1363,14 @@ StaticInstPtr
|
||||||
raise
|
raise
|
||||||
error(t,
|
error(t,
|
||||||
'error: %s in def operand_types block "%s".' % (exc, t[3]))
|
'error: %s in def operand_types block "%s".' % (exc, t[3]))
|
||||||
buildOperandTypeMap(user_dict, t.lexer.lineno)
|
self.buildOperandTypeMap(user_dict, t.lexer.lineno)
|
||||||
t[0] = GenCode(self) # contributes nothing to the output C++ file
|
t[0] = GenCode(self) # contributes nothing to the output C++ file
|
||||||
|
|
||||||
# Define the mapping from operand names to operand classes and
|
# Define the mapping from operand names to operand classes and
|
||||||
# other traits. Stored in operandNameMap.
|
# other traits. Stored in operandNameMap.
|
||||||
def p_def_operands(self, t):
|
def p_def_operands(self, t):
|
||||||
'def_operands : DEF OPERANDS CODELIT SEMI'
|
'def_operands : DEF OPERANDS CODELIT SEMI'
|
||||||
if not globals().has_key('operandTypeMap'):
|
if not hasattr(self, '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] + '}', self.exportContext)
|
user_dict = eval('{' + t[3] + '}', self.exportContext)
|
||||||
|
@ -1504,7 +1378,7 @@ StaticInstPtr
|
||||||
if debug:
|
if debug:
|
||||||
raise
|
raise
|
||||||
error(t, 'error: %s in def operands block "%s".' % (exc, t[3]))
|
error(t, 'error: %s in def operands block "%s".' % (exc, t[3]))
|
||||||
buildOperandNameMap(user_dict, t.lexer.lineno)
|
self.buildOperandNameMap(user_dict, t.lexer.lineno)
|
||||||
t[0] = GenCode(self) # contributes nothing to the output C++ file
|
t[0] = GenCode(self) # contributes nothing to the output C++ file
|
||||||
|
|
||||||
# A bitfield definition looks like:
|
# A bitfield definition looks like:
|
||||||
|
@ -1950,6 +1824,133 @@ StaticInstPtr
|
||||||
|
|
||||||
return re.sub(r'%(?!\()', '%%', s)
|
return re.sub(r'%(?!\()', '%%', s)
|
||||||
|
|
||||||
|
def buildOperandTypeMap(self, user_dict, lineno):
|
||||||
|
"""Generate operandTypeMap from the user's 'def operand_types'
|
||||||
|
statement."""
|
||||||
|
operand_type = {}
|
||||||
|
for (ext, (desc, size)) in user_dict.iteritems():
|
||||||
|
if desc == 'signed int':
|
||||||
|
ctype = 'int%d_t' % size
|
||||||
|
is_signed = 1
|
||||||
|
elif desc == 'unsigned int':
|
||||||
|
ctype = 'uint%d_t' % size
|
||||||
|
is_signed = 0
|
||||||
|
elif desc == 'float':
|
||||||
|
is_signed = 1 # shouldn't really matter
|
||||||
|
if size == 32:
|
||||||
|
ctype = 'float'
|
||||||
|
elif size == 64:
|
||||||
|
ctype = 'double'
|
||||||
|
elif desc == 'twin64 int':
|
||||||
|
is_signed = 0
|
||||||
|
ctype = 'Twin64_t'
|
||||||
|
elif desc == 'twin32 int':
|
||||||
|
is_signed = 0
|
||||||
|
ctype = 'Twin32_t'
|
||||||
|
if ctype == '':
|
||||||
|
error(parser, lineno,
|
||||||
|
'Unrecognized type description "%s" in user_dict')
|
||||||
|
operand_type[ext] = (size, ctype, is_signed)
|
||||||
|
|
||||||
|
self.operandTypeMap = operand_type
|
||||||
|
|
||||||
|
def buildOperandNameMap(self, user_dict, lineno):
|
||||||
|
operand_name = {}
|
||||||
|
for op_name, val in user_dict.iteritems():
|
||||||
|
base_cls_name, dflt_ext, reg_spec, flags, sort_pri = val[:5]
|
||||||
|
if len(val) > 5:
|
||||||
|
read_code = val[5]
|
||||||
|
else:
|
||||||
|
read_code = None
|
||||||
|
if len(val) > 6:
|
||||||
|
write_code = val[6]
|
||||||
|
else:
|
||||||
|
write_code = None
|
||||||
|
if len(val) > 7:
|
||||||
|
error(lineno,
|
||||||
|
'error: too many attributes for operand "%s"' %
|
||||||
|
base_cls_name)
|
||||||
|
|
||||||
|
(dflt_size, dflt_ctype, dflt_is_signed) = \
|
||||||
|
self.operandTypeMap[dflt_ext]
|
||||||
|
# Canonical flag structure is a triple of lists, where each list
|
||||||
|
# indicates the set of flags implied by this operand always, when
|
||||||
|
# used as a source, and when used as a dest, respectively.
|
||||||
|
# For simplicity this can be initialized using a variety of fairly
|
||||||
|
# obvious shortcuts; we convert these to canonical form here.
|
||||||
|
if not flags:
|
||||||
|
# no flags specified (e.g., 'None')
|
||||||
|
flags = ( [], [], [] )
|
||||||
|
elif isinstance(flags, str):
|
||||||
|
# a single flag: assumed to be unconditional
|
||||||
|
flags = ( [ flags ], [], [] )
|
||||||
|
elif isinstance(flags, list):
|
||||||
|
# a list of flags: also assumed to be unconditional
|
||||||
|
flags = ( flags, [], [] )
|
||||||
|
elif isinstance(flags, tuple):
|
||||||
|
# it's a tuple: it should be a triple,
|
||||||
|
# but each item could be a single string or a list
|
||||||
|
(uncond_flags, src_flags, dest_flags) = flags
|
||||||
|
flags = (makeList(uncond_flags),
|
||||||
|
makeList(src_flags), makeList(dest_flags))
|
||||||
|
# Accumulate attributes of new operand class in tmp_dict
|
||||||
|
tmp_dict = {}
|
||||||
|
for attr in ('dflt_ext', 'reg_spec', 'flags', 'sort_pri',
|
||||||
|
'dflt_size', 'dflt_ctype', 'dflt_is_signed',
|
||||||
|
'read_code', 'write_code'):
|
||||||
|
tmp_dict[attr] = eval(attr)
|
||||||
|
tmp_dict['base_name'] = op_name
|
||||||
|
# New class name will be e.g. "IntReg_Ra"
|
||||||
|
cls_name = base_cls_name + '_' + op_name
|
||||||
|
# Evaluate string arg to get class object. Note that the
|
||||||
|
# actual base class for "IntReg" is "IntRegOperand", i.e. we
|
||||||
|
# have to append "Operand".
|
||||||
|
try:
|
||||||
|
base_cls = eval(base_cls_name + 'Operand')
|
||||||
|
except NameError:
|
||||||
|
error(lineno,
|
||||||
|
'error: unknown operand base class "%s"' % base_cls_name)
|
||||||
|
# The following statement creates a new class called
|
||||||
|
# <cls_name> as a subclass of <base_cls> with the attributes
|
||||||
|
# in tmp_dict, just as if we evaluated a class declaration.
|
||||||
|
operand_name[op_name] = type(cls_name, (base_cls,), tmp_dict)
|
||||||
|
|
||||||
|
self.operandNameMap = operand_name
|
||||||
|
|
||||||
|
# Define operand variables.
|
||||||
|
operands = user_dict.keys()
|
||||||
|
|
||||||
|
operandsREString = (r'''
|
||||||
|
(?<![\w\.]) # neg. lookbehind assertion: prevent partial matches
|
||||||
|
((%s)(?:\.(\w+))?) # match: operand with optional '.' then suffix
|
||||||
|
(?![\w\.]) # neg. lookahead assertion: prevent partial matches
|
||||||
|
'''
|
||||||
|
% string.join(operands, '|'))
|
||||||
|
|
||||||
|
self.operandsRE = re.compile(operandsREString, re.MULTILINE|re.VERBOSE)
|
||||||
|
|
||||||
|
# Same as operandsREString, but extension is mandatory, and only two
|
||||||
|
# groups are returned (base and ext, not full name as above).
|
||||||
|
# Used for subtituting '_' for '.' to make C++ identifiers.
|
||||||
|
operandsWithExtREString = (r'(?<![\w\.])(%s)\.(\w+)(?![\w\.])'
|
||||||
|
% string.join(operands, '|'))
|
||||||
|
|
||||||
|
self.operandsWithExtRE = \
|
||||||
|
re.compile(operandsWithExtREString, re.MULTILINE)
|
||||||
|
|
||||||
|
def substMungedOpNames(self, code):
|
||||||
|
'''Munge operand names in code string to make legal C++
|
||||||
|
variable names. This means getting rid of the type extension
|
||||||
|
if any. Will match base_name attribute of Operand object.)'''
|
||||||
|
return self.operandsWithExtRE.sub(r'\1', code)
|
||||||
|
|
||||||
|
def mungeSnippet(self, s):
|
||||||
|
'''Fix up code snippets for final substitution in templates.'''
|
||||||
|
if isinstance(s, str):
|
||||||
|
return self.substMungedOpNames(substBitOps(s))
|
||||||
|
else:
|
||||||
|
return s
|
||||||
|
|
||||||
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
|
||||||
|
@ -2001,14 +2002,14 @@ StaticInstPtr
|
||||||
except IOError:
|
except IOError:
|
||||||
error('Error including file "%s"' % filename)
|
error('Error including file "%s"' % filename)
|
||||||
|
|
||||||
fileNameStack.push((filename, 0))
|
self.fileNameStack.push((filename, 0))
|
||||||
|
|
||||||
# Find any includes and include them
|
# Find any includes and include them
|
||||||
def replace(matchobj):
|
def replace(matchobj):
|
||||||
return self.replace_include(matchobj, current_dir)
|
return self.replace_include(matchobj, current_dir)
|
||||||
contents = self.includeRE.sub(replace, contents)
|
contents = self.includeRE.sub(replace, contents)
|
||||||
|
|
||||||
fileNameStack.pop()
|
self.fileNameStack.pop()
|
||||||
return contents
|
return contents
|
||||||
|
|
||||||
def _parse_isa_desc(self, isa_desc_file):
|
def _parse_isa_desc(self, isa_desc_file):
|
||||||
|
@ -2020,7 +2021,7 @@ StaticInstPtr
|
||||||
isa_desc = self.read_and_flatten(isa_desc_file)
|
isa_desc = self.read_and_flatten(isa_desc_file)
|
||||||
|
|
||||||
# Initialize filename stack with outer file.
|
# Initialize filename stack with outer file.
|
||||||
fileNameStack.push((isa_desc_file, 0))
|
self.fileNameStack.push((isa_desc_file, 0))
|
||||||
|
|
||||||
# Parse it.
|
# Parse it.
|
||||||
(isa_name, namespace, global_code, namespace_code) = \
|
(isa_name, namespace, global_code, namespace_code) = \
|
||||||
|
@ -2067,7 +2068,7 @@ StaticInstPtr
|
||||||
try:
|
try:
|
||||||
self._parse_isa_desc(*args, **kwargs)
|
self._parse_isa_desc(*args, **kwargs)
|
||||||
except ISAParserError, e:
|
except ISAParserError, e:
|
||||||
e.exit(fileNameStack)
|
e.exit(self.fileNameStack)
|
||||||
|
|
||||||
# Called as script: get args from command line.
|
# Called as script: get args from command line.
|
||||||
# Args are: <path to cpu_models.py> <isa desc file> <output dir> <cpu models>
|
# Args are: <path to cpu_models.py> <isa desc file> <output dir> <cpu models>
|
||||||
|
|
Loading…
Reference in a new issue