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