Deleted Added
sdiff udiff text old ( 12222:6db0fc7407a5 ) new ( 12234:78ece221f9f5 )
full compact
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 # CPU-model-specific substitutions are handled later (in GenCode).
126 template = self.parser.protectCpuSymbols(template)
127
128 # Build a dict ('myDict') to use for the template substitution.
129 # Start with the template namespace. Make a copy since we're
130 # going to modify it.
131 myDict = self.parser.templateMap.copy()
132
133 if isinstance(d, InstObjParams):
134 # If we're dealing with an InstObjParams object, we need

--- 78 unchanged lines hidden (view full) ---

213 myDict.update(d)
214 elif hasattr(d, '__dict__'):
215 # if the argument is an object, we use its attribute map.
216 myDict.update(d.__dict__)
217 else:
218 raise TypeError, "Template.subst() arg must be or have dictionary"
219 return template % myDict
220
221 # Convert to string. This handles the case when a template with a
222 # CPU-specific term gets interpolated into another template or into
223 # an output block.
224 def __str__(self):
225 return self.parser.expandCpuSymbolsToString(self.template)
226
227################
228# Format object.
229#
230# A format object encapsulates an instruction format. It must provide
231# a defineInst() method that generates the code for an instruction
232# definition.
233

--- 45 unchanged lines hidden (view full) ---

279###############
280# GenCode class
281#
282# The GenCode class encapsulates generated code destined for various
283# output files. The header_output and decoder_output attributes are
284# strings containing code destined for decoder.hh and decoder.cc
285# respectively. The decode_block attribute contains code to be
286# incorporated in the decode function itself (that will also end up in
287# decoder.cc). The exec_output attribute is a dictionary with a key
288# for each CPU model name; the value associated with a particular key
289# is the string of code for that CPU model's exec.cc file. The
290# has_decode_default attribute is used in the decode block to allow
291# explicit default clauses to override default default clauses.
292
293class GenCode(object):
294 # Constructor. At this point we substitute out all CPU-specific
295 # symbols. For the exec output, these go into the per-model
296 # dictionary. For all other output types they get collapsed into
297 # a single string.
298 def __init__(self, parser,
299 header_output = '', decoder_output = '', exec_output = '',
300 decode_block = '', has_decode_default = False):
301 self.parser = parser
302 self.header_output = parser.expandCpuSymbolsToString(header_output)
303 self.decoder_output = parser.expandCpuSymbolsToString(decoder_output)
304 self.exec_output = exec_output
305 self.decode_block = decode_block
306 self.has_decode_default = has_decode_default
307
308 # Write these code chunks out to the filesystem. They will be properly
309 # interwoven by the write_top_level_files().
310 def emit(self):
311 if self.header_output:

--- 1145 unchanged lines hidden (view full) ---

1457
1458#######################
1459#
1460# ISA Parser
1461# parses ISA DSL and emits C++ headers and source
1462#
1463
1464class ISAParser(Grammar):
1465 class CpuModel(object):
1466 def __init__(self, name, filename, includes, strings):
1467 self.name = name
1468 self.filename = filename
1469 self.includes = includes
1470 self.strings = strings
1471
1472 def __init__(self, output_dir):
1473 super(ISAParser, self).__init__()
1474 self.output_dir = output_dir
1475
1476 self.filename = None # for output file watermarking/scaremongering
1477
1478 self.cpuModels = [
1479 ISAParser.CpuModel('ExecContext',
1480 'generic_cpu_exec.cc',
1481 '#include "cpu/exec_context.hh"',
1482 { "CPU_exec_context" : "ExecContext" }),
1483 ]
1484
1485 # variable to hold templates
1486 self.templateMap = {}
1487
1488 # This dictionary maps format name strings to Format objects.
1489 self.formatMap = {}
1490
1491 # Track open files and, if applicable, how many chunks it has been
1492 # split into so far.

--- 127 unchanged lines hidden (view full) ---

1620 fn = 'decoder-ns.cc.inc'
1621 assert(fn in self.files)
1622 print >>f, 'namespace %s {' % self.namespace
1623 if splits > 1:
1624 print >>f, '#define __SPLIT %u' % i
1625 print >>f, '#include "%s"' % fn
1626 print >>f, '}'
1627
1628 # instruction execution per-CPU model
1629 splits = self.splits[self.get_file('exec')]
1630 for cpu in self.cpuModels:
1631 for i in range(1, splits+1):
1632 if splits > 1:
1633 file = extn.sub(r'_%d\1' % i, cpu.filename)
1634 else:
1635 file = cpu.filename
1636 with self.open(file) as f:
1637 fn = 'exec-g.cc.inc'
1638 assert(fn in self.files)
1639 f.write('#include "%s"\n' % fn)
1640
1641 f.write(cpu.includes+"\n")
1642
1643 fn = 'decoder.hh'
1644 f.write('#include "%s"\n' % fn)
1645
1646 fn = 'exec-ns.cc.inc'
1647 assert(fn in self.files)
1648 print >>f, 'namespace %s {' % self.namespace
1649 print >>f, '#define CPU_EXEC_CONTEXT %s' \
1650 % cpu.strings['CPU_exec_context']
1651 if splits > 1:
1652 print >>f, '#define __SPLIT %u' % i
1653 print >>f, '#include "%s"' % fn
1654 print >>f, '}'
1655
1656 # max_inst_regs.hh
1657 self.update('max_inst_regs.hh',
1658 '''namespace %(namespace)s {
1659 const int MaxInstSrcRegs = %(maxInstSrcRegs)d;
1660 const int MaxInstDestRegs = %(maxInstDestRegs)d;
1661 const int MaxMiscDestRegs = %(maxMiscDestRegs)d;\n}\n''' % self)
1662
1663 scaremonger_template ='''// DO NOT EDIT

--- 252 unchanged lines hidden (view full) ---

1916 self.isa_name = t[2]
1917 self.namespace = t[2] + 'Inst'
1918
1919 # Output blocks 'output <foo> {{...}}' (C++ code blocks) are copied
1920 # directly to the appropriate output section.
1921
1922 # Massage output block by substituting in template definitions and
1923 # bit operators. We handle '%'s embedded in the string that don't
1924 # indicate template substitutions (or CPU-specific symbols, which
1925 # get handled in GenCode) by doubling them first so that the
1926 # format operation will reduce them back to single '%'s.
1927 def process_output(self, s):
1928 s = self.protectNonSubstPercents(s)
1929 # protects cpu-specific symbols too
1930 s = self.protectCpuSymbols(s)
1931 return substBitOps(s % self.templateMap)
1932
1933 def p_output(self, t):
1934 'output : OUTPUT output_type CODELIT SEMI'
1935 kwargs = { t[2]+'_output' : self.process_output(t[3]) }
1936 GenCode(self, **kwargs).emit()
1937
1938 # global let blocks 'let {{...}}' (Python code blocks) are

--- 482 unchanged lines hidden (view full) ---

2421
2422 # make sure we haven't already defined this one
2423 if id in self.formatMap:
2424 error(lineno, 'format %s redefined.' % id)
2425
2426 # create new object and store in global map
2427 self.formatMap[id] = Format(id, params, code)
2428
2429 def expandCpuSymbolsToDict(self, template):
2430 '''Expand template with CPU-specific references into a
2431 dictionary with an entry for each CPU model name. The entry
2432 key is the model name and the corresponding value is the
2433 template with the CPU-specific refs substituted for that
2434 model.'''
2435
2436 # Protect '%'s that don't go with CPU-specific terms
2437 t = re.sub(r'%(?!\(CPU_)', '%%', template)
2438 result = {}
2439 for cpu in self.cpuModels:
2440 result[cpu.name] = t % cpu.strings
2441 return result
2442
2443 def expandCpuSymbolsToString(self, template):
2444 '''*If* the template has CPU-specific references, return a
2445 single string containing a copy of the template for each CPU
2446 model with the corresponding values substituted in. If the
2447 template has no CPU-specific references, it is returned
2448 unmodified.'''
2449
2450 if template.find('%(CPU_') != -1:
2451 return reduce(lambda x,y: x+y,
2452 self.expandCpuSymbolsToDict(template).values())
2453 else:
2454 return template
2455
2456 def protectCpuSymbols(self, template):
2457 '''Protect CPU-specific references by doubling the
2458 corresponding '%'s (in preparation for substituting a different
2459 set of references into the template).'''
2460
2461 return re.sub(r'%(?=\(CPU_)', '%%', template)
2462
2463 def protectNonSubstPercents(self, s):
2464 '''Protect any non-dict-substitution '%'s in a format string
2465 (i.e. those not followed by '(')'''
2466
2467 return re.sub(r'%(?!\()', '%%', s)
2468
2469 def buildOperandNameMap(self, user_dict, lineno):
2470 operand_name = {}

--- 212 unchanged lines hidden ---