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