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.
38 # Check arguments. Right now there are only two: the name of the ISA
39 # description (input) file and the name of the C++ decoder (output) file.
40 isa_desc_filename
= sys
.argv
[1]
41 decoder_filename
= sys
.argv
[2]
43 # Might as well suck the file in while we're here. This way if it's a
44 # bad filename we don't waste a lot of time building the parser :-).
45 input = open(isa_desc_filename
)
46 isa_desc
= input.read()
49 # Prepend the directory where the PLY lex & yacc modules are found
50 # to the search path. Assumes we're compiling in a subdirectory
51 # of 'build' in the current tree.
52 sys
.path
[0:0] = [os
.environ
['M5_EXT'] + '/ply']
57 #####################################################################
61 # The PLY lexer module takes two things as input:
62 # - A list of token names (the string list 'tokens')
63 # - A regular expression describing a match for each token. The
64 # regexp for token FOO can be provided in two ways:
65 # - as a string variable named t_FOO
66 # - as the doc string for a function named t_FOO. In this case,
67 # the function is also executed, allowing an action to be
68 # associated with each token match.
70 #####################################################################
72 # Reserved words. These are listed separately as they are matched
73 # using the same regexp as generic IDs, but distinguished in the
74 # t_ID() function. The PLY documentation suggests this approach.
76 'BITFIELD', 'DECLARE', 'DECODE', 'DEFAULT', 'DEF', 'FORMAT',
77 'LET', 'NAMESPACE', 'SIGNED', 'TEMPLATE'
80 # List of tokens. The lex module requires this.
94 # ( ) [ ] { } < > , ; : :: *
96 # not used any more... commented out to suppress PLY warning
97 # 'LBRACKET', 'RBRACKET',
100 'COMMA', 'SEMI', 'COLON', 'DBLCOLON',
103 # C preprocessor directives
107 # Regular expressions for token matching
110 # not used any more... commented out to suppress PLY warning
123 # Identifiers and reserved words
126 reserved_map
[r
.lower()] = r
130 t
.type = reserved_map
.get(t
.value
,'ID')
135 r
'(0x[\da-fA-F]+)|\d+'
137 t
.value
= int(t
.value
,0)
139 error(t
.lineno
, 'Integer value "%s" too large' % t
.value
)
143 # String literal. Note that these use only single quotes, and
144 # can span multiple lines.
148 t
.value
= t
.value
[1:-1]
149 t
.lineno
+= t
.value
.count('\n')
153 # "Code literal"... like a string literal, but delimiters are
154 # '{{' and '}}' so they get formatted nicely under emacs c-mode
156 r
"(?m)\{\{([^\}]|}(?!\}))+\}\}"
158 t
.value
= t
.value
[2:-2]
159 t
.lineno
+= t
.value
.count('\n')
162 def t_CPPDIRECTIVE(t
):
164 t
.lineno
+= t
.value
.count('\n')
168 # The functions t_NEWLINE, t_ignore, and t_error are
169 # special for the lex module.
175 t
.lineno
+= t
.value
.count('\n')
181 # Completely ignored characters
186 error(t
.lineno
, "illegal character '%s'" % t
.value
[0])
192 #####################################################################
196 # Every function whose name starts with 'p_' defines a grammar rule.
197 # The rule is encoded in the function's doc string, while the
198 # function body provides the action taken when the rule is matched.
199 # The argument to each function is a list of the values of the
200 # rule's symbols: t[0] for the LHS, and t[1..n] for the symbols
201 # on the RHS. For tokens, the value is copied from the t.value
202 # attribute provided by the lexer. For non-terminals, the value
203 # is assigned by the producing rule; i.e., the job of the grammar
204 # rule function is to set the value for the non-terminal on the LHS
205 # (by assigning to t[0]).
206 #####################################################################
208 # Not sure why, but we get a handful of shift/reduce conflicts on DECLARE.
209 # By default these get resolved as shifts, which is correct, but
210 # warnings are printed. Explicitly marking DECLARE as right-associative
211 # suppresses the warnings.
213 ('right', 'DECLARE'),
216 # The LHS of the first grammar rule is used as the start symbol
217 # (in this case, 'specification'). Note that this rule enforces
218 # that there will be exactly one namespace declaration, with 0 or more
219 # global defs/decls before and after it. The defs & decls before
220 # the namespace decl will be outside the namespace; those after
221 # will be inside. The decoder function is always inside the namespace.
222 def p_specification(t
):
223 'specification : opt_defs_and_declares name_decl opt_defs_and_declares decode_block'
226 namespace
= isa_name
+ "Inst"
228 (inst_decls
, code
) = t
[4]
230 # grab the last three path components of isa_desc_filename
231 filename
= '/'.join(isa_desc_filename
.split('/')[-3:])
232 # if the isa_desc file defines a 'rcs_id' string,
233 # echo that into the output too
235 local_rcs_id
= rcs_id
236 # strip $s out of ID so it doesn't get re-substituted
237 local_rcs_id
= re
.sub(r
'\$', '', local_rcs_id
)
239 local_rcs_id
= 'Id: no RCS id found'
240 output
= open(decoder_filename
, 'w')
241 # split string to keep rcs from substituting this file's RCS id in
242 print >> output
, '/* $Id' + '''$ */
246 * The Regents of The University of Michigan
247 * All Rights Reserved
249 * Permission is granted to use, copy, create derivative works and
250 * redistribute this software and such derivative works for any
251 * purpose, so long as the copyright notice above, this grant of
252 * permission, and the disclaimer below appear in all copies made; and
253 * so long as the name of The University of Michigan is not used in
254 * any advertising or publicity pertaining to the use or distribution
255 * of this software without specific, written prior authorization.
257 * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE
258 * UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND
259 * WITHOUT WARRANTY BY THE UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER
260 * EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
261 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
262 * PURPOSE. THE REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE
263 * LIABLE FOR ANY DAMAGES, INCLUDING DIRECT, SPECIAL, INDIRECT,
264 * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM
265 * ARISING OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
266 * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF SUCH
271 * DO NOT EDIT THIS FILE!!!
273 * It was automatically generated from this ISA description:
274 * Filename: %(filename)s
275 * RCS %(local_rcs_id)s
278 #include "bitfield.hh" // required for bitfield support
281 /////////////////////////////////////
282 // Global defs (outside namespace) //
283 /////////////////////////////////////
288 * Namespace for %(isa_name)s static instruction objects.
290 namespace %(namespace)s
293 /////////////////////////////////////
294 // Global defs (within namespace) //
295 /////////////////////////////////////
299 ////////////////////////////////////
300 // Declares from inst definitions //
301 ////////////////////////////////////
305 } // namespace %(namespace)s
307 //////////////////////
308 // Decoder function //
309 //////////////////////
311 StaticInstPtr<%(isa_name)s>
312 %(isa_name)s::decodeInst(%(isa_name)s::MachInst machInst)
314 using namespace %(namespace)s;
320 # ISA name declaration looks like "namespace <foo>;"
322 'name_decl : NAMESPACE ID SEMI'
325 # 'opt_defs_and_declares' is a possibly empty sequence of
326 # defs and/or declares.
327 def p_opt_defs_and_declares_0(t
):
328 'opt_defs_and_declares : empty'
331 def p_opt_defs_and_declares_1(t
):
332 'opt_defs_and_declares : defs_and_declares'
335 def p_defs_and_declares_0(t
):
336 'defs_and_declares : def_or_declare'
339 def p_defs_and_declares_1(t
):
340 'defs_and_declares : defs_and_declares def_or_declare'
343 # The list of possible definition/declaration statements.
344 def p_def_or_declare(t
):
345 '''def_or_declare : def_format
353 # preprocessor directives are copied directly to the output.
354 def p_cpp_directive(t
):
355 '''cpp_directive : CPPDIRECTIVE'''
358 # Global declares 'declare {{...}}' (C++ code blocks) are copied
359 # directly to the output.
360 def p_global_declare(t
):
361 'global_declare : DECLARE CODELIT SEMI'
362 t
[0] = substBitOps(t
[2])
364 # global let blocks 'let {{...}}' (Python code blocks) are executed
365 # directly when seen. These are typically used to initialize global
366 # Python variables used in later format definitions.
368 'global_let : LET CODELIT SEMI'
370 exec(fixPythonIndentation(t
[2]))
372 error_bt(t
.lineno(1), 'error in global let block "%s".' % t
[2])
373 t
[0] = '' # contributes nothing to the output C++ file
375 # A bitfield definition looks like:
376 # 'def [signed] bitfield <ID> [<first>:<last>]'
377 # This generates a preprocessor macro in the output file.
378 def p_def_bitfield_0(t
):
379 'def_bitfield : DEF opt_signed BITFIELD ID LESS INTLIT COLON INTLIT GREATER SEMI'
380 expr
= 'bits(machInst, %2d, %2d)' % (t
[6], t
[8])
381 if (t
[2] == 'signed'):
382 expr
= 'sext<%d>(%s)' % (t
[6] - t
[8] + 1, expr
)
383 t
[0] = '#undef %s\n#define %s\t%s\n' % (t
[4], t
[4], expr
)
385 # alternate form for single bit: 'def [signed] bitfield <ID> [<bit>]'
386 def p_def_bitfield_1(t
):
387 'def_bitfield : DEF opt_signed BITFIELD ID LESS INTLIT GREATER SEMI'
388 expr
= 'bits(machInst, %2d, %2d)' % (t
[6], t
[6])
389 if (t
[2] == 'signed'):
390 expr
= 'sext<%d>(%s)' % (1, expr
)
391 t
[0] = '#undef %s\n#define %s\t%s\n' % (t
[4], t
[4], expr
)
393 def p_opt_signed_0(t
):
394 'opt_signed : SIGNED'
397 def p_opt_signed_1(t
):
401 # Global map variable to hold templates
404 def p_def_template(t
):
405 'def_template : DEF TEMPLATE ID CODELIT SEMI'
406 templateMap
[t
[3]] = t
[4]
409 # An instruction format definition looks like
410 # "def format <fmt>(<params>) {{...}};"
412 'def_format : DEF FORMAT ID LPAREN param_list RPAREN CODELIT SEMI'
413 (id, params
, code
) = (t
[3], t
[5], t
[7])
414 defFormat(id, params
, code
, t
.lineno(1))
415 # insert a comment into the output to note that the def was processed
418 // parser: format %s defined
422 # The formal parameter list for an instruction format is a possibly
423 # empty list of comma-separated parameters.
424 def p_param_list_0(t
):
428 def p_param_list_1(t
):
432 def p_param_list_2(t
):
433 'param_list : param_list COMMA param'
437 # Each formal parameter is either an identifier or an identifier
438 # preceded by an asterisk. As in Python, the latter (if present) gets
439 # a tuple containing all the excess positional arguments, allowing
446 'param : ASTERISK ID'
447 # just concatenate them: '*ID'
450 # End of format definition-related rules.
454 # A decode block looks like:
455 # decode <field1> [, <field2>]* [default <inst>] { ... }
457 def p_decode_block(t
):
458 'decode_block : DECODE ID opt_default LBRACE decode_stmt_list RBRACE'
459 default_defaults
= defaultStack
.pop()
460 (decls
, code
, has_default
) = t
[5]
461 # use the "default defaults" only if there was no explicit
462 # default statement in decode_stmt_list
464 (default_decls
, default_code
) = default_defaults
465 decls
+= default_decls
471 ''' % (t
[2], indent(code
)))
473 # The opt_default statement serves only to push the "default defaults"
474 # onto defaultStack. This value will be used by nested decode blocks,
475 # and used and popped off when the current decode_block is processed
476 # (in p_decode_block() above).
477 def p_opt_default_0(t
):
478 'opt_default : empty'
479 # no default specified: reuse the one currently at the top of the stack
480 defaultStack
.push(defaultStack
.top())
481 # no meaningful value returned
484 def p_opt_default_1(t
):
485 'opt_default : DEFAULT inst'
486 # push the new default
488 defaultStack
.push((decls
, '\ndefault:\n%sbreak;' % code
))
489 # no meaningful value returned
492 def p_decode_stmt_list_0(t
):
493 'decode_stmt_list : decode_stmt'
496 def p_decode_stmt_list_1(t
):
497 'decode_stmt_list : decode_stmt decode_stmt_list'
498 (decls1
, code1
, has_default1
) = t
[1]
499 (decls2
, code2
, has_default2
) = t
[2]
500 if (has_default1
and has_default2
):
501 error(t
.lineno(1), 'Two default cases in decode block')
502 t
[0] = (decls1
+ '\n' + decls2
, code1
+ '\n' + code2
,
503 has_default1
or has_default2
)
506 # Decode statement rules
508 # There are four types of statements allowed in a decode block:
509 # 1. Format blocks 'format <foo> { ... }'
510 # 2. Nested decode blocks
511 # 3. Instruction definitions.
512 # 4. C preprocessor directives.
515 # Preprocessor directives found in a decode statement list are passed
516 # through to the output, replicated to both the declaration and decode
517 # streams. This works well for ifdefs, so we can ifdef out both the
518 # declarations and the decode cases generated by an instruction
519 # definition. Handling them as part of the grammar makes it easy to
520 # keep them in the right place with respect to the code generated by
521 # the other statements.
522 def p_decode_stmt_cpp(t
):
523 'decode_stmt : CPPDIRECTIVE'
524 t
[0] = (t
[1], t
[1], 0)
526 # A format block 'format <foo> { ... }' sets the default instruction
527 # format used to handle instruction definitions inside the block.
528 # This format can be overridden by using an explicit format on the
529 # instruction definition or with a nested format block.
530 def p_decode_stmt_format(t
):
531 'decode_stmt : FORMAT push_format_id LBRACE decode_stmt_list RBRACE'
532 # The format will be pushed on the stack when 'push_format_id' is
533 # processed (see below). Once the parser has recognized the full
534 # production (though the right brace), we're done with the format,
535 # so now we can pop it.
539 # This rule exists so we can set the current format (& push the stack)
540 # when we recognize the format name part of the format block.
541 def p_push_format_id(t
):
542 'push_format_id : ID'
544 formatStack
.push(formatMap
[t
[1]])
545 t
[0] = ('', '// format %s' % t
[1])
547 error(t
.lineno(1), 'instruction format "%s" not defined.' % t
[1])
549 # Nested decode block: if the value of the current field matches the
550 # specified constant, do a nested decode on some other field.
551 def p_decode_stmt_decode(t
):
552 'decode_stmt : case_label COLON decode_block'
553 (label
, is_default
) = t
[1]
555 # just wrap the decoding code from the block as a case in the
556 # outer switch statement.
557 t
[0] = (decls
, '\n%s:\n%s' % (label
, indent(code
)), is_default
)
559 # Instruction definition (finally!).
560 def p_decode_stmt_inst(t
):
561 'decode_stmt : case_label COLON inst SEMI'
562 (label
, is_default
) = t
[1]
564 t
[0] = (decls
, '\n%s:%sbreak;' % (label
, indent(code
)), is_default
)
566 # The case label is either a list of one or more constants or 'default'
567 def p_case_label_0(t
):
568 'case_label : intlit_list'
569 t
[0] = (': '.join(map(lambda a
: 'case %#x' % a
, t
[1])), 0)
571 def p_case_label_1(t
):
572 'case_label : DEFAULT'
573 t
[0] = ('default', 1)
576 # The constant list for a decode case label must be non-empty, but may have
577 # one or more comma-separated integer literals in it.
579 def p_intlit_list_0(t
):
580 'intlit_list : INTLIT'
583 def p_intlit_list_1(t
):
584 'intlit_list : intlit_list COMMA INTLIT'
588 # Define an instruction using the current instruction format (specified
589 # by an enclosing format block).
590 # "<mnemonic>(<args>)"
592 'inst : ID LPAREN arg_list RPAREN'
593 # Pass the ID and arg list to the current format class to deal with.
594 currentFormat
= formatStack
.top()
595 (decls
, code
) = 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
+ 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
, code
) = format
.defineInst(t
[3], t
[5], t
.lineno(1))
611 comment
= '// %s::%s(%s)\n' % (t
[1], t
[3], t
[5])
612 t
[0] = (comment
+ decls
, comment
+ code
)
623 'arg_list : arg_list COMMA arg'
635 # Empty production... use in other rules for readability.
641 # Parse error handler. Note that the argument here is the offending
642 # *token*, not a grammar symbol (hence the need to use t.value)
645 error(t
.lineno
, "syntax error at '%s'" % t
.value
)
647 error_bt(0, "unknown syntax error")
649 # END OF GRAMMAR RULES
651 # Now build the parser.
657 # A format object encapsulates an instruction format. It must provide
658 # a defineInst() method that generates the code for an instruction
662 def __init__(self
, id, params
, code
):
663 # constructor: just save away arguments
666 # strip blank lines from code (ones at the end are troublesome)
667 code
= re
.sub(r
'(?m)^\s*$', '', code
);
670 param_list
= string
.join(params
, ", ")
671 f
= 'def defInst(name, Name, ' + param_list
+ '):\n' + code
675 def defineInst(self
, name
, args
, lineno
):
676 # automatically provide a capitalized version of mnemonic
677 Name
= string
.capitalize(name
)
679 retval
= self
.func(name
, Name
, *args
)
681 error_bt(lineno
, 'error defining "%s".' % name
)
684 # Special null format to catch an implicit-format instruction
685 # definition outside of any format block.
688 self
.defaultInst
= ''
690 def defineInst(self
, name
, args
, lineno
):
692 'instruction definition "%s" with no active format!' % name
)
694 # This dictionary maps format name strings to Format objects.
697 # Define a new format
698 def defFormat(id, params
, code
, lineno
):
699 # make sure we haven't already defined this one
700 if formatMap
.get(id, None) != None:
701 error(lineno
, 'format %s redefined.' % id)
702 # create new object and store in global map
703 formatMap
[id] = Format(id, params
, code
)
707 # Stack: a simple stack object. Used for both formats (formatStack)
708 # and default cases (defaultStack).
711 def __init__(self
, initItem
):
712 self
.stack
= [ initItem
]
714 def push(self
, item
):
715 self
.stack
.append(item
);
718 return self
.stack
.pop()
721 return self
.stack
[-1]
723 # The global format stack.
724 formatStack
= Stack(NoFormat())
726 # The global default case stack.
727 defaultStack
= Stack( None )
733 # Indent every line in string 's' by two spaces
734 # (except preprocessor directives).
735 # Used to make nested code blocks look pretty.
738 return re
.sub(r
'(?m)^(?!\#)', ' ', s
)
741 # Munge a somewhat arbitrarily formatted piece of Python code
742 # (e.g. from a format 'let' block) into something whose indentation
743 # will get by the Python parser.
745 # The two keys here are that Python will give a syntax error if
746 # there's any whitespace at the beginning of the first line, and that
747 # all lines at the same lexical nesting level must have identical
748 # indentation. Unfortunately the way code literals work, an entire
749 # let block tends to have some initial indentation. Rather than
750 # trying to figure out what that is and strip it off, we prepend 'if
751 # 1:' to make the let code the nested block inside the if (and have
752 # the parser automatically deal with the indentation for us).
754 # We don't want to do this if (1) the code block is empty or (2) the
755 # first line of the block doesn't have any whitespace at the front.
757 def fixPythonIndentation(s
):
758 # get rid of blank lines first
759 s
= re
.sub(r
'(?m)^\s*\n', '', s
);
760 if (s
!= '' and re
.match(r
'[ \t]', s
[0])):
764 # Error handler. Just call exit. Output formatted to work under
765 # Emacs compile-mode.
766 def error(lineno
, string
):
767 sys
.exit("%s:%d: %s" % (isa_desc_filename
, lineno
, string
))
769 # Like error(), but include a Python stack backtrace (for processing
770 # Python exceptions).
771 def error_bt(lineno
, string
):
772 print >> sys
.stderr
, "%s:%d: %s" % (isa_desc_filename
, lineno
, string
)
776 #####################################################################
778 # Bitfield Operator Support
780 #####################################################################
782 bitOp1ArgRE
= re
.compile(r
'<\s*(\w+)\s*:\s*>')
784 bitOpWordRE
= re
.compile(r
'(?<![\w\.])([\w\.]+)<\s*(\w+)\s*:\s*(\w+)\s*>')
785 bitOpExprRE
= re
.compile(r
'\)<\s*(\w+)\s*:\s*(\w+)\s*>')
787 def substBitOps(code
):
788 # first convert single-bit selectors to two-index form
789 # i.e., <n> --> <n:n>
790 code
= bitOp1ArgRE
.sub(r
'<\1:\1>', code
)
791 # simple case: selector applied to ID (name)
792 # i.e., foo<a:b> --> bits(foo, a, b)
793 code
= bitOpWordRE
.sub(r
'bits(\1, \2, \3)', code
)
794 # if selector is applied to expression (ending in ')'),
795 # we need to search backward for matching '('
796 match
= bitOpExprRE
.search(code
)
798 exprEnd
= match
.start()
802 if code
[here
] == '(':
804 elif code
[here
] == ')':
808 sys
.exit("Didn't find '('!")
810 newExpr
= r
'bits(%s, %s, %s)' % (code
[exprStart
:exprEnd
+1],
811 match
.group(1), match
.group(2))
812 code
= code
[:exprStart
] + newExpr
+ code
[match
.end():]
813 match
= bitOpExprRE
.search(code
)
817 #####################################################################
821 # The remaining code is the support for automatically extracting
822 # instruction characteristics from pseudocode.
824 #####################################################################
826 # Force the argument to be a list
827 def makeList(list_or_item
):
830 elif type(list_or_item
) == ListType
:
833 return [ list_or_item
]
835 # generate operandSizeMap based on provided operandTypeMap:
836 # basically generate equiv. C++ type and make is_signed flag
837 def buildOperandSizeMap():
838 global operandSizeMap
840 for ext
in operandTypeMap
.keys():
841 (desc
, size
) = operandTypeMap
[ext
]
842 if desc
== 'signed int':
843 type = 'int%d_t' % size
845 elif desc
== 'unsigned int':
846 type = 'uint%d_t' % size
848 elif desc
== 'float':
849 is_signed
= 1 # shouldn't really matter
855 error(0, 'Unrecognized type description "%s" in operandTypeMap')
856 operandSizeMap
[ext
] = (size
, type, is_signed
)
859 # Base class for operand traits. An instance of this class (or actually
860 # a class derived from this one) encapsulates the traits of a particular
861 # operand type (e.g., "32-bit integer register").
864 def __init__(self
, dflt_ext
, reg_spec
, flags
, sort_pri
):
865 # Force construction of operandSizeMap from operandTypeMap
866 # if it hasn't happened yet
867 if not globals().has_key('operandSizeMap'):
868 buildOperandSizeMap()
869 self
.dflt_ext
= dflt_ext
870 (self
.dflt_size
, self
.dflt_type
, self
.dflt_is_signed
) = \
871 operandSizeMap
[dflt_ext
]
872 self
.reg_spec
= reg_spec
873 # Canonical flag structure is a triple of lists, where each list
874 # indicates the set of flags implied by this operand always, when
875 # used as a source, and when used as a dest, respectively.
876 # For simplicity this can be initialized using a variety of fairly
877 # obvious shortcuts; we convert these to canonical form here.
879 # no flags specified (e.g., 'None')
880 self
.flags
= ( [], [], [] )
881 elif type(flags
) == StringType
:
882 # a single flag: assumed to be unconditional
883 self
.flags
= ( [ flags
], [], [] )
884 elif type(flags
) == ListType
:
885 # a list of flags: also assumed to be unconditional
886 self
.flags
= ( flags
, [], [] )
887 elif type(flags
) == TupleType
:
888 # it's a tuple: it should be a triple,
889 # but each item could be a single string or a list
890 (uncond_flags
, src_flags
, dest_flags
) = flags
891 self
.flags
= (makeList(uncond_flags
),
892 makeList(src_flags
), makeList(dest_flags
))
893 self
.sort_pri
= sort_pri
901 def isFloatReg(self
):
907 def isControlReg(self
):
910 def getFlags(self
, op_desc
):
911 # note the empty slice '[:]' gives us a copy of self.flags[0]
912 # instead of a reference to it
913 my_flags
= self
.flags
[0][:]
915 my_flags
+= self
.flags
[1]
917 my_flags
+= self
.flags
[2]
920 def makeDecl(self
, op_desc
):
921 (size
, type, is_signed
) = operandSizeMap
[op_desc
.eff_ext
]
922 # Note that initializations in the declarations are solely
923 # to avoid 'uninitialized variable' errors from the compiler.
924 return type + ' ' + op_desc
.munged_name
+ ' = 0;\n';
926 class IntRegOperandTraits(OperandTraits
):
933 def makeConstructor(self
, op_desc
):
936 c
+= '\n\t_srcRegIdx[%d] = %s;' % \
937 (op_desc
.src_reg_idx
, self
.reg_spec
)
939 c
+= '\n\t_destRegIdx[%d] = %s;' % \
940 (op_desc
.dest_reg_idx
, self
.reg_spec
)
943 def makeRead(self
, op_desc
, cpu_model
):
944 (size
, type, is_signed
) = operandSizeMap
[op_desc
.eff_ext
]
945 if (type == 'float' or type == 'double'):
946 error(0, 'Attempt to read integer register as FP')
947 if (size
== self
.dflt_size
):
948 return '%s = xc->readIntReg(_srcRegIdx[%d]);\n' % \
949 (op_desc
.munged_name
, op_desc
.src_reg_idx
)
951 return '%s = bits(xc->readIntReg(_srcRegIdx[%d]), %d, 0);\n' % \
952 (op_desc
.munged_name
, op_desc
.src_reg_idx
, size
-1)
954 def makeWrite(self
, op_desc
, cpu_model
):
955 (size
, type, is_signed
) = operandSizeMap
[op_desc
.eff_ext
]
956 if (type == 'float' or type == 'double'):
957 error(0, 'Attempt to write integer register as FP')
958 if (size
!= self
.dflt_size
and is_signed
):
959 final_val
= 'sext<%d>(%s)' % (size
, op_desc
.munged_name
)
961 final_val
= op_desc
.munged_name
965 xc->setIntReg(_destRegIdx[%d], final_val);\n
966 if (traceData) { traceData->setData(final_val); }
967 }''' % (self
.dflt_type
, final_val
, op_desc
.dest_reg_idx
)
970 class FloatRegOperandTraits(OperandTraits
):
974 def isFloatReg(self
):
977 def makeConstructor(self
, op_desc
):
980 c
+= '\n\t_srcRegIdx[%d] = %s + FP_Base_DepTag;' % \
981 (op_desc
.src_reg_idx
, self
.reg_spec
)
983 c
+= '\n\t_destRegIdx[%d] = %s + FP_Base_DepTag;' % \
984 (op_desc
.dest_reg_idx
, self
.reg_spec
)
987 def makeRead(self
, op_desc
, cpu_model
):
988 (size
, type, is_signed
) = operandSizeMap
[op_desc
.eff_ext
]
990 if (type == 'float'):
991 func
= 'readFloatRegSingle'
992 elif (type == 'double'):
993 func
= 'readFloatRegDouble'
995 func
= 'readFloatRegInt'
996 if (size
!= self
.dflt_size
):
998 base
= 'xc->%s(_srcRegIdx[%d] - FP_Base_DepTag)' % \
999 (func
, op_desc
.src_reg_idx
)
1001 return '%s = bits(%s, %d, 0);\n' % \
1002 (op_desc
.munged_name
, base
, size
-1)
1004 return '%s = %s;\n' % (op_desc
.munged_name
, base
)
1006 def makeWrite(self
, op_desc
, cpu_model
):
1007 (size
, type, is_signed
) = operandSizeMap
[op_desc
.eff_ext
]
1008 final_val
= op_desc
.munged_name
1009 if (type == 'float'):
1010 func
= 'setFloatRegSingle'
1011 elif (type == 'double'):
1012 func
= 'setFloatRegDouble'
1014 func
= 'setFloatRegInt'
1015 type = 'uint%d_t' % self
.dflt_size
1016 if (size
!= self
.dflt_size
and is_signed
):
1017 final_val
= 'sext<%d>(%s)' % (size
, op_desc
.munged_name
)
1021 xc->%s(_destRegIdx[%d] - FP_Base_DepTag, final_val);\n
1022 if (traceData) { traceData->setData(final_val); }
1023 }''' % (type, final_val
, func
, op_desc
.dest_reg_idx
)
1026 class ControlRegOperandTraits(OperandTraits
):
1030 def isControlReg(self
):
1033 def makeConstructor(self
, op_desc
):
1036 c
+= '\n\t_srcRegIdx[%d] = %s_DepTag;' % \
1037 (op_desc
.src_reg_idx
, self
.reg_spec
)
1039 c
+= '\n\t_destRegIdx[%d] = %s_DepTag;' % \
1040 (op_desc
.dest_reg_idx
, self
.reg_spec
)
1043 def makeRead(self
, op_desc
, cpu_model
):
1044 (size
, type, is_signed
) = operandSizeMap
[op_desc
.eff_ext
]
1046 if (type == 'float' or type == 'double'):
1047 error(0, 'Attempt to read control register as FP')
1048 base
= 'xc->read%s()' % self
.reg_spec
1049 if size
== self
.dflt_size
:
1050 return '%s = %s;\n' % (op_desc
.munged_name
, base
)
1052 return '%s = bits(%s, %d, 0);\n' % \
1053 (op_desc
.munged_name
, base
, size
-1)
1055 def makeWrite(self
, op_desc
, cpu_model
):
1056 (size
, type, is_signed
) = operandSizeMap
[op_desc
.eff_ext
]
1057 if (type == 'float' or type == 'double'):
1058 error(0, 'Attempt to write control register as FP')
1059 wb
= 'xc->set%s(%s);\n' % (self
.reg_spec
, op_desc
.munged_name
)
1060 wb
+= 'if (traceData) { traceData->setData(%s); }' % \
1064 class MemOperandTraits(OperandTraits
):
1068 def makeConstructor(self
, op_desc
):
1071 def makeDecl(self
, op_desc
):
1072 (size
, type, is_signed
) = operandSizeMap
[op_desc
.eff_ext
]
1073 # Note that initializations in the declarations are solely
1074 # to avoid 'uninitialized variable' errors from the compiler.
1075 # Declare memory data variable.
1076 c
= '%s %s = 0;\n' % (type, op_desc
.munged_name
)
1077 # Declare var to hold memory access flags.
1078 c
+= 'unsigned %s_flags = memAccessFlags;\n' % op_desc
.base_name
1079 # If this operand is a dest (i.e., it's a store operation),
1080 # then we need to declare a variable for the write result code
1083 c
+= 'uint64_t %s_write_result = 0;\n' % op_desc
.base_name
1086 def makeRead(self
, op_desc
, cpu_model
):
1087 (size
, type, is_signed
) = operandSizeMap
[op_desc
.eff_ext
]
1088 eff_type
= 'uint%d_t' % size
1089 return 'fault = memAccessObj->read(EA, (%s&)%s, %s_flags);\n' \
1090 % (eff_type
, op_desc
.munged_name
, op_desc
.base_name
)
1092 def makeWrite(self
, op_desc
, cpu_model
):
1093 (size
, type, is_signed
) = operandSizeMap
[op_desc
.eff_ext
]
1094 eff_type
= 'uint%d_t' % size
1095 return 'fault = memAccessObj->write((%s&)%s, EA, %s_flags,' \
1096 ' &%s_write_result);\n' \
1097 % (eff_type
, op_desc
.munged_name
, op_desc
.base_name
,
1100 class NPCOperandTraits(OperandTraits
):
1101 def makeConstructor(self
, op_desc
):
1104 def makeRead(self
, op_desc
, cpu_model
):
1105 return '%s = xc->readPC() + 4;\n' % op_desc
.munged_name
1107 def makeWrite(self
, op_desc
, cpu_model
):
1108 return 'xc->setNextPC(%s);\n' % op_desc
.munged_name
1112 # Define operand variables that get derived from the basic declaration
1113 # of ISA-specific operands in operandTraitsMap. This function must be
1114 # called by the ISA description file explicitly after defining
1115 # operandTraitsMap (in a 'let' block).
1117 def defineDerivedOperandVars():
1119 operands
= operandTraitsMap
.keys()
1121 operandsREString
= (r
'''
1122 (?<![\w\.]) # neg. lookbehind assertion: prevent partial matches
1123 ((%s)(?:\.(\w+))?) # match: operand with optional '.' then suffix
1124 (?![\w\.]) # neg. lookahead assertion: prevent partial matches
1126 % string
.join(operands
, '|'))
1129 operandsRE
= re
.compile(operandsREString
, re
.MULTILINE|re
.VERBOSE
)
1131 # Same as operandsREString, but extension is mandatory, and only two
1132 # groups are returned (base and ext, not full name as above).
1133 # Used for subtituting '_' for '.' to make C++ identifiers.
1134 operandsWithExtREString
= (r
'(?<![\w\.])(%s)\.(\w+)(?![\w\.])'
1135 % string
.join(operands
, '|'))
1137 global operandsWithExtRE
1138 operandsWithExtRE
= re
.compile(operandsWithExtREString
, re
.MULTILINE
)
1142 # Operand descriptor class. An instance of this class represents
1143 # a specific operand for a code block.
1145 class OperandDescriptor
:
1146 def __init__(self
, full_name
, base_name
, ext
, is_src
, is_dest
):
1147 self
.full_name
= full_name
1148 self
.base_name
= base_name
1150 self
.is_src
= is_src
1151 self
.is_dest
= is_dest
1152 self
.traits
= operandTraitsMap
[base_name
]
1153 # The 'effective extension' (eff_ext) is either the actual
1154 # extension, if one was explicitly provided, or the default.
1155 # The 'munged name' replaces the '.' between the base and
1156 # extension (if any) with a '_' to make a legal C++ variable name.
1159 self
.munged_name
= base_name
+ '_' + ext
1161 self
.eff_ext
= self
.traits
.dflt_ext
1162 self
.munged_name
= base_name
1164 # Finalize additional fields (primarily code fields). This step
1165 # is done separately since some of these fields may depend on the
1166 # register index enumeration that hasn't been performed yet at the
1167 # time of __init__().
1169 self
.flags
= self
.traits
.getFlags(self
)
1170 self
.constructor
= self
.traits
.makeConstructor(self
)
1171 self
.exec_decl
= self
.traits
.makeDecl(self
)
1174 self
.simple_rd
= self
.traits
.makeRead(self
, 'simple')
1175 self
.dtld_rd
= self
.traits
.makeRead(self
, 'dtld')
1181 self
.simple_wb
= self
.traits
.makeWrite(self
, 'simple')
1182 self
.dtld_wb
= self
.traits
.makeWrite(self
, 'dtld')
1187 class OperandDescriptorList
:
1193 return len(self
.items
)
1195 def __getitem__(self
, index
):
1196 return self
.items
[index
]
1198 def append(self
, op_desc
):
1199 self
.items
.append(op_desc
)
1200 self
.bases
[op_desc
.base_name
] = op_desc
1202 def find_base(self
, base_name
):
1203 # like self.bases[base_name], but returns None if not found
1204 # (rather than raising exception)
1205 return self
.bases
.get(base_name
)
1207 # internal helper function for concat[Some]Attr{Strings|Lists}
1208 def __internalConcatAttrs(self
, attr_name
, filter, result
):
1209 for op_desc
in self
.items
:
1211 result
+= getattr(op_desc
, attr_name
)
1214 # return a single string that is the concatenation of the (string)
1215 # values of the specified attribute for all operands
1216 def concatAttrStrings(self
, attr_name
):
1217 return self
.__internalConcatAttrs
(attr_name
, lambda x
: 1, '')
1219 # like concatAttrStrings, but only include the values for the operands
1220 # for which the provided filter function returns true
1221 def concatSomeAttrStrings(self
, filter, attr_name
):
1222 return self
.__internalConcatAttrs
(attr_name
, filter, '')
1224 # return a single list that is the concatenation of the (list)
1225 # values of the specified attribute for all operands
1226 def concatAttrLists(self
, attr_name
):
1227 return self
.__internalConcatAttrs
(attr_name
, lambda x
: 1, [])
1229 # like concatAttrLists, but only include the values for the operands
1230 # for which the provided filter function returns true
1231 def concatSomeAttrLists(self
, filter, attr_name
):
1232 return self
.__internalConcatAttrs
(attr_name
, filter, [])
1235 self
.items
.sort(lambda a
, b
: a
.traits
.sort_pri
- b
.traits
.sort_pri
)
1237 # Regular expression object to match C++ comments
1238 # (used in findOperands())
1239 commentRE
= re
.compile(r
'//.*\n')
1241 # Regular expression object to match assignment statements
1242 # (used in findOperands())
1243 assignRE
= re
.compile(r
'\s*=(?!=)', re
.MULTILINE
)
1246 # Find all the operands in the given code block. Returns an operand
1247 # descriptor list (instance of class OperandDescriptorList).
1249 def findOperands(code
):
1250 operands
= OperandDescriptorList()
1251 # delete comments so we don't accidentally match on reg specifiers inside
1252 code
= commentRE
.sub('', code
)
1253 # search for operands
1256 match
= operandsRE
.search(code
, next_pos
)
1258 # no more matches: we're done
1261 # regexp groups are operand full name, base, and extension
1262 (op_full
, op_base
, op_ext
) = op
1263 # if the token following the operand is an assignment, this is
1264 # a destination (LHS), else it's a source (RHS)
1265 is_dest
= (assignRE
.match(code
, match
.end()) != None)
1266 is_src
= not is_dest
1267 # see if we've already seen this one
1268 op_desc
= operands
.find_base(op_base
)
1270 if op_desc
.ext
!= op_ext
:
1271 error(0, 'Inconsistent extensions for operand %s' % op_base
)
1272 op_desc
.is_src
= op_desc
.is_src
or is_src
1273 op_desc
.is_dest
= op_desc
.is_dest
or is_dest
1275 # new operand: create new descriptor
1276 op_desc
= OperandDescriptor(op_full
, op_base
, op_ext
,
1278 operands
.append(op_desc
)
1279 # start next search after end of current match
1280 next_pos
= match
.end()
1282 # enumerate source & dest register operands... used in building
1286 operands
.numFPDestRegs
= 0
1287 operands
.numIntDestRegs
= 0
1288 for op_desc
in operands
:
1289 if op_desc
.traits
.isReg():
1291 op_desc
.src_reg_idx
= srcRegs
1294 op_desc
.dest_reg_idx
= destRegs
1296 if op_desc
.traits
.isFloatReg():
1297 operands
.numFPDestRegs
+= 1
1298 elif op_desc
.traits
.isIntReg():
1299 operands
.numIntDestRegs
+= 1
1300 operands
.numSrcRegs
= srcRegs
1301 operands
.numDestRegs
= destRegs
1302 # now make a final pass to finalize op_desc fields that may depend
1303 # on the register enumeration
1304 for op_desc
in operands
:
1308 # Munge operand names in code string to make legal C++ variable names.
1309 # (Will match munged_name attribute of OperandDescriptor object.)
1310 def substMungedOpNames(code
):
1311 return operandsWithExtRE
.sub(r
'\1_\2', code
)
1314 return map(string
.join
, t
)
1316 def makeFlagConstructor(flag_list
):
1317 if len(flag_list
) == 0:
1319 # filter out repeated flags
1322 while i
< len(flag_list
):
1323 if flag_list
[i
] == flag_list
[i
-1]:
1329 code
= pre
+ string
.join(flag_list
, post
+ pre
) + post
1333 def __init__(self
, code
):
1334 self
.orig_code
= code
1335 self
.operands
= findOperands(code
)
1336 self
.code
= substMungedOpNames(substBitOps(code
))
1337 self
.constructor
= self
.operands
.concatAttrStrings('constructor')
1338 self
.constructor
+= \
1339 '\n\t_numSrcRegs = %d;' % self
.operands
.numSrcRegs
1340 self
.constructor
+= \
1341 '\n\t_numDestRegs = %d;' % self
.operands
.numDestRegs
1342 self
.constructor
+= \
1343 '\n\t_numFPDestRegs = %d;' % self
.operands
.numFPDestRegs
1344 self
.constructor
+= \
1345 '\n\t_numIntDestRegs = %d;' % self
.operands
.numIntDestRegs
1347 self
.exec_decl
= self
.operands
.concatAttrStrings('exec_decl')
1349 is_mem
= lambda op
: op
.traits
.isMem()
1350 not_mem
= lambda op
: not op
.traits
.isMem()
1352 self
.simple_rd
= self
.operands
.concatAttrStrings('simple_rd')
1353 self
.simple_wb
= self
.operands
.concatAttrStrings('simple_wb')
1354 self
.simple_mem_rd
= \
1355 self
.operands
.concatSomeAttrStrings(is_mem
, 'simple_rd')
1356 self
.simple_mem_wb
= \
1357 self
.operands
.concatSomeAttrStrings(is_mem
, 'simple_wb')
1358 self
.simple_nonmem_rd
= \
1359 self
.operands
.concatSomeAttrStrings(not_mem
, 'simple_rd')
1360 self
.simple_nonmem_wb
= \
1361 self
.operands
.concatSomeAttrStrings(not_mem
, 'simple_wb')
1363 self
.dtld_rd
= self
.operands
.concatAttrStrings('dtld_rd')
1364 self
.dtld_wb
= self
.operands
.concatAttrStrings('dtld_wb')
1365 self
.dtld_mem_rd
= \
1366 self
.operands
.concatSomeAttrStrings(is_mem
, 'dtld_rd')
1367 self
.dtld_mem_wb
= \
1368 self
.operands
.concatSomeAttrStrings(is_mem
, 'dtld_wb')
1369 self
.dtld_nonmem_rd
= \
1370 self
.operands
.concatSomeAttrStrings(not_mem
, 'dtld_rd')
1371 self
.dtld_nonmem_wb
= \
1372 self
.operands
.concatSomeAttrStrings(not_mem
, 'dtld_wb')
1374 self
.flags
= self
.operands
.concatAttrLists('flags')
1376 # Make a basic guess on the operand class (function unit type).
1377 # These are good enough for most cases, and will be overridden
1379 if 'IsStore' in self
.flags
:
1380 self
.op_class
= 'WrPort'
1381 elif 'IsLoad' in self
.flags
or 'IsPrefetch' in self
.flags
:
1382 self
.op_class
= 'RdPort'
1383 elif 'IsFloating' in self
.flags
:
1384 self
.op_class
= 'FloatADD'
1386 self
.op_class
= 'IntALU'
1388 # Assume all instruction flags are of the form 'IsFoo'
1389 instFlagRE
= re
.compile(r
'Is.*')
1391 # OpClass constants are just a little more complicated
1392 opClassRE
= re
.compile(r
'Int.*|Float.*|.*Port|No_OpClass')
1394 class InstObjParams
:
1395 def __init__(self
, mnem
, class_name
, base_class
= '',
1396 code_block
= None, opt_args
= []):
1397 self
.mnemonic
= mnem
1398 self
.class_name
= class_name
1399 self
.base_class
= base_class
1401 for code_attr
in code_block
.__dict
__.keys():
1402 setattr(self
, code_attr
, getattr(code_block
, code_attr
))
1404 self
.constructor
= ''
1406 # Optional arguments are assumed to be either StaticInst flags
1407 # or an OpClass value. To avoid having to import a complete
1408 # list of these values to match against, we do it ad-hoc
1411 if instFlagRE
.match(oa
):
1412 self
.flags
.append(oa
)
1413 elif opClassRE
.match(oa
):
1416 error(0, 'InstObjParams: optional arg "%s" not recognized '
1417 'as StaticInst::Flag or OpClass.' % oa
)
1419 # add flag initialization to contructor here to include
1420 # any flags added via opt_args
1421 self
.constructor
+= makeFlagConstructor(self
.flags
)
1423 # if 'IsFloating' is set, add call to the FP enable check
1424 # function (which should be provided by isa_desc via a declare)
1425 if 'IsFloating' in self
.flags
:
1426 self
.fp_enable_check
= 'fault = checkFpEnableFault(xc);'
1428 self
.fp_enable_check
= ''
1430 def subst(self
, *args
):
1433 if not templateMap
.has_key(t
):
1434 error(0, 'InstObjParams::subst: undefined template "%s"' % t
)
1436 result
.append(templateMap
[t
] % self
.__dict
__)
1437 except KeyError, key
:
1438 error(0, 'InstObjParams::subst: no definition for "%s"' % key
)
1444 # All set... read in and parse the ISA description.
1446 yacc
.parse(isa_desc
)