isa_parser.py revision 6986:f4895857bb48
1# Copyright (c) 2003-2005 The Regents of The University of Michigan
2# All rights reserved.
3#
4# Redistribution and use in source and binary forms, with or without
5# modification, are permitted provided that the following conditions are
6# met: redistributions of source code must retain the above copyright
7# notice, this list of conditions and the following disclaimer;
8# redistributions in binary form must reproduce the above copyright
9# notice, this list of conditions and the following disclaimer in the
10# documentation and/or other materials provided with the distribution;
11# neither the name of the copyright holders nor the names of its
12# contributors may be used to endorse or promote products derived from
13# this software without specific prior written permission.
14#
15# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26#
27# Authors: Steve Reinhardt
28
29import os
30import sys
31import re
32import string
33import inspect, traceback
34# get type names
35from types import *
36
37from m5.util.grammar import Grammar
38
39###################
40# Utility functions
41
42#
43# Indent every line in string 's' by two spaces
44# (except preprocessor directives).
45# Used to make nested code blocks look pretty.
46#
47def indent(s):
48    return re.sub(r'(?m)^(?!#)', '  ', s)
49
50#
51# Munge a somewhat arbitrarily formatted piece of Python code
52# (e.g. from a format 'let' block) into something whose indentation
53# will get by the Python parser.
54#
55# The two keys here are that Python will give a syntax error if
56# there's any whitespace at the beginning of the first line, and that
57# all lines at the same lexical nesting level must have identical
58# indentation.  Unfortunately the way code literals work, an entire
59# let block tends to have some initial indentation.  Rather than
60# trying to figure out what that is and strip it off, we prepend 'if
61# 1:' to make the let code the nested block inside the if (and have
62# the parser automatically deal with the indentation for us).
63#
64# We don't want to do this if (1) the code block is empty or (2) the
65# first line of the block doesn't have any whitespace at the front.
66
67def fixPythonIndentation(s):
68    # get rid of blank lines first
69    s = re.sub(r'(?m)^\s*\n', '', s);
70    if (s != '' and re.match(r'[ \t]', s[0])):
71        s = 'if 1:\n' + s
72    return s
73
74class ISAParserError(Exception):
75    """Error handler for parser errors"""
76    def __init__(self, first, second=None):
77        if second is None:
78            self.lineno = 0
79            self.string = first
80        else:
81            if hasattr(first, 'lexer'):
82                first = first.lexer.lineno
83            self.lineno = first
84            self.string = second
85
86    def display(self, filename_stack, print_traceback=False):
87        # Output formatted to work under Emacs compile-mode.  Optional
88        # 'print_traceback' arg, if set to True, prints a Python stack
89        # backtrace too (can be handy when trying to debug the parser
90        # itself).
91
92        spaces = ""
93        for (filename, line) in filename_stack[:-1]:
94            print "%sIn file included from %s:" % (spaces, filename)
95            spaces += "  "
96
97        # Print a Python stack backtrace if requested.
98        if print_traceback or not self.lineno:
99            traceback.print_exc()
100
101        line_str = "%s:" % (filename_stack[-1][0], )
102        if self.lineno:
103            line_str += "%d:" % (self.lineno, )
104
105        return "%s%s %s" % (spaces, line_str, self.string)
106
107    def exit(self, filename_stack, print_traceback=False):
108        # Just call exit.
109
110        sys.exit(self.display(filename_stack, print_traceback))
111
112def error(*args):
113    raise ISAParserError(*args)
114
115####################
116# Template objects.
117#
118# Template objects are format strings that allow substitution from
119# the attribute spaces of other objects (e.g. InstObjParams instances).
120
121labelRE = re.compile(r'(?<!%)%\(([^\)]+)\)[sd]')
122
123class Template(object):
124    def __init__(self, t):
125        self.template = t
126
127    def subst(self, d):
128        myDict = None
129
130        # Protect non-Python-dict substitutions (e.g. if there's a printf
131        # in the templated C++ code)
132        template = protect_non_subst_percents(self.template)
133        # CPU-model-specific substitutions are handled later (in GenCode).
134        template = protect_cpu_symbols(template)
135
136        # Build a dict ('myDict') to use for the template substitution.
137        # Start with the template namespace.  Make a copy since we're
138        # going to modify it.
139        myDict = parser.templateMap.copy()
140
141        if isinstance(d, InstObjParams):
142            # If we're dealing with an InstObjParams object, we need
143            # to be a little more sophisticated.  The instruction-wide
144            # parameters are already formed, but the parameters which
145            # are only function wide still need to be generated.
146            compositeCode = ''
147
148            myDict.update(d.__dict__)
149            # The "operands" and "snippets" attributes of the InstObjParams
150            # objects are for internal use and not substitution.
151            del myDict['operands']
152            del myDict['snippets']
153
154            snippetLabels = [l for l in labelRE.findall(template)
155                             if d.snippets.has_key(l)]
156
157            snippets = dict([(s, mungeSnippet(d.snippets[s]))
158                             for s in snippetLabels])
159
160            myDict.update(snippets)
161
162            compositeCode = ' '.join(map(str, snippets.values()))
163
164            # Add in template itself in case it references any
165            # operands explicitly (like Mem)
166            compositeCode += ' ' + template
167
168            operands = SubOperandList(compositeCode, d.operands)
169
170            myDict['op_decl'] = operands.concatAttrStrings('op_decl')
171
172            is_src = lambda op: op.is_src
173            is_dest = lambda op: op.is_dest
174
175            myDict['op_src_decl'] = \
176                      operands.concatSomeAttrStrings(is_src, 'op_src_decl')
177            myDict['op_dest_decl'] = \
178                      operands.concatSomeAttrStrings(is_dest, 'op_dest_decl')
179
180            myDict['op_rd'] = operands.concatAttrStrings('op_rd')
181            myDict['op_wb'] = operands.concatAttrStrings('op_wb')
182
183            if d.operands.memOperand:
184                myDict['mem_acc_size'] = d.operands.memOperand.mem_acc_size
185                myDict['mem_acc_type'] = d.operands.memOperand.mem_acc_type
186
187        elif isinstance(d, dict):
188            # if the argument is a dictionary, we just use it.
189            myDict.update(d)
190        elif hasattr(d, '__dict__'):
191            # if the argument is an object, we use its attribute map.
192            myDict.update(d.__dict__)
193        else:
194            raise TypeError, "Template.subst() arg must be or have dictionary"
195        return template % myDict
196
197    # Convert to string.  This handles the case when a template with a
198    # CPU-specific term gets interpolated into another template or into
199    # an output block.
200    def __str__(self):
201        return expand_cpu_symbols_to_string(self.template)
202
203################
204# Format object.
205#
206# A format object encapsulates an instruction format.  It must provide
207# a defineInst() method that generates the code for an instruction
208# definition.
209
210exportContextSymbols = ('InstObjParams', 'makeList', 're', 'string')
211
212exportContext = {}
213
214def updateExportContext():
215    exportContext.update(exportDict(*exportContextSymbols))
216    exportContext.update(parser.templateMap)
217
218def exportDict(*symNames):
219    return dict([(s, eval(s)) for s in symNames])
220
221
222class Format(object):
223    def __init__(self, id, params, code):
224        # constructor: just save away arguments
225        self.id = id
226        self.params = params
227        label = 'def format ' + id
228        self.user_code = compile(fixPythonIndentation(code), label, 'exec')
229        param_list = string.join(params, ", ")
230        f = '''def defInst(_code, _context, %s):
231                my_locals = vars().copy()
232                exec _code in _context, my_locals
233                return my_locals\n''' % param_list
234        c = compile(f, label + ' wrapper', 'exec')
235        exec c
236        self.func = defInst
237
238    def defineInst(self, name, args, lineno):
239        context = {}
240        updateExportContext()
241        context.update(exportContext)
242        if len(name):
243            Name = name[0].upper()
244            if len(name) > 1:
245                Name += name[1:]
246        context.update({ 'name': name, 'Name': Name })
247        try:
248            vars = self.func(self.user_code, context, *args[0], **args[1])
249        except Exception, exc:
250            error(lineno, 'error defining "%s": %s.' % (name, exc))
251        for k in vars.keys():
252            if k not in ('header_output', 'decoder_output',
253                         'exec_output', 'decode_block'):
254                del vars[k]
255        return GenCode(**vars)
256
257# Special null format to catch an implicit-format instruction
258# definition outside of any format block.
259class NoFormat(object):
260    def __init__(self):
261        self.defaultInst = ''
262
263    def defineInst(self, name, args, lineno):
264        error(lineno,
265              'instruction definition "%s" with no active format!' % name)
266
267# This dictionary maps format name strings to Format objects.
268formatMap = {}
269
270# Define a new format
271def defFormat(id, params, code, lineno):
272    # make sure we haven't already defined this one
273    if formatMap.get(id, None) != None:
274        error(lineno, 'format %s redefined.' % id)
275    # create new object and store in global map
276    formatMap[id] = Format(id, params, code)
277
278#####################################################################
279#
280#                           Support Classes
281#
282#####################################################################
283
284# Expand template with CPU-specific references into a dictionary with
285# an entry for each CPU model name.  The entry key is the model name
286# and the corresponding value is the template with the CPU-specific
287# refs substituted for that model.
288def expand_cpu_symbols_to_dict(template):
289    # Protect '%'s that don't go with CPU-specific terms
290    t = re.sub(r'%(?!\(CPU_)', '%%', template)
291    result = {}
292    for cpu in cpu_models:
293        result[cpu.name] = t % cpu.strings
294    return result
295
296# *If* the template has CPU-specific references, return a single
297# string containing a copy of the template for each CPU model with the
298# corresponding values substituted in.  If the template has no
299# CPU-specific references, it is returned unmodified.
300def expand_cpu_symbols_to_string(template):
301    if template.find('%(CPU_') != -1:
302        return reduce(lambda x,y: x+y,
303                      expand_cpu_symbols_to_dict(template).values())
304    else:
305        return template
306
307# Protect CPU-specific references by doubling the corresponding '%'s
308# (in preparation for substituting a different set of references into
309# the template).
310def protect_cpu_symbols(template):
311    return re.sub(r'%(?=\(CPU_)', '%%', template)
312
313# Protect any non-dict-substitution '%'s in a format string
314# (i.e. those not followed by '(')
315def protect_non_subst_percents(s):
316    return re.sub(r'%(?!\()', '%%', s)
317
318###############
319# GenCode class
320#
321# The GenCode class encapsulates generated code destined for various
322# output files.  The header_output and decoder_output attributes are
323# strings containing code destined for decoder.hh and decoder.cc
324# respectively.  The decode_block attribute contains code to be
325# incorporated in the decode function itself (that will also end up in
326# decoder.cc).  The exec_output attribute is a dictionary with a key
327# for each CPU model name; the value associated with a particular key
328# is the string of code for that CPU model's exec.cc file.  The
329# has_decode_default attribute is used in the decode block to allow
330# explicit default clauses to override default default clauses.
331
332class GenCode(object):
333    # Constructor.  At this point we substitute out all CPU-specific
334    # symbols.  For the exec output, these go into the per-model
335    # dictionary.  For all other output types they get collapsed into
336    # a single string.
337    def __init__(self,
338                 header_output = '', decoder_output = '', exec_output = '',
339                 decode_block = '', has_decode_default = False):
340        self.header_output = expand_cpu_symbols_to_string(header_output)
341        self.decoder_output = expand_cpu_symbols_to_string(decoder_output)
342        if isinstance(exec_output, dict):
343            self.exec_output = exec_output
344        elif isinstance(exec_output, str):
345            # If the exec_output arg is a single string, we replicate
346            # it for each of the CPU models, substituting and
347            # %(CPU_foo)s params appropriately.
348            self.exec_output = expand_cpu_symbols_to_dict(exec_output)
349        self.decode_block = expand_cpu_symbols_to_string(decode_block)
350        self.has_decode_default = has_decode_default
351
352    # Override '+' operator: generate a new GenCode object that
353    # concatenates all the individual strings in the operands.
354    def __add__(self, other):
355        exec_output = {}
356        for cpu in cpu_models:
357            n = cpu.name
358            exec_output[n] = self.exec_output[n] + other.exec_output[n]
359        return GenCode(self.header_output + other.header_output,
360                       self.decoder_output + other.decoder_output,
361                       exec_output,
362                       self.decode_block + other.decode_block,
363                       self.has_decode_default or other.has_decode_default)
364
365    # Prepend a string (typically a comment) to all the strings.
366    def prepend_all(self, pre):
367        self.header_output = pre + self.header_output
368        self.decoder_output  = pre + self.decoder_output
369        self.decode_block = pre + self.decode_block
370        for cpu in cpu_models:
371            self.exec_output[cpu.name] = pre + self.exec_output[cpu.name]
372
373    # Wrap the decode block in a pair of strings (e.g., 'case foo:'
374    # and 'break;').  Used to build the big nested switch statement.
375    def wrap_decode_block(self, pre, post = ''):
376        self.decode_block = pre + indent(self.decode_block) + post
377
378#####################################################################
379#
380#                      Bitfield Operator Support
381#
382#####################################################################
383
384bitOp1ArgRE = re.compile(r'<\s*(\w+)\s*:\s*>')
385
386bitOpWordRE = re.compile(r'(?<![\w\.])([\w\.]+)<\s*(\w+)\s*:\s*(\w+)\s*>')
387bitOpExprRE = re.compile(r'\)<\s*(\w+)\s*:\s*(\w+)\s*>')
388
389def substBitOps(code):
390    # first convert single-bit selectors to two-index form
391    # i.e., <n> --> <n:n>
392    code = bitOp1ArgRE.sub(r'<\1:\1>', code)
393    # simple case: selector applied to ID (name)
394    # i.e., foo<a:b> --> bits(foo, a, b)
395    code = bitOpWordRE.sub(r'bits(\1, \2, \3)', code)
396    # if selector is applied to expression (ending in ')'),
397    # we need to search backward for matching '('
398    match = bitOpExprRE.search(code)
399    while match:
400        exprEnd = match.start()
401        here = exprEnd - 1
402        nestLevel = 1
403        while nestLevel > 0:
404            if code[here] == '(':
405                nestLevel -= 1
406            elif code[here] == ')':
407                nestLevel += 1
408            here -= 1
409            if here < 0:
410                sys.exit("Didn't find '('!")
411        exprStart = here+1
412        newExpr = r'bits(%s, %s, %s)' % (code[exprStart:exprEnd+1],
413                                         match.group(1), match.group(2))
414        code = code[:exprStart] + newExpr + code[match.end():]
415        match = bitOpExprRE.search(code)
416    return code
417
418
419#####################################################################
420#
421#                             Code Parser
422#
423# The remaining code is the support for automatically extracting
424# instruction characteristics from pseudocode.
425#
426#####################################################################
427
428# Force the argument to be a list.  Useful for flags, where a caller
429# can specify a singleton flag or a list of flags.  Also usful for
430# converting tuples to lists so they can be modified.
431def makeList(arg):
432    if isinstance(arg, list):
433        return arg
434    elif isinstance(arg, tuple):
435        return list(arg)
436    elif not arg:
437        return []
438    else:
439        return [ arg ]
440
441# Generate operandTypeMap from the user's 'def operand_types'
442# statement.
443def buildOperandTypeMap(user_dict, lineno):
444    global operandTypeMap
445    operandTypeMap = {}
446    for (ext, (desc, size)) in user_dict.iteritems():
447        if desc == 'signed int':
448            ctype = 'int%d_t' % size
449            is_signed = 1
450        elif desc == 'unsigned int':
451            ctype = 'uint%d_t' % size
452            is_signed = 0
453        elif desc == 'float':
454            is_signed = 1       # shouldn't really matter
455            if size == 32:
456                ctype = 'float'
457            elif size == 64:
458                ctype = 'double'
459        elif desc == 'twin64 int':
460            is_signed = 0
461            ctype = 'Twin64_t'
462        elif desc == 'twin32 int':
463            is_signed = 0
464            ctype = 'Twin32_t'
465        if ctype == '':
466            error(lineno, 'Unrecognized type description "%s" in user_dict')
467        operandTypeMap[ext] = (size, ctype, is_signed)
468
469class Operand(object):
470    '''Base class for operand descriptors.  An instance of this class
471    (or actually a class derived from this one) represents a specific
472    operand for a code block (e.g, "Rc.sq" as a dest). Intermediate
473    derived classes encapsulates the traits of a particular operand
474    type (e.g., "32-bit integer register").'''
475
476    def buildReadCode(self, func = None):
477        code = self.read_code % {"name": self.base_name,
478                                 "func": func,
479                                 "op_idx": self.src_reg_idx,
480                                 "reg_idx": self.reg_spec,
481                                 "size": self.size,
482                                 "ctype": self.ctype}
483        if self.size != self.dflt_size:
484            return '%s = bits(%s, %d, 0);\n' % \
485                   (self.base_name, code, self.size-1)
486        else:
487            return '%s = %s;\n' % \
488                   (self.base_name, code)
489
490    def buildWriteCode(self, func = None):
491        if (self.size != self.dflt_size and self.is_signed):
492            final_val = 'sext<%d>(%s)' % (self.size, self.base_name)
493        else:
494            final_val = self.base_name
495        code = self.write_code % {"name": self.base_name,
496                                  "func": func,
497                                  "op_idx": self.dest_reg_idx,
498                                  "reg_idx": self.reg_spec,
499                                  "size": self.size,
500                                  "ctype": self.ctype,
501                                  "final_val": final_val}
502        return '''
503        {
504            %s final_val = %s;
505            %s;
506            if (traceData) { traceData->setData(final_val); }
507        }''' % (self.dflt_ctype, final_val, code)
508
509    def __init__(self, full_name, ext, is_src, is_dest):
510        self.full_name = full_name
511        self.ext = ext
512        self.is_src = is_src
513        self.is_dest = is_dest
514        # The 'effective extension' (eff_ext) is either the actual
515        # extension, if one was explicitly provided, or the default.
516        if ext:
517            self.eff_ext = ext
518        else:
519            self.eff_ext = self.dflt_ext
520
521        (self.size, self.ctype, self.is_signed) = operandTypeMap[self.eff_ext]
522
523        # note that mem_acc_size is undefined for non-mem operands...
524        # template must be careful not to use it if it doesn't apply.
525        if self.isMem():
526            self.mem_acc_size = self.makeAccSize()
527            if self.ctype in ['Twin32_t', 'Twin64_t']:
528                self.mem_acc_type = 'Twin'
529            else:
530                self.mem_acc_type = 'uint'
531
532    # Finalize additional fields (primarily code fields).  This step
533    # is done separately since some of these fields may depend on the
534    # register index enumeration that hasn't been performed yet at the
535    # time of __init__().
536    def finalize(self):
537        self.flags = self.getFlags()
538        self.constructor = self.makeConstructor()
539        self.op_decl = self.makeDecl()
540
541        if self.is_src:
542            self.op_rd = self.makeRead()
543            self.op_src_decl = self.makeDecl()
544        else:
545            self.op_rd = ''
546            self.op_src_decl = ''
547
548        if self.is_dest:
549            self.op_wb = self.makeWrite()
550            self.op_dest_decl = self.makeDecl()
551        else:
552            self.op_wb = ''
553            self.op_dest_decl = ''
554
555    def isMem(self):
556        return 0
557
558    def isReg(self):
559        return 0
560
561    def isFloatReg(self):
562        return 0
563
564    def isIntReg(self):
565        return 0
566
567    def isControlReg(self):
568        return 0
569
570    def getFlags(self):
571        # note the empty slice '[:]' gives us a copy of self.flags[0]
572        # instead of a reference to it
573        my_flags = self.flags[0][:]
574        if self.is_src:
575            my_flags += self.flags[1]
576        if self.is_dest:
577            my_flags += self.flags[2]
578        return my_flags
579
580    def makeDecl(self):
581        # Note that initializations in the declarations are solely
582        # to avoid 'uninitialized variable' errors from the compiler.
583        return self.ctype + ' ' + self.base_name + ' = 0;\n';
584
585class IntRegOperand(Operand):
586    def isReg(self):
587        return 1
588
589    def isIntReg(self):
590        return 1
591
592    def makeConstructor(self):
593        c = ''
594        if self.is_src:
595            c += '\n\t_srcRegIdx[%d] = %s;' % \
596                 (self.src_reg_idx, self.reg_spec)
597        if self.is_dest:
598            c += '\n\t_destRegIdx[%d] = %s;' % \
599                 (self.dest_reg_idx, self.reg_spec)
600        return c
601
602    def makeRead(self):
603        if (self.ctype == 'float' or self.ctype == 'double'):
604            error('Attempt to read integer register as FP')
605        if self.read_code != None:
606            return self.buildReadCode('readIntRegOperand')
607        if (self.size == self.dflt_size):
608            return '%s = xc->readIntRegOperand(this, %d);\n' % \
609                   (self.base_name, self.src_reg_idx)
610        elif (self.size > self.dflt_size):
611            int_reg_val = 'xc->readIntRegOperand(this, %d)' % \
612                          (self.src_reg_idx)
613            if (self.is_signed):
614                int_reg_val = 'sext<%d>(%s)' % (self.dflt_size, int_reg_val)
615            return '%s = %s;\n' % (self.base_name, int_reg_val)
616        else:
617            return '%s = bits(xc->readIntRegOperand(this, %d), %d, 0);\n' % \
618                   (self.base_name, self.src_reg_idx, self.size-1)
619
620    def makeWrite(self):
621        if (self.ctype == 'float' or self.ctype == 'double'):
622            error('Attempt to write integer register as FP')
623        if self.write_code != None:
624            return self.buildWriteCode('setIntRegOperand')
625        if (self.size != self.dflt_size and self.is_signed):
626            final_val = 'sext<%d>(%s)' % (self.size, self.base_name)
627        else:
628            final_val = self.base_name
629        wb = '''
630        {
631            %s final_val = %s;
632            xc->setIntRegOperand(this, %d, final_val);\n
633            if (traceData) { traceData->setData(final_val); }
634        }''' % (self.dflt_ctype, final_val, self.dest_reg_idx)
635        return wb
636
637class FloatRegOperand(Operand):
638    def isReg(self):
639        return 1
640
641    def isFloatReg(self):
642        return 1
643
644    def makeConstructor(self):
645        c = ''
646        if self.is_src:
647            c += '\n\t_srcRegIdx[%d] = %s + FP_Base_DepTag;' % \
648                 (self.src_reg_idx, self.reg_spec)
649        if self.is_dest:
650            c += '\n\t_destRegIdx[%d] = %s + FP_Base_DepTag;' % \
651                 (self.dest_reg_idx, self.reg_spec)
652        return c
653
654    def makeRead(self):
655        bit_select = 0
656        if (self.ctype == 'float' or self.ctype == 'double'):
657            func = 'readFloatRegOperand'
658        else:
659            func = 'readFloatRegOperandBits'
660            if (self.size != self.dflt_size):
661                bit_select = 1
662        base = 'xc->%s(this, %d)' % (func, self.src_reg_idx)
663        if self.read_code != None:
664            return self.buildReadCode(func)
665        if bit_select:
666            return '%s = bits(%s, %d, 0);\n' % \
667                   (self.base_name, base, self.size-1)
668        else:
669            return '%s = %s;\n' % (self.base_name, base)
670
671    def makeWrite(self):
672        final_val = self.base_name
673        final_ctype = self.ctype
674        if (self.ctype == 'float' or self.ctype == 'double'):
675            func = 'setFloatRegOperand'
676        elif (self.ctype == 'uint32_t' or self.ctype == 'uint64_t'):
677            func = 'setFloatRegOperandBits'
678        else:
679            func = 'setFloatRegOperandBits'
680            final_ctype = 'uint%d_t' % self.dflt_size
681            if (self.size != self.dflt_size and self.is_signed):
682                final_val = 'sext<%d>(%s)' % (self.size, self.base_name)
683        if self.write_code != None:
684            return self.buildWriteCode(func)
685        wb = '''
686        {
687            %s final_val = %s;
688            xc->%s(this, %d, final_val);\n
689            if (traceData) { traceData->setData(final_val); }
690        }''' % (final_ctype, final_val, func, self.dest_reg_idx)
691        return wb
692
693class ControlRegOperand(Operand):
694    def isReg(self):
695        return 1
696
697    def isControlReg(self):
698        return 1
699
700    def makeConstructor(self):
701        c = ''
702        if self.is_src:
703            c += '\n\t_srcRegIdx[%d] = %s + Ctrl_Base_DepTag;' % \
704                 (self.src_reg_idx, self.reg_spec)
705        if self.is_dest:
706            c += '\n\t_destRegIdx[%d] = %s + Ctrl_Base_DepTag;' % \
707                 (self.dest_reg_idx, self.reg_spec)
708        return c
709
710    def makeRead(self):
711        bit_select = 0
712        if (self.ctype == 'float' or self.ctype == 'double'):
713            error('Attempt to read control register as FP')
714        if self.read_code != None:
715            return self.buildReadCode('readMiscRegOperand')
716        base = 'xc->readMiscRegOperand(this, %s)' % self.src_reg_idx
717        if self.size == self.dflt_size:
718            return '%s = %s;\n' % (self.base_name, base)
719        else:
720            return '%s = bits(%s, %d, 0);\n' % \
721                   (self.base_name, base, self.size-1)
722
723    def makeWrite(self):
724        if (self.ctype == 'float' or self.ctype == 'double'):
725            error('Attempt to write control register as FP')
726        if self.write_code != None:
727            return self.buildWriteCode('setMiscRegOperand')
728        wb = 'xc->setMiscRegOperand(this, %s, %s);\n' % \
729             (self.dest_reg_idx, self.base_name)
730        wb += 'if (traceData) { traceData->setData(%s); }' % \
731              self.base_name
732        return wb
733
734class MemOperand(Operand):
735    def isMem(self):
736        return 1
737
738    def makeConstructor(self):
739        return ''
740
741    def makeDecl(self):
742        # Note that initializations in the declarations are solely
743        # to avoid 'uninitialized variable' errors from the compiler.
744        # Declare memory data variable.
745        if self.ctype in ['Twin32_t','Twin64_t']:
746            return "%s %s; %s.a = 0; %s.b = 0;\n" % \
747                   (self.ctype, self.base_name, self.base_name, self.base_name)
748        return '%s %s = 0;\n' % (self.ctype, self.base_name)
749
750    def makeRead(self):
751        if self.read_code != None:
752            return self.buildReadCode()
753        return ''
754
755    def makeWrite(self):
756        if self.write_code != None:
757            return self.buildWriteCode()
758        return ''
759
760    # Return the memory access size *in bits*, suitable for
761    # forming a type via "uint%d_t".  Divide by 8 if you want bytes.
762    def makeAccSize(self):
763        return self.size
764
765class PCOperand(Operand):
766    def makeConstructor(self):
767        return ''
768
769    def makeRead(self):
770        return '%s = xc->readPC();\n' % self.base_name
771
772    def makeWrite(self):
773        return 'xc->setPC(%s);\n' % self.base_name
774
775class UPCOperand(Operand):
776    def makeConstructor(self):
777        return ''
778
779    def makeRead(self):
780        if self.read_code != None:
781            return self.buildReadCode('readMicroPC')
782        return '%s = xc->readMicroPC();\n' % self.base_name
783
784    def makeWrite(self):
785        if self.write_code != None:
786            return self.buildWriteCode('setMicroPC')
787        return 'xc->setMicroPC(%s);\n' % self.base_name
788
789class NUPCOperand(Operand):
790    def makeConstructor(self):
791        return ''
792
793    def makeRead(self):
794        if self.read_code != None:
795            return self.buildReadCode('readNextMicroPC')
796        return '%s = xc->readNextMicroPC();\n' % self.base_name
797
798    def makeWrite(self):
799        if self.write_code != None:
800            return self.buildWriteCode('setNextMicroPC')
801        return 'xc->setNextMicroPC(%s);\n' % self.base_name
802
803class NPCOperand(Operand):
804    def makeConstructor(self):
805        return ''
806
807    def makeRead(self):
808        if self.read_code != None:
809            return self.buildReadCode('readNextPC')
810        return '%s = xc->readNextPC();\n' % self.base_name
811
812    def makeWrite(self):
813        if self.write_code != None:
814            return self.buildWriteCode('setNextPC')
815        return 'xc->setNextPC(%s);\n' % self.base_name
816
817class NNPCOperand(Operand):
818    def makeConstructor(self):
819        return ''
820
821    def makeRead(self):
822        if self.read_code != None:
823            return self.buildReadCode('readNextNPC')
824        return '%s = xc->readNextNPC();\n' % self.base_name
825
826    def makeWrite(self):
827        if self.write_code != None:
828            return self.buildWriteCode('setNextNPC')
829        return 'xc->setNextNPC(%s);\n' % self.base_name
830
831def buildOperandNameMap(user_dict, lineno):
832    global operandNameMap
833    operandNameMap = {}
834    for (op_name, val) in user_dict.iteritems():
835        (base_cls_name, dflt_ext, reg_spec, flags, sort_pri) = val[:5]
836        if len(val) > 5:
837            read_code = val[5]
838        else:
839            read_code = None
840        if len(val) > 6:
841            write_code = val[6]
842        else:
843            write_code = None
844        if len(val) > 7:
845            error(lineno,
846                  'error: too many attributes for operand "%s"' %
847                  base_cls_name)
848
849        (dflt_size, dflt_ctype, dflt_is_signed) = operandTypeMap[dflt_ext]
850        # Canonical flag structure is a triple of lists, where each list
851        # indicates the set of flags implied by this operand always, when
852        # used as a source, and when used as a dest, respectively.
853        # For simplicity this can be initialized using a variety of fairly
854        # obvious shortcuts; we convert these to canonical form here.
855        if not flags:
856            # no flags specified (e.g., 'None')
857            flags = ( [], [], [] )
858        elif isinstance(flags, str):
859            # a single flag: assumed to be unconditional
860            flags = ( [ flags ], [], [] )
861        elif isinstance(flags, list):
862            # a list of flags: also assumed to be unconditional
863            flags = ( flags, [], [] )
864        elif isinstance(flags, tuple):
865            # it's a tuple: it should be a triple,
866            # but each item could be a single string or a list
867            (uncond_flags, src_flags, dest_flags) = flags
868            flags = (makeList(uncond_flags),
869                     makeList(src_flags), makeList(dest_flags))
870        # Accumulate attributes of new operand class in tmp_dict
871        tmp_dict = {}
872        for attr in ('dflt_ext', 'reg_spec', 'flags', 'sort_pri',
873                     'dflt_size', 'dflt_ctype', 'dflt_is_signed',
874                     'read_code', 'write_code'):
875            tmp_dict[attr] = eval(attr)
876        tmp_dict['base_name'] = op_name
877        # New class name will be e.g. "IntReg_Ra"
878        cls_name = base_cls_name + '_' + op_name
879        # Evaluate string arg to get class object.  Note that the
880        # actual base class for "IntReg" is "IntRegOperand", i.e. we
881        # have to append "Operand".
882        try:
883            base_cls = eval(base_cls_name + 'Operand')
884        except NameError:
885            error(lineno,
886                  'error: unknown operand base class "%s"' % base_cls_name)
887        # The following statement creates a new class called
888        # <cls_name> as a subclass of <base_cls> with the attributes
889        # in tmp_dict, just as if we evaluated a class declaration.
890        operandNameMap[op_name] = type(cls_name, (base_cls,), tmp_dict)
891
892    # Define operand variables.
893    operands = user_dict.keys()
894
895    operandsREString = (r'''
896    (?<![\w\.])      # neg. lookbehind assertion: prevent partial matches
897    ((%s)(?:\.(\w+))?)   # match: operand with optional '.' then suffix
898    (?![\w\.])       # neg. lookahead assertion: prevent partial matches
899    '''
900                        % string.join(operands, '|'))
901
902    global operandsRE
903    operandsRE = re.compile(operandsREString, re.MULTILINE|re.VERBOSE)
904
905    # Same as operandsREString, but extension is mandatory, and only two
906    # groups are returned (base and ext, not full name as above).
907    # Used for subtituting '_' for '.' to make C++ identifiers.
908    operandsWithExtREString = (r'(?<![\w\.])(%s)\.(\w+)(?![\w\.])'
909                               % string.join(operands, '|'))
910
911    global operandsWithExtRE
912    operandsWithExtRE = re.compile(operandsWithExtREString, re.MULTILINE)
913
914maxInstSrcRegs = 0
915maxInstDestRegs = 0
916
917class OperandList(object):
918    '''Find all the operands in the given code block.  Returns an operand
919    descriptor list (instance of class OperandList).'''
920    def __init__(self, code):
921        self.items = []
922        self.bases = {}
923        # delete comments so we don't match on reg specifiers inside
924        code = commentRE.sub('', code)
925        # search for operands
926        next_pos = 0
927        while 1:
928            match = operandsRE.search(code, next_pos)
929            if not match:
930                # no more matches: we're done
931                break
932            op = match.groups()
933            # regexp groups are operand full name, base, and extension
934            (op_full, op_base, op_ext) = op
935            # if the token following the operand is an assignment, this is
936            # a destination (LHS), else it's a source (RHS)
937            is_dest = (assignRE.match(code, match.end()) != None)
938            is_src = not is_dest
939            # see if we've already seen this one
940            op_desc = self.find_base(op_base)
941            if op_desc:
942                if op_desc.ext != op_ext:
943                    error('Inconsistent extensions for operand %s' % \
944                          op_base)
945                op_desc.is_src = op_desc.is_src or is_src
946                op_desc.is_dest = op_desc.is_dest or is_dest
947            else:
948                # new operand: create new descriptor
949                op_desc = operandNameMap[op_base](op_full, op_ext,
950                                                  is_src, is_dest)
951                self.append(op_desc)
952            # start next search after end of current match
953            next_pos = match.end()
954        self.sort()
955        # enumerate source & dest register operands... used in building
956        # constructor later
957        self.numSrcRegs = 0
958        self.numDestRegs = 0
959        self.numFPDestRegs = 0
960        self.numIntDestRegs = 0
961        self.memOperand = None
962        for op_desc in self.items:
963            if op_desc.isReg():
964                if op_desc.is_src:
965                    op_desc.src_reg_idx = self.numSrcRegs
966                    self.numSrcRegs += 1
967                if op_desc.is_dest:
968                    op_desc.dest_reg_idx = self.numDestRegs
969                    self.numDestRegs += 1
970                    if op_desc.isFloatReg():
971                        self.numFPDestRegs += 1
972                    elif op_desc.isIntReg():
973                        self.numIntDestRegs += 1
974            elif op_desc.isMem():
975                if self.memOperand:
976                    error("Code block has more than one memory operand.")
977                self.memOperand = op_desc
978        global maxInstSrcRegs
979        global maxInstDestRegs
980        if maxInstSrcRegs < self.numSrcRegs:
981            maxInstSrcRegs = self.numSrcRegs
982        if maxInstDestRegs < self.numDestRegs:
983            maxInstDestRegs = self.numDestRegs
984        # now make a final pass to finalize op_desc fields that may depend
985        # on the register enumeration
986        for op_desc in self.items:
987            op_desc.finalize()
988
989    def __len__(self):
990        return len(self.items)
991
992    def __getitem__(self, index):
993        return self.items[index]
994
995    def append(self, op_desc):
996        self.items.append(op_desc)
997        self.bases[op_desc.base_name] = op_desc
998
999    def find_base(self, base_name):
1000        # like self.bases[base_name], but returns None if not found
1001        # (rather than raising exception)
1002        return self.bases.get(base_name)
1003
1004    # internal helper function for concat[Some]Attr{Strings|Lists}
1005    def __internalConcatAttrs(self, attr_name, filter, result):
1006        for op_desc in self.items:
1007            if filter(op_desc):
1008                result += getattr(op_desc, attr_name)
1009        return result
1010
1011    # return a single string that is the concatenation of the (string)
1012    # values of the specified attribute for all operands
1013    def concatAttrStrings(self, attr_name):
1014        return self.__internalConcatAttrs(attr_name, lambda x: 1, '')
1015
1016    # like concatAttrStrings, but only include the values for the operands
1017    # for which the provided filter function returns true
1018    def concatSomeAttrStrings(self, filter, attr_name):
1019        return self.__internalConcatAttrs(attr_name, filter, '')
1020
1021    # return a single list that is the concatenation of the (list)
1022    # values of the specified attribute for all operands
1023    def concatAttrLists(self, attr_name):
1024        return self.__internalConcatAttrs(attr_name, lambda x: 1, [])
1025
1026    # like concatAttrLists, but only include the values for the operands
1027    # for which the provided filter function returns true
1028    def concatSomeAttrLists(self, filter, attr_name):
1029        return self.__internalConcatAttrs(attr_name, filter, [])
1030
1031    def sort(self):
1032        self.items.sort(lambda a, b: a.sort_pri - b.sort_pri)
1033
1034class SubOperandList(OperandList):
1035    '''Find all the operands in the given code block.  Returns an operand
1036    descriptor list (instance of class OperandList).'''
1037    def __init__(self, code, master_list):
1038        self.items = []
1039        self.bases = {}
1040        # delete comments so we don't match on reg specifiers inside
1041        code = commentRE.sub('', code)
1042        # search for operands
1043        next_pos = 0
1044        while 1:
1045            match = operandsRE.search(code, next_pos)
1046            if not match:
1047                # no more matches: we're done
1048                break
1049            op = match.groups()
1050            # regexp groups are operand full name, base, and extension
1051            (op_full, op_base, op_ext) = op
1052            # find this op in the master list
1053            op_desc = master_list.find_base(op_base)
1054            if not op_desc:
1055                error('Found operand %s which is not in the master list!' \
1056                      ' This is an internal error' % op_base)
1057            else:
1058                # See if we've already found this operand
1059                op_desc = self.find_base(op_base)
1060                if not op_desc:
1061                    # if not, add a reference to it to this sub list
1062                    self.append(master_list.bases[op_base])
1063
1064            # start next search after end of current match
1065            next_pos = match.end()
1066        self.sort()
1067        self.memOperand = None
1068        for op_desc in self.items:
1069            if op_desc.isMem():
1070                if self.memOperand:
1071                    error("Code block has more than one memory operand.")
1072                self.memOperand = op_desc
1073
1074# Regular expression object to match C++ comments
1075# (used in findOperands())
1076commentRE = re.compile(r'//.*\n')
1077
1078# Regular expression object to match assignment statements
1079# (used in findOperands())
1080assignRE = re.compile(r'\s*=(?!=)', re.MULTILINE)
1081
1082# Munge operand names in code string to make legal C++ variable names.
1083# This means getting rid of the type extension if any.
1084# (Will match base_name attribute of Operand object.)
1085def substMungedOpNames(code):
1086    return operandsWithExtRE.sub(r'\1', code)
1087
1088# Fix up code snippets for final substitution in templates.
1089def mungeSnippet(s):
1090    if isinstance(s, str):
1091        return substMungedOpNames(substBitOps(s))
1092    else:
1093        return s
1094
1095def makeFlagConstructor(flag_list):
1096    if len(flag_list) == 0:
1097        return ''
1098    # filter out repeated flags
1099    flag_list.sort()
1100    i = 1
1101    while i < len(flag_list):
1102        if flag_list[i] == flag_list[i-1]:
1103            del flag_list[i]
1104        else:
1105            i += 1
1106    pre = '\n\tflags['
1107    post = '] = true;'
1108    code = pre + string.join(flag_list, post + pre) + post
1109    return code
1110
1111# Assume all instruction flags are of the form 'IsFoo'
1112instFlagRE = re.compile(r'Is.*')
1113
1114# OpClass constants end in 'Op' except No_OpClass
1115opClassRE = re.compile(r'.*Op|No_OpClass')
1116
1117class InstObjParams(object):
1118    def __init__(self, mnem, class_name, base_class = '',
1119                 snippets = {}, opt_args = []):
1120        self.mnemonic = mnem
1121        self.class_name = class_name
1122        self.base_class = base_class
1123        if not isinstance(snippets, dict):
1124            snippets = {'code' : snippets}
1125        compositeCode = ' '.join(map(str, snippets.values()))
1126        self.snippets = snippets
1127
1128        self.operands = OperandList(compositeCode)
1129        self.constructor = self.operands.concatAttrStrings('constructor')
1130        self.constructor += \
1131                 '\n\t_numSrcRegs = %d;' % self.operands.numSrcRegs
1132        self.constructor += \
1133                 '\n\t_numDestRegs = %d;' % self.operands.numDestRegs
1134        self.constructor += \
1135                 '\n\t_numFPDestRegs = %d;' % self.operands.numFPDestRegs
1136        self.constructor += \
1137                 '\n\t_numIntDestRegs = %d;' % self.operands.numIntDestRegs
1138        self.flags = self.operands.concatAttrLists('flags')
1139
1140        # Make a basic guess on the operand class (function unit type).
1141        # These are good enough for most cases, and can be overridden
1142        # later otherwise.
1143        if 'IsStore' in self.flags:
1144            self.op_class = 'MemWriteOp'
1145        elif 'IsLoad' in self.flags or 'IsPrefetch' in self.flags:
1146            self.op_class = 'MemReadOp'
1147        elif 'IsFloating' in self.flags:
1148            self.op_class = 'FloatAddOp'
1149        else:
1150            self.op_class = 'IntAluOp'
1151
1152        # Optional arguments are assumed to be either StaticInst flags
1153        # or an OpClass value.  To avoid having to import a complete
1154        # list of these values to match against, we do it ad-hoc
1155        # with regexps.
1156        for oa in opt_args:
1157            if instFlagRE.match(oa):
1158                self.flags.append(oa)
1159            elif opClassRE.match(oa):
1160                self.op_class = oa
1161            else:
1162                error('InstObjParams: optional arg "%s" not recognized '
1163                      'as StaticInst::Flag or OpClass.' % oa)
1164
1165        # add flag initialization to contructor here to include
1166        # any flags added via opt_args
1167        self.constructor += makeFlagConstructor(self.flags)
1168
1169        # if 'IsFloating' is set, add call to the FP enable check
1170        # function (which should be provided by isa_desc via a declare)
1171        if 'IsFloating' in self.flags:
1172            self.fp_enable_check = 'fault = checkFpEnableFault(xc);'
1173        else:
1174            self.fp_enable_check = ''
1175
1176##############
1177# Stack: a simple stack object.  Used for both formats (formatStack)
1178# and default cases (defaultStack).  Simply wraps a list to give more
1179# stack-like syntax and enable initialization with an argument list
1180# (as opposed to an argument that's a list).
1181
1182class Stack(list):
1183    def __init__(self, *items):
1184        list.__init__(self, items)
1185
1186    def push(self, item):
1187        self.append(item);
1188
1189    def top(self):
1190        return self[-1]
1191
1192# The global format stack.
1193formatStack = Stack(NoFormat())
1194
1195# The global default case stack.
1196defaultStack = Stack(None)
1197
1198# Global stack that tracks current file and line number.
1199# Each element is a tuple (filename, lineno) that records the
1200# *current* filename and the line number in the *previous* file where
1201# it was included.
1202fileNameStack = Stack()
1203
1204
1205#######################
1206#
1207# Output file template
1208#
1209
1210file_template = '''
1211/*
1212 * DO NOT EDIT THIS FILE!!!
1213 *
1214 * It was automatically generated from the ISA description in %(filename)s
1215 */
1216
1217%(includes)s
1218
1219%(global_output)s
1220
1221namespace %(namespace)s {
1222
1223%(namespace_output)s
1224
1225} // namespace %(namespace)s
1226
1227%(decode_function)s
1228'''
1229
1230max_inst_regs_template = '''
1231/*
1232 * DO NOT EDIT THIS FILE!!!
1233 *
1234 * It was automatically generated from the ISA description in %(filename)s
1235 */
1236
1237namespace %(namespace)s {
1238
1239    const int MaxInstSrcRegs = %(MaxInstSrcRegs)d;
1240    const int MaxInstDestRegs = %(MaxInstDestRegs)d;
1241
1242} // namespace %(namespace)s
1243
1244'''
1245
1246class ISAParser(Grammar):
1247    def __init__(self, output_dir):
1248        super(ISAParser, self).__init__()
1249        self.output_dir = output_dir
1250
1251        self.templateMap = {}
1252
1253    #####################################################################
1254    #
1255    #                                Lexer
1256    #
1257    # The PLY lexer module takes two things as input:
1258    # - A list of token names (the string list 'tokens')
1259    # - A regular expression describing a match for each token.  The
1260    #   regexp for token FOO can be provided in two ways:
1261    #   - as a string variable named t_FOO
1262    #   - as the doc string for a function named t_FOO.  In this case,
1263    #     the function is also executed, allowing an action to be
1264    #     associated with each token match.
1265    #
1266    #####################################################################
1267
1268    # Reserved words.  These are listed separately as they are matched
1269    # using the same regexp as generic IDs, but distinguished in the
1270    # t_ID() function.  The PLY documentation suggests this approach.
1271    reserved = (
1272        'BITFIELD', 'DECODE', 'DECODER', 'DEFAULT', 'DEF', 'EXEC', 'FORMAT',
1273        'HEADER', 'LET', 'NAMESPACE', 'OPERAND_TYPES', 'OPERANDS',
1274        'OUTPUT', 'SIGNED', 'TEMPLATE'
1275        )
1276
1277    # List of tokens.  The lex module requires this.
1278    tokens = reserved + (
1279        # identifier
1280        'ID',
1281
1282        # integer literal
1283        'INTLIT',
1284
1285        # string literal
1286        'STRLIT',
1287
1288        # code literal
1289        'CODELIT',
1290
1291        # ( ) [ ] { } < > , ; . : :: *
1292        'LPAREN', 'RPAREN',
1293        'LBRACKET', 'RBRACKET',
1294        'LBRACE', 'RBRACE',
1295        'LESS', 'GREATER', 'EQUALS',
1296        'COMMA', 'SEMI', 'DOT', 'COLON', 'DBLCOLON',
1297        'ASTERISK',
1298
1299        # C preprocessor directives
1300        'CPPDIRECTIVE'
1301
1302    # The following are matched but never returned. commented out to
1303    # suppress PLY warning
1304        # newfile directive
1305    #    'NEWFILE',
1306
1307        # endfile directive
1308    #    'ENDFILE'
1309    )
1310
1311    # Regular expressions for token matching
1312    t_LPAREN           = r'\('
1313    t_RPAREN           = r'\)'
1314    t_LBRACKET         = r'\['
1315    t_RBRACKET         = r'\]'
1316    t_LBRACE           = r'\{'
1317    t_RBRACE           = r'\}'
1318    t_LESS             = r'\<'
1319    t_GREATER          = r'\>'
1320    t_EQUALS           = r'='
1321    t_COMMA            = r','
1322    t_SEMI             = r';'
1323    t_DOT              = r'\.'
1324    t_COLON            = r':'
1325    t_DBLCOLON         = r'::'
1326    t_ASTERISK         = r'\*'
1327
1328    # Identifiers and reserved words
1329    reserved_map = { }
1330    for r in reserved:
1331        reserved_map[r.lower()] = r
1332
1333    def t_ID(self, t):
1334        r'[A-Za-z_]\w*'
1335        t.type = self.reserved_map.get(t.value, 'ID')
1336        return t
1337
1338    # Integer literal
1339    def t_INTLIT(self, t):
1340        r'-?(0x[\da-fA-F]+)|\d+'
1341        try:
1342            t.value = int(t.value,0)
1343        except ValueError:
1344            error(t, 'Integer value "%s" too large' % t.value)
1345            t.value = 0
1346        return t
1347
1348    # String literal.  Note that these use only single quotes, and
1349    # can span multiple lines.
1350    def t_STRLIT(self, t):
1351        r"(?m)'([^'])+'"
1352        # strip off quotes
1353        t.value = t.value[1:-1]
1354        t.lexer.lineno += t.value.count('\n')
1355        return t
1356
1357
1358    # "Code literal"... like a string literal, but delimiters are
1359    # '{{' and '}}' so they get formatted nicely under emacs c-mode
1360    def t_CODELIT(self, t):
1361        r"(?m)\{\{([^\}]|}(?!\}))+\}\}"
1362        # strip off {{ & }}
1363        t.value = t.value[2:-2]
1364        t.lexer.lineno += t.value.count('\n')
1365        return t
1366
1367    def t_CPPDIRECTIVE(self, t):
1368        r'^\#[^\#].*\n'
1369        t.lexer.lineno += t.value.count('\n')
1370        return t
1371
1372    def t_NEWFILE(self, t):
1373        r'^\#\#newfile\s+"[\w/.-]*"'
1374        fileNameStack.push((t.value[11:-1], t.lexer.lineno))
1375        t.lexer.lineno = 0
1376
1377    def t_ENDFILE(self, t):
1378        r'^\#\#endfile'
1379        (old_filename, t.lexer.lineno) = fileNameStack.pop()
1380
1381    #
1382    # The functions t_NEWLINE, t_ignore, and t_error are
1383    # special for the lex module.
1384    #
1385
1386    # Newlines
1387    def t_NEWLINE(self, t):
1388        r'\n+'
1389        t.lexer.lineno += t.value.count('\n')
1390
1391    # Comments
1392    def t_comment(self, t):
1393        r'//.*'
1394
1395    # Completely ignored characters
1396    t_ignore = ' \t\x0c'
1397
1398    # Error handler
1399    def t_error(self, t):
1400        error(t, "illegal character '%s'" % t.value[0])
1401        t.skip(1)
1402
1403    #####################################################################
1404    #
1405    #                                Parser
1406    #
1407    # Every function whose name starts with 'p_' defines a grammar
1408    # rule.  The rule is encoded in the function's doc string, while
1409    # the function body provides the action taken when the rule is
1410    # matched.  The argument to each function is a list of the values
1411    # of the rule's symbols: t[0] for the LHS, and t[1..n] for the
1412    # symbols on the RHS.  For tokens, the value is copied from the
1413    # t.value attribute provided by the lexer.  For non-terminals, the
1414    # value is assigned by the producing rule; i.e., the job of the
1415    # grammar rule function is to set the value for the non-terminal
1416    # on the LHS (by assigning to t[0]).
1417    #####################################################################
1418
1419    # The LHS of the first grammar rule is used as the start symbol
1420    # (in this case, 'specification').  Note that this rule enforces
1421    # that there will be exactly one namespace declaration, with 0 or
1422    # more global defs/decls before and after it.  The defs & decls
1423    # before the namespace decl will be outside the namespace; those
1424    # after will be inside.  The decoder function is always inside the
1425    # namespace.
1426    def p_specification(self, t):
1427        'specification : opt_defs_and_outputs name_decl opt_defs_and_outputs decode_block'
1428        global_code = t[1]
1429        isa_name = t[2]
1430        namespace = isa_name + "Inst"
1431        # wrap the decode block as a function definition
1432        t[4].wrap_decode_block('''
1433StaticInstPtr
1434%(isa_name)s::decodeInst(%(isa_name)s::ExtMachInst machInst)
1435{
1436    using namespace %(namespace)s;
1437''' % vars(), '}')
1438        # both the latter output blocks and the decode block are in
1439        # the namespace
1440        namespace_code = t[3] + t[4]
1441        # pass it all back to the caller of yacc.parse()
1442        t[0] = (isa_name, namespace, global_code, namespace_code)
1443
1444    # ISA name declaration looks like "namespace <foo>;"
1445    def p_name_decl(self, t):
1446        'name_decl : NAMESPACE ID SEMI'
1447        t[0] = t[2]
1448
1449    # 'opt_defs_and_outputs' is a possibly empty sequence of
1450    # def and/or output statements.
1451    def p_opt_defs_and_outputs_0(self, t):
1452        'opt_defs_and_outputs : empty'
1453        t[0] = GenCode()
1454
1455    def p_opt_defs_and_outputs_1(self, t):
1456        'opt_defs_and_outputs : defs_and_outputs'
1457        t[0] = t[1]
1458
1459    def p_defs_and_outputs_0(self, t):
1460        'defs_and_outputs : def_or_output'
1461        t[0] = t[1]
1462
1463    def p_defs_and_outputs_1(self, t):
1464        'defs_and_outputs : defs_and_outputs def_or_output'
1465        t[0] = t[1] + t[2]
1466
1467    # The list of possible definition/output statements.
1468    def p_def_or_output(self, t):
1469        '''def_or_output : def_format
1470                         | def_bitfield
1471                         | def_bitfield_struct
1472                         | def_template
1473                         | def_operand_types
1474                         | def_operands
1475                         | output_header
1476                         | output_decoder
1477                         | output_exec
1478                         | global_let'''
1479        t[0] = t[1]
1480
1481    # Output blocks 'output <foo> {{...}}' (C++ code blocks) are copied
1482    # directly to the appropriate output section.
1483
1484    # Massage output block by substituting in template definitions and
1485    # bit operators.  We handle '%'s embedded in the string that don't
1486    # indicate template substitutions (or CPU-specific symbols, which
1487    # get handled in GenCode) by doubling them first so that the
1488    # format operation will reduce them back to single '%'s.
1489    def process_output(self, s):
1490        s = protect_non_subst_percents(s)
1491        # protects cpu-specific symbols too
1492        s = protect_cpu_symbols(s)
1493        return substBitOps(s % self.templateMap)
1494
1495    def p_output_header(self, t):
1496        'output_header : OUTPUT HEADER CODELIT SEMI'
1497        t[0] = GenCode(header_output = self.process_output(t[3]))
1498
1499    def p_output_decoder(self, t):
1500        'output_decoder : OUTPUT DECODER CODELIT SEMI'
1501        t[0] = GenCode(decoder_output = self.process_output(t[3]))
1502
1503    def p_output_exec(self, t):
1504        'output_exec : OUTPUT EXEC CODELIT SEMI'
1505        t[0] = GenCode(exec_output = self.process_output(t[3]))
1506
1507    # global let blocks 'let {{...}}' (Python code blocks) are
1508    # executed directly when seen.  Note that these execute in a
1509    # special variable context 'exportContext' to prevent the code
1510    # from polluting this script's namespace.
1511    def p_global_let(self, t):
1512        'global_let : LET CODELIT SEMI'
1513        updateExportContext()
1514        exportContext["header_output"] = ''
1515        exportContext["decoder_output"] = ''
1516        exportContext["exec_output"] = ''
1517        exportContext["decode_block"] = ''
1518        try:
1519            exec fixPythonIndentation(t[2]) in exportContext
1520        except Exception, exc:
1521            error(t, 'error: %s in global let block "%s".' % (exc, t[2]))
1522        t[0] = GenCode(header_output = exportContext["header_output"],
1523                       decoder_output = exportContext["decoder_output"],
1524                       exec_output = exportContext["exec_output"],
1525                       decode_block = exportContext["decode_block"])
1526
1527    # Define the mapping from operand type extensions to C++ types and
1528    # bit widths (stored in operandTypeMap).
1529    def p_def_operand_types(self, t):
1530        'def_operand_types : DEF OPERAND_TYPES CODELIT SEMI'
1531        try:
1532            user_dict = eval('{' + t[3] + '}')
1533        except Exception, exc:
1534            error(t,
1535                  'error: %s in def operand_types block "%s".' % (exc, t[3]))
1536        buildOperandTypeMap(user_dict, t.lexer.lineno)
1537        t[0] = GenCode() # contributes nothing to the output C++ file
1538
1539    # Define the mapping from operand names to operand classes and
1540    # other traits.  Stored in operandNameMap.
1541    def p_def_operands(self, t):
1542        'def_operands : DEF OPERANDS CODELIT SEMI'
1543        if not globals().has_key('operandTypeMap'):
1544            error(t, 'error: operand types must be defined before operands')
1545        try:
1546            user_dict = eval('{' + t[3] + '}', exportContext)
1547        except Exception, exc:
1548            error(t, 'error: %s in def operands block "%s".' % (exc, t[3]))
1549        buildOperandNameMap(user_dict, t.lexer.lineno)
1550        t[0] = GenCode() # contributes nothing to the output C++ file
1551
1552    # A bitfield definition looks like:
1553    # 'def [signed] bitfield <ID> [<first>:<last>]'
1554    # This generates a preprocessor macro in the output file.
1555    def p_def_bitfield_0(self, t):
1556        'def_bitfield : DEF opt_signed BITFIELD ID LESS INTLIT COLON INTLIT GREATER SEMI'
1557        expr = 'bits(machInst, %2d, %2d)' % (t[6], t[8])
1558        if (t[2] == 'signed'):
1559            expr = 'sext<%d>(%s)' % (t[6] - t[8] + 1, expr)
1560        hash_define = '#undef %s\n#define %s\t%s\n' % (t[4], t[4], expr)
1561        t[0] = GenCode(header_output = hash_define)
1562
1563    # alternate form for single bit: 'def [signed] bitfield <ID> [<bit>]'
1564    def p_def_bitfield_1(self, t):
1565        'def_bitfield : DEF opt_signed BITFIELD ID LESS INTLIT GREATER SEMI'
1566        expr = 'bits(machInst, %2d, %2d)' % (t[6], t[6])
1567        if (t[2] == 'signed'):
1568            expr = 'sext<%d>(%s)' % (1, expr)
1569        hash_define = '#undef %s\n#define %s\t%s\n' % (t[4], t[4], expr)
1570        t[0] = GenCode(header_output = hash_define)
1571
1572    # alternate form for structure member: 'def bitfield <ID> <ID>'
1573    def p_def_bitfield_struct(self, t):
1574        'def_bitfield_struct : DEF opt_signed BITFIELD ID id_with_dot SEMI'
1575        if (t[2] != ''):
1576            error(t, 'error: structure bitfields are always unsigned.')
1577        expr = 'machInst.%s' % t[5]
1578        hash_define = '#undef %s\n#define %s\t%s\n' % (t[4], t[4], expr)
1579        t[0] = GenCode(header_output = hash_define)
1580
1581    def p_id_with_dot_0(self, t):
1582        'id_with_dot : ID'
1583        t[0] = t[1]
1584
1585    def p_id_with_dot_1(self, t):
1586        'id_with_dot : ID DOT id_with_dot'
1587        t[0] = t[1] + t[2] + t[3]
1588
1589    def p_opt_signed_0(self, t):
1590        'opt_signed : SIGNED'
1591        t[0] = t[1]
1592
1593    def p_opt_signed_1(self, t):
1594        'opt_signed : empty'
1595        t[0] = ''
1596
1597    def p_def_template(self, t):
1598        'def_template : DEF TEMPLATE ID CODELIT SEMI'
1599        self.templateMap[t[3]] = Template(t[4])
1600        t[0] = GenCode()
1601
1602    # An instruction format definition looks like
1603    # "def format <fmt>(<params>) {{...}};"
1604    def p_def_format(self, t):
1605        'def_format : DEF FORMAT ID LPAREN param_list RPAREN CODELIT SEMI'
1606        (id, params, code) = (t[3], t[5], t[7])
1607        defFormat(id, params, code, t.lexer.lineno)
1608        t[0] = GenCode()
1609
1610    # The formal parameter list for an instruction format is a
1611    # possibly empty list of comma-separated parameters.  Positional
1612    # (standard, non-keyword) parameters must come first, followed by
1613    # keyword parameters, followed by a '*foo' parameter that gets
1614    # excess positional arguments (as in Python).  Each of these three
1615    # parameter categories is optional.
1616    #
1617    # Note that we do not support the '**foo' parameter for collecting
1618    # otherwise undefined keyword args.  Otherwise the parameter list
1619    # is (I believe) identical to what is supported in Python.
1620    #
1621    # The param list generates a tuple, where the first element is a
1622    # list of the positional params and the second element is a dict
1623    # containing the keyword params.
1624    def p_param_list_0(self, t):
1625        'param_list : positional_param_list COMMA nonpositional_param_list'
1626        t[0] = t[1] + t[3]
1627
1628    def p_param_list_1(self, t):
1629        '''param_list : positional_param_list
1630                      | nonpositional_param_list'''
1631        t[0] = t[1]
1632
1633    def p_positional_param_list_0(self, t):
1634        'positional_param_list : empty'
1635        t[0] = []
1636
1637    def p_positional_param_list_1(self, t):
1638        'positional_param_list : ID'
1639        t[0] = [t[1]]
1640
1641    def p_positional_param_list_2(self, t):
1642        'positional_param_list : positional_param_list COMMA ID'
1643        t[0] = t[1] + [t[3]]
1644
1645    def p_nonpositional_param_list_0(self, t):
1646        'nonpositional_param_list : keyword_param_list COMMA excess_args_param'
1647        t[0] = t[1] + t[3]
1648
1649    def p_nonpositional_param_list_1(self, t):
1650        '''nonpositional_param_list : keyword_param_list
1651                                    | excess_args_param'''
1652        t[0] = t[1]
1653
1654    def p_keyword_param_list_0(self, t):
1655        'keyword_param_list : keyword_param'
1656        t[0] = [t[1]]
1657
1658    def p_keyword_param_list_1(self, t):
1659        'keyword_param_list : keyword_param_list COMMA keyword_param'
1660        t[0] = t[1] + [t[3]]
1661
1662    def p_keyword_param(self, t):
1663        'keyword_param : ID EQUALS expr'
1664        t[0] = t[1] + ' = ' + t[3].__repr__()
1665
1666    def p_excess_args_param(self, t):
1667        'excess_args_param : ASTERISK ID'
1668        # Just concatenate them: '*ID'.  Wrap in list to be consistent
1669        # with positional_param_list and keyword_param_list.
1670        t[0] = [t[1] + t[2]]
1671
1672    # End of format definition-related rules.
1673    ##############
1674
1675    #
1676    # A decode block looks like:
1677    #       decode <field1> [, <field2>]* [default <inst>] { ... }
1678    #
1679    def p_decode_block(self, t):
1680        'decode_block : DECODE ID opt_default LBRACE decode_stmt_list RBRACE'
1681        default_defaults = defaultStack.pop()
1682        codeObj = t[5]
1683        # use the "default defaults" only if there was no explicit
1684        # default statement in decode_stmt_list
1685        if not codeObj.has_decode_default:
1686            codeObj += default_defaults
1687        codeObj.wrap_decode_block('switch (%s) {\n' % t[2], '}\n')
1688        t[0] = codeObj
1689
1690    # The opt_default statement serves only to push the "default
1691    # defaults" onto defaultStack.  This value will be used by nested
1692    # decode blocks, and used and popped off when the current
1693    # decode_block is processed (in p_decode_block() above).
1694    def p_opt_default_0(self, t):
1695        'opt_default : empty'
1696        # no default specified: reuse the one currently at the top of
1697        # the stack
1698        defaultStack.push(defaultStack.top())
1699        # no meaningful value returned
1700        t[0] = None
1701
1702    def p_opt_default_1(self, t):
1703        'opt_default : DEFAULT inst'
1704        # push the new default
1705        codeObj = t[2]
1706        codeObj.wrap_decode_block('\ndefault:\n', 'break;\n')
1707        defaultStack.push(codeObj)
1708        # no meaningful value returned
1709        t[0] = None
1710
1711    def p_decode_stmt_list_0(self, t):
1712        'decode_stmt_list : decode_stmt'
1713        t[0] = t[1]
1714
1715    def p_decode_stmt_list_1(self, t):
1716        'decode_stmt_list : decode_stmt decode_stmt_list'
1717        if (t[1].has_decode_default and t[2].has_decode_default):
1718            error(t, 'Two default cases in decode block')
1719        t[0] = t[1] + t[2]
1720
1721    #
1722    # Decode statement rules
1723    #
1724    # There are four types of statements allowed in a decode block:
1725    # 1. Format blocks 'format <foo> { ... }'
1726    # 2. Nested decode blocks
1727    # 3. Instruction definitions.
1728    # 4. C preprocessor directives.
1729
1730
1731    # Preprocessor directives found in a decode statement list are
1732    # passed through to the output, replicated to all of the output
1733    # code streams.  This works well for ifdefs, so we can ifdef out
1734    # both the declarations and the decode cases generated by an
1735    # instruction definition.  Handling them as part of the grammar
1736    # makes it easy to keep them in the right place with respect to
1737    # the code generated by the other statements.
1738    def p_decode_stmt_cpp(self, t):
1739        'decode_stmt : CPPDIRECTIVE'
1740        t[0] = GenCode(t[1], t[1], t[1], t[1])
1741
1742    # A format block 'format <foo> { ... }' sets the default
1743    # instruction format used to handle instruction definitions inside
1744    # the block.  This format can be overridden by using an explicit
1745    # format on the instruction definition or with a nested format
1746    # block.
1747    def p_decode_stmt_format(self, t):
1748        'decode_stmt : FORMAT push_format_id LBRACE decode_stmt_list RBRACE'
1749        # The format will be pushed on the stack when 'push_format_id'
1750        # is processed (see below).  Once the parser has recognized
1751        # the full production (though the right brace), we're done
1752        # with the format, so now we can pop it.
1753        formatStack.pop()
1754        t[0] = t[4]
1755
1756    # This rule exists so we can set the current format (& push the
1757    # stack) when we recognize the format name part of the format
1758    # block.
1759    def p_push_format_id(self, t):
1760        'push_format_id : ID'
1761        try:
1762            formatStack.push(formatMap[t[1]])
1763            t[0] = ('', '// format %s' % t[1])
1764        except KeyError:
1765            error(t, 'instruction format "%s" not defined.' % t[1])
1766
1767    # Nested decode block: if the value of the current field matches
1768    # the specified constant, do a nested decode on some other field.
1769    def p_decode_stmt_decode(self, t):
1770        'decode_stmt : case_label COLON decode_block'
1771        label = t[1]
1772        codeObj = t[3]
1773        # just wrap the decoding code from the block as a case in the
1774        # outer switch statement.
1775        codeObj.wrap_decode_block('\n%s:\n' % label)
1776        codeObj.has_decode_default = (label == 'default')
1777        t[0] = codeObj
1778
1779    # Instruction definition (finally!).
1780    def p_decode_stmt_inst(self, t):
1781        'decode_stmt : case_label COLON inst SEMI'
1782        label = t[1]
1783        codeObj = t[3]
1784        codeObj.wrap_decode_block('\n%s:' % label, 'break;\n')
1785        codeObj.has_decode_default = (label == 'default')
1786        t[0] = codeObj
1787
1788    # The case label is either a list of one or more constants or
1789    # 'default'
1790    def p_case_label_0(self, t):
1791        'case_label : intlit_list'
1792        def make_case(intlit):
1793            if intlit >= 2**32:
1794                return 'case ULL(%#x)' % intlit
1795            else:
1796                return 'case %#x' % intlit
1797        t[0] = ': '.join(map(make_case, t[1]))
1798
1799    def p_case_label_1(self, t):
1800        'case_label : DEFAULT'
1801        t[0] = 'default'
1802
1803    #
1804    # The constant list for a decode case label must be non-empty, but
1805    # may have one or more comma-separated integer literals in it.
1806    #
1807    def p_intlit_list_0(self, t):
1808        'intlit_list : INTLIT'
1809        t[0] = [t[1]]
1810
1811    def p_intlit_list_1(self, t):
1812        'intlit_list : intlit_list COMMA INTLIT'
1813        t[0] = t[1]
1814        t[0].append(t[3])
1815
1816    # Define an instruction using the current instruction format
1817    # (specified by an enclosing format block).
1818    # "<mnemonic>(<args>)"
1819    def p_inst_0(self, t):
1820        'inst : ID LPAREN arg_list RPAREN'
1821        # Pass the ID and arg list to the current format class to deal with.
1822        currentFormat = formatStack.top()
1823        codeObj = currentFormat.defineInst(t[1], t[3], t.lexer.lineno)
1824        args = ','.join(map(str, t[3]))
1825        args = re.sub('(?m)^', '//', args)
1826        args = re.sub('^//', '', args)
1827        comment = '\n// %s::%s(%s)\n' % (currentFormat.id, t[1], args)
1828        codeObj.prepend_all(comment)
1829        t[0] = codeObj
1830
1831    # Define an instruction using an explicitly specified format:
1832    # "<fmt>::<mnemonic>(<args>)"
1833    def p_inst_1(self, t):
1834        'inst : ID DBLCOLON ID LPAREN arg_list RPAREN'
1835        try:
1836            format = formatMap[t[1]]
1837        except KeyError:
1838            error(t, 'instruction format "%s" not defined.' % t[1])
1839        codeObj = format.defineInst(t[3], t[5], t.lexer.lineno)
1840        comment = '\n// %s::%s(%s)\n' % (t[1], t[3], t[5])
1841        codeObj.prepend_all(comment)
1842        t[0] = codeObj
1843
1844    # The arg list generates a tuple, where the first element is a
1845    # list of the positional args and the second element is a dict
1846    # containing the keyword args.
1847    def p_arg_list_0(self, t):
1848        'arg_list : positional_arg_list COMMA keyword_arg_list'
1849        t[0] = ( t[1], t[3] )
1850
1851    def p_arg_list_1(self, t):
1852        'arg_list : positional_arg_list'
1853        t[0] = ( t[1], {} )
1854
1855    def p_arg_list_2(self, t):
1856        'arg_list : keyword_arg_list'
1857        t[0] = ( [], t[1] )
1858
1859    def p_positional_arg_list_0(self, t):
1860        'positional_arg_list : empty'
1861        t[0] = []
1862
1863    def p_positional_arg_list_1(self, t):
1864        'positional_arg_list : expr'
1865        t[0] = [t[1]]
1866
1867    def p_positional_arg_list_2(self, t):
1868        'positional_arg_list : positional_arg_list COMMA expr'
1869        t[0] = t[1] + [t[3]]
1870
1871    def p_keyword_arg_list_0(self, t):
1872        'keyword_arg_list : keyword_arg'
1873        t[0] = t[1]
1874
1875    def p_keyword_arg_list_1(self, t):
1876        'keyword_arg_list : keyword_arg_list COMMA keyword_arg'
1877        t[0] = t[1]
1878        t[0].update(t[3])
1879
1880    def p_keyword_arg(self, t):
1881        'keyword_arg : ID EQUALS expr'
1882        t[0] = { t[1] : t[3] }
1883
1884    #
1885    # Basic expressions.  These constitute the argument values of
1886    # "function calls" (i.e. instruction definitions in the decode
1887    # block) and default values for formal parameters of format
1888    # functions.
1889    #
1890    # Right now, these are either strings, integers, or (recursively)
1891    # lists of exprs (using Python square-bracket list syntax).  Note
1892    # that bare identifiers are trated as string constants here (since
1893    # there isn't really a variable namespace to refer to).
1894    #
1895    def p_expr_0(self, t):
1896        '''expr : ID
1897                | INTLIT
1898                | STRLIT
1899                | CODELIT'''
1900        t[0] = t[1]
1901
1902    def p_expr_1(self, t):
1903        '''expr : LBRACKET list_expr RBRACKET'''
1904        t[0] = t[2]
1905
1906    def p_list_expr_0(self, t):
1907        'list_expr : expr'
1908        t[0] = [t[1]]
1909
1910    def p_list_expr_1(self, t):
1911        'list_expr : list_expr COMMA expr'
1912        t[0] = t[1] + [t[3]]
1913
1914    def p_list_expr_2(self, t):
1915        'list_expr : empty'
1916        t[0] = []
1917
1918    #
1919    # Empty production... use in other rules for readability.
1920    #
1921    def p_empty(self, t):
1922        'empty :'
1923        pass
1924
1925    # Parse error handler.  Note that the argument here is the
1926    # offending *token*, not a grammar symbol (hence the need to use
1927    # t.value)
1928    def p_error(self, t):
1929        if t:
1930            error(t, "syntax error at '%s'" % t.value)
1931        else:
1932            error("unknown syntax error")
1933
1934    # END OF GRAMMAR RULES
1935
1936    def update_if_needed(self, file, contents):
1937        '''Update the output file only if the new contents are
1938        different from the current contents.  Minimizes the files that
1939        need to be rebuilt after minor changes.'''
1940
1941        file = os.path.join(self.output_dir, file)
1942        update = False
1943        if os.access(file, os.R_OK):
1944            f = open(file, 'r')
1945            old_contents = f.read()
1946            f.close()
1947            if contents != old_contents:
1948                print 'Updating', file
1949                os.remove(file) # in case it's write-protected
1950                update = True
1951            else:
1952                print 'File', file, 'is unchanged'
1953        else:
1954            print 'Generating', file
1955            update = True
1956        if update:
1957            f = open(file, 'w')
1958            f.write(contents)
1959            f.close()
1960
1961    # This regular expression matches '##include' directives
1962    includeRE = re.compile(r'^\s*##include\s+"(?P<filename>[\w/.-]*)".*$',
1963                           re.MULTILINE)
1964
1965    def replace_include(self, matchobj, dirname):
1966        """Function to replace a matched '##include' directive with the
1967        contents of the specified file (with nested ##includes
1968        replaced recursively).  'matchobj' is an re match object
1969        (from a match of includeRE) and 'dirname' is the directory
1970        relative to which the file path should be resolved."""
1971
1972        fname = matchobj.group('filename')
1973        full_fname = os.path.normpath(os.path.join(dirname, fname))
1974        contents = '##newfile "%s"\n%s\n##endfile\n' % \
1975                   (full_fname, self.read_and_flatten(full_fname))
1976        return contents
1977
1978    def read_and_flatten(self, filename):
1979        """Read a file and recursively flatten nested '##include' files."""
1980
1981        current_dir = os.path.dirname(filename)
1982        try:
1983            contents = open(filename).read()
1984        except IOError:
1985            error('Error including file "%s"' % filename)
1986
1987        fileNameStack.push((filename, 0))
1988
1989        # Find any includes and include them
1990        def replace(matchobj):
1991            return self.replace_include(matchobj, current_dir)
1992        contents = self.includeRE.sub(replace, contents)
1993
1994        fileNameStack.pop()
1995        return contents
1996
1997    def _parse_isa_desc(self, isa_desc_file):
1998        '''Read in and parse the ISA description.'''
1999
2000        # Read file and (recursively) all included files into a string.
2001        # PLY requires that the input be in a single string so we have to
2002        # do this up front.
2003        isa_desc = self.read_and_flatten(isa_desc_file)
2004
2005        # Initialize filename stack with outer file.
2006        fileNameStack.push((isa_desc_file, 0))
2007
2008        # Parse it.
2009        (isa_name, namespace, global_code, namespace_code) = \
2010                   self.parse(isa_desc)
2011
2012        # grab the last three path components of isa_desc_file to put in
2013        # the output
2014        filename = '/'.join(isa_desc_file.split('/')[-3:])
2015
2016        # generate decoder.hh
2017        includes = '#include "base/bitfield.hh" // for bitfield support'
2018        global_output = global_code.header_output
2019        namespace_output = namespace_code.header_output
2020        decode_function = ''
2021        self.update_if_needed('decoder.hh', file_template % vars())
2022
2023        # generate decoder.cc
2024        includes = '#include "decoder.hh"'
2025        global_output = global_code.decoder_output
2026        namespace_output = namespace_code.decoder_output
2027        # namespace_output += namespace_code.decode_block
2028        decode_function = namespace_code.decode_block
2029        self.update_if_needed('decoder.cc', file_template % vars())
2030
2031        # generate per-cpu exec files
2032        for cpu in cpu_models:
2033            includes = '#include "decoder.hh"\n'
2034            includes += cpu.includes
2035            global_output = global_code.exec_output[cpu.name]
2036            namespace_output = namespace_code.exec_output[cpu.name]
2037            decode_function = ''
2038            self.update_if_needed(cpu.filename, file_template % vars())
2039
2040        # The variable names here are hacky, but this will creat local
2041        # variables which will be referenced in vars() which have the
2042        # value of the globals.
2043        global maxInstSrcRegs
2044        MaxInstSrcRegs = maxInstSrcRegs
2045        global maxInstDestRegs
2046        MaxInstDestRegs = maxInstDestRegs
2047        # max_inst_regs.hh
2048        self.update_if_needed('max_inst_regs.hh',
2049                              max_inst_regs_template % vars())
2050
2051    def parse_isa_desc(self, *args, **kwargs):
2052        try:
2053            self._parse_isa_desc(*args, **kwargs)
2054        except ISAParserError, e:
2055            e.exit(fileNameStack)
2056
2057# global list of CpuModel objects (see cpu_models.py)
2058cpu_models = []
2059
2060# Called as script: get args from command line.
2061# Args are: <path to cpu_models.py> <isa desc file> <output dir> <cpu models>
2062if __name__ == '__main__':
2063    execfile(sys.argv[1])  # read in CpuModel definitions
2064    cpu_models = [CpuModel.dict[cpu] for cpu in sys.argv[4:]]
2065    parser = ISAParser(sys.argv[3])
2066    parser.parse_isa_desc(sys.argv[2])
2067