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