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