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