5 # Copyright (c) 2003 The Regents of The University of Michigan
8 # Redistribution and use in source and binary forms, with or without
9 # modification, are permitted provided that the following conditions are
10 # met: redistributions of source code must retain the above copyright
11 # notice, this list of conditions and the following disclaimer;
12 # redistributions in binary form must reproduce the above copyright
13 # notice, this list of conditions and the following disclaimer in the
14 # documentation and/or other materials provided with the distribution;
15 # neither the name of the copyright holders nor the names of its
16 # contributors may be used to endorse or promote products derived from
17 # this software without specific prior written permission.
19 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 # Prepend the directory where the PLY lex & yacc modules are found
40 # to the search path. Assumes we're compiling in a subdirectory
41 # of 'build' in the current tree.
42 sys
.path
[0:0] = [os
.environ
['M5_EXT'] + '/ply']
47 #####################################################################
51 # The PLY lexer module takes two things as input:
52 # - A list of token names (the string list 'tokens')
53 # - A regular expression describing a match for each token. The
54 # regexp for token FOO can be provided in two ways:
55 # - as a string variable named t_FOO
56 # - as the doc string for a function named t_FOO. In this case,
57 # the function is also executed, allowing an action to be
58 # associated with each token match.
60 #####################################################################
62 # Reserved words. These are listed separately as they are matched
63 # using the same regexp as generic IDs, but distinguished in the
64 # t_ID() function. The PLY documentation suggests this approach.
66 'BITFIELD', 'DECLARE', 'DECODE', 'DEFAULT', 'DEF', 'FORMAT',
67 'LET', 'NAMESPACE', 'SIGNED', 'TEMPLATE'
70 # List of tokens. The lex module requires this.
84 # ( ) [ ] { } < > , ; : :: *
86 # not used any more... commented out to suppress PLY warning
87 # 'LBRACKET', 'RBRACKET',
90 'COMMA', 'SEMI', 'COLON', 'DBLCOLON',
93 # C preprocessor directives
97 # Regular expressions for token matching
100 # not used any more... commented out to suppress PLY warning
113 # Identifiers and reserved words
116 reserved_map
[r
.lower()] = r
120 t
.type = reserved_map
.get(t
.value
,'ID')
125 r
'(0x[\da-fA-F]+)|\d+'
127 t
.value
= int(t
.value
,0)
129 error(t
.lineno
, 'Integer value "%s" too large' % t
.value
)
133 # String literal. Note that these use only single quotes, and
134 # can span multiple lines.
138 t
.value
= t
.value
[1:-1]
139 t
.lineno
+= t
.value
.count('\n')
143 # "Code literal"... like a string literal, but delimiters are
144 # '{{' and '}}' so they get formatted nicely under emacs c-mode
146 r
"(?m)\{\{([^\}]|}(?!\}))+\}\}"
148 t
.value
= t
.value
[2:-2]
149 t
.lineno
+= t
.value
.count('\n')
152 def t_CPPDIRECTIVE(t
):
154 t
.lineno
+= t
.value
.count('\n')
158 # The functions t_NEWLINE, t_ignore, and t_error are
159 # special for the lex module.
165 t
.lineno
+= t
.value
.count('\n')
171 # Completely ignored characters
176 error(t
.lineno
, "illegal character '%s'" % t
.value
[0])
182 #####################################################################
186 # Every function whose name starts with 'p_' defines a grammar rule.
187 # The rule is encoded in the function's doc string, while the
188 # function body provides the action taken when the rule is matched.
189 # The argument to each function is a list of the values of the
190 # rule's symbols: t[0] for the LHS, and t[1..n] for the symbols
191 # on the RHS. For tokens, the value is copied from the t.value
192 # attribute provided by the lexer. For non-terminals, the value
193 # is assigned by the producing rule; i.e., the job of the grammar
194 # rule function is to set the value for the non-terminal on the LHS
195 # (by assigning to t[0]).
196 #####################################################################
198 # Not sure why, but we get a handful of shift/reduce conflicts on DECLARE.
199 # By default these get resolved as shifts, which is correct, but
200 # warnings are printed. Explicitly marking DECLARE as right-associative
201 # suppresses the warnings.
203 ('right', 'DECLARE'),
206 # The LHS of the first grammar rule is used as the start symbol
207 # (in this case, 'specification'). Note that this rule enforces
208 # that there will be exactly one namespace declaration, with 0 or more
209 # global defs/decls before and after it. The defs & decls before
210 # the namespace decl will be outside the namespace; those after
211 # will be inside. The decoder function is always inside the namespace.
212 def p_specification(t
):
213 'specification : opt_defs_and_declares name_decl opt_defs_and_declares decode_block'
216 namespace
= isa_name
+ "Inst"
218 (inst_decls
, decode_code
, exec_code
) = t
[4]
219 decode_code
= indent(decode_code
)
220 # grab the last three path components of isa_desc_filename
221 filename
= '/'.join(isa_desc_filename
.split('/')[-3:])
222 # if the isa_desc file defines a 'rcs_id' string,
223 # echo that into the output too
225 local_rcs_id
= rcs_id
226 # strip $s out of ID so it doesn't get re-substituted
227 local_rcs_id
= re
.sub(r
'\$', '', local_rcs_id
)
229 local_rcs_id
= 'Id: no RCS id found'
230 output
= open(decoder_filename
, 'w')
231 # split string to keep rcs from substituting this file's RCS id in
232 print >> output
, '/* $Id' + '''$ */
236 * The Regents of The University of Michigan
237 * All Rights Reserved
239 * This code is part of the M5 simulator, developed by Nathan Binkert,
240 * Erik Hallnor, Steve Raasch, and Steve Reinhardt, with contributions
241 * from Ron Dreslinski, Dave Greene, and Lisa Hsu.
243 * Permission is granted to use, copy, create derivative works and
244 * redistribute this software and such derivative works for any
245 * purpose, so long as the copyright notice above, this grant of
246 * permission, and the disclaimer below appear in all copies made; and
247 * so long as the name of The University of Michigan is not used in
248 * any advertising or publicity pertaining to the use or distribution
249 * of this software without specific, written prior authorization.
251 * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE
252 * UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND
253 * WITHOUT WARRANTY BY THE UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER
254 * EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
255 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
256 * PURPOSE. THE REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE
257 * LIABLE FOR ANY DAMAGES, INCLUDING DIRECT, SPECIAL, INDIRECT,
258 * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM
259 * ARISING OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
260 * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF SUCH
265 * DO NOT EDIT THIS FILE!!!
267 * It was automatically generated from this ISA description:
268 * Filename: %(filename)s
269 * RCS %(local_rcs_id)s
272 #include "base/bitfield.hh" // required for bitfield support
275 /////////////////////////////////////
276 // Global defs (outside namespace) //
277 /////////////////////////////////////
282 * Namespace for %(isa_name)s static instruction objects.
284 namespace %(namespace)s
287 /////////////////////////////////////
288 // Global defs (within namespace) //
289 /////////////////////////////////////
293 ////////////////////////////////////
294 // Declares from inst definitions //
295 ////////////////////////////////////
301 } // namespace %(namespace)s
303 //////////////////////
304 // Decoder function //
305 //////////////////////
307 StaticInstPtr<%(isa_name)s>
308 %(isa_name)s::decodeInst(%(isa_name)s::MachInst machInst)
310 using namespace %(namespace)s;
316 # ISA name declaration looks like "namespace <foo>;"
318 'name_decl : NAMESPACE ID SEMI'
321 # 'opt_defs_and_declares' is a possibly empty sequence of
322 # defs and/or declares.
323 def p_opt_defs_and_declares_0(t
):
324 'opt_defs_and_declares : empty'
327 def p_opt_defs_and_declares_1(t
):
328 'opt_defs_and_declares : defs_and_declares'
331 def p_defs_and_declares_0(t
):
332 'defs_and_declares : def_or_declare'
335 def p_defs_and_declares_1(t
):
336 'defs_and_declares : defs_and_declares def_or_declare'
339 # The list of possible definition/declaration statements.
340 def p_def_or_declare(t
):
341 '''def_or_declare : def_format
349 # preprocessor directives are copied directly to the output.
350 def p_cpp_directive(t
):
351 '''cpp_directive : CPPDIRECTIVE'''
354 # Global declares 'declare {{...}}' (C++ code blocks) are copied
355 # directly to the output.
356 def p_global_declare(t
):
357 'global_declare : DECLARE CODELIT SEMI'
358 t
[0] = substBitOps(t
[2])
360 # global let blocks 'let {{...}}' (Python code blocks) are executed
361 # directly when seen. These are typically used to initialize global
362 # Python variables used in later format definitions.
364 'global_let : LET CODELIT SEMI'
366 exec(fixPythonIndentation(t
[2]))
368 error_bt(t
.lineno(1), 'error in global let block "%s".' % t
[2])
369 t
[0] = '' # contributes nothing to the output C++ file
371 # A bitfield definition looks like:
372 # 'def [signed] bitfield <ID> [<first>:<last>]'
373 # This generates a preprocessor macro in the output file.
374 def p_def_bitfield_0(t
):
375 'def_bitfield : DEF opt_signed BITFIELD ID LESS INTLIT COLON INTLIT GREATER SEMI'
376 expr
= 'bits(machInst, %2d, %2d)' % (t
[6], t
[8])
377 if (t
[2] == 'signed'):
378 expr
= 'sext<%d>(%s)' % (t
[6] - t
[8] + 1, expr
)
379 t
[0] = '#undef %s\n#define %s\t%s\n' % (t
[4], t
[4], expr
)
381 # alternate form for single bit: 'def [signed] bitfield <ID> [<bit>]'
382 def p_def_bitfield_1(t
):
383 'def_bitfield : DEF opt_signed BITFIELD ID LESS INTLIT GREATER SEMI'
384 expr
= 'bits(machInst, %2d, %2d)' % (t
[6], t
[6])
385 if (t
[2] == 'signed'):
386 expr
= 'sext<%d>(%s)' % (1, expr
)
387 t
[0] = '#undef %s\n#define %s\t%s\n' % (t
[4], t
[4], expr
)
389 def p_opt_signed_0(t
):
390 'opt_signed : SIGNED'
393 def p_opt_signed_1(t
):
397 # Global map variable to hold templates
400 def p_def_template(t
):
401 'def_template : DEF TEMPLATE ID CODELIT SEMI'
402 templateMap
[t
[3]] = t
[4]
405 # An instruction format definition looks like
406 # "def format <fmt>(<params>) {{...}};"
408 'def_format : DEF FORMAT ID LPAREN param_list RPAREN CODELIT SEMI'
409 (id, params
, code
) = (t
[3], t
[5], t
[7])
410 defFormat(id, params
, code
, t
.lineno(1))
411 # insert a comment into the output to note that the def was processed
414 // parser: format %s defined
418 # The formal parameter list for an instruction format is a possibly
419 # empty list of comma-separated parameters.
420 def p_param_list_0(t
):
424 def p_param_list_1(t
):
428 def p_param_list_2(t
):
429 'param_list : param_list COMMA param'
433 # Each formal parameter is either an identifier or an identifier
434 # preceded by an asterisk. As in Python, the latter (if present) gets
435 # a tuple containing all the excess positional arguments, allowing
442 'param : ASTERISK ID'
443 # just concatenate them: '*ID'
446 # End of format definition-related rules.
450 # A decode block looks like:
451 # decode <field1> [, <field2>]* [default <inst>] { ... }
453 def p_decode_block(t
):
454 'decode_block : DECODE ID opt_default LBRACE decode_stmt_list RBRACE'
455 default_defaults
= defaultStack
.pop()
456 (decls
, decode_code
, exec_code
, has_default
) = t
[5]
457 # use the "default defaults" only if there was no explicit
458 # default statement in decode_stmt_list
460 (default_decls
, default_decode
, default_exec
) = default_defaults
461 decls
+= default_decls
462 decode_code
+= default_decode
463 exec_code
+= default_exec
468 ''' % (t
[2], indent(decode_code
)), exec_code
)
470 # The opt_default statement serves only to push the "default defaults"
471 # onto defaultStack. This value will be used by nested decode blocks,
472 # and used and popped off when the current decode_block is processed
473 # (in p_decode_block() above).
474 def p_opt_default_0(t
):
475 'opt_default : empty'
476 # no default specified: reuse the one currently at the top of the stack
477 defaultStack
.push(defaultStack
.top())
478 # no meaningful value returned
481 def p_opt_default_1(t
):
482 'opt_default : DEFAULT inst'
483 # push the new default
484 (decls
, decode_code
, exec_code
) = t
[2]
485 defaultStack
.push((decls
, '\ndefault:\n%sbreak;' % decode_code
, exec_code
))
486 # no meaningful value returned
489 def p_decode_stmt_list_0(t
):
490 'decode_stmt_list : decode_stmt'
493 def p_decode_stmt_list_1(t
):
494 'decode_stmt_list : decode_stmt decode_stmt_list'
495 (decls1
, decode_code1
, exec_code1
, has_default1
) = t
[1]
496 (decls2
, decode_code2
, exec_code2
, has_default2
) = t
[2]
497 if (has_default1
and has_default2
):
498 error(t
.lineno(1), 'Two default cases in decode block')
499 t
[0] = (decls1
+ '\n' + decls2
, decode_code1
+ '\n' + decode_code2
,
500 exec_code1
+ '\n' + exec_code2
, has_default1
or has_default2
)
503 # Decode statement rules
505 # There are four types of statements allowed in a decode block:
506 # 1. Format blocks 'format <foo> { ... }'
507 # 2. Nested decode blocks
508 # 3. Instruction definitions.
509 # 4. C preprocessor directives.
512 # Preprocessor directives found in a decode statement list are passed
513 # through to the output, replicated to both the declaration and decode
514 # streams. This works well for ifdefs, so we can ifdef out both the
515 # declarations and the decode cases generated by an instruction
516 # definition. Handling them as part of the grammar makes it easy to
517 # keep them in the right place with respect to the code generated by
518 # the other statements.
519 def p_decode_stmt_cpp(t
):
520 'decode_stmt : CPPDIRECTIVE'
521 t
[0] = (t
[1], t
[1], t
[1], 0)
523 # A format block 'format <foo> { ... }' sets the default instruction
524 # format used to handle instruction definitions inside the block.
525 # This format can be overridden by using an explicit format on the
526 # instruction definition or with a nested format block.
527 def p_decode_stmt_format(t
):
528 'decode_stmt : FORMAT push_format_id LBRACE decode_stmt_list RBRACE'
529 # The format will be pushed on the stack when 'push_format_id' is
530 # processed (see below). Once the parser has recognized the full
531 # production (though the right brace), we're done with the format,
532 # so now we can pop it.
536 # This rule exists so we can set the current format (& push the stack)
537 # when we recognize the format name part of the format block.
538 def p_push_format_id(t
):
539 'push_format_id : ID'
541 formatStack
.push(formatMap
[t
[1]])
542 t
[0] = ('', '// format %s' % t
[1])
544 error(t
.lineno(1), 'instruction format "%s" not defined.' % t
[1])
546 # Nested decode block: if the value of the current field matches the
547 # specified constant, do a nested decode on some other field.
548 def p_decode_stmt_decode(t
):
549 'decode_stmt : case_label COLON decode_block'
550 (label
, is_default
) = t
[1]
551 (decls
, decode_code
, exec_code
) = t
[3]
552 # just wrap the decoding code from the block as a case in the
553 # outer switch statement.
554 t
[0] = (decls
, '\n%s:\n%s' % (label
, indent(decode_code
)),
555 exec_code
, is_default
)
557 # Instruction definition (finally!).
558 def p_decode_stmt_inst(t
):
559 'decode_stmt : case_label COLON inst SEMI'
560 (label
, is_default
) = t
[1]
561 (decls
, decode_code
, exec_code
) = t
[3]
562 t
[0] = (decls
, '\n%s:%sbreak;' % (label
, indent(decode_code
)),
563 exec_code
, is_default
)
565 # The case label is either a list of one or more constants or 'default'
566 def p_case_label_0(t
):
567 'case_label : intlit_list'
568 t
[0] = (': '.join(map(lambda a
: 'case %#x' % a
, t
[1])), 0)
570 def p_case_label_1(t
):
571 'case_label : DEFAULT'
572 t
[0] = ('default', 1)
575 # The constant list for a decode case label must be non-empty, but may have
576 # one or more comma-separated integer literals in it.
578 def p_intlit_list_0(t
):
579 'intlit_list : INTLIT'
582 def p_intlit_list_1(t
):
583 'intlit_list : intlit_list COMMA INTLIT'
587 # Define an instruction using the current instruction format (specified
588 # by an enclosing format block).
589 # "<mnemonic>(<args>)"
591 'inst : ID LPAREN arg_list RPAREN'
592 # Pass the ID and arg list to the current format class to deal with.
593 currentFormat
= formatStack
.top()
594 (decls
, decode_code
, exec_code
) = \
595 currentFormat
.defineInst(t
[1], t
[3], t
.lineno(1))
596 args
= ','.join(map(str, t
[3]))
597 args
= re
.sub('(?m)^', '//', args
)
598 args
= re
.sub('^//', '', args
)
599 comment
= '// %s::%s(%s)\n' % (currentFormat
.id, t
[1], args
)
600 t
[0] = (comment
+ decls
, comment
+ decode_code
, comment
+ exec_code
)
602 # Define an instruction using an explicitly specified format:
603 # "<fmt>::<mnemonic>(<args>)"
605 'inst : ID DBLCOLON ID LPAREN arg_list RPAREN'
607 format
= formatMap
[t
[1]]
609 error(t
.lineno(1), 'instruction format "%s" not defined.' % t
[1])
610 (decls
, decode_code
, exec_code
) = \
611 format
.defineInst(t
[3], t
[5], t
.lineno(1))
612 comment
= '// %s::%s(%s)\n' % (t
[1], t
[3], t
[5])
613 t
[0] = (comment
+ decls
, comment
+ decode_code
, comment
+ exec_code
)
624 'arg_list : arg_list COMMA arg'
636 # Empty production... use in other rules for readability.
642 # Parse error handler. Note that the argument here is the offending
643 # *token*, not a grammar symbol (hence the need to use t.value)
646 error(t
.lineno
, "syntax error at '%s'" % t
.value
)
648 error_bt(0, "unknown syntax error")
650 # END OF GRAMMAR RULES
652 # Now build the parser.
658 # A format object encapsulates an instruction format. It must provide
659 # a defineInst() method that generates the code for an instruction
663 def __init__(self
, id, params
, code
):
664 # constructor: just save away arguments
667 # strip blank lines from code (ones at the end are troublesome)
668 code
= re
.sub(r
'(?m)^\s*$', '', code
);
671 param_list
= string
.join(params
, ", ")
672 f
= 'def defInst(name, Name, ' + param_list
+ '):\n' + code
673 c
= compile(f
, 'def format ' + id, 'exec')
677 def defineInst(self
, name
, args
, lineno
):
678 # automatically provide a capitalized version of mnemonic
679 Name
= string
.capitalize(name
)
681 retval
= self
.func(name
, Name
, *args
)
683 error_bt(lineno
, 'error defining "%s".' % name
)
686 # Special null format to catch an implicit-format instruction
687 # definition outside of any format block.
690 self
.defaultInst
= ''
692 def defineInst(self
, name
, args
, lineno
):
694 'instruction definition "%s" with no active format!' % name
)
696 # This dictionary maps format name strings to Format objects.
699 # Define a new format
700 def defFormat(id, params
, code
, lineno
):
701 # make sure we haven't already defined this one
702 if formatMap
.get(id, None) != None:
703 error(lineno
, 'format %s redefined.' % id)
704 # create new object and store in global map
705 formatMap
[id] = Format(id, params
, code
)
709 # Stack: a simple stack object. Used for both formats (formatStack)
710 # and default cases (defaultStack).
713 def __init__(self
, initItem
):
714 self
.stack
= [ initItem
]
716 def push(self
, item
):
717 self
.stack
.append(item
);
720 return self
.stack
.pop()
723 return self
.stack
[-1]
725 # The global format stack.
726 formatStack
= Stack(NoFormat())
728 # The global default case stack.
729 defaultStack
= Stack( None )
735 # Indent every line in string 's' by two spaces
736 # (except preprocessor directives).
737 # Used to make nested code blocks look pretty.
740 return re
.sub(r
'(?m)^(?!\#)', ' ', s
)
743 # Munge a somewhat arbitrarily formatted piece of Python code
744 # (e.g. from a format 'let' block) into something whose indentation
745 # will get by the Python parser.
747 # The two keys here are that Python will give a syntax error if
748 # there's any whitespace at the beginning of the first line, and that
749 # all lines at the same lexical nesting level must have identical
750 # indentation. Unfortunately the way code literals work, an entire
751 # let block tends to have some initial indentation. Rather than
752 # trying to figure out what that is and strip it off, we prepend 'if
753 # 1:' to make the let code the nested block inside the if (and have
754 # the parser automatically deal with the indentation for us).
756 # We don't want to do this if (1) the code block is empty or (2) the
757 # first line of the block doesn't have any whitespace at the front.
759 def fixPythonIndentation(s
):
760 # get rid of blank lines first
761 s
= re
.sub(r
'(?m)^\s*\n', '', s
);
762 if (s
!= '' and re
.match(r
'[ \t]', s
[0])):
766 # Error handler. Just call exit. Output formatted to work under
767 # Emacs compile-mode.
768 def error(lineno
, string
):
769 sys
.exit("%s:%d: %s" % (isa_desc_filename
, lineno
, string
))
771 # Like error(), but include a Python stack backtrace (for processing
772 # Python exceptions).
773 def error_bt(lineno
, string
):
774 traceback
.print_exc()
775 print >> sys
.stderr
, "%s:%d: %s" % (isa_desc_filename
, lineno
, string
)
779 #####################################################################
781 # Bitfield Operator Support
783 #####################################################################
785 bitOp1ArgRE
= re
.compile(r
'<\s*(\w+)\s*:\s*>')
787 bitOpWordRE
= re
.compile(r
'(?<![\w\.])([\w\.]+)<\s*(\w+)\s*:\s*(\w+)\s*>')
788 bitOpExprRE
= re
.compile(r
'\)<\s*(\w+)\s*:\s*(\w+)\s*>')
790 def substBitOps(code
):
791 # first convert single-bit selectors to two-index form
792 # i.e., <n> --> <n:n>
793 code
= bitOp1ArgRE
.sub(r
'<\1:\1>', code
)
794 # simple case: selector applied to ID (name)
795 # i.e., foo<a:b> --> bits(foo, a, b)
796 code
= bitOpWordRE
.sub(r
'bits(\1, \2, \3)', code
)
797 # if selector is applied to expression (ending in ')'),
798 # we need to search backward for matching '('
799 match
= bitOpExprRE
.search(code
)
801 exprEnd
= match
.start()
805 if code
[here
] == '(':
807 elif code
[here
] == ')':
811 sys
.exit("Didn't find '('!")
813 newExpr
= r
'bits(%s, %s, %s)' % (code
[exprStart
:exprEnd
+1],
814 match
.group(1), match
.group(2))
815 code
= code
[:exprStart
] + newExpr
+ code
[match
.end():]
816 match
= bitOpExprRE
.search(code
)
820 #####################################################################
824 # The remaining code is the support for automatically extracting
825 # instruction characteristics from pseudocode.
827 #####################################################################
829 # Force the argument to be a list
830 def makeList(list_or_item
):
833 elif type(list_or_item
) == ListType
:
836 return [ list_or_item
]
838 # generate operandSizeMap based on provided operandTypeMap:
839 # basically generate equiv. C++ type and make is_signed flag
840 def buildOperandSizeMap():
841 global operandSizeMap
843 for ext
in operandTypeMap
.keys():
844 (desc
, size
) = operandTypeMap
[ext
]
845 if desc
== 'signed int':
846 type = 'int%d_t' % size
848 elif desc
== 'unsigned int':
849 type = 'uint%d_t' % size
851 elif desc
== 'float':
852 is_signed
= 1 # shouldn't really matter
858 error(0, 'Unrecognized type description "%s" in operandTypeMap')
859 operandSizeMap
[ext
] = (size
, type, is_signed
)
862 # Base class for operand traits. An instance of this class (or actually
863 # a class derived from this one) encapsulates the traits of a particular
864 # operand type (e.g., "32-bit integer register").
867 def __init__(self
, dflt_ext
, reg_spec
, flags
, sort_pri
):
868 # Force construction of operandSizeMap from operandTypeMap
869 # if it hasn't happened yet
870 if not globals().has_key('operandSizeMap'):
871 buildOperandSizeMap()
872 self
.dflt_ext
= dflt_ext
873 (self
.dflt_size
, self
.dflt_type
, self
.dflt_is_signed
) = \
874 operandSizeMap
[dflt_ext
]
875 self
.reg_spec
= reg_spec
876 # Canonical flag structure is a triple of lists, where each list
877 # indicates the set of flags implied by this operand always, when
878 # used as a source, and when used as a dest, respectively.
879 # For simplicity this can be initialized using a variety of fairly
880 # obvious shortcuts; we convert these to canonical form here.
882 # no flags specified (e.g., 'None')
883 self
.flags
= ( [], [], [] )
884 elif type(flags
) == StringType
:
885 # a single flag: assumed to be unconditional
886 self
.flags
= ( [ flags
], [], [] )
887 elif type(flags
) == ListType
:
888 # a list of flags: also assumed to be unconditional
889 self
.flags
= ( flags
, [], [] )
890 elif type(flags
) == TupleType
:
891 # it's a tuple: it should be a triple,
892 # but each item could be a single string or a list
893 (uncond_flags
, src_flags
, dest_flags
) = flags
894 self
.flags
= (makeList(uncond_flags
),
895 makeList(src_flags
), makeList(dest_flags
))
896 self
.sort_pri
= sort_pri
904 def isFloatReg(self
):
910 def isControlReg(self
):
913 def getFlags(self
, op_desc
):
914 # note the empty slice '[:]' gives us a copy of self.flags[0]
915 # instead of a reference to it
916 my_flags
= self
.flags
[0][:]
918 my_flags
+= self
.flags
[1]
920 my_flags
+= self
.flags
[2]
923 def makeDecl(self
, op_desc
):
924 (size
, type, is_signed
) = operandSizeMap
[op_desc
.eff_ext
]
925 # Note that initializations in the declarations are solely
926 # to avoid 'uninitialized variable' errors from the compiler.
927 return type + ' ' + op_desc
.munged_name
+ ' = 0;\n';
929 class IntRegOperandTraits(OperandTraits
):
936 def makeConstructor(self
, op_desc
):
939 c
+= '\n\t_srcRegIdx[%d] = %s;' % \
940 (op_desc
.src_reg_idx
, self
.reg_spec
)
942 c
+= '\n\t_destRegIdx[%d] = %s;' % \
943 (op_desc
.dest_reg_idx
, self
.reg_spec
)
946 def makeRead(self
, op_desc
):
947 (size
, type, is_signed
) = operandSizeMap
[op_desc
.eff_ext
]
948 if (type == 'float' or type == 'double'):
949 error(0, 'Attempt to read integer register as FP')
950 if (size
== self
.dflt_size
):
951 return '%s = xc->readIntReg(_srcRegIdx[%d]);\n' % \
952 (op_desc
.munged_name
, op_desc
.src_reg_idx
)
954 return '%s = bits(xc->readIntReg(_srcRegIdx[%d]), %d, 0);\n' % \
955 (op_desc
.munged_name
, op_desc
.src_reg_idx
, size
-1)
957 def makeWrite(self
, op_desc
):
958 (size
, type, is_signed
) = operandSizeMap
[op_desc
.eff_ext
]
959 if (type == 'float' or type == 'double'):
960 error(0, 'Attempt to write integer register as FP')
961 if (size
!= self
.dflt_size
and is_signed
):
962 final_val
= 'sext<%d>(%s)' % (size
, op_desc
.munged_name
)
964 final_val
= op_desc
.munged_name
968 xc->setIntReg(_destRegIdx[%d], final_val);\n
969 if (traceData) { traceData->setData(final_val); }
970 }''' % (self
.dflt_type
, final_val
, op_desc
.dest_reg_idx
)
973 class FloatRegOperandTraits(OperandTraits
):
977 def isFloatReg(self
):
980 def makeConstructor(self
, op_desc
):
983 c
+= '\n\t_srcRegIdx[%d] = %s + FP_Base_DepTag;' % \
984 (op_desc
.src_reg_idx
, self
.reg_spec
)
986 c
+= '\n\t_destRegIdx[%d] = %s + FP_Base_DepTag;' % \
987 (op_desc
.dest_reg_idx
, self
.reg_spec
)
990 def makeRead(self
, op_desc
):
991 (size
, type, is_signed
) = operandSizeMap
[op_desc
.eff_ext
]
993 if (type == 'float'):
994 func
= 'readFloatRegSingle'
995 elif (type == 'double'):
996 func
= 'readFloatRegDouble'
998 func
= 'readFloatRegInt'
999 if (size
!= self
.dflt_size
):
1001 base
= 'xc->%s(_srcRegIdx[%d] - FP_Base_DepTag)' % \
1002 (func
, op_desc
.src_reg_idx
)
1004 return '%s = bits(%s, %d, 0);\n' % \
1005 (op_desc
.munged_name
, base
, size
-1)
1007 return '%s = %s;\n' % (op_desc
.munged_name
, base
)
1009 def makeWrite(self
, op_desc
):
1010 (size
, type, is_signed
) = operandSizeMap
[op_desc
.eff_ext
]
1011 final_val
= op_desc
.munged_name
1012 if (type == 'float'):
1013 func
= 'setFloatRegSingle'
1014 elif (type == 'double'):
1015 func
= 'setFloatRegDouble'
1017 func
= 'setFloatRegInt'
1018 type = 'uint%d_t' % self
.dflt_size
1019 if (size
!= self
.dflt_size
and is_signed
):
1020 final_val
= 'sext<%d>(%s)' % (size
, op_desc
.munged_name
)
1024 xc->%s(_destRegIdx[%d] - FP_Base_DepTag, final_val);\n
1025 if (traceData) { traceData->setData(final_val); }
1026 }''' % (type, final_val
, func
, op_desc
.dest_reg_idx
)
1029 class ControlRegOperandTraits(OperandTraits
):
1033 def isControlReg(self
):
1036 def makeConstructor(self
, op_desc
):
1039 c
+= '\n\t_srcRegIdx[%d] = %s_DepTag;' % \
1040 (op_desc
.src_reg_idx
, self
.reg_spec
)
1042 c
+= '\n\t_destRegIdx[%d] = %s_DepTag;' % \
1043 (op_desc
.dest_reg_idx
, self
.reg_spec
)
1046 def makeRead(self
, op_desc
):
1047 (size
, type, is_signed
) = operandSizeMap
[op_desc
.eff_ext
]
1049 if (type == 'float' or type == 'double'):
1050 error(0, 'Attempt to read control register as FP')
1051 base
= 'xc->read%s()' % self
.reg_spec
1052 if size
== self
.dflt_size
:
1053 return '%s = %s;\n' % (op_desc
.munged_name
, base
)
1055 return '%s = bits(%s, %d, 0);\n' % \
1056 (op_desc
.munged_name
, base
, size
-1)
1058 def makeWrite(self
, op_desc
):
1059 (size
, type, is_signed
) = operandSizeMap
[op_desc
.eff_ext
]
1060 if (type == 'float' or type == 'double'):
1061 error(0, 'Attempt to write control register as FP')
1062 wb
= 'xc->set%s(%s);\n' % (self
.reg_spec
, op_desc
.munged_name
)
1063 wb
+= 'if (traceData) { traceData->setData(%s); }' % \
1067 class MemOperandTraits(OperandTraits
):
1071 def makeConstructor(self
, op_desc
):
1074 def makeDecl(self
, op_desc
):
1075 (size
, type, is_signed
) = operandSizeMap
[op_desc
.eff_ext
]
1076 # Note that initializations in the declarations are solely
1077 # to avoid 'uninitialized variable' errors from the compiler.
1078 # Declare memory data variable.
1079 c
= '%s %s = 0;\n' % (type, op_desc
.munged_name
)
1080 # Declare var to hold memory access flags.
1081 c
+= 'unsigned %s_flags = memAccessFlags;\n' % op_desc
.base_name
1082 # If this operand is a dest (i.e., it's a store operation),
1083 # then we need to declare a variable for the write result code
1086 c
+= 'uint64_t %s_write_result = 0;\n' % op_desc
.base_name
1089 def makeRead(self
, op_desc
):
1090 (size
, type, is_signed
) = operandSizeMap
[op_desc
.eff_ext
]
1091 eff_type
= 'uint%d_t' % size
1092 return 'fault = xc->read(EA, (%s&)%s, %s_flags);\n' \
1093 % (eff_type
, op_desc
.munged_name
, op_desc
.base_name
)
1095 def makeWrite(self
, op_desc
):
1096 (size
, type, is_signed
) = operandSizeMap
[op_desc
.eff_ext
]
1097 eff_type
= 'uint%d_t' % size
1098 return 'fault = xc->write((%s&)%s, EA, %s_flags,' \
1099 ' &%s_write_result);\n' \
1100 % (eff_type
, op_desc
.munged_name
, op_desc
.base_name
,
1103 class NPCOperandTraits(OperandTraits
):
1104 def makeConstructor(self
, op_desc
):
1107 def makeRead(self
, op_desc
):
1108 return '%s = xc->readPC() + 4;\n' % op_desc
.munged_name
1110 def makeWrite(self
, op_desc
):
1111 return 'xc->setNextPC(%s);\n' % op_desc
.munged_name
1115 # Define operand variables that get derived from the basic declaration
1116 # of ISA-specific operands in operandTraitsMap. This function must be
1117 # called by the ISA description file explicitly after defining
1118 # operandTraitsMap (in a 'let' block).
1120 def defineDerivedOperandVars():
1122 operands
= operandTraitsMap
.keys()
1124 operandsREString
= (r
'''
1125 (?<![\w\.]) # neg. lookbehind assertion: prevent partial matches
1126 ((%s)(?:\.(\w+))?) # match: operand with optional '.' then suffix
1127 (?![\w\.]) # neg. lookahead assertion: prevent partial matches
1129 % string
.join(operands
, '|'))
1132 operandsRE
= re
.compile(operandsREString
, re
.MULTILINE|re
.VERBOSE
)
1134 # Same as operandsREString, but extension is mandatory, and only two
1135 # groups are returned (base and ext, not full name as above).
1136 # Used for subtituting '_' for '.' to make C++ identifiers.
1137 operandsWithExtREString
= (r
'(?<![\w\.])(%s)\.(\w+)(?![\w\.])'
1138 % string
.join(operands
, '|'))
1140 global operandsWithExtRE
1141 operandsWithExtRE
= re
.compile(operandsWithExtREString
, re
.MULTILINE
)
1145 # Operand descriptor class. An instance of this class represents
1146 # a specific operand for a code block.
1148 class OperandDescriptor
:
1149 def __init__(self
, full_name
, base_name
, ext
, is_src
, is_dest
):
1150 self
.full_name
= full_name
1151 self
.base_name
= base_name
1153 self
.is_src
= is_src
1154 self
.is_dest
= is_dest
1155 self
.traits
= operandTraitsMap
[base_name
]
1156 # The 'effective extension' (eff_ext) is either the actual
1157 # extension, if one was explicitly provided, or the default.
1158 # The 'munged name' replaces the '.' between the base and
1159 # extension (if any) with a '_' to make a legal C++ variable name.
1162 self
.munged_name
= base_name
+ '_' + ext
1164 self
.eff_ext
= self
.traits
.dflt_ext
1165 self
.munged_name
= base_name
1167 # Finalize additional fields (primarily code fields). This step
1168 # is done separately since some of these fields may depend on the
1169 # register index enumeration that hasn't been performed yet at the
1170 # time of __init__().
1172 self
.flags
= self
.traits
.getFlags(self
)
1173 self
.constructor
= self
.traits
.makeConstructor(self
)
1174 self
.op_decl
= self
.traits
.makeDecl(self
)
1177 self
.op_rd
= self
.traits
.makeRead(self
)
1182 self
.op_wb
= self
.traits
.makeWrite(self
)
1186 class OperandDescriptorList
:
1192 return len(self
.items
)
1194 def __getitem__(self
, index
):
1195 return self
.items
[index
]
1197 def append(self
, op_desc
):
1198 self
.items
.append(op_desc
)
1199 self
.bases
[op_desc
.base_name
] = op_desc
1201 def find_base(self
, base_name
):
1202 # like self.bases[base_name], but returns None if not found
1203 # (rather than raising exception)
1204 return self
.bases
.get(base_name
)
1206 # internal helper function for concat[Some]Attr{Strings|Lists}
1207 def __internalConcatAttrs(self
, attr_name
, filter, result
):
1208 for op_desc
in self
.items
:
1210 result
+= getattr(op_desc
, attr_name
)
1213 # return a single string that is the concatenation of the (string)
1214 # values of the specified attribute for all operands
1215 def concatAttrStrings(self
, attr_name
):
1216 return self
.__internalConcatAttrs
(attr_name
, lambda x
: 1, '')
1218 # like concatAttrStrings, but only include the values for the operands
1219 # for which the provided filter function returns true
1220 def concatSomeAttrStrings(self
, filter, attr_name
):
1221 return self
.__internalConcatAttrs
(attr_name
, filter, '')
1223 # return a single list that is the concatenation of the (list)
1224 # values of the specified attribute for all operands
1225 def concatAttrLists(self
, attr_name
):
1226 return self
.__internalConcatAttrs
(attr_name
, lambda x
: 1, [])
1228 # like concatAttrLists, but only include the values for the operands
1229 # for which the provided filter function returns true
1230 def concatSomeAttrLists(self
, filter, attr_name
):
1231 return self
.__internalConcatAttrs
(attr_name
, filter, [])
1234 self
.items
.sort(lambda a
, b
: a
.traits
.sort_pri
- b
.traits
.sort_pri
)
1236 # Regular expression object to match C++ comments
1237 # (used in findOperands())
1238 commentRE
= re
.compile(r
'//.*\n')
1240 # Regular expression object to match assignment statements
1241 # (used in findOperands())
1242 assignRE
= re
.compile(r
'\s*=(?!=)', re
.MULTILINE
)
1245 # Find all the operands in the given code block. Returns an operand
1246 # descriptor list (instance of class OperandDescriptorList).
1248 def findOperands(code
):
1249 operands
= OperandDescriptorList()
1250 # delete comments so we don't accidentally match on reg specifiers inside
1251 code
= commentRE
.sub('', code
)
1252 # search for operands
1255 match
= operandsRE
.search(code
, next_pos
)
1257 # no more matches: we're done
1260 # regexp groups are operand full name, base, and extension
1261 (op_full
, op_base
, op_ext
) = op
1262 # if the token following the operand is an assignment, this is
1263 # a destination (LHS), else it's a source (RHS)
1264 is_dest
= (assignRE
.match(code
, match
.end()) != None)
1265 is_src
= not is_dest
1266 # see if we've already seen this one
1267 op_desc
= operands
.find_base(op_base
)
1269 if op_desc
.ext
!= op_ext
:
1270 error(0, 'Inconsistent extensions for operand %s' % op_base
)
1271 op_desc
.is_src
= op_desc
.is_src
or is_src
1272 op_desc
.is_dest
= op_desc
.is_dest
or is_dest
1274 # new operand: create new descriptor
1275 op_desc
= OperandDescriptor(op_full
, op_base
, op_ext
,
1277 operands
.append(op_desc
)
1278 # start next search after end of current match
1279 next_pos
= match
.end()
1281 # enumerate source & dest register operands... used in building
1285 operands
.numFPDestRegs
= 0
1286 operands
.numIntDestRegs
= 0
1287 for op_desc
in operands
:
1288 if op_desc
.traits
.isReg():
1290 op_desc
.src_reg_idx
= srcRegs
1293 op_desc
.dest_reg_idx
= destRegs
1295 if op_desc
.traits
.isFloatReg():
1296 operands
.numFPDestRegs
+= 1
1297 elif op_desc
.traits
.isIntReg():
1298 operands
.numIntDestRegs
+= 1
1299 operands
.numSrcRegs
= srcRegs
1300 operands
.numDestRegs
= destRegs
1301 # now make a final pass to finalize op_desc fields that may depend
1302 # on the register enumeration
1303 for op_desc
in operands
:
1307 # Munge operand names in code string to make legal C++ variable names.
1308 # (Will match munged_name attribute of OperandDescriptor object.)
1309 def substMungedOpNames(code
):
1310 return operandsWithExtRE
.sub(r
'\1_\2', code
)
1313 return map(string
.join
, t
)
1315 def makeFlagConstructor(flag_list
):
1316 if len(flag_list
) == 0:
1318 # filter out repeated flags
1321 while i
< len(flag_list
):
1322 if flag_list
[i
] == flag_list
[i
-1]:
1328 code
= pre
+ string
.join(flag_list
, post
+ pre
) + post
1332 def __init__(self
, code
):
1333 self
.orig_code
= code
1334 self
.operands
= findOperands(code
)
1335 self
.code
= substMungedOpNames(substBitOps(code
))
1336 self
.constructor
= self
.operands
.concatAttrStrings('constructor')
1337 self
.constructor
+= \
1338 '\n\t_numSrcRegs = %d;' % self
.operands
.numSrcRegs
1339 self
.constructor
+= \
1340 '\n\t_numDestRegs = %d;' % self
.operands
.numDestRegs
1341 self
.constructor
+= \
1342 '\n\t_numFPDestRegs = %d;' % self
.operands
.numFPDestRegs
1343 self
.constructor
+= \
1344 '\n\t_numIntDestRegs = %d;' % self
.operands
.numIntDestRegs
1346 self
.op_decl
= self
.operands
.concatAttrStrings('op_decl')
1348 is_mem
= lambda op
: op
.traits
.isMem()
1349 not_mem
= lambda op
: not op
.traits
.isMem()
1351 self
.op_rd
= self
.operands
.concatAttrStrings('op_rd')
1352 self
.op_wb
= self
.operands
.concatAttrStrings('op_wb')
1354 self
.operands
.concatSomeAttrStrings(is_mem
, 'op_rd')
1356 self
.operands
.concatSomeAttrStrings(is_mem
, 'op_wb')
1357 self
.op_nonmem_rd
= \
1358 self
.operands
.concatSomeAttrStrings(not_mem
, 'op_rd')
1359 self
.op_nonmem_wb
= \
1360 self
.operands
.concatSomeAttrStrings(not_mem
, 'op_wb')
1362 self
.flags
= self
.operands
.concatAttrLists('flags')
1364 # Make a basic guess on the operand class (function unit type).
1365 # These are good enough for most cases, and will be overridden
1367 if 'IsStore' in self
.flags
:
1368 self
.op_class
= 'WrPort'
1369 elif 'IsLoad' in self
.flags
or 'IsPrefetch' in self
.flags
:
1370 self
.op_class
= 'RdPort'
1371 elif 'IsFloating' in self
.flags
:
1372 self
.op_class
= 'FloatADD'
1374 self
.op_class
= 'IntALU'
1376 # Assume all instruction flags are of the form 'IsFoo'
1377 instFlagRE
= re
.compile(r
'Is.*')
1379 # OpClass constants are just a little more complicated
1380 opClassRE
= re
.compile(r
'Int.*|Float.*|.*Port|No_OpClass')
1382 class InstObjParams
:
1383 def __init__(self
, mnem
, class_name
, base_class
= '',
1384 code_block
= None, opt_args
= []):
1385 self
.mnemonic
= mnem
1386 self
.class_name
= class_name
1387 self
.base_class
= base_class
1388 self
.exec_func_declarations
= '''
1389 Fault execute(SimpleCPUExecContext *, Trace::InstRecord *);
1390 Fault execute(FastCPUExecContext *, Trace::InstRecord *);
1391 Fault execute(FullCPUExecContext *, Trace::InstRecord *);
1394 for code_attr
in code_block
.__dict
__.keys():
1395 setattr(self
, code_attr
, getattr(code_block
, code_attr
))
1397 self
.constructor
= ''
1399 # Optional arguments are assumed to be either StaticInst flags
1400 # or an OpClass value. To avoid having to import a complete
1401 # list of these values to match against, we do it ad-hoc
1404 if instFlagRE
.match(oa
):
1405 self
.flags
.append(oa
)
1406 elif opClassRE
.match(oa
):
1409 error(0, 'InstObjParams: optional arg "%s" not recognized '
1410 'as StaticInst::Flag or OpClass.' % oa
)
1412 # add flag initialization to contructor here to include
1413 # any flags added via opt_args
1414 self
.constructor
+= makeFlagConstructor(self
.flags
)
1416 # if 'IsFloating' is set, add call to the FP enable check
1417 # function (which should be provided by isa_desc via a declare)
1418 if 'IsFloating' in self
.flags
:
1419 self
.fp_enable_check
= 'fault = checkFpEnableFault(xc);'
1421 self
.fp_enable_check
= ''
1423 def _subst(self
, template
):
1425 return template
% self
.__dict
__
1426 except KeyError, key
:
1427 raise KeyError, 'InstObjParams.subst: no definition for %s' % key
1429 def subst(self
, *args
):
1432 try: template
= templateMap
[t
]
1434 error(0, 'InstObjParams::subst: undefined template "%s"' % t
)
1435 if template
.find('%(cpu_model)') != -1:
1437 for cpu_model
in ('SimpleCPUExecContext', 'FastCPUExecContext',
1438 'FullCPUExecContext'):
1439 self
.cpu_model
= cpu_model
1440 tmp
+= self
._subst
(template
)
1443 result
.append(self
._subst
(template
))
1449 # Read in and parse the ISA description.
1451 def parse_isa_desc(isa_desc_file
, decoder_file
):
1452 # Arguments are the name of the ISA description (input) file and
1453 # the name of the C++ decoder (output) file.
1454 global isa_desc_filename
, decoder_filename
1455 isa_desc_filename
= isa_desc_file
1456 decoder_filename
= decoder_file
1458 # Suck the ISA description file in.
1459 input = open(isa_desc_filename
)
1460 isa_desc
= input.read()
1464 yacc
.parse(isa_desc
)
1466 # Called as script: get args from command line.
1467 if __name__
== '__main__':
1468 parse_isa_desc(sys
.argv
[1], sys
.argv
[2])