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