diff --git a/src/arch/isa_parser.py b/src/arch/isa_parser.py index 9590e2453..282010429 100755 --- a/src/arch/isa_parser.py +++ b/src/arch/isa_parser.py @@ -157,7 +157,7 @@ class Template(object): snippetLabels = [l for l in labelRE.findall(template) 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]) myDict.update(snippets) @@ -168,7 +168,7 @@ class Template(object): # operands explicitly (like Mem) compositeCode += ' ' + template - operands = SubOperandList(compositeCode, d.operands) + operands = SubOperandList(self.parser, compositeCode, d.operands) myDict['op_decl'] = operands.concatAttrStrings('op_decl') @@ -380,34 +380,6 @@ def makeList(arg): else: 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): '''Base class for operand descriptors. An instance of this class (or actually a class derived from this one) represents a specific @@ -448,7 +420,7 @@ class Operand(object): if (traceData) { traceData->setData(final_val); } }''' % (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.ext = ext self.is_src = is_src @@ -460,7 +432,8 @@ class Operand(object): else: 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... # 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 '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 - # as a subclass of 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''' - (? 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 + # as a subclass of 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''' + (?