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