1# Copyright (c) 2014, 2016 ARM Limited 2# All rights reserved 3# 4# The license below extends only to copyright in the software and shall 5# not be construed as granting a license to any other intellectual 6# property including but not limited to intellectual property relating 7# to a hardware implementation of the functionality of the software 8# licensed hereunder. You may use the software subject to the license --- 108 unchanged lines hidden (view full) --- 117 self.template = t 118 119 def subst(self, d): 120 myDict = None 121 122 # Protect non-Python-dict substitutions (e.g. if there's a printf 123 # in the templated C++ code) 124 template = self.parser.protectNonSubstPercents(self.template) |
125 126 # Build a dict ('myDict') to use for the template substitution. 127 # Start with the template namespace. Make a copy since we're 128 # going to modify it. 129 myDict = self.parser.templateMap.copy() 130 131 if isinstance(d, InstObjParams): 132 # If we're dealing with an InstObjParams object, we need --- 78 unchanged lines hidden (view full) --- 211 myDict.update(d) 212 elif hasattr(d, '__dict__'): 213 # if the argument is an object, we use its attribute map. 214 myDict.update(d.__dict__) 215 else: 216 raise TypeError, "Template.subst() arg must be or have dictionary" 217 return template % myDict 218 |
219 # Convert to string. |
220 def __str__(self): |
221 return self.template |
222 223################ 224# Format object. 225# 226# A format object encapsulates an instruction format. It must provide 227# a defineInst() method that generates the code for an instruction 228# definition. 229 --- 45 unchanged lines hidden (view full) --- 275############### 276# GenCode class 277# 278# The GenCode class encapsulates generated code destined for various 279# output files. The header_output and decoder_output attributes are 280# strings containing code destined for decoder.hh and decoder.cc 281# respectively. The decode_block attribute contains code to be 282# incorporated in the decode function itself (that will also end up in |
283# decoder.cc). The exec_output attribute is the string of code for the 284# exec.cc file. The has_decode_default attribute is used in the decode block 285# to allow explicit default clauses to override default default clauses. |
286 287class GenCode(object): |
288 # Constructor. |
289 def __init__(self, parser, 290 header_output = '', decoder_output = '', exec_output = '', 291 decode_block = '', has_decode_default = False): 292 self.parser = parser |
293 self.header_output = header_output 294 self.decoder_output = decoder_output |
295 self.exec_output = exec_output 296 self.decode_block = decode_block 297 self.has_decode_default = has_decode_default 298 299 # Write these code chunks out to the filesystem. They will be properly 300 # interwoven by the write_top_level_files(). 301 def emit(self): 302 if self.header_output: --- 1145 unchanged lines hidden (view full) --- 1448 1449####################### 1450# 1451# ISA Parser 1452# parses ISA DSL and emits C++ headers and source 1453# 1454 1455class ISAParser(Grammar): |
1456 def __init__(self, output_dir): 1457 super(ISAParser, self).__init__() 1458 self.output_dir = output_dir 1459 1460 self.filename = None # for output file watermarking/scaremongering 1461 |
1462 # variable to hold templates 1463 self.templateMap = {} 1464 1465 # This dictionary maps format name strings to Format objects. 1466 self.formatMap = {} 1467 1468 # Track open files and, if applicable, how many chunks it has been 1469 # split into so far. --- 127 unchanged lines hidden (view full) --- 1597 fn = 'decoder-ns.cc.inc' 1598 assert(fn in self.files) 1599 print >>f, 'namespace %s {' % self.namespace 1600 if splits > 1: 1601 print >>f, '#define __SPLIT %u' % i 1602 print >>f, '#include "%s"' % fn 1603 print >>f, '}' 1604 |
1605 # instruction execution |
1606 splits = self.splits[self.get_file('exec')] |
1607 for i in range(1, splits+1): 1608 file = 'generic_cpu_exec.cc' 1609 if splits > 1: 1610 file = extn.sub(r'_%d\1' % i, file) 1611 with self.open(file) as f: 1612 fn = 'exec-g.cc.inc' 1613 assert(fn in self.files) 1614 f.write('#include "%s"\n' % fn) 1615 f.write('#include "cpu/exec_context.hh"\n') 1616 f.write('#include "decoder.hh"\n') 1617 1618 fn = 'exec-ns.cc.inc' 1619 assert(fn in self.files) 1620 print >>f, 'namespace %s {' % self.namespace |
1621 if splits > 1: |
1622 print >>f, '#define __SPLIT %u' % i 1623 print >>f, '#include "%s"' % fn 1624 print >>f, '}' |
1625 |
1626 # max_inst_regs.hh 1627 self.update('max_inst_regs.hh', 1628 '''namespace %(namespace)s { 1629 const int MaxInstSrcRegs = %(maxInstSrcRegs)d; 1630 const int MaxInstDestRegs = %(maxInstDestRegs)d; 1631 const int MaxMiscDestRegs = %(maxMiscDestRegs)d;\n}\n''' % self) 1632 1633 scaremonger_template ='''// DO NOT EDIT --- 252 unchanged lines hidden (view full) --- 1886 self.isa_name = t[2] 1887 self.namespace = t[2] + 'Inst' 1888 1889 # Output blocks 'output <foo> {{...}}' (C++ code blocks) are copied 1890 # directly to the appropriate output section. 1891 1892 # Massage output block by substituting in template definitions and 1893 # bit operators. We handle '%'s embedded in the string that don't |
1894 # indicate template substitutions by doubling them first so that the |
1895 # format operation will reduce them back to single '%'s. 1896 def process_output(self, s): 1897 s = self.protectNonSubstPercents(s) |
1898 return substBitOps(s % self.templateMap) 1899 1900 def p_output(self, t): 1901 'output : OUTPUT output_type CODELIT SEMI' 1902 kwargs = { t[2]+'_output' : self.process_output(t[3]) } 1903 GenCode(self, **kwargs).emit() 1904 1905 # global let blocks 'let {{...}}' (Python code blocks) are --- 482 unchanged lines hidden (view full) --- 2388 2389 # make sure we haven't already defined this one 2390 if id in self.formatMap: 2391 error(lineno, 'format %s redefined.' % id) 2392 2393 # create new object and store in global map 2394 self.formatMap[id] = Format(id, params, code) 2395 |
2396 def protectNonSubstPercents(self, s): 2397 '''Protect any non-dict-substitution '%'s in a format string 2398 (i.e. those not followed by '(')''' 2399 2400 return re.sub(r'%(?!\()', '%%', s) 2401 2402 def buildOperandNameMap(self, user_dict, lineno): 2403 operand_name = {} --- 212 unchanged lines hidden --- |