diff options
author | Gabe Black <gabeblack@google.com> | 2017-11-02 01:58:38 -0700 |
---|---|---|
committer | Gabe Black <gabeblack@google.com> | 2017-11-02 09:43:35 +0000 |
commit | 8be75f49fd37712e7cf04c0853bb7504f69a04d6 (patch) | |
tree | f791cd8adccee52d054f5a10b62948021a3d121b /src/arch/isa_parser.py | |
parent | 97c68e8fc56baa39ce7901ac1f73d2ff79b550f2 (diff) | |
download | gem5-8be75f49fd37712e7cf04c0853bb7504f69a04d6.tar.xz |
alpha,arm,mips,power,riscv,sparc,x86,isa: De-specialize ExecContexts.
The ISA parser used to generate different copies of exec functions
for each exec context class a particular CPU wanted to use. That's
since been changed so that those functions take a pointer to the base
ExecContext, so the code which would generate those extra functions
can be removed, and some functions which used to be templated on an
ExecContext subclass can be untemplated, or minimally less templated.
Now that some functions aren't going to be instantiated multiple times
with different signatures, there are also opportunities to collapse
templates and make many instruction definitions simpler within the
parser. Since those changes will be less mechanical, they're left for
later changes and will probably be done in smaller increments.
Change-Id: I0015307bb02dfb9c60380b56d2a820f12169ebea
Reviewed-on: https://gem5-review.googlesource.com/5381
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
Diffstat (limited to 'src/arch/isa_parser.py')
-rwxr-xr-x | src/arch/isa_parser.py | 121 |
1 files changed, 27 insertions, 94 deletions
diff --git a/src/arch/isa_parser.py b/src/arch/isa_parser.py index 7764c344c..fe95d06bf 100755 --- a/src/arch/isa_parser.py +++ b/src/arch/isa_parser.py @@ -122,8 +122,6 @@ class Template(object): # Protect non-Python-dict substitutions (e.g. if there's a printf # in the templated C++ code) template = self.parser.protectNonSubstPercents(self.template) - # CPU-model-specific substitutions are handled later (in GenCode). - template = self.parser.protectCpuSymbols(template) # Build a dict ('myDict') to use for the template substitution. # Start with the template namespace. Make a copy since we're @@ -218,11 +216,9 @@ class Template(object): raise TypeError, "Template.subst() arg must be or have dictionary" return template % myDict - # Convert to string. This handles the case when a template with a - # CPU-specific term gets interpolated into another template or into - # an output block. + # Convert to string. def __str__(self): - return self.parser.expandCpuSymbolsToString(self.template) + return self.template ################ # Format object. @@ -284,23 +280,18 @@ class NoFormat(object): # strings containing code destined for decoder.hh and decoder.cc # respectively. The decode_block attribute contains code to be # incorporated in the decode function itself (that will also end up in -# decoder.cc). The exec_output attribute is a dictionary with a key -# for each CPU model name; the value associated with a particular key -# is the string of code for that CPU model's exec.cc file. The -# has_decode_default attribute is used in the decode block to allow -# explicit default clauses to override default default clauses. +# decoder.cc). The exec_output attribute is the string of code for the +# exec.cc file. The has_decode_default attribute is used in the decode block +# to allow explicit default clauses to override default default clauses. class GenCode(object): - # Constructor. At this point we substitute out all CPU-specific - # symbols. For the exec output, these go into the per-model - # dictionary. For all other output types they get collapsed into - # a single string. + # Constructor. def __init__(self, parser, header_output = '', decoder_output = '', exec_output = '', decode_block = '', has_decode_default = False): self.parser = parser - self.header_output = parser.expandCpuSymbolsToString(header_output) - self.decoder_output = parser.expandCpuSymbolsToString(decoder_output) + self.header_output = header_output + self.decoder_output = decoder_output self.exec_output = exec_output self.decode_block = decode_block self.has_decode_default = has_decode_default @@ -1462,26 +1453,12 @@ class LineTracker(object): # class ISAParser(Grammar): - class CpuModel(object): - def __init__(self, name, filename, includes, strings): - self.name = name - self.filename = filename - self.includes = includes - self.strings = strings - def __init__(self, output_dir): super(ISAParser, self).__init__() self.output_dir = output_dir self.filename = None # for output file watermarking/scaremongering - self.cpuModels = [ - ISAParser.CpuModel('ExecContext', - 'generic_cpu_exec.cc', - '#include "cpu/exec_context.hh"', - { "CPU_exec_context" : "ExecContext" }), - ] - # variable to hold templates self.templateMap = {} @@ -1625,33 +1602,26 @@ class ISAParser(Grammar): print >>f, '#include "%s"' % fn print >>f, '}' - # instruction execution per-CPU model + # instruction execution splits = self.splits[self.get_file('exec')] - for cpu in self.cpuModels: - for i in range(1, splits+1): + for i in range(1, splits+1): + file = 'generic_cpu_exec.cc' + if splits > 1: + file = extn.sub(r'_%d\1' % i, file) + with self.open(file) as f: + fn = 'exec-g.cc.inc' + assert(fn in self.files) + f.write('#include "%s"\n' % fn) + f.write('#include "cpu/exec_context.hh"\n') + f.write('#include "decoder.hh"\n') + + fn = 'exec-ns.cc.inc' + assert(fn in self.files) + print >>f, 'namespace %s {' % self.namespace if splits > 1: - file = extn.sub(r'_%d\1' % i, cpu.filename) - else: - file = cpu.filename - with self.open(file) as f: - fn = 'exec-g.cc.inc' - assert(fn in self.files) - f.write('#include "%s"\n' % fn) - - f.write(cpu.includes+"\n") - - fn = 'decoder.hh' - f.write('#include "%s"\n' % fn) - - fn = 'exec-ns.cc.inc' - assert(fn in self.files) - print >>f, 'namespace %s {' % self.namespace - print >>f, '#define CPU_EXEC_CONTEXT %s' \ - % cpu.strings['CPU_exec_context'] - if splits > 1: - print >>f, '#define __SPLIT %u' % i - print >>f, '#include "%s"' % fn - print >>f, '}' + print >>f, '#define __SPLIT %u' % i + print >>f, '#include "%s"' % fn + print >>f, '}' # max_inst_regs.hh self.update('max_inst_regs.hh', @@ -1921,13 +1891,10 @@ class ISAParser(Grammar): # Massage output block by substituting in template definitions and # bit operators. We handle '%'s embedded in the string that don't - # indicate template substitutions (or CPU-specific symbols, which - # get handled in GenCode) by doubling them first so that the + # indicate template substitutions by doubling them first so that the # format operation will reduce them back to single '%'s. def process_output(self, s): s = self.protectNonSubstPercents(s) - # protects cpu-specific symbols too - s = self.protectCpuSymbols(s) return substBitOps(s % self.templateMap) def p_output(self, t): @@ -2426,40 +2393,6 @@ StaticInstPtr # create new object and store in global map self.formatMap[id] = Format(id, params, code) - def expandCpuSymbolsToDict(self, template): - '''Expand template with CPU-specific references into a - dictionary with an entry for each CPU model name. The entry - key is the model name and the corresponding value is the - template with the CPU-specific refs substituted for that - model.''' - - # Protect '%'s that don't go with CPU-specific terms - t = re.sub(r'%(?!\(CPU_)', '%%', template) - result = {} - for cpu in self.cpuModels: - result[cpu.name] = t % cpu.strings - return result - - def expandCpuSymbolsToString(self, template): - '''*If* the template has CPU-specific references, return a - single string containing a copy of the template for each CPU - model with the corresponding values substituted in. If the - template has no CPU-specific references, it is returned - unmodified.''' - - if template.find('%(CPU_') != -1: - return reduce(lambda x,y: x+y, - self.expandCpuSymbolsToDict(template).values()) - else: - return template - - def protectCpuSymbols(self, template): - '''Protect CPU-specific references by doubling the - corresponding '%'s (in preparation for substituting a different - set of references into the template).''' - - return re.sub(r'%(?=\(CPU_)', '%%', template) - def protectNonSubstPercents(self, s): '''Protect any non-dict-substitution '%'s in a format string (i.e. those not followed by '(')''' |