PageRenderTime 36ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/src/arch/isa_parser.py

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