PageRenderTime 65ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/src/arch/isa_parser.py

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