Merge zizzer:/bk/m5 into isabel.reinhardt.house:/z/stever/bk/m5
[gem5.git] / arch / isa_parser.py
1 #! /usr/bin/env python
2
3 # $Id$
4
5 # Copyright (c) 2003 The Regents of The University of Michigan
6 # All rights reserved.
7 #
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.
18 #
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.
30
31 import os
32 import sys
33 import re
34 import string
35 # get type names
36 from types import *
37
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]
42
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()
47 input.close()
48
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']
53
54 import lex
55 import yacc
56
57 #####################################################################
58 #
59 # Lexer
60 #
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.
69 #
70 #####################################################################
71
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.
75 reserved = (
76 'BITFIELD', 'DECLARE', 'DECODE', 'DEFAULT', 'DEF', 'FORMAT',
77 'LET', 'NAMESPACE', 'SIGNED', 'TEMPLATE'
78 )
79
80 # List of tokens. The lex module requires this.
81 tokens = reserved + (
82 # identifier
83 'ID',
84
85 # integer literal
86 'INTLIT',
87
88 # string literal
89 'STRLIT',
90
91 # code literal
92 'CODELIT',
93
94 # ( ) [ ] { } < > , ; : :: *
95 'LPAREN', 'RPAREN',
96 # not used any more... commented out to suppress PLY warning
97 # 'LBRACKET', 'RBRACKET',
98 'LBRACE', 'RBRACE',
99 'LESS', 'GREATER',
100 'COMMA', 'SEMI', 'COLON', 'DBLCOLON',
101 'ASTERISK',
102
103 # C preprocessor directives
104 'CPPDIRECTIVE'
105 )
106
107 # Regular expressions for token matching
108 t_LPAREN = r'\('
109 t_RPAREN = r'\)'
110 # not used any more... commented out to suppress PLY warning
111 # t_LBRACKET = r'\['
112 # t_RBRACKET = r'\]'
113 t_LBRACE = r'\{'
114 t_RBRACE = r'\}'
115 t_LESS = r'\<'
116 t_GREATER = r'\>'
117 t_COMMA = r','
118 t_SEMI = r';'
119 t_COLON = r':'
120 t_DBLCOLON = r'::'
121 t_ASTERISK = r'\*'
122
123 # Identifiers and reserved words
124 reserved_map = { }
125 for r in reserved:
126 reserved_map[r.lower()] = r
127
128 def t_ID(t):
129 r'[A-Za-z_]\w*'
130 t.type = reserved_map.get(t.value,'ID')
131 return t
132
133 # Integer literal
134 def t_INTLIT(t):
135 r'(0x[\da-fA-F]+)|\d+'
136 try:
137 t.value = int(t.value,0)
138 except ValueError:
139 error(t.lineno, 'Integer value "%s" too large' % t.value)
140 t.value = 0
141 return t
142
143 # String literal. Note that these use only single quotes, and
144 # can span multiple lines.
145 def t_STRLIT(t):
146 r"(?m)'([^'])+'"
147 # strip off quotes
148 t.value = t.value[1:-1]
149 t.lineno += t.value.count('\n')
150 return t
151
152
153 # "Code literal"... like a string literal, but delimiters are
154 # '{{' and '}}' so they get formatted nicely under emacs c-mode
155 def t_CODELIT(t):
156 r"(?m)\{\{([^\}]|}(?!\}))+\}\}"
157 # strip off {{ & }}
158 t.value = t.value[2:-2]
159 t.lineno += t.value.count('\n')
160 return t
161
162 def t_CPPDIRECTIVE(t):
163 r'^\#.*\n'
164 t.lineno += t.value.count('\n')
165 return t
166
167 #
168 # The functions t_NEWLINE, t_ignore, and t_error are
169 # special for the lex module.
170 #
171
172 # Newlines
173 def t_NEWLINE(t):
174 r'\n+'
175 t.lineno += t.value.count('\n')
176
177 # Comments
178 def t_comment(t):
179 r'//.*'
180
181 # Completely ignored characters
182 t_ignore = ' \t\x0c'
183
184 # Error handler
185 def t_error(t):
186 error(t.lineno, "illegal character '%s'" % t.value[0])
187 t.skip(1)
188
189 # Build the lexer
190 lex.lex()
191
192 #####################################################################
193 #
194 # Parser
195 #
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 #####################################################################
207
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.
212 precedence = (
213 ('right', 'DECLARE'),
214 )
215
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'
224 global_decls1 = t[1]
225 isa_name = t[2]
226 namespace = isa_name + "Inst"
227 global_decls2 = t[3]
228 (inst_decls, code) = t[4]
229 code = indent(code)
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
234 try:
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)
238 except NameError:
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' + '''$ */
243
244 /*
245 * Copyright (c) 2003
246 * The Regents of The University of Michigan
247 * All Rights Reserved
248 *
249 * This code is part of the M5 simulator, developed by Nathan Binkert,
250 * Erik Hallnor, Steve Raasch, and Steve Reinhardt, with contributions
251 * from Ron Dreslinski, Dave Greene, and Lisa Hsu.
252 *
253 * Permission is granted to use, copy, create derivative works and
254 * redistribute this software and such derivative works for any
255 * purpose, so long as the copyright notice above, this grant of
256 * permission, and the disclaimer below appear in all copies made; and
257 * so long as the name of The University of Michigan is not used in
258 * any advertising or publicity pertaining to the use or distribution
259 * of this software without specific, written prior authorization.
260 *
261 * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE
262 * UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND
263 * WITHOUT WARRANTY BY THE UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER
264 * EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
265 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
266 * PURPOSE. THE REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE
267 * LIABLE FOR ANY DAMAGES, INCLUDING DIRECT, SPECIAL, INDIRECT,
268 * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM
269 * ARISING OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
270 * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF SUCH
271 * DAMAGES.
272 */
273
274 /*
275 * DO NOT EDIT THIS FILE!!!
276 *
277 * It was automatically generated from this ISA description:
278 * Filename: %(filename)s
279 * RCS %(local_rcs_id)s
280 */
281
282 #include "base/bitfield.hh" // required for bitfield support
283
284
285 /////////////////////////////////////
286 // Global defs (outside namespace) //
287 /////////////////////////////////////
288
289 %(global_decls1)s
290
291 /**
292 * Namespace for %(isa_name)s static instruction objects.
293 */
294 namespace %(namespace)s
295 {
296
297 /////////////////////////////////////
298 // Global defs (within namespace) //
299 /////////////////////////////////////
300
301 %(global_decls2)s
302
303 ////////////////////////////////////
304 // Declares from inst definitions //
305 ////////////////////////////////////
306
307 %(inst_decls)s
308
309 } // namespace %(namespace)s
310
311 //////////////////////
312 // Decoder function //
313 //////////////////////
314
315 StaticInstPtr<%(isa_name)s>
316 %(isa_name)s::decodeInst(%(isa_name)s::MachInst machInst)
317 {
318 using namespace %(namespace)s;
319 %(code)s
320 } // decodeInst
321 ''' % vars()
322 output.close()
323
324 # ISA name declaration looks like "namespace <foo>;"
325 def p_name_decl(t):
326 'name_decl : NAMESPACE ID SEMI'
327 t[0] = t[2]
328
329 # 'opt_defs_and_declares' is a possibly empty sequence of
330 # defs and/or declares.
331 def p_opt_defs_and_declares_0(t):
332 'opt_defs_and_declares : empty'
333 t[0] = ''
334
335 def p_opt_defs_and_declares_1(t):
336 'opt_defs_and_declares : defs_and_declares'
337 t[0] = t[1]
338
339 def p_defs_and_declares_0(t):
340 'defs_and_declares : def_or_declare'
341 t[0] = t[1]
342
343 def p_defs_and_declares_1(t):
344 'defs_and_declares : defs_and_declares def_or_declare'
345 t[0] = t[1] + t[2]
346
347 # The list of possible definition/declaration statements.
348 def p_def_or_declare(t):
349 '''def_or_declare : def_format
350 | def_bitfield
351 | def_template
352 | global_declare
353 | global_let
354 | cpp_directive'''
355 t[0] = t[1]
356
357 # preprocessor directives are copied directly to the output.
358 def p_cpp_directive(t):
359 '''cpp_directive : CPPDIRECTIVE'''
360 t[0] = t[1]
361
362 # Global declares 'declare {{...}}' (C++ code blocks) are copied
363 # directly to the output.
364 def p_global_declare(t):
365 'global_declare : DECLARE CODELIT SEMI'
366 t[0] = substBitOps(t[2])
367
368 # global let blocks 'let {{...}}' (Python code blocks) are executed
369 # directly when seen. These are typically used to initialize global
370 # Python variables used in later format definitions.
371 def p_global_let(t):
372 'global_let : LET CODELIT SEMI'
373 try:
374 exec(fixPythonIndentation(t[2]))
375 except:
376 error_bt(t.lineno(1), 'error in global let block "%s".' % t[2])
377 t[0] = '' # contributes nothing to the output C++ file
378
379 # A bitfield definition looks like:
380 # 'def [signed] bitfield <ID> [<first>:<last>]'
381 # This generates a preprocessor macro in the output file.
382 def p_def_bitfield_0(t):
383 'def_bitfield : DEF opt_signed BITFIELD ID LESS INTLIT COLON INTLIT GREATER SEMI'
384 expr = 'bits(machInst, %2d, %2d)' % (t[6], t[8])
385 if (t[2] == 'signed'):
386 expr = 'sext<%d>(%s)' % (t[6] - t[8] + 1, expr)
387 t[0] = '#undef %s\n#define %s\t%s\n' % (t[4], t[4], expr)
388
389 # alternate form for single bit: 'def [signed] bitfield <ID> [<bit>]'
390 def p_def_bitfield_1(t):
391 'def_bitfield : DEF opt_signed BITFIELD ID LESS INTLIT GREATER SEMI'
392 expr = 'bits(machInst, %2d, %2d)' % (t[6], t[6])
393 if (t[2] == 'signed'):
394 expr = 'sext<%d>(%s)' % (1, expr)
395 t[0] = '#undef %s\n#define %s\t%s\n' % (t[4], t[4], expr)
396
397 def p_opt_signed_0(t):
398 'opt_signed : SIGNED'
399 t[0] = t[1]
400
401 def p_opt_signed_1(t):
402 'opt_signed : empty'
403 t[0] = ''
404
405 # Global map variable to hold templates
406 templateMap = {}
407
408 def p_def_template(t):
409 'def_template : DEF TEMPLATE ID CODELIT SEMI'
410 templateMap[t[3]] = t[4]
411 t[0] = ''
412
413 # An instruction format definition looks like
414 # "def format <fmt>(<params>) {{...}};"
415 def p_def_format(t):
416 'def_format : DEF FORMAT ID LPAREN param_list RPAREN CODELIT SEMI'
417 (id, params, code) = (t[3], t[5], t[7])
418 defFormat(id, params, code, t.lineno(1))
419 # insert a comment into the output to note that the def was processed
420 t[0] = '''
421 //
422 // parser: format %s defined
423 //
424 ''' % id
425
426 # The formal parameter list for an instruction format is a possibly
427 # empty list of comma-separated parameters.
428 def p_param_list_0(t):
429 'param_list : empty'
430 t[0] = [ ]
431
432 def p_param_list_1(t):
433 'param_list : param'
434 t[0] = [t[1]]
435
436 def p_param_list_2(t):
437 'param_list : param_list COMMA param'
438 t[0] = t[1]
439 t[0].append(t[3])
440
441 # Each formal parameter is either an identifier or an identifier
442 # preceded by an asterisk. As in Python, the latter (if present) gets
443 # a tuple containing all the excess positional arguments, allowing
444 # varargs functions.
445 def p_param_0(t):
446 'param : ID'
447 t[0] = t[1]
448
449 def p_param_1(t):
450 'param : ASTERISK ID'
451 # just concatenate them: '*ID'
452 t[0] = t[1] + t[2]
453
454 # End of format definition-related rules.
455 ##############
456
457 #
458 # A decode block looks like:
459 # decode <field1> [, <field2>]* [default <inst>] { ... }
460 #
461 def p_decode_block(t):
462 'decode_block : DECODE ID opt_default LBRACE decode_stmt_list RBRACE'
463 default_defaults = defaultStack.pop()
464 (decls, code, has_default) = t[5]
465 # use the "default defaults" only if there was no explicit
466 # default statement in decode_stmt_list
467 if not has_default:
468 (default_decls, default_code) = default_defaults
469 decls += default_decls
470 code += default_code
471 t[0] = (decls, '''
472 switch (%s) {
473 %s
474 }
475 ''' % (t[2], indent(code)))
476
477 # The opt_default statement serves only to push the "default defaults"
478 # onto defaultStack. This value will be used by nested decode blocks,
479 # and used and popped off when the current decode_block is processed
480 # (in p_decode_block() above).
481 def p_opt_default_0(t):
482 'opt_default : empty'
483 # no default specified: reuse the one currently at the top of the stack
484 defaultStack.push(defaultStack.top())
485 # no meaningful value returned
486 t[0] = None
487
488 def p_opt_default_1(t):
489 'opt_default : DEFAULT inst'
490 # push the new default
491 (decls, code) = t[2]
492 defaultStack.push((decls, '\ndefault:\n%sbreak;' % code))
493 # no meaningful value returned
494 t[0] = None
495
496 def p_decode_stmt_list_0(t):
497 'decode_stmt_list : decode_stmt'
498 t[0] = t[1]
499
500 def p_decode_stmt_list_1(t):
501 'decode_stmt_list : decode_stmt decode_stmt_list'
502 (decls1, code1, has_default1) = t[1]
503 (decls2, code2, has_default2) = t[2]
504 if (has_default1 and has_default2):
505 error(t.lineno(1), 'Two default cases in decode block')
506 t[0] = (decls1 + '\n' + decls2, code1 + '\n' + code2,
507 has_default1 or has_default2)
508
509 #
510 # Decode statement rules
511 #
512 # There are four types of statements allowed in a decode block:
513 # 1. Format blocks 'format <foo> { ... }'
514 # 2. Nested decode blocks
515 # 3. Instruction definitions.
516 # 4. C preprocessor directives.
517
518
519 # Preprocessor directives found in a decode statement list are passed
520 # through to the output, replicated to both the declaration and decode
521 # streams. This works well for ifdefs, so we can ifdef out both the
522 # declarations and the decode cases generated by an instruction
523 # definition. Handling them as part of the grammar makes it easy to
524 # keep them in the right place with respect to the code generated by
525 # the other statements.
526 def p_decode_stmt_cpp(t):
527 'decode_stmt : CPPDIRECTIVE'
528 t[0] = (t[1], t[1], 0)
529
530 # A format block 'format <foo> { ... }' sets the default instruction
531 # format used to handle instruction definitions inside the block.
532 # This format can be overridden by using an explicit format on the
533 # instruction definition or with a nested format block.
534 def p_decode_stmt_format(t):
535 'decode_stmt : FORMAT push_format_id LBRACE decode_stmt_list RBRACE'
536 # The format will be pushed on the stack when 'push_format_id' is
537 # processed (see below). Once the parser has recognized the full
538 # production (though the right brace), we're done with the format,
539 # so now we can pop it.
540 formatStack.pop()
541 t[0] = t[4]
542
543 # This rule exists so we can set the current format (& push the stack)
544 # when we recognize the format name part of the format block.
545 def p_push_format_id(t):
546 'push_format_id : ID'
547 try:
548 formatStack.push(formatMap[t[1]])
549 t[0] = ('', '// format %s' % t[1])
550 except KeyError:
551 error(t.lineno(1), 'instruction format "%s" not defined.' % t[1])
552
553 # Nested decode block: if the value of the current field matches the
554 # specified constant, do a nested decode on some other field.
555 def p_decode_stmt_decode(t):
556 'decode_stmt : case_label COLON decode_block'
557 (label, is_default) = t[1]
558 (decls, code) = t[3]
559 # just wrap the decoding code from the block as a case in the
560 # outer switch statement.
561 t[0] = (decls, '\n%s:\n%s' % (label, indent(code)), is_default)
562
563 # Instruction definition (finally!).
564 def p_decode_stmt_inst(t):
565 'decode_stmt : case_label COLON inst SEMI'
566 (label, is_default) = t[1]
567 (decls, code) = t[3]
568 t[0] = (decls, '\n%s:%sbreak;' % (label, indent(code)), is_default)
569
570 # The case label is either a list of one or more constants or 'default'
571 def p_case_label_0(t):
572 'case_label : intlit_list'
573 t[0] = (': '.join(map(lambda a: 'case %#x' % a, t[1])), 0)
574
575 def p_case_label_1(t):
576 'case_label : DEFAULT'
577 t[0] = ('default', 1)
578
579 #
580 # The constant list for a decode case label must be non-empty, but may have
581 # one or more comma-separated integer literals in it.
582 #
583 def p_intlit_list_0(t):
584 'intlit_list : INTLIT'
585 t[0] = [t[1]]
586
587 def p_intlit_list_1(t):
588 'intlit_list : intlit_list COMMA INTLIT'
589 t[0] = t[1]
590 t[0].append(t[3])
591
592 # Define an instruction using the current instruction format (specified
593 # by an enclosing format block).
594 # "<mnemonic>(<args>)"
595 def p_inst_0(t):
596 'inst : ID LPAREN arg_list RPAREN'
597 # Pass the ID and arg list to the current format class to deal with.
598 currentFormat = formatStack.top()
599 (decls, code) = currentFormat.defineInst(t[1], t[3], t.lineno(1))
600 args = ','.join(map(str, t[3]))
601 args = re.sub('(?m)^', '//', args)
602 args = re.sub('^//', '', args)
603 comment = '// %s::%s(%s)\n' % (currentFormat.id, t[1], args)
604 t[0] = (comment + decls, comment + code)
605
606 # Define an instruction using an explicitly specified format:
607 # "<fmt>::<mnemonic>(<args>)"
608 def p_inst_1(t):
609 'inst : ID DBLCOLON ID LPAREN arg_list RPAREN'
610 try:
611 format = formatMap[t[1]]
612 except KeyError:
613 error(t.lineno(1), 'instruction format "%s" not defined.' % t[1])
614 (decls, code) = format.defineInst(t[3], t[5], t.lineno(1))
615 comment = '// %s::%s(%s)\n' % (t[1], t[3], t[5])
616 t[0] = (comment + decls, comment + code)
617
618 def p_arg_list_0(t):
619 'arg_list : empty'
620 t[0] = [ ]
621
622 def p_arg_list_1(t):
623 'arg_list : arg'
624 t[0] = [t[1]]
625
626 def p_arg_list_2(t):
627 'arg_list : arg_list COMMA arg'
628 t[0] = t[1]
629 t[0].append(t[3])
630
631 def p_arg(t):
632 '''arg : ID
633 | INTLIT
634 | STRLIT
635 | CODELIT'''
636 t[0] = t[1]
637
638 #
639 # Empty production... use in other rules for readability.
640 #
641 def p_empty(t):
642 'empty :'
643 pass
644
645 # Parse error handler. Note that the argument here is the offending
646 # *token*, not a grammar symbol (hence the need to use t.value)
647 def p_error(t):
648 if t:
649 error(t.lineno, "syntax error at '%s'" % t.value)
650 else:
651 error_bt(0, "unknown syntax error")
652
653 # END OF GRAMMAR RULES
654 #
655 # Now build the parser.
656 yacc.yacc()
657
658 ################
659 # Format object.
660 #
661 # A format object encapsulates an instruction format. It must provide
662 # a defineInst() method that generates the code for an instruction
663 # definition.
664
665 class Format:
666 def __init__(self, id, params, code):
667 # constructor: just save away arguments
668 self.id = id
669 self.params = params
670 # strip blank lines from code (ones at the end are troublesome)
671 code = re.sub(r'(?m)^\s*$', '', code);
672 if code == '':
673 code = ' pass\n'
674 param_list = string.join(params, ", ")
675 f = 'def defInst(name, Name, ' + param_list + '):\n' + code
676 exec(f)
677 self.func = defInst
678
679 def defineInst(self, name, args, lineno):
680 # automatically provide a capitalized version of mnemonic
681 Name = string.capitalize(name)
682 try:
683 retval = self.func(name, Name, *args)
684 except:
685 error_bt(lineno, 'error defining "%s".' % name)
686 return retval
687
688 # Special null format to catch an implicit-format instruction
689 # definition outside of any format block.
690 class NoFormat:
691 def __init__(self):
692 self.defaultInst = ''
693
694 def defineInst(self, name, args, lineno):
695 error(lineno,
696 'instruction definition "%s" with no active format!' % name)
697
698 # This dictionary maps format name strings to Format objects.
699 formatMap = {}
700
701 # Define a new format
702 def defFormat(id, params, code, lineno):
703 # make sure we haven't already defined this one
704 if formatMap.get(id, None) != None:
705 error(lineno, 'format %s redefined.' % id)
706 # create new object and store in global map
707 formatMap[id] = Format(id, params, code)
708
709
710 ##############
711 # Stack: a simple stack object. Used for both formats (formatStack)
712 # and default cases (defaultStack).
713
714 class Stack:
715 def __init__(self, initItem):
716 self.stack = [ initItem ]
717
718 def push(self, item):
719 self.stack.append(item);
720
721 def pop(self):
722 return self.stack.pop()
723
724 def top(self):
725 return self.stack[-1]
726
727 # The global format stack.
728 formatStack = Stack(NoFormat())
729
730 # The global default case stack.
731 defaultStack = Stack( None )
732
733 ###################
734 # Utility functions
735
736 #
737 # Indent every line in string 's' by two spaces
738 # (except preprocessor directives).
739 # Used to make nested code blocks look pretty.
740 #
741 def indent(s):
742 return re.sub(r'(?m)^(?!\#)', ' ', s)
743
744 #
745 # Munge a somewhat arbitrarily formatted piece of Python code
746 # (e.g. from a format 'let' block) into something whose indentation
747 # will get by the Python parser.
748 #
749 # The two keys here are that Python will give a syntax error if
750 # there's any whitespace at the beginning of the first line, and that
751 # all lines at the same lexical nesting level must have identical
752 # indentation. Unfortunately the way code literals work, an entire
753 # let block tends to have some initial indentation. Rather than
754 # trying to figure out what that is and strip it off, we prepend 'if
755 # 1:' to make the let code the nested block inside the if (and have
756 # the parser automatically deal with the indentation for us).
757 #
758 # We don't want to do this if (1) the code block is empty or (2) the
759 # first line of the block doesn't have any whitespace at the front.
760
761 def fixPythonIndentation(s):
762 # get rid of blank lines first
763 s = re.sub(r'(?m)^\s*\n', '', s);
764 if (s != '' and re.match(r'[ \t]', s[0])):
765 s = 'if 1:\n' + s
766 return s
767
768 # Error handler. Just call exit. Output formatted to work under
769 # Emacs compile-mode.
770 def error(lineno, string):
771 sys.exit("%s:%d: %s" % (isa_desc_filename, lineno, string))
772
773 # Like error(), but include a Python stack backtrace (for processing
774 # Python exceptions).
775 def error_bt(lineno, string):
776 print >> sys.stderr, "%s:%d: %s" % (isa_desc_filename, lineno, string)
777 raise
778
779
780 #####################################################################
781 #
782 # Bitfield Operator Support
783 #
784 #####################################################################
785
786 bitOp1ArgRE = re.compile(r'<\s*(\w+)\s*:\s*>')
787
788 bitOpWordRE = re.compile(r'(?<![\w\.])([\w\.]+)<\s*(\w+)\s*:\s*(\w+)\s*>')
789 bitOpExprRE = re.compile(r'\)<\s*(\w+)\s*:\s*(\w+)\s*>')
790
791 def substBitOps(code):
792 # first convert single-bit selectors to two-index form
793 # i.e., <n> --> <n:n>
794 code = bitOp1ArgRE.sub(r'<\1:\1>', code)
795 # simple case: selector applied to ID (name)
796 # i.e., foo<a:b> --> bits(foo, a, b)
797 code = bitOpWordRE.sub(r'bits(\1, \2, \3)', code)
798 # if selector is applied to expression (ending in ')'),
799 # we need to search backward for matching '('
800 match = bitOpExprRE.search(code)
801 while match:
802 exprEnd = match.start()
803 here = exprEnd - 1
804 nestLevel = 1
805 while nestLevel > 0:
806 if code[here] == '(':
807 nestLevel -= 1
808 elif code[here] == ')':
809 nestLevel += 1
810 here -= 1
811 if here < 0:
812 sys.exit("Didn't find '('!")
813 exprStart = here+1
814 newExpr = r'bits(%s, %s, %s)' % (code[exprStart:exprEnd+1],
815 match.group(1), match.group(2))
816 code = code[:exprStart] + newExpr + code[match.end():]
817 match = bitOpExprRE.search(code)
818 return code
819
820
821 #####################################################################
822 #
823 # Code Parser
824 #
825 # The remaining code is the support for automatically extracting
826 # instruction characteristics from pseudocode.
827 #
828 #####################################################################
829
830 # Force the argument to be a list
831 def makeList(list_or_item):
832 if not list_or_item:
833 return []
834 elif type(list_or_item) == ListType:
835 return list_or_item
836 else:
837 return [ list_or_item ]
838
839 # generate operandSizeMap based on provided operandTypeMap:
840 # basically generate equiv. C++ type and make is_signed flag
841 def buildOperandSizeMap():
842 global operandSizeMap
843 operandSizeMap = {}
844 for ext in operandTypeMap.keys():
845 (desc, size) = operandTypeMap[ext]
846 if desc == 'signed int':
847 type = 'int%d_t' % size
848 is_signed = 1
849 elif desc == 'unsigned int':
850 type = 'uint%d_t' % size
851 is_signed = 0
852 elif desc == 'float':
853 is_signed = 1 # shouldn't really matter
854 if size == 32:
855 type = 'float'
856 elif size == 64:
857 type = 'double'
858 if type == '':
859 error(0, 'Unrecognized type description "%s" in operandTypeMap')
860 operandSizeMap[ext] = (size, type, is_signed)
861
862 #
863 # Base class for operand traits. An instance of this class (or actually
864 # a class derived from this one) encapsulates the traits of a particular
865 # operand type (e.g., "32-bit integer register").
866 #
867 class OperandTraits:
868 def __init__(self, dflt_ext, reg_spec, flags, sort_pri):
869 # Force construction of operandSizeMap from operandTypeMap
870 # if it hasn't happened yet
871 if not globals().has_key('operandSizeMap'):
872 buildOperandSizeMap()
873 self.dflt_ext = dflt_ext
874 (self.dflt_size, self.dflt_type, self.dflt_is_signed) = \
875 operandSizeMap[dflt_ext]
876 self.reg_spec = reg_spec
877 # Canonical flag structure is a triple of lists, where each list
878 # indicates the set of flags implied by this operand always, when
879 # used as a source, and when used as a dest, respectively.
880 # For simplicity this can be initialized using a variety of fairly
881 # obvious shortcuts; we convert these to canonical form here.
882 if not flags:
883 # no flags specified (e.g., 'None')
884 self.flags = ( [], [], [] )
885 elif type(flags) == StringType:
886 # a single flag: assumed to be unconditional
887 self.flags = ( [ flags ], [], [] )
888 elif type(flags) == ListType:
889 # a list of flags: also assumed to be unconditional
890 self.flags = ( flags, [], [] )
891 elif type(flags) == TupleType:
892 # it's a tuple: it should be a triple,
893 # but each item could be a single string or a list
894 (uncond_flags, src_flags, dest_flags) = flags
895 self.flags = (makeList(uncond_flags),
896 makeList(src_flags), makeList(dest_flags))
897 self.sort_pri = sort_pri
898
899 def isMem(self):
900 return 0
901
902 def isReg(self):
903 return 0
904
905 def isFloatReg(self):
906 return 0
907
908 def isIntReg(self):
909 return 0
910
911 def isControlReg(self):
912 return 0
913
914 def getFlags(self, op_desc):
915 # note the empty slice '[:]' gives us a copy of self.flags[0]
916 # instead of a reference to it
917 my_flags = self.flags[0][:]
918 if op_desc.is_src:
919 my_flags += self.flags[1]
920 if op_desc.is_dest:
921 my_flags += self.flags[2]
922 return my_flags
923
924 def makeDecl(self, op_desc):
925 (size, type, is_signed) = operandSizeMap[op_desc.eff_ext]
926 # Note that initializations in the declarations are solely
927 # to avoid 'uninitialized variable' errors from the compiler.
928 return type + ' ' + op_desc.munged_name + ' = 0;\n';
929
930 class IntRegOperandTraits(OperandTraits):
931 def isReg(self):
932 return 1
933
934 def isIntReg(self):
935 return 1
936
937 def makeConstructor(self, op_desc):
938 c = ''
939 if op_desc.is_src:
940 c += '\n\t_srcRegIdx[%d] = %s;' % \
941 (op_desc.src_reg_idx, self.reg_spec)
942 if op_desc.is_dest:
943 c += '\n\t_destRegIdx[%d] = %s;' % \
944 (op_desc.dest_reg_idx, self.reg_spec)
945 return c
946
947 def makeRead(self, op_desc, cpu_model):
948 (size, type, is_signed) = operandSizeMap[op_desc.eff_ext]
949 if (type == 'float' or type == 'double'):
950 error(0, 'Attempt to read integer register as FP')
951 if (size == self.dflt_size):
952 return '%s = xc->readIntReg(_srcRegIdx[%d]);\n' % \
953 (op_desc.munged_name, op_desc.src_reg_idx)
954 else:
955 return '%s = bits(xc->readIntReg(_srcRegIdx[%d]), %d, 0);\n' % \
956 (op_desc.munged_name, op_desc.src_reg_idx, size-1)
957
958 def makeWrite(self, op_desc, cpu_model):
959 (size, type, is_signed) = operandSizeMap[op_desc.eff_ext]
960 if (type == 'float' or type == 'double'):
961 error(0, 'Attempt to write integer register as FP')
962 if (size != self.dflt_size and is_signed):
963 final_val = 'sext<%d>(%s)' % (size, op_desc.munged_name)
964 else:
965 final_val = op_desc.munged_name
966 wb = '''
967 {
968 %s final_val = %s;
969 xc->setIntReg(_destRegIdx[%d], final_val);\n
970 if (traceData) { traceData->setData(final_val); }
971 }''' % (self.dflt_type, final_val, op_desc.dest_reg_idx)
972 return wb
973
974 class FloatRegOperandTraits(OperandTraits):
975 def isReg(self):
976 return 1
977
978 def isFloatReg(self):
979 return 1
980
981 def makeConstructor(self, op_desc):
982 c = ''
983 if op_desc.is_src:
984 c += '\n\t_srcRegIdx[%d] = %s + FP_Base_DepTag;' % \
985 (op_desc.src_reg_idx, self.reg_spec)
986 if op_desc.is_dest:
987 c += '\n\t_destRegIdx[%d] = %s + FP_Base_DepTag;' % \
988 (op_desc.dest_reg_idx, self.reg_spec)
989 return c
990
991 def makeRead(self, op_desc, cpu_model):
992 (size, type, is_signed) = operandSizeMap[op_desc.eff_ext]
993 bit_select = 0
994 if (type == 'float'):
995 func = 'readFloatRegSingle'
996 elif (type == 'double'):
997 func = 'readFloatRegDouble'
998 else:
999 func = 'readFloatRegInt'
1000 if (size != self.dflt_size):
1001 bit_select = 1
1002 base = 'xc->%s(_srcRegIdx[%d] - FP_Base_DepTag)' % \
1003 (func, op_desc.src_reg_idx)
1004 if bit_select:
1005 return '%s = bits(%s, %d, 0);\n' % \
1006 (op_desc.munged_name, base, size-1)
1007 else:
1008 return '%s = %s;\n' % (op_desc.munged_name, base)
1009
1010 def makeWrite(self, op_desc, cpu_model):
1011 (size, type, is_signed) = operandSizeMap[op_desc.eff_ext]
1012 final_val = op_desc.munged_name
1013 if (type == 'float'):
1014 func = 'setFloatRegSingle'
1015 elif (type == 'double'):
1016 func = 'setFloatRegDouble'
1017 else:
1018 func = 'setFloatRegInt'
1019 type = 'uint%d_t' % self.dflt_size
1020 if (size != self.dflt_size and is_signed):
1021 final_val = 'sext<%d>(%s)' % (size, op_desc.munged_name)
1022 wb = '''
1023 {
1024 %s final_val = %s;
1025 xc->%s(_destRegIdx[%d] - FP_Base_DepTag, final_val);\n
1026 if (traceData) { traceData->setData(final_val); }
1027 }''' % (type, final_val, func, op_desc.dest_reg_idx)
1028 return wb
1029
1030 class ControlRegOperandTraits(OperandTraits):
1031 def isReg(self):
1032 return 1
1033
1034 def isControlReg(self):
1035 return 1
1036
1037 def makeConstructor(self, op_desc):
1038 c = ''
1039 if op_desc.is_src:
1040 c += '\n\t_srcRegIdx[%d] = %s_DepTag;' % \
1041 (op_desc.src_reg_idx, self.reg_spec)
1042 if op_desc.is_dest:
1043 c += '\n\t_destRegIdx[%d] = %s_DepTag;' % \
1044 (op_desc.dest_reg_idx, self.reg_spec)
1045 return c
1046
1047 def makeRead(self, op_desc, cpu_model):
1048 (size, type, is_signed) = operandSizeMap[op_desc.eff_ext]
1049 bit_select = 0
1050 if (type == 'float' or type == 'double'):
1051 error(0, 'Attempt to read control register as FP')
1052 base = 'xc->read%s()' % self.reg_spec
1053 if size == self.dflt_size:
1054 return '%s = %s;\n' % (op_desc.munged_name, base)
1055 else:
1056 return '%s = bits(%s, %d, 0);\n' % \
1057 (op_desc.munged_name, base, size-1)
1058
1059 def makeWrite(self, op_desc, cpu_model):
1060 (size, type, is_signed) = operandSizeMap[op_desc.eff_ext]
1061 if (type == 'float' or type == 'double'):
1062 error(0, 'Attempt to write control register as FP')
1063 wb = 'xc->set%s(%s);\n' % (self.reg_spec, op_desc.munged_name)
1064 wb += 'if (traceData) { traceData->setData(%s); }' % \
1065 op_desc.munged_name
1066 return wb
1067
1068 class MemOperandTraits(OperandTraits):
1069 def isMem(self):
1070 return 1
1071
1072 def makeConstructor(self, op_desc):
1073 return ''
1074
1075 def makeDecl(self, op_desc):
1076 (size, type, is_signed) = operandSizeMap[op_desc.eff_ext]
1077 # Note that initializations in the declarations are solely
1078 # to avoid 'uninitialized variable' errors from the compiler.
1079 # Declare memory data variable.
1080 c = '%s %s = 0;\n' % (type, op_desc.munged_name)
1081 # Declare var to hold memory access flags.
1082 c += 'unsigned %s_flags = memAccessFlags;\n' % op_desc.base_name
1083 # If this operand is a dest (i.e., it's a store operation),
1084 # then we need to declare a variable for the write result code
1085 # as well.
1086 if op_desc.is_dest:
1087 c += 'uint64_t %s_write_result = 0;\n' % op_desc.base_name
1088 return c
1089
1090 def makeRead(self, op_desc, cpu_model):
1091 (size, type, is_signed) = operandSizeMap[op_desc.eff_ext]
1092 eff_type = 'uint%d_t' % size
1093 return 'fault = memAccessObj->read(EA, (%s&)%s, %s_flags);\n' \
1094 % (eff_type, op_desc.munged_name, op_desc.base_name)
1095
1096 def makeWrite(self, op_desc, cpu_model):
1097 (size, type, is_signed) = operandSizeMap[op_desc.eff_ext]
1098 eff_type = 'uint%d_t' % size
1099 return 'fault = memAccessObj->write((%s&)%s, EA, %s_flags,' \
1100 ' &%s_write_result);\n' \
1101 % (eff_type, op_desc.munged_name, op_desc.base_name,
1102 op_desc.base_name)
1103
1104 class NPCOperandTraits(OperandTraits):
1105 def makeConstructor(self, op_desc):
1106 return ''
1107
1108 def makeRead(self, op_desc, cpu_model):
1109 return '%s = xc->readPC() + 4;\n' % op_desc.munged_name
1110
1111 def makeWrite(self, op_desc, cpu_model):
1112 return 'xc->setNextPC(%s);\n' % op_desc.munged_name
1113
1114
1115 #
1116 # Define operand variables that get derived from the basic declaration
1117 # of ISA-specific operands in operandTraitsMap. This function must be
1118 # called by the ISA description file explicitly after defining
1119 # operandTraitsMap (in a 'let' block).
1120 #
1121 def defineDerivedOperandVars():
1122 global operands
1123 operands = operandTraitsMap.keys()
1124
1125 operandsREString = (r'''
1126 (?<![\w\.]) # neg. lookbehind assertion: prevent partial matches
1127 ((%s)(?:\.(\w+))?) # match: operand with optional '.' then suffix
1128 (?![\w\.]) # neg. lookahead assertion: prevent partial matches
1129 '''
1130 % string.join(operands, '|'))
1131
1132 global operandsRE
1133 operandsRE = re.compile(operandsREString, re.MULTILINE|re.VERBOSE)
1134
1135 # Same as operandsREString, but extension is mandatory, and only two
1136 # groups are returned (base and ext, not full name as above).
1137 # Used for subtituting '_' for '.' to make C++ identifiers.
1138 operandsWithExtREString = (r'(?<![\w\.])(%s)\.(\w+)(?![\w\.])'
1139 % string.join(operands, '|'))
1140
1141 global operandsWithExtRE
1142 operandsWithExtRE = re.compile(operandsWithExtREString, re.MULTILINE)
1143
1144
1145 #
1146 # Operand descriptor class. An instance of this class represents
1147 # a specific operand for a code block.
1148 #
1149 class OperandDescriptor:
1150 def __init__(self, full_name, base_name, ext, is_src, is_dest):
1151 self.full_name = full_name
1152 self.base_name = base_name
1153 self.ext = ext
1154 self.is_src = is_src
1155 self.is_dest = is_dest
1156 self.traits = operandTraitsMap[base_name]
1157 # The 'effective extension' (eff_ext) is either the actual
1158 # extension, if one was explicitly provided, or the default.
1159 # The 'munged name' replaces the '.' between the base and
1160 # extension (if any) with a '_' to make a legal C++ variable name.
1161 if ext:
1162 self.eff_ext = ext
1163 self.munged_name = base_name + '_' + ext
1164 else:
1165 self.eff_ext = self.traits.dflt_ext
1166 self.munged_name = base_name
1167
1168 # Finalize additional fields (primarily code fields). This step
1169 # is done separately since some of these fields may depend on the
1170 # register index enumeration that hasn't been performed yet at the
1171 # time of __init__().
1172 def finalize(self):
1173 self.flags = self.traits.getFlags(self)
1174 self.constructor = self.traits.makeConstructor(self)
1175 self.exec_decl = self.traits.makeDecl(self)
1176
1177 if self.is_src:
1178 self.simple_rd = self.traits.makeRead(self, 'simple')
1179 self.dtld_rd = self.traits.makeRead(self, 'dtld')
1180 else:
1181 self.simple_rd = ''
1182 self.dtld_rd = ''
1183
1184 if self.is_dest:
1185 self.simple_wb = self.traits.makeWrite(self, 'simple')
1186 self.dtld_wb = self.traits.makeWrite(self, 'dtld')
1187 else:
1188 self.simple_wb = ''
1189 self.dtld_wb = ''
1190
1191 class OperandDescriptorList:
1192 def __init__(self):
1193 self.items = []
1194 self.bases = {}
1195
1196 def __len__(self):
1197 return len(self.items)
1198
1199 def __getitem__(self, index):
1200 return self.items[index]
1201
1202 def append(self, op_desc):
1203 self.items.append(op_desc)
1204 self.bases[op_desc.base_name] = op_desc
1205
1206 def find_base(self, base_name):
1207 # like self.bases[base_name], but returns None if not found
1208 # (rather than raising exception)
1209 return self.bases.get(base_name)
1210
1211 # internal helper function for concat[Some]Attr{Strings|Lists}
1212 def __internalConcatAttrs(self, attr_name, filter, result):
1213 for op_desc in self.items:
1214 if filter(op_desc):
1215 result += getattr(op_desc, attr_name)
1216 return result
1217
1218 # return a single string that is the concatenation of the (string)
1219 # values of the specified attribute for all operands
1220 def concatAttrStrings(self, attr_name):
1221 return self.__internalConcatAttrs(attr_name, lambda x: 1, '')
1222
1223 # like concatAttrStrings, but only include the values for the operands
1224 # for which the provided filter function returns true
1225 def concatSomeAttrStrings(self, filter, attr_name):
1226 return self.__internalConcatAttrs(attr_name, filter, '')
1227
1228 # return a single list that is the concatenation of the (list)
1229 # values of the specified attribute for all operands
1230 def concatAttrLists(self, attr_name):
1231 return self.__internalConcatAttrs(attr_name, lambda x: 1, [])
1232
1233 # like concatAttrLists, but only include the values for the operands
1234 # for which the provided filter function returns true
1235 def concatSomeAttrLists(self, filter, attr_name):
1236 return self.__internalConcatAttrs(attr_name, filter, [])
1237
1238 def sort(self):
1239 self.items.sort(lambda a, b: a.traits.sort_pri - b.traits.sort_pri)
1240
1241 # Regular expression object to match C++ comments
1242 # (used in findOperands())
1243 commentRE = re.compile(r'//.*\n')
1244
1245 # Regular expression object to match assignment statements
1246 # (used in findOperands())
1247 assignRE = re.compile(r'\s*=(?!=)', re.MULTILINE)
1248
1249 #
1250 # Find all the operands in the given code block. Returns an operand
1251 # descriptor list (instance of class OperandDescriptorList).
1252 #
1253 def findOperands(code):
1254 operands = OperandDescriptorList()
1255 # delete comments so we don't accidentally match on reg specifiers inside
1256 code = commentRE.sub('', code)
1257 # search for operands
1258 next_pos = 0
1259 while 1:
1260 match = operandsRE.search(code, next_pos)
1261 if not match:
1262 # no more matches: we're done
1263 break
1264 op = match.groups()
1265 # regexp groups are operand full name, base, and extension
1266 (op_full, op_base, op_ext) = op
1267 # if the token following the operand is an assignment, this is
1268 # a destination (LHS), else it's a source (RHS)
1269 is_dest = (assignRE.match(code, match.end()) != None)
1270 is_src = not is_dest
1271 # see if we've already seen this one
1272 op_desc = operands.find_base(op_base)
1273 if op_desc:
1274 if op_desc.ext != op_ext:
1275 error(0, 'Inconsistent extensions for operand %s' % op_base)
1276 op_desc.is_src = op_desc.is_src or is_src
1277 op_desc.is_dest = op_desc.is_dest or is_dest
1278 else:
1279 # new operand: create new descriptor
1280 op_desc = OperandDescriptor(op_full, op_base, op_ext,
1281 is_src, is_dest)
1282 operands.append(op_desc)
1283 # start next search after end of current match
1284 next_pos = match.end()
1285 operands.sort()
1286 # enumerate source & dest register operands... used in building
1287 # constructor later
1288 srcRegs = 0
1289 destRegs = 0
1290 operands.numFPDestRegs = 0
1291 operands.numIntDestRegs = 0
1292 for op_desc in operands:
1293 if op_desc.traits.isReg():
1294 if op_desc.is_src:
1295 op_desc.src_reg_idx = srcRegs
1296 srcRegs += 1
1297 if op_desc.is_dest:
1298 op_desc.dest_reg_idx = destRegs
1299 destRegs += 1
1300 if op_desc.traits.isFloatReg():
1301 operands.numFPDestRegs += 1
1302 elif op_desc.traits.isIntReg():
1303 operands.numIntDestRegs += 1
1304 operands.numSrcRegs = srcRegs
1305 operands.numDestRegs = destRegs
1306 # now make a final pass to finalize op_desc fields that may depend
1307 # on the register enumeration
1308 for op_desc in operands:
1309 op_desc.finalize()
1310 return operands
1311
1312 # Munge operand names in code string to make legal C++ variable names.
1313 # (Will match munged_name attribute of OperandDescriptor object.)
1314 def substMungedOpNames(code):
1315 return operandsWithExtRE.sub(r'\1_\2', code)
1316
1317 def joinLists(t):
1318 return map(string.join, t)
1319
1320 def makeFlagConstructor(flag_list):
1321 if len(flag_list) == 0:
1322 return ''
1323 # filter out repeated flags
1324 flag_list.sort()
1325 i = 1
1326 while i < len(flag_list):
1327 if flag_list[i] == flag_list[i-1]:
1328 del flag_list[i]
1329 else:
1330 i += 1
1331 pre = '\n\tflags['
1332 post = '] = true;'
1333 code = pre + string.join(flag_list, post + pre) + post
1334 return code
1335
1336 class CodeBlock:
1337 def __init__(self, code):
1338 self.orig_code = code
1339 self.operands = findOperands(code)
1340 self.code = substMungedOpNames(substBitOps(code))
1341 self.constructor = self.operands.concatAttrStrings('constructor')
1342 self.constructor += \
1343 '\n\t_numSrcRegs = %d;' % self.operands.numSrcRegs
1344 self.constructor += \
1345 '\n\t_numDestRegs = %d;' % self.operands.numDestRegs
1346 self.constructor += \
1347 '\n\t_numFPDestRegs = %d;' % self.operands.numFPDestRegs
1348 self.constructor += \
1349 '\n\t_numIntDestRegs = %d;' % self.operands.numIntDestRegs
1350
1351 self.exec_decl = self.operands.concatAttrStrings('exec_decl')
1352
1353 is_mem = lambda op: op.traits.isMem()
1354 not_mem = lambda op: not op.traits.isMem()
1355
1356 self.simple_rd = self.operands.concatAttrStrings('simple_rd')
1357 self.simple_wb = self.operands.concatAttrStrings('simple_wb')
1358 self.simple_mem_rd = \
1359 self.operands.concatSomeAttrStrings(is_mem, 'simple_rd')
1360 self.simple_mem_wb = \
1361 self.operands.concatSomeAttrStrings(is_mem, 'simple_wb')
1362 self.simple_nonmem_rd = \
1363 self.operands.concatSomeAttrStrings(not_mem, 'simple_rd')
1364 self.simple_nonmem_wb = \
1365 self.operands.concatSomeAttrStrings(not_mem, 'simple_wb')
1366
1367 self.dtld_rd = self.operands.concatAttrStrings('dtld_rd')
1368 self.dtld_wb = self.operands.concatAttrStrings('dtld_wb')
1369 self.dtld_mem_rd = \
1370 self.operands.concatSomeAttrStrings(is_mem, 'dtld_rd')
1371 self.dtld_mem_wb = \
1372 self.operands.concatSomeAttrStrings(is_mem, 'dtld_wb')
1373 self.dtld_nonmem_rd = \
1374 self.operands.concatSomeAttrStrings(not_mem, 'dtld_rd')
1375 self.dtld_nonmem_wb = \
1376 self.operands.concatSomeAttrStrings(not_mem, 'dtld_wb')
1377
1378 self.flags = self.operands.concatAttrLists('flags')
1379
1380 # Make a basic guess on the operand class (function unit type).
1381 # These are good enough for most cases, and will be overridden
1382 # later otherwise.
1383 if 'IsStore' in self.flags:
1384 self.op_class = 'WrPort'
1385 elif 'IsLoad' in self.flags or 'IsPrefetch' in self.flags:
1386 self.op_class = 'RdPort'
1387 elif 'IsFloating' in self.flags:
1388 self.op_class = 'FloatADD'
1389 else:
1390 self.op_class = 'IntALU'
1391
1392 # Assume all instruction flags are of the form 'IsFoo'
1393 instFlagRE = re.compile(r'Is.*')
1394
1395 # OpClass constants are just a little more complicated
1396 opClassRE = re.compile(r'Int.*|Float.*|.*Port|No_OpClass')
1397
1398 class InstObjParams:
1399 def __init__(self, mnem, class_name, base_class = '',
1400 code_block = None, opt_args = []):
1401 self.mnemonic = mnem
1402 self.class_name = class_name
1403 self.base_class = base_class
1404 if code_block:
1405 for code_attr in code_block.__dict__.keys():
1406 setattr(self, code_attr, getattr(code_block, code_attr))
1407 else:
1408 self.constructor = ''
1409 self.flags = []
1410 # Optional arguments are assumed to be either StaticInst flags
1411 # or an OpClass value. To avoid having to import a complete
1412 # list of these values to match against, we do it ad-hoc
1413 # with regexps.
1414 for oa in opt_args:
1415 if instFlagRE.match(oa):
1416 self.flags.append(oa)
1417 elif opClassRE.match(oa):
1418 self.op_class = oa
1419 else:
1420 error(0, 'InstObjParams: optional arg "%s" not recognized '
1421 'as StaticInst::Flag or OpClass.' % oa)
1422
1423 # add flag initialization to contructor here to include
1424 # any flags added via opt_args
1425 self.constructor += makeFlagConstructor(self.flags)
1426
1427 # if 'IsFloating' is set, add call to the FP enable check
1428 # function (which should be provided by isa_desc via a declare)
1429 if 'IsFloating' in self.flags:
1430 self.fp_enable_check = 'fault = checkFpEnableFault(xc);'
1431 else:
1432 self.fp_enable_check = ''
1433
1434 def subst(self, *args):
1435 result = []
1436 for t in args:
1437 if not templateMap.has_key(t):
1438 error(0, 'InstObjParams::subst: undefined template "%s"' % t)
1439 try:
1440 result.append(templateMap[t] % self.__dict__)
1441 except KeyError, key:
1442 error(0, 'InstObjParams::subst: no definition for "%s"' % key)
1443 if len(args) == 1:
1444 result = result[0]
1445 return result
1446
1447 #
1448 # All set... read in and parse the ISA description.
1449 #
1450 yacc.parse(isa_desc)